16
16
# limitations under the License.
17
17
18
18
19
- import typing as t
20
19
from codecs import decode
21
20
from contextlib import contextmanager
22
21
from struct import (
23
22
pack as struct_pack ,
24
23
unpack as struct_unpack ,
25
24
)
26
25
27
- from ...._optional_deps import (
28
- np ,
29
- pd ,
30
- )
31
26
from ...hydration import DehydrationHooks
32
27
from .._common import Structure
28
+ from .types import *
33
29
34
30
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
59
39
60
40
61
41
PACKED_UINT_8 = [struct_pack (">B" , value ) for value in range (0x100 )]
@@ -74,12 +54,17 @@ def __init__(self, stream):
74
54
self .stream = stream
75
55
self ._write = self .stream .write
76
56
77
- def _pack_raw (self , data ):
78
- self ._write (data )
79
-
80
57
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 )
83
68
84
69
@classmethod
85
70
def _inject_hooks (cls , dehydration_hooks = None ):
@@ -93,8 +78,7 @@ def _inject_hooks(cls, dehydration_hooks=None):
93
78
subtypes = {}
94
79
)
95
80
96
-
97
- def _pack (self , value , dehydration_hooks = None ):
81
+ def _py_pack (self , value , dehydration_hooks = None ):
98
82
write = self ._write
99
83
100
84
# None
@@ -136,18 +120,18 @@ def _pack(self, value, dehydration_hooks=None):
136
120
elif isinstance (value , str ):
137
121
encoded = value .encode ("utf-8" )
138
122
self ._pack_string_header (len (encoded ))
139
- self ._pack_raw (encoded )
123
+ self ._write (encoded )
140
124
141
125
# Bytes
142
126
elif isinstance (value , BYTES_TYPES ):
143
127
self ._pack_bytes_header (len (value ))
144
- self ._pack_raw (value )
128
+ self ._write (value )
145
129
146
130
# List
147
131
elif isinstance (value , SEQUENCE_TYPES ):
148
132
self ._pack_list_header (len (value ))
149
133
for item in value :
150
- self ._pack (item , dehydration_hooks )
134
+ self ._py_pack (item , dehydration_hooks )
151
135
152
136
# Map
153
137
elif isinstance (value , MAPPING_TYPES ):
@@ -157,8 +141,8 @@ def _pack(self, value, dehydration_hooks=None):
157
141
raise TypeError (
158
142
"Map keys must be strings, not {}" .format (type (key ))
159
143
)
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 )
162
146
163
147
# Structure
164
148
elif isinstance (value , Structure ):
@@ -169,7 +153,7 @@ def _pack(self, value, dehydration_hooks=None):
169
153
if dehydration_hooks :
170
154
transformer = dehydration_hooks .get_transformer (value )
171
155
if transformer is not None :
172
- self ._pack (transformer (value ), dehydration_hooks )
156
+ self ._py_pack (transformer (value ), dehydration_hooks )
173
157
return
174
158
175
159
raise ValueError ("Values of type %s are not supported" % type (value ))
@@ -298,11 +282,16 @@ def read(self, n=1):
298
282
def read_u8 (self ):
299
283
return self .unpackable .read_u8 ()
300
284
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 )
306
295
307
296
def _unpack (self , hydration_hooks = None ):
308
297
marker = self .read_u8 ()
@@ -384,8 +373,13 @@ def _unpack(self, hydration_hooks=None):
384
373
size , tag = self ._unpack_structure_header (marker )
385
374
value = Structure (tag , * ([None ] * size ))
386
375
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 )
389
383
390
384
else :
391
385
raise ValueError ("Unknown PackStream marker %02X" % marker )
@@ -397,22 +391,22 @@ def _unpack_list_items(self, marker, hydration_hooks=None):
397
391
if size == 0 :
398
392
return
399
393
elif size == 1 :
400
- yield self .unpack (hydration_hooks = hydration_hooks )
394
+ yield self ._unpack (hydration_hooks = hydration_hooks )
401
395
else :
402
396
for _ in range (size ):
403
- yield self .unpack (hydration_hooks = hydration_hooks )
397
+ yield self ._unpack (hydration_hooks = hydration_hooks )
404
398
elif marker == 0xD4 : # LIST_8:
405
399
size , = struct_unpack (">B" , self .read (1 ))
406
400
for _ in range (size ):
407
- yield self .unpack (hydration_hooks = hydration_hooks )
401
+ yield self ._unpack (hydration_hooks = hydration_hooks )
408
402
elif marker == 0xD5 : # LIST_16:
409
403
size , = struct_unpack (">H" , self .read (2 ))
410
404
for _ in range (size ):
411
- yield self .unpack (hydration_hooks = hydration_hooks )
405
+ yield self ._unpack (hydration_hooks = hydration_hooks )
412
406
elif marker == 0xD6 : # LIST_32:
413
407
size , = struct_unpack (">I" , self .read (4 ))
414
408
for _ in range (size ):
415
- yield self .unpack (hydration_hooks = hydration_hooks )
409
+ yield self ._unpack (hydration_hooks = hydration_hooks )
416
410
else :
417
411
return
418
412
@@ -426,29 +420,29 @@ def _unpack_map(self, marker, hydration_hooks=None):
426
420
size = marker & 0x0F
427
421
value = {}
428
422
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 )
431
425
return value
432
426
elif marker == 0xD8 : # MAP_8:
433
427
size , = struct_unpack (">B" , self .read (1 ))
434
428
value = {}
435
429
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 )
438
432
return value
439
433
elif marker == 0xD9 : # MAP_16:
440
434
size , = struct_unpack (">H" , self .read (2 ))
441
435
value = {}
442
436
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 )
445
439
return value
446
440
elif marker == 0xDA : # MAP_32:
447
441
size , = struct_unpack (">I" , self .read (4 ))
448
442
value = {}
449
443
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 )
452
446
return value
453
447
else :
454
448
return None
0 commit comments