blob: e61815ccba415c6a78a095e3aedc9af1f6109624 [file] [log] [blame]
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001/***********************************************************
Guido van Rossum0b0db8e1993-01-21 16:07:51 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The 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 '{'
47#define TYPE_CODE 'C'
48#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{
124 long i, n;
125
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);
150 w_byte((int)n, p);
151 w_string(buf, (int)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 Rossum0b0db8e1993-01-21 16:07:51 +0000156 w_long(n, p);
157 w_string(getstringvalue(v), (int)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 Rossum0b0db8e1993-01-21 16:07:51 +0000162 w_long(n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000163 for (i = 0; i < n; i++) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000164 w_object(gettupleitem(v, (int)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 Rossum0b0db8e1993-01-21 16:07:51 +0000170 w_long(n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000171 for (i = 0; i < n; i++) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000172 w_object(getlistitem(v, (int)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);
190 w_object((object *)co->co_code, p);
191 w_object(co->co_consts, p);
192 w_object(co->co_names, p);
193 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000194 w_object(co->co_name, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000195 }
196 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000197 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000198 }
199}
200
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000201void
202wr_long(x, fp)
203 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000204 FILE *fp;
205{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000206 WFILE wf;
207 wf.fp = fp;
208 w_long(x, &wf);
209}
210
211void
212wr_object(x, fp)
213 object *x;
214 FILE *fp;
215{
216 WFILE wf;
217 wf.fp = fp;
218 w_object(x, &wf);
219}
220
221typedef WFILE RFILE; /* Same struct with different invariants */
222
223#define r_byte(p) ((p)->fp ? getc((p)->fp) \
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000224 : ((p)->ptr != (p)->end) ? \
225 (unsigned char)*(p)->ptr++ : EOF)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000226
227static int
228r_string(s, n, p)
229 char *s;
230 int n;
231 RFILE *p;
232{
233 if (p->fp != NULL)
234 return fread(s, 1, n, p->fp);
235 if (p->end - p->ptr < n)
236 n = p->end - p->ptr;
237 memcpy(s, p->ptr, n);
238 p->ptr += n;
239 return n;
240}
241
242static int
243r_short(p)
244 RFILE *p;
245{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000246 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000247 x = r_byte(p);
248 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000249 /* XXX If your short is > 16 bits, add sign-extension here!!! */
250 return x;
251}
252
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000253static long
254r_long(p)
255 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000256{
257 register long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000258 x = r_byte(p);
259 x |= (long)r_byte(p) << 8;
260 x |= (long)r_byte(p) << 16;
261 x |= (long)r_byte(p) << 24;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000262 /* XXX If your long is > 32 bits, add sign-extension here!!! */
263 return x;
264}
265
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000266static object *
267r_object(p)
268 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000269{
270 object *v;
271 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000272 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000273
274 switch (type) {
275
276 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000277 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000278 return NULL;
279
280 case TYPE_NULL:
281 return NULL;
282
283 case TYPE_NONE:
284 INCREF(None);
285 return None;
286
287 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000288 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000289
290 case TYPE_LONG:
291 {
292 int size;
293 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000294 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000295 size = n<0 ? -n : n;
296 ob = alloclongobject(size);
297 if (ob == NULL)
298 return NULL;
299 ob->ob_size = n;
300 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000301 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000302 return (object *)ob;
303 }
304
305 case TYPE_FLOAT:
306 {
Guido van Rossum2807d191992-03-27 17:23:17 +0000307 extern double strtod PROTO((const char *, char **));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000308 char buf[256];
309 double res;
310 char *end;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000311 n = r_byte(p);
312 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000313 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000314 "EOF read where object expected");
315 return NULL;
316 }
317 buf[n] = '\0';
318 errno = 0;
319 res = strtod(buf, &end);
320 if (*end != '\0') {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000321 err_setstr(ValueError, "bad float syntax");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000322 return NULL;
323 }
324 if (errno != 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000325 err_setstr(ValueError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000326 "float constant too large");
327 return NULL;
328 }
329 return newfloatobject(res);
330 }
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 Rossum0b0db8e1993-01-21 16:07:51 +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 Rossum0b0db8e1993-01-21 16:07:51 +0000381 object *code = r_object(p);
382 object *consts = r_object(p);
383 object *names = r_object(p);
384 object *filename = r_object(p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000385 object *name = r_object(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000386 if (!err_occurred()) {
387 v = (object *) newcodeobject(code,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000388 consts, names, filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000389 }
390 else
391 v = NULL;
392 XDECREF(code);
393 XDECREF(consts);
394 XDECREF(names);
395 XDECREF(filename);
396
397 }
398 return v;
399
400 default:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000401 err_setstr(TypeError, "read unknown object");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000402 return NULL;
403
404 }
405}
406
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000407long
408rd_long(fp)
409 FILE *fp;
410{
411 RFILE rf;
412 rf.fp = fp;
413 return r_long(&rf);
414}
415
416object *
417rd_object(fp)
418 FILE *fp;
419{
420 RFILE rf;
421 rf.fp = fp;
422 return r_object(&rf);
423}
424
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000425object *
426rds_object(str, len)
427 char *str;
428 int len;
429{
430 RFILE rf;
431 rf.fp = NULL;
432 rf.str = NULL;
433 rf.ptr = str;
434 rf.end = str + len;
435 return r_object(&rf);
436}
437
Guido van Rossum64b45521991-06-07 13:58:22 +0000438/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000439
440static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000441marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000442 object *self;
443 object *args;
444{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000445 WFILE wf;
446 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000447 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000448 if (!getargs(args, "(OO)", &x, &f))
449 return NULL;
450 if (!is_fileobject(f)) {
451 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000452 return NULL;
453 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000454 wf.fp = getfilefile(f);
455 wf.str = NULL;
456 wf.ptr = wf.end = NULL;
457 w_object(x, &wf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000458 INCREF(None);
459 return None;
460}
461
462static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000463marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000464 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000465 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000466{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000467 RFILE rf;
468 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000469 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000470 if (!getargs(args, "O", &f))
471 return NULL;
472 if (!is_fileobject(f)) {
473 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000474 return NULL;
475 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000476 rf.fp = getfilefile(f);
477 rf.str = NULL;
478 rf.ptr = rf.end = NULL;
479 err_clear();
480 v = r_object(&rf);
481 if (err_occurred()) {
482 XDECREF(v);
483 v = NULL;
484 }
485 return v;
486}
487
488static object *
489marshal_dumps(self, args)
490 object *self;
491 object *args;
492{
493 WFILE wf;
494 object *x;
495 if (!getargs(args, "O", &x))
496 return NULL;
497 wf.fp = NULL;
498 wf.str = newsizedstringobject((char *)NULL, 50);
499 if (wf.str == NULL)
500 return NULL;
501 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
502 wf.end = wf.ptr + getstringsize(wf.str);
503 w_object(x, &wf);
504 if (wf.str != NULL)
505 resizestring(&wf.str,
506 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
507 return wf.str;
508}
509
510static object *
511marshal_loads(self, args)
512 object *self;
513 object *args;
514{
515 RFILE rf;
516 object *v;
517 char *s;
518 int n;
519 if (!getargs(args, "s#", &s, &n))
520 return NULL;
521 rf.fp = NULL;
522 rf.str = args;
523 rf.ptr = s;
524 rf.end = s + n;
525 err_clear();
526 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000527 if (err_occurred()) {
528 XDECREF(v);
529 v = NULL;
530 }
531 return v;
532}
533
534static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000535 {"dump", marshal_dump},
536 {"load", marshal_load},
537 {"dumps", marshal_dumps},
538 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000539 {NULL, NULL} /* sentinel */
540};
541
542void
543initmarshal()
544{
545 (void) initmodule("marshal", marshal_methods);
546}