Saved and restored logging._handlerList at the same time as saving/restoring logging...
[python.git] / Modules / structmodule.c
blobf07f21a30cc8c07ef4cddefc15ab6ed55b0c333d
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 #include "Python.h"
7 #include <ctype.h>
9 PyDoc_STRVAR(struct__doc__,
10 "Functions to convert between Python values and C structs.\n\
11 Python strings are used to hold the data representing the C struct\n\
12 and also as format strings to describe the layout of data in the C struct.\n\
13 \n\
14 The optional first format char indicates byte order, size and alignment:\n\
15 @: native order, size & alignment (default)\n\
16 =: native order, std. size & alignment\n\
17 <: little-endian, std. size & alignment\n\
18 >: big-endian, std. size & alignment\n\
19 !: same as >\n\
20 \n\
21 The remaining chars indicate types of args and must match exactly;\n\
22 these can be preceded by a decimal repeat count:\n\
23 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
24 h:short; H:unsigned short; i:int; I:unsigned int;\n\
25 l:long; L:unsigned long; f:float; d:double.\n\
26 Special cases (preceding decimal count indicates length):\n\
27 s:string (array of char); p: pascal string (with count byte).\n\
28 Special case (only available in native format):\n\
29 P:an integer type that is wide enough to hold a pointer.\n\
30 Special case (not in native mode unless 'long long' in platform C):\n\
31 q:long long; Q:unsigned long long\n\
32 Whitespace between formats is ignored.\n\
33 \n\
34 The variable struct.error is an exception raised on errors.");
37 /* Exception */
39 static PyObject *StructError;
42 /* Define various structs to figure out the alignments of types */
45 typedef struct { char c; short x; } st_short;
46 typedef struct { char c; int x; } st_int;
47 typedef struct { char c; long x; } st_long;
48 typedef struct { char c; float x; } st_float;
49 typedef struct { char c; double x; } st_double;
50 typedef struct { char c; void *x; } st_void_p;
52 #define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
53 #define INT_ALIGN (sizeof(st_int) - sizeof(int))
54 #define LONG_ALIGN (sizeof(st_long) - sizeof(long))
55 #define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
56 #define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
57 #define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
59 /* We can't support q and Q in native mode unless the compiler does;
60 in std mode, they're 8 bytes on all platforms. */
61 #ifdef HAVE_LONG_LONG
62 typedef struct { char c; PY_LONG_LONG x; } s_long_long;
63 #define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
64 #endif
66 #define STRINGIFY(x) #x
68 #ifdef __powerc
69 #pragma options align=reset
70 #endif
72 /* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
74 static PyObject *
75 get_pylong(PyObject *v)
77 PyNumberMethods *m;
79 assert(v != NULL);
80 if (PyInt_Check(v))
81 return PyLong_FromLong(PyInt_AS_LONG(v));
82 if (PyLong_Check(v)) {
83 Py_INCREF(v);
84 return v;
86 m = v->ob_type->tp_as_number;
87 if (m != NULL && m->nb_long != NULL) {
88 v = m->nb_long(v);
89 if (v == NULL)
90 return NULL;
91 if (PyLong_Check(v))
92 return v;
93 Py_DECREF(v);
95 PyErr_SetString(StructError,
96 "cannot convert argument to long");
97 return NULL;
100 /* Helper routine to get a Python integer and raise the appropriate error
101 if it isn't one */
103 static int
104 get_long(PyObject *v, long *p)
106 long x = PyInt_AsLong(v);
107 if (x == -1 && PyErr_Occurred()) {
108 if (PyErr_ExceptionMatches(PyExc_TypeError))
109 PyErr_SetString(StructError,
110 "required argument is not an integer");
111 return -1;
113 *p = x;
114 return 0;
118 /* Same, but handling unsigned long */
120 static int
121 get_ulong(PyObject *v, unsigned long *p)
123 if (PyLong_Check(v)) {
124 unsigned long x = PyLong_AsUnsignedLong(v);
125 if (x == (unsigned long)(-1) && PyErr_Occurred())
126 return -1;
127 *p = x;
128 return 0;
130 else {
131 return get_long(v, (long *)p);
135 #ifdef HAVE_LONG_LONG
137 /* Same, but handling native long long. */
139 static int
140 get_longlong(PyObject *v, PY_LONG_LONG *p)
142 PY_LONG_LONG x;
144 v = get_pylong(v);
145 if (v == NULL)
146 return -1;
147 assert(PyLong_Check(v));
148 x = PyLong_AsLongLong(v);
149 Py_DECREF(v);
150 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
151 return -1;
152 *p = x;
153 return 0;
156 /* Same, but handling native unsigned long long. */
158 static int
159 get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
161 unsigned PY_LONG_LONG x;
163 v = get_pylong(v);
164 if (v == NULL)
165 return -1;
166 assert(PyLong_Check(v));
167 x = PyLong_AsUnsignedLongLong(v);
168 Py_DECREF(v);
169 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
170 return -1;
171 *p = x;
172 return 0;
175 #endif
177 /* Floating point helpers */
179 static PyObject *
180 unpack_float(const char *p, /* start of 4-byte string */
181 int le) /* true for little-endian, false for big-endian */
183 double x;
185 x = _PyFloat_Unpack4((unsigned char *)p, le);
186 if (x == -1.0 && PyErr_Occurred())
187 return NULL;
188 return PyFloat_FromDouble(x);
191 static PyObject *
192 unpack_double(const char *p, /* start of 8-byte string */
193 int le) /* true for little-endian, false for big-endian */
195 double x;
197 x = _PyFloat_Unpack8((unsigned char *)p, le);
198 if (x == -1.0 && PyErr_Occurred())
199 return NULL;
200 return PyFloat_FromDouble(x);
204 /* The translation function for each format character is table driven */
206 typedef struct _formatdef {
207 char format;
208 int size;
209 int alignment;
210 PyObject* (*unpack)(const char *,
211 const struct _formatdef *);
212 int (*pack)(char *, PyObject *,
213 const struct _formatdef *);
214 } formatdef;
216 /* A large number of small routines follow, with names of the form
218 [bln][up]_TYPE
220 [bln] distiguishes among big-endian, little-endian and native.
221 [pu] distiguishes between pack (to struct) and unpack (from struct).
222 TYPE is one of char, byte, ubyte, etc.
225 /* Native mode routines. ****************************************************/
226 /* NOTE:
227 In all n[up]_<type> routines handling types larger than 1 byte, there is
228 *no* guarantee that the p pointer is properly aligned for each type,
229 therefore memcpy is called. An intermediate variable is used to
230 compensate for big-endian architectures.
231 Normally both the intermediate variable and the memcpy call will be
232 skipped by C optimisation in little-endian architectures (gcc >= 2.91
233 does this). */
235 static PyObject *
236 nu_char(const char *p, const formatdef *f)
238 return PyString_FromStringAndSize(p, 1);
241 static PyObject *
242 nu_byte(const char *p, const formatdef *f)
244 return PyInt_FromLong((long) *(signed char *)p);
247 static PyObject *
248 nu_ubyte(const char *p, const formatdef *f)
250 return PyInt_FromLong((long) *(unsigned char *)p);
253 static PyObject *
254 nu_short(const char *p, const formatdef *f)
256 short x;
257 memcpy((char *)&x, p, sizeof x);
258 return PyInt_FromLong((long)x);
261 static PyObject *
262 nu_ushort(const char *p, const formatdef *f)
264 unsigned short x;
265 memcpy((char *)&x, p, sizeof x);
266 return PyInt_FromLong((long)x);
269 static PyObject *
270 nu_int(const char *p, const formatdef *f)
272 int x;
273 memcpy((char *)&x, p, sizeof x);
274 return PyInt_FromLong((long)x);
277 static PyObject *
278 nu_uint(const char *p, const formatdef *f)
280 unsigned int x;
281 memcpy((char *)&x, p, sizeof x);
282 return PyLong_FromUnsignedLong((unsigned long)x);
285 static PyObject *
286 nu_long(const char *p, const formatdef *f)
288 long x;
289 memcpy((char *)&x, p, sizeof x);
290 return PyInt_FromLong(x);
293 static PyObject *
294 nu_ulong(const char *p, const formatdef *f)
296 unsigned long x;
297 memcpy((char *)&x, p, sizeof x);
298 return PyLong_FromUnsignedLong(x);
301 /* Native mode doesn't support q or Q unless the platform C supports
302 long long (or, on Windows, __int64). */
304 #ifdef HAVE_LONG_LONG
306 static PyObject *
307 nu_longlong(const char *p, const formatdef *f)
309 PY_LONG_LONG x;
310 memcpy((char *)&x, p, sizeof x);
311 return PyLong_FromLongLong(x);
314 static PyObject *
315 nu_ulonglong(const char *p, const formatdef *f)
317 unsigned PY_LONG_LONG x;
318 memcpy((char *)&x, p, sizeof x);
319 return PyLong_FromUnsignedLongLong(x);
322 #endif
324 static PyObject *
325 nu_float(const char *p, const formatdef *f)
327 float x;
328 memcpy((char *)&x, p, sizeof x);
329 return PyFloat_FromDouble((double)x);
332 static PyObject *
333 nu_double(const char *p, const formatdef *f)
335 double x;
336 memcpy((char *)&x, p, sizeof x);
337 return PyFloat_FromDouble(x);
340 static PyObject *
341 nu_void_p(const char *p, const formatdef *f)
343 void *x;
344 memcpy((char *)&x, p, sizeof x);
345 return PyLong_FromVoidPtr(x);
348 static int
349 np_byte(char *p, PyObject *v, const formatdef *f)
351 long x;
352 if (get_long(v, &x) < 0)
353 return -1;
354 if (x < -128 || x > 127){
355 PyErr_SetString(StructError,
356 "byte format requires -128<=number<=127");
357 return -1;
359 *p = (char)x;
360 return 0;
363 static int
364 np_ubyte(char *p, PyObject *v, const formatdef *f)
366 long x;
367 if (get_long(v, &x) < 0)
368 return -1;
369 if (x < 0 || x > 255){
370 PyErr_SetString(StructError,
371 "ubyte format requires 0<=number<=255");
372 return -1;
374 *p = (char)x;
375 return 0;
378 static int
379 np_char(char *p, PyObject *v, const formatdef *f)
381 if (!PyString_Check(v) || PyString_Size(v) != 1) {
382 PyErr_SetString(StructError,
383 "char format require string of length 1");
384 return -1;
386 *p = *PyString_AsString(v);
387 return 0;
390 static int
391 np_short(char *p, PyObject *v, const formatdef *f)
393 long x;
394 short y;
395 if (get_long(v, &x) < 0)
396 return -1;
397 if (x < SHRT_MIN || x > SHRT_MAX){
398 PyErr_SetString(StructError,
399 "short format requires " STRINGIFY(SHRT_MIN)
400 "<=number<=" STRINGIFY(SHRT_MAX));
401 return -1;
403 y = (short)x;
404 memcpy(p, (char *)&y, sizeof y);
405 return 0;
408 static int
409 np_ushort(char *p, PyObject *v, const formatdef *f)
411 long x;
412 unsigned short y;
413 if (get_long(v, &x) < 0)
414 return -1;
415 if (x < 0 || x > USHRT_MAX){
416 PyErr_SetString(StructError,
417 "short format requires 0<=number<=" STRINGIFY(USHRT_MAX));
418 return -1;
420 y = (unsigned short)x;
421 memcpy(p, (char *)&y, sizeof y);
422 return 0;
425 static int
426 np_int(char *p, PyObject *v, const formatdef *f)
428 long x;
429 int y;
430 if (get_long(v, &x) < 0)
431 return -1;
432 y = (int)x;
433 memcpy(p, (char *)&y, sizeof y);
434 return 0;
437 static int
438 np_uint(char *p, PyObject *v, const formatdef *f)
440 unsigned long x;
441 unsigned int y;
442 if (get_ulong(v, &x) < 0)
443 return -1;
444 y = (unsigned int)x;
445 memcpy(p, (char *)&y, sizeof y);
446 return 0;
449 static int
450 np_long(char *p, PyObject *v, const formatdef *f)
452 long x;
453 if (get_long(v, &x) < 0)
454 return -1;
455 memcpy(p, (char *)&x, sizeof x);
456 return 0;
459 static int
460 np_ulong(char *p, PyObject *v, const formatdef *f)
462 unsigned long x;
463 if (get_ulong(v, &x) < 0)
464 return -1;
465 memcpy(p, (char *)&x, sizeof x);
466 return 0;
469 #ifdef HAVE_LONG_LONG
471 static int
472 np_longlong(char *p, PyObject *v, const formatdef *f)
474 PY_LONG_LONG x;
475 if (get_longlong(v, &x) < 0)
476 return -1;
477 memcpy(p, (char *)&x, sizeof x);
478 return 0;
481 static int
482 np_ulonglong(char *p, PyObject *v, const formatdef *f)
484 unsigned PY_LONG_LONG x;
485 if (get_ulonglong(v, &x) < 0)
486 return -1;
487 memcpy(p, (char *)&x, sizeof x);
488 return 0;
490 #endif
492 static int
493 np_float(char *p, PyObject *v, const formatdef *f)
495 float x = (float)PyFloat_AsDouble(v);
496 if (x == -1 && PyErr_Occurred()) {
497 PyErr_SetString(StructError,
498 "required argument is not a float");
499 return -1;
501 memcpy(p, (char *)&x, sizeof x);
502 return 0;
505 static int
506 np_double(char *p, PyObject *v, const formatdef *f)
508 double x = PyFloat_AsDouble(v);
509 if (x == -1 && PyErr_Occurred()) {
510 PyErr_SetString(StructError,
511 "required argument is not a float");
512 return -1;
514 memcpy(p, (char *)&x, sizeof(double));
515 return 0;
518 static int
519 np_void_p(char *p, PyObject *v, const formatdef *f)
521 void *x;
523 v = get_pylong(v);
524 if (v == NULL)
525 return -1;
526 assert(PyLong_Check(v));
527 x = PyLong_AsVoidPtr(v);
528 Py_DECREF(v);
529 if (x == NULL && PyErr_Occurred())
530 return -1;
531 memcpy(p, (char *)&x, sizeof x);
532 return 0;
535 static formatdef native_table[] = {
536 {'x', sizeof(char), 0, NULL},
537 {'b', sizeof(char), 0, nu_byte, np_byte},
538 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
539 {'c', sizeof(char), 0, nu_char, np_char},
540 {'s', sizeof(char), 0, NULL},
541 {'p', sizeof(char), 0, NULL},
542 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
543 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
544 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
545 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
546 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
547 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
548 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
549 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
550 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
551 #ifdef HAVE_LONG_LONG
552 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
553 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
554 #endif
558 /* Big-endian routines. *****************************************************/
560 static PyObject *
561 bu_int(const char *p, const formatdef *f)
563 long x = 0;
564 int i = f->size;
565 do {
566 x = (x<<8) | (*p++ & 0xFF);
567 } while (--i > 0);
568 /* Extend the sign bit. */
569 if (SIZEOF_LONG > f->size)
570 x |= -(x & (1L << (8*f->size - 1)));
571 return PyInt_FromLong(x);
574 static PyObject *
575 bu_uint(const char *p, const formatdef *f)
577 unsigned long x = 0;
578 int i = f->size;
579 do {
580 x = (x<<8) | (*p++ & 0xFF);
581 } while (--i > 0);
582 if (f->size >= 4)
583 return PyLong_FromUnsignedLong(x);
584 else
585 return PyInt_FromLong((long)x);
588 static PyObject *
589 bu_longlong(const char *p, const formatdef *f)
591 return _PyLong_FromByteArray((const unsigned char *)p,
593 0, /* little-endian */
594 1 /* signed */);
597 static PyObject *
598 bu_ulonglong(const char *p, const formatdef *f)
600 return _PyLong_FromByteArray((const unsigned char *)p,
602 0, /* little-endian */
603 0 /* signed */);
606 static PyObject *
607 bu_float(const char *p, const formatdef *f)
609 return unpack_float(p, 0);
612 static PyObject *
613 bu_double(const char *p, const formatdef *f)
615 return unpack_double(p, 0);
618 static int
619 bp_int(char *p, PyObject *v, const formatdef *f)
621 long x;
622 int i;
623 if (get_long(v, &x) < 0)
624 return -1;
625 i = f->size;
626 do {
627 p[--i] = (char)x;
628 x >>= 8;
629 } while (i > 0);
630 return 0;
633 static int
634 bp_uint(char *p, PyObject *v, const formatdef *f)
636 unsigned long x;
637 int i;
638 if (get_ulong(v, &x) < 0)
639 return -1;
640 i = f->size;
641 do {
642 p[--i] = (char)x;
643 x >>= 8;
644 } while (i > 0);
645 return 0;
648 static int
649 bp_longlong(char *p, PyObject *v, const formatdef *f)
651 int res;
652 v = get_pylong(v);
653 if (v == NULL)
654 return -1;
655 res = _PyLong_AsByteArray((PyLongObject *)v,
656 (unsigned char *)p,
658 0, /* little_endian */
659 1 /* signed */);
660 Py_DECREF(v);
661 return res;
664 static int
665 bp_ulonglong(char *p, PyObject *v, const formatdef *f)
667 int res;
668 v = get_pylong(v);
669 if (v == NULL)
670 return -1;
671 res = _PyLong_AsByteArray((PyLongObject *)v,
672 (unsigned char *)p,
674 0, /* little_endian */
675 0 /* signed */);
676 Py_DECREF(v);
677 return res;
680 static int
681 bp_float(char *p, PyObject *v, const formatdef *f)
683 double x = PyFloat_AsDouble(v);
684 if (x == -1 && PyErr_Occurred()) {
685 PyErr_SetString(StructError,
686 "required argument is not a float");
687 return -1;
689 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
692 static int
693 bp_double(char *p, PyObject *v, const formatdef *f)
695 double x = PyFloat_AsDouble(v);
696 if (x == -1 && PyErr_Occurred()) {
697 PyErr_SetString(StructError,
698 "required argument is not a float");
699 return -1;
701 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
704 static formatdef bigendian_table[] = {
705 {'x', 1, 0, NULL},
706 {'b', 1, 0, bu_int, bp_int},
707 {'B', 1, 0, bu_uint, bp_int},
708 {'c', 1, 0, nu_char, np_char},
709 {'s', 1, 0, NULL},
710 {'p', 1, 0, NULL},
711 {'h', 2, 0, bu_int, bp_int},
712 {'H', 2, 0, bu_uint, bp_uint},
713 {'i', 4, 0, bu_int, bp_int},
714 {'I', 4, 0, bu_uint, bp_uint},
715 {'l', 4, 0, bu_int, bp_int},
716 {'L', 4, 0, bu_uint, bp_uint},
717 {'q', 8, 0, bu_longlong, bp_longlong},
718 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
719 {'f', 4, 0, bu_float, bp_float},
720 {'d', 8, 0, bu_double, bp_double},
724 /* Little-endian routines. *****************************************************/
726 static PyObject *
727 lu_int(const char *p, const formatdef *f)
729 long x = 0;
730 int i = f->size;
731 do {
732 x = (x<<8) | (p[--i] & 0xFF);
733 } while (i > 0);
734 /* Extend the sign bit. */
735 if (SIZEOF_LONG > f->size)
736 x |= -(x & (1L << (8*f->size - 1)));
737 return PyInt_FromLong(x);
740 static PyObject *
741 lu_uint(const char *p, const formatdef *f)
743 unsigned long x = 0;
744 int i = f->size;
745 do {
746 x = (x<<8) | (p[--i] & 0xFF);
747 } while (i > 0);
748 if (f->size >= 4)
749 return PyLong_FromUnsignedLong(x);
750 else
751 return PyInt_FromLong((long)x);
754 static PyObject *
755 lu_longlong(const char *p, const formatdef *f)
757 return _PyLong_FromByteArray((const unsigned char *)p,
759 1, /* little-endian */
760 1 /* signed */);
763 static PyObject *
764 lu_ulonglong(const char *p, const formatdef *f)
766 return _PyLong_FromByteArray((const unsigned char *)p,
768 1, /* little-endian */
769 0 /* signed */);
772 static PyObject *
773 lu_float(const char *p, const formatdef *f)
775 return unpack_float(p, 1);
778 static PyObject *
779 lu_double(const char *p, const formatdef *f)
781 return unpack_double(p, 1);
784 static int
785 lp_int(char *p, PyObject *v, const formatdef *f)
787 long x;
788 int i;
789 if (get_long(v, &x) < 0)
790 return -1;
791 i = f->size;
792 do {
793 *p++ = (char)x;
794 x >>= 8;
795 } while (--i > 0);
796 return 0;
799 static int
800 lp_uint(char *p, PyObject *v, const formatdef *f)
802 unsigned long x;
803 int i;
804 if (get_ulong(v, &x) < 0)
805 return -1;
806 i = f->size;
807 do {
808 *p++ = (char)x;
809 x >>= 8;
810 } while (--i > 0);
811 return 0;
814 static int
815 lp_longlong(char *p, PyObject *v, const formatdef *f)
817 int res;
818 v = get_pylong(v);
819 if (v == NULL)
820 return -1;
821 res = _PyLong_AsByteArray((PyLongObject*)v,
822 (unsigned char *)p,
824 1, /* little_endian */
825 1 /* signed */);
826 Py_DECREF(v);
827 return res;
830 static int
831 lp_ulonglong(char *p, PyObject *v, const formatdef *f)
833 int res;
834 v = get_pylong(v);
835 if (v == NULL)
836 return -1;
837 res = _PyLong_AsByteArray((PyLongObject*)v,
838 (unsigned char *)p,
840 1, /* little_endian */
841 0 /* signed */);
842 Py_DECREF(v);
843 return res;
846 static int
847 lp_float(char *p, PyObject *v, const formatdef *f)
849 double x = PyFloat_AsDouble(v);
850 if (x == -1 && PyErr_Occurred()) {
851 PyErr_SetString(StructError,
852 "required argument is not a float");
853 return -1;
855 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
858 static int
859 lp_double(char *p, PyObject *v, const formatdef *f)
861 double x = PyFloat_AsDouble(v);
862 if (x == -1 && PyErr_Occurred()) {
863 PyErr_SetString(StructError,
864 "required argument is not a float");
865 return -1;
867 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
870 static formatdef lilendian_table[] = {
871 {'x', 1, 0, NULL},
872 {'b', 1, 0, lu_int, lp_int},
873 {'B', 1, 0, lu_uint, lp_int},
874 {'c', 1, 0, nu_char, np_char},
875 {'s', 1, 0, NULL},
876 {'p', 1, 0, NULL},
877 {'h', 2, 0, lu_int, lp_int},
878 {'H', 2, 0, lu_uint, lp_uint},
879 {'i', 4, 0, lu_int, lp_int},
880 {'I', 4, 0, lu_uint, lp_uint},
881 {'l', 4, 0, lu_int, lp_int},
882 {'L', 4, 0, lu_uint, lp_uint},
883 {'q', 8, 0, lu_longlong, lp_longlong},
884 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
885 {'f', 4, 0, lu_float, lp_float},
886 {'d', 8, 0, lu_double, lp_double},
891 static const formatdef *
892 whichtable(char **pfmt)
894 const char *fmt = (*pfmt)++; /* May be backed out of later */
895 switch (*fmt) {
896 case '<':
897 return lilendian_table;
898 case '>':
899 case '!': /* Network byte order is big-endian */
900 return bigendian_table;
901 case '=': { /* Host byte order -- different from native in aligment! */
902 int n = 1;
903 char *p = (char *) &n;
904 if (*p == 1)
905 return lilendian_table;
906 else
907 return bigendian_table;
909 default:
910 --*pfmt; /* Back out of pointer increment */
911 /* Fall through */
912 case '@':
913 return native_table;
918 /* Get the table entry for a format code */
920 static const formatdef *
921 getentry(int c, const formatdef *f)
923 for (; f->format != '\0'; f++) {
924 if (f->format == c) {
925 return f;
928 PyErr_SetString(StructError, "bad char in struct format");
929 return NULL;
933 /* Align a size according to a format code */
935 static int
936 align(int size, int c, const formatdef *e)
938 if (e->format == c) {
939 if (e->alignment) {
940 size = ((size + e->alignment - 1)
941 / e->alignment)
942 * e->alignment;
945 return size;
949 /* calculate the size of a format string */
951 static int
952 calcsize(const char *fmt, const formatdef *f)
954 const formatdef *e;
955 const char *s;
956 char c;
957 int size, num, itemsize, x;
959 s = fmt;
960 size = 0;
961 while ((c = *s++) != '\0') {
962 if (isspace(Py_CHARMASK(c)))
963 continue;
964 if ('0' <= c && c <= '9') {
965 num = c - '0';
966 while ('0' <= (c = *s++) && c <= '9') {
967 x = num*10 + (c - '0');
968 if (x/10 != num) {
969 PyErr_SetString(
970 StructError,
971 "overflow in item count");
972 return -1;
974 num = x;
976 if (c == '\0')
977 break;
979 else
980 num = 1;
982 e = getentry(c, f);
983 if (e == NULL)
984 return -1;
985 itemsize = e->size;
986 size = align(size, c, e);
987 x = num * itemsize;
988 size += x;
989 if (x/itemsize != num || size < 0) {
990 PyErr_SetString(StructError,
991 "total struct size too long");
992 return -1;
996 return size;
1000 PyDoc_STRVAR(calcsize__doc__,
1001 "calcsize(fmt) -> int\n\
1002 Return size of C struct described by format string fmt.\n\
1003 See struct.__doc__ for more on format strings.");
1005 static PyObject *
1006 struct_calcsize(PyObject *self, PyObject *args)
1008 char *fmt;
1009 const formatdef *f;
1010 int size;
1012 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
1013 return NULL;
1014 f = whichtable(&fmt);
1015 size = calcsize(fmt, f);
1016 if (size < 0)
1017 return NULL;
1018 return PyInt_FromLong((long)size);
1022 PyDoc_STRVAR(pack__doc__,
1023 "pack(fmt, v1, v2, ...) -> string\n\
1024 Return string containing values v1, v2, ... packed according to fmt.\n\
1025 See struct.__doc__ for more on format strings.");
1027 static PyObject *
1028 struct_pack(PyObject *self, PyObject *args)
1030 const formatdef *f, *e;
1031 PyObject *format, *result, *v;
1032 char *fmt;
1033 int size, num;
1034 int i, n;
1035 char *s, *res, *restart, *nres;
1036 char c;
1038 if (args == NULL || !PyTuple_Check(args) ||
1039 (n = PyTuple_Size(args)) < 1)
1041 PyErr_SetString(PyExc_TypeError,
1042 "struct.pack requires at least one argument");
1043 return NULL;
1045 format = PyTuple_GetItem(args, 0);
1046 fmt = PyString_AsString(format);
1047 if (!fmt)
1048 return NULL;
1049 f = whichtable(&fmt);
1050 size = calcsize(fmt, f);
1051 if (size < 0)
1052 return NULL;
1053 result = PyString_FromStringAndSize((char *)NULL, size);
1054 if (result == NULL)
1055 return NULL;
1057 s = fmt;
1058 i = 1;
1059 res = restart = PyString_AsString(result);
1061 while ((c = *s++) != '\0') {
1062 if (isspace(Py_CHARMASK(c)))
1063 continue;
1064 if ('0' <= c && c <= '9') {
1065 num = c - '0';
1066 while ('0' <= (c = *s++) && c <= '9')
1067 num = num*10 + (c - '0');
1068 if (c == '\0')
1069 break;
1071 else
1072 num = 1;
1074 e = getentry(c, f);
1075 if (e == NULL)
1076 goto fail;
1077 nres = restart + align((int)(res-restart), c, e);
1078 /* Fill padd bytes with zeros */
1079 while (res < nres)
1080 *res++ = '\0';
1081 if (num == 0 && c != 's')
1082 continue;
1083 do {
1084 if (c == 'x') {
1085 /* doesn't consume arguments */
1086 memset(res, '\0', num);
1087 res += num;
1088 break;
1090 if (i >= n) {
1091 PyErr_SetString(StructError,
1092 "insufficient arguments to pack");
1093 goto fail;
1095 v = PyTuple_GetItem(args, i++);
1096 if (v == NULL)
1097 goto fail;
1098 if (c == 's') {
1099 /* num is string size, not repeat count */
1100 int n;
1101 if (!PyString_Check(v)) {
1102 PyErr_SetString(StructError,
1103 "argument for 's' must be a string");
1104 goto fail;
1106 n = PyString_Size(v);
1107 if (n > num)
1108 n = num;
1109 if (n > 0)
1110 memcpy(res, PyString_AsString(v), n);
1111 if (n < num)
1112 memset(res+n, '\0', num-n);
1113 res += num;
1114 break;
1116 else if (c == 'p') {
1117 /* num is string size + 1,
1118 to fit in the count byte */
1119 int n;
1120 num--; /* now num is max string size */
1121 if (!PyString_Check(v)) {
1122 PyErr_SetString(StructError,
1123 "argument for 'p' must be a string");
1124 goto fail;
1126 n = PyString_Size(v);
1127 if (n > num)
1128 n = num;
1129 if (n > 0)
1130 memcpy(res+1, PyString_AsString(v), n);
1131 if (n < num)
1132 /* no real need, just to be nice */
1133 memset(res+1+n, '\0', num-n);
1134 if (n > 255)
1135 n = 255;
1136 *res++ = n; /* store the length byte */
1137 res += num;
1138 break;
1140 else {
1141 if (e->pack(res, v, e) < 0)
1142 goto fail;
1143 res += e->size;
1145 } while (--num > 0);
1148 if (i < n) {
1149 PyErr_SetString(StructError,
1150 "too many arguments for pack format");
1151 goto fail;
1154 return result;
1156 fail:
1157 Py_DECREF(result);
1158 return NULL;
1162 PyDoc_STRVAR(unpack__doc__,
1163 "unpack(fmt, string) -> (v1, v2, ...)\n\
1164 Unpack the string, containing packed C structure data, according\n\
1165 to fmt. Requires len(string)==calcsize(fmt).\n\
1166 See struct.__doc__ for more on format strings.");
1168 static PyObject *
1169 struct_unpack(PyObject *self, PyObject *args)
1171 const formatdef *f, *e;
1172 char *str, *start, *fmt, *s;
1173 char c;
1174 int len, size, num;
1175 PyObject *res, *v;
1177 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
1178 return NULL;
1179 f = whichtable(&fmt);
1180 size = calcsize(fmt, f);
1181 if (size < 0)
1182 return NULL;
1183 if (size != len) {
1184 PyErr_SetString(StructError,
1185 "unpack str size does not match format");
1186 return NULL;
1188 res = PyList_New(0);
1189 if (res == NULL)
1190 return NULL;
1191 str = start;
1192 s = fmt;
1193 while ((c = *s++) != '\0') {
1194 if (isspace(Py_CHARMASK(c)))
1195 continue;
1196 if ('0' <= c && c <= '9') {
1197 num = c - '0';
1198 while ('0' <= (c = *s++) && c <= '9')
1199 num = num*10 + (c - '0');
1200 if (c == '\0')
1201 break;
1203 else
1204 num = 1;
1206 e = getentry(c, f);
1207 if (e == NULL)
1208 goto fail;
1209 str = start + align((int)(str-start), c, e);
1210 if (num == 0 && c != 's')
1211 continue;
1213 do {
1214 if (c == 'x') {
1215 str += num;
1216 break;
1218 if (c == 's') {
1219 /* num is string size, not repeat count */
1220 v = PyString_FromStringAndSize(str, num);
1221 if (v == NULL)
1222 goto fail;
1223 str += num;
1224 num = 0;
1226 else if (c == 'p') {
1227 /* num is string buffer size,
1228 not repeat count */
1229 int n = *(unsigned char*)str;
1230 /* first byte (unsigned) is string size */
1231 if (n >= num)
1232 n = num-1;
1233 v = PyString_FromStringAndSize(str+1, n);
1234 if (v == NULL)
1235 goto fail;
1236 str += num;
1237 num = 0;
1239 else {
1240 v = e->unpack(str, e);
1241 if (v == NULL)
1242 goto fail;
1243 str += e->size;
1245 if (v == NULL || PyList_Append(res, v) < 0)
1246 goto fail;
1247 Py_DECREF(v);
1248 } while (--num > 0);
1251 v = PyList_AsTuple(res);
1252 Py_DECREF(res);
1253 return v;
1255 fail:
1256 Py_DECREF(res);
1257 return NULL;
1261 /* List of functions */
1263 static PyMethodDef struct_methods[] = {
1264 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1265 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1266 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
1267 {NULL, NULL} /* sentinel */
1271 /* Module initialization */
1273 PyMODINIT_FUNC
1274 initstruct(void)
1276 PyObject *m;
1278 /* Create the module and add the functions */
1279 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1280 (PyObject*)NULL, PYTHON_API_VERSION);
1281 if (m == NULL)
1282 return;
1284 /* Add some symbolic constants to the module */
1285 if (StructError == NULL) {
1286 StructError = PyErr_NewException("struct.error", NULL, NULL);
1287 if (StructError == NULL)
1288 return;
1290 Py_INCREF(StructError);
1291 PyModule_AddObject(m, "error", StructError);