@@ -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 ):
0 commit comments