blob: 93503d13ee27ed558ddfe08f74d0a0e79e77fab4 [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 Rossum25831651993-05-19 14:50:45 +0000177 int pos;
178 object *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000179 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000180 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000181 pos = 0;
182 while (mappinggetnext(v, &pos, &key, &value)) {
183 w_object(key, p);
184 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000185 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000186 w_object((object *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000187 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000188 else if (is_codeobject(v)) {
189 codeobject *co = (codeobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000190 w_byte(TYPE_CODE, p);
191 w_object((object *)co->co_code, p);
192 w_object(co->co_consts, p);
193 w_object(co->co_names, p);
194 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000195 w_object(co->co_name, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000196 }
197 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000198 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000199 }
200}
201
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000202void
203wr_long(x, fp)
204 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000205 FILE *fp;
206{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000207 WFILE wf;
208 wf.fp = fp;
209 w_long(x, &wf);
210}
211
212void
213wr_object(x, fp)
214 object *x;
215 FILE *fp;
216{
217 WFILE wf;
218 wf.fp = fp;
219 w_object(x, &wf);
220}
221
222typedef WFILE RFILE; /* Same struct with different invariants */
223
224#define r_byte(p) ((p)->fp ? getc((p)->fp) \
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000225 : ((p)->ptr != (p)->end) ? \
226 (unsigned char)*(p)->ptr++ : EOF)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000227
228static int
229r_string(s, n, p)
230 char *s;
231 int n;
232 RFILE *p;
233{
234 if (p->fp != NULL)
235 return fread(s, 1, n, p->fp);
236 if (p->end - p->ptr < n)
237 n = p->end - p->ptr;
238 memcpy(s, p->ptr, n);
239 p->ptr += n;
240 return n;
241}
242
243static int
244r_short(p)
245 RFILE *p;
246{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000247 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000248 x = r_byte(p);
249 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000250 /* XXX If your short is > 16 bits, add sign-extension here!!! */
251 return x;
252}
253
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000254static long
255r_long(p)
256 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000257{
258 register long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000259 x = r_byte(p);
260 x |= (long)r_byte(p) << 8;
261 x |= (long)r_byte(p) << 16;
262 x |= (long)r_byte(p) << 24;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000263 /* XXX If your long is > 32 bits, add sign-extension here!!! */
264 return x;
265}
266
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000267static object *
268r_object(p)
269 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000270{
271 object *v;
272 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000273 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000274
275 switch (type) {
276
277 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000278 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000279 return NULL;
280
281 case TYPE_NULL:
282 return NULL;
283
284 case TYPE_NONE:
285 INCREF(None);
286 return None;
287
288 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000289 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000290
291 case TYPE_LONG:
292 {
293 int size;
294 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000295 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000296 size = n<0 ? -n : n;
297 ob = alloclongobject(size);
298 if (ob == NULL)
299 return NULL;
300 ob->ob_size = n;
301 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000302 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000303 return (object *)ob;
304 }
305
306 case TYPE_FLOAT:
307 {
Guido van Rossum2807d191992-03-27 17:23:17 +0000308 extern double strtod PROTO((const char *, char **));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000309 char buf[256];
310 double res;
311 char *end;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000312 n = r_byte(p);
313 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000314 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000315 "EOF read where object expected");
316 return NULL;
317 }
318 buf[n] = '\0';
319 errno = 0;
320 res = strtod(buf, &end);
321 if (*end != '\0') {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000322 err_setstr(ValueError, "bad float syntax");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000323 return NULL;
324 }
325 if (errno != 0) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000326 err_setstr(ValueError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000327 "float constant too large");
328 return NULL;
329 }
330 return newfloatobject(res);
331 }
332
333 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000334 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000335 v = newsizedstringobject((char *)NULL, n);
336 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000337 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000338 DECREF(v);
339 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000340 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000341 "EOF read where object expected");
342 }
343 }
344 return v;
345
346 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000347 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000348 v = newtupleobject((int)n);
349 if (v == NULL)
350 return v;
351 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000352 settupleitem(v, (int)i, r_object(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000353 return v;
354
355 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000356 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000357 v = newlistobject((int)n);
358 if (v == NULL)
359 return v;
360 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000361 setlistitem(v, (int)i, r_object(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000362 return v;
363
Guido van Rossum64b45521991-06-07 13:58:22 +0000364 case TYPE_DICT:
365 v = newdictobject();
366 if (v == NULL)
367 return NULL;
368 for (;;) {
369 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000370 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000371 if (key == NULL)
372 break;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000373 val = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000374 dict2insert(v, key, val);
375 DECREF(key);
376 XDECREF(val);
377 }
378 return v;
379
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000380 case TYPE_CODE:
381 {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000382 object *code = r_object(p);
383 object *consts = r_object(p);
384 object *names = r_object(p);
385 object *filename = r_object(p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000386 object *name = r_object(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000387 if (!err_occurred()) {
388 v = (object *) newcodeobject(code,
Guido van Rossum9bfef441993-03-29 10:43:31 +0000389 consts, names, filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000390 }
391 else
392 v = NULL;
393 XDECREF(code);
394 XDECREF(consts);
395 XDECREF(names);
396 XDECREF(filename);
397
398 }
399 return v;
400
401 default:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000402 err_setstr(TypeError, "read unknown object");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000403 return NULL;
404
405 }
406}
407
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000408long
409rd_long(fp)
410 FILE *fp;
411{
412 RFILE rf;
413 rf.fp = fp;
414 return r_long(&rf);
415}
416
417object *
418rd_object(fp)
419 FILE *fp;
420{
421 RFILE rf;
422 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;
432 rf.fp = NULL;
433 rf.str = NULL;
434 rf.ptr = str;
435 rf.end = str + len;
436 return r_object(&rf);
437}
438
Guido van Rossum64b45521991-06-07 13:58:22 +0000439/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000440
441static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000442marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000443 object *self;
444 object *args;
445{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000446 WFILE wf;
447 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000448 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000449 if (!getargs(args, "(OO)", &x, &f))
450 return NULL;
451 if (!is_fileobject(f)) {
452 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000453 return NULL;
454 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000455 wf.fp = getfilefile(f);
456 wf.str = NULL;
457 wf.ptr = wf.end = NULL;
458 w_object(x, &wf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000459 INCREF(None);
460 return None;
461}
462
463static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000464marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000465 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000466 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000467{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000468 RFILE rf;
469 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000470 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000471 if (!getargs(args, "O", &f))
472 return NULL;
473 if (!is_fileobject(f)) {
474 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000475 return NULL;
476 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000477 rf.fp = getfilefile(f);
478 rf.str = NULL;
479 rf.ptr = rf.end = NULL;
480 err_clear();
481 v = r_object(&rf);
482 if (err_occurred()) {
483 XDECREF(v);
484 v = NULL;
485 }
486 return v;
487}
488
489static object *
490marshal_dumps(self, args)
491 object *self;
492 object *args;
493{
494 WFILE wf;
495 object *x;
496 if (!getargs(args, "O", &x))
497 return NULL;
498 wf.fp = NULL;
499 wf.str = newsizedstringobject((char *)NULL, 50);
500 if (wf.str == NULL)
501 return NULL;
502 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
503 wf.end = wf.ptr + getstringsize(wf.str);
504 w_object(x, &wf);
505 if (wf.str != NULL)
506 resizestring(&wf.str,
507 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
508 return wf.str;
509}
510
511static object *
512marshal_loads(self, args)
513 object *self;
514 object *args;
515{
516 RFILE rf;
517 object *v;
518 char *s;
519 int n;
520 if (!getargs(args, "s#", &s, &n))
521 return NULL;
522 rf.fp = NULL;
523 rf.str = args;
524 rf.ptr = s;
525 rf.end = s + n;
526 err_clear();
527 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000528 if (err_occurred()) {
529 XDECREF(v);
530 v = NULL;
531 }
532 return v;
533}
534
535static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000536 {"dump", marshal_dump},
537 {"load", marshal_load},
538 {"dumps", marshal_dumps},
539 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000540 {NULL, NULL} /* sentinel */
541};
542
543void
544initmarshal()
545{
546 (void) initmodule("marshal", marshal_methods);
547}