blob: f4634f013b5daccff332c86175b7cbefdfc0b918 [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);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000247 w_short(co->co_stacksize, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000248 w_short(co->co_flags, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000249 w_object((object *)co->co_code, p);
250 w_object(co->co_consts, p);
251 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000252 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000253 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000254 w_object(co->co_name, p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000255 w_short(co->co_firstlineno, p);
256 w_object(co->co_lnotab, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000257 }
258 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000259 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000260 p->error = 1;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000261 }
262}
263
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000264void
265wr_long(x, fp)
266 long x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000267 FILE *fp;
268{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000269 WFILE wf;
270 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000271 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000272 w_long(x, &wf);
273}
274
275void
276wr_object(x, fp)
277 object *x;
278 FILE *fp;
279{
280 WFILE wf;
281 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000282 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000283 w_object(x, &wf);
284}
285
286typedef WFILE RFILE; /* Same struct with different invariants */
287
Guido van Rossum8d617a61995-03-09 12:12:11 +0000288#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
289
290#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000291
292static int
293r_string(s, n, p)
294 char *s;
295 int n;
296 RFILE *p;
297{
298 if (p->fp != NULL)
299 return fread(s, 1, n, p->fp);
300 if (p->end - p->ptr < n)
301 n = p->end - p->ptr;
302 memcpy(s, p->ptr, n);
303 p->ptr += n;
304 return n;
305}
306
307static int
308r_short(p)
309 RFILE *p;
310{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000311 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000312 x = r_byte(p);
313 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000314 /* XXX If your short is > 16 bits, add sign-extension here!!! */
315 return x;
316}
317
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000318static long
319r_long(p)
320 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000321{
322 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000323 register FILE *fp = p->fp;
324 if (fp) {
325 x = getc(fp);
326 x |= (long)getc(fp) << 8;
327 x |= (long)getc(fp) << 16;
328 x |= (long)getc(fp) << 24;
329 }
330 else {
331 x = rs_byte(p);
332 x |= (long)rs_byte(p) << 8;
333 x |= (long)rs_byte(p) << 16;
334 x |= (long)rs_byte(p) << 24;
335 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000336#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000337 /* Sign extension for 64-bit machines */
338 x <<= (8*sizeof(long) - 32);
339 x >>= (8*sizeof(long) - 32);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000340#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000341 return x;
342}
343
344static long
345r_long64(p)
346 RFILE *p;
347{
348 register long x;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000349 x = r_long(p);
350#if SIZEOF_LONG > 4
351 x = (x & 0xFFFFFFFF) | (r_long(p) << 32);
352#else
353 if (r_long(p) != 0) {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000354 object *f = sysget("stderr");
355 err_clear();
Guido van Rossumc1547d91996-12-10 15:39:04 +0000356 if (f != NULL)
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000357 writestring(
Guido van Rossumc1547d91996-12-10 15:39:04 +0000358 "Warning: un-marshal 64-bit int in 32-bit mode\n",
359 f);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000360 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000361#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000362 return x;
363}
364
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000365static object *
366r_object(p)
367 RFILE *p;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000368{
Jack Jansen9513f2c1995-10-27 13:21:28 +0000369 object *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000370 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000371 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000372
373 switch (type) {
374
375 case EOF:
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000376 err_setstr(EOFError, "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000377 return NULL;
378
379 case TYPE_NULL:
380 return NULL;
381
382 case TYPE_NONE:
383 INCREF(None);
384 return None;
385
Guido van Rossume449af71996-10-11 16:25:41 +0000386 case TYPE_ELLIPSIS:
387 INCREF(Py_Ellipsis);
388 return Py_Ellipsis;
Guido van Rossum8861b741996-07-30 16:49:37 +0000389
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000390 case TYPE_INT:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000391 return newintobject(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000392
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000393 case TYPE_INT64:
394 return newintobject(r_long64(p));
395
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000396 case TYPE_LONG:
397 {
398 int size;
399 longobject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000400 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000401 size = n<0 ? -n : n;
402 ob = alloclongobject(size);
403 if (ob == NULL)
404 return NULL;
405 ob->ob_size = n;
406 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000407 ob->ob_digit[i] = r_short(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000408 return (object *)ob;
409 }
410
411 case TYPE_FLOAT:
412 {
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000413 extern double atof PROTO((const char *));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000414 char buf[256];
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000415 double dx;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000416 n = r_byte(p);
417 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000418 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000419 "EOF read where object expected");
420 return NULL;
421 }
422 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000423 PyFPE_START_PROTECT("atof", return 0)
424 dx = atof(buf);
425 PyFPE_END_PROTECT
426 return newfloatobject(dx);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000427 }
428
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000429#ifndef WITHOUT_COMPLEX
430 case TYPE_COMPLEX:
431 {
432 extern double atof PROTO((const char *));
433 char buf[256];
Guido van Rossum530956d1996-07-21 02:27:43 +0000434 Py_complex c;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000435 n = r_byte(p);
436 if (r_string(buf, (int)n, p) != n) {
437 err_setstr(EOFError,
438 "EOF read where object expected");
439 return NULL;
440 }
441 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000442 PyFPE_START_PROTECT("atof", return 0)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000443 c.real = atof(buf);
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000444 PyFPE_END_PROTECT
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000445 n = r_byte(p);
446 if (r_string(buf, (int)n, p) != n) {
447 err_setstr(EOFError,
448 "EOF read where object expected");
449 return NULL;
450 }
451 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000452 PyFPE_START_PROTECT("atof", return 0)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000453 c.imag = atof(buf);
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000454 PyFPE_END_PROTECT
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000455 return newcomplexobject(c);
456 }
457#endif
458
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000459 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000460 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000461 v = newsizedstringobject((char *)NULL, n);
462 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000463 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000464 DECREF(v);
465 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000466 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000467 "EOF read where object expected");
468 }
469 }
470 return v;
471
472 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000473 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000474 v = newtupleobject((int)n);
475 if (v == NULL)
476 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000477 for (i = 0; i < n; i++) {
478 v2 = r_object(p);
479 if ( v2 == NULL ) {
480 DECREF(v);
481 v = NULL;
482 break;
483 }
484 SETTUPLEITEM(v, (int)i, v2);
485 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000486 return v;
487
488 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000489 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000490 v = newlistobject((int)n);
491 if (v == NULL)
492 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000493 for (i = 0; i < n; i++) {
494 v2 = r_object(p);
495 if ( v2 == NULL ) {
496 DECREF(v);
497 v = NULL;
498 break;
499 }
500 setlistitem(v, (int)i, v2);
501 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000502 return v;
503
Guido van Rossum64b45521991-06-07 13:58:22 +0000504 case TYPE_DICT:
505 v = newdictobject();
506 if (v == NULL)
507 return NULL;
508 for (;;) {
509 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000510 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000511 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000512 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000513 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000514 if (val != NULL)
515 dict2insert(v, key, val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000516 DECREF(key);
517 XDECREF(val);
518 }
519 return v;
520
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000521 case TYPE_CODE:
522 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000523 int argcount = r_short(p);
524 int nlocals = r_short(p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000525 int stacksize = r_short(p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000526 int flags = r_short(p);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000527 object *code = NULL;
528 object *consts = NULL;
529 object *names = NULL;
530 object *varnames = NULL;
531 object *filename = NULL;
532 object *name = NULL;
Guido van Rossum0f4bbd21997-02-14 21:12:56 +0000533 int firstlineno = 0;
Guido van Rossumd031c891997-01-24 03:44:17 +0000534 object *lnotab = NULL;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000535
536 code = r_object(p);
537 if (code) consts = r_object(p);
538 if (consts) names = r_object(p);
539 if (names) varnames = r_object(p);
540 if (varnames) filename = r_object(p);
541 if (filename) name = r_object(p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000542 if (name) {
543 firstlineno = r_short(p);
544 lnotab = r_object(p);
545 }
Jack Jansen9513f2c1995-10-27 13:21:28 +0000546
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000547 if (!err_occurred()) {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000548 v = (object *) newcodeobject(
Guido van Rossum98a9b311997-01-17 21:07:08 +0000549 argcount, nlocals, stacksize, flags,
Guido van Rossum681d79a1995-07-18 14:51:37 +0000550 code, consts, names, varnames,
Guido van Rossumd031c891997-01-24 03:44:17 +0000551 filename, name, firstlineno, lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000552 }
553 else
554 v = NULL;
555 XDECREF(code);
556 XDECREF(consts);
557 XDECREF(names);
Guido van Rossum0a8626e1996-05-28 22:28:12 +0000558 XDECREF(varnames);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000559 XDECREF(filename);
Guido van Rossuma4403101994-10-05 12:24:16 +0000560 XDECREF(name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000561
562 }
563 return v;
564
565 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000566 /* Bogus data got written, which isn't ideal.
567 This will let you keep working and recover. */
568 INCREF(None);
569 return None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000570
571 }
572}
573
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000574long
575rd_long(fp)
576 FILE *fp;
577{
578 RFILE rf;
579 rf.fp = fp;
580 return r_long(&rf);
581}
582
583object *
584rd_object(fp)
585 FILE *fp;
586{
587 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000588 if (err_occurred()) {
Guido van Rossum05870111995-08-28 02:56:20 +0000589 fatal("XXX rd_object called with exception set"); /* tmp */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000590 fprintf(stderr, "XXX rd_object called with exception set\n");
591 return NULL;
592 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000593 rf.fp = fp;
594 return r_object(&rf);
595}
596
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000597object *
598rds_object(str, len)
599 char *str;
600 int len;
601{
602 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000603 if (err_occurred()) {
604 fprintf(stderr, "XXX rds_object called with exception set\n");
605 return NULL;
606 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000607 rf.fp = NULL;
608 rf.str = NULL;
609 rf.ptr = str;
610 rf.end = str + len;
611 return r_object(&rf);
612}
613
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000614object *
615PyMarshal_WriteObjectToString(x) /* wrs_object() */
616 object *x;
617{
618 WFILE wf;
619 wf.fp = NULL;
620 wf.str = newsizedstringobject((char *)NULL, 50);
621 if (wf.str == NULL)
622 return NULL;
623 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
624 wf.end = wf.ptr + getstringsize(wf.str);
625 wf.error = 0;
626 w_object(x, &wf);
627 if (wf.str != NULL)
628 resizestring(&wf.str,
629 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
630 if (wf.error) {
631 XDECREF(wf.str);
632 err_setstr(ValueError, "unmarshallable object");
633 return NULL;
634 }
635 return wf.str;
636}
637
Guido van Rossum64b45521991-06-07 13:58:22 +0000638/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000639
640static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000641marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000642 object *self;
643 object *args;
644{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000645 WFILE wf;
646 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000647 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000648 if (!getargs(args, "(OO)", &x, &f))
649 return NULL;
650 if (!is_fileobject(f)) {
651 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000652 return NULL;
653 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000654 wf.fp = getfilefile(f);
655 wf.str = NULL;
656 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000657 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000658 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000659 if (wf.error) {
660 err_setstr(ValueError, "unmarshallable object");
661 return NULL;
662 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000663 INCREF(None);
664 return None;
665}
666
667static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000668marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000669 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000670 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000671{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000672 RFILE rf;
673 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000674 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000675 if (!getargs(args, "O", &f))
676 return NULL;
677 if (!is_fileobject(f)) {
678 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000679 return NULL;
680 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000681 rf.fp = getfilefile(f);
682 rf.str = NULL;
683 rf.ptr = rf.end = NULL;
684 err_clear();
685 v = r_object(&rf);
686 if (err_occurred()) {
687 XDECREF(v);
688 v = NULL;
689 }
690 return v;
691}
692
693static object *
694marshal_dumps(self, args)
695 object *self;
696 object *args;
697{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000698 object *x;
699 if (!getargs(args, "O", &x))
700 return NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000701 return PyMarshal_WriteObjectToString(x);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000702}
703
704static object *
705marshal_loads(self, args)
706 object *self;
707 object *args;
708{
709 RFILE rf;
710 object *v;
711 char *s;
712 int n;
713 if (!getargs(args, "s#", &s, &n))
714 return NULL;
715 rf.fp = NULL;
716 rf.str = args;
717 rf.ptr = s;
718 rf.end = s + n;
719 err_clear();
720 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000721 if (err_occurred()) {
722 XDECREF(v);
723 v = NULL;
724 }
725 return v;
726}
727
728static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000729 {"dump", marshal_dump},
730 {"load", marshal_load},
731 {"dumps", marshal_dumps},
732 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000733 {NULL, NULL} /* sentinel */
734};
735
736void
737initmarshal()
738{
739 (void) initmodule("marshal", marshal_methods);
740}