blob: 3664734c0a2f6e0fd201bc11a221bdb8c2905c51 [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
Guido van Rossum730806d1998-04-10 22:27:42 +0000146 if (v == NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000147 w_byte(TYPE_NULL, p);
Guido van Rossum730806d1998-04-10 22:27:42 +0000148 }
149 else if (v == Py_None) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000150 w_byte(TYPE_NONE, p);
Guido van Rossum730806d1998-04-10 22:27:42 +0000151 }
152 else if (v == Py_Ellipsis) {
153 w_byte(TYPE_ELLIPSIS, p);
154 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000155 else if (PyInt_Check(v)) {
156 long x = PyInt_AS_LONG((PyIntObject *)v);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000157#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000158 long y = x>>31;
159 if (y && y != -1) {
160 w_byte(TYPE_INT64, p);
161 w_long64(x, p);
162 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000163 else
164#endif
165 {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000166 w_byte(TYPE_INT, p);
167 w_long(x, p);
168 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000169 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000170 else if (PyLong_Check(v)) {
171 PyLongObject *ob = (PyLongObject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000172 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000173 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000174 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000175 if (n < 0)
176 n = -n;
177 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000178 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000179 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000180 else if (PyFloat_Check(v)) {
181 extern void PyFloat_AsString
182 Py_PROTO((char *, PyFloatObject *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000183 char buf[256]; /* Plenty to format any double */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000184 PyFloat_AsString(buf, (PyFloatObject *)v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000185 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000186 w_byte(TYPE_FLOAT, p);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000187 w_byte(n, p);
188 w_string(buf, n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000189 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000190#ifndef WITHOUT_COMPLEX
Guido van Rossum79f25d91997-04-29 20:08:16 +0000191 else if (PyComplex_Check(v)) {
192 extern void PyFloat_AsString
193 Py_PROTO((char *, PyFloatObject *));
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000194 char buf[256]; /* Plenty to format any double */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000195 PyFloatObject *temp;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000196 w_byte(TYPE_COMPLEX, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000197 temp = (PyFloatObject*)PyFloat_FromDouble(
198 PyComplex_RealAsDouble(v));
199 PyFloat_AsString(buf, temp);
200 Py_DECREF(temp);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000201 n = strlen(buf);
202 w_byte(n, p);
203 w_string(buf, n, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000204 temp = (PyFloatObject*)PyFloat_FromDouble(
205 PyComplex_ImagAsDouble(v));
206 PyFloat_AsString(buf, temp);
207 Py_DECREF(temp);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000208 n = strlen(buf);
209 w_byte(n, p);
210 w_string(buf, n, p);
211 }
212#endif
Guido van Rossum79f25d91997-04-29 20:08:16 +0000213 else if (PyString_Check(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000214 w_byte(TYPE_STRING, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000215 n = PyString_Size(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000216 w_long((long)n, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000217 w_string(PyString_AsString(v), n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000218 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000219 else if (PyTuple_Check(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000220 w_byte(TYPE_TUPLE, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000221 n = PyTuple_Size(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000222 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000223 for (i = 0; i < n; i++) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000224 w_object(PyTuple_GET_ITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000225 }
226 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000227 else if (PyList_Check(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000228 w_byte(TYPE_LIST, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000229 n = PyList_Size(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000230 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000231 for (i = 0; i < n; i++) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000232 w_object(PyList_GetItem(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000233 }
234 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000235 else if (PyDict_Check(v)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000236 int pos;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000237 PyObject *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000238 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000239 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000240 pos = 0;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000241 while (PyDict_Next(v, &pos, &key, &value)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000242 w_object(key, p);
243 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000244 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000245 w_object((PyObject *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000246 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000247 else if (PyCode_Check(v)) {
248 PyCodeObject *co = (PyCodeObject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000249 w_byte(TYPE_CODE, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000250 w_short(co->co_argcount, p);
251 w_short(co->co_nlocals, p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000252 w_short(co->co_stacksize, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000253 w_short(co->co_flags, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000254 w_object((PyObject *)co->co_code, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000255 w_object(co->co_consts, p);
256 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000257 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000258 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000259 w_object(co->co_name, p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000260 w_short(co->co_firstlineno, p);
261 w_object(co->co_lnotab, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000262 }
263 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000264 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000265 p->error = 1;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000266 }
267}
268
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000269void
Guido van Rossum79f25d91997-04-29 20:08:16 +0000270PyMarshal_WriteLongToFile(x, fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000271 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000272 FILE *fp;
273{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000274 WFILE wf;
275 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000276 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000277 w_long(x, &wf);
278}
279
280void
Guido van Rossum79f25d91997-04-29 20:08:16 +0000281PyMarshal_WriteObjectToFile(x, fp)
282 PyObject *x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000283 FILE *fp;
284{
285 WFILE wf;
286 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000287 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000288 w_object(x, &wf);
289}
290
291typedef WFILE RFILE; /* Same struct with different invariants */
292
Guido van Rossum8d617a61995-03-09 12:12:11 +0000293#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
294
295#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000296
297static int
298r_string(s, n, p)
299 char *s;
300 int n;
301 RFILE *p;
302{
303 if (p->fp != NULL)
304 return fread(s, 1, n, p->fp);
305 if (p->end - p->ptr < n)
306 n = p->end - p->ptr;
307 memcpy(s, p->ptr, n);
308 p->ptr += n;
309 return n;
310}
311
312static int
313r_short(p)
314 RFILE *p;
315{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000316 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000317 x = r_byte(p);
318 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000319 /* XXX If your short is > 16 bits, add sign-extension here!!! */
320 return x;
321}
322
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000323static long
324r_long(p)
325 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000326{
327 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000328 register FILE *fp = p->fp;
329 if (fp) {
330 x = getc(fp);
331 x |= (long)getc(fp) << 8;
332 x |= (long)getc(fp) << 16;
333 x |= (long)getc(fp) << 24;
334 }
335 else {
336 x = rs_byte(p);
337 x |= (long)rs_byte(p) << 8;
338 x |= (long)rs_byte(p) << 16;
339 x |= (long)rs_byte(p) << 24;
340 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000341#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000342 /* Sign extension for 64-bit machines */
343 x <<= (8*sizeof(long) - 32);
344 x >>= (8*sizeof(long) - 32);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000345#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000346 return x;
347}
348
349static long
350r_long64(p)
351 RFILE *p;
352{
353 register long x;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000354 x = r_long(p);
355#if SIZEOF_LONG > 4
356 x = (x & 0xFFFFFFFF) | (r_long(p) << 32);
357#else
358 if (r_long(p) != 0) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000359 PyObject *f = PySys_GetObject("stderr");
Guido van Rossumc1547d91996-12-10 15:39:04 +0000360 if (f != NULL)
Guido van Rossum7e8d26d1997-05-22 22:35:47 +0000361 (void) PyFile_WriteString(
Guido van Rossumc1547d91996-12-10 15:39:04 +0000362 "Warning: un-marshal 64-bit int in 32-bit mode\n",
363 f);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000364 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000365#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000366 return x;
367}
368
Guido van Rossum79f25d91997-04-29 20:08:16 +0000369static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000370r_object(p)
371 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000372{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000373 PyObject *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000374 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000375 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000376
377 switch (type) {
378
379 case EOF:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000380 PyErr_SetString(PyExc_EOFError,
381 "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000382 return NULL;
383
384 case TYPE_NULL:
385 return NULL;
386
387 case TYPE_NONE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000388 Py_INCREF(Py_None);
389 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000390
Guido van Rossume449af71996-10-11 16:25:41 +0000391 case TYPE_ELLIPSIS:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000392 Py_INCREF(Py_Ellipsis);
Guido van Rossume449af71996-10-11 16:25:41 +0000393 return Py_Ellipsis;
Guido van Rossum8861b741996-07-30 16:49:37 +0000394
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000395 case TYPE_INT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000396 return PyInt_FromLong(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000397
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000398 case TYPE_INT64:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000399 return PyInt_FromLong(r_long64(p));
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000400
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000401 case TYPE_LONG:
402 {
403 int size;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000404 PyLongObject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000405 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000406 size = n<0 ? -n : n;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000407 ob = _PyLong_New(size);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000408 if (ob == NULL)
409 return NULL;
410 ob->ob_size = n;
411 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000412 ob->ob_digit[i] = r_short(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000413 return (PyObject *)ob;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000414 }
415
416 case TYPE_FLOAT:
417 {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000418 extern double atof Py_PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000419 char buf[256];
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000420 double dx;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000421 n = r_byte(p);
422 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000423 PyErr_SetString(PyExc_EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000424 "EOF read where object expected");
425 return NULL;
426 }
427 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000428 PyFPE_START_PROTECT("atof", return 0)
429 dx = atof(buf);
Guido van Rossum45b83911997-03-14 04:32:50 +0000430 PyFPE_END_PROTECT(dx)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000431 return PyFloat_FromDouble(dx);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000432 }
433
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000434#ifndef WITHOUT_COMPLEX
435 case TYPE_COMPLEX:
436 {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000437 extern double atof Py_PROTO((const char *));
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000438 char buf[256];
Guido van Rossum530956d1996-07-21 02:27:43 +0000439 Py_complex c;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000440 n = r_byte(p);
441 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000442 PyErr_SetString(PyExc_EOFError,
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000443 "EOF read where object expected");
444 return NULL;
445 }
446 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000447 PyFPE_START_PROTECT("atof", return 0)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000448 c.real = atof(buf);
Guido van Rossum45b83911997-03-14 04:32:50 +0000449 PyFPE_END_PROTECT(c)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000450 n = r_byte(p);
451 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000452 PyErr_SetString(PyExc_EOFError,
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000453 "EOF read where object expected");
454 return NULL;
455 }
456 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000457 PyFPE_START_PROTECT("atof", return 0)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000458 c.imag = atof(buf);
Guido van Rossum45b83911997-03-14 04:32:50 +0000459 PyFPE_END_PROTECT(c)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000460 return PyComplex_FromCComplex(c);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000461 }
462#endif
463
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000464 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000465 n = r_long(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000466 v = PyString_FromStringAndSize((char *)NULL, n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000467 if (v != NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000468 if (r_string(PyString_AsString(v), (int)n, p) != n) {
469 Py_DECREF(v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000470 v = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000471 PyErr_SetString(PyExc_EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000472 "EOF read where object expected");
473 }
474 }
475 return v;
476
477 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000478 n = r_long(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000479 v = PyTuple_New((int)n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000480 if (v == NULL)
481 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000482 for (i = 0; i < n; i++) {
483 v2 = r_object(p);
484 if ( v2 == NULL ) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000485 Py_DECREF(v);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000486 v = NULL;
487 break;
488 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000489 PyTuple_SET_ITEM(v, (int)i, v2);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000490 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000491 return v;
492
493 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000494 n = r_long(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000495 v = PyList_New((int)n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000496 if (v == NULL)
497 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000498 for (i = 0; i < n; i++) {
499 v2 = r_object(p);
500 if ( v2 == NULL ) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000501 Py_DECREF(v);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000502 v = NULL;
503 break;
504 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000505 PyList_SetItem(v, (int)i, v2);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000506 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000507 return v;
508
Guido van Rossum64b45521991-06-07 13:58:22 +0000509 case TYPE_DICT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000510 v = PyDict_New();
Guido van Rossum64b45521991-06-07 13:58:22 +0000511 if (v == NULL)
512 return NULL;
513 for (;;) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000514 PyObject *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000515 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000516 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000517 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000518 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000519 if (val != NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000520 PyDict_SetItem(v, key, val);
521 Py_DECREF(key);
522 Py_XDECREF(val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000523 }
524 return v;
525
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000526 case TYPE_CODE:
527 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000528 int argcount = r_short(p);
529 int nlocals = r_short(p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000530 int stacksize = r_short(p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000531 int flags = r_short(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000532 PyObject *code = NULL;
533 PyObject *consts = NULL;
534 PyObject *names = NULL;
535 PyObject *varnames = NULL;
536 PyObject *filename = NULL;
537 PyObject *name = NULL;
Guido van Rossum0f4bbd21997-02-14 21:12:56 +0000538 int firstlineno = 0;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000539 PyObject *lnotab = NULL;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000540
541 code = r_object(p);
542 if (code) consts = r_object(p);
543 if (consts) names = r_object(p);
544 if (names) varnames = r_object(p);
545 if (varnames) filename = r_object(p);
546 if (filename) name = r_object(p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000547 if (name) {
548 firstlineno = r_short(p);
549 lnotab = r_object(p);
550 }
Jack Jansen9513f2c1995-10-27 13:21:28 +0000551
Guido van Rossum79f25d91997-04-29 20:08:16 +0000552 if (!PyErr_Occurred()) {
553 v = (PyObject *) PyCode_New(
Guido van Rossum98a9b311997-01-17 21:07:08 +0000554 argcount, nlocals, stacksize, flags,
Guido van Rossum681d79a1995-07-18 14:51:37 +0000555 code, consts, names, varnames,
Guido van Rossumd031c891997-01-24 03:44:17 +0000556 filename, name, firstlineno, lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000557 }
558 else
559 v = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000560 Py_XDECREF(code);
561 Py_XDECREF(consts);
562 Py_XDECREF(names);
563 Py_XDECREF(varnames);
564 Py_XDECREF(filename);
565 Py_XDECREF(name);
Guido van Rossum6fc06e71997-07-26 23:30:18 +0000566 Py_XDECREF(lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000567
568 }
569 return v;
570
571 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000572 /* Bogus data got written, which isn't ideal.
573 This will let you keep working and recover. */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000574 Py_INCREF(Py_None);
575 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000576
577 }
578}
579
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000580long
Guido van Rossum79f25d91997-04-29 20:08:16 +0000581PyMarshal_ReadLongFromFile(fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000582 FILE *fp;
583{
584 RFILE rf;
585 rf.fp = fp;
586 return r_long(&rf);
587}
588
Guido van Rossum79f25d91997-04-29 20:08:16 +0000589PyObject *
590PyMarshal_ReadObjectFromFile(fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000591 FILE *fp;
592{
593 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000594 if (PyErr_Occurred()) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000595 fprintf(stderr, "XXX rd_object called with exception set\n");
596 return NULL;
597 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000598 rf.fp = fp;
599 return r_object(&rf);
600}
601
Guido van Rossum79f25d91997-04-29 20:08:16 +0000602PyObject *
603PyMarshal_ReadObjectFromString(str, len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000604 char *str;
605 int len;
606{
607 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000608 if (PyErr_Occurred()) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000609 fprintf(stderr, "XXX rds_object called with exception set\n");
610 return NULL;
611 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000612 rf.fp = NULL;
613 rf.str = NULL;
614 rf.ptr = str;
615 rf.end = str + len;
616 return r_object(&rf);
617}
618
Guido van Rossum79f25d91997-04-29 20:08:16 +0000619PyObject *
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000620PyMarshal_WriteObjectToString(x) /* wrs_object() */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000621 PyObject *x;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000622{
623 WFILE wf;
624 wf.fp = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000625 wf.str = PyString_FromStringAndSize((char *)NULL, 50);
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000626 if (wf.str == NULL)
627 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000628 wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
629 wf.end = wf.ptr + PyString_Size(wf.str);
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000630 wf.error = 0;
631 w_object(x, &wf);
632 if (wf.str != NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000633 _PyString_Resize(&wf.str,
634 (int) (wf.ptr -
635 PyString_AS_STRING((PyStringObject *)wf.str)));
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000636 if (wf.error) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000637 Py_XDECREF(wf.str);
638 PyErr_SetString(PyExc_ValueError, "unmarshallable object");
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000639 return NULL;
640 }
641 return wf.str;
642}
643
Guido van Rossum64b45521991-06-07 13:58:22 +0000644/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000645
Guido van Rossum79f25d91997-04-29 20:08:16 +0000646static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000647marshal_dump(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000648 PyObject *self;
649 PyObject *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000650{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000651 WFILE wf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000652 PyObject *x;
653 PyObject *f;
654 if (!PyArg_Parse(args, "(OO)", &x, &f))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000655 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000656 if (!PyFile_Check(f)) {
657 PyErr_SetString(PyExc_TypeError,
658 "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000659 return NULL;
660 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000661 wf.fp = PyFile_AsFile(f);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000662 wf.str = NULL;
663 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000664 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000665 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000666 if (wf.error) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000667 PyErr_SetString(PyExc_ValueError, "unmarshallable object");
Guido van Rossumf2150601996-06-26 20:41:23 +0000668 return NULL;
669 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000670 Py_INCREF(Py_None);
671 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000672}
673
Guido van Rossum79f25d91997-04-29 20:08:16 +0000674static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000675marshal_load(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000676 PyObject *self;
677 PyObject *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000678{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000679 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000680 PyObject *f;
681 PyObject *v;
682 if (!PyArg_Parse(args, "O", &f))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000683 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000684 if (!PyFile_Check(f)) {
685 PyErr_SetString(PyExc_TypeError,
686 "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000687 return NULL;
688 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000689 rf.fp = PyFile_AsFile(f);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000690 rf.str = NULL;
691 rf.ptr = rf.end = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000692 PyErr_Clear();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000693 v = r_object(&rf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000694 if (PyErr_Occurred()) {
695 Py_XDECREF(v);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000696 v = NULL;
697 }
698 return v;
699}
700
Guido van Rossum79f25d91997-04-29 20:08:16 +0000701static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000702marshal_dumps(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000703 PyObject *self;
704 PyObject *args;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000705{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000706 PyObject *x;
707 if (!PyArg_Parse(args, "O", &x))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000708 return NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000709 return PyMarshal_WriteObjectToString(x);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000710}
711
Guido van Rossum79f25d91997-04-29 20:08:16 +0000712static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000713marshal_loads(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000714 PyObject *self;
715 PyObject *args;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000716{
717 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000718 PyObject *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000719 char *s;
720 int n;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000721 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000722 return NULL;
723 rf.fp = NULL;
724 rf.str = args;
725 rf.ptr = s;
726 rf.end = s + n;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000727 PyErr_Clear();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000728 v = r_object(&rf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000729 if (PyErr_Occurred()) {
730 Py_XDECREF(v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000731 v = NULL;
732 }
733 return v;
734}
735
Guido van Rossum79f25d91997-04-29 20:08:16 +0000736static PyMethodDef marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000737 {"dump", marshal_dump},
738 {"load", marshal_load},
739 {"dumps", marshal_dumps},
740 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000741 {NULL, NULL} /* sentinel */
742};
743
744void
Guido van Rossum79f25d91997-04-29 20:08:16 +0000745PyMarshal_Init()
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000746{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000747 (void) Py_InitModule("marshal", marshal_methods);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000748}