blob: 2fab46f070da4d56ce08585f8980d2db60aada70 [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
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Write Python objects to files and read them back.
26 This is intended for writing and reading compiled Python code only;
27 a true persistent storage facility would be much harder, since
28 it would have to take circular links and sharing into account. */
29
30#include "allobjects.h"
Guido van Rossum2807d191992-03-27 17:23:17 +000031#include "modsupport.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000032#include "longintrepr.h"
33#include "compile.h"
34#include "marshal.h"
35
36#include <errno.h>
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000037
38#define TYPE_NULL '0'
39#define TYPE_NONE 'N'
40#define TYPE_INT 'i'
41#define TYPE_FLOAT 'f'
Guido van Rossum8a5c5d21996-01-12 01:09:56 +000042#define TYPE_COMPLEX 'x'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000043#define TYPE_LONG 'l'
44#define TYPE_STRING 's'
45#define TYPE_TUPLE '('
46#define TYPE_LIST '['
47#define TYPE_DICT '{'
Guido van Rossum681d79a1995-07-18 14:51:37 +000048#define TYPE_CODE 'c'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000049#define TYPE_UNKNOWN '?'
50
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000051typedef struct {
52 FILE *fp;
Guido van Rossumf2150601996-06-26 20:41:23 +000053 int error;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000054 /* If fp == NULL, the following are valid: */
55 object *str;
56 char *ptr;
57 char *end;
58} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000059
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000060#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
61 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
62 else w_more(c, p)
63
64static void
65w_more(c, p)
66 char c;
67 WFILE *p;
68{
69 int size, newsize;
70 if (p->str == NULL)
71 return; /* An error already occurred */
72 size = getstringsize(p->str);
73 newsize = size + 1024;
74 if (resizestring(&p->str, newsize) != 0) {
75 p->ptr = p->end = NULL;
76 }
77 else {
78 p->ptr = GETSTRINGVALUE((stringobject *)p->str) + size;
79 p->end = GETSTRINGVALUE((stringobject *)p->str) + newsize;
80 *p->ptr++ = c;
81 }
82}
83
84static void
85w_string(s, n, p)
86 char *s;
87 int n;
88 WFILE *p;
89{
90 if (p->fp != NULL) {
91 fwrite(s, 1, n, p->fp);
92 }
93 else {
94 while (--n >= 0) {
95 w_byte(*s, p);
96 s++;
97 }
98 }
99}
100
101static void
102w_short(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000103 int x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000104 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000105{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000106 w_byte( x & 0xff, p);
107 w_byte((x>> 8) & 0xff, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000108}
109
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000110static void
111w_long(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000112 long 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((int)( x & 0xff), p);
116 w_byte((int)((x>> 8) & 0xff), p);
117 w_byte((int)((x>>16) & 0xff), p);
118 w_byte((int)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000119}
120
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000121static void
122w_object(v, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000123 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000124 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000125{
Guido van Rossum3a205f71995-02-17 15:10:07 +0000126 int i, n;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000127
128 if (v == NULL)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000129 w_byte(TYPE_NULL, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000130 else if (v == None)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000131 w_byte(TYPE_NONE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000132 else if (is_intobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000133 w_byte(TYPE_INT, p);
134 w_long(getintvalue(v), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000135 }
136 else if (is_longobject(v)) {
137 longobject *ob = (longobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000138 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000139 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000140 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000141 if (n < 0)
142 n = -n;
143 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000144 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000145 }
146 else if (is_floatobject(v)) {
147 extern void float_buf_repr PROTO((char *, floatobject *));
148 char buf[256]; /* Plenty to format any double */
149 float_buf_repr(buf, (floatobject *)v);
150 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000151 w_byte(TYPE_FLOAT, p);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000152 w_byte(n, p);
153 w_string(buf, n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000154 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000155#ifndef WITHOUT_COMPLEX
156 else if (is_complexobject(v)) {
157 extern void float_buf_repr PROTO((char *, floatobject *));
158 char buf[256]; /* Plenty to format any double */
159 floatobject *temp;
160 w_byte(TYPE_COMPLEX, p);
161 temp = (floatobject*)newfloatobject(PyComplex_RealAsDouble(v));
162 float_buf_repr(buf, temp);
163 DECREF(temp);
164 n = strlen(buf);
165 w_byte(n, p);
166 w_string(buf, n, p);
167 temp = (floatobject*)newfloatobject(PyComplex_ImagAsDouble(v));
168 float_buf_repr(buf, temp);
169 DECREF(temp);
170 n = strlen(buf);
171 w_byte(n, p);
172 w_string(buf, n, p);
173 }
174#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000175 else if (is_stringobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000176 w_byte(TYPE_STRING, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000177 n = getstringsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000178 w_long((long)n, p);
179 w_string(getstringvalue(v), n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000180 }
181 else if (is_tupleobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000182 w_byte(TYPE_TUPLE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000183 n = gettuplesize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000184 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000185 for (i = 0; i < n; i++) {
Guido van Rossum8d617a61995-03-09 12:12:11 +0000186 w_object(GETTUPLEITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000187 }
188 }
189 else if (is_listobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000190 w_byte(TYPE_LIST, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000191 n = getlistsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000192 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000193 for (i = 0; i < n; i++) {
Guido van Rossum3a205f71995-02-17 15:10:07 +0000194 w_object(getlistitem(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000195 }
196 }
Guido van Rossum64b45521991-06-07 13:58:22 +0000197 else if (is_dictobject(v)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000198 int pos;
199 object *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000200 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000201 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000202 pos = 0;
203 while (mappinggetnext(v, &pos, &key, &value)) {
204 w_object(key, p);
205 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000206 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000207 w_object((object *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000208 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000209 else if (is_codeobject(v)) {
210 codeobject *co = (codeobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000211 w_byte(TYPE_CODE, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000212 w_short(co->co_argcount, p);
213 w_short(co->co_nlocals, p);
214 w_short(co->co_flags, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000215 w_object((object *)co->co_code, p);
216 w_object(co->co_consts, p);
217 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000218 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000219 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000220 w_object(co->co_name, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000221 }
222 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000223 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000224 p->error = 1;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000225 }
226}
227
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000228void
229wr_long(x, fp)
230 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000231 FILE *fp;
232{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000233 WFILE wf;
234 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000235 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000236 w_long(x, &wf);
237}
238
239void
240wr_object(x, fp)
241 object *x;
242 FILE *fp;
243{
244 WFILE wf;
245 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000246 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000247 w_object(x, &wf);
248}
249
250typedef WFILE RFILE; /* Same struct with different invariants */
251
Guido van Rossum8d617a61995-03-09 12:12:11 +0000252#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
253
254#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000255
256static int
257r_string(s, n, p)
258 char *s;
259 int n;
260 RFILE *p;
261{
262 if (p->fp != NULL)
263 return fread(s, 1, n, p->fp);
264 if (p->end - p->ptr < n)
265 n = p->end - p->ptr;
266 memcpy(s, p->ptr, n);
267 p->ptr += n;
268 return n;
269}
270
271static int
272r_short(p)
273 RFILE *p;
274{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000275 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000276 x = r_byte(p);
277 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000278 /* XXX If your short is > 16 bits, add sign-extension here!!! */
279 return x;
280}
281
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000282static long
283r_long(p)
284 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000285{
286 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000287 register FILE *fp = p->fp;
288 if (fp) {
289 x = getc(fp);
290 x |= (long)getc(fp) << 8;
291 x |= (long)getc(fp) << 16;
292 x |= (long)getc(fp) << 24;
293 }
294 else {
295 x = rs_byte(p);
296 x |= (long)rs_byte(p) << 8;
297 x |= (long)rs_byte(p) << 16;
298 x |= (long)rs_byte(p) << 24;
299 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000300 /* XXX If your long is > 32 bits, add sign-extension here!!! */
301 return x;
302}
303
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000304static object *
305r_object(p)
306 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000307{
Jack Jansen9513f2c1995-10-27 13:21:28 +0000308 object *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000309 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000310 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000311
312 switch (type) {
313
314 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000315 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000316 return NULL;
317
318 case TYPE_NULL:
319 return NULL;
320
321 case TYPE_NONE:
322 INCREF(None);
323 return None;
324
325 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000326 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000327
328 case TYPE_LONG:
329 {
330 int size;
331 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000332 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000333 size = n<0 ? -n : n;
334 ob = alloclongobject(size);
335 if (ob == NULL)
336 return NULL;
337 ob->ob_size = n;
338 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000339 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000340 return (object *)ob;
341 }
342
343 case TYPE_FLOAT:
344 {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000345 extern double atof PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000346 char buf[256];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000347 n = r_byte(p);
348 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000349 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000350 "EOF read where object expected");
351 return NULL;
352 }
353 buf[n] = '\0';
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000354 return newfloatobject(atof(buf));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000355 }
356
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000357#ifndef WITHOUT_COMPLEX
358 case TYPE_COMPLEX:
359 {
360 extern double atof PROTO((const char *));
361 char buf[256];
362 complex c;
363 n = r_byte(p);
364 if (r_string(buf, (int)n, p) != n) {
365 err_setstr(EOFError,
366 "EOF read where object expected");
367 return NULL;
368 }
369 buf[n] = '\0';
370 c.real = atof(buf);
371 n = r_byte(p);
372 if (r_string(buf, (int)n, p) != n) {
373 err_setstr(EOFError,
374 "EOF read where object expected");
375 return NULL;
376 }
377 buf[n] = '\0';
378 c.imag = atof(buf);
379 return newcomplexobject(c);
380 }
381#endif
382
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000383 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000384 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000385 v = newsizedstringobject((char *)NULL, n);
386 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000387 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000388 DECREF(v);
389 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000390 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000391 "EOF read where object expected");
392 }
393 }
394 return v;
395
396 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000397 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000398 v = newtupleobject((int)n);
399 if (v == NULL)
400 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000401 for (i = 0; i < n; i++) {
402 v2 = r_object(p);
403 if ( v2 == NULL ) {
404 DECREF(v);
405 v = NULL;
406 break;
407 }
408 SETTUPLEITEM(v, (int)i, v2);
409 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000410 return v;
411
412 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000413 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000414 v = newlistobject((int)n);
415 if (v == NULL)
416 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000417 for (i = 0; i < n; i++) {
418 v2 = r_object(p);
419 if ( v2 == NULL ) {
420 DECREF(v);
421 v = NULL;
422 break;
423 }
424 setlistitem(v, (int)i, v2);
425 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000426 return v;
427
Guido van Rossum64b45521991-06-07 13:58:22 +0000428 case TYPE_DICT:
429 v = newdictobject();
430 if (v == NULL)
431 return NULL;
432 for (;;) {
433 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000434 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000435 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000436 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000437 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000438 if (val != NULL)
439 dict2insert(v, key, val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000440 DECREF(key);
441 XDECREF(val);
442 }
443 return v;
444
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000445 case TYPE_CODE:
446 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000447 int argcount = r_short(p);
448 int nlocals = r_short(p);
449 int flags = r_short(p);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000450 object *code = NULL;
451 object *consts = NULL;
452 object *names = NULL;
453 object *varnames = NULL;
454 object *filename = NULL;
455 object *name = NULL;
456
457 code = r_object(p);
458 if (code) consts = r_object(p);
459 if (consts) names = r_object(p);
460 if (names) varnames = r_object(p);
461 if (varnames) filename = r_object(p);
462 if (filename) name = r_object(p);
463
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000464 if (!err_occurred()) {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000465 v = (object *) newcodeobject(
466 argcount, nlocals, flags,
467 code, consts, names, varnames,
468 filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000469 }
470 else
471 v = NULL;
472 XDECREF(code);
473 XDECREF(consts);
474 XDECREF(names);
Guido van Rossum0a8626e1996-05-28 22:28:12 +0000475 XDECREF(varnames);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000476 XDECREF(filename);
Guido van Rossuma4403101994-10-05 12:24:16 +0000477 XDECREF(name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000478
479 }
480 return v;
481
482 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000483 /* Bogus data got written, which isn't ideal.
484 This will let you keep working and recover. */
485 INCREF(None);
486 return None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000487
488 }
489}
490
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000491long
492rd_long(fp)
493 FILE *fp;
494{
495 RFILE rf;
496 rf.fp = fp;
497 return r_long(&rf);
498}
499
500object *
501rd_object(fp)
502 FILE *fp;
503{
504 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000505 if (err_occurred()) {
Guido van Rossum05870111995-08-28 02:56:20 +0000506 fatal("XXX rd_object called with exception set"); /* tmp */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000507 fprintf(stderr, "XXX rd_object called with exception set\n");
508 return NULL;
509 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000510 rf.fp = fp;
511 return r_object(&rf);
512}
513
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000514object *
515rds_object(str, len)
516 char *str;
517 int len;
518{
519 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000520 if (err_occurred()) {
521 fprintf(stderr, "XXX rds_object called with exception set\n");
522 return NULL;
523 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000524 rf.fp = NULL;
525 rf.str = NULL;
526 rf.ptr = str;
527 rf.end = str + len;
528 return r_object(&rf);
529}
530
Guido van Rossum64b45521991-06-07 13:58:22 +0000531/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000532
533static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000534marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000535 object *self;
536 object *args;
537{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000538 WFILE wf;
539 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000540 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000541 if (!getargs(args, "(OO)", &x, &f))
542 return NULL;
543 if (!is_fileobject(f)) {
544 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000545 return NULL;
546 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000547 wf.fp = getfilefile(f);
548 wf.str = NULL;
549 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000550 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000551 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000552 if (wf.error) {
553 err_setstr(ValueError, "unmarshallable object");
554 return NULL;
555 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000556 INCREF(None);
557 return None;
558}
559
560static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000561marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000562 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000563 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000564{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000565 RFILE rf;
566 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000567 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000568 if (!getargs(args, "O", &f))
569 return NULL;
570 if (!is_fileobject(f)) {
571 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000572 return NULL;
573 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000574 rf.fp = getfilefile(f);
575 rf.str = NULL;
576 rf.ptr = rf.end = NULL;
577 err_clear();
578 v = r_object(&rf);
579 if (err_occurred()) {
580 XDECREF(v);
581 v = NULL;
582 }
583 return v;
584}
585
586static object *
587marshal_dumps(self, args)
588 object *self;
589 object *args;
590{
591 WFILE wf;
592 object *x;
593 if (!getargs(args, "O", &x))
594 return NULL;
595 wf.fp = NULL;
596 wf.str = newsizedstringobject((char *)NULL, 50);
597 if (wf.str == NULL)
598 return NULL;
599 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
600 wf.end = wf.ptr + getstringsize(wf.str);
Guido van Rossumf2150601996-06-26 20:41:23 +0000601 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000602 w_object(x, &wf);
603 if (wf.str != NULL)
604 resizestring(&wf.str,
605 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
Guido van Rossumf2150601996-06-26 20:41:23 +0000606 if (wf.error) {
607 XDECREF(wf.str);
608 err_setstr(ValueError, "unmarshallable object");
609 return NULL;
610 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000611 return wf.str;
612}
613
614static object *
615marshal_loads(self, args)
616 object *self;
617 object *args;
618{
619 RFILE rf;
620 object *v;
621 char *s;
622 int n;
623 if (!getargs(args, "s#", &s, &n))
624 return NULL;
625 rf.fp = NULL;
626 rf.str = args;
627 rf.ptr = s;
628 rf.end = s + n;
629 err_clear();
630 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000631 if (err_occurred()) {
632 XDECREF(v);
633 v = NULL;
634 }
635 return v;
636}
637
638static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000639 {"dump", marshal_dump},
640 {"load", marshal_load},
641 {"dumps", marshal_dumps},
642 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000643 {NULL, NULL} /* sentinel */
644};
645
646void
647initmarshal()
648{
649 (void) initmodule("marshal", marshal_methods);
650}