[Zope-Checkins] CVS: Zope2 - cPickle.c:1.72.98.1
Jim Fulton
jim@digicool.com
Tue, 10 Apr 2001 12:49:33 -0400 (EDT)
Update of /cvs-repository/Zope2/lib/Components/cPickle
In directory korak:/tmp/cvs-serv7735
Modified Files:
Tag: zope-2_3-branch
cPickle.c
Log Message:
Merged Tim's fixes to cross-platform handling of binary integers.
--- Updated File cPickle.c in package Zope2 --
--- cPickle.c 2000/05/09 18:05:09 1.72
+++ cPickle.c 2001/04/10 16:49:32 1.72.98.1
@@ -69,6 +69,20 @@
#define WRITE_BUF_SIZE 256
+/* --------------------------------------------------------------------------
+NOTES on format codes.
+XXX much more is needed here
+
+Integer types
+BININT1 8-bit unsigned integer; followed by 1 byte.
+BININT2 16-bit unsigned integer; followed by 2 bytes, little-endian.
+BININT 32-bit signed integer; followed by 4 bytes, little-endian.
+INT Integer; natural decimal string conversion, then newline.
+ CAUTION: INT-reading code can't assume that what follows
+ fits in a Python int, because the size of Python ints varies
+ across platforms.
+LONG Long (unbounded) integer; repr(i), then newline.
+-------------------------------------------------------------------------- */
#define MARK '('
#define STOP '.'
@@ -905,18 +919,20 @@
if (!self->bin
#if SIZEOF_LONG > 4
- || (l >> 32)
+ || l > 0x7fffffffL
+ || l < -0x80000000L
#endif
- ) {
- /* Save extra-long ints in non-binary mode, so that
- we can use python long parsing code to restore,
- if necessary. */
+ ) {
+ /* Text-mode pickle, or long too big to fit in the 4-byte
+ * signed BININT format: store as a string.
+ */
c_str[0] = INT;
sprintf(c_str + 1, "%ld\n", l);
if ((*self->write_func)(self, c_str, strlen(c_str)) < 0)
return -1;
}
else {
+ /* Binary pickle and l fits in a signed 4-byte int. */
c_str[1] = (int)( l & 0xff);
c_str[2] = (int)((l >> 8) & 0xff);
c_str[3] = (int)((l >> 16) & 0xff);
@@ -2401,7 +2417,14 @@
c = (unsigned char)s[i];
l |= (long)c << (i * 8);
}
-
+#if SIZEOF_LONG > 4
+ /* Unlike BININT1 and BININT2, BININT (more accurately BININT4)
+ * is signed, so on a box with longs bigger than 4 bytes we need
+ * to extend a BININT's sign bit to the full width.
+ */
+ if (x == 4 && l & (1L << 31))
+ l |= (~0L) << 32;
+#endif
return l;
}