blob: 08ad79008c850bc5e393a32f993c1b9da5c69623 [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'
Guido van Rossum8861b741996-07-30 16:49:37 +000040#define TYPE_ELLIPSES '.'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000041#define TYPE_INT 'i'
42#define TYPE_FLOAT 'f'
Guido van Rossum8a5c5d21996-01-12 01:09:56 +000043#define TYPE_COMPLEX 'x'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000044#define TYPE_LONG 'l'
45#define TYPE_STRING 's'
46#define TYPE_TUPLE '('
47#define TYPE_LIST '['
48#define TYPE_DICT '{'
Guido van Rossum681d79a1995-07-18 14:51:37 +000049#define TYPE_CODE 'c'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000050#define TYPE_UNKNOWN '?'
51
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000052typedef struct {
53 FILE *fp;
Guido van Rossumf2150601996-06-26 20:41:23 +000054 int error;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000055 /* If fp == NULL, the following are valid: */
56 object *str;
57 char *ptr;
58 char *end;
59} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000060
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000061#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
62 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
63 else w_more(c, p)
64
65static void
66w_more(c, p)
67 char c;
68 WFILE *p;
69{
70 int size, newsize;
71 if (p->str == NULL)
72 return; /* An error already occurred */
73 size = getstringsize(p->str);
74 newsize = size + 1024;
75 if (resizestring(&p->str, newsize) != 0) {
76 p->ptr = p->end = NULL;
77 }
78 else {
79 p->ptr = GETSTRINGVALUE((stringobject *)p->str) + size;
80 p->end = GETSTRINGVALUE((stringobject *)p->str) + newsize;
81 *p->ptr++ = c;
82 }
83}
84
85static void
86w_string(s, n, p)
87 char *s;
88 int n;
89 WFILE *p;
90{
91 if (p->fp != NULL) {
92 fwrite(s, 1, n, p->fp);
93 }
94 else {
95 while (--n >= 0) {
96 w_byte(*s, p);
97 s++;
98 }
99 }
100}
101
102static void
103w_short(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000104 int x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000105 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000106{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000107 w_byte( x & 0xff, p);
108 w_byte((x>> 8) & 0xff, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000109}
110
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000111static void
112w_long(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000113 long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000114 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000115{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000116 w_byte((int)( x & 0xff), p);
117 w_byte((int)((x>> 8) & 0xff), p);
118 w_byte((int)((x>>16) & 0xff), p);
119 w_byte((int)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000120}
121
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000122static void
123w_object(v, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000124 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000125 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000126{
Guido van Rossum3a205f71995-02-17 15:10:07 +0000127 int i, n;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000128
129 if (v == NULL)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000130 w_byte(TYPE_NULL, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000131 else if (v == None)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000132 w_byte(TYPE_NONE, p);
Guido van Rossum8861b741996-07-30 16:49:37 +0000133 else if (v == Py_Ellipses)
134 w_byte(TYPE_ELLIPSES, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000135 else if (is_intobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000136 w_byte(TYPE_INT, p);
137 w_long(getintvalue(v), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000138 }
139 else if (is_longobject(v)) {
140 longobject *ob = (longobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000141 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000142 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000143 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000144 if (n < 0)
145 n = -n;
146 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000147 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000148 }
149 else if (is_floatobject(v)) {
150 extern void float_buf_repr PROTO((char *, floatobject *));
151 char buf[256]; /* Plenty to format any double */
152 float_buf_repr(buf, (floatobject *)v);
153 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000154 w_byte(TYPE_FLOAT, p);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000155 w_byte(n, p);
156 w_string(buf, n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000157 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000158#ifndef WITHOUT_COMPLEX
159 else if (is_complexobject(v)) {
160 extern void float_buf_repr PROTO((char *, floatobject *));
161 char buf[256]; /* Plenty to format any double */
162 floatobject *temp;
163 w_byte(TYPE_COMPLEX, p);
164 temp = (floatobject*)newfloatobject(PyComplex_RealAsDouble(v));
165 float_buf_repr(buf, temp);
166 DECREF(temp);
167 n = strlen(buf);
168 w_byte(n, p);
169 w_string(buf, n, p);
170 temp = (floatobject*)newfloatobject(PyComplex_ImagAsDouble(v));
171 float_buf_repr(buf, temp);
172 DECREF(temp);
173 n = strlen(buf);
174 w_byte(n, p);
175 w_string(buf, n, p);
176 }
177#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000178 else if (is_stringobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000179 w_byte(TYPE_STRING, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000180 n = getstringsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000181 w_long((long)n, p);
182 w_string(getstringvalue(v), n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000183 }
184 else if (is_tupleobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000185 w_byte(TYPE_TUPLE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000186 n = gettuplesize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000187 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000188 for (i = 0; i < n; i++) {
Guido van Rossum8d617a61995-03-09 12:12:11 +0000189 w_object(GETTUPLEITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000190 }
191 }
192 else if (is_listobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000193 w_byte(TYPE_LIST, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000194 n = getlistsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000195 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000196 for (i = 0; i < n; i++) {
Guido van Rossum3a205f71995-02-17 15:10:07 +0000197 w_object(getlistitem(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000198 }
199 }
Guido van Rossum64b45521991-06-07 13:58:22 +0000200 else if (is_dictobject(v)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000201 int pos;
202 object *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000203 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000204 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000205 pos = 0;
206 while (mappinggetnext(v, &pos, &key, &value)) {
207 w_object(key, p);
208 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000209 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000210 w_object((object *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000211 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000212 else if (is_codeobject(v)) {
213 codeobject *co = (codeobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000214 w_byte(TYPE_CODE, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000215 w_short(co->co_argcount, p);
216 w_short(co->co_nlocals, p);
217 w_short(co->co_flags, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000218 w_object((object *)co->co_code, p);
219 w_object(co->co_consts, p);
220 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000221 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000222 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000223 w_object(co->co_name, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000224 }
225 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000226 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000227 p->error = 1;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000228 }
229}
230
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000231void
232wr_long(x, fp)
233 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000234 FILE *fp;
235{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000236 WFILE wf;
237 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000238 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000239 w_long(x, &wf);
240}
241
242void
243wr_object(x, fp)
244 object *x;
245 FILE *fp;
246{
247 WFILE wf;
248 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000249 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000250 w_object(x, &wf);
251}
252
253typedef WFILE RFILE; /* Same struct with different invariants */
254
Guido van Rossum8d617a61995-03-09 12:12:11 +0000255#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
256
257#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000258
259static int
260r_string(s, n, p)
261 char *s;
262 int n;
263 RFILE *p;
264{
265 if (p->fp != NULL)
266 return fread(s, 1, n, p->fp);
267 if (p->end - p->ptr < n)
268 n = p->end - p->ptr;
269 memcpy(s, p->ptr, n);
270 p->ptr += n;
271 return n;
272}
273
274static int
275r_short(p)
276 RFILE *p;
277{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000278 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000279 x = r_byte(p);
280 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000281 /* XXX If your short is > 16 bits, add sign-extension here!!! */
282 return x;
283}
284
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000285static long
286r_long(p)
287 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000288{
289 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000290 register FILE *fp = p->fp;
291 if (fp) {
292 x = getc(fp);
293 x |= (long)getc(fp) << 8;
294 x |= (long)getc(fp) << 16;
295 x |= (long)getc(fp) << 24;
296 }
297 else {
298 x = rs_byte(p);
299 x |= (long)rs_byte(p) << 8;
300 x |= (long)rs_byte(p) << 16;
301 x |= (long)rs_byte(p) << 24;
302 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000303 /* XXX If your long is > 32 bits, add sign-extension here!!! */
304 return x;
305}
306
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000307static object *
308r_object(p)
309 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000310{
Jack Jansen9513f2c1995-10-27 13:21:28 +0000311 object *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000312 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000313 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000314
315 switch (type) {
316
317 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000318 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000319 return NULL;
320
321 case TYPE_NULL:
322 return NULL;
323
324 case TYPE_NONE:
325 INCREF(None);
326 return None;
327
Guido van Rossum8861b741996-07-30 16:49:37 +0000328 case TYPE_ELLIPSES:
329 INCREF(Py_Ellipses);
330 return Py_Ellipses;
331
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000332 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000333 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000334
335 case TYPE_LONG:
336 {
337 int size;
338 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000339 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000340 size = n<0 ? -n : n;
341 ob = alloclongobject(size);
342 if (ob == NULL)
343 return NULL;
344 ob->ob_size = n;
345 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000346 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000347 return (object *)ob;
348 }
349
350 case TYPE_FLOAT:
351 {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000352 extern double atof PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000353 char buf[256];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000354 n = r_byte(p);
355 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000356 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000357 "EOF read where object expected");
358 return NULL;
359 }
360 buf[n] = '\0';
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000361 return newfloatobject(atof(buf));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000362 }
363
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000364#ifndef WITHOUT_COMPLEX
365 case TYPE_COMPLEX:
366 {
367 extern double atof PROTO((const char *));
368 char buf[256];
Guido van Rossum530956d1996-07-21 02:27:43 +0000369 Py_complex c;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000370 n = r_byte(p);
371 if (r_string(buf, (int)n, p) != n) {
372 err_setstr(EOFError,
373 "EOF read where object expected");
374 return NULL;
375 }
376 buf[n] = '\0';
377 c.real = atof(buf);
378 n = r_byte(p);
379 if (r_string(buf, (int)n, p) != n) {
380 err_setstr(EOFError,
381 "EOF read where object expected");
382 return NULL;
383 }
384 buf[n] = '\0';
385 c.imag = atof(buf);
386 return newcomplexobject(c);
387 }
388#endif
389
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000390 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000391 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000392 v = newsizedstringobject((char *)NULL, n);
393 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000394 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000395 DECREF(v);
396 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000397 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000398 "EOF read where object expected");
399 }
400 }
401 return v;
402
403 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000404 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000405 v = newtupleobject((int)n);
406 if (v == NULL)
407 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000408 for (i = 0; i < n; i++) {
409 v2 = r_object(p);
410 if ( v2 == NULL ) {
411 DECREF(v);
412 v = NULL;
413 break;
414 }
415 SETTUPLEITEM(v, (int)i, v2);
416 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000417 return v;
418
419 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000420 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000421 v = newlistobject((int)n);
422 if (v == NULL)
423 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000424 for (i = 0; i < n; i++) {
425 v2 = r_object(p);
426 if ( v2 == NULL ) {
427 DECREF(v);
428 v = NULL;
429 break;
430 }
431 setlistitem(v, (int)i, v2);
432 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000433 return v;
434
Guido van Rossum64b45521991-06-07 13:58:22 +0000435 case TYPE_DICT:
436 v = newdictobject();
437 if (v == NULL)
438 return NULL;
439 for (;;) {
440 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000441 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000442 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000443 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000444 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000445 if (val != NULL)
446 dict2insert(v, key, val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000447 DECREF(key);
448 XDECREF(val);
449 }
450 return v;
451
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000452 case TYPE_CODE:
453 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000454 int argcount = r_short(p);
455 int nlocals = r_short(p);
456 int flags = r_short(p);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000457 object *code = NULL;
458 object *consts = NULL;
459 object *names = NULL;
460 object *varnames = NULL;
461 object *filename = NULL;
462 object *name = NULL;
463
464 code = r_object(p);
465 if (code) consts = r_object(p);
466 if (consts) names = r_object(p);
467 if (names) varnames = r_object(p);
468 if (varnames) filename = r_object(p);
469 if (filename) name = r_object(p);
470
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000471 if (!err_occurred()) {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000472 v = (object *) newcodeobject(
473 argcount, nlocals, flags,
474 code, consts, names, varnames,
475 filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000476 }
477 else
478 v = NULL;
479 XDECREF(code);
480 XDECREF(consts);
481 XDECREF(names);
Guido van Rossum0a8626e1996-05-28 22:28:12 +0000482 XDECREF(varnames);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000483 XDECREF(filename);
Guido van Rossuma4403101994-10-05 12:24:16 +0000484 XDECREF(name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000485
486 }
487 return v;
488
489 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000490 /* Bogus data got written, which isn't ideal.
491 This will let you keep working and recover. */
492 INCREF(None);
493 return None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000494
495 }
496}
497
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000498long
499rd_long(fp)
500 FILE *fp;
501{
502 RFILE rf;
503 rf.fp = fp;
504 return r_long(&rf);
505}
506
507object *
508rd_object(fp)
509 FILE *fp;
510{
511 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000512 if (err_occurred()) {
Guido van Rossum05870111995-08-28 02:56:20 +0000513 fatal("XXX rd_object called with exception set"); /* tmp */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000514 fprintf(stderr, "XXX rd_object called with exception set\n");
515 return NULL;
516 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000517 rf.fp = fp;
518 return r_object(&rf);
519}
520
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000521object *
522rds_object(str, len)
523 char *str;
524 int len;
525{
526 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000527 if (err_occurred()) {
528 fprintf(stderr, "XXX rds_object called with exception set\n");
529 return NULL;
530 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000531 rf.fp = NULL;
532 rf.str = NULL;
533 rf.ptr = str;
534 rf.end = str + len;
535 return r_object(&rf);
536}
537
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000538object *
539PyMarshal_WriteObjectToString(x) /* wrs_object() */
540 object *x;
541{
542 WFILE wf;
543 wf.fp = NULL;
544 wf.str = newsizedstringobject((char *)NULL, 50);
545 if (wf.str == NULL)
546 return NULL;
547 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
548 wf.end = wf.ptr + getstringsize(wf.str);
549 wf.error = 0;
550 w_object(x, &wf);
551 if (wf.str != NULL)
552 resizestring(&wf.str,
553 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
554 if (wf.error) {
555 XDECREF(wf.str);
556 err_setstr(ValueError, "unmarshallable object");
557 return NULL;
558 }
559 return wf.str;
560}
561
Guido van Rossum64b45521991-06-07 13:58:22 +0000562/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000563
564static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000565marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000566 object *self;
567 object *args;
568{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000569 WFILE wf;
570 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000571 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000572 if (!getargs(args, "(OO)", &x, &f))
573 return NULL;
574 if (!is_fileobject(f)) {
575 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000576 return NULL;
577 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000578 wf.fp = getfilefile(f);
579 wf.str = NULL;
580 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000581 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000582 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000583 if (wf.error) {
584 err_setstr(ValueError, "unmarshallable object");
585 return NULL;
586 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000587 INCREF(None);
588 return None;
589}
590
591static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000592marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000593 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000594 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000595{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000596 RFILE rf;
597 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000598 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000599 if (!getargs(args, "O", &f))
600 return NULL;
601 if (!is_fileobject(f)) {
602 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000603 return NULL;
604 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000605 rf.fp = getfilefile(f);
606 rf.str = NULL;
607 rf.ptr = rf.end = NULL;
608 err_clear();
609 v = r_object(&rf);
610 if (err_occurred()) {
611 XDECREF(v);
612 v = NULL;
613 }
614 return v;
615}
616
617static object *
618marshal_dumps(self, args)
619 object *self;
620 object *args;
621{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000622 object *x;
623 if (!getargs(args, "O", &x))
624 return NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000625 return PyMarshal_WriteObjectToString(x);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000626}
627
628static object *
629marshal_loads(self, args)
630 object *self;
631 object *args;
632{
633 RFILE rf;
634 object *v;
635 char *s;
636 int n;
637 if (!getargs(args, "s#", &s, &n))
638 return NULL;
639 rf.fp = NULL;
640 rf.str = args;
641 rf.ptr = s;
642 rf.end = s + n;
643 err_clear();
644 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000645 if (err_occurred()) {
646 XDECREF(v);
647 v = NULL;
648 }
649 return v;
650}
651
652static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000653 {"dump", marshal_dump},
654 {"load", marshal_load},
655 {"dumps", marshal_dumps},
656 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000657 {NULL, NULL} /* sentinel */
658};
659
660void
661initmarshal()
662{
663 (void) initmodule("marshal", marshal_methods);
664}