1/* struct module -- pack values into and (out of) strings */
2
3/* New version supporting byte order, alignment and size options,
4   character strings, and unsigned numbers */
5
6#define PY_SSIZE_T_CLEAN
7
8#include "Python.h"
9#include "structseq.h"
10#include "structmember.h"
11#include <ctype.h>
12
13static PyTypeObject PyStructType;
14
15/* compatibility macros */
16#if (PY_VERSION_HEX < 0x02050000)
17typedef int Py_ssize_t;
18#endif
19
20/* warning messages */
21#define FLOAT_COERCE_WARN "integer argument expected, got float"
22#define NON_INTEGER_WARN "integer argument expected, got non-integer " \
23    "(implicit conversion using __int__ is deprecated)"
24
25
26/* The translation function for each format character is table driven */
27typedef struct _formatdef {
28    char format;
29    Py_ssize_t size;
30    Py_ssize_t alignment;
31    PyObject* (*unpack)(const char *,
32                        const struct _formatdef *);
33    int (*pack)(char *, PyObject *,
34                const struct _formatdef *);
35} formatdef;
36
37typedef struct _formatcode {
38    const struct _formatdef *fmtdef;
39    Py_ssize_t offset;
40    Py_ssize_t size;
41} formatcode;
42
43/* Struct object interface */
44
45typedef struct {
46    PyObject_HEAD
47    Py_ssize_t s_size;
48    Py_ssize_t s_len;
49    formatcode *s_codes;
50    PyObject *s_format;
51    PyObject *weakreflist; /* List of weak references */
52} PyStructObject;
53
54
55#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
56#define PyStruct_CheckExact(op) (Py_TYPE(op) == &PyStructType)
57
58
59/* Exception */
60
61static PyObject *StructError;
62
63
64/* Define various structs to figure out the alignments of types */
65
66
67typedef struct { char c; short x; } st_short;
68typedef struct { char c; int x; } st_int;
69typedef struct { char c; long x; } st_long;
70typedef struct { char c; float x; } st_float;
71typedef struct { char c; double x; } st_double;
72typedef struct { char c; void *x; } st_void_p;
73
74#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
75#define INT_ALIGN (sizeof(st_int) - sizeof(int))
76#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
77#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
78#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
79#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
80
81/* We can't support q and Q in native mode unless the compiler does;
82   in std mode, they're 8 bytes on all platforms. */
83#ifdef HAVE_LONG_LONG
84typedef struct { char c; PY_LONG_LONG x; } s_long_long;
85#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
86#endif
87
88#ifdef HAVE_C99_BOOL
89#define BOOL_TYPE _Bool
90typedef struct { char c; _Bool x; } s_bool;
91#define BOOL_ALIGN (sizeof(s_bool) - sizeof(BOOL_TYPE))
92#else
93#define BOOL_TYPE char
94#define BOOL_ALIGN 0
95#endif
96
97#define STRINGIFY(x)    #x
98
99#ifdef __powerc
100#pragma options align=reset
101#endif
102
103static char *integer_codes = "bBhHiIlLqQ";
104
105/* Helper to get a PyLongObject by hook or by crook.  Caller should decref. */
106
107static PyObject *
108get_pylong(PyObject *v)
109{
110    PyObject *r, *w;
111    int converted = 0;
112    assert(v != NULL);
113    if (!PyInt_Check(v) && !PyLong_Check(v)) {
114        PyNumberMethods *m;
115        /* Not an integer; first try to use __index__ to
116           convert to an integer.  If the __index__ method
117           doesn't exist, or raises a TypeError, try __int__.
118           Use of the latter is deprecated, and will fail in
119           Python 3.x. */
120
121        m = Py_TYPE(v)->tp_as_number;
122        if (PyIndex_Check(v)) {
123            w = PyNumber_Index(v);
124            if (w != NULL) {
125                v = w;
126                /* successfully converted to an integer */
127                converted = 1;
128            }
129            else if (PyErr_ExceptionMatches(PyExc_TypeError)) {
130                PyErr_Clear();
131            }
132            else
133                return NULL;
134        }
135        if (!converted && m != NULL && m->nb_int != NULL) {
136            /* Special case warning message for floats, for
137               backwards compatibility. */
138            if (PyFloat_Check(v)) {
139                if (PyErr_WarnEx(
140                            PyExc_DeprecationWarning,
141                            FLOAT_COERCE_WARN, 1))
142                    return NULL;
143            }
144            else {
145                if (PyErr_WarnEx(
146                            PyExc_DeprecationWarning,
147                            NON_INTEGER_WARN, 1))
148                    return NULL;
149            }
150            v = m->nb_int(v);
151            if (v == NULL)
152                return NULL;
153            if (!PyInt_Check(v) && !PyLong_Check(v)) {
154                PyErr_SetString(PyExc_TypeError,
155                                "__int__ method returned "
156                                "non-integer");
157                return NULL;
158            }
159            converted = 1;
160        }
161        if (!converted) {
162            PyErr_SetString(StructError,
163                            "cannot convert argument "
164                            "to integer");
165            return NULL;
166        }
167    }
168    else
169        /* Ensure we own a reference to v. */
170        Py_INCREF(v);
171
172    assert(PyInt_Check(v) || PyLong_Check(v));
173    if (PyInt_Check(v)) {
174        r = PyLong_FromLong(PyInt_AS_LONG(v));
175        Py_DECREF(v);
176    }
177    else if (PyLong_Check(v)) {
178        assert(PyLong_Check(v));
179        r = v;
180    }
181    else {
182        r = NULL;   /* silence compiler warning about
183                       possibly uninitialized variable */
184        assert(0);  /* shouldn't ever get here */
185    }
186
187    return r;
188}
189
190/* Helper to convert a Python object to a C long.  Sets an exception
191   (struct.error for an inconvertible type, OverflowError for
192   out-of-range values) and returns -1 on error. */
193
194static int
195get_long(PyObject *v, long *p)
196{
197    long x;
198
199    v = get_pylong(v);
200    if (v == NULL)
201        return -1;
202    assert(PyLong_Check(v));
203    x = PyLong_AsLong(v);
204    Py_DECREF(v);
205    if (x == (long)-1 && PyErr_Occurred())
206        return -1;
207    *p = x;
208    return 0;
209}
210
211/* Same, but handling unsigned long */
212
213static int
214get_ulong(PyObject *v, unsigned long *p)
215{
216    unsigned long x;
217
218    v = get_pylong(v);
219    if (v == NULL)
220        return -1;
221    assert(PyLong_Check(v));
222    x = PyLong_AsUnsignedLong(v);
223    Py_DECREF(v);
224    if (x == (unsigned long)-1 && PyErr_Occurred())
225        return -1;
226    *p = x;
227    return 0;
228}
229
230#ifdef HAVE_LONG_LONG
231
232/* Same, but handling native long long. */
233
234static int
235get_longlong(PyObject *v, PY_LONG_LONG *p)
236{
237    PY_LONG_LONG x;
238
239    v = get_pylong(v);
240    if (v == NULL)
241        return -1;
242    assert(PyLong_Check(v));
243    x = PyLong_AsLongLong(v);
244    Py_DECREF(v);
245    if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
246        return -1;
247    *p = x;
248    return 0;
249}
250
251/* Same, but handling native unsigned long long. */
252
253static int
254get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
255{
256    unsigned PY_LONG_LONG x;
257
258    v = get_pylong(v);
259    if (v == NULL)
260        return -1;
261    assert(PyLong_Check(v));
262    x = PyLong_AsUnsignedLongLong(v);
263    Py_DECREF(v);
264    if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
265        return -1;
266    *p = x;
267    return 0;
268}
269
270#endif
271
272/* Floating point helpers */
273
274static PyObject *
275unpack_float(const char *p,  /* start of 4-byte string */
276         int le)             /* true for little-endian, false for big-endian */
277{
278    double x;
279
280    x = _PyFloat_Unpack4((unsigned char *)p, le);
281    if (x == -1.0 && PyErr_Occurred())
282        return NULL;
283    return PyFloat_FromDouble(x);
284}
285
286static PyObject *
287unpack_double(const char *p,  /* start of 8-byte string */
288          int le)         /* true for little-endian, false for big-endian */
289{
290    double x;
291
292    x = _PyFloat_Unpack8((unsigned char *)p, le);
293    if (x == -1.0 && PyErr_Occurred())
294        return NULL;
295    return PyFloat_FromDouble(x);
296}
297
298/* Helper to format the range error exceptions */
299static int
300_range_error(const formatdef *f, int is_unsigned)
301{
302    /* ulargest is the largest unsigned value with f->size bytes.
303     * Note that the simpler:
304     *     ((size_t)1 << (f->size * 8)) - 1
305     * doesn't work when f->size == sizeof(size_t) because C doesn't
306     * define what happens when a left shift count is >= the number of
307     * bits in the integer being shifted; e.g., on some boxes it doesn't
308     * shift at all when they're equal.
309     */
310    const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
311    assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
312    if (is_unsigned)
313        PyErr_Format(StructError,
314            "'%c' format requires 0 <= number <= %zu",
315            f->format,
316            ulargest);
317    else {
318        const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
319        PyErr_Format(StructError,
320            "'%c' format requires %zd <= number <= %zd",
321            f->format,
322            ~ largest,
323            largest);
324    }
325    return -1;
326}
327
328
329
330/* A large number of small routines follow, with names of the form
331
332   [bln][up]_TYPE
333
334   [bln] distiguishes among big-endian, little-endian and native.
335   [pu] distiguishes between pack (to struct) and unpack (from struct).
336   TYPE is one of char, byte, ubyte, etc.
337*/
338
339/* Native mode routines. ****************************************************/
340/* NOTE:
341   In all n[up]_<type> routines handling types larger than 1 byte, there is
342   *no* guarantee that the p pointer is properly aligned for each type,
343   therefore memcpy is called.  An intermediate variable is used to
344   compensate for big-endian architectures.
345   Normally both the intermediate variable and the memcpy call will be
346   skipped by C optimisation in little-endian architectures (gcc >= 2.91
347   does this). */
348
349static PyObject *
350nu_char(const char *p, const formatdef *f)
351{
352    return PyString_FromStringAndSize(p, 1);
353}
354
355static PyObject *
356nu_byte(const char *p, const formatdef *f)
357{
358    return PyInt_FromLong((long) *(signed char *)p);
359}
360
361static PyObject *
362nu_ubyte(const char *p, const formatdef *f)
363{
364    return PyInt_FromLong((long) *(unsigned char *)p);
365}
366
367static PyObject *
368nu_short(const char *p, const formatdef *f)
369{
370    short x;
371    memcpy((char *)&x, p, sizeof x);
372    return PyInt_FromLong((long)x);
373}
374
375static PyObject *
376nu_ushort(const char *p, const formatdef *f)
377{
378    unsigned short x;
379    memcpy((char *)&x, p, sizeof x);
380    return PyInt_FromLong((long)x);
381}
382
383static PyObject *
384nu_int(const char *p, const formatdef *f)
385{
386    int x;
387    memcpy((char *)&x, p, sizeof x);
388    return PyInt_FromLong((long)x);
389}
390
391static PyObject *
392nu_uint(const char *p, const formatdef *f)
393{
394    unsigned int x;
395    memcpy((char *)&x, p, sizeof x);
396#if (SIZEOF_LONG > SIZEOF_INT)
397    return PyInt_FromLong((long)x);
398#else
399    if (x <= ((unsigned int)LONG_MAX))
400        return PyInt_FromLong((long)x);
401    return PyLong_FromUnsignedLong((unsigned long)x);
402#endif
403}
404
405static PyObject *
406nu_long(const char *p, const formatdef *f)
407{
408    long x;
409    memcpy((char *)&x, p, sizeof x);
410    return PyInt_FromLong(x);
411}
412
413static PyObject *
414nu_ulong(const char *p, const formatdef *f)
415{
416    unsigned long x;
417    memcpy((char *)&x, p, sizeof x);
418    if (x <= LONG_MAX)
419        return PyInt_FromLong((long)x);
420    return PyLong_FromUnsignedLong(x);
421}
422
423/* Native mode doesn't support q or Q unless the platform C supports
424   long long (or, on Windows, __int64). */
425
426#ifdef HAVE_LONG_LONG
427
428static PyObject *
429nu_longlong(const char *p, const formatdef *f)
430{
431    PY_LONG_LONG x;
432    memcpy((char *)&x, p, sizeof x);
433    if (x >= LONG_MIN && x <= LONG_MAX)
434        return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
435    return PyLong_FromLongLong(x);
436}
437
438static PyObject *
439nu_ulonglong(const char *p, const formatdef *f)
440{
441    unsigned PY_LONG_LONG x;
442    memcpy((char *)&x, p, sizeof x);
443    if (x <= LONG_MAX)
444        return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
445    return PyLong_FromUnsignedLongLong(x);
446}
447
448#endif
449
450static PyObject *
451nu_bool(const char *p, const formatdef *f)
452{
453    BOOL_TYPE x;
454    memcpy((char *)&x, p, sizeof x);
455    return PyBool_FromLong(x != 0);
456}
457
458
459static PyObject *
460nu_float(const char *p, const formatdef *f)
461{
462    float x;
463    memcpy((char *)&x, p, sizeof x);
464    return PyFloat_FromDouble((double)x);
465}
466
467static PyObject *
468nu_double(const char *p, const formatdef *f)
469{
470    double x;
471    memcpy((char *)&x, p, sizeof x);
472    return PyFloat_FromDouble(x);
473}
474
475static PyObject *
476nu_void_p(const char *p, const formatdef *f)
477{
478    void *x;
479    memcpy((char *)&x, p, sizeof x);
480    return PyLong_FromVoidPtr(x);
481}
482
483static int
484np_byte(char *p, PyObject *v, const formatdef *f)
485{
486    long x;
487    if (get_long(v, &x) < 0)
488        return -1;
489    if (x < -128 || x > 127){
490        PyErr_SetString(StructError,
491                        "byte format requires -128 <= number <= 127");
492        return -1;
493    }
494    *p = (char)x;
495    return 0;
496}
497
498static int
499np_ubyte(char *p, PyObject *v, const formatdef *f)
500{
501    long x;
502    if (get_long(v, &x) < 0)
503        return -1;
504    if (x < 0 || x > 255){
505        PyErr_SetString(StructError,
506                        "ubyte format requires 0 <= number <= 255");
507        return -1;
508    }
509    *p = (char)x;
510    return 0;
511}
512
513static int
514np_char(char *p, PyObject *v, const formatdef *f)
515{
516    if (!PyString_Check(v) || PyString_Size(v) != 1) {
517        PyErr_SetString(StructError,
518                        "char format require string of length 1");
519        return -1;
520    }
521    *p = *PyString_AsString(v);
522    return 0;
523}
524
525static int
526np_short(char *p, PyObject *v, const formatdef *f)
527{
528    long x;
529    short y;
530    if (get_long(v, &x) < 0)
531        return -1;
532    if (x < SHRT_MIN || x > SHRT_MAX){
533        PyErr_SetString(StructError,
534                        "short format requires " STRINGIFY(SHRT_MIN)
535                        " <= number <= " STRINGIFY(SHRT_MAX));
536        return -1;
537    }
538    y = (short)x;
539    memcpy(p, (char *)&y, sizeof y);
540    return 0;
541}
542
543static int
544np_ushort(char *p, PyObject *v, const formatdef *f)
545{
546    long x;
547    unsigned short y;
548    if (get_long(v, &x) < 0)
549        return -1;
550    if (x < 0 || x > USHRT_MAX){
551        PyErr_SetString(StructError,
552                        "ushort format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
553        return -1;
554    }
555    y = (unsigned short)x;
556    memcpy(p, (char *)&y, sizeof y);
557    return 0;
558}
559
560static int
561np_int(char *p, PyObject *v, const formatdef *f)
562{
563    long x;
564    int y;
565    if (get_long(v, &x) < 0)
566        return -1;
567#if (SIZEOF_LONG > SIZEOF_INT)
568    if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
569        return _range_error(f, 0);
570#endif
571    y = (int)x;
572    memcpy(p, (char *)&y, sizeof y);
573    return 0;
574}
575
576static int
577np_uint(char *p, PyObject *v, const formatdef *f)
578{
579    unsigned long x;
580    unsigned int y;
581    if (get_ulong(v, &x) < 0)
582        return -1;
583    y = (unsigned int)x;
584#if (SIZEOF_LONG > SIZEOF_INT)
585    if (x > ((unsigned long)UINT_MAX))
586        return _range_error(f, 1);
587#endif
588    memcpy(p, (char *)&y, sizeof y);
589    return 0;
590}
591
592static int
593np_long(char *p, PyObject *v, const formatdef *f)
594{
595    long x;
596    if (get_long(v, &x) < 0)
597        return -1;
598    memcpy(p, (char *)&x, sizeof x);
599    return 0;
600}
601
602static int
603np_ulong(char *p, PyObject *v, const formatdef *f)
604{
605    unsigned long x;
606    if (get_ulong(v, &x) < 0)
607        return -1;
608    memcpy(p, (char *)&x, sizeof x);
609    return 0;
610}
611
612#ifdef HAVE_LONG_LONG
613
614static int
615np_longlong(char *p, PyObject *v, const formatdef *f)
616{
617    PY_LONG_LONG x;
618    if (get_longlong(v, &x) < 0)
619        return -1;
620    memcpy(p, (char *)&x, sizeof x);
621    return 0;
622}
623
624static int
625np_ulonglong(char *p, PyObject *v, const formatdef *f)
626{
627    unsigned PY_LONG_LONG x;
628    if (get_ulonglong(v, &x) < 0)
629        return -1;
630    memcpy(p, (char *)&x, sizeof x);
631    return 0;
632}
633#endif
634
635
636static int
637np_bool(char *p, PyObject *v, const formatdef *f)
638{
639    int y;
640    BOOL_TYPE x;
641    y = PyObject_IsTrue(v);
642    if (y < 0)
643        return -1;
644    x = y;
645    memcpy(p, (char *)&x, sizeof x);
646    return 0;
647}
648
649static int
650np_float(char *p, PyObject *v, const formatdef *f)
651{
652    float x = (float)PyFloat_AsDouble(v);
653    if (x == -1 && PyErr_Occurred()) {
654        PyErr_SetString(StructError,
655                        "required argument is not a float");
656        return -1;
657    }
658    memcpy(p, (char *)&x, sizeof x);
659    return 0;
660}
661
662static int
663np_double(char *p, PyObject *v, const formatdef *f)
664{
665    double x = PyFloat_AsDouble(v);
666    if (x == -1 && PyErr_Occurred()) {
667        PyErr_SetString(StructError,
668                        "required argument is not a float");
669        return -1;
670    }
671    memcpy(p, (char *)&x, sizeof(double));
672    return 0;
673}
674
675static int
676np_void_p(char *p, PyObject *v, const formatdef *f)
677{
678    void *x;
679
680    v = get_pylong(v);
681    if (v == NULL)
682        return -1;
683    assert(PyLong_Check(v));
684    x = PyLong_AsVoidPtr(v);
685    Py_DECREF(v);
686    if (x == NULL && PyErr_Occurred())
687        return -1;
688    memcpy(p, (char *)&x, sizeof x);
689    return 0;
690}
691
692static formatdef native_table[] = {
693    {'x',       sizeof(char),   0,              NULL},
694    {'b',       sizeof(char),   0,              nu_byte,        np_byte},
695    {'B',       sizeof(char),   0,              nu_ubyte,       np_ubyte},
696    {'c',       sizeof(char),   0,              nu_char,        np_char},
697    {'s',       sizeof(char),   0,              NULL},
698    {'p',       sizeof(char),   0,              NULL},
699    {'h',       sizeof(short),  SHORT_ALIGN,    nu_short,       np_short},
700    {'H',       sizeof(short),  SHORT_ALIGN,    nu_ushort,      np_ushort},
701    {'i',       sizeof(int),    INT_ALIGN,      nu_int,         np_int},
702    {'I',       sizeof(int),    INT_ALIGN,      nu_uint,        np_uint},
703    {'l',       sizeof(long),   LONG_ALIGN,     nu_long,        np_long},
704    {'L',       sizeof(long),   LONG_ALIGN,     nu_ulong,       np_ulong},
705#ifdef HAVE_LONG_LONG
706    {'q',       sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
707    {'Q',       sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
708#endif
709    {'?',       sizeof(BOOL_TYPE),      BOOL_ALIGN,     nu_bool,        np_bool},
710    {'f',       sizeof(float),  FLOAT_ALIGN,    nu_float,       np_float},
711    {'d',       sizeof(double), DOUBLE_ALIGN,   nu_double,      np_double},
712    {'P',       sizeof(void *), VOID_P_ALIGN,   nu_void_p,      np_void_p},
713    {0}
714};
715
716/* Big-endian routines. *****************************************************/
717
718static PyObject *
719bu_int(const char *p, const formatdef *f)
720{
721    long x = 0;
722    Py_ssize_t i = f->size;
723    const unsigned char *bytes = (const unsigned char *)p;
724    do {
725        x = (x<<8) | *bytes++;
726    } while (--i > 0);
727    /* Extend the sign bit. */
728    if (SIZEOF_LONG > f->size)
729        x |= -(x & (1L << ((8 * f->size) - 1)));
730    return PyInt_FromLong(x);
731}
732
733static PyObject *
734bu_uint(const char *p, const formatdef *f)
735{
736    unsigned long x = 0;
737    Py_ssize_t i = f->size;
738    const unsigned char *bytes = (const unsigned char *)p;
739    do {
740        x = (x<<8) | *bytes++;
741    } while (--i > 0);
742    if (x <= LONG_MAX)
743        return PyInt_FromLong((long)x);
744    return PyLong_FromUnsignedLong(x);
745}
746
747static PyObject *
748bu_longlong(const char *p, const formatdef *f)
749{
750#ifdef HAVE_LONG_LONG
751    PY_LONG_LONG x = 0;
752    Py_ssize_t i = f->size;
753    const unsigned char *bytes = (const unsigned char *)p;
754    do {
755        x = (x<<8) | *bytes++;
756    } while (--i > 0);
757    /* Extend the sign bit. */
758    if (SIZEOF_LONG_LONG > f->size)
759        x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
760    if (x >= LONG_MIN && x <= LONG_MAX)
761        return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
762    return PyLong_FromLongLong(x);
763#else
764    return _PyLong_FromByteArray((const unsigned char *)p,
765                                  8,
766                                  0, /* little-endian */
767                      1  /* signed */);
768#endif
769}
770
771static PyObject *
772bu_ulonglong(const char *p, const formatdef *f)
773{
774#ifdef HAVE_LONG_LONG
775    unsigned PY_LONG_LONG x = 0;
776    Py_ssize_t i = f->size;
777    const unsigned char *bytes = (const unsigned char *)p;
778    do {
779        x = (x<<8) | *bytes++;
780    } while (--i > 0);
781    if (x <= LONG_MAX)
782        return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
783    return PyLong_FromUnsignedLongLong(x);
784#else
785    return _PyLong_FromByteArray((const unsigned char *)p,
786                                  8,
787                                  0, /* little-endian */
788                      0  /* signed */);
789#endif
790}
791
792static PyObject *
793bu_float(const char *p, const formatdef *f)
794{
795    return unpack_float(p, 0);
796}
797
798static PyObject *
799bu_double(const char *p, const formatdef *f)
800{
801    return unpack_double(p, 0);
802}
803
804static PyObject *
805bu_bool(const char *p, const formatdef *f)
806{
807    char x;
808    memcpy((char *)&x, p, sizeof x);
809    return PyBool_FromLong(x != 0);
810}
811
812static int
813bp_int(char *p, PyObject *v, const formatdef *f)
814{
815    long x;
816    Py_ssize_t i;
817    if (get_long(v, &x) < 0)
818        return -1;
819    i = f->size;
820    if (i != SIZEOF_LONG) {
821        if ((i == 2) && (x < -32768 || x > 32767))
822            return _range_error(f, 0);
823#if (SIZEOF_LONG != 4)
824        else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
825            return _range_error(f, 0);
826#endif
827    }
828    do {
829        p[--i] = (char)x;
830        x >>= 8;
831    } while (i > 0);
832    return 0;
833}
834
835static int
836bp_uint(char *p, PyObject *v, const formatdef *f)
837{
838    unsigned long x;
839    Py_ssize_t i;
840    if (get_ulong(v, &x) < 0)
841        return -1;
842    i = f->size;
843    if (i != SIZEOF_LONG) {
844        unsigned long maxint = 1;
845        maxint <<= (unsigned long)(i * 8);
846        if (x >= maxint)
847            return _range_error(f, 1);
848    }
849    do {
850        p[--i] = (char)x;
851        x >>= 8;
852    } while (i > 0);
853    return 0;
854}
855
856static int
857bp_longlong(char *p, PyObject *v, const formatdef *f)
858{
859    int res;
860    v = get_pylong(v);
861    if (v == NULL)
862        return -1;
863    res = _PyLong_AsByteArray((PyLongObject *)v,
864                              (unsigned char *)p,
865                              8,
866                              0, /* little_endian */
867                  1  /* signed */);
868    Py_DECREF(v);
869    return res;
870}
871
872static int
873bp_ulonglong(char *p, PyObject *v, const formatdef *f)
874{
875    int res;
876    v = get_pylong(v);
877    if (v == NULL)
878        return -1;
879    res = _PyLong_AsByteArray((PyLongObject *)v,
880                              (unsigned char *)p,
881                              8,
882                              0, /* little_endian */
883                  0  /* signed */);
884    Py_DECREF(v);
885    return res;
886}
887
888static int
889bp_float(char *p, PyObject *v, const formatdef *f)
890{
891    double x = PyFloat_AsDouble(v);
892    if (x == -1 && PyErr_Occurred()) {
893        PyErr_SetString(StructError,
894                        "required argument is not a float");
895        return -1;
896    }
897    return _PyFloat_Pack4(x, (unsigned char *)p, 0);
898}
899
900static int
901bp_double(char *p, PyObject *v, const formatdef *f)
902{
903    double x = PyFloat_AsDouble(v);
904    if (x == -1 && PyErr_Occurred()) {
905        PyErr_SetString(StructError,
906                        "required argument is not a float");
907        return -1;
908    }
909    return _PyFloat_Pack8(x, (unsigned char *)p, 0);
910}
911
912static int
913bp_bool(char *p, PyObject *v, const formatdef *f)
914{
915    int y;
916    y = PyObject_IsTrue(v);
917    if (y < 0)
918        return -1;
919    *p = (char)y;
920    return 0;
921}
922
923static formatdef bigendian_table[] = {
924    {'x',       1,              0,              NULL},
925    {'b',       1,              0,              nu_byte,        np_byte},
926    {'B',       1,              0,              nu_ubyte,       np_ubyte},
927    {'c',       1,              0,              nu_char,        np_char},
928    {'s',       1,              0,              NULL},
929    {'p',       1,              0,              NULL},
930    {'h',       2,              0,              bu_int,         bp_int},
931    {'H',       2,              0,              bu_uint,        bp_uint},
932    {'i',       4,              0,              bu_int,         bp_int},
933    {'I',       4,              0,              bu_uint,        bp_uint},
934    {'l',       4,              0,              bu_int,         bp_int},
935    {'L',       4,              0,              bu_uint,        bp_uint},
936    {'q',       8,              0,              bu_longlong,    bp_longlong},
937    {'Q',       8,              0,              bu_ulonglong,   bp_ulonglong},
938    {'?',       1,              0,              bu_bool,        bp_bool},
939    {'f',       4,              0,              bu_float,       bp_float},
940    {'d',       8,              0,              bu_double,      bp_double},
941    {0}
942};
943
944/* Little-endian routines. *****************************************************/
945
946static PyObject *
947lu_int(const char *p, const formatdef *f)
948{
949    long x = 0;
950    Py_ssize_t i = f->size;
951    const unsigned char *bytes = (const unsigned char *)p;
952    do {
953        x = (x<<8) | bytes[--i];
954    } while (i > 0);
955    /* Extend the sign bit. */
956    if (SIZEOF_LONG > f->size)
957        x |= -(x & (1L << ((8 * f->size) - 1)));
958    return PyInt_FromLong(x);
959}
960
961static PyObject *
962lu_uint(const char *p, const formatdef *f)
963{
964    unsigned long x = 0;
965    Py_ssize_t i = f->size;
966    const unsigned char *bytes = (const unsigned char *)p;
967    do {
968        x = (x<<8) | bytes[--i];
969    } while (i > 0);
970    if (x <= LONG_MAX)
971        return PyInt_FromLong((long)x);
972    return PyLong_FromUnsignedLong((long)x);
973}
974
975static PyObject *
976lu_longlong(const char *p, const formatdef *f)
977{
978#ifdef HAVE_LONG_LONG
979    PY_LONG_LONG x = 0;
980    Py_ssize_t i = f->size;
981    const unsigned char *bytes = (const unsigned char *)p;
982    do {
983        x = (x<<8) | bytes[--i];
984    } while (i > 0);
985    /* Extend the sign bit. */
986    if (SIZEOF_LONG_LONG > f->size)
987        x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
988    if (x >= LONG_MIN && x <= LONG_MAX)
989        return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
990    return PyLong_FromLongLong(x);
991#else
992    return _PyLong_FromByteArray((const unsigned char *)p,
993                                  8,
994                                  1, /* little-endian */
995                      1  /* signed */);
996#endif
997}
998
999static PyObject *
1000lu_ulonglong(const char *p, const formatdef *f)
1001{
1002#ifdef HAVE_LONG_LONG
1003    unsigned PY_LONG_LONG x = 0;
1004    Py_ssize_t i = f->size;
1005    const unsigned char *bytes = (const unsigned char *)p;
1006    do {
1007        x = (x<<8) | bytes[--i];
1008    } while (i > 0);
1009    if (x <= LONG_MAX)
1010        return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
1011    return PyLong_FromUnsignedLongLong(x);
1012#else
1013    return _PyLong_FromByteArray((const unsigned char *)p,
1014                                  8,
1015                                  1, /* little-endian */
1016                      0  /* signed */);
1017#endif
1018}
1019
1020static PyObject *
1021lu_float(const char *p, const formatdef *f)
1022{
1023    return unpack_float(p, 1);
1024}
1025
1026static PyObject *
1027lu_double(const char *p, const formatdef *f)
1028{
1029    return unpack_double(p, 1);
1030}
1031
1032static int
1033lp_int(char *p, PyObject *v, const formatdef *f)
1034{
1035    long x;
1036    Py_ssize_t i;
1037    if (get_long(v, &x) < 0)
1038        return -1;
1039    i = f->size;
1040    if (i != SIZEOF_LONG) {
1041        if ((i == 2) && (x < -32768 || x > 32767))
1042            return _range_error(f, 0);
1043#if (SIZEOF_LONG != 4)
1044        else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
1045            return _range_error(f, 0);
1046#endif
1047    }
1048    do {
1049        *p++ = (char)x;
1050        x >>= 8;
1051    } while (--i > 0);
1052    return 0;
1053}
1054
1055static int
1056lp_uint(char *p, PyObject *v, const formatdef *f)
1057{
1058    unsigned long x;
1059    Py_ssize_t i;
1060    if (get_ulong(v, &x) < 0)
1061        return -1;
1062    i = f->size;
1063    if (i != SIZEOF_LONG) {
1064        unsigned long maxint = 1;
1065        maxint <<= (unsigned long)(i * 8);
1066        if (x >= maxint)
1067            return _range_error(f, 1);
1068    }
1069    do {
1070        *p++ = (char)x;
1071        x >>= 8;
1072    } while (--i > 0);
1073    return 0;
1074}
1075
1076static int
1077lp_longlong(char *p, PyObject *v, const formatdef *f)
1078{
1079    int res;
1080    v = get_pylong(v);
1081    if (v == NULL)
1082        return -1;
1083    res = _PyLong_AsByteArray((PyLongObject*)v,
1084                              (unsigned char *)p,
1085                              8,
1086                              1, /* little_endian */
1087                  1  /* signed */);
1088    Py_DECREF(v);
1089    return res;
1090}
1091
1092static int
1093lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1094{
1095    int res;
1096    v = get_pylong(v);
1097    if (v == NULL)
1098        return -1;
1099    res = _PyLong_AsByteArray((PyLongObject*)v,
1100                              (unsigned char *)p,
1101                              8,
1102                              1, /* little_endian */
1103                  0  /* signed */);
1104    Py_DECREF(v);
1105    return res;
1106}
1107
1108static int
1109lp_float(char *p, PyObject *v, const formatdef *f)
1110{
1111    double x = PyFloat_AsDouble(v);
1112    if (x == -1 && PyErr_Occurred()) {
1113        PyErr_SetString(StructError,
1114                        "required argument is not a float");
1115        return -1;
1116    }
1117    return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1118}
1119
1120static int
1121lp_double(char *p, PyObject *v, const formatdef *f)
1122{
1123    double x = PyFloat_AsDouble(v);
1124    if (x == -1 && PyErr_Occurred()) {
1125        PyErr_SetString(StructError,
1126                        "required argument is not a float");
1127        return -1;
1128    }
1129    return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1130}
1131
1132static formatdef lilendian_table[] = {
1133    {'x',       1,              0,              NULL},
1134    {'b',       1,              0,              nu_byte,        np_byte},
1135    {'B',       1,              0,              nu_ubyte,       np_ubyte},
1136    {'c',       1,              0,              nu_char,        np_char},
1137    {'s',       1,              0,              NULL},
1138    {'p',       1,              0,              NULL},
1139    {'h',       2,              0,              lu_int,         lp_int},
1140    {'H',       2,              0,              lu_uint,        lp_uint},
1141    {'i',       4,              0,              lu_int,         lp_int},
1142    {'I',       4,              0,              lu_uint,        lp_uint},
1143    {'l',       4,              0,              lu_int,         lp_int},
1144    {'L',       4,              0,              lu_uint,        lp_uint},
1145    {'q',       8,              0,              lu_longlong,    lp_longlong},
1146    {'Q',       8,              0,              lu_ulonglong,   lp_ulonglong},
1147    {'?',       1,              0,              bu_bool,        bp_bool}, /* Std rep not endian dep,
1148        but potentially different from native rep -- reuse bx_bool funcs. */
1149    {'f',       4,              0,              lu_float,       lp_float},
1150    {'d',       8,              0,              lu_double,      lp_double},
1151    {0}
1152};
1153
1154
1155static const formatdef *
1156whichtable(char **pfmt)
1157{
1158    const char *fmt = (*pfmt)++; /* May be backed out of later */
1159    switch (*fmt) {
1160    case '<':
1161        return lilendian_table;
1162    case '>':
1163    case '!': /* Network byte order is big-endian */
1164        return bigendian_table;
1165    case '=': { /* Host byte order -- different from native in alignment! */
1166        int n = 1;
1167        char *p = (char *) &n;
1168        if (*p == 1)
1169            return lilendian_table;
1170        else
1171            return bigendian_table;
1172    }
1173    default:
1174        --*pfmt; /* Back out of pointer increment */
1175        /* Fall through */
1176    case '@':
1177        return native_table;
1178    }
1179}
1180
1181
1182/* Get the table entry for a format code */
1183
1184static const formatdef *
1185getentry(int c, const formatdef *f)
1186{
1187    for (; f->format != '\0'; f++) {
1188        if (f->format == c) {
1189            return f;
1190        }
1191    }
1192    PyErr_SetString(StructError, "bad char in struct format");
1193    return NULL;
1194}
1195
1196
1197/* Align a size according to a format code.  Return -1 on overflow. */
1198
1199static Py_ssize_t
1200align(Py_ssize_t size, char c, const formatdef *e)
1201{
1202    Py_ssize_t extra;
1203
1204    if (e->format == c) {
1205        if (e->alignment && size > 0) {
1206            extra = (e->alignment - 1) - (size - 1) % (e->alignment);
1207            if (extra > PY_SSIZE_T_MAX - size)
1208                return -1;
1209            size += extra;
1210        }
1211    }
1212    return size;
1213}
1214
1215
1216/* calculate the size of a format string */
1217
1218static int
1219prepare_s(PyStructObject *self)
1220{
1221    const formatdef *f;
1222    const formatdef *e;
1223    formatcode *codes;
1224
1225    const char *s;
1226    const char *fmt;
1227    char c;
1228    Py_ssize_t size, len, num, itemsize;
1229
1230    fmt = PyString_AS_STRING(self->s_format);
1231
1232    f = whichtable((char **)&fmt);
1233
1234    s = fmt;
1235    size = 0;
1236    len = 0;
1237    while ((c = *s++) != '\0') {
1238        if (isspace(Py_CHARMASK(c)))
1239            continue;
1240        if ('0' <= c && c <= '9') {
1241            num = c - '0';
1242            while ('0' <= (c = *s++) && c <= '9') {
1243                /* overflow-safe version of
1244                   if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1245                if (num >= PY_SSIZE_T_MAX / 10 && (
1246                        num > PY_SSIZE_T_MAX / 10 ||
1247                        (c - '0') > PY_SSIZE_T_MAX % 10))
1248                    goto overflow;
1249                num = num*10 + (c - '0');
1250            }
1251            if (c == '\0')
1252                break;
1253        }
1254        else
1255            num = 1;
1256
1257        e = getentry(c, f);
1258        if (e == NULL)
1259            return -1;
1260
1261        switch (c) {
1262            case 's': /* fall through */
1263            case 'p': len++; break;
1264            case 'x': break;
1265            default: len += num; break;
1266        }
1267
1268        itemsize = e->size;
1269        size = align(size, c, e);
1270        if (size == -1)
1271            goto overflow;
1272
1273        /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1274        if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1275            goto overflow;
1276        size += num * itemsize;
1277    }
1278
1279    /* check for overflow */
1280    if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {
1281        PyErr_NoMemory();
1282        return -1;
1283    }
1284
1285    self->s_size = size;
1286    self->s_len = len;
1287    codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1288    if (codes == NULL) {
1289        PyErr_NoMemory();
1290        return -1;
1291    }
1292    /* Free any s_codes value left over from a previous initialization. */
1293    if (self->s_codes != NULL)
1294        PyMem_FREE(self->s_codes);
1295    self->s_codes = codes;
1296
1297    s = fmt;
1298    size = 0;
1299    while ((c = *s++) != '\0') {
1300        if (isspace(Py_CHARMASK(c)))
1301            continue;
1302        if ('0' <= c && c <= '9') {
1303            num = c - '0';
1304            while ('0' <= (c = *s++) && c <= '9')
1305                num = num*10 + (c - '0');
1306            if (c == '\0')
1307                break;
1308        }
1309        else
1310            num = 1;
1311
1312        e = getentry(c, f);
1313
1314        size = align(size, c, e);
1315        if (c == 's' || c == 'p') {
1316            codes->offset = size;
1317            codes->size = num;
1318            codes->fmtdef = e;
1319            codes++;
1320            size += num;
1321        } else if (c == 'x') {
1322            size += num;
1323        } else {
1324            while (--num >= 0) {
1325                codes->offset = size;
1326                codes->size = e->size;
1327                codes->fmtdef = e;
1328                codes++;
1329                size += e->size;
1330            }
1331        }
1332    }
1333    codes->fmtdef = NULL;
1334    codes->offset = size;
1335    codes->size = 0;
1336
1337    return 0;
1338
1339  overflow:
1340    PyErr_SetString(StructError,
1341                    "total struct size too long");
1342    return -1;
1343}
1344
1345static PyObject *
1346s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1347{
1348    PyObject *self;
1349
1350    assert(type != NULL && type->tp_alloc != NULL);
1351
1352    self = type->tp_alloc(type, 0);
1353    if (self != NULL) {
1354        PyStructObject *s = (PyStructObject*)self;
1355        Py_INCREF(Py_None);
1356        s->s_format = Py_None;
1357        s->s_codes = NULL;
1358        s->s_size = -1;
1359        s->s_len = -1;
1360    }
1361    return self;
1362}
1363
1364static int
1365s_init(PyObject *self, PyObject *args, PyObject *kwds)
1366{
1367    PyStructObject *soself = (PyStructObject *)self;
1368    PyObject *o_format = NULL;
1369    int ret = 0;
1370    static char *kwlist[] = {"format", 0};
1371
1372    assert(PyStruct_Check(self));
1373
1374    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Struct", kwlist,
1375                                     &o_format))
1376        return -1;
1377
1378    if (PyString_Check(o_format)) {
1379        Py_INCREF(o_format);
1380        Py_CLEAR(soself->s_format);
1381        soself->s_format = o_format;
1382    }
1383    else if (PyUnicode_Check(o_format)) {
1384        PyObject *str = PyUnicode_AsEncodedString(o_format, "ascii", NULL);
1385        if (str == NULL)
1386            return -1;
1387        Py_CLEAR(soself->s_format);
1388        soself->s_format = str;
1389    }
1390    else {
1391        PyErr_Format(PyExc_TypeError,
1392                     "Struct() argument 1 must be string, not %s",
1393                     Py_TYPE(o_format)->tp_name);
1394        return -1;
1395    }
1396
1397    ret = prepare_s(soself);
1398    return ret;
1399}
1400
1401static void
1402s_dealloc(PyStructObject *s)
1403{
1404    if (s->weakreflist != NULL)
1405        PyObject_ClearWeakRefs((PyObject *)s);
1406    if (s->s_codes != NULL) {
1407        PyMem_FREE(s->s_codes);
1408    }
1409    Py_XDECREF(s->s_format);
1410    Py_TYPE(s)->tp_free((PyObject *)s);
1411}
1412
1413static PyObject *
1414s_unpack_internal(PyStructObject *soself, char *startfrom) {
1415    formatcode *code;
1416    Py_ssize_t i = 0;
1417    PyObject *result = PyTuple_New(soself->s_len);
1418    if (result == NULL)
1419        return NULL;
1420
1421    for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1422        PyObject *v;
1423        const formatdef *e = code->fmtdef;
1424        const char *res = startfrom + code->offset;
1425        if (e->format == 's') {
1426            v = PyString_FromStringAndSize(res, code->size);
1427        } else if (e->format == 'p') {
1428            Py_ssize_t n = *(unsigned char*)res;
1429            if (n >= code->size)
1430                n = code->size - 1;
1431            v = PyString_FromStringAndSize(res + 1, n);
1432        } else {
1433            v = e->unpack(res, e);
1434        }
1435        if (v == NULL)
1436            goto fail;
1437        PyTuple_SET_ITEM(result, i++, v);
1438    }
1439
1440    return result;
1441fail:
1442    Py_DECREF(result);
1443    return NULL;
1444}
1445
1446
1447PyDoc_STRVAR(s_unpack__doc__,
1448"S.unpack(str) -> (v1, v2, ...)\n\
1449\n\
1450Return tuple containing values unpacked according to this Struct's format.\n\
1451Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1452strings.");
1453
1454static PyObject *
1455s_unpack(PyObject *self, PyObject *inputstr)
1456{
1457    Py_buffer buf;
1458    char *start;
1459    Py_ssize_t len;
1460    PyObject *args=NULL, *result;
1461    PyStructObject *soself = (PyStructObject *)self;
1462    assert(PyStruct_Check(self));
1463    assert(soself->s_codes != NULL);
1464    if (inputstr == NULL)
1465        goto fail;
1466    if (PyString_Check(inputstr) &&
1467        PyString_GET_SIZE(inputstr) == soself->s_size) {
1468            return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1469    }
1470    args = PyTuple_Pack(1, inputstr);
1471    if (args == NULL)
1472        return NULL;
1473    if (!PyArg_ParseTuple(args, "s*:unpack", &buf))
1474        goto fail;
1475    start = buf.buf;
1476    len = buf.len;
1477    if (soself->s_size != len) {
1478        PyBuffer_Release(&buf);
1479        goto fail;
1480    }
1481    result = s_unpack_internal(soself, start);
1482    Py_DECREF(args);
1483    PyBuffer_Release(&buf);
1484    return result;
1485
1486fail:
1487    Py_XDECREF(args);
1488    PyErr_Format(StructError,
1489        "unpack requires a string argument of length %zd",
1490        soself->s_size);
1491    return NULL;
1492}
1493
1494PyDoc_STRVAR(s_unpack_from__doc__,
1495"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1496\n\
1497Return tuple containing values unpacked according to this Struct's format.\n\
1498Unlike unpack, unpack_from can unpack values from any object supporting\n\
1499the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1500See struct.__doc__ for more on format strings.");
1501
1502static PyObject *
1503s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1504{
1505    static char *kwlist[] = {"buffer", "offset", 0};
1506    static char *fmt = "z*|n:unpack_from";
1507    Py_buffer buf;
1508    Py_ssize_t buffer_len = 0, offset = 0;
1509    char *buffer = NULL;
1510    PyStructObject *soself = (PyStructObject *)self;
1511    PyObject *result;
1512    assert(PyStruct_Check(self));
1513    assert(soself->s_codes != NULL);
1514
1515    if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1516                                     &buf, &offset))
1517        return NULL;
1518    buffer = buf.buf;
1519    buffer_len = buf.len;
1520    if (buffer == NULL) {
1521        PyErr_Format(StructError,
1522            "unpack_from requires a buffer argument");
1523        PyBuffer_Release(&buf);
1524        return NULL;
1525    }
1526
1527    if (offset < 0)
1528        offset += buffer_len;
1529
1530    if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1531        PyErr_Format(StructError,
1532            "unpack_from requires a buffer of at least %zd bytes",
1533            soself->s_size);
1534        PyBuffer_Release(&buf);
1535        return NULL;
1536    }
1537    result = s_unpack_internal(soself, buffer + offset);
1538    PyBuffer_Release(&buf);
1539    return result;
1540}
1541
1542
1543/*
1544 * Guts of the pack function.
1545 *
1546 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1547 * argument for where to start processing the arguments for packing, and a
1548 * character buffer for writing the packed string.  The caller must insure
1549 * that the buffer may contain the required length for packing the arguments.
1550 * 0 is returned on success, 1 is returned if there is an error.
1551 *
1552 */
1553static int
1554s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1555{
1556    formatcode *code;
1557    /* XXX(nnorwitz): why does i need to be a local?  can we use
1558       the offset parameter or do we need the wider width? */
1559    Py_ssize_t i;
1560
1561    memset(buf, '\0', soself->s_size);
1562    i = offset;
1563    for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1564        Py_ssize_t n;
1565        PyObject *v = PyTuple_GET_ITEM(args, i++);
1566        const formatdef *e = code->fmtdef;
1567        char *res = buf + code->offset;
1568        if (e->format == 's') {
1569            if (!PyString_Check(v)) {
1570                PyErr_SetString(StructError,
1571                                "argument for 's' must "
1572                                "be a string");
1573                return -1;
1574            }
1575            n = PyString_GET_SIZE(v);
1576            if (n > code->size)
1577                n = code->size;
1578            if (n > 0)
1579                memcpy(res, PyString_AS_STRING(v), n);
1580        } else if (e->format == 'p') {
1581            if (!PyString_Check(v)) {
1582                PyErr_SetString(StructError,
1583                                "argument for 'p' must "
1584                                "be a string");
1585                return -1;
1586            }
1587            n = PyString_GET_SIZE(v);
1588            if (n > (code->size - 1))
1589                n = code->size - 1;
1590            if (n > 0)
1591                memcpy(res + 1, PyString_AS_STRING(v), n);
1592            if (n > 255)
1593                n = 255;
1594            *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1595        } else if (e->pack(res, v, e) < 0) {
1596            if (strchr(integer_codes, e->format) != NULL &&
1597                PyErr_ExceptionMatches(PyExc_OverflowError))
1598                PyErr_Format(StructError,
1599                             "integer out of range for "
1600                             "'%c' format code",
1601                             e->format);
1602            return -1;
1603        }
1604    }
1605
1606    /* Success */
1607    return 0;
1608}
1609
1610
1611PyDoc_STRVAR(s_pack__doc__,
1612"S.pack(v1, v2, ...) -> string\n\
1613\n\
1614Return a string containing values v1, v2, ... packed according to this\n\
1615Struct's format. See struct.__doc__ for more on format strings.");
1616
1617static PyObject *
1618s_pack(PyObject *self, PyObject *args)
1619{
1620    PyStructObject *soself;
1621    PyObject *result;
1622
1623    /* Validate arguments. */
1624    soself = (PyStructObject *)self;
1625    assert(PyStruct_Check(self));
1626    assert(soself->s_codes != NULL);
1627    if (PyTuple_GET_SIZE(args) != soself->s_len)
1628    {
1629        PyErr_Format(StructError,
1630            "pack expected %zd items for packing (got %zd)", soself->s_len, PyTuple_GET_SIZE(args));
1631        return NULL;
1632    }
1633
1634    /* Allocate a new string */
1635    result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1636    if (result == NULL)
1637        return NULL;
1638
1639    /* Call the guts */
1640    if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1641        Py_DECREF(result);
1642        return NULL;
1643    }
1644
1645    return result;
1646}
1647
1648PyDoc_STRVAR(s_pack_into__doc__,
1649"S.pack_into(buffer, offset, v1, v2, ...)\n\
1650\n\
1651Pack the values v1, v2, ... according to this Struct's format, write \n\
1652the packed bytes into the writable buffer buf starting at offset.  Note\n\
1653that the offset is not an optional argument.  See struct.__doc__ for \n\
1654more on format strings.");
1655
1656static PyObject *
1657s_pack_into(PyObject *self, PyObject *args)
1658{
1659    PyStructObject *soself;
1660    Py_buffer buf;
1661    Py_ssize_t offset;
1662
1663    /* Validate arguments.  +1 is for the first arg as buffer. */
1664    soself = (PyStructObject *)self;
1665    assert(PyStruct_Check(self));
1666    assert(soself->s_codes != NULL);
1667    if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
1668    {
1669        if (PyTuple_GET_SIZE(args) == 0) {
1670            PyErr_Format(StructError,
1671                        "pack_into expected buffer argument");
1672        }
1673        else if (PyTuple_GET_SIZE(args) == 1) {
1674            PyErr_Format(StructError,
1675                        "pack_into expected offset argument");
1676        }
1677        else {
1678            PyErr_Format(StructError,
1679                        "pack_into expected %zd items for packing (got %zd)",
1680                        soself->s_len, (PyTuple_GET_SIZE(args) - 2));
1681        }
1682        return NULL;
1683    }
1684
1685    /* Extract a writable memory buffer from the first argument */
1686    if (!PyArg_Parse(PyTuple_GET_ITEM(args, 0), "w*", &buf))
1687        return NULL;
1688
1689    /* Extract the offset from the first argument */
1690    offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
1691    if (offset == -1 && PyErr_Occurred()) {
1692        PyBuffer_Release(&buf);
1693        return NULL;
1694    }
1695
1696    /* Support negative offsets. */
1697    if (offset < 0)
1698        offset += buf.len;
1699
1700    /* Check boundaries */
1701    if (offset < 0 || (buf.len - offset) < soself->s_size) {
1702        PyErr_Format(StructError,
1703                     "pack_into requires a buffer of at least %zd bytes",
1704                     soself->s_size);
1705        PyBuffer_Release(&buf);
1706        return NULL;
1707    }
1708
1709    /* Call the guts */
1710    if (s_pack_internal(soself, args, 2, (char *)buf.buf + offset) != 0) {
1711        PyBuffer_Release(&buf);
1712        return NULL;
1713    }
1714    PyBuffer_Release(&buf);
1715
1716    Py_RETURN_NONE;
1717}
1718
1719static PyObject *
1720s_get_format(PyStructObject *self, void *unused)
1721{
1722    Py_INCREF(self->s_format);
1723    return self->s_format;
1724}
1725
1726static PyObject *
1727s_get_size(PyStructObject *self, void *unused)
1728{
1729    return PyInt_FromSsize_t(self->s_size);
1730}
1731
1732PyDoc_STRVAR(s_sizeof__doc__,
1733"S.__sizeof__() -> size of S in memory, in bytes");
1734
1735static PyObject *
1736s_sizeof(PyStructObject *self, void *unused)
1737{
1738    Py_ssize_t size;
1739
1740    size = sizeof(PyStructObject) + sizeof(formatcode) * (self->s_len + 1);
1741    return PyLong_FromSsize_t(size);
1742}
1743
1744/* List of functions */
1745
1746static struct PyMethodDef s_methods[] = {
1747    {"pack",            s_pack,         METH_VARARGS, s_pack__doc__},
1748    {"pack_into",       s_pack_into,    METH_VARARGS, s_pack_into__doc__},
1749    {"unpack",          s_unpack,       METH_O, s_unpack__doc__},
1750    {"unpack_from",     (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS,
1751                    s_unpack_from__doc__},
1752    {"__sizeof__",      (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
1753    {NULL,       NULL}          /* sentinel */
1754};
1755
1756PyDoc_STRVAR(s__doc__, "Compiled struct object");
1757
1758#define OFF(x) offsetof(PyStructObject, x)
1759
1760static PyGetSetDef s_getsetlist[] = {
1761    {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1762    {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1763    {NULL} /* sentinel */
1764};
1765
1766static
1767PyTypeObject PyStructType = {
1768    PyVarObject_HEAD_INIT(NULL, 0)
1769    "Struct",
1770    sizeof(PyStructObject),
1771    0,
1772    (destructor)s_dealloc,      /* tp_dealloc */
1773    0,                                          /* tp_print */
1774    0,                                          /* tp_getattr */
1775    0,                                          /* tp_setattr */
1776    0,                                          /* tp_compare */
1777    0,                                          /* tp_repr */
1778    0,                                          /* tp_as_number */
1779    0,                                          /* tp_as_sequence */
1780    0,                                          /* tp_as_mapping */
1781    0,                                          /* tp_hash */
1782    0,                                          /* tp_call */
1783    0,                                          /* tp_str */
1784    PyObject_GenericGetAttr,            /* tp_getattro */
1785    PyObject_GenericSetAttr,            /* tp_setattro */
1786    0,                                          /* tp_as_buffer */
1787    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1788    s__doc__,                           /* tp_doc */
1789    0,                                          /* tp_traverse */
1790    0,                                          /* tp_clear */
1791    0,                                          /* tp_richcompare */
1792    offsetof(PyStructObject, weakreflist),      /* tp_weaklistoffset */
1793    0,                                          /* tp_iter */
1794    0,                                          /* tp_iternext */
1795    s_methods,                          /* tp_methods */
1796    NULL,                               /* tp_members */
1797    s_getsetlist,               /* tp_getset */
1798    0,                                          /* tp_base */
1799    0,                                          /* tp_dict */
1800    0,                                          /* tp_descr_get */
1801    0,                                          /* tp_descr_set */
1802    0,                                          /* tp_dictoffset */
1803    s_init,                             /* tp_init */
1804    PyType_GenericAlloc,/* tp_alloc */
1805    s_new,                              /* tp_new */
1806    PyObject_Del,               /* tp_free */
1807};
1808
1809
1810/* ---- Standalone functions  ---- */
1811
1812#define MAXCACHE 100
1813static PyObject *cache = NULL;
1814
1815static PyObject *
1816cache_struct(PyObject *fmt)
1817{
1818    PyObject * s_object;
1819
1820    if (cache == NULL) {
1821        cache = PyDict_New();
1822        if (cache == NULL)
1823            return NULL;
1824    }
1825
1826    s_object = PyDict_GetItem(cache, fmt);
1827    if (s_object != NULL) {
1828        Py_INCREF(s_object);
1829        return s_object;
1830    }
1831
1832    s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
1833    if (s_object != NULL) {
1834        if (PyDict_Size(cache) >= MAXCACHE)
1835            PyDict_Clear(cache);
1836        /* Attempt to cache the result */
1837        if (PyDict_SetItem(cache, fmt, s_object) == -1)
1838            PyErr_Clear();
1839    }
1840    return s_object;
1841}
1842
1843PyDoc_STRVAR(clearcache_doc,
1844"Clear the internal cache.");
1845
1846static PyObject *
1847clearcache(PyObject *self)
1848{
1849    Py_CLEAR(cache);
1850    Py_RETURN_NONE;
1851}
1852
1853PyDoc_STRVAR(calcsize_doc,
1854"Return size of C struct described by format string fmt.");
1855
1856static PyObject *
1857calcsize(PyObject *self, PyObject *fmt)
1858{
1859    Py_ssize_t n;
1860    PyObject *s_object = cache_struct(fmt);
1861    if (s_object == NULL)
1862        return NULL;
1863    n = ((PyStructObject *)s_object)->s_size;
1864    Py_DECREF(s_object);
1865    return PyInt_FromSsize_t(n);
1866}
1867
1868PyDoc_STRVAR(pack_doc,
1869"Return string containing values v1, v2, ... packed according to fmt.");
1870
1871static PyObject *
1872pack(PyObject *self, PyObject *args)
1873{
1874    PyObject *s_object, *fmt, *newargs, *result;
1875    Py_ssize_t n = PyTuple_GET_SIZE(args);
1876
1877    if (n == 0) {
1878        PyErr_SetString(PyExc_TypeError, "missing format argument");
1879        return NULL;
1880    }
1881    fmt = PyTuple_GET_ITEM(args, 0);
1882    newargs = PyTuple_GetSlice(args, 1, n);
1883    if (newargs == NULL)
1884        return NULL;
1885
1886    s_object = cache_struct(fmt);
1887    if (s_object == NULL) {
1888        Py_DECREF(newargs);
1889        return NULL;
1890    }
1891    result = s_pack(s_object, newargs);
1892    Py_DECREF(newargs);
1893    Py_DECREF(s_object);
1894    return result;
1895}
1896
1897PyDoc_STRVAR(pack_into_doc,
1898"Pack the values v1, v2, ... according to fmt.\n\
1899Write the packed bytes into the writable buffer buf starting at offset.");
1900
1901static PyObject *
1902pack_into(PyObject *self, PyObject *args)
1903{
1904    PyObject *s_object, *fmt, *newargs, *result;
1905    Py_ssize_t n = PyTuple_GET_SIZE(args);
1906
1907    if (n == 0) {
1908        PyErr_SetString(PyExc_TypeError, "missing format argument");
1909        return NULL;
1910    }
1911    fmt = PyTuple_GET_ITEM(args, 0);
1912    newargs = PyTuple_GetSlice(args, 1, n);
1913    if (newargs == NULL)
1914        return NULL;
1915
1916    s_object = cache_struct(fmt);
1917    if (s_object == NULL) {
1918        Py_DECREF(newargs);
1919        return NULL;
1920    }
1921    result = s_pack_into(s_object, newargs);
1922    Py_DECREF(newargs);
1923    Py_DECREF(s_object);
1924    return result;
1925}
1926
1927PyDoc_STRVAR(unpack_doc,
1928"Unpack the string containing packed C structure data, according to fmt.\n\
1929Requires len(string) == calcsize(fmt).");
1930
1931static PyObject *
1932unpack(PyObject *self, PyObject *args)
1933{
1934    PyObject *s_object, *fmt, *inputstr, *result;
1935
1936    if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr))
1937        return NULL;
1938
1939    s_object = cache_struct(fmt);
1940    if (s_object == NULL)
1941        return NULL;
1942    result = s_unpack(s_object, inputstr);
1943    Py_DECREF(s_object);
1944    return result;
1945}
1946
1947PyDoc_STRVAR(unpack_from_doc,
1948"Unpack the buffer, containing packed C structure data, according to\n\
1949fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).");
1950
1951static PyObject *
1952unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1953{
1954    PyObject *s_object, *fmt, *newargs, *result;
1955    Py_ssize_t n = PyTuple_GET_SIZE(args);
1956
1957    if (n == 0) {
1958        PyErr_SetString(PyExc_TypeError, "missing format argument");
1959        return NULL;
1960    }
1961    fmt = PyTuple_GET_ITEM(args, 0);
1962    newargs = PyTuple_GetSlice(args, 1, n);
1963    if (newargs == NULL)
1964        return NULL;
1965
1966    s_object = cache_struct(fmt);
1967    if (s_object == NULL) {
1968        Py_DECREF(newargs);
1969        return NULL;
1970    }
1971    result = s_unpack_from(s_object, newargs, kwds);
1972    Py_DECREF(newargs);
1973    Py_DECREF(s_object);
1974    return result;
1975}
1976
1977static struct PyMethodDef module_functions[] = {
1978    {"_clearcache",     (PyCFunction)clearcache,        METH_NOARGS,    clearcache_doc},
1979    {"calcsize",        calcsize,       METH_O, calcsize_doc},
1980    {"pack",            pack,           METH_VARARGS,   pack_doc},
1981    {"pack_into",       pack_into,      METH_VARARGS,   pack_into_doc},
1982    {"unpack",          unpack, METH_VARARGS,   unpack_doc},
1983    {"unpack_from",     (PyCFunction)unpack_from,
1984                    METH_VARARGS|METH_KEYWORDS,         unpack_from_doc},
1985    {NULL,       NULL}          /* sentinel */
1986};
1987
1988
1989/* Module initialization */
1990
1991PyDoc_STRVAR(module_doc,
1992"Functions to convert between Python values and C structs represented\n\
1993as Python strings. It uses format strings (explained below) as compact\n\
1994descriptions of the lay-out of the C structs and the intended conversion\n\
1995to/from Python values.\n\
1996\n\
1997The optional first format char indicates byte order, size and alignment:\n\
1998  @: native order, size & alignment (default)\n\
1999  =: native order, std. size & alignment\n\
2000  <: little-endian, std. size & alignment\n\
2001  >: big-endian, std. size & alignment\n\
2002  !: same as >\n\
2003\n\
2004The remaining chars indicate types of args and must match exactly;\n\
2005these can be preceded by a decimal repeat count:\n\
2006  x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
2007  ?: _Bool (requires C99; if not available, char is used instead)\n\
2008  h:short; H:unsigned short; i:int; I:unsigned int;\n\
2009  l:long; L:unsigned long; f:float; d:double.\n\
2010Special cases (preceding decimal count indicates length):\n\
2011  s:string (array of char); p: pascal string (with count byte).\n\
2012Special case (only available in native format):\n\
2013  P:an integer type that is wide enough to hold a pointer.\n\
2014Special case (not in native mode unless 'long long' in platform C):\n\
2015  q:long long; Q:unsigned long long\n\
2016Whitespace between formats is ignored.\n\
2017\n\
2018The variable struct.error is an exception raised on errors.\n");
2019
2020PyMODINIT_FUNC
2021init_struct(void)
2022{
2023    PyObject *ver, *m;
2024
2025    ver = PyString_FromString("0.2");
2026    if (ver == NULL)
2027        return;
2028
2029    m = Py_InitModule3("_struct", module_functions, module_doc);
2030    if (m == NULL)
2031        return;
2032
2033    Py_TYPE(&PyStructType) = &PyType_Type;
2034    if (PyType_Ready(&PyStructType) < 0)
2035        return;
2036
2037    /* This speed trick can't be used until overflow masking goes
2038       away, because native endian always raises exceptions
2039       instead of overflow masking. */
2040
2041    /* Check endian and swap in faster functions */
2042    {
2043        int one = 1;
2044        formatdef *native = native_table;
2045        formatdef *other, *ptr;
2046        if ((int)*(unsigned char*)&one)
2047            other = lilendian_table;
2048        else
2049            other = bigendian_table;
2050        /* Scan through the native table, find a matching
2051           entry in the endian table and swap in the
2052           native implementations whenever possible
2053           (64-bit platforms may not have "standard" sizes) */
2054        while (native->format != '\0' && other->format != '\0') {
2055            ptr = other;
2056            while (ptr->format != '\0') {
2057                if (ptr->format == native->format) {
2058                    /* Match faster when formats are
2059                       listed in the same order */
2060                    if (ptr == other)
2061                        other++;
2062                    /* Only use the trick if the
2063                       size matches */
2064                    if (ptr->size != native->size)
2065                        break;
2066                    /* Skip float and double, could be
2067                       "unknown" float format */
2068                    if (ptr->format == 'd' || ptr->format == 'f')
2069                        break;
2070                    ptr->pack = native->pack;
2071                    ptr->unpack = native->unpack;
2072                    break;
2073                }
2074                ptr++;
2075            }
2076            native++;
2077        }
2078    }
2079
2080    /* Add some symbolic constants to the module */
2081    if (StructError == NULL) {
2082        StructError = PyErr_NewException("struct.error", NULL, NULL);
2083        if (StructError == NULL)
2084            return;
2085    }
2086
2087    Py_INCREF(StructError);
2088    PyModule_AddObject(m, "error", StructError);
2089
2090    Py_INCREF((PyObject*)&PyStructType);
2091    PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
2092
2093    PyModule_AddObject(m, "__version__", ver);
2094
2095    PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
2096    PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
2097}
2098