Package proton :: Module _data
[frames] | no frames]

Source Code for Module proton._data

   1  # 
   2  # Licensed to the Apache Software Foundation (ASF) under one 
   3  # or more contributor license agreements.  See the NOTICE file 
   4  # distributed with this work for additional information 
   5  # regarding copyright ownership.  The ASF licenses this file 
   6  # to you under the Apache License, Version 2.0 (the 
   7  # "License"); you may not use this file except in compliance 
   8  # with the License.  You may obtain a copy of the License at 
   9  # 
  10  #   http://www.apache.org/licenses/LICENSE-2.0 
  11  # 
  12  # Unless required by applicable law or agreed to in writing, 
  13  # software distributed under the License is distributed on an 
  14  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
  15  # KIND, either express or implied.  See the License for the 
  16  # specific language governing permissions and limitations 
  17  # under the License. 
  18  # 
  19   
  20  from __future__ import absolute_import 
  21   
  22  import uuid 
  23   
  24  from cproton import PN_ARRAY, PN_BINARY, PN_BOOL, PN_BYTE, PN_CHAR, PN_DECIMAL128, PN_DECIMAL32, PN_DECIMAL64, \ 
  25      PN_DESCRIBED, PN_DOUBLE, PN_FLOAT, PN_INT, PN_LIST, PN_LONG, PN_MAP, PN_NULL, PN_OVERFLOW, PN_SHORT, PN_STRING, \ 
  26      PN_SYMBOL, PN_TIMESTAMP, PN_UBYTE, PN_UINT, PN_ULONG, PN_USHORT, PN_UUID, pn_data, pn_data_clear, pn_data_copy, \ 
  27      pn_data_decode, pn_data_dump, pn_data_encode, pn_data_encoded_size, pn_data_enter, pn_data_error, pn_data_exit, \ 
  28      pn_data_format, pn_data_free, pn_data_get_array, pn_data_get_array_type, pn_data_get_binary, pn_data_get_bool, \ 
  29      pn_data_get_byte, pn_data_get_char, pn_data_get_decimal128, pn_data_get_decimal32, pn_data_get_decimal64, \ 
  30      pn_data_get_double, pn_data_get_float, pn_data_get_int, pn_data_get_list, pn_data_get_long, pn_data_get_map, \ 
  31      pn_data_get_short, pn_data_get_string, pn_data_get_symbol, pn_data_get_timestamp, pn_data_get_ubyte, \ 
  32      pn_data_get_uint, pn_data_get_ulong, pn_data_get_ushort, pn_data_get_uuid, pn_data_is_array_described, \ 
  33      pn_data_is_described, pn_data_is_null, pn_data_lookup, pn_data_narrow, pn_data_next, pn_data_prev, \ 
  34      pn_data_put_array, pn_data_put_binary, pn_data_put_bool, pn_data_put_byte, pn_data_put_char, pn_data_put_decimal128, \ 
  35      pn_data_put_decimal32, pn_data_put_decimal64, pn_data_put_described, pn_data_put_double, pn_data_put_float, \ 
  36      pn_data_put_int, pn_data_put_list, pn_data_put_long, pn_data_put_map, pn_data_put_null, pn_data_put_short, \ 
  37      pn_data_put_string, pn_data_put_symbol, pn_data_put_timestamp, pn_data_put_ubyte, pn_data_put_uint, \ 
  38      pn_data_put_ulong, pn_data_put_ushort, pn_data_put_uuid, pn_data_rewind, pn_data_type, pn_data_widen, pn_error_text 
  39   
  40  from . import _compat 
  41  from ._common import Constant 
  42  from ._exceptions import DataException, EXCEPTIONS 
  43   
  44  # 
  45  # Hacks to provide Python2 <---> Python3 compatibility 
  46  # 
  47  # The results are 
  48  # |       |long|unicode| 
  49  # |python2|long|unicode| 
  50  # |python3| int|    str| 
  51  try: 
  52      long() 
  53  except NameError: 
  54      long = int 
  55  try: 
  56      unicode() 
  57  except NameError: 
  58      unicode = str 
59 60 61 -class UnmappedType:
62
63 - def __init__(self, msg):
64 self.msg = msg
65
66 - def __repr__(self):
67 return "UnmappedType(%s)" % self.msg
68
69 70 -class ulong(long):
71
72 - def __init__(self, l):
73 if (l < 0): 74 raise AssertionError("initializing ulong with negative value") 75 super(ulong, self).__new__(ulong, l)
76
77 - def __repr__(self):
78 return "ulong(%s)" % long.__repr__(self)
79
80 81 -class timestamp(long):
82
83 - def __repr__(self):
84 return "timestamp(%s)" % long.__repr__(self)
85
86 87 -class symbol(unicode):
88
89 - def __repr__(self):
90 return "symbol(%s)" % unicode.__repr__(self)
91
92 93 -class char(unicode):
94
95 - def __repr__(self):
96 return "char(%s)" % unicode.__repr__(self)
97
98 99 -class byte(int):
100
101 - def __repr__(self):
102 return "byte(%s)" % int.__repr__(self)
103
104 105 -class short(int):
106
107 - def __repr__(self):
108 return "short(%s)" % int.__repr__(self)
109
110 111 -class int32(int):
112
113 - def __repr__(self):
114 return "int32(%s)" % int.__repr__(self)
115
116 117 -class ubyte(int):
118
119 - def __init__(self, i):
120 if (i < 0): 121 raise AssertionError("initializing ubyte with negative value") 122 super(ubyte, self).__new__(ubyte, i)
123
124 - def __repr__(self):
125 return "ubyte(%s)" % int.__repr__(self)
126
127 128 -class ushort(int):
129
130 - def __init__(self, i):
131 if (i < 0): 132 raise AssertionError("initializing ushort with negative value") 133 super(ushort, self).__new__(ushort, i)
134
135 - def __repr__(self):
136 return "ushort(%s)" % int.__repr__(self)
137
138 139 -class uint(long):
140
141 - def __init__(self, l):
142 if (l < 0): 143 raise AssertionError("initializing uint with negative value") 144 super(uint, self).__new__(uint, l)
145
146 - def __repr__(self):
147 return "uint(%s)" % long.__repr__(self)
148
149 150 -class float32(float):
151
152 - def __repr__(self):
153 return "float32(%s)" % float.__repr__(self)
154
155 156 -class decimal32(int):
157
158 - def __repr__(self):
159 return "decimal32(%s)" % int.__repr__(self)
160
161 162 -class decimal64(long):
163
164 - def __repr__(self):
165 return "decimal64(%s)" % long.__repr__(self)
166
167 168 -class decimal128(bytes):
169
170 - def __repr__(self):
171 return "decimal128(%s)" % bytes.__repr__(self)
172
173 174 -class Described(object):
175
176 - def __init__(self, descriptor, value):
177 self.descriptor = descriptor 178 self.value = value
179
180 - def __repr__(self):
181 return "Described(%r, %r)" % (self.descriptor, self.value)
182
183 - def __eq__(self, o):
184 if isinstance(o, Described): 185 return self.descriptor == o.descriptor and self.value == o.value 186 else: 187 return False
188 189 190 UNDESCRIBED = Constant("UNDESCRIBED")
191 192 193 -class Array(object):
194
195 - def __init__(self, descriptor, type, *elements):
196 self.descriptor = descriptor 197 self.type = type 198 self.elements = elements
199
200 - def __iter__(self):
201 return iter(self.elements)
202
203 - def __repr__(self):
204 if self.elements: 205 els = ", %s" % (", ".join(map(repr, self.elements))) 206 else: 207 els = "" 208 return "Array(%r, %r%s)" % (self.descriptor, self.type, els)
209
210 - def __eq__(self, o):
211 if isinstance(o, Array): 212 return self.descriptor == o.descriptor and \ 213 self.type == o.type and self.elements == o.elements 214 else: 215 return False
216
217 218 -class Data:
219 """ 220 The L{Data} class provides an interface for decoding, extracting, 221 creating, and encoding arbitrary AMQP data. A L{Data} object 222 contains a tree of AMQP values. Leaf nodes in this tree correspond 223 to scalars in the AMQP type system such as L{ints<INT>} or 224 L{strings<STRING>}. Non-leaf nodes in this tree correspond to 225 compound values in the AMQP type system such as L{lists<LIST>}, 226 L{maps<MAP>}, L{arrays<ARRAY>}, or L{described values<DESCRIBED>}. 227 The root node of the tree is the L{Data} object itself and can have 228 an arbitrary number of children. 229 230 A L{Data} object maintains the notion of the current sibling node 231 and a current parent node. Siblings are ordered within their parent. 232 Values are accessed and/or added by using the L{next}, L{prev}, 233 L{enter}, and L{exit} methods to navigate to the desired location in 234 the tree and using the supplied variety of put_*/get_* methods to 235 access or add a value of the desired type. 236 237 The put_* methods will always add a value I{after} the current node 238 in the tree. If the current node has a next sibling the put_* method 239 will overwrite the value on this node. If there is no current node 240 or the current node has no next sibling then one will be added. The 241 put_* methods always set the added/modified node to the current 242 node. The get_* methods read the value of the current node and do 243 not change which node is current. 244 245 The following types of scalar values are supported: 246 247 - L{NULL} 248 - L{BOOL} 249 - L{UBYTE} 250 - L{USHORT} 251 - L{SHORT} 252 - L{UINT} 253 - L{INT} 254 - L{ULONG} 255 - L{LONG} 256 - L{FLOAT} 257 - L{DOUBLE} 258 - L{BINARY} 259 - L{STRING} 260 - L{SYMBOL} 261 262 The following types of compound values are supported: 263 264 - L{DESCRIBED} 265 - L{ARRAY} 266 - L{LIST} 267 - L{MAP} 268 """ 269 270 NULL = PN_NULL; "A null value." 271 BOOL = PN_BOOL; "A boolean value." 272 UBYTE = PN_UBYTE; "An unsigned byte value." 273 BYTE = PN_BYTE; "A signed byte value." 274 USHORT = PN_USHORT; "An unsigned short value." 275 SHORT = PN_SHORT; "A short value." 276 UINT = PN_UINT; "An unsigned int value." 277 INT = PN_INT; "A signed int value." 278 CHAR = PN_CHAR; "A character value." 279 ULONG = PN_ULONG; "An unsigned long value." 280 LONG = PN_LONG; "A signed long value." 281 TIMESTAMP = PN_TIMESTAMP; "A timestamp value." 282 FLOAT = PN_FLOAT; "A float value." 283 DOUBLE = PN_DOUBLE; "A double value." 284 DECIMAL32 = PN_DECIMAL32; "A DECIMAL32 value." 285 DECIMAL64 = PN_DECIMAL64; "A DECIMAL64 value." 286 DECIMAL128 = PN_DECIMAL128; "A DECIMAL128 value." 287 UUID = PN_UUID; "A UUID value." 288 BINARY = PN_BINARY; "A binary string." 289 STRING = PN_STRING; "A unicode string." 290 SYMBOL = PN_SYMBOL; "A symbolic string." 291 DESCRIBED = PN_DESCRIBED; "A described value." 292 ARRAY = PN_ARRAY; "An array value." 293 LIST = PN_LIST; "A list value." 294 MAP = PN_MAP; "A map value." 295 296 type_names = { 297 NULL: "null", 298 BOOL: "bool", 299 BYTE: "byte", 300 UBYTE: "ubyte", 301 SHORT: "short", 302 USHORT: "ushort", 303 INT: "int", 304 UINT: "uint", 305 CHAR: "char", 306 LONG: "long", 307 ULONG: "ulong", 308 TIMESTAMP: "timestamp", 309 FLOAT: "float", 310 DOUBLE: "double", 311 DECIMAL32: "decimal32", 312 DECIMAL64: "decimal64", 313 DECIMAL128: "decimal128", 314 UUID: "uuid", 315 BINARY: "binary", 316 STRING: "string", 317 SYMBOL: "symbol", 318 DESCRIBED: "described", 319 ARRAY: "array", 320 LIST: "list", 321 MAP: "map" 322 } 323 324 @classmethod
325 - def type_name(type):
326 return Data.type_names[type]
327
328 - def __init__(self, capacity=16):
329 if isinstance(capacity, (int, long)): 330 self._data = pn_data(capacity) 331 self._free = True 332 else: 333 self._data = capacity 334 self._free = False
335
336 - def __del__(self):
337 if self._free and hasattr(self, "_data"): 338 pn_data_free(self._data) 339 del self._data
340
341 - def _check(self, err):
342 if err < 0: 343 exc = EXCEPTIONS.get(err, DataException) 344 raise exc("[%s]: %s" % (err, pn_error_text(pn_data_error(self._data)))) 345 else: 346 return err
347
348 - def clear(self):
349 """ 350 Clears the data object. 351 """ 352 pn_data_clear(self._data)
353
354 - def rewind(self):
355 """ 356 Clears current node and sets the parent to the root node. Clearing the 357 current node sets it _before_ the first node, calling next() will advance to 358 the first node. 359 """ 360 assert self._data is not None 361 pn_data_rewind(self._data)
362
363 - def next(self):
364 """ 365 Advances the current node to its next sibling and returns its 366 type. If there is no next sibling the current node remains 367 unchanged and None is returned. 368 """ 369 found = pn_data_next(self._data) 370 if found: 371 return self.type() 372 else: 373 return None
374
375 - def prev(self):
376 """ 377 Advances the current node to its previous sibling and returns its 378 type. If there is no previous sibling the current node remains 379 unchanged and None is returned. 380 """ 381 found = pn_data_prev(self._data) 382 if found: 383 return self.type() 384 else: 385 return None
386
387 - def enter(self):
388 """ 389 Sets the parent node to the current node and clears the current node. 390 Clearing the current node sets it _before_ the first child, 391 call next() advances to the first child. 392 """ 393 return pn_data_enter(self._data)
394
395 - def exit(self):
396 """ 397 Sets the current node to the parent node and the parent node to 398 its own parent. 399 """ 400 return pn_data_exit(self._data)
401
402 - def lookup(self, name):
403 return pn_data_lookup(self._data, name)
404
405 - def narrow(self):
406 pn_data_narrow(self._data)
407
408 - def widen(self):
409 pn_data_widen(self._data)
410
411 - def type(self):
412 """ 413 Returns the type of the current node. 414 """ 415 dtype = pn_data_type(self._data) 416 if dtype == -1: 417 return None 418 else: 419 return dtype
420
421 - def encoded_size(self):
422 """ 423 Returns the size in bytes needed to encode the data in AMQP format. 424 """ 425 return pn_data_encoded_size(self._data)
426
427 - def encode(self):
428 """ 429 Returns a representation of the data encoded in AMQP format. 430 """ 431 size = 1024 432 while True: 433 cd, enc = pn_data_encode(self._data, size) 434 if cd == PN_OVERFLOW: 435 size *= 2 436 elif cd >= 0: 437 return enc 438 else: 439 self._check(cd)
440
441 - def decode(self, encoded):
442 """ 443 Decodes the first value from supplied AMQP data and returns the 444 number of bytes consumed. 445 446 @type encoded: binary 447 @param encoded: AMQP encoded binary data 448 """ 449 return self._check(pn_data_decode(self._data, encoded))
450
451 - def put_list(self):
452 """ 453 Puts a list value. Elements may be filled by entering the list 454 node and putting element values. 455 456 >>> data = Data() 457 >>> data.put_list() 458 >>> data.enter() 459 >>> data.put_int(1) 460 >>> data.put_int(2) 461 >>> data.put_int(3) 462 >>> data.exit() 463 """ 464 self._check(pn_data_put_list(self._data))
465
466 - def put_map(self):
467 """ 468 Puts a map value. Elements may be filled by entering the map node 469 and putting alternating key value pairs. 470 471 >>> data = Data() 472 >>> data.put_map() 473 >>> data.enter() 474 >>> data.put_string("key") 475 >>> data.put_string("value") 476 >>> data.exit() 477 """ 478 self._check(pn_data_put_map(self._data))
479
480 - def put_array(self, described, element_type):
481 """ 482 Puts an array value. Elements may be filled by entering the array 483 node and putting the element values. The values must all be of the 484 specified array element type. If an array is described then the 485 first child value of the array is the descriptor and may be of any 486 type. 487 488 >>> data = Data() 489 >>> 490 >>> data.put_array(False, Data.INT) 491 >>> data.enter() 492 >>> data.put_int(1) 493 >>> data.put_int(2) 494 >>> data.put_int(3) 495 >>> data.exit() 496 >>> 497 >>> data.put_array(True, Data.DOUBLE) 498 >>> data.enter() 499 >>> data.put_symbol("array-descriptor") 500 >>> data.put_double(1.1) 501 >>> data.put_double(1.2) 502 >>> data.put_double(1.3) 503 >>> data.exit() 504 505 @type described: bool 506 @param described: specifies whether the array is described 507 @type element_type: int 508 @param element_type: the type of the array elements 509 """ 510 self._check(pn_data_put_array(self._data, described, element_type))
511
512 - def put_described(self):
513 """ 514 Puts a described value. A described node has two children, the 515 descriptor and the value. These are specified by entering the node 516 and putting the desired values. 517 518 >>> data = Data() 519 >>> data.put_described() 520 >>> data.enter() 521 >>> data.put_symbol("value-descriptor") 522 >>> data.put_string("the value") 523 >>> data.exit() 524 """ 525 self._check(pn_data_put_described(self._data))
526
527 - def put_null(self):
528 """ 529 Puts a null value. 530 """ 531 self._check(pn_data_put_null(self._data))
532
533 - def put_bool(self, b):
534 """ 535 Puts a boolean value. 536 537 @param b: a boolean value 538 """ 539 self._check(pn_data_put_bool(self._data, b))
540
541 - def put_ubyte(self, ub):
542 """ 543 Puts an unsigned byte value. 544 545 @param ub: an integral value 546 """ 547 self._check(pn_data_put_ubyte(self._data, ub))
548
549 - def put_byte(self, b):
550 """ 551 Puts a signed byte value. 552 553 @param b: an integral value 554 """ 555 self._check(pn_data_put_byte(self._data, b))
556
557 - def put_ushort(self, us):
558 """ 559 Puts an unsigned short value. 560 561 @param us: an integral value. 562 """ 563 self._check(pn_data_put_ushort(self._data, us))
564
565 - def put_short(self, s):
566 """ 567 Puts a signed short value. 568 569 @param s: an integral value 570 """ 571 self._check(pn_data_put_short(self._data, s))
572
573 - def put_uint(self, ui):
574 """ 575 Puts an unsigned int value. 576 577 @param ui: an integral value 578 """ 579 self._check(pn_data_put_uint(self._data, ui))
580
581 - def put_int(self, i):
582 """ 583 Puts a signed int value. 584 585 @param i: an integral value 586 """ 587 self._check(pn_data_put_int(self._data, i))
588
589 - def put_char(self, c):
590 """ 591 Puts a char value. 592 593 @param c: a single character 594 """ 595 self._check(pn_data_put_char(self._data, ord(c)))
596
597 - def put_ulong(self, ul):
598 """ 599 Puts an unsigned long value. 600 601 @param ul: an integral value 602 """ 603 self._check(pn_data_put_ulong(self._data, ul))
604
605 - def put_long(self, l):
606 """ 607 Puts a signed long value. 608 609 @param l: an integral value 610 """ 611 self._check(pn_data_put_long(self._data, l))
612
613 - def put_timestamp(self, t):
614 """ 615 Puts a timestamp value. 616 617 @param t: an integral value 618 """ 619 self._check(pn_data_put_timestamp(self._data, t))
620
621 - def put_float(self, f):
622 """ 623 Puts a float value. 624 625 @param f: a floating point value 626 """ 627 self._check(pn_data_put_float(self._data, f))
628
629 - def put_double(self, d):
630 """ 631 Puts a double value. 632 633 @param d: a floating point value. 634 """ 635 self._check(pn_data_put_double(self._data, d))
636
637 - def put_decimal32(self, d):
638 """ 639 Puts a decimal32 value. 640 641 @param d: a decimal32 value 642 """ 643 self._check(pn_data_put_decimal32(self._data, d))
644
645 - def put_decimal64(self, d):
646 """ 647 Puts a decimal64 value. 648 649 @param d: a decimal64 value 650 """ 651 self._check(pn_data_put_decimal64(self._data, d))
652
653 - def put_decimal128(self, d):
654 """ 655 Puts a decimal128 value. 656 657 @param d: a decimal128 value 658 """ 659 self._check(pn_data_put_decimal128(self._data, d))
660
661 - def put_uuid(self, u):
662 """ 663 Puts a UUID value. 664 665 @param u: a uuid value 666 """ 667 self._check(pn_data_put_uuid(self._data, u.bytes))
668
669 - def put_binary(self, b):
670 """ 671 Puts a binary value. 672 673 @type b: binary 674 @param b: a binary value 675 """ 676 self._check(pn_data_put_binary(self._data, b))
677
678 - def put_memoryview(self, mv):
679 """Put a python memoryview object as an AMQP binary value""" 680 self.put_binary(mv.tobytes())
681
682 - def put_buffer(self, buff):
683 """Put a python buffer object as an AMQP binary value""" 684 self.put_binary(bytes(buff))
685
686 - def put_string(self, s):
687 """ 688 Puts a unicode value. 689 690 @type s: unicode 691 @param s: a unicode value 692 """ 693 self._check(pn_data_put_string(self._data, s.encode("utf8")))
694
695 - def put_symbol(self, s):
696 """ 697 Puts a symbolic value. 698 699 @type s: string 700 @param s: the symbol name 701 """ 702 self._check(pn_data_put_symbol(self._data, s.encode('ascii')))
703
704 - def get_list(self):
705 """ 706 If the current node is a list, return the number of elements, 707 otherwise return zero. List elements can be accessed by entering 708 the list. 709 710 >>> count = data.get_list() 711 >>> data.enter() 712 >>> for i in range(count): 713 ... type = data.next() 714 ... if type == Data.STRING: 715 ... print data.get_string() 716 ... elif type == ...: 717 ... ... 718 >>> data.exit() 719 """ 720 return pn_data_get_list(self._data)
721
722 - def get_map(self):
723 """ 724 If the current node is a map, return the number of child elements, 725 otherwise return zero. Key value pairs can be accessed by entering 726 the map. 727 728 >>> count = data.get_map() 729 >>> data.enter() 730 >>> for i in range(count/2): 731 ... type = data.next() 732 ... if type == Data.STRING: 733 ... print data.get_string() 734 ... elif type == ...: 735 ... ... 736 >>> data.exit() 737 """ 738 return pn_data_get_map(self._data)
739
740 - def get_array(self):
741 """ 742 If the current node is an array, return a tuple of the element 743 count, a boolean indicating whether the array is described, and 744 the type of each element, otherwise return (0, False, None). Array 745 data can be accessed by entering the array. 746 747 >>> # read an array of strings with a symbolic descriptor 748 >>> count, described, type = data.get_array() 749 >>> data.enter() 750 >>> data.next() 751 >>> print "Descriptor:", data.get_symbol() 752 >>> for i in range(count): 753 ... data.next() 754 ... print "Element:", data.get_string() 755 >>> data.exit() 756 """ 757 count = pn_data_get_array(self._data) 758 described = pn_data_is_array_described(self._data) 759 type = pn_data_get_array_type(self._data) 760 if type == -1: 761 type = None 762 return count, described, type
763
764 - def is_described(self):
765 """ 766 Checks if the current node is a described value. The descriptor 767 and value may be accessed by entering the described value. 768 769 >>> # read a symbolically described string 770 >>> assert data.is_described() # will error if the current node is not described 771 >>> data.enter() 772 >>> data.next() 773 >>> print data.get_symbol() 774 >>> data.next() 775 >>> print data.get_string() 776 >>> data.exit() 777 """ 778 return pn_data_is_described(self._data)
779
780 - def is_null(self):
781 """ 782 Checks if the current node is a null. 783 """ 784 return pn_data_is_null(self._data)
785
786 - def get_bool(self):
787 """ 788 If the current node is a boolean, returns its value, returns False 789 otherwise. 790 """ 791 return pn_data_get_bool(self._data)
792
793 - def get_ubyte(self):
794 """ 795 If the current node is an unsigned byte, returns its value, 796 returns 0 otherwise. 797 """ 798 return ubyte(pn_data_get_ubyte(self._data))
799
800 - def get_byte(self):
801 """ 802 If the current node is a signed byte, returns its value, returns 0 803 otherwise. 804 """ 805 return byte(pn_data_get_byte(self._data))
806
807 - def get_ushort(self):
808 """ 809 If the current node is an unsigned short, returns its value, 810 returns 0 otherwise. 811 """ 812 return ushort(pn_data_get_ushort(self._data))
813
814 - def get_short(self):
815 """ 816 If the current node is a signed short, returns its value, returns 817 0 otherwise. 818 """ 819 return short(pn_data_get_short(self._data))
820
821 - def get_uint(self):
822 """ 823 If the current node is an unsigned int, returns its value, returns 824 0 otherwise. 825 """ 826 return uint(pn_data_get_uint(self._data))
827
828 - def get_int(self):
829 """ 830 If the current node is a signed int, returns its value, returns 0 831 otherwise. 832 """ 833 return int32(pn_data_get_int(self._data))
834
835 - def get_char(self):
836 """ 837 If the current node is a char, returns its value, returns 0 838 otherwise. 839 """ 840 return char(_compat.unichr(pn_data_get_char(self._data)))
841
842 - def get_ulong(self):
843 """ 844 If the current node is an unsigned long, returns its value, 845 returns 0 otherwise. 846 """ 847 return ulong(pn_data_get_ulong(self._data))
848
849 - def get_long(self):
850 """ 851 If the current node is an signed long, returns its value, returns 852 0 otherwise. 853 """ 854 return long(pn_data_get_long(self._data))
855
856 - def get_timestamp(self):
857 """ 858 If the current node is a timestamp, returns its value, returns 0 859 otherwise. 860 """ 861 return timestamp(pn_data_get_timestamp(self._data))
862
863 - def get_float(self):
864 """ 865 If the current node is a float, returns its value, raises 0 866 otherwise. 867 """ 868 return float32(pn_data_get_float(self._data))
869
870 - def get_double(self):
871 """ 872 If the current node is a double, returns its value, returns 0 873 otherwise. 874 """ 875 return pn_data_get_double(self._data)
876 877 # XXX: need to convert
878 - def get_decimal32(self):
879 """ 880 If the current node is a decimal32, returns its value, returns 0 881 otherwise. 882 """ 883 return decimal32(pn_data_get_decimal32(self._data))
884 885 # XXX: need to convert
886 - def get_decimal64(self):
887 """ 888 If the current node is a decimal64, returns its value, returns 0 889 otherwise. 890 """ 891 return decimal64(pn_data_get_decimal64(self._data))
892 893 # XXX: need to convert
894 - def get_decimal128(self):
895 """ 896 If the current node is a decimal128, returns its value, returns 0 897 otherwise. 898 """ 899 return decimal128(pn_data_get_decimal128(self._data))
900
901 - def get_uuid(self):
902 """ 903 If the current node is a UUID, returns its value, returns None 904 otherwise. 905 """ 906 if pn_data_type(self._data) == Data.UUID: 907 return uuid.UUID(bytes=pn_data_get_uuid(self._data)) 908 else: 909 return None
910
911 - def get_binary(self):
912 """ 913 If the current node is binary, returns its value, returns "" 914 otherwise. 915 """ 916 return pn_data_get_binary(self._data)
917
918 - def get_string(self):
919 """ 920 If the current node is a string, returns its value, returns "" 921 otherwise. 922 """ 923 return pn_data_get_string(self._data).decode("utf8")
924
925 - def get_symbol(self):
926 """ 927 If the current node is a symbol, returns its value, returns "" 928 otherwise. 929 """ 930 return symbol(pn_data_get_symbol(self._data).decode('ascii'))
931
932 - def copy(self, src):
933 self._check(pn_data_copy(self._data, src._data))
934
935 - def format(self):
936 sz = 16 937 while True: 938 err, result = pn_data_format(self._data, sz) 939 if err == PN_OVERFLOW: 940 sz *= 2 941 continue 942 else: 943 self._check(err) 944 return result
945
946 - def dump(self):
947 pn_data_dump(self._data)
948
949 - def put_dict(self, d):
950 self.put_map() 951 self.enter() 952 try: 953 for k, v in d.items(): 954 self.put_object(k) 955 self.put_object(v) 956 finally: 957 self.exit()
958
959 - def get_dict(self):
960 if self.enter(): 961 try: 962 result = {} 963 while self.next(): 964 k = self.get_object() 965 if self.next(): 966 v = self.get_object() 967 else: 968 v = None 969 result[k] = v 970 finally: 971 self.exit() 972 return result
973
974 - def put_sequence(self, s):
975 self.put_list() 976 self.enter() 977 try: 978 for o in s: 979 self.put_object(o) 980 finally: 981 self.exit()
982
983 - def get_sequence(self):
984 if self.enter(): 985 try: 986 result = [] 987 while self.next(): 988 result.append(self.get_object()) 989 finally: 990 self.exit() 991 return result
992
993 - def get_py_described(self):
994 if self.enter(): 995 try: 996 self.next() 997 descriptor = self.get_object() 998 self.next() 999 value = self.get_object() 1000 finally: 1001 self.exit() 1002 return Described(descriptor, value)
1003
1004 - def put_py_described(self, d):
1005 self.put_described() 1006 self.enter() 1007 try: 1008 self.put_object(d.descriptor) 1009 self.put_object(d.value) 1010 finally: 1011 self.exit()
1012
1013 - def get_py_array(self):
1014 """ 1015 If the current node is an array, return an Array object 1016 representing the array and its contents. Otherwise return None. 1017 This is a convenience wrapper around get_array, enter, etc. 1018 """ 1019 1020 count, described, type = self.get_array() 1021 if type is None: return None 1022 if self.enter(): 1023 try: 1024 if described: 1025 self.next() 1026 descriptor = self.get_object() 1027 else: 1028 descriptor = UNDESCRIBED 1029 elements = [] 1030 while self.next(): 1031 elements.append(self.get_object()) 1032 finally: 1033 self.exit() 1034 return Array(descriptor, type, *elements)
1035
1036 - def put_py_array(self, a):
1037 described = a.descriptor != UNDESCRIBED 1038 self.put_array(described, a.type) 1039 self.enter() 1040 try: 1041 if described: 1042 self.put_object(a.descriptor) 1043 for e in a.elements: 1044 self.put_object(e) 1045 finally: 1046 self.exit()
1047 1048 put_mappings = { 1049 None.__class__: lambda s, _: s.put_null(), 1050 bool: put_bool, 1051 ubyte: put_ubyte, 1052 ushort: put_ushort, 1053 uint: put_uint, 1054 ulong: put_ulong, 1055 byte: put_byte, 1056 short: put_short, 1057 int32: put_int, 1058 long: put_long, 1059 float32: put_float, 1060 float: put_double, 1061 decimal32: put_decimal32, 1062 decimal64: put_decimal64, 1063 decimal128: put_decimal128, 1064 char: put_char, 1065 timestamp: put_timestamp, 1066 uuid.UUID: put_uuid, 1067 bytes: put_binary, 1068 unicode: put_string, 1069 symbol: put_symbol, 1070 list: put_sequence, 1071 tuple: put_sequence, 1072 dict: put_dict, 1073 Described: put_py_described, 1074 Array: put_py_array 1075 } 1076 # for python 3.x, long is merely an alias for int, but for python 2.x 1077 # we need to add an explicit int since it is a different type 1078 if int not in put_mappings: 1079 put_mappings[int] = put_int 1080 # Python >=3.0 has 'memoryview', <=2.5 has 'buffer', >=2.6 has both. 1081 try: 1082 put_mappings[memoryview] = put_memoryview 1083 except NameError: 1084 pass 1085 try: 1086 put_mappings[buffer] = put_buffer 1087 except NameError: 1088 pass 1089 get_mappings = { 1090 NULL: lambda s: None, 1091 BOOL: get_bool, 1092 BYTE: get_byte, 1093 UBYTE: get_ubyte, 1094 SHORT: get_short, 1095 USHORT: get_ushort, 1096 INT: get_int, 1097 UINT: get_uint, 1098 CHAR: get_char, 1099 LONG: get_long, 1100 ULONG: get_ulong, 1101 TIMESTAMP: get_timestamp, 1102 FLOAT: get_float, 1103 DOUBLE: get_double, 1104 DECIMAL32: get_decimal32, 1105 DECIMAL64: get_decimal64, 1106 DECIMAL128: get_decimal128, 1107 UUID: get_uuid, 1108 BINARY: get_binary, 1109 STRING: get_string, 1110 SYMBOL: get_symbol, 1111 DESCRIBED: get_py_described, 1112 ARRAY: get_py_array, 1113 LIST: get_sequence, 1114 MAP: get_dict 1115 } 1116
1117 - def put_object(self, obj):
1118 putter = self.put_mappings[obj.__class__] 1119 putter(self, obj)
1120
1121 - def get_object(self):
1122 type = self.type() 1123 if type is None: return None 1124 getter = self.get_mappings.get(type) 1125 if getter: 1126 return getter(self) 1127 else: 1128 return UnmappedType(str(type))
1129
1130 1131 -def dat2obj(dimpl):
1132 if dimpl: 1133 d = Data(dimpl) 1134 d.rewind() 1135 d.next() 1136 obj = d.get_object() 1137 d.rewind() 1138 return obj
1139
1140 1141 -def obj2dat(obj, dimpl):
1142 if obj is not None: 1143 d = Data(dimpl) 1144 d.put_object(obj)
1145