1616# limitations under the License.
1717
1818
19- import typing as t
2019from codecs import decode
2120from contextlib import contextmanager
2221from struct import (
2322 pack as struct_pack ,
2423 unpack as struct_unpack ,
2524)
2625
27- from ...._optional_deps import (
28- np ,
29- pd ,
30- )
3126from ...hydration import DehydrationHooks
3227from .._common import Structure
28+ from .types import *
3329
3430
35- NONE_VALUES : t .Tuple = (None ,)
36- TRUE_VALUES : t .Tuple = (True ,)
37- FALSE_VALUES : t .Tuple = (False ,)
38- INT_TYPES : t .Tuple [t .Type , ...] = (int ,)
39- FLOAT_TYPES : t .Tuple [t .Type , ...] = (float ,)
40- # we can't put tuple here because spatial types subclass tuple,
41- # and we don't want to treat them as sequences
42- SEQUENCE_TYPES : t .Tuple [t .Type , ...] = (list ,)
43- MAPPING_TYPES : t .Tuple [t .Type , ...] = (dict ,)
44- BYTES_TYPES : t .Tuple [t .Type , ...] = (bytes , bytearray )
45-
46-
47- if np is not None :
48- TRUE_VALUES = (* TRUE_VALUES , np .bool_ (True ))
49- FALSE_VALUES = (* FALSE_VALUES , np .bool_ (False ))
50- INT_TYPES = (* INT_TYPES , np .integer )
51- FLOAT_TYPES = (* FLOAT_TYPES , np .floating )
52- SEQUENCE_TYPES = (* SEQUENCE_TYPES , np .ndarray )
53-
54- if pd is not None :
55- NONE_VALUES = (* NONE_VALUES , pd .NA )
56- SEQUENCE_TYPES = (* SEQUENCE_TYPES , pd .Series , pd .Categorical ,
57- pd .core .arrays .ExtensionArray )
58- MAPPING_TYPES = (* MAPPING_TYPES , pd .DataFrame )
31+ try :
32+ from .._rust .v1 import (
33+ pack as _rust_pack ,
34+ unpack as _rust_unpack ,
35+ )
36+ except ImportError :
37+ _rust_pack = None
38+ _rust_unpack = None
5939
6040
6141PACKED_UINT_8 = [struct_pack (">B" , value ) for value in range (0x100 )]
@@ -74,12 +54,17 @@ def __init__(self, stream):
7454 self .stream = stream
7555 self ._write = self .stream .write
7656
77- def _pack_raw (self , data ):
78- self ._write (data )
79-
8057 def pack (self , data , dehydration_hooks = None ):
81- self ._pack (data ,
82- dehydration_hooks = self ._inject_hooks (dehydration_hooks ))
58+ dehydration_hooks = self ._inject_hooks (dehydration_hooks )
59+ self ._pack (data , dehydration_hooks = dehydration_hooks )
60+
61+ if _rust_pack :
62+ def _pack (self , data , dehydration_hooks = None ):
63+ data = _rust_pack (data , dehydration_hooks )
64+ self ._write (data )
65+ else :
66+ def _pack (self , data , dehydration_hooks = None ):
67+ self ._py_pack (data , dehydration_hooks )
8368
8469 @classmethod
8570 def _inject_hooks (cls , dehydration_hooks = None ):
@@ -93,8 +78,7 @@ def _inject_hooks(cls, dehydration_hooks=None):
9378 subtypes = {}
9479 )
9580
96-
97- def _pack (self , value , dehydration_hooks = None ):
81+ def _py_pack (self , value , dehydration_hooks = None ):
9882 write = self ._write
9983
10084 # None
@@ -136,18 +120,18 @@ def _pack(self, value, dehydration_hooks=None):
136120 elif isinstance (value , str ):
137121 encoded = value .encode ("utf-8" )
138122 self ._pack_string_header (len (encoded ))
139- self ._pack_raw (encoded )
123+ self ._write (encoded )
140124
141125 # Bytes
142126 elif isinstance (value , BYTES_TYPES ):
143127 self ._pack_bytes_header (len (value ))
144- self ._pack_raw (value )
128+ self ._write (value )
145129
146130 # List
147131 elif isinstance (value , SEQUENCE_TYPES ):
148132 self ._pack_list_header (len (value ))
149133 for item in value :
150- self ._pack (item , dehydration_hooks )
134+ self ._py_pack (item , dehydration_hooks )
151135
152136 # Map
153137 elif isinstance (value , MAPPING_TYPES ):
@@ -157,8 +141,8 @@ def _pack(self, value, dehydration_hooks=None):
157141 raise TypeError (
158142 "Map keys must be strings, not {}" .format (type (key ))
159143 )
160- self ._pack (key , dehydration_hooks )
161- self ._pack (item , dehydration_hooks )
144+ self ._py_pack (key , dehydration_hooks )
145+ self ._py_pack (item , dehydration_hooks )
162146
163147 # Structure
164148 elif isinstance (value , Structure ):
@@ -169,7 +153,7 @@ def _pack(self, value, dehydration_hooks=None):
169153 if dehydration_hooks :
170154 transformer = dehydration_hooks .get_transformer (value )
171155 if transformer is not None :
172- self ._pack (transformer (value ), dehydration_hooks )
156+ self ._py_pack (transformer (value ), dehydration_hooks )
173157 return
174158
175159 raise ValueError ("Values of type %s are not supported" % type (value ))
@@ -298,11 +282,16 @@ def read(self, n=1):
298282 def read_u8 (self ):
299283 return self .unpackable .read_u8 ()
300284
301- def unpack (self , hydration_hooks = None ):
302- value = self ._unpack (hydration_hooks = hydration_hooks )
303- if hydration_hooks and type (value ) in hydration_hooks :
304- return hydration_hooks [type (value )](value )
305- return value
285+ if _rust_unpack :
286+ def unpack (self , hydration_hooks = None ):
287+ value , i = _rust_unpack (
288+ self .unpackable .data , self .unpackable .p , hydration_hooks
289+ )
290+ self .unpackable .p = i
291+ return value
292+ else :
293+ def unpack (self , hydration_hooks = None ):
294+ return self ._unpack (hydration_hooks = hydration_hooks )
306295
307296 def _unpack (self , hydration_hooks = None ):
308297 marker = self .read_u8 ()
@@ -384,8 +373,13 @@ def _unpack(self, hydration_hooks=None):
384373 size , tag = self ._unpack_structure_header (marker )
385374 value = Structure (tag , * ([None ] * size ))
386375 for i in range (len (value )):
387- value [i ] = self .unpack (hydration_hooks = hydration_hooks )
388- return value
376+ value [i ] = self ._unpack (hydration_hooks = hydration_hooks )
377+ if not hydration_hooks :
378+ return value
379+ hydration_hook = hydration_hooks .get (type (value ))
380+ if not hydration_hook :
381+ return value
382+ return hydration_hook (value )
389383
390384 else :
391385 raise ValueError ("Unknown PackStream marker %02X" % marker )
@@ -397,22 +391,22 @@ def _unpack_list_items(self, marker, hydration_hooks=None):
397391 if size == 0 :
398392 return
399393 elif size == 1 :
400- yield self .unpack (hydration_hooks = hydration_hooks )
394+ yield self ._unpack (hydration_hooks = hydration_hooks )
401395 else :
402396 for _ in range (size ):
403- yield self .unpack (hydration_hooks = hydration_hooks )
397+ yield self ._unpack (hydration_hooks = hydration_hooks )
404398 elif marker == 0xD4 : # LIST_8:
405399 size , = struct_unpack (">B" , self .read (1 ))
406400 for _ in range (size ):
407- yield self .unpack (hydration_hooks = hydration_hooks )
401+ yield self ._unpack (hydration_hooks = hydration_hooks )
408402 elif marker == 0xD5 : # LIST_16:
409403 size , = struct_unpack (">H" , self .read (2 ))
410404 for _ in range (size ):
411- yield self .unpack (hydration_hooks = hydration_hooks )
405+ yield self ._unpack (hydration_hooks = hydration_hooks )
412406 elif marker == 0xD6 : # LIST_32:
413407 size , = struct_unpack (">I" , self .read (4 ))
414408 for _ in range (size ):
415- yield self .unpack (hydration_hooks = hydration_hooks )
409+ yield self ._unpack (hydration_hooks = hydration_hooks )
416410 else :
417411 return
418412
@@ -426,29 +420,29 @@ def _unpack_map(self, marker, hydration_hooks=None):
426420 size = marker & 0x0F
427421 value = {}
428422 for _ in range (size ):
429- key = self .unpack (hydration_hooks = hydration_hooks )
430- value [key ] = self .unpack (hydration_hooks = hydration_hooks )
423+ key = self ._unpack (hydration_hooks = hydration_hooks )
424+ value [key ] = self ._unpack (hydration_hooks = hydration_hooks )
431425 return value
432426 elif marker == 0xD8 : # MAP_8:
433427 size , = struct_unpack (">B" , self .read (1 ))
434428 value = {}
435429 for _ in range (size ):
436- key = self .unpack (hydration_hooks = hydration_hooks )
437- value [key ] = self .unpack (hydration_hooks = hydration_hooks )
430+ key = self ._unpack (hydration_hooks = hydration_hooks )
431+ value [key ] = self ._unpack (hydration_hooks = hydration_hooks )
438432 return value
439433 elif marker == 0xD9 : # MAP_16:
440434 size , = struct_unpack (">H" , self .read (2 ))
441435 value = {}
442436 for _ in range (size ):
443- key = self .unpack (hydration_hooks = hydration_hooks )
444- value [key ] = self .unpack (hydration_hooks = hydration_hooks )
437+ key = self ._unpack (hydration_hooks = hydration_hooks )
438+ value [key ] = self ._unpack (hydration_hooks = hydration_hooks )
445439 return value
446440 elif marker == 0xDA : # MAP_32:
447441 size , = struct_unpack (">I" , self .read (4 ))
448442 value = {}
449443 for _ in range (size ):
450- key = self .unpack (hydration_hooks = hydration_hooks )
451- value [key ] = self .unpack (hydration_hooks = hydration_hooks )
444+ key = self ._unpack (hydration_hooks = hydration_hooks )
445+ value [key ] = self ._unpack (hydration_hooks = hydration_hooks )
452446 return value
453447 else :
454448 return None
0 commit comments