blob: 54cabf63e6d98b63b5a266dc717099e8ce17cbf8 [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 '{'
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 Rossum1d5735e1994-08-30 08:27:36 +0000307 extern double atof PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000308 char buf[256];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000309 n = r_byte(p);
310 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000311 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000312 "EOF read where object expected");
313 return NULL;
314 }
315 buf[n] = '\0';
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000316 return newfloatobject(atof(buf));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000317 }
318
319 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000320 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000321 v = newsizedstringobject((char *)NULL, n);
322 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000323 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000324 DECREF(v);
325 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000326 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000327 "EOF read where object expected");
328 }
329 }
330 return v;
331
332 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000333 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000334 v = newtupleobject((int)n);
335 if (v == NULL)
336 return v;
337 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000338 settupleitem(v, (int)i, r_object(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000339 return v;
340
341 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000342 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000343 v = newlistobject((int)n);
344 if (v == NULL)
345 return v;
346 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000347 setlistitem(v, (int)i, r_object(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000348 return v;
349
Guido van Rossum64b45521991-06-07 13:58:22 +0000350 case TYPE_DICT:
351 v = newdictobject();
352 if (v == NULL)
353 return NULL;
354 for (;;) {
355 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000356 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000357 if (key == NULL)
358 break;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000359 val = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000360 dict2insert(v, key, val);
361 DECREF(key);
362 XDECREF(val);
363 }
364 return v;
365
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000366 case TYPE_CODE:
367 {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000368 object *code = r_object(p);
369 object *consts = r_object(p);
370 object *names = r_object(p);
371 object *filename = r_object(p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000372 object *name = r_object(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000373 if (!err_occurred()) {
374 v = (object *) newcodeobject(code,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000375 consts, names, filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000376 }
377 else
378 v = NULL;
379 XDECREF(code);
380 XDECREF(consts);
381 XDECREF(names);
382 XDECREF(filename);
Guido van Rossuma4403101994-10-05 12:24:16 +0000383 XDECREF(name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000384
385 }
386 return v;
387
388 default:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000389 err_setstr(TypeError, "read unknown object");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000390 return NULL;
391
392 }
393}
394
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000395long
396rd_long(fp)
397 FILE *fp;
398{
399 RFILE rf;
400 rf.fp = fp;
401 return r_long(&rf);
402}
403
404object *
405rd_object(fp)
406 FILE *fp;
407{
408 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000409 if (err_occurred()) {
410 fprintf(stderr, "XXX rd_object called with exception set\n");
411 return NULL;
412 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000413 rf.fp = fp;
414 return r_object(&rf);
415}
416
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000417object *
418rds_object(str, len)
419 char *str;
420 int len;
421{
422 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000423 if (err_occurred()) {
424 fprintf(stderr, "XXX rds_object called with exception set\n");
425 return NULL;
426 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000427 rf.fp = NULL;
428 rf.str = NULL;
429 rf.ptr = str;
430 rf.end = str + len;
431 return r_object(&rf);
432}
433
Guido van Rossum64b45521991-06-07 13:58:22 +0000434/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000435
436static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000437marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000438 object *self;
439 object *args;
440{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000441 WFILE wf;
442 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000443 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000444 if (!getargs(args, "(OO)", &x, &f))
445 return NULL;
446 if (!is_fileobject(f)) {
447 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000448 return NULL;
449 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000450 wf.fp = getfilefile(f);
451 wf.str = NULL;
452 wf.ptr = wf.end = NULL;
453 w_object(x, &wf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000454 INCREF(None);
455 return None;
456}
457
458static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000459marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000460 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000461 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000462{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000463 RFILE rf;
464 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000465 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000466 if (!getargs(args, "O", &f))
467 return NULL;
468 if (!is_fileobject(f)) {
469 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000470 return NULL;
471 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000472 rf.fp = getfilefile(f);
473 rf.str = NULL;
474 rf.ptr = rf.end = NULL;
475 err_clear();
476 v = r_object(&rf);
477 if (err_occurred()) {
478 XDECREF(v);
479 v = NULL;
480 }
481 return v;
482}
483
484static object *
485marshal_dumps(self, args)
486 object *self;
487 object *args;
488{
489 WFILE wf;
490 object *x;
491 if (!getargs(args, "O", &x))
492 return NULL;
493 wf.fp = NULL;
494 wf.str = newsizedstringobject((char *)NULL, 50);
495 if (wf.str == NULL)
496 return NULL;
497 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
498 wf.end = wf.ptr + getstringsize(wf.str);
499 w_object(x, &wf);
500 if (wf.str != NULL)
501 resizestring(&wf.str,
502 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
503 return wf.str;
504}
505
506static object *
507marshal_loads(self, args)
508 object *self;
509 object *args;
510{
511 RFILE rf;
512 object *v;
513 char *s;
514 int n;
515 if (!getargs(args, "s#", &s, &n))
516 return NULL;
517 rf.fp = NULL;
518 rf.str = args;
519 rf.ptr = s;
520 rf.end = s + n;
521 err_clear();
522 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000523 if (err_occurred()) {
524 XDECREF(v);
525 v = NULL;
526 }
527 return v;
528}
529
530static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000531 {"dump", marshal_dump},
532 {"load", marshal_load},
533 {"dumps", marshal_dumps},
534 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000535 {NULL, NULL} /* sentinel */
536};
537
538void
539initmarshal()
540{
541 (void) initmodule("marshal", marshal_methods);
542}