📄 cpickle.c
字号:
}
PyErr_SetFromErrno(PyExc_IOError);
return -1;
}
*s = self->buf;
return n;
}
static int
readline_file(Unpicklerobject *self, char **s) {
int i;
if (self->buf_size == 0) {
UNLESS (self->buf = (char *)malloc(40 * sizeof(char))) {
PyErr_NoMemory();
return -1;
}
self->buf_size = 40;
}
i = 0;
while (1) {
for (; i < (self->buf_size - 1); i++) {
if (feof(self->fp) || (self->buf[i] = getc(self->fp)) == '\n') {
self->buf[i + 1] = '\0';
*s = self->buf;
return i + 1;
}
}
UNLESS (self->buf = (char *)realloc(self->buf,
(self->buf_size * 2) * sizeof(char))) {
PyErr_NoMemory();
return -1;
}
self->buf_size *= 2;
}
}
static int
read_cStringIO(Unpicklerobject *self, char **s, int n) {
char *ptr;
if (PycStringIO->cread((PyObject *)self->file, &ptr, n) != n) {
PyErr_SetNone(PyExc_EOFError);
return -1;
}
*s = ptr;
return n;
}
static int
readline_cStringIO(Unpicklerobject *self, char **s) {
int n;
char *ptr;
if ((n = PycStringIO->creadline((PyObject *)self->file, &ptr)) < 0) {
return -1;
}
*s = ptr;
return n;
}
static int
read_other(Unpicklerobject *self, char **s, int n) {
PyObject *bytes, *str=0;
UNLESS (bytes = PyInt_FromLong(n)) return -1;
ARG_TUP(self, bytes);
if (self->arg) {
str = PyObject_Call(self->read, self->arg, NULL);
FREE_ARG_TUP(self);
}
if (! str) return -1;
Py_XDECREF(self->last_string);
self->last_string = str;
if (! (*s = PyString_AsString(str))) return -1;
return n;
}
static int
readline_other(Unpicklerobject *self, char **s) {
PyObject *str;
int str_size;
UNLESS (str = PyObject_CallObject(self->readline, empty_tuple)) {
return -1;
}
if ((str_size = PyString_Size(str)) < 0)
return -1;
Py_XDECREF(self->last_string);
self->last_string = str;
if (! (*s = PyString_AsString(str)))
return -1;
return str_size;
}
static char *
pystrndup(char *s, int l) {
char *r;
UNLESS (r=malloc((l+1)*sizeof(char))) return (char*)PyErr_NoMemory();
memcpy(r,s,l);
r[l]=0;
return r;
}
static int
get(Picklerobject *self, PyObject *id) {
PyObject *value, *mv;
long c_value;
char s[30];
size_t len;
UNLESS (mv = PyDict_GetItem(self->memo, id)) {
PyErr_SetObject(PyExc_KeyError, id);
return -1;
}
UNLESS (value = PyTuple_GetItem(mv, 0))
return -1;
UNLESS (PyInt_Check(value)) {
PyErr_SetString(PicklingError, "no int where int expected in memo");
return -1;
}
c_value = PyInt_AS_LONG((PyIntObject*)value);
if (!self->bin) {
s[0] = GET;
PyOS_snprintf(s + 1, sizeof(s) - 1, "%ld\n", c_value);
len = strlen(s);
}
else if (Pdata_Check(self->file)) {
if (write_other(self, NULL, 0) < 0) return -1;
PDATA_APPEND(self->file, mv, -1);
return 0;
}
else {
if (c_value < 256) {
s[0] = BINGET;
s[1] = (int)(c_value & 0xff);
len = 2;
}
else {
s[0] = LONG_BINGET;
s[1] = (int)(c_value & 0xff);
s[2] = (int)((c_value >> 8) & 0xff);
s[3] = (int)((c_value >> 16) & 0xff);
s[4] = (int)((c_value >> 24) & 0xff);
len = 5;
}
}
if ((*self->write_func)(self, s, len) < 0)
return -1;
return 0;
}
static int
put(Picklerobject *self, PyObject *ob) {
if (ob->ob_refcnt < 2 || self->fast)
return 0;
return put2(self, ob);
}
static int
put2(Picklerobject *self, PyObject *ob) {
char c_str[30];
int p;
size_t len;
int res = -1;
PyObject *py_ob_id = 0, *memo_len = 0, *t = 0;
if (self->fast)
return 0;
if ((p = PyDict_Size(self->memo)) < 0)
goto finally;
p++; /* Make sure memo keys are positive! */
UNLESS (py_ob_id = PyLong_FromVoidPtr(ob))
goto finally;
UNLESS (memo_len = PyInt_FromLong(p))
goto finally;
UNLESS (t = PyTuple_New(2))
goto finally;
PyTuple_SET_ITEM(t, 0, memo_len);
Py_INCREF(memo_len);
PyTuple_SET_ITEM(t, 1, ob);
Py_INCREF(ob);
if (PyDict_SetItem(self->memo, py_ob_id, t) < 0)
goto finally;
if (!self->bin) {
c_str[0] = PUT;
PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%d\n", p);
len = strlen(c_str);
}
else if (Pdata_Check(self->file)) {
if (write_other(self, NULL, 0) < 0) return -1;
PDATA_APPEND(self->file, memo_len, -1);
res=0; /* Job well done ;) */
goto finally;
}
else {
if (p >= 256) {
c_str[0] = LONG_BINPUT;
c_str[1] = (int)(p & 0xff);
c_str[2] = (int)((p >> 8) & 0xff);
c_str[3] = (int)((p >> 16) & 0xff);
c_str[4] = (int)((p >> 24) & 0xff);
len = 5;
}
else {
c_str[0] = BINPUT;
c_str[1] = p;
len = 2;
}
}
if ((*self->write_func)(self, c_str, len) < 0)
goto finally;
res = 0;
finally:
Py_XDECREF(py_ob_id);
Py_XDECREF(memo_len);
Py_XDECREF(t);
return res;
}
#define PyImport_Import cPickle_Import
static PyObject *
PyImport_Import(PyObject *module_name) {
static PyObject *silly_list=0, *__builtins___str=0, *__import___str;
static PyObject *standard_builtins=0;
PyObject *globals=0, *__import__=0, *__builtins__=0, *r=0;
UNLESS (silly_list) {
UNLESS (__import___str=PyString_FromString("__import__"))
return NULL;
UNLESS (__builtins___str=PyString_FromString("__builtins__"))
return NULL;
UNLESS (silly_list=Py_BuildValue("[s]","__doc__"))
return NULL;
}
if ((globals=PyEval_GetGlobals())) {
Py_INCREF(globals);
UNLESS (__builtins__=PyObject_GetItem(globals,__builtins___str))
goto err;
}
else {
PyErr_Clear();
UNLESS (standard_builtins ||
(standard_builtins=PyImport_ImportModule("__builtin__")))
return NULL;
__builtins__=standard_builtins;
Py_INCREF(__builtins__);
UNLESS (globals = Py_BuildValue("{sO}", "__builtins__", __builtins__))
goto err;
}
if (PyDict_Check(__builtins__)) {
UNLESS (__import__=PyObject_GetItem(__builtins__,__import___str)) goto err;
}
else {
UNLESS (__import__=PyObject_GetAttr(__builtins__,__import___str)) goto err;
}
UNLESS (r=PyObject_CallFunction(__import__,"OOOO",
module_name, globals, globals, silly_list))
goto err;
Py_DECREF(globals);
Py_DECREF(__builtins__);
Py_DECREF(__import__);
return r;
err:
Py_XDECREF(globals);
Py_XDECREF(__builtins__);
Py_XDECREF(__import__);
return NULL;
}
static PyObject *
whichmodule(PyObject *global, PyObject *global_name) {
int i, j;
PyObject *module = 0, *modules_dict = 0,
*global_name_attr = 0, *name = 0;
module = PyObject_GetAttrString(global, "__module__");
if (module) return module;
PyErr_Clear();
UNLESS (modules_dict = PySys_GetObject("modules"))
return NULL;
i = 0;
while ((j = PyDict_Next(modules_dict, &i, &name, &module))) {
if (PyObject_Compare(name, __main___str)==0) continue;
UNLESS (global_name_attr = PyObject_GetAttr(module, global_name)) {
PyErr_Clear();
continue;
}
if (global_name_attr != global) {
Py_DECREF(global_name_attr);
continue;
}
Py_DECREF(global_name_attr);
break;
}
/* The following implements the rule in pickle.py added in 1.5
that used __main__ if no module is found. I don't actually
like this rule. jlf
*/
if (!j) {
j=1;
name=__main___str;
}
Py_INCREF(name);
return name;
}
static int
fast_save_enter(Picklerobject *self, PyObject *obj)
{
/* if fast_container < 0, we're doing an error exit. */
if (++self->fast_container >= PY_CPICKLE_FAST_LIMIT) {
PyObject *key = NULL;
if (self->fast_memo == NULL) {
self->fast_memo = PyDict_New();
if (self->fast_memo == NULL) {
self->fast_container = -1;
return 0;
}
}
key = PyLong_FromVoidPtr(obj);
if (key == NULL)
return 0;
if (PyDict_GetItem(self->fast_memo, key)) {
PyErr_Format(PyExc_ValueError,
"fast mode: can't pickle cyclic objects including object type %s at %p",
obj->ob_type->tp_name, obj);
self->fast_container = -1;
return 0;
}
if (PyDict_SetItem(self->fast_memo, key, Py_None) < 0) {
self->fast_container = -1;
return 0;
}
}
return 1;
}
int
fast_save_leave(Picklerobject *self, PyObject *obj)
{
if (self->fast_container-- >= PY_CPICKLE_FAST_LIMIT) {
PyObject *key = PyLong_FromVoidPtr(obj);
if (key == NULL)
return 0;
if (PyDict_DelItem(self->fast_memo, key) < 0) {
return 0;
}
}
return 1;
}
static int
save_none(Picklerobject *self, PyObject *args) {
static char none = NONE;
if ((*self->write_func)(self, &none, 1) < 0)
return -1;
return 0;
}
static int
save_int(Picklerobject *self, PyObject *args) {
char c_str[32];
long l = PyInt_AS_LONG((PyIntObject *)args);
int len = 0;
if (!self->bin
#if SIZEOF_LONG > 4
|| l > 0x7fffffffL
|| l < -0x80000000L
#endif
) {
/* Text-mode pickle, or long too big to fit in the 4-byte
* signed BININT format: store as a string.
*/
c_str[0] = INT;
PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%ld\n", l);
if ((*self->write_func)(self, c_str, strlen(c_str)) < 0)
return -1;
}
else {
/* Binary pickle and l fits in a signed 4-byte int. */
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] == 0) && (c_str[3] == 0)) {
if (c_str[2] == 0) {
c_str[0] = BININT1;
len = 2;
}
else {
c_str[0] = BININT2;
len = 3;
}
}
else {
c_str[0] = BININT;
len = 5;
}
if ((*self->write_func)(self, c_str, len) < 0)
return -1;
}
return 0;
}
static int
save_long(Picklerobject *self, PyObject *args) {
int size, res = -1;
PyObject *repr = 0;
static char l = LONG;
UNLESS (repr = PyObject_Repr(args))
goto finally;
if ((size = PyString_Size(repr)) < 0)
goto finally;
if ((*self->write_func)(self, &l, 1) < 0)
goto finally;
if ((*self->write_func)(self,
PyString_AS_STRING((PyStringObject *)repr), size) < 0)
goto finally;
if ((*self->write_func)(self, "\n", 1) < 0)
goto finally;
res = 0;
finally:
Py_XDECREF(repr);
return res;
}
static int
save_float(Picklerobject *self, PyObject *args) {
double x = PyFloat_AS_DOUBLE((PyFloatObject *)args);
if (self->bin) {
int s, e;
double f;
long fhi, flo;
char str[9];
unsigned char *p = (unsigned char *)str;
*p = BINFLOAT;
p++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -