/* $Id$ Copyright Copyright 1996 Digital Creations, L.C., 910 Princess Anne Street, Suite 300, Fredericksburg, Virginia 22401 U.S.A. All rights reserved. Copyright in this software is owned by DCLC, unless otherwise indicated. Permission to use, copy and distribute this software is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear. Note that any product, process or technology described in this software may be the subject of other Intellectual Property rights reserved by Digital Creations, L.C. and are not licensed hereunder. Trademarks Digital Creations & DCLC, are trademarks of Digital Creations, L.C.. All other trademarks are owned by their respective companies. No Warranty The software is provided "as is" without warranty of any kind, either express or implied, including, but not limited to, the implied warranties of merchantability, fitness for a particular purpose, or non-infringement. This software could include technical inaccuracies or typographical errors. Changes are periodically made to the software; these changes will be incorporated in new editions of the software. DCLC may make improvements and/or changes in this software at any time without notice. Limitation Of Liability In no event will DCLC be liable for direct, indirect, special, incidental, economic, cover, or consequential damages arising out of the use of or inability to use this software even if advised of the possibility of such damages. Some states do not allow the exclusion or limitation of implied warranties or limitation of liability for incidental or consequential damages, so the above limitation or exclusion may not apply to you. If you have questions regarding this software, contact: Jim Fulton, jim@digicool.com Digital Creations L.C. (540) 371-6909 */ static char cPickle_module_documentation[] = "" ; #include "Python.h" #include "cStringIO.h" #include "graminit.h" #include static PyObject *ErrorObject; #ifdef __cplusplus #define ARG(T, N) T N #define ARGDECL(T, N) #else #define ARG(T, N) N #define ARGDECL(T, N) T N; #endif #define UNLESS(E) if (!(E)) #define ASSIGN(V,E) {PyObject *__e; __e=(E); Py_XDECREF(V); (V)=__e;} #define UNLESS_ASSIGN(V,E) ASSIGN(V,E) UNLESS(V) #define DEL_LIST_SLICE(list, from, to) \ (PyList_SetSlice(list, from, to, empty_list)) #define APPEND 'a' #define BUILD 'b' #define DUP '2' #define GET 'g' #define BINGET 'h' #define INST 'i' #define OBJ 'o' #define MARK '(' static char MARKv = MARK; #define PUT 'p' #define BINPUT 'q' #define POP '0' #define SETITEM 's' #define STOP '.' #define CLASS 'c' #define DICT 'd' #define LIST 'l' #define TUPLE 't' #define NONE 'N' #define INT 'I' #define BININT 'J' #define BININT1 'K' #define BININT2 'M' #define BININT3 'O' #define LONG 'L' #define FLOAT 'F' #define STRING 'S' #define BINSTRING 'T' #define SHORT_BINSTRING 'U' #define PERSID 'P' PyTypeObject *BuiltinFunctionType; /* atol function from string module */ static PyObject *atol_func; static PyObject *PicklingError; static PyObject *UnpicklingError; static PyObject *class_map; static PyObject *empty_list, *empty_tuple; static PyObject *save(); typedef struct { PyObject_HEAD FILE *fp; PyObject *write; PyObject *file; PyObject *memo; PyObject *arg; PyObject *pers_func; char *mark; int bin; int (*write_func)(); } Picklerobject; staticforward PyTypeObject Picklertype; typedef struct { PyObject_HEAD FILE *fp; PyObject *file; PyObject *readline; PyObject *read; PyObject *memo; PyObject *arg; PyObject *stack; PyObject *mark; PyObject *pers_func; int *marks; int num_marks; int marks_size; int (*read_func)(); int (*readline_func)(); } Unpicklerobject; staticforward PyTypeObject Unpicklertype; static int write_file(ARG(Picklerobject *, self), ARG(char *, s), ARG(int, n)) ARGDECL(Picklerobject *, self) ARGDECL(char *, s) ARGDECL(int, n) { if (fwrite(s, sizeof(char), n, self->fp) != n) { PyErr_SetFromErrno(PyExc_IOError); return -1; } return n; } static int write_cStringIO(ARG(Picklerobject *, self), ARG(char *, s), ARG(int, n)) ARGDECL(Picklerobject *, self) ARGDECL(char *, s) ARGDECL(int, n) { if ((*PycStringIO_cwrite)((PyObject *)self->file, s, n) != n) { return -1; } return n; } static int write_other(ARG(Picklerobject *, self), ARG(char *, s), ARG(int, n)) ARGDECL(Picklerobject *, self) ARGDECL(char *, s) ARGDECL(int, n) { PyObject *py_str, *junk; UNLESS(py_str = PyString_FromStringAndSize(s, n)) return -1; UNLESS(self->arg) UNLESS(self->arg = PyTuple_New(1)) { Py_DECREF(py_str); return -1; } if (PyTuple_SetItem(self->arg, 0, py_str) == -1) { Py_DECREF(py_str); return -1; } Py_INCREF(py_str); UNLESS(junk = PyObject_CallObject(self->write, self->arg)) { Py_DECREF(py_str); return -1; } Py_DECREF(junk); return n; } static int read_file(ARG(Unpicklerobject *, self), ARG(char **, s), ARG(int, n)) ARGDECL(Unpicklerobject *, self) ARGDECL(char **, s) ARGDECL(int, n) { if (fread(*s, sizeof(char), n, self->fp) != n) { if (feof(self->fp)) { PyErr_SetNone(PyExc_EOFError); return -1; } PyErr_SetFromErrno(PyExc_IOError); return -1; } return n; } static int readline_file(ARG(Unpicklerobject *, self), ARG(char **, s)) ARGDECL(Unpicklerobject *, self) ARGDECL(char **, s) { int size, i; char *str; UNLESS(str = (char *)malloc(100)) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return -1; } size = 100; i = 0; while (1) { for (; i < size; i++) { if (feof(self->fp) || (str[i] = getc(self->fp)) == '\n') { str[i] = 0; *s = str; return i; } } UNLESS(str = realloc(str, size += 100)) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return -1; } } } static int read_cStringIO(ARG(Unpicklerobject *, self), ARG(char **, s), ARG(int, n)) ARGDECL(Unpicklerobject *, self) ARGDECL(char **, s) ARGDECL(int, n) { char *ptr; if ((*PycStringIO_cread)((PyObject *)self->file, &ptr, n) != n) { PyErr_SetNone(PyExc_EOFError); return -1; } memcpy(*s, ptr, n); return n; } static int readline_cStringIO(ARG(Unpicklerobject *, self), ARG(char **, s)) ARGDECL(Unpicklerobject *, self) ARGDECL(char **, s) { int n; char *ptr, *str; if ((n = (*PycStringIO_creadline)((PyObject *)self->file, &ptr)) == -1) { return -1; } UNLESS(str = (char *)malloc(n * sizeof(char) + 1)) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return -1; } memcpy(str, ptr, n); str[((str[n - 1] == '\n') ? --n : n)] = 0; *s = str; return n; } static int read_other(ARG(Unpicklerobject *, self), ARG(char **, s), ARG(int, n)) ARGDECL(Unpicklerobject *, self) ARGDECL(char **, s) ARGDECL(int, n) { PyObject *bytes, *str; char *ret_str; UNLESS(bytes = PyInt_FromLong(n)) { if (!PyErr_Occurred()) PyErr_SetNone(PyExc_EOFError); return -1; } UNLESS(self->arg) UNLESS(self->arg = PyTuple_New(1)) { Py_DECREF(bytes); return -1; } if (PyTuple_SetItem(self->arg, 0, bytes) == -1) { Py_DECREF(bytes); return -1; } Py_INCREF(bytes); UNLESS(str = PyObject_CallObject(self->read, self->arg)) { Py_DECREF(bytes); return -1; } memcpy(*s, PyString_AsString(str), n); Py_DECREF(bytes); Py_DECREF(str); return n; } static int readline_other(ARG(Unpicklerobject *, self), ARG(char **, s)) ARGDECL(Unpicklerobject *, self) ARGDECL(char **, s) { PyObject *str; char *c_str; int size; UNLESS(str = PyObject_CallObject(self->readline, empty_tuple)) { return -1; } size = PyString_Size(str); UNLESS(c_str = (char *)malloc((size + 1) * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return -1; } memcpy(c_str, PyString_AsString(str), size); if (size > 0) { c_str[((c_str[size - 1] == '\n') ? --size : size)] = 0; } *s = c_str; Py_DECREF(str); return size; } static int put(ARG(Picklerobject *, self), ARG(PyObject *, ob)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, ob) { char c_str[30]; int p, len; PyObject *py_ob_id = 0, *memo_len = 0; if ((p = PyDict_Size(self->memo)) == -1) return -1; if (!self->bin || (p >= 256)) { c_str[0] = PUT; sprintf(c_str + 1, "%d\n", p); len = strlen(c_str); } else { c_str[0] = BINPUT; c_str[1] = p; len = 2; } if ((*self->write_func)(self, c_str, len) == -1) return -1; UNLESS(py_ob_id = PyInt_FromLong((long)ob)) return -1; UNLESS(memo_len = PyInt_FromLong(p)) goto err; if (PyDict_SetItem(self->memo, py_ob_id, memo_len) == -1) goto err; Py_DECREF(py_ob_id); Py_DECREF(memo_len); return 1; err: Py_XDECREF(py_ob_id); Py_XDECREF(memo_len); return -1; } static int safe(ARG(PyObject *, ob)) ARGDECL(PyObject *, ob) { PyTypeObject *type; PyObject *this_item; int len, res, i; type = ob->ob_type; if (type == &PyInt_Type || type == &PyFloat_Type || type == &PyString_Type || ob == Py_None) { return 1; } if (type == &PyTuple_Type) { len = PyTuple_Size(ob); for (i = 0; i < len; i++) { UNLESS(this_item = PyTuple_GET_ITEM((PyTupleObject *)ob, i)) return -1; if ((res = safe(this_item)) == 1) continue; return res; } return 1; } return 0; } static PyObject * whichmodule(ARG(PyObject *, class)) ARGDECL(PyObject *, class) { int has_key, i, j; PyObject *module = 0, *modules_dict = 0, *class_name = 0, *class_name_attr = 0, *name = 0; char *name_str, *class_name_str; static PyObject *__main__str; if ((has_key = PyMapping_HasKey(class_map, class)) == -1) return NULL; if (has_key) { return ((module = PyDict_GetItem(class_map, class)) ? module : NULL); } UNLESS(modules_dict = PySys_GetObject("modules")) return NULL; UNLESS(class_name = ((PyClassObject *)class)->cl_name) { PyErr_SetString(PicklingError, "class has no name"); return NULL; } UNLESS(class_name_str = PyString_AsString(class_name)) return NULL; i = 0; while (j = PyDict_Next(modules_dict, &i, &name, &module)) { UNLESS(name_str = PyString_AsString(name)) return NULL; if (!strcmp(name_str, "__main__")) continue; UNLESS(class_name_attr = PyObject_GetAttr(module, class_name)) { PyErr_Clear(); continue; } if (class_name_attr != class) { Py_DECREF(class_name_attr); continue; } Py_DECREF(class_name_attr); break; } if (!j) /* previous while exited normally */ { UNLESS(__main__str) UNLESS(__main__str = PyString_FromString("__main__")) return NULL; name = __main__str; } else /* previous while exited via break */ { Py_INCREF(name); } PyDict_SetItem(class_map, class, name); return name; } static PyObject * save_none(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { static char none[] = { NONE }; if ((*self->write_func)(self, none, 1) == -1) return NULL; Py_INCREF(Py_None); return Py_None; } static PyObject * save_int(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { char c_str[25]; long l = PyInt_AS_LONG((PyIntObject *)args); int len; if (!self->bin) { c_str[0] = INT; sprintf(c_str + 1, "%ld\n", l); if ((*self->write_func)(self, c_str, strlen(c_str)) == -1) return NULL; } else { c_str[1] = (int)(l & 0xff); c_str[2] = (int)((l >> 8) & 0xff); c_str[3] = (int)((l >> 16) & 0xff); c_str[4] = (int)((l >> 24) & 0xff); if (!c_str[4]) { if (!c_str[3]) { if (!c_str[2]) { c_str[0] = BININT3; len = 2; } else { c_str[0] = BININT2; len = 3; } } else { c_str[0] = BININT1; len = 4; } } else { c_str[0] = BININT; len = 5; } if ((*self->write_func)(self, c_str, len) == -1) return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * save_long(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { char *c_str; int size; PyObject *repr = 0; UNLESS(repr = PyObject_Repr(args)) return NULL; if ((size = PyString_Size(repr)) == -1) { Py_DECREF(repr); return NULL; } UNLESS(c_str = (char *)malloc((size + 2) * sizeof(char))) { Py_DECREF(repr); PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } c_str[0] = LONG; memcpy(c_str + 1, PyString_AS_STRING((PyStringObject *)repr), size); c_str[size + 1] = '\n'; Py_DECREF(repr); if ((*self->write_func)(self, c_str, size + 2) == -1) { free(c_str); return NULL; } free(c_str); Py_INCREF(Py_None); return Py_None; } static PyObject * save_float(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { char c_str[250]; c_str[0] = FLOAT; sprintf(c_str + 1, "%f\n", PyFloat_AS_DOUBLE((PyFloatObject *)args)); if ((*self->write_func)(self, c_str, strlen(c_str)) == -1) return NULL; Py_INCREF(Py_None); return Py_None; } static PyObject * save_string(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { char *c_str; int size, len; if (!self->bin) { PyObject *repr; char *repr_str; UNLESS(repr = PyObject_Repr(args)) return NULL; repr_str = PyString_AS_STRING((PyStringObject *)repr); size = PyString_Size(repr); UNLESS(c_str = (char *)malloc((size + 2) * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } c_str[0] = STRING; memcpy(c_str + 1, repr_str, size); c_str[size + 1] = '\n'; len = size + 2; Py_XDECREF(repr); } else { size = PyString_Size(args); UNLESS(c_str = (char *)malloc((size + 30) * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } if (size < 256) { c_str[0] = SHORT_BINSTRING; c_str[1] = size; len = 2; } else { c_str[0] = BINSTRING; sprintf(c_str + 1, "%d\n", size); len = strlen(c_str); } memcpy(c_str + len, PyString_AS_STRING((PyStringObject *)args), size); len += size; } if ((*self->write_func)(self, c_str, len) == -1) { free(c_str); return NULL; } free(c_str); if (args->ob_refcnt > 1) { if (put(self, args) == -1) { return NULL; } } Py_INCREF(Py_None); return Py_None; } static PyObject * save_tuple(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { PyObject *element = 0, *junk = 0, *py_tuple_id = 0; int len, i, dict_size; static char tuple = TUPLE; if ((*self->write_func)(self, &MARKv, 1) == -1) return NULL; UNLESS(py_tuple_id = PyInt_FromLong((long)args)) return NULL; if ((len = PyTuple_Size(args)) == -1) goto err; for (i = 0; i < len; i++) { UNLESS(element = PyTuple_GET_ITEM((PyTupleObject *)args, i)) goto err; dict_size = PyDict_Size(self->memo); UNLESS(junk = save(self, element)) goto err; Py_DECREF(junk); if (((PyDict_Size(self->memo) - dict_size) > 1) && PyMapping_HasKey(self->memo, py_tuple_id)) { char c_str[30]; long c_value; int c_str_len; PyObject *value; static char pop = POP; while (i-- >= 0) { if ((*self->write_func)(self, &pop, 1) == -1) goto err; } UNLESS(value = PyDict_GetItem(self->memo, py_tuple_id)) goto err; c_value = PyInt_AsLong(value); if (self->bin && (c_value < 256)) { c_str[0] = BINGET; c_str[1] = c_value; c_str_len = 2; } else { c_str[0] = GET; sprintf(c_str + 1, "%ld\n", c_value); c_str_len = strlen(c_str); } if ((*self->write_func)(self, c_str, c_str_len) == -1) goto err; break; } } if (i >= len) { if ((*self->write_func)(self, &tuple, 1) == -1) goto err; if (args->ob_refcnt > 1) { if (put(self, args) == -1) { goto err; } } } Py_DECREF(py_tuple_id); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(py_tuple_id); return NULL; } static PyObject * save_list(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { PyObject *element = 0, *junk = 0; int len, i, safe_val; static char append = APPEND, list = LIST; if ((*self->write_func)(self, &MARKv, 1) == -1) return NULL; if ((len = PyList_Size(args)) == -1) return NULL; for (i = 0; i < len; i++) { UNLESS(element = PyList_GET_ITEM((PyListObject *)args, i)) return NULL; if ((safe_val = safe(element)) == -1) return NULL; UNLESS(safe_val) break; UNLESS(junk = save(self, element)) return NULL; Py_DECREF(junk); } if (args->ob_refcnt > 1) { if (put(self, args) == -1) { return NULL; } } if ((*self->write_func)(self, &list, 1) == -1) return NULL; for (; i < len; i++) { UNLESS(element = PyList_GET_ITEM((PyListObject *)args, i)) return NULL; UNLESS(junk = save(self, element)) return NULL; Py_DECREF(junk); if ((*self->write_func)(self, &append, 1) == -1) return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * save_dict(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { PyObject *key = 0, *value = 0, *junk = 0; int i, safe_key, safe_value; static char setitem = SETITEM, dict = DICT; if ((*self->write_func)(self, &MARKv, 1) == -1) return NULL; i = 0; while (PyDict_Next(args, &i, &key, &value)) { if ((safe_key = safe(key)) == -1) return NULL; UNLESS(safe_key) break; if ((safe_value = safe(value)) == -1) return NULL; UNLESS(safe_value) break; UNLESS(junk = save(self, key)) return NULL; Py_DECREF(junk); UNLESS(junk = save(self, value)) return NULL; Py_DECREF(junk); } if ((*self->write_func)(self, &dict, 1) == -1) return NULL; if (args->ob_refcnt > 1) { if (put(self, args) == -1) { return NULL; } } while (PyDict_Next(args, &i, &key, &value)) { UNLESS(junk = save(self, key)) return NULL; Py_DECREF(junk); UNLESS(junk = save(self, value)) return NULL; Py_DECREF(junk); if ((*self->write_func)(self, &setitem, 1) == -1) return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * save_inst(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { PyObject *class = 0, *module = 0, *name = 0, *py_inst_id = 0, *init_args = 0, *junk = 0, *state = 0, *getinitargs_func = 0, *getstate_func = 0; char *module_str, *name_str, *c_str; int len, p, module_size, name_size, size; static char build = BUILD; if ((*self->write_func)(self, &MARKv, 1) == -1) return NULL; UNLESS(class = PyObject_GetAttrString(args, "__class__")) return NULL; if (self->bin) { UNLESS(junk = save(self, class)) goto err; Py_DECREF(junk); } if (getinitargs_func = PyObject_GetAttrString(args, "__getinitargs__")) { PyObject *class_args = 0, *element = 0; int i, len; UNLESS(class_args = PyObject_CallObject(getinitargs_func, empty_tuple)) { Py_DECREF(getinitargs_func); goto err; } if ((len = PyObject_Length(class_args)) == -1) { Py_DECREF(class_args); goto err; } for (i = 0; i < len; i++) { UNLESS(element = PySequence_GetItem(class_args, i)) { Py_DECREF(class_args); goto err; } UNLESS(junk = save(self, element)) { Py_DECREF(element); Py_DECREF(class_args); goto err; } Py_DECREF(junk); Py_DECREF(element); } Py_DECREF(class_args); } else { PyErr_Clear(); } if (!self->bin) { UNLESS(module = whichmodule(class)) goto err; UNLESS(name = ((PyClassObject *)class)->cl_name) { PyErr_SetString(PicklingError, "class has no name"); goto err; } module_str = PyString_AS_STRING((PyStringObject *)module); module_size = PyString_Size(module); name_str = PyString_AS_STRING((PyStringObject *)name); name_size = PyString_Size(name); size = name_size + module_size + 3; UNLESS(c_str = (char *)malloc(size * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } c_str[0] = INST; memcpy(c_str + 1, module_str, module_size); c_str[module_size + 1] = '\n'; memcpy(c_str + module_size + 2, name_str, name_size); c_str[module_size + name_size + 2] = '\n'; if ((*self->write_func)(self, c_str, size) == -1) { free(c_str); goto err; } free(c_str); } if (args->ob_refcnt > 1) { if (put(self, args) == -1) { goto err; } } if (getstate_func = PyObject_GetAttrString(args, "__getstate__")) { UNLESS(state = PyObject_CallObject(getstate_func, empty_tuple)) { Py_DECREF(getstate_func); goto err; } } else { PyErr_Clear(); UNLESS(state = PyObject_GetAttrString(args, "__dict__")) goto err; } UNLESS(junk = save(self, state)) goto err; Py_DECREF(junk); Py_XDECREF(getinitargs_func); Py_XDECREF(getstate_func); Py_XDECREF(module); Py_XDECREF(state); if ((*self->write_func)(self, &build, 1) == -1) return NULL; Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(getinitargs_func); Py_XDECREF(getstate_func); Py_XDECREF(module); Py_XDECREF(state); return NULL; } static PyObject * save_class(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { PyObject *module = 0, *name = 0; char *name_str, *module_str, *c_str; int module_size, name_size, size; UNLESS(module = whichmodule(args)) return NULL; UNLESS(name = ((PyClassObject *)args)->cl_name) { PyErr_SetString(PicklingError, "class has no name"); goto err; } module_str = PyString_AS_STRING((PyStringObject *)module); module_size = PyString_Size(module); name_str = PyString_AS_STRING((PyStringObject *)name); name_size = PyString_Size(name); size = name_size + module_size + 3; UNLESS(c_str = (char *)malloc(size * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } c_str[0] = CLASS; memcpy(c_str + 1, module_str, module_size); c_str[module_size + 1] = '\n'; memcpy(c_str + module_size + 2, name_str, name_size); c_str[module_size + name_size + 2] = '\n'; if ((*self->write_func)(self, c_str, size) == -1) { free(c_str); goto err; } free(c_str); if (args->ob_refcnt > 1) { if (put(self, args) == -1) { goto err; } } Py_DECREF(module); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(module); return NULL; } static PyObject * save(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { PyTypeObject *type; char *error_str, *name_c; PyObject *name, *name_repr; if (self->pers_func) { PyObject *pid; int size; UNLESS(self->arg) UNLESS(self->arg = PyTuple_New(1)) return NULL; if (PyTuple_SetItem(self->arg, 0, args) == -1) return NULL; Py_INCREF(args); UNLESS(pid = PyObject_CallObject(self->pers_func, self->arg)) return NULL; if (pid != Py_None) { char *pid_str; if ((size = PyString_Size(pid)) == -1) { Py_DECREF(pid); return NULL; } UNLESS(pid_str = (char *)malloc((2 + size) * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); Py_DECREF(pid); return NULL; } pid_str[0] = PERSID; memcpy(pid_str + 1, PyString_AS_STRING((PyStringObject *)pid), size); pid_str[size + 1] = '\n'; Py_DECREF(pid); if ((*self->write_func)(self, pid_str, size + 2) == -1) { free(pid_str); return NULL; } free(pid_str); Py_INCREF(Py_None); return Py_None; } Py_DECREF(pid); } if (args == Py_None) { return save_none(self, args); } type = args->ob_type; if (type == &PyInt_Type) { return save_int(self, args); } if (type == &PyLong_Type) { return save_long(self, args); } if (type == &PyFloat_Type) { return save_float(self, args); } if (args->ob_refcnt > 1) { long ob_id; int has_key; PyObject *py_ob_id; ob_id = (long)args; UNLESS(py_ob_id = PyInt_FromLong(ob_id)) return NULL; if ((has_key = PyMapping_HasKey(self->memo, py_ob_id)) == -1) { Py_DECREF(py_ob_id); return NULL; } if (has_key) { PyObject *value; long c_value; char get_str[30]; int len; UNLESS(value = PyDict_GetItem(self->memo, py_ob_id)) { Py_DECREF(py_ob_id); return NULL; } Py_DECREF(py_ob_id); c_value = PyInt_AsLong(value); if (self->bin && (c_value < 256)) { get_str[0] = BINGET; get_str[1] = c_value; len = 2; } else { get_str[0] = GET; sprintf(get_str + 1, "%ld\n", c_value); len = strlen(get_str); } if ((*self->write_func)(self, get_str, len) == -1) return NULL; Py_INCREF(Py_None); return Py_None; } Py_DECREF(py_ob_id); } if (type == &PyString_Type) { return save_string(self, args); } if (type == &PyTuple_Type) { return save_tuple(self, args); } if (type == &PyList_Type) { return save_list(self, args); } if (type == &PyDict_Type) { return save_dict(self, args); } if (type == &PyInstance_Type) { return save_inst(self, args); } if (type == &PyClass_Type) { return save_class(self, args); } if (PyObject_HasAttrString(args, "__class__")) { return save_inst(self, args); } UNLESS(name = PyObject_GetAttrString((PyObject *)type, "__name__")) return NULL; UNLESS(name_repr = PyObject_Repr(name)) { Py_DECREF(name); } name_c = PyString_AsString(name_repr); UNLESS(error_str = (char *)malloc((strlen(name_c) + 25) * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); Py_DECREF(name); Py_DECREF(name_repr); return NULL; } sprintf(error_str, "Cannot pickle %s objects.", name_c); Py_DECREF(name); Py_DECREF(name_repr); PyErr_SetString(PicklingError, error_str); free(error_str); return NULL; } static PyObject * Pickler_dump(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { PyObject *junk; static char stop = STOP; UNLESS(PyArg_Parse(args, "O", &args)) return NULL; UNLESS(junk = save(self, args)) return NULL; Py_DECREF(junk); if ((*self->write_func)(self, &stop, 1) == -1) return NULL; Py_INCREF(Py_None); return Py_None; } static PyObject * write(ARG(Picklerobject *, self), ARG(PyObject *, args)) ARGDECL(Picklerobject *, self) ARGDECL(PyObject *, args) { char *ptr; int size; UNLESS(ptr = PyString_AsString(args)) return NULL; if ((size = PyString_Size(args)) == -1) return NULL; if ((*self->write_func)(self, ptr, size) == -1) return NULL; Py_INCREF(Py_None); return Py_None; } static struct PyMethodDef Pickler_methods[] = { {"save", (PyCFunction)save, 0, ""}, {"dump", (PyCFunction)Pickler_dump, 0, ""}, {"save_none", (PyCFunction)save_none, 0, ""}, {"save_int", (PyCFunction)save_int, 0, ""}, {"save_long", (PyCFunction)save_long, 0, ""}, {"save_float", (PyCFunction)save_float, 0, ""}, {"save_string", (PyCFunction)save_string, 0, ""}, {"save_tuple", (PyCFunction)save_tuple, 0, ""}, {"save_list", (PyCFunction)save_list, 0, ""}, {"save_dict", (PyCFunction)save_dict, 0, ""}, {"save_inst", (PyCFunction)save_inst, 0, ""}, {"save_class", (PyCFunction)save_class, 0, ""}, {"write", (PyCFunction)write, 0, ""}, {NULL, NULL} /* sentinel */ }; static Picklerobject * newPicklerobject(ARG(PyObject *, file), ARG(int, bin)) ARGDECL(PyObject *, file) ARGDECL(int, bin) { Picklerobject *self; PyObject *memo = 0; UNLESS(memo = PyDict_New()) goto err; UNLESS(self = PyObject_NEW(Picklerobject, &Picklertype)) goto err; if (PyFile_Check(file)) { self->fp = PyFile_AsFile(file); self->write_func = write_file; self->write = NULL; } else if (PycStringIO_OutputCheck(file)) { self->fp = NULL; self->write_func = write_cStringIO; self->write = NULL; } else { PyObject *write; self->fp = NULL; self->write_func = write_other; UNLESS(write = PyObject_GetAttrString(file, "write")) goto err; self->write = write; } Py_INCREF(file); self->file = file; self->bin = bin; self->memo = memo; self->arg = NULL; self->pers_func = NULL; return self; err: Py_XDECREF((PyObject *)self); Py_XDECREF(memo); return NULL; } static PyObject * get_Pickler(ARG(PyObject *, self), ARG(PyObject *, args)) ARGDECL(PyObject *, self) ARGDECL(PyObject *, args) { PyObject *file; int bin = 0; UNLESS(PyArg_ParseTuple(args, "O|i", &file, &bin)) return NULL; return (PyObject *)newPicklerobject(file, bin); } static void Pickler_dealloc(ARG(Picklerobject *, self)) ARGDECL(Picklerobject *, self) { Py_XDECREF(self->write); Py_XDECREF(self->memo); Py_XDECREF(self->arg); Py_XDECREF(self->file); Py_XDECREF(self->pers_func); PyMem_DEL(self); } static PyObject * Pickler_getattr(ARG(Picklerobject *, self), ARG(char *, name)) ARGDECL(Picklerobject *, self) ARGDECL(char *, name) { if (!strcmp(name, "persistent_id")) { if (!self->pers_func) { PyErr_SetString(PyExc_NameError, name); return NULL; } Py_INCREF(self->pers_func); return self->pers_func; } if (!strcmp(name, "memo")) { if (!self->memo) { PyErr_SetString(PyExc_NameError, name); return NULL; } Py_INCREF(self->memo); return self->memo; } if (!strcmp(name, "PicklingError")) { Py_INCREF(PicklingError); return PicklingError; } return Py_FindMethod(Pickler_methods, (PyObject *)self, name); } int Pickler_setattr(ARG(Picklerobject *, self), ARG(char *, name), ARG(PyObject *, value)) ARGDECL(Picklerobject *, self) ARGDECL(char *, name) ARGDECL(PyObject *, value) { if (!strcmp(name, "persistent_id")) { Py_XDECREF(self->pers_func); self->pers_func = value; Py_INCREF(value); return 0; } return -1; } static char Picklertype__doc__[] = ""; static PyTypeObject Picklertype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "Pickler", /*tp_name*/ sizeof(Picklerobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)Pickler_dealloc, /*tp_dealloc*/ (printfunc)0, /*tp_print*/ (getattrfunc)Pickler_getattr, /*tp_getattr*/ (setattrfunc)Pickler_setattr, /*tp_setattr*/ (cmpfunc)0, /*tp_compare*/ (reprfunc)0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)0, /*tp_hash*/ (ternaryfunc)0, /*tp_call*/ (reprfunc)0, /*tp_str*/ /* Space for future expansion */ 0L,0L,0L,0L, Picklertype__doc__ /* Documentation string */ }; static PyObject * find_class(ARG(char *, module_name), ARG(char *, class_name)) ARGDECL(char *, module_name) ARGDECL(char *, class_name) { PyObject *import = 0, *class = 0, *py_module_name = 0, *py_class_name = 0, *t = 0; char *error_str; int has_key; UNLESS(py_module_name = PyString_FromString(module_name)) return NULL; UNLESS(py_class_name = PyString_FromString(class_name)) goto err; UNLESS(t = PyTuple_New(2)) goto err; UNLESS(PyTuple_SET_ITEM((PyTupleObject *)t, 0, py_module_name)) goto err; Py_INCREF(py_module_name); UNLESS(PyTuple_SET_ITEM((PyTupleObject *)t, 1, py_class_name)) goto err; Py_INCREF(py_module_name); if ((has_key = PyMapping_HasKey(class_map, t)) == -1) goto err; if (has_key) { UNLESS(class = PyDict_GetItem(class_map, t)) goto err; Py_INCREF(class); Py_DECREF(py_module_name); Py_DECREF(py_class_name); Py_DECREF(t); return class; } if (!(import = PyImport_ImportModule(module_name)) || !(class = PyObject_GetAttrString(import, class_name))) { UNLESS(error_str = (char *)malloc((strlen(module_name) + strlen(class_name) + 40) * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); goto err; } sprintf(error_str, "Failed to import class %s from module %s", class_name, module_name); PyErr_SetString(PyExc_SystemError, error_str); free(error_str); goto err; } if (class->ob_type == BuiltinFunctionType) { UNLESS(error_str = (char *)malloc((strlen(module_name) + strlen(class_name) + 45) * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); goto err; } sprintf(error_str, "Imported object %s from module %s is not a class", class_name, module_name); PyErr_SetString(PyExc_SystemError, error_str); free(error_str); goto err; } if (PyDict_SetItem(class_map, t, class) == -1) goto err; Py_DECREF(t); Py_DECREF(py_module_name); Py_DECREF(py_class_name); Py_DECREF(import); return class; err: Py_XDECREF(import); Py_XDECREF(class); Py_XDECREF(t); Py_XDECREF(py_module_name); Py_XDECREF(py_class_name); return NULL; } int marker(ARG(Unpicklerobject *, self)) ARGDECL(Unpicklerobject *, self) { if (!self->num_marks) return -1; return self->marks[--self->num_marks]; } static PyObject * load_none(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { if (PyList_Append(self->stack, Py_None) == -1) return NULL; Py_INCREF(Py_None); return Py_None; } static PyObject * load_int(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_int = 0; char *s, *endptr; int len; long l; if ((len = (*self->readline_func)(self, &s)) == -1) return NULL; errno = 0; l = strtol(s, &endptr, 0); free(s); if (errno || strlen(endptr)) { PyErr_SetString(PyExc_ValueError, "could not convert string to int"); goto err; } UNLESS(py_int = PyInt_FromLong(l)) goto err; if (PyList_Append(self->stack, py_int) == -1) goto err; Py_DECREF(py_int); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(py_int); return NULL; } static PyObject * load_binint(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_int = 0; char *s; unsigned char c; long l; UNLESS(s = (char *)malloc(4 * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } if ((*self->read_func)(self, &s, 4) == -1) { free(s); return NULL; } c = (unsigned char)s[0]; l = (long)c; c = (unsigned char)s[1]; l |= (long)c << 8; c = (unsigned char)s[2]; l |= (long)c << 16; c = (unsigned char)s[3]; l |= (long)c << 24; free(s); UNLESS(py_int = PyInt_FromLong(l)) return NULL; if (PyList_Append(self->stack, py_int) == -1) { Py_DECREF(py_int); return NULL; } Py_DECREF(py_int); Py_INCREF(Py_None); return Py_None; } static PyObject * load_binint1(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_int = 0; char *s; unsigned char c; long l; UNLESS(s = (char *)malloc(3 * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } if ((*self->read_func)(self, &s, 3) == -1) { free(s); return NULL; } c = (unsigned char)s[0]; l = (long)c; c = (unsigned char)s[1]; l |= (long)c << 8; c = (unsigned char)s[2]; l |= (long)c << 16; free(s); UNLESS(py_int = PyInt_FromLong(l)) return NULL; if (PyList_Append(self->stack, py_int) == -1) { Py_DECREF(py_int); return NULL; } Py_DECREF(py_int); Py_INCREF(Py_None); return Py_None; } static PyObject * load_binint2(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_int = 0; char *s; unsigned char c; long l; UNLESS(s = (char *)malloc(2 * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } if ((*self->read_func)(self, &s, 2) == -1) return NULL; c = (unsigned char)s[0]; l = (long)c; c = (unsigned char)s[1]; l |= (long)c << 8; free(s); UNLESS(py_int = PyInt_FromLong(l)) return NULL; if (PyList_Append(self->stack, py_int) == -1) { Py_DECREF(py_int); return NULL; } Py_DECREF(py_int); Py_INCREF(Py_None); return Py_None; } static PyObject * load_binint3(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_int = 0; char *s; unsigned char c; long l; UNLESS(s = (char *)malloc(sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } if ((*self->read_func)(self, &s, 1) == -1) { free(s); return NULL; } c = (unsigned char)s[0]; l = (long)c; free(s); UNLESS(py_int = PyInt_FromLong(l)) return NULL; if (PyList_Append(self->stack, py_int) == -1) { Py_DECREF(py_int); return NULL; } Py_DECREF(py_int); Py_INCREF(Py_None); return Py_None; } static PyObject * load_long(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_str = 0, *l = 0; char *s; int len; static PyObject *arg; if ((len = (*self->readline_func)(self, &s)) == -1) return NULL; UNLESS(py_str = PyString_FromStringAndSize(s, len)) { free(s); return NULL; } free(s); UNLESS(arg) { UNLESS(arg = Py_BuildValue("(Oi)", py_str, 0)) return NULL; } else { if (PyTuple_SetItem(arg, 0, py_str) == -1) goto err; Py_INCREF(py_str); } UNLESS(l = PyObject_CallObject(atol_func, arg)) goto err; if (PyList_Append(self->stack, l) == -1) goto err; Py_DECREF(py_str); Py_DECREF(l); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(l); Py_XDECREF(py_str); return NULL; } static PyObject * load_float(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_float = 0; char *s, *endptr; int len; double d; if ((len = (*self->readline_func)(self, &s)) == -1) return NULL; errno = 0; d = strtod(s, &endptr); free(s); if (errno || strlen(endptr)) { PyErr_SetString(PyExc_ValueError, "could not convert string to long"); goto err; } UNLESS(py_float = PyFloat_FromDouble(d)) goto err; if (PyList_Append(self->stack, py_float) == -1) goto err; Py_DECREF(py_float); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(py_float); return NULL; } static PyObject * load_string(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *str = 0; char *s; int len; static PyObject *eval_dict = 0; UNLESS(eval_dict) UNLESS(eval_dict = Py_BuildValue("{s{}}", "__builtins__")) return NULL; if ((len = (*self->readline_func)(self, &s)) == -1) return NULL; UNLESS(str = PyRun_String(s, eval_input, eval_dict, eval_dict)) { free(s); goto err; } free(s); if (PyList_Append(self->stack, str) == -1) goto err; Py_DECREF(str); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(str); return NULL; } static PyObject * load_binstring(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_string = 0; char *s, *endptr; int len, i; if ((len = (*self->readline_func)(self, &s)) == -1) return NULL; i = atoi(s); if (i > len) { free(s); UNLESS(s = (char *)malloc(i * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } } if ((*self->read_func)(self, &s, i) == -1) { free(s); return NULL; } UNLESS(py_string = PyString_FromStringAndSize(s, i)) { free(s); return NULL; } free(s); if (PyList_Append(self->stack, py_string) == -1) goto err; Py_DECREF(py_string); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(py_string); return NULL; } static PyObject * load_short_binstring(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_string = 0; char *s; unsigned char l; UNLESS(s = (char *)malloc(sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } if ((*self->read_func)(self, &s, 1) == -1) { free(s); return NULL; } l = (unsigned char)s[0]; if (l > 1) { free(s); UNLESS(s = (char *)malloc(l * sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } } if ((*self->read_func)(self, &s, l) == -1) { free(s); return NULL; } UNLESS(py_string = PyString_FromStringAndSize(s, l)) { free(s); return NULL; } free(s); if (PyList_Append(self->stack, py_string) == -1) { Py_DECREF(py_string); return NULL; } Py_DECREF(py_string); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(py_string); return NULL; } static PyObject * load_tuple(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *tup = 0, *slice = 0, *list = 0; int i, j; if ((i = marker(self)) == -1) return NULL; if ((j = PyList_Size(self->stack)) == -1) goto err; UNLESS(slice = PyList_GetSlice(self->stack, i, j)) goto err; UNLESS(tup = PySequence_Tuple(slice)) goto err; UNLESS(list = PyList_New(1)) goto err; if (PyList_SetItem(list, 0, tup) == -1) goto err; Py_INCREF(tup); if (PyList_SetSlice(self->stack, i, j, list) == -1) goto err; Py_DECREF(tup); Py_DECREF(list); Py_DECREF(slice); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(tup); Py_XDECREF(list); Py_XDECREF(slice); return NULL; } static PyObject * load_list(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *list = 0, *slice = 0; int i, j; if ((i = marker(self)) == -1) return NULL; if ((j = PyList_Size(self->stack)) == -1) goto err; UNLESS(slice = PyList_GetSlice(self->stack, i, j)) goto err; UNLESS(list = PyList_New(1)) goto err; if (PyList_SetItem(list, 0, slice) == -1) goto err; Py_INCREF(slice); if (PyList_SetSlice(self->stack, i, j, list) == -1) goto err; Py_DECREF(list); Py_DECREF(slice); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(list); Py_XDECREF(slice); return NULL; } static PyObject * load_dict(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *list = 0, *dict = 0, *key = 0, *value = 0; int i, j, k; if ((i = marker(self)) == -1) return NULL; if ((j = PyList_Size(self->stack)) == -1) goto err; UNLESS(dict = PyDict_New()) goto err; for (k = i; k < j; k += 2) { UNLESS(key = PyList_GET_ITEM((PyListObject *)self->stack, k)) goto err; UNLESS(value = PyList_GET_ITEM((PyListObject *)self->stack, k + 1)) goto err; if (PyDict_SetItem(dict, key, value) == -1) goto err; } UNLESS(list = PyList_New(1)) goto err; if (PyList_SetItem(list, 0, dict) == -1) goto err; Py_INCREF(dict); if (PyList_SetSlice(self->stack, i, j, list) == -1) goto err; Py_DECREF(list); Py_DECREF(dict); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(dict); Py_XDECREF(list); return NULL; } static PyObject * load_obj(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *class = 0, *slice = 0, *tup = 0, *obj = 0; long i; int len; if ((i = marker(self)) == -1) return NULL; class = PyList_GET_ITEM((PyListObject *)self->stack, i); Py_INCREF(class); if ((len = PyList_Size(self->stack)) == -1) goto err; UNLESS(slice = PyList_GetSlice(self->stack, i + 1, len)) goto err; UNLESS(tup = PySequence_Tuple(slice)) goto err; if (DEL_LIST_SLICE(self->stack, i, len) == -1) goto err; UNLESS(obj = PyInstance_New(class, tup, NULL)) goto err; if (PyList_Append(self->stack, obj) == -1) goto err; Py_DECREF(class); Py_DECREF(slice); Py_DECREF(tup); Py_DECREF(obj); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(class); Py_XDECREF(slice); Py_XDECREF(tup); Py_XDECREF(obj); return NULL; } static PyObject * load_inst(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *arg_tup = 0, *arg_slice = 0, *class = 0, *obj = 0; int i, j, len; char *s, *module_name, *class_name; if ((i = marker(self)) == -1) return NULL; if ((j = PyList_Size(self->stack)) == -1) goto err; UNLESS(arg_slice = PyList_GetSlice(self->stack, i, j)) goto err; UNLESS(arg_tup = PySequence_Tuple(arg_slice)) goto err; if (DEL_LIST_SLICE(self->stack, i, j) == -1) goto err; if ((*self->readline_func)(self, &s) == -1) goto err; module_name = s; if ((*self->readline_func)(self, &s) == -1) { free(module_name); goto err; } class_name = s; UNLESS(class = find_class(module_name, class_name)) { free(module_name); free(class_name); goto err; } free(module_name); free(class_name); UNLESS(obj = PyInstance_New(class, arg_tup, NULL)) goto err; if (PyList_Append(self->stack, obj) == -1) goto err; Py_DECREF(arg_slice); Py_DECREF(arg_tup); Py_DECREF(class); Py_DECREF(obj); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(arg_slice); Py_XDECREF(arg_tup); Py_XDECREF(class); Py_XDECREF(obj); return NULL; } static PyObject * load_class(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *class = 0; char *s, *module_name, *class_name; if ((*self->readline_func)(self, &s) == -1) return NULL; module_name = s; if ((*self->readline_func)(self, &s) == -1) { free(module_name); return NULL; } class_name = s; UNLESS(class = find_class(module_name, class_name)) { free(module_name); free(class_name); return NULL; } free(module_name); free(class_name); if (PyList_Append(self->stack, class) == -1) goto err; Py_DECREF(class); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(class); return NULL; } static PyObject * load_persid(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *pid = 0, *pers_load_val = 0; char *s; int len; if (self->pers_func) { if ((len = (*self->readline_func)(self, &s)) == -1) return NULL; UNLESS(pid = PyString_FromStringAndSize(s, len)) { free(s); return NULL; } free(s); UNLESS(self->arg) UNLESS(self->arg = PyTuple_New(1)) goto err; if (PyTuple_SetItem(self->arg, 0, pid) == -1) goto err; Py_INCREF(pid); UNLESS(pers_load_val = PyObject_CallObject(self->pers_func, self->arg)) goto err; if (PyList_Append(self->stack, pers_load_val) == -1) goto err; Py_DECREF(pid); Py_DECREF(pers_load_val); Py_INCREF(Py_None); return Py_None; } Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(pid); Py_XDECREF(pers_load_val); return NULL; } static PyObject * load_pop(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { int len; if ((len = PyList_Size(self->stack)) == -1) return NULL; if (DEL_LIST_SLICE(self->stack, len - 1, len) == -1) return NULL; Py_INCREF(Py_None); return Py_None; } static PyObject * load_dup(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *last; int len; if ((len = PyList_Size(self->stack)) == -1) return NULL; UNLESS(last = PyList_GetItem(self->stack, len - 1)) return NULL; if (PyList_Append(self->stack, last) == -1) return NULL; Py_INCREF(Py_None); return Py_None; } static PyObject * load_get(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_str = 0, *value = 0; char *s; int len; if ((len = (*self->readline_func)(self, &s)) == -1) return NULL; UNLESS(py_str = PyString_FromStringAndSize(s, len)) { free(s); return NULL; } free(s); UNLESS(value = PyDict_GetItem(self->memo, py_str)) goto err; if (PyList_Append(self->stack, value) == -1) goto err; Py_DECREF(py_str); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(py_str); return NULL; } static PyObject * load_binget(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_key = 0, *value = 0; char *s; unsigned char key; UNLESS(s = (char *)malloc(sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } if ((*self->read_func)(self, &s, 1) == -1) { free(s); return NULL; } key = (unsigned char)s[0]; free(s); UNLESS(py_key = PyInt_FromLong((long)key)) return NULL; UNLESS(value = PyDict_GetItem(self->memo, py_key)) goto err; if (PyList_Append(self->stack, value) == -1) return NULL; Py_DECREF(py_key); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(py_key); return NULL; } static PyObject * load_put(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_str = 0, *value = 0; int len; char *s; if ((len = (*self->readline_func)(self, &s)) == -1) return NULL; UNLESS(py_str = PyString_FromStringAndSize(s, len)) { free(s); return NULL; } free(s); if ((len = PyList_Size(self->stack)) == -1) goto err; UNLESS(value = PyList_GetItem(self->stack, len - 1)) goto err; if (PyDict_SetItem(self->memo, py_str, value) == -1) goto err; Py_DECREF(py_str); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(py_str); return NULL; } static PyObject * load_binput(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *py_key = 0, *value = 0; char *s; unsigned char key; int len; UNLESS(s = (char *)malloc(sizeof(char))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } if ((*self->read_func)(self, &s, 1) == -1) return NULL; key = (unsigned char)s[0]; free(s); UNLESS(py_key = PyInt_FromLong((long)key)) return NULL; if ((len = PyList_Size(self->stack)) == -1) goto err; UNLESS(value = PyList_GetItem(self->stack, len - 1)) goto err; if (PyDict_SetItem(self->memo, py_key, value) == -1) goto err; Py_DECREF(py_key); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(py_key); return NULL; } static PyObject * load_append(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *value = 0, *list = 0; int len; static PyObject *append_str = 0; UNLESS(append_str) UNLESS(append_str = PyString_FromString("append")) return NULL; if ((len = PyList_Size(self->stack)) == -1) return NULL; UNLESS(value = PyList_GetItem(self->stack, len - 1)) return NULL; Py_INCREF(value); if (DEL_LIST_SLICE(self->stack, len - 1, len) == -1) goto err; UNLESS(list = PyList_GetItem(self->stack, len - 2)) goto err; if (PyList_Check(list)) { if (PyList_Append(list, value) == -1) goto err; } else { PyObject *append_method, *junk; UNLESS(append_method = PyObject_GetAttr(list, append_str)) return NULL; UNLESS(self->arg) UNLESS(self->arg = PyTuple_New(1)) { Py_DECREF(append_method); goto err; } if (PyTuple_SetItem(self->arg, 0, value) == -1) { Py_DECREF(append_method); goto err; } Py_INCREF(value); UNLESS(junk = PyObject_CallObject(append_method, self->arg)) { Py_DECREF(append_method); goto err; } Py_DECREF(junk); Py_DECREF(append_method); } Py_DECREF(value); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(value); return NULL; } static PyObject * load_setitem(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *value = 0, *key = 0, *dict = 0; int len; if ((len = PyList_Size(self->stack)) == -1) return NULL; UNLESS(value = PyList_GetItem(self->stack, len - 1)) return NULL; Py_INCREF(value); UNLESS(key = PyList_GetItem(self->stack, len - 2)) goto err; Py_INCREF(key); if (DEL_LIST_SLICE(self->stack, len - 2, len) == -1) goto err; UNLESS(dict = PyList_GetItem(self->stack, len - 3)) goto err; if (PyObject_SetItem(dict, key, value) == -1) goto err; Py_DECREF(value); Py_DECREF(key); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(value); Py_XDECREF(key); return NULL; } static PyObject * load_build(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *value = 0, *inst = 0, *instdict = 0, *d_key = 0, *d_value = 0, *junk = 0; static PyObject *py_string__dict__; int len, i; UNLESS(py_string__dict__) UNLESS(py_string__dict__ = PyString_FromString("__dict__")) return NULL; if ((len = PyList_Size(self->stack)) == -1) goto err; UNLESS(value = PyList_GetItem(self->stack, len - 1)) goto err; Py_INCREF(value); if (DEL_LIST_SLICE(self->stack, len - 1, len) == -1) goto err; UNLESS(inst = PyList_GetItem(self->stack, len - 2)) goto err; UNLESS(PyObject_HasAttrString(inst, "__setstate__")) { UNLESS(instdict = PyObject_GetAttr(inst, py_string__dict__)) goto err; i = 0; while (PyDict_Next(value, &i, &d_key, &d_value)) { if (PyObject_SetItem(instdict, d_key, d_value) == -1) goto err; } } else { UNLESS(junk = PyObject_CallMethod(inst, "__setstate__", "O", value)) goto err; Py_DECREF(junk); } Py_DECREF(value); Py_XDECREF(instdict); Py_INCREF(Py_None); return Py_None; err: Py_XDECREF(value); Py_XDECREF(instdict); return NULL; } static PyObject * load_mark(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { int len; if ((len = PyList_Size(self->stack)) == -1) return NULL; if (!self->num_marks) { UNLESS(self->marks = (int *)malloc(20 * sizeof(int))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } self->marks_size = 20; } else if ((self->num_marks + 1) > self->marks_size) { UNLESS(self->marks = (int *)realloc(self->marks, (self->marks_size + 20) * sizeof(int))) { PyErr_SetString(PyExc_MemoryError, "out of memory"); return NULL; } self->marks_size += 20; } self->marks[self->num_marks++] = len; Py_INCREF(Py_None); return Py_None; } static PyObject * load_eof(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyErr_SetNone(PyExc_EOFError); return NULL; } static PyObject * Unpickler_load(ARG(Unpicklerobject *, self), ARG(PyObject *, args)) ARGDECL(Unpicklerobject *, self) ARGDECL(PyObject *, args) { PyObject *stack = 0, *key = 0, *junk = 0, *err = 0, *exc = 0, *val = 0, *tb = 0, *str = 0, *key_repr = 0; char c; char *c_str; int len; c_str=&c; UNLESS(stack = PyList_New(0)) goto err; self->stack = stack; self->num_marks = 0; while (1) { if ((*self->read_func)(self, &c_str, 1) == -1) break; switch (c_str[0]) { case NONE: UNLESS(junk = load_none(self, NULL)) break; continue; case BININT: UNLESS(junk = load_binint(self, NULL)) break; continue; case BININT1: UNLESS(junk = load_binint1(self, NULL)) break; continue; case BININT2: UNLESS(junk = load_binint2(self, NULL)) break; continue; case BININT3: UNLESS(junk = load_binint3(self, NULL)) break; continue; case INT: UNLESS(junk = load_int(self, NULL)) break; continue; case LONG: UNLESS(junk = load_long(self, NULL)) break; continue; case FLOAT: UNLESS(junk = load_float(self, NULL)) break; continue; case BINSTRING: UNLESS(junk = load_binstring(self, NULL)) break; continue; case SHORT_BINSTRING: UNLESS(junk = load_short_binstring(self, NULL)) break; continue; case STRING: UNLESS(junk = load_string(self, NULL)) break; Py_DECREF(junk); continue; case TUPLE: UNLESS(junk = load_tuple(self, NULL)) break; Py_DECREF(junk); continue; case LIST: UNLESS(junk = load_list(self, NULL)) break; Py_DECREF(junk); continue; case DICT: UNLESS(junk = load_dict(self, NULL)) break; Py_DECREF(junk); continue; case OBJ: UNLESS(junk = load_obj(self, NULL)) break; Py_DECREF(junk); continue; case INST: UNLESS(junk = load_inst(self, NULL)) break; Py_DECREF(junk); continue; case CLASS: UNLESS(junk = load_class(self, NULL)) break; Py_DECREF(junk); continue; case APPEND: UNLESS(junk = load_append(self, NULL)) break; Py_DECREF(junk); continue; case BUILD: UNLESS(junk = load_build(self, NULL)) break; Py_DECREF(junk); continue; case DUP: UNLESS(junk = load_dup(self, NULL)) break; Py_DECREF(junk); continue; case BINGET: UNLESS(junk = load_binget(self, NULL)) break; Py_DECREF(junk); continue; case GET: UNLESS(junk = load_get(self, NULL)) break; Py_DECREF(junk); continue; case MARK: UNLESS(junk = load_mark(self, NULL)) break; Py_DECREF(junk); continue; case BINPUT: UNLESS(junk = load_binput(self, NULL)) break; Py_DECREF(junk); continue; case PUT: UNLESS(junk = load_put(self, NULL)) break; Py_DECREF(junk); continue; case POP: UNLESS(junk = load_pop(self, NULL)) break; Py_DECREF(junk); continue; case SETITEM: UNLESS(junk = load_setitem(self, NULL)) break; Py_DECREF(junk); continue; case STOP: break; case PERSID: UNLESS(junk = load_persid(self, NULL)) break; Py_DECREF(junk); continue; default: UNLESS(key = PyString_FromStringAndSize(c_str, 1)) return NULL; UNLESS(key_repr = PyObject_Repr(key)) return NULL; UNLESS(str = PyString_FromStringAndSize(NULL, 19 + PyString_Size(key_repr))) return NULL; sprintf(PyString_AS_STRING((PyStringObject *)str), "invalid load key, \%s\.", PyString_AS_STRING((PyStringObject *)key_repr)); PyErr_SetObject(UnpicklingError, str); Py_DECREF(str); Py_DECREF(key); Py_DECREF(key_repr); return NULL; } break; } if ((err = PyErr_Occurred()) == PyExc_EOFError) { return load_eof(self, NULL); } if (err) return NULL; if ((len = PyList_Size(self->stack)) == -1) return NULL; UNLESS(val = PyList_GetItem(self->stack, len - 1)) return NULL; Py_INCREF(val); if (DEL_LIST_SLICE(self->stack, len - 1, len) == -1) { Py_DECREF(val); return NULL; } return val; err: Py_XDECREF(stack); return NULL; } static struct PyMethodDef Unpickler_methods[] = { {"load", (PyCFunction)Unpickler_load, 0, ""}, {"load_none", (PyCFunction)load_none, 0, ""}, {"load_int", (PyCFunction)load_int, 0, ""}, {"load_long", (PyCFunction)load_long, 0, ""}, {"load_float", (PyCFunction)load_float, 0, ""}, {"load_string", (PyCFunction)load_string, 0, ""}, {"load_tuple", (PyCFunction)load_tuple, 0, ""}, {"load_list", (PyCFunction)load_list, 0, ""}, {"load_dict", (PyCFunction)load_dict, 0, ""}, {"load_inst", (PyCFunction)load_inst, 0, ""}, {"load_class", (PyCFunction)load_class, 0, ""}, {"load_persid", (PyCFunction)load_persid, 0, ""}, {"load_pop", (PyCFunction)load_pop, 0, ""}, {"load_dup", (PyCFunction)load_dup, 0, ""}, {"load_get", (PyCFunction)load_get, 0, ""}, {"load_put", (PyCFunction)load_put, 0, ""}, {"load_append", (PyCFunction)load_append, 0, ""}, {"load_setitem", (PyCFunction)load_setitem, 0, ""}, {"load_build", (PyCFunction)load_build, 0, ""}, {"load_mark", (PyCFunction)load_mark, 0, ""}, {"load_eof", (PyCFunction)load_eof, 0, ""}, {NULL, NULL} /* sentinel */ }; static Unpicklerobject * newUnpicklerobject(ARG(PyObject *, f)) ARGDECL(PyObject *, f) { Unpicklerobject *self; PyObject *memo = 0; UNLESS(memo = PyDict_New()) goto err; UNLESS(self = PyObject_NEW(Unpicklerobject, &Unpicklertype)) goto err; if (PyFile_Check(f)) { self->fp = PyFile_AsFile(f); self->read_func = read_file; self->readline_func = readline_file; self->read = NULL; self->readline = NULL; } else if (PycStringIO_InputCheck(f)) { self->fp = NULL; self->read_func = read_cStringIO; self->readline_func = readline_cStringIO; self->read = NULL; self->readline = NULL; } else { PyObject *readline, *read; self->fp = NULL; self->read_func = read_other; self->readline_func = readline_other; UNLESS(readline = PyObject_GetAttrString(f, "readline")) goto err; UNLESS(read = PyObject_GetAttrString(f, "read")) { Py_DECREF(readline); goto err; } self->read = read; self->readline = readline; } Py_INCREF(f); self->file = f; self->memo = memo; self->arg = NULL; self->stack = NULL; self->pers_func = NULL; self->marks = NULL; self->num_marks = 0; self->marks_size = 0; return self; err: Py_XDECREF(memo); Py_XDECREF((PyObject *)self); return NULL; } static PyObject * get_Unpickler(ARG(PyObject *, self), ARG(PyObject *, args)) ARGDECL(PyObject *, self) ARGDECL(PyObject *, args) { PyObject *file; UNLESS(PyArg_Parse(args, "O", &file)) return NULL; return (PyObject *)newUnpicklerobject(file); } static void Unpickler_dealloc(ARG(Unpicklerobject *, self)) ARGDECL(Unpicklerobject *, self) { Py_XDECREF(self->readline); Py_XDECREF(self->read); Py_XDECREF(self->file); Py_XDECREF(self->memo); Py_XDECREF(self->stack); Py_XDECREF(self->pers_func); Py_XDECREF(self->arg); free(self->marks); PyMem_DEL(self); } static PyObject * Unpickler_getattr(ARG(Unpicklerobject *, self), ARG(char *, name)) ARGDECL(Unpicklerobject *, self) ARGDECL(char *, name) { if (!strcmp(name, "persistent_load")) { if (!self->pers_func) { PyErr_SetString(PyExc_NameError, name); return NULL; } Py_INCREF(self->pers_func); return self->pers_func; } if (!strcmp(name, "memo")) { if (!self->memo) { PyErr_SetString(PyExc_NameError, name); return NULL; } Py_INCREF(self->memo); return self->memo; } if (!strcmp(name, "UnpicklingError")) { Py_INCREF(UnpicklingError); return UnpicklingError; } return Py_FindMethod(Unpickler_methods, (PyObject *)self, name); } static int Unpickler_setattr(ARG(Unpicklerobject *, self), ARG(char *, name), ARG(PyObject *, value)) ARGDECL(Unpicklerobject *, self) ARGDECL(char *, name) ARGDECL(PyObject *, value) { if (!strcmp(name, "persistent_load")) { Py_XDECREF(self->pers_func); self->pers_func = value; Py_INCREF(value); return 0; } return -1; } static PyObject * dump(ARG(PyObject *, self), ARG(PyObject *, args)) ARGDECL(PyObject *, self) ARGDECL(PyObject *, args) { PyObject *ob, *file, *ret_val; Picklerobject *pickler; int bin = 0; UNLESS(PyArg_ParseTuple(args, "OO|i", &ob, &file, &bin)) return NULL; UNLESS(pickler = newPicklerobject(file, bin)) return NULL; UNLESS(ret_val = Pickler_dump(pickler, ob)) { Pickler_dealloc(pickler); return NULL; } Pickler_dealloc(pickler); return ret_val; } static PyObject * dumps(ARG(PyObject *, self), ARG(PyObject *, args)) ARGDECL(PyObject *, self) ARGDECL(PyObject *, args) { PyObject *ob, *file, *pickle_str; Picklerobject *pickler; int bin = 0; UNLESS(PyArg_ParseTuple(args, "O|i", &ob, &bin)) return NULL; UNLESS(file = (*PycStringIO_NewOutput)(128)) return NULL; UNLESS(pickler = newPicklerobject(file, bin)) { Py_DECREF(file); return NULL; } UNLESS(Pickler_dump(pickler, ob)) { Pickler_dealloc(pickler); Py_DECREF(file); return NULL; } Pickler_dealloc(pickler); UNLESS(pickle_str = (*PycStringIO_cgetvalue)((PyObject *)file)) { Py_DECREF(file); return NULL; } Py_DECREF(file); return pickle_str; } static PyObject * cpm_load(ARG(PyObject *, self), ARG(PyObject *, args)) ARGDECL(PyObject *, self) ARGDECL(PyObject *, args) { Unpicklerobject *unpickler; PyObject *load_result; UNLESS(PyArg_Parse(args, "O", &args)) return NULL; UNLESS(unpickler = newUnpicklerobject(args)) return NULL; UNLESS(load_result = Unpickler_load(unpickler, NULL)) { Unpickler_dealloc(unpickler); return NULL; } Py_DECREF(unpickler); return load_result; } static PyObject * loads(ARG(PyObject *, self), ARG(PyObject *, args)) ARGDECL(PyObject *, self) ARGDECL(PyObject *, args) { PyObject *file, *load_result; Unpicklerobject *unpickler; UNLESS(PyArg_Parse(args, "O", &args)) return NULL; UNLESS(file = (*PycStringIO_NewInput)(args)) return NULL; UNLESS(unpickler = newUnpicklerobject(file)) { Py_DECREF(file); return NULL; } UNLESS(load_result = Unpickler_load(unpickler, NULL)) { Unpickler_dealloc(unpickler); Py_DECREF(file); return NULL; } Py_DECREF(file); Unpickler_dealloc(unpickler); return load_result; } static char Unpicklertype__doc__[] = ""; static PyTypeObject Unpicklertype = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "Unpickler", /*tp_name*/ sizeof(Unpicklerobject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)Unpickler_dealloc, /*tp_dealloc*/ (printfunc)0, /*tp_print*/ (getattrfunc)Unpickler_getattr, /*tp_getattr*/ (setattrfunc)Unpickler_setattr, /*tp_setattr*/ (cmpfunc)0, /*tp_compare*/ (reprfunc)0, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ (hashfunc)0, /*tp_hash*/ (ternaryfunc)0, /*tp_call*/ (reprfunc)0, /*tp_str*/ /* Space for future expansion */ 0L,0L,0L,0L, Unpicklertype__doc__ /* Documentation string */ }; static struct PyMethodDef cPickle_methods[] = { {"dump", (PyCFunction)dump, 1, ""}, {"dumps", (PyCFunction)dumps, 1, ""}, {"load", (PyCFunction)cpm_load, 0, ""}, {"loads", (PyCFunction)loads, 0, ""}, {"Pickler", (PyCFunction)get_Pickler, 1, ""}, {"Unpickler", (PyCFunction)get_Unpickler, 0, ""}, { NULL, NULL } }; static int init_stuff() { PyObject *builtins, *apply_func, *string; UNLESS(builtins = PyImport_ImportModule("__builtin__")) return NULL; UNLESS(apply_func = PyObject_GetAttrString(builtins, "apply")) return NULL; BuiltinFunctionType = apply_func->ob_type; Py_DECREF(apply_func); Py_DECREF(builtins); UNLESS(string = PyImport_ImportModule("string")) return NULL; UNLESS(atol_func = PyObject_GetAttrString(string, "atol")) return NULL; Py_DECREF(string); UNLESS(empty_list = PyList_New(0)) return NULL; UNLESS(empty_tuple = PyTuple_New(0)) return NULL; UNLESS(class_map = PyDict_New()) return NULL; UNLESS(PicklingError = PyString_FromString("cPickle.PicklingError")) return NULL; UNLESS(UnpicklingError = PyString_FromString("cPickle.UnpicklingError")) return NULL; PycString_IMPORT; } #define CHECK_FOR_ERRORS(MESS) \ if(PyErr_Occurred()) { \ PyObject *__sys_exc_type, *__sys_exc_value, *__sys_exc_traceback; \ PyErr_Fetch( &__sys_exc_type, &__sys_exc_value, &__sys_exc_traceback); \ fprintf(stderr, # MESS ":\n\t"); \ PyObject_Print(__sys_exc_type, stderr,0); \ fprintf(stderr,", "); \ PyObject_Print(__sys_exc_value, stderr,0); \ fprintf(stderr,"\n"); \ fflush(stderr); \ Py_FatalError(# MESS); \ } /* Initialization function for the module (*must* be called initcPickle) */ void initcPickle() { PyObject *m, *d; /* Create the module and add the functions */ m = Py_InitModule4("cPickle", cPickle_methods, cPickle_module_documentation, (PyObject*)NULL,PYTHON_API_VERSION); /* Add some symbolic constants to the module */ d = PyModule_GetDict(m); ErrorObject = PyString_FromString("cPickle.error"); PyDict_SetItemString(d, "error", ErrorObject); /* XXXX Add constants here */ init_stuff(); CHECK_FOR_ERRORS("can't initialize module cPickle"); PyDict_SetItemString(d, "PicklingError", PicklingError); CHECK_FOR_ERRORS("can't initialize module cPickle: error creating PicklingError"); PyDict_SetItemString(d, "UnpicklingError", UnpicklingError); CHECK_FOR_ERRORS("can't initialize module cPickle: error creating UnpicklingError"); }