blob: 0ad493a3db687766f2c2b6928d009ad1e9ee3813 [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 Rossum0b0db8e1993-01-21 16:07:51 +0000415 n = r_byte(p);
416 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000417 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000418 "EOF read where object expected");
419 return NULL;
420 }
421 buf[n] = '\0';
Guido van Rossum1d5735e1994-08-30 08:27:36 +0000422 return newfloatobject(atof(buf));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000423 }
424
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000425#ifndef WITHOUT_COMPLEX
426 case TYPE_COMPLEX:
427 {
428 extern double atof PROTO((const char *));
429 char buf[256];
Guido van Rossum530956d1996-07-21 02:27:43 +0000430 Py_complex c;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000431 n = r_byte(p);
432 if (r_string(buf, (int)n, p) != n) {
433 err_setstr(EOFError,
434 "EOF read where object expected");
435 return NULL;
436 }
437 buf[n] = '\0';
438 c.real = atof(buf);
439 n = r_byte(p);
440 if (r_string(buf, (int)n, p) != n) {
441 err_setstr(EOFError,
442 "EOF read where object expected");
443 return NULL;
444 }
445 buf[n] = '\0';
446 c.imag = atof(buf);
447 return newcomplexobject(c);
448 }
449#endif
450
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000451 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000452 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000453 v = newsizedstringobject((char *)NULL, n);
454 if (v != NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000455 if (r_string(getstringvalue(v), (int)n, p) != n) {
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000456 DECREF(v);
457 v = NULL;
Guido van Rossum87e7ea71991-12-10 14:00:03 +0000458 err_setstr(EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000459 "EOF read where object expected");
460 }
461 }
462 return v;
463
464 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000465 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000466 v = newtupleobject((int)n);
467 if (v == NULL)
468 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000469 for (i = 0; i < n; i++) {
470 v2 = r_object(p);
471 if ( v2 == NULL ) {
472 DECREF(v);
473 v = NULL;
474 break;
475 }
476 SETTUPLEITEM(v, (int)i, v2);
477 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000478 return v;
479
480 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000481 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000482 v = newlistobject((int)n);
483 if (v == NULL)
484 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000485 for (i = 0; i < n; i++) {
486 v2 = r_object(p);
487 if ( v2 == NULL ) {
488 DECREF(v);
489 v = NULL;
490 break;
491 }
492 setlistitem(v, (int)i, v2);
493 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000494 return v;
495
Guido van Rossum64b45521991-06-07 13:58:22 +0000496 case TYPE_DICT:
497 v = newdictobject();
498 if (v == NULL)
499 return NULL;
500 for (;;) {
501 object *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000502 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000503 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000504 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000505 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000506 if (val != NULL)
507 dict2insert(v, key, val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000508 DECREF(key);
509 XDECREF(val);
510 }
511 return v;
512
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000513 case TYPE_CODE:
514 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000515 int argcount = r_short(p);
516 int nlocals = r_short(p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000517 int stacksize = r_short(p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000518 int flags = r_short(p);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000519 object *code = NULL;
520 object *consts = NULL;
521 object *names = NULL;
522 object *varnames = NULL;
523 object *filename = NULL;
524 object *name = NULL;
Guido van Rossum0f4bbd21997-02-14 21:12:56 +0000525 int firstlineno = 0;
Guido van Rossumd031c891997-01-24 03:44:17 +0000526 object *lnotab = NULL;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000527
528 code = r_object(p);
529 if (code) consts = r_object(p);
530 if (consts) names = r_object(p);
531 if (names) varnames = r_object(p);
532 if (varnames) filename = r_object(p);
533 if (filename) name = r_object(p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000534 if (name) {
535 firstlineno = r_short(p);
536 lnotab = r_object(p);
537 }
Jack Jansen9513f2c1995-10-27 13:21:28 +0000538
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000539 if (!err_occurred()) {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000540 v = (object *) newcodeobject(
Guido van Rossum98a9b311997-01-17 21:07:08 +0000541 argcount, nlocals, stacksize, flags,
Guido van Rossum681d79a1995-07-18 14:51:37 +0000542 code, consts, names, varnames,
Guido van Rossumd031c891997-01-24 03:44:17 +0000543 filename, name, firstlineno, lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000544 }
545 else
546 v = NULL;
547 XDECREF(code);
548 XDECREF(consts);
549 XDECREF(names);
Guido van Rossum0a8626e1996-05-28 22:28:12 +0000550 XDECREF(varnames);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000551 XDECREF(filename);
Guido van Rossuma4403101994-10-05 12:24:16 +0000552 XDECREF(name);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000553
554 }
555 return v;
556
557 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000558 /* Bogus data got written, which isn't ideal.
559 This will let you keep working and recover. */
560 INCREF(None);
561 return None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000562
563 }
564}
565
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000566long
567rd_long(fp)
568 FILE *fp;
569{
570 RFILE rf;
571 rf.fp = fp;
572 return r_long(&rf);
573}
574
575object *
576rd_object(fp)
577 FILE *fp;
578{
579 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000580 if (err_occurred()) {
Guido van Rossum05870111995-08-28 02:56:20 +0000581 fatal("XXX rd_object called with exception set"); /* tmp */
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000582 fprintf(stderr, "XXX rd_object called with exception set\n");
583 return NULL;
584 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000585 rf.fp = fp;
586 return r_object(&rf);
587}
588
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000589object *
590rds_object(str, len)
591 char *str;
592 int len;
593{
594 RFILE rf;
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000595 if (err_occurred()) {
596 fprintf(stderr, "XXX rds_object called with exception set\n");
597 return NULL;
598 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000599 rf.fp = NULL;
600 rf.str = NULL;
601 rf.ptr = str;
602 rf.end = str + len;
603 return r_object(&rf);
604}
605
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000606object *
607PyMarshal_WriteObjectToString(x) /* wrs_object() */
608 object *x;
609{
610 WFILE wf;
611 wf.fp = NULL;
612 wf.str = newsizedstringobject((char *)NULL, 50);
613 if (wf.str == NULL)
614 return NULL;
615 wf.ptr = GETSTRINGVALUE((stringobject *)wf.str);
616 wf.end = wf.ptr + getstringsize(wf.str);
617 wf.error = 0;
618 w_object(x, &wf);
619 if (wf.str != NULL)
620 resizestring(&wf.str,
621 (int) (wf.ptr - GETSTRINGVALUE((stringobject *)wf.str)));
622 if (wf.error) {
623 XDECREF(wf.str);
624 err_setstr(ValueError, "unmarshallable object");
625 return NULL;
626 }
627 return wf.str;
628}
629
Guido van Rossum64b45521991-06-07 13:58:22 +0000630/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000631
632static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000633marshal_dump(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000634 object *self;
635 object *args;
636{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000637 WFILE wf;
638 object *x;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000639 object *f;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000640 if (!getargs(args, "(OO)", &x, &f))
641 return NULL;
642 if (!is_fileobject(f)) {
643 err_setstr(TypeError, "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000644 return NULL;
645 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000646 wf.fp = getfilefile(f);
647 wf.str = NULL;
648 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000649 wf.error = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000650 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000651 if (wf.error) {
652 err_setstr(ValueError, "unmarshallable object");
653 return NULL;
654 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000655 INCREF(None);
656 return None;
657}
658
659static object *
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000660marshal_load(self, args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000661 object *self;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000662 object *args;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000663{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000664 RFILE rf;
665 object *f;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000666 object *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000667 if (!getargs(args, "O", &f))
668 return NULL;
669 if (!is_fileobject(f)) {
670 err_setstr(TypeError, "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000671 return NULL;
672 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000673 rf.fp = getfilefile(f);
674 rf.str = NULL;
675 rf.ptr = rf.end = NULL;
676 err_clear();
677 v = r_object(&rf);
678 if (err_occurred()) {
679 XDECREF(v);
680 v = NULL;
681 }
682 return v;
683}
684
685static object *
686marshal_dumps(self, args)
687 object *self;
688 object *args;
689{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000690 object *x;
691 if (!getargs(args, "O", &x))
692 return NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000693 return PyMarshal_WriteObjectToString(x);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000694}
695
696static object *
697marshal_loads(self, args)
698 object *self;
699 object *args;
700{
701 RFILE rf;
702 object *v;
703 char *s;
704 int n;
705 if (!getargs(args, "s#", &s, &n))
706 return NULL;
707 rf.fp = NULL;
708 rf.str = args;
709 rf.ptr = s;
710 rf.end = s + n;
711 err_clear();
712 v = r_object(&rf);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000713 if (err_occurred()) {
714 XDECREF(v);
715 v = NULL;
716 }
717 return v;
718}
719
720static struct methodlist marshal_methods[] = {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000721 {"dump", marshal_dump},
722 {"load", marshal_load},
723 {"dumps", marshal_dumps},
724 {"loads", marshal_loads},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000725 {NULL, NULL} /* sentinel */
726};
727
728void
729initmarshal()
730{
731 (void) initmodule("marshal", marshal_methods);
732}