blob: 73d73ee28130c45472e219a021a323a33cb97ed1 [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
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000029
30******************************************************************/
31
32/* Write Python objects to files and read them back.
33 This is intended for writing and reading compiled Python code only;
34 a true persistent storage facility would be much harder, since
35 it would have to take circular links and sharing into account. */
36
37#include "allobjects.h"
Guido van Rossum2807d191992-03-27 17:23:17 +000038#include "modsupport.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000039#include "longintrepr.h"
40#include "compile.h"
41#include "marshal.h"
42
43#include <errno.h>
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000044
45#define TYPE_NULL '0'
46#define TYPE_NONE 'N'
Guido van Rossume449af71996-10-11 16:25:41 +000047#define TYPE_ELLIPSIS '.'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000048#define TYPE_INT 'i'
49#define TYPE_FLOAT 'f'
Guido van Rossum8a5c5d21996-01-12 01:09:56 +000050#define TYPE_COMPLEX 'x'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000051#define TYPE_LONG 'l'
52#define TYPE_STRING 's'
53#define TYPE_TUPLE '('
54#define TYPE_LIST '['
55#define TYPE_DICT '{'
Guido van Rossum681d79a1995-07-18 14:51:37 +000056#define TYPE_CODE 'c'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000057#define TYPE_UNKNOWN '?'
58
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000059typedef struct {
60 FILE *fp;
Guido van Rossumf2150601996-06-26 20:41:23 +000061 int error;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000062 /* If fp == NULL, the following are valid: */
63 object *str;
64 char *ptr;
65 char *end;
66} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000067
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000068#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
69 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
70 else w_more(c, p)
71
72static void
73w_more(c, p)
74 char c;
75 WFILE *p;
76{
77 int size, newsize;
78 if (p->str == NULL)
79 return; /* An error already occurred */
80 size = getstringsize(p->str);
81 newsize = size + 1024;
82 if (resizestring(&p->str, newsize) != 0) {
83 p->ptr = p->end = NULL;
84 }
85 else {
86 p->ptr = GETSTRINGVALUE((stringobject *)p->str) + size;
87 p->end = GETSTRINGVALUE((stringobject *)p->str) + newsize;
88 *p->ptr++ = c;
89 }
90}
91
92static void
93w_string(s, n, p)
94 char *s;
95 int n;
96 WFILE *p;
97{
98 if (p->fp != NULL) {
99 fwrite(s, 1, n, p->fp);
100 }
101 else {
102 while (--n >= 0) {
103 w_byte(*s, p);
104 s++;
105 }
106 }
107}
108
109static void
110w_short(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000111 int 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( x & 0xff, p);
115 w_byte((x>> 8) & 0xff, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000116}
117
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000118static void
119w_long(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000120 long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000121 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000122{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000123 w_byte((int)( x & 0xff), p);
124 w_byte((int)((x>> 8) & 0xff), p);
125 w_byte((int)((x>>16) & 0xff), p);
126 w_byte((int)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000127}
128
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000129static void
130w_object(v, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000131 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000132 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000133{
Guido van Rossum3a205f71995-02-17 15:10:07 +0000134 int i, n;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000135
136 if (v == NULL)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000137 w_byte(TYPE_NULL, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000138 else if (v == None)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000139 w_byte(TYPE_NONE, p);
Guido van Rossume449af71996-10-11 16:25:41 +0000140 else if (v == Py_Ellipsis)
141 w_byte(TYPE_ELLIPSIS, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000142 else if (is_intobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000143 w_byte(TYPE_INT, p);
144 w_long(getintvalue(v), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000145 }
146 else if (is_longobject(v)) {
147 longobject *ob = (longobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000148 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000149 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000150 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000151 if (n < 0)
152 n = -n;
153 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000154 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000155 }
156 else if (is_floatobject(v)) {
157 extern void float_buf_repr PROTO((char *, floatobject *));
158 char buf[256]; /* Plenty to format any double */
159 float_buf_repr(buf, (floatobject *)v);
160 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000161 w_byte(TYPE_FLOAT, p);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000162 w_byte(n, p);
163 w_string(buf, n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000164 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000165#ifndef WITHOUT_COMPLEX
166 else if (is_complexobject(v)) {
167 extern void float_buf_repr PROTO((char *, floatobject *));
168 char buf[256]; /* Plenty to format any double */
169 floatobject *temp;
170 w_byte(TYPE_COMPLEX, p);
171 temp = (floatobject*)newfloatobject(PyComplex_RealAsDouble(v));
172 float_buf_repr(buf, temp);
173 DECREF(temp);
174 n = strlen(buf);
175 w_byte(n, p);
176 w_string(buf, n, p);
177 temp = (floatobject*)newfloatobject(PyComplex_ImagAsDouble(v));
178 float_buf_repr(buf, temp);
179 DECREF(temp);
180 n = strlen(buf);
181 w_byte(n, p);
182 w_string(buf, n, p);
183 }
184#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000185 else if (is_stringobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000186 w_byte(TYPE_STRING, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000187 n = getstringsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000188 w_long((long)n, p);
189 w_string(getstringvalue(v), n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000190 }
191 else if (is_tupleobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000192 w_byte(TYPE_TUPLE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000193 n = gettuplesize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000194 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000195 for (i = 0; i < n; i++) {
Guido van Rossum8d617a61995-03-09 12:12:11 +0000196 w_object(GETTUPLEITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000197 }
198 }
199 else if (is_listobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000200 w_byte(TYPE_LIST, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000201 n = getlistsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000202 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000203 for (i = 0; i < n; i++) {
Guido van Rossum3a205f71995-02-17 15:10:07 +0000204 w_object(getlistitem(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000205 }
206 }
Guido van Rossum64b45521991-06-07 13:58:22 +0000207 else if (is_dictobject(v)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000208 int pos;
209 object *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000210 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000211 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000212 pos = 0;
213 while (mappinggetnext(v, &pos, &key, &value)) {
214 w_object(key, p);
215 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000216 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000217 w_object((object *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000218 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000219 else if (is_codeobject(v)) {
220 codeobject *co = (codeobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000221 w_byte(TYPE_CODE, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000222 w_short(co->co_argcount, p);
223 w_short(co->co_nlocals, p);
224 w_short(co->co_flags, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000225 w_object((object *)co->co_code, p);
226 w_object(co->co_consts, p);
227 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000228 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000229 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000230 w_object(co->co_name, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000231 }
232 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000233 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000234 p->error = 1;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000235 }
236}
237
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000238void
239wr_long(x, fp)
240 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000241 FILE *fp;
242{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000243 WFILE wf;
244 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000245 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000246 w_long(x, &wf);
247}
248
249void
250wr_object(x, fp)
251 object *x;
252 FILE *fp;
253{
254 WFILE wf;
255 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000256 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000257 w_object(x, &wf);
258}
259
260typedef WFILE RFILE; /* Same struct with different invariants */
261
Guido van Rossum8d617a61995-03-09 12:12:11 +0000262#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
263
264#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000265
266static int
267r_string(s, n, p)
268 char *s;
269 int n;
270 RFILE *p;
271{
272 if (p->fp != NULL)
273 return fread(s, 1, n, p->fp);
274 if (p->end - p->ptr < n)
275 n = p->end - p->ptr;
276 memcpy(s, p->ptr, n);
277 p->ptr += n;
278 return n;
279}
280
281static int
282r_short(p)
283 RFILE *p;
284{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000285 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000286 x = r_byte(p);
287 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000288 /* XXX If your short is > 16 bits, add sign-extension here!!! */
289 return x;
290}
291
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000292static long
293r_long(p)
294 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000295{
296 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000297 register FILE *fp = p->fp;
298 if (fp) {
299 x = getc(fp);
300 x |= (long)getc(fp) << 8;
301 x |= (long)getc(fp) << 16;
302 x |= (long)getc(fp) << 24;
303 }
304 else {
305 x = rs_byte(p);
306 x |= (long)rs_byte(p) << 8;
307 x |= (long)rs_byte(p) << 16;
308 x |= (long)rs_byte(p) << 24;
309 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000310 /* XXX If your long is > 32 bits, add sign-extension here!!! */
311 return x;
312}
313
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000314static object *
315r_object(p)
316 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000317{
Jack Jansen9513f2c1995-10-27 13:21:28 +0000318 object *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000319 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000320 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000321
322 switch (type) {
323
324 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000325 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000326 return NULL;
327
328 case TYPE_NULL:
329 return NULL;
330
331 case TYPE_NONE:
332 INCREF(None);
333 return None;
334
Guido van Rossume449af71996-10-11 16:25:41 +0000335 case TYPE_ELLIPSIS:
336 INCREF(Py_Ellipsis);
337 return Py_Ellipsis;
Guido van Rossum8861b741996-07-30 16:49:37 +0000338
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000339 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000340 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000341
342 case TYPE_LONG:
343 {
344 int size;
345 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000346 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000347 size = n<0 ? -n : n;
348 ob = alloclongobject(size);
349 if (ob == NULL)
350 return NULL;
351 ob->ob_size = n;
352 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000353 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000354 return (object *)ob;
355 }
356
357 case TYPE_FLOAT:
358 {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000359 extern double atof PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000360 char buf[256];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000361 n = r_byte(p);
362 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000363 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000364 "EOF read where object expected");
365 return NULL;
366 }
367 buf[n] = '\0';
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000368 return newfloatobject(atof(buf));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000369 }
370
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000371#ifndef WITHOUT_COMPLEX
372 case TYPE_COMPLEX:
373 {
374 extern double atof PROTO((const char *));
375 char buf[256];
Guido van Rossum530956d1996-07-21 02:27:43 +0000376 Py_complex c;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000377 n = r_byte(p);
378 if (r_string(buf, (int)n, p) != n) {
379 err_setstr(EOFError,
380 "EOF read where object expected");
381 return NULL;
382 }
383 buf[n] = '\0';
384 c.real = atof(buf);
385 n = r_byte(p);
386 if (r_string(buf, (int)n, p) != n) {
387 err_setstr(EOFError,
388 "EOF read where object expected");
389 return NULL;
390 }
391 buf[n] = '\0';
392 c.imag = atof(buf);
393 return newcomplexobject(c);
394 }
395#endif
396
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000397 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000398 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000399 v = newsizedstringobject((char *)NULL, n);
400 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000401 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000402 DECREF(v);
403 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000404 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000405 "EOF read where object expected");
406 }
407 }
408 return v;
409
410 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000411 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000412 v = newtupleobject((int)n);
413 if (v == NULL)
414 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000415 for (i = 0; i < n; i++) {
416 v2 = r_object(p);
417 if ( v2 == NULL ) {
418 DECREF(v);
419 v = NULL;
420 break;
421 }
422 SETTUPLEITEM(v, (int)i, v2);
423 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000424 return v;
425
426 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000427 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000428 v = newlistobject((int)n);
429 if (v == NULL)
430 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000431 for (i = 0; i < n; i++) {
432 v2 = r_object(p);
433 if ( v2 == NULL ) {
434 DECREF(v);
435 v = NULL;
436 break;
437 }
438 setlistitem(v, (int)i, v2);
439 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000440 return v;
441
Guido van Rossum64b45521991-06-07 13:58:22 +0000442 case TYPE_DICT:
443 v = newdictobject();
444 if (v == NULL)
445 return NULL;
446 for (;;) {
447 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000448 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000449 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000450 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000451 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000452 if (val != NULL)
453 dict2insert(v, key, val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000454 DECREF(key);
455 XDECREF(val);
456 }
457 return v;
458
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000459 case TYPE_CODE:
460 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000461 int argcount = r_short(p);
462 int nlocals = r_short(p);
463 int flags = r_short(p);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000464 object *code = NULL;
465 object *consts = NULL;
466 object *names = NULL;
467 object *varnames = NULL;
468 object *filename = NULL;
469 object *name = NULL;
470
471 code = r_object(p);
472 if (code) consts = r_object(p);
473 if (consts) names = r_object(p);
474 if (names) varnames = r_object(p);
475 if (varnames) filename = r_object(p);
476 if (filename) name = r_object(p);
477
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000478 if (!err_occurred()) {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000479 v = (object *) newcodeobject(
480 argcount, nlocals, flags,
481 code, consts, names, varnames,
482 filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000483 }
484 else
485 v = NULL;
486 XDECREF(code);
487 XDECREF(consts);
488 XDECREF(names);
Guido van Rossum0a8626e1996-05-28 22:28:12 +0000489 XDECREF(varnames);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000490 XDECREF(filename);
Guido van Rossuma4403101994-10-05 12:24:16 +0000491 XDECREF(name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000492
493 }
494 return v;
495
496 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000497 /* Bogus data got written, which isn't ideal.
498 This will let you keep working and recover. */
499 INCREF(None);
500 return None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000501
502 }
503}
504
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000505long
506rd_long(fp)
507 FILE *fp;
508{
509 RFILE rf;
510 rf.fp = fp;
511 return r_long(&rf);
512}
513
514object *
515rd_object(fp)
516 FILE *fp;
517{
518 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000519 if (err_occurred()) {
Guido van Rossum05870111995-08-28 02:56:20 +0000520 fatal("XXX rd_object called with exception set"); /* tmp */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000521 fprintf(stderr, "XXX rd_object called with exception set\n");
522 return NULL;
523 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000524 rf.fp = fp;
525 return r_object(&rf);
526}
527
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000528object *
529rds_object(str, len)
530 char *str;
531 int len;
532{
533 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000534 if (err_occurred()) {
535 fprintf(stderr, "XXX rds_object called with exception set\n");
536 return NULL;
537 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000538 rf.fp = NULL;
539 rf.str = NULL;
540 rf.ptr = str;
541 rf.end = str + len;
542 return r_object(&rf);
543}
544
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000545object *
546PyMarshal_WriteObjectToString(x) /* wrs_object() */
547 object *x;
548{
549 WFILE wf;
550 wf.fp = NULL;
551 wf.str = newsizedstringobject((char *)NULL, 50);
552 if (wf.str == NULL)
553 return NULL;
554 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
555 wf.end = wf.ptr + getstringsize(wf.str);
556 wf.error = 0;
557 w_object(x, &wf);
558 if (wf.str != NULL)
559 resizestring(&wf.str,
560 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
561 if (wf.error) {
562 XDECREF(wf.str);
563 err_setstr(ValueError, "unmarshallable object");
564 return NULL;
565 }
566 return wf.str;
567}
568
Guido van Rossum64b45521991-06-07 13:58:22 +0000569/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000570
571static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000572marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000573 object *self;
574 object *args;
575{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000576 WFILE wf;
577 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000578 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000579 if (!getargs(args, "(OO)", &x, &f))
580 return NULL;
581 if (!is_fileobject(f)) {
582 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000583 return NULL;
584 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000585 wf.fp = getfilefile(f);
586 wf.str = NULL;
587 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000588 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000589 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000590 if (wf.error) {
591 err_setstr(ValueError, "unmarshallable object");
592 return NULL;
593 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000594 INCREF(None);
595 return None;
596}
597
598static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000599marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000600 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000601 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000602{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000603 RFILE rf;
604 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000605 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000606 if (!getargs(args, "O", &f))
607 return NULL;
608 if (!is_fileobject(f)) {
609 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000610 return NULL;
611 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000612 rf.fp = getfilefile(f);
613 rf.str = NULL;
614 rf.ptr = rf.end = NULL;
615 err_clear();
616 v = r_object(&rf);
617 if (err_occurred()) {
618 XDECREF(v);
619 v = NULL;
620 }
621 return v;
622}
623
624static object *
625marshal_dumps(self, args)
626 object *self;
627 object *args;
628{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000629 object *x;
630 if (!getargs(args, "O", &x))
631 return NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000632 return PyMarshal_WriteObjectToString(x);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000633}
634
635static object *
636marshal_loads(self, args)
637 object *self;
638 object *args;
639{
640 RFILE rf;
641 object *v;
642 char *s;
643 int n;
644 if (!getargs(args, "s#", &s, &n))
645 return NULL;
646 rf.fp = NULL;
647 rf.str = args;
648 rf.ptr = s;
649 rf.end = s + n;
650 err_clear();
651 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000652 if (err_occurred()) {
653 XDECREF(v);
654 v = NULL;
655 }
656 return v;
657}
658
659static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000660 {"dump", marshal_dump},
661 {"load", marshal_load},
662 {"dumps", marshal_dumps},
663 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000664 {NULL, NULL} /* sentinel */
665};
666
667void
668initmarshal()
669{
670 (void) initmodule("marshal", marshal_methods);
671}