blob: 65f7f2d47fce4b663a126e38e2465c7c732ff386 [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 Rossum065d71e1991-06-04 20:23:28 +000037extern int errno;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000038
39#define TYPE_NULL '0'
40#define TYPE_NONE 'N'
41#define TYPE_INT 'i'
42#define TYPE_FLOAT 'f'
43#define TYPE_LONG 'l'
44#define TYPE_STRING 's'
45#define TYPE_TUPLE '('
46#define TYPE_LIST '['
47#define TYPE_DICT '{'
48#define TYPE_CODE 'C'
49#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{
125 long i, n;
126
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);
151 w_byte((int)n, p);
152 w_string(buf, (int)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000153 }
154 else if (is_stringobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000155 w_byte(TYPE_STRING, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000156 n = getstringsize(v);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000157 w_long(n, p);
158 w_string(getstringvalue(v), (int)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000159 }
160 else if (is_tupleobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000161 w_byte(TYPE_TUPLE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000162 n = gettuplesize(v);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000163 w_long(n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000164 for (i = 0; i < n; i++) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000165 w_object(gettupleitem(v, (int)i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000166 }
167 }
168 else if (is_listobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000169 w_byte(TYPE_LIST, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000170 n = getlistsize(v);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000171 w_long(n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000172 for (i = 0; i < n; i++) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000173 w_object(getlistitem(v, (int)i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000174 }
175 }
Guido van Rossum64b45521991-06-07 13:58:22 +0000176 else if (is_dictobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000177 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000178 /* This one is NULL object terminated! */
179 n = getdictsize(v);
180 for (i = 0; i < n; i++) {
181 object *key, *val;
Guido van Rossum64b45521991-06-07 13:58:22 +0000182 key = getdict2key(v, (int)i);
183 if (key != NULL) {
Guido van Rossumb8813141991-08-16 09:01:55 +0000184 val = dict2lookup(v, key); /* Can't be NULL */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000185 w_object(key, p);
186 w_object(val, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000187 }
188 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000189 w_object((object *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000190 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000191 else if (is_codeobject(v)) {
192 codeobject *co = (codeobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000193 w_byte(TYPE_CODE, p);
194 w_object((object *)co->co_code, p);
195 w_object(co->co_consts, p);
196 w_object(co->co_names, p);
197 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
227#define r_byte(p) ((p)->fp ? getc((p)->fp) \
228 : ((p)->ptr != (p)->end) ? *(p)->ptr++ : EOF)
229
230static int
231r_string(s, n, p)
232 char *s;
233 int n;
234 RFILE *p;
235{
236 if (p->fp != NULL)
237 return fread(s, 1, n, p->fp);
238 if (p->end - p->ptr < n)
239 n = p->end - p->ptr;
240 memcpy(s, p->ptr, n);
241 p->ptr += n;
242 return n;
243}
244
245static int
246r_short(p)
247 RFILE *p;
248{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000249 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000250 x = r_byte(p);
251 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000252 /* XXX If your short is > 16 bits, add sign-extension here!!! */
253 return x;
254}
255
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000256static long
257r_long(p)
258 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000259{
260 register long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000261 x = r_byte(p);
262 x |= (long)r_byte(p) << 8;
263 x |= (long)r_byte(p) << 16;
264 x |= (long)r_byte(p) << 24;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000265 /* XXX If your long is > 32 bits, add sign-extension here!!! */
266 return x;
267}
268
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000269static object *
270r_object(p)
271 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000272{
273 object *v;
274 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000275 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000276
277 switch (type) {
278
279 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000280 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000281 return NULL;
282
283 case TYPE_NULL:
284 return NULL;
285
286 case TYPE_NONE:
287 INCREF(None);
288 return None;
289
290 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000291 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000292
293 case TYPE_LONG:
294 {
295 int size;
296 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000297 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000298 size = n<0 ? -n : n;
299 ob = alloclongobject(size);
300 if (ob == NULL)
301 return NULL;
302 ob->ob_size = n;
303 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000304 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000305 return (object *)ob;
306 }
307
308 case TYPE_FLOAT:
309 {
Guido van Rossum2807d191992-03-27 17:23:17 +0000310 extern double strtod PROTO((const char *, char **));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000311 char buf[256];
312 double res;
313 char *end;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000314 n = r_byte(p);
315 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000316 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000317 "EOF read where object expected");
318 return NULL;
319 }
320 buf[n] = '\0';
321 errno = 0;
322 res = strtod(buf, &end);
323 if (*end != '\0') {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000324 err_setstr(ValueError, "bad float syntax");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000325 return NULL;
326 }
327 if (errno != 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000328 err_setstr(ValueError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000329 "float constant too large");
330 return NULL;
331 }
332 return newfloatobject(res);
333 }
334
335 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000336 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000337 v = newsizedstringobject((char *)NULL, n);
338 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000339 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000340 DECREF(v);
341 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000342 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000343 "EOF read where object expected");
344 }
345 }
346 return v;
347
348 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000349 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000350 v = newtupleobject((int)n);
351 if (v == NULL)
352 return v;
353 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000354 settupleitem(v, (int)i, r_object(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000355 return v;
356
357 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000358 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000359 v = newlistobject((int)n);
360 if (v == NULL)
361 return v;
362 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000363 setlistitem(v, (int)i, r_object(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000364 return v;
365
Guido van Rossum64b45521991-06-07 13:58:22 +0000366 case TYPE_DICT:
367 v = newdictobject();
368 if (v == NULL)
369 return NULL;
370 for (;;) {
371 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000372 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000373 if (key == NULL)
374 break;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000375 val = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000376 dict2insert(v, key, val);
377 DECREF(key);
378 XDECREF(val);
379 }
380 return v;
381
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000382 case TYPE_CODE:
383 {
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);
387 object *filename = r_object(p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000388 object *name = r_object(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000389 if (!err_occurred()) {
390 v = (object *) newcodeobject(code,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000391 consts, names, filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000392 }
393 else
394 v = NULL;
395 XDECREF(code);
396 XDECREF(consts);
397 XDECREF(names);
398 XDECREF(filename);
399
400 }
401 return v;
402
403 default:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000404 err_setstr(TypeError, "read unknown object");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000405 return NULL;
406
407 }
408}
409
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000410long
411rd_long(fp)
412 FILE *fp;
413{
414 RFILE rf;
415 rf.fp = fp;
416 return r_long(&rf);
417}
418
419object *
420rd_object(fp)
421 FILE *fp;
422{
423 RFILE rf;
424 rf.fp = fp;
425 return r_object(&rf);
426}
427
Guido van Rossum64b45521991-06-07 13:58:22 +0000428/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000429
430static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000431marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000432 object *self;
433 object *args;
434{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000435 WFILE wf;
436 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000437 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000438 if (!getargs(args, "(OO)", &x, &f))
439 return NULL;
440 if (!is_fileobject(f)) {
441 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000442 return NULL;
443 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000444 wf.fp = getfilefile(f);
445 wf.str = NULL;
446 wf.ptr = wf.end = NULL;
447 w_object(x, &wf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000448 INCREF(None);
449 return None;
450}
451
452static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000453marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000454 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000455 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000456{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000457 RFILE rf;
458 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000459 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000460 if (!getargs(args, "O", &f))
461 return NULL;
462 if (!is_fileobject(f)) {
463 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000464 return NULL;
465 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000466 rf.fp = getfilefile(f);
467 rf.str = NULL;
468 rf.ptr = rf.end = NULL;
469 err_clear();
470 v = r_object(&rf);
471 if (err_occurred()) {
472 XDECREF(v);
473 v = NULL;
474 }
475 return v;
476}
477
478static object *
479marshal_dumps(self, args)
480 object *self;
481 object *args;
482{
483 WFILE wf;
484 object *x;
485 if (!getargs(args, "O", &x))
486 return NULL;
487 wf.fp = NULL;
488 wf.str = newsizedstringobject((char *)NULL, 50);
489 if (wf.str == NULL)
490 return NULL;
491 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
492 wf.end = wf.ptr + getstringsize(wf.str);
493 w_object(x, &wf);
494 if (wf.str != NULL)
495 resizestring(&wf.str,
496 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
497 return wf.str;
498}
499
500static object *
501marshal_loads(self, args)
502 object *self;
503 object *args;
504{
505 RFILE rf;
506 object *v;
507 char *s;
508 int n;
509 if (!getargs(args, "s#", &s, &n))
510 return NULL;
511 rf.fp = NULL;
512 rf.str = args;
513 rf.ptr = s;
514 rf.end = s + n;
515 err_clear();
516 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000517 if (err_occurred()) {
518 XDECREF(v);
519 v = NULL;
520 }
521 return v;
522}
523
524static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000525 {"dump", marshal_dump},
526 {"load", marshal_load},
527 {"dumps", marshal_dumps},
528 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000529 {NULL, NULL} /* sentinel */
530};
531
532void
533initmarshal()
534{
535 (void) initmodule("marshal", marshal_methods);
536}