blob: 75a20c23ec844c270960c6575abb5a1dc47aaff8 [file] [log] [blame]
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001/***********************************************************
Guido van Rossum6d023c91995-01-04 19:12:13 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000029
30******************************************************************/
31
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. */
36
Guido van Rossum79f25d91997-04-29 20:08:16 +000037#include "Python.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000038#include "longintrepr.h"
39#include "compile.h"
40#include "marshal.h"
41
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000042#define TYPE_NULL '0'
43#define TYPE_NONE 'N'
Guido van Rossume449af71996-10-11 16:25:41 +000044#define TYPE_ELLIPSIS '.'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000045#define TYPE_INT 'i'
Guido van Rossumb0c168c1996-12-05 23:15:02 +000046#define TYPE_INT64 'I'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000047#define TYPE_FLOAT 'f'
Guido van Rossum8a5c5d21996-01-12 01:09:56 +000048#define TYPE_COMPLEX 'x'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000049#define TYPE_LONG 'l'
50#define TYPE_STRING 's'
51#define TYPE_TUPLE '('
52#define TYPE_LIST '['
53#define TYPE_DICT '{'
Guido van Rossum681d79a1995-07-18 14:51:37 +000054#define TYPE_CODE 'c'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000055#define TYPE_UNKNOWN '?'
56
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000057typedef struct {
58 FILE *fp;
Guido van Rossumf2150601996-06-26 20:41:23 +000059 int error;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000060 /* If fp == NULL, the following are valid: */
Guido van Rossum79f25d91997-04-29 20:08:16 +000061 PyObject *str;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000062 char *ptr;
63 char *end;
64} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000065
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000066#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)
69
70static void
71w_more(c, p)
72 char c;
73 WFILE *p;
74{
75 int size, newsize;
76 if (p->str == NULL)
77 return; /* An error already occurred */
Guido van Rossum79f25d91997-04-29 20:08:16 +000078 size = PyString_Size(p->str);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000079 newsize = size + 1024;
Guido van Rossum79f25d91997-04-29 20:08:16 +000080 if (_PyString_Resize(&p->str, newsize) != 0) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000081 p->ptr = p->end = NULL;
82 }
83 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +000084 p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
85 p->end =
86 PyString_AS_STRING((PyStringObject *)p->str) + newsize;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000087 *p->ptr++ = c;
88 }
89}
90
91static void
92w_string(s, n, p)
93 char *s;
94 int n;
95 WFILE *p;
96{
97 if (p->fp != NULL) {
98 fwrite(s, 1, n, p->fp);
99 }
100 else {
101 while (--n >= 0) {
102 w_byte(*s, p);
103 s++;
104 }
105 }
106}
107
108static void
109w_short(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000110 int x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000111 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000112{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000113 w_byte( x & 0xff, p);
114 w_byte((x>> 8) & 0xff, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000115}
116
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000117static void
118w_long(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000119 long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000120 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000121{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000122 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);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000126}
127
Guido van Rossumc1547d91996-12-10 15:39:04 +0000128#if SIZEOF_LONG > 4
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000129static void
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000130w_long64(x, p)
131 long x;
132 WFILE *p;
133{
134 w_long(x, p);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000135 w_long(x>>32, p);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000136}
Guido van Rossumc1547d91996-12-10 15:39:04 +0000137#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000138
139static void
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000140w_object(v, p)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000141 PyObject *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000142 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000143{
Guido van Rossum3a205f71995-02-17 15:10:07 +0000144 int i, n;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000145
146 if (v == NULL)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000147 w_byte(TYPE_NULL, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000148 else if (v == Py_None)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000149 w_byte(TYPE_NONE, p);
Guido van Rossume449af71996-10-11 16:25:41 +0000150 else if (v == Py_Ellipsis)
151 w_byte(TYPE_ELLIPSIS, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000152 else if (PyInt_Check(v)) {
153 long x = PyInt_AS_LONG((PyIntObject *)v);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000154#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000155 long y = x>>31;
156 if (y && y != -1) {
157 w_byte(TYPE_INT64, p);
158 w_long64(x, p);
159 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000160 else
161#endif
162 {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000163 w_byte(TYPE_INT, p);
164 w_long(x, p);
165 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000166 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000167 else if (PyLong_Check(v)) {
168 PyLongObject *ob = (PyLongObject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000169 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000170 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000171 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000172 if (n < 0)
173 n = -n;
174 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000175 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000176 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000177 else if (PyFloat_Check(v)) {
178 extern void PyFloat_AsString
179 Py_PROTO((char *, PyFloatObject *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000180 char buf[256]; /* Plenty to format any double */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000181 PyFloat_AsString(buf, (PyFloatObject *)v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000182 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000183 w_byte(TYPE_FLOAT, p);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000184 w_byte(n, p);
185 w_string(buf, n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000186 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000187#ifndef WITHOUT_COMPLEX
Guido van Rossum79f25d91997-04-29 20:08:16 +0000188 else if (PyComplex_Check(v)) {
189 extern void PyFloat_AsString
190 Py_PROTO((char *, PyFloatObject *));
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000191 char buf[256]; /* Plenty to format any double */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000192 PyFloatObject *temp;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000193 w_byte(TYPE_COMPLEX, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000194 temp = (PyFloatObject*)PyFloat_FromDouble(
195 PyComplex_RealAsDouble(v));
196 PyFloat_AsString(buf, temp);
197 Py_DECREF(temp);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000198 n = strlen(buf);
199 w_byte(n, p);
200 w_string(buf, n, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000201 temp = (PyFloatObject*)PyFloat_FromDouble(
202 PyComplex_ImagAsDouble(v));
203 PyFloat_AsString(buf, temp);
204 Py_DECREF(temp);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000205 n = strlen(buf);
206 w_byte(n, p);
207 w_string(buf, n, p);
208 }
209#endif
Guido van Rossum79f25d91997-04-29 20:08:16 +0000210 else if (PyString_Check(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000211 w_byte(TYPE_STRING, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000212 n = PyString_Size(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000213 w_long((long)n, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000214 w_string(PyString_AsString(v), n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000215 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000216 else if (PyTuple_Check(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000217 w_byte(TYPE_TUPLE, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000218 n = PyTuple_Size(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000219 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000220 for (i = 0; i < n; i++) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000221 w_object(PyTuple_GET_ITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000222 }
223 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000224 else if (PyList_Check(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000225 w_byte(TYPE_LIST, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000226 n = PyList_Size(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000227 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000228 for (i = 0; i < n; i++) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000229 w_object(PyList_GetItem(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000230 }
231 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000232 else if (PyDict_Check(v)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000233 int pos;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000234 PyObject *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000235 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000236 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000237 pos = 0;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000238 while (PyDict_Next(v, &pos, &key, &value)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000239 w_object(key, p);
240 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000241 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000242 w_object((PyObject *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000243 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000244 else if (PyCode_Check(v)) {
245 PyCodeObject *co = (PyCodeObject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000246 w_byte(TYPE_CODE, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000247 w_short(co->co_argcount, p);
248 w_short(co->co_nlocals, p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000249 w_short(co->co_stacksize, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000250 w_short(co->co_flags, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000251 w_object((PyObject *)co->co_code, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000252 w_object(co->co_consts, p);
253 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000254 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000255 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000256 w_object(co->co_name, p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000257 w_short(co->co_firstlineno, p);
258 w_object(co->co_lnotab, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000259 }
260 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000261 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000262 p->error = 1;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000263 }
264}
265
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000266void
Guido van Rossum79f25d91997-04-29 20:08:16 +0000267PyMarshal_WriteLongToFile(x, fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000268 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000269 FILE *fp;
270{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000271 WFILE wf;
272 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000273 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000274 w_long(x, &wf);
275}
276
277void
Guido van Rossum79f25d91997-04-29 20:08:16 +0000278PyMarshal_WriteObjectToFile(x, fp)
279 PyObject *x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000280 FILE *fp;
281{
282 WFILE wf;
283 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000284 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000285 w_object(x, &wf);
286}
287
288typedef WFILE RFILE; /* Same struct with different invariants */
289
Guido van Rossum8d617a61995-03-09 12:12:11 +0000290#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
291
292#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000293
294static int
295r_string(s, n, p)
296 char *s;
297 int n;
298 RFILE *p;
299{
300 if (p->fp != NULL)
301 return fread(s, 1, n, p->fp);
302 if (p->end - p->ptr < n)
303 n = p->end - p->ptr;
304 memcpy(s, p->ptr, n);
305 p->ptr += n;
306 return n;
307}
308
309static int
310r_short(p)
311 RFILE *p;
312{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000313 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000314 x = r_byte(p);
315 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000316 /* XXX If your short is > 16 bits, add sign-extension here!!! */
317 return x;
318}
319
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000320static long
321r_long(p)
322 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000323{
324 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000325 register FILE *fp = p->fp;
326 if (fp) {
327 x = getc(fp);
328 x |= (long)getc(fp) << 8;
329 x |= (long)getc(fp) << 16;
330 x |= (long)getc(fp) << 24;
331 }
332 else {
333 x = rs_byte(p);
334 x |= (long)rs_byte(p) << 8;
335 x |= (long)rs_byte(p) << 16;
336 x |= (long)rs_byte(p) << 24;
337 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000338#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000339 /* Sign extension for 64-bit machines */
340 x <<= (8*sizeof(long) - 32);
341 x >>= (8*sizeof(long) - 32);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000342#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000343 return x;
344}
345
346static long
347r_long64(p)
348 RFILE *p;
349{
350 register long x;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000351 x = r_long(p);
352#if SIZEOF_LONG > 4
353 x = (x & 0xFFFFFFFF) | (r_long(p) << 32);
354#else
355 if (r_long(p) != 0) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000356 PyObject *f = PySys_GetObject("stderr");
Guido van Rossumc1547d91996-12-10 15:39:04 +0000357 if (f != NULL)
Guido van Rossum7e8d26d1997-05-22 22:35:47 +0000358 (void) PyFile_WriteString(
Guido van Rossumc1547d91996-12-10 15:39:04 +0000359 "Warning: un-marshal 64-bit int in 32-bit mode\n",
360 f);
Guido van Rossum7e8d26d1997-05-22 22:35:47 +0000361 PyErr_Clear();
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000362 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000363#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000364 return x;
365}
366
Guido van Rossum79f25d91997-04-29 20:08:16 +0000367static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000368r_object(p)
369 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000370{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000371 PyObject *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000372 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000373 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000374
375 switch (type) {
376
377 case EOF:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000378 PyErr_SetString(PyExc_EOFError,
379 "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000380 return NULL;
381
382 case TYPE_NULL:
383 return NULL;
384
385 case TYPE_NONE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000386 Py_INCREF(Py_None);
387 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000388
Guido van Rossume449af71996-10-11 16:25:41 +0000389 case TYPE_ELLIPSIS:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000390 Py_INCREF(Py_Ellipsis);
Guido van Rossume449af71996-10-11 16:25:41 +0000391 return Py_Ellipsis;
Guido van Rossum8861b741996-07-30 16:49:37 +0000392
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000393 case TYPE_INT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000394 return PyInt_FromLong(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000395
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000396 case TYPE_INT64:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000397 return PyInt_FromLong(r_long64(p));
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000398
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000399 case TYPE_LONG:
400 {
401 int size;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000402 PyLongObject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000403 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000404 size = n<0 ? -n : n;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000405 ob = _PyLong_New(size);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000406 if (ob == NULL)
407 return NULL;
408 ob->ob_size = n;
409 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000410 ob->ob_digit[i] = r_short(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000411 return (PyObject *)ob;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000412 }
413
414 case TYPE_FLOAT:
415 {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000416 extern double atof Py_PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000417 char buf[256];
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000418 double dx;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000419 n = r_byte(p);
420 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000421 PyErr_SetString(PyExc_EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000422 "EOF read where object expected");
423 return NULL;
424 }
425 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000426 PyFPE_START_PROTECT("atof", return 0)
427 dx = atof(buf);
Guido van Rossum45b83911997-03-14 04:32:50 +0000428 PyFPE_END_PROTECT(dx)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000429 return PyFloat_FromDouble(dx);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000430 }
431
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000432#ifndef WITHOUT_COMPLEX
433 case TYPE_COMPLEX:
434 {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000435 extern double atof Py_PROTO((const char *));
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000436 char buf[256];
Guido van Rossum530956d1996-07-21 02:27:43 +0000437 Py_complex c;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000438 n = r_byte(p);
439 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000440 PyErr_SetString(PyExc_EOFError,
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000441 "EOF read where object expected");
442 return NULL;
443 }
444 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000445 PyFPE_START_PROTECT("atof", return 0)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000446 c.real = atof(buf);
Guido van Rossum45b83911997-03-14 04:32:50 +0000447 PyFPE_END_PROTECT(c)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000448 n = r_byte(p);
449 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000450 PyErr_SetString(PyExc_EOFError,
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000451 "EOF read where object expected");
452 return NULL;
453 }
454 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000455 PyFPE_START_PROTECT("atof", return 0)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000456 c.imag = atof(buf);
Guido van Rossum45b83911997-03-14 04:32:50 +0000457 PyFPE_END_PROTECT(c)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000458 return PyComplex_FromCComplex(c);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000459 }
460#endif
461
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000462 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000463 n = r_long(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000464 v = PyString_FromStringAndSize((char *)NULL, n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000465 if (v != NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000466 if (r_string(PyString_AsString(v), (int)n, p) != n) {
467 Py_DECREF(v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000468 v = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000469 PyErr_SetString(PyExc_EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000470 "EOF read where object expected");
471 }
472 }
473 return v;
474
475 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000476 n = r_long(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000477 v = PyTuple_New((int)n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000478 if (v == NULL)
479 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000480 for (i = 0; i < n; i++) {
481 v2 = r_object(p);
482 if ( v2 == NULL ) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000483 Py_DECREF(v);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000484 v = NULL;
485 break;
486 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000487 PyTuple_SET_ITEM(v, (int)i, v2);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000488 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000489 return v;
490
491 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000492 n = r_long(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000493 v = PyList_New((int)n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000494 if (v == NULL)
495 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000496 for (i = 0; i < n; i++) {
497 v2 = r_object(p);
498 if ( v2 == NULL ) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000499 Py_DECREF(v);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000500 v = NULL;
501 break;
502 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000503 PyList_SetItem(v, (int)i, v2);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000504 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000505 return v;
506
Guido van Rossum64b45521991-06-07 13:58:22 +0000507 case TYPE_DICT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000508 v = PyDict_New();
Guido van Rossum64b45521991-06-07 13:58:22 +0000509 if (v == NULL)
510 return NULL;
511 for (;;) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000512 PyObject *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000513 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000514 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000515 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000516 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000517 if (val != NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000518 PyDict_SetItem(v, key, val);
519 Py_DECREF(key);
520 Py_XDECREF(val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000521 }
522 return v;
523
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000524 case TYPE_CODE:
525 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000526 int argcount = r_short(p);
527 int nlocals = r_short(p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000528 int stacksize = r_short(p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000529 int flags = r_short(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000530 PyObject *code = NULL;
531 PyObject *consts = NULL;
532 PyObject *names = NULL;
533 PyObject *varnames = NULL;
534 PyObject *filename = NULL;
535 PyObject *name = NULL;
Guido van Rossum0f4bbd21997-02-14 21:12:56 +0000536 int firstlineno = 0;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000537 PyObject *lnotab = NULL;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000538
539 code = r_object(p);
540 if (code) consts = r_object(p);
541 if (consts) names = r_object(p);
542 if (names) varnames = r_object(p);
543 if (varnames) filename = r_object(p);
544 if (filename) name = r_object(p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000545 if (name) {
546 firstlineno = r_short(p);
547 lnotab = r_object(p);
548 }
Jack Jansen9513f2c1995-10-27 13:21:28 +0000549
Guido van Rossum79f25d91997-04-29 20:08:16 +0000550 if (!PyErr_Occurred()) {
551 v = (PyObject *) PyCode_New(
Guido van Rossum98a9b311997-01-17 21:07:08 +0000552 argcount, nlocals, stacksize, flags,
Guido van Rossum681d79a1995-07-18 14:51:37 +0000553 code, consts, names, varnames,
Guido van Rossumd031c891997-01-24 03:44:17 +0000554 filename, name, firstlineno, lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000555 }
556 else
557 v = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000558 Py_XDECREF(code);
559 Py_XDECREF(consts);
560 Py_XDECREF(names);
561 Py_XDECREF(varnames);
562 Py_XDECREF(filename);
563 Py_XDECREF(name);
Guido van Rossum6fc06e71997-07-26 23:30:18 +0000564 Py_XDECREF(lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000565
566 }
567 return v;
568
569 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000570 /* Bogus data got written, which isn't ideal.
571 This will let you keep working and recover. */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000572 Py_INCREF(Py_None);
573 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000574
575 }
576}
577
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000578long
Guido van Rossum79f25d91997-04-29 20:08:16 +0000579PyMarshal_ReadLongFromFile(fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000580 FILE *fp;
581{
582 RFILE rf;
583 rf.fp = fp;
584 return r_long(&rf);
585}
586
Guido van Rossum79f25d91997-04-29 20:08:16 +0000587PyObject *
588PyMarshal_ReadObjectFromFile(fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000589 FILE *fp;
590{
591 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000592 if (PyErr_Occurred()) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000593 fprintf(stderr, "XXX rd_object called with exception set\n");
594 return NULL;
595 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000596 rf.fp = fp;
597 return r_object(&rf);
598}
599
Guido van Rossum79f25d91997-04-29 20:08:16 +0000600PyObject *
601PyMarshal_ReadObjectFromString(str, len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000602 char *str;
603 int len;
604{
605 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000606 if (PyErr_Occurred()) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000607 fprintf(stderr, "XXX rds_object called with exception set\n");
608 return NULL;
609 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000610 rf.fp = NULL;
611 rf.str = NULL;
612 rf.ptr = str;
613 rf.end = str + len;
614 return r_object(&rf);
615}
616
Guido van Rossum79f25d91997-04-29 20:08:16 +0000617PyObject *
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000618PyMarshal_WriteObjectToString(x) /* wrs_object() */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000619 PyObject *x;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000620{
621 WFILE wf;
622 wf.fp = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000623 wf.str = PyString_FromStringAndSize((char *)NULL, 50);
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000624 if (wf.str == NULL)
625 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000626 wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
627 wf.end = wf.ptr + PyString_Size(wf.str);
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000628 wf.error = 0;
629 w_object(x, &wf);
630 if (wf.str != NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000631 _PyString_Resize(&wf.str,
632 (int) (wf.ptr -
633 PyString_AS_STRING((PyStringObject *)wf.str)));
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000634 if (wf.error) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000635 Py_XDECREF(wf.str);
636 PyErr_SetString(PyExc_ValueError, "unmarshallable object");
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000637 return NULL;
638 }
639 return wf.str;
640}
641
Guido van Rossum64b45521991-06-07 13:58:22 +0000642/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000643
Guido van Rossum79f25d91997-04-29 20:08:16 +0000644static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000645marshal_dump(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000646 PyObject *self;
647 PyObject *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000648{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000649 WFILE wf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000650 PyObject *x;
651 PyObject *f;
652 if (!PyArg_Parse(args, "(OO)", &x, &f))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000653 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000654 if (!PyFile_Check(f)) {
655 PyErr_SetString(PyExc_TypeError,
656 "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000657 return NULL;
658 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000659 wf.fp = PyFile_AsFile(f);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000660 wf.str = NULL;
661 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000662 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000663 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000664 if (wf.error) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000665 PyErr_SetString(PyExc_ValueError, "unmarshallable object");
Guido van Rossumf2150601996-06-26 20:41:23 +0000666 return NULL;
667 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000668 Py_INCREF(Py_None);
669 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000670}
671
Guido van Rossum79f25d91997-04-29 20:08:16 +0000672static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000673marshal_load(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000674 PyObject *self;
675 PyObject *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000676{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000677 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000678 PyObject *f;
679 PyObject *v;
680 if (!PyArg_Parse(args, "O", &f))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000681 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000682 if (!PyFile_Check(f)) {
683 PyErr_SetString(PyExc_TypeError,
684 "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000685 return NULL;
686 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000687 rf.fp = PyFile_AsFile(f);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000688 rf.str = NULL;
689 rf.ptr = rf.end = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000690 PyErr_Clear();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000691 v = r_object(&rf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000692 if (PyErr_Occurred()) {
693 Py_XDECREF(v);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000694 v = NULL;
695 }
696 return v;
697}
698
Guido van Rossum79f25d91997-04-29 20:08:16 +0000699static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000700marshal_dumps(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000701 PyObject *self;
702 PyObject *args;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000703{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000704 PyObject *x;
705 if (!PyArg_Parse(args, "O", &x))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000706 return NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000707 return PyMarshal_WriteObjectToString(x);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000708}
709
Guido van Rossum79f25d91997-04-29 20:08:16 +0000710static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000711marshal_loads(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000712 PyObject *self;
713 PyObject *args;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000714{
715 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000716 PyObject *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000717 char *s;
718 int n;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000719 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000720 return NULL;
721 rf.fp = NULL;
722 rf.str = args;
723 rf.ptr = s;
724 rf.end = s + n;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000725 PyErr_Clear();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000726 v = r_object(&rf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000727 if (PyErr_Occurred()) {
728 Py_XDECREF(v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000729 v = NULL;
730 }
731 return v;
732}
733
Guido van Rossum79f25d91997-04-29 20:08:16 +0000734static PyMethodDef marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000735 {"dump", marshal_dump},
736 {"load", marshal_load},
737 {"dumps", marshal_dumps},
738 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000739 {NULL, NULL} /* sentinel */
740};
741
742void
Guido van Rossum79f25d91997-04-29 20:08:16 +0000743PyMarshal_Init()
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000744{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000745 (void) Py_InitModule("marshal", marshal_methods);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000746}