| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1 | /* | 
| Guido van Rossum | 2f80d96 | 1999-07-13 15:18:58 +0000 | [diff] [blame] | 2 |  * cPickle.c,v 1.71 1999/07/11 13:30:34 jim Exp | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3 |  *  | 
 | 4 |  * Copyright (c) 1996-1998, Digital Creations, Fredericksburg, VA, USA.   | 
 | 5 |  * All rights reserved. | 
 | 6 |  *  | 
 | 7 |  * Redistribution and use in source and binary forms, with or without | 
 | 8 |  * modification, are permitted provided that the following conditions are | 
 | 9 |  * met: | 
 | 10 |  *  | 
 | 11 |  *   o Redistributions of source code must retain the above copyright | 
 | 12 |  *     notice, this list of conditions, and the disclaimer that follows. | 
 | 13 |  *  | 
 | 14 |  *   o Redistributions in binary form must reproduce the above copyright | 
 | 15 |  *     notice, this list of conditions, and the following disclaimer in | 
 | 16 |  *     the documentation and/or other materials provided with the | 
 | 17 |  *     distribution. | 
 | 18 |  *  | 
 | 19 |  *   o Neither the name of Digital Creations nor the names of its | 
 | 20 |  *     contributors may be used to endorse or promote products derived | 
 | 21 |  *     from this software without specific prior written permission. | 
 | 22 |  *  | 
 | 23 |  *  | 
 | 24 |  * THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS | 
 | 25 |  * IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 
 | 26 |  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | 
 | 27 |  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL | 
 | 28 |  * CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | 
 | 29 |  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | 
 | 30 |  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | 
 | 31 |  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 
 | 32 |  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | 
 | 33 |  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | 
 | 34 |  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH | 
 | 35 |  * DAMAGE. | 
 | 36 |  *  | 
 | 37 |  #  | 
 | 38 |  # If you have questions regarding this software, contact: | 
 | 39 |  # | 
 | 40 |  #   Digital Creations, L.C. | 
 | 41 |  #   910 Princess Ann Street | 
 | 42 |  #   Fredericksburge, Virginia  22401 | 
 | 43 |  # | 
 | 44 |  #   info@digicool.com | 
 | 45 |  # | 
 | 46 |  #   (540) 371-6909 | 
 | 47 |  */ | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 48 |  | 
 | 49 | static char cPickle_module_documentation[] =  | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 50 | "C implementation and optimization of the Python pickle module\n" | 
 | 51 | "\n" | 
| Guido van Rossum | 2f80d96 | 1999-07-13 15:18:58 +0000 | [diff] [blame] | 52 | "cPickle.c,v 1.71 1999/07/11 13:30:34 jim Exp\n" | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 53 | ; | 
 | 54 |  | 
 | 55 | #include "Python.h" | 
 | 56 | #include "cStringIO.h" | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 57 |  | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 58 | #ifndef Py_eval_input | 
 | 59 | #include <graminit.h> | 
 | 60 | #define Py_eval_input eval_input | 
| Guido van Rossum | c6ef204 | 1997-08-21 02:30:45 +0000 | [diff] [blame] | 61 | #endif /* Py_eval_input */ | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 62 |  | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 63 | #include <errno.h> | 
 | 64 |  | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 65 | #define UNLESS(E) if (!(E)) | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 66 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 67 | #define DEL_LIST_SLICE(list, from, to) (PyList_SetSlice(list, from, to, NULL)) | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 68 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 69 | #define WRITE_BUF_SIZE 256 | 
 | 70 |  | 
 | 71 |  | 
 | 72 | #define MARK        '(' | 
 | 73 | #define STOP        '.' | 
 | 74 | #define POP         '0' | 
 | 75 | #define POP_MARK    '1' | 
 | 76 | #define DUP         '2' | 
 | 77 | #define FLOAT       'F' | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 78 | #define BINFLOAT    'G' | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 79 | #define INT         'I' | 
 | 80 | #define BININT      'J' | 
 | 81 | #define BININT1     'K' | 
 | 82 | #define LONG        'L' | 
 | 83 | #define BININT2     'M' | 
 | 84 | #define NONE        'N' | 
 | 85 | #define PERSID      'P' | 
 | 86 | #define BINPERSID   'Q' | 
 | 87 | #define REDUCE      'R' | 
 | 88 | #define STRING      'S' | 
 | 89 | #define BINSTRING   'T' | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 90 | #define SHORT_BINSTRING 'U' | 
| Guido van Rossum | 5fccb7c | 2000-03-10 23:11:40 +0000 | [diff] [blame] | 91 | #define UNICODE     'V' | 
 | 92 | #define BINUNICODE  'X' | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 93 | #define APPEND      'a' | 
 | 94 | #define BUILD       'b' | 
 | 95 | #define GLOBAL      'c' | 
 | 96 | #define DICT        'd' | 
 | 97 | #define EMPTY_DICT  '}' | 
 | 98 | #define APPENDS     'e' | 
 | 99 | #define GET         'g' | 
 | 100 | #define BINGET      'h' | 
 | 101 | #define INST        'i' | 
 | 102 | #define LONG_BINGET 'j' | 
 | 103 | #define LIST        'l' | 
 | 104 | #define EMPTY_LIST  ']' | 
 | 105 | #define OBJ         'o' | 
 | 106 | #define PUT         'p' | 
 | 107 | #define BINPUT      'q' | 
 | 108 | #define LONG_BINPUT 'r' | 
 | 109 | #define SETITEM     's' | 
 | 110 | #define TUPLE       't' | 
 | 111 | #define EMPTY_TUPLE ')' | 
 | 112 | #define SETITEMS    'u' | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 113 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 114 | static char MARKv = MARK; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 115 |  | 
 | 116 | /* atol function from string module */ | 
 | 117 | static PyObject *atol_func; | 
 | 118 |  | 
| Guido van Rossum | c03158b | 1999-06-09 15:23:31 +0000 | [diff] [blame] | 119 | static PyObject *PickleError; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 120 | static PyObject *PicklingError; | 
| Guido van Rossum | c03158b | 1999-06-09 15:23:31 +0000 | [diff] [blame] | 121 | static PyObject *UnpickleableError; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 122 | static PyObject *UnpicklingError; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 123 | static PyObject *BadPickleGet; | 
 | 124 |  | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 125 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 126 | static PyObject *dispatch_table; | 
 | 127 | static PyObject *safe_constructors; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 128 | static PyObject *empty_tuple; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 129 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 130 | static PyObject *__class___str, *__getinitargs___str, *__dict___str, | 
 | 131 |   *__getstate___str, *__setstate___str, *__name___str, *__reduce___str, | 
 | 132 |   *write_str, *__safe_for_unpickling___str, *append_str, | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 133 |   *read_str, *readline_str, *__main___str, *__basicnew___str, | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 134 |   *copy_reg_str, *dispatch_table_str, *safe_constructors_str, *empty_str; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 135 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 136 | #ifndef PyList_SET_ITEM | 
 | 137 | #define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v)) | 
 | 138 | #endif | 
 | 139 | #ifndef PyList_GET_SIZE | 
 | 140 | #define PyList_GET_SIZE(op)    (((PyListObject *)(op))->ob_size) | 
 | 141 | #endif | 
 | 142 | #ifndef PyTuple_SET_ITEM | 
 | 143 | #define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = (v)) | 
 | 144 | #endif | 
 | 145 | #ifndef PyTuple_GET_SIZE | 
 | 146 | #define PyTuple_GET_SIZE(op)    (((PyTupleObject *)(op))->ob_size) | 
 | 147 | #endif | 
 | 148 | #ifndef PyString_GET_SIZE | 
 | 149 | #define PyString_GET_SIZE(op)    (((PyStringObject *)(op))->ob_size) | 
 | 150 | #endif | 
 | 151 |  | 
 | 152 | /************************************************************************* | 
 | 153 |  Internal Data type for pickle data.                                     */ | 
 | 154 |  | 
 | 155 | typedef struct { | 
 | 156 |      PyObject_HEAD | 
 | 157 |      int length, size; | 
 | 158 |      PyObject **data; | 
 | 159 | } Pdata; | 
 | 160 |  | 
 | 161 | static void  | 
 | 162 | Pdata_dealloc(Pdata *self) { | 
 | 163 |     int i; | 
 | 164 |     PyObject **p; | 
 | 165 |  | 
 | 166 |     for (i=self->length, p=self->data; --i >= 0; p++) Py_DECREF(*p); | 
 | 167 |  | 
 | 168 |     if (self->data) free(self->data); | 
 | 169 |  | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 170 |     PyObject_Del(self); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 171 | } | 
 | 172 |  | 
 | 173 | static PyTypeObject PdataType = { | 
 | 174 |     PyObject_HEAD_INIT(NULL) 0, "Pdata", sizeof(Pdata), 0, | 
 | 175 |     (destructor)Pdata_dealloc, | 
 | 176 |     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0L,0L,0L,0L, "" | 
 | 177 | }; | 
 | 178 |  | 
 | 179 | #define Pdata_Check(O) ((O)->ob_type == &PdataType) | 
 | 180 |  | 
 | 181 | static PyObject * | 
| Thomas Wouters | 58d0510 | 2000-07-24 14:43:35 +0000 | [diff] [blame] | 182 | Pdata_New(void) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 183 |     Pdata *self; | 
 | 184 |  | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 185 |     UNLESS (self = PyObject_New(Pdata, &PdataType)) return NULL; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 186 |     self->size=8; | 
 | 187 |     self->length=0; | 
 | 188 |     self->data=malloc(self->size * sizeof(PyObject*)); | 
 | 189 |     if (self->data) return (PyObject*)self; | 
 | 190 |     Py_DECREF(self); | 
 | 191 |     return PyErr_NoMemory(); | 
 | 192 | } | 
 | 193 |  | 
 | 194 | static int  | 
| Thomas Wouters | 58d0510 | 2000-07-24 14:43:35 +0000 | [diff] [blame] | 195 | stackUnderflow(void) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 196 |     PyErr_SetString(UnpicklingError, "unpickling stack underflow"); | 
 | 197 |     return -1; | 
 | 198 | } | 
 | 199 |  | 
 | 200 | static int | 
 | 201 | Pdata_clear(Pdata *self, int clearto) { | 
 | 202 |     int i; | 
 | 203 |     PyObject **p; | 
 | 204 |  | 
 | 205 |     if (clearto < 0) return stackUnderflow(); | 
 | 206 |     if (clearto >= self->length) return 0; | 
 | 207 |  | 
 | 208 |     for (i=self->length, p=self->data+clearto; --i >= clearto; p++) | 
 | 209 |       Py_DECREF(*p); | 
 | 210 |     self->length=clearto; | 
 | 211 |  | 
 | 212 |     return 0; | 
 | 213 | } | 
 | 214 |  | 
 | 215 |  | 
 | 216 | static int  | 
 | 217 | Pdata_grow(Pdata *self) { | 
 | 218 |   if (! self->size) { | 
 | 219 |       PyErr_NoMemory(); | 
 | 220 |       return -1; | 
 | 221 |   } | 
 | 222 |   self->size *= 2;                           | 
 | 223 |   self->data = realloc(self->data, self->size*sizeof(PyObject*)); | 
 | 224 |   if (! self->data) { | 
 | 225 |     self->size = 0;                        | 
 | 226 |     PyErr_NoMemory();                               | 
 | 227 |     return -1;                                      | 
 | 228 |   } | 
 | 229 |   return 0; | 
 | 230 | }                                                       | 
 | 231 |  | 
 | 232 | #define PDATA_POP(D,V) {                                      \ | 
 | 233 |     if ((D)->length) V=D->data[--((D)->length)];              \ | 
 | 234 |     else {                                                    \ | 
 | 235 |         PyErr_SetString(UnpicklingError, "bad pickle data");  \ | 
 | 236 |         V=NULL;                                               \ | 
 | 237 |     }                                                         \ | 
 | 238 | } | 
 | 239 |  | 
 | 240 |  | 
 | 241 | static PyObject * | 
 | 242 | Pdata_popTuple(Pdata *self, int start) { | 
 | 243 |     PyObject *r; | 
 | 244 |     int i, j, l; | 
 | 245 |  | 
 | 246 |     l=self->length-start; | 
 | 247 |     UNLESS (r=PyTuple_New(l)) return NULL; | 
| Guido van Rossum | ea2b715 | 2000-05-09 18:14:50 +0000 | [diff] [blame] | 248 |     for (i=start, j=0 ; j < l; i++, j++) | 
 | 249 |         PyTuple_SET_ITEM(r, j, self->data[i]); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 250 |  | 
 | 251 |     self->length=start; | 
 | 252 |     return r; | 
 | 253 | } | 
 | 254 |  | 
 | 255 | static PyObject * | 
 | 256 | Pdata_popList(Pdata *self, int start) { | 
 | 257 |     PyObject *r; | 
 | 258 |     int i, j, l; | 
 | 259 |  | 
 | 260 |     l=self->length-start; | 
 | 261 |     UNLESS (r=PyList_New(l)) return NULL; | 
| Guido van Rossum | ea2b715 | 2000-05-09 18:14:50 +0000 | [diff] [blame] | 262 |     for (i=start, j=0 ; j < l; i++, j++) | 
 | 263 |         PyList_SET_ITEM(r, j, self->data[i]); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 264 |  | 
 | 265 |     self->length=start; | 
 | 266 |     return r; | 
 | 267 | } | 
 | 268 |  | 
 | 269 | #define PDATA_APPEND_(D,O,ER) { \ | 
 | 270 |   if (Pdata_Append(((Pdata*)(D)), O) < 0) return ER; \ | 
 | 271 | } | 
 | 272 |  | 
 | 273 | #define PDATA_APPEND(D,O,ER) {                                 \ | 
 | 274 |     if (((Pdata*)(D))->length == ((Pdata*)(D))->size &&        \ | 
 | 275 |         Pdata_grow((Pdata*)(D)) < 0)                           \ | 
 | 276 |         return ER;                                             \ | 
 | 277 |     Py_INCREF(O);                                              \ | 
 | 278 |     ((Pdata*)(D))->data[((Pdata*)(D))->length++]=O;            \ | 
 | 279 | } | 
 | 280 |  | 
 | 281 | #define PDATA_PUSH(D,O,ER) {                                   \ | 
 | 282 |     if (((Pdata*)(D))->length == ((Pdata*)(D))->size &&        \ | 
 | 283 |         Pdata_grow((Pdata*)(D)) < 0) {                         \ | 
 | 284 |         Py_DECREF(O);                                          \ | 
 | 285 |         return ER;                                             \ | 
 | 286 |     }                                                          \ | 
 | 287 |     ((Pdata*)(D))->data[((Pdata*)(D))->length++]=O;            \ | 
 | 288 | } | 
 | 289 |  | 
 | 290 | /*************************************************************************/ | 
 | 291 |  | 
 | 292 | #define ARG_TUP(self, o) {                          \ | 
 | 293 |   if (self->arg || (self->arg=PyTuple_New(1))) {    \ | 
 | 294 |       Py_XDECREF(PyTuple_GET_ITEM(self->arg,0));    \ | 
 | 295 |       PyTuple_SET_ITEM(self->arg,0,o);              \ | 
 | 296 |   }                                                 \ | 
 | 297 |   else {                                            \ | 
 | 298 |       Py_DECREF(o);                                 \ | 
 | 299 |   }                                                 \ | 
 | 300 | } | 
 | 301 |  | 
 | 302 | #define FREE_ARG_TUP(self) {                        \ | 
 | 303 |     if (self->arg->ob_refcnt > 1) {                 \ | 
 | 304 |       Py_DECREF(self->arg);                         \ | 
 | 305 |       self->arg=NULL;                               \ | 
 | 306 |     }                                               \ | 
 | 307 |   } | 
 | 308 |  | 
| Thomas Wouters | 3b6448f | 2000-07-22 23:56:07 +0000 | [diff] [blame] | 309 | typedef struct Picklerobject { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 310 |      PyObject_HEAD | 
 | 311 |      FILE *fp; | 
 | 312 |      PyObject *write; | 
 | 313 |      PyObject *file; | 
 | 314 |      PyObject *memo; | 
 | 315 |      PyObject *arg; | 
 | 316 |      PyObject *pers_func; | 
 | 317 |      PyObject *inst_pers_func; | 
 | 318 |      int bin; | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 319 |      int fast; /* Fast mode doesn't save in memo, don't use if circ ref */ | 
| Thomas Wouters | 3b6448f | 2000-07-22 23:56:07 +0000 | [diff] [blame] | 320 |      int (*write_func)(struct Picklerobject *, char *, int); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 321 |      char *write_buf; | 
 | 322 |      int buf_size; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 323 |      PyObject *dispatch_table; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 324 | } Picklerobject; | 
 | 325 |  | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 326 | staticforward PyTypeObject Picklertype; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 327 |  | 
| Thomas Wouters | 3b6448f | 2000-07-22 23:56:07 +0000 | [diff] [blame] | 328 | typedef struct Unpicklerobject { | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 329 |      PyObject_HEAD | 
 | 330 |      FILE *fp; | 
 | 331 |      PyObject *file; | 
 | 332 |      PyObject *readline; | 
 | 333 |      PyObject *read; | 
 | 334 |      PyObject *memo; | 
 | 335 |      PyObject *arg; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 336 |      Pdata *stack; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 337 |      PyObject *mark; | 
 | 338 |      PyObject *pers_func; | 
 | 339 |      PyObject *last_string; | 
 | 340 |      int *marks; | 
 | 341 |      int num_marks; | 
 | 342 |      int marks_size; | 
| Thomas Wouters | 3b6448f | 2000-07-22 23:56:07 +0000 | [diff] [blame] | 343 |      int (*read_func)(struct Unpicklerobject *, char **, int); | 
 | 344 |      int (*readline_func)(struct Unpicklerobject *, char **); | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 345 |      int buf_size; | 
 | 346 |      char *buf; | 
 | 347 |      PyObject *safe_constructors; | 
| Guido van Rossum | 1b9e0aa | 1999-04-19 17:58:18 +0000 | [diff] [blame] | 348 |      PyObject *find_class; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 349 | } Unpicklerobject; | 
 | 350 |   | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 351 | staticforward PyTypeObject Unpicklertype; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 352 |  | 
| Thomas Wouters | 4789b3a | 2000-07-24 11:36:47 +0000 | [diff] [blame] | 353 | /* Forward decls that need the above structs */ | 
 | 354 | static int save(Picklerobject *, PyObject *, int); | 
 | 355 | static int put2(Picklerobject *, PyObject *); | 
 | 356 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 357 | int  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 358 | cPickle_PyMapping_HasKey(PyObject *o, PyObject *key) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 359 |     PyObject *v; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 360 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 361 |     if ((v = PyObject_GetItem(o,key))) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 362 |         Py_DECREF(v); | 
 | 363 |         return 1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 364 |     } | 
 | 365 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 366 |     PyErr_Clear(); | 
 | 367 |     return 0; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 368 | } | 
 | 369 |  | 
| Guido van Rossum | d385d59 | 1997-04-09 17:47:47 +0000 | [diff] [blame] | 370 | static | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 371 | PyObject * | 
| Thomas Wouters | 3b6448f | 2000-07-22 23:56:07 +0000 | [diff] [blame] | 372 | cPickle_ErrFormat(PyObject *ErrType, char *stringformat, char *format, ...) | 
 | 373 | { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 374 |   va_list va; | 
 | 375 |   PyObject *args=0, *retval=0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 376 |   va_start(va, format); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 377 |    | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 378 |   if (format) args = Py_VaBuildValue(format, va); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 379 |   va_end(va); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 380 |   if (format && ! args) return NULL; | 
 | 381 |   if (stringformat && !(retval=PyString_FromString(stringformat))) return NULL; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 382 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 383 |   if (retval) { | 
 | 384 |       if (args) { | 
 | 385 |           PyObject *v; | 
 | 386 |           v=PyString_Format(retval, args); | 
 | 387 |           Py_DECREF(retval); | 
 | 388 |           Py_DECREF(args); | 
 | 389 |           if (! v) return NULL; | 
 | 390 |           retval=v; | 
 | 391 |         } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 392 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 393 |   else | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 394 |     if (args) retval=args; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 395 |     else { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 396 |         PyErr_SetObject(ErrType,Py_None); | 
 | 397 |         return NULL; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 398 |       } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 399 |   PyErr_SetObject(ErrType,retval); | 
 | 400 |   Py_DECREF(retval); | 
 | 401 |   return NULL; | 
 | 402 | } | 
 | 403 |  | 
 | 404 | static int  | 
 | 405 | write_file(Picklerobject *self, char *s, int  n) { | 
 | 406 |     if (s == NULL) { | 
 | 407 |         return 0; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 408 |     } | 
 | 409 |  | 
| Trent Mick | 6c116dd | 2000-08-12 20:58:11 +0000 | [diff] [blame] | 410 |     if (fwrite(s, sizeof(char), n, self->fp) != (size_t)n) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 411 |         PyErr_SetFromErrno(PyExc_IOError); | 
 | 412 |         return -1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 413 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 414 |  | 
 | 415 |     return n; | 
 | 416 | } | 
 | 417 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 418 | static int  | 
 | 419 | write_cStringIO(Picklerobject *self, char *s, int  n) { | 
 | 420 |     if (s == NULL) { | 
 | 421 |         return 0; | 
 | 422 |     } | 
 | 423 |  | 
 | 424 |     if (PycStringIO->cwrite((PyObject *)self->file, s, n) != n) { | 
 | 425 |         return -1; | 
 | 426 |     } | 
 | 427 |  | 
 | 428 |     return n; | 
 | 429 | } | 
 | 430 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 431 | static int  | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 432 | write_none(Picklerobject *self, char *s, int  n) { | 
 | 433 |     if (s == NULL) return 0; | 
 | 434 |     return n; | 
 | 435 | } | 
 | 436 |  | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 437 | static int  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 438 | write_other(Picklerobject *self, char *s, int  n) { | 
 | 439 |     PyObject *py_str = 0, *junk = 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 440 |  | 
 | 441 |     if (s == NULL) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 442 |         UNLESS (self->buf_size) return 0; | 
 | 443 |         UNLESS (py_str =  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 444 |             PyString_FromStringAndSize(self->write_buf, self->buf_size)) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 445 |             return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 446 |     } | 
 | 447 |     else { | 
 | 448 |         if (self->buf_size && (n + self->buf_size) > WRITE_BUF_SIZE) { | 
 | 449 |             if (write_other(self, NULL, 0) < 0) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 450 |                 return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 451 |         } | 
 | 452 |  | 
 | 453 |         if (n > WRITE_BUF_SIZE) {     | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 454 |             UNLESS (py_str =  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 455 |                 PyString_FromStringAndSize(s, n)) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 456 |                 return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 457 |         } | 
 | 458 |         else { | 
 | 459 |             memcpy(self->write_buf + self->buf_size, s, n); | 
 | 460 |             self->buf_size += n; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 461 |             return n; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 462 |         } | 
 | 463 |     } | 
 | 464 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 465 |     if (self->write) { | 
 | 466 |         /* object with write method */ | 
 | 467 |         ARG_TUP(self, py_str); | 
 | 468 |         if (self->arg) { | 
 | 469 |             junk = PyObject_CallObject(self->write, self->arg); | 
 | 470 |             FREE_ARG_TUP(self); | 
 | 471 |         } | 
 | 472 |         if (junk) Py_DECREF(junk); | 
 | 473 |         else return -1; | 
 | 474 |       } | 
 | 475 |     else  | 
 | 476 |       PDATA_PUSH(self->file, py_str, -1); | 
 | 477 |      | 
 | 478 |     self->buf_size = 0;  | 
 | 479 |     return n; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 480 | } | 
 | 481 |  | 
 | 482 |  | 
 | 483 | static int  | 
 | 484 | read_file(Unpicklerobject *self, char **s, int  n) { | 
 | 485 |  | 
 | 486 |     if (self->buf_size == 0) { | 
 | 487 |         int size; | 
 | 488 |  | 
 | 489 |         size = ((n < 32) ? 32 : n);  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 490 |         UNLESS (self->buf = (char *)malloc(size * sizeof(char))) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 491 |             PyErr_NoMemory(); | 
 | 492 |             return -1; | 
 | 493 |         } | 
 | 494 |  | 
 | 495 |         self->buf_size = size; | 
 | 496 |     } | 
 | 497 |     else if (n > self->buf_size) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 498 |         UNLESS (self->buf = (char *)realloc(self->buf, n * sizeof(char))) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 499 |             PyErr_NoMemory(); | 
 | 500 |             return -1; | 
 | 501 |         } | 
 | 502 |   | 
 | 503 |         self->buf_size = n; | 
 | 504 |     } | 
 | 505 |              | 
| Trent Mick | 6c116dd | 2000-08-12 20:58:11 +0000 | [diff] [blame] | 506 |     if (fread(self->buf, sizeof(char), n, self->fp) != (size_t)n) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 507 |         if (feof(self->fp)) { | 
 | 508 |             PyErr_SetNone(PyExc_EOFError); | 
 | 509 |             return -1; | 
 | 510 |         } | 
 | 511 |  | 
 | 512 |         PyErr_SetFromErrno(PyExc_IOError); | 
 | 513 |         return -1; | 
 | 514 |     } | 
 | 515 |  | 
 | 516 |     *s = self->buf; | 
 | 517 |  | 
 | 518 |     return n; | 
 | 519 | } | 
 | 520 |  | 
 | 521 |  | 
 | 522 | static int  | 
 | 523 | readline_file(Unpicklerobject *self, char **s) { | 
 | 524 |     int i; | 
 | 525 |  | 
 | 526 |     if (self->buf_size == 0) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 527 |         UNLESS (self->buf = (char *)malloc(40 * sizeof(char))) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 528 |             PyErr_NoMemory(); | 
 | 529 |             return -1; | 
 | 530 |         } | 
 | 531 |     | 
 | 532 |         self->buf_size = 40; | 
 | 533 |     } | 
 | 534 |  | 
 | 535 |     i = 0; | 
 | 536 |     while (1) { | 
 | 537 |         for (; i < (self->buf_size - 1); i++) { | 
 | 538 |             if (feof(self->fp) || (self->buf[i] = getc(self->fp)) == '\n') { | 
 | 539 |                 self->buf[i + 1] = '\0'; | 
 | 540 |                 *s = self->buf; | 
 | 541 |                 return i + 1; | 
 | 542 |             } | 
 | 543 |         } | 
 | 544 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 545 |         UNLESS (self->buf = (char *)realloc(self->buf,  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 546 |             (self->buf_size * 2) * sizeof(char))) { | 
 | 547 |             PyErr_NoMemory(); | 
 | 548 |             return -1; | 
 | 549 |         } | 
 | 550 |  | 
 | 551 |         self->buf_size *= 2; | 
 | 552 |     } | 
 | 553 |  | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 554 | }     | 
 | 555 |  | 
 | 556 |  | 
 | 557 | static int  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 558 | read_cStringIO(Unpicklerobject *self, char **s, int  n) { | 
 | 559 |     char *ptr; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 560 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 561 |     if (PycStringIO->cread((PyObject *)self->file, &ptr, n) != n) { | 
 | 562 |         PyErr_SetNone(PyExc_EOFError); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 563 |         return -1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 564 |     } | 
 | 565 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 566 |     *s = ptr; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 567 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 568 |     return n; | 
 | 569 | } | 
 | 570 |  | 
 | 571 |  | 
 | 572 | static int  | 
 | 573 | readline_cStringIO(Unpicklerobject *self, char **s) { | 
 | 574 |     int n; | 
 | 575 |     char *ptr; | 
 | 576 |  | 
 | 577 |     if ((n = PycStringIO->creadline((PyObject *)self->file, &ptr)) < 0) { | 
 | 578 |         return -1; | 
 | 579 |     } | 
 | 580 |  | 
 | 581 |     *s = ptr; | 
 | 582 |  | 
 | 583 |     return n; | 
 | 584 | } | 
 | 585 |  | 
 | 586 |  | 
 | 587 | static int  | 
 | 588 | read_other(Unpicklerobject *self, char **s, int  n) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 589 |     PyObject *bytes, *str=0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 590 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 591 |     UNLESS (bytes = PyInt_FromLong(n)) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 592 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 593 |     ARG_TUP(self, bytes); | 
 | 594 |     if (self->arg) { | 
 | 595 |         str = PyObject_CallObject(self->read, self->arg); | 
 | 596 |         FREE_ARG_TUP(self); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 597 |     } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 598 |     if (! str) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 599 |  | 
 | 600 |     Py_XDECREF(self->last_string); | 
 | 601 |     self->last_string = str; | 
 | 602 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 603 |     if (! (*s = PyString_AsString(str))) return -1; | 
 | 604 |     return n; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 605 | } | 
 | 606 |  | 
 | 607 |  | 
 | 608 | static int  | 
 | 609 | readline_other(Unpicklerobject *self, char **s) { | 
 | 610 |     PyObject *str; | 
 | 611 |     int str_size; | 
 | 612 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 613 |     UNLESS (str = PyObject_CallObject(self->readline, empty_tuple)) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 614 |         return -1; | 
 | 615 |     } | 
 | 616 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 617 |     if ((str_size = PyString_Size(str)) < 0) | 
 | 618 |       return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 619 |  | 
 | 620 |     Py_XDECREF(self->last_string); | 
 | 621 |     self->last_string = str; | 
 | 622 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 623 |     if (! (*s = PyString_AsString(str))) | 
 | 624 |       return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 625 |  | 
 | 626 |     return str_size; | 
 | 627 | } | 
 | 628 |  | 
 | 629 |  | 
 | 630 | static char * | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 631 | pystrndup(char *s, int l) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 632 |   char *r; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 633 |   UNLESS (r=malloc((l+1)*sizeof(char))) return (char*)PyErr_NoMemory(); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 634 |   memcpy(r,s,l); | 
 | 635 |   r[l]=0; | 
 | 636 |   return r; | 
 | 637 | } | 
 | 638 |  | 
 | 639 |  | 
 | 640 | static int | 
 | 641 | get(Picklerobject *self, PyObject *id) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 642 |     PyObject *value, *mv; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 643 |     long c_value; | 
 | 644 |     char s[30]; | 
| Guido van Rossum | 534b7c5 | 2000-06-28 22:23:56 +0000 | [diff] [blame] | 645 |     size_t len; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 646 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 647 |     UNLESS (mv = PyDict_GetItem(self->memo, id)) { | 
 | 648 |         PyErr_SetObject(PyExc_KeyError, id); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 649 |         return -1; | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 650 |       } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 651 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 652 |     UNLESS (value = PyTuple_GetItem(mv, 0)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 653 |         return -1; | 
 | 654 |          | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 655 |     UNLESS (PyInt_Check(value)) { | 
 | 656 |       PyErr_SetString(PicklingError, "no int where int expected in memo"); | 
 | 657 |       return -1; | 
 | 658 |     } | 
 | 659 |     c_value = PyInt_AS_LONG((PyIntObject*)value); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 660 |  | 
 | 661 |     if (!self->bin) { | 
 | 662 |         s[0] = GET; | 
 | 663 |         sprintf(s + 1, "%ld\n", c_value); | 
 | 664 |         len = strlen(s); | 
 | 665 |     } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 666 |     else if (Pdata_Check(self->file)) { | 
 | 667 |         if (write_other(self, NULL, 0) < 0) return -1; | 
 | 668 |         PDATA_APPEND(self->file, mv, -1); | 
 | 669 |         return 0; | 
 | 670 |       } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 671 |     else { | 
 | 672 |         if (c_value < 256) { | 
 | 673 |             s[0] = BINGET; | 
 | 674 |             s[1] = (int)(c_value & 0xff); | 
 | 675 |             len = 2; | 
 | 676 |         } | 
 | 677 |         else { | 
 | 678 |             s[0] = LONG_BINGET; | 
 | 679 |             s[1] = (int)(c_value & 0xff); | 
 | 680 |             s[2] = (int)((c_value >> 8)  & 0xff); | 
 | 681 |             s[3] = (int)((c_value >> 16) & 0xff); | 
 | 682 |             s[4] = (int)((c_value >> 24) & 0xff); | 
 | 683 |             len = 5; | 
 | 684 |         } | 
 | 685 |     } | 
 | 686 |  | 
 | 687 |     if ((*self->write_func)(self, s, len) < 0) | 
 | 688 |         return -1; | 
 | 689 |  | 
 | 690 |     return 0; | 
 | 691 | } | 
 | 692 |      | 
 | 693 |  | 
 | 694 | static int | 
 | 695 | put(Picklerobject *self, PyObject *ob) { | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 696 |     if (ob->ob_refcnt < 2 || self->fast) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 697 |         return 0; | 
 | 698 |  | 
 | 699 |     return put2(self, ob); | 
 | 700 | } | 
 | 701 |  | 
 | 702 |    | 
 | 703 | static int | 
 | 704 | put2(Picklerobject *self, PyObject *ob) { | 
 | 705 |     char c_str[30]; | 
| Guido van Rossum | 534b7c5 | 2000-06-28 22:23:56 +0000 | [diff] [blame] | 706 |     int p; | 
 | 707 |     size_t len; | 
 | 708 |     int res = -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 709 |     PyObject *py_ob_id = 0, *memo_len = 0, *t = 0; | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 710 |  | 
 | 711 |     if (self->fast) return 0; | 
 | 712 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 713 |     if ((p = PyDict_Size(self->memo)) < 0) | 
 | 714 |         goto finally; | 
 | 715 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 716 |     p++;  /* Make sure memo keys are positive! */ | 
 | 717 |  | 
| Guido van Rossum | 534b7c5 | 2000-06-28 22:23:56 +0000 | [diff] [blame] | 718 |     UNLESS (py_ob_id = PyLong_FromVoidPtr(ob)) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 719 |         goto finally; | 
 | 720 |  | 
 | 721 |     UNLESS (memo_len = PyInt_FromLong(p)) | 
 | 722 |         goto finally; | 
 | 723 |  | 
 | 724 |     UNLESS (t = PyTuple_New(2)) | 
 | 725 |         goto finally; | 
 | 726 |  | 
 | 727 |     PyTuple_SET_ITEM(t, 0, memo_len); | 
 | 728 |     Py_INCREF(memo_len); | 
 | 729 |     PyTuple_SET_ITEM(t, 1, ob); | 
 | 730 |     Py_INCREF(ob); | 
 | 731 |  | 
 | 732 |     if (PyDict_SetItem(self->memo, py_ob_id, t) < 0) | 
 | 733 |         goto finally; | 
 | 734 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 735 |     if (!self->bin) { | 
 | 736 |         c_str[0] = PUT; | 
 | 737 |         sprintf(c_str + 1, "%d\n", p); | 
 | 738 |         len = strlen(c_str); | 
 | 739 |     } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 740 |     else if (Pdata_Check(self->file)) { | 
 | 741 |         if (write_other(self, NULL, 0) < 0) return -1; | 
 | 742 |         PDATA_APPEND(self->file, memo_len, -1); | 
 | 743 |         res=0;          /* Job well done ;) */ | 
 | 744 |         goto finally; | 
 | 745 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 746 |     else { | 
 | 747 |         if (p >= 256) { | 
 | 748 |             c_str[0] = LONG_BINPUT; | 
 | 749 |             c_str[1] = (int)(p & 0xff); | 
 | 750 |             c_str[2] = (int)((p >> 8)  & 0xff); | 
 | 751 |             c_str[3] = (int)((p >> 16) & 0xff); | 
 | 752 |             c_str[4] = (int)((p >> 24) & 0xff); | 
 | 753 |             len = 5; | 
 | 754 |         } | 
 | 755 |         else { | 
 | 756 |             c_str[0] = BINPUT; | 
 | 757 |             c_str[1] = p; | 
 | 758 |             len = 2;  | 
 | 759 |         } | 
 | 760 |     } | 
 | 761 |  | 
 | 762 |     if ((*self->write_func)(self, c_str, len) < 0) | 
 | 763 |         goto finally; | 
 | 764 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 765 |     res = 0; | 
 | 766 |  | 
 | 767 | finally: | 
 | 768 |     Py_XDECREF(py_ob_id); | 
 | 769 |     Py_XDECREF(memo_len); | 
 | 770 |     Py_XDECREF(t); | 
 | 771 |  | 
 | 772 |     return res; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 773 | } | 
 | 774 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 775 | #define PyImport_Import cPickle_Import | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 776 |  | 
 | 777 | static PyObject * | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 778 | PyImport_Import(PyObject *module_name) { | 
 | 779 |   static PyObject *silly_list=0, *__builtins___str=0, *__import___str; | 
 | 780 |   static PyObject *standard_builtins=0; | 
 | 781 |   PyObject *globals=0, *__import__=0, *__builtins__=0, *r=0; | 
 | 782 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 783 |   UNLESS (silly_list) { | 
 | 784 |       UNLESS (__import___str=PyString_FromString("__import__")) | 
 | 785 |         return NULL; | 
 | 786 |       UNLESS (__builtins___str=PyString_FromString("__builtins__")) | 
 | 787 |         return NULL; | 
 | 788 |       UNLESS (silly_list=Py_BuildValue("[s]","__doc__")) | 
 | 789 |         return NULL; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 790 |     } | 
 | 791 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 792 |   if ((globals=PyEval_GetGlobals())) { | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 793 |       Py_INCREF(globals); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 794 |       UNLESS (__builtins__=PyObject_GetItem(globals,__builtins___str)) | 
 | 795 |         goto err; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 796 |     } | 
 | 797 |   else { | 
 | 798 |       PyErr_Clear(); | 
 | 799 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 800 |       UNLESS (standard_builtins || | 
 | 801 |              (standard_builtins=PyImport_ImportModule("__builtin__"))) | 
 | 802 |         return NULL; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 803 |        | 
 | 804 |       __builtins__=standard_builtins; | 
 | 805 |       Py_INCREF(__builtins__); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 806 |       UNLESS (globals = Py_BuildValue("{sO}", "__builtins__", __builtins__)) | 
 | 807 |         goto err; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 808 |     } | 
 | 809 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 810 |   if (PyDict_Check(__builtins__)) { | 
 | 811 |     UNLESS (__import__=PyObject_GetItem(__builtins__,__import___str)) goto err; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 812 |   } | 
 | 813 |   else { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 814 |     UNLESS (__import__=PyObject_GetAttr(__builtins__,__import___str)) goto err; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 815 |   } | 
 | 816 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 817 |   UNLESS (r=PyObject_CallFunction(__import__,"OOOO", | 
 | 818 |                                  module_name, globals, globals, silly_list)) | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 819 |     goto err; | 
 | 820 |  | 
 | 821 |   Py_DECREF(globals); | 
 | 822 |   Py_DECREF(__builtins__); | 
 | 823 |   Py_DECREF(__import__); | 
 | 824 |    | 
 | 825 |   return r; | 
 | 826 | err: | 
 | 827 |   Py_XDECREF(globals); | 
 | 828 |   Py_XDECREF(__builtins__); | 
 | 829 |   Py_XDECREF(__import__); | 
 | 830 |   return NULL; | 
 | 831 | } | 
 | 832 |  | 
 | 833 | static PyObject * | 
| Guido van Rossum | e2d81cd | 1998-08-08 19:40:10 +0000 | [diff] [blame] | 834 | whichmodule(PyObject *global, PyObject *global_name) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 835 |     int i, j; | 
 | 836 |     PyObject *module = 0, *modules_dict = 0, | 
 | 837 |         *global_name_attr = 0, *name = 0; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 838 |  | 
| Guido van Rossum | 4518823 | 1997-09-28 05:38:51 +0000 | [diff] [blame] | 839 |     module = PyObject_GetAttrString(global, "__module__"); | 
 | 840 |     if (module) return module; | 
 | 841 |     PyErr_Clear(); | 
 | 842 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 843 |     UNLESS (modules_dict = PySys_GetObject("modules")) | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 844 |         return NULL; | 
 | 845 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 846 |     i = 0; | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 847 |     while ((j = PyDict_Next(modules_dict, &i, &name, &module))) { | 
 | 848 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 849 |         if (PyObject_Compare(name, __main___str)==0) continue; | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 850 |        | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 851 |         UNLESS (global_name_attr = PyObject_GetAttr(module, global_name)) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 852 |             PyErr_Clear(); | 
 | 853 |             continue; | 
 | 854 |         } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 855 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 856 |         if (global_name_attr != global) { | 
 | 857 |             Py_DECREF(global_name_attr); | 
 | 858 |             continue; | 
 | 859 |         } | 
 | 860 |  | 
 | 861 |         Py_DECREF(global_name_attr); | 
 | 862 |  | 
 | 863 |         break; | 
 | 864 |     } | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 865 |  | 
 | 866 |     /* The following implements the rule in pickle.py added in 1.5 | 
 | 867 |        that used __main__ if no module is found.  I don't actually | 
 | 868 |        like this rule. jlf | 
 | 869 |      */ | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 870 |     if (!j) { | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 871 |         j=1; | 
 | 872 |         name=__main___str; | 
 | 873 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 874 |  | 
 | 875 |     Py_INCREF(name); | 
 | 876 |     return name; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 877 | } | 
 | 878 |  | 
 | 879 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 880 | static int | 
 | 881 | save_none(Picklerobject *self, PyObject *args) { | 
 | 882 |     static char none = NONE; | 
 | 883 |     if ((*self->write_func)(self, &none, 1) < 0)   | 
 | 884 |         return -1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 885 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 886 |     return 0; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 887 | } | 
 | 888 |  | 
 | 889 |        | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 890 | static int | 
 | 891 | save_int(Picklerobject *self, PyObject *args) { | 
 | 892 |     char c_str[32]; | 
 | 893 |     long l = PyInt_AS_LONG((PyIntObject *)args); | 
 | 894 |     int len = 0; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 895 |  | 
| Guido van Rossum | de8d6d7 | 1997-05-13 18:00:44 +0000 | [diff] [blame] | 896 |     if (!self->bin | 
 | 897 | #if SIZEOF_LONG > 4 | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 898 |         || (l >> 32) | 
| Guido van Rossum | de8d6d7 | 1997-05-13 18:00:44 +0000 | [diff] [blame] | 899 | #endif | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 900 |             ) { | 
 | 901 |                 /* Save extra-long ints in non-binary mode, so that | 
 | 902 |                    we can use python long parsing code to restore, | 
 | 903 |                    if necessary. */ | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 904 |         c_str[0] = INT; | 
 | 905 |         sprintf(c_str + 1, "%ld\n", l); | 
 | 906 |         if ((*self->write_func)(self, c_str, strlen(c_str)) < 0) | 
 | 907 |             return -1; | 
 | 908 |     } | 
 | 909 |     else { | 
 | 910 |         c_str[1] = (int)( l        & 0xff); | 
 | 911 |         c_str[2] = (int)((l >> 8)  & 0xff); | 
 | 912 |         c_str[3] = (int)((l >> 16) & 0xff); | 
 | 913 |         c_str[4] = (int)((l >> 24) & 0xff); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 914 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 915 |         if ((c_str[4] == 0) && (c_str[3] == 0)) { | 
 | 916 |             if (c_str[2] == 0) { | 
 | 917 |                 c_str[0] = BININT1; | 
 | 918 |                 len = 2; | 
 | 919 |             } | 
 | 920 |             else { | 
 | 921 |                 c_str[0] = BININT2; | 
 | 922 |                 len = 3; | 
 | 923 |             } | 
 | 924 |         } | 
 | 925 |         else { | 
 | 926 |             c_str[0] = BININT; | 
 | 927 |             len = 5; | 
 | 928 |         } | 
 | 929 |  | 
 | 930 |         if ((*self->write_func)(self, c_str, len) < 0) | 
 | 931 |             return -1; | 
 | 932 |     } | 
 | 933 |  | 
 | 934 |     return 0; | 
 | 935 | } | 
 | 936 |  | 
 | 937 |  | 
 | 938 | static int | 
 | 939 | save_long(Picklerobject *self, PyObject *args) { | 
 | 940 |     int size, res = -1; | 
 | 941 |     PyObject *repr = 0; | 
 | 942 |  | 
 | 943 |     static char l = LONG; | 
 | 944 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 945 |     UNLESS (repr = PyObject_Repr(args)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 946 |         goto finally; | 
 | 947 |  | 
 | 948 |     if ((size = PyString_Size(repr)) < 0) | 
 | 949 |         goto finally; | 
 | 950 |  | 
 | 951 |     if ((*self->write_func)(self, &l, 1) < 0) | 
 | 952 |         goto finally; | 
 | 953 |  | 
 | 954 |     if ((*self->write_func)(self,  | 
 | 955 |         PyString_AS_STRING((PyStringObject *)repr), size) < 0) | 
 | 956 |         goto finally; | 
 | 957 |  | 
 | 958 |     if ((*self->write_func)(self, "\n", 1) < 0) | 
 | 959 |         goto finally; | 
 | 960 |  | 
 | 961 |     res = 0; | 
 | 962 |  | 
 | 963 | finally: | 
 | 964 |     Py_XDECREF(repr); | 
 | 965 |  | 
 | 966 |     return res; | 
 | 967 | } | 
 | 968 |  | 
 | 969 |  | 
 | 970 | static int | 
 | 971 | save_float(Picklerobject *self, PyObject *args) { | 
 | 972 |     double x = PyFloat_AS_DOUBLE((PyFloatObject *)args); | 
 | 973 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 974 |     if (self->bin) { | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 975 |         int s, e; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 976 |         double f; | 
 | 977 |         long fhi, flo; | 
 | 978 |         char str[9], *p = str; | 
 | 979 |  | 
 | 980 |         *p = BINFLOAT; | 
 | 981 |         p++; | 
 | 982 |  | 
 | 983 |         if (x < 0) { | 
 | 984 |             s = 1; | 
 | 985 |             x = -x; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 986 |         } | 
 | 987 |         else | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 988 |             s = 0; | 
 | 989 |  | 
 | 990 |         f = frexp(x, &e); | 
 | 991 |  | 
 | 992 |         /* Normalize f to be in the range [1.0, 2.0) */ | 
 | 993 |         if (0.5 <= f && f < 1.0) { | 
 | 994 |             f *= 2.0; | 
 | 995 |             e--; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 996 |         } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 997 |         else if (f == 0.0) { | 
 | 998 |             e = 0; | 
 | 999 |         } | 
 | 1000 |         else { | 
 | 1001 |             PyErr_SetString(PyExc_SystemError, | 
 | 1002 |                             "frexp() result out of range"); | 
 | 1003 |             return -1; | 
 | 1004 |         } | 
 | 1005 |  | 
 | 1006 |         if (e >= 1024) { | 
 | 1007 |             /* XXX 1024 itself is reserved for Inf/NaN */ | 
 | 1008 |             PyErr_SetString(PyExc_OverflowError, | 
 | 1009 |                             "float too large to pack with d format"); | 
 | 1010 |             return -1; | 
 | 1011 |         } | 
 | 1012 |         else if (e < -1022) { | 
 | 1013 |             /* Gradual underflow */ | 
 | 1014 |             f = ldexp(f, 1022 + e); | 
 | 1015 |             e = 0; | 
 | 1016 |         } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1017 |         else if (!(e == 0 && f == 0.0)) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1018 |             e += 1023; | 
 | 1019 |             f -= 1.0; /* Get rid of leading 1 */ | 
 | 1020 |         } | 
 | 1021 |  | 
 | 1022 |         /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */ | 
 | 1023 |         f *= 268435456.0; /* 2**28 */ | 
 | 1024 |         fhi = (long) floor(f); /* Truncate */ | 
 | 1025 |         f -= (double)fhi; | 
 | 1026 |         f *= 16777216.0; /* 2**24 */ | 
 | 1027 |         flo = (long) floor(f + 0.5); /* Round */ | 
 | 1028 |  | 
 | 1029 |         /* First byte */ | 
 | 1030 |         *p = (s<<7) | (e>>4); | 
 | 1031 |         p++; | 
 | 1032 |  | 
 | 1033 |         /* Second byte */ | 
| Guido van Rossum | e94e3fb | 1998-12-08 17:37:19 +0000 | [diff] [blame] | 1034 |         *p = (char) (((e&0xF)<<4) | (fhi>>24)); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1035 |         p++; | 
 | 1036 |  | 
 | 1037 |         /* Third byte */ | 
 | 1038 |         *p = (fhi>>16) & 0xFF; | 
 | 1039 |         p++; | 
 | 1040 |  | 
 | 1041 |         /* Fourth byte */ | 
 | 1042 |         *p = (fhi>>8) & 0xFF; | 
 | 1043 |         p++; | 
 | 1044 |  | 
 | 1045 |         /* Fifth byte */ | 
 | 1046 |         *p = fhi & 0xFF; | 
 | 1047 |         p++; | 
 | 1048 |  | 
 | 1049 |         /* Sixth byte */ | 
 | 1050 |         *p = (flo>>16) & 0xFF; | 
 | 1051 |         p++; | 
 | 1052 |  | 
 | 1053 |         /* Seventh byte */ | 
 | 1054 |         *p = (flo>>8) & 0xFF; | 
 | 1055 |         p++; | 
 | 1056 |  | 
 | 1057 |         /* Eighth byte */ | 
 | 1058 |         *p = flo & 0xFF; | 
 | 1059 |  | 
 | 1060 |         if ((*self->write_func)(self, str, 9) < 0) | 
 | 1061 |             return -1; | 
 | 1062 |     } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1063 |     else { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1064 |         char c_str[250]; | 
 | 1065 |         c_str[0] = FLOAT; | 
| Guido van Rossum | 104be4a | 1998-04-03 21:13:02 +0000 | [diff] [blame] | 1066 |         sprintf(c_str + 1, "%.17g\n", x); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1067 |  | 
 | 1068 |         if ((*self->write_func)(self, c_str, strlen(c_str)) < 0) | 
 | 1069 |             return -1; | 
 | 1070 |     } | 
 | 1071 |  | 
 | 1072 |     return 0; | 
 | 1073 | } | 
 | 1074 |  | 
 | 1075 |  | 
 | 1076 | static int | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1077 | save_string(Picklerobject *self, PyObject *args, int doput) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1078 |     int size, len; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1079 |     PyObject *repr=0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1080 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1081 |     if ((size = PyString_Size(args)) < 0) | 
 | 1082 |       return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1083 |  | 
 | 1084 |     if (!self->bin) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1085 |         char *repr_str; | 
 | 1086 |  | 
 | 1087 |         static char string = STRING; | 
 | 1088 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1089 |         UNLESS (repr = PyObject_Repr(args)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1090 |             return -1; | 
 | 1091 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1092 |         if ((len = PyString_Size(repr)) < 0) | 
 | 1093 |           goto err; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1094 |         repr_str = PyString_AS_STRING((PyStringObject *)repr); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1095 |  | 
 | 1096 |         if ((*self->write_func)(self, &string, 1) < 0) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1097 |             goto err; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1098 |  | 
 | 1099 |         if ((*self->write_func)(self, repr_str, len) < 0) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1100 |             goto err; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1101 |  | 
 | 1102 |         if ((*self->write_func)(self, "\n", 1) < 0) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1103 |             goto err; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1104 |  | 
 | 1105 |         Py_XDECREF(repr); | 
 | 1106 |     } | 
 | 1107 |     else { | 
 | 1108 |         int i; | 
 | 1109 |         char c_str[5]; | 
 | 1110 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1111 |         if ((size = PyString_Size(args)) < 0) | 
 | 1112 |           return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1113 |  | 
 | 1114 |         if (size < 256) { | 
 | 1115 |             c_str[0] = SHORT_BINSTRING; | 
 | 1116 |             c_str[1] = size; | 
 | 1117 |             len = 2; | 
 | 1118 |         } | 
 | 1119 |         else { | 
 | 1120 |             c_str[0] = BINSTRING; | 
 | 1121 |             for (i = 1; i < 5; i++) | 
 | 1122 |                 c_str[i] = (int)(size >> ((i - 1) * 8)); | 
 | 1123 |             len = 5; | 
 | 1124 |         } | 
 | 1125 |  | 
 | 1126 |         if ((*self->write_func)(self, c_str, len) < 0) | 
 | 1127 |             return -1; | 
 | 1128 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1129 |         if (size > 128 && Pdata_Check(self->file)) { | 
 | 1130 |             if (write_other(self, NULL, 0) < 0) return -1; | 
 | 1131 |             PDATA_APPEND(self->file, args, -1); | 
 | 1132 |           } | 
 | 1133 |         else { | 
 | 1134 |           if ((*self->write_func)(self,  | 
 | 1135 |               PyString_AS_STRING((PyStringObject *)args), size) < 0) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1136 |             return -1; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1137 |         } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1138 |     } | 
 | 1139 |  | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1140 |     if (doput) | 
 | 1141 |       if (put(self, args) < 0) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1142 |         return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1143 |  | 
 | 1144 |     return 0; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1145 |  | 
 | 1146 | err: | 
 | 1147 |     Py_XDECREF(repr); | 
 | 1148 |     return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1149 | } | 
 | 1150 |  | 
 | 1151 |  | 
| Guido van Rossum | fb10c3f | 2000-12-19 02:08:38 +0000 | [diff] [blame] | 1152 | /* A copy of PyUnicode_EncodeRawUnicodeEscape() that also translates | 
 | 1153 |    backslash and newline characters to \uXXXX escapes. */ | 
 | 1154 | static PyObject * | 
 | 1155 | modified_EncodeRawUnicodeEscape(const Py_UNICODE *s, int size) | 
 | 1156 | { | 
 | 1157 |     PyObject *repr; | 
 | 1158 |     char *p; | 
 | 1159 |     char *q; | 
 | 1160 |  | 
 | 1161 |     static const char *hexdigit = "0123456789ABCDEF"; | 
 | 1162 |  | 
 | 1163 |     repr = PyString_FromStringAndSize(NULL, 6 * size); | 
 | 1164 |     if (repr == NULL) | 
 | 1165 |         return NULL; | 
 | 1166 |     if (size == 0) | 
 | 1167 | 	return repr; | 
 | 1168 |  | 
 | 1169 |     p = q = PyString_AS_STRING(repr); | 
 | 1170 |     while (size-- > 0) { | 
 | 1171 |         Py_UNICODE ch = *s++; | 
 | 1172 | 	/* Map 16-bit characters to '\uxxxx' */ | 
 | 1173 | 	if (ch >= 256 || ch == '\\' || ch == '\n') { | 
 | 1174 |             *p++ = '\\'; | 
 | 1175 |             *p++ = 'u'; | 
 | 1176 |             *p++ = hexdigit[(ch >> 12) & 0xf]; | 
 | 1177 |             *p++ = hexdigit[(ch >> 8) & 0xf]; | 
 | 1178 |             *p++ = hexdigit[(ch >> 4) & 0xf]; | 
 | 1179 |             *p++ = hexdigit[ch & 15]; | 
 | 1180 |         } | 
 | 1181 | 	/* Copy everything else as-is */ | 
 | 1182 | 	else | 
 | 1183 |             *p++ = (char) ch; | 
 | 1184 |     } | 
 | 1185 |     *p = '\0'; | 
 | 1186 |     if (_PyString_Resize(&repr, p - q)) | 
 | 1187 | 	goto onError; | 
 | 1188 |  | 
 | 1189 |     return repr; | 
 | 1190 |  | 
 | 1191 |  onError: | 
 | 1192 |     Py_DECREF(repr); | 
 | 1193 |     return NULL; | 
 | 1194 | } | 
 | 1195 |  | 
 | 1196 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1197 | static int | 
| Guido van Rossum | 5fccb7c | 2000-03-10 23:11:40 +0000 | [diff] [blame] | 1198 | save_unicode(Picklerobject *self, PyObject *args, int doput) { | 
 | 1199 |     int size, len; | 
 | 1200 |     PyObject *repr=0; | 
 | 1201 |  | 
 | 1202 |     if (!PyUnicode_Check(args)) | 
 | 1203 |       return -1; | 
 | 1204 |  | 
 | 1205 |     if (!self->bin) { | 
 | 1206 |         char *repr_str; | 
 | 1207 |         static char string = UNICODE; | 
 | 1208 |  | 
| Guido van Rossum | fb10c3f | 2000-12-19 02:08:38 +0000 | [diff] [blame] | 1209 |         UNLESS(repr = modified_EncodeRawUnicodeEscape( | 
 | 1210 | 		PyUnicode_AS_UNICODE(args), PyUnicode_GET_SIZE(args))) | 
| Guido van Rossum | 5fccb7c | 2000-03-10 23:11:40 +0000 | [diff] [blame] | 1211 |             return -1; | 
 | 1212 |  | 
 | 1213 |         if ((len = PyString_Size(repr)) < 0) | 
 | 1214 |           goto err; | 
 | 1215 |         repr_str = PyString_AS_STRING((PyStringObject *)repr); | 
 | 1216 |  | 
 | 1217 |         if ((*self->write_func)(self, &string, 1) < 0) | 
 | 1218 |             goto err; | 
 | 1219 |  | 
 | 1220 |         if ((*self->write_func)(self, repr_str, len) < 0) | 
 | 1221 |             goto err; | 
 | 1222 |  | 
 | 1223 |         if ((*self->write_func)(self, "\n", 1) < 0) | 
 | 1224 |             goto err; | 
 | 1225 |  | 
 | 1226 |         Py_XDECREF(repr); | 
 | 1227 |     } | 
 | 1228 |     else { | 
 | 1229 |         int i; | 
 | 1230 |         char c_str[5]; | 
 | 1231 |  | 
 | 1232 |         UNLESS (repr = PyUnicode_AsUTF8String(args)) | 
 | 1233 |             return -1; | 
 | 1234 |  | 
 | 1235 |         if ((size = PyString_Size(repr)) < 0) | 
 | 1236 | 	    goto err; | 
 | 1237 |  | 
 | 1238 | 	c_str[0] = BINUNICODE; | 
 | 1239 | 	for (i = 1; i < 5; i++) | 
 | 1240 | 	    c_str[i] = (int)(size >> ((i - 1) * 8)); | 
 | 1241 | 	len = 5; | 
 | 1242 |  | 
 | 1243 |         if ((*self->write_func)(self, c_str, len) < 0) | 
 | 1244 |             goto err; | 
 | 1245 |  | 
 | 1246 |         if (size > 128 && Pdata_Check(self->file)) { | 
 | 1247 |             if (write_other(self, NULL, 0) < 0) | 
 | 1248 | 		goto err; | 
 | 1249 |             PDATA_APPEND(self->file, repr, -1); | 
 | 1250 |           } | 
 | 1251 |         else { | 
 | 1252 |           if ((*self->write_func)(self, PyString_AS_STRING(repr), size) < 0) | 
 | 1253 | 	      goto err; | 
 | 1254 |         } | 
 | 1255 |  | 
 | 1256 | 	Py_DECREF(repr); | 
 | 1257 |     } | 
 | 1258 |  | 
 | 1259 |     if (doput) | 
 | 1260 |       if (put(self, args) < 0) | 
 | 1261 |         return -1; | 
 | 1262 |  | 
 | 1263 |     return 0; | 
 | 1264 |  | 
 | 1265 | err: | 
 | 1266 |     Py_XDECREF(repr); | 
 | 1267 |     return -1; | 
 | 1268 | } | 
 | 1269 |  | 
 | 1270 |  | 
 | 1271 | static int | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1272 | save_tuple(Picklerobject *self, PyObject *args) { | 
 | 1273 |     PyObject *element = 0, *py_tuple_id = 0; | 
 | 1274 |     int len, i, has_key, res = -1; | 
 | 1275 |  | 
 | 1276 |     static char tuple = TUPLE; | 
 | 1277 |  | 
 | 1278 |     if ((*self->write_func)(self, &MARKv, 1) < 0) | 
 | 1279 |         goto finally; | 
 | 1280 |  | 
 | 1281 |     if ((len = PyTuple_Size(args)) < 0)   | 
 | 1282 |         goto finally; | 
 | 1283 |  | 
 | 1284 |     for (i = 0; i < len; i++) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1285 |         UNLESS (element = PyTuple_GET_ITEM((PyTupleObject *)args, i))   | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1286 |             goto finally; | 
 | 1287 |      | 
 | 1288 |         if (save(self, element, 0) < 0) | 
 | 1289 |             goto finally; | 
 | 1290 |     } | 
 | 1291 |  | 
| Guido van Rossum | 534b7c5 | 2000-06-28 22:23:56 +0000 | [diff] [blame] | 1292 |     UNLESS (py_tuple_id = PyLong_FromVoidPtr(args)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1293 |         goto finally; | 
 | 1294 |  | 
 | 1295 |     if (len) { | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1296 |         if ((has_key = cPickle_PyMapping_HasKey(self->memo, py_tuple_id)) < 0) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1297 |             goto finally; | 
 | 1298 |  | 
 | 1299 |         if (has_key) { | 
 | 1300 |             if (self->bin) { | 
 | 1301 |                 static char pop_mark = POP_MARK; | 
 | 1302 |    | 
 | 1303 |                 if ((*self->write_func)(self, &pop_mark, 1) < 0) | 
 | 1304 |                     goto finally; | 
 | 1305 |             } | 
 | 1306 |             else { | 
 | 1307 |                 static char pop = POP; | 
 | 1308 |         | 
 | 1309 |                 for (i = 0; i <= len; i++) { | 
 | 1310 |                     if ((*self->write_func)(self, &pop, 1) < 0) | 
 | 1311 |                         goto finally; | 
 | 1312 |                 }  | 
 | 1313 |             } | 
 | 1314 |          | 
 | 1315 |             if (get(self, py_tuple_id) < 0) | 
 | 1316 |                 goto finally; | 
 | 1317 |  | 
 | 1318 |             res = 0; | 
 | 1319 |             goto finally; | 
 | 1320 |         } | 
 | 1321 |     } | 
 | 1322 |  | 
 | 1323 |     if ((*self->write_func)(self, &tuple, 1) < 0) { | 
 | 1324 |         goto finally; | 
 | 1325 |     } | 
 | 1326 |  | 
 | 1327 |     if (put(self, args) < 0) | 
 | 1328 |         goto finally; | 
 | 1329 |   | 
 | 1330 |     res = 0; | 
 | 1331 |  | 
 | 1332 | finally: | 
 | 1333 |     Py_XDECREF(py_tuple_id); | 
 | 1334 |  | 
 | 1335 |     return res; | 
 | 1336 | } | 
 | 1337 |  | 
 | 1338 | static int | 
 | 1339 | save_empty_tuple(Picklerobject *self, PyObject *args) { | 
 | 1340 |     static char tuple = EMPTY_TUPLE; | 
 | 1341 |  | 
 | 1342 |     return (*self->write_func)(self, &tuple, 1); | 
 | 1343 | } | 
 | 1344 |  | 
 | 1345 |  | 
 | 1346 | static int | 
 | 1347 | save_list(Picklerobject *self, PyObject *args) { | 
 | 1348 |     PyObject *element = 0; | 
 | 1349 |     int s_len, len, i, using_appends, res = -1; | 
 | 1350 |     char s[3]; | 
 | 1351 |  | 
 | 1352 |     static char append = APPEND, appends = APPENDS; | 
 | 1353 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1354 |     if (self->bin) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1355 |         s[0] = EMPTY_LIST; | 
 | 1356 |         s_len = 1; | 
 | 1357 |     }  | 
 | 1358 |     else { | 
 | 1359 |         s[0] = MARK; | 
 | 1360 |         s[1] = LIST; | 
 | 1361 |         s_len = 2; | 
 | 1362 |     } | 
 | 1363 |  | 
 | 1364 |     if ((len = PyList_Size(args)) < 0) | 
 | 1365 |         goto finally; | 
 | 1366 |  | 
 | 1367 |     if ((*self->write_func)(self, s, s_len) < 0) | 
 | 1368 |         goto finally; | 
 | 1369 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 1370 |     if (len == 0) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1371 |         if (put(self, args) < 0) | 
 | 1372 |             goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1373 |     } | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 1374 |     else { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1375 |         if (put2(self, args) < 0) | 
 | 1376 |             goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1377 |     } | 
 | 1378 |  | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1379 |     if ((using_appends = (self->bin && (len > 1)))) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1380 |         if ((*self->write_func)(self, &MARKv, 1) < 0) | 
 | 1381 |             goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1382 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1383 |     for (i = 0; i < len; i++) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1384 |         UNLESS (element = PyList_GET_ITEM((PyListObject *)args, i))   | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1385 |             goto finally; | 
 | 1386 |  | 
 | 1387 |         if (save(self, element, 0) < 0)   | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1388 |             goto finally;        | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1389 |  | 
 | 1390 |         if (!using_appends) { | 
 | 1391 |             if ((*self->write_func)(self, &append, 1) < 0) | 
 | 1392 |                 goto finally; | 
 | 1393 |         } | 
 | 1394 |     } | 
 | 1395 |  | 
 | 1396 |     if (using_appends) { | 
 | 1397 |         if ((*self->write_func)(self, &appends, 1) < 0) | 
 | 1398 |             goto finally; | 
 | 1399 |     } | 
 | 1400 |  | 
 | 1401 |     res = 0; | 
 | 1402 |  | 
 | 1403 | finally: | 
 | 1404 |  | 
 | 1405 |     return res; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1406 | } | 
 | 1407 |  | 
 | 1408 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1409 | static int | 
 | 1410 | save_dict(Picklerobject *self, PyObject *args) { | 
 | 1411 |     PyObject *key = 0, *value = 0; | 
 | 1412 |     int i, len, res = -1, using_setitems; | 
 | 1413 |     char s[3]; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1414 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1415 |     static char setitem = SETITEM, setitems = SETITEMS; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1416 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1417 |     if (self->bin) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1418 |         s[0] = EMPTY_DICT; | 
 | 1419 |         len = 1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1420 |     } | 
 | 1421 |     else { | 
 | 1422 |         s[0] = MARK; | 
 | 1423 |         s[1] = DICT; | 
 | 1424 |         len = 2; | 
 | 1425 |     } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1426 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1427 |     if ((*self->write_func)(self, s, len) < 0) | 
 | 1428 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1429 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1430 |     if ((len = PyDict_Size(args)) < 0) | 
 | 1431 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1432 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 1433 |     if (len == 0) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1434 |         if (put(self, args) < 0) | 
 | 1435 |             goto finally; | 
 | 1436 |     } | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 1437 |     else { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1438 |         if (put2(self, args) < 0) | 
 | 1439 |             goto finally; | 
 | 1440 |     } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1441 |  | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1442 |     if ((using_setitems = (self->bin && (PyDict_Size(args) > 1)))) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1443 |         if ((*self->write_func)(self, &MARKv, 1) < 0) | 
 | 1444 |             goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1445 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1446 |     i = 0; | 
 | 1447 |     while (PyDict_Next(args, &i, &key, &value)) { | 
 | 1448 |         if (save(self, key, 0) < 0) | 
 | 1449 |             goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1450 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1451 |         if (save(self, value, 0) < 0) | 
 | 1452 |             goto finally; | 
 | 1453 |  | 
 | 1454 |         if (!using_setitems) { | 
 | 1455 |             if ((*self->write_func)(self, &setitem, 1) < 0) | 
 | 1456 |                 goto finally; | 
 | 1457 |         } | 
 | 1458 |     } | 
 | 1459 |  | 
 | 1460 |     if (using_setitems) { | 
 | 1461 |         if ((*self->write_func)(self, &setitems, 1) < 0) | 
 | 1462 |             goto finally; | 
 | 1463 |     } | 
 | 1464 |  | 
 | 1465 |     res = 0; | 
 | 1466 |  | 
 | 1467 | finally: | 
 | 1468 |  | 
 | 1469 |     return res; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1470 | } | 
 | 1471 |  | 
 | 1472 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1473 | static int   | 
 | 1474 | save_inst(Picklerobject *self, PyObject *args) { | 
 | 1475 |     PyObject *class = 0, *module = 0, *name = 0, *state = 0,  | 
 | 1476 |              *getinitargs_func = 0, *getstate_func = 0, *class_args = 0; | 
 | 1477 |     char *module_str, *name_str; | 
 | 1478 |     int module_size, name_size, res = -1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1479 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1480 |     static char inst = INST, obj = OBJ, build = BUILD; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1481 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1482 |     if ((*self->write_func)(self, &MARKv, 1) < 0) | 
 | 1483 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1484 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1485 |     UNLESS (class = PyObject_GetAttr(args, __class___str)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1486 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1487 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1488 |     if (self->bin) { | 
 | 1489 |         if (save(self, class, 0) < 0) | 
 | 1490 |             goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1491 |     } | 
 | 1492 |  | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1493 |     if ((getinitargs_func = PyObject_GetAttr(args, __getinitargs___str))) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1494 |         PyObject *element = 0; | 
 | 1495 |         int i, len; | 
 | 1496 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1497 |         UNLESS (class_args =  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1498 |             PyObject_CallObject(getinitargs_func, empty_tuple)) | 
 | 1499 |             goto finally; | 
 | 1500 |  | 
| Jeremy Hylton | 03657cf | 2000-07-12 13:05:33 +0000 | [diff] [blame] | 1501 |         if ((len = PyObject_Size(class_args)) < 0)   | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1502 |             goto finally; | 
 | 1503 |  | 
 | 1504 |         for (i = 0; i < len; i++) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1505 |             UNLESS (element = PySequence_GetItem(class_args, i))  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1506 |                 goto finally; | 
 | 1507 |  | 
 | 1508 |             if (save(self, element, 0) < 0) { | 
 | 1509 |                 Py_DECREF(element); | 
 | 1510 |                 goto finally; | 
 | 1511 |             } | 
 | 1512 |  | 
 | 1513 |             Py_DECREF(element); | 
 | 1514 |         } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1515 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1516 |     else { | 
 | 1517 |         PyErr_Clear(); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1518 |     } | 
 | 1519 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1520 |     if (!self->bin) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1521 |         UNLESS (name = ((PyClassObject *)class)->cl_name) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1522 |             PyErr_SetString(PicklingError, "class has no name"); | 
 | 1523 |             goto finally; | 
 | 1524 |         } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1525 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1526 |         UNLESS (module = whichmodule(class, name)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1527 |             goto finally; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1528 |  | 
 | 1529 |          | 
 | 1530 |         if ((module_size = PyString_Size(module)) < 0 || | 
 | 1531 |            (name_size = PyString_Size(name)) < 0) | 
 | 1532 |           goto finally; | 
 | 1533 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1534 |         module_str = PyString_AS_STRING((PyStringObject *)module); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1535 |         name_str   = PyString_AS_STRING((PyStringObject *)name); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1536 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1537 |         if ((*self->write_func)(self, &inst, 1) < 0) | 
 | 1538 |             goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1539 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1540 |         if ((*self->write_func)(self, module_str, module_size) < 0) | 
 | 1541 |             goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1542 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1543 |         if ((*self->write_func)(self, "\n", 1) < 0) | 
 | 1544 |             goto finally; | 
 | 1545 |  | 
 | 1546 |         if ((*self->write_func)(self, name_str, name_size) < 0) | 
 | 1547 |             goto finally; | 
 | 1548 |  | 
 | 1549 |         if ((*self->write_func)(self, "\n", 1) < 0) | 
 | 1550 |             goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1551 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1552 |     else if ((*self->write_func)(self, &obj, 1) < 0) { | 
 | 1553 |         goto finally; | 
 | 1554 |     } | 
 | 1555 |  | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1556 |     if ((getstate_func = PyObject_GetAttr(args, __getstate___str))) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1557 |         UNLESS (state = PyObject_CallObject(getstate_func, empty_tuple)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1558 |             goto finally; | 
 | 1559 |     } | 
 | 1560 |     else { | 
 | 1561 |         PyErr_Clear(); | 
 | 1562 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1563 |         UNLESS (state = PyObject_GetAttr(args, __dict___str)) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1564 |             PyErr_Clear(); | 
 | 1565 |             res = 0; | 
 | 1566 |             goto finally; | 
 | 1567 |         } | 
 | 1568 |     } | 
 | 1569 |  | 
 | 1570 |     if (!PyDict_Check(state)) { | 
 | 1571 |         if (put2(self, args) < 0) | 
 | 1572 |             goto finally; | 
 | 1573 |     } | 
 | 1574 |     else { | 
 | 1575 |         if (put(self, args) < 0) | 
 | 1576 |             goto finally; | 
 | 1577 |     } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1578 |    | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1579 |     if (save(self, state, 0) < 0) | 
 | 1580 |         goto finally; | 
 | 1581 |  | 
 | 1582 |     if ((*self->write_func)(self, &build, 1) < 0) | 
 | 1583 |         goto finally; | 
 | 1584 |  | 
 | 1585 |     res = 0; | 
 | 1586 |  | 
 | 1587 | finally: | 
 | 1588 |     Py_XDECREF(module); | 
 | 1589 |     Py_XDECREF(class); | 
 | 1590 |     Py_XDECREF(state); | 
 | 1591 |     Py_XDECREF(getinitargs_func); | 
 | 1592 |     Py_XDECREF(getstate_func); | 
 | 1593 |     Py_XDECREF(class_args); | 
 | 1594 |  | 
 | 1595 |     return res; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1596 | } | 
 | 1597 |  | 
 | 1598 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1599 | static int | 
 | 1600 | save_global(Picklerobject *self, PyObject *args, PyObject *name) { | 
 | 1601 |     PyObject *global_name = 0, *module = 0; | 
 | 1602 |     char *name_str, *module_str;  | 
 | 1603 |     int module_size, name_size, res = -1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1604 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1605 |     static char global = GLOBAL; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1606 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 1607 |     if (name) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1608 |         global_name = name; | 
 | 1609 |         Py_INCREF(global_name); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1610 |     } | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 1611 |     else { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1612 |         UNLESS (global_name = PyObject_GetAttr(args, __name___str)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1613 |             goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1614 |     } | 
 | 1615 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1616 |     UNLESS (module = whichmodule(args, global_name)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1617 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1618 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1619 |     if ((module_size = PyString_Size(module)) < 0 || | 
 | 1620 |         (name_size = PyString_Size(global_name)) < 0) | 
 | 1621 |       goto finally; | 
 | 1622 |  | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1623 |     module_str = PyString_AS_STRING((PyStringObject *)module); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1624 |     name_str   = PyString_AS_STRING((PyStringObject *)global_name); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1625 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1626 |     if ((*self->write_func)(self, &global, 1) < 0) | 
 | 1627 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1628 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1629 |     if ((*self->write_func)(self, module_str, module_size) < 0) | 
 | 1630 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1631 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1632 |     if ((*self->write_func)(self, "\n", 1) < 0) | 
 | 1633 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1634 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1635 |     if ((*self->write_func)(self, name_str, name_size) < 0) | 
 | 1636 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1637 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1638 |     if ((*self->write_func)(self, "\n", 1) < 0) | 
 | 1639 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1640 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1641 |     if (put(self, args) < 0) | 
 | 1642 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1643 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1644 |     res = 0; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1645 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1646 | finally: | 
 | 1647 |     Py_XDECREF(module); | 
 | 1648 |     Py_XDECREF(global_name); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1649 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1650 |     return res; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1651 | } | 
 | 1652 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1653 | static int | 
 | 1654 | save_pers(Picklerobject *self, PyObject *args, PyObject *f) { | 
 | 1655 |     PyObject *pid = 0; | 
 | 1656 |     int size, res = -1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1657 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1658 |     static char persid = PERSID, binpersid = BINPERSID; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1659 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1660 |     Py_INCREF(args); | 
 | 1661 |     ARG_TUP(self, args); | 
 | 1662 |     if (self->arg) { | 
 | 1663 |         pid = PyObject_CallObject(f, self->arg); | 
 | 1664 |         FREE_ARG_TUP(self); | 
 | 1665 |     } | 
 | 1666 |     if (! pid) return -1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1667 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1668 |     if (pid != Py_None) { | 
 | 1669 |         if (!self->bin) { | 
 | 1670 |             if (!PyString_Check(pid)) { | 
 | 1671 |                 PyErr_SetString(PicklingError,  | 
 | 1672 |                     "persistent id must be string"); | 
 | 1673 |                 goto finally; | 
 | 1674 |             } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1675 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1676 |             if ((*self->write_func)(self, &persid, 1) < 0) | 
 | 1677 |                 goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1678 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1679 |             if ((size = PyString_Size(pid)) < 0) | 
 | 1680 |                 goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1681 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1682 |             if ((*self->write_func)(self,  | 
 | 1683 |                 PyString_AS_STRING((PyStringObject *)pid), size) < 0) | 
 | 1684 |                 goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1685 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1686 |             if ((*self->write_func)(self, "\n", 1) < 0) | 
 | 1687 |                 goto finally; | 
 | 1688 |       | 
 | 1689 |             res = 1; | 
 | 1690 |             goto finally; | 
 | 1691 |         } | 
 | 1692 |         else if (save(self, pid, 1) >= 0) { | 
 | 1693 |             if ((*self->write_func)(self, &binpersid, 1) < 0) | 
 | 1694 |                 res = -1; | 
 | 1695 |             else | 
 | 1696 |                 res = 1; | 
 | 1697 |         } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1698 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1699 |         goto finally;               | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1700 |     } | 
 | 1701 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1702 |     res = 0; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1703 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1704 | finally: | 
 | 1705 |     Py_XDECREF(pid); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1706 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1707 |     return res; | 
 | 1708 | } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1709 |  | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1710 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1711 | static int  | 
 | 1712 | save_reduce(Picklerobject *self, PyObject *callable, | 
 | 1713 |             PyObject *tup, PyObject *state, PyObject *ob) { | 
 | 1714 |     static char reduce = REDUCE, build = BUILD; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1715 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1716 |     if (save(self, callable, 0) < 0) | 
 | 1717 |         return -1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1718 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1719 |     if (save(self, tup, 0) < 0) | 
 | 1720 |         return -1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1721 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1722 |     if ((*self->write_func)(self, &reduce, 1) < 0) | 
 | 1723 |         return -1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1724 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 1725 |     if (ob != NULL) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1726 |         if (state && !PyDict_Check(state)) { | 
 | 1727 |             if (put2(self, ob) < 0) | 
 | 1728 |                 return -1; | 
 | 1729 |         } | 
 | 1730 |         else { | 
 | 1731 |             if (put(self, ob) < 0) | 
 | 1732 |                 return -1; | 
 | 1733 |         } | 
 | 1734 |     } | 
 | 1735 |      | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 1736 |     if (state) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1737 |         if (save(self, state, 0) < 0) | 
 | 1738 |             return -1; | 
 | 1739 |  | 
 | 1740 |         if ((*self->write_func)(self, &build, 1) < 0) | 
 | 1741 |             return -1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1742 |     } | 
 | 1743 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1744 |     return 0; | 
 | 1745 | } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1746 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1747 | static int | 
 | 1748 | save(Picklerobject *self, PyObject *args, int  pers_save) { | 
 | 1749 |     PyTypeObject *type; | 
 | 1750 |     PyObject *py_ob_id = 0, *__reduce__ = 0, *t = 0, *arg_tup = 0, | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1751 |              *callable = 0, *state = 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1752 |     int res = -1, tmp, size; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1753 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1754 |     if (!pers_save && self->pers_func) { | 
 | 1755 |         if ((tmp = save_pers(self, args, self->pers_func)) != 0) { | 
 | 1756 |             res = tmp; | 
 | 1757 |             goto finally; | 
 | 1758 |         } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1759 |     } | 
 | 1760 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1761 |     if (args == Py_None) { | 
 | 1762 |         res = save_none(self, args); | 
 | 1763 |         goto finally; | 
 | 1764 |     } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1765 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1766 |     type = args->ob_type; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1767 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1768 |     switch (type->tp_name[0]) { | 
 | 1769 |         case 'i': | 
 | 1770 |             if (type == &PyInt_Type) { | 
 | 1771 |                 res = save_int(self, args); | 
 | 1772 |                 goto finally; | 
 | 1773 |             } | 
 | 1774 |             break; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1775 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1776 |         case 'l': | 
 | 1777 |             if (type == &PyLong_Type) { | 
 | 1778 |                 res = save_long(self, args); | 
 | 1779 |                 goto finally; | 
 | 1780 |             } | 
 | 1781 |             break; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1782 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1783 |         case 'f': | 
 | 1784 |             if (type == &PyFloat_Type) { | 
 | 1785 |                 res = save_float(self, args); | 
 | 1786 |                 goto finally; | 
 | 1787 |             } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1788 |             break; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1789 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1790 |         case 't': | 
 | 1791 |             if (type == &PyTuple_Type && PyTuple_Size(args)==0) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1792 |                 if (self->bin) res = save_empty_tuple(self, args); | 
 | 1793 |                 else          res = save_tuple(self, args); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1794 |                 goto finally; | 
 | 1795 |             } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1796 |             break; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1797 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1798 |         case 's': | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1799 |             if ((type == &PyString_Type) && (PyString_GET_SIZE(args) < 2)) { | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1800 |                 res = save_string(self, args, 0); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1801 |                 goto finally; | 
 | 1802 |             } | 
| Guido van Rossum | 5fccb7c | 2000-03-10 23:11:40 +0000 | [diff] [blame] | 1803 |  | 
 | 1804 |         case 'u': | 
 | 1805 |             if ((type == &PyUnicode_Type) && (PyString_GET_SIZE(args) < 2)) { | 
 | 1806 |                 res = save_unicode(self, args, 0); | 
 | 1807 |                 goto finally; | 
 | 1808 |             } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1809 |     } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1810 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1811 |     if (args->ob_refcnt > 1) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1812 |         int  has_key; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1813 |  | 
| Guido van Rossum | 534b7c5 | 2000-06-28 22:23:56 +0000 | [diff] [blame] | 1814 |         UNLESS (py_ob_id = PyLong_FromVoidPtr(args)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1815 |             goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1816 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1817 |         if ((has_key = cPickle_PyMapping_HasKey(self->memo, py_ob_id)) < 0) | 
 | 1818 |             goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1819 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1820 |         if (has_key) { | 
 | 1821 |             if (get(self, py_ob_id) < 0) | 
 | 1822 |                 goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1823 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1824 |             res = 0; | 
 | 1825 |             goto finally; | 
 | 1826 |         } | 
 | 1827 |     } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1828 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1829 |     switch (type->tp_name[0]) { | 
 | 1830 |         case 's': | 
 | 1831 |             if (type == &PyString_Type) { | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1832 |                 res = save_string(self, args, 1); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1833 |                 goto finally; | 
 | 1834 |             } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1835 |             break; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1836 |  | 
| Guido van Rossum | 5fccb7c | 2000-03-10 23:11:40 +0000 | [diff] [blame] | 1837 |         case 'u': | 
 | 1838 |             if (type == &PyUnicode_Type) { | 
 | 1839 |                 res = save_unicode(self, args, 1); | 
 | 1840 |                 goto finally; | 
 | 1841 |             } | 
 | 1842 |             break; | 
 | 1843 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1844 |         case 't': | 
 | 1845 |             if (type == &PyTuple_Type) { | 
 | 1846 |                 res = save_tuple(self, args); | 
 | 1847 |                 goto finally; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1848 |             } | 
 | 1849 |             break; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 1850 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1851 |         case 'l': | 
 | 1852 |             if (type == &PyList_Type) { | 
 | 1853 |                 res = save_list(self, args); | 
 | 1854 |                 goto finally; | 
 | 1855 |             } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1856 |             break; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1857 |  | 
 | 1858 |         case 'd': | 
 | 1859 |             if (type == &PyDict_Type) { | 
 | 1860 |                 res = save_dict(self, args); | 
 | 1861 |                 goto finally;  | 
 | 1862 |             } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1863 |             break; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1864 |  | 
 | 1865 |         case 'i': | 
 | 1866 |             if (type == &PyInstance_Type) { | 
 | 1867 |                 res = save_inst(self, args); | 
 | 1868 |                 goto finally; | 
 | 1869 |             } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1870 |             break; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1871 |  | 
 | 1872 |         case 'c': | 
 | 1873 |             if (type == &PyClass_Type) { | 
 | 1874 |                 res = save_global(self, args, NULL); | 
 | 1875 |                 goto finally; | 
 | 1876 |             } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1877 |             break; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1878 |  | 
 | 1879 |         case 'f': | 
 | 1880 |             if (type == &PyFunction_Type) { | 
 | 1881 |                 res = save_global(self, args, NULL); | 
 | 1882 |                 goto finally; | 
 | 1883 |             } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1884 |             break; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1885 |  | 
 | 1886 |         case 'b': | 
 | 1887 |             if (type == &PyCFunction_Type) { | 
 | 1888 |                 res = save_global(self, args, NULL); | 
 | 1889 |                 goto finally; | 
 | 1890 |             } | 
 | 1891 |     } | 
 | 1892 |  | 
 | 1893 |     if (!pers_save && self->inst_pers_func) { | 
 | 1894 |         if ((tmp = save_pers(self, args, self->inst_pers_func)) != 0) { | 
 | 1895 |             res = tmp; | 
 | 1896 |             goto finally; | 
 | 1897 |         } | 
 | 1898 |     } | 
 | 1899 |  | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1900 |     if ((__reduce__ = PyDict_GetItem(dispatch_table, (PyObject *)type))) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1901 |         Py_INCREF(__reduce__); | 
 | 1902 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1903 |         Py_INCREF(args); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1904 |         ARG_TUP(self, args); | 
 | 1905 |         if (self->arg) { | 
 | 1906 |             t = PyObject_CallObject(__reduce__, self->arg); | 
 | 1907 |             FREE_ARG_TUP(self); | 
 | 1908 |         } | 
 | 1909 |         if (! t) goto finally; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1910 |     }         | 
 | 1911 |     else { | 
 | 1912 |         PyErr_Clear(); | 
 | 1913 |  | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1914 |         if ((__reduce__ = PyObject_GetAttr(args, __reduce___str))) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1915 |             UNLESS (t = PyObject_CallObject(__reduce__, empty_tuple)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1916 |                 goto finally; | 
 | 1917 |         } | 
 | 1918 |         else { | 
 | 1919 |             PyErr_Clear(); | 
 | 1920 |         } | 
 | 1921 |     } | 
 | 1922 |  | 
 | 1923 |     if (t) { | 
 | 1924 |         if (PyString_Check(t)) { | 
 | 1925 |             res = save_global(self, args, t); | 
 | 1926 |             goto finally; | 
 | 1927 |         } | 
 | 1928 |   | 
 | 1929 |         if (!PyTuple_Check(t)) { | 
| Guido van Rossum | 57d9f2e | 1998-01-19 23:18:18 +0000 | [diff] [blame] | 1930 |             cPickle_ErrFormat(PicklingError, "Value returned by %s must " | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1931 |                 "be a tuple", "O", __reduce__); | 
 | 1932 |             goto finally; | 
 | 1933 |         } | 
 | 1934 |  | 
 | 1935 |         size = PyTuple_Size(t); | 
 | 1936 |          | 
 | 1937 |         if ((size != 3) && (size != 2)) { | 
| Guido van Rossum | 57d9f2e | 1998-01-19 23:18:18 +0000 | [diff] [blame] | 1938 |             cPickle_ErrFormat(PicklingError, "tuple returned by %s must "      | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1939 |                 "contain only two or three elements", "O", __reduce__); | 
 | 1940 |                 goto finally; | 
 | 1941 |         } | 
 | 1942 |          | 
 | 1943 |         callable = PyTuple_GET_ITEM(t, 0); | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 1944 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1945 |         arg_tup = PyTuple_GET_ITEM(t, 1); | 
 | 1946 |  | 
 | 1947 |         if (size > 2) { | 
 | 1948 |             state = PyTuple_GET_ITEM(t, 2); | 
 | 1949 |         } | 
 | 1950 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1951 |         UNLESS (PyTuple_Check(arg_tup) || arg_tup==Py_None) { | 
| Guido van Rossum | 57d9f2e | 1998-01-19 23:18:18 +0000 | [diff] [blame] | 1952 |             cPickle_ErrFormat(PicklingError, "Second element of tuple " | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1953 |                 "returned by %s must be a tuple", "O", __reduce__); | 
 | 1954 |             goto finally; | 
 | 1955 |         } | 
 | 1956 |  | 
 | 1957 |         res = save_reduce(self, callable, arg_tup, state, args); | 
 | 1958 |         goto finally; | 
 | 1959 |     } | 
 | 1960 |  | 
| Guido van Rossum | c03158b | 1999-06-09 15:23:31 +0000 | [diff] [blame] | 1961 |     PyErr_SetObject(UnpickleableError, args); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 1962 |  | 
 | 1963 | finally: | 
 | 1964 |     Py_XDECREF(py_ob_id); | 
 | 1965 |     Py_XDECREF(__reduce__); | 
 | 1966 |     Py_XDECREF(t); | 
 | 1967 |     | 
 | 1968 |     return res; | 
 | 1969 | } | 
 | 1970 |  | 
 | 1971 |  | 
 | 1972 | static int | 
 | 1973 | dump(Picklerobject *self, PyObject *args) { | 
 | 1974 |     static char stop = STOP; | 
 | 1975 |  | 
 | 1976 |     if (save(self, args, 0) < 0) | 
 | 1977 |         return -1; | 
 | 1978 |  | 
 | 1979 |     if ((*self->write_func)(self, &stop, 1) < 0) | 
 | 1980 |         return -1; | 
 | 1981 |  | 
 | 1982 |     if ((*self->write_func)(self, NULL, 0) < 0) | 
 | 1983 |         return -1; | 
 | 1984 |  | 
 | 1985 |     return 0; | 
 | 1986 | } | 
 | 1987 |  | 
 | 1988 | static PyObject * | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1989 | Pickle_clear_memo(Picklerobject *self, PyObject *args) { | 
| Guido van Rossum | 43713e5 | 2000-02-29 13:59:29 +0000 | [diff] [blame] | 1990 |   if (args && ! PyArg_ParseTuple(args,":clear_memo")) return NULL; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 1991 |   if (self->memo) PyDict_Clear(self->memo); | 
 | 1992 |   Py_INCREF(Py_None); | 
 | 1993 |   return Py_None; | 
 | 1994 | } | 
 | 1995 |  | 
 | 1996 | static PyObject * | 
 | 1997 | Pickle_getvalue(Picklerobject *self, PyObject *args) { | 
 | 1998 |   int l, i, rsize, ssize, clear=1, lm; | 
| Guido van Rossum | e94e3fb | 1998-12-08 17:37:19 +0000 | [diff] [blame] | 1999 |   long ik; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2000 |   PyObject *k, *r; | 
 | 2001 |   char *s, *p, *have_get; | 
 | 2002 |   Pdata *data; | 
 | 2003 |  | 
| Guido van Rossum | 43713e5 | 2000-02-29 13:59:29 +0000 | [diff] [blame] | 2004 |   if (args && ! PyArg_ParseTuple(args,"|i:getvalue",&clear)) return NULL; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2005 |  | 
 | 2006 |   /* Check to make sure we are based on a list */ | 
 | 2007 |   if (! Pdata_Check(self->file)) { | 
 | 2008 |       PyErr_SetString(PicklingError, | 
 | 2009 |                       "Attempt to getvalue a non-list-based pickler"); | 
 | 2010 |       return NULL; | 
 | 2011 |     } | 
 | 2012 |  | 
 | 2013 |   /* flush write buffer */ | 
 | 2014 |   if (write_other(self, NULL, 0) < 0) return NULL; | 
 | 2015 |  | 
 | 2016 |   data=(Pdata*)self->file; | 
 | 2017 |   l=data->length; | 
 | 2018 |  | 
 | 2019 |   /* set up an array to hold get/put status */ | 
 | 2020 |   if ((lm=PyDict_Size(self->memo)) < 0) return NULL; | 
 | 2021 |   lm++; | 
 | 2022 |   if (! (have_get=malloc((lm)*sizeof(char)))) return PyErr_NoMemory();   | 
 | 2023 |   memset(have_get,0,lm); | 
 | 2024 |  | 
 | 2025 |   /* Scan for gets. */ | 
 | 2026 |   for (rsize=0, i=l; --i >= 0; ) { | 
 | 2027 |       k=data->data[i]; | 
 | 2028 |        | 
 | 2029 |       if (PyString_Check(k)) { | 
 | 2030 |         rsize += PyString_GET_SIZE(k); | 
 | 2031 |       } | 
 | 2032 |  | 
 | 2033 |       else if (PyInt_Check(k)) { /* put */ | 
 | 2034 |         ik=PyInt_AS_LONG((PyIntObject*)k); | 
 | 2035 |         if (ik >= lm || ik==0) { | 
 | 2036 |           PyErr_SetString(PicklingError, | 
 | 2037 |                           "Invalid get data"); | 
 | 2038 |           return NULL; | 
 | 2039 |         }       | 
 | 2040 |         if (have_get[ik]) { /* with matching get */ | 
 | 2041 |           if (ik < 256) rsize += 2; | 
 | 2042 |           else rsize+=5; | 
 | 2043 |         } | 
 | 2044 |       } | 
 | 2045 |  | 
 | 2046 |       else if (! (PyTuple_Check(k) && | 
 | 2047 |                   PyTuple_GET_SIZE(k) == 2 && | 
 | 2048 |                   PyInt_Check((k=PyTuple_GET_ITEM(k,0)))) | 
 | 2049 |                ) { | 
 | 2050 |         PyErr_SetString(PicklingError, | 
 | 2051 |                         "Unexpected data in internal list"); | 
 | 2052 |         return NULL; | 
 | 2053 |       } | 
 | 2054 |  | 
 | 2055 |       else { /* put */ | 
 | 2056 |         ik=PyInt_AS_LONG((PyIntObject*)k); | 
 | 2057 |         if (ik >= lm || ik==0) { | 
 | 2058 |           PyErr_SetString(PicklingError, | 
 | 2059 |                           "Invalid get data"); | 
 | 2060 |           return NULL; | 
 | 2061 |         }       | 
 | 2062 |         have_get[ik]=1; | 
 | 2063 |         if (ik < 256) rsize += 2; | 
 | 2064 |         else rsize+=5; | 
 | 2065 |       } | 
 | 2066 |  | 
 | 2067 |     } | 
 | 2068 |  | 
 | 2069 |   /* Now generate the result */ | 
 | 2070 |   UNLESS (r=PyString_FromStringAndSize(NULL,rsize)) goto err; | 
 | 2071 |   s=PyString_AS_STRING((PyStringObject*)r); | 
 | 2072 |  | 
 | 2073 |   for (i=0; i<l; i++) { | 
 | 2074 |       k=data->data[i]; | 
 | 2075 |  | 
 | 2076 |       if (PyString_Check(k)) { | 
 | 2077 |         ssize=PyString_GET_SIZE(k); | 
 | 2078 |         if (ssize) { | 
 | 2079 |             p=PyString_AS_STRING((PyStringObject*)k); | 
 | 2080 |             while (--ssize >= 0) *s++=*p++; | 
 | 2081 |           } | 
 | 2082 |       } | 
 | 2083 |  | 
 | 2084 |       else if (PyTuple_Check(k)) { /* get */ | 
 | 2085 |         ik=PyInt_AS_LONG((PyIntObject*)PyTuple_GET_ITEM(k,0)); | 
 | 2086 |         if (ik < 256) { | 
 | 2087 |           *s++ = BINGET; | 
 | 2088 |           *s++ = (int)(ik & 0xff); | 
 | 2089 |         } | 
 | 2090 |         else { | 
 | 2091 |           *s++ = LONG_BINGET; | 
 | 2092 |           *s++ = (int)(ik & 0xff); | 
 | 2093 |           *s++ = (int)((ik >> 8)  & 0xff); | 
 | 2094 |           *s++ = (int)((ik >> 16) & 0xff); | 
 | 2095 |           *s++ = (int)((ik >> 24) & 0xff); | 
 | 2096 |         } | 
 | 2097 |       } | 
 | 2098 |  | 
 | 2099 |       else { /* put */ | 
 | 2100 |         ik=PyInt_AS_LONG((PyIntObject*)k); | 
 | 2101 |  | 
 | 2102 |         if (have_get[ik]) { /* with matching get */ | 
 | 2103 |           if (ik < 256) { | 
 | 2104 |             *s++ = BINPUT; | 
 | 2105 |             *s++ = (int)(ik & 0xff); | 
 | 2106 |           } | 
 | 2107 |           else { | 
 | 2108 |             *s++ = LONG_BINPUT; | 
 | 2109 |             *s++ = (int)(ik & 0xff); | 
 | 2110 |             *s++ = (int)((ik >> 8)  & 0xff); | 
 | 2111 |             *s++ = (int)((ik >> 16) & 0xff); | 
 | 2112 |             *s++ = (int)((ik >> 24) & 0xff); | 
 | 2113 |           } | 
 | 2114 |         } | 
 | 2115 |       } | 
 | 2116 |  | 
 | 2117 |     } | 
 | 2118 |  | 
 | 2119 |   if (clear) { | 
 | 2120 |     PyDict_Clear(self->memo); | 
 | 2121 |     Pdata_clear(data,0); | 
 | 2122 |   } | 
 | 2123 |      | 
 | 2124 |   free(have_get); | 
 | 2125 |   return r; | 
 | 2126 | err: | 
 | 2127 |   free(have_get); | 
 | 2128 |   return NULL; | 
 | 2129 | } | 
 | 2130 |  | 
 | 2131 | static PyObject * | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2132 | Pickler_dump(Picklerobject *self, PyObject *args) { | 
 | 2133 |     PyObject *ob; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2134 |     int get=0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2135 |  | 
| Guido van Rossum | 43713e5 | 2000-02-29 13:59:29 +0000 | [diff] [blame] | 2136 |     UNLESS (PyArg_ParseTuple(args, "O|i:dump", &ob, &get)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2137 |         return NULL; | 
 | 2138 |  | 
 | 2139 |     if (dump(self, ob) < 0) | 
 | 2140 |         return NULL; | 
 | 2141 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2142 |     if (get) return Pickle_getvalue(self, NULL); | 
 | 2143 |  | 
 | 2144 |     Py_INCREF(self); | 
 | 2145 |     return (PyObject*)self; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2146 | } | 
 | 2147 |  | 
 | 2148 |  | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2149 | static struct PyMethodDef Pickler_methods[] = { | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 2150 |   {"dump",          (PyCFunction)Pickler_dump,  1, | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2151 |    "dump(object) --" | 
 | 2152 |    "Write an object in pickle format to the object's pickle stream\n" | 
 | 2153 |   }, | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 2154 |   {"clear_memo",  (PyCFunction)Pickle_clear_memo,  1, | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2155 |    "clear_memo() -- Clear the picklers memo"}, | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2156 |   {"getvalue",  (PyCFunction)Pickle_getvalue,  1, | 
 | 2157 |    "getvalue() -- Finish picking a list-based pickle"}, | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2158 |   {NULL,                NULL}           /* sentinel */ | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2159 | }; | 
 | 2160 |  | 
 | 2161 |  | 
 | 2162 | static Picklerobject * | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2163 | newPicklerobject(PyObject *file, int bin) { | 
 | 2164 |     Picklerobject *self; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2165 |  | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 2166 |     UNLESS (self = PyObject_New(Picklerobject, &Picklertype)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2167 |         return NULL; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2168 |  | 
 | 2169 |     self->fp = NULL; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2170 |     self->write = NULL; | 
 | 2171 |     self->memo = NULL; | 
 | 2172 |     self->arg = NULL; | 
 | 2173 |     self->pers_func = NULL; | 
 | 2174 |     self->inst_pers_func = NULL; | 
 | 2175 |     self->write_buf = NULL; | 
 | 2176 |     self->bin = bin; | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 2177 |     self->fast = 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2178 |     self->buf_size = 0; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2179 |     self->dispatch_table = NULL; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2180 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2181 |     if (file) | 
 | 2182 |       Py_INCREF(file); | 
 | 2183 |     else | 
| Guido van Rossum | 50f385c | 1998-12-04 18:48:44 +0000 | [diff] [blame] | 2184 |       file=Pdata_New(); | 
| Guido van Rossum | 83addc7 | 2000-04-21 20:49:36 +0000 | [diff] [blame] | 2185 |      | 
 | 2186 |     UNLESS (self->file = file)  | 
 | 2187 |       goto err; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2188 |  | 
| Guido van Rossum | 83addc7 | 2000-04-21 20:49:36 +0000 | [diff] [blame] | 2189 |     UNLESS (self->memo = PyDict_New())  | 
 | 2190 |        goto err; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2191 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2192 |     if (PyFile_Check(file)) { | 
 | 2193 |         self->fp = PyFile_AsFile(file); | 
| Guido van Rossum | c91fcaa | 1999-03-29 20:00:14 +0000 | [diff] [blame] | 2194 | 	if (self->fp == NULL) { | 
| Guido van Rossum | 83addc7 | 2000-04-21 20:49:36 +0000 | [diff] [blame] | 2195 | 	    PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); | 
 | 2196 | 	    goto err; | 
| Guido van Rossum | c91fcaa | 1999-03-29 20:00:14 +0000 | [diff] [blame] | 2197 | 	} | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2198 |         self->write_func = write_file; | 
 | 2199 |     } | 
 | 2200 |     else if (PycStringIO_OutputCheck(file)) { | 
 | 2201 |         self->write_func = write_cStringIO; | 
 | 2202 |     } | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 2203 |     else if (file == Py_None) { | 
 | 2204 |         self->write_func = write_none; | 
 | 2205 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2206 |     else { | 
 | 2207 |         self->write_func = write_other; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2208 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2209 |         if (! Pdata_Check(file)) { | 
 | 2210 |           UNLESS (self->write = PyObject_GetAttr(file, write_str)) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2211 |             PyErr_Clear(); | 
 | 2212 |             PyErr_SetString(PyExc_TypeError, "argument must have 'write' " | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2213 |                             "attribute"); | 
 | 2214 |             goto err; | 
 | 2215 |           } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2216 |         } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2217 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2218 |         UNLESS (self->write_buf =  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2219 |             (char *)malloc(WRITE_BUF_SIZE * sizeof(char))) {  | 
 | 2220 |             PyErr_NoMemory(); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2221 |             goto err; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2222 |         } | 
 | 2223 |     } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2224 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2225 |     if (PyEval_GetRestricted()) { | 
 | 2226 |         /* Restricted execution, get private tables */ | 
 | 2227 |         PyObject *m; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2228 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2229 |         UNLESS (m=PyImport_Import(copy_reg_str)) goto err; | 
 | 2230 |         self->dispatch_table=PyObject_GetAttr(m, dispatch_table_str); | 
 | 2231 |         Py_DECREF(m); | 
 | 2232 |         UNLESS (self->dispatch_table) goto err; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2233 |     } | 
 | 2234 |     else { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2235 |         self->dispatch_table=dispatch_table; | 
 | 2236 |         Py_INCREF(dispatch_table); | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2237 |     } | 
 | 2238 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2239 |     return self; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2240 |  | 
 | 2241 | err: | 
 | 2242 |     Py_DECREF((PyObject *)self); | 
 | 2243 |     return NULL; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2244 | } | 
 | 2245 |  | 
 | 2246 |  | 
 | 2247 | static PyObject * | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2248 | get_Pickler(PyObject *self, PyObject *args) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2249 |     PyObject *file=NULL; | 
 | 2250 |     int bin; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2251 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2252 |     bin=1; | 
| Guido van Rossum | 43713e5 | 2000-02-29 13:59:29 +0000 | [diff] [blame] | 2253 |     if (! PyArg_ParseTuple(args, "|i:Pickler", &bin)) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2254 |         PyErr_Clear(); | 
 | 2255 |         bin=0; | 
| Guido van Rossum | 43713e5 | 2000-02-29 13:59:29 +0000 | [diff] [blame] | 2256 |         if (! PyArg_ParseTuple(args, "O|i:Pickler", &file, &bin)) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2257 |           return NULL; | 
 | 2258 |       } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2259 |     return (PyObject *)newPicklerobject(file, bin); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2260 | } | 
 | 2261 |  | 
 | 2262 |  | 
 | 2263 | static void | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2264 | Pickler_dealloc(Picklerobject *self) { | 
 | 2265 |     Py_XDECREF(self->write); | 
 | 2266 |     Py_XDECREF(self->memo); | 
 | 2267 |     Py_XDECREF(self->arg); | 
 | 2268 |     Py_XDECREF(self->file); | 
 | 2269 |     Py_XDECREF(self->pers_func); | 
 | 2270 |     Py_XDECREF(self->inst_pers_func); | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2271 |     Py_XDECREF(self->dispatch_table); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2272 |  | 
 | 2273 |     if (self->write_buf) {     | 
 | 2274 |         free(self->write_buf); | 
 | 2275 |     } | 
 | 2276 |  | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 2277 |     PyObject_Del(self); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2278 | } | 
 | 2279 |  | 
 | 2280 |  | 
 | 2281 | static PyObject * | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2282 | Pickler_getattr(Picklerobject *self, char *name) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2283 |  | 
 | 2284 |   switch (*name) { | 
 | 2285 |   case 'p': | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2286 |     if (strcmp(name, "persistent_id") == 0) { | 
 | 2287 |         if (!self->pers_func) { | 
 | 2288 |             PyErr_SetString(PyExc_AttributeError, name); | 
 | 2289 |             return NULL; | 
 | 2290 |         } | 
 | 2291 |  | 
 | 2292 |         Py_INCREF(self->pers_func); | 
 | 2293 |         return self->pers_func; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2294 |     } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2295 |     break; | 
 | 2296 |   case 'm': | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2297 |     if (strcmp(name, "memo") == 0) { | 
 | 2298 |         if (!self->memo) { | 
 | 2299 |             PyErr_SetString(PyExc_AttributeError, name); | 
 | 2300 |             return NULL; | 
 | 2301 |         } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2302 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2303 |         Py_INCREF(self->memo); | 
 | 2304 |         return self->memo; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2305 |     } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2306 |     break; | 
 | 2307 |   case 'P': | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2308 |     if (strcmp(name, "PicklingError") == 0) { | 
 | 2309 |         Py_INCREF(PicklingError); | 
 | 2310 |         return PicklingError; | 
 | 2311 |     } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2312 |     break; | 
 | 2313 |   case 'b': | 
 | 2314 |     if (strcmp(name, "binary")==0) | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 2315 |       return PyInt_FromLong(self->bin); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2316 |     break; | 
 | 2317 |   case 'f': | 
 | 2318 |     if (strcmp(name, "fast")==0) | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 2319 |       return PyInt_FromLong(self->fast); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2320 |     break; | 
 | 2321 |   case 'g': | 
 | 2322 |     if (strcmp(name, "getvalue")==0 && ! Pdata_Check(self->file)) { | 
 | 2323 |       PyErr_SetString(PyExc_AttributeError, name); | 
 | 2324 |       return NULL; | 
 | 2325 |     } | 
 | 2326 |     break; | 
 | 2327 |   } | 
 | 2328 |   return Py_FindMethod(Pickler_methods, (PyObject *)self, name); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2329 | } | 
 | 2330 |  | 
 | 2331 |  | 
 | 2332 | int  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2333 | Pickler_setattr(Picklerobject *self, char *name, PyObject *value) { | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 2334 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2335 |     if (! value) { | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 2336 |         PyErr_SetString(PyExc_TypeError, | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2337 |                         "attribute deletion is not supported"); | 
 | 2338 |         return -1; | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 2339 |     } | 
 | 2340 |    | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2341 |     if (strcmp(name, "persistent_id") == 0) { | 
 | 2342 |         Py_XDECREF(self->pers_func); | 
 | 2343 |         self->pers_func = value; | 
 | 2344 |         Py_INCREF(value); | 
 | 2345 |         return 0; | 
 | 2346 |     } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2347 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2348 |     if (strcmp(name, "inst_persistent_id") == 0) { | 
 | 2349 |         Py_XDECREF(self->inst_pers_func); | 
 | 2350 |         self->inst_pers_func = value; | 
 | 2351 |         Py_INCREF(value); | 
 | 2352 |         return 0; | 
 | 2353 |     } | 
 | 2354 |  | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 2355 |     if (strcmp(name, "memo") == 0) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2356 |         if (! PyDict_Check(value)) { | 
 | 2357 |           PyErr_SetString(PyExc_TypeError, "memo must be a dictionary"); | 
 | 2358 |           return -1; | 
 | 2359 |         } | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 2360 |         Py_XDECREF(self->memo); | 
 | 2361 |         self->memo = value; | 
 | 2362 |         Py_INCREF(value); | 
 | 2363 |         return 0; | 
 | 2364 |     } | 
 | 2365 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2366 |     if (strcmp(name, "binary")==0) { | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 2367 |         self->bin=PyObject_IsTrue(value); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2368 |         return 0; | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 2369 |     } | 
 | 2370 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2371 |     if (strcmp(name, "fast")==0) { | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 2372 |         self->fast=PyObject_IsTrue(value); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2373 |         return 0; | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 2374 |     } | 
 | 2375 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2376 |     PyErr_SetString(PyExc_AttributeError, name); | 
 | 2377 |     return -1; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2378 | } | 
 | 2379 |  | 
 | 2380 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2381 | static char Picklertype__doc__[] = | 
 | 2382 | "Objects that know how to pickle objects\n" | 
 | 2383 | ; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2384 |  | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 2385 | static PyTypeObject Picklertype = { | 
 | 2386 |     PyObject_HEAD_INIT(NULL) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2387 |     0,                            /*ob_size*/ | 
 | 2388 |     "Pickler",                    /*tp_name*/ | 
 | 2389 |     sizeof(Picklerobject),                /*tp_basicsize*/ | 
 | 2390 |     0,                            /*tp_itemsize*/ | 
 | 2391 |     /* methods */ | 
 | 2392 |     (destructor)Pickler_dealloc,  /*tp_dealloc*/ | 
 | 2393 |     (printfunc)0,         /*tp_print*/ | 
 | 2394 |     (getattrfunc)Pickler_getattr, /*tp_getattr*/ | 
 | 2395 |     (setattrfunc)Pickler_setattr, /*tp_setattr*/ | 
 | 2396 |     (cmpfunc)0,           /*tp_compare*/ | 
 | 2397 |     (reprfunc)0,          /*tp_repr*/ | 
 | 2398 |     0,                    /*tp_as_number*/ | 
 | 2399 |     0,            /*tp_as_sequence*/ | 
 | 2400 |     0,            /*tp_as_mapping*/ | 
 | 2401 |     (hashfunc)0,          /*tp_hash*/ | 
 | 2402 |     (ternaryfunc)0,               /*tp_call*/ | 
 | 2403 |     (reprfunc)0,          /*tp_str*/ | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2404 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2405 |     /* Space for future expansion */ | 
 | 2406 |     0L,0L,0L,0L, | 
 | 2407 |     Picklertype__doc__ /* Documentation string */ | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 2408 | }; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2409 |  | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2410 | static PyObject * | 
| Guido van Rossum | 1b9e0aa | 1999-04-19 17:58:18 +0000 | [diff] [blame] | 2411 | find_class(PyObject *py_module_name, PyObject *py_global_name, PyObject *fc) { | 
| Guido van Rossum | e2d81cd | 1998-08-08 19:40:10 +0000 | [diff] [blame] | 2412 |     PyObject *global = 0, *module; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2413 |  | 
| Guido van Rossum | 1b9e0aa | 1999-04-19 17:58:18 +0000 | [diff] [blame] | 2414 |     if (fc) { | 
 | 2415 |       if (fc==Py_None) { | 
 | 2416 | 	PyErr_SetString(UnpicklingError,  | 
 | 2417 | 			"Global and instance pickles are not supported."); | 
 | 2418 | 	return NULL; | 
 | 2419 |       } | 
 | 2420 |       return PyObject_CallFunction(fc, "OO", py_module_name, py_global_name); | 
 | 2421 |     } | 
 | 2422 |  | 
| Jeremy Hylton | d105523 | 1998-08-11 19:52:51 +0000 | [diff] [blame] | 2423 |     module = PySys_GetObject("modules"); | 
 | 2424 |     if (module == NULL) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2425 |       return NULL; | 
| Jeremy Hylton | d105523 | 1998-08-11 19:52:51 +0000 | [diff] [blame] | 2426 |  | 
 | 2427 |     module = PyDict_GetItem(module, py_module_name); | 
 | 2428 |     if (module == NULL) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2429 |       module = PyImport_Import(py_module_name); | 
 | 2430 |       if (!module) | 
 | 2431 |           return NULL; | 
 | 2432 |       global = PyObject_GetAttr(module, py_global_name); | 
 | 2433 |       Py_DECREF(module); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2434 |     } | 
| Jeremy Hylton | d105523 | 1998-08-11 19:52:51 +0000 | [diff] [blame] | 2435 |     else | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2436 |       global = PyObject_GetAttr(module, py_global_name); | 
| Jeremy Hylton | d105523 | 1998-08-11 19:52:51 +0000 | [diff] [blame] | 2437 |     if (global == NULL) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2438 |       char buf[256 + 37]; | 
 | 2439 |       sprintf(buf, "Failed to import class %.128s from module %.128s", | 
 | 2440 |               PyString_AS_STRING((PyStringObject*)py_global_name), | 
 | 2441 |               PyString_AS_STRING((PyStringObject*)py_module_name));   | 
 | 2442 |       PyErr_SetString(PyExc_SystemError, buf); | 
 | 2443 |       return NULL; | 
| Jeremy Hylton | d105523 | 1998-08-11 19:52:51 +0000 | [diff] [blame] | 2444 |     } | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2445 |     return global; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2446 | } | 
 | 2447 |  | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2448 | static int | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2449 | marker(Unpicklerobject *self) { | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2450 |     if (self->num_marks < 1) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2451 |         PyErr_SetString(UnpicklingError, "could not find MARK"); | 
 | 2452 |         return -1; | 
 | 2453 |     } | 
 | 2454 |  | 
 | 2455 |     return self->marks[--self->num_marks]; | 
 | 2456 | } | 
 | 2457 |  | 
 | 2458 |      | 
 | 2459 | static int | 
 | 2460 | load_none(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2461 |     PDATA_APPEND(self->stack, Py_None, -1); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2462 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2463 | } | 
 | 2464 |  | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 2465 | static int | 
| Thomas Wouters | 58d0510 | 2000-07-24 14:43:35 +0000 | [diff] [blame] | 2466 | bad_readline(void) { | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 2467 |     PyErr_SetString(UnpicklingError, "pickle data was truncated"); | 
 | 2468 |     return -1; | 
 | 2469 | } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2470 |  | 
 | 2471 | static int | 
 | 2472 | load_int(Unpicklerobject *self) { | 
 | 2473 |     PyObject *py_int = 0; | 
 | 2474 |     char *endptr, *s; | 
 | 2475 |     int len, res = -1; | 
 | 2476 |     long l; | 
 | 2477 |  | 
 | 2478 |     if ((len = (*self->readline_func)(self, &s)) < 0) return -1; | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 2479 |     if (len < 2) return bad_readline(); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2480 |     UNLESS (s=pystrndup(s,len)) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2481 |  | 
 | 2482 |     errno = 0; | 
 | 2483 |     l = strtol(s, &endptr, 0); | 
 | 2484 |  | 
 | 2485 |     if (errno || (*endptr != '\n') || (endptr[1] != '\0')) { | 
 | 2486 |         /* Hm, maybe we've got something long.  Let's try reading | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2487 |            it as a Python long object. */ | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2488 |         errno=0; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2489 |         UNLESS (py_int=PyLong_FromString(s,&endptr,0)) goto finally; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2490 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2491 |         if ((*endptr != '\n') || (endptr[1] != '\0')) { | 
 | 2492 |             PyErr_SetString(PyExc_ValueError, | 
 | 2493 |                             "could not convert string to int"); | 
 | 2494 |             goto finally; | 
 | 2495 |         } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2496 |     } | 
 | 2497 |     else { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2498 |         UNLESS (py_int = PyInt_FromLong(l)) goto finally; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2499 |     } | 
 | 2500 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2501 |     free(s); | 
 | 2502 |     PDATA_PUSH(self->stack, py_int, -1); | 
 | 2503 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2504 |  | 
 | 2505 | finally: | 
 | 2506 |     free(s); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2507 |  | 
 | 2508 |     return res; | 
 | 2509 | } | 
 | 2510 |  | 
 | 2511 |  | 
 | 2512 | static long  | 
 | 2513 | calc_binint(char *s, int  x) { | 
 | 2514 |     unsigned char c; | 
 | 2515 |     int i; | 
 | 2516 |     long l; | 
 | 2517 |  | 
 | 2518 |     for (i = 0, l = 0L; i < x; i++) { | 
 | 2519 |         c = (unsigned char)s[i]; | 
 | 2520 |         l |= (long)c << (i * 8); | 
 | 2521 |     } | 
 | 2522 |  | 
 | 2523 |     return l; | 
 | 2524 | } | 
 | 2525 |  | 
 | 2526 |  | 
 | 2527 | static int | 
 | 2528 | load_binintx(Unpicklerobject *self, char *s, int  x) { | 
 | 2529 |     PyObject *py_int = 0; | 
 | 2530 |     long l; | 
 | 2531 |  | 
 | 2532 |     l = calc_binint(s, x); | 
 | 2533 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2534 |     UNLESS (py_int = PyInt_FromLong(l)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2535 |         return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2536 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2537 |     PDATA_PUSH(self->stack, py_int, -1); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2538 |     return 0; | 
 | 2539 | } | 
 | 2540 |  | 
 | 2541 |  | 
 | 2542 | static int | 
 | 2543 | load_binint(Unpicklerobject *self) { | 
 | 2544 |     char *s; | 
 | 2545 |  | 
 | 2546 |     if ((*self->read_func)(self, &s, 4) < 0) | 
 | 2547 |         return -1; | 
 | 2548 |  | 
 | 2549 |     return load_binintx(self, s, 4); | 
 | 2550 | } | 
 | 2551 |  | 
 | 2552 |  | 
 | 2553 | static int | 
 | 2554 | load_binint1(Unpicklerobject *self) { | 
 | 2555 |     char *s; | 
 | 2556 |  | 
 | 2557 |     if ((*self->read_func)(self, &s, 1) < 0) | 
 | 2558 |         return -1; | 
 | 2559 |  | 
 | 2560 |     return load_binintx(self, s, 1); | 
 | 2561 | } | 
 | 2562 |  | 
 | 2563 |  | 
 | 2564 | static int | 
 | 2565 | load_binint2(Unpicklerobject *self) { | 
 | 2566 |     char *s; | 
 | 2567 |  | 
 | 2568 |     if ((*self->read_func)(self, &s, 2) < 0) | 
 | 2569 |         return -1; | 
 | 2570 |  | 
 | 2571 |     return load_binintx(self, s, 2); | 
 | 2572 | } | 
 | 2573 |      | 
 | 2574 | static int | 
 | 2575 | load_long(Unpicklerobject *self) { | 
 | 2576 |     PyObject *l = 0; | 
 | 2577 |     char *end, *s; | 
 | 2578 |     int len, res = -1; | 
 | 2579 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2580 |     if ((len = (*self->readline_func)(self, &s)) < 0) return -1; | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 2581 |     if (len < 2) return bad_readline(); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2582 |     UNLESS (s=pystrndup(s,len)) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2583 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2584 |     UNLESS (l = PyLong_FromString(s, &end, 0)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2585 |         goto finally; | 
 | 2586 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2587 |     free(s); | 
 | 2588 |     PDATA_PUSH(self->stack, l, -1); | 
 | 2589 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2590 |  | 
 | 2591 | finally: | 
 | 2592 |     free(s); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2593 |  | 
 | 2594 |     return res; | 
 | 2595 | } | 
 | 2596 |  | 
 | 2597 |   | 
 | 2598 | static int | 
 | 2599 | load_float(Unpicklerobject *self) { | 
 | 2600 |     PyObject *py_float = 0; | 
 | 2601 |     char *endptr, *s; | 
 | 2602 |     int len, res = -1; | 
 | 2603 |     double d; | 
 | 2604 |  | 
 | 2605 |     if ((len = (*self->readline_func)(self, &s)) < 0) return -1; | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 2606 |     if (len < 2) return bad_readline(); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2607 |     UNLESS (s=pystrndup(s,len)) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2608 |  | 
 | 2609 |     errno = 0; | 
 | 2610 |     d = strtod(s, &endptr); | 
 | 2611 |  | 
 | 2612 |     if (errno || (endptr[0] != '\n') || (endptr[1] != '\0')) { | 
 | 2613 |         PyErr_SetString(PyExc_ValueError,  | 
 | 2614 |         "could not convert string to float"); | 
 | 2615 |         goto finally; | 
 | 2616 |     } | 
 | 2617 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2618 |     UNLESS (py_float = PyFloat_FromDouble(d)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2619 |         goto finally; | 
 | 2620 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2621 |     free(s); | 
 | 2622 |     PDATA_PUSH(self->stack, py_float, -1); | 
 | 2623 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2624 |  | 
 | 2625 | finally: | 
 | 2626 |     free(s); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2627 |  | 
 | 2628 |     return res; | 
 | 2629 | } | 
 | 2630 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2631 | static int | 
 | 2632 | load_binfloat(Unpicklerobject *self) { | 
 | 2633 |     PyObject *py_float = 0; | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 2634 |     int s, e; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2635 |     long fhi, flo; | 
 | 2636 |     double x; | 
 | 2637 |     char *p; | 
 | 2638 |  | 
 | 2639 |     if ((*self->read_func)(self, &p, 8) < 0) | 
 | 2640 |         return -1; | 
 | 2641 |  | 
 | 2642 |     /* First byte */ | 
 | 2643 |     s = (*p>>7) & 1; | 
 | 2644 |     e = (*p & 0x7F) << 4; | 
 | 2645 |     p++; | 
 | 2646 |  | 
 | 2647 |     /* Second byte */ | 
 | 2648 |     e |= (*p>>4) & 0xF; | 
 | 2649 |     fhi = (*p & 0xF) << 24; | 
 | 2650 |     p++; | 
 | 2651 |  | 
 | 2652 |     /* Third byte */ | 
 | 2653 |     fhi |= (*p & 0xFF) << 16; | 
 | 2654 |     p++; | 
 | 2655 |  | 
 | 2656 |     /* Fourth byte */ | 
 | 2657 |     fhi |= (*p & 0xFF) << 8; | 
 | 2658 |     p++; | 
 | 2659 |  | 
 | 2660 |     /* Fifth byte */ | 
 | 2661 |     fhi |= *p & 0xFF; | 
 | 2662 |     p++; | 
 | 2663 |  | 
 | 2664 |     /* Sixth byte */ | 
 | 2665 |     flo = (*p & 0xFF) << 16; | 
 | 2666 |     p++; | 
 | 2667 |  | 
 | 2668 |     /* Seventh byte */ | 
 | 2669 |     flo |= (*p & 0xFF) << 8; | 
 | 2670 |     p++; | 
 | 2671 |  | 
 | 2672 |     /* Eighth byte */ | 
 | 2673 |     flo |= *p & 0xFF; | 
 | 2674 |  | 
 | 2675 |     x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */ | 
 | 2676 |     x /= 268435456.0; /* 2**28 */ | 
 | 2677 |  | 
 | 2678 |     /* XXX This sadly ignores Inf/NaN */ | 
 | 2679 |     if (e == 0) | 
 | 2680 |         e = -1022; | 
 | 2681 |     else { | 
 | 2682 |         x += 1.0; | 
 | 2683 |         e -= 1023; | 
 | 2684 |     } | 
 | 2685 |     x = ldexp(x, e); | 
 | 2686 |  | 
 | 2687 |     if (s) | 
 | 2688 |         x = -x; | 
 | 2689 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2690 |     UNLESS (py_float = PyFloat_FromDouble(x)) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2691 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2692 |     PDATA_PUSH(self->stack, py_float, -1); | 
 | 2693 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2694 | } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2695 |  | 
 | 2696 | static int | 
 | 2697 | load_string(Unpicklerobject *self) { | 
 | 2698 |     PyObject *str = 0; | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 2699 |     int len, res = -1, nslash; | 
 | 2700 |     char *s, q, *p; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2701 |  | 
 | 2702 |     static PyObject *eval_dict = 0; | 
 | 2703 |  | 
 | 2704 |     if ((len = (*self->readline_func)(self, &s)) < 0) return -1; | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 2705 |     if (len < 2) return bad_readline(); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2706 |     UNLESS (s=pystrndup(s,len)) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2707 |  | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 2708 |     /* Check for unquoted quotes (evil strings) */ | 
 | 2709 |     q=*s; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2710 |     if (q != '"' && q != '\'') goto insecure; | 
 | 2711 |     for (p=s+1, nslash=0; *p; p++) { | 
 | 2712 |         if (*p==q && nslash%2==0) break; | 
 | 2713 |         if (*p=='\\') nslash++; | 
 | 2714 |         else nslash=0; | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 2715 |       } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2716 |     if (*p==q) | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 2717 |       { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2718 |         for (p++; *p; p++) if (*p > ' ') goto insecure; | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 2719 |       } | 
 | 2720 |     else goto insecure; | 
 | 2721 |     /********************************************/ | 
 | 2722 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2723 |     UNLESS (eval_dict) | 
 | 2724 |         UNLESS (eval_dict = Py_BuildValue("{s{}}", "__builtins__")) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2725 |             goto finally; | 
 | 2726 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2727 |     UNLESS (str = PyRun_String(s, Py_eval_input, eval_dict, eval_dict)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2728 |         goto finally; | 
 | 2729 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2730 |     free(s); | 
 | 2731 |     PDATA_PUSH(self->stack, str, -1); | 
 | 2732 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2733 |  | 
 | 2734 | finally: | 
 | 2735 |     free(s); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2736 |  | 
 | 2737 |     return res; | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 2738 |      | 
 | 2739 | insecure: | 
 | 2740 |     free(s); | 
 | 2741 |     PyErr_SetString(PyExc_ValueError,"insecure string pickle"); | 
 | 2742 |     return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2743 | }  | 
 | 2744 |  | 
 | 2745 |  | 
 | 2746 | static int | 
 | 2747 | load_binstring(Unpicklerobject *self) { | 
 | 2748 |     PyObject *py_string = 0; | 
 | 2749 |     long l; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2750 |     char *s; | 
 | 2751 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2752 |     if ((*self->read_func)(self, &s, 4) < 0) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2753 |  | 
 | 2754 |     l = calc_binint(s, 4); | 
 | 2755 |  | 
 | 2756 |     if ((*self->read_func)(self, &s, l) < 0) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2757 |         return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2758 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2759 |     UNLESS (py_string = PyString_FromStringAndSize(s, l)) | 
 | 2760 |         return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2761 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2762 |     PDATA_PUSH(self->stack, py_string, -1); | 
 | 2763 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2764 | } | 
 | 2765 |  | 
 | 2766 |  | 
 | 2767 | static int | 
 | 2768 | load_short_binstring(Unpicklerobject *self) { | 
 | 2769 |     PyObject *py_string = 0; | 
 | 2770 |     unsigned char l;   | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2771 |     char *s; | 
 | 2772 |  | 
 | 2773 |     if ((*self->read_func)(self, &s, 1) < 0) | 
 | 2774 |         return -1; | 
 | 2775 |  | 
 | 2776 |     l = (unsigned char)s[0]; | 
 | 2777 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2778 |     if ((*self->read_func)(self, &s, l) < 0) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2779 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2780 |     UNLESS (py_string = PyString_FromStringAndSize(s, l)) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2781 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2782 |     PDATA_PUSH(self->stack, py_string, -1); | 
 | 2783 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2784 | }  | 
 | 2785 |  | 
 | 2786 |  | 
 | 2787 | static int | 
| Guido van Rossum | 5fccb7c | 2000-03-10 23:11:40 +0000 | [diff] [blame] | 2788 | load_unicode(Unpicklerobject *self) { | 
 | 2789 |     PyObject *str = 0; | 
 | 2790 |     int len, res = -1; | 
 | 2791 |     char *s; | 
 | 2792 |  | 
 | 2793 |     if ((len = (*self->readline_func)(self, &s)) < 0) return -1; | 
| Guido van Rossum | fb10c3f | 2000-12-19 02:08:38 +0000 | [diff] [blame] | 2794 |     if (len < 1) return bad_readline(); | 
| Guido van Rossum | 5fccb7c | 2000-03-10 23:11:40 +0000 | [diff] [blame] | 2795 |  | 
 | 2796 |     UNLESS (str = PyUnicode_DecodeRawUnicodeEscape(s, len - 1, NULL)) | 
 | 2797 |         goto finally; | 
 | 2798 |  | 
 | 2799 |     PDATA_PUSH(self->stack, str, -1); | 
 | 2800 |     return 0; | 
 | 2801 |  | 
 | 2802 | finally: | 
 | 2803 |     return res; | 
 | 2804 | }  | 
 | 2805 |  | 
 | 2806 |  | 
 | 2807 | static int | 
 | 2808 | load_binunicode(Unpicklerobject *self) { | 
 | 2809 |     PyObject *unicode; | 
 | 2810 |     long l; | 
 | 2811 |     char *s; | 
 | 2812 |  | 
 | 2813 |     if ((*self->read_func)(self, &s, 4) < 0) return -1; | 
 | 2814 |  | 
 | 2815 |     l = calc_binint(s, 4); | 
 | 2816 |  | 
 | 2817 |     if ((*self->read_func)(self, &s, l) < 0) | 
 | 2818 |         return -1; | 
 | 2819 |  | 
 | 2820 |     UNLESS (unicode = PyUnicode_DecodeUTF8(s, l, NULL)) | 
 | 2821 |         return -1; | 
 | 2822 |  | 
 | 2823 |     PDATA_PUSH(self->stack, unicode, -1); | 
 | 2824 |     return 0; | 
 | 2825 | } | 
 | 2826 |  | 
 | 2827 |  | 
 | 2828 | static int | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2829 | load_tuple(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2830 |     PyObject *tup; | 
 | 2831 |     int i; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2832 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2833 |     if ((i = marker(self)) < 0) return -1; | 
 | 2834 |     UNLESS (tup=Pdata_popTuple(self->stack, i)) return -1; | 
 | 2835 |     PDATA_PUSH(self->stack, tup, -1); | 
 | 2836 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2837 | } | 
 | 2838 |  | 
 | 2839 | static int | 
 | 2840 | load_empty_tuple(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2841 |     PyObject *tup; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2842 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2843 |     UNLESS (tup=PyTuple_New(0)) return -1; | 
 | 2844 |     PDATA_PUSH(self->stack, tup, -1); | 
 | 2845 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2846 | } | 
 | 2847 |  | 
 | 2848 | static int | 
 | 2849 | load_empty_list(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2850 |     PyObject *list; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2851 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2852 |     UNLESS (list=PyList_New(0)) return -1; | 
 | 2853 |     PDATA_PUSH(self->stack, list, -1); | 
 | 2854 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2855 | } | 
 | 2856 |  | 
 | 2857 | static int | 
 | 2858 | load_empty_dict(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2859 |     PyObject *dict; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2860 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2861 |     UNLESS (dict=PyDict_New()) return -1; | 
 | 2862 |     PDATA_PUSH(self->stack, dict, -1); | 
 | 2863 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2864 | } | 
 | 2865 |  | 
 | 2866 |  | 
 | 2867 | static int | 
 | 2868 | load_list(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2869 |     PyObject *list = 0; | 
 | 2870 |     int i; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2871 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2872 |     if ((i = marker(self)) < 0) return -1; | 
 | 2873 |     UNLESS (list=Pdata_popList(self->stack, i)) return -1; | 
 | 2874 |     PDATA_PUSH(self->stack, list, -1); | 
 | 2875 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2876 | } | 
 | 2877 |  | 
 | 2878 | static int | 
 | 2879 | load_dict(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2880 |     PyObject *dict, *key, *value; | 
 | 2881 |     int i, j, k; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2882 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2883 |     if ((i = marker(self)) < 0) return -1; | 
 | 2884 |     j=self->stack->length; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2885 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2886 |     UNLESS (dict = PyDict_New()) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2887 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2888 |     for (k = i+1; k < j; k += 2) { | 
 | 2889 |         key  =self->stack->data[k-1]; | 
 | 2890 |         value=self->stack->data[k  ]; | 
 | 2891 |         if (PyDict_SetItem(dict, key, value) < 0) { | 
 | 2892 |             Py_DECREF(dict); | 
 | 2893 |             return -1; | 
 | 2894 |         } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2895 |     } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2896 |     Pdata_clear(self->stack, i); | 
 | 2897 |     PDATA_PUSH(self->stack, dict, -1); | 
 | 2898 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2899 | } | 
 | 2900 |  | 
 | 2901 | static PyObject * | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2902 | Instance_New(PyObject *cls, PyObject *args) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2903 |   int has_key; | 
 | 2904 |   PyObject *safe=0, *r=0; | 
 | 2905 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2906 |   if (PyClass_Check(cls)) { | 
 | 2907 |       int l; | 
 | 2908 |        | 
| Jeremy Hylton | 03657cf | 2000-07-12 13:05:33 +0000 | [diff] [blame] | 2909 |       if ((l=PyObject_Size(args)) < 0) goto err; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2910 |       UNLESS (l) { | 
 | 2911 |           PyObject *__getinitargs__; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2912 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2913 |           UNLESS (__getinitargs__=PyObject_GetAttr(cls, __getinitargs___str)) { | 
 | 2914 |               /* We have a class with no __getinitargs__, so bypass usual | 
 | 2915 |                  construction  */ | 
 | 2916 |               PyInstanceObject *inst; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2917 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2918 |               PyErr_Clear(); | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 2919 |               UNLESS (inst=PyObject_New(PyInstanceObject, &PyInstance_Type)) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2920 |                 goto err; | 
 | 2921 |               inst->in_class=(PyClassObject*)cls; | 
 | 2922 |               Py_INCREF(cls); | 
 | 2923 |               UNLESS (inst->in_dict=PyDict_New()) { | 
| Neil Schemenauer | 5196c58 | 2000-10-04 16:22:26 +0000 | [diff] [blame] | 2924 |                 inst = (PyInstanceObject *) PyObject_AS_GC(inst); | 
 | 2925 |                 PyObject_DEL(inst); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2926 |                 goto err; | 
 | 2927 |               } | 
| Jeremy Hylton | c5007aa | 2000-06-30 05:02:53 +0000 | [diff] [blame] | 2928 |               PyObject_GC_Init(inst); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2929 |               return (PyObject *)inst; | 
 | 2930 |             } | 
 | 2931 |           Py_DECREF(__getinitargs__); | 
 | 2932 |         } | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2933 |        | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2934 |       if ((r=PyInstance_New(cls, args, NULL))) return r; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 2935 |       else goto err; | 
 | 2936 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2937 |         | 
 | 2938 |    | 
 | 2939 |   if ((has_key = cPickle_PyMapping_HasKey(safe_constructors, cls)) < 0) | 
 | 2940 |     goto err; | 
 | 2941 |      | 
 | 2942 |   if (!has_key) | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2943 |     if (!(safe = PyObject_GetAttr(cls, __safe_for_unpickling___str)) || | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2944 |        !PyObject_IsTrue(safe)) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2945 |       cPickle_ErrFormat(UnpicklingError, | 
 | 2946 |                         "%s is not safe for unpickling", "O", cls); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2947 |       Py_XDECREF(safe); | 
 | 2948 |       return NULL; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 2949 |   } | 
 | 2950 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2951 |   if (args==Py_None) { | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 2952 |       /* Special case, call cls.__basicnew__() */ | 
 | 2953 |       PyObject *basicnew; | 
 | 2954 |        | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2955 |       UNLESS (basicnew=PyObject_GetAttr(cls, __basicnew___str)) return NULL; | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 2956 |       r=PyObject_CallObject(basicnew, NULL); | 
 | 2957 |       Py_DECREF(basicnew); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2958 |       if (r) return r; | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 2959 |     } | 
 | 2960 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2961 |   if ((r=PyObject_CallObject(cls, args))) return r; | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 2962 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2963 | err: | 
 | 2964 |   { | 
 | 2965 |     PyObject *tp, *v, *tb; | 
 | 2966 |  | 
 | 2967 |     PyErr_Fetch(&tp, &v, &tb); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2968 |     if ((r=Py_BuildValue("OOO",v,cls,args))) { | 
 | 2969 |         Py_XDECREF(v); | 
 | 2970 |         v=r; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2971 |       } | 
 | 2972 |     PyErr_Restore(tp,v,tb); | 
 | 2973 |   } | 
 | 2974 |   return NULL; | 
 | 2975 | } | 
 | 2976 |    | 
 | 2977 |  | 
 | 2978 | static int | 
 | 2979 | load_obj(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2980 |     PyObject *class, *tup, *obj=0; | 
 | 2981 |     int i; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2982 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2983 |     if ((i = marker(self)) < 0) return -1; | 
 | 2984 |     UNLESS (tup=Pdata_popTuple(self->stack, i+1)) return -1; | 
 | 2985 |     PDATA_POP(self->stack, class); | 
 | 2986 |     if (class) { | 
 | 2987 |         obj = Instance_New(class, tup); | 
 | 2988 |         Py_DECREF(class); | 
 | 2989 |     } | 
 | 2990 |     Py_DECREF(tup); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2991 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 2992 |     if (! obj) return -1; | 
 | 2993 |     PDATA_PUSH(self->stack, obj, -1); | 
 | 2994 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 2995 | } | 
 | 2996 |  | 
 | 2997 |  | 
 | 2998 | static int | 
 | 2999 | load_inst(Unpicklerobject *self) { | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 3000 |     PyObject *tup, *class=0, *obj=0, *module_name, *class_name; | 
| Guido van Rossum | e94e3fb | 1998-12-08 17:37:19 +0000 | [diff] [blame] | 3001 |     int i, len; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3002 |     char *s; | 
 | 3003 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3004 |     if ((i = marker(self)) < 0) return -1; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3005 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3006 |     if ((len = (*self->readline_func)(self, &s)) < 0) return -1; | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 3007 |     if (len < 2) return bad_readline(); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3008 |     UNLESS (module_name = PyString_FromStringAndSize(s, len - 1)) return -1; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3009 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3010 |     if ((len = (*self->readline_func)(self, &s)) >= 0) { | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 3011 |         if (len < 2) return bad_readline(); | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 3012 |         if ((class_name = PyString_FromStringAndSize(s, len - 1))) { | 
| Guido van Rossum | 1b9e0aa | 1999-04-19 17:58:18 +0000 | [diff] [blame] | 3013 |             class = find_class(module_name, class_name, self->find_class); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3014 |             Py_DECREF(class_name); | 
 | 3015 |         } | 
 | 3016 |     } | 
 | 3017 |     Py_DECREF(module_name); | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3018 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3019 |     if (! class) return -1; | 
 | 3020 |        | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 3021 |     if ((tup=Pdata_popTuple(self->stack, i))) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3022 |         obj = Instance_New(class, tup); | 
 | 3023 |         Py_DECREF(tup); | 
 | 3024 |     } | 
 | 3025 |     Py_DECREF(class); | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3026 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3027 |     if (! obj) return -1; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3028 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3029 |     PDATA_PUSH(self->stack, obj, -1); | 
 | 3030 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3031 | } | 
 | 3032 |  | 
 | 3033 |  | 
 | 3034 | static int | 
 | 3035 | load_global(Unpicklerobject *self) { | 
 | 3036 |     PyObject *class = 0, *module_name = 0, *class_name = 0; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3037 |     int len; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3038 |     char *s; | 
 | 3039 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3040 |     if ((len = (*self->readline_func)(self, &s)) < 0) return -1; | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 3041 |     if (len < 2) return bad_readline(); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3042 |     UNLESS (module_name = PyString_FromStringAndSize(s, len - 1)) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3043 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3044 |     if ((len = (*self->readline_func)(self, &s)) >= 0) { | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 3045 |         if (len < 2) return bad_readline(); | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 3046 |         if ((class_name = PyString_FromStringAndSize(s, len - 1))) { | 
| Guido van Rossum | 1b9e0aa | 1999-04-19 17:58:18 +0000 | [diff] [blame] | 3047 |             class = find_class(module_name, class_name, self->find_class); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3048 |             Py_DECREF(class_name); | 
 | 3049 |         } | 
 | 3050 |     } | 
 | 3051 |     Py_DECREF(module_name); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3052 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3053 |     if (! class) return -1; | 
 | 3054 |     PDATA_PUSH(self->stack, class, -1); | 
 | 3055 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3056 | } | 
 | 3057 |  | 
 | 3058 |  | 
 | 3059 | static int | 
 | 3060 | load_persid(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3061 |     PyObject *pid = 0; | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 3062 |     int len; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3063 |     char *s; | 
 | 3064 |  | 
 | 3065 |     if (self->pers_func) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3066 |         if ((len = (*self->readline_func)(self, &s)) < 0) return -1; | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 3067 | 	if (len < 2) return bad_readline(); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3068 |    | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3069 |         UNLESS (pid = PyString_FromStringAndSize(s, len - 1)) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3070 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3071 |         if (PyList_Check(self->pers_func)) { | 
 | 3072 |             if (PyList_Append(self->pers_func, pid) < 0) { | 
 | 3073 |                 Py_DECREF(pid); | 
 | 3074 |                 return -1; | 
 | 3075 |             } | 
 | 3076 |         } | 
 | 3077 |         else { | 
 | 3078 |             ARG_TUP(self, pid); | 
 | 3079 |             if (self->arg) { | 
 | 3080 |                 pid = PyObject_CallObject(self->pers_func, self->arg); | 
 | 3081 |                 FREE_ARG_TUP(self); | 
 | 3082 |             } | 
 | 3083 |         } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3084 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3085 |         if (! pid) return -1; | 
 | 3086 |  | 
 | 3087 |         PDATA_PUSH(self->stack, pid, -1); | 
 | 3088 |         return 0; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3089 |     } | 
 | 3090 |     else { | 
 | 3091 |       PyErr_SetString(UnpicklingError, | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3092 |                       "A load persistent id instruction was encountered,\n" | 
 | 3093 |                       "but no persistent_load function was specified."); | 
 | 3094 |       return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3095 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3096 | } | 
 | 3097 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3098 | static int | 
 | 3099 | load_binpersid(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3100 |     PyObject *pid = 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3101 |  | 
 | 3102 |     if (self->pers_func) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3103 |         PDATA_POP(self->stack, pid); | 
 | 3104 |         if (! pid) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3105 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3106 |         if (PyList_Check(self->pers_func)) { | 
 | 3107 |             if (PyList_Append(self->pers_func, pid) < 0) { | 
 | 3108 |                 Py_DECREF(pid); | 
 | 3109 |                 return -1; | 
 | 3110 |             } | 
 | 3111 |           } | 
 | 3112 |         else { | 
 | 3113 |             ARG_TUP(self, pid); | 
 | 3114 |             if (self->arg) { | 
 | 3115 |                 pid = PyObject_CallObject(self->pers_func, self->arg); | 
 | 3116 |                 FREE_ARG_TUP(self); | 
 | 3117 |             } | 
 | 3118 |             if (! pid) return -1; | 
 | 3119 |         } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3120 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3121 |         PDATA_PUSH(self->stack, pid, -1); | 
 | 3122 |         return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3123 |     } | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3124 |     else { | 
 | 3125 |       PyErr_SetString(UnpicklingError, | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3126 |                       "A load persistent id instruction was encountered,\n" | 
 | 3127 |                       "but no persistent_load function was specified."); | 
 | 3128 |       return -1; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3129 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3130 | } | 
 | 3131 |  | 
 | 3132 |  | 
 | 3133 | static int | 
 | 3134 | load_pop(Unpicklerobject *self) { | 
 | 3135 |     int len; | 
 | 3136 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3137 |     UNLESS ((len=self->stack->length) > 0) return stackUnderflow(); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3138 |  | 
| Guido van Rossum | ea2b715 | 2000-05-09 18:14:50 +0000 | [diff] [blame] | 3139 |     /* Note that we split the (pickle.py) stack into two stacks,  | 
 | 3140 |        an object stack and a mark stack. We have to be clever and | 
 | 3141 |        pop the right one. We do this by looking at the top of the | 
 | 3142 |        mark stack. | 
 | 3143 |     */ | 
 | 3144 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3145 |     if ((self->num_marks > 0) &&  | 
 | 3146 |         (self->marks[self->num_marks - 1] == len)) | 
 | 3147 |         self->num_marks--; | 
| Guido van Rossum | ea2b715 | 2000-05-09 18:14:50 +0000 | [diff] [blame] | 3148 |     else {  | 
 | 3149 |         len--; | 
 | 3150 |         Py_DECREF(self->stack->data[len]); | 
 | 3151 | 	self->stack->length=len; | 
 | 3152 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3153 |  | 
 | 3154 |     return 0; | 
 | 3155 | } | 
 | 3156 |  | 
 | 3157 |  | 
 | 3158 | static int | 
 | 3159 | load_pop_mark(Unpicklerobject *self) { | 
| Guido van Rossum | e94e3fb | 1998-12-08 17:37:19 +0000 | [diff] [blame] | 3160 |     int i; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3161 |  | 
 | 3162 |     if ((i = marker(self)) < 0) | 
 | 3163 |         return -1; | 
 | 3164 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3165 |     Pdata_clear(self->stack, i); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3166 |  | 
 | 3167 |     return 0; | 
 | 3168 | } | 
 | 3169 |  | 
 | 3170 |  | 
 | 3171 | static int | 
 | 3172 | load_dup(Unpicklerobject *self) { | 
 | 3173 |     PyObject *last; | 
 | 3174 |     int len; | 
 | 3175 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3176 |     if ((len = self->stack->length) <= 0) return stackUnderflow(); | 
 | 3177 |     last=self->stack->data[len-1]; | 
 | 3178 |     Py_INCREF(last); | 
 | 3179 |     PDATA_PUSH(self->stack, last, -1); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3180 |     return 0; | 
 | 3181 | } | 
 | 3182 |  | 
 | 3183 |  | 
 | 3184 | static int | 
 | 3185 | load_get(Unpicklerobject *self) { | 
 | 3186 |     PyObject *py_str = 0, *value = 0; | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 3187 |     int len; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3188 |     char *s; | 
| Guido van Rossum | 2f80d96 | 1999-07-13 15:18:58 +0000 | [diff] [blame] | 3189 |     int rc; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3190 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3191 |     if ((len = (*self->readline_func)(self, &s)) < 0) return -1; | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 3192 |     if (len < 2) return bad_readline(); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3193 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3194 |     UNLESS (py_str = PyString_FromStringAndSize(s, len - 1)) return -1; | 
 | 3195 |  | 
 | 3196 |     value = PyDict_GetItem(self->memo, py_str); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3197 |     if (! value) { | 
 | 3198 |         PyErr_SetObject(BadPickleGet, py_str); | 
| Guido van Rossum | 2f80d96 | 1999-07-13 15:18:58 +0000 | [diff] [blame] | 3199 |         rc = -1; | 
 | 3200 |     } else { | 
 | 3201 |       PDATA_APPEND(self->stack, value, -1); | 
 | 3202 |       rc = 0; | 
 | 3203 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3204 |  | 
| Guido van Rossum | 2f80d96 | 1999-07-13 15:18:58 +0000 | [diff] [blame] | 3205 |     Py_DECREF(py_str); | 
 | 3206 |     return rc; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3207 | } | 
 | 3208 |  | 
 | 3209 |  | 
 | 3210 | static int | 
 | 3211 | load_binget(Unpicklerobject *self) { | 
 | 3212 |     PyObject *py_key = 0, *value = 0; | 
 | 3213 |     unsigned char key; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3214 |     char *s; | 
| Guido van Rossum | 2f80d96 | 1999-07-13 15:18:58 +0000 | [diff] [blame] | 3215 |     int rc; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3216 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3217 |     if ((*self->read_func)(self, &s, 1) < 0) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3218 |  | 
 | 3219 |     key = (unsigned char)s[0]; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3220 |     UNLESS (py_key = PyInt_FromLong((long)key)) return -1; | 
 | 3221 |      | 
 | 3222 |     value = PyDict_GetItem(self->memo, py_key); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3223 |     if (! value) { | 
 | 3224 |         PyErr_SetObject(BadPickleGet, py_key); | 
| Guido van Rossum | 2f80d96 | 1999-07-13 15:18:58 +0000 | [diff] [blame] | 3225 |         rc = -1; | 
 | 3226 |     } else { | 
 | 3227 |       PDATA_APPEND(self->stack, value, -1); | 
 | 3228 |       rc = 0; | 
 | 3229 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3230 |  | 
| Guido van Rossum | 2f80d96 | 1999-07-13 15:18:58 +0000 | [diff] [blame] | 3231 |     Py_DECREF(py_key); | 
 | 3232 |     return rc; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3233 | } | 
 | 3234 |  | 
 | 3235 |  | 
 | 3236 | static int | 
 | 3237 | load_long_binget(Unpicklerobject *self) { | 
 | 3238 |     PyObject *py_key = 0, *value = 0; | 
| Thomas Wouters | 3b6448f | 2000-07-22 23:56:07 +0000 | [diff] [blame] | 3239 |     unsigned char c; | 
 | 3240 |     char *s; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3241 |     long key; | 
| Guido van Rossum | 2f80d96 | 1999-07-13 15:18:58 +0000 | [diff] [blame] | 3242 |     int rc; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3243 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3244 |     if ((*self->read_func)(self, &s, 4) < 0) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3245 |  | 
 | 3246 |     c = (unsigned char)s[0]; | 
 | 3247 |     key = (long)c; | 
 | 3248 |     c = (unsigned char)s[1]; | 
 | 3249 |     key |= (long)c << 8; | 
 | 3250 |     c = (unsigned char)s[2]; | 
 | 3251 |     key |= (long)c << 16; | 
 | 3252 |     c = (unsigned char)s[3]; | 
 | 3253 |     key |= (long)c << 24; | 
 | 3254 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3255 |     UNLESS (py_key = PyInt_FromLong((long)key)) return -1; | 
 | 3256 |      | 
 | 3257 |     value = PyDict_GetItem(self->memo, py_key); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3258 |     if (! value) { | 
 | 3259 |         PyErr_SetObject(BadPickleGet, py_key); | 
| Guido van Rossum | 2f80d96 | 1999-07-13 15:18:58 +0000 | [diff] [blame] | 3260 |         rc = -1; | 
 | 3261 |     } else { | 
 | 3262 |       PDATA_APPEND(self->stack, value, -1); | 
 | 3263 |       rc = 0; | 
 | 3264 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3265 |  | 
| Guido van Rossum | 2f80d96 | 1999-07-13 15:18:58 +0000 | [diff] [blame] | 3266 |     Py_DECREF(py_key); | 
 | 3267 |     return rc; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3268 | } | 
 | 3269 |  | 
 | 3270 |  | 
 | 3271 | static int | 
 | 3272 | load_put(Unpicklerobject *self) { | 
 | 3273 |     PyObject *py_str = 0, *value = 0; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3274 |     int len, l; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3275 |     char *s; | 
 | 3276 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3277 |     if ((l = (*self->readline_func)(self, &s)) < 0) return -1; | 
| Guido van Rossum | d1f66dc | 1999-02-08 22:38:25 +0000 | [diff] [blame] | 3278 |     if (l < 2) return bad_readline(); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3279 |     UNLESS (len=self->stack->length) return stackUnderflow(); | 
 | 3280 |     UNLESS (py_str = PyString_FromStringAndSize(s, l - 1)) return -1; | 
 | 3281 |     value=self->stack->data[len-1]; | 
 | 3282 |     l=PyDict_SetItem(self->memo, py_str, value); | 
 | 3283 |     Py_DECREF(py_str); | 
 | 3284 |     return l; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3285 | } | 
 | 3286 |  | 
 | 3287 |  | 
 | 3288 | static int | 
 | 3289 | load_binput(Unpicklerobject *self) { | 
 | 3290 |     PyObject *py_key = 0, *value = 0; | 
| Thomas Wouters | 3b6448f | 2000-07-22 23:56:07 +0000 | [diff] [blame] | 3291 |     unsigned char key; | 
 | 3292 |     char *s; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3293 |     int len; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3294 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3295 |     if ((*self->read_func)(self, &s, 1) < 0) return -1; | 
 | 3296 |     UNLESS ((len=self->stack->length) > 0) return stackUnderflow(); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3297 |  | 
 | 3298 |     key = (unsigned char)s[0]; | 
 | 3299 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3300 |     UNLESS (py_key = PyInt_FromLong((long)key)) return -1; | 
 | 3301 |     value=self->stack->data[len-1]; | 
 | 3302 |     len=PyDict_SetItem(self->memo, py_key, value); | 
 | 3303 |     Py_DECREF(py_key); | 
 | 3304 |     return len; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3305 | } | 
 | 3306 |  | 
 | 3307 |  | 
 | 3308 | static int | 
 | 3309 | load_long_binput(Unpicklerobject *self) { | 
 | 3310 |     PyObject *py_key = 0, *value = 0; | 
 | 3311 |     long key; | 
| Thomas Wouters | 3b6448f | 2000-07-22 23:56:07 +0000 | [diff] [blame] | 3312 |     unsigned char c; | 
 | 3313 |     char *s; | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 3314 |     int len; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3315 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3316 |     if ((*self->read_func)(self, &s, 4) < 0) return -1; | 
 | 3317 |     UNLESS (len=self->stack->length) return stackUnderflow(); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3318 |  | 
 | 3319 |     c = (unsigned char)s[0]; | 
 | 3320 |     key = (long)c; | 
 | 3321 |     c = (unsigned char)s[1]; | 
 | 3322 |     key |= (long)c << 8; | 
 | 3323 |     c = (unsigned char)s[2]; | 
 | 3324 |     key |= (long)c << 16; | 
 | 3325 |     c = (unsigned char)s[3]; | 
 | 3326 |     key |= (long)c << 24; | 
 | 3327 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3328 |     UNLESS (py_key = PyInt_FromLong(key)) return -1; | 
 | 3329 |     value=self->stack->data[len-1]; | 
 | 3330 |     len=PyDict_SetItem(self->memo, py_key, value); | 
 | 3331 |     Py_DECREF(py_key); | 
 | 3332 |     return len; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3333 | } | 
 | 3334 |  | 
 | 3335 |  | 
 | 3336 | static int  | 
 | 3337 | do_append(Unpicklerobject *self, int  x) { | 
 | 3338 |     PyObject *value = 0, *list = 0, *append_method = 0; | 
 | 3339 |     int len, i; | 
 | 3340 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3341 |     UNLESS ((len=self->stack->length) >= x && x > 0) return stackUnderflow(); | 
 | 3342 |     if (len==x) return 0;       /* nothing to do */ | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3343 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3344 |     list=self->stack->data[x-1]; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3345 |  | 
 | 3346 |     if (PyList_Check(list)) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3347 |         PyObject *slice; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3348 |         int list_len; | 
 | 3349 |         | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3350 |         slice=Pdata_popList(self->stack, x); | 
 | 3351 |         list_len = PyList_GET_SIZE(list); | 
 | 3352 |         i=PyList_SetSlice(list, list_len, list_len, slice); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3353 |         Py_DECREF(slice); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3354 |         return i; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3355 |     } | 
 | 3356 |     else { | 
 | 3357 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3358 |         UNLESS (append_method = PyObject_GetAttr(list, append_str)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3359 |             return -1; | 
 | 3360 |           | 
 | 3361 |         for (i = x; i < len; i++) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3362 |             PyObject *junk; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3363 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3364 |             value=self->stack->data[i]; | 
 | 3365 |             junk=0; | 
 | 3366 |             ARG_TUP(self, value); | 
 | 3367 |             if (self->arg) { | 
 | 3368 |               junk = PyObject_CallObject(append_method, self->arg); | 
 | 3369 |               FREE_ARG_TUP(self); | 
 | 3370 |             } | 
 | 3371 |             if (! junk) { | 
 | 3372 |                 Pdata_clear(self->stack, i+1); | 
 | 3373 |                 self->stack->length=x; | 
 | 3374 |                 Py_DECREF(append_method); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3375 |                 return -1; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3376 |             } | 
 | 3377 |             Py_DECREF(junk); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3378 |         } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3379 |         self->stack->length=x; | 
 | 3380 |         Py_DECREF(append_method); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3381 |     } | 
 | 3382 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3383 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3384 | } | 
 | 3385 |  | 
 | 3386 |      | 
 | 3387 | static int | 
 | 3388 | load_append(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3389 |     return do_append(self, self->stack->length - 1); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3390 | } | 
 | 3391 |  | 
 | 3392 |  | 
 | 3393 | static int | 
 | 3394 | load_appends(Unpicklerobject *self) { | 
 | 3395 |     return do_append(self, marker(self)); | 
 | 3396 | } | 
 | 3397 |  | 
 | 3398 |  | 
 | 3399 | static int | 
 | 3400 | do_setitems(Unpicklerobject *self, int  x) { | 
 | 3401 |     PyObject *value = 0, *key = 0, *dict = 0; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3402 |     int len, i, r=0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3403 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3404 |     UNLESS ((len=self->stack->length) >= x | 
 | 3405 |             && x > 0) return stackUnderflow(); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3406 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3407 |     dict=self->stack->data[x-1]; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3408 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3409 |     for (i = x+1; i < len; i += 2) { | 
 | 3410 |         key  =self->stack->data[i-1]; | 
 | 3411 |         value=self->stack->data[i  ]; | 
 | 3412 |         if (PyObject_SetItem(dict, key, value) < 0) { | 
 | 3413 |             r=-1; | 
 | 3414 |             break; | 
 | 3415 |         } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3416 |     } | 
 | 3417 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3418 |     Pdata_clear(self->stack, x); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3419 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3420 |     return r; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3421 | } | 
 | 3422 |  | 
 | 3423 |  | 
 | 3424 | static int | 
 | 3425 | load_setitem(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3426 |     return do_setitems(self, self->stack->length - 2); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3427 | } | 
 | 3428 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3429 | static int | 
 | 3430 | load_setitems(Unpicklerobject *self) { | 
 | 3431 |     return do_setitems(self, marker(self)); | 
 | 3432 | } | 
 | 3433 |  | 
 | 3434 |  | 
 | 3435 | static int | 
 | 3436 | load_build(Unpicklerobject *self) { | 
 | 3437 |     PyObject *value = 0, *inst = 0, *instdict = 0, *d_key = 0, *d_value = 0,  | 
 | 3438 |              *junk = 0, *__setstate__ = 0; | 
| Guido van Rossum | e94e3fb | 1998-12-08 17:37:19 +0000 | [diff] [blame] | 3439 |     int i, r = 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3440 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3441 |     if (self->stack->length < 2) return stackUnderflow(); | 
 | 3442 |     PDATA_POP(self->stack, value); | 
 | 3443 |     if (! value) return -1; | 
 | 3444 |     inst=self->stack->data[self->stack->length-1]; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3445 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3446 |     if ((__setstate__ = PyObject_GetAttr(inst, __setstate___str))) { | 
 | 3447 |         ARG_TUP(self, value); | 
 | 3448 |         if (self->arg) { | 
 | 3449 |             junk = PyObject_CallObject(__setstate__, self->arg); | 
 | 3450 |             FREE_ARG_TUP(self); | 
 | 3451 |         } | 
 | 3452 |         Py_DECREF(__setstate__); | 
 | 3453 |         if (! junk) return -1; | 
 | 3454 |         Py_DECREF(junk); | 
 | 3455 |         return 0; | 
 | 3456 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3457 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3458 |     PyErr_Clear(); | 
 | 3459 |     if ((instdict = PyObject_GetAttr(inst, __dict___str))) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3460 |         i = 0; | 
 | 3461 |         while (PyDict_Next(value, &i, &d_key, &d_value)) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3462 |             if (PyObject_SetItem(instdict, d_key, d_value) < 0) { | 
 | 3463 |                 r=-1; | 
 | 3464 |                 break; | 
 | 3465 |             } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3466 |         } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3467 |         Py_DECREF(instdict); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3468 |     } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3469 |     else r=-1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3470 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3471 |     Py_XDECREF(value); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3472 |    | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3473 |     return r; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3474 | } | 
 | 3475 |  | 
 | 3476 |  | 
 | 3477 | static int | 
 | 3478 | load_mark(Unpicklerobject *self) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3479 |     int s; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3480 |  | 
| Guido van Rossum | ea2b715 | 2000-05-09 18:14:50 +0000 | [diff] [blame] | 3481 |     /* Note that we split the (pickle.py) stack into two stacks, an | 
 | 3482 |        object stack and a mark stack. Here we push a mark onto the | 
 | 3483 |        mark stack.   | 
 | 3484 |     */ | 
 | 3485 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3486 |     if ((self->num_marks + 1) >= self->marks_size) { | 
 | 3487 |         s=self->marks_size+20; | 
 | 3488 |         if (s <= self->num_marks) s=self->num_marks + 1; | 
| Guido van Rossum | 761fcd0 | 1999-04-12 22:51:20 +0000 | [diff] [blame] | 3489 |         if (self->marks == NULL) | 
| Guido van Rossum | aa8d167 | 1999-01-25 21:43:51 +0000 | [diff] [blame] | 3490 |             self->marks=(int *)malloc(s * sizeof(int)); | 
 | 3491 |         else | 
 | 3492 |             self->marks=(int *)realloc(self->marks, s * sizeof(int)); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3493 |         if (! self->marks) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3494 |             PyErr_NoMemory(); | 
 | 3495 |             return -1; | 
 | 3496 |         } | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3497 |         self->marks_size = s; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3498 |     } | 
 | 3499 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3500 |     self->marks[self->num_marks++] = self->stack->length; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3501 |  | 
 | 3502 |     return 0; | 
 | 3503 | } | 
 | 3504 |  | 
 | 3505 | static int | 
 | 3506 | load_reduce(Unpicklerobject *self) { | 
 | 3507 |     PyObject *callable = 0, *arg_tup = 0, *ob = 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3508 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3509 |     PDATA_POP(self->stack, arg_tup); | 
 | 3510 |     if (! arg_tup) return -1; | 
 | 3511 |     PDATA_POP(self->stack, callable); | 
 | 3512 |     if (callable) { | 
 | 3513 |         ob = Instance_New(callable, arg_tup); | 
 | 3514 |         Py_DECREF(callable); | 
 | 3515 |     } | 
 | 3516 |     Py_DECREF(arg_tup); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3517 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3518 |     if (! ob) return -1; | 
 | 3519 |     | 
 | 3520 |     PDATA_PUSH(self->stack, ob, -1); | 
 | 3521 |     return 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3522 | } | 
 | 3523 |      | 
 | 3524 | static PyObject * | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3525 | load(Unpicklerobject *self) { | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 3526 |     PyObject *err = 0, *val = 0; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3527 |     char *s; | 
 | 3528 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3529 |     self->num_marks = 0; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3530 |     if (self->stack->length) Pdata_clear(self->stack, 0); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3531 |  | 
 | 3532 |     while (1) { | 
 | 3533 |         if ((*self->read_func)(self, &s, 1) < 0) | 
 | 3534 |             break; | 
 | 3535 |  | 
 | 3536 |         switch (s[0]) { | 
 | 3537 |             case NONE: | 
 | 3538 |                 if (load_none(self) < 0) | 
 | 3539 |                     break; | 
 | 3540 |                 continue; | 
 | 3541 |  | 
 | 3542 |             case BININT: | 
 | 3543 |                  if (load_binint(self) < 0) | 
 | 3544 |                      break; | 
 | 3545 |                  continue; | 
 | 3546 |  | 
 | 3547 |             case BININT1: | 
 | 3548 |                 if (load_binint1(self) < 0) | 
 | 3549 |                     break; | 
 | 3550 |                 continue; | 
 | 3551 |  | 
 | 3552 |             case BININT2: | 
 | 3553 |                 if (load_binint2(self) < 0) | 
 | 3554 |                     break; | 
 | 3555 |                 continue; | 
 | 3556 |  | 
 | 3557 |             case INT: | 
 | 3558 |                 if (load_int(self) < 0) | 
 | 3559 |                     break; | 
 | 3560 |                 continue; | 
 | 3561 |  | 
 | 3562 |             case LONG: | 
 | 3563 |                 if (load_long(self) < 0) | 
 | 3564 |                     break; | 
 | 3565 |                 continue; | 
 | 3566 |  | 
 | 3567 |             case FLOAT: | 
 | 3568 |                 if (load_float(self) < 0) | 
 | 3569 |                     break; | 
 | 3570 |                 continue; | 
 | 3571 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3572 |             case BINFLOAT: | 
 | 3573 |                 if (load_binfloat(self) < 0) | 
 | 3574 |                     break; | 
 | 3575 |                 continue; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3576 |  | 
 | 3577 |             case BINSTRING: | 
 | 3578 |                 if (load_binstring(self) < 0) | 
 | 3579 |                     break; | 
 | 3580 |                 continue; | 
 | 3581 |  | 
 | 3582 |             case SHORT_BINSTRING: | 
 | 3583 |                 if (load_short_binstring(self) < 0) | 
 | 3584 |                     break; | 
 | 3585 |                 continue; | 
 | 3586 |  | 
 | 3587 |             case STRING: | 
 | 3588 |                 if (load_string(self) < 0) | 
 | 3589 |                     break; | 
 | 3590 |                 continue; | 
 | 3591 |  | 
| Guido van Rossum | 5fccb7c | 2000-03-10 23:11:40 +0000 | [diff] [blame] | 3592 |             case UNICODE: | 
 | 3593 |                 if (load_unicode(self) < 0) | 
 | 3594 |                     break; | 
 | 3595 |                 continue; | 
 | 3596 |  | 
 | 3597 |             case BINUNICODE: | 
 | 3598 |                 if (load_binunicode(self) < 0) | 
 | 3599 |                     break; | 
 | 3600 |                 continue; | 
 | 3601 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3602 |             case EMPTY_TUPLE: | 
 | 3603 |                 if (load_empty_tuple(self) < 0) | 
 | 3604 |                     break; | 
 | 3605 |                 continue; | 
 | 3606 |  | 
 | 3607 |             case TUPLE: | 
 | 3608 |                 if (load_tuple(self) < 0) | 
 | 3609 |                     break; | 
 | 3610 |                 continue; | 
 | 3611 |  | 
 | 3612 |             case EMPTY_LIST: | 
 | 3613 |                 if (load_empty_list(self) < 0) | 
 | 3614 |                     break; | 
 | 3615 |                 continue; | 
 | 3616 |  | 
 | 3617 |             case LIST: | 
 | 3618 |                 if (load_list(self) < 0) | 
 | 3619 |                     break; | 
 | 3620 |                 continue; | 
 | 3621 |  | 
 | 3622 |             case EMPTY_DICT: | 
 | 3623 |                 if (load_empty_dict(self) < 0) | 
 | 3624 |                     break; | 
 | 3625 |                 continue; | 
 | 3626 |  | 
 | 3627 |             case DICT: | 
 | 3628 |                 if (load_dict(self) < 0) | 
 | 3629 |                     break; | 
 | 3630 |                 continue; | 
 | 3631 |  | 
 | 3632 |             case OBJ: | 
 | 3633 |                 if (load_obj(self) < 0) | 
 | 3634 |                     break; | 
 | 3635 |                 continue; | 
 | 3636 |  | 
 | 3637 |             case INST: | 
 | 3638 |                 if (load_inst(self) < 0) | 
 | 3639 |                     break; | 
 | 3640 |                 continue; | 
 | 3641 |  | 
 | 3642 |             case GLOBAL: | 
 | 3643 |                 if (load_global(self) < 0) | 
 | 3644 |                     break; | 
 | 3645 |                 continue; | 
 | 3646 |  | 
 | 3647 |             case APPEND: | 
 | 3648 |                 if (load_append(self) < 0) | 
 | 3649 |                     break; | 
 | 3650 |                 continue; | 
 | 3651 |  | 
 | 3652 |             case APPENDS: | 
 | 3653 |                 if (load_appends(self) < 0) | 
 | 3654 |                     break; | 
 | 3655 |                 continue; | 
 | 3656 |     | 
 | 3657 |             case BUILD: | 
 | 3658 |                 if (load_build(self) < 0) | 
 | 3659 |                     break; | 
 | 3660 |                 continue; | 
 | 3661 |    | 
 | 3662 |             case DUP: | 
 | 3663 |                 if (load_dup(self) < 0) | 
 | 3664 |                     break; | 
 | 3665 |                 continue; | 
 | 3666 |  | 
 | 3667 |             case BINGET: | 
 | 3668 |                 if (load_binget(self) < 0) | 
 | 3669 |                     break; | 
 | 3670 |                 continue; | 
 | 3671 |  | 
 | 3672 |             case LONG_BINGET: | 
 | 3673 |                 if (load_long_binget(self) < 0) | 
 | 3674 |                     break; | 
 | 3675 |                 continue; | 
 | 3676 |           | 
 | 3677 |             case GET: | 
 | 3678 |                 if (load_get(self) < 0) | 
 | 3679 |                     break; | 
 | 3680 |                 continue; | 
 | 3681 |  | 
 | 3682 |             case MARK: | 
 | 3683 |                 if (load_mark(self) < 0) | 
 | 3684 |                     break; | 
 | 3685 |                 continue; | 
 | 3686 |  | 
 | 3687 |             case BINPUT: | 
 | 3688 |                 if (load_binput(self) < 0) | 
 | 3689 |                     break; | 
 | 3690 |                 continue; | 
 | 3691 |  | 
 | 3692 |             case LONG_BINPUT: | 
 | 3693 |                 if (load_long_binput(self) < 0) | 
 | 3694 |                     break; | 
 | 3695 |                 continue; | 
 | 3696 |           | 
 | 3697 |             case PUT: | 
 | 3698 |                 if (load_put(self) < 0) | 
 | 3699 |                     break; | 
 | 3700 |                 continue; | 
 | 3701 |  | 
 | 3702 |             case POP: | 
 | 3703 |                 if (load_pop(self) < 0) | 
 | 3704 |                     break; | 
 | 3705 |                 continue; | 
 | 3706 |  | 
 | 3707 |             case POP_MARK: | 
 | 3708 |                 if (load_pop_mark(self) < 0) | 
 | 3709 |                     break; | 
 | 3710 |                 continue; | 
 | 3711 |  | 
 | 3712 |             case SETITEM: | 
 | 3713 |                 if (load_setitem(self) < 0) | 
 | 3714 |                     break; | 
 | 3715 |                 continue; | 
 | 3716 |  | 
 | 3717 |             case SETITEMS: | 
 | 3718 |                 if (load_setitems(self) < 0) | 
 | 3719 |                     break; | 
 | 3720 |                 continue; | 
 | 3721 |  | 
 | 3722 |             case STOP: | 
 | 3723 |                 break; | 
 | 3724 |  | 
 | 3725 |             case PERSID: | 
 | 3726 |                 if (load_persid(self) < 0) | 
 | 3727 |                     break; | 
 | 3728 |                 continue; | 
 | 3729 |  | 
 | 3730 |             case BINPERSID: | 
 | 3731 |                 if (load_binpersid(self) < 0) | 
 | 3732 |                     break; | 
 | 3733 |                 continue; | 
 | 3734 |  | 
 | 3735 |             case REDUCE: | 
 | 3736 |                 if (load_reduce(self) < 0) | 
 | 3737 |                     break; | 
 | 3738 |                 continue; | 
 | 3739 |  | 
 | 3740 |             default:  | 
| Guido van Rossum | 57d9f2e | 1998-01-19 23:18:18 +0000 | [diff] [blame] | 3741 |                 cPickle_ErrFormat(UnpicklingError, "invalid load key, '%s'.",  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3742 |                     "c", s[0]); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3743 |                 return NULL; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3744 |         } | 
 | 3745 |  | 
 | 3746 |         break; | 
 | 3747 |     } | 
 | 3748 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3749 |     if ((err = PyErr_Occurred())) { | 
 | 3750 |         if (err == PyExc_EOFError) { | 
 | 3751 |             PyErr_SetNone(PyExc_EOFError); | 
 | 3752 |         }     | 
 | 3753 |         return NULL; | 
 | 3754 |     } | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3755 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3756 |     PDATA_POP(self->stack, val);     | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3757 |     return val; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 3758 | } | 
 | 3759 |      | 
 | 3760 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3761 | /* No-load functions to support noload, which is used to | 
 | 3762 |    find persistent references. */ | 
 | 3763 |  | 
 | 3764 | static int | 
 | 3765 | noload_obj(Unpicklerobject *self) { | 
| Guido van Rossum | e94e3fb | 1998-12-08 17:37:19 +0000 | [diff] [blame] | 3766 |     int i; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3767 |  | 
 | 3768 |     if ((i = marker(self)) < 0) return -1; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3769 |     return Pdata_clear(self->stack, i+1); | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3770 | } | 
 | 3771 |  | 
 | 3772 |  | 
 | 3773 | static int | 
 | 3774 | noload_inst(Unpicklerobject *self) { | 
| Guido van Rossum | e94e3fb | 1998-12-08 17:37:19 +0000 | [diff] [blame] | 3775 |     int i; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3776 |     char *s; | 
 | 3777 |  | 
 | 3778 |     if ((i = marker(self)) < 0) return -1; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3779 |     Pdata_clear(self->stack, i); | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3780 |     if ((*self->readline_func)(self, &s) < 0) return -1; | 
 | 3781 |     if ((*self->readline_func)(self, &s) < 0) return -1; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3782 |     PDATA_APPEND(self->stack, Py_None,-1); | 
 | 3783 |     return 0; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3784 | } | 
 | 3785 |  | 
 | 3786 | static int | 
 | 3787 | noload_global(Unpicklerobject *self) { | 
 | 3788 |     char *s; | 
 | 3789 |  | 
 | 3790 |     if ((*self->readline_func)(self, &s) < 0) return -1; | 
 | 3791 |     if ((*self->readline_func)(self, &s) < 0) return -1; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3792 |     PDATA_APPEND(self->stack, Py_None,-1); | 
 | 3793 |     return 0; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3794 | } | 
 | 3795 |  | 
 | 3796 | static int | 
 | 3797 | noload_reduce(Unpicklerobject *self) { | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3798 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3799 |     if (self->stack->length < 2) return stackUnderflow(); | 
 | 3800 |     Pdata_clear(self->stack, self->stack->length-2); | 
 | 3801 |     PDATA_APPEND(self->stack, Py_None,-1); | 
 | 3802 |     return 0; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3803 | } | 
 | 3804 |  | 
 | 3805 | static int | 
 | 3806 | noload_build(Unpicklerobject *self) { | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3807 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3808 |   if (self->stack->length < 1) return stackUnderflow(); | 
 | 3809 |   Pdata_clear(self->stack, self->stack->length-1); | 
| Guido van Rossum | 50f385c | 1998-12-04 18:48:44 +0000 | [diff] [blame] | 3810 |   return 0; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3811 | } | 
 | 3812 |  | 
 | 3813 |  | 
 | 3814 | static PyObject * | 
 | 3815 | noload(Unpicklerobject *self) { | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 3816 |     PyObject *err = 0, *val = 0; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3817 |     char *s; | 
 | 3818 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3819 |     self->num_marks = 0; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 3820 |     Pdata_clear(self->stack, 0); | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3821 |  | 
 | 3822 |     while (1) { | 
 | 3823 |         if ((*self->read_func)(self, &s, 1) < 0) | 
 | 3824 |             break; | 
 | 3825 |  | 
 | 3826 |         switch (s[0]) { | 
 | 3827 |             case NONE: | 
 | 3828 |                 if (load_none(self) < 0) | 
 | 3829 |                     break; | 
 | 3830 |                 continue; | 
 | 3831 |  | 
 | 3832 |             case BININT: | 
 | 3833 |                  if (load_binint(self) < 0) | 
 | 3834 |                      break; | 
 | 3835 |                  continue; | 
 | 3836 |  | 
 | 3837 |             case BININT1: | 
 | 3838 |                 if (load_binint1(self) < 0) | 
 | 3839 |                     break; | 
 | 3840 |                 continue; | 
 | 3841 |  | 
 | 3842 |             case BININT2: | 
 | 3843 |                 if (load_binint2(self) < 0) | 
 | 3844 |                     break; | 
 | 3845 |                 continue; | 
 | 3846 |  | 
 | 3847 |             case INT: | 
 | 3848 |                 if (load_int(self) < 0) | 
 | 3849 |                     break; | 
 | 3850 |                 continue; | 
 | 3851 |  | 
 | 3852 |             case LONG: | 
 | 3853 |                 if (load_long(self) < 0) | 
 | 3854 |                     break; | 
 | 3855 |                 continue; | 
 | 3856 |  | 
 | 3857 |             case FLOAT: | 
 | 3858 |                 if (load_float(self) < 0) | 
 | 3859 |                     break; | 
 | 3860 |                 continue; | 
 | 3861 |  | 
 | 3862 |             case BINFLOAT: | 
 | 3863 |                 if (load_binfloat(self) < 0) | 
 | 3864 |                     break; | 
 | 3865 |                 continue; | 
 | 3866 |  | 
 | 3867 |             case BINSTRING: | 
 | 3868 |                 if (load_binstring(self) < 0) | 
 | 3869 |                     break; | 
 | 3870 |                 continue; | 
 | 3871 |  | 
 | 3872 |             case SHORT_BINSTRING: | 
 | 3873 |                 if (load_short_binstring(self) < 0) | 
 | 3874 |                     break; | 
 | 3875 |                 continue; | 
 | 3876 |  | 
 | 3877 |             case STRING: | 
 | 3878 |                 if (load_string(self) < 0) | 
 | 3879 |                     break; | 
 | 3880 |                 continue; | 
 | 3881 |  | 
| Guido van Rossum | 5fccb7c | 2000-03-10 23:11:40 +0000 | [diff] [blame] | 3882 |             case UNICODE: | 
 | 3883 |                 if (load_unicode(self) < 0) | 
 | 3884 |                     break; | 
 | 3885 |                 continue; | 
 | 3886 |  | 
 | 3887 |             case BINUNICODE: | 
 | 3888 |                 if (load_binunicode(self) < 0) | 
 | 3889 |                     break; | 
 | 3890 |                 continue; | 
 | 3891 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 3892 |             case EMPTY_TUPLE: | 
 | 3893 |                 if (load_empty_tuple(self) < 0) | 
 | 3894 |                     break; | 
 | 3895 |                 continue; | 
 | 3896 |  | 
 | 3897 |             case TUPLE: | 
 | 3898 |                 if (load_tuple(self) < 0) | 
 | 3899 |                     break; | 
 | 3900 |                 continue; | 
 | 3901 |  | 
 | 3902 |             case EMPTY_LIST: | 
 | 3903 |                 if (load_empty_list(self) < 0) | 
 | 3904 |                     break; | 
 | 3905 |                 continue; | 
 | 3906 |  | 
 | 3907 |             case LIST: | 
 | 3908 |                 if (load_list(self) < 0) | 
 | 3909 |                     break; | 
 | 3910 |                 continue; | 
 | 3911 |  | 
 | 3912 |             case EMPTY_DICT: | 
 | 3913 |                 if (load_empty_dict(self) < 0) | 
 | 3914 |                     break; | 
 | 3915 |                 continue; | 
 | 3916 |  | 
 | 3917 |             case DICT: | 
 | 3918 |                 if (load_dict(self) < 0) | 
 | 3919 |                     break; | 
 | 3920 |                 continue; | 
 | 3921 |  | 
 | 3922 |             case OBJ: | 
 | 3923 |                 if (noload_obj(self) < 0) | 
 | 3924 |                     break; | 
 | 3925 |                 continue; | 
 | 3926 |  | 
 | 3927 |             case INST: | 
 | 3928 |                 if (noload_inst(self) < 0) | 
 | 3929 |                     break; | 
 | 3930 |                 continue; | 
 | 3931 |  | 
 | 3932 |             case GLOBAL: | 
 | 3933 |                 if (noload_global(self) < 0) | 
 | 3934 |                     break; | 
 | 3935 |                 continue; | 
 | 3936 |  | 
 | 3937 |             case APPEND: | 
 | 3938 |                 if (load_append(self) < 0) | 
 | 3939 |                     break; | 
 | 3940 |                 continue; | 
 | 3941 |  | 
 | 3942 |             case APPENDS: | 
 | 3943 |                 if (load_appends(self) < 0) | 
 | 3944 |                     break; | 
 | 3945 |                 continue; | 
 | 3946 |     | 
 | 3947 |             case BUILD: | 
 | 3948 |                 if (noload_build(self) < 0) | 
 | 3949 |                     break; | 
 | 3950 |                 continue; | 
 | 3951 |    | 
 | 3952 |             case DUP: | 
 | 3953 |                 if (load_dup(self) < 0) | 
 | 3954 |                     break; | 
 | 3955 |                 continue; | 
 | 3956 |  | 
 | 3957 |             case BINGET: | 
 | 3958 |                 if (load_binget(self) < 0) | 
 | 3959 |                     break; | 
 | 3960 |                 continue; | 
 | 3961 |  | 
 | 3962 |             case LONG_BINGET: | 
 | 3963 |                 if (load_long_binget(self) < 0) | 
 | 3964 |                     break; | 
 | 3965 |                 continue; | 
 | 3966 |           | 
 | 3967 |             case GET: | 
 | 3968 |                 if (load_get(self) < 0) | 
 | 3969 |                     break; | 
 | 3970 |                 continue; | 
 | 3971 |  | 
 | 3972 |             case MARK: | 
 | 3973 |                 if (load_mark(self) < 0) | 
 | 3974 |                     break; | 
 | 3975 |                 continue; | 
 | 3976 |  | 
 | 3977 |             case BINPUT: | 
 | 3978 |                 if (load_binput(self) < 0) | 
 | 3979 |                     break; | 
 | 3980 |                 continue; | 
 | 3981 |  | 
 | 3982 |             case LONG_BINPUT: | 
 | 3983 |                 if (load_long_binput(self) < 0) | 
 | 3984 |                     break; | 
 | 3985 |                 continue; | 
 | 3986 |           | 
 | 3987 |             case PUT: | 
 | 3988 |                 if (load_put(self) < 0) | 
 | 3989 |                     break; | 
 | 3990 |                 continue; | 
 | 3991 |  | 
 | 3992 |             case POP: | 
 | 3993 |                 if (load_pop(self) < 0) | 
 | 3994 |                     break; | 
 | 3995 |                 continue; | 
 | 3996 |  | 
 | 3997 |             case POP_MARK: | 
 | 3998 |                 if (load_pop_mark(self) < 0) | 
 | 3999 |                     break; | 
 | 4000 |                 continue; | 
 | 4001 |  | 
 | 4002 |             case SETITEM: | 
 | 4003 |                 if (load_setitem(self) < 0) | 
 | 4004 |                     break; | 
 | 4005 |                 continue; | 
 | 4006 |  | 
 | 4007 |             case SETITEMS: | 
 | 4008 |                 if (load_setitems(self) < 0) | 
 | 4009 |                     break; | 
 | 4010 |                 continue; | 
 | 4011 |  | 
 | 4012 |             case STOP: | 
 | 4013 |                 break; | 
 | 4014 |  | 
 | 4015 |             case PERSID: | 
 | 4016 |                 if (load_persid(self) < 0) | 
 | 4017 |                     break; | 
 | 4018 |                 continue; | 
 | 4019 |  | 
 | 4020 |             case BINPERSID: | 
 | 4021 |                 if (load_binpersid(self) < 0) | 
 | 4022 |                     break; | 
 | 4023 |                 continue; | 
 | 4024 |  | 
 | 4025 |             case REDUCE: | 
 | 4026 |                 if (noload_reduce(self) < 0) | 
 | 4027 |                     break; | 
 | 4028 |                 continue; | 
 | 4029 |  | 
 | 4030 |             default:  | 
| Guido van Rossum | 57d9f2e | 1998-01-19 23:18:18 +0000 | [diff] [blame] | 4031 |                 cPickle_ErrFormat(UnpicklingError, "invalid load key, '%s'.",  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4032 |                     "c", s[0]); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4033 |                 return NULL; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4034 |         } | 
 | 4035 |  | 
 | 4036 |         break; | 
 | 4037 |     } | 
 | 4038 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4039 |     if ((err = PyErr_Occurred())) { | 
 | 4040 |         if (err == PyExc_EOFError) { | 
 | 4041 |             PyErr_SetNone(PyExc_EOFError); | 
 | 4042 |         }     | 
 | 4043 |         return NULL; | 
 | 4044 |     } | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4045 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4046 |     PDATA_POP(self->stack, val);     | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4047 |     return val; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4048 | } | 
 | 4049 |      | 
 | 4050 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4051 | static PyObject * | 
 | 4052 | Unpickler_load(Unpicklerobject *self, PyObject *args) { | 
| Guido van Rossum | 43713e5 | 2000-02-29 13:59:29 +0000 | [diff] [blame] | 4053 |     UNLESS (PyArg_ParseTuple(args, ":load"))  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4054 |         return NULL; | 
 | 4055 |  | 
 | 4056 |     return load(self); | 
 | 4057 | } | 
 | 4058 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4059 | static PyObject * | 
 | 4060 | Unpickler_noload(Unpicklerobject *self, PyObject *args) { | 
| Guido van Rossum | 43713e5 | 2000-02-29 13:59:29 +0000 | [diff] [blame] | 4061 |     UNLESS (PyArg_ParseTuple(args, ":noload"))  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4062 |         return NULL; | 
 | 4063 |  | 
 | 4064 |     return noload(self); | 
 | 4065 | } | 
 | 4066 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4067 |  | 
 | 4068 | static struct PyMethodDef Unpickler_methods[] = { | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4069 |   {"load",         (PyCFunction)Unpickler_load,   1, | 
 | 4070 |    "load() -- Load a pickle" | 
 | 4071 |   }, | 
 | 4072 |   {"noload",         (PyCFunction)Unpickler_noload,   1, | 
 | 4073 |    "noload() -- not load a pickle, but go through most of the motions\n" | 
 | 4074 |    "\n" | 
 | 4075 |    "This function can be used to read past a pickle without instantiating\n" | 
 | 4076 |    "any objects or importing any modules.  It can also be used to find all\n" | 
 | 4077 |    "persistent references without instantiating any objects or importing\n" | 
 | 4078 |    "any modules.\n" | 
 | 4079 |   }, | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4080 |   {NULL,              NULL}           /* sentinel */ | 
 | 4081 | }; | 
 | 4082 |  | 
 | 4083 |  | 
 | 4084 | static Unpicklerobject * | 
 | 4085 | newUnpicklerobject(PyObject *f) { | 
 | 4086 |     Unpicklerobject *self; | 
 | 4087 |  | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 4088 |     UNLESS (self = PyObject_New(Unpicklerobject, &Unpicklertype)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4089 |         return NULL; | 
 | 4090 |  | 
 | 4091 |     self->file = NULL; | 
 | 4092 |     self->arg = NULL; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4093 |     self->stack = (Pdata*)Pdata_New(); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4094 |     self->pers_func = NULL; | 
 | 4095 |     self->last_string = NULL; | 
 | 4096 |     self->marks = NULL; | 
 | 4097 |     self->num_marks = 0; | 
 | 4098 |     self->marks_size = 0; | 
 | 4099 |     self->buf_size = 0; | 
 | 4100 |     self->read = NULL; | 
| Guido van Rossum | 8a6dba3 | 1998-03-06 01:39:39 +0000 | [diff] [blame] | 4101 |     self->readline = NULL; | 
| Guido van Rossum | 21ef088 | 1998-12-11 03:20:00 +0000 | [diff] [blame] | 4102 |     self->safe_constructors = NULL; | 
| Guido van Rossum | 1b9e0aa | 1999-04-19 17:58:18 +0000 | [diff] [blame] | 4103 |     self->find_class = NULL; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4104 |  | 
| Guido van Rossum | 83addc7 | 2000-04-21 20:49:36 +0000 | [diff] [blame] | 4105 |     UNLESS (self->memo = PyDict_New())  | 
 | 4106 |        goto err; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4107 |  | 
 | 4108 |     Py_INCREF(f); | 
 | 4109 |     self->file = f; | 
 | 4110 |  | 
 | 4111 |     /* Set read, readline based on type of f */ | 
 | 4112 |     if (PyFile_Check(f)) { | 
 | 4113 |         self->fp = PyFile_AsFile(f); | 
| Guido van Rossum | c91fcaa | 1999-03-29 20:00:14 +0000 | [diff] [blame] | 4114 | 	if (self->fp == NULL) { | 
| Guido van Rossum | 83addc7 | 2000-04-21 20:49:36 +0000 | [diff] [blame] | 4115 | 	    PyErr_SetString(PyExc_ValueError, "I/O operation on closed file"); | 
 | 4116 | 	    goto err; | 
| Guido van Rossum | c91fcaa | 1999-03-29 20:00:14 +0000 | [diff] [blame] | 4117 | 	} | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4118 |         self->read_func = read_file; | 
 | 4119 |         self->readline_func = readline_file; | 
 | 4120 |     } | 
 | 4121 |     else if (PycStringIO_InputCheck(f)) { | 
 | 4122 |         self->fp = NULL; | 
 | 4123 |         self->read_func = read_cStringIO; | 
 | 4124 |         self->readline_func = readline_cStringIO; | 
 | 4125 |     } | 
 | 4126 |     else { | 
 | 4127 |  | 
 | 4128 |         self->fp = NULL; | 
 | 4129 |         self->read_func = read_other; | 
 | 4130 |         self->readline_func = readline_other; | 
 | 4131 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4132 |         UNLESS ((self->readline = PyObject_GetAttr(f, readline_str)) && | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4133 |             (self->read = PyObject_GetAttr(f, read_str))) { | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4134 |             PyErr_Clear(); | 
 | 4135 |             PyErr_SetString( PyExc_TypeError, "argument must have 'read' and " | 
 | 4136 |                 "'readline' attributes" ); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4137 |             goto err; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4138 |         } | 
 | 4139 |     } | 
 | 4140 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4141 |     if (PyEval_GetRestricted()) { | 
 | 4142 |         /* Restricted execution, get private tables */ | 
 | 4143 |         PyObject *m; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4144 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4145 |         UNLESS (m=PyImport_Import(copy_reg_str)) goto err; | 
 | 4146 |         self->safe_constructors=PyObject_GetAttr(m, safe_constructors_str); | 
 | 4147 |         Py_DECREF(m); | 
 | 4148 |         UNLESS (self->safe_constructors) goto err; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4149 |     } | 
 | 4150 |     else { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4151 |         self->safe_constructors=safe_constructors; | 
 | 4152 |         Py_INCREF(safe_constructors); | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4153 |     } | 
 | 4154 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4155 |     return self; | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4156 |  | 
 | 4157 | err: | 
 | 4158 |     Py_DECREF((PyObject *)self); | 
 | 4159 |     return NULL; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4160 | } | 
 | 4161 |  | 
 | 4162 |  | 
 | 4163 | static PyObject * | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4164 | get_Unpickler(PyObject *self, PyObject *args) { | 
 | 4165 |     PyObject *file; | 
 | 4166 |    | 
| Guido van Rossum | 43713e5 | 2000-02-29 13:59:29 +0000 | [diff] [blame] | 4167 |     UNLESS (PyArg_ParseTuple(args, "O:Unpickler", &file)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4168 |         return NULL; | 
 | 4169 |     return (PyObject *)newUnpicklerobject(file); | 
 | 4170 | } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4171 |  | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4172 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4173 | static void | 
 | 4174 | Unpickler_dealloc(Unpicklerobject *self) { | 
 | 4175 |     Py_XDECREF(self->readline); | 
 | 4176 |     Py_XDECREF(self->read); | 
 | 4177 |     Py_XDECREF(self->file); | 
 | 4178 |     Py_XDECREF(self->memo); | 
 | 4179 |     Py_XDECREF(self->stack); | 
 | 4180 |     Py_XDECREF(self->pers_func); | 
 | 4181 |     Py_XDECREF(self->arg); | 
 | 4182 |     Py_XDECREF(self->last_string); | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4183 |     Py_XDECREF(self->safe_constructors); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4184 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4185 |     if (self->marks) { | 
 | 4186 |         free(self->marks); | 
 | 4187 |     } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4188 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4189 |     if (self->buf_size) { | 
 | 4190 |         free(self->buf); | 
 | 4191 |     } | 
 | 4192 |      | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 4193 |     PyObject_Del(self); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4194 | } | 
 | 4195 |  | 
 | 4196 |  | 
 | 4197 | static PyObject * | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4198 | Unpickler_getattr(Unpicklerobject *self, char *name) { | 
 | 4199 |     if (!strcmp(name, "persistent_load")) { | 
 | 4200 |         if (!self->pers_func) { | 
 | 4201 |             PyErr_SetString(PyExc_AttributeError, name); | 
 | 4202 |             return NULL; | 
 | 4203 |         } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4204 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4205 |         Py_INCREF(self->pers_func); | 
 | 4206 |         return self->pers_func; | 
 | 4207 |     } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4208 |  | 
| Guido van Rossum | 1b9e0aa | 1999-04-19 17:58:18 +0000 | [diff] [blame] | 4209 |     if (!strcmp(name, "find_global")) { | 
 | 4210 |         if (!self->find_class) { | 
 | 4211 |             PyErr_SetString(PyExc_AttributeError, name); | 
 | 4212 |             return NULL; | 
 | 4213 |         } | 
 | 4214 |  | 
 | 4215 |         Py_INCREF(self->find_class); | 
 | 4216 |         return self->find_class; | 
 | 4217 |     } | 
 | 4218 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4219 |     if (!strcmp(name, "memo")) { | 
 | 4220 |         if (!self->memo) { | 
 | 4221 |             PyErr_SetString(PyExc_AttributeError, name); | 
 | 4222 |             return NULL; | 
 | 4223 |         } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4224 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4225 |         Py_INCREF(self->memo); | 
 | 4226 |         return self->memo; | 
 | 4227 |     } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4228 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4229 |     if (!strcmp(name, "UnpicklingError")) { | 
 | 4230 |         Py_INCREF(UnpicklingError); | 
 | 4231 |         return UnpicklingError; | 
 | 4232 |     } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4233 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4234 |     return Py_FindMethod(Unpickler_methods, (PyObject *)self, name); | 
 | 4235 | } | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4236 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4237 |  | 
 | 4238 | static int | 
 | 4239 | Unpickler_setattr(Unpicklerobject *self, char *name, PyObject *value) { | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 4240 |  | 
| Guido van Rossum | 1b9e0aa | 1999-04-19 17:58:18 +0000 | [diff] [blame] | 4241 |     if (!strcmp(name, "persistent_load")) { | 
 | 4242 |         Py_XDECREF(self->pers_func); | 
 | 4243 |         self->pers_func = value; | 
 | 4244 |         Py_XINCREF(value); | 
 | 4245 |         return 0; | 
 | 4246 |     } | 
 | 4247 |  | 
 | 4248 |     if (!strcmp(name, "find_global")) { | 
 | 4249 |         Py_XDECREF(self->find_class); | 
 | 4250 |         self->find_class = value; | 
 | 4251 |         Py_XINCREF(value); | 
 | 4252 |         return 0; | 
 | 4253 |     } | 
 | 4254 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4255 |     if (! value) { | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 4256 |         PyErr_SetString(PyExc_TypeError, | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4257 |                         "attribute deletion is not supported"); | 
 | 4258 |         return -1; | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 4259 |     } | 
 | 4260 |  | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 4261 |     if (strcmp(name, "memo") == 0) { | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4262 |         if (! PyDict_Check(value)) { | 
 | 4263 |           PyErr_SetString(PyExc_TypeError, "memo must be a dictionary"); | 
 | 4264 |           return -1; | 
 | 4265 |         } | 
| Jeremy Hylton | ce616e4 | 1998-08-13 23:13:52 +0000 | [diff] [blame] | 4266 |         Py_XDECREF(self->memo); | 
 | 4267 |         self->memo = value; | 
 | 4268 |         Py_INCREF(value); | 
 | 4269 |         return 0; | 
 | 4270 |     } | 
 | 4271 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4272 |     PyErr_SetString(PyExc_AttributeError, name); | 
 | 4273 |     return -1; | 
 | 4274 | } | 
 | 4275 |  | 
 | 4276 |  | 
 | 4277 | static PyObject * | 
 | 4278 | cpm_dump(PyObject *self, PyObject *args) { | 
 | 4279 |     PyObject *ob, *file, *res = NULL; | 
 | 4280 |     Picklerobject *pickler = 0; | 
 | 4281 |     int bin = 0; | 
 | 4282 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4283 |     UNLESS (PyArg_ParseTuple(args, "OO|i", &ob, &file, &bin)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4284 |         goto finally; | 
 | 4285 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4286 |     UNLESS (pickler = newPicklerobject(file, bin)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4287 |         goto finally; | 
 | 4288 |  | 
 | 4289 |     if (dump(pickler, ob) < 0) | 
 | 4290 |         goto finally; | 
 | 4291 |  | 
 | 4292 |     Py_INCREF(Py_None); | 
 | 4293 |     res = Py_None; | 
 | 4294 |  | 
 | 4295 | finally: | 
 | 4296 |     Py_XDECREF(pickler); | 
 | 4297 |  | 
 | 4298 |     return res; | 
 | 4299 | } | 
 | 4300 |  | 
 | 4301 |  | 
 | 4302 | static PyObject * | 
 | 4303 | cpm_dumps(PyObject *self, PyObject *args) { | 
 | 4304 |     PyObject *ob, *file = 0, *res = NULL; | 
 | 4305 |     Picklerobject *pickler = 0; | 
 | 4306 |     int bin = 0; | 
 | 4307 |  | 
| Guido van Rossum | 43713e5 | 2000-02-29 13:59:29 +0000 | [diff] [blame] | 4308 |     UNLESS (PyArg_ParseTuple(args, "O|i:dumps", &ob, &bin)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4309 |         goto finally; | 
 | 4310 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4311 |     UNLESS (file = PycStringIO->NewOutput(128)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4312 |         goto finally; | 
 | 4313 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4314 |     UNLESS (pickler = newPicklerobject(file, bin)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4315 |         goto finally; | 
 | 4316 |  | 
 | 4317 |     if (dump(pickler, ob) < 0) | 
 | 4318 |         goto finally; | 
 | 4319 |  | 
 | 4320 |     res = PycStringIO->cgetvalue(file); | 
 | 4321 |  | 
 | 4322 | finally: | 
 | 4323 |     Py_XDECREF(pickler); | 
 | 4324 |     Py_XDECREF(file); | 
 | 4325 |  | 
 | 4326 |     return res; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4327 | }   | 
 | 4328 |    | 
 | 4329 |  | 
 | 4330 | static PyObject * | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4331 | cpm_load(PyObject *self, PyObject *args) { | 
 | 4332 |     Unpicklerobject *unpickler = 0; | 
 | 4333 |     PyObject *ob, *res = NULL; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4334 |  | 
| Guido van Rossum | 43713e5 | 2000-02-29 13:59:29 +0000 | [diff] [blame] | 4335 |     UNLESS (PyArg_ParseTuple(args, "O:load", &ob)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4336 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4337 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4338 |     UNLESS (unpickler = newUnpicklerobject(ob)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4339 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4340 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4341 |     res = load(unpickler); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4342 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4343 | finally: | 
 | 4344 |     Py_XDECREF(unpickler); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4345 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4346 |     return res; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4347 | } | 
 | 4348 |  | 
 | 4349 |  | 
 | 4350 | static PyObject * | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4351 | cpm_loads(PyObject *self, PyObject *args) { | 
 | 4352 |     PyObject *ob, *file = 0, *res = NULL; | 
 | 4353 |     Unpicklerobject *unpickler = 0; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4354 |  | 
| Guido van Rossum | 43713e5 | 2000-02-29 13:59:29 +0000 | [diff] [blame] | 4355 |     UNLESS (PyArg_ParseTuple(args, "S:loads", &ob)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4356 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4357 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4358 |     UNLESS (file = PycStringIO->NewInput(ob)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4359 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4360 |    | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4361 |     UNLESS (unpickler = newUnpicklerobject(file)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4362 |         goto finally; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4363 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4364 |     res = load(unpickler); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4365 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4366 | finally: | 
 | 4367 |     Py_XDECREF(file); | 
 | 4368 |     Py_XDECREF(unpickler); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4369 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4370 |     return res; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4371 | } | 
 | 4372 |  | 
 | 4373 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4374 | static char Unpicklertype__doc__[] =  | 
 | 4375 | "Objects that know how to unpickle"; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4376 |  | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 4377 | static PyTypeObject Unpicklertype = { | 
 | 4378 |     PyObject_HEAD_INIT(NULL) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4379 |     0,                            /*ob_size*/ | 
 | 4380 |     "Unpickler",                  /*tp_name*/ | 
 | 4381 |     sizeof(Unpicklerobject),              /*tp_basicsize*/ | 
 | 4382 |     0,                            /*tp_itemsize*/ | 
 | 4383 |     /* methods */ | 
 | 4384 |     (destructor)Unpickler_dealloc,        /*tp_dealloc*/ | 
 | 4385 |     (printfunc)0,         /*tp_print*/ | 
 | 4386 |     (getattrfunc)Unpickler_getattr,       /*tp_getattr*/ | 
 | 4387 |     (setattrfunc)Unpickler_setattr,       /*tp_setattr*/ | 
 | 4388 |     (cmpfunc)0,           /*tp_compare*/ | 
 | 4389 |     (reprfunc)0,          /*tp_repr*/ | 
 | 4390 |     0,                    /*tp_as_number*/ | 
 | 4391 |     0,            /*tp_as_sequence*/ | 
 | 4392 |     0,            /*tp_as_mapping*/ | 
 | 4393 |     (hashfunc)0,          /*tp_hash*/ | 
 | 4394 |     (ternaryfunc)0,               /*tp_call*/ | 
 | 4395 |     (reprfunc)0,          /*tp_str*/ | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4396 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4397 |     /* Space for future expansion */ | 
 | 4398 |     0L,0L,0L,0L, | 
 | 4399 |     Unpicklertype__doc__ /* Documentation string */ | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 4400 | }; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4401 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4402 | static struct PyMethodDef cPickle_methods[] = { | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4403 |   {"dump",         (PyCFunction)cpm_dump,         1, | 
 | 4404 |    "dump(object, file, [binary]) --" | 
 | 4405 |    "Write an object in pickle format to the given file\n" | 
 | 4406 |    "\n" | 
 | 4407 |    "If the optional argument, binary, is provided and is true, then the\n" | 
 | 4408 |    "pickle will be written in binary format, which is more space and\n" | 
 | 4409 |    "computationally efficient. \n" | 
 | 4410 |   }, | 
 | 4411 |   {"dumps",        (PyCFunction)cpm_dumps,        1, | 
 | 4412 |    "dumps(object, [binary]) --" | 
 | 4413 |    "Return a string containing an object in pickle format\n" | 
 | 4414 |    "\n" | 
 | 4415 |    "If the optional argument, binary, is provided and is true, then the\n" | 
 | 4416 |    "pickle will be written in binary format, which is more space and\n" | 
 | 4417 |    "computationally efficient. \n" | 
 | 4418 |   }, | 
 | 4419 |   {"load",         (PyCFunction)cpm_load,         1, | 
 | 4420 |    "load(file) -- Load a pickle from the given file"}, | 
 | 4421 |   {"loads",        (PyCFunction)cpm_loads,        1, | 
 | 4422 |    "loads(string) -- Load a pickle from the given string"}, | 
 | 4423 |   {"Pickler",      (PyCFunction)get_Pickler,      1, | 
 | 4424 |    "Pickler(file, [binary]) -- Create a pickler\n" | 
 | 4425 |    "\n" | 
 | 4426 |    "If the optional argument, binary, is provided and is true, then\n" | 
 | 4427 |    "pickles will be written in binary format, which is more space and\n" | 
 | 4428 |    "computationally efficient. \n" | 
 | 4429 |   }, | 
 | 4430 |   {"Unpickler",    (PyCFunction)get_Unpickler,    1, | 
 | 4431 |    "Unpickler(file) -- Create an unpickler"}, | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4432 |   { NULL, NULL } | 
 | 4433 | }; | 
 | 4434 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4435 | static int | 
| Guido van Rossum | ebba420 | 2000-09-07 14:35:37 +0000 | [diff] [blame] | 4436 | init_stuff(PyObject *module_dict) { | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 4437 |     PyObject *string, *copy_reg, *t, *r; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4438 |  | 
 | 4439 | #define INIT_STR(S) UNLESS(S ## _str=PyString_FromString(#S)) return -1; | 
 | 4440 |  | 
 | 4441 |     INIT_STR(__class__); | 
 | 4442 |     INIT_STR(__getinitargs__); | 
 | 4443 |     INIT_STR(__dict__); | 
 | 4444 |     INIT_STR(__getstate__); | 
 | 4445 |     INIT_STR(__setstate__); | 
 | 4446 |     INIT_STR(__name__); | 
| Guido van Rossum | 142eeb8 | 1997-08-13 03:14:41 +0000 | [diff] [blame] | 4447 |     INIT_STR(__main__); | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4448 |     INIT_STR(__reduce__); | 
 | 4449 |     INIT_STR(write); | 
 | 4450 |     INIT_STR(__safe_for_unpickling__); | 
 | 4451 |     INIT_STR(append); | 
 | 4452 |     INIT_STR(read); | 
 | 4453 |     INIT_STR(readline); | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4454 |     INIT_STR(copy_reg); | 
 | 4455 |     INIT_STR(dispatch_table); | 
 | 4456 |     INIT_STR(safe_constructors); | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 4457 |     INIT_STR(__basicnew__); | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4458 |     UNLESS (empty_str=PyString_FromString("")) return -1; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4459 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4460 |     UNLESS (copy_reg = PyImport_ImportModule("copy_reg")) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4461 |         return -1; | 
 | 4462 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4463 |     /* These next few are special because we want to use different | 
 | 4464 |        ones in restricted mode. */ | 
 | 4465 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4466 |     UNLESS (dispatch_table = PyObject_GetAttr(copy_reg, dispatch_table_str)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4467 |         return -1; | 
 | 4468 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4469 |     UNLESS (safe_constructors = PyObject_GetAttr(copy_reg, | 
 | 4470 |                                                 safe_constructors_str)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4471 |         return -1; | 
 | 4472 |  | 
 | 4473 |     Py_DECREF(copy_reg); | 
 | 4474 |  | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4475 |     /* Down to here ********************************** */ | 
 | 4476 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4477 |     UNLESS (string = PyImport_ImportModule("string")) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4478 |         return -1; | 
 | 4479 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4480 |     UNLESS (atol_func = PyObject_GetAttrString(string, "atol")) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4481 |         return -1; | 
 | 4482 |  | 
 | 4483 |     Py_DECREF(string); | 
 | 4484 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4485 |     UNLESS (empty_tuple = PyTuple_New(0)) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4486 |         return -1; | 
 | 4487 |  | 
| Guido van Rossum | c03158b | 1999-06-09 15:23:31 +0000 | [diff] [blame] | 4488 |     /* Ugh */ | 
 | 4489 |     UNLESS (t=PyImport_ImportModule("__builtin__")) return -1; | 
 | 4490 |     if (PyDict_SetItemString(module_dict, "__builtins__", t) < 0) | 
 | 4491 |       return -1; | 
 | 4492 |  | 
 | 4493 |     UNLESS (t=PyDict_New()) return -1; | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 4494 |     UNLESS (r=PyRun_String( | 
 | 4495 |        "def __init__(self, *args): self.args=args\n\n" | 
 | 4496 |        "def __str__(self):\n" | 
 | 4497 |        "  return self.args and ('%s' % self.args[0]) or '(what)'\n", | 
 | 4498 |        Py_file_input, | 
 | 4499 |        module_dict, t) ) return -1; | 
 | 4500 |     Py_DECREF(r); | 
| Guido van Rossum | c03158b | 1999-06-09 15:23:31 +0000 | [diff] [blame] | 4501 |  | 
 | 4502 |     UNLESS (PickleError = PyErr_NewException("cPickle.PickleError", NULL, t)) | 
 | 4503 |       return -1; | 
 | 4504 |  | 
 | 4505 |     Py_DECREF(t); | 
 | 4506 |      | 
 | 4507 |  | 
 | 4508 |     UNLESS (PicklingError = PyErr_NewException("cPickle.PicklingError",  | 
 | 4509 | 					       PickleError, NULL)) | 
 | 4510 |       return -1; | 
 | 4511 |  | 
 | 4512 |     UNLESS (t=PyDict_New()) return -1; | 
| Guido van Rossum | c3be1a3 | 1999-06-15 14:36:59 +0000 | [diff] [blame] | 4513 |     UNLESS (r=PyRun_String( | 
 | 4514 |        "def __init__(self, *args): self.args=args\n\n" | 
 | 4515 |        "def __str__(self):\n" | 
 | 4516 |        "  a=self.args\n" | 
 | 4517 |        "  a=a and type(a[0]) or '(what)'\n" | 
 | 4518 |        "  return 'Cannot pickle %s objects' % a\n" | 
 | 4519 |        , Py_file_input, | 
 | 4520 |        module_dict, t) ) return -1; | 
 | 4521 |     Py_DECREF(r); | 
| Guido van Rossum | c03158b | 1999-06-09 15:23:31 +0000 | [diff] [blame] | 4522 |  | 
 | 4523 |     UNLESS (UnpickleableError = PyErr_NewException( | 
 | 4524 |                 "cPickle.UnpickleableError", PicklingError, t)) | 
 | 4525 |       return -1; | 
 | 4526 |  | 
 | 4527 |     Py_DECREF(t); | 
 | 4528 |  | 
 | 4529 |     UNLESS (UnpicklingError = PyErr_NewException("cPickle.UnpicklingError",  | 
 | 4530 |    					         PickleError, NULL)) | 
 | 4531 |       return -1; | 
 | 4532 |  | 
 | 4533 |     if (PyDict_SetItemString(module_dict, "PickleError",  | 
 | 4534 |         PickleError) < 0) | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4535 |         return -1; | 
 | 4536 |  | 
 | 4537 |     if (PyDict_SetItemString(module_dict, "PicklingError",  | 
 | 4538 |         PicklingError) < 0) | 
 | 4539 |         return -1; | 
 | 4540 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4541 |     if (PyDict_SetItemString(module_dict, "UnpicklingError", | 
 | 4542 |         UnpicklingError) < 0) | 
 | 4543 |         return -1; | 
 | 4544 |  | 
| Guido van Rossum | c03158b | 1999-06-09 15:23:31 +0000 | [diff] [blame] | 4545 |     if (PyDict_SetItemString(module_dict, "UnpickleableError", | 
 | 4546 |         UnpickleableError) < 0) | 
 | 4547 |         return -1; | 
 | 4548 |  | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4549 |     UNLESS (BadPickleGet = PyString_FromString("cPickle.BadPickleGet")) | 
 | 4550 |         return -1; | 
 | 4551 |  | 
 | 4552 |     if (PyDict_SetItemString(module_dict, "BadPickleGet", | 
 | 4553 |         BadPickleGet) < 0) | 
 | 4554 |         return -1; | 
 | 4555 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4556 |     PycString_IMPORT; | 
 | 4557 |   | 
 | 4558 |     return 0; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4559 | } | 
 | 4560 |  | 
| Guido van Rossum | f9ffb03 | 1999-02-04 14:54:04 +0000 | [diff] [blame] | 4561 | #ifndef DL_EXPORT	/* declarations for DLL import/export */ | 
 | 4562 | #define DL_EXPORT(RTYPE) RTYPE | 
 | 4563 | #endif | 
| Guido van Rossum | 50f385c | 1998-12-04 18:48:44 +0000 | [diff] [blame] | 4564 | DL_EXPORT(void) | 
| Thomas Wouters | 58d0510 | 2000-07-24 14:43:35 +0000 | [diff] [blame] | 4565 | initcPickle(void) { | 
| Guido van Rossum | ebba420 | 2000-09-07 14:35:37 +0000 | [diff] [blame] | 4566 |     PyObject *m, *d, *di, *v, *k; | 
 | 4567 |     int i; | 
| Guido van Rossum | 2f80d96 | 1999-07-13 15:18:58 +0000 | [diff] [blame] | 4568 |     char *rev="1.71"; | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4569 |     PyObject *format_version; | 
 | 4570 |     PyObject *compatible_formats; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4571 |  | 
| Guido van Rossum | 9716aaa | 1997-12-08 15:15:16 +0000 | [diff] [blame] | 4572 |     Picklertype.ob_type = &PyType_Type; | 
 | 4573 |     Unpicklertype.ob_type = &PyType_Type; | 
| Guido van Rossum | 053b8df | 1998-11-25 16:18:00 +0000 | [diff] [blame] | 4574 |     PdataType.ob_type = &PyType_Type; | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4575 |  | 
| Guido van Rossum | ebba420 | 2000-09-07 14:35:37 +0000 | [diff] [blame] | 4576 |     /* Initialize some pieces. We need to do this before module creation,  | 
 | 4577 |        so we're forced to use a temporary dictionary. :(  | 
 | 4578 |     */ | 
 | 4579 |     di=PyDict_New(); | 
 | 4580 |     if (!di) return; | 
 | 4581 |     if (init_stuff(di) < 0) return; | 
 | 4582 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4583 |     /* Create the module and add the functions */ | 
 | 4584 |     m = Py_InitModule4("cPickle", cPickle_methods, | 
 | 4585 |                      cPickle_module_documentation, | 
 | 4586 |                      (PyObject*)NULL,PYTHON_API_VERSION); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4587 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4588 |     /* Add some symbolic constants to the module */ | 
 | 4589 |     d = PyModule_GetDict(m); | 
| Guido van Rossum | fdde96c | 1997-12-04 01:13:01 +0000 | [diff] [blame] | 4590 |     PyDict_SetItemString(d,"__version__", v = PyString_FromString(rev)); | 
| Guido van Rossum | 9efe8ef | 1997-09-03 18:19:40 +0000 | [diff] [blame] | 4591 |     Py_XDECREF(v); | 
| Barry Warsaw | 93d29b6 | 1997-01-14 17:45:08 +0000 | [diff] [blame] | 4592 |  | 
| Guido van Rossum | ebba420 | 2000-09-07 14:35:37 +0000 | [diff] [blame] | 4593 |     /* Copy data from di. Waaa. */ | 
 | 4594 |     for (i=0; PyDict_Next(di, &i, &k, &v); ) { | 
 | 4595 |         if (PyObject_SetItem(d, k, v) < 0) { | 
 | 4596 |             Py_DECREF(di); | 
 | 4597 |             return; | 
 | 4598 |         } | 
 | 4599 |     } | 
 | 4600 |     Py_DECREF(di); | 
 | 4601 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4602 |     format_version = PyString_FromString("1.3"); | 
 | 4603 |     compatible_formats = Py_BuildValue("[sss]", "1.0", "1.1", "1.2"); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4604 |  | 
| Guido van Rossum | 60456fd | 1997-04-09 17:36:32 +0000 | [diff] [blame] | 4605 |     PyDict_SetItemString(d, "format_version", format_version); | 
 | 4606 |     PyDict_SetItemString(d, "compatible_formats", compatible_formats); | 
| Guido van Rossum | 9efe8ef | 1997-09-03 18:19:40 +0000 | [diff] [blame] | 4607 |     Py_XDECREF(format_version); | 
 | 4608 |     Py_XDECREF(compatible_formats); | 
| Guido van Rossum | 2f4caa4 | 1997-01-06 22:59:08 +0000 | [diff] [blame] | 4609 | } |