Commit d173b366 authored by Jim Fulton's avatar Jim Fulton

Merged Tim's fixes to cross-platform handling of binary integers.

parent f7b9f3b2
/* /*
* $Id: cPickle.c,v 1.72 2000/05/09 18:05:09 jim Exp $ * $Id: cPickle.c,v 1.73 2001/04/10 16:55:33 jim Exp $
* *
* Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA. * Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
* All rights reserved. * All rights reserved.
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
static char cPickle_module_documentation[] = static char cPickle_module_documentation[] =
"C implementation and optimization of the Python pickle module\n" "C implementation and optimization of the Python pickle module\n"
"\n" "\n"
"$Id: cPickle.c,v 1.72 2000/05/09 18:05:09 jim Exp $\n" "$Id: cPickle.c,v 1.73 2001/04/10 16:55:33 jim Exp $\n"
; ;
#include "Python.h" #include "Python.h"
...@@ -69,6 +69,20 @@ static char cPickle_module_documentation[] = ...@@ -69,6 +69,20 @@ static char cPickle_module_documentation[] =
#define WRITE_BUF_SIZE 256 #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 MARK '('
#define STOP '.' #define STOP '.'
...@@ -905,18 +919,20 @@ save_int(Picklerobject *self, PyObject *args) { ...@@ -905,18 +919,20 @@ save_int(Picklerobject *self, PyObject *args) {
if (!self->bin if (!self->bin
#if SIZEOF_LONG > 4 #if SIZEOF_LONG > 4
|| (l >> 32) || l > 0x7fffffffL
|| l < -0x80000000L
#endif #endif
) { ) {
/* Save extra-long ints in non-binary mode, so that /* Text-mode pickle, or long too big to fit in the 4-byte
we can use python long parsing code to restore, * signed BININT format: store as a string.
if necessary. */ */
c_str[0] = INT; c_str[0] = INT;
sprintf(c_str + 1, "%ld\n", l); sprintf(c_str + 1, "%ld\n", l);
if ((*self->write_func)(self, c_str, strlen(c_str)) < 0) if ((*self->write_func)(self, c_str, strlen(c_str)) < 0)
return -1; return -1;
} }
else { else {
/* Binary pickle and l fits in a signed 4-byte int. */
c_str[1] = (int)( l & 0xff); c_str[1] = (int)( l & 0xff);
c_str[2] = (int)((l >> 8) & 0xff); c_str[2] = (int)((l >> 8) & 0xff);
c_str[3] = (int)((l >> 16) & 0xff); c_str[3] = (int)((l >> 16) & 0xff);
...@@ -2401,7 +2417,14 @@ calc_binint(char *s, int x) { ...@@ -2401,7 +2417,14 @@ calc_binint(char *s, int x) {
c = (unsigned char)s[i]; c = (unsigned char)s[i];
l |= (long)c << (i * 8); 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; return l;
} }
...@@ -4382,7 +4405,7 @@ init_stuff(PyObject *module, PyObject *module_dict) { ...@@ -4382,7 +4405,7 @@ init_stuff(PyObject *module, PyObject *module_dict) {
DL_EXPORT(void) DL_EXPORT(void)
initcPickle() { initcPickle() {
PyObject *m, *d, *v; PyObject *m, *d, *v;
char *rev="$Revision: 1.72 $"; char *rev="$Revision: 1.73 $";
PyObject *format_version; PyObject *format_version;
PyObject *compatible_formats; PyObject *compatible_formats;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment