1111 f64_b_t ,
1212)
1313
14- # dereference for performance
14+ # deference for performance
1515u8_b_pack = u8_b_t .pack
1616u16_b_pack = u16_b_t .pack
1717u32_b_pack = u32_b_t .pack
3434f32_b_unpack = f32_b_t .unpack
3535f64_b_unpack = f64_b_t .unpack
3636
37- u8_s = u8_b_t .struct
38- u16_s = u16_b_t .struct
39- u32_s = u32_b_t .struct
40- u64_s = u64_b_t .struct
41- s8_s = s8_b_t .struct
42- s16_s = s16_b_t .struct
43- s32_s = s32_b_t .struct
44- s64_s = s64_b_t .struct
45- f32_s = f32_b_t .struct
46- f64_s = f64_b_t .struct
47-
4837
4938def pack_stream (stream , obj ):
5039 if isinstance (obj , dict ):
@@ -152,96 +141,63 @@ def pack_stream(stream, obj):
152141 raise TypeError ("type not supported:" , obj , type (obj ))
153142
154143
155- def unpack_stream (stream , offset = 0 ):
156- (first_byte ,) = u8_s .unpack_from (stream , offset )
157- offset += u8_s .size
144+ def unpack_stream (stream ):
145+ first_byte = u8_b_unpack (stream )
158146 if first_byte <= 0x7F :
159147 obj = first_byte
160148 elif first_byte <= 0x8F :
161149 map_length = first_byte & 0b1111
162- unpack_stream .__offset__ = offset
163- obj = {
164- unpack_stream (stream , unpack_stream .__offset__ ): unpack_stream (
165- stream , unpack_stream .__offset__
166- )
167- for _ in range (map_length )
168- }
169- offset = unpack_stream .__offset__
150+ obj = {unpack_stream (stream ): unpack_stream (stream ) for _ in range (map_length )}
170151 elif first_byte <= 0x9F :
171152 array_length = first_byte & 0b1111
172- unpack_stream .__offset__ = offset
173- obj = [
174- unpack_stream (stream , unpack_stream .__offset__ ) for _ in range (array_length )
175- ]
176- offset = unpack_stream .__offset__
153+ obj = [unpack_stream (stream ) for _ in range (array_length )]
177154 elif first_byte <= 0xBF :
178155 str_length = first_byte & 0b11111
179- _offset = offset + str_length
180- obj = bytes (stream [offset :_offset ]).decode ("utf-8" )
181- offset = _offset
156+ obj = stream .read (str_length ).decode ("utf-8" )
182157 elif 0xE0 <= first_byte and first_byte <= 0xFF :
183- ( obj ,) = s8_s . unpack_from ( stream , offset - s8_s . size )
184- # peek backwards, offset is good where it's at
158+ stream . seek ( - 1 , 1 )
159+ obj = s8_b_unpack ( stream )
185160 elif first_byte == 0xC0 :
186161 obj = None
187162 elif first_byte == 0xC2 :
188163 obj = False
189164 elif first_byte == 0xC3 :
190165 obj = True
191166 elif first_byte == 0xC4 :
192- (bin_length ,) = u8_s .unpack_from (stream , offset )
193- offset += u8_s .size
194- _offset = offset + bin_length
195- obj = bytes (stream [offset :_offset ])
196- offset = _offset
167+ bin_length = u8_b_unpack (stream )
168+ obj = stream .read (bin_length )
197169 elif first_byte == 0xC5 :
198- (bin_length ,) = u16_s .unpack_from (stream , offset )
199- offset += u16_s .size
200- _offset = offset + bin_length
201- obj = bytes (stream [offset :_offset ])
202- offset = _offset
170+ bin_length = u16_b_unpack (stream )
171+ obj = stream .read (bin_length )
203172 elif first_byte == 0xC6 :
204- (bin_length ,) = u32_s .unpack_from (stream , offset )
205- offset += u32_s .size
206- _offset = offset + bin_length
207- obj = bytes (stream [offset :_offset ])
208- offset = _offset
173+ bin_length = u32_b_unpack (stream )
174+ obj = stream .read (bin_length )
209175 elif first_byte == 0xC7 :
210176 raise NotImplementedError
211177 elif first_byte == 0xC8 :
212178 raise NotImplementedError
213179 elif first_byte == 0xC9 :
214180 raise NotImplementedError
215181 elif first_byte == 0xCA :
216- (obj ,) = f32_s .unpack_from (stream , offset )
217- offset += f32_s .size
182+ obj = f32_b_unpack (stream )
218183 elif first_byte == 0xCB :
219- (obj ,) = f64_s .unpack_from (stream , offset )
220- offset += f64_s .size
184+ obj = f64_b_unpack (stream )
221185 elif first_byte == 0xCC :
222- (obj ,) = u8_s .unpack_from (stream , offset )
223- offset += u8_s .size
186+ obj = u8_b_unpack (stream )
224187 elif first_byte == 0xCD :
225- (obj ,) = u16_s .unpack_from (stream , offset )
226- offset += u16_s .size
188+ obj = u16_b_unpack (stream )
227189 elif first_byte == 0xCE :
228- (obj ,) = u32_s .unpack_from (stream , offset )
229- offset += u32_s .size
190+ obj = u32_b_unpack (stream )
230191 elif first_byte == 0xCF :
231- (obj ,) = u64_s .unpack_from (stream , offset )
232- offset += u64_s .size
192+ obj = u64_b_unpack (stream )
233193 elif first_byte == 0xD0 :
234- (obj ,) = s8_s .unpack_from (stream , offset )
235- offset += s8_s .size
194+ obj = s8_b_unpack (stream )
236195 elif first_byte == 0xD1 :
237- (obj ,) = s16_s .unpack_from (stream , offset )
238- offset += s16_s .size
196+ obj = s16_b_unpack (stream )
239197 elif first_byte == 0xD2 :
240- (obj ,) = s32_s .unpack_from (stream , offset )
241- offset += s32_s .size
198+ obj = s32_b_unpack (stream )
242199 elif first_byte == 0xD3 :
243- (obj ,) = s64_s .unpack_from (stream , offset )
244- offset += s64_s .size
200+ obj = s64_b_unpack (stream )
245201 elif first_byte == 0xD4 :
246202 raise NotImplementedError
247203 elif first_byte == 0xD5 :
@@ -253,63 +209,27 @@ def unpack_stream(stream, offset=0):
253209 elif first_byte == 0xD8 :
254210 raise NotImplementedError
255211 elif first_byte == 0xD9 :
256- (str_length ,) = u8_s .unpack_from (stream , offset )
257- offset += u8_s .size
258- _offset = offset + str_length
259- obj = bytes (stream [offset :_offset ]).decode ("utf-8" )
260- offset = _offset
212+ str_length = u8_b_unpack (stream )
213+ obj = stream .read (str_length ).decode ("utf-8" )
261214 elif first_byte == 0xDA :
262- (str_length ,) = u16_s .unpack_from (stream , offset )
263- offset += u16_s .size
264- _offset = offset + str_length
265- obj = bytes (stream [offset :_offset ]).decode ("utf-8" )
266- offset = _offset
215+ str_length = u16_b_unpack (stream )
216+ obj = stream .read (str_length ).decode ("utf-8" )
267217 elif first_byte == 0xDB :
268- (str_length ,) = u32_s .unpack_from (stream , offset )
269- offset += u32_s .size
270- _offset = offset + str_length
271- obj = bytes (stream [offset :_offset ]).decode ("utf-8" )
272- offset = _offset
218+ str_length = u32_b_unpack (stream )
219+ obj = stream .read (str_length ).decode ("utf-8" )
273220 elif first_byte == 0xDC :
274- (array_length ,) = u16_s .unpack_from (stream , offset )
275- offset += u16_s .size
276- unpack_stream .__offset__ = offset
277- obj = [
278- unpack_stream (stream , unpack_stream .__offset__ ) for _ in range (array_length )
279- ]
280- offset = unpack_stream .__offset__
221+ array_length = u16_b_unpack (stream )
222+ obj = [unpack_stream (stream ) for _ in range (array_length )]
281223 elif first_byte == 0xDD :
282- (array_length ,) = u32_s .unpack_from (stream , offset )
283- offset += u32_s .size
284- unpack_stream .__offset__ = offset
285- obj = [
286- unpack_stream (stream , unpack_stream .__offset__ ) for _ in range (array_length )
287- ]
288- offset = unpack_stream .__offset__
224+ array_length = u32_b_unpack (stream )
225+ obj = [unpack_stream (stream ) for _ in range (array_length )]
289226 elif first_byte == 0xDE :
290- (map_length ,) = u16_s .unpack_from (stream , offset )
291- offset += u16_s .size
292- unpack_stream .__offset__ = offset
293- obj = {
294- unpack_stream (stream , unpack_stream .__offset__ ): unpack_stream (
295- stream , offset = unpack_stream .__offset__
296- )
297- for _ in range (map_length )
298- }
299- offset = unpack_stream .__offset__
227+ map_length = u16_b_unpack (stream )
228+ obj = {unpack_stream (stream ): unpack_stream (stream ) for _ in range (map_length )}
300229 elif first_byte == 0xDF :
301- (map_length ,) = u32_s .unpack_from (stream , offset )
302- offset += u32_s .size
303- unpack_stream .__offset__ = offset
304- obj = {
305- unpack_stream (stream , unpack_stream .__offset__ ): unpack_stream (
306- stream , offset = unpack_stream .__offset__
307- )
308- for _ in range (map_length )
309- }
310- offset = unpack_stream .__offset__
230+ map_length = u32_b_unpack (stream )
231+ obj = {unpack_stream (stream ): unpack_stream (stream ) for _ in range (map_length )}
311232 else :
312233 raise ValueError ("invalid first byte" , first_byte , hex (first_byte ))
313234
314- unpack_stream .__offset__ = offset
315235 return obj
0 commit comments