blob: 3d5f2e5315514b2f59bff92e043a6eb6e9205b97 [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 Rossuma45cb451998-06-08 20:27:29 +0000466 if (n < 0) {
467 PyErr_SetString(PyExc_ValueError, "bad marshal data");
468 return NULL;
469 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000470 v = PyString_FromStringAndSize((char *)NULL, n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000471 if (v != NULL) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000472 if (r_string(PyString_AsString(v), (int)n, p) != n) {
473 Py_DECREF(v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000474 v = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000475 PyErr_SetString(PyExc_EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000476 "EOF read where object expected");
477 }
478 }
479 return v;
480
481 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000482 n = r_long(p);
Guido van Rossuma45cb451998-06-08 20:27:29 +0000483 if (n < 0) {
484 PyErr_SetString(PyExc_ValueError, "bad marshal data");
485 return NULL;
486 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000487 v = PyTuple_New((int)n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000488 if (v == NULL)
489 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000490 for (i = 0; i < n; i++) {
491 v2 = r_object(p);
492 if ( v2 == NULL ) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000493 Py_DECREF(v);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000494 v = NULL;
495 break;
496 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000497 PyTuple_SET_ITEM(v, (int)i, v2);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000498 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000499 return v;
500
501 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000502 n = r_long(p);
Guido van Rossuma45cb451998-06-08 20:27:29 +0000503 if (n < 0) {
504 PyErr_SetString(PyExc_ValueError, "bad marshal data");
505 return NULL;
506 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000507 v = PyList_New((int)n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000508 if (v == NULL)
509 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000510 for (i = 0; i < n; i++) {
511 v2 = r_object(p);
512 if ( v2 == NULL ) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000513 Py_DECREF(v);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000514 v = NULL;
515 break;
516 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000517 PyList_SetItem(v, (int)i, v2);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000518 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000519 return v;
520
Guido van Rossum64b45521991-06-07 13:58:22 +0000521 case TYPE_DICT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000522 v = PyDict_New();
Guido van Rossum64b45521991-06-07 13:58:22 +0000523 if (v == NULL)
524 return NULL;
525 for (;;) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000526 PyObject *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000527 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000528 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000529 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000530 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000531 if (val != NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000532 PyDict_SetItem(v, key, val);
533 Py_DECREF(key);
534 Py_XDECREF(val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000535 }
536 return v;
537
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000538 case TYPE_CODE:
539 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000540 int argcount = r_short(p);
541 int nlocals = r_short(p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000542 int stacksize = r_short(p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000543 int flags = r_short(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000544 PyObject *code = NULL;
545 PyObject *consts = NULL;
546 PyObject *names = NULL;
547 PyObject *varnames = NULL;
548 PyObject *filename = NULL;
549 PyObject *name = NULL;
Guido van Rossum0f4bbd21997-02-14 21:12:56 +0000550 int firstlineno = 0;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000551 PyObject *lnotab = NULL;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000552
553 code = r_object(p);
554 if (code) consts = r_object(p);
555 if (consts) names = r_object(p);
556 if (names) varnames = r_object(p);
557 if (varnames) filename = r_object(p);
558 if (filename) name = r_object(p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000559 if (name) {
560 firstlineno = r_short(p);
561 lnotab = r_object(p);
562 }
Jack Jansen9513f2c1995-10-27 13:21:28 +0000563
Guido van Rossum79f25d91997-04-29 20:08:16 +0000564 if (!PyErr_Occurred()) {
565 v = (PyObject *) PyCode_New(
Guido van Rossum98a9b311997-01-17 21:07:08 +0000566 argcount, nlocals, stacksize, flags,
Guido van Rossum681d79a1995-07-18 14:51:37 +0000567 code, consts, names, varnames,
Guido van Rossumd031c891997-01-24 03:44:17 +0000568 filename, name, firstlineno, lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000569 }
570 else
571 v = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000572 Py_XDECREF(code);
573 Py_XDECREF(consts);
574 Py_XDECREF(names);
575 Py_XDECREF(varnames);
576 Py_XDECREF(filename);
577 Py_XDECREF(name);
Guido van Rossum6fc06e71997-07-26 23:30:18 +0000578 Py_XDECREF(lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000579
580 }
581 return v;
582
583 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000584 /* Bogus data got written, which isn't ideal.
585 This will let you keep working and recover. */
Guido van Rossuma45cb451998-06-08 20:27:29 +0000586 PyErr_SetString(PyExc_ValueError, "bad marshal data");
587 return NULL;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000588
589 }
590}
591
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000592long
Guido van Rossum79f25d91997-04-29 20:08:16 +0000593PyMarshal_ReadLongFromFile(fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000594 FILE *fp;
595{
596 RFILE rf;
597 rf.fp = fp;
598 return r_long(&rf);
599}
600
Guido van Rossum79f25d91997-04-29 20:08:16 +0000601PyObject *
602PyMarshal_ReadObjectFromFile(fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000603 FILE *fp;
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 rd_object called with exception set\n");
608 return NULL;
609 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000610 rf.fp = fp;
611 return r_object(&rf);
612}
613
Guido van Rossum79f25d91997-04-29 20:08:16 +0000614PyObject *
615PyMarshal_ReadObjectFromString(str, len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000616 char *str;
617 int len;
618{
619 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000620 if (PyErr_Occurred()) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000621 fprintf(stderr, "XXX rds_object called with exception set\n");
622 return NULL;
623 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000624 rf.fp = NULL;
625 rf.str = NULL;
626 rf.ptr = str;
627 rf.end = str + len;
628 return r_object(&rf);
629}
630
Guido van Rossum79f25d91997-04-29 20:08:16 +0000631PyObject *
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000632PyMarshal_WriteObjectToString(x) /* wrs_object() */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000633 PyObject *x;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000634{
635 WFILE wf;
636 wf.fp = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000637 wf.str = PyString_FromStringAndSize((char *)NULL, 50);
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000638 if (wf.str == NULL)
639 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000640 wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
641 wf.end = wf.ptr + PyString_Size(wf.str);
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000642 wf.error = 0;
643 w_object(x, &wf);
644 if (wf.str != NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000645 _PyString_Resize(&wf.str,
646 (int) (wf.ptr -
647 PyString_AS_STRING((PyStringObject *)wf.str)));
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000648 if (wf.error) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000649 Py_XDECREF(wf.str);
650 PyErr_SetString(PyExc_ValueError, "unmarshallable object");
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000651 return NULL;
652 }
653 return wf.str;
654}
655
Guido van Rossum64b45521991-06-07 13:58:22 +0000656/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000657
Guido van Rossum79f25d91997-04-29 20:08:16 +0000658static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000659marshal_dump(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000660 PyObject *self;
661 PyObject *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000662{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000663 WFILE wf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000664 PyObject *x;
665 PyObject *f;
666 if (!PyArg_Parse(args, "(OO)", &x, &f))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000667 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000668 if (!PyFile_Check(f)) {
669 PyErr_SetString(PyExc_TypeError,
670 "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000671 return NULL;
672 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000673 wf.fp = PyFile_AsFile(f);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000674 wf.str = NULL;
675 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000676 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000677 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000678 if (wf.error) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000679 PyErr_SetString(PyExc_ValueError, "unmarshallable object");
Guido van Rossumf2150601996-06-26 20:41:23 +0000680 return NULL;
681 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000682 Py_INCREF(Py_None);
683 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000684}
685
Guido van Rossum79f25d91997-04-29 20:08:16 +0000686static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000687marshal_load(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000688 PyObject *self;
689 PyObject *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000690{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000691 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000692 PyObject *f;
693 PyObject *v;
694 if (!PyArg_Parse(args, "O", &f))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000695 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000696 if (!PyFile_Check(f)) {
697 PyErr_SetString(PyExc_TypeError,
698 "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000699 return NULL;
700 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000701 rf.fp = PyFile_AsFile(f);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000702 rf.str = NULL;
703 rf.ptr = rf.end = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000704 PyErr_Clear();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000705 v = r_object(&rf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000706 if (PyErr_Occurred()) {
707 Py_XDECREF(v);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000708 v = NULL;
709 }
710 return v;
711}
712
Guido van Rossum79f25d91997-04-29 20:08:16 +0000713static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000714marshal_dumps(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000715 PyObject *self;
716 PyObject *args;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000717{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000718 PyObject *x;
719 if (!PyArg_Parse(args, "O", &x))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000720 return NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000721 return PyMarshal_WriteObjectToString(x);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000722}
723
Guido van Rossum79f25d91997-04-29 20:08:16 +0000724static PyObject *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000725marshal_loads(self, args)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000726 PyObject *self;
727 PyObject *args;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000728{
729 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000730 PyObject *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000731 char *s;
732 int n;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000733 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000734 return NULL;
735 rf.fp = NULL;
736 rf.str = args;
737 rf.ptr = s;
738 rf.end = s + n;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000739 PyErr_Clear();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000740 v = r_object(&rf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000741 if (PyErr_Occurred()) {
742 Py_XDECREF(v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000743 v = NULL;
744 }
745 return v;
746}
747
Guido van Rossum79f25d91997-04-29 20:08:16 +0000748static PyMethodDef marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000749 {"dump", marshal_dump},
750 {"load", marshal_load},
751 {"dumps", marshal_dumps},
752 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000753 {NULL, NULL} /* sentinel */
754};
755
756void
Guido van Rossum79f25d91997-04-29 20:08:16 +0000757PyMarshal_Init()
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000758{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000759 (void) Py_InitModule("marshal", marshal_methods);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000760}