⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpickle.c

📁 python s60 1.4.5版本的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * cPickle.c,v 1.71 1999/07/11 13:30:34 jim Exp
 *
 * Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *   o Redistributions of source code must retain the above copyright
 *     notice, this list of conditions, and the disclaimer that follows.
 *
 *   o Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions, and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *
 *   o Neither the name of Digital Creations nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
 * IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL
 * CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 #
 # If you have questions regarding this software, contact:
 #
 #   Digital Creations, L.C.
 #   910 Princess Ann Street
 #   Fredericksburge, Virginia  22401
 #
 #   info@digicool.com
 #
 #   (540) 371-6909
 */

static char cPickle_module_documentation[] =
"C implementation and optimization of the Python pickle module\n"
"\n"
"cPickle.c,v 1.71 1999/07/11 13:30:34 jim Exp\n"
;

#include "Python.h"
#include "cStringIO.h"
#include "structmember.h"

#ifndef Py_eval_input
#include <graminit.h>
#define Py_eval_input eval_input
#endif /* Py_eval_input */

#include <errno.h>

#define UNLESS(E) if (!(E))

#define DEL_LIST_SLICE(list, from, to) (PyList_SetSlice(list, from, to, NULL))

#define WRITE_BUF_SIZE 256

/* --------------------------------------------------------------------------
NOTES on format codes.
XXX much more is needed here

Integer types
BININT1         8-bit unsigned integer; followed by 1 byte.
BININT2         16-bit unsigned integer; followed by 2 bytes, little-endian.
BININT          32-bit signed integer; followed by 4 bytes, little-endian.
INT             Integer; natural decimal string conversion, then newline.
                CAUTION:  INT-reading code can't assume that what follows
                fits in a Python int, because the size of Python ints varies
                across platforms.
LONG            Long (unbounded) integer; repr(i), then newline.
-------------------------------------------------------------------------- */

#define MARK        '('
#define STOP        '.'
#define POP         '0'
#define POP_MARK    '1'
#define DUP         '2'
#define FLOAT       'F'
#define BINFLOAT    'G'
#define INT         'I'
#define BININT      'J'
#define BININT1     'K'
#define LONG        'L'
#define BININT2     'M'
#define NONE        'N'
#define PERSID      'P'
#define BINPERSID   'Q'
#define REDUCE      'R'
#define STRING      'S'
#define BINSTRING   'T'
#define SHORT_BINSTRING 'U'
#define UNICODE     'V'
#define BINUNICODE  'X'
#define APPEND      'a'
#define BUILD       'b'
#define GLOBAL      'c'
#define DICT        'd'
#define EMPTY_DICT  '}'
#define APPENDS     'e'
#define GET         'g'
#define BINGET      'h'
#define INST        'i'
#define LONG_BINGET 'j'
#define LIST        'l'
#define EMPTY_LIST  ']'
#define OBJ         'o'
#define PUT         'p'
#define BINPUT      'q'
#define LONG_BINPUT 'r'
#define SETITEM     's'
#define TUPLE       't'
#define EMPTY_TUPLE ')'
#define SETITEMS    'u'

static char MARKv = MARK;

static PyObject *PickleError;
static PyObject *PicklingError;
static PyObject *UnpickleableError;
static PyObject *UnpicklingError;
static PyObject *BadPickleGet;


static PyObject *dispatch_table;
static PyObject *safe_constructors;
static PyObject *empty_tuple;

static PyObject *__class___str, *__getinitargs___str, *__dict___str,
  *__getstate___str, *__setstate___str, *__name___str, *__reduce___str,
  *write_str, *__safe_for_unpickling___str, *append_str,
  *read_str, *readline_str, *__main___str, *__basicnew___str,
  *copy_reg_str, *dispatch_table_str, *safe_constructors_str;

/*************************************************************************
 Internal Data type for pickle data.                                     */

typedef struct {
     PyObject_HEAD
     int length, size;
     PyObject **data;
} Pdata;

static void
Pdata_dealloc(Pdata *self) {
    int i;
    PyObject **p;

    for (i=self->length, p=self->data; --i >= 0; p++) Py_DECREF(*p);

    if (self->data) free(self->data);

    PyObject_Del(self);
}

static PyTypeObject PdataType = {
    PyObject_HEAD_INIT(NULL) 0, "cPickle.Pdata", sizeof(Pdata), 0,
    (destructor)Pdata_dealloc,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0L,0L,0L,0L, ""
};

#define Pdata_Check(O) ((O)->ob_type == &PdataType)

static PyObject *
Pdata_New(void) {
    Pdata *self;

    UNLESS (self = PyObject_New(Pdata, &PdataType)) return NULL;
    self->size=8;
    self->length=0;
    self->data=malloc(self->size * sizeof(PyObject*));
    if (self->data) return (PyObject*)self;
    Py_DECREF(self);
    return PyErr_NoMemory();
}

static int
stackUnderflow(void) {
    PyErr_SetString(UnpicklingError, "unpickling stack underflow");
    return -1;
}

static int
Pdata_clear(Pdata *self, int clearto) {
    int i;
    PyObject **p;

    if (clearto < 0) return stackUnderflow();
    if (clearto >= self->length) return 0;

    for (i=self->length, p=self->data+clearto; --i >= clearto; p++)
      Py_DECREF(*p);
    self->length=clearto;

    return 0;
}


static int
Pdata_grow(Pdata *self) {
  if (! self->size) {
      PyErr_NoMemory();
      return -1;
  }
  self->size *= 2;
  self->data = realloc(self->data, self->size*sizeof(PyObject*));
  if (! self->data) {
    self->size = 0;
    PyErr_NoMemory();
    return -1;
  }
  return 0;
}

#define PDATA_POP(D,V) {                                      \
    if ((D)->length) V=D->data[--((D)->length)];              \
    else {                                                    \
        PyErr_SetString(UnpicklingError, "bad pickle data");  \
        V=NULL;                                               \
    }                                                         \
}


static PyObject *
Pdata_popTuple(Pdata *self, int start) {
    PyObject *r;
    int i, j, l;

    l=self->length-start;
    UNLESS (r=PyTuple_New(l)) return NULL;
    for (i=start, j=0 ; j < l; i++, j++)
        PyTuple_SET_ITEM(r, j, self->data[i]);

    self->length=start;
    return r;
}

static PyObject *
Pdata_popList(Pdata *self, int start) {
    PyObject *r;
    int i, j, l;

    l=self->length-start;
    UNLESS (r=PyList_New(l)) return NULL;
    for (i=start, j=0 ; j < l; i++, j++)
        PyList_SET_ITEM(r, j, self->data[i]);

    self->length=start;
    return r;
}

#define PDATA_APPEND_(D,O,ER) { \
  if (Pdata_Append(((Pdata*)(D)), O) < 0) return ER; \
}

#define PDATA_APPEND(D,O,ER) {                                 \
    if (((Pdata*)(D))->length == ((Pdata*)(D))->size &&        \
        Pdata_grow((Pdata*)(D)) < 0)                           \
        return ER;                                             \
    Py_INCREF(O);                                              \
    ((Pdata*)(D))->data[((Pdata*)(D))->length++]=O;            \
}

#define PDATA_PUSH(D,O,ER) {                                   \
    if (((Pdata*)(D))->length == ((Pdata*)(D))->size &&        \
        Pdata_grow((Pdata*)(D)) < 0) {                         \
        Py_DECREF(O);                                          \
        return ER;                                             \
    }                                                          \
    ((Pdata*)(D))->data[((Pdata*)(D))->length++]=O;            \
}

/*************************************************************************/

#define ARG_TUP(self, o) {                          \
  if (self->arg || (self->arg=PyTuple_New(1))) {    \
      Py_XDECREF(PyTuple_GET_ITEM(self->arg,0));    \
      PyTuple_SET_ITEM(self->arg,0,o);              \
  }                                                 \
  else {                                            \
      Py_DECREF(o);                                 \
  }                                                 \
}

#define FREE_ARG_TUP(self) {                        \
    if (self->arg->ob_refcnt > 1) {                 \
      Py_DECREF(self->arg);                         \
      self->arg=NULL;                               \
    }                                               \
  }

typedef struct Picklerobject {
    PyObject_HEAD
    FILE *fp;
    PyObject *write;
    PyObject *file;
    PyObject *memo;
    PyObject *arg;
    PyObject *pers_func;
    PyObject *inst_pers_func;
    int bin;
    int fast; /* Fast mode doesn't save in memo, don't use if circ ref */
    int nesting;
    int (*write_func)(struct Picklerobject *, char *, int);
    char *write_buf;
    int buf_size;
    PyObject *dispatch_table;
    int fast_container; /* count nested container dumps */
    PyObject *fast_memo;
} Picklerobject;

#ifndef PY_CPICKLE_FAST_LIMIT
#define PY_CPICKLE_FAST_LIMIT 50
#endif

staticforward PyTypeObject Picklertype;

typedef struct Unpicklerobject {
     PyObject_HEAD
     FILE *fp;
     PyObject *file;
     PyObject *readline;
     PyObject *read;
     PyObject *memo;
     PyObject *arg;
     Pdata *stack;
     PyObject *mark;
     PyObject *pers_func;
     PyObject *last_string;
     int *marks;
     int num_marks;
     int marks_size;
     int (*read_func)(struct Unpicklerobject *, char **, int);
     int (*readline_func)(struct Unpicklerobject *, char **);
     int buf_size;
     char *buf;
     PyObject *safe_constructors;
     PyObject *find_class;
} Unpicklerobject;

staticforward PyTypeObject Unpicklertype;

/* Forward decls that need the above structs */
static int save(Picklerobject *, PyObject *, int);
static int put2(Picklerobject *, PyObject *);

int
cPickle_PyMapping_HasKey(PyObject *o, PyObject *key) {
    PyObject *v;

    if ((v = PyObject_GetItem(o,key))) {
        Py_DECREF(v);
        return 1;
    }

    PyErr_Clear();
    return 0;
}

static
PyObject *
cPickle_ErrFormat(PyObject *ErrType, char *stringformat, char *format, ...)
{
  va_list va;
  PyObject *args=0, *retval=0;
  va_start(va, format);

  if (format) args = Py_VaBuildValue(format, va);
  va_end(va);
  if (format && ! args) return NULL;
  if (stringformat && !(retval=PyString_FromString(stringformat))) return NULL;

  if (retval) {
      if (args) {
          PyObject *v;
          v=PyString_Format(retval, args);
          Py_DECREF(retval);
          Py_DECREF(args);
          if (! v) return NULL;
          retval=v;
        }
    }
  else
    if (args) retval=args;
    else {
        PyErr_SetObject(ErrType,Py_None);
        return NULL;
      }
  PyErr_SetObject(ErrType,retval);
  Py_DECREF(retval);
  return NULL;
}

static int
write_file(Picklerobject *self, char *s, int  n) {
    size_t nbyteswritten;

    if (s == NULL) {
        return 0;
    }

    Py_BEGIN_ALLOW_THREADS
    nbyteswritten = fwrite(s, sizeof(char), n, self->fp);
    Py_END_ALLOW_THREADS
    if (nbyteswritten != (size_t)n) {
        PyErr_SetFromErrno(PyExc_IOError);
        return -1;
    }

    return n;
}

static int
write_cStringIO(Picklerobject *self, char *s, int  n) {
    if (s == NULL) {
        return 0;
    }

    if (PycStringIO->cwrite((PyObject *)self->file, s, n) != n) {
        return -1;
    }

    return n;
}

static int
write_none(Picklerobject *self, char *s, int  n) {
    if (s == NULL) return 0;
    return n;
}

static int
write_other(Picklerobject *self, char *s, int  n) {
    PyObject *py_str = 0, *junk = 0;

    if (s == NULL) {
        UNLESS (self->buf_size) return 0;
        UNLESS (py_str =
            PyString_FromStringAndSize(self->write_buf, self->buf_size))
            return -1;
    }
    else {
        if (self->buf_size && (n + self->buf_size) > WRITE_BUF_SIZE) {
            if (write_other(self, NULL, 0) < 0)
                return -1;
        }

        if (n > WRITE_BUF_SIZE) {
            UNLESS (py_str =
                PyString_FromStringAndSize(s, n))
                return -1;
        }
        else {
            memcpy(self->write_buf + self->buf_size, s, n);
            self->buf_size += n;
            return n;
        }
    }

    if (self->write) {
        /* object with write method */
        ARG_TUP(self, py_str);
        if (self->arg) {
            junk = PyObject_Call(self->write, self->arg, NULL);
            FREE_ARG_TUP(self);
        }
        if (junk) Py_DECREF(junk);
        else return -1;
      }
    else
      PDATA_PUSH(self->file, py_str, -1);

    self->buf_size = 0;
    return n;
}


static int
read_file(Unpicklerobject *self, char **s, int  n) {
    size_t nbytesread;

    if (self->buf_size == 0) {
        int size;

        size = ((n < 32) ? 32 : n);
        UNLESS (self->buf = (char *)malloc(size * sizeof(char))) {
            PyErr_NoMemory();
            return -1;
        }

        self->buf_size = size;
    }
    else if (n > self->buf_size) {
        UNLESS (self->buf = (char *)realloc(self->buf, n * sizeof(char))) {
            PyErr_NoMemory();
            return -1;
        }

        self->buf_size = n;
    }

    Py_BEGIN_ALLOW_THREADS
    nbytesread = fread(self->buf, sizeof(char), n, self->fp);
    Py_END_ALLOW_THREADS
    if (nbytesread != (size_t)n) {
        if (feof(self->fp)) {
            PyErr_SetNone(PyExc_EOFError);
            return -1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -