blob: 95f1825bc71fc4883f631dff6fee57febf7673f1 [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 Rossum0b0db8e1993-01-21 16:07:51 +0000130static void
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000131w_long64(x, p)
132 long x;
133 WFILE *p;
134{
135 w_long(x, p);
136 w_byte((int)((x>>32) & 0xff), p);
137 w_byte((int)((x>>40) & 0xff), p);
138 w_byte((int)((x>>48) & 0xff), p);
139 w_byte((int)((x>>56) & 0xff), p);
140}
141
142static void
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000143w_object(v, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000144 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000145 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000146{
Guido van Rossum3a205f71995-02-17 15:10:07 +0000147 int i, n;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000148
149 if (v == NULL)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000150 w_byte(TYPE_NULL, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000151 else if (v == None)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000152 w_byte(TYPE_NONE, p);
Guido van Rossume449af71996-10-11 16:25:41 +0000153 else if (v == Py_Ellipsis)
154 w_byte(TYPE_ELLIPSIS, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000155 else if (is_intobject(v)) {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000156 long x = GETINTVALUE((intobject *)v);
157 long y = x>>31;
158 if (y && y != -1) {
159 w_byte(TYPE_INT64, p);
160 w_long64(x, p);
161 }
162 else {
163 w_byte(TYPE_INT, p);
164 w_long(x, p);
165 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000166 }
167 else if (is_longobject(v)) {
168 longobject *ob = (longobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000169 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000170 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000171 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000172 if (n < 0)
173 n = -n;
174 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000175 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000176 }
177 else if (is_floatobject(v)) {
178 extern void float_buf_repr PROTO((char *, floatobject *));
179 char buf[256]; /* Plenty to format any double */
180 float_buf_repr(buf, (floatobject *)v);
181 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000182 w_byte(TYPE_FLOAT, p);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000183 w_byte(n, p);
184 w_string(buf, n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000185 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000186#ifndef WITHOUT_COMPLEX
187 else if (is_complexobject(v)) {
188 extern void float_buf_repr PROTO((char *, floatobject *));
189 char buf[256]; /* Plenty to format any double */
190 floatobject *temp;
191 w_byte(TYPE_COMPLEX, p);
192 temp = (floatobject*)newfloatobject(PyComplex_RealAsDouble(v));
193 float_buf_repr(buf, temp);
194 DECREF(temp);
195 n = strlen(buf);
196 w_byte(n, p);
197 w_string(buf, n, p);
198 temp = (floatobject*)newfloatobject(PyComplex_ImagAsDouble(v));
199 float_buf_repr(buf, temp);
200 DECREF(temp);
201 n = strlen(buf);
202 w_byte(n, p);
203 w_string(buf, n, p);
204 }
205#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000206 else if (is_stringobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000207 w_byte(TYPE_STRING, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000208 n = getstringsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000209 w_long((long)n, p);
210 w_string(getstringvalue(v), n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000211 }
212 else if (is_tupleobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000213 w_byte(TYPE_TUPLE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000214 n = gettuplesize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000215 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000216 for (i = 0; i < n; i++) {
Guido van Rossum8d617a61995-03-09 12:12:11 +0000217 w_object(GETTUPLEITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000218 }
219 }
220 else if (is_listobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000221 w_byte(TYPE_LIST, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000222 n = getlistsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000223 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000224 for (i = 0; i < n; i++) {
Guido van Rossum3a205f71995-02-17 15:10:07 +0000225 w_object(getlistitem(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000226 }
227 }
Guido van Rossum64b45521991-06-07 13:58:22 +0000228 else if (is_dictobject(v)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000229 int pos;
230 object *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000231 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000232 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000233 pos = 0;
234 while (mappinggetnext(v, &pos, &key, &value)) {
235 w_object(key, p);
236 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000237 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000238 w_object((object *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000239 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000240 else if (is_codeobject(v)) {
241 codeobject *co = (codeobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000242 w_byte(TYPE_CODE, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000243 w_short(co->co_argcount, p);
244 w_short(co->co_nlocals, p);
245 w_short(co->co_flags, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000246 w_object((object *)co->co_code, p);
247 w_object(co->co_consts, p);
248 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000249 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000250 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000251 w_object(co->co_name, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000252 }
253 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000254 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000255 p->error = 1;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000256 }
257}
258
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000259void
260wr_long(x, fp)
261 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000262 FILE *fp;
263{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000264 WFILE wf;
265 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000266 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000267 w_long(x, &wf);
268}
269
270void
271wr_object(x, fp)
272 object *x;
273 FILE *fp;
274{
275 WFILE wf;
276 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000277 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000278 w_object(x, &wf);
279}
280
281typedef WFILE RFILE; /* Same struct with different invariants */
282
Guido van Rossum8d617a61995-03-09 12:12:11 +0000283#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
284
285#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000286
287static int
288r_string(s, n, p)
289 char *s;
290 int n;
291 RFILE *p;
292{
293 if (p->fp != NULL)
294 return fread(s, 1, n, p->fp);
295 if (p->end - p->ptr < n)
296 n = p->end - p->ptr;
297 memcpy(s, p->ptr, n);
298 p->ptr += n;
299 return n;
300}
301
302static int
303r_short(p)
304 RFILE *p;
305{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000306 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000307 x = r_byte(p);
308 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000309 /* XXX If your short is > 16 bits, add sign-extension here!!! */
310 return x;
311}
312
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000313static long
314r_long(p)
315 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000316{
317 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000318 register FILE *fp = p->fp;
319 if (fp) {
320 x = getc(fp);
321 x |= (long)getc(fp) << 8;
322 x |= (long)getc(fp) << 16;
323 x |= (long)getc(fp) << 24;
324 }
325 else {
326 x = rs_byte(p);
327 x |= (long)rs_byte(p) << 8;
328 x |= (long)rs_byte(p) << 16;
329 x |= (long)rs_byte(p) << 24;
330 }
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000331 /* Sign extension for 64-bit machines */
332 x <<= (8*sizeof(long) - 32);
333 x >>= (8*sizeof(long) - 32);
334 return x;
335}
336
337static long
338r_long64(p)
339 RFILE *p;
340{
341 register long x;
342 register FILE *fp = p->fp;
343 if (sizeof(long) < 8) {
344 object *f = sysget("stderr");
345 err_clear();
346 if (f != NULL) {
347 writestring(
348 "Warning: un-marshal 64-bit int in 32-bit mode\n", f);
349 }
350 }
351 if (fp) {
352 x = getc(fp);
353 x |= (long)getc(fp) << 8;
354 x |= (long)getc(fp) << 16;
355 x |= (long)getc(fp) << 24;
356 x |= (long)getc(fp) << 32;
357 x |= (long)getc(fp) << 40;
358 x |= (long)getc(fp) << 48;
359 x |= (long)getc(fp) << 56;
360 }
361 else {
362 x = rs_byte(p);
363 x |= (long)rs_byte(p) << 8;
364 x |= (long)rs_byte(p) << 16;
365 x |= (long)rs_byte(p) << 24;
366 x |= (long)rs_byte(p) << 32;
367 x |= (long)rs_byte(p) << 40;
368 x |= (long)rs_byte(p) << 48;
369 x |= (long)rs_byte(p) << 56;
370 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000371 return x;
372}
373
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000374static object *
375r_object(p)
376 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000377{
Jack Jansen9513f2c1995-10-27 13:21:28 +0000378 object *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000379 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000380 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000381
382 switch (type) {
383
384 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000385 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000386 return NULL;
387
388 case TYPE_NULL:
389 return NULL;
390
391 case TYPE_NONE:
392 INCREF(None);
393 return None;
394
Guido van Rossume449af71996-10-11 16:25:41 +0000395 case TYPE_ELLIPSIS:
396 INCREF(Py_Ellipsis);
397 return Py_Ellipsis;
Guido van Rossum8861b741996-07-30 16:49:37 +0000398
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000399 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000400 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000401
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000402 case TYPE_INT64:
403 return newintobject(r_long64(p));
404
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000405 case TYPE_LONG:
406 {
407 int size;
408 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000409 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000410 size = n<0 ? -n : n;
411 ob = alloclongobject(size);
412 if (ob == NULL)
413 return NULL;
414 ob->ob_size = n;
415 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000416 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000417 return (object *)ob;
418 }
419
420 case TYPE_FLOAT:
421 {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000422 extern double atof PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000423 char buf[256];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000424 n = r_byte(p);
425 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000426 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000427 "EOF read where object expected");
428 return NULL;
429 }
430 buf[n] = '\0';
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000431 return newfloatobject(atof(buf));
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 {
437 extern double atof PROTO((const char *));
438 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) {
442 err_setstr(EOFError,
443 "EOF read where object expected");
444 return NULL;
445 }
446 buf[n] = '\0';
447 c.real = atof(buf);
448 n = r_byte(p);
449 if (r_string(buf, (int)n, p) != n) {
450 err_setstr(EOFError,
451 "EOF read where object expected");
452 return NULL;
453 }
454 buf[n] = '\0';
455 c.imag = atof(buf);
456 return newcomplexobject(c);
457 }
458#endif
459
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000460 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000461 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000462 v = newsizedstringobject((char *)NULL, n);
463 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000464 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000465 DECREF(v);
466 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000467 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000468 "EOF read where object expected");
469 }
470 }
471 return v;
472
473 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000474 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000475 v = newtupleobject((int)n);
476 if (v == NULL)
477 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000478 for (i = 0; i < n; i++) {
479 v2 = r_object(p);
480 if ( v2 == NULL ) {
481 DECREF(v);
482 v = NULL;
483 break;
484 }
485 SETTUPLEITEM(v, (int)i, v2);
486 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000487 return v;
488
489 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000490 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000491 v = newlistobject((int)n);
492 if (v == NULL)
493 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000494 for (i = 0; i < n; i++) {
495 v2 = r_object(p);
496 if ( v2 == NULL ) {
497 DECREF(v);
498 v = NULL;
499 break;
500 }
501 setlistitem(v, (int)i, v2);
502 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000503 return v;
504
Guido van Rossum64b45521991-06-07 13:58:22 +0000505 case TYPE_DICT:
506 v = newdictobject();
507 if (v == NULL)
508 return NULL;
509 for (;;) {
510 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000511 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000512 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000513 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000514 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000515 if (val != NULL)
516 dict2insert(v, key, val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000517 DECREF(key);
518 XDECREF(val);
519 }
520 return v;
521
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000522 case TYPE_CODE:
523 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000524 int argcount = r_short(p);
525 int nlocals = r_short(p);
526 int flags = r_short(p);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000527 object *code = NULL;
528 object *consts = NULL;
529 object *names = NULL;
530 object *varnames = NULL;
531 object *filename = NULL;
532 object *name = NULL;
533
534 code = r_object(p);
535 if (code) consts = r_object(p);
536 if (consts) names = r_object(p);
537 if (names) varnames = r_object(p);
538 if (varnames) filename = r_object(p);
539 if (filename) name = r_object(p);
540
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000541 if (!err_occurred()) {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000542 v = (object *) newcodeobject(
543 argcount, nlocals, flags,
544 code, consts, names, varnames,
545 filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000546 }
547 else
548 v = NULL;
549 XDECREF(code);
550 XDECREF(consts);
551 XDECREF(names);
Guido van Rossum0a8626e1996-05-28 22:28:12 +0000552 XDECREF(varnames);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000553 XDECREF(filename);
Guido van Rossuma4403101994-10-05 12:24:16 +0000554 XDECREF(name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000555
556 }
557 return v;
558
559 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000560 /* Bogus data got written, which isn't ideal.
561 This will let you keep working and recover. */
562 INCREF(None);
563 return None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000564
565 }
566}
567
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000568long
569rd_long(fp)
570 FILE *fp;
571{
572 RFILE rf;
573 rf.fp = fp;
574 return r_long(&rf);
575}
576
577object *
578rd_object(fp)
579 FILE *fp;
580{
581 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000582 if (err_occurred()) {
Guido van Rossum05870111995-08-28 02:56:20 +0000583 fatal("XXX rd_object called with exception set"); /* tmp */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000584 fprintf(stderr, "XXX rd_object called with exception set\n");
585 return NULL;
586 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000587 rf.fp = fp;
588 return r_object(&rf);
589}
590
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000591object *
592rds_object(str, len)
593 char *str;
594 int len;
595{
596 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000597 if (err_occurred()) {
598 fprintf(stderr, "XXX rds_object called with exception set\n");
599 return NULL;
600 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000601 rf.fp = NULL;
602 rf.str = NULL;
603 rf.ptr = str;
604 rf.end = str + len;
605 return r_object(&rf);
606}
607
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000608object *
609PyMarshal_WriteObjectToString(x) /* wrs_object() */
610 object *x;
611{
612 WFILE wf;
613 wf.fp = NULL;
614 wf.str = newsizedstringobject((char *)NULL, 50);
615 if (wf.str == NULL)
616 return NULL;
617 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
618 wf.end = wf.ptr + getstringsize(wf.str);
619 wf.error = 0;
620 w_object(x, &wf);
621 if (wf.str != NULL)
622 resizestring(&wf.str,
623 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
624 if (wf.error) {
625 XDECREF(wf.str);
626 err_setstr(ValueError, "unmarshallable object");
627 return NULL;
628 }
629 return wf.str;
630}
631
Guido van Rossum64b45521991-06-07 13:58:22 +0000632/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000633
634static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000635marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000636 object *self;
637 object *args;
638{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000639 WFILE wf;
640 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000641 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000642 if (!getargs(args, "(OO)", &x, &f))
643 return NULL;
644 if (!is_fileobject(f)) {
645 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000646 return NULL;
647 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000648 wf.fp = getfilefile(f);
649 wf.str = NULL;
650 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000651 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000652 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000653 if (wf.error) {
654 err_setstr(ValueError, "unmarshallable object");
655 return NULL;
656 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000657 INCREF(None);
658 return None;
659}
660
661static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000662marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000663 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000664 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000665{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000666 RFILE rf;
667 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000668 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000669 if (!getargs(args, "O", &f))
670 return NULL;
671 if (!is_fileobject(f)) {
672 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000673 return NULL;
674 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000675 rf.fp = getfilefile(f);
676 rf.str = NULL;
677 rf.ptr = rf.end = NULL;
678 err_clear();
679 v = r_object(&rf);
680 if (err_occurred()) {
681 XDECREF(v);
682 v = NULL;
683 }
684 return v;
685}
686
687static object *
688marshal_dumps(self, args)
689 object *self;
690 object *args;
691{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000692 object *x;
693 if (!getargs(args, "O", &x))
694 return NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000695 return PyMarshal_WriteObjectToString(x);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000696}
697
698static object *
699marshal_loads(self, args)
700 object *self;
701 object *args;
702{
703 RFILE rf;
704 object *v;
705 char *s;
706 int n;
707 if (!getargs(args, "s#", &s, &n))
708 return NULL;
709 rf.fp = NULL;
710 rf.str = args;
711 rf.ptr = s;
712 rf.end = s + n;
713 err_clear();
714 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000715 if (err_occurred()) {
716 XDECREF(v);
717 v = NULL;
718 }
719 return v;
720}
721
722static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000723 {"dump", marshal_dump},
724 {"load", marshal_load},
725 {"dumps", marshal_dumps},
726 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000727 {NULL, NULL} /* sentinel */
728};
729
730void
731initmarshal()
732{
733 (void) initmodule("marshal", marshal_methods);
734}