cpickle.c
来自「python s60 1.4.5版本的源代码」· C语言 代码 · 共 2,601 行 · 第 1/5 页
C
2,601 行
if (x < 0) {
s = 1;
x = -x;
}
else
s = 0;
f = frexp(x, &e);
/* Normalize f to be in the range [1.0, 2.0) */
if (0.5 <= f && f < 1.0) {
f *= 2.0;
e--;
}
else if (f == 0.0) {
e = 0;
}
else {
PyErr_SetString(PyExc_SystemError,
"frexp() result out of range");
return -1;
}
if (e >= 1024) {
/* XXX 1024 itself is reserved for Inf/NaN */
PyErr_SetString(PyExc_OverflowError,
"float too large to pack with d format");
return -1;
}
else if (e < -1022) {
/* Gradual underflow */
f = ldexp(f, 1022 + e);
e = 0;
}
else if (!(e == 0 && f == 0.0)) {
e += 1023;
f -= 1.0; /* Get rid of leading 1 */
}
/* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
f *= 268435456.0; /* 2**28 */
fhi = (long) floor(f); /* Truncate */
f -= (double)fhi;
f *= 16777216.0; /* 2**24 */
flo = (long) floor(f + 0.5); /* Round */
/* First byte */
*p = (s<<7) | (e>>4);
p++;
/* Second byte */
*p = (unsigned char) (((e&0xF)<<4) | (fhi>>24));
p++;
/* Third byte */
*p = (unsigned char) ((fhi>>16) & 0xFF);
p++;
/* Fourth byte */
*p = (unsigned char) ((fhi>>8) & 0xFF);
p++;
/* Fifth byte */
*p = (unsigned char) (fhi & 0xFF);
p++;
/* Sixth byte */
*p = (unsigned char) ((flo>>16) & 0xFF);
p++;
/* Seventh byte */
*p = (unsigned char) ((flo>>8) & 0xFF);
p++;
/* Eighth byte */
*p = (unsigned char) (flo & 0xFF);
if ((*self->write_func)(self, str, 9) < 0)
return -1;
}
else {
char c_str[250];
c_str[0] = FLOAT;
PyOS_snprintf(c_str + 1, sizeof(c_str) - 1, "%.17g\n", x);
if ((*self->write_func)(self, c_str, strlen(c_str)) < 0)
return -1;
}
return 0;
}
static int
save_string(Picklerobject *self, PyObject *args, int doput) {
int size, len;
PyObject *repr=0;
if ((size = PyString_Size(args)) < 0)
return -1;
if (!self->bin) {
char *repr_str;
static char string = STRING;
UNLESS (repr = PyObject_Repr(args))
return -1;
if ((len = PyString_Size(repr)) < 0)
goto err;
repr_str = PyString_AS_STRING((PyStringObject *)repr);
if ((*self->write_func)(self, &string, 1) < 0)
goto err;
if ((*self->write_func)(self, repr_str, len) < 0)
goto err;
if ((*self->write_func)(self, "\n", 1) < 0)
goto err;
Py_XDECREF(repr);
}
else {
int i;
char c_str[5];
if ((size = PyString_Size(args)) < 0)
return -1;
if (size < 256) {
c_str[0] = SHORT_BINSTRING;
c_str[1] = size;
len = 2;
}
else {
c_str[0] = BINSTRING;
for (i = 1; i < 5; i++)
c_str[i] = (int)(size >> ((i - 1) * 8));
len = 5;
}
if ((*self->write_func)(self, c_str, len) < 0)
return -1;
if (size > 128 && Pdata_Check(self->file)) {
if (write_other(self, NULL, 0) < 0) return -1;
PDATA_APPEND(self->file, args, -1);
}
else {
if ((*self->write_func)(self,
PyString_AS_STRING((PyStringObject *)args), size) < 0)
return -1;
}
}
if (doput)
if (put(self, args) < 0)
return -1;
return 0;
err:
Py_XDECREF(repr);
return -1;
}
#ifdef Py_USING_UNICODE
/* A copy of PyUnicode_EncodeRawUnicodeEscape() that also translates
backslash and newline characters to \uXXXX escapes. */
static PyObject *
modified_EncodeRawUnicodeEscape(const Py_UNICODE *s, int size)
{
PyObject *repr;
char *p;
char *q;
static const char *hexdigit = "0123456789ABCDEF";
repr = PyString_FromStringAndSize(NULL, 6 * size);
if (repr == NULL)
return NULL;
if (size == 0)
return repr;
p = q = PyString_AS_STRING(repr);
while (size-- > 0) {
Py_UNICODE ch = *s++;
/* Map 16-bit characters to '\uxxxx' */
if (ch >= 256 || ch == '\\' || ch == '\n') {
*p++ = '\\';
*p++ = 'u';
*p++ = hexdigit[(ch >> 12) & 0xf];
*p++ = hexdigit[(ch >> 8) & 0xf];
*p++ = hexdigit[(ch >> 4) & 0xf];
*p++ = hexdigit[ch & 15];
}
/* Copy everything else as-is */
else
*p++ = (char) ch;
}
*p = '\0';
if (_PyString_Resize(&repr, p - q))
goto onError;
return repr;
onError:
Py_DECREF(repr);
return NULL;
}
static int
save_unicode(Picklerobject *self, PyObject *args, int doput) {
int size, len;
PyObject *repr=0;
if (!PyUnicode_Check(args))
return -1;
if (!self->bin) {
char *repr_str;
static char string = UNICODE;
UNLESS(repr = modified_EncodeRawUnicodeEscape(
PyUnicode_AS_UNICODE(args), PyUnicode_GET_SIZE(args)))
return -1;
if ((len = PyString_Size(repr)) < 0)
goto err;
repr_str = PyString_AS_STRING((PyStringObject *)repr);
if ((*self->write_func)(self, &string, 1) < 0)
goto err;
if ((*self->write_func)(self, repr_str, len) < 0)
goto err;
if ((*self->write_func)(self, "\n", 1) < 0)
goto err;
Py_XDECREF(repr);
}
else {
int i;
char c_str[5];
UNLESS (repr = PyUnicode_AsUTF8String(args))
return -1;
if ((size = PyString_Size(repr)) < 0)
goto err;
c_str[0] = BINUNICODE;
for (i = 1; i < 5; i++)
c_str[i] = (int)(size >> ((i - 1) * 8));
len = 5;
if ((*self->write_func)(self, c_str, len) < 0)
goto err;
if (size > 128 && Pdata_Check(self->file)) {
if (write_other(self, NULL, 0) < 0)
goto err;
PDATA_APPEND(self->file, repr, -1);
}
else {
if ((*self->write_func)(self, PyString_AS_STRING(repr), size) < 0)
goto err;
}
Py_DECREF(repr);
}
if (doput)
if (put(self, args) < 0)
return -1;
return 0;
err:
Py_XDECREF(repr);
return -1;
}
#endif
static int
save_tuple(Picklerobject *self, PyObject *args) {
PyObject *element = 0, *py_tuple_id = 0;
int len, i, res = -1;
static char tuple = TUPLE;
if ((*self->write_func)(self, &MARKv, 1) < 0)
goto finally;
if ((len = PyTuple_Size(args)) < 0)
goto finally;
for (i = 0; i < len; i++) {
UNLESS (element = PyTuple_GET_ITEM((PyTupleObject *)args, i))
goto finally;
if (save(self, element, 0) < 0)
goto finally;
}
UNLESS (py_tuple_id = PyLong_FromVoidPtr(args))
goto finally;
if (len) {
if (PyDict_GetItem(self->memo, py_tuple_id)) {
if (self->bin) {
static char pop_mark = POP_MARK;
if ((*self->write_func)(self, &pop_mark, 1) < 0)
goto finally;
}
else {
static char pop = POP;
for (i = 0; i <= len; i++) {
if ((*self->write_func)(self, &pop, 1) < 0)
goto finally;
}
}
if (get(self, py_tuple_id) < 0)
goto finally;
res = 0;
goto finally;
}
}
if ((*self->write_func)(self, &tuple, 1) < 0) {
goto finally;
}
if (put(self, args) < 0)
goto finally;
res = 0;
finally:
Py_XDECREF(py_tuple_id);
return res;
}
static int
save_empty_tuple(Picklerobject *self, PyObject *args) {
static char tuple = EMPTY_TUPLE;
return (*self->write_func)(self, &tuple, 1);
}
static int
save_list(Picklerobject *self, PyObject *args) {
PyObject *element = 0;
int s_len, len, i, using_appends, res = -1;
char s[3];
static char append = APPEND, appends = APPENDS;
if (self->fast && !fast_save_enter(self, args))
goto finally;
if (self->bin) {
s[0] = EMPTY_LIST;
s_len = 1;
}
else {
s[0] = MARK;
s[1] = LIST;
s_len = 2;
}
if ((len = PyList_Size(args)) < 0)
goto finally;
if ((*self->write_func)(self, s, s_len) < 0)
goto finally;
if (len == 0) {
if (put(self, args) < 0)
goto finally;
}
else {
if (put2(self, args) < 0)
goto finally;
}
if ((using_appends = (self->bin && (len > 1))))
if ((*self->write_func)(self, &MARKv, 1) < 0)
goto finally;
for (i = 0; i < len; i++) {
UNLESS (element = PyList_GET_ITEM((PyListObject *)args, i))
goto finally;
if (save(self, element, 0) < 0)
goto finally;
if (!using_appends) {
if ((*self->write_func)(self, &append, 1) < 0)
goto finally;
}
}
if (using_appends) {
if ((*self->write_func)(self, &appends, 1) < 0)
goto finally;
}
res = 0;
finally:
if (self->fast && !fast_save_leave(self, args))
res = -1;
return res;
}
static int
save_dict(Picklerobject *self, PyObject *args) {
PyObject *key = 0, *value = 0;
int i, len, res = -1, using_setitems;
char s[3];
static char setitem = SETITEM, setitems = SETITEMS;
if (self->fast && !fast_save_enter(self, args))
goto finally;
if (self->bin) {
s[0] = EMPTY_DICT;
len = 1;
}
else {
s[0] = MARK;
s[1] = DICT;
len = 2;
}
if ((*self->write_func)(self, s, len) < 0)
goto finally;
if ((len = PyDict_Size(args)) < 0)
goto finally;
if (len == 0) {
if (put(self, args) < 0)
goto finally;
}
else {
if (put2(self, args) < 0)
goto finally;
}
if ((using_setitems = (self->bin && (PyDict_Size(args) > 1))))
if ((*self->write_func)(self, &MARKv, 1) < 0)
goto finally;
i = 0;
while (PyDict_Next(args, &i, &key, &value)) {
if (save(self, key, 0) < 0)
goto finally;
if (save(self, value, 0) < 0)
goto finally;
if (!using_setitems) {
if ((*self->write_func)(self, &setitem, 1) < 0)
goto finally;
}
}
if (using_setitems) {
if ((*self->write_func)(self, &setitems, 1) < 0)
goto finally;
}
res = 0;
finally:
if (self->fast && !fast_save_leave(self, args))
res = -1;
return res;
}
static int
save_inst(Picklerobject *self, PyObject *args) {
PyObject *class = 0, *module = 0, *name = 0, *state = 0,
*getinitargs_func = 0, *getstate_func = 0, *class_args = 0;
char *module_str, *name_str;
int module_size, name_size, res = -1;
static char inst = INST, obj = OBJ, build = BUILD;
if (self->fast && !fast_save_enter(self, args))
goto finally;
if ((*self->write_func)(self, &MARKv, 1) < 0)
goto finally;
UNLESS (class = PyObject_GetAttr(args, __class___str))
goto finally;
if (self->bin) {
if (save(self, class, 0) < 0)
goto finally;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?