[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()