The 0.5 release happened on 2/15, not on 2/14. :-)
[python/dscho.git] / Python / marshal.c
blobddccc89c23297f8a42967c27d582f8b10c43341f
1 /***********************************************************
2 Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3 The Netherlands.
5 All Rights Reserved
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI or Corporation for National Research Initiatives or
13 CNRI not be used in advertising or publicity pertaining to
14 distribution of the software without specific, written prior
15 permission.
17 While CWI is the initial source for this software, a modified version
18 is made available by the Corporation for National Research Initiatives
19 (CNRI) at the Internet address ftp://ftp.python.org.
21 STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22 REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23 MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24 CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25 DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26 PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28 PERFORMANCE OF THIS SOFTWARE.
30 ******************************************************************/
32 /* Write Python objects to files and read them back.
33 This is intended for writing and reading compiled Python code only;
34 a true persistent storage facility would be much harder, since
35 it would have to take circular links and sharing into account. */
37 #include "Python.h"
38 #include "longintrepr.h"
39 #include "compile.h"
40 #include "marshal.h"
42 #define TYPE_NULL '0'
43 #define TYPE_NONE 'N'
44 #define TYPE_ELLIPSIS '.'
45 #define TYPE_INT 'i'
46 #define TYPE_INT64 'I'
47 #define TYPE_FLOAT 'f'
48 #define TYPE_COMPLEX 'x'
49 #define TYPE_LONG 'l'
50 #define TYPE_STRING 's'
51 #define TYPE_TUPLE '('
52 #define TYPE_LIST '['
53 #define TYPE_DICT '{'
54 #define TYPE_CODE 'c'
55 #define TYPE_UNKNOWN '?'
57 typedef struct {
58 FILE *fp;
59 int error;
60 /* If fp == NULL, the following are valid: */
61 PyObject *str;
62 char *ptr;
63 char *end;
64 } WFILE;
66 #define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
67 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
68 else w_more(c, p)
70 static void
71 w_more(c, p)
72 char c;
73 WFILE *p;
75 int size, newsize;
76 if (p->str == NULL)
77 return; /* An error already occurred */
78 size = PyString_Size(p->str);
79 newsize = size + 1024;
80 if (_PyString_Resize(&p->str, newsize) != 0) {
81 p->ptr = p->end = NULL;
83 else {
84 p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
85 p->end =
86 PyString_AS_STRING((PyStringObject *)p->str) + newsize;
87 *p->ptr++ = c;
91 static void
92 w_string(s, n, p)
93 char *s;
94 int n;
95 WFILE *p;
97 if (p->fp != NULL) {
98 fwrite(s, 1, n, p->fp);
100 else {
101 while (--n >= 0) {
102 w_byte(*s, p);
103 s++;
108 static void
109 w_short(x, p)
110 int x;
111 WFILE *p;
113 w_byte( x & 0xff, p);
114 w_byte((x>> 8) & 0xff, p);
117 static void
118 w_long(x, p)
119 long x;
120 WFILE *p;
122 w_byte((int)( x & 0xff), p);
123 w_byte((int)((x>> 8) & 0xff), p);
124 w_byte((int)((x>>16) & 0xff), p);
125 w_byte((int)((x>>24) & 0xff), p);
128 #if SIZEOF_LONG > 4
129 static void
130 w_long64(x, p)
131 long x;
132 WFILE *p;
134 w_long(x, p);
135 w_long(x>>32, p);
137 #endif
139 static void
140 w_object(v, p)
141 PyObject *v;
142 WFILE *p;
144 int i, n;
145 PyBufferProcs *pb;
147 if (v == NULL) {
148 w_byte(TYPE_NULL, p);
150 else if (v == Py_None) {
151 w_byte(TYPE_NONE, p);
153 else if (v == Py_Ellipsis) {
154 w_byte(TYPE_ELLIPSIS, p);
156 else if (PyInt_Check(v)) {
157 long x = PyInt_AS_LONG((PyIntObject *)v);
158 #if SIZEOF_LONG > 4
159 long y = x>>31;
160 if (y && y != -1) {
161 w_byte(TYPE_INT64, p);
162 w_long64(x, p);
164 else
165 #endif
167 w_byte(TYPE_INT, p);
168 w_long(x, p);
171 else if (PyLong_Check(v)) {
172 PyLongObject *ob = (PyLongObject *)v;
173 w_byte(TYPE_LONG, p);
174 n = ob->ob_size;
175 w_long((long)n, p);
176 if (n < 0)
177 n = -n;
178 for (i = 0; i < n; i++)
179 w_short(ob->ob_digit[i], p);
181 else if (PyFloat_Check(v)) {
182 extern void PyFloat_AsString
183 Py_PROTO((char *, PyFloatObject *));
184 char buf[256]; /* Plenty to format any double */
185 PyFloat_AsString(buf, (PyFloatObject *)v);
186 n = strlen(buf);
187 w_byte(TYPE_FLOAT, p);
188 w_byte(n, p);
189 w_string(buf, n, p);
191 #ifndef WITHOUT_COMPLEX
192 else if (PyComplex_Check(v)) {
193 extern void PyFloat_AsString
194 Py_PROTO((char *, PyFloatObject *));
195 char buf[256]; /* Plenty to format any double */
196 PyFloatObject *temp;
197 w_byte(TYPE_COMPLEX, p);
198 temp = (PyFloatObject*)PyFloat_FromDouble(
199 PyComplex_RealAsDouble(v));
200 PyFloat_AsString(buf, temp);
201 Py_DECREF(temp);
202 n = strlen(buf);
203 w_byte(n, p);
204 w_string(buf, n, p);
205 temp = (PyFloatObject*)PyFloat_FromDouble(
206 PyComplex_ImagAsDouble(v));
207 PyFloat_AsString(buf, temp);
208 Py_DECREF(temp);
209 n = strlen(buf);
210 w_byte(n, p);
211 w_string(buf, n, p);
213 #endif
214 else if (PyString_Check(v)) {
215 w_byte(TYPE_STRING, p);
216 n = PyString_Size(v);
217 w_long((long)n, p);
218 w_string(PyString_AsString(v), n, p);
220 else if (PyTuple_Check(v)) {
221 w_byte(TYPE_TUPLE, p);
222 n = PyTuple_Size(v);
223 w_long((long)n, p);
224 for (i = 0; i < n; i++) {
225 w_object(PyTuple_GET_ITEM(v, i), p);
228 else if (PyList_Check(v)) {
229 w_byte(TYPE_LIST, p);
230 n = PyList_Size(v);
231 w_long((long)n, p);
232 for (i = 0; i < n; i++) {
233 w_object(PyList_GetItem(v, i), p);
236 else if (PyDict_Check(v)) {
237 int pos;
238 PyObject *key, *value;
239 w_byte(TYPE_DICT, p);
240 /* This one is NULL object terminated! */
241 pos = 0;
242 while (PyDict_Next(v, &pos, &key, &value)) {
243 w_object(key, p);
244 w_object(value, p);
246 w_object((PyObject *)NULL, p);
248 else if (PyCode_Check(v)) {
249 PyCodeObject *co = (PyCodeObject *)v;
250 w_byte(TYPE_CODE, p);
251 w_short(co->co_argcount, p);
252 w_short(co->co_nlocals, p);
253 w_short(co->co_stacksize, p);
254 w_short(co->co_flags, p);
255 w_object(co->co_code, p);
256 w_object(co->co_consts, p);
257 w_object(co->co_names, p);
258 w_object(co->co_varnames, p);
259 w_object(co->co_filename, p);
260 w_object(co->co_name, p);
261 w_short(co->co_firstlineno, p);
262 w_object(co->co_lnotab, p);
264 else if ((pb = v->ob_type->tp_as_buffer) != NULL &&
265 pb->bf_getsegcount != NULL &&
266 pb->bf_getreadbuffer != NULL &&
267 (*pb->bf_getsegcount)(v, NULL) == 1)
269 /* Write unknown buffer-style objects as a string */
270 char *s;
271 w_byte(TYPE_STRING, p);
272 n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
273 w_long((long)n, p);
274 w_string(s, n, p);
276 else {
277 w_byte(TYPE_UNKNOWN, p);
278 p->error = 1;
282 void
283 PyMarshal_WriteLongToFile(x, fp)
284 long x;
285 FILE *fp;
287 WFILE wf;
288 wf.fp = fp;
289 wf.error = 0;
290 w_long(x, &wf);
293 void
294 PyMarshal_WriteObjectToFile(x, fp)
295 PyObject *x;
296 FILE *fp;
298 WFILE wf;
299 wf.fp = fp;
300 wf.error = 0;
301 w_object(x, &wf);
304 typedef WFILE RFILE; /* Same struct with different invariants */
306 #define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
308 #define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
310 static int
311 r_string(s, n, p)
312 char *s;
313 int n;
314 RFILE *p;
316 if (p->fp != NULL)
317 return fread(s, 1, n, p->fp);
318 if (p->end - p->ptr < n)
319 n = p->end - p->ptr;
320 memcpy(s, p->ptr, n);
321 p->ptr += n;
322 return n;
325 static int
326 r_short(p)
327 RFILE *p;
329 register short x;
330 x = r_byte(p);
331 x |= r_byte(p) << 8;
332 /* XXX If your short is > 16 bits, add sign-extension here!!! */
333 return x;
336 static long
337 r_long(p)
338 RFILE *p;
340 register long x;
341 register FILE *fp = p->fp;
342 if (fp) {
343 x = getc(fp);
344 x |= (long)getc(fp) << 8;
345 x |= (long)getc(fp) << 16;
346 x |= (long)getc(fp) << 24;
348 else {
349 x = rs_byte(p);
350 x |= (long)rs_byte(p) << 8;
351 x |= (long)rs_byte(p) << 16;
352 x |= (long)rs_byte(p) << 24;
354 #if SIZEOF_LONG > 4
355 /* Sign extension for 64-bit machines */
356 x <<= (8*sizeof(long) - 32);
357 x >>= (8*sizeof(long) - 32);
358 #endif
359 return x;
362 static long
363 r_long64(p)
364 RFILE *p;
366 register long x;
367 x = r_long(p);
368 #if SIZEOF_LONG > 4
369 x = (x & 0xFFFFFFFF) | (r_long(p) << 32);
370 #else
371 if (r_long(p) != 0) {
372 PyObject *f = PySys_GetObject("stderr");
373 if (f != NULL)
374 (void) PyFile_WriteString(
375 "Warning: un-marshal 64-bit int in 32-bit mode\n",
378 #endif
379 return x;
382 static PyObject *
383 r_object(p)
384 RFILE *p;
386 PyObject *v, *v2;
387 long i, n;
388 int type = r_byte(p);
390 switch (type) {
392 case EOF:
393 PyErr_SetString(PyExc_EOFError,
394 "EOF read where object expected");
395 return NULL;
397 case TYPE_NULL:
398 return NULL;
400 case TYPE_NONE:
401 Py_INCREF(Py_None);
402 return Py_None;
404 case TYPE_ELLIPSIS:
405 Py_INCREF(Py_Ellipsis);
406 return Py_Ellipsis;
408 case TYPE_INT:
409 return PyInt_FromLong(r_long(p));
411 case TYPE_INT64:
412 return PyInt_FromLong(r_long64(p));
414 case TYPE_LONG:
416 int size;
417 PyLongObject *ob;
418 n = r_long(p);
419 size = n<0 ? -n : n;
420 ob = _PyLong_New(size);
421 if (ob == NULL)
422 return NULL;
423 ob->ob_size = n;
424 for (i = 0; i < size; i++)
425 ob->ob_digit[i] = r_short(p);
426 return (PyObject *)ob;
429 case TYPE_FLOAT:
431 extern double atof Py_PROTO((const char *));
432 char buf[256];
433 double dx;
434 n = r_byte(p);
435 if (r_string(buf, (int)n, p) != n) {
436 PyErr_SetString(PyExc_EOFError,
437 "EOF read where object expected");
438 return NULL;
440 buf[n] = '\0';
441 PyFPE_START_PROTECT("atof", return 0)
442 dx = atof(buf);
443 PyFPE_END_PROTECT(dx)
444 return PyFloat_FromDouble(dx);
447 #ifndef WITHOUT_COMPLEX
448 case TYPE_COMPLEX:
450 extern double atof Py_PROTO((const char *));
451 char buf[256];
452 Py_complex c;
453 n = r_byte(p);
454 if (r_string(buf, (int)n, p) != n) {
455 PyErr_SetString(PyExc_EOFError,
456 "EOF read where object expected");
457 return NULL;
459 buf[n] = '\0';
460 PyFPE_START_PROTECT("atof", return 0)
461 c.real = atof(buf);
462 PyFPE_END_PROTECT(c)
463 n = r_byte(p);
464 if (r_string(buf, (int)n, p) != n) {
465 PyErr_SetString(PyExc_EOFError,
466 "EOF read where object expected");
467 return NULL;
469 buf[n] = '\0';
470 PyFPE_START_PROTECT("atof", return 0)
471 c.imag = atof(buf);
472 PyFPE_END_PROTECT(c)
473 return PyComplex_FromCComplex(c);
475 #endif
477 case TYPE_STRING:
478 n = r_long(p);
479 if (n < 0) {
480 PyErr_SetString(PyExc_ValueError, "bad marshal data");
481 return NULL;
483 v = PyString_FromStringAndSize((char *)NULL, n);
484 if (v != NULL) {
485 if (r_string(PyString_AsString(v), (int)n, p) != n) {
486 Py_DECREF(v);
487 v = NULL;
488 PyErr_SetString(PyExc_EOFError,
489 "EOF read where object expected");
492 return v;
494 case TYPE_TUPLE:
495 n = r_long(p);
496 if (n < 0) {
497 PyErr_SetString(PyExc_ValueError, "bad marshal data");
498 return NULL;
500 v = PyTuple_New((int)n);
501 if (v == NULL)
502 return v;
503 for (i = 0; i < n; i++) {
504 v2 = r_object(p);
505 if ( v2 == NULL ) {
506 Py_DECREF(v);
507 v = NULL;
508 break;
510 PyTuple_SET_ITEM(v, (int)i, v2);
512 return v;
514 case TYPE_LIST:
515 n = r_long(p);
516 if (n < 0) {
517 PyErr_SetString(PyExc_ValueError, "bad marshal data");
518 return NULL;
520 v = PyList_New((int)n);
521 if (v == NULL)
522 return v;
523 for (i = 0; i < n; i++) {
524 v2 = r_object(p);
525 if ( v2 == NULL ) {
526 Py_DECREF(v);
527 v = NULL;
528 break;
530 PyList_SetItem(v, (int)i, v2);
532 return v;
534 case TYPE_DICT:
535 v = PyDict_New();
536 if (v == NULL)
537 return NULL;
538 for (;;) {
539 PyObject *key, *val;
540 key = r_object(p);
541 if (key == NULL)
542 break; /* XXX Assume TYPE_NULL, not an error */
543 val = r_object(p);
544 if (val != NULL)
545 PyDict_SetItem(v, key, val);
546 Py_DECREF(key);
547 Py_XDECREF(val);
549 return v;
551 case TYPE_CODE:
553 int argcount = r_short(p);
554 int nlocals = r_short(p);
555 int stacksize = r_short(p);
556 int flags = r_short(p);
557 PyObject *code = NULL;
558 PyObject *consts = NULL;
559 PyObject *names = NULL;
560 PyObject *varnames = NULL;
561 PyObject *filename = NULL;
562 PyObject *name = NULL;
563 int firstlineno = 0;
564 PyObject *lnotab = NULL;
566 code = r_object(p);
567 if (code) consts = r_object(p);
568 if (consts) names = r_object(p);
569 if (names) varnames = r_object(p);
570 if (varnames) filename = r_object(p);
571 if (filename) name = r_object(p);
572 if (name) {
573 firstlineno = r_short(p);
574 lnotab = r_object(p);
577 if (!PyErr_Occurred()) {
578 v = (PyObject *) PyCode_New(
579 argcount, nlocals, stacksize, flags,
580 code, consts, names, varnames,
581 filename, name, firstlineno, lnotab);
583 else
584 v = NULL;
585 Py_XDECREF(code);
586 Py_XDECREF(consts);
587 Py_XDECREF(names);
588 Py_XDECREF(varnames);
589 Py_XDECREF(filename);
590 Py_XDECREF(name);
591 Py_XDECREF(lnotab);
594 return v;
596 default:
597 /* Bogus data got written, which isn't ideal.
598 This will let you keep working and recover. */
599 PyErr_SetString(PyExc_ValueError, "bad marshal data");
600 return NULL;
605 long
606 PyMarshal_ReadLongFromFile(fp)
607 FILE *fp;
609 RFILE rf;
610 rf.fp = fp;
611 return r_long(&rf);
614 PyObject *
615 PyMarshal_ReadObjectFromFile(fp)
616 FILE *fp;
618 RFILE rf;
619 if (PyErr_Occurred()) {
620 fprintf(stderr, "XXX rd_object called with exception set\n");
621 return NULL;
623 rf.fp = fp;
624 return r_object(&rf);
627 PyObject *
628 PyMarshal_ReadObjectFromString(str, len)
629 char *str;
630 int len;
632 RFILE rf;
633 if (PyErr_Occurred()) {
634 fprintf(stderr, "XXX rds_object called with exception set\n");
635 return NULL;
637 rf.fp = NULL;
638 rf.str = NULL;
639 rf.ptr = str;
640 rf.end = str + len;
641 return r_object(&rf);
644 PyObject *
645 PyMarshal_WriteObjectToString(x) /* wrs_object() */
646 PyObject *x;
648 WFILE wf;
649 wf.fp = NULL;
650 wf.str = PyString_FromStringAndSize((char *)NULL, 50);
651 if (wf.str == NULL)
652 return NULL;
653 wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
654 wf.end = wf.ptr + PyString_Size(wf.str);
655 wf.error = 0;
656 w_object(x, &wf);
657 if (wf.str != NULL)
658 _PyString_Resize(&wf.str,
659 (int) (wf.ptr -
660 PyString_AS_STRING((PyStringObject *)wf.str)));
661 if (wf.error) {
662 Py_XDECREF(wf.str);
663 PyErr_SetString(PyExc_ValueError, "unmarshallable object");
664 return NULL;
666 return wf.str;
669 /* And an interface for Python programs... */
671 static PyObject *
672 marshal_dump(self, args)
673 PyObject *self;
674 PyObject *args;
676 WFILE wf;
677 PyObject *x;
678 PyObject *f;
679 if (!PyArg_Parse(args, "(OO)", &x, &f))
680 return NULL;
681 if (!PyFile_Check(f)) {
682 PyErr_SetString(PyExc_TypeError,
683 "marshal.dump() 2nd arg must be file");
684 return NULL;
686 wf.fp = PyFile_AsFile(f);
687 wf.str = NULL;
688 wf.ptr = wf.end = NULL;
689 wf.error = 0;
690 w_object(x, &wf);
691 if (wf.error) {
692 PyErr_SetString(PyExc_ValueError, "unmarshallable object");
693 return NULL;
695 Py_INCREF(Py_None);
696 return Py_None;
699 static PyObject *
700 marshal_load(self, args)
701 PyObject *self;
702 PyObject *args;
704 RFILE rf;
705 PyObject *f;
706 PyObject *v;
707 if (!PyArg_Parse(args, "O", &f))
708 return NULL;
709 if (!PyFile_Check(f)) {
710 PyErr_SetString(PyExc_TypeError,
711 "marshal.load() arg must be file");
712 return NULL;
714 rf.fp = PyFile_AsFile(f);
715 rf.str = NULL;
716 rf.ptr = rf.end = NULL;
717 PyErr_Clear();
718 v = r_object(&rf);
719 if (PyErr_Occurred()) {
720 Py_XDECREF(v);
721 v = NULL;
723 return v;
726 static PyObject *
727 marshal_dumps(self, args)
728 PyObject *self;
729 PyObject *args;
731 PyObject *x;
732 if (!PyArg_Parse(args, "O", &x))
733 return NULL;
734 return PyMarshal_WriteObjectToString(x);
737 static PyObject *
738 marshal_loads(self, args)
739 PyObject *self;
740 PyObject *args;
742 RFILE rf;
743 PyObject *v;
744 char *s;
745 int n;
746 if (!PyArg_Parse(args, "s#", &s, &n))
747 return NULL;
748 rf.fp = NULL;
749 rf.str = args;
750 rf.ptr = s;
751 rf.end = s + n;
752 PyErr_Clear();
753 v = r_object(&rf);
754 if (PyErr_Occurred()) {
755 Py_XDECREF(v);
756 v = NULL;
758 return v;
761 static PyMethodDef marshal_methods[] = {
762 {"dump", marshal_dump},
763 {"load", marshal_load},
764 {"dumps", marshal_dumps},
765 {"loads", marshal_loads},
766 {NULL, NULL} /* sentinel */
769 void
770 PyMarshal_Init()
772 (void) Py_InitModule("marshal", marshal_methods);