Whitespace normalization.
[python/dscho.git] / Modules / structmodule.c
blobb78231f4d3cfcb85d3e3bcd19f03160ad8d775d6
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 = PyLong_AsVoidPtr(v);
522 if (x == NULL && PyErr_Occurred()) {
523 /* ### hrm. PyLong_AsVoidPtr raises SystemError */
524 if (PyErr_ExceptionMatches(PyExc_TypeError))
525 PyErr_SetString(StructError,
526 "required argument is not an integer");
527 return -1;
529 memcpy(p, (char *)&x, sizeof x);
530 return 0;
533 static formatdef native_table[] = {
534 {'x', sizeof(char), 0, NULL},
535 {'b', sizeof(char), 0, nu_byte, np_byte},
536 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
537 {'c', sizeof(char), 0, nu_char, np_char},
538 {'s', sizeof(char), 0, NULL},
539 {'p', sizeof(char), 0, NULL},
540 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
541 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
542 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
543 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
544 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
545 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
546 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
547 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
548 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
549 #ifdef HAVE_LONG_LONG
550 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
551 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
552 #endif
556 /* Big-endian routines. *****************************************************/
558 static PyObject *
559 bu_int(const char *p, const formatdef *f)
561 long x = 0;
562 int i = f->size;
563 do {
564 x = (x<<8) | (*p++ & 0xFF);
565 } while (--i > 0);
566 /* Extend the sign bit. */
567 if (SIZEOF_LONG > f->size)
568 x |= -(x & (1L << (8*f->size - 1)));
569 return PyInt_FromLong(x);
572 static PyObject *
573 bu_uint(const char *p, const formatdef *f)
575 unsigned long x = 0;
576 int i = f->size;
577 do {
578 x = (x<<8) | (*p++ & 0xFF);
579 } while (--i > 0);
580 if (f->size >= 4)
581 return PyLong_FromUnsignedLong(x);
582 else
583 return PyInt_FromLong((long)x);
586 static PyObject *
587 bu_longlong(const char *p, const formatdef *f)
589 return _PyLong_FromByteArray((const unsigned char *)p,
591 0, /* little-endian */
592 1 /* signed */);
595 static PyObject *
596 bu_ulonglong(const char *p, const formatdef *f)
598 return _PyLong_FromByteArray((const unsigned char *)p,
600 0, /* little-endian */
601 0 /* signed */);
604 static PyObject *
605 bu_float(const char *p, const formatdef *f)
607 return unpack_float(p, 0);
610 static PyObject *
611 bu_double(const char *p, const formatdef *f)
613 return unpack_double(p, 0);
616 static int
617 bp_int(char *p, PyObject *v, const formatdef *f)
619 long x;
620 int i;
621 if (get_long(v, &x) < 0)
622 return -1;
623 i = f->size;
624 do {
625 p[--i] = (char)x;
626 x >>= 8;
627 } while (i > 0);
628 return 0;
631 static int
632 bp_uint(char *p, PyObject *v, const formatdef *f)
634 unsigned long x;
635 int i;
636 if (get_ulong(v, &x) < 0)
637 return -1;
638 i = f->size;
639 do {
640 p[--i] = (char)x;
641 x >>= 8;
642 } while (i > 0);
643 return 0;
646 static int
647 bp_longlong(char *p, PyObject *v, const formatdef *f)
649 int res;
650 v = get_pylong(v);
651 if (v == NULL)
652 return -1;
653 res = _PyLong_AsByteArray((PyLongObject *)v,
654 (unsigned char *)p,
656 0, /* little_endian */
657 1 /* signed */);
658 Py_DECREF(v);
659 return res;
662 static int
663 bp_ulonglong(char *p, PyObject *v, const formatdef *f)
665 int res;
666 v = get_pylong(v);
667 if (v == NULL)
668 return -1;
669 res = _PyLong_AsByteArray((PyLongObject *)v,
670 (unsigned char *)p,
672 0, /* little_endian */
673 0 /* signed */);
674 Py_DECREF(v);
675 return res;
678 static int
679 bp_float(char *p, PyObject *v, const formatdef *f)
681 double x = PyFloat_AsDouble(v);
682 if (x == -1 && PyErr_Occurred()) {
683 PyErr_SetString(StructError,
684 "required argument is not a float");
685 return -1;
687 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
690 static int
691 bp_double(char *p, PyObject *v, const formatdef *f)
693 double x = PyFloat_AsDouble(v);
694 if (x == -1 && PyErr_Occurred()) {
695 PyErr_SetString(StructError,
696 "required argument is not a float");
697 return -1;
699 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
702 static formatdef bigendian_table[] = {
703 {'x', 1, 0, NULL},
704 {'b', 1, 0, bu_int, bp_int},
705 {'B', 1, 0, bu_uint, bp_int},
706 {'c', 1, 0, nu_char, np_char},
707 {'s', 1, 0, NULL},
708 {'p', 1, 0, NULL},
709 {'h', 2, 0, bu_int, bp_int},
710 {'H', 2, 0, bu_uint, bp_uint},
711 {'i', 4, 0, bu_int, bp_int},
712 {'I', 4, 0, bu_uint, bp_uint},
713 {'l', 4, 0, bu_int, bp_int},
714 {'L', 4, 0, bu_uint, bp_uint},
715 {'q', 8, 0, bu_longlong, bp_longlong},
716 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
717 {'f', 4, 0, bu_float, bp_float},
718 {'d', 8, 0, bu_double, bp_double},
722 /* Little-endian routines. *****************************************************/
724 static PyObject *
725 lu_int(const char *p, const formatdef *f)
727 long x = 0;
728 int i = f->size;
729 do {
730 x = (x<<8) | (p[--i] & 0xFF);
731 } while (i > 0);
732 /* Extend the sign bit. */
733 if (SIZEOF_LONG > f->size)
734 x |= -(x & (1L << (8*f->size - 1)));
735 return PyInt_FromLong(x);
738 static PyObject *
739 lu_uint(const char *p, const formatdef *f)
741 unsigned long x = 0;
742 int i = f->size;
743 do {
744 x = (x<<8) | (p[--i] & 0xFF);
745 } while (i > 0);
746 if (f->size >= 4)
747 return PyLong_FromUnsignedLong(x);
748 else
749 return PyInt_FromLong((long)x);
752 static PyObject *
753 lu_longlong(const char *p, const formatdef *f)
755 return _PyLong_FromByteArray((const unsigned char *)p,
757 1, /* little-endian */
758 1 /* signed */);
761 static PyObject *
762 lu_ulonglong(const char *p, const formatdef *f)
764 return _PyLong_FromByteArray((const unsigned char *)p,
766 1, /* little-endian */
767 0 /* signed */);
770 static PyObject *
771 lu_float(const char *p, const formatdef *f)
773 return unpack_float(p, 1);
776 static PyObject *
777 lu_double(const char *p, const formatdef *f)
779 return unpack_double(p, 1);
782 static int
783 lp_int(char *p, PyObject *v, const formatdef *f)
785 long x;
786 int i;
787 if (get_long(v, &x) < 0)
788 return -1;
789 i = f->size;
790 do {
791 *p++ = (char)x;
792 x >>= 8;
793 } while (--i > 0);
794 return 0;
797 static int
798 lp_uint(char *p, PyObject *v, const formatdef *f)
800 unsigned long x;
801 int i;
802 if (get_ulong(v, &x) < 0)
803 return -1;
804 i = f->size;
805 do {
806 *p++ = (char)x;
807 x >>= 8;
808 } while (--i > 0);
809 return 0;
812 static int
813 lp_longlong(char *p, PyObject *v, const formatdef *f)
815 int res;
816 v = get_pylong(v);
817 if (v == NULL)
818 return -1;
819 res = _PyLong_AsByteArray((PyLongObject*)v,
820 (unsigned char *)p,
822 1, /* little_endian */
823 1 /* signed */);
824 Py_DECREF(v);
825 return res;
828 static int
829 lp_ulonglong(char *p, PyObject *v, const formatdef *f)
831 int res;
832 v = get_pylong(v);
833 if (v == NULL)
834 return -1;
835 res = _PyLong_AsByteArray((PyLongObject*)v,
836 (unsigned char *)p,
838 1, /* little_endian */
839 0 /* signed */);
840 Py_DECREF(v);
841 return res;
844 static int
845 lp_float(char *p, PyObject *v, const formatdef *f)
847 double x = PyFloat_AsDouble(v);
848 if (x == -1 && PyErr_Occurred()) {
849 PyErr_SetString(StructError,
850 "required argument is not a float");
851 return -1;
853 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
856 static int
857 lp_double(char *p, PyObject *v, const formatdef *f)
859 double x = PyFloat_AsDouble(v);
860 if (x == -1 && PyErr_Occurred()) {
861 PyErr_SetString(StructError,
862 "required argument is not a float");
863 return -1;
865 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
868 static formatdef lilendian_table[] = {
869 {'x', 1, 0, NULL},
870 {'b', 1, 0, lu_int, lp_int},
871 {'B', 1, 0, lu_uint, lp_int},
872 {'c', 1, 0, nu_char, np_char},
873 {'s', 1, 0, NULL},
874 {'p', 1, 0, NULL},
875 {'h', 2, 0, lu_int, lp_int},
876 {'H', 2, 0, lu_uint, lp_uint},
877 {'i', 4, 0, lu_int, lp_int},
878 {'I', 4, 0, lu_uint, lp_uint},
879 {'l', 4, 0, lu_int, lp_int},
880 {'L', 4, 0, lu_uint, lp_uint},
881 {'q', 8, 0, lu_longlong, lp_longlong},
882 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
883 {'f', 4, 0, lu_float, lp_float},
884 {'d', 8, 0, lu_double, lp_double},
889 static const formatdef *
890 whichtable(char **pfmt)
892 const char *fmt = (*pfmt)++; /* May be backed out of later */
893 switch (*fmt) {
894 case '<':
895 return lilendian_table;
896 case '>':
897 case '!': /* Network byte order is big-endian */
898 return bigendian_table;
899 case '=': { /* Host byte order -- different from native in aligment! */
900 int n = 1;
901 char *p = (char *) &n;
902 if (*p == 1)
903 return lilendian_table;
904 else
905 return bigendian_table;
907 default:
908 --*pfmt; /* Back out of pointer increment */
909 /* Fall through */
910 case '@':
911 return native_table;
916 /* Get the table entry for a format code */
918 static const formatdef *
919 getentry(int c, const formatdef *f)
921 for (; f->format != '\0'; f++) {
922 if (f->format == c) {
923 return f;
926 PyErr_SetString(StructError, "bad char in struct format");
927 return NULL;
931 /* Align a size according to a format code */
933 static int
934 align(int size, int c, const formatdef *e)
936 if (e->format == c) {
937 if (e->alignment) {
938 size = ((size + e->alignment - 1)
939 / e->alignment)
940 * e->alignment;
943 return size;
947 /* calculate the size of a format string */
949 static int
950 calcsize(const char *fmt, const formatdef *f)
952 const formatdef *e;
953 const char *s;
954 char c;
955 int size, num, itemsize, x;
957 s = fmt;
958 size = 0;
959 while ((c = *s++) != '\0') {
960 if (isspace((int)c))
961 continue;
962 if ('0' <= c && c <= '9') {
963 num = c - '0';
964 while ('0' <= (c = *s++) && c <= '9') {
965 x = num*10 + (c - '0');
966 if (x/10 != num) {
967 PyErr_SetString(
968 StructError,
969 "overflow in item count");
970 return -1;
972 num = x;
974 if (c == '\0')
975 break;
977 else
978 num = 1;
980 e = getentry(c, f);
981 if (e == NULL)
982 return -1;
983 itemsize = e->size;
984 size = align(size, c, e);
985 x = num * itemsize;
986 size += x;
987 if (x/itemsize != num || size < 0) {
988 PyErr_SetString(StructError,
989 "total struct size too long");
990 return -1;
994 return size;
998 PyDoc_STRVAR(calcsize__doc__,
999 "calcsize(fmt) -> int\n\
1000 Return size of C struct described by format string fmt.\n\
1001 See struct.__doc__ for more on format strings.");
1003 static PyObject *
1004 struct_calcsize(PyObject *self, PyObject *args)
1006 char *fmt;
1007 const formatdef *f;
1008 int size;
1010 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
1011 return NULL;
1012 f = whichtable(&fmt);
1013 size = calcsize(fmt, f);
1014 if (size < 0)
1015 return NULL;
1016 return PyInt_FromLong((long)size);
1020 PyDoc_STRVAR(pack__doc__,
1021 "pack(fmt, v1, v2, ...) -> string\n\
1022 Return string containing values v1, v2, ... packed according to fmt.\n\
1023 See struct.__doc__ for more on format strings.");
1025 static PyObject *
1026 struct_pack(PyObject *self, PyObject *args)
1028 const formatdef *f, *e;
1029 PyObject *format, *result, *v;
1030 char *fmt;
1031 int size, num;
1032 int i, n;
1033 char *s, *res, *restart, *nres;
1034 char c;
1036 if (args == NULL || !PyTuple_Check(args) ||
1037 (n = PyTuple_Size(args)) < 1)
1039 PyErr_SetString(PyExc_TypeError,
1040 "struct.pack requires at least one argument");
1041 return NULL;
1043 format = PyTuple_GetItem(args, 0);
1044 fmt = PyString_AsString(format);
1045 if (!fmt)
1046 return NULL;
1047 f = whichtable(&fmt);
1048 size = calcsize(fmt, f);
1049 if (size < 0)
1050 return NULL;
1051 result = PyString_FromStringAndSize((char *)NULL, size);
1052 if (result == NULL)
1053 return NULL;
1055 s = fmt;
1056 i = 1;
1057 res = restart = PyString_AsString(result);
1059 while ((c = *s++) != '\0') {
1060 if (isspace((int)c))
1061 continue;
1062 if ('0' <= c && c <= '9') {
1063 num = c - '0';
1064 while ('0' <= (c = *s++) && c <= '9')
1065 num = num*10 + (c - '0');
1066 if (c == '\0')
1067 break;
1069 else
1070 num = 1;
1072 e = getentry(c, f);
1073 if (e == NULL)
1074 goto fail;
1075 nres = restart + align((int)(res-restart), c, e);
1076 /* Fill padd bytes with zeros */
1077 while (res < nres)
1078 *res++ = '\0';
1079 if (num == 0 && c != 's')
1080 continue;
1081 do {
1082 if (c == 'x') {
1083 /* doesn't consume arguments */
1084 memset(res, '\0', num);
1085 res += num;
1086 break;
1088 if (i >= n) {
1089 PyErr_SetString(StructError,
1090 "insufficient arguments to pack");
1091 goto fail;
1093 v = PyTuple_GetItem(args, i++);
1094 if (v == NULL)
1095 goto fail;
1096 if (c == 's') {
1097 /* num is string size, not repeat count */
1098 int n;
1099 if (!PyString_Check(v)) {
1100 PyErr_SetString(StructError,
1101 "argument for 's' must be a string");
1102 goto fail;
1104 n = PyString_Size(v);
1105 if (n > num)
1106 n = num;
1107 if (n > 0)
1108 memcpy(res, PyString_AsString(v), n);
1109 if (n < num)
1110 memset(res+n, '\0', num-n);
1111 res += num;
1112 break;
1114 else if (c == 'p') {
1115 /* num is string size + 1,
1116 to fit in the count byte */
1117 int n;
1118 num--; /* now num is max string size */
1119 if (!PyString_Check(v)) {
1120 PyErr_SetString(StructError,
1121 "argument for 'p' must be a string");
1122 goto fail;
1124 n = PyString_Size(v);
1125 if (n > num)
1126 n = num;
1127 if (n > 0)
1128 memcpy(res+1, PyString_AsString(v), n);
1129 if (n < num)
1130 /* no real need, just to be nice */
1131 memset(res+1+n, '\0', num-n);
1132 if (n > 255)
1133 n = 255;
1134 *res++ = n; /* store the length byte */
1135 res += num;
1136 break;
1138 else {
1139 if (e->pack(res, v, e) < 0)
1140 goto fail;
1141 res += e->size;
1143 } while (--num > 0);
1146 if (i < n) {
1147 PyErr_SetString(StructError,
1148 "too many arguments for pack format");
1149 goto fail;
1152 return result;
1154 fail:
1155 Py_DECREF(result);
1156 return NULL;
1160 PyDoc_STRVAR(unpack__doc__,
1161 "unpack(fmt, string) -> (v1, v2, ...)\n\
1162 Unpack the string, containing packed C structure data, according\n\
1163 to fmt. Requires len(string)==calcsize(fmt).\n\
1164 See struct.__doc__ for more on format strings.");
1166 static PyObject *
1167 struct_unpack(PyObject *self, PyObject *args)
1169 const formatdef *f, *e;
1170 char *str, *start, *fmt, *s;
1171 char c;
1172 int len, size, num;
1173 PyObject *res, *v;
1175 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
1176 return NULL;
1177 f = whichtable(&fmt);
1178 size = calcsize(fmt, f);
1179 if (size < 0)
1180 return NULL;
1181 if (size != len) {
1182 PyErr_SetString(StructError,
1183 "unpack str size does not match format");
1184 return NULL;
1186 res = PyList_New(0);
1187 if (res == NULL)
1188 return NULL;
1189 str = start;
1190 s = fmt;
1191 while ((c = *s++) != '\0') {
1192 if (isspace((int)c))
1193 continue;
1194 if ('0' <= c && c <= '9') {
1195 num = c - '0';
1196 while ('0' <= (c = *s++) && c <= '9')
1197 num = num*10 + (c - '0');
1198 if (c == '\0')
1199 break;
1201 else
1202 num = 1;
1204 e = getentry(c, f);
1205 if (e == NULL)
1206 goto fail;
1207 str = start + align((int)(str-start), c, e);
1208 if (num == 0 && c != 's')
1209 continue;
1211 do {
1212 if (c == 'x') {
1213 str += num;
1214 break;
1216 if (c == 's') {
1217 /* num is string size, not repeat count */
1218 v = PyString_FromStringAndSize(str, num);
1219 if (v == NULL)
1220 goto fail;
1221 str += num;
1222 num = 0;
1224 else if (c == 'p') {
1225 /* num is string buffer size,
1226 not repeat count */
1227 int n = *(unsigned char*)str;
1228 /* first byte (unsigned) is string size */
1229 if (n >= num)
1230 n = num-1;
1231 v = PyString_FromStringAndSize(str+1, n);
1232 if (v == NULL)
1233 goto fail;
1234 str += num;
1235 num = 0;
1237 else {
1238 v = e->unpack(str, e);
1239 if (v == NULL)
1240 goto fail;
1241 str += e->size;
1243 if (v == NULL || PyList_Append(res, v) < 0)
1244 goto fail;
1245 Py_DECREF(v);
1246 } while (--num > 0);
1249 v = PyList_AsTuple(res);
1250 Py_DECREF(res);
1251 return v;
1253 fail:
1254 Py_DECREF(res);
1255 return NULL;
1259 /* List of functions */
1261 static PyMethodDef struct_methods[] = {
1262 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1263 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1264 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
1265 {NULL, NULL} /* sentinel */
1269 /* Module initialization */
1271 PyMODINIT_FUNC
1272 initstruct(void)
1274 PyObject *m;
1276 /* Create the module and add the functions */
1277 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1278 (PyObject*)NULL, PYTHON_API_VERSION);
1280 /* Add some symbolic constants to the module */
1281 if (StructError == NULL) {
1282 StructError = PyErr_NewException("struct.error", NULL, NULL);
1283 if (StructError == NULL)
1284 return;
1286 Py_INCREF(StructError);
1287 PyModule_AddObject(m, "error", StructError);