[Python-checkins] python/dist/src/Lib pickle.py,1.99,1.100

gvanrossum@users.sourceforge.net gvanrossum@users.sourceforge.net
Mon, 27 Jan 2003 19:49:54 -0800


Update of /cvsroot/python/python/dist/src/Lib
In directory sc8-pr-cvs1:/tmp/cvs-serv25222

Modified Files:
	pickle.py 
Log Message:
First baby steps towards implementing protocol 2: PROTO, LONG1 and LONG4.


Index: pickle.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v
retrieving revision 1.99
retrieving revision 1.100
diff -C2 -d -r1.99 -r1.100
*** pickle.py	28 Jan 2003 03:41:54 -0000	1.99
--- pickle.py	28 Jan 2003 03:49:52 -0000	1.100
***************
*** 177,180 ****
--- 177,182 ----
  
          """
+         if not 0 <= proto <= 2:
+             raise ValueError, "pickle protocol must be 0, 1 or 2"
          self.write = file.write
          self.memo = {}
***************
*** 200,203 ****
--- 202,207 ----
  
          """
+         if self.proto >= 2:
+             self.write(PROTO + chr(self.proto))
          self.save(object)
          self.write(STOP)
***************
*** 386,390 ****
      dispatch[IntType] = save_int
  
!     def save_long(self, object):
          self.write(LONG + `object` + '\n')
      dispatch[LongType] = save_long
--- 390,401 ----
      dispatch[IntType] = save_int
  
!     def save_long(self, object, pack=struct.pack):
!         if self.proto >= 2:
!             bytes = encode_long(object)
!             n = len(bytes)
!             if n < 256:
!                 self.write(LONG1 + chr(n) + bytes)
!             else:
!                 self.write(LONG4 + pack("<i", n) + bytes)
          self.write(LONG + `object` + '\n')
      dispatch[LongType] = save_long
***************
*** 725,728 ****
--- 736,745 ----
      dispatch[''] = load_eof
  
+     def load_proto(self):
+         proto = ord(self.read(1))
+         if not 0 <= proto <= 2:
+             raise ValueError, "unsupported pickle protocol: %d" % proto
+     dispatch[PROTO] = load_proto
+ 
      def load_persid(self):
          pid = self.readline()[:-1]
***************
*** 769,772 ****
--- 786,801 ----
      dispatch[LONG] = load_long
  
+     def load_long1(self):
+         n = ord(self.read(1))
+         bytes = self.read(n)
+         return decode_long(bytes)
+     dispatch[LONG1] = load_long1
+ 
+     def load_long4(self):
+         n = mloads('i' + self.read(4))
+         bytes = self.read(n)
+         return decode_long(bytes)
+     dispatch[LONG4] = load_long4
+ 
      def load_float(self):
          self.append(float(self.readline()[:-1]))
***************
*** 1082,1085 ****
--- 1111,1163 ----
      pass
  
+ # Encode/decode longs.
+ 
+ def encode_long(x):
+     r"""Encode a long to a two's complement little-ending binary string.
+     >>> encode_long(255L)
+     '\xff\x00'
+     >>> encode_long(32767L)
+     '\xff\x7f'
+     >>> encode_long(-256L)
+     '\x00\xff'
+     >>> encode_long(-32768L)
+     '\x00\x80'
+     >>> encode_long(-128L)
+     '\x80'
+     >>> encode_long(127L)
+     '\x7f'
+     >>>
+     """
+     digits = []
+     while not -128 <= x < 128:
+         digits.append(x & 0xff)
+         x >>= 8
+     digits.append(x & 0xff)
+     return "".join(map(chr, digits))
+ 
+ def decode_long(data):
+     r"""Decode a long from a two's complement little-endian binary string.
+     >>> decode_long("\xff\x00")
+     255L
+     >>> decode_long("\xff\x7f")
+     32767L
+     >>> decode_long("\x00\xff")
+     -256L
+     >>> decode_long("\x00\x80")
+     -32768L
+     >>> decode_long("\x80")
+     -128L
+     >>> decode_long("\x7f")
+     127L
+     """
+     x = 0L
+     i = 0L
+     for c in data:
+         x |= long(ord(c)) << i
+         i += 8L
+     if data and ord(c) >= 0x80:
+         x -= 1L << i
+     return x
+ 
  # Shorthands
  
***************
*** 1103,1104 ****
--- 1181,1191 ----
      file = StringIO(str)
      return Unpickler(file).load()
+ 
+ # Doctest
+ 
+ def _test():
+     import doctest
+     return doctest.testmod()
+ 
+ if __name__ == "__main__":
+     _test()