Skip to content

Commit c727440

Browse files
committed
automatically find the best format to encode extended types
1 parent 522c4bf commit c727440

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

msgpack/fallback.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -545,13 +545,29 @@ def handle_unknown_type(self, obj):
545545
# overridden by subclasses
546546
return None
547547

548-
def pack_extended_type(self, fmt, typecode, data):
549-
# for now we support only this. We should add support for the other
550-
# fixext/ext formats
551-
assert fmt == "ext 32"
548+
def pack_extended_type(self, typecode, data):
552549
assert 0 <= typecode <= 127
553-
N = len(data)
554-
self._buffer.write(struct.pack('>BIB', 0xc9, N, typecode))
550+
n = len(data)
551+
if n == 1:
552+
header = struct.pack(">BB", 0xd4, typecode) # fixext 1
553+
elif n == 2:
554+
header = struct.pack(">BB", 0xd5, typecode) # fixext 2
555+
elif n == 4:
556+
header = struct.pack(">BB", 0xd6, typecode) # fixext 4
557+
elif n == 8:
558+
header = struct.pack(">BB", 0xd7, typecode) # fixext 8
559+
elif n == 16:
560+
header = struct.pack(">BB", 0xd8, typecode) # fixext 16
561+
elif n <= 2**8-1:
562+
header = struct.pack(">BBB", 0xc7, n, typecode) # ext 8
563+
elif n <= 2**16-1:
564+
header = struct.pack(">BHB", 0xc8, n, typecode) # ext 16
565+
elif n <= 2**32-1:
566+
header = struct.pack(">BIB", 0xc9, n, typecode) # ext 32
567+
else:
568+
raise PackValueError("ext data too large")
569+
#
570+
self._buffer.write(header)
555571
self._buffer.write(data)
556572

557573
def pack(self, obj):

test/test_extension.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
import array
2+
import struct
23
import msgpack
34

5+
def test_pack_extended_type():
6+
def p(s):
7+
packer = msgpack.Packer()
8+
packer.pack_extended_type(0x42, s)
9+
return packer._buffer.getvalue()
10+
assert p('A') == '\xd4\x42A' # fixext 1
11+
assert p('AB') == '\xd5\x42AB' # fixext 2
12+
assert p('ABCD') == '\xd6\x42ABCD' # fixext 4
13+
assert p('ABCDEFGH') == '\xd7\x42ABCDEFGH' # fixext 8
14+
assert p('A'*16) == '\xd8\x42' + 'A'*16 # fixext 16
15+
assert p('ABC') == '\xc7\x03\x42ABC' # ext 8
16+
assert p('A'*0x0123) == '\xc8\x01\x23\x42' + 'A'*0x0123 # ext 16
17+
assert p('A'*0x00012345) == '\xc9\x00\x01\x23\x45\x42' + 'A'*0x00012345 # ext 32
18+
419
def test_extension_type():
520
class MyPacker(msgpack.Packer):
621
def handle_unknown_type(self, obj):
722
if isinstance(obj, array.array):
8-
fmt = "ext 32"
923
typecode = 123 # application specific typecode
1024
data = obj.tostring()
11-
self.pack_extended_type(fmt, typecode, data)
25+
self.pack_extended_type(typecode, data)
1226
return True
1327

1428
class MyUnpacker(msgpack.Unpacker):

0 commit comments

Comments
 (0)