Issue #1523: Remove deprecated overflow masking in struct module, and
[python.git] / Modules / _struct.c
blob7f8198b31657ddb2826d863d67a81b7f4b0dd45e
1 /* struct module -- pack values into and (out of) strings */
3 /* New version supporting byte order, alignment and size options,
4 character strings, and unsigned numbers */
6 #define PY_SSIZE_T_CLEAN
8 #include "Python.h"
9 #include "structseq.h"
10 #include "structmember.h"
11 #include <ctype.h>
13 static PyTypeObject PyStructType;
15 /* compatibility macros */
16 #if (PY_VERSION_HEX < 0x02050000)
17 typedef int Py_ssize_t;
18 #endif
20 /* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float
21 arguments for integer formats with a warning for backwards
22 compatibility. */
24 #define PY_STRUCT_FLOAT_COERCE 1
26 #ifdef PY_STRUCT_FLOAT_COERCE
27 #define FLOAT_COERCE "integer argument expected, got float"
28 #endif
31 /* The translation function for each format character is table driven */
32 typedef struct _formatdef {
33 char format;
34 Py_ssize_t size;
35 Py_ssize_t alignment;
36 PyObject* (*unpack)(const char *,
37 const struct _formatdef *);
38 int (*pack)(char *, PyObject *,
39 const struct _formatdef *);
40 } formatdef;
42 typedef struct _formatcode {
43 const struct _formatdef *fmtdef;
44 Py_ssize_t offset;
45 Py_ssize_t size;
46 } formatcode;
48 /* Struct object interface */
50 typedef struct {
51 PyObject_HEAD
52 Py_ssize_t s_size;
53 Py_ssize_t s_len;
54 formatcode *s_codes;
55 PyObject *s_format;
56 PyObject *weakreflist; /* List of weak references */
57 } PyStructObject;
60 #define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
61 #define PyStruct_CheckExact(op) (Py_TYPE(op) == &PyStructType)
64 /* Exception */
66 static PyObject *StructError;
69 /* Define various structs to figure out the alignments of types */
72 typedef struct { char c; short x; } st_short;
73 typedef struct { char c; int x; } st_int;
74 typedef struct { char c; long x; } st_long;
75 typedef struct { char c; float x; } st_float;
76 typedef struct { char c; double x; } st_double;
77 typedef struct { char c; void *x; } st_void_p;
79 #define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
80 #define INT_ALIGN (sizeof(st_int) - sizeof(int))
81 #define LONG_ALIGN (sizeof(st_long) - sizeof(long))
82 #define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
83 #define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
84 #define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
86 /* We can't support q and Q in native mode unless the compiler does;
87 in std mode, they're 8 bytes on all platforms. */
88 #ifdef HAVE_LONG_LONG
89 typedef struct { char c; PY_LONG_LONG x; } s_long_long;
90 #define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
91 #endif
93 #ifdef HAVE_C99_BOOL
94 #define BOOL_TYPE _Bool
95 typedef struct { char c; _Bool x; } s_bool;
96 #define BOOL_ALIGN (sizeof(s_bool) - sizeof(BOOL_TYPE))
97 #else
98 #define BOOL_TYPE char
99 #define BOOL_ALIGN 0
100 #endif
102 #define STRINGIFY(x) #x
104 #ifdef __powerc
105 #pragma options align=reset
106 #endif
108 static char *integer_codes = "bBhHiIlLqQ";
110 /* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
112 static PyObject *
113 get_pylong(PyObject *v)
115 assert(v != NULL);
116 if (PyInt_Check(v))
117 return PyLong_FromLong(PyInt_AS_LONG(v));
118 if (PyLong_Check(v)) {
119 Py_INCREF(v);
120 return v;
122 #ifdef PY_STRUCT_FLOAT_COERCE
123 if (PyFloat_Check(v)) {
124 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2)<0)
125 return NULL;
126 return PyNumber_Long(v);
128 #endif
129 PyErr_SetString(StructError,
130 "cannot convert argument to long");
131 return NULL;
134 /* Helper to convert a Python object to a C long. Sets an exception
135 (struct.error for an inconvertible type, OverflowError for
136 out-of-range values) and returns -1 on error. */
138 static int
139 get_long(PyObject *v, long *p)
141 long x;
143 v = get_pylong(v);
144 if (v == NULL)
145 return -1;
146 assert(PyLong_Check(v));
147 x = PyLong_AsLong(v);
148 Py_DECREF(v);
149 if (x == (long)-1 && PyErr_Occurred())
150 return -1;
151 *p = x;
152 return 0;
155 /* Same, but handling unsigned long */
157 static int
158 get_ulong(PyObject *v, unsigned long *p)
160 unsigned long x;
162 v = get_pylong(v);
163 if (v == NULL)
164 return -1;
165 assert(PyLong_Check(v));
166 x = PyLong_AsUnsignedLong(v);
167 Py_DECREF(v);
168 if (x == (unsigned long)-1 && PyErr_Occurred())
169 return -1;
170 *p = x;
171 return 0;
174 #ifdef HAVE_LONG_LONG
176 /* Same, but handling native long long. */
178 static int
179 get_longlong(PyObject *v, PY_LONG_LONG *p)
181 PY_LONG_LONG x;
183 v = get_pylong(v);
184 if (v == NULL)
185 return -1;
186 assert(PyLong_Check(v));
187 x = PyLong_AsLongLong(v);
188 Py_DECREF(v);
189 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
190 return -1;
191 *p = x;
192 return 0;
195 /* Same, but handling native unsigned long long. */
197 static int
198 get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
200 unsigned PY_LONG_LONG x;
202 v = get_pylong(v);
203 if (v == NULL)
204 return -1;
205 assert(PyLong_Check(v));
206 x = PyLong_AsUnsignedLongLong(v);
207 Py_DECREF(v);
208 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
209 return -1;
210 *p = x;
211 return 0;
214 #endif
216 #define get_wrapped_long get_long
217 #define get_wrapped_ulong get_ulong
219 /* Floating point helpers */
221 static PyObject *
222 unpack_float(const char *p, /* start of 4-byte string */
223 int le) /* true for little-endian, false for big-endian */
225 double x;
227 x = _PyFloat_Unpack4((unsigned char *)p, le);
228 if (x == -1.0 && PyErr_Occurred())
229 return NULL;
230 return PyFloat_FromDouble(x);
233 static PyObject *
234 unpack_double(const char *p, /* start of 8-byte string */
235 int le) /* true for little-endian, false for big-endian */
237 double x;
239 x = _PyFloat_Unpack8((unsigned char *)p, le);
240 if (x == -1.0 && PyErr_Occurred())
241 return NULL;
242 return PyFloat_FromDouble(x);
245 /* Helper to format the range error exceptions */
246 static int
247 _range_error(const formatdef *f, int is_unsigned)
249 /* ulargest is the largest unsigned value with f->size bytes.
250 * Note that the simpler:
251 * ((size_t)1 << (f->size * 8)) - 1
252 * doesn't work when f->size == sizeof(size_t) because C doesn't
253 * define what happens when a left shift count is >= the number of
254 * bits in the integer being shifted; e.g., on some boxes it doesn't
255 * shift at all when they're equal.
257 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
258 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
259 if (is_unsigned)
260 PyErr_Format(StructError,
261 "'%c' format requires 0 <= number <= %zu",
262 f->format,
263 ulargest);
264 else {
265 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
266 PyErr_Format(StructError,
267 "'%c' format requires %zd <= number <= %zd",
268 f->format,
269 ~ largest,
270 largest);
272 return -1;
277 /* A large number of small routines follow, with names of the form
279 [bln][up]_TYPE
281 [bln] distiguishes among big-endian, little-endian and native.
282 [pu] distiguishes between pack (to struct) and unpack (from struct).
283 TYPE is one of char, byte, ubyte, etc.
286 /* Native mode routines. ****************************************************/
287 /* NOTE:
288 In all n[up]_<type> routines handling types larger than 1 byte, there is
289 *no* guarantee that the p pointer is properly aligned for each type,
290 therefore memcpy is called. An intermediate variable is used to
291 compensate for big-endian architectures.
292 Normally both the intermediate variable and the memcpy call will be
293 skipped by C optimisation in little-endian architectures (gcc >= 2.91
294 does this). */
296 static PyObject *
297 nu_char(const char *p, const formatdef *f)
299 return PyString_FromStringAndSize(p, 1);
302 static PyObject *
303 nu_byte(const char *p, const formatdef *f)
305 return PyInt_FromLong((long) *(signed char *)p);
308 static PyObject *
309 nu_ubyte(const char *p, const formatdef *f)
311 return PyInt_FromLong((long) *(unsigned char *)p);
314 static PyObject *
315 nu_short(const char *p, const formatdef *f)
317 short x;
318 memcpy((char *)&x, p, sizeof x);
319 return PyInt_FromLong((long)x);
322 static PyObject *
323 nu_ushort(const char *p, const formatdef *f)
325 unsigned short x;
326 memcpy((char *)&x, p, sizeof x);
327 return PyInt_FromLong((long)x);
330 static PyObject *
331 nu_int(const char *p, const formatdef *f)
333 int x;
334 memcpy((char *)&x, p, sizeof x);
335 return PyInt_FromLong((long)x);
338 static PyObject *
339 nu_uint(const char *p, const formatdef *f)
341 unsigned int x;
342 memcpy((char *)&x, p, sizeof x);
343 #if (SIZEOF_LONG > SIZEOF_INT)
344 return PyInt_FromLong((long)x);
345 #else
346 if (x <= ((unsigned int)LONG_MAX))
347 return PyInt_FromLong((long)x);
348 return PyLong_FromUnsignedLong((unsigned long)x);
349 #endif
352 static PyObject *
353 nu_long(const char *p, const formatdef *f)
355 long x;
356 memcpy((char *)&x, p, sizeof x);
357 return PyInt_FromLong(x);
360 static PyObject *
361 nu_ulong(const char *p, const formatdef *f)
363 unsigned long x;
364 memcpy((char *)&x, p, sizeof x);
365 if (x <= LONG_MAX)
366 return PyInt_FromLong((long)x);
367 return PyLong_FromUnsignedLong(x);
370 /* Native mode doesn't support q or Q unless the platform C supports
371 long long (or, on Windows, __int64). */
373 #ifdef HAVE_LONG_LONG
375 static PyObject *
376 nu_longlong(const char *p, const formatdef *f)
378 PY_LONG_LONG x;
379 memcpy((char *)&x, p, sizeof x);
380 if (x >= LONG_MIN && x <= LONG_MAX)
381 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
382 return PyLong_FromLongLong(x);
385 static PyObject *
386 nu_ulonglong(const char *p, const formatdef *f)
388 unsigned PY_LONG_LONG x;
389 memcpy((char *)&x, p, sizeof x);
390 if (x <= LONG_MAX)
391 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
392 return PyLong_FromUnsignedLongLong(x);
395 #endif
397 static PyObject *
398 nu_bool(const char *p, const formatdef *f)
400 BOOL_TYPE x;
401 memcpy((char *)&x, p, sizeof x);
402 return PyBool_FromLong(x != 0);
406 static PyObject *
407 nu_float(const char *p, const formatdef *f)
409 float x;
410 memcpy((char *)&x, p, sizeof x);
411 return PyFloat_FromDouble((double)x);
414 static PyObject *
415 nu_double(const char *p, const formatdef *f)
417 double x;
418 memcpy((char *)&x, p, sizeof x);
419 return PyFloat_FromDouble(x);
422 static PyObject *
423 nu_void_p(const char *p, const formatdef *f)
425 void *x;
426 memcpy((char *)&x, p, sizeof x);
427 return PyLong_FromVoidPtr(x);
430 static int
431 np_byte(char *p, PyObject *v, const formatdef *f)
433 long x;
434 if (get_long(v, &x) < 0)
435 return -1;
436 if (x < -128 || x > 127){
437 PyErr_SetString(StructError,
438 "byte format requires -128 <= number <= 127");
439 return -1;
441 *p = (char)x;
442 return 0;
445 static int
446 np_ubyte(char *p, PyObject *v, const formatdef *f)
448 long x;
449 if (get_long(v, &x) < 0)
450 return -1;
451 if (x < 0 || x > 255){
452 PyErr_SetString(StructError,
453 "ubyte format requires 0 <= number <= 255");
454 return -1;
456 *p = (char)x;
457 return 0;
460 static int
461 np_char(char *p, PyObject *v, const formatdef *f)
463 if (!PyString_Check(v) || PyString_Size(v) != 1) {
464 PyErr_SetString(StructError,
465 "char format require string of length 1");
466 return -1;
468 *p = *PyString_AsString(v);
469 return 0;
472 static int
473 np_short(char *p, PyObject *v, const formatdef *f)
475 long x;
476 short y;
477 if (get_long(v, &x) < 0)
478 return -1;
479 if (x < SHRT_MIN || x > SHRT_MAX){
480 PyErr_SetString(StructError,
481 "short format requires " STRINGIFY(SHRT_MIN)
482 " <= number <= " STRINGIFY(SHRT_MAX));
483 return -1;
485 y = (short)x;
486 memcpy(p, (char *)&y, sizeof y);
487 return 0;
490 static int
491 np_ushort(char *p, PyObject *v, const formatdef *f)
493 long x;
494 unsigned short y;
495 if (get_long(v, &x) < 0)
496 return -1;
497 if (x < 0 || x > USHRT_MAX){
498 PyErr_SetString(StructError,
499 "ushort format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
500 return -1;
502 y = (unsigned short)x;
503 memcpy(p, (char *)&y, sizeof y);
504 return 0;
507 static int
508 np_int(char *p, PyObject *v, const formatdef *f)
510 long x;
511 int y;
512 if (get_long(v, &x) < 0)
513 return -1;
514 #if (SIZEOF_LONG > SIZEOF_INT)
515 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
516 return _range_error(f, 0);
517 #endif
518 y = (int)x;
519 memcpy(p, (char *)&y, sizeof y);
520 return 0;
523 static int
524 np_uint(char *p, PyObject *v, const formatdef *f)
526 unsigned long x;
527 unsigned int y;
528 if (get_wrapped_ulong(v, &x) < 0)
529 return -1;
530 y = (unsigned int)x;
531 #if (SIZEOF_LONG > SIZEOF_INT)
532 if (x > ((unsigned long)UINT_MAX))
533 return _range_error(f, 1);
534 #endif
535 memcpy(p, (char *)&y, sizeof y);
536 return 0;
539 static int
540 np_long(char *p, PyObject *v, const formatdef *f)
542 long x;
543 if (get_long(v, &x) < 0)
544 return -1;
545 memcpy(p, (char *)&x, sizeof x);
546 return 0;
549 static int
550 np_ulong(char *p, PyObject *v, const formatdef *f)
552 unsigned long x;
553 if (get_wrapped_ulong(v, &x) < 0)
554 return -1;
555 memcpy(p, (char *)&x, sizeof x);
556 return 0;
559 #ifdef HAVE_LONG_LONG
561 static int
562 np_longlong(char *p, PyObject *v, const formatdef *f)
564 PY_LONG_LONG x;
565 if (get_longlong(v, &x) < 0)
566 return -1;
567 memcpy(p, (char *)&x, sizeof x);
568 return 0;
571 static int
572 np_ulonglong(char *p, PyObject *v, const formatdef *f)
574 unsigned PY_LONG_LONG x;
575 if (get_ulonglong(v, &x) < 0)
576 return -1;
577 memcpy(p, (char *)&x, sizeof x);
578 return 0;
580 #endif
583 static int
584 np_bool(char *p, PyObject *v, const formatdef *f)
586 BOOL_TYPE y;
587 y = PyObject_IsTrue(v);
588 memcpy(p, (char *)&y, sizeof y);
589 return 0;
592 static int
593 np_float(char *p, PyObject *v, const formatdef *f)
595 float x = (float)PyFloat_AsDouble(v);
596 if (x == -1 && PyErr_Occurred()) {
597 PyErr_SetString(StructError,
598 "required argument is not a float");
599 return -1;
601 memcpy(p, (char *)&x, sizeof x);
602 return 0;
605 static int
606 np_double(char *p, PyObject *v, const formatdef *f)
608 double x = PyFloat_AsDouble(v);
609 if (x == -1 && PyErr_Occurred()) {
610 PyErr_SetString(StructError,
611 "required argument is not a float");
612 return -1;
614 memcpy(p, (char *)&x, sizeof(double));
615 return 0;
618 static int
619 np_void_p(char *p, PyObject *v, const formatdef *f)
621 void *x;
623 v = get_pylong(v);
624 if (v == NULL)
625 return -1;
626 assert(PyLong_Check(v));
627 x = PyLong_AsVoidPtr(v);
628 Py_DECREF(v);
629 if (x == NULL && PyErr_Occurred())
630 return -1;
631 memcpy(p, (char *)&x, sizeof x);
632 return 0;
635 static formatdef native_table[] = {
636 {'x', sizeof(char), 0, NULL},
637 {'b', sizeof(char), 0, nu_byte, np_byte},
638 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
639 {'c', sizeof(char), 0, nu_char, np_char},
640 {'s', sizeof(char), 0, NULL},
641 {'p', sizeof(char), 0, NULL},
642 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
643 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
644 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
645 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
646 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
647 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
648 #ifdef HAVE_LONG_LONG
649 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
650 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
651 #endif
652 {'?', sizeof(BOOL_TYPE), BOOL_ALIGN, nu_bool, np_bool},
653 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
654 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
655 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
659 /* Big-endian routines. *****************************************************/
661 static PyObject *
662 bu_int(const char *p, const formatdef *f)
664 long x = 0;
665 Py_ssize_t i = f->size;
666 const unsigned char *bytes = (const unsigned char *)p;
667 do {
668 x = (x<<8) | *bytes++;
669 } while (--i > 0);
670 /* Extend the sign bit. */
671 if (SIZEOF_LONG > f->size)
672 x |= -(x & (1L << ((8 * f->size) - 1)));
673 return PyInt_FromLong(x);
676 static PyObject *
677 bu_uint(const char *p, const formatdef *f)
679 unsigned long x = 0;
680 Py_ssize_t i = f->size;
681 const unsigned char *bytes = (const unsigned char *)p;
682 do {
683 x = (x<<8) | *bytes++;
684 } while (--i > 0);
685 if (x <= LONG_MAX)
686 return PyInt_FromLong((long)x);
687 return PyLong_FromUnsignedLong(x);
690 static PyObject *
691 bu_longlong(const char *p, const formatdef *f)
693 #ifdef HAVE_LONG_LONG
694 PY_LONG_LONG x = 0;
695 Py_ssize_t i = f->size;
696 const unsigned char *bytes = (const unsigned char *)p;
697 do {
698 x = (x<<8) | *bytes++;
699 } while (--i > 0);
700 /* Extend the sign bit. */
701 if (SIZEOF_LONG_LONG > f->size)
702 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
703 if (x >= LONG_MIN && x <= LONG_MAX)
704 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
705 return PyLong_FromLongLong(x);
706 #else
707 return _PyLong_FromByteArray((const unsigned char *)p,
709 0, /* little-endian */
710 1 /* signed */);
711 #endif
714 static PyObject *
715 bu_ulonglong(const char *p, const formatdef *f)
717 #ifdef HAVE_LONG_LONG
718 unsigned PY_LONG_LONG x = 0;
719 Py_ssize_t i = f->size;
720 const unsigned char *bytes = (const unsigned char *)p;
721 do {
722 x = (x<<8) | *bytes++;
723 } while (--i > 0);
724 if (x <= LONG_MAX)
725 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
726 return PyLong_FromUnsignedLongLong(x);
727 #else
728 return _PyLong_FromByteArray((const unsigned char *)p,
730 0, /* little-endian */
731 0 /* signed */);
732 #endif
735 static PyObject *
736 bu_float(const char *p, const formatdef *f)
738 return unpack_float(p, 0);
741 static PyObject *
742 bu_double(const char *p, const formatdef *f)
744 return unpack_double(p, 0);
747 static PyObject *
748 bu_bool(const char *p, const formatdef *f)
750 char x;
751 memcpy((char *)&x, p, sizeof x);
752 return PyBool_FromLong(x != 0);
755 static int
756 bp_int(char *p, PyObject *v, const formatdef *f)
758 long x;
759 Py_ssize_t i;
760 if (get_wrapped_long(v, &x) < 0)
761 return -1;
762 i = f->size;
763 if (i != SIZEOF_LONG) {
764 if ((i == 2) && (x < -32768 || x > 32767))
765 return _range_error(f, 0);
766 #if (SIZEOF_LONG != 4)
767 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
768 return _range_error(f, 0);
769 #endif
771 do {
772 p[--i] = (char)x;
773 x >>= 8;
774 } while (i > 0);
775 return 0;
778 static int
779 bp_uint(char *p, PyObject *v, const formatdef *f)
781 unsigned long x;
782 Py_ssize_t i;
783 if (get_wrapped_ulong(v, &x) < 0)
784 return -1;
785 i = f->size;
786 if (i != SIZEOF_LONG) {
787 unsigned long maxint = 1;
788 maxint <<= (unsigned long)(i * 8);
789 if (x >= maxint)
790 return _range_error(f, 1);
792 do {
793 p[--i] = (char)x;
794 x >>= 8;
795 } while (i > 0);
796 return 0;
799 static int
800 bp_longlong(char *p, PyObject *v, const formatdef *f)
802 int res;
803 v = get_pylong(v);
804 if (v == NULL)
805 return -1;
806 res = _PyLong_AsByteArray((PyLongObject *)v,
807 (unsigned char *)p,
809 0, /* little_endian */
810 1 /* signed */);
811 Py_DECREF(v);
812 return res;
815 static int
816 bp_ulonglong(char *p, PyObject *v, const formatdef *f)
818 int res;
819 v = get_pylong(v);
820 if (v == NULL)
821 return -1;
822 res = _PyLong_AsByteArray((PyLongObject *)v,
823 (unsigned char *)p,
825 0, /* little_endian */
826 0 /* signed */);
827 Py_DECREF(v);
828 return res;
831 static int
832 bp_float(char *p, PyObject *v, const formatdef *f)
834 double x = PyFloat_AsDouble(v);
835 if (x == -1 && PyErr_Occurred()) {
836 PyErr_SetString(StructError,
837 "required argument is not a float");
838 return -1;
840 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
843 static int
844 bp_double(char *p, PyObject *v, const formatdef *f)
846 double x = PyFloat_AsDouble(v);
847 if (x == -1 && PyErr_Occurred()) {
848 PyErr_SetString(StructError,
849 "required argument is not a float");
850 return -1;
852 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
855 static int
856 bp_bool(char *p, PyObject *v, const formatdef *f)
858 char y;
859 y = PyObject_IsTrue(v);
860 memcpy(p, (char *)&y, sizeof y);
861 return 0;
864 static formatdef bigendian_table[] = {
865 {'x', 1, 0, NULL},
866 {'b', 1, 0, nu_byte, np_byte},
867 {'B', 1, 0, nu_ubyte, np_ubyte},
868 {'c', 1, 0, nu_char, np_char},
869 {'s', 1, 0, NULL},
870 {'p', 1, 0, NULL},
871 {'h', 2, 0, bu_int, bp_int},
872 {'H', 2, 0, bu_uint, bp_uint},
873 {'i', 4, 0, bu_int, bp_int},
874 {'I', 4, 0, bu_uint, bp_uint},
875 {'l', 4, 0, bu_int, bp_int},
876 {'L', 4, 0, bu_uint, bp_uint},
877 {'q', 8, 0, bu_longlong, bp_longlong},
878 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
879 {'?', 1, 0, bu_bool, bp_bool},
880 {'f', 4, 0, bu_float, bp_float},
881 {'d', 8, 0, bu_double, bp_double},
885 /* Little-endian routines. *****************************************************/
887 static PyObject *
888 lu_int(const char *p, const formatdef *f)
890 long x = 0;
891 Py_ssize_t i = f->size;
892 const unsigned char *bytes = (const unsigned char *)p;
893 do {
894 x = (x<<8) | bytes[--i];
895 } while (i > 0);
896 /* Extend the sign bit. */
897 if (SIZEOF_LONG > f->size)
898 x |= -(x & (1L << ((8 * f->size) - 1)));
899 return PyInt_FromLong(x);
902 static PyObject *
903 lu_uint(const char *p, const formatdef *f)
905 unsigned long x = 0;
906 Py_ssize_t i = f->size;
907 const unsigned char *bytes = (const unsigned char *)p;
908 do {
909 x = (x<<8) | bytes[--i];
910 } while (i > 0);
911 if (x <= LONG_MAX)
912 return PyInt_FromLong((long)x);
913 return PyLong_FromUnsignedLong((long)x);
916 static PyObject *
917 lu_longlong(const char *p, const formatdef *f)
919 #ifdef HAVE_LONG_LONG
920 PY_LONG_LONG x = 0;
921 Py_ssize_t i = f->size;
922 const unsigned char *bytes = (const unsigned char *)p;
923 do {
924 x = (x<<8) | bytes[--i];
925 } while (i > 0);
926 /* Extend the sign bit. */
927 if (SIZEOF_LONG_LONG > f->size)
928 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
929 if (x >= LONG_MIN && x <= LONG_MAX)
930 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
931 return PyLong_FromLongLong(x);
932 #else
933 return _PyLong_FromByteArray((const unsigned char *)p,
935 1, /* little-endian */
936 1 /* signed */);
937 #endif
940 static PyObject *
941 lu_ulonglong(const char *p, const formatdef *f)
943 #ifdef HAVE_LONG_LONG
944 unsigned PY_LONG_LONG x = 0;
945 Py_ssize_t i = f->size;
946 const unsigned char *bytes = (const unsigned char *)p;
947 do {
948 x = (x<<8) | bytes[--i];
949 } while (i > 0);
950 if (x <= LONG_MAX)
951 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
952 return PyLong_FromUnsignedLongLong(x);
953 #else
954 return _PyLong_FromByteArray((const unsigned char *)p,
956 1, /* little-endian */
957 0 /* signed */);
958 #endif
961 static PyObject *
962 lu_float(const char *p, const formatdef *f)
964 return unpack_float(p, 1);
967 static PyObject *
968 lu_double(const char *p, const formatdef *f)
970 return unpack_double(p, 1);
973 static int
974 lp_int(char *p, PyObject *v, const formatdef *f)
976 long x;
977 Py_ssize_t i;
978 if (get_wrapped_long(v, &x) < 0)
979 return -1;
980 i = f->size;
981 if (i != SIZEOF_LONG) {
982 if ((i == 2) && (x < -32768 || x > 32767))
983 return _range_error(f, 0);
984 #if (SIZEOF_LONG != 4)
985 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
986 return _range_error(f, 0);
987 #endif
989 do {
990 *p++ = (char)x;
991 x >>= 8;
992 } while (--i > 0);
993 return 0;
996 static int
997 lp_uint(char *p, PyObject *v, const formatdef *f)
999 unsigned long x;
1000 Py_ssize_t i;
1001 if (get_wrapped_ulong(v, &x) < 0)
1002 return -1;
1003 i = f->size;
1004 if (i != SIZEOF_LONG) {
1005 unsigned long maxint = 1;
1006 maxint <<= (unsigned long)(i * 8);
1007 if (x >= maxint)
1008 return _range_error(f, 1);
1010 do {
1011 *p++ = (char)x;
1012 x >>= 8;
1013 } while (--i > 0);
1014 return 0;
1017 static int
1018 lp_longlong(char *p, PyObject *v, const formatdef *f)
1020 int res;
1021 v = get_pylong(v);
1022 if (v == NULL)
1023 return -1;
1024 res = _PyLong_AsByteArray((PyLongObject*)v,
1025 (unsigned char *)p,
1027 1, /* little_endian */
1028 1 /* signed */);
1029 Py_DECREF(v);
1030 return res;
1033 static int
1034 lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1036 int res;
1037 v = get_pylong(v);
1038 if (v == NULL)
1039 return -1;
1040 res = _PyLong_AsByteArray((PyLongObject*)v,
1041 (unsigned char *)p,
1043 1, /* little_endian */
1044 0 /* signed */);
1045 Py_DECREF(v);
1046 return res;
1049 static int
1050 lp_float(char *p, PyObject *v, const formatdef *f)
1052 double x = PyFloat_AsDouble(v);
1053 if (x == -1 && PyErr_Occurred()) {
1054 PyErr_SetString(StructError,
1055 "required argument is not a float");
1056 return -1;
1058 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1061 static int
1062 lp_double(char *p, PyObject *v, const formatdef *f)
1064 double x = PyFloat_AsDouble(v);
1065 if (x == -1 && PyErr_Occurred()) {
1066 PyErr_SetString(StructError,
1067 "required argument is not a float");
1068 return -1;
1070 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1073 static formatdef lilendian_table[] = {
1074 {'x', 1, 0, NULL},
1075 {'b', 1, 0, nu_byte, np_byte},
1076 {'B', 1, 0, nu_ubyte, np_ubyte},
1077 {'c', 1, 0, nu_char, np_char},
1078 {'s', 1, 0, NULL},
1079 {'p', 1, 0, NULL},
1080 {'h', 2, 0, lu_int, lp_int},
1081 {'H', 2, 0, lu_uint, lp_uint},
1082 {'i', 4, 0, lu_int, lp_int},
1083 {'I', 4, 0, lu_uint, lp_uint},
1084 {'l', 4, 0, lu_int, lp_int},
1085 {'L', 4, 0, lu_uint, lp_uint},
1086 {'q', 8, 0, lu_longlong, lp_longlong},
1087 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1088 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1089 but potentially different from native rep -- reuse bx_bool funcs. */
1090 {'f', 4, 0, lu_float, lp_float},
1091 {'d', 8, 0, lu_double, lp_double},
1096 static const formatdef *
1097 whichtable(char **pfmt)
1099 const char *fmt = (*pfmt)++; /* May be backed out of later */
1100 switch (*fmt) {
1101 case '<':
1102 return lilendian_table;
1103 case '>':
1104 case '!': /* Network byte order is big-endian */
1105 return bigendian_table;
1106 case '=': { /* Host byte order -- different from native in aligment! */
1107 int n = 1;
1108 char *p = (char *) &n;
1109 if (*p == 1)
1110 return lilendian_table;
1111 else
1112 return bigendian_table;
1114 default:
1115 --*pfmt; /* Back out of pointer increment */
1116 /* Fall through */
1117 case '@':
1118 return native_table;
1123 /* Get the table entry for a format code */
1125 static const formatdef *
1126 getentry(int c, const formatdef *f)
1128 for (; f->format != '\0'; f++) {
1129 if (f->format == c) {
1130 return f;
1133 PyErr_SetString(StructError, "bad char in struct format");
1134 return NULL;
1138 /* Align a size according to a format code */
1140 static int
1141 align(Py_ssize_t size, char c, const formatdef *e)
1143 if (e->format == c) {
1144 if (e->alignment) {
1145 size = ((size + e->alignment - 1)
1146 / e->alignment)
1147 * e->alignment;
1150 return size;
1154 /* calculate the size of a format string */
1156 static int
1157 prepare_s(PyStructObject *self)
1159 const formatdef *f;
1160 const formatdef *e;
1161 formatcode *codes;
1163 const char *s;
1164 const char *fmt;
1165 char c;
1166 Py_ssize_t size, len, num, itemsize, x;
1168 fmt = PyString_AS_STRING(self->s_format);
1170 f = whichtable((char **)&fmt);
1172 s = fmt;
1173 size = 0;
1174 len = 0;
1175 while ((c = *s++) != '\0') {
1176 if (isspace(Py_CHARMASK(c)))
1177 continue;
1178 if ('0' <= c && c <= '9') {
1179 num = c - '0';
1180 while ('0' <= (c = *s++) && c <= '9') {
1181 x = num*10 + (c - '0');
1182 if (x/10 != num) {
1183 PyErr_SetString(
1184 StructError,
1185 "overflow in item count");
1186 return -1;
1188 num = x;
1190 if (c == '\0')
1191 break;
1193 else
1194 num = 1;
1196 e = getentry(c, f);
1197 if (e == NULL)
1198 return -1;
1200 switch (c) {
1201 case 's': /* fall through */
1202 case 'p': len++; break;
1203 case 'x': break;
1204 default: len += num; break;
1207 itemsize = e->size;
1208 size = align(size, c, e);
1209 x = num * itemsize;
1210 size += x;
1211 if (x/itemsize != num || size < 0) {
1212 PyErr_SetString(StructError,
1213 "total struct size too long");
1214 return -1;
1218 /* check for overflow */
1219 if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {
1220 PyErr_NoMemory();
1221 return -1;
1224 self->s_size = size;
1225 self->s_len = len;
1226 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1227 if (codes == NULL) {
1228 PyErr_NoMemory();
1229 return -1;
1231 self->s_codes = codes;
1233 s = fmt;
1234 size = 0;
1235 while ((c = *s++) != '\0') {
1236 if (isspace(Py_CHARMASK(c)))
1237 continue;
1238 if ('0' <= c && c <= '9') {
1239 num = c - '0';
1240 while ('0' <= (c = *s++) && c <= '9')
1241 num = num*10 + (c - '0');
1242 if (c == '\0')
1243 break;
1245 else
1246 num = 1;
1248 e = getentry(c, f);
1250 size = align(size, c, e);
1251 if (c == 's' || c == 'p') {
1252 codes->offset = size;
1253 codes->size = num;
1254 codes->fmtdef = e;
1255 codes++;
1256 size += num;
1257 } else if (c == 'x') {
1258 size += num;
1259 } else {
1260 while (--num >= 0) {
1261 codes->offset = size;
1262 codes->size = e->size;
1263 codes->fmtdef = e;
1264 codes++;
1265 size += e->size;
1269 codes->fmtdef = NULL;
1270 codes->offset = size;
1271 codes->size = 0;
1273 return 0;
1276 static PyObject *
1277 s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1279 PyObject *self;
1281 assert(type != NULL && type->tp_alloc != NULL);
1283 self = type->tp_alloc(type, 0);
1284 if (self != NULL) {
1285 PyStructObject *s = (PyStructObject*)self;
1286 Py_INCREF(Py_None);
1287 s->s_format = Py_None;
1288 s->s_codes = NULL;
1289 s->s_size = -1;
1290 s->s_len = -1;
1292 return self;
1295 static int
1296 s_init(PyObject *self, PyObject *args, PyObject *kwds)
1298 PyStructObject *soself = (PyStructObject *)self;
1299 PyObject *o_format = NULL;
1300 int ret = 0;
1301 static char *kwlist[] = {"format", 0};
1303 assert(PyStruct_Check(self));
1305 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1306 &o_format))
1307 return -1;
1309 Py_INCREF(o_format);
1310 Py_CLEAR(soself->s_format);
1311 soself->s_format = o_format;
1313 ret = prepare_s(soself);
1314 return ret;
1317 static void
1318 s_dealloc(PyStructObject *s)
1320 if (s->weakreflist != NULL)
1321 PyObject_ClearWeakRefs((PyObject *)s);
1322 if (s->s_codes != NULL) {
1323 PyMem_FREE(s->s_codes);
1325 Py_XDECREF(s->s_format);
1326 Py_TYPE(s)->tp_free((PyObject *)s);
1329 static PyObject *
1330 s_unpack_internal(PyStructObject *soself, char *startfrom) {
1331 formatcode *code;
1332 Py_ssize_t i = 0;
1333 PyObject *result = PyTuple_New(soself->s_len);
1334 if (result == NULL)
1335 return NULL;
1337 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1338 PyObject *v;
1339 const formatdef *e = code->fmtdef;
1340 const char *res = startfrom + code->offset;
1341 if (e->format == 's') {
1342 v = PyString_FromStringAndSize(res, code->size);
1343 } else if (e->format == 'p') {
1344 Py_ssize_t n = *(unsigned char*)res;
1345 if (n >= code->size)
1346 n = code->size - 1;
1347 v = PyString_FromStringAndSize(res + 1, n);
1348 } else {
1349 v = e->unpack(res, e);
1351 if (v == NULL)
1352 goto fail;
1353 PyTuple_SET_ITEM(result, i++, v);
1356 return result;
1357 fail:
1358 Py_DECREF(result);
1359 return NULL;
1363 PyDoc_STRVAR(s_unpack__doc__,
1364 "S.unpack(str) -> (v1, v2, ...)\n\
1366 Return tuple containing values unpacked according to this Struct's format.\n\
1367 Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1368 strings.");
1370 static PyObject *
1371 s_unpack(PyObject *self, PyObject *inputstr)
1373 char *start;
1374 Py_ssize_t len;
1375 PyObject *args=NULL, *result;
1376 PyStructObject *soself = (PyStructObject *)self;
1377 assert(PyStruct_Check(self));
1378 assert(soself->s_codes != NULL);
1379 if (inputstr == NULL)
1380 goto fail;
1381 if (PyString_Check(inputstr) &&
1382 PyString_GET_SIZE(inputstr) == soself->s_size) {
1383 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1385 args = PyTuple_Pack(1, inputstr);
1386 if (args == NULL)
1387 return NULL;
1388 if (!PyArg_ParseTuple(args, "s#:unpack", &start, &len))
1389 goto fail;
1390 if (soself->s_size != len)
1391 goto fail;
1392 result = s_unpack_internal(soself, start);
1393 Py_DECREF(args);
1394 return result;
1396 fail:
1397 Py_XDECREF(args);
1398 PyErr_Format(StructError,
1399 "unpack requires a string argument of length %zd",
1400 soself->s_size);
1401 return NULL;
1404 PyDoc_STRVAR(s_unpack_from__doc__,
1405 "S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1407 Return tuple containing values unpacked according to this Struct's format.\n\
1408 Unlike unpack, unpack_from can unpack values from any object supporting\n\
1409 the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1410 See struct.__doc__ for more on format strings.");
1412 static PyObject *
1413 s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1415 static char *kwlist[] = {"buffer", "offset", 0};
1416 #if (PY_VERSION_HEX < 0x02050000)
1417 static char *fmt = "z#|i:unpack_from";
1418 #else
1419 static char *fmt = "z#|n:unpack_from";
1420 #endif
1421 Py_ssize_t buffer_len = 0, offset = 0;
1422 char *buffer = NULL;
1423 PyStructObject *soself = (PyStructObject *)self;
1424 assert(PyStruct_Check(self));
1425 assert(soself->s_codes != NULL);
1427 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1428 &buffer, &buffer_len, &offset))
1429 return NULL;
1431 if (buffer == NULL) {
1432 PyErr_Format(StructError,
1433 "unpack_from requires a buffer argument");
1434 return NULL;
1437 if (offset < 0)
1438 offset += buffer_len;
1440 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1441 PyErr_Format(StructError,
1442 "unpack_from requires a buffer of at least %zd bytes",
1443 soself->s_size);
1444 return NULL;
1446 return s_unpack_internal(soself, buffer + offset);
1451 * Guts of the pack function.
1453 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1454 * argument for where to start processing the arguments for packing, and a
1455 * character buffer for writing the packed string. The caller must insure
1456 * that the buffer may contain the required length for packing the arguments.
1457 * 0 is returned on success, 1 is returned if there is an error.
1460 static int
1461 s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1463 formatcode *code;
1464 /* XXX(nnorwitz): why does i need to be a local? can we use
1465 the offset parameter or do we need the wider width? */
1466 Py_ssize_t i;
1468 memset(buf, '\0', soself->s_size);
1469 i = offset;
1470 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1471 Py_ssize_t n;
1472 PyObject *v = PyTuple_GET_ITEM(args, i++);
1473 const formatdef *e = code->fmtdef;
1474 char *res = buf + code->offset;
1475 if (e->format == 's') {
1476 if (!PyString_Check(v)) {
1477 PyErr_SetString(StructError,
1478 "argument for 's' must "
1479 "be a string");
1480 return -1;
1482 n = PyString_GET_SIZE(v);
1483 if (n > code->size)
1484 n = code->size;
1485 if (n > 0)
1486 memcpy(res, PyString_AS_STRING(v), n);
1487 } else if (e->format == 'p') {
1488 if (!PyString_Check(v)) {
1489 PyErr_SetString(StructError,
1490 "argument for 'p' must "
1491 "be a string");
1492 return -1;
1494 n = PyString_GET_SIZE(v);
1495 if (n > (code->size - 1))
1496 n = code->size - 1;
1497 if (n > 0)
1498 memcpy(res + 1, PyString_AS_STRING(v), n);
1499 if (n > 255)
1500 n = 255;
1501 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1502 } else if (e->pack(res, v, e) < 0) {
1503 if (strchr(integer_codes, e->format) != NULL &&
1504 PyErr_ExceptionMatches(PyExc_OverflowError))
1505 PyErr_Format(StructError,
1506 "integer out of range for "
1507 "'%c' format code",
1508 e->format);
1509 return -1;
1513 /* Success */
1514 return 0;
1518 PyDoc_STRVAR(s_pack__doc__,
1519 "S.pack(v1, v2, ...) -> string\n\
1521 Return a string containing values v1, v2, ... packed according to this\n\
1522 Struct's format. See struct.__doc__ for more on format strings.");
1524 static PyObject *
1525 s_pack(PyObject *self, PyObject *args)
1527 PyStructObject *soself;
1528 PyObject *result;
1530 /* Validate arguments. */
1531 soself = (PyStructObject *)self;
1532 assert(PyStruct_Check(self));
1533 assert(soself->s_codes != NULL);
1534 if (PyTuple_GET_SIZE(args) != soself->s_len)
1536 PyErr_Format(StructError,
1537 "pack requires exactly %zd arguments", soself->s_len);
1538 return NULL;
1541 /* Allocate a new string */
1542 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1543 if (result == NULL)
1544 return NULL;
1546 /* Call the guts */
1547 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1548 Py_DECREF(result);
1549 return NULL;
1552 return result;
1555 PyDoc_STRVAR(s_pack_into__doc__,
1556 "S.pack_into(buffer, offset, v1, v2, ...)\n\
1558 Pack the values v1, v2, ... according to this Struct's format, write \n\
1559 the packed bytes into the writable buffer buf starting at offset. Note\n\
1560 that the offset is not an optional argument. See struct.__doc__ for \n\
1561 more on format strings.");
1563 static PyObject *
1564 s_pack_into(PyObject *self, PyObject *args)
1566 PyStructObject *soself;
1567 char *buffer;
1568 Py_ssize_t buffer_len, offset;
1570 /* Validate arguments. +1 is for the first arg as buffer. */
1571 soself = (PyStructObject *)self;
1572 assert(PyStruct_Check(self));
1573 assert(soself->s_codes != NULL);
1574 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
1576 PyErr_Format(StructError,
1577 "pack_into requires exactly %zd arguments",
1578 (soself->s_len + 2));
1579 return NULL;
1582 /* Extract a writable memory buffer from the first argument */
1583 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1584 (void**)&buffer, &buffer_len) == -1 ) {
1585 return NULL;
1587 assert( buffer_len >= 0 );
1589 /* Extract the offset from the first argument */
1590 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
1591 if (offset == -1 && PyErr_Occurred())
1592 return NULL;
1594 /* Support negative offsets. */
1595 if (offset < 0)
1596 offset += buffer_len;
1598 /* Check boundaries */
1599 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1600 PyErr_Format(StructError,
1601 "pack_into requires a buffer of at least %zd bytes",
1602 soself->s_size);
1603 return NULL;
1606 /* Call the guts */
1607 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1608 return NULL;
1611 Py_RETURN_NONE;
1614 static PyObject *
1615 s_get_format(PyStructObject *self, void *unused)
1617 Py_INCREF(self->s_format);
1618 return self->s_format;
1621 static PyObject *
1622 s_get_size(PyStructObject *self, void *unused)
1624 return PyInt_FromSsize_t(self->s_size);
1627 /* List of functions */
1629 static struct PyMethodDef s_methods[] = {
1630 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1631 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1632 {"unpack", s_unpack, METH_O, s_unpack__doc__},
1633 {"unpack_from", (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS,
1634 s_unpack_from__doc__},
1635 {NULL, NULL} /* sentinel */
1638 PyDoc_STRVAR(s__doc__, "Compiled struct object");
1640 #define OFF(x) offsetof(PyStructObject, x)
1642 static PyGetSetDef s_getsetlist[] = {
1643 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1644 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1645 {NULL} /* sentinel */
1648 static
1649 PyTypeObject PyStructType = {
1650 PyVarObject_HEAD_INIT(NULL, 0)
1651 "Struct",
1652 sizeof(PyStructObject),
1654 (destructor)s_dealloc, /* tp_dealloc */
1655 0, /* tp_print */
1656 0, /* tp_getattr */
1657 0, /* tp_setattr */
1658 0, /* tp_compare */
1659 0, /* tp_repr */
1660 0, /* tp_as_number */
1661 0, /* tp_as_sequence */
1662 0, /* tp_as_mapping */
1663 0, /* tp_hash */
1664 0, /* tp_call */
1665 0, /* tp_str */
1666 PyObject_GenericGetAttr, /* tp_getattro */
1667 PyObject_GenericSetAttr, /* tp_setattro */
1668 0, /* tp_as_buffer */
1669 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1670 s__doc__, /* tp_doc */
1671 0, /* tp_traverse */
1672 0, /* tp_clear */
1673 0, /* tp_richcompare */
1674 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1675 0, /* tp_iter */
1676 0, /* tp_iternext */
1677 s_methods, /* tp_methods */
1678 NULL, /* tp_members */
1679 s_getsetlist, /* tp_getset */
1680 0, /* tp_base */
1681 0, /* tp_dict */
1682 0, /* tp_descr_get */
1683 0, /* tp_descr_set */
1684 0, /* tp_dictoffset */
1685 s_init, /* tp_init */
1686 PyType_GenericAlloc,/* tp_alloc */
1687 s_new, /* tp_new */
1688 PyObject_Del, /* tp_free */
1692 /* ---- Standalone functions ---- */
1694 #define MAXCACHE 100
1695 static PyObject *cache = NULL;
1697 static PyObject *
1698 cache_struct(PyObject *fmt)
1700 PyObject * s_object;
1702 if (cache == NULL) {
1703 cache = PyDict_New();
1704 if (cache == NULL)
1705 return NULL;
1708 s_object = PyDict_GetItem(cache, fmt);
1709 if (s_object != NULL) {
1710 Py_INCREF(s_object);
1711 return s_object;
1714 s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
1715 if (s_object != NULL) {
1716 if (PyDict_Size(cache) >= MAXCACHE)
1717 PyDict_Clear(cache);
1718 /* Attempt to cache the result */
1719 if (PyDict_SetItem(cache, fmt, s_object) == -1)
1720 PyErr_Clear();
1722 return s_object;
1725 PyDoc_STRVAR(clearcache_doc,
1726 "Clear the internal cache.");
1728 static PyObject *
1729 clearcache(PyObject *self)
1731 Py_CLEAR(cache);
1732 Py_RETURN_NONE;
1735 PyDoc_STRVAR(calcsize_doc,
1736 "Return size of C struct described by format string fmt.");
1738 static PyObject *
1739 calcsize(PyObject *self, PyObject *fmt)
1741 Py_ssize_t n;
1742 PyObject *s_object = cache_struct(fmt);
1743 if (s_object == NULL)
1744 return NULL;
1745 n = ((PyStructObject *)s_object)->s_size;
1746 Py_DECREF(s_object);
1747 return PyInt_FromSsize_t(n);
1750 PyDoc_STRVAR(pack_doc,
1751 "Return string containing values v1, v2, ... packed according to fmt.");
1753 static PyObject *
1754 pack(PyObject *self, PyObject *args)
1756 PyObject *s_object, *fmt, *newargs, *result;
1757 Py_ssize_t n = PyTuple_GET_SIZE(args);
1759 if (n == 0) {
1760 PyErr_SetString(PyExc_TypeError, "missing format argument");
1761 return NULL;
1763 fmt = PyTuple_GET_ITEM(args, 0);
1764 newargs = PyTuple_GetSlice(args, 1, n);
1765 if (newargs == NULL)
1766 return NULL;
1768 s_object = cache_struct(fmt);
1769 if (s_object == NULL) {
1770 Py_DECREF(newargs);
1771 return NULL;
1773 result = s_pack(s_object, newargs);
1774 Py_DECREF(newargs);
1775 Py_DECREF(s_object);
1776 return result;
1779 PyDoc_STRVAR(pack_into_doc,
1780 "Pack the values v1, v2, ... according to fmt.\n\
1781 Write the packed bytes into the writable buffer buf starting at offset.");
1783 static PyObject *
1784 pack_into(PyObject *self, PyObject *args)
1786 PyObject *s_object, *fmt, *newargs, *result;
1787 Py_ssize_t n = PyTuple_GET_SIZE(args);
1789 if (n == 0) {
1790 PyErr_SetString(PyExc_TypeError, "missing format argument");
1791 return NULL;
1793 fmt = PyTuple_GET_ITEM(args, 0);
1794 newargs = PyTuple_GetSlice(args, 1, n);
1795 if (newargs == NULL)
1796 return NULL;
1798 s_object = cache_struct(fmt);
1799 if (s_object == NULL) {
1800 Py_DECREF(newargs);
1801 return NULL;
1803 result = s_pack_into(s_object, newargs);
1804 Py_DECREF(newargs);
1805 Py_DECREF(s_object);
1806 return result;
1809 PyDoc_STRVAR(unpack_doc,
1810 "Unpack the string containing packed C structure data, according to fmt.\n\
1811 Requires len(string) == calcsize(fmt).");
1813 static PyObject *
1814 unpack(PyObject *self, PyObject *args)
1816 PyObject *s_object, *fmt, *inputstr, *result;
1818 if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr))
1819 return NULL;
1821 s_object = cache_struct(fmt);
1822 if (s_object == NULL)
1823 return NULL;
1824 result = s_unpack(s_object, inputstr);
1825 Py_DECREF(s_object);
1826 return result;
1829 PyDoc_STRVAR(unpack_from_doc,
1830 "Unpack the buffer, containing packed C structure data, according to\n\
1831 fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).");
1833 static PyObject *
1834 unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1836 PyObject *s_object, *fmt, *newargs, *result;
1837 Py_ssize_t n = PyTuple_GET_SIZE(args);
1839 if (n == 0) {
1840 PyErr_SetString(PyExc_TypeError, "missing format argument");
1841 return NULL;
1843 fmt = PyTuple_GET_ITEM(args, 0);
1844 newargs = PyTuple_GetSlice(args, 1, n);
1845 if (newargs == NULL)
1846 return NULL;
1848 s_object = cache_struct(fmt);
1849 if (s_object == NULL) {
1850 Py_DECREF(newargs);
1851 return NULL;
1853 result = s_unpack_from(s_object, newargs, kwds);
1854 Py_DECREF(newargs);
1855 Py_DECREF(s_object);
1856 return result;
1859 static struct PyMethodDef module_functions[] = {
1860 {"_clearcache", (PyCFunction)clearcache, METH_NOARGS, clearcache_doc},
1861 {"calcsize", calcsize, METH_O, calcsize_doc},
1862 {"pack", pack, METH_VARARGS, pack_doc},
1863 {"pack_into", pack_into, METH_VARARGS, pack_into_doc},
1864 {"unpack", unpack, METH_VARARGS, unpack_doc},
1865 {"unpack_from", (PyCFunction)unpack_from,
1866 METH_VARARGS|METH_KEYWORDS, unpack_from_doc},
1867 {NULL, NULL} /* sentinel */
1871 /* Module initialization */
1873 PyDoc_STRVAR(module_doc,
1874 "Functions to convert between Python values and C structs.\n\
1875 Python strings are used to hold the data representing the C struct\n\
1876 and also as format strings to describe the layout of data in the C struct.\n\
1878 The optional first format char indicates byte order, size and alignment:\n\
1879 @: native order, size & alignment (default)\n\
1880 =: native order, std. size & alignment\n\
1881 <: little-endian, std. size & alignment\n\
1882 >: big-endian, std. size & alignment\n\
1883 !: same as >\n\
1885 The remaining chars indicate types of args and must match exactly;\n\
1886 these can be preceded by a decimal repeat count:\n\
1887 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
1888 h:short; H:unsigned short; i:int; I:unsigned int;\n\
1889 l:long; L:unsigned long; f:float; d:double.\n\
1890 Special cases (preceding decimal count indicates length):\n\
1891 s:string (array of char); p: pascal string (with count byte).\n\
1892 Special case (only available in native format):\n\
1893 P:an integer type that is wide enough to hold a pointer.\n\
1894 Special case (not in native mode unless 'long long' in platform C):\n\
1895 q:long long; Q:unsigned long long\n\
1896 Whitespace between formats is ignored.\n\
1898 The variable struct.error is an exception raised on errors.\n");
1900 PyMODINIT_FUNC
1901 init_struct(void)
1903 PyObject *ver, *m;
1905 ver = PyString_FromString("0.2");
1906 if (ver == NULL)
1907 return;
1909 m = Py_InitModule3("_struct", module_functions, module_doc);
1910 if (m == NULL)
1911 return;
1913 Py_TYPE(&PyStructType) = &PyType_Type;
1914 if (PyType_Ready(&PyStructType) < 0)
1915 return;
1917 /* This speed trick can't be used until overflow masking goes
1918 away, because native endian always raises exceptions
1919 instead of overflow masking. */
1921 /* Check endian and swap in faster functions */
1923 int one = 1;
1924 formatdef *native = native_table;
1925 formatdef *other, *ptr;
1926 if ((int)*(unsigned char*)&one)
1927 other = lilendian_table;
1928 else
1929 other = bigendian_table;
1930 /* Scan through the native table, find a matching
1931 entry in the endian table and swap in the
1932 native implementations whenever possible
1933 (64-bit platforms may not have "standard" sizes) */
1934 while (native->format != '\0' && other->format != '\0') {
1935 ptr = other;
1936 while (ptr->format != '\0') {
1937 if (ptr->format == native->format) {
1938 /* Match faster when formats are
1939 listed in the same order */
1940 if (ptr == other)
1941 other++;
1942 /* Only use the trick if the
1943 size matches */
1944 if (ptr->size != native->size)
1945 break;
1946 /* Skip float and double, could be
1947 "unknown" float format */
1948 if (ptr->format == 'd' || ptr->format == 'f')
1949 break;
1950 ptr->pack = native->pack;
1951 ptr->unpack = native->unpack;
1952 break;
1954 ptr++;
1956 native++;
1960 /* Add some symbolic constants to the module */
1961 if (StructError == NULL) {
1962 StructError = PyErr_NewException("struct.error", NULL, NULL);
1963 if (StructError == NULL)
1964 return;
1967 Py_INCREF(StructError);
1968 PyModule_AddObject(m, "error", StructError);
1970 Py_INCREF((PyObject*)&PyStructType);
1971 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
1973 PyModule_AddObject(m, "__version__", ver);
1975 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
1976 #ifdef PY_STRUCT_FLOAT_COERCE
1977 PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
1978 #endif