blob: 74c547417a2837325c9bf5b1631ac2d4affe11b3 [file] [log] [blame]
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumdce2e3d1991-06-04 19:42:30 +00009******************************************************************/
10
11/* Write Python objects to files and read them back.
12 This is intended for writing and reading compiled Python code only;
13 a true persistent storage facility would be much harder, since
14 it would have to take circular links and sharing into account. */
15
Guido van Rossum79f25d91997-04-29 20:08:16 +000016#include "Python.h"
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000017#include "longintrepr.h"
18#include "compile.h"
19#include "marshal.h"
20
Fred Drake6da0b912000-06-28 18:47:56 +000021/* High water mark to determine when the marshalled object is dangerously deep
22 * and risks coring the interpreter. When the object stack gets this deep,
23 * raise an exception instead of continuing.
24 */
25#define MAX_MARSHAL_STACK_DEPTH 5000
26
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000027#define TYPE_NULL '0'
28#define TYPE_NONE 'N'
Guido van Rossume449af71996-10-11 16:25:41 +000029#define TYPE_ELLIPSIS '.'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000030#define TYPE_INT 'i'
Guido van Rossumb0c168c1996-12-05 23:15:02 +000031#define TYPE_INT64 'I'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000032#define TYPE_FLOAT 'f'
Guido van Rossum8a5c5d21996-01-12 01:09:56 +000033#define TYPE_COMPLEX 'x'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000034#define TYPE_LONG 'l'
35#define TYPE_STRING 's'
36#define TYPE_TUPLE '('
37#define TYPE_LIST '['
38#define TYPE_DICT '{'
Guido van Rossum681d79a1995-07-18 14:51:37 +000039#define TYPE_CODE 'c'
Guido van Rossumc279b532000-03-10 23:03:02 +000040#define TYPE_UNICODE 'u'
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000041#define TYPE_UNKNOWN '?'
42
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000043typedef struct {
44 FILE *fp;
Guido van Rossumf2150601996-06-26 20:41:23 +000045 int error;
Fred Drake6da0b912000-06-28 18:47:56 +000046 int depth;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000047 /* If fp == NULL, the following are valid: */
Guido van Rossum79f25d91997-04-29 20:08:16 +000048 PyObject *str;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000049 char *ptr;
50 char *end;
51} WFILE;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000052
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000053#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
54 else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
55 else w_more(c, p)
56
57static void
Fredrik Lundh11534382000-07-23 18:24:06 +000058w_more(int c, WFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000059{
60 int size, newsize;
61 if (p->str == NULL)
62 return; /* An error already occurred */
Guido van Rossum79f25d91997-04-29 20:08:16 +000063 size = PyString_Size(p->str);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000064 newsize = size + 1024;
Guido van Rossum79f25d91997-04-29 20:08:16 +000065 if (_PyString_Resize(&p->str, newsize) != 0) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000066 p->ptr = p->end = NULL;
67 }
68 else {
Guido van Rossum79f25d91997-04-29 20:08:16 +000069 p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
70 p->end =
71 PyString_AS_STRING((PyStringObject *)p->str) + newsize;
Fredrik Lundh11534382000-07-23 18:24:06 +000072 *p->ptr++ = (char) c;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000073 }
74}
75
76static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000077w_string(char *s, int n, WFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000078{
79 if (p->fp != NULL) {
80 fwrite(s, 1, n, p->fp);
81 }
82 else {
83 while (--n >= 0) {
84 w_byte(*s, p);
85 s++;
86 }
87 }
88}
89
90static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000091w_short(int x, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000092{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000093 w_byte( x & 0xff, p);
94 w_byte((x>> 8) & 0xff, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000095}
96
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000097static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +000098w_long(long x, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +000099{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000100 w_byte((int)( x & 0xff), p);
101 w_byte((int)((x>> 8) & 0xff), p);
102 w_byte((int)((x>>16) & 0xff), p);
103 w_byte((int)((x>>24) & 0xff), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000104}
105
Guido van Rossumc1547d91996-12-10 15:39:04 +0000106#if SIZEOF_LONG > 4
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000107static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000108w_long64(long x, WFILE *p)
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000109{
110 w_long(x, p);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000111 w_long(x>>32, p);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000112}
Guido van Rossumc1547d91996-12-10 15:39:04 +0000113#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000114
115static void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000116w_object(PyObject *v, WFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000117{
Guido van Rossum3a205f71995-02-17 15:10:07 +0000118 int i, n;
Guido van Rossumd076c731998-10-07 19:42:25 +0000119 PyBufferProcs *pb;
Fred Drake6da0b912000-06-28 18:47:56 +0000120
121 p->depth++;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000122
Fred Drake6da0b912000-06-28 18:47:56 +0000123 if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
124 p->error = 2;
125 }
126 else if (v == NULL) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000127 w_byte(TYPE_NULL, p);
Guido van Rossum730806d1998-04-10 22:27:42 +0000128 }
129 else if (v == Py_None) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000130 w_byte(TYPE_NONE, p);
Guido van Rossum730806d1998-04-10 22:27:42 +0000131 }
132 else if (v == Py_Ellipsis) {
133 w_byte(TYPE_ELLIPSIS, p);
134 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000135 else if (PyInt_Check(v)) {
136 long x = PyInt_AS_LONG((PyIntObject *)v);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000137#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000138 long y = x>>31;
139 if (y && y != -1) {
140 w_byte(TYPE_INT64, p);
141 w_long64(x, p);
142 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000143 else
144#endif
145 {
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000146 w_byte(TYPE_INT, p);
147 w_long(x, p);
148 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000149 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000150 else if (PyLong_Check(v)) {
151 PyLongObject *ob = (PyLongObject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000152 w_byte(TYPE_LONG, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000153 n = ob->ob_size;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000154 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000155 if (n < 0)
156 n = -n;
157 for (i = 0; i < n; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000158 w_short(ob->ob_digit[i], p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000159 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000160 else if (PyFloat_Check(v)) {
Tim Petersdbd9ba62000-07-09 03:09:57 +0000161 extern void PyFloat_AsString(char *, PyFloatObject *);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000162 char buf[256]; /* Plenty to format any double */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000163 PyFloat_AsString(buf, (PyFloatObject *)v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000164 n = strlen(buf);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000165 w_byte(TYPE_FLOAT, p);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000166 w_byte(n, p);
167 w_string(buf, n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000168 }
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000169#ifndef WITHOUT_COMPLEX
Guido van Rossum79f25d91997-04-29 20:08:16 +0000170 else if (PyComplex_Check(v)) {
Tim Petersdbd9ba62000-07-09 03:09:57 +0000171 extern void PyFloat_AsString(char *, PyFloatObject *);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000172 char buf[256]; /* Plenty to format any double */
Guido van Rossum79f25d91997-04-29 20:08:16 +0000173 PyFloatObject *temp;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000174 w_byte(TYPE_COMPLEX, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000175 temp = (PyFloatObject*)PyFloat_FromDouble(
176 PyComplex_RealAsDouble(v));
177 PyFloat_AsString(buf, temp);
178 Py_DECREF(temp);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000179 n = strlen(buf);
180 w_byte(n, p);
181 w_string(buf, n, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000182 temp = (PyFloatObject*)PyFloat_FromDouble(
183 PyComplex_ImagAsDouble(v));
184 PyFloat_AsString(buf, temp);
185 Py_DECREF(temp);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000186 n = strlen(buf);
187 w_byte(n, p);
188 w_string(buf, n, p);
189 }
190#endif
Guido van Rossum79f25d91997-04-29 20:08:16 +0000191 else if (PyString_Check(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000192 w_byte(TYPE_STRING, p);
Guido van Rossumc279b532000-03-10 23:03:02 +0000193 n = PyString_GET_SIZE(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000194 w_long((long)n, p);
Guido van Rossumc279b532000-03-10 23:03:02 +0000195 w_string(PyString_AS_STRING(v), n, p);
196 }
197 else if (PyUnicode_Check(v)) {
198 PyObject *utf8;
199 utf8 = PyUnicode_AsUTF8String(v);
200 if (utf8 == NULL) {
Guido van Rossum98626cd2000-06-28 23:24:19 +0000201 p->depth--;
202 p->error = 1;
203 return;
Guido van Rossumc279b532000-03-10 23:03:02 +0000204 }
205 w_byte(TYPE_UNICODE, p);
206 n = PyString_GET_SIZE(utf8);
207 w_long((long)n, p);
208 w_string(PyString_AS_STRING(utf8), n, p);
209 Py_DECREF(utf8);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000210 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000211 else if (PyTuple_Check(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000212 w_byte(TYPE_TUPLE, p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000213 n = PyTuple_Size(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000214 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000215 for (i = 0; i < n; i++) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000216 w_object(PyTuple_GET_ITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000217 }
218 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000219 else if (PyList_Check(v)) {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000220 w_byte(TYPE_LIST, p);
Guido van Rossumc279b532000-03-10 23:03:02 +0000221 n = PyList_GET_SIZE(v);
Guido van Rossum3a205f71995-02-17 15:10:07 +0000222 w_long((long)n, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000223 for (i = 0; i < n; i++) {
Guido van Rossumc279b532000-03-10 23:03:02 +0000224 w_object(PyList_GET_ITEM(v, i), p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000225 }
226 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000227 else if (PyDict_Check(v)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000228 int pos;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000229 PyObject *key, *value;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000230 w_byte(TYPE_DICT, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000231 /* This one is NULL object terminated! */
Guido van Rossum25831651993-05-19 14:50:45 +0000232 pos = 0;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000233 while (PyDict_Next(v, &pos, &key, &value)) {
Guido van Rossum25831651993-05-19 14:50:45 +0000234 w_object(key, p);
235 w_object(value, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000236 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000237 w_object((PyObject *)NULL, p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000238 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000239 else if (PyCode_Check(v)) {
240 PyCodeObject *co = (PyCodeObject *)v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000241 w_byte(TYPE_CODE, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000242 w_short(co->co_argcount, p);
243 w_short(co->co_nlocals, p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000244 w_short(co->co_stacksize, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000245 w_short(co->co_flags, p);
Guido van Rossumd076c731998-10-07 19:42:25 +0000246 w_object(co->co_code, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000247 w_object(co->co_consts, p);
248 w_object(co->co_names, p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000249 w_object(co->co_varnames, p);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000250 w_object(co->co_filename, p);
Guido van Rossum9bfef441993-03-29 10:43:31 +0000251 w_object(co->co_name, p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000252 w_short(co->co_firstlineno, p);
253 w_object(co->co_lnotab, p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000254 }
Guido van Rossumd076c731998-10-07 19:42:25 +0000255 else if ((pb = v->ob_type->tp_as_buffer) != NULL &&
256 pb->bf_getsegcount != NULL &&
257 pb->bf_getreadbuffer != NULL &&
258 (*pb->bf_getsegcount)(v, NULL) == 1)
259 {
260 /* Write unknown buffer-style objects as a string */
261 char *s;
262 w_byte(TYPE_STRING, p);
263 n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
264 w_long((long)n, p);
265 w_string(s, n, p);
266 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000267 else {
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000268 w_byte(TYPE_UNKNOWN, p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000269 p->error = 1;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000270 }
Guido van Rossum98626cd2000-06-28 23:24:19 +0000271
272 p->depth--;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000273}
274
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000275void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000276PyMarshal_WriteLongToFile(long x, FILE *fp)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000277{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000278 WFILE wf;
279 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000280 wf.error = 0;
Fred Drake6da0b912000-06-28 18:47:56 +0000281 wf.depth = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000282 w_long(x, &wf);
283}
284
285void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000286PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000287{
288 WFILE wf;
289 wf.fp = fp;
Guido van Rossumf2150601996-06-26 20:41:23 +0000290 wf.error = 0;
Guido van Rossum98626cd2000-06-28 23:24:19 +0000291 wf.depth = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000292 w_object(x, &wf);
293}
294
295typedef WFILE RFILE; /* Same struct with different invariants */
296
Guido van Rossum8d617a61995-03-09 12:12:11 +0000297#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
298
299#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000300
301static int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000302r_string(char *s, int n, RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000303{
304 if (p->fp != NULL)
305 return fread(s, 1, n, p->fp);
306 if (p->end - p->ptr < n)
307 n = p->end - p->ptr;
308 memcpy(s, p->ptr, n);
309 p->ptr += n;
310 return n;
311}
312
313static int
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000314r_short(RFILE *p)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000315{
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000316 register short x;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000317 x = r_byte(p);
318 x |= r_byte(p) << 8;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000319 /* XXX If your short is > 16 bits, add sign-extension here!!! */
320 return x;
321}
322
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000323static long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000324r_long(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000325{
326 register long x;
Guido van Rossum8d617a61995-03-09 12:12:11 +0000327 register FILE *fp = p->fp;
328 if (fp) {
329 x = getc(fp);
330 x |= (long)getc(fp) << 8;
331 x |= (long)getc(fp) << 16;
332 x |= (long)getc(fp) << 24;
333 }
334 else {
335 x = rs_byte(p);
336 x |= (long)rs_byte(p) << 8;
337 x |= (long)rs_byte(p) << 16;
338 x |= (long)rs_byte(p) << 24;
339 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000340#if SIZEOF_LONG > 4
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000341 /* Sign extension for 64-bit machines */
342 x <<= (8*sizeof(long) - 32);
343 x >>= (8*sizeof(long) - 32);
Guido van Rossumc1547d91996-12-10 15:39:04 +0000344#endif
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000345 return x;
346}
347
348static long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000349r_long64(RFILE *p)
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000350{
351 register long x;
Guido van Rossumc1547d91996-12-10 15:39:04 +0000352 x = r_long(p);
353#if SIZEOF_LONG > 4
354 x = (x & 0xFFFFFFFF) | (r_long(p) << 32);
355#else
356 if (r_long(p) != 0) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000357 PyObject *f = PySys_GetObject("stderr");
Guido van Rossumc1547d91996-12-10 15:39:04 +0000358 if (f != NULL)
Guido van Rossum7e8d26d1997-05-22 22:35:47 +0000359 (void) PyFile_WriteString(
Guido van Rossumc1547d91996-12-10 15:39:04 +0000360 "Warning: un-marshal 64-bit int in 32-bit mode\n",
361 f);
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000362 }
Guido van Rossumc1547d91996-12-10 15:39:04 +0000363#endif
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000364 return x;
365}
366
Guido van Rossum79f25d91997-04-29 20:08:16 +0000367static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000368r_object(RFILE *p)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000369{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000370 PyObject *v, *v2;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000371 long i, n;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000372 int type = r_byte(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000373
374 switch (type) {
375
376 case EOF:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000377 PyErr_SetString(PyExc_EOFError,
378 "EOF read where object expected");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000379 return NULL;
380
381 case TYPE_NULL:
382 return NULL;
383
384 case TYPE_NONE:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000385 Py_INCREF(Py_None);
386 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000387
Guido van Rossume449af71996-10-11 16:25:41 +0000388 case TYPE_ELLIPSIS:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000389 Py_INCREF(Py_Ellipsis);
Guido van Rossume449af71996-10-11 16:25:41 +0000390 return Py_Ellipsis;
Guido van Rossum8861b741996-07-30 16:49:37 +0000391
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000392 case TYPE_INT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000393 return PyInt_FromLong(r_long(p));
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000394
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000395 case TYPE_INT64:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000396 return PyInt_FromLong(r_long64(p));
Guido van Rossumb0c168c1996-12-05 23:15:02 +0000397
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000398 case TYPE_LONG:
399 {
400 int size;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000401 PyLongObject *ob;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000402 n = r_long(p);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000403 size = n<0 ? -n : n;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000404 ob = _PyLong_New(size);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000405 if (ob == NULL)
406 return NULL;
407 ob->ob_size = n;
408 for (i = 0; i < size; i++)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000409 ob->ob_digit[i] = r_short(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000410 return (PyObject *)ob;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000411 }
412
413 case TYPE_FLOAT:
414 {
Tim Petersdbd9ba62000-07-09 03:09:57 +0000415 extern double atof(const char *);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000416 char buf[256];
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000417 double dx;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000418 n = r_byte(p);
419 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000420 PyErr_SetString(PyExc_EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000421 "EOF read where object expected");
422 return NULL;
423 }
424 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000425 PyFPE_START_PROTECT("atof", return 0)
426 dx = atof(buf);
Guido van Rossum45b83911997-03-14 04:32:50 +0000427 PyFPE_END_PROTECT(dx)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000428 return PyFloat_FromDouble(dx);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000429 }
430
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000431#ifndef WITHOUT_COMPLEX
432 case TYPE_COMPLEX:
433 {
Tim Petersdbd9ba62000-07-09 03:09:57 +0000434 extern double atof(const char *);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000435 char buf[256];
Guido van Rossum530956d1996-07-21 02:27:43 +0000436 Py_complex c;
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000437 n = r_byte(p);
438 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000439 PyErr_SetString(PyExc_EOFError,
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000440 "EOF read where object expected");
441 return NULL;
442 }
443 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000444 PyFPE_START_PROTECT("atof", return 0)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000445 c.real = atof(buf);
Guido van Rossum45b83911997-03-14 04:32:50 +0000446 PyFPE_END_PROTECT(c)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000447 n = r_byte(p);
448 if (r_string(buf, (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000449 PyErr_SetString(PyExc_EOFError,
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000450 "EOF read where object expected");
451 return NULL;
452 }
453 buf[n] = '\0';
Guido van Rossum0ae748d1997-02-14 22:58:07 +0000454 PyFPE_START_PROTECT("atof", return 0)
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000455 c.imag = atof(buf);
Guido van Rossum45b83911997-03-14 04:32:50 +0000456 PyFPE_END_PROTECT(c)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000457 return PyComplex_FromCComplex(c);
Guido van Rossum8a5c5d21996-01-12 01:09:56 +0000458 }
459#endif
460
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000461 case TYPE_STRING:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000462 n = r_long(p);
Guido van Rossuma45cb451998-06-08 20:27:29 +0000463 if (n < 0) {
464 PyErr_SetString(PyExc_ValueError, "bad marshal data");
465 return NULL;
466 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000467 v = PyString_FromStringAndSize((char *)NULL, n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000468 if (v != NULL) {
Guido van Rossumc279b532000-03-10 23:03:02 +0000469 if (r_string(PyString_AS_STRING(v), (int)n, p) != n) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000470 Py_DECREF(v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000471 v = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000472 PyErr_SetString(PyExc_EOFError,
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000473 "EOF read where object expected");
474 }
475 }
476 return v;
477
Guido van Rossumc279b532000-03-10 23:03:02 +0000478 case TYPE_UNICODE:
479 {
480 char *buffer;
481
482 n = r_long(p);
483 if (n < 0) {
484 PyErr_SetString(PyExc_ValueError, "bad marshal data");
485 return NULL;
486 }
Guido van Rossumb18618d2000-05-03 23:44:39 +0000487 buffer = PyMem_NEW(char, n);
Guido van Rossumc279b532000-03-10 23:03:02 +0000488 if (buffer == NULL)
Guido van Rossumb18618d2000-05-03 23:44:39 +0000489 return PyErr_NoMemory();
Guido van Rossumc279b532000-03-10 23:03:02 +0000490 if (r_string(buffer, (int)n, p) != n) {
Guido van Rossumb18618d2000-05-03 23:44:39 +0000491 PyMem_DEL(buffer);
Guido van Rossumc279b532000-03-10 23:03:02 +0000492 PyErr_SetString(PyExc_EOFError,
493 "EOF read where object expected");
494 return NULL;
495 }
496 v = PyUnicode_DecodeUTF8(buffer, n, NULL);
Guido van Rossumb18618d2000-05-03 23:44:39 +0000497 PyMem_DEL(buffer);
Guido van Rossumc279b532000-03-10 23:03:02 +0000498 return v;
499 }
500
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000501 case TYPE_TUPLE:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000502 n = r_long(p);
Guido van Rossuma45cb451998-06-08 20:27:29 +0000503 if (n < 0) {
504 PyErr_SetString(PyExc_ValueError, "bad marshal data");
505 return NULL;
506 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000507 v = PyTuple_New((int)n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000508 if (v == NULL)
509 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000510 for (i = 0; i < n; i++) {
511 v2 = r_object(p);
512 if ( v2 == NULL ) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000513 Py_DECREF(v);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000514 v = NULL;
515 break;
516 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000517 PyTuple_SET_ITEM(v, (int)i, v2);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000518 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000519 return v;
520
521 case TYPE_LIST:
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000522 n = r_long(p);
Guido van Rossuma45cb451998-06-08 20:27:29 +0000523 if (n < 0) {
524 PyErr_SetString(PyExc_ValueError, "bad marshal data");
525 return NULL;
526 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000527 v = PyList_New((int)n);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000528 if (v == NULL)
529 return v;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000530 for (i = 0; i < n; i++) {
531 v2 = r_object(p);
532 if ( v2 == NULL ) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000533 Py_DECREF(v);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000534 v = NULL;
535 break;
536 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000537 PyList_SetItem(v, (int)i, v2);
Jack Jansen9513f2c1995-10-27 13:21:28 +0000538 }
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000539 return v;
540
Guido van Rossum64b45521991-06-07 13:58:22 +0000541 case TYPE_DICT:
Guido van Rossum79f25d91997-04-29 20:08:16 +0000542 v = PyDict_New();
Guido van Rossum64b45521991-06-07 13:58:22 +0000543 if (v == NULL)
544 return NULL;
545 for (;;) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000546 PyObject *key, *val;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000547 key = r_object(p);
Guido van Rossum64b45521991-06-07 13:58:22 +0000548 if (key == NULL)
Guido van Rossumf2150601996-06-26 20:41:23 +0000549 break; /* XXX Assume TYPE_NULL, not an error */
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000550 val = r_object(p);
Guido van Rossumf2150601996-06-26 20:41:23 +0000551 if (val != NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000552 PyDict_SetItem(v, key, val);
553 Py_DECREF(key);
554 Py_XDECREF(val);
Guido van Rossum64b45521991-06-07 13:58:22 +0000555 }
556 return v;
557
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000558 case TYPE_CODE:
559 {
Guido van Rossum681d79a1995-07-18 14:51:37 +0000560 int argcount = r_short(p);
561 int nlocals = r_short(p);
Guido van Rossum98a9b311997-01-17 21:07:08 +0000562 int stacksize = r_short(p);
Guido van Rossum681d79a1995-07-18 14:51:37 +0000563 int flags = r_short(p);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000564 PyObject *code = NULL;
565 PyObject *consts = NULL;
566 PyObject *names = NULL;
567 PyObject *varnames = NULL;
568 PyObject *filename = NULL;
569 PyObject *name = NULL;
Guido van Rossum0f4bbd21997-02-14 21:12:56 +0000570 int firstlineno = 0;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000571 PyObject *lnotab = NULL;
Jack Jansen9513f2c1995-10-27 13:21:28 +0000572
573 code = r_object(p);
574 if (code) consts = r_object(p);
575 if (consts) names = r_object(p);
576 if (names) varnames = r_object(p);
577 if (varnames) filename = r_object(p);
578 if (filename) name = r_object(p);
Guido van Rossumd031c891997-01-24 03:44:17 +0000579 if (name) {
580 firstlineno = r_short(p);
581 lnotab = r_object(p);
582 }
Jack Jansen9513f2c1995-10-27 13:21:28 +0000583
Guido van Rossum79f25d91997-04-29 20:08:16 +0000584 if (!PyErr_Occurred()) {
585 v = (PyObject *) PyCode_New(
Guido van Rossum98a9b311997-01-17 21:07:08 +0000586 argcount, nlocals, stacksize, flags,
Guido van Rossum681d79a1995-07-18 14:51:37 +0000587 code, consts, names, varnames,
Guido van Rossumd031c891997-01-24 03:44:17 +0000588 filename, name, firstlineno, lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000589 }
590 else
591 v = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000592 Py_XDECREF(code);
593 Py_XDECREF(consts);
594 Py_XDECREF(names);
595 Py_XDECREF(varnames);
596 Py_XDECREF(filename);
597 Py_XDECREF(name);
Guido van Rossum6fc06e71997-07-26 23:30:18 +0000598 Py_XDECREF(lnotab);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000599
600 }
601 return v;
602
603 default:
Guido van Rossumf2150601996-06-26 20:41:23 +0000604 /* Bogus data got written, which isn't ideal.
605 This will let you keep working and recover. */
Guido van Rossuma45cb451998-06-08 20:27:29 +0000606 PyErr_SetString(PyExc_ValueError, "bad marshal data");
607 return NULL;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000608
609 }
610}
611
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000612long
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000613PyMarshal_ReadLongFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000614{
615 RFILE rf;
616 rf.fp = fp;
617 return r_long(&rf);
618}
619
Guido van Rossum79f25d91997-04-29 20:08:16 +0000620PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000621PyMarshal_ReadObjectFromFile(FILE *fp)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000622{
623 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000624 if (PyErr_Occurred()) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000625 fprintf(stderr, "XXX rd_object called with exception set\n");
626 return NULL;
627 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000628 rf.fp = fp;
629 return r_object(&rf);
630}
631
Guido van Rossum79f25d91997-04-29 20:08:16 +0000632PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000633PyMarshal_ReadObjectFromString(char *str, int len)
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000634{
635 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000636 if (PyErr_Occurred()) {
Guido van Rossum1ae940a1995-01-02 19:04:15 +0000637 fprintf(stderr, "XXX rds_object called with exception set\n");
638 return NULL;
639 }
Guido van Rossumf56e3db1993-04-01 20:59:32 +0000640 rf.fp = NULL;
641 rf.str = NULL;
642 rf.ptr = str;
643 rf.end = str + len;
644 return r_object(&rf);
645}
646
Guido van Rossum79f25d91997-04-29 20:08:16 +0000647PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000648PyMarshal_WriteObjectToString(PyObject *x) /* wrs_object() */
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000649{
650 WFILE wf;
651 wf.fp = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000652 wf.str = PyString_FromStringAndSize((char *)NULL, 50);
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000653 if (wf.str == NULL)
654 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000655 wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
656 wf.end = wf.ptr + PyString_Size(wf.str);
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000657 wf.error = 0;
Fred Drake6da0b912000-06-28 18:47:56 +0000658 wf.depth = 0;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000659 w_object(x, &wf);
660 if (wf.str != NULL)
Guido van Rossum79f25d91997-04-29 20:08:16 +0000661 _PyString_Resize(&wf.str,
662 (int) (wf.ptr -
663 PyString_AS_STRING((PyStringObject *)wf.str)));
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000664 if (wf.error) {
Guido van Rossum79f25d91997-04-29 20:08:16 +0000665 Py_XDECREF(wf.str);
Fred Drake6da0b912000-06-28 18:47:56 +0000666 PyErr_SetString(PyExc_ValueError,
667 (wf.error==1)?"unmarshallable object"
668 :"object too deeply nested to marshal");
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000669 return NULL;
670 }
671 return wf.str;
672}
673
Guido van Rossum64b45521991-06-07 13:58:22 +0000674/* And an interface for Python programs... */
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000675
Guido van Rossum79f25d91997-04-29 20:08:16 +0000676static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000677marshal_dump(PyObject *self, PyObject *args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000678{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000679 WFILE wf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000680 PyObject *x;
681 PyObject *f;
Guido van Rossum2efa3692000-03-31 00:37:41 +0000682 if (!PyArg_ParseTuple(args, "OO:dump", &x, &f))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000683 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000684 if (!PyFile_Check(f)) {
685 PyErr_SetString(PyExc_TypeError,
686 "marshal.dump() 2nd arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000687 return NULL;
688 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000689 wf.fp = PyFile_AsFile(f);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000690 wf.str = NULL;
691 wf.ptr = wf.end = NULL;
Guido van Rossumf2150601996-06-26 20:41:23 +0000692 wf.error = 0;
Fred Drake6da0b912000-06-28 18:47:56 +0000693 wf.depth = 0;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000694 w_object(x, &wf);
Guido van Rossumf2150601996-06-26 20:41:23 +0000695 if (wf.error) {
Fred Drake6da0b912000-06-28 18:47:56 +0000696 PyErr_SetString(PyExc_ValueError,
697 (wf.error==1)?"unmarshallable object"
698 :"object too deeply nested to marshal");
Guido van Rossumf2150601996-06-26 20:41:23 +0000699 return NULL;
700 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000701 Py_INCREF(Py_None);
702 return Py_None;
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000703}
704
Guido van Rossum79f25d91997-04-29 20:08:16 +0000705static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000706marshal_load(PyObject *self, PyObject *args)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000707{
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000708 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000709 PyObject *f;
710 PyObject *v;
Guido van Rossum2efa3692000-03-31 00:37:41 +0000711 if (!PyArg_ParseTuple(args, "O:load", &f))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000712 return NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000713 if (!PyFile_Check(f)) {
714 PyErr_SetString(PyExc_TypeError,
715 "marshal.load() arg must be file");
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000716 return NULL;
717 }
Guido van Rossum79f25d91997-04-29 20:08:16 +0000718 rf.fp = PyFile_AsFile(f);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000719 rf.str = NULL;
720 rf.ptr = rf.end = NULL;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000721 PyErr_Clear();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000722 v = r_object(&rf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000723 if (PyErr_Occurred()) {
724 Py_XDECREF(v);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000725 v = NULL;
726 }
727 return v;
728}
729
Guido van Rossum79f25d91997-04-29 20:08:16 +0000730static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000731marshal_dumps(PyObject *self, PyObject *args)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000732{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000733 PyObject *x;
Guido van Rossum2efa3692000-03-31 00:37:41 +0000734 if (!PyArg_ParseTuple(args, "O:dumps", &x))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000735 return NULL;
Guido van Rossum3f3bb3d1996-08-19 22:07:17 +0000736 return PyMarshal_WriteObjectToString(x);
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000737}
738
Guido van Rossum79f25d91997-04-29 20:08:16 +0000739static PyObject *
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000740marshal_loads(PyObject *self, PyObject *args)
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000741{
742 RFILE rf;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000743 PyObject *v;
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000744 char *s;
745 int n;
Guido van Rossum2efa3692000-03-31 00:37:41 +0000746 if (!PyArg_ParseTuple(args, "s#:loads", &s, &n))
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000747 return NULL;
748 rf.fp = NULL;
749 rf.str = args;
750 rf.ptr = s;
751 rf.end = s + n;
Guido van Rossum79f25d91997-04-29 20:08:16 +0000752 PyErr_Clear();
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000753 v = r_object(&rf);
Guido van Rossum79f25d91997-04-29 20:08:16 +0000754 if (PyErr_Occurred()) {
755 Py_XDECREF(v);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000756 v = NULL;
757 }
758 return v;
759}
760
Guido van Rossum79f25d91997-04-29 20:08:16 +0000761static PyMethodDef marshal_methods[] = {
Guido van Rossum2efa3692000-03-31 00:37:41 +0000762 {"dump", marshal_dump, 1},
763 {"load", marshal_load, 1},
764 {"dumps", marshal_dumps, 1},
765 {"loads", marshal_loads, 1},
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000766 {NULL, NULL} /* sentinel */
767};
768
769void
Thomas Woutersf70ef4f2000-07-22 18:47:25 +0000770PyMarshal_Init(void)
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000771{
Guido van Rossum79f25d91997-04-29 20:08:16 +0000772 (void) Py_InitModule("marshal", marshal_methods);
Guido van Rossumdce2e3d1991-06-04 19:42:30 +0000773}