3838
3939
4040def pack_stream (stream , obj ):
41- _ps = pack_stream
42- _b = _B
43- _write = stream .write
4441 _type = type (obj )
4542 if _type is int :
4643 i = obj
4744 if 0 <= i <= 0x7F : # positive fixint
48- _write ( _b [i ])
45+ stream . write ( _B [i ])
4946 elif - 32 <= i < 0 : # negative fixint
50- _write ( _b [i & 0xFF ])
47+ stream . write ( _B [i & 0xFF ])
5148 elif i < 0 : # wider negative
52- ai = - i
53- if ai <= 0x80 :
54- _write (b"\xd0 " )
49+ u_i = - i
50+ if u_i <= 0x80 :
51+ stream . write (b"\xd0 " )
5552 s8_b_pack (stream , i )
56- elif ai <= 0x80_00 :
57- _write (b"\xd1 " )
53+ elif u_i <= 0x80_00 :
54+ stream . write (b"\xd1 " )
5855 s16_b_pack (stream , i )
59- elif ai <= 0x80_00_00_00 :
60- _write (b"\xd2 " )
56+ elif u_i <= 0x80_00_00_00 :
57+ stream . write (b"\xd2 " )
6158 s32_b_pack (stream , i )
62- elif ai <= 0x80_00_00_00_00_00_00_00 :
63- _write (b"\xd3 " )
59+ elif u_i <= 0x80_00_00_00_00_00_00_00 :
60+ stream . write (b"\xd3 " )
6461 s64_b_pack (stream , i )
6562 else :
6663 raise ValueError ("int too large" )
6764 elif i <= 0xFF :
68- _write (b"\xcc " )
65+ stream . write (b"\xcc " )
6966 u8_b_pack (stream , i )
7067 elif i <= 0xFF_FF :
71- _write (b"\xcd " )
68+ stream . write (b"\xcd " )
7269 u16_b_pack (stream , i )
7370 elif i <= 0xFF_FF_FF_FF :
74- _write (b"\xce " )
71+ stream . write (b"\xce " )
7572 u32_b_pack (stream , i )
7673 elif i <= 0xFF_FF_FF_FF_FF_FF_FF_FF :
77- _write (b"\xcf " )
74+ stream . write (b"\xcf " )
7875 u64_b_pack (stream , i )
7976 else :
8077 raise ValueError ("uint too large" )
8178 elif _type is float :
82- _write (b"\xcb " )
79+ stream . write (b"\xcb " )
8380 f64_b_pack (stream , obj )
8481 elif _type is dict :
85- map_length = len (obj )
86- if map_length <= 0x0F :
87- _write ( _b [0x80 | map_length ])
88- elif map_length <= 0xFF_FF :
89- _write (b"\xde " )
90- u16_b_pack (stream , map_length )
91- elif map_length <= 0xFF_FF_FF_FF :
92- _write (b"\xdf " )
93- u32_b_pack (stream , map_length )
82+ ml = len (obj )
83+ if ml <= 0x0F :
84+ stream . write ( _B [0x80 | ml ])
85+ elif ml <= 0xFF_FF :
86+ stream . write (b"\xde " )
87+ u16_b_pack (stream , ml )
88+ elif ml <= 0xFF_FF_FF_FF :
89+ stream . write (b"\xdf " )
90+ u32_b_pack (stream , ml )
9491 else :
9592 raise ValueError ("map too large" , obj )
9693 for k , v in obj .items ():
97- _ps (stream , k )
98- _ps (stream , v )
94+ pack_stream (stream , k )
95+ pack_stream (stream , v )
9996 elif _type is list :
100- array_length = len (obj )
101- if array_length <= 0x0F :
102- _write ( _b [0x90 | array_length ])
103- elif array_length <= 0xFF_FF :
104- _write (b"\xdc " )
105- u16_b_pack (stream , array_length )
106- elif array_length <= 0xFF_FF_FF_FF :
107- _write (b"\xdd " )
108- u32_b_pack (stream , array_length )
97+ al = len (obj )
98+ if al <= 0x0F :
99+ stream . write ( _B [0x90 | al ])
100+ elif al <= 0xFF_FF :
101+ stream . write (b"\xdc " )
102+ u16_b_pack (stream , al )
103+ elif al <= 0xFF_FF_FF_FF :
104+ stream . write (b"\xdd " )
105+ u32_b_pack (stream , al )
109106 else :
110107 raise ValueError ("array too large" , obj )
111108 for v in obj :
112- _ps (stream , v )
109+ pack_stream (stream , v )
113110 elif _type is str :
114111 s = obj .encode ("utf-8" )
115112 sl = len (s )
116113 if sl <= 0x1F :
117- _write ( _b [0xA0 | sl ])
114+ stream . write ( _B [0xA0 | sl ])
118115 elif sl <= 0xFF :
119- _write (b"\xd9 " )
116+ stream . write (b"\xd9 " )
120117 elif sl <= 0xFF_FF :
121- _write (b"\xda " )
118+ stream . write (b"\xda " )
122119 elif sl <= 0xFF_FF_FF_FF :
123- _write (b"\xdb " )
120+ stream . write (b"\xdb " )
124121 else :
125122 raise ValueError ("str too large" , obj )
126- _write (s )
123+ stream . write (s )
127124 elif obj is None :
128- _write (b"\xc0 " )
125+ stream . write (b"\xc0 " )
129126 elif _type is bool :
130- _write (b"\xc3 " if obj else b"\xc2 " )
127+ stream . write (b"\xc3 " if obj else b"\xc2 " )
131128 elif _type is bytes :
132- bin_length = len (obj )
133- if bin_length <= 0xFF :
134- _write (b"\xc4 " )
135- u8_b_pack (stream , bin_length )
136- elif bin_length <= 0xFF_FF :
137- _write (b"\xc5 " )
138- u16_b_pack (stream , bin_length )
139- elif bin_length <= 0xFF_FF_FF_FF :
140- _write (b"\xc6 " )
141- u32_b_pack (stream , bin_length )
129+ bl = len (obj )
130+ if bl <= 0xFF :
131+ stream . write (b"\xc4 " )
132+ u8_b_pack (stream , bl )
133+ elif bl <= 0xFF_FF :
134+ stream . write (b"\xc5 " )
135+ u16_b_pack (stream , bl )
136+ elif bl <= 0xFF_FF_FF_FF :
137+ stream . write (b"\xc6 " )
138+ u32_b_pack (stream , bl )
142139 else :
143140 raise ValueError ("bin too large" , obj )
144- _write (obj )
141+ stream . write (obj )
145142 else :
146143 raise TypeError ("type not supported:" , obj , type (obj ))
147144
@@ -150,76 +147,78 @@ def unpack_stream(stream):
150147 b = stream .read (1 )
151148 first_byte = b [0 ]
152149 if first_byte <= 0x7F : # positive fixint
153- return first_byte
154- if first_byte >= 0xE0 : # negative fixint
155- return first_byte - 0x100
156- if first_byte <= 0x8F : # fixmap
157- mlen = first_byte & 0x0F
158- return {unpack_stream (stream ): unpack_stream (stream ) for _ in range (mlen )}
159- if first_byte <= 0x9F : # fixarray
160- alen = first_byte & 0x0F
161- return [unpack_stream (stream ) for _ in range (alen )]
162- if first_byte <= 0xBF : # fixstr
163- slen = first_byte & 0x1F
164- return stream .read (slen ).decode ("utf-8" )
165- if first_byte == 0xC0 :
166- return None
167- if first_byte == 0xC2 :
168- return False
169- if first_byte == 0xC3 :
170- return True
171- if first_byte == 0xC4 :
150+ obj = first_byte
151+ elif first_byte >= 0xE0 : # negative fixint
152+ obj = first_byte - 0x100
153+ elif first_byte <= 0x8F : # fixmap
154+ ml = first_byte & 0x0F
155+ obj = {unpack_stream (stream ): unpack_stream (stream ) for _ in range (ml )}
156+ elif first_byte <= 0x9F : # fixarray
157+ al = first_byte & 0x0F
158+ obj = [unpack_stream (stream ) for _ in range (al )]
159+ elif first_byte <= 0xBF : # fixstr
160+ sl = first_byte & 0x1F
161+ obj = stream .read (sl ).decode ("utf-8" )
162+ elif first_byte == 0xC0 :
163+ obj = None
164+ elif first_byte == 0xC2 :
165+ obj = False
166+ elif first_byte == 0xC3 :
167+ obj = True
168+ elif first_byte == 0xC4 :
172169 bl = u8_b_unpack (stream )
173- return stream .read (bl )
174- if first_byte == 0xC5 :
170+ obj = stream .read (bl )
171+ elif first_byte == 0xC5 :
175172 bl = u16_b_unpack (stream )
176- return stream .read (bl )
177- if first_byte == 0xC6 :
173+ obj = stream .read (bl )
174+ elif first_byte == 0xC6 :
178175 bl = u32_b_unpack (stream )
179- return stream .read (bl )
180- if 0xC7 <= first_byte <= 0xC9 :
176+ obj = stream .read (bl )
177+ elif 0xC7 <= first_byte <= 0xC9 :
181178 raise NotImplementedError
182- if first_byte == 0xCA :
183- return f32_b_unpack (stream )
184- if first_byte == 0xCB :
185- return f64_b_unpack (stream )
186- if first_byte == 0xCC :
187- return u8_b_unpack (stream )
188- if first_byte == 0xCD :
189- return u16_b_unpack (stream )
190- if first_byte == 0xCE :
191- return u32_b_unpack (stream )
192- if first_byte == 0xCF :
193- return u64_b_unpack (stream )
194- if first_byte == 0xD0 :
195- return s8_b_unpack (stream )
196- if first_byte == 0xD1 :
197- return s16_b_unpack (stream )
198- if first_byte == 0xD2 :
199- return s32_b_unpack (stream )
200- if first_byte == 0xD3 :
201- return s64_b_unpack (stream )
202- if 0xD4 <= first_byte <= 0xD8 :
179+ elif first_byte == 0xCA :
180+ obj = f32_b_unpack (stream )
181+ elif first_byte == 0xCB :
182+ obj = f64_b_unpack (stream )
183+ elif first_byte == 0xCC :
184+ obj = u8_b_unpack (stream )
185+ elif first_byte == 0xCD :
186+ obj = u16_b_unpack (stream )
187+ elif first_byte == 0xCE :
188+ obj = u32_b_unpack (stream )
189+ elif first_byte == 0xCF :
190+ obj = u64_b_unpack (stream )
191+ elif first_byte == 0xD0 :
192+ obj = s8_b_unpack (stream )
193+ elif first_byte == 0xD1 :
194+ obj = s16_b_unpack (stream )
195+ elif first_byte == 0xD2 :
196+ obj = s32_b_unpack (stream )
197+ elif first_byte == 0xD3 :
198+ obj = s64_b_unpack (stream )
199+ elif 0xD4 <= first_byte <= 0xD8 :
203200 raise NotImplementedError
204- if first_byte == 0xD9 :
201+ elif first_byte == 0xD9 :
205202 sl = u8_b_unpack (stream )
206- return stream .read (sl ).decode ("utf-8" )
207- if first_byte == 0xDA :
203+ obj = stream .read (sl ).decode ("utf-8" )
204+ elif first_byte == 0xDA :
208205 sl = u16_b_unpack (stream )
209- return stream .read (sl ).decode ("utf-8" )
210- if first_byte == 0xDB :
206+ obj = stream .read (sl ).decode ("utf-8" )
207+ elif first_byte == 0xDB :
211208 sl = u32_b_unpack (stream )
212- return stream .read (sl ).decode ("utf-8" )
213- if first_byte == 0xDC :
209+ obj = stream .read (sl ).decode ("utf-8" )
210+ elif first_byte == 0xDC :
214211 al = u16_b_unpack (stream )
215- return [unpack_stream (stream ) for _ in range (al )]
216- if first_byte == 0xDD :
212+ obj = [unpack_stream (stream ) for _ in range (al )]
213+ elif first_byte == 0xDD :
217214 al = u32_b_unpack (stream )
218- return [unpack_stream (stream ) for _ in range (al )]
219- if first_byte == 0xDE :
215+ obj = [unpack_stream (stream ) for _ in range (al )]
216+ elif first_byte == 0xDE :
220217 ml = u16_b_unpack (stream )
221- return {unpack_stream (stream ): unpack_stream (stream ) for _ in range (ml )}
222- if first_byte == 0xDF :
218+ obj = {unpack_stream (stream ): unpack_stream (stream ) for _ in range (ml )}
219+ elif first_byte == 0xDF :
223220 ml = u32_b_unpack (stream )
224- return {unpack_stream (stream ): unpack_stream (stream ) for _ in range (ml )}
225- raise ValueError ("invalid first byte" , first_byte , hex (first_byte ))
221+ obj = {unpack_stream (stream ): unpack_stream (stream ) for _ in range (ml )}
222+ else :
223+ raise ValueError ("invalid first byte" , first_byte , hex (first_byte ))
224+ return obj
0 commit comments