|
55 | 55 |
|
56 | 56 | def pack_stream(stream, obj): |
57 | 57 | _type = type(obj) |
58 | | - if _type is int: |
| 58 | + if _type is int: # int |
59 | 59 | i = obj |
60 | 60 | if 0 <= i <= 0x7F: # positive fixint |
61 | 61 | stream.write(_B[i]) |
62 | 62 | elif -32 <= i < 0: # negative fixint |
63 | 63 | stream.write(_B[i & 0xFF]) |
64 | 64 | elif i < 0: # wider negative |
65 | 65 | u_i = -i |
66 | | - if u_i <= 0x80: |
| 66 | + if u_i <= 0x80: # int8 |
67 | 67 | stream.write(b"\xd0" + s8_b_pack(i)) |
68 | | - elif u_i <= 0x80_00: |
| 68 | + elif u_i <= 0x80_00: # int16 |
69 | 69 | stream.write(b"\xd1" + s16_b_pack(i)) |
70 | | - elif u_i <= 0x80_00_00_00: |
| 70 | + elif u_i <= 0x80_00_00_00: # int32 |
71 | 71 | stream.write(b"\xd2" + s32_b_pack(i)) |
72 | | - elif u_i <= 0x80_00_00_00_00_00_00_00: |
| 72 | + elif u_i <= 0x80_00_00_00_00_00_00_00: # int64 |
73 | 73 | stream.write(b"\xd3" + s64_b_pack(i)) |
74 | 74 | else: |
75 | 75 | raise ValueError("int too large") |
76 | | - elif i <= 0xFF: |
| 76 | + elif i <= 0xFF: # uint8 |
77 | 77 | stream.write(b"\xcc" + _B[i]) |
78 | | - elif i <= 0xFF_FF: |
| 78 | + elif i <= 0xFF_FF: # uint16 |
79 | 79 | stream.write(b"\xcd" + u16_b_pack(i)) |
80 | | - elif i <= 0xFF_FF_FF_FF: |
| 80 | + elif i <= 0xFF_FF_FF_FF: # uint32 |
81 | 81 | stream.write(b"\xce" + u32_b_pack(i)) |
82 | | - elif i <= 0xFF_FF_FF_FF_FF_FF_FF_FF: |
| 82 | + elif i <= 0xFF_FF_FF_FF_FF_FF_FF_FF: # uint64 |
83 | 83 | stream.write(b"\xcf" + u64_b_pack(i)) |
84 | 84 | else: |
85 | 85 | raise ValueError("uint too large") |
86 | | - elif _type is float: |
| 86 | + elif _type is float: # float32 / float64 (depends on MSGPACK_PACK_FLOAT32) |
87 | 87 | stream.write(b"\xcb" + f_b_pack(obj)) |
88 | | - elif _type is dict: |
| 88 | + elif _type is dict: # map |
89 | 89 | ml = len(obj) |
90 | | - if ml <= 0x0F: |
| 90 | + if ml <= 0x0F: # fixmap |
91 | 91 | stream.write(_B[0x80 | ml]) |
92 | | - elif ml <= 0xFF_FF: |
| 92 | + elif ml <= 0xFF_FF: # map16 |
93 | 93 | stream.write(b"\xde" + u16_b_pack(ml)) |
94 | | - elif ml <= 0xFF_FF_FF_FF: |
| 94 | + elif ml <= 0xFF_FF_FF_FF: # map32 |
95 | 95 | stream.write(b"\xdf" + u32_b_pack(ml)) |
96 | 96 | else: |
97 | 97 | raise ValueError("map too large", obj) |
98 | 98 | for k, v in obj.items(): |
99 | 99 | pack_stream(stream, k) |
100 | 100 | pack_stream(stream, v) |
101 | | - elif _type is list: |
| 101 | + elif _type is list: # array |
102 | 102 | al = len(obj) |
103 | | - if al <= 0x0F: |
| 103 | + if al <= 0x0F: # fixarray |
104 | 104 | stream.write(_B[0x90 | al]) |
105 | | - elif al <= 0xFF_FF: |
| 105 | + elif al <= 0xFF_FF: # array16 |
106 | 106 | stream.write(b"\xdc" + u16_b_pack(al)) |
107 | | - elif al <= 0xFF_FF_FF_FF: |
| 107 | + elif al <= 0xFF_FF_FF_FF: # array32 |
108 | 108 | stream.write(b"\xdd" + u32_b_pack(al)) |
109 | 109 | else: |
110 | 110 | raise ValueError("array too large", obj) |
111 | 111 | for v in obj: |
112 | 112 | pack_stream(stream, v) |
113 | | - elif _type is str: |
| 113 | + elif _type is str: # str |
114 | 114 | s = obj.encode("utf-8") |
115 | 115 | sl = len(s) |
116 | | - if sl <= 0x1F: |
| 116 | + if sl <= 0x1F: # fixstr |
117 | 117 | stream.write(_B[0xA0 | sl]) |
118 | | - elif sl <= 0xFF: |
| 118 | + elif sl <= 0xFF: # str8 |
119 | 119 | stream.write(b"\xd9" + _B[sl]) |
120 | | - elif sl <= 0xFF_FF: |
| 120 | + elif sl <= 0xFF_FF: # str16 |
121 | 121 | stream.write(b"\xda" + u16_b_pack(sl)) |
122 | | - elif sl <= 0xFF_FF_FF_FF: |
| 122 | + elif sl <= 0xFF_FF_FF_FF: # str32 |
123 | 123 | stream.write(b"\xdb" + u32_b_pack(sl)) |
124 | 124 | else: |
125 | 125 | raise ValueError("str too large", obj) |
126 | 126 | stream.write(s) |
127 | | - elif obj is None: |
| 127 | + elif obj is None: # nil |
128 | 128 | stream.write(b"\xc0") |
129 | | - elif _type is bool: |
| 129 | + elif _type is bool: # true / false |
130 | 130 | stream.write(b"\xc3" if obj else b"\xc2") |
131 | | - elif _type is bytes: |
| 131 | + elif _type is bytes: # bin |
132 | 132 | bl = len(obj) |
133 | | - if bl <= 0xFF: |
| 133 | + if bl <= 0xFF: # bin8 |
134 | 134 | stream.write(b"\xc4" + _B[bl]) |
135 | | - elif bl <= 0xFF_FF: |
| 135 | + elif bl <= 0xFF_FF: # bin16 |
136 | 136 | stream.write(b"\xc5" + u16_b_pack(bl)) |
137 | | - elif bl <= 0xFF_FF_FF_FF: |
| 137 | + elif bl <= 0xFF_FF_FF_FF: # bin32 |
138 | 138 | stream.write(b"\xc6" + u32_b_pack(bl)) |
139 | 139 | else: |
140 | 140 | raise ValueError("bin too large", obj) |
141 | 141 | stream.write(obj) |
142 | | - elif _type is ExtType: |
| 142 | + elif _type is ExtType: # ext |
143 | 143 | data = obj.data |
144 | 144 | p_code = s8_b_pack(obj.code) |
145 | 145 | extl = len(data) |
@@ -174,71 +174,73 @@ def unpack_stream(stream): |
174 | 174 | elif first_byte <= 0xBF: # fixstr |
175 | 175 | sl = first_byte & 0x1F |
176 | 176 | obj = stream.read(sl).decode("utf-8") |
177 | | - elif first_byte == 0xC0: |
| 177 | + elif first_byte == 0xC0: # nil |
178 | 178 | obj = None |
179 | | - elif first_byte == 0xC2: |
| 179 | + elif first_byte == 0xC1: # (never used) |
| 180 | + raise ValueError("invalid first byte", first_byte, hex(first_byte)) |
| 181 | + elif first_byte == 0xC2: # false |
180 | 182 | obj = False |
181 | | - elif first_byte == 0xC3: |
| 183 | + elif first_byte == 0xC3: # true |
182 | 184 | obj = True |
183 | | - elif first_byte == 0xC4: |
| 185 | + elif first_byte == 0xC4: # bin8 |
184 | 186 | bl = u8_b_unpack(stream) |
185 | 187 | obj = stream.read(bl) |
186 | | - elif first_byte == 0xC5: |
| 188 | + elif first_byte == 0xC5: # bin16 |
187 | 189 | bl = u16_b_unpack(stream) |
188 | 190 | obj = stream.read(bl) |
189 | | - elif first_byte == 0xC6: |
| 191 | + elif first_byte == 0xC6: # bin32 |
190 | 192 | bl = u32_b_unpack(stream) |
191 | 193 | obj = stream.read(bl) |
192 | 194 | elif first_byte <= 0xC9: # ext (0xC7 - 0xC9) |
193 | | - if first_byte == 0xC7: # ext8 |
194 | | - extl = u8_b_unpack(stream) |
195 | | - elif first_byte == 0xC8: # ext16 |
196 | | - extl = u16_b_unpack(stream) |
197 | | - else: # ext32 |
198 | | - extl = u32_b_unpack(stream) |
| 195 | + if first_byte == 0xC7: |
| 196 | + extl = u8_b_unpack(stream) # ext8 |
| 197 | + elif first_byte == 0xC8: |
| 198 | + extl = u16_b_unpack(stream) # ext16 |
| 199 | + else: |
| 200 | + extl = u32_b_unpack(stream) # ext32 |
199 | 201 | obj = ExtType(s8_b_unpack(stream), stream.read(extl)) |
200 | | - elif first_byte == 0xCA: |
| 202 | + elif first_byte == 0xCA: # float32 |
201 | 203 | obj = f32_b_unpack(stream) |
202 | | - elif first_byte == 0xCB: |
| 204 | + elif first_byte == 0xCB: # float64 |
203 | 205 | obj = f64_b_unpack(stream) |
204 | | - elif first_byte == 0xCC: |
| 206 | + elif first_byte == 0xCC: # uint8 |
205 | 207 | obj = u8_b_unpack(stream) |
206 | | - elif first_byte == 0xCD: |
| 208 | + elif first_byte == 0xCD: # uint16 |
207 | 209 | obj = u16_b_unpack(stream) |
208 | | - elif first_byte == 0xCE: |
| 210 | + elif first_byte == 0xCE: # uint32 |
209 | 211 | obj = u32_b_unpack(stream) |
210 | | - elif first_byte == 0xCF: |
| 212 | + elif first_byte == 0xCF: # uint64 |
211 | 213 | obj = u64_b_unpack(stream) |
212 | | - elif first_byte == 0xD0: |
| 214 | + elif first_byte == 0xD0: # int8 |
213 | 215 | obj = s8_b_unpack(stream) |
214 | | - elif first_byte == 0xD1: |
| 216 | + elif first_byte == 0xD1: # int16 |
215 | 217 | obj = s16_b_unpack(stream) |
216 | | - elif first_byte == 0xD2: |
| 218 | + elif first_byte == 0xD2: # int32 |
217 | 219 | obj = s32_b_unpack(stream) |
218 | | - elif first_byte == 0xD3: |
| 220 | + elif first_byte == 0xD3: # int64 |
219 | 221 | obj = s64_b_unpack(stream) |
220 | 222 | elif first_byte <= 0xD8: # fixext (0xD4 - 0xD8) |
221 | 223 | obj = ExtType(s8_b_unpack(stream), stream.read(1 << (first_byte - 0xD4))) |
222 | | - elif first_byte == 0xD9: |
| 224 | + elif first_byte == 0xD9: # str8 |
223 | 225 | sl = u8_b_unpack(stream) |
224 | 226 | obj = stream.read(sl).decode("utf-8") |
225 | | - elif first_byte == 0xDA: |
| 227 | + elif first_byte == 0xDA: # str16 |
226 | 228 | sl = u16_b_unpack(stream) |
227 | 229 | obj = stream.read(sl).decode("utf-8") |
228 | | - elif first_byte == 0xDB: |
| 230 | + elif first_byte == 0xDB: # str32 |
229 | 231 | sl = u32_b_unpack(stream) |
230 | 232 | obj = stream.read(sl).decode("utf-8") |
231 | | - elif first_byte == 0xDC: |
232 | | - al = u16_b_unpack(stream) |
233 | | - obj = [unpack_stream(stream) for _ in range(al)] |
234 | | - elif first_byte == 0xDD: |
235 | | - al = u32_b_unpack(stream) |
| 233 | + elif first_byte <= 0xDD: # array |
| 234 | + if first_byte == 0xDC: |
| 235 | + al = u16_b_unpack(stream) # array16 |
| 236 | + else: |
| 237 | + al = u32_b_unpack(stream) # array32 |
236 | 238 | obj = [unpack_stream(stream) for _ in range(al)] |
237 | | - elif first_byte == 0xDE: |
238 | | - ml = u16_b_unpack(stream) |
239 | | - obj = {unpack_stream(stream): unpack_stream(stream) for _ in range(ml)} |
240 | | - elif first_byte == 0xDF: |
241 | | - ml = u32_b_unpack(stream) |
| 239 | + elif first_byte <= 0xDF: # map |
| 240 | + if first_byte == 0xDE: |
| 241 | + ml = u16_b_unpack(stream) # map16 |
| 242 | + else: |
| 243 | + ml = u32_b_unpack(stream) # map32 |
242 | 244 | obj = {unpack_stream(stream): unpack_stream(stream) for _ in range(ml)} |
243 | 245 | else: |
244 | 246 | raise ValueError("invalid first byte", first_byte, hex(first_byte)) |
|
0 commit comments