summaryrefslogtreecommitdiffstats
path: root/Modules/cPickle.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1997-01-06 22:59:08 (GMT)
committerGuido van Rossum <guido@python.org>1997-01-06 22:59:08 (GMT)
commit2f4caa4c4897d0d760d5469835eec16dd285f8bb (patch)
tree27ae8d023e70dc2062762e2bdd4a5b84f1ae751a /Modules/cPickle.c
parent55702f8d6a4dd4d6422ddac7259ebb00dfcb108a (diff)
downloadcpython-2f4caa4c4897d0d760d5469835eec16dd285f8bb.zip
cpython-2f4caa4c4897d0d760d5469835eec16dd285f8bb.tar.gz
cpython-2f4caa4c4897d0d760d5469835eec16dd285f8bb.tar.bz2
cPickle, version 0.1.
Diffstat (limited to 'Modules/cPickle.c')
-rw-r--r--Modules/cPickle.c3767
1 files changed, 3767 insertions, 0 deletions
diff --git a/Modules/cPickle.c b/Modules/cPickle.c
new file mode 100644
index 0000000..f342051
--- /dev/null
+++ b/Modules/cPickle.c
@@ -0,0 +1,3767 @@
+/*
+ $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 <errno.h>
+
+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");
+}