diff options
author | INADA Naoki <songofacandy@gmail.com> | 2013-10-17 08:52:59 +0900 |
---|---|---|
committer | INADA Naoki <songofacandy@gmail.com> | 2013-10-17 08:52:59 +0900 |
commit | 84f6b100190049a5d1bceb916208eeae2a3d2591 (patch) | |
tree | 5ca1a706ba8e4d6704fb7fde8d424087ae993ca1 /msgpack | |
parent | 171c5381135bdfc6db154100ad5a9913955408a7 (diff) | |
download | msgpack-python-84f6b100190049a5d1bceb916208eeae2a3d2591.tar.gz |
Add bin type support to pure Python packer.
Diffstat (limited to 'msgpack')
-rw-r--r-- | msgpack/fallback.py | 32 | ||||
-rw-r--r-- | msgpack/pack_template.h | 2 |
2 files changed, 25 insertions, 9 deletions
diff --git a/msgpack/fallback.py b/msgpack/fallback.py index 3bf0489..49a2bc5 100644 --- a/msgpack/fallback.py +++ b/msgpack/fallback.py @@ -429,11 +429,15 @@ class Packer(object): :param bool autoreset: Reset buffer after each pack and return it's content as `bytes`. (default: True). If set this to false, use `bytes()` to get content and `.reset()` to clear buffer. + :param bool use_bin_type: + Use bin type introduced in msgpack spec 2.0 for bytes. + It also enable str8 type for unicode. """ def __init__(self, default=None, encoding='utf-8', unicode_errors='strict', - use_single_float=False, autoreset=True): + use_single_float=False, autoreset=True, use_bin_type=False): self._use_float = use_single_float self._autoreset = autoreset + self._use_bin_type = use_bin_type self._encoding = encoding self._unicode_errors = unicode_errors self._buffer = StringIO() @@ -473,6 +477,17 @@ class Packer(object): if -0x8000000000000000 <= obj < -0x80000000: return self._buffer.write(struct.pack(">Bq", 0xd3, obj)) raise PackValueError("Integer value out of range") + if self._use_bin_type and isinstance(obj, bytes): + n = len(obj) + if n <= 0xff: + self._buffer.write(struct.pack('>BB', 0xc4, n)) + elif n <= 0xffff: + self._buffer.write(struct.pack(">BH", 0xc5, n)) + elif n <= 0xffffffff: + self._buffer.write(struct.pack(">BI", 0xc6, n)) + else: + raise PackValueError("Bytes is too large") + return self._buffer.write(obj) if isinstance(obj, (Unicode, bytes)): if isinstance(obj, Unicode): if self._encoding is None: @@ -483,19 +498,20 @@ class Packer(object): n = len(obj) if n <= 0x1f: self._buffer.write(struct.pack('B', 0xa0 + n)) - return self._buffer.write(obj) - if n <= 0xffff: + elif self._use_bin_type and n <= 0xff: + self._buffer.write(struct.pack('>BB', 0xd9, n)) + elif n <= 0xffff: self._buffer.write(struct.pack(">BH", 0xda, n)) - return self._buffer.write(obj) - if n <= 0xffffffff: + elif n <= 0xffffffff: self._buffer.write(struct.pack(">BI", 0xdb, n)) - return self._buffer.write(obj) - raise PackValueError("String is too large") + else: + raise PackValueError("String is too large") + return self._buffer.write(obj) if isinstance(obj, float): if self._use_float: return self._buffer.write(struct.pack(">Bf", 0xca, obj)) return self._buffer.write(struct.pack(">Bd", 0xcb, obj)) - if isinstance(obj, list) or isinstance(obj, tuple): + if isinstance(obj, (list, tuple)): n = len(obj) self._fb_pack_array_header(n) for i in xrange(n): diff --git a/msgpack/pack_template.h b/msgpack/pack_template.h index ff1cbaa..d228d7a 100644 --- a/msgpack/pack_template.h +++ b/msgpack/pack_template.h @@ -664,7 +664,7 @@ static inline int msgpack_pack_map(msgpack_packer* x, unsigned int n) static inline int msgpack_pack_raw(msgpack_packer* x, size_t l) { - if(l < 32) { + if (l < 32) { unsigned char d = 0xa0 | (uint8_t)l; msgpack_pack_append_buffer(x, &TAKE8_8(d), 1); } else if (x->use_bin_type && l < 256) { // str8 is new format introduced with bin. |