blob: 6638c9ddd0119efb4a6046f94f178a44047ccd94 [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
37#include "allobjects.h"
Guido van Rossum2807d191992-03-27 17:23:17 +000038#include "modsupport.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000039#include "longintrepr.h"
40#include "compile.h"
41#include "marshal.h"
42
43#include <errno.h>
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000044
45#define TYPE_NULL '0'
46#define TYPE_NONE 'N'
Guido van Rossume449af71996-10-11 16:25:41 +000047#define TYPE_ELLIPSIS '.'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000048#define TYPE_INT 'i'
Guido van Rossumb0c168c1996-12-05 23:15:02 +000049#define TYPE_INT64 'I'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000050#define TYPE_FLOAT 'f'
Guido van Rossum8a5c5d21996-01-12 01:09:56 +000051#define TYPE_COMPLEX 'x'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000052#define TYPE_LONG 'l'
53#define TYPE_STRING 's'
54#define TYPE_TUPLE '('
55#define TYPE_LIST '['
56#define TYPE_DICT '{'
Guido van Rossum681d79a1995-07-18 14:51:37 +000057#define TYPE_CODE 'c'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000058#define TYPE_UNKNOWN '?'
59
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000060typedef struct {
61 FILE *fp;
Guido van Rossumf2150601996-06-26 20:41:23 +000062 int error;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000063 /* If fp == NULL, the following are valid: */
64 object *str;
65 char *ptr;
66 char *end;
67} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000068
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000069#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
70 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
71 else w_more(c, p)
72
73static void
74w_more(c, p)
75 char c;
76 WFILE *p;
77{
78 int size, newsize;
79 if (p->str == NULL)
80 return; /* An error already occurred */
81 size = getstringsize(p->str);
82 newsize = size + 1024;
83 if (resizestring(&p->str, newsize) != 0) {
84 p->ptr = p->end = NULL;
85 }
86 else {
87 p->ptr = GETSTRINGVALUE((stringobject *)p->str) + size;
88 p->end = GETSTRINGVALUE((stringobject *)p->str) + newsize;
89 *p->ptr++ = c;
90 }
91}
92
93static void
94w_string(s, n, p)
95 char *s;
96 int n;
97 WFILE *p;
98{
99 if (p->fp != NULL) {
100 fwrite(s, 1, n, p->fp);
101 }
102 else {
103 while (--n >= 0) {
104 w_byte(*s, p);
105 s++;
106 }
107 }
108}
109
110static void
111w_short(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000112 int x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000113 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000114{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000115 w_byte( x & 0xff, p);
116 w_byte((x>> 8) & 0xff, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000117}
118
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000119static void
120w_long(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000121 long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000122 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000123{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000124 w_byte((int)( x & 0xff), p);
125 w_byte((int)((x>> 8) & 0xff), p);
126 w_byte((int)((x>>16) & 0xff), p);
127 w_byte((int)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000128}
129
Guido van Rossumc1547d91996-12-10 15:39:04 +0000130#if SIZEOF_LONG > 4
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000131static void
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000132w_long64(x, p)
133 long x;
134 WFILE *p;
135{
136 w_long(x, p);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000137 w_long(x>>32, p);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000138}
Guido van Rossumc1547d91996-12-10 15:39:04 +0000139#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000140
141static void
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000142w_object(v, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000143 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000144 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000145{
Guido van Rossum3a205f71995-02-17 15:10:07 +0000146 int i, n;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000147
148 if (v == NULL)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000149 w_byte(TYPE_NULL, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000150 else if (v == None)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000151 w_byte(TYPE_NONE, p);
Guido van Rossume449af71996-10-11 16:25:41 +0000152 else if (v == Py_Ellipsis)
153 w_byte(TYPE_ELLIPSIS, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000154 else if (is_intobject(v)) {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000155 long x = GETINTVALUE((intobject *)v);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000156#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000157 long y = x>>31;
158 if (y && y != -1) {
159 w_byte(TYPE_INT64, p);
160 w_long64(x, p);
161 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000162 else
163#endif
164 {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000165 w_byte(TYPE_INT, p);
166 w_long(x, p);
167 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000168 }
169 else if (is_longobject(v)) {
170 longobject *ob = (longobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000171 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000172 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000173 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000174 if (n < 0)
175 n = -n;
176 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000177 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000178 }
179 else if (is_floatobject(v)) {
180 extern void float_buf_repr PROTO((char *, floatobject *));
181 char buf[256]; /* Plenty to format any double */
182 float_buf_repr(buf, (floatobject *)v);
183 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000184 w_byte(TYPE_FLOAT, p);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000185 w_byte(n, p);
186 w_string(buf, n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000187 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000188#ifndef WITHOUT_COMPLEX
189 else if (is_complexobject(v)) {
190 extern void float_buf_repr PROTO((char *, floatobject *));
191 char buf[256]; /* Plenty to format any double */
192 floatobject *temp;
193 w_byte(TYPE_COMPLEX, p);
194 temp = (floatobject*)newfloatobject(PyComplex_RealAsDouble(v));
195 float_buf_repr(buf, temp);
196 DECREF(temp);
197 n = strlen(buf);
198 w_byte(n, p);
199 w_string(buf, n, p);
200 temp = (floatobject*)newfloatobject(PyComplex_ImagAsDouble(v));
201 float_buf_repr(buf, temp);
202 DECREF(temp);
203 n = strlen(buf);
204 w_byte(n, p);
205 w_string(buf, n, p);
206 }
207#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000208 else if (is_stringobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000209 w_byte(TYPE_STRING, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000210 n = getstringsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000211 w_long((long)n, p);
212 w_string(getstringvalue(v), n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000213 }
214 else if (is_tupleobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000215 w_byte(TYPE_TUPLE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000216 n = gettuplesize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000217 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000218 for (i = 0; i < n; i++) {
Guido van Rossum8d617a61995-03-09 12:12:11 +0000219 w_object(GETTUPLEITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000220 }
221 }
222 else if (is_listobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000223 w_byte(TYPE_LIST, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000224 n = getlistsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000225 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000226 for (i = 0; i < n; i++) {
Guido van Rossum3a205f71995-02-17 15:10:07 +0000227 w_object(getlistitem(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000228 }
229 }
Guido van Rossum64b45521991-06-07 13:58:22 +0000230 else if (is_dictobject(v)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000231 int pos;
232 object *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000233 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000234 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000235 pos = 0;
236 while (mappinggetnext(v, &pos, &key, &value)) {
237 w_object(key, p);
238 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000239 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000240 w_object((object *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000241 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000242 else if (is_codeobject(v)) {
243 codeobject *co = (codeobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000244 w_byte(TYPE_CODE, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000245 w_short(co->co_argcount, p);
246 w_short(co->co_nlocals, p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000247 w_short(co->co_stacksize, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000248 w_short(co->co_flags, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000249 w_object((object *)co->co_code, p);
250 w_object(co->co_consts, p);
251 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000252 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000253 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000254 w_object(co->co_name, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000255 }
256 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000257 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000258 p->error = 1;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000259 }
260}
261
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000262void
263wr_long(x, fp)
264 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000265 FILE *fp;
266{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000267 WFILE wf;
268 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000269 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000270 w_long(x, &wf);
271}
272
273void
274wr_object(x, fp)
275 object *x;
276 FILE *fp;
277{
278 WFILE wf;
279 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000280 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000281 w_object(x, &wf);
282}
283
284typedef WFILE RFILE; /* Same struct with different invariants */
285
Guido van Rossum8d617a61995-03-09 12:12:11 +0000286#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
287
288#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000289
290static int
291r_string(s, n, p)
292 char *s;
293 int n;
294 RFILE *p;
295{
296 if (p->fp != NULL)
297 return fread(s, 1, n, p->fp);
298 if (p->end - p->ptr < n)
299 n = p->end - p->ptr;
300 memcpy(s, p->ptr, n);
301 p->ptr += n;
302 return n;
303}
304
305static int
306r_short(p)
307 RFILE *p;
308{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000309 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000310 x = r_byte(p);
311 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000312 /* XXX If your short is > 16 bits, add sign-extension here!!! */
313 return x;
314}
315
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000316static long
317r_long(p)
318 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000319{
320 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000321 register FILE *fp = p->fp;
322 if (fp) {
323 x = getc(fp);
324 x |= (long)getc(fp) << 8;
325 x |= (long)getc(fp) << 16;
326 x |= (long)getc(fp) << 24;
327 }
328 else {
329 x = rs_byte(p);
330 x |= (long)rs_byte(p) << 8;
331 x |= (long)rs_byte(p) << 16;
332 x |= (long)rs_byte(p) << 24;
333 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000334#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000335 /* Sign extension for 64-bit machines */
336 x <<= (8*sizeof(long) - 32);
337 x >>= (8*sizeof(long) - 32);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000338#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000339 return x;
340}
341
342static long
343r_long64(p)
344 RFILE *p;
345{
346 register long x;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000347 x = r_long(p);
348#if SIZEOF_LONG > 4
349 x = (x & 0xFFFFFFFF) | (r_long(p) << 32);
350#else
351 if (r_long(p) != 0) {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000352 object *f = sysget("stderr");
353 err_clear();
Guido van Rossumc1547d91996-12-10 15:39:04 +0000354 if (f != NULL)
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000355 writestring(
Guido van Rossumc1547d91996-12-10 15:39:04 +0000356 "Warning: un-marshal 64-bit int in 32-bit mode\n",
357 f);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000358 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000359#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000360 return x;
361}
362
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000363static object *
364r_object(p)
365 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000366{
Jack Jansen9513f2c1995-10-27 13:21:28 +0000367 object *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000368 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000369 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000370
371 switch (type) {
372
373 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000374 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000375 return NULL;
376
377 case TYPE_NULL:
378 return NULL;
379
380 case TYPE_NONE:
381 INCREF(None);
382 return None;
383
Guido van Rossume449af71996-10-11 16:25:41 +0000384 case TYPE_ELLIPSIS:
385 INCREF(Py_Ellipsis);
386 return Py_Ellipsis;
Guido van Rossum8861b741996-07-30 16:49:37 +0000387
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000388 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000389 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000390
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000391 case TYPE_INT64:
392 return newintobject(r_long64(p));
393
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000394 case TYPE_LONG:
395 {
396 int size;
397 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000398 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000399 size = n<0 ? -n : n;
400 ob = alloclongobject(size);
401 if (ob == NULL)
402 return NULL;
403 ob->ob_size = n;
404 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000405 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000406 return (object *)ob;
407 }
408
409 case TYPE_FLOAT:
410 {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000411 extern double atof PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000412 char buf[256];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000413 n = r_byte(p);
414 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000415 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000416 "EOF read where object expected");
417 return NULL;
418 }
419 buf[n] = '\0';
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000420 return newfloatobject(atof(buf));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000421 }
422
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000423#ifndef WITHOUT_COMPLEX
424 case TYPE_COMPLEX:
425 {
426 extern double atof PROTO((const char *));
427 char buf[256];
Guido van Rossum530956d1996-07-21 02:27:43 +0000428 Py_complex c;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000429 n = r_byte(p);
430 if (r_string(buf, (int)n, p) != n) {
431 err_setstr(EOFError,
432 "EOF read where object expected");
433 return NULL;
434 }
435 buf[n] = '\0';
436 c.real = atof(buf);
437 n = r_byte(p);
438 if (r_string(buf, (int)n, p) != n) {
439 err_setstr(EOFError,
440 "EOF read where object expected");
441 return NULL;
442 }
443 buf[n] = '\0';
444 c.imag = atof(buf);
445 return newcomplexobject(c);
446 }
447#endif
448
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000449 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000450 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000451 v = newsizedstringobject((char *)NULL, n);
452 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000453 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000454 DECREF(v);
455 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000456 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000457 "EOF read where object expected");
458 }
459 }
460 return v;
461
462 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000463 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000464 v = newtupleobject((int)n);
465 if (v == NULL)
466 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000467 for (i = 0; i < n; i++) {
468 v2 = r_object(p);
469 if ( v2 == NULL ) {
470 DECREF(v);
471 v = NULL;
472 break;
473 }
474 SETTUPLEITEM(v, (int)i, v2);
475 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000476 return v;
477
478 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000479 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000480 v = newlistobject((int)n);
481 if (v == NULL)
482 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000483 for (i = 0; i < n; i++) {
484 v2 = r_object(p);
485 if ( v2 == NULL ) {
486 DECREF(v);
487 v = NULL;
488 break;
489 }
490 setlistitem(v, (int)i, v2);
491 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000492 return v;
493
Guido van Rossum64b45521991-06-07 13:58:22 +0000494 case TYPE_DICT:
495 v = newdictobject();
496 if (v == NULL)
497 return NULL;
498 for (;;) {
499 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000500 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000501 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000502 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000503 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000504 if (val != NULL)
505 dict2insert(v, key, val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000506 DECREF(key);
507 XDECREF(val);
508 }
509 return v;
510
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000511 case TYPE_CODE:
512 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000513 int argcount = r_short(p);
514 int nlocals = r_short(p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000515 int stacksize = r_short(p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000516 int flags = r_short(p);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000517 object *code = NULL;
518 object *consts = NULL;
519 object *names = NULL;
520 object *varnames = NULL;
521 object *filename = NULL;
522 object *name = NULL;
523
524 code = r_object(p);
525 if (code) consts = r_object(p);
526 if (consts) names = r_object(p);
527 if (names) varnames = r_object(p);
528 if (varnames) filename = r_object(p);
529 if (filename) name = r_object(p);
530
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000531 if (!err_occurred()) {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000532 v = (object *) newcodeobject(
Guido van Rossum98a9b311997-01-17 21:07:08 +0000533 argcount, nlocals, stacksize, flags,
Guido van Rossum681d79a1995-07-18 14:51:37 +0000534 code, consts, names, varnames,
535 filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000536 }
537 else
538 v = NULL;
539 XDECREF(code);
540 XDECREF(consts);
541 XDECREF(names);
Guido van Rossum0a8626e1996-05-28 22:28:12 +0000542 XDECREF(varnames);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000543 XDECREF(filename);
Guido van Rossuma4403101994-10-05 12:24:16 +0000544 XDECREF(name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000545
546 }
547 return v;
548
549 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000550 /* Bogus data got written, which isn't ideal.
551 This will let you keep working and recover. */
552 INCREF(None);
553 return None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000554
555 }
556}
557
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000558long
559rd_long(fp)
560 FILE *fp;
561{
562 RFILE rf;
563 rf.fp = fp;
564 return r_long(&rf);
565}
566
567object *
568rd_object(fp)
569 FILE *fp;
570{
571 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000572 if (err_occurred()) {
Guido van Rossum05870111995-08-28 02:56:20 +0000573 fatal("XXX rd_object called with exception set"); /* tmp */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000574 fprintf(stderr, "XXX rd_object called with exception set\n");
575 return NULL;
576 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000577 rf.fp = fp;
578 return r_object(&rf);
579}
580
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000581object *
582rds_object(str, len)
583 char *str;
584 int len;
585{
586 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000587 if (err_occurred()) {
588 fprintf(stderr, "XXX rds_object called with exception set\n");
589 return NULL;
590 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000591 rf.fp = NULL;
592 rf.str = NULL;
593 rf.ptr = str;
594 rf.end = str + len;
595 return r_object(&rf);
596}
597
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000598object *
599PyMarshal_WriteObjectToString(x) /* wrs_object() */
600 object *x;
601{
602 WFILE wf;
603 wf.fp = NULL;
604 wf.str = newsizedstringobject((char *)NULL, 50);
605 if (wf.str == NULL)
606 return NULL;
607 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
608 wf.end = wf.ptr + getstringsize(wf.str);
609 wf.error = 0;
610 w_object(x, &wf);
611 if (wf.str != NULL)
612 resizestring(&wf.str,
613 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
614 if (wf.error) {
615 XDECREF(wf.str);
616 err_setstr(ValueError, "unmarshallable object");
617 return NULL;
618 }
619 return wf.str;
620}
621
Guido van Rossum64b45521991-06-07 13:58:22 +0000622/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000623
624static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000625marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000626 object *self;
627 object *args;
628{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000629 WFILE wf;
630 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000631 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000632 if (!getargs(args, "(OO)", &x, &f))
633 return NULL;
634 if (!is_fileobject(f)) {
635 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000636 return NULL;
637 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000638 wf.fp = getfilefile(f);
639 wf.str = NULL;
640 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000641 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000642 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000643 if (wf.error) {
644 err_setstr(ValueError, "unmarshallable object");
645 return NULL;
646 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000647 INCREF(None);
648 return None;
649}
650
651static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000652marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000653 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000654 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000655{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000656 RFILE rf;
657 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000658 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000659 if (!getargs(args, "O", &f))
660 return NULL;
661 if (!is_fileobject(f)) {
662 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000663 return NULL;
664 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000665 rf.fp = getfilefile(f);
666 rf.str = NULL;
667 rf.ptr = rf.end = NULL;
668 err_clear();
669 v = r_object(&rf);
670 if (err_occurred()) {
671 XDECREF(v);
672 v = NULL;
673 }
674 return v;
675}
676
677static object *
678marshal_dumps(self, args)
679 object *self;
680 object *args;
681{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000682 object *x;
683 if (!getargs(args, "O", &x))
684 return NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000685 return PyMarshal_WriteObjectToString(x);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000686}
687
688static object *
689marshal_loads(self, args)
690 object *self;
691 object *args;
692{
693 RFILE rf;
694 object *v;
695 char *s;
696 int n;
697 if (!getargs(args, "s#", &s, &n))
698 return NULL;
699 rf.fp = NULL;
700 rf.str = args;
701 rf.ptr = s;
702 rf.end = s + n;
703 err_clear();
704 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000705 if (err_occurred()) {
706 XDECREF(v);
707 v = NULL;
708 }
709 return v;
710}
711
712static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000713 {"dump", marshal_dump},
714 {"load", marshal_load},
715 {"dumps", marshal_dumps},
716 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000717 {NULL, NULL} /* sentinel */
718};
719
720void
721initmarshal()
722{
723 (void) initmodule("marshal", marshal_methods);
724}