r51506 - in python/branches/int_unification: Lib/pickle.py Modules/cPickle.c
Author: martin.v.loewis Date: Wed Aug 23 17:00:19 2006 New Revision: 51506 Modified: python/branches/int_unification/Lib/pickle.py python/branches/int_unification/Modules/cPickle.c Log: Adjust pickle implementation to int/long unification. Use INT codes for small integers on binary protocols, and LONG codes otherwise. Modified: python/branches/int_unification/Lib/pickle.py ============================================================================== --- python/branches/int_unification/Lib/pickle.py (original) +++ python/branches/int_unification/Lib/pickle.py Wed Aug 23 17:00:19 2006 @@ -456,9 +456,29 @@ return # Text pickle, or int too big to fit in signed 4-byte format. self.write(INT + repr(obj) + '\n') - dispatch[IntType] = save_int + # XXX save_int is merged into save_long + # dispatch[IntType] = save_int def save_long(self, obj, pack=struct.pack): + if self.bin: + # If the int is small enough to fit in a signed 4-byte 2's-comp + # format, we can store it more efficiently than the general + # case. + # First one- and two-byte unsigned ints: + if obj >= 0: + if obj <= 0xff: + self.write(BININT1 + chr(obj)) + return + if obj <= 0xffff: + self.write("%c%c%c" % (BININT2, obj&0xff, obj>>8)) + return + # Next check for 4-byte signed ints: + high_bits = obj >> 31 # note that Python shift sign-extends + if high_bits == 0 or high_bits == -1: + # All high bits are copies of bit 2**31, so the value + # fits in a 4-byte signed int. + self.write(BININT + pack("<i", obj)) + return if self.proto >= 2: bytes = encode_long(obj) n = len(bytes) Modified: python/branches/int_unification/Modules/cPickle.c ============================================================================== --- python/branches/int_unification/Modules/cPickle.c (original) +++ python/branches/int_unification/Modules/cPickle.c Wed Aug 23 17:00:19 2006 @@ -711,7 +711,9 @@ PyErr_SetString(PicklingError, "no int where int expected in memo"); return -1; } - c_value = PyInt_AS_LONG((PyIntObject*)value); + c_value = PyInt_AsLong(value); + if (c_value == -1 && PyErr_Occurred()) + return -1; if (!self->bin) { s[0] = GET; @@ -958,7 +960,7 @@ { static const char *buf[2] = {FALSE, TRUE}; static char len[2] = {sizeof(FALSE)-1, sizeof(TRUE)-1}; - long l = PyInt_AS_LONG((PyIntObject *)args); + long l = args == Py_True; if (self->proto >= 2) { char opcode = l ? NEWTRUE : NEWFALSE; @@ -971,10 +973,9 @@ } static int -save_int(Picklerobject *self, PyObject *args) +save_int(Picklerobject *self, long l) { char c_str[32]; - long l = PyInt_AS_LONG((PyIntObject *)args); int len = 0; if (!self->bin @@ -1027,9 +1028,16 @@ int size; int res = -1; PyObject *repr = NULL; - + int val = PyInt_AsLong(args); static char l = LONG; + if (val == -1 && PyErr_Occurred()) { + /* out of range for int pickling */ + PyErr_Clear(); + } + else + return save_int(self, val); + if (self->proto >= 2) { /* Linear-time pickling. */ size_t nbits; @@ -2179,13 +2187,6 @@ goto finally; } break; - case 'i': - if (type == &PyInt_Type) { - res = save_int(self, args); - goto finally; - } - break; - case 'l': if (type == &PyLong_Type) { res = save_long(self, args); @@ -2482,7 +2483,9 @@ rsize += PyString_GET_SIZE(k); else if (PyInt_Check(k)) { /* put */ - ik = PyInt_AS_LONG((PyIntObject*)k); + ik = PyInt_AsLong(k); + if (ik == -1 && PyErr_Occurred()) + goto err; if (ik >= lm || ik == 0) { PyErr_SetString(PicklingError, "Invalid get data"); @@ -2502,7 +2505,9 @@ } else { /* put */ - ik = PyInt_AS_LONG((PyIntObject *)k); + ik = PyInt_AsLong(k); + if (ik == -1 && PyErr_Occurred()) + goto err; if (ik >= lm || ik == 0) { PyErr_SetString(PicklingError, "Invalid get data"); @@ -2531,8 +2536,9 @@ } else if (PyTuple_Check(k)) { /* get */ - ik = PyInt_AS_LONG((PyIntObject *) - PyTuple_GET_ITEM(k, 0)); + ik = PyLong_AsLong(PyTuple_GET_ITEM(k, 0)); + if (ik == -1 && PyErr_Occurred()) + goto err; if (ik < 256) { *s++ = BINGET; *s++ = (int)(ik & 0xff); @@ -2547,7 +2553,9 @@ } else { /* put */ - ik = PyInt_AS_LONG((PyIntObject*)k); + ik = PyLong_AsLong(k); + if (ik == -1 && PyErr_Occurred()) + goto err; if (have_get[ik]) { /* with matching get */ if (ik < 256) {
participants (1)
-
martin.v.loewis