Skip to content

Commit 84f6b10

Browse files
committed
Add bin type support to pure Python packer.
1 parent 171c538 commit 84f6b10

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

msgpack/fallback.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -429,11 +429,15 @@ class Packer(object):
429429
:param bool autoreset:
430430
Reset buffer after each pack and return it's content as `bytes`. (default: True).
431431
If set this to false, use `bytes()` to get content and `.reset()` to clear buffer.
432+
:param bool use_bin_type:
433+
Use bin type introduced in msgpack spec 2.0 for bytes.
434+
It also enable str8 type for unicode.
432435
"""
433436
def __init__(self, default=None, encoding='utf-8', unicode_errors='strict',
434-
use_single_float=False, autoreset=True):
437+
use_single_float=False, autoreset=True, use_bin_type=False):
435438
self._use_float = use_single_float
436439
self._autoreset = autoreset
440+
self._use_bin_type = use_bin_type
437441
self._encoding = encoding
438442
self._unicode_errors = unicode_errors
439443
self._buffer = StringIO()
@@ -473,6 +477,17 @@ def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, isinstance=isinstance):
473477
if -0x8000000000000000 <= obj < -0x80000000:
474478
return self._buffer.write(struct.pack(">Bq", 0xd3, obj))
475479
raise PackValueError("Integer value out of range")
480+
if self._use_bin_type and isinstance(obj, bytes):
481+
n = len(obj)
482+
if n <= 0xff:
483+
self._buffer.write(struct.pack('>BB', 0xc4, n))
484+
elif n <= 0xffff:
485+
self._buffer.write(struct.pack(">BH", 0xc5, n))
486+
elif n <= 0xffffffff:
487+
self._buffer.write(struct.pack(">BI", 0xc6, n))
488+
else:
489+
raise PackValueError("Bytes is too large")
490+
return self._buffer.write(obj)
476491
if isinstance(obj, (Unicode, bytes)):
477492
if isinstance(obj, Unicode):
478493
if self._encoding is None:
@@ -483,19 +498,20 @@ def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, isinstance=isinstance):
483498
n = len(obj)
484499
if n <= 0x1f:
485500
self._buffer.write(struct.pack('B', 0xa0 + n))
486-
return self._buffer.write(obj)
487-
if n <= 0xffff:
501+
elif self._use_bin_type and n <= 0xff:
502+
self._buffer.write(struct.pack('>BB', 0xd9, n))
503+
elif n <= 0xffff:
488504
self._buffer.write(struct.pack(">BH", 0xda, n))
489-
return self._buffer.write(obj)
490-
if n <= 0xffffffff:
505+
elif n <= 0xffffffff:
491506
self._buffer.write(struct.pack(">BI", 0xdb, n))
492-
return self._buffer.write(obj)
493-
raise PackValueError("String is too large")
507+
else:
508+
raise PackValueError("String is too large")
509+
return self._buffer.write(obj)
494510
if isinstance(obj, float):
495511
if self._use_float:
496512
return self._buffer.write(struct.pack(">Bf", 0xca, obj))
497513
return self._buffer.write(struct.pack(">Bd", 0xcb, obj))
498-
if isinstance(obj, list) or isinstance(obj, tuple):
514+
if isinstance(obj, (list, tuple)):
499515
n = len(obj)
500516
self._fb_pack_array_header(n)
501517
for i in xrange(n):

msgpack/pack_template.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,7 @@ static inline int msgpack_pack_map(msgpack_packer* x, unsigned int n)
664664

665665
static inline int msgpack_pack_raw(msgpack_packer* x, size_t l)
666666
{
667-
if(l < 32) {
667+
if (l < 32) {
668668
unsigned char d = 0xa0 | (uint8_t)l;
669669
msgpack_pack_append_buffer(x, &TAKE8_8(d), 1);
670670
} else if (x->use_bin_type && l < 256) { // str8 is new format introduced with bin.

0 commit comments

Comments
 (0)