blob: c094b981e17364cb07f491daa89fabc550cb2e2b [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'
42#define TYPE_LONG 'l'
43#define TYPE_STRING 's'
44#define TYPE_TUPLE '('
45#define TYPE_LIST '['
46#define TYPE_DICT '{'
Guido van Rossum681d79a1995-07-18 14:51:37 +000047#define TYPE_CODE 'c'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000048#define TYPE_UNKNOWN '?'
49
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000050typedef struct {
51 FILE *fp;
52 /* If fp == NULL, the following are valid: */
53 object *str;
54 char *ptr;
55 char *end;
56} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000057
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000058#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
59 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
60 else w_more(c, p)
61
62static void
63w_more(c, p)
64 char c;
65 WFILE *p;
66{
67 int size, newsize;
68 if (p->str == NULL)
69 return; /* An error already occurred */
70 size = getstringsize(p->str);
71 newsize = size + 1024;
72 if (resizestring(&p->str, newsize) != 0) {
73 p->ptr = p->end = NULL;
74 }
75 else {
76 p->ptr = GETSTRINGVALUE((stringobject *)p->str) + size;
77 p->end = GETSTRINGVALUE((stringobject *)p->str) + newsize;
78 *p->ptr++ = c;
79 }
80}
81
82static void
83w_string(s, n, p)
84 char *s;
85 int n;
86 WFILE *p;
87{
88 if (p->fp != NULL) {
89 fwrite(s, 1, n, p->fp);
90 }
91 else {
92 while (--n >= 0) {
93 w_byte(*s, p);
94 s++;
95 }
96 }
97}
98
99static void
100w_short(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000101 int x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000102 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000103{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000104 w_byte( x & 0xff, p);
105 w_byte((x>> 8) & 0xff, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000106}
107
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000108static void
109w_long(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000110 long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000111 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000112{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000113 w_byte((int)( x & 0xff), p);
114 w_byte((int)((x>> 8) & 0xff), p);
115 w_byte((int)((x>>16) & 0xff), p);
116 w_byte((int)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000117}
118
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000119static void
120w_object(v, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000121 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000122 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000123{
Guido van Rossum3a205f71995-02-17 15:10:07 +0000124 int i, n;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000125
126 if (v == NULL)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000127 w_byte(TYPE_NULL, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000128 else if (v == None)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000129 w_byte(TYPE_NONE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000130 else if (is_intobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000131 w_byte(TYPE_INT, p);
132 w_long(getintvalue(v), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000133 }
134 else if (is_longobject(v)) {
135 longobject *ob = (longobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000136 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000137 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000138 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000139 if (n < 0)
140 n = -n;
141 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000142 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000143 }
144 else if (is_floatobject(v)) {
145 extern void float_buf_repr PROTO((char *, floatobject *));
146 char buf[256]; /* Plenty to format any double */
147 float_buf_repr(buf, (floatobject *)v);
148 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000149 w_byte(TYPE_FLOAT, p);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000150 w_byte(n, p);
151 w_string(buf, n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000152 }
153 else if (is_stringobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000154 w_byte(TYPE_STRING, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000155 n = getstringsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000156 w_long((long)n, p);
157 w_string(getstringvalue(v), n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000158 }
159 else if (is_tupleobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000160 w_byte(TYPE_TUPLE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000161 n = gettuplesize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000162 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000163 for (i = 0; i < n; i++) {
Guido van Rossum8d617a61995-03-09 12:12:11 +0000164 w_object(GETTUPLEITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000165 }
166 }
167 else if (is_listobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000168 w_byte(TYPE_LIST, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000169 n = getlistsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000170 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000171 for (i = 0; i < n; i++) {
Guido van Rossum3a205f71995-02-17 15:10:07 +0000172 w_object(getlistitem(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000173 }
174 }
Guido van Rossum64b45521991-06-07 13:58:22 +0000175 else if (is_dictobject(v)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000176 int pos;
177 object *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000178 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000179 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000180 pos = 0;
181 while (mappinggetnext(v, &pos, &key, &value)) {
182 w_object(key, p);
183 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000184 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000185 w_object((object *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000186 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000187 else if (is_codeobject(v)) {
188 codeobject *co = (codeobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000189 w_byte(TYPE_CODE, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000190 w_short(co->co_argcount, p);
191 w_short(co->co_nlocals, p);
192 w_short(co->co_flags, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000193 w_object((object *)co->co_code, p);
194 w_object(co->co_consts, p);
195 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000196 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000197 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000198 w_object(co->co_name, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000199 }
200 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000201 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000202 }
203}
204
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000205void
206wr_long(x, fp)
207 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000208 FILE *fp;
209{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000210 WFILE wf;
211 wf.fp = fp;
212 w_long(x, &wf);
213}
214
215void
216wr_object(x, fp)
217 object *x;
218 FILE *fp;
219{
220 WFILE wf;
221 wf.fp = fp;
222 w_object(x, &wf);
223}
224
225typedef WFILE RFILE; /* Same struct with different invariants */
226
Guido van Rossum8d617a61995-03-09 12:12:11 +0000227#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
228
229#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000230
231static int
232r_string(s, n, p)
233 char *s;
234 int n;
235 RFILE *p;
236{
237 if (p->fp != NULL)
238 return fread(s, 1, n, p->fp);
239 if (p->end - p->ptr < n)
240 n = p->end - p->ptr;
241 memcpy(s, p->ptr, n);
242 p->ptr += n;
243 return n;
244}
245
246static int
247r_short(p)
248 RFILE *p;
249{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000250 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000251 x = r_byte(p);
252 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000253 /* XXX If your short is > 16 bits, add sign-extension here!!! */
254 return x;
255}
256
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000257static long
258r_long(p)
259 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000260{
261 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000262 register FILE *fp = p->fp;
263 if (fp) {
264 x = getc(fp);
265 x |= (long)getc(fp) << 8;
266 x |= (long)getc(fp) << 16;
267 x |= (long)getc(fp) << 24;
268 }
269 else {
270 x = rs_byte(p);
271 x |= (long)rs_byte(p) << 8;
272 x |= (long)rs_byte(p) << 16;
273 x |= (long)rs_byte(p) << 24;
274 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000275 /* XXX If your long is > 32 bits, add sign-extension here!!! */
276 return x;
277}
278
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000279static object *
280r_object(p)
281 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000282{
283 object *v;
284 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000285 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000286
287 switch (type) {
288
289 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000290 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000291 return NULL;
292
293 case TYPE_NULL:
294 return NULL;
295
296 case TYPE_NONE:
297 INCREF(None);
298 return None;
299
300 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000301 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000302
303 case TYPE_LONG:
304 {
305 int size;
306 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000307 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000308 size = n<0 ? -n : n;
309 ob = alloclongobject(size);
310 if (ob == NULL)
311 return NULL;
312 ob->ob_size = n;
313 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000314 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000315 return (object *)ob;
316 }
317
318 case TYPE_FLOAT:
319 {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000320 extern double atof PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000321 char buf[256];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000322 n = r_byte(p);
323 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000324 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000325 "EOF read where object expected");
326 return NULL;
327 }
328 buf[n] = '\0';
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000329 return newfloatobject(atof(buf));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000330 }
331
332 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000333 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000334 v = newsizedstringobject((char *)NULL, n);
335 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000336 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000337 DECREF(v);
338 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000339 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000340 "EOF read where object expected");
341 }
342 }
343 return v;
344
345 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000346 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000347 v = newtupleobject((int)n);
348 if (v == NULL)
349 return v;
350 for (i = 0; i < n; i++)
Guido van Rossum8d617a61995-03-09 12:12:11 +0000351 SETTUPLEITEM(v, (int)i, r_object(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000352 return v;
353
354 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000355 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000356 v = newlistobject((int)n);
357 if (v == NULL)
358 return v;
359 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000360 setlistitem(v, (int)i, r_object(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000361 return v;
362
Guido van Rossum64b45521991-06-07 13:58:22 +0000363 case TYPE_DICT:
364 v = newdictobject();
365 if (v == NULL)
366 return NULL;
367 for (;;) {
368 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000369 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000370 if (key == NULL)
371 break;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000372 val = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000373 dict2insert(v, key, val);
374 DECREF(key);
375 XDECREF(val);
376 }
377 return v;
378
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000379 case TYPE_CODE:
380 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000381 int argcount = r_short(p);
382 int nlocals = r_short(p);
383 int flags = r_short(p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000384 object *code = r_object(p);
385 object *consts = r_object(p);
386 object *names = r_object(p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000387 object *varnames = r_object(p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000388 object *filename = r_object(p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000389 object *name = r_object(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000390 if (!err_occurred()) {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000391 v = (object *) newcodeobject(
392 argcount, nlocals, flags,
393 code, consts, names, varnames,
394 filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000395 }
396 else
397 v = NULL;
398 XDECREF(code);
399 XDECREF(consts);
400 XDECREF(names);
401 XDECREF(filename);
Guido van Rossuma4403101994-10-05 12:24:16 +0000402 XDECREF(name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000403
404 }
405 return v;
406
407 default:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000408 err_setstr(TypeError, "read unknown object");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000409 return NULL;
410
411 }
412}
413
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000414long
415rd_long(fp)
416 FILE *fp;
417{
418 RFILE rf;
419 rf.fp = fp;
420 return r_long(&rf);
421}
422
423object *
424rd_object(fp)
425 FILE *fp;
426{
427 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000428 if (err_occurred()) {
Guido van Rossum05870111995-08-28 02:56:20 +0000429 fatal("XXX rd_object called with exception set"); /* tmp */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000430 fprintf(stderr, "XXX rd_object called with exception set\n");
431 return NULL;
432 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000433 rf.fp = fp;
434 return r_object(&rf);
435}
436
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000437object *
438rds_object(str, len)
439 char *str;
440 int len;
441{
442 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000443 if (err_occurred()) {
444 fprintf(stderr, "XXX rds_object called with exception set\n");
445 return NULL;
446 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000447 rf.fp = NULL;
448 rf.str = NULL;
449 rf.ptr = str;
450 rf.end = str + len;
451 return r_object(&rf);
452}
453
Guido van Rossum64b45521991-06-07 13:58:22 +0000454/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000455
456static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000457marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000458 object *self;
459 object *args;
460{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000461 WFILE wf;
462 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000463 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000464 if (!getargs(args, "(OO)", &x, &f))
465 return NULL;
466 if (!is_fileobject(f)) {
467 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000468 return NULL;
469 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000470 wf.fp = getfilefile(f);
471 wf.str = NULL;
472 wf.ptr = wf.end = NULL;
473 w_object(x, &wf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000474 INCREF(None);
475 return None;
476}
477
478static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000479marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000480 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000481 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000482{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000483 RFILE rf;
484 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000485 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000486 if (!getargs(args, "O", &f))
487 return NULL;
488 if (!is_fileobject(f)) {
489 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000490 return NULL;
491 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000492 rf.fp = getfilefile(f);
493 rf.str = NULL;
494 rf.ptr = rf.end = NULL;
495 err_clear();
496 v = r_object(&rf);
497 if (err_occurred()) {
498 XDECREF(v);
499 v = NULL;
500 }
501 return v;
502}
503
504static object *
505marshal_dumps(self, args)
506 object *self;
507 object *args;
508{
509 WFILE wf;
510 object *x;
511 if (!getargs(args, "O", &x))
512 return NULL;
513 wf.fp = NULL;
514 wf.str = newsizedstringobject((char *)NULL, 50);
515 if (wf.str == NULL)
516 return NULL;
517 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
518 wf.end = wf.ptr + getstringsize(wf.str);
519 w_object(x, &wf);
520 if (wf.str != NULL)
521 resizestring(&wf.str,
522 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
523 return wf.str;
524}
525
526static object *
527marshal_loads(self, args)
528 object *self;
529 object *args;
530{
531 RFILE rf;
532 object *v;
533 char *s;
534 int n;
535 if (!getargs(args, "s#", &s, &n))
536 return NULL;
537 rf.fp = NULL;
538 rf.str = args;
539 rf.ptr = s;
540 rf.end = s + n;
541 err_clear();
542 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000543 if (err_occurred()) {
544 XDECREF(v);
545 v = NULL;
546 }
547 return v;
548}
549
550static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000551 {"dump", marshal_dump},
552 {"load", marshal_load},
553 {"dumps", marshal_dumps},
554 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000555 {NULL, NULL} /* sentinel */
556};
557
558void
559initmarshal()
560{
561 (void) initmodule("marshal", marshal_methods);
562}