Skip to content

Commit 5a1c4e7

Browse files
committed
Bytes, strings and byte arrays
1 parent 44a7c48 commit 5a1c4e7

File tree

1 file changed

+46
-38
lines changed

1 file changed

+46
-38
lines changed

neo4j/v1/packstream.py

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,9 @@
397397
UNPACKED_MARKERS.update({bytes(bytearray([z + 256])): z for z in range(MINUS_2_TO_THE_4, 0)})
398398

399399

400+
EndOfStream = object()
401+
402+
400403
class Structure(list):
401404

402405
def __init__(self, capacity, signature):
@@ -614,7 +617,10 @@ def __init__(self):
614617
self.pos = 0
615618

616619
def load(self, buffer):
617-
self.buffer = buffer
620+
if isinstance(buffer, bytearray):
621+
self.buffer = buffer
622+
else:
623+
self.buffer = bytearray(buffer)
618624
self.pos = 0
619625

620626
def read(self, n=1):
@@ -624,7 +630,10 @@ def read(self, n=1):
624630
self.pos += n
625631
else:
626632
self.pos = len(self.buffer)
627-
return bytes(self.buffer[start:self.pos])
633+
return self.buffer[start:self.pos]
634+
635+
def read_bytes(self, n=1):
636+
return bytes(self.read(n))
628637

629638
def read_marker(self):
630639
if self.pos < len(self.buffer):
@@ -635,7 +644,6 @@ def read_marker(self):
635644
return -1
636645

637646
def unpack(self):
638-
stream_read = self.read
639647
marker = self.read_marker()
640648

641649
if marker == -1:
@@ -653,7 +661,7 @@ def unpack(self):
653661

654662
# Float
655663
elif marker == 0xC1:
656-
return struct_unpack(DOUBLE_STRUCT, stream_read(8))[0]
664+
return struct_unpack(DOUBLE_STRUCT, self.read(8))[0]
657665

658666
# Boolean
659667
elif marker == 0xC2:
@@ -663,61 +671,61 @@ def unpack(self):
663671

664672
# Integer
665673
elif marker == 0xC8:
666-
return UNPACKED_INT_8[stream_read(1)]
674+
return UNPACKED_INT_8[self.read_bytes(1)]
667675
elif marker == 0xC9:
668-
return UNPACKED_INT_16[stream_read(2)]
676+
return UNPACKED_INT_16[self.read_bytes(2)]
669677
elif marker == 0xCA:
670-
return struct_unpack(INT_32_STRUCT, stream_read(4))[0]
678+
return struct_unpack(INT_32_STRUCT, self.read(4))[0]
671679
elif marker == 0xCB:
672-
return struct_unpack(INT_64_STRUCT, stream_read(8))[0]
680+
return struct_unpack(INT_64_STRUCT, self.read(8))[0]
673681

674682
# Bytes
675683
elif marker == 0xCC:
676-
byte_size = UNPACKED_UINT_8[stream_read(1)]
677-
return stream_read(byte_size)
684+
byte_size = UNPACKED_UINT_8[self.read_bytes(1)]
685+
return self.read(byte_size)
678686
elif marker == 0xCD:
679-
byte_size = UNPACKED_UINT_16[stream_read(2)]
680-
return stream_read(byte_size)
687+
byte_size = UNPACKED_UINT_16[self.read_bytes(2)]
688+
return self.read(byte_size)
681689
elif marker == 0xCE:
682-
byte_size = struct_unpack(UINT_32_STRUCT, stream_read(4))[0]
683-
return stream_read(byte_size)
690+
byte_size = struct_unpack(UINT_32_STRUCT, self.read(4))[0]
691+
return self.read(byte_size)
684692

685693
else:
686694
marker_high = marker & 0xF0
687695
unpack = self.unpack
688696

689697
# String
690698
if marker_high == 0x80: # TINY_STRING
691-
return stream_read(marker & 0x0F).decode(ENCODING)
699+
return self.read(marker & 0x0F).decode(ENCODING)
692700
elif marker == 0xD0: # STRING_8:
693-
byte_size = UNPACKED_UINT_8[stream_read(1)]
694-
return stream_read(byte_size).decode(ENCODING)
701+
byte_size = UNPACKED_UINT_8[self.read_bytes(1)]
702+
return self.read(byte_size).decode(ENCODING)
695703
elif marker == 0xD1: # STRING_16:
696-
byte_size = UNPACKED_UINT_16[stream_read(2)]
697-
return stream_read(byte_size).decode(ENCODING)
704+
byte_size = UNPACKED_UINT_16[self.read_bytes(2)]
705+
return self.read(byte_size).decode(ENCODING)
698706
elif marker == 0xD2: # STRING_32:
699-
byte_size = struct_unpack(UINT_32_STRUCT, stream_read(4))[0]
700-
return stream_read(byte_size).decode(ENCODING)
707+
byte_size = struct_unpack(UINT_32_STRUCT, self.read(4))[0]
708+
return self.read(byte_size).decode(ENCODING)
701709

702710
# List
703711
elif marker_high == 0x90:
704712
size = marker & 0x0F
705713
return [unpack() for _ in range(size)]
706714
elif marker == 0xD4: # LIST_8:
707-
size = UNPACKED_UINT_8[stream_read(1)]
715+
size = UNPACKED_UINT_8[self.read_bytes(1)]
708716
return [unpack() for _ in range(size)]
709717
elif marker == 0xD5: # LIST_16:
710-
size = UNPACKED_UINT_16[stream_read(2)]
718+
size = UNPACKED_UINT_16[self.read_bytes(2)]
711719
return [unpack() for _ in range(size)]
712720
elif marker == 0xD6: # LIST_32:
713-
size = struct_unpack(UINT_32_STRUCT, stream_read(4))[0]
721+
size = struct_unpack(UINT_32_STRUCT, self.read(4))[0]
714722
return [unpack() for _ in range(size)]
715723
elif marker == 0xD7: # LIST_STREAM:
716724
value = []
717725
item = None
718-
while item != END_OF_STREAM:
726+
while item is not EndOfStream:
719727
item = unpack()
720-
if item != END_OF_STREAM:
728+
if item is not EndOfStream:
721729
value.append(item)
722730
return value
723731

@@ -730,21 +738,21 @@ def unpack(self):
730738
value[key] = unpack()
731739
return value
732740
elif marker == 0xD8: # MAP_8:
733-
size = UNPACKED_UINT_8[stream_read(1)]
741+
size = UNPACKED_UINT_8[self.read_bytes(1)]
734742
value = {}
735743
for _ in range(size):
736744
key = unpack()
737745
value[key] = unpack()
738746
return value
739747
elif marker == 0xD9: # MAP_16:
740-
size = UNPACKED_UINT_16[stream_read(2)]
748+
size = UNPACKED_UINT_16[self.read_bytes(2)]
741749
value = {}
742750
for _ in range(size):
743751
key = unpack()
744752
value[key] = unpack()
745753
return value
746754
elif marker == 0xDA: # MAP_32:
747-
size = struct_unpack(UINT_32_STRUCT, stream_read(4))[0]
755+
size = struct_unpack(UINT_32_STRUCT, self.read(4))[0]
748756
value = {}
749757
for _ in range(size):
750758
key = unpack()
@@ -753,34 +761,34 @@ def unpack(self):
753761
elif marker == 0xDB: # MAP_STREAM:
754762
value = {}
755763
key = None
756-
while key != END_OF_STREAM:
764+
while key is not EndOfStream:
757765
key = unpack()
758-
if key != END_OF_STREAM:
766+
if key is not EndOfStream:
759767
value[key] = unpack()
760768
return value
761769

762770
# Structure
763771
elif marker_high == 0xB0:
764-
signature = stream_read(1)
772+
signature = self.read_bytes(1)
765773
value = Structure(marker & 0x0F, signature)
766774
for _ in range(value.capacity):
767775
value.append(unpack())
768776
return value
769777
elif marker == 0xDC: #STRUCT_8:
770-
size, signature = stream_read(2)
778+
size, signature = self.read_bytes(2)
771779
value = Structure(UNPACKED_UINT_8[size], signature)
772780
for _ in range(value.capacity):
773781
value.append(unpack())
774782
return value
775783
elif marker == 0xDD: #STRUCT_16:
776-
data = stream_read(3)
784+
data = self.read_bytes(3)
777785
value = Structure(UNPACKED_UINT_16[data[0:2]], data[2])
778786
for _ in range(value.capacity):
779787
value.append(unpack())
780788
return value
781789

782790
elif marker == 0xDF: #END_OF_STREAM:
783-
return END_OF_STREAM
791+
return EndOfStream
784792

785793
else:
786794
raise RuntimeError("Unknown PackStream marker %02X" % marker)
@@ -795,13 +803,13 @@ def unpack_structure_header(self):
795803
def _unpack_structure_header(self, marker):
796804
marker_high = marker & 0xF0
797805
if marker_high == 0xB0: # TINY_STRUCT
798-
signature = self.read(1)
806+
signature = self.read_bytes(1)
799807
return marker & 0x0F, signature
800808
elif marker == 0xDC: # STRUCT_8:
801-
size, signature = self.read(2)
809+
size, signature = self.read_bytes(2)
802810
return UNPACKED_UINT_8[size], signature
803811
elif marker == 0xDD: # STRUCT_16:
804-
data = self.read(3)
812+
data = self.read_bytes(3)
805813
return UNPACKED_UINT_16[data[0:2]], data[2]
806814
else:
807815
raise RuntimeError("Expected structure, found marker %02X" % marker)

0 commit comments

Comments
 (0)