blob: f3d7b5cb4d4f6f77413812f2970e68e6a58b873c [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;
53 /* If fp == NULL, the following are valid: */
54 object *str;
55 char *ptr;
56 char *end;
57} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000058
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000059#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
60 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
61 else w_more(c, p)
62
63static void
64w_more(c, p)
65 char c;
66 WFILE *p;
67{
68 int size, newsize;
69 if (p->str == NULL)
70 return; /* An error already occurred */
71 size = getstringsize(p->str);
72 newsize = size + 1024;
73 if (resizestring(&p->str, newsize) != 0) {
74 p->ptr = p->end = NULL;
75 }
76 else {
77 p->ptr = GETSTRINGVALUE((stringobject *)p->str) + size;
78 p->end = GETSTRINGVALUE((stringobject *)p->str) + newsize;
79 *p->ptr++ = c;
80 }
81}
82
83static void
84w_string(s, n, p)
85 char *s;
86 int n;
87 WFILE *p;
88{
89 if (p->fp != NULL) {
90 fwrite(s, 1, n, p->fp);
91 }
92 else {
93 while (--n >= 0) {
94 w_byte(*s, p);
95 s++;
96 }
97 }
98}
99
100static void
101w_short(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000102 int x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000103 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000104{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000105 w_byte( x & 0xff, p);
106 w_byte((x>> 8) & 0xff, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000107}
108
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000109static void
110w_long(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000111 long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000112 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000113{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000114 w_byte((int)( x & 0xff), p);
115 w_byte((int)((x>> 8) & 0xff), p);
116 w_byte((int)((x>>16) & 0xff), p);
117 w_byte((int)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000118}
119
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000120static void
121w_object(v, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000122 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000123 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000124{
Guido van Rossum3a205f71995-02-17 15:10:07 +0000125 int i, n;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000126
127 if (v == NULL)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000128 w_byte(TYPE_NULL, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000129 else if (v == None)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000130 w_byte(TYPE_NONE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000131 else if (is_intobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000132 w_byte(TYPE_INT, p);
133 w_long(getintvalue(v), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000134 }
135 else if (is_longobject(v)) {
136 longobject *ob = (longobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000137 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000138 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000139 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000140 if (n < 0)
141 n = -n;
142 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000143 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000144 }
145 else if (is_floatobject(v)) {
146 extern void float_buf_repr PROTO((char *, floatobject *));
147 char buf[256]; /* Plenty to format any double */
148 float_buf_repr(buf, (floatobject *)v);
149 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000150 w_byte(TYPE_FLOAT, p);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000151 w_byte(n, p);
152 w_string(buf, n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000153 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000154#ifndef WITHOUT_COMPLEX
155 else if (is_complexobject(v)) {
156 extern void float_buf_repr PROTO((char *, floatobject *));
157 char buf[256]; /* Plenty to format any double */
158 floatobject *temp;
159 w_byte(TYPE_COMPLEX, p);
160 temp = (floatobject*)newfloatobject(PyComplex_RealAsDouble(v));
161 float_buf_repr(buf, temp);
162 DECREF(temp);
163 n = strlen(buf);
164 w_byte(n, p);
165 w_string(buf, n, p);
166 temp = (floatobject*)newfloatobject(PyComplex_ImagAsDouble(v));
167 float_buf_repr(buf, temp);
168 DECREF(temp);
169 n = strlen(buf);
170 w_byte(n, p);
171 w_string(buf, n, p);
172 }
173#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000174 else if (is_stringobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000175 w_byte(TYPE_STRING, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000176 n = getstringsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000177 w_long((long)n, p);
178 w_string(getstringvalue(v), n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000179 }
180 else if (is_tupleobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000181 w_byte(TYPE_TUPLE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000182 n = gettuplesize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000183 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000184 for (i = 0; i < n; i++) {
Guido van Rossum8d617a61995-03-09 12:12:11 +0000185 w_object(GETTUPLEITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000186 }
187 }
188 else if (is_listobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000189 w_byte(TYPE_LIST, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000190 n = getlistsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000191 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000192 for (i = 0; i < n; i++) {
Guido van Rossum3a205f71995-02-17 15:10:07 +0000193 w_object(getlistitem(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000194 }
195 }
Guido van Rossum64b45521991-06-07 13:58:22 +0000196 else if (is_dictobject(v)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000197 int pos;
198 object *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000199 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000200 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000201 pos = 0;
202 while (mappinggetnext(v, &pos, &key, &value)) {
203 w_object(key, p);
204 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000205 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000206 w_object((object *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000207 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000208 else if (is_codeobject(v)) {
209 codeobject *co = (codeobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000210 w_byte(TYPE_CODE, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000211 w_short(co->co_argcount, p);
212 w_short(co->co_nlocals, p);
213 w_short(co->co_flags, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000214 w_object((object *)co->co_code, p);
215 w_object(co->co_consts, p);
216 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000217 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000218 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000219 w_object(co->co_name, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000220 }
221 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000222 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000223 }
224}
225
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000226void
227wr_long(x, fp)
228 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000229 FILE *fp;
230{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000231 WFILE wf;
232 wf.fp = fp;
233 w_long(x, &wf);
234}
235
236void
237wr_object(x, fp)
238 object *x;
239 FILE *fp;
240{
241 WFILE wf;
242 wf.fp = fp;
243 w_object(x, &wf);
244}
245
246typedef WFILE RFILE; /* Same struct with different invariants */
247
Guido van Rossum8d617a61995-03-09 12:12:11 +0000248#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
249
250#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000251
252static int
253r_string(s, n, p)
254 char *s;
255 int n;
256 RFILE *p;
257{
258 if (p->fp != NULL)
259 return fread(s, 1, n, p->fp);
260 if (p->end - p->ptr < n)
261 n = p->end - p->ptr;
262 memcpy(s, p->ptr, n);
263 p->ptr += n;
264 return n;
265}
266
267static int
268r_short(p)
269 RFILE *p;
270{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000271 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000272 x = r_byte(p);
273 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000274 /* XXX If your short is > 16 bits, add sign-extension here!!! */
275 return x;
276}
277
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000278static long
279r_long(p)
280 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000281{
282 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000283 register FILE *fp = p->fp;
284 if (fp) {
285 x = getc(fp);
286 x |= (long)getc(fp) << 8;
287 x |= (long)getc(fp) << 16;
288 x |= (long)getc(fp) << 24;
289 }
290 else {
291 x = rs_byte(p);
292 x |= (long)rs_byte(p) << 8;
293 x |= (long)rs_byte(p) << 16;
294 x |= (long)rs_byte(p) << 24;
295 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000296 /* XXX If your long is > 32 bits, add sign-extension here!!! */
297 return x;
298}
299
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000300static object *
301r_object(p)
302 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000303{
Jack Jansen9513f2c1995-10-27 13:21:28 +0000304 object *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000305 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000306 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000307
308 switch (type) {
309
310 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000311 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000312 return NULL;
313
314 case TYPE_NULL:
315 return NULL;
316
317 case TYPE_NONE:
318 INCREF(None);
319 return None;
320
321 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000322 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000323
324 case TYPE_LONG:
325 {
326 int size;
327 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000328 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000329 size = n<0 ? -n : n;
330 ob = alloclongobject(size);
331 if (ob == NULL)
332 return NULL;
333 ob->ob_size = n;
334 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000335 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000336 return (object *)ob;
337 }
338
339 case TYPE_FLOAT:
340 {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000341 extern double atof PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000342 char buf[256];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000343 n = r_byte(p);
344 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000345 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000346 "EOF read where object expected");
347 return NULL;
348 }
349 buf[n] = '\0';
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000350 return newfloatobject(atof(buf));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000351 }
352
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000353#ifndef WITHOUT_COMPLEX
354 case TYPE_COMPLEX:
355 {
356 extern double atof PROTO((const char *));
357 char buf[256];
358 complex c;
359 n = r_byte(p);
360 if (r_string(buf, (int)n, p) != n) {
361 err_setstr(EOFError,
362 "EOF read where object expected");
363 return NULL;
364 }
365 buf[n] = '\0';
366 c.real = atof(buf);
367 n = r_byte(p);
368 if (r_string(buf, (int)n, p) != n) {
369 err_setstr(EOFError,
370 "EOF read where object expected");
371 return NULL;
372 }
373 buf[n] = '\0';
374 c.imag = atof(buf);
375 return newcomplexobject(c);
376 }
377#endif
378
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000379 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000380 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000381 v = newsizedstringobject((char *)NULL, n);
382 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000383 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000384 DECREF(v);
385 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000386 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000387 "EOF read where object expected");
388 }
389 }
390 return v;
391
392 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000393 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000394 v = newtupleobject((int)n);
395 if (v == NULL)
396 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000397 for (i = 0; i < n; i++) {
398 v2 = r_object(p);
399 if ( v2 == NULL ) {
400 DECREF(v);
401 v = NULL;
402 break;
403 }
404 SETTUPLEITEM(v, (int)i, v2);
405 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000406 return v;
407
408 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000409 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000410 v = newlistobject((int)n);
411 if (v == NULL)
412 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000413 for (i = 0; i < n; i++) {
414 v2 = r_object(p);
415 if ( v2 == NULL ) {
416 DECREF(v);
417 v = NULL;
418 break;
419 }
420 setlistitem(v, (int)i, v2);
421 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000422 return v;
423
Guido van Rossum64b45521991-06-07 13:58:22 +0000424 case TYPE_DICT:
425 v = newdictobject();
426 if (v == NULL)
427 return NULL;
428 for (;;) {
429 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000430 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000431 if (key == NULL)
Jack Jansen9513f2c1995-10-27 13:21:28 +0000432 break; /* XXXX and how about memory errors? */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000433 val = r_object(p);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000434 /* XXXX error check? */
Guido van Rossum64b45521991-06-07 13:58:22 +0000435 dict2insert(v, key, val);
436 DECREF(key);
437 XDECREF(val);
438 }
439 return v;
440
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000441 case TYPE_CODE:
442 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000443 int argcount = r_short(p);
444 int nlocals = r_short(p);
445 int flags = r_short(p);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000446 object *code = NULL;
447 object *consts = NULL;
448 object *names = NULL;
449 object *varnames = NULL;
450 object *filename = NULL;
451 object *name = NULL;
452
453 code = r_object(p);
454 if (code) consts = r_object(p);
455 if (consts) names = r_object(p);
456 if (names) varnames = r_object(p);
457 if (varnames) filename = r_object(p);
458 if (filename) name = r_object(p);
459
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000460 if (!err_occurred()) {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000461 v = (object *) newcodeobject(
462 argcount, nlocals, flags,
463 code, consts, names, varnames,
464 filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000465 }
466 else
467 v = NULL;
468 XDECREF(code);
469 XDECREF(consts);
470 XDECREF(names);
471 XDECREF(filename);
Guido van Rossuma4403101994-10-05 12:24:16 +0000472 XDECREF(name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000473
474 }
475 return v;
476
477 default:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000478 err_setstr(TypeError, "read unknown object");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000479 return NULL;
480
481 }
482}
483
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000484long
485rd_long(fp)
486 FILE *fp;
487{
488 RFILE rf;
489 rf.fp = fp;
490 return r_long(&rf);
491}
492
493object *
494rd_object(fp)
495 FILE *fp;
496{
497 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000498 if (err_occurred()) {
Guido van Rossum05870111995-08-28 02:56:20 +0000499 fatal("XXX rd_object called with exception set"); /* tmp */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000500 fprintf(stderr, "XXX rd_object called with exception set\n");
501 return NULL;
502 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000503 rf.fp = fp;
504 return r_object(&rf);
505}
506
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000507object *
508rds_object(str, len)
509 char *str;
510 int len;
511{
512 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000513 if (err_occurred()) {
514 fprintf(stderr, "XXX rds_object called with exception set\n");
515 return NULL;
516 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000517 rf.fp = NULL;
518 rf.str = NULL;
519 rf.ptr = str;
520 rf.end = str + len;
521 return r_object(&rf);
522}
523
Guido van Rossum64b45521991-06-07 13:58:22 +0000524/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000525
526static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000527marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000528 object *self;
529 object *args;
530{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000531 WFILE wf;
532 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000533 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000534 if (!getargs(args, "(OO)", &x, &f))
535 return NULL;
536 if (!is_fileobject(f)) {
537 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000538 return NULL;
539 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000540 wf.fp = getfilefile(f);
541 wf.str = NULL;
542 wf.ptr = wf.end = NULL;
543 w_object(x, &wf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000544 INCREF(None);
545 return None;
546}
547
548static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000549marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000550 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000551 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000552{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000553 RFILE rf;
554 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000555 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000556 if (!getargs(args, "O", &f))
557 return NULL;
558 if (!is_fileobject(f)) {
559 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000560 return NULL;
561 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000562 rf.fp = getfilefile(f);
563 rf.str = NULL;
564 rf.ptr = rf.end = NULL;
565 err_clear();
566 v = r_object(&rf);
567 if (err_occurred()) {
568 XDECREF(v);
569 v = NULL;
570 }
571 return v;
572}
573
574static object *
575marshal_dumps(self, args)
576 object *self;
577 object *args;
578{
579 WFILE wf;
580 object *x;
581 if (!getargs(args, "O", &x))
582 return NULL;
583 wf.fp = NULL;
584 wf.str = newsizedstringobject((char *)NULL, 50);
585 if (wf.str == NULL)
586 return NULL;
587 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
588 wf.end = wf.ptr + getstringsize(wf.str);
589 w_object(x, &wf);
590 if (wf.str != NULL)
591 resizestring(&wf.str,
592 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
593 return wf.str;
594}
595
596static object *
597marshal_loads(self, args)
598 object *self;
599 object *args;
600{
601 RFILE rf;
602 object *v;
603 char *s;
604 int n;
605 if (!getargs(args, "s#", &s, &n))
606 return NULL;
607 rf.fp = NULL;
608 rf.str = args;
609 rf.ptr = s;
610 rf.end = s + n;
611 err_clear();
612 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000613 if (err_occurred()) {
614 XDECREF(v);
615 v = NULL;
616 }
617 return v;
618}
619
620static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000621 {"dump", marshal_dump},
622 {"load", marshal_load},
623 {"dumps", marshal_dumps},
624 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000625 {NULL, NULL} /* sentinel */
626};
627
628void
629initmarshal()
630{
631 (void) initmodule("marshal", marshal_methods);
632}