@@ -506,82 +506,111 @@ def __init__(self, default=None, encoding='utf-8', unicode_errors='strict',
506506 self ._default = default
507507
508508 def _pack (self , obj , nest_limit = DEFAULT_RECURSE_LIMIT , isinstance = isinstance ):
509- if nest_limit < 0 :
510- raise PackValueError ("recursion limit exceeded" )
511- if obj is None :
512- return self ._buffer .write (b"\xc0 " )
513- if isinstance (obj , bool ):
514- if obj :
515- return self ._buffer .write (b"\xc3 " )
516- return self ._buffer .write (b"\xc2 " )
517- if isinstance (obj , int_types ):
518- if 0 <= obj < 0x80 :
519- return self ._buffer .write (struct .pack ("B" , obj ))
520- if - 0x20 <= obj < 0 :
521- return self ._buffer .write (struct .pack ("b" , obj ))
522- if 0x80 <= obj <= 0xff :
523- return self ._buffer .write (struct .pack ("BB" , 0xcc , obj ))
524- if - 0x80 <= obj < 0 :
525- return self ._buffer .write (struct .pack (">Bb" , 0xd0 , obj ))
526- if 0xff < obj <= 0xffff :
527- return self ._buffer .write (struct .pack (">BH" , 0xcd , obj ))
528- if - 0x8000 <= obj < - 0x80 :
529- return self ._buffer .write (struct .pack (">Bh" , 0xd1 , obj ))
530- if 0xffff < obj <= 0xffffffff :
531- return self ._buffer .write (struct .pack (">BI" , 0xce , obj ))
532- if - 0x80000000 <= obj < - 0x8000 :
533- return self ._buffer .write (struct .pack (">Bi" , 0xd2 , obj ))
534- if 0xffffffff < obj <= 0xffffffffffffffff :
535- return self ._buffer .write (struct .pack (">BQ" , 0xcf , obj ))
536- if - 0x8000000000000000 <= obj < - 0x80000000 :
537- return self ._buffer .write (struct .pack (">Bq" , 0xd3 , obj ))
538- raise PackValueError ("Integer value out of range" )
539- if self ._use_bin_type and isinstance (obj , bytes ):
540- n = len (obj )
541- if n <= 0xff :
542- self ._buffer .write (struct .pack ('>BB' , 0xc4 , n ))
543- elif n <= 0xffff :
544- self ._buffer .write (struct .pack (">BH" , 0xc5 , n ))
545- elif n <= 0xffffffff :
546- self ._buffer .write (struct .pack (">BI" , 0xc6 , n ))
547- else :
548- raise PackValueError ("Bytes is too large" )
549- return self ._buffer .write (obj )
550- if isinstance (obj , (Unicode , bytes )):
551- if isinstance (obj , Unicode ):
552- if self ._encoding is None :
553- raise TypeError (
554- "Can't encode unicode string: "
555- "no encoding is specified" )
556- obj = obj .encode (self ._encoding , self ._unicode_errors )
557- n = len (obj )
558- if n <= 0x1f :
559- self ._buffer .write (struct .pack ('B' , 0xa0 + n ))
560- elif self ._use_bin_type and n <= 0xff :
561- self ._buffer .write (struct .pack ('>BB' , 0xd9 , n ))
562- elif n <= 0xffff :
563- self ._buffer .write (struct .pack (">BH" , 0xda , n ))
564- elif n <= 0xffffffff :
565- self ._buffer .write (struct .pack (">BI" , 0xdb , n ))
566- else :
567- raise PackValueError ("String is too large" )
568- return self ._buffer .write (obj )
569- if isinstance (obj , float ):
570- if self ._use_float :
571- return self ._buffer .write (struct .pack (">Bf" , 0xca , obj ))
572- return self ._buffer .write (struct .pack (">Bd" , 0xcb , obj ))
573- if isinstance (obj , (list , tuple )):
574- n = len (obj )
575- self ._fb_pack_array_header (n )
576- for i in xrange (n ):
577- self ._pack (obj [i ], nest_limit - 1 )
578- return
579- if isinstance (obj , dict ):
580- return self ._fb_pack_map_pairs (len (obj ), dict_iteritems (obj ),
581- nest_limit - 1 )
582- if self ._default is not None :
583- return self ._pack (self ._default (obj ), nest_limit - 1 )
584- raise TypeError ("Cannot serialize %r" % obj )
509+ default_used = False
510+ while True :
511+ if nest_limit < 0 :
512+ raise PackValueError ("recursion limit exceeded" )
513+ if obj is None :
514+ return self ._buffer .write (b"\xc0 " )
515+ if isinstance (obj , bool ):
516+ if obj :
517+ return self ._buffer .write (b"\xc3 " )
518+ return self ._buffer .write (b"\xc2 " )
519+ if isinstance (obj , int_types ):
520+ if 0 <= obj < 0x80 :
521+ return self ._buffer .write (struct .pack ("B" , obj ))
522+ if - 0x20 <= obj < 0 :
523+ return self ._buffer .write (struct .pack ("b" , obj ))
524+ if 0x80 <= obj <= 0xff :
525+ return self ._buffer .write (struct .pack ("BB" , 0xcc , obj ))
526+ if - 0x80 <= obj < 0 :
527+ return self ._buffer .write (struct .pack (">Bb" , 0xd0 , obj ))
528+ if 0xff < obj <= 0xffff :
529+ return self ._buffer .write (struct .pack (">BH" , 0xcd , obj ))
530+ if - 0x8000 <= obj < - 0x80 :
531+ return self ._buffer .write (struct .pack (">Bh" , 0xd1 , obj ))
532+ if 0xffff < obj <= 0xffffffff :
533+ return self ._buffer .write (struct .pack (">BI" , 0xce , obj ))
534+ if - 0x80000000 <= obj < - 0x8000 :
535+ return self ._buffer .write (struct .pack (">Bi" , 0xd2 , obj ))
536+ if 0xffffffff < obj <= 0xffffffffffffffff :
537+ return self ._buffer .write (struct .pack (">BQ" , 0xcf , obj ))
538+ if - 0x8000000000000000 <= obj < - 0x80000000 :
539+ return self ._buffer .write (struct .pack (">Bq" , 0xd3 , obj ))
540+ raise PackValueError ("Integer value out of range" )
541+ if self ._use_bin_type and isinstance (obj , bytes ):
542+ n = len (obj )
543+ if n <= 0xff :
544+ self ._buffer .write (struct .pack ('>BB' , 0xc4 , n ))
545+ elif n <= 0xffff :
546+ self ._buffer .write (struct .pack (">BH" , 0xc5 , n ))
547+ elif n <= 0xffffffff :
548+ self ._buffer .write (struct .pack (">BI" , 0xc6 , n ))
549+ else :
550+ raise PackValueError ("Bytes is too large" )
551+ return self ._buffer .write (obj )
552+ if isinstance (obj , (Unicode , bytes )):
553+ if isinstance (obj , Unicode ):
554+ if self ._encoding is None :
555+ raise TypeError (
556+ "Can't encode unicode string: "
557+ "no encoding is specified" )
558+ obj = obj .encode (self ._encoding , self ._unicode_errors )
559+ n = len (obj )
560+ if n <= 0x1f :
561+ self ._buffer .write (struct .pack ('B' , 0xa0 + n ))
562+ elif self ._use_bin_type and n <= 0xff :
563+ self ._buffer .write (struct .pack ('>BB' , 0xd9 , n ))
564+ elif n <= 0xffff :
565+ self ._buffer .write (struct .pack (">BH" , 0xda , n ))
566+ elif n <= 0xffffffff :
567+ self ._buffer .write (struct .pack (">BI" , 0xdb , n ))
568+ else :
569+ raise PackValueError ("String is too large" )
570+ return self ._buffer .write (obj )
571+ if isinstance (obj , float ):
572+ if self ._use_float :
573+ return self ._buffer .write (struct .pack (">Bf" , 0xca , obj ))
574+ return self ._buffer .write (struct .pack (">Bd" , 0xcb , obj ))
575+ if isinstance (obj , ExtType ):
576+ code = obj .code
577+ data = obj .data
578+ assert isinstance (code , int )
579+ assert isinstance (data , bytes )
580+ L = len (data )
581+ if L == 1 :
582+ self ._buffer .write (b'\xd4 ' )
583+ elif L == 2 :
584+ self ._buffer .write (b'\xd5 ' )
585+ elif L == 4 :
586+ self ._buffer .write (b'\xd6 ' )
587+ elif L == 8 :
588+ self ._buffer .write (b'\xd7 ' )
589+ elif L == 16 :
590+ self ._buffer .write (b'\xd8 ' )
591+ elif L <= 0xff :
592+ self ._buffer .write (struct .pack (">BB" , 0xc7 , L ))
593+ elif L <= 0xffff :
594+ self ._buffer .write (struct .pack (">BH" , 0xc8 , L ))
595+ else :
596+ self ._buffer .write (struct .pack (">BI" , 0xc9 , L ))
597+ self ._buffer .write (struct .pack ("b" , code ))
598+ self ._buffer .write (data )
599+ return
600+ if isinstance (obj , (list , tuple )):
601+ n = len (obj )
602+ self ._fb_pack_array_header (n )
603+ for i in xrange (n ):
604+ self ._pack (obj [i ], nest_limit - 1 )
605+ return
606+ if isinstance (obj , dict ):
607+ return self ._fb_pack_map_pairs (len (obj ), dict_iteritems (obj ),
608+ nest_limit - 1 )
609+ if not default_used and self ._default is not None :
610+ obj = self ._default (obj )
611+ default_used = 1
612+ continue
613+ raise TypeError ("Cannot serialize %r" % obj )
585614
586615 def pack (self , obj ):
587616 self ._pack (obj )
0 commit comments