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 */
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\
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\
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\
34 The variable struct.error is an exception raised on errors.");
39 static PyObject
*StructError
;
42 /* Define various structs to figure out the alignments of types */
46 ** XXXX We have a problem here. There are no unique alignment rules
47 ** on the PowerPC mac.
50 #pragma options align=mac68k
52 #endif /* __MWERKS__ */
54 typedef struct { char c
; short x
; } st_short
;
55 typedef struct { char c
; int x
; } st_int
;
56 typedef struct { char c
; long x
; } st_long
;
57 typedef struct { char c
; float x
; } st_float
;
58 typedef struct { char c
; double x
; } st_double
;
59 typedef struct { char c
; void *x
; } st_void_p
;
61 #define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
62 #define INT_ALIGN (sizeof(st_int) - sizeof(int))
63 #define LONG_ALIGN (sizeof(st_long) - sizeof(long))
64 #define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
65 #define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
66 #define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
68 /* We can't support q and Q in native mode unless the compiler does;
69 in std mode, they're 8 bytes on all platforms. */
71 typedef struct { char c
; LONG_LONG x
; } s_long_long
;
72 #define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(LONG_LONG))
75 #define STRINGIFY(x) #x
78 #pragma options align=reset
81 /* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
84 get_pylong(PyObject
*v
)
90 return PyLong_FromLong(PyInt_AS_LONG(v
));
91 if (PyLong_Check(v
)) {
95 m
= v
->ob_type
->tp_as_number
;
96 if (m
!= NULL
&& m
->nb_long
!= NULL
) {
104 PyErr_SetString(StructError
,
105 "cannot convert argument to long");
109 /* Helper routine to get a Python integer and raise the appropriate error
113 get_long(PyObject
*v
, long *p
)
115 long x
= PyInt_AsLong(v
);
116 if (x
== -1 && PyErr_Occurred()) {
117 if (PyErr_ExceptionMatches(PyExc_TypeError
))
118 PyErr_SetString(StructError
,
119 "required argument is not an integer");
127 /* Same, but handling unsigned long */
130 get_ulong(PyObject
*v
, unsigned long *p
)
132 if (PyLong_Check(v
)) {
133 unsigned long x
= PyLong_AsUnsignedLong(v
);
134 if (x
== (unsigned long)(-1) && PyErr_Occurred())
140 return get_long(v
, (long *)p
);
144 #ifdef HAVE_LONG_LONG
146 /* Same, but handling native long long. */
149 get_longlong(PyObject
*v
, LONG_LONG
*p
)
156 assert(PyLong_Check(v
));
157 x
= PyLong_AsLongLong(v
);
159 if (x
== (LONG_LONG
)-1 && PyErr_Occurred())
165 /* Same, but handling native unsigned long long. */
168 get_ulonglong(PyObject
*v
, unsigned LONG_LONG
*p
)
170 unsigned LONG_LONG x
;
175 assert(PyLong_Check(v
));
176 x
= PyLong_AsUnsignedLongLong(v
);
178 if (x
== (unsigned LONG_LONG
)-1 && PyErr_Occurred())
186 /* Floating point helpers */
188 /* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
189 Point Arithmetic). See the following URL:
190 http://www.psc.edu/general/software/packages/ieee/ieee.html */
192 /* XXX Inf/NaN are not handled quite right (but underflow is!) */
195 pack_float(double x
, /* The number to pack */
196 char *p
, /* Where to pack the high order byte */
197 int incr
) /* 1 for big-endian; -1 for little-endian */
213 /* Normalize f to be in the range [1.0, 2.0) */
214 if (0.5 <= f
&& f
< 1.0) {
222 PyErr_SetString(PyExc_SystemError
,
223 "frexp() result out of range");
228 /* XXX 128 itself is reserved for Inf/NaN */
229 PyErr_SetString(PyExc_OverflowError
,
230 "float too large to pack with f format");
234 /* Gradual underflow */
235 f
= ldexp(f
, 126 + e
);
238 else if (!(e
== 0 && f
== 0.0)) {
240 f
-= 1.0; /* Get rid of leading 1 */
243 f
*= 8388608.0; /* 2**23 */
244 fbits
= (long) floor(f
+ 0.5); /* Round */
247 *p
= (s
<<7) | (e
>>1);
251 *p
= (char) (((e
&1)<<7) | (fbits
>>16));
255 *p
= (fbits
>>8) & 0xFF;
266 pack_double(double x
, /* The number to pack */
267 char *p
, /* Where to pack the high order byte */
268 int incr
) /* 1 for big-endian; -1 for little-endian */
284 /* Normalize f to be in the range [1.0, 2.0) */
285 if (0.5 <= f
&& f
< 1.0) {
293 PyErr_SetString(PyExc_SystemError
,
294 "frexp() result out of range");
299 /* XXX 1024 itself is reserved for Inf/NaN */
300 PyErr_SetString(PyExc_OverflowError
,
301 "float too large to pack with d format");
304 else if (e
< -1022) {
305 /* Gradual underflow */
306 f
= ldexp(f
, 1022 + e
);
309 else if (!(e
== 0 && f
== 0.0)) {
311 f
-= 1.0; /* Get rid of leading 1 */
314 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
315 f
*= 268435456.0; /* 2**28 */
316 fhi
= (long) floor(f
); /* Truncate */
318 f
*= 16777216.0; /* 2**24 */
319 flo
= (long) floor(f
+ 0.5); /* Round */
322 *p
= (s
<<7) | (e
>>4);
326 *p
= (char) (((e
&0xF)<<4) | (fhi
>>24));
330 *p
= (fhi
>>16) & 0xFF;
334 *p
= (fhi
>>8) & 0xFF;
342 *p
= (flo
>>16) & 0xFF;
346 *p
= (flo
>>8) & 0xFF;
358 unpack_float(const char *p
, /* Where the high order byte is */
359 int incr
) /* 1 for big-endian; -1 for little-endian */
368 e
= (*p
& 0x7F) << 1;
373 f
= (*p
& 0x7F) << 16;
377 f
|= (*p
& 0xFF) << 8;
383 x
= (double)f
/ 8388608.0;
385 /* XXX This sadly ignores Inf/NaN issues */
397 return PyFloat_FromDouble(x
);
401 unpack_double(const char *p
, /* Where the high order byte is */
402 int incr
) /* 1 for big-endian; -1 for little-endian */
411 e
= (*p
& 0x7F) << 4;
416 fhi
= (*p
& 0xF) << 24;
420 fhi
|= (*p
& 0xFF) << 16;
424 fhi
|= (*p
& 0xFF) << 8;
432 flo
= (*p
& 0xFF) << 16;
436 flo
|= (*p
& 0xFF) << 8;
443 x
= (double)fhi
+ (double)flo
/ 16777216.0; /* 2**24 */
444 x
/= 268435456.0; /* 2**28 */
446 /* XXX This sadly ignores Inf/NaN */
458 return PyFloat_FromDouble(x
);
462 /* The translation function for each format character is table driven */
464 typedef struct _formatdef
{
468 PyObject
* (*unpack
)(const char *,
469 const struct _formatdef
*);
470 int (*pack
)(char *, PyObject
*,
471 const struct _formatdef
*);
474 /* A large number of small routines follow, with names of the form
478 [bln] distiguishes among big-endian, little-endian and native.
479 [pu] distiguishes between pack (to struct) and unpack (from struct).
480 TYPE is one of char, byte, ubyte, etc.
483 /* Native mode routines. ****************************************************/
485 In all n[up]_<type> routines handling types larger than 1 byte, there is
486 *no* guarantee that the p pointer is properly aligned for each type,
487 therefore memcpy is called. An intermediate variable is used to
488 compensate for big-endian architectures.
489 Normally both the intermediate variable and the memcpy call will be
490 skipped by C optimisation in little-endian architectures (gcc >= 2.91
494 nu_char(const char *p
, const formatdef
*f
)
496 return PyString_FromStringAndSize(p
, 1);
500 nu_byte(const char *p
, const formatdef
*f
)
502 return PyInt_FromLong((long) *(signed char *)p
);
506 nu_ubyte(const char *p
, const formatdef
*f
)
508 return PyInt_FromLong((long) *(unsigned char *)p
);
512 nu_short(const char *p
, const formatdef
*f
)
515 memcpy((char *)&x
, p
, sizeof x
);
516 return PyInt_FromLong((long)x
);
520 nu_ushort(const char *p
, const formatdef
*f
)
523 memcpy((char *)&x
, p
, sizeof x
);
524 return PyInt_FromLong((long)x
);
528 nu_int(const char *p
, const formatdef
*f
)
531 memcpy((char *)&x
, p
, sizeof x
);
532 return PyInt_FromLong((long)x
);
536 nu_uint(const char *p
, const formatdef
*f
)
539 memcpy((char *)&x
, p
, sizeof x
);
540 return PyLong_FromUnsignedLong((unsigned long)x
);
544 nu_long(const char *p
, const formatdef
*f
)
547 memcpy((char *)&x
, p
, sizeof x
);
548 return PyInt_FromLong(x
);
552 nu_ulong(const char *p
, const formatdef
*f
)
555 memcpy((char *)&x
, p
, sizeof x
);
556 return PyLong_FromUnsignedLong(x
);
559 /* Native mode doesn't support q or Q unless the platform C supports
560 long long (or, on Windows, __int64). */
562 #ifdef HAVE_LONG_LONG
565 nu_longlong(const char *p
, const formatdef
*f
)
568 memcpy((char *)&x
, p
, sizeof x
);
569 return PyLong_FromLongLong(x
);
573 nu_ulonglong(const char *p
, const formatdef
*f
)
575 unsigned LONG_LONG x
;
576 memcpy((char *)&x
, p
, sizeof x
);
577 return PyLong_FromUnsignedLongLong(x
);
583 nu_float(const char *p
, const formatdef
*f
)
586 memcpy((char *)&x
, p
, sizeof x
);
587 return PyFloat_FromDouble((double)x
);
591 nu_double(const char *p
, const formatdef
*f
)
594 memcpy((char *)&x
, p
, sizeof x
);
595 return PyFloat_FromDouble(x
);
599 nu_void_p(const char *p
, const formatdef
*f
)
602 memcpy((char *)&x
, p
, sizeof x
);
603 return PyLong_FromVoidPtr(x
);
607 np_byte(char *p
, PyObject
*v
, const formatdef
*f
)
610 if (get_long(v
, &x
) < 0)
612 if (x
< -128 || x
> 127){
613 PyErr_SetString(StructError
,
614 "byte format requires -128<=number<=127");
622 np_ubyte(char *p
, PyObject
*v
, const formatdef
*f
)
625 if (get_long(v
, &x
) < 0)
627 if (x
< 0 || x
> 255){
628 PyErr_SetString(StructError
,
629 "ubyte format requires 0<=number<=255");
637 np_char(char *p
, PyObject
*v
, const formatdef
*f
)
639 if (!PyString_Check(v
) || PyString_Size(v
) != 1) {
640 PyErr_SetString(StructError
,
641 "char format require string of length 1");
644 *p
= *PyString_AsString(v
);
649 np_short(char *p
, PyObject
*v
, const formatdef
*f
)
653 if (get_long(v
, &x
) < 0)
655 if (x
< SHRT_MIN
|| x
> SHRT_MAX
){
656 PyErr_SetString(StructError
,
657 "short format requires " STRINGIFY(SHRT_MIN
)
658 "<=number<=" STRINGIFY(SHRT_MAX
));
662 memcpy(p
, (char *)&y
, sizeof y
);
667 np_ushort(char *p
, PyObject
*v
, const formatdef
*f
)
671 if (get_long(v
, &x
) < 0)
673 if (x
< 0 || x
> USHRT_MAX
){
674 PyErr_SetString(StructError
,
675 "short format requires 0<=number<=" STRINGIFY(USHRT_MAX
));
678 y
= (unsigned short)x
;
679 memcpy(p
, (char *)&y
, sizeof y
);
684 np_int(char *p
, PyObject
*v
, const formatdef
*f
)
688 if (get_long(v
, &x
) < 0)
691 memcpy(p
, (char *)&y
, sizeof y
);
696 np_uint(char *p
, PyObject
*v
, const formatdef
*f
)
700 if (get_ulong(v
, &x
) < 0)
703 memcpy(p
, (char *)&y
, sizeof y
);
708 np_long(char *p
, PyObject
*v
, const formatdef
*f
)
711 if (get_long(v
, &x
) < 0)
713 memcpy(p
, (char *)&x
, sizeof x
);
718 np_ulong(char *p
, PyObject
*v
, const formatdef
*f
)
721 if (get_ulong(v
, &x
) < 0)
723 memcpy(p
, (char *)&x
, sizeof x
);
727 #ifdef HAVE_LONG_LONG
730 np_longlong(char *p
, PyObject
*v
, const formatdef
*f
)
733 if (get_longlong(v
, &x
) < 0)
735 memcpy(p
, (char *)&x
, sizeof x
);
740 np_ulonglong(char *p
, PyObject
*v
, const formatdef
*f
)
742 unsigned LONG_LONG x
;
743 if (get_ulonglong(v
, &x
) < 0)
745 memcpy(p
, (char *)&x
, sizeof x
);
751 np_float(char *p
, PyObject
*v
, const formatdef
*f
)
753 float x
= (float)PyFloat_AsDouble(v
);
754 if (x
== -1 && PyErr_Occurred()) {
755 PyErr_SetString(StructError
,
756 "required argument is not a float");
759 memcpy(p
, (char *)&x
, sizeof x
);
764 np_double(char *p
, PyObject
*v
, const formatdef
*f
)
766 double x
= PyFloat_AsDouble(v
);
767 if (x
== -1 && PyErr_Occurred()) {
768 PyErr_SetString(StructError
,
769 "required argument is not a float");
772 memcpy(p
, (char *)&x
, sizeof(double));
777 np_void_p(char *p
, PyObject
*v
, const formatdef
*f
)
779 void *x
= PyLong_AsVoidPtr(v
);
780 if (x
== NULL
&& PyErr_Occurred()) {
781 /* ### hrm. PyLong_AsVoidPtr raises SystemError */
782 if (PyErr_ExceptionMatches(PyExc_TypeError
))
783 PyErr_SetString(StructError
,
784 "required argument is not an integer");
787 memcpy(p
, (char *)&x
, sizeof x
);
791 static formatdef native_table
[] = {
792 {'x', sizeof(char), 0, NULL
},
793 {'b', sizeof(char), 0, nu_byte
, np_byte
},
794 {'B', sizeof(char), 0, nu_ubyte
, np_ubyte
},
795 {'c', sizeof(char), 0, nu_char
, np_char
},
796 {'s', sizeof(char), 0, NULL
},
797 {'p', sizeof(char), 0, NULL
},
798 {'h', sizeof(short), SHORT_ALIGN
, nu_short
, np_short
},
799 {'H', sizeof(short), SHORT_ALIGN
, nu_ushort
, np_ushort
},
800 {'i', sizeof(int), INT_ALIGN
, nu_int
, np_int
},
801 {'I', sizeof(int), INT_ALIGN
, nu_uint
, np_uint
},
802 {'l', sizeof(long), LONG_ALIGN
, nu_long
, np_long
},
803 {'L', sizeof(long), LONG_ALIGN
, nu_ulong
, np_ulong
},
804 {'f', sizeof(float), FLOAT_ALIGN
, nu_float
, np_float
},
805 {'d', sizeof(double), DOUBLE_ALIGN
, nu_double
, np_double
},
806 {'P', sizeof(void *), VOID_P_ALIGN
, nu_void_p
, np_void_p
},
807 #ifdef HAVE_LONG_LONG
808 {'q', sizeof(LONG_LONG
), LONG_LONG_ALIGN
, nu_longlong
, np_longlong
},
809 {'Q', sizeof(LONG_LONG
), LONG_LONG_ALIGN
, nu_ulonglong
,np_ulonglong
},
814 /* Big-endian routines. *****************************************************/
817 bu_int(const char *p
, const formatdef
*f
)
822 x
= (x
<<8) | (*p
++ & 0xFF);
824 /* Extend the sign bit. */
825 if (SIZEOF_LONG
> f
->size
)
826 x
|= -(x
& (1L << (8*f
->size
- 1)));
827 return PyInt_FromLong(x
);
831 bu_uint(const char *p
, const formatdef
*f
)
836 x
= (x
<<8) | (*p
++ & 0xFF);
839 return PyLong_FromUnsignedLong(x
);
841 return PyInt_FromLong((long)x
);
845 bu_longlong(const char *p
, const formatdef
*f
)
847 return _PyLong_FromByteArray((const unsigned char *)p
,
849 0, /* little-endian */
854 bu_ulonglong(const char *p
, const formatdef
*f
)
856 return _PyLong_FromByteArray((const unsigned char *)p
,
858 0, /* little-endian */
863 bu_float(const char *p
, const formatdef
*f
)
865 return unpack_float(p
, 1);
869 bu_double(const char *p
, const formatdef
*f
)
871 return unpack_double(p
, 1);
875 bp_int(char *p
, PyObject
*v
, const formatdef
*f
)
879 if (get_long(v
, &x
) < 0)
890 bp_uint(char *p
, PyObject
*v
, const formatdef
*f
)
894 if (get_ulong(v
, &x
) < 0)
905 bp_longlong(char *p
, PyObject
*v
, const formatdef
*f
)
911 res
= _PyLong_AsByteArray((PyLongObject
*)v
,
914 0, /* little_endian */
921 bp_ulonglong(char *p
, PyObject
*v
, const formatdef
*f
)
927 res
= _PyLong_AsByteArray((PyLongObject
*)v
,
930 0, /* little_endian */
937 bp_float(char *p
, PyObject
*v
, const formatdef
*f
)
939 double x
= PyFloat_AsDouble(v
);
940 if (x
== -1 && PyErr_Occurred()) {
941 PyErr_SetString(StructError
,
942 "required argument is not a float");
945 return pack_float(x
, p
, 1);
949 bp_double(char *p
, PyObject
*v
, const formatdef
*f
)
951 double x
= PyFloat_AsDouble(v
);
952 if (x
== -1 && PyErr_Occurred()) {
953 PyErr_SetString(StructError
,
954 "required argument is not a float");
957 return pack_double(x
, p
, 1);
960 static formatdef bigendian_table
[] = {
962 {'b', 1, 0, bu_int
, bp_int
},
963 {'B', 1, 0, bu_uint
, bp_int
},
964 {'c', 1, 0, nu_char
, np_char
},
967 {'h', 2, 0, bu_int
, bp_int
},
968 {'H', 2, 0, bu_uint
, bp_uint
},
969 {'i', 4, 0, bu_int
, bp_int
},
970 {'I', 4, 0, bu_uint
, bp_uint
},
971 {'l', 4, 0, bu_int
, bp_int
},
972 {'L', 4, 0, bu_uint
, bp_uint
},
973 {'q', 8, 0, bu_longlong
, bp_longlong
},
974 {'Q', 8, 0, bu_ulonglong
, bp_ulonglong
},
975 {'f', 4, 0, bu_float
, bp_float
},
976 {'d', 8, 0, bu_double
, bp_double
},
980 /* Little-endian routines. *****************************************************/
983 lu_int(const char *p
, const formatdef
*f
)
988 x
= (x
<<8) | (p
[--i
] & 0xFF);
990 /* Extend the sign bit. */
991 if (SIZEOF_LONG
> f
->size
)
992 x
|= -(x
& (1L << (8*f
->size
- 1)));
993 return PyInt_FromLong(x
);
997 lu_uint(const char *p
, const formatdef
*f
)
1002 x
= (x
<<8) | (p
[--i
] & 0xFF);
1005 return PyLong_FromUnsignedLong(x
);
1007 return PyInt_FromLong((long)x
);
1011 lu_longlong(const char *p
, const formatdef
*f
)
1013 return _PyLong_FromByteArray((const unsigned char *)p
,
1015 1, /* little-endian */
1020 lu_ulonglong(const char *p
, const formatdef
*f
)
1022 return _PyLong_FromByteArray((const unsigned char *)p
,
1024 1, /* little-endian */
1029 lu_float(const char *p
, const formatdef
*f
)
1031 return unpack_float(p
+3, -1);
1035 lu_double(const char *p
, const formatdef
*f
)
1037 return unpack_double(p
+7, -1);
1041 lp_int(char *p
, PyObject
*v
, const formatdef
*f
)
1045 if (get_long(v
, &x
) < 0)
1056 lp_uint(char *p
, PyObject
*v
, const formatdef
*f
)
1060 if (get_ulong(v
, &x
) < 0)
1071 lp_longlong(char *p
, PyObject
*v
, const formatdef
*f
)
1077 res
= _PyLong_AsByteArray((PyLongObject
*)v
,
1080 1, /* little_endian */
1087 lp_ulonglong(char *p
, PyObject
*v
, const formatdef
*f
)
1093 res
= _PyLong_AsByteArray((PyLongObject
*)v
,
1096 1, /* little_endian */
1103 lp_float(char *p
, PyObject
*v
, const formatdef
*f
)
1105 double x
= PyFloat_AsDouble(v
);
1106 if (x
== -1 && PyErr_Occurred()) {
1107 PyErr_SetString(StructError
,
1108 "required argument is not a float");
1111 return pack_float(x
, p
+3, -1);
1115 lp_double(char *p
, PyObject
*v
, const formatdef
*f
)
1117 double x
= PyFloat_AsDouble(v
);
1118 if (x
== -1 && PyErr_Occurred()) {
1119 PyErr_SetString(StructError
,
1120 "required argument is not a float");
1123 return pack_double(x
, p
+7, -1);
1126 static formatdef lilendian_table
[] = {
1128 {'b', 1, 0, lu_int
, lp_int
},
1129 {'B', 1, 0, lu_uint
, lp_int
},
1130 {'c', 1, 0, nu_char
, np_char
},
1133 {'h', 2, 0, lu_int
, lp_int
},
1134 {'H', 2, 0, lu_uint
, lp_uint
},
1135 {'i', 4, 0, lu_int
, lp_int
},
1136 {'I', 4, 0, lu_uint
, lp_uint
},
1137 {'l', 4, 0, lu_int
, lp_int
},
1138 {'L', 4, 0, lu_uint
, lp_uint
},
1139 {'q', 8, 0, lu_longlong
, lp_longlong
},
1140 {'Q', 8, 0, lu_ulonglong
, lp_ulonglong
},
1141 {'f', 4, 0, lu_float
, lp_float
},
1142 {'d', 8, 0, lu_double
, lp_double
},
1147 static const formatdef
*
1148 whichtable(char **pfmt
)
1150 const char *fmt
= (*pfmt
)++; /* May be backed out of later */
1153 return lilendian_table
;
1155 case '!': /* Network byte order is big-endian */
1156 return bigendian_table
;
1157 case '=': { /* Host byte order -- different from native in aligment! */
1159 char *p
= (char *) &n
;
1161 return lilendian_table
;
1163 return bigendian_table
;
1166 --*pfmt
; /* Back out of pointer increment */
1169 return native_table
;
1174 /* Get the table entry for a format code */
1176 static const formatdef
*
1177 getentry(int c
, const formatdef
*f
)
1179 for (; f
->format
!= '\0'; f
++) {
1180 if (f
->format
== c
) {
1184 PyErr_SetString(StructError
, "bad char in struct format");
1189 /* Align a size according to a format code */
1192 align(int size
, int c
, const formatdef
*e
)
1194 if (e
->format
== c
) {
1196 size
= ((size
+ e
->alignment
- 1)
1205 /* calculate the size of a format string */
1208 calcsize(const char *fmt
, const formatdef
*f
)
1213 int size
, num
, itemsize
, x
;
1217 while ((c
= *s
++) != '\0') {
1218 if (isspace((int)c
))
1220 if ('0' <= c
&& c
<= '9') {
1222 while ('0' <= (c
= *s
++) && c
<= '9') {
1223 x
= num
*10 + (c
- '0');
1227 "overflow in item count");
1242 size
= align(size
, c
, e
);
1245 if (x
/itemsize
!= num
|| size
< 0) {
1246 PyErr_SetString(StructError
,
1247 "total struct size too long");
1256 PyDoc_STRVAR(calcsize__doc__
,
1257 "calcsize(fmt) -> int\n\
1258 Return size of C struct described by format string fmt.\n\
1259 See struct.__doc__ for more on format strings.");
1262 struct_calcsize(PyObject
*self
, PyObject
*args
)
1268 if (!PyArg_ParseTuple(args
, "s:calcsize", &fmt
))
1270 f
= whichtable(&fmt
);
1271 size
= calcsize(fmt
, f
);
1274 return PyInt_FromLong((long)size
);
1278 PyDoc_STRVAR(pack__doc__
,
1279 "pack(fmt, v1, v2, ...) -> string\n\
1280 Return string containing values v1, v2, ... packed according to fmt.\n\
1281 See struct.__doc__ for more on format strings.");
1284 struct_pack(PyObject
*self
, PyObject
*args
)
1286 const formatdef
*f
, *e
;
1287 PyObject
*format
, *result
, *v
;
1291 char *s
, *res
, *restart
, *nres
;
1294 if (args
== NULL
|| !PyTuple_Check(args
) ||
1295 (n
= PyTuple_Size(args
)) < 1)
1297 PyErr_SetString(PyExc_TypeError
,
1298 "struct.pack requires at least one argument");
1301 format
= PyTuple_GetItem(args
, 0);
1302 fmt
= PyString_AsString(format
);
1305 f
= whichtable(&fmt
);
1306 size
= calcsize(fmt
, f
);
1309 result
= PyString_FromStringAndSize((char *)NULL
, size
);
1315 res
= restart
= PyString_AsString(result
);
1317 while ((c
= *s
++) != '\0') {
1318 if (isspace((int)c
))
1320 if ('0' <= c
&& c
<= '9') {
1322 while ('0' <= (c
= *s
++) && c
<= '9')
1323 num
= num
*10 + (c
- '0');
1333 nres
= restart
+ align((int)(res
-restart
), c
, e
);
1334 /* Fill padd bytes with zeros */
1337 if (num
== 0 && c
!= 's')
1341 /* doesn't consume arguments */
1342 memset(res
, '\0', num
);
1347 PyErr_SetString(StructError
,
1348 "insufficient arguments to pack");
1351 v
= PyTuple_GetItem(args
, i
++);
1355 /* num is string size, not repeat count */
1357 if (!PyString_Check(v
)) {
1358 PyErr_SetString(StructError
,
1359 "argument for 's' must be a string");
1362 n
= PyString_Size(v
);
1366 memcpy(res
, PyString_AsString(v
), n
);
1368 memset(res
+n
, '\0', num
-n
);
1372 else if (c
== 'p') {
1373 /* num is string size + 1,
1374 to fit in the count byte */
1376 num
--; /* now num is max string size */
1377 if (!PyString_Check(v
)) {
1378 PyErr_SetString(StructError
,
1379 "argument for 'p' must be a string");
1382 n
= PyString_Size(v
);
1386 memcpy(res
+1, PyString_AsString(v
), n
);
1388 /* no real need, just to be nice */
1389 memset(res
+1+n
, '\0', num
-n
);
1392 *res
++ = n
; /* store the length byte */
1397 if (e
->pack(res
, v
, e
) < 0)
1401 } while (--num
> 0);
1405 PyErr_SetString(StructError
,
1406 "too many arguments for pack format");
1418 PyDoc_STRVAR(unpack__doc__
,
1419 "unpack(fmt, string) -> (v1, v2, ...)\n\
1420 Unpack the string, containing packed C structure data, according\n\
1421 to fmt. Requires len(string)==calcsize(fmt).\n\
1422 See struct.__doc__ for more on format strings.");
1425 struct_unpack(PyObject
*self
, PyObject
*args
)
1427 const formatdef
*f
, *e
;
1428 char *str
, *start
, *fmt
, *s
;
1433 if (!PyArg_ParseTuple(args
, "ss#:unpack", &fmt
, &start
, &len
))
1435 f
= whichtable(&fmt
);
1436 size
= calcsize(fmt
, f
);
1440 PyErr_SetString(StructError
,
1441 "unpack str size does not match format");
1444 res
= PyList_New(0);
1449 while ((c
= *s
++) != '\0') {
1450 if (isspace((int)c
))
1452 if ('0' <= c
&& c
<= '9') {
1454 while ('0' <= (c
= *s
++) && c
<= '9')
1455 num
= num
*10 + (c
- '0');
1465 str
= start
+ align((int)(str
-start
), c
, e
);
1466 if (num
== 0 && c
!= 's')
1475 /* num is string size, not repeat count */
1476 v
= PyString_FromStringAndSize(str
, num
);
1482 else if (c
== 'p') {
1483 /* num is string buffer size,
1485 int n
= *(unsigned char*)str
;
1486 /* first byte (unsigned) is string size */
1489 v
= PyString_FromStringAndSize(str
+1, n
);
1496 v
= e
->unpack(str
, e
);
1501 if (v
== NULL
|| PyList_Append(res
, v
) < 0)
1504 } while (--num
> 0);
1507 v
= PyList_AsTuple(res
);
1517 /* List of functions */
1519 static PyMethodDef struct_methods
[] = {
1520 {"calcsize", struct_calcsize
, METH_VARARGS
, calcsize__doc__
},
1521 {"pack", struct_pack
, METH_VARARGS
, pack__doc__
},
1522 {"unpack", struct_unpack
, METH_VARARGS
, unpack__doc__
},
1523 {NULL
, NULL
} /* sentinel */
1527 /* Module initialization */
1534 /* Create the module and add the functions */
1535 m
= Py_InitModule4("struct", struct_methods
, struct__doc__
,
1536 (PyObject
*)NULL
, PYTHON_API_VERSION
);
1538 /* Add some symbolic constants to the module */
1539 if (StructError
== NULL
) {
1540 StructError
= PyErr_NewException("struct.error", NULL
, NULL
);
1541 if (StructError
== NULL
)
1544 Py_INCREF(StructError
);
1545 PyModule_AddObject(m
, "error", StructError
);