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