blob: 8c01020ddcadef0b9b6bef791ae45d98ad56b820 [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{
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);
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
Guido van Rossum8d617a61995-03-09 12:12:11 +0000223#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
224
225#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
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 Rossum8d617a61995-03-09 12:12:11 +0000258 register FILE *fp = p->fp;
259 if (fp) {
260 x = getc(fp);
261 x |= (long)getc(fp) << 8;
262 x |= (long)getc(fp) << 16;
263 x |= (long)getc(fp) << 24;
264 }
265 else {
266 x = rs_byte(p);
267 x |= (long)rs_byte(p) << 8;
268 x |= (long)rs_byte(p) << 16;
269 x |= (long)rs_byte(p) << 24;
270 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000271 /* XXX If your long is > 32 bits, add sign-extension here!!! */
272 return x;
273}
274
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000275static object *
276r_object(p)
277 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000278{
279 object *v;
280 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000281 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000282
283 switch (type) {
284
285 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000286 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000287 return NULL;
288
289 case TYPE_NULL:
290 return NULL;
291
292 case TYPE_NONE:
293 INCREF(None);
294 return None;
295
296 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000297 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000298
299 case TYPE_LONG:
300 {
301 int size;
302 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000303 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000304 size = n<0 ? -n : n;
305 ob = alloclongobject(size);
306 if (ob == NULL)
307 return NULL;
308 ob->ob_size = n;
309 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000310 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000311 return (object *)ob;
312 }
313
314 case TYPE_FLOAT:
315 {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000316 extern double atof PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000317 char buf[256];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000318 n = r_byte(p);
319 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000320 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000321 "EOF read where object expected");
322 return NULL;
323 }
324 buf[n] = '\0';
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000325 return newfloatobject(atof(buf));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000326 }
327
328 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000329 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000330 v = newsizedstringobject((char *)NULL, n);
331 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000332 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000333 DECREF(v);
334 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000335 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000336 "EOF read where object expected");
337 }
338 }
339 return v;
340
341 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000342 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000343 v = newtupleobject((int)n);
344 if (v == NULL)
345 return v;
346 for (i = 0; i < n; i++)
Guido van Rossum8d617a61995-03-09 12:12:11 +0000347 SETTUPLEITEM(v, (int)i, r_object(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000348 return v;
349
350 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000351 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000352 v = newlistobject((int)n);
353 if (v == NULL)
354 return v;
355 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000356 setlistitem(v, (int)i, r_object(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000357 return v;
358
Guido van Rossum64b45521991-06-07 13:58:22 +0000359 case TYPE_DICT:
360 v = newdictobject();
361 if (v == NULL)
362 return NULL;
363 for (;;) {
364 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000365 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000366 if (key == NULL)
367 break;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000368 val = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000369 dict2insert(v, key, val);
370 DECREF(key);
371 XDECREF(val);
372 }
373 return v;
374
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000375 case TYPE_CODE:
376 {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000377 object *code = r_object(p);
378 object *consts = r_object(p);
379 object *names = r_object(p);
380 object *filename = r_object(p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000381 object *name = r_object(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000382 if (!err_occurred()) {
383 v = (object *) newcodeobject(code,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000384 consts, names, filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000385 }
386 else
387 v = NULL;
388 XDECREF(code);
389 XDECREF(consts);
390 XDECREF(names);
391 XDECREF(filename);
Guido van Rossuma4403101994-10-05 12:24:16 +0000392 XDECREF(name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000393
394 }
395 return v;
396
397 default:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000398 err_setstr(TypeError, "read unknown object");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000399 return NULL;
400
401 }
402}
403
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000404long
405rd_long(fp)
406 FILE *fp;
407{
408 RFILE rf;
409 rf.fp = fp;
410 return r_long(&rf);
411}
412
413object *
414rd_object(fp)
415 FILE *fp;
416{
417 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000418 if (err_occurred()) {
419 fprintf(stderr, "XXX rd_object called with exception set\n");
420 return NULL;
421 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000422 rf.fp = fp;
423 return r_object(&rf);
424}
425
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000426object *
427rds_object(str, len)
428 char *str;
429 int len;
430{
431 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000432 if (err_occurred()) {
433 fprintf(stderr, "XXX rds_object called with exception set\n");
434 return NULL;
435 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000436 rf.fp = NULL;
437 rf.str = NULL;
438 rf.ptr = str;
439 rf.end = str + len;
440 return r_object(&rf);
441}
442
Guido van Rossum64b45521991-06-07 13:58:22 +0000443/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000444
445static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000446marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000447 object *self;
448 object *args;
449{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000450 WFILE wf;
451 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000452 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000453 if (!getargs(args, "(OO)", &x, &f))
454 return NULL;
455 if (!is_fileobject(f)) {
456 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000457 return NULL;
458 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000459 wf.fp = getfilefile(f);
460 wf.str = NULL;
461 wf.ptr = wf.end = NULL;
462 w_object(x, &wf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000463 INCREF(None);
464 return None;
465}
466
467static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000468marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000469 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000470 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000471{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000472 RFILE rf;
473 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000474 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000475 if (!getargs(args, "O", &f))
476 return NULL;
477 if (!is_fileobject(f)) {
478 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000479 return NULL;
480 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000481 rf.fp = getfilefile(f);
482 rf.str = NULL;
483 rf.ptr = rf.end = NULL;
484 err_clear();
485 v = r_object(&rf);
486 if (err_occurred()) {
487 XDECREF(v);
488 v = NULL;
489 }
490 return v;
491}
492
493static object *
494marshal_dumps(self, args)
495 object *self;
496 object *args;
497{
498 WFILE wf;
499 object *x;
500 if (!getargs(args, "O", &x))
501 return NULL;
502 wf.fp = NULL;
503 wf.str = newsizedstringobject((char *)NULL, 50);
504 if (wf.str == NULL)
505 return NULL;
506 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
507 wf.end = wf.ptr + getstringsize(wf.str);
508 w_object(x, &wf);
509 if (wf.str != NULL)
510 resizestring(&wf.str,
511 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
512 return wf.str;
513}
514
515static object *
516marshal_loads(self, args)
517 object *self;
518 object *args;
519{
520 RFILE rf;
521 object *v;
522 char *s;
523 int n;
524 if (!getargs(args, "s#", &s, &n))
525 return NULL;
526 rf.fp = NULL;
527 rf.str = args;
528 rf.ptr = s;
529 rf.end = s + n;
530 err_clear();
531 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000532 if (err_occurred()) {
533 XDECREF(v);
534 v = NULL;
535 }
536 return v;
537}
538
539static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000540 {"dump", marshal_dump},
541 {"load", marshal_load},
542 {"dumps", marshal_dumps},
543 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000544 {NULL, NULL} /* sentinel */
545};
546
547void
548initmarshal()
549{
550 (void) initmodule("marshal", marshal_methods);
551}