blob: 2052495fb150eeaf3e1c213b14e6aa0ce4c66374 [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'
Guido van Rossumb0c168c1996-12-05 23:15:02 +000049#define TYPE_INT64 'I'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000050#define TYPE_FLOAT 'f'
Guido van Rossum8a5c5d21996-01-12 01:09:56 +000051#define TYPE_COMPLEX 'x'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000052#define TYPE_LONG 'l'
53#define TYPE_STRING 's'
54#define TYPE_TUPLE '('
55#define TYPE_LIST '['
56#define TYPE_DICT '{'
Guido van Rossum681d79a1995-07-18 14:51:37 +000057#define TYPE_CODE 'c'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000058#define TYPE_UNKNOWN '?'
59
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000060typedef struct {
61 FILE *fp;
Guido van Rossumf2150601996-06-26 20:41:23 +000062 int error;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000063 /* If fp == NULL, the following are valid: */
64 object *str;
65 char *ptr;
66 char *end;
67} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000068
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000069#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
70 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
71 else w_more(c, p)
72
73static void
74w_more(c, p)
75 char c;
76 WFILE *p;
77{
78 int size, newsize;
79 if (p->str == NULL)
80 return; /* An error already occurred */
81 size = getstringsize(p->str);
82 newsize = size + 1024;
83 if (resizestring(&p->str, newsize) != 0) {
84 p->ptr = p->end = NULL;
85 }
86 else {
87 p->ptr = GETSTRINGVALUE((stringobject *)p->str) + size;
88 p->end = GETSTRINGVALUE((stringobject *)p->str) + newsize;
89 *p->ptr++ = c;
90 }
91}
92
93static void
94w_string(s, n, p)
95 char *s;
96 int n;
97 WFILE *p;
98{
99 if (p->fp != NULL) {
100 fwrite(s, 1, n, p->fp);
101 }
102 else {
103 while (--n >= 0) {
104 w_byte(*s, p);
105 s++;
106 }
107 }
108}
109
110static void
111w_short(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000112 int x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000113 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000114{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000115 w_byte( x & 0xff, p);
116 w_byte((x>> 8) & 0xff, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000117}
118
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000119static void
120w_long(x, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000121 long x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000122 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000123{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000124 w_byte((int)( x & 0xff), p);
125 w_byte((int)((x>> 8) & 0xff), p);
126 w_byte((int)((x>>16) & 0xff), p);
127 w_byte((int)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000128}
129
Guido van Rossumc1547d91996-12-10 15:39:04 +0000130#if SIZEOF_LONG > 4
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000131static void
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000132w_long64(x, p)
133 long x;
134 WFILE *p;
135{
136 w_long(x, p);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000137 w_long(x>>32, p);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000138}
Guido van Rossumc1547d91996-12-10 15:39:04 +0000139#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000140
141static void
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000142w_object(v, p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000143 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000144 WFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000145{
Guido van Rossum3a205f71995-02-17 15:10:07 +0000146 int i, n;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000147
148 if (v == NULL)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000149 w_byte(TYPE_NULL, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000150 else if (v == None)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000151 w_byte(TYPE_NONE, p);
Guido van Rossume449af71996-10-11 16:25:41 +0000152 else if (v == Py_Ellipsis)
153 w_byte(TYPE_ELLIPSIS, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000154 else if (is_intobject(v)) {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000155 long x = GETINTVALUE((intobject *)v);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000156#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000157 long y = x>>31;
158 if (y && y != -1) {
159 w_byte(TYPE_INT64, p);
160 w_long64(x, p);
161 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000162 else
163#endif
164 {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000165 w_byte(TYPE_INT, p);
166 w_long(x, p);
167 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000168 }
169 else if (is_longobject(v)) {
170 longobject *ob = (longobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000171 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000172 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000173 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000174 if (n < 0)
175 n = -n;
176 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000177 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000178 }
179 else if (is_floatobject(v)) {
180 extern void float_buf_repr PROTO((char *, floatobject *));
181 char buf[256]; /* Plenty to format any double */
182 float_buf_repr(buf, (floatobject *)v);
183 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000184 w_byte(TYPE_FLOAT, p);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000185 w_byte(n, p);
186 w_string(buf, n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000187 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000188#ifndef WITHOUT_COMPLEX
189 else if (is_complexobject(v)) {
190 extern void float_buf_repr PROTO((char *, floatobject *));
191 char buf[256]; /* Plenty to format any double */
192 floatobject *temp;
193 w_byte(TYPE_COMPLEX, p);
194 temp = (floatobject*)newfloatobject(PyComplex_RealAsDouble(v));
195 float_buf_repr(buf, temp);
196 DECREF(temp);
197 n = strlen(buf);
198 w_byte(n, p);
199 w_string(buf, n, p);
200 temp = (floatobject*)newfloatobject(PyComplex_ImagAsDouble(v));
201 float_buf_repr(buf, temp);
202 DECREF(temp);
203 n = strlen(buf);
204 w_byte(n, p);
205 w_string(buf, n, p);
206 }
207#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000208 else if (is_stringobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000209 w_byte(TYPE_STRING, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000210 n = getstringsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000211 w_long((long)n, p);
212 w_string(getstringvalue(v), n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000213 }
214 else if (is_tupleobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000215 w_byte(TYPE_TUPLE, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000216 n = gettuplesize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000217 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000218 for (i = 0; i < n; i++) {
Guido van Rossum8d617a61995-03-09 12:12:11 +0000219 w_object(GETTUPLEITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000220 }
221 }
222 else if (is_listobject(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000223 w_byte(TYPE_LIST, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000224 n = getlistsize(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000225 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000226 for (i = 0; i < n; i++) {
Guido van Rossum3a205f71995-02-17 15:10:07 +0000227 w_object(getlistitem(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000228 }
229 }
Guido van Rossum64b45521991-06-07 13:58:22 +0000230 else if (is_dictobject(v)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000231 int pos;
232 object *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000233 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000234 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000235 pos = 0;
236 while (mappinggetnext(v, &pos, &key, &value)) {
237 w_object(key, p);
238 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000239 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000240 w_object((object *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000241 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000242 else if (is_codeobject(v)) {
243 codeobject *co = (codeobject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000244 w_byte(TYPE_CODE, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000245 w_short(co->co_argcount, p);
246 w_short(co->co_nlocals, p);
247 w_short(co->co_flags, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000248 w_object((object *)co->co_code, p);
249 w_object(co->co_consts, p);
250 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000251 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000252 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000253 w_object(co->co_name, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000254 }
255 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000256 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000257 p->error = 1;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000258 }
259}
260
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000261void
262wr_long(x, fp)
263 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000264 FILE *fp;
265{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000266 WFILE wf;
267 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000268 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000269 w_long(x, &wf);
270}
271
272void
273wr_object(x, fp)
274 object *x;
275 FILE *fp;
276{
277 WFILE wf;
278 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000279 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000280 w_object(x, &wf);
281}
282
283typedef WFILE RFILE; /* Same struct with different invariants */
284
Guido van Rossum8d617a61995-03-09 12:12:11 +0000285#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
286
287#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000288
289static int
290r_string(s, n, p)
291 char *s;
292 int n;
293 RFILE *p;
294{
295 if (p->fp != NULL)
296 return fread(s, 1, n, p->fp);
297 if (p->end - p->ptr < n)
298 n = p->end - p->ptr;
299 memcpy(s, p->ptr, n);
300 p->ptr += n;
301 return n;
302}
303
304static int
305r_short(p)
306 RFILE *p;
307{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000308 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000309 x = r_byte(p);
310 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000311 /* XXX If your short is > 16 bits, add sign-extension here!!! */
312 return x;
313}
314
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000315static long
316r_long(p)
317 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000318{
319 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000320 register FILE *fp = p->fp;
321 if (fp) {
322 x = getc(fp);
323 x |= (long)getc(fp) << 8;
324 x |= (long)getc(fp) << 16;
325 x |= (long)getc(fp) << 24;
326 }
327 else {
328 x = rs_byte(p);
329 x |= (long)rs_byte(p) << 8;
330 x |= (long)rs_byte(p) << 16;
331 x |= (long)rs_byte(p) << 24;
332 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000333#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000334 /* Sign extension for 64-bit machines */
335 x <<= (8*sizeof(long) - 32);
336 x >>= (8*sizeof(long) - 32);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000337#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000338 return x;
339}
340
341static long
342r_long64(p)
343 RFILE *p;
344{
345 register long x;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000346 x = r_long(p);
347#if SIZEOF_LONG > 4
348 x = (x & 0xFFFFFFFF) | (r_long(p) << 32);
349#else
350 if (r_long(p) != 0) {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000351 object *f = sysget("stderr");
352 err_clear();
Guido van Rossumc1547d91996-12-10 15:39:04 +0000353 if (f != NULL)
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000354 writestring(
Guido van Rossumc1547d91996-12-10 15:39:04 +0000355 "Warning: un-marshal 64-bit int in 32-bit mode\n",
356 f);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000357 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000358#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000359 return x;
360}
361
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000362static object *
363r_object(p)
364 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000365{
Jack Jansen9513f2c1995-10-27 13:21:28 +0000366 object *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000367 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000368 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000369
370 switch (type) {
371
372 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000373 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000374 return NULL;
375
376 case TYPE_NULL:
377 return NULL;
378
379 case TYPE_NONE:
380 INCREF(None);
381 return None;
382
Guido van Rossume449af71996-10-11 16:25:41 +0000383 case TYPE_ELLIPSIS:
384 INCREF(Py_Ellipsis);
385 return Py_Ellipsis;
Guido van Rossum8861b741996-07-30 16:49:37 +0000386
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000387 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000388 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000389
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000390 case TYPE_INT64:
391 return newintobject(r_long64(p));
392
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000393 case TYPE_LONG:
394 {
395 int size;
396 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000397 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000398 size = n<0 ? -n : n;
399 ob = alloclongobject(size);
400 if (ob == NULL)
401 return NULL;
402 ob->ob_size = n;
403 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000404 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000405 return (object *)ob;
406 }
407
408 case TYPE_FLOAT:
409 {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000410 extern double atof PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000411 char buf[256];
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000412 n = r_byte(p);
413 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000414 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000415 "EOF read where object expected");
416 return NULL;
417 }
418 buf[n] = '\0';
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000419 return newfloatobject(atof(buf));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000420 }
421
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000422#ifndef WITHOUT_COMPLEX
423 case TYPE_COMPLEX:
424 {
425 extern double atof PROTO((const char *));
426 char buf[256];
Guido van Rossum530956d1996-07-21 02:27:43 +0000427 Py_complex c;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000428 n = r_byte(p);
429 if (r_string(buf, (int)n, p) != n) {
430 err_setstr(EOFError,
431 "EOF read where object expected");
432 return NULL;
433 }
434 buf[n] = '\0';
435 c.real = atof(buf);
436 n = r_byte(p);
437 if (r_string(buf, (int)n, p) != n) {
438 err_setstr(EOFError,
439 "EOF read where object expected");
440 return NULL;
441 }
442 buf[n] = '\0';
443 c.imag = atof(buf);
444 return newcomplexobject(c);
445 }
446#endif
447
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000448 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000449 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000450 v = newsizedstringobject((char *)NULL, n);
451 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000452 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000453 DECREF(v);
454 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000455 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000456 "EOF read where object expected");
457 }
458 }
459 return v;
460
461 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000462 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000463 v = newtupleobject((int)n);
464 if (v == NULL)
465 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000466 for (i = 0; i < n; i++) {
467 v2 = r_object(p);
468 if ( v2 == NULL ) {
469 DECREF(v);
470 v = NULL;
471 break;
472 }
473 SETTUPLEITEM(v, (int)i, v2);
474 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000475 return v;
476
477 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000478 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000479 v = newlistobject((int)n);
480 if (v == NULL)
481 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000482 for (i = 0; i < n; i++) {
483 v2 = r_object(p);
484 if ( v2 == NULL ) {
485 DECREF(v);
486 v = NULL;
487 break;
488 }
489 setlistitem(v, (int)i, v2);
490 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000491 return v;
492
Guido van Rossum64b45521991-06-07 13:58:22 +0000493 case TYPE_DICT:
494 v = newdictobject();
495 if (v == NULL)
496 return NULL;
497 for (;;) {
498 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000499 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000500 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000501 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000502 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000503 if (val != NULL)
504 dict2insert(v, key, val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000505 DECREF(key);
506 XDECREF(val);
507 }
508 return v;
509
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000510 case TYPE_CODE:
511 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000512 int argcount = r_short(p);
513 int nlocals = r_short(p);
514 int flags = r_short(p);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000515 object *code = NULL;
516 object *consts = NULL;
517 object *names = NULL;
518 object *varnames = NULL;
519 object *filename = NULL;
520 object *name = NULL;
521
522 code = r_object(p);
523 if (code) consts = r_object(p);
524 if (consts) names = r_object(p);
525 if (names) varnames = r_object(p);
526 if (varnames) filename = r_object(p);
527 if (filename) name = r_object(p);
528
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000529 if (!err_occurred()) {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000530 v = (object *) newcodeobject(
531 argcount, nlocals, flags,
532 code, consts, names, varnames,
533 filename, name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000534 }
535 else
536 v = NULL;
537 XDECREF(code);
538 XDECREF(consts);
539 XDECREF(names);
Guido van Rossum0a8626e1996-05-28 22:28:12 +0000540 XDECREF(varnames);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000541 XDECREF(filename);
Guido van Rossuma4403101994-10-05 12:24:16 +0000542 XDECREF(name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000543
544 }
545 return v;
546
547 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000548 /* Bogus data got written, which isn't ideal.
549 This will let you keep working and recover. */
550 INCREF(None);
551 return None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000552
553 }
554}
555
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000556long
557rd_long(fp)
558 FILE *fp;
559{
560 RFILE rf;
561 rf.fp = fp;
562 return r_long(&rf);
563}
564
565object *
566rd_object(fp)
567 FILE *fp;
568{
569 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000570 if (err_occurred()) {
Guido van Rossum05870111995-08-28 02:56:20 +0000571 fatal("XXX rd_object called with exception set"); /* tmp */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000572 fprintf(stderr, "XXX rd_object called with exception set\n");
573 return NULL;
574 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000575 rf.fp = fp;
576 return r_object(&rf);
577}
578
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000579object *
580rds_object(str, len)
581 char *str;
582 int len;
583{
584 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000585 if (err_occurred()) {
586 fprintf(stderr, "XXX rds_object called with exception set\n");
587 return NULL;
588 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000589 rf.fp = NULL;
590 rf.str = NULL;
591 rf.ptr = str;
592 rf.end = str + len;
593 return r_object(&rf);
594}
595
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000596object *
597PyMarshal_WriteObjectToString(x) /* wrs_object() */
598 object *x;
599{
600 WFILE wf;
601 wf.fp = NULL;
602 wf.str = newsizedstringobject((char *)NULL, 50);
603 if (wf.str == NULL)
604 return NULL;
605 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
606 wf.end = wf.ptr + getstringsize(wf.str);
607 wf.error = 0;
608 w_object(x, &wf);
609 if (wf.str != NULL)
610 resizestring(&wf.str,
611 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
612 if (wf.error) {
613 XDECREF(wf.str);
614 err_setstr(ValueError, "unmarshallable object");
615 return NULL;
616 }
617 return wf.str;
618}
619
Guido van Rossum64b45521991-06-07 13:58:22 +0000620/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000621
622static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000623marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000624 object *self;
625 object *args;
626{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000627 WFILE wf;
628 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000629 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000630 if (!getargs(args, "(OO)", &x, &f))
631 return NULL;
632 if (!is_fileobject(f)) {
633 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000634 return NULL;
635 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000636 wf.fp = getfilefile(f);
637 wf.str = NULL;
638 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000639 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000640 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000641 if (wf.error) {
642 err_setstr(ValueError, "unmarshallable object");
643 return NULL;
644 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000645 INCREF(None);
646 return None;
647}
648
649static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000650marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000651 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000652 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000653{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000654 RFILE rf;
655 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000656 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000657 if (!getargs(args, "O", &f))
658 return NULL;
659 if (!is_fileobject(f)) {
660 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000661 return NULL;
662 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000663 rf.fp = getfilefile(f);
664 rf.str = NULL;
665 rf.ptr = rf.end = NULL;
666 err_clear();
667 v = r_object(&rf);
668 if (err_occurred()) {
669 XDECREF(v);
670 v = NULL;
671 }
672 return v;
673}
674
675static object *
676marshal_dumps(self, args)
677 object *self;
678 object *args;
679{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000680 object *x;
681 if (!getargs(args, "O", &x))
682 return NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000683 return PyMarshal_WriteObjectToString(x);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000684}
685
686static object *
687marshal_loads(self, args)
688 object *self;
689 object *args;
690{
691 RFILE rf;
692 object *v;
693 char *s;
694 int n;
695 if (!getargs(args, "s#", &s, &n))
696 return NULL;
697 rf.fp = NULL;
698 rf.str = args;
699 rf.ptr = s;
700 rf.end = s + n;
701 err_clear();
702 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000703 if (err_occurred()) {
704 XDECREF(v);
705 v = NULL;
706 }
707 return v;
708}
709
710static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000711 {"dump", marshal_dump},
712 {"load", marshal_load},
713 {"dumps", marshal_dumps},
714 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000715 {NULL, NULL} /* sentinel */
716};
717
718void
719initmarshal()
720{
721 (void) initmodule("marshal", marshal_methods);
722}