~ubuntu-branches/ubuntu/feisty/decompyle/feisty

« back to all changes in this revision

Viewing changes to decompyle/marshal_22_for_20.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Burton
  • Date: 2005-03-24 07:59:47 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050324075947-gszdigwx7sdwzaz3
Tags: 2.3.2-2
Added notes in the package description and README.Debian explaining the
roles of the new decompyle and old decompyle2.2 packages.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
 
3
 
/* Write Python objects to files and read them back.
4
 
   This is intended for writing and reading compiled Python code only;
5
 
   a true persistent storage facility would be much harder, since
6
 
   it would have to take circular links and sharing into account. */
7
 
 
8
 
#include "Python.h"
9
 
#include "longintrepr.h"
10
 
#include "compile.h"
11
 
#include "marshal.h"
12
 
 
13
 
/* High water mark to determine when the marshalled object is dangerously deep
14
 
 * and risks coring the interpreter.  When the object stack gets this deep,
15
 
 * raise an exception instead of continuing.
16
 
 */
17
 
#define MAX_MARSHAL_STACK_DEPTH 5000
18
 
 
19
 
#define TYPE_NULL       '0'
20
 
#define TYPE_NONE       'N'
21
 
#define TYPE_STOPITER   'S'
22
 
#define TYPE_ELLIPSIS   '.'
23
 
#define TYPE_INT        'i'
24
 
#define TYPE_INT64      'I'
25
 
#define TYPE_FLOAT      'f'
26
 
#define TYPE_COMPLEX    'x'
27
 
#define TYPE_LONG       'l'
28
 
#define TYPE_STRING     's'
29
 
#define TYPE_TUPLE      '('
30
 
#define TYPE_LIST       '['
31
 
#define TYPE_DICT       '{'
32
 
#define TYPE_CODE       'c'
33
 
#define TYPE_UNICODE    'u'
34
 
#define TYPE_UNKNOWN    '?'
35
 
 
36
 
typedef struct {
37
 
        FILE *fp;
38
 
        int error;
39
 
        int depth;
40
 
        /* If fp == NULL, the following are valid: */
41
 
        PyObject *str;
42
 
        char *ptr;
43
 
        char *end;
44
 
} WFILE;
45
 
 
46
 
#define w_byte(c, p) if (((p)->fp)) putc((c), (p)->fp); \
47
 
                      else if ((p)->ptr != (p)->end) *(p)->ptr++ = (c); \
48
 
                           else w_more(c, p)
49
 
 
50
 
static void
51
 
w_more(int c, WFILE *p)
52
 
{
53
 
        int size, newsize;
54
 
        if (p->str == NULL)
55
 
                return; /* An error already occurred */
56
 
        size = PyString_Size(p->str);
57
 
        newsize = size + 1024;
58
 
        if (_PyString_Resize(&p->str, newsize) != 0) {
59
 
                p->ptr = p->end = NULL;
60
 
        }
61
 
        else {
62
 
                p->ptr = PyString_AS_STRING((PyStringObject *)p->str) + size;
63
 
                p->end =
64
 
                        PyString_AS_STRING((PyStringObject *)p->str) + newsize;
65
 
                *p->ptr++ = Py_SAFE_DOWNCAST(c, int, char);
66
 
        }
67
 
}
68
 
 
69
 
static void
70
 
w_string(char *s, int n, WFILE *p)
71
 
{
72
 
        if (p->fp != NULL) {
73
 
                fwrite(s, 1, n, p->fp);
74
 
        }
75
 
        else {
76
 
                while (--n >= 0) {
77
 
                        w_byte(*s, p);
78
 
                        s++;
79
 
                }
80
 
        }
81
 
}
82
 
 
83
 
static void
84
 
w_short(int x, WFILE *p)
85
 
{
86
 
        w_byte( x      & 0xff, p);
87
 
        w_byte((x>> 8) & 0xff, p);
88
 
}
89
 
 
90
 
static void
91
 
w_long(long x, WFILE *p)
92
 
{
93
 
        w_byte((int)( x      & 0xff), p);
94
 
        w_byte((int)((x>> 8) & 0xff), p);
95
 
        w_byte((int)((x>>16) & 0xff), p);
96
 
        w_byte((int)((x>>24) & 0xff), p);
97
 
}
98
 
 
99
 
#if SIZEOF_LONG > 4
100
 
static void
101
 
w_long64(long x, WFILE *p)
102
 
{
103
 
        w_long(x, p);
104
 
        w_long(x>>32, p);
105
 
}
106
 
#endif
107
 
 
108
 
static void
109
 
w_object(PyObject *v, WFILE *p)
110
 
{
111
 
        int i, n;
112
 
 
113
 
        p->depth++;
114
 
 
115
 
        if (p->depth > MAX_MARSHAL_STACK_DEPTH) {
116
 
                p->error = 2;
117
 
        }
118
 
        else if (v == NULL) {
119
 
                w_byte(TYPE_NULL, p);
120
 
        }
121
 
        else if (v == Py_None) {
122
 
                w_byte(TYPE_NONE, p);
123
 
        }
124
 
        else if (v == PyExc_StopIteration) {
125
 
                w_byte(TYPE_STOPITER, p);
126
 
        }
127
 
        else if (v == Py_Ellipsis) {
128
 
                w_byte(TYPE_ELLIPSIS, p);
129
 
        }
130
 
        else if (PyInt_Check(v)) {
131
 
                long x = PyInt_AS_LONG((PyIntObject *)v);
132
 
#if SIZEOF_LONG > 4
133
 
                long y = Py_ARITHMETIC_RIGHT_SHIFT(long, x, 31);
134
 
                if (y && y != -1) {
135
 
                        w_byte(TYPE_INT64, p);
136
 
                        w_long64(x, p);
137
 
                }
138
 
                else
139
 
#endif
140
 
                        {
141
 
                        w_byte(TYPE_INT, p);
142
 
                        w_long(x, p);
143
 
                }
144
 
        }
145
 
        else if (PyLong_Check(v)) {
146
 
                PyLongObject *ob = (PyLongObject *)v;
147
 
                w_byte(TYPE_LONG, p);
148
 
                n = ob->ob_size;
149
 
                w_long((long)n, p);
150
 
                if (n < 0)
151
 
                        n = -n;
152
 
                for (i = 0; i < n; i++)
153
 
                        w_short(ob->ob_digit[i], p);
154
 
        }
155
 
        else if (PyFloat_Check(v)) {
156
 
                char buf[256]; /* Plenty to format any double */
157
 
                PyFloat_AsReprString(buf, (PyFloatObject *)v);
158
 
                n = strlen(buf);
159
 
                w_byte(TYPE_FLOAT, p);
160
 
                w_byte(n, p);
161
 
                w_string(buf, n, p);
162
 
        }
163
 
#ifndef WITHOUT_COMPLEX
164
 
        else if (PyComplex_Check(v)) {
165
 
                char buf[256]; /* Plenty to format any double */
166
 
                PyFloatObject *temp;
167
 
                w_byte(TYPE_COMPLEX, p);
168
 
                temp = (PyFloatObject*)PyFloat_FromDouble(
169
 
                        PyComplex_RealAsDouble(v));
170
 
                PyFloat_AsReprString(buf, temp);
171
 
                Py_DECREF(temp);
172
 
                n = strlen(buf);
173
 
                w_byte(n, p);
174
 
                w_string(buf, n, p);
175
 
                temp = (PyFloatObject*)PyFloat_FromDouble(
176
 
                        PyComplex_ImagAsDouble(v));
177
 
                PyFloat_AsReprString(buf, temp);
178
 
                Py_DECREF(temp);
179
 
                n = strlen(buf);
180
 
                w_byte(n, p);
181
 
                w_string(buf, n, p);
182
 
        }
183
 
#endif
184
 
        else if (PyString_Check(v)) {
185
 
                w_byte(TYPE_STRING, p);
186
 
                n = PyString_GET_SIZE(v);
187
 
                w_long((long)n, p);
188
 
                w_string(PyString_AS_STRING(v), n, p);
189
 
        }
190
 
#ifdef Py_USING_UNICODE
191
 
        else if (PyUnicode_Check(v)) {
192
 
                PyObject *utf8;
193
 
                utf8 = PyUnicode_AsUTF8String(v);
194
 
                if (utf8 == NULL) {
195
 
                        p->depth--;
196
 
                        p->error = 1;
197
 
                        return;
198
 
                }
199
 
                w_byte(TYPE_UNICODE, p);
200
 
                n = PyString_GET_SIZE(utf8);
201
 
                w_long((long)n, p);
202
 
                w_string(PyString_AS_STRING(utf8), n, p);
203
 
                Py_DECREF(utf8);
204
 
        }
205
 
#endif
206
 
        else if (PyTuple_Check(v)) {
207
 
                w_byte(TYPE_TUPLE, p);
208
 
                n = PyTuple_Size(v);
209
 
                w_long((long)n, p);
210
 
                for (i = 0; i < n; i++) {
211
 
                        w_object(PyTuple_GET_ITEM(v, i), p);
212
 
                }
213
 
        }
214
 
        else if (PyList_Check(v)) {
215
 
                w_byte(TYPE_LIST, p);
216
 
                n = PyList_GET_SIZE(v);
217
 
                w_long((long)n, p);
218
 
                for (i = 0; i < n; i++) {
219
 
                        w_object(PyList_GET_ITEM(v, i), p);
220
 
                }
221
 
        }
222
 
        else if (PyDict_Check(v)) {
223
 
                int pos;
224
 
                PyObject *key, *value;
225
 
                w_byte(TYPE_DICT, p);
226
 
                /* This one is NULL object terminated! */
227
 
                pos = 0;
228
 
                while (PyDict_Next(v, &pos, &key, &value)) {
229
 
                        w_object(key, p);
230
 
                        w_object(value, p);
231
 
                }
232
 
                w_object((PyObject *)NULL, p);
233
 
        }
234
 
        else if (PyCode_Check(v)) {
235
 
                PyCodeObject *co = (PyCodeObject *)v;
236
 
                w_byte(TYPE_CODE, p);
237
 
                w_short(co->co_argcount, p);
238
 
                w_short(co->co_nlocals, p);
239
 
                w_short(co->co_stacksize, p);
240
 
                w_short(co->co_flags, p);
241
 
                w_object(co->co_code, p);
242
 
                w_object(co->co_consts, p);
243
 
                w_object(co->co_names, p);
244
 
                w_object(co->co_varnames, p);
245
 
                w_object(co->co_freevars, p);
246
 
                w_object(co->co_cellvars, p);
247
 
                w_object(co->co_filename, p);
248
 
                w_object(co->co_name, p);
249
 
                w_short(co->co_firstlineno, p);
250
 
                w_object(co->co_lnotab, p);
251
 
        }
252
 
        else if (PyObject_CheckReadBuffer(v)) {
253
 
                /* Write unknown buffer-style objects as a string */
254
 
                char *s;
255
 
                PyBufferProcs *pb = v->ob_type->tp_as_buffer;
256
 
                w_byte(TYPE_STRING, p);
257
 
                n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s);
258
 
                w_long((long)n, p);
259
 
                w_string(s, n, p);
260
 
        }
261
 
        else {
262
 
                w_byte(TYPE_UNKNOWN, p);
263
 
                p->error = 1;
264
 
        }
265
 
 
266
 
        p->depth--;
267
 
}
268
 
 
269
 
void
270
 
PyMarshal_WriteLongToFile(long x, FILE *fp)
271
 
{
272
 
        WFILE wf;
273
 
        wf.fp = fp;
274
 
        wf.error = 0;
275
 
        wf.depth = 0;
276
 
        w_long(x, &wf);
277
 
}
278
 
 
279
 
void
280
 
PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp)
281
 
{
282
 
        WFILE wf;
283
 
        wf.fp = fp;
284
 
        wf.error = 0;
285
 
        wf.depth = 0;
286
 
        w_object(x, &wf);
287
 
}
288
 
 
289
 
typedef WFILE RFILE; /* Same struct with different invariants */
290
 
 
291
 
#define rs_byte(p) (((p)->ptr != (p)->end) ? (unsigned char)*(p)->ptr++ : EOF)
292
 
 
293
 
#define r_byte(p) ((p)->fp ? getc((p)->fp) : rs_byte(p))
294
 
 
295
 
static int
296
 
r_string(char *s, int n, 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
 
 
307
 
static int
308
 
r_short(RFILE *p)
309
 
{
310
 
        register short x;
311
 
        x = r_byte(p);
312
 
        x |= r_byte(p) << 8;
313
 
        /* Sign-extension, in case short greater than 16 bits */
314
 
        x |= -(x & 0x8000);
315
 
        return x;
316
 
}
317
 
 
318
 
static long
319
 
r_long(RFILE *p)
320
 
{
321
 
        register long x;
322
 
        register FILE *fp = p->fp;
323
 
        if (fp) {
324
 
                x = getc(fp);
325
 
                x |= (long)getc(fp) << 8;
326
 
                x |= (long)getc(fp) << 16;
327
 
                x |= (long)getc(fp) << 24;
328
 
        }
329
 
        else {
330
 
                x = rs_byte(p);
331
 
                x |= (long)rs_byte(p) << 8;
332
 
                x |= (long)rs_byte(p) << 16;
333
 
                x |= (long)rs_byte(p) << 24;
334
 
        }
335
 
#if SIZEOF_LONG > 4
336
 
        /* Sign extension for 64-bit machines */
337
 
        x |= -(x & 0x80000000L);
338
 
#endif
339
 
        return x;
340
 
}
341
 
 
342
 
/* r_long64 deals with the TYPE_INT64 code.  On a machine with
343
 
   sizeof(long) > 4, it returns a Python int object, else a Python long
344
 
   object.  Note that w_long64 writes out TYPE_INT if 32 bits is enough,
345
 
   so there's no inefficiency here in returning a PyLong on 32-bit boxes
346
 
   for everything written via TYPE_INT64 (i.e., if an int is written via
347
 
   TYPE_INT64, it *needs* more than 32 bits).
348
 
*/
349
 
static PyObject *
350
 
r_long64(RFILE *p)
351
 
{
352
 
        long lo4 = r_long(p);
353
 
        long hi4 = r_long(p);
354
 
#if SIZEOF_LONG > 4
355
 
        long x = (hi4 << 32) | (lo4 & 0xFFFFFFFFL);
356
 
        return PyInt_FromLong(x);
357
 
#else
358
 
        unsigned char buf[8];
359
 
        int one = 1;
360
 
        int is_little_endian = (int)*(char*)&one;
361
 
        if (is_little_endian) {
362
 
                memcpy(buf, &lo4, 4);
363
 
                memcpy(buf+4, &hi4, 4);
364
 
        }
365
 
        else {
366
 
                memcpy(buf, &hi4, 4);
367
 
                memcpy(buf+4, &lo4, 4);
368
 
        }
369
 
        return _PyLong_FromByteArray(buf, 8, is_little_endian, 1);
370
 
#endif
371
 
}
372
 
 
373
 
static PyObject *
374
 
r_object(RFILE *p)
375
 
{
376
 
        PyObject *v, *v2;
377
 
        long i, n;
378
 
        int type = r_byte(p);
379
 
 
380
 
        switch (type) {
381
 
 
382
 
        case EOF:
383
 
                PyErr_SetString(PyExc_EOFError,
384
 
                                "EOF read where object expected");
385
 
                return NULL;
386
 
 
387
 
        case TYPE_NULL:
388
 
                return NULL;
389
 
 
390
 
        case TYPE_NONE:
391
 
                Py_INCREF(Py_None);
392
 
                return Py_None;
393
 
 
394
 
        case TYPE_STOPITER:
395
 
                Py_INCREF(PyExc_StopIteration);
396
 
                return PyExc_StopIteration;
397
 
 
398
 
        case TYPE_ELLIPSIS:
399
 
                Py_INCREF(Py_Ellipsis);
400
 
                return Py_Ellipsis;
401
 
 
402
 
        case TYPE_INT:
403
 
                return PyInt_FromLong(r_long(p));
404
 
 
405
 
        case TYPE_INT64:
406
 
                return r_long64(p);
407
 
 
408
 
        case TYPE_LONG:
409
 
                {
410
 
                        int size;
411
 
                        PyLongObject *ob;
412
 
                        n = r_long(p);
413
 
                        size = n<0 ? -n : n;
414
 
                        ob = _PyLong_New(size);
415
 
                        if (ob == NULL)
416
 
                                return NULL;
417
 
                        ob->ob_size = n;
418
 
                        for (i = 0; i < size; i++)
419
 
                                ob->ob_digit[i] = r_short(p);
420
 
                        return (PyObject *)ob;
421
 
                }
422
 
 
423
 
        case TYPE_FLOAT:
424
 
                {
425
 
                        char buf[256];
426
 
                        double dx;
427
 
                        n = r_byte(p);
428
 
                        if (r_string(buf, (int)n, p) != n) {
429
 
                                PyErr_SetString(PyExc_EOFError,
430
 
                                        "EOF read where object expected");
431
 
                                return NULL;
432
 
                        }
433
 
                        buf[n] = '\0';
434
 
                        PyFPE_START_PROTECT("atof", return 0)
435
 
                        dx = atof(buf);
436
 
                        PyFPE_END_PROTECT(dx)
437
 
                        return PyFloat_FromDouble(dx);
438
 
                }
439
 
 
440
 
#ifndef WITHOUT_COMPLEX
441
 
        case TYPE_COMPLEX:
442
 
                {
443
 
                        char buf[256];
444
 
                        Py_complex c;
445
 
                        n = r_byte(p);
446
 
                        if (r_string(buf, (int)n, p) != n) {
447
 
                                PyErr_SetString(PyExc_EOFError,
448
 
                                        "EOF read where object expected");
449
 
                                return NULL;
450
 
                        }
451
 
                        buf[n] = '\0';
452
 
                        PyFPE_START_PROTECT("atof", return 0)
453
 
                        c.real = atof(buf);
454
 
                        PyFPE_END_PROTECT(c)
455
 
                        n = r_byte(p);
456
 
                        if (r_string(buf, (int)n, p) != n) {
457
 
                                PyErr_SetString(PyExc_EOFError,
458
 
                                        "EOF read where object expected");
459
 
                                return NULL;
460
 
                        }
461
 
                        buf[n] = '\0';
462
 
                        PyFPE_START_PROTECT("atof", return 0)
463
 
                        c.imag = atof(buf);
464
 
                        PyFPE_END_PROTECT(c)
465
 
                        return PyComplex_FromCComplex(c);
466
 
                }
467
 
#endif
468
 
 
469
 
        case TYPE_STRING:
470
 
                n = r_long(p);
471
 
                if (n < 0) {
472
 
                        PyErr_SetString(PyExc_ValueError, "bad marshal data");
473
 
                        return NULL;
474
 
                }
475
 
                v = PyString_FromStringAndSize((char *)NULL, n);
476
 
                if (v != NULL) {
477
 
                        if (r_string(PyString_AS_STRING(v), (int)n, p) != n) {
478
 
                                Py_DECREF(v);
479
 
                                v = NULL;
480
 
                                PyErr_SetString(PyExc_EOFError,
481
 
                                        "EOF read where object expected");
482
 
                        }
483
 
                }
484
 
                return v;
485
 
 
486
 
#ifdef Py_USING_UNICODE
487
 
        case TYPE_UNICODE:
488
 
            {
489
 
                char *buffer;
490
 
 
491
 
                n = r_long(p);
492
 
                if (n < 0) {
493
 
                        PyErr_SetString(PyExc_ValueError, "bad marshal data");
494
 
                        return NULL;
495
 
                }
496
 
                buffer = PyMem_NEW(char, n);
497
 
                if (buffer == NULL)
498
 
                        return PyErr_NoMemory();
499
 
                if (r_string(buffer, (int)n, p) != n) {
500
 
                        PyMem_DEL(buffer);
501
 
                        PyErr_SetString(PyExc_EOFError,
502
 
                                "EOF read where object expected");
503
 
                        return NULL;
504
 
                }
505
 
                v = PyUnicode_DecodeUTF8(buffer, n, NULL);
506
 
                PyMem_DEL(buffer);
507
 
                return v;
508
 
            }
509
 
#endif
510
 
 
511
 
        case TYPE_TUPLE:
512
 
                n = r_long(p);
513
 
                if (n < 0) {
514
 
                        PyErr_SetString(PyExc_ValueError, "bad marshal data");
515
 
                        return NULL;
516
 
                }
517
 
                v = PyTuple_New((int)n);
518
 
                if (v == NULL)
519
 
                        return v;
520
 
                for (i = 0; i < n; i++) {
521
 
                        v2 = r_object(p);
522
 
                        if ( v2 == NULL ) {
523
 
                                Py_DECREF(v);
524
 
                                v = NULL;
525
 
                                break;
526
 
                        }
527
 
                        PyTuple_SET_ITEM(v, (int)i, v2);
528
 
                }
529
 
                return v;
530
 
 
531
 
        case TYPE_LIST:
532
 
                n = r_long(p);
533
 
                if (n < 0) {
534
 
                        PyErr_SetString(PyExc_ValueError, "bad marshal data");
535
 
                        return NULL;
536
 
                }
537
 
                v = PyList_New((int)n);
538
 
                if (v == NULL)
539
 
                        return v;
540
 
                for (i = 0; i < n; i++) {
541
 
                        v2 = r_object(p);
542
 
                        if ( v2 == NULL ) {
543
 
                                Py_DECREF(v);
544
 
                                v = NULL;
545
 
                                break;
546
 
                        }
547
 
                        PyList_SetItem(v, (int)i, v2);
548
 
                }
549
 
                return v;
550
 
 
551
 
        case TYPE_DICT:
552
 
                v = PyDict_New();
553
 
                if (v == NULL)
554
 
                        return NULL;
555
 
                for (;;) {
556
 
                        PyObject *key, *val;
557
 
                        key = r_object(p);
558
 
                        if (key == NULL)
559
 
                                break; /* XXX Assume TYPE_NULL, not an error */
560
 
                        val = r_object(p);
561
 
                        if (val != NULL)
562
 
                                PyDict_SetItem(v, key, val);
563
 
                        Py_DECREF(key);
564
 
                        Py_XDECREF(val);
565
 
                }
566
 
                return v;
567
 
 
568
 
        case TYPE_CODE:
569
 
                if (PyEval_GetRestricted()) {
570
 
                        PyErr_SetString(PyExc_RuntimeError,
571
 
                                "cannot unmarshal code objects in "
572
 
                                "restricted execution mode");
573
 
                        return NULL;
574
 
                }
575
 
                else {
576
 
                        int argcount = r_short(p);
577
 
                        int nlocals = r_short(p);
578
 
                        int stacksize = r_short(p);
579
 
                        int flags = r_short(p);
580
 
                        PyObject *code = NULL;
581
 
                        PyObject *consts = NULL;
582
 
                        PyObject *names = NULL;
583
 
                        PyObject *varnames = NULL;
584
 
                        PyObject *freevars = NULL;
585
 
                        PyObject *cellvars = NULL;
586
 
                        PyObject *filename = NULL;
587
 
                        PyObject *name = NULL;
588
 
                        int firstlineno = 0;
589
 
                        PyObject *lnotab = NULL;
590
 
 
591
 
                        code = r_object(p);
592
 
                        if (code) consts = r_object(p);
593
 
                        if (consts) names = r_object(p);
594
 
                        if (names) varnames = r_object(p);
595
 
#if MARSHAL_VERSION >= 21
596
 
                        if (varnames) freevars = r_object(p);
597
 
                        if (freevars) cellvars = r_object(p);
598
 
#else
599
 
                        if (varnames) freevars = PyTuple_New(0);
600
 
                        if (freevars) cellvars = PyTuple_New(0);
601
 
#endif
602
 
                        if (cellvars) filename = r_object(p);
603
 
                        if (filename) name = r_object(p);
604
 
                        if (name) {
605
 
                                firstlineno = r_short(p);
606
 
                                lnotab = r_object(p);
607
 
                        }
608
 
 
609
 
                        if (!PyErr_Occurred()) {
610
 
                                v = (PyObject *) PyCode_New(
611
 
                                        argcount, nlocals, stacksize, flags,
612
 
                                        code, consts, names, varnames,
613
 
                                        freevars, cellvars, filename, name,
614
 
                                        firstlineno, lnotab);
615
 
                        }
616
 
                        else
617
 
                                v = NULL;
618
 
                        Py_XDECREF(code);
619
 
                        Py_XDECREF(consts);
620
 
                        Py_XDECREF(names);
621
 
                        Py_XDECREF(varnames);
622
 
                        Py_XDECREF(freevars);
623
 
                        Py_XDECREF(cellvars);
624
 
                        Py_XDECREF(filename);
625
 
                        Py_XDECREF(name);
626
 
                        Py_XDECREF(lnotab);
627
 
 
628
 
                }
629
 
                return v;
630
 
 
631
 
        default:
632
 
                /* Bogus data got written, which isn't ideal.
633
 
                   This will let you keep working and recover. */
634
 
                PyErr_SetString(PyExc_ValueError, "bad marshal data");
635
 
                return NULL;
636
 
 
637
 
        }
638
 
}
639
 
 
640
 
int
641
 
PyMarshal_ReadShortFromFile(FILE *fp)
642
 
{
643
 
        RFILE rf;
644
 
        rf.fp = fp;
645
 
        return r_short(&rf);
646
 
}
647
 
 
648
 
long
649
 
PyMarshal_ReadLongFromFile(FILE *fp)
650
 
{
651
 
        RFILE rf;
652
 
        rf.fp = fp;
653
 
        return r_long(&rf);
654
 
}
655
 
 
656
 
#ifdef HAVE_FSTAT
657
 
/* Return size of file in bytes; < 0 if unknown. */
658
 
static off_t
659
 
getfilesize(FILE *fp)
660
 
{
661
 
        struct stat st;
662
 
        if (fstat(fileno(fp), &st) != 0)
663
 
                return -1;
664
 
        else
665
 
                return st.st_size;
666
 
}
667
 
#endif
668
 
 
669
 
/* If we can get the size of the file up-front, and it's reasonably small,
670
 
 * read it in one gulp and delegate to ...FromString() instead.  Much quicker
671
 
 * than reading a byte at a time from file; speeds .pyc imports.
672
 
 * CAUTION:  since this may read the entire remainder of the file, don't
673
 
 * call it unless you know you're done with the file.
674
 
 */
675
 
PyObject *
676
 
PyMarshal_ReadLastObjectFromFile(FILE *fp)
677
 
{
678
 
/* 75% of 2.1's .pyc files can exploit SMALL_FILE_LIMIT.
679
 
 * REASONABLE_FILE_LIMIT is by defn something big enough for Tkinter.pyc.
680
 
 */
681
 
#define SMALL_FILE_LIMIT (1L << 14)
682
 
#define REASONABLE_FILE_LIMIT (1L << 18)
683
 
#ifdef HAVE_FSTAT
684
 
        off_t filesize;
685
 
#endif
686
 
        if (PyErr_Occurred()) {
687
 
                fprintf(stderr, "XXX rd_object called with exception set\n");
688
 
                return NULL;
689
 
        }
690
 
#ifdef HAVE_FSTAT
691
 
        filesize = getfilesize(fp);
692
 
        if (filesize > 0) {
693
 
                char buf[SMALL_FILE_LIMIT];
694
 
                char* pBuf = NULL;
695
 
                if (filesize <= SMALL_FILE_LIMIT)
696
 
                        pBuf = buf;
697
 
                else if (filesize <= REASONABLE_FILE_LIMIT)
698
 
                        pBuf = (char *)PyMem_MALLOC(filesize);
699
 
                if (pBuf != NULL) {
700
 
                        PyObject* v;
701
 
                        size_t n = fread(pBuf, 1, filesize, fp);
702
 
                        v = PyMarshal_ReadObjectFromString(pBuf, n);
703
 
                        if (pBuf != buf)
704
 
                                PyMem_FREE(pBuf);
705
 
                        return v;
706
 
                }
707
 
 
708
 
        }
709
 
#endif
710
 
        /* We don't have fstat, or we do but the file is larger than
711
 
         * REASONABLE_FILE_LIMIT or malloc failed -- read a byte at a time.
712
 
         */
713
 
        return PyMarshal_ReadObjectFromFile(fp);
714
 
 
715
 
#undef SMALL_FILE_LIMIT
716
 
#undef REASONABLE_FILE_LIMIT
717
 
}
718
 
 
719
 
PyObject *
720
 
PyMarshal_ReadObjectFromFile(FILE *fp)
721
 
{
722
 
        RFILE rf;
723
 
        if (PyErr_Occurred()) {
724
 
                fprintf(stderr, "XXX rd_object called with exception set\n");
725
 
                return NULL;
726
 
        }
727
 
        rf.fp = fp;
728
 
        return r_object(&rf);
729
 
}
730
 
 
731
 
PyObject *
732
 
PyMarshal_ReadObjectFromString(char *str, int len)
733
 
{
734
 
        RFILE rf;
735
 
        if (PyErr_Occurred()) {
736
 
                fprintf(stderr, "XXX rds_object called with exception set\n");
737
 
                return NULL;
738
 
        }
739
 
        rf.fp = NULL;
740
 
        rf.str = NULL;
741
 
        rf.ptr = str;
742
 
        rf.end = str + len;
743
 
        return r_object(&rf);
744
 
}
745
 
 
746
 
PyObject *
747
 
PyMarshal_WriteObjectToString(PyObject *x) /* wrs_object() */
748
 
{
749
 
        WFILE wf;
750
 
        wf.fp = NULL;
751
 
        wf.str = PyString_FromStringAndSize((char *)NULL, 50);
752
 
        if (wf.str == NULL)
753
 
                return NULL;
754
 
        wf.ptr = PyString_AS_STRING((PyStringObject *)wf.str);
755
 
        wf.end = wf.ptr + PyString_Size(wf.str);
756
 
        wf.error = 0;
757
 
        wf.depth = 0;
758
 
        w_object(x, &wf);
759
 
        if (wf.str != NULL)
760
 
                _PyString_Resize(&wf.str,
761
 
                    (int) (wf.ptr -
762
 
                           PyString_AS_STRING((PyStringObject *)wf.str)));
763
 
        if (wf.error) {
764
 
                Py_XDECREF(wf.str);
765
 
                PyErr_SetString(PyExc_ValueError,
766
 
                                (wf.error==1)?"unmarshallable object"
767
 
                                :"object too deeply nested to marshal");
768
 
                return NULL;
769
 
        }
770
 
        return wf.str;
771
 
}
772
 
 
773
 
/* And an interface for Python programs... */
774
 
 
775
 
static PyObject *
776
 
marshal_dump(PyObject *self, PyObject *args)
777
 
{
778
 
        WFILE wf;
779
 
        PyObject *x;
780
 
        PyObject *f;
781
 
        if (!PyArg_ParseTuple(args, "OO:dump", &x, &f))
782
 
                return NULL;
783
 
        if (!PyFile_Check(f)) {
784
 
                PyErr_SetString(PyExc_TypeError,
785
 
                                "marshal.dump() 2nd arg must be file");
786
 
                return NULL;
787
 
        }
788
 
        wf.fp = PyFile_AsFile(f);
789
 
        wf.str = NULL;
790
 
        wf.ptr = wf.end = NULL;
791
 
        wf.error = 0;
792
 
        wf.depth = 0;
793
 
        w_object(x, &wf);
794
 
        if (wf.error) {
795
 
                PyErr_SetString(PyExc_ValueError,
796
 
                                (wf.error==1)?"unmarshallable object"
797
 
                                :"object too deeply nested to marshal");
798
 
                return NULL;
799
 
        }
800
 
        Py_INCREF(Py_None);
801
 
        return Py_None;
802
 
}
803
 
 
804
 
static PyObject *
805
 
marshal_load(PyObject *self, PyObject *args)
806
 
{
807
 
        RFILE rf;
808
 
        PyObject *f;
809
 
        PyObject *v;
810
 
        if (!PyArg_ParseTuple(args, "O:load", &f))
811
 
                return NULL;
812
 
        if (!PyFile_Check(f)) {
813
 
                PyErr_SetString(PyExc_TypeError,
814
 
                                "marshal.load() arg must be file");
815
 
                return NULL;
816
 
        }
817
 
        rf.fp = PyFile_AsFile(f);
818
 
        rf.str = NULL;
819
 
        rf.ptr = rf.end = NULL;
820
 
        PyErr_Clear();
821
 
        v = r_object(&rf);
822
 
        if (PyErr_Occurred()) {
823
 
                Py_XDECREF(v);
824
 
                v = NULL;
825
 
        }
826
 
        return v;
827
 
}
828
 
 
829
 
static PyObject *
830
 
marshal_dumps(PyObject *self, PyObject *args)
831
 
{
832
 
        PyObject *x;
833
 
        if (!PyArg_ParseTuple(args, "O:dumps", &x))
834
 
                return NULL;
835
 
        return PyMarshal_WriteObjectToString(x);
836
 
}
837
 
 
838
 
static PyObject *
839
 
marshal_loads(PyObject *self, PyObject *args)
840
 
{
841
 
        RFILE rf;
842
 
        PyObject *v;
843
 
        char *s;
844
 
        int n;
845
 
        if (!PyArg_ParseTuple(args, "s#:loads", &s, &n))
846
 
                return NULL;
847
 
        rf.fp = NULL;
848
 
        rf.str = args;
849
 
        rf.ptr = s;
850
 
        rf.end = s + n;
851
 
        PyErr_Clear();
852
 
        v = r_object(&rf);
853
 
        if (PyErr_Occurred()) {
854
 
                Py_XDECREF(v);
855
 
                v = NULL;
856
 
        }
857
 
        return v;
858
 
}
859
 
 
860
 
static PyMethodDef marshal_methods[] = {
861
 
#ifndef MARSHAL_VERSION
862
 
        {"dump",        marshal_dump,   1},
863
 
        {"load",        marshal_load,   1},
864
 
        {"dumps",       marshal_dumps,  1},
865
 
        {"loads",       marshal_loads,  1},
866
 
#else
867
 
        {"load",        marshal_load,   1},
868
 
        {"loads",       marshal_loads,  1},
869
 
#endif
870
 
        {NULL,          NULL}           /* sentinel */
871
 
};
872
 
 
873
 
#if MARSHAL_VERSION == 20
874
 
void
875
 
initmarshal_20 (void)
876
 
{
877
 
  (void) Py_InitModule("marshal_20" , marshal_methods);
878
 
}
879
 
/*
880
 
##elif MARSHAL_VERSION == 22
881
 
#void
882
 
#initmarshal_22 (void)
883
 
#{
884
 
#  (void) Py_InitModule("marshal_22" , marshal_methods);
885
 
#}
886
 
*/
887
 
#else
888
 
void
889
 
PyMarshal_Init(void)
890
 
{
891
 
        (void) Py_InitModule("marshal", marshal_methods);
892
 
}
893
 
#endif