[Python-checkins] CVS: python/dist/src/Modules cPickle.c,2.38,2.39
Guido van Rossum
guido@cnri.reston.va.us
Fri, 10 Mar 2000 18:11:43 -0500 (EST)
Update of /projects/cvsroot/python/dist/src/Modules
In directory eric:/home/guido/hp/mal/py-patched/Modules
Modified Files:
cPickle.c
Log Message:
Marc-Andre Lemburg: support pickling Unicode objects, both in text
mode ('V') and in binary mode ('X').
Index: cPickle.c
===================================================================
RCS file: /projects/cvsroot/python/dist/src/Modules/cPickle.c,v
retrieving revision 2.38
retrieving revision 2.39
diff -C2 -r2.38 -r2.39
*** cPickle.c 2000/02/29 13:59:22 2.38
--- cPickle.c 2000/03/10 23:11:40 2.39
***************
*** 90,93 ****
--- 90,95 ----
#define BINSTRING 'T'
#define SHORT_BINSTRING 'U'
+ #define UNICODE 'V'
+ #define BINUNICODE 'X'
#define APPEND 'a'
#define BUILD 'b'
***************
*** 1161,1164 ****
--- 1163,1239 ----
static int
+ save_unicode(Picklerobject *self, PyObject *args, int doput) {
+ int size, len;
+ PyObject *repr=0;
+
+ if (!PyUnicode_Check(args))
+ return -1;
+
+ if (!self->bin) {
+ char *repr_str;
+ static char string = UNICODE;
+
+ UNLESS (repr = PyUnicode_AsRawUnicodeEscapeString(args))
+ return -1;
+
+ if ((len = PyString_Size(repr)) < 0)
+ goto err;
+ repr_str = PyString_AS_STRING((PyStringObject *)repr);
+
+ if ((*self->write_func)(self, &string, 1) < 0)
+ goto err;
+
+ if ((*self->write_func)(self, repr_str, len) < 0)
+ goto err;
+
+ if ((*self->write_func)(self, "\n", 1) < 0)
+ goto err;
+
+ Py_XDECREF(repr);
+ }
+ else {
+ int i;
+ char c_str[5];
+
+ UNLESS (repr = PyUnicode_AsUTF8String(args))
+ return -1;
+
+ if ((size = PyString_Size(repr)) < 0)
+ goto err;
+
+ c_str[0] = BINUNICODE;
+ for (i = 1; i < 5; i++)
+ c_str[i] = (int)(size >> ((i - 1) * 8));
+ len = 5;
+
+ if ((*self->write_func)(self, c_str, len) < 0)
+ goto err;
+
+ if (size > 128 && Pdata_Check(self->file)) {
+ if (write_other(self, NULL, 0) < 0)
+ goto err;
+ PDATA_APPEND(self->file, repr, -1);
+ }
+ else {
+ if ((*self->write_func)(self, PyString_AS_STRING(repr), size) < 0)
+ goto err;
+ }
+
+ Py_DECREF(repr);
+ }
+
+ if (doput)
+ if (put(self, args) < 0)
+ return -1;
+
+ return 0;
+
+ err:
+ Py_XDECREF(repr);
+ return -1;
+ }
+
+
+ static int
save_tuple(Picklerobject *self, PyObject *args) {
PyObject *element = 0, *py_tuple_id = 0;
***************
*** 1692,1695 ****
--- 1767,1776 ----
goto finally;
}
+
+ case 'u':
+ if ((type == &PyUnicode_Type) && (PyString_GET_SIZE(args) < 2)) {
+ res = save_unicode(self, args, 0);
+ goto finally;
+ }
}
***************
*** 1723,1726 ****
--- 1804,1814 ----
break;
+ case 'u':
+ if (type == &PyUnicode_Type) {
+ res = save_unicode(self, args, 1);
+ goto finally;
+ }
+ break;
+
case 't':
if (type == &PyTuple_Type) {
***************
*** 2668,2671 ****
--- 2756,2800 ----
static int
+ load_unicode(Unpicklerobject *self) {
+ PyObject *str = 0;
+ int len, res = -1;
+ char *s;
+
+ if ((len = (*self->readline_func)(self, &s)) < 0) return -1;
+ if (len < 2) return bad_readline();
+
+ UNLESS (str = PyUnicode_DecodeRawUnicodeEscape(s, len - 1, NULL))
+ goto finally;
+
+ PDATA_PUSH(self->stack, str, -1);
+ return 0;
+
+ finally:
+ return res;
+ }
+
+
+ static int
+ load_binunicode(Unpicklerobject *self) {
+ PyObject *unicode;
+ long l;
+ char *s;
+
+ if ((*self->read_func)(self, &s, 4) < 0) return -1;
+
+ l = calc_binint(s, 4);
+
+ if ((*self->read_func)(self, &s, l) < 0)
+ return -1;
+
+ UNLESS (unicode = PyUnicode_DecodeUTF8(s, l, NULL))
+ return -1;
+
+ PDATA_PUSH(self->stack, unicode, -1);
+ return 0;
+ }
+
+
+ static int
load_tuple(Unpicklerobject *self) {
PyObject *tup;
***************
*** 3413,3416 ****
--- 3542,3555 ----
continue;
+ case UNICODE:
+ if (load_unicode(self) < 0)
+ break;
+ continue;
+
+ case BINUNICODE:
+ if (load_binunicode(self) < 0)
+ break;
+ continue;
+
case EMPTY_TUPLE:
if (load_empty_tuple(self) < 0)
***************
*** 3690,3693 ****
--- 3829,3842 ----
case STRING:
if (load_string(self) < 0)
+ break;
+ continue;
+
+ case UNICODE:
+ if (load_unicode(self) < 0)
+ break;
+ continue;
+
+ case BINUNICODE:
+ if (load_binunicode(self) < 0)
break;
continue;