blob: 22f1c549772633eb6d4954cbd86fc73e37616e2f [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001/* struct module -- pack values into and (out of) strings */
2
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00003/* New version supporting byte order, alignment and size options,
4 character strings, and unsigned numbers */
5
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006#include "Python.h"
7#include <ctype.h>
8
9PyDoc_STRVAR(struct__doc__,
10"Functions to convert between Python values and C structs.\n\
Guido van Rossum414fd481997-12-19 04:24:24 +000011Python strings are used to hold the data representing the C struct\n\
12and also as format strings to describe the layout of data in the C struct.\n\
13\n\
Tim Petersbe800852001-06-11 16:45:33 +000014The 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\
Guido van Rossum414fd481997-12-19 04:24:24 +000020\n\
21The remaining chars indicate types of args and must match exactly;\n\
22these 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\
26Special cases (preceding decimal count indicates length):\n\
Tim Peters7b9542a2001-06-10 23:40:19 +000027 s:string (array of char); p: pascal string (with count byte).\n\
Guido van Rossum78694d91998-09-18 14:14:13 +000028Special case (only available in native format):\n\
29 P:an integer type that is wide enough to hold a pointer.\n\
Tim Peters7b9542a2001-06-10 23:40:19 +000030Special case (not in native mode unless 'long long' in platform C):\n\
31 q:long long; Q:unsigned long long\n\
Guido van Rossum414fd481997-12-19 04:24:24 +000032Whitespace between formats is ignored.\n\
33\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034The variable struct.error is an exception raised on errors.");
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000035
36
37/* Exception */
38
Barry Warsaw30695fa1996-12-12 23:32:31 +000039static PyObject *StructError;
Guido van Rossum02975121992-08-17 08:55:12 +000040
41
42/* Define various structs to figure out the alignments of types */
43
Jack Jansen971e1df1995-02-02 14:29:10 +000044#ifdef __MWERKS__
45/*
46** XXXX We have a problem here. There are no unique alignment rules
Tim Peters2d4e0772001-06-11 16:57:33 +000047** on the PowerPC mac.
Jack Jansen971e1df1995-02-02 14:29:10 +000048*/
49#ifdef __powerc
50#pragma options align=mac68k
51#endif
52#endif /* __MWERKS__ */
53
Guido van Rossume2ae77b2001-10-24 20:42:55 +000054typedef struct { char c; short x; } st_short;
55typedef struct { char c; int x; } st_int;
56typedef struct { char c; long x; } st_long;
57typedef struct { char c; float x; } st_float;
58typedef struct { char c; double x; } st_double;
59typedef struct { char c; void *x; } st_void_p;
Guido van Rossum02975121992-08-17 08:55:12 +000060
Guido van Rossume2ae77b2001-10-24 20:42:55 +000061#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 *))
Guido van Rossum02975121992-08-17 08:55:12 +000067
Tim Peters7b9542a2001-06-10 23:40:19 +000068/* 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. */
70#ifdef HAVE_LONG_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +000071typedef struct { char c; PY_LONG_LONG x; } s_long_long;
72#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
Tim Peters7b9542a2001-06-10 23:40:19 +000073#endif
74
Martin v. Löwis2af72d52000-09-15 08:10:33 +000075#define STRINGIFY(x) #x
76
Jack Jansen971e1df1995-02-02 14:29:10 +000077#ifdef __powerc
78#pragma options align=reset
79#endif
80
Tim Peters7a3bfc32001-06-12 01:22:22 +000081/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
82
83static PyObject *
84get_pylong(PyObject *v)
85{
86 PyNumberMethods *m;
87
88 assert(v != NULL);
89 if (PyInt_Check(v))
90 return PyLong_FromLong(PyInt_AS_LONG(v));
91 if (PyLong_Check(v)) {
92 Py_INCREF(v);
93 return v;
94 }
95 m = v->ob_type->tp_as_number;
96 if (m != NULL && m->nb_long != NULL) {
97 v = m->nb_long(v);
98 if (v == NULL)
99 return NULL;
100 if (PyLong_Check(v))
101 return v;
102 Py_DECREF(v);
103 }
104 PyErr_SetString(StructError,
105 "cannot convert argument to long");
106 return NULL;
107}
108
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000109/* Helper routine to get a Python integer and raise the appropriate error
110 if it isn't one */
111
112static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000113get_long(PyObject *v, long *p)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000114{
115 long x = PyInt_AsLong(v);
116 if (x == -1 && PyErr_Occurred()) {
Fred Draked3dbb381998-05-28 04:35:49 +0000117 if (PyErr_ExceptionMatches(PyExc_TypeError))
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000118 PyErr_SetString(StructError,
119 "required argument is not an integer");
120 return -1;
121 }
122 *p = x;
123 return 0;
124}
125
126
Guido van Rossum60c50611996-12-31 16:29:52 +0000127/* Same, but handling unsigned long */
128
129static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000130get_ulong(PyObject *v, unsigned long *p)
Guido van Rossum60c50611996-12-31 16:29:52 +0000131{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000132 if (PyLong_Check(v)) {
133 unsigned long x = PyLong_AsUnsignedLong(v);
134 if (x == (unsigned long)(-1) && PyErr_Occurred())
Guido van Rossum60c50611996-12-31 16:29:52 +0000135 return -1;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000136 *p = x;
137 return 0;
Guido van Rossum60c50611996-12-31 16:29:52 +0000138 }
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000139 else {
140 return get_long(v, (long *)p);
141 }
Guido van Rossum60c50611996-12-31 16:29:52 +0000142}
143
Tim Peters7b9542a2001-06-10 23:40:19 +0000144#ifdef HAVE_LONG_LONG
145
146/* Same, but handling native long long. */
147
148static int
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000149get_longlong(PyObject *v, PY_LONG_LONG *p)
Tim Peters7b9542a2001-06-10 23:40:19 +0000150{
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000151 PY_LONG_LONG x;
Tim Peters7b9542a2001-06-10 23:40:19 +0000152
Tim Peters7a3bfc32001-06-12 01:22:22 +0000153 v = get_pylong(v);
154 if (v == NULL)
155 return -1;
Tim Peters7b9542a2001-06-10 23:40:19 +0000156 assert(PyLong_Check(v));
157 x = PyLong_AsLongLong(v);
Tim Peters7a3bfc32001-06-12 01:22:22 +0000158 Py_DECREF(v);
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000159 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
Tim Peters7b9542a2001-06-10 23:40:19 +0000160 return -1;
161 *p = x;
162 return 0;
163}
164
165/* Same, but handling native unsigned long long. */
166
167static int
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000168get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
Tim Peters7b9542a2001-06-10 23:40:19 +0000169{
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000170 unsigned PY_LONG_LONG x;
Tim Peters7b9542a2001-06-10 23:40:19 +0000171
Tim Peters7a3bfc32001-06-12 01:22:22 +0000172 v = get_pylong(v);
173 if (v == NULL)
174 return -1;
Tim Peters7b9542a2001-06-10 23:40:19 +0000175 assert(PyLong_Check(v));
176 x = PyLong_AsUnsignedLongLong(v);
Tim Peters7a3bfc32001-06-12 01:22:22 +0000177 Py_DECREF(v);
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000178 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
Tim Peters7b9542a2001-06-10 23:40:19 +0000179 return -1;
180 *p = x;
181 return 0;
182}
183
184#endif
Guido van Rossum60c50611996-12-31 16:29:52 +0000185
Guido van Rossum74679b41997-01-02 22:21:36 +0000186/* Floating point helpers */
187
Guido van Rossum74679b41997-01-02 22:21:36 +0000188static PyObject *
Tim Peters9905b942003-03-20 20:53:32 +0000189unpack_float(const char *p, /* start of 4-byte string */
190 int le) /* true for little-endian, false for big-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000191{
Guido van Rossum74679b41997-01-02 22:21:36 +0000192 double x;
193
Tim Peters9905b942003-03-20 20:53:32 +0000194 x = _PyFloat_Unpack4((unsigned char *)p, le);
195 if (x == -1.0 && PyErr_Occurred())
196 return NULL;
Guido van Rossum74679b41997-01-02 22:21:36 +0000197 return PyFloat_FromDouble(x);
198}
199
200static PyObject *
Tim Peters9905b942003-03-20 20:53:32 +0000201unpack_double(const char *p, /* start of 8-byte string */
202 int le) /* true for little-endian, false for big-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000203{
Guido van Rossum74679b41997-01-02 22:21:36 +0000204 double x;
205
Tim Peters9905b942003-03-20 20:53:32 +0000206 x = _PyFloat_Unpack8((unsigned char *)p, le);
207 if (x == -1.0 && PyErr_Occurred())
208 return NULL;
Guido van Rossum74679b41997-01-02 22:21:36 +0000209 return PyFloat_FromDouble(x);
210}
211
212
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000213/* The translation function for each format character is table driven */
214
215typedef struct _formatdef {
216 char format;
217 int size;
218 int alignment;
Tim Petersdbd9ba62000-07-09 03:09:57 +0000219 PyObject* (*unpack)(const char *,
220 const struct _formatdef *);
221 int (*pack)(char *, PyObject *,
222 const struct _formatdef *);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000223} formatdef;
224
Tim Peters7b9542a2001-06-10 23:40:19 +0000225/* A large number of small routines follow, with names of the form
226
227 [bln][up]_TYPE
228
229 [bln] distiguishes among big-endian, little-endian and native.
230 [pu] distiguishes between pack (to struct) and unpack (from struct).
231 TYPE is one of char, byte, ubyte, etc.
232*/
233
Tim Peters7a3bfc32001-06-12 01:22:22 +0000234/* Native mode routines. ****************************************************/
Guido van Rossum960bc542002-09-03 18:42:21 +0000235/* NOTE:
236 In all n[up]_<type> routines handling types larger than 1 byte, there is
237 *no* guarantee that the p pointer is properly aligned for each type,
238 therefore memcpy is called. An intermediate variable is used to
239 compensate for big-endian architectures.
240 Normally both the intermediate variable and the memcpy call will be
241 skipped by C optimisation in little-endian architectures (gcc >= 2.91
242 does this). */
Tim Peters7b9542a2001-06-10 23:40:19 +0000243
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000244static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000245nu_char(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000246{
247 return PyString_FromStringAndSize(p, 1);
248}
249
250static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000251nu_byte(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000252{
253 return PyInt_FromLong((long) *(signed char *)p);
254}
255
256static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000257nu_ubyte(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000258{
259 return PyInt_FromLong((long) *(unsigned char *)p);
260}
261
262static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000263nu_short(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000264{
Guido van Rossum960bc542002-09-03 18:42:21 +0000265 short x;
266 memcpy((char *)&x, p, sizeof x);
267 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000268}
269
270static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000271nu_ushort(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000272{
Guido van Rossum960bc542002-09-03 18:42:21 +0000273 unsigned short x;
274 memcpy((char *)&x, p, sizeof x);
275 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000276}
277
278static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000279nu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000280{
Guido van Rossum960bc542002-09-03 18:42:21 +0000281 int x;
282 memcpy((char *)&x, p, sizeof x);
283 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000284}
285
286static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000287nu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000288{
Guido van Rossum960bc542002-09-03 18:42:21 +0000289 unsigned int x;
290 memcpy((char *)&x, p, sizeof x);
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000291 return PyLong_FromUnsignedLong((unsigned long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000292}
293
294static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000295nu_long(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000296{
Guido van Rossum960bc542002-09-03 18:42:21 +0000297 long x;
298 memcpy((char *)&x, p, sizeof x);
299 return PyInt_FromLong(x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000300}
301
302static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000303nu_ulong(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000304{
Guido van Rossum960bc542002-09-03 18:42:21 +0000305 unsigned long x;
306 memcpy((char *)&x, p, sizeof x);
307 return PyLong_FromUnsignedLong(x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000308}
309
Tim Peters7b9542a2001-06-10 23:40:19 +0000310/* Native mode doesn't support q or Q unless the platform C supports
311 long long (or, on Windows, __int64). */
312
313#ifdef HAVE_LONG_LONG
314
315static PyObject *
316nu_longlong(const char *p, const formatdef *f)
317{
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000318 PY_LONG_LONG x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000319 memcpy((char *)&x, p, sizeof x);
Tim Peters3dac5592001-07-18 20:47:31 +0000320 return PyLong_FromLongLong(x);
Tim Peters7b9542a2001-06-10 23:40:19 +0000321}
322
323static PyObject *
324nu_ulonglong(const char *p, const formatdef *f)
325{
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000326 unsigned PY_LONG_LONG x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000327 memcpy((char *)&x, p, sizeof x);
Tim Peters3dac5592001-07-18 20:47:31 +0000328 return PyLong_FromUnsignedLongLong(x);
Tim Peters7b9542a2001-06-10 23:40:19 +0000329}
Guido van Rossum960bc542002-09-03 18:42:21 +0000330
Tim Peters7b9542a2001-06-10 23:40:19 +0000331#endif
332
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000333static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000334nu_float(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000335{
336 float x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000337 memcpy((char *)&x, p, sizeof x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000338 return PyFloat_FromDouble((double)x);
339}
340
341static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000342nu_double(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000343{
344 double x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000345 memcpy((char *)&x, p, sizeof x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000346 return PyFloat_FromDouble(x);
347}
348
Guido van Rossum78694d91998-09-18 14:14:13 +0000349static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000350nu_void_p(const char *p, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000351{
Guido van Rossum960bc542002-09-03 18:42:21 +0000352 void *x;
353 memcpy((char *)&x, p, sizeof x);
354 return PyLong_FromVoidPtr(x);
Guido van Rossum78694d91998-09-18 14:14:13 +0000355}
356
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000357static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000358np_byte(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000359{
360 long x;
361 if (get_long(v, &x) < 0)
362 return -1;
Martin v. Löwis66de5492000-09-15 07:31:57 +0000363 if (x < -128 || x > 127){
364 PyErr_SetString(StructError,
365 "byte format requires -128<=number<=127");
366 return -1;
367 }
368 *p = (char)x;
369 return 0;
370}
371
372static int
373np_ubyte(char *p, PyObject *v, const formatdef *f)
374{
375 long x;
376 if (get_long(v, &x) < 0)
377 return -1;
378 if (x < 0 || x > 255){
379 PyErr_SetString(StructError,
380 "ubyte format requires 0<=number<=255");
381 return -1;
382 }
Guido van Rossum7844e381997-04-11 20:44:04 +0000383 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000384 return 0;
385}
386
387static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000388np_char(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000389{
390 if (!PyString_Check(v) || PyString_Size(v) != 1) {
391 PyErr_SetString(StructError,
392 "char format require string of length 1");
393 return -1;
394 }
395 *p = *PyString_AsString(v);
396 return 0;
397}
398
399static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000400np_short(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000401{
402 long x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000403 short y;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000404 if (get_long(v, &x) < 0)
405 return -1;
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000406 if (x < SHRT_MIN || x > SHRT_MAX){
Martin v. Löwis66de5492000-09-15 07:31:57 +0000407 PyErr_SetString(StructError,
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000408 "short format requires " STRINGIFY(SHRT_MIN)
Guido van Rossum960bc542002-09-03 18:42:21 +0000409 "<=number<=" STRINGIFY(SHRT_MAX));
Martin v. Löwis66de5492000-09-15 07:31:57 +0000410 return -1;
411 }
Guido van Rossum960bc542002-09-03 18:42:21 +0000412 y = (short)x;
413 memcpy(p, (char *)&y, sizeof y);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000414 return 0;
415}
416
417static int
Martin v. Löwis66de5492000-09-15 07:31:57 +0000418np_ushort(char *p, PyObject *v, const formatdef *f)
419{
420 long x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000421 unsigned short y;
Martin v. Löwis66de5492000-09-15 07:31:57 +0000422 if (get_long(v, &x) < 0)
423 return -1;
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000424 if (x < 0 || x > USHRT_MAX){
Martin v. Löwis66de5492000-09-15 07:31:57 +0000425 PyErr_SetString(StructError,
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000426 "short format requires 0<=number<=" STRINGIFY(USHRT_MAX));
Martin v. Löwis66de5492000-09-15 07:31:57 +0000427 return -1;
428 }
Guido van Rossum960bc542002-09-03 18:42:21 +0000429 y = (unsigned short)x;
430 memcpy(p, (char *)&y, sizeof y);
Martin v. Löwis66de5492000-09-15 07:31:57 +0000431 return 0;
432}
433
434static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000435np_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000436{
437 long x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000438 int y;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000439 if (get_long(v, &x) < 0)
440 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000441 y = (int)x;
442 memcpy(p, (char *)&y, sizeof y);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000443 return 0;
444}
445
446static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000447np_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000448{
449 unsigned long x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000450 unsigned int y;
Guido van Rossum60c50611996-12-31 16:29:52 +0000451 if (get_ulong(v, &x) < 0)
452 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000453 y = (unsigned int)x;
454 memcpy(p, (char *)&y, sizeof y);
Guido van Rossum60c50611996-12-31 16:29:52 +0000455 return 0;
456}
457
458static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000459np_long(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000460{
461 long x;
462 if (get_long(v, &x) < 0)
463 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000464 memcpy(p, (char *)&x, sizeof x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000465 return 0;
466}
467
468static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000469np_ulong(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000470{
471 unsigned long x;
472 if (get_ulong(v, &x) < 0)
473 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000474 memcpy(p, (char *)&x, sizeof x);
Guido van Rossum60c50611996-12-31 16:29:52 +0000475 return 0;
476}
477
Tim Peters7b9542a2001-06-10 23:40:19 +0000478#ifdef HAVE_LONG_LONG
479
480static int
481np_longlong(char *p, PyObject *v, const formatdef *f)
482{
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000483 PY_LONG_LONG x;
Tim Peters7b9542a2001-06-10 23:40:19 +0000484 if (get_longlong(v, &x) < 0)
485 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000486 memcpy(p, (char *)&x, sizeof x);
Tim Peters7b9542a2001-06-10 23:40:19 +0000487 return 0;
488}
489
490static int
491np_ulonglong(char *p, PyObject *v, const formatdef *f)
492{
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000493 unsigned PY_LONG_LONG x;
Tim Peters7b9542a2001-06-10 23:40:19 +0000494 if (get_ulonglong(v, &x) < 0)
495 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000496 memcpy(p, (char *)&x, sizeof x);
Tim Peters7b9542a2001-06-10 23:40:19 +0000497 return 0;
498}
Tim Peters7b9542a2001-06-10 23:40:19 +0000499#endif
500
Guido van Rossum60c50611996-12-31 16:29:52 +0000501static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000502np_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000503{
504 float x = (float)PyFloat_AsDouble(v);
505 if (x == -1 && PyErr_Occurred()) {
506 PyErr_SetString(StructError,
507 "required argument is not a float");
508 return -1;
509 }
Guido van Rossum960bc542002-09-03 18:42:21 +0000510 memcpy(p, (char *)&x, sizeof x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000511 return 0;
512}
513
514static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000515np_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000516{
517 double x = PyFloat_AsDouble(v);
518 if (x == -1 && PyErr_Occurred()) {
519 PyErr_SetString(StructError,
520 "required argument is not a float");
521 return -1;
522 }
523 memcpy(p, (char *)&x, sizeof(double));
524 return 0;
525}
526
Guido van Rossum78694d91998-09-18 14:14:13 +0000527static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000528np_void_p(char *p, PyObject *v, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000529{
530 void *x = PyLong_AsVoidPtr(v);
531 if (x == NULL && PyErr_Occurred()) {
532 /* ### hrm. PyLong_AsVoidPtr raises SystemError */
533 if (PyErr_ExceptionMatches(PyExc_TypeError))
534 PyErr_SetString(StructError,
535 "required argument is not an integer");
536 return -1;
537 }
Guido van Rossum960bc542002-09-03 18:42:21 +0000538 memcpy(p, (char *)&x, sizeof x);
Guido van Rossum78694d91998-09-18 14:14:13 +0000539 return 0;
540}
541
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000542static formatdef native_table[] = {
543 {'x', sizeof(char), 0, NULL},
544 {'b', sizeof(char), 0, nu_byte, np_byte},
Martin v. Löwis66de5492000-09-15 07:31:57 +0000545 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000546 {'c', sizeof(char), 0, nu_char, np_char},
547 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000548 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000549 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
Martin v. Löwis66de5492000-09-15 07:31:57 +0000550 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000551 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000552 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000553 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000554 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000555 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
556 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
Guido van Rossum78694d91998-09-18 14:14:13 +0000557 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Tim Peters7b9542a2001-06-10 23:40:19 +0000558#ifdef HAVE_LONG_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000559 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
560 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Tim Peters7b9542a2001-06-10 23:40:19 +0000561#endif
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000562 {0}
563};
564
Tim Peters7a3bfc32001-06-12 01:22:22 +0000565/* Big-endian routines. *****************************************************/
566
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000567static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000568bu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000569{
570 long x = 0;
571 int i = f->size;
572 do {
573 x = (x<<8) | (*p++ & 0xFF);
574 } while (--i > 0);
Tim Petersf0e717b2001-04-08 23:39:38 +0000575 /* Extend the sign bit. */
576 if (SIZEOF_LONG > f->size)
577 x |= -(x & (1L << (8*f->size - 1)));
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000578 return PyInt_FromLong(x);
579}
580
581static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000582bu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000583{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000584 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000585 int i = f->size;
586 do {
587 x = (x<<8) | (*p++ & 0xFF);
588 } while (--i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000589 if (f->size >= 4)
590 return PyLong_FromUnsignedLong(x);
591 else
592 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000593}
594
Guido van Rossum74679b41997-01-02 22:21:36 +0000595static PyObject *
Tim Peters7a3bfc32001-06-12 01:22:22 +0000596bu_longlong(const char *p, const formatdef *f)
597{
598 return _PyLong_FromByteArray((const unsigned char *)p,
599 8,
600 0, /* little-endian */
601 1 /* signed */);
602}
603
604static PyObject *
605bu_ulonglong(const char *p, const formatdef *f)
606{
607 return _PyLong_FromByteArray((const unsigned char *)p,
608 8,
609 0, /* little-endian */
610 0 /* signed */);
611}
612
613static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000614bu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000615{
Tim Peters9905b942003-03-20 20:53:32 +0000616 return unpack_float(p, 0);
Guido van Rossum74679b41997-01-02 22:21:36 +0000617}
618
619static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000620bu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000621{
Tim Peters9905b942003-03-20 20:53:32 +0000622 return unpack_double(p, 0);
Guido van Rossum74679b41997-01-02 22:21:36 +0000623}
624
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000625static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000626bp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000627{
628 long x;
629 int i;
630 if (get_long(v, &x) < 0)
631 return -1;
632 i = f->size;
633 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000634 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000635 x >>= 8;
636 } while (i > 0);
637 return 0;
638}
639
Guido van Rossum60c50611996-12-31 16:29:52 +0000640static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000641bp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000642{
643 unsigned long x;
644 int i;
645 if (get_ulong(v, &x) < 0)
646 return -1;
647 i = f->size;
648 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000649 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000650 x >>= 8;
651 } while (i > 0);
652 return 0;
653}
654
Guido van Rossum74679b41997-01-02 22:21:36 +0000655static int
Tim Peters7a3bfc32001-06-12 01:22:22 +0000656bp_longlong(char *p, PyObject *v, const formatdef *f)
657{
658 int res;
659 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000660 if (v == NULL)
661 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000662 res = _PyLong_AsByteArray((PyLongObject *)v,
663 (unsigned char *)p,
664 8,
665 0, /* little_endian */
666 1 /* signed */);
667 Py_DECREF(v);
668 return res;
669}
670
671static int
672bp_ulonglong(char *p, PyObject *v, const formatdef *f)
673{
674 int res;
675 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000676 if (v == NULL)
677 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000678 res = _PyLong_AsByteArray((PyLongObject *)v,
679 (unsigned char *)p,
680 8,
681 0, /* little_endian */
682 0 /* signed */);
683 Py_DECREF(v);
684 return res;
685}
686
687static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000688bp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000689{
690 double x = PyFloat_AsDouble(v);
691 if (x == -1 && PyErr_Occurred()) {
692 PyErr_SetString(StructError,
693 "required argument is not a float");
694 return -1;
695 }
Tim Peters9905b942003-03-20 20:53:32 +0000696 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
Guido van Rossum74679b41997-01-02 22:21:36 +0000697}
698
699static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000700bp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000701{
702 double x = PyFloat_AsDouble(v);
703 if (x == -1 && PyErr_Occurred()) {
704 PyErr_SetString(StructError,
705 "required argument is not a float");
706 return -1;
707 }
Tim Peters9905b942003-03-20 20:53:32 +0000708 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
Guido van Rossum74679b41997-01-02 22:21:36 +0000709}
710
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000711static formatdef bigendian_table[] = {
712 {'x', 1, 0, NULL},
713 {'b', 1, 0, bu_int, bp_int},
714 {'B', 1, 0, bu_uint, bp_int},
715 {'c', 1, 0, nu_char, np_char},
716 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000717 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000718 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000719 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000720 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000721 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000722 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000723 {'L', 4, 0, bu_uint, bp_uint},
Tim Peters7a3bfc32001-06-12 01:22:22 +0000724 {'q', 8, 0, bu_longlong, bp_longlong},
725 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
Guido van Rossum74679b41997-01-02 22:21:36 +0000726 {'f', 4, 0, bu_float, bp_float},
727 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000728 {0}
729};
730
Tim Peters7a3bfc32001-06-12 01:22:22 +0000731/* Little-endian routines. *****************************************************/
732
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000733static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000734lu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000735{
736 long x = 0;
737 int i = f->size;
738 do {
739 x = (x<<8) | (p[--i] & 0xFF);
740 } while (i > 0);
Tim Petersf0e717b2001-04-08 23:39:38 +0000741 /* Extend the sign bit. */
742 if (SIZEOF_LONG > f->size)
743 x |= -(x & (1L << (8*f->size - 1)));
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000744 return PyInt_FromLong(x);
745}
746
747static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000748lu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000749{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000750 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000751 int i = f->size;
752 do {
753 x = (x<<8) | (p[--i] & 0xFF);
754 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000755 if (f->size >= 4)
756 return PyLong_FromUnsignedLong(x);
757 else
758 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000759}
760
Guido van Rossum74679b41997-01-02 22:21:36 +0000761static PyObject *
Tim Peters7a3bfc32001-06-12 01:22:22 +0000762lu_longlong(const char *p, const formatdef *f)
763{
764 return _PyLong_FromByteArray((const unsigned char *)p,
765 8,
766 1, /* little-endian */
767 1 /* signed */);
768}
769
770static PyObject *
771lu_ulonglong(const char *p, const formatdef *f)
772{
773 return _PyLong_FromByteArray((const unsigned char *)p,
774 8,
775 1, /* little-endian */
776 0 /* signed */);
777}
778
779static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000780lu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000781{
Tim Peters9905b942003-03-20 20:53:32 +0000782 return unpack_float(p, 1);
Guido van Rossum74679b41997-01-02 22:21:36 +0000783}
784
785static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000786lu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000787{
Tim Peters9905b942003-03-20 20:53:32 +0000788 return unpack_double(p, 1);
Guido van Rossum74679b41997-01-02 22:21:36 +0000789}
790
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000791static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000792lp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000793{
794 long x;
795 int i;
796 if (get_long(v, &x) < 0)
797 return -1;
798 i = f->size;
799 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000800 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000801 x >>= 8;
802 } while (--i > 0);
803 return 0;
804}
805
Guido van Rossum60c50611996-12-31 16:29:52 +0000806static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000807lp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000808{
809 unsigned long x;
810 int i;
811 if (get_ulong(v, &x) < 0)
812 return -1;
813 i = f->size;
814 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000815 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000816 x >>= 8;
817 } while (--i > 0);
818 return 0;
819}
820
Guido van Rossum74679b41997-01-02 22:21:36 +0000821static int
Tim Peters7a3bfc32001-06-12 01:22:22 +0000822lp_longlong(char *p, PyObject *v, const formatdef *f)
823{
824 int res;
825 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000826 if (v == NULL)
827 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000828 res = _PyLong_AsByteArray((PyLongObject*)v,
829 (unsigned char *)p,
830 8,
831 1, /* little_endian */
832 1 /* signed */);
833 Py_DECREF(v);
834 return res;
835}
836
837static int
838lp_ulonglong(char *p, PyObject *v, const formatdef *f)
839{
840 int res;
841 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000842 if (v == NULL)
843 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000844 res = _PyLong_AsByteArray((PyLongObject*)v,
845 (unsigned char *)p,
846 8,
847 1, /* little_endian */
848 0 /* signed */);
849 Py_DECREF(v);
850 return res;
851}
852
853static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000854lp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000855{
856 double x = PyFloat_AsDouble(v);
857 if (x == -1 && PyErr_Occurred()) {
858 PyErr_SetString(StructError,
859 "required argument is not a float");
860 return -1;
861 }
Tim Peters9905b942003-03-20 20:53:32 +0000862 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
Guido van Rossum74679b41997-01-02 22:21:36 +0000863}
864
865static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000866lp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000867{
868 double x = PyFloat_AsDouble(v);
869 if (x == -1 && PyErr_Occurred()) {
870 PyErr_SetString(StructError,
871 "required argument is not a float");
872 return -1;
873 }
Tim Peters9905b942003-03-20 20:53:32 +0000874 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
Guido van Rossum74679b41997-01-02 22:21:36 +0000875}
876
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000877static formatdef lilendian_table[] = {
878 {'x', 1, 0, NULL},
879 {'b', 1, 0, lu_int, lp_int},
880 {'B', 1, 0, lu_uint, lp_int},
881 {'c', 1, 0, nu_char, np_char},
882 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000883 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000884 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000885 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000886 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000887 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000888 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000889 {'L', 4, 0, lu_uint, lp_uint},
Tim Peters7a3bfc32001-06-12 01:22:22 +0000890 {'q', 8, 0, lu_longlong, lp_longlong},
891 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
Guido van Rossum74679b41997-01-02 22:21:36 +0000892 {'f', 4, 0, lu_float, lp_float},
893 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000894 {0}
895};
896
897
898static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000899whichtable(char **pfmt)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000900{
901 const char *fmt = (*pfmt)++; /* May be backed out of later */
902 switch (*fmt) {
903 case '<':
904 return lilendian_table;
905 case '>':
906 case '!': /* Network byte order is big-endian */
907 return bigendian_table;
908 case '=': { /* Host byte order -- different from native in aligment! */
909 int n = 1;
910 char *p = (char *) &n;
911 if (*p == 1)
912 return lilendian_table;
913 else
914 return bigendian_table;
915 }
916 default:
917 --*pfmt; /* Back out of pointer increment */
918 /* Fall through */
919 case '@':
920 return native_table;
921 }
922}
923
924
925/* Get the table entry for a format code */
926
927static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000928getentry(int c, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000929{
930 for (; f->format != '\0'; f++) {
931 if (f->format == c) {
932 return f;
933 }
934 }
935 PyErr_SetString(StructError, "bad char in struct format");
936 return NULL;
937}
938
939
Guido van Rossum02975121992-08-17 08:55:12 +0000940/* Align a size according to a format code */
941
942static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000943align(int size, int c, const formatdef *e)
Guido van Rossum02975121992-08-17 08:55:12 +0000944{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000945 if (e->format == c) {
946 if (e->alignment) {
947 size = ((size + e->alignment - 1)
948 / e->alignment)
949 * e->alignment;
950 }
Guido van Rossum02975121992-08-17 08:55:12 +0000951 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000952 return size;
Guido van Rossum02975121992-08-17 08:55:12 +0000953}
954
955
956/* calculate the size of a format string */
957
958static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000959calcsize(const char *fmt, const formatdef *f)
Guido van Rossum02975121992-08-17 08:55:12 +0000960{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000961 const formatdef *e;
962 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +0000963 char c;
964 int size, num, itemsize, x;
965
966 s = fmt;
967 size = 0;
968 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +0000969 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +0000970 continue;
Guido van Rossum02975121992-08-17 08:55:12 +0000971 if ('0' <= c && c <= '9') {
972 num = c - '0';
973 while ('0' <= (c = *s++) && c <= '9') {
974 x = num*10 + (c - '0');
975 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000976 PyErr_SetString(
977 StructError,
978 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +0000979 return -1;
980 }
981 num = x;
982 }
983 if (c == '\0')
984 break;
985 }
986 else
987 num = 1;
Tim Peters2d4e0772001-06-11 16:57:33 +0000988
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000989 e = getentry(c, f);
990 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +0000991 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000992 itemsize = e->size;
993 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +0000994 x = num * itemsize;
995 size += x;
996 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +0000997 PyErr_SetString(StructError,
Guido van Rossum960bc542002-09-03 18:42:21 +0000998 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000999 return -1;
1000 }
Guido van Rossum02975121992-08-17 08:55:12 +00001001 }
1002
1003 return size;
1004}
1005
1006
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001007PyDoc_STRVAR(calcsize__doc__,
1008"calcsize(fmt) -> int\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001009Return size of C struct described by format string fmt.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001010See struct.__doc__ for more on format strings.");
Guido van Rossum02975121992-08-17 08:55:12 +00001011
Barry Warsaw30695fa1996-12-12 23:32:31 +00001012static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001013struct_calcsize(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001014{
1015 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001016 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001017 int size;
1018
Guido van Rossum43713e52000-02-29 13:59:29 +00001019 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001020 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001021 f = whichtable(&fmt);
1022 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001023 if (size < 0)
1024 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001025 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001026}
1027
1028
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001029PyDoc_STRVAR(pack__doc__,
1030"pack(fmt, v1, v2, ...) -> string\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001031Return string containing values v1, v2, ... packed according to fmt.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001032See struct.__doc__ for more on format strings.");
Guido van Rossum02975121992-08-17 08:55:12 +00001033
Barry Warsaw30695fa1996-12-12 23:32:31 +00001034static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001035struct_pack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001036{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001037 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001038 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001039 char *fmt;
1040 int size, num;
1041 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001042 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001043 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001044
Barry Warsaw30695fa1996-12-12 23:32:31 +00001045 if (args == NULL || !PyTuple_Check(args) ||
1046 (n = PyTuple_Size(args)) < 1)
Guido van Rossum960bc542002-09-03 18:42:21 +00001047 {
Tim Peters2d4e0772001-06-11 16:57:33 +00001048 PyErr_SetString(PyExc_TypeError,
Fred Drake137507e2000-06-01 02:02:46 +00001049 "struct.pack requires at least one argument");
Guido van Rossum02975121992-08-17 08:55:12 +00001050 return NULL;
1051 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001052 format = PyTuple_GetItem(args, 0);
Neal Norwitz187ae562002-04-02 18:17:57 +00001053 fmt = PyString_AsString(format);
1054 if (!fmt)
Guido van Rossum02975121992-08-17 08:55:12 +00001055 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001056 f = whichtable(&fmt);
1057 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001058 if (size < 0)
1059 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001060 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001061 if (result == NULL)
1062 return NULL;
1063
1064 s = fmt;
1065 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001066 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001067
1068 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001069 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001070 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001071 if ('0' <= c && c <= '9') {
1072 num = c - '0';
1073 while ('0' <= (c = *s++) && c <= '9')
1074 num = num*10 + (c - '0');
1075 if (c == '\0')
1076 break;
1077 }
1078 else
1079 num = 1;
1080
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001081 e = getentry(c, f);
1082 if (e == NULL)
1083 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001084 nres = restart + align((int)(res-restart), c, e);
1085 /* Fill padd bytes with zeros */
1086 while (res < nres)
1087 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001088 if (num == 0 && c != 's')
1089 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001090 do {
1091 if (c == 'x') {
1092 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001093 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001094 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001095 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001096 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001097 if (i >= n) {
1098 PyErr_SetString(StructError,
1099 "insufficient arguments to pack");
1100 goto fail;
1101 }
1102 v = PyTuple_GetItem(args, i++);
1103 if (v == NULL)
1104 goto fail;
1105 if (c == 's') {
1106 /* num is string size, not repeat count */
1107 int n;
1108 if (!PyString_Check(v)) {
1109 PyErr_SetString(StructError,
1110 "argument for 's' must be a string");
1111 goto fail;
1112 }
1113 n = PyString_Size(v);
1114 if (n > num)
1115 n = num;
1116 if (n > 0)
1117 memcpy(res, PyString_AsString(v), n);
1118 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001119 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001120 res += num;
1121 break;
1122 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001123 else if (c == 'p') {
1124 /* num is string size + 1,
1125 to fit in the count byte */
1126 int n;
1127 num--; /* now num is max string size */
1128 if (!PyString_Check(v)) {
1129 PyErr_SetString(StructError,
1130 "argument for 'p' must be a string");
1131 goto fail;
1132 }
1133 n = PyString_Size(v);
1134 if (n > num)
1135 n = num;
1136 if (n > 0)
1137 memcpy(res+1, PyString_AsString(v), n);
1138 if (n < num)
1139 /* no real need, just to be nice */
1140 memset(res+1+n, '\0', num-n);
Tim Peters0891ac02001-09-15 02:35:15 +00001141 if (n > 255)
1142 n = 255;
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001143 *res++ = n; /* store the length byte */
1144 res += num;
1145 break;
1146 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001147 else {
1148 if (e->pack(res, v, e) < 0)
1149 goto fail;
1150 res += e->size;
1151 }
1152 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001153 }
1154
1155 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001156 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001157 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001158 goto fail;
1159 }
1160
1161 return result;
1162
1163 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001164 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001165 return NULL;
1166}
1167
1168
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001169PyDoc_STRVAR(unpack__doc__,
1170"unpack(fmt, string) -> (v1, v2, ...)\n\
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001171Unpack the string, containing packed C structure data, according\n\
1172to fmt. Requires len(string)==calcsize(fmt).\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001173See struct.__doc__ for more on format strings.");
Guido van Rossum02975121992-08-17 08:55:12 +00001174
Barry Warsaw30695fa1996-12-12 23:32:31 +00001175static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001176struct_unpack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001177{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001178 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001179 char *str, *start, *fmt, *s;
1180 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001181 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001182 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001183
Guido van Rossum43713e52000-02-29 13:59:29 +00001184 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001185 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001186 f = whichtable(&fmt);
1187 size = calcsize(fmt, f);
1188 if (size < 0)
1189 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001190 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001191 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001192 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001193 return NULL;
1194 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001195 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001196 if (res == NULL)
1197 return NULL;
1198 str = start;
1199 s = fmt;
1200 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001201 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001202 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001203 if ('0' <= c && c <= '9') {
1204 num = c - '0';
1205 while ('0' <= (c = *s++) && c <= '9')
1206 num = num*10 + (c - '0');
1207 if (c == '\0')
1208 break;
1209 }
1210 else
1211 num = 1;
1212
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001213 e = getentry(c, f);
1214 if (e == NULL)
1215 goto fail;
1216 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001217 if (num == 0 && c != 's')
1218 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001219
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001220 do {
1221 if (c == 'x') {
1222 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001223 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001224 }
1225 if (c == 's') {
1226 /* num is string size, not repeat count */
1227 v = PyString_FromStringAndSize(str, num);
1228 if (v == NULL)
1229 goto fail;
1230 str += num;
1231 num = 0;
1232 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001233 else if (c == 'p') {
1234 /* num is string buffer size,
1235 not repeat count */
1236 int n = *(unsigned char*)str;
1237 /* first byte (unsigned) is string size */
1238 if (n >= num)
1239 n = num-1;
1240 v = PyString_FromStringAndSize(str+1, n);
1241 if (v == NULL)
1242 goto fail;
1243 str += num;
1244 num = 0;
1245 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001246 else {
1247 v = e->unpack(str, e);
1248 if (v == NULL)
1249 goto fail;
1250 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001251 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001252 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001253 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001254 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001255 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001256 }
1257
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001258 v = PyList_AsTuple(res);
1259 Py_DECREF(res);
1260 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001261
1262 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001263 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001264 return NULL;
1265}
1266
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001267
Guido van Rossum02975121992-08-17 08:55:12 +00001268/* List of functions */
1269
Barry Warsaw30695fa1996-12-12 23:32:31 +00001270static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001271 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1272 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1273 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001274 {NULL, NULL} /* sentinel */
1275};
1276
1277
1278/* Module initialization */
1279
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001280PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001281initstruct(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001282{
Fred Drake78f6c862002-02-14 07:11:23 +00001283 PyObject *m;
Guido van Rossum02975121992-08-17 08:55:12 +00001284
1285 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001286 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1287 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001288
1289 /* Add some symbolic constants to the module */
Fred Drake78f6c862002-02-14 07:11:23 +00001290 if (StructError == NULL) {
1291 StructError = PyErr_NewException("struct.error", NULL, NULL);
1292 if (StructError == NULL)
1293 return;
1294 }
1295 Py_INCREF(StructError);
Fred Drake2eeec9b2002-02-14 07:16:30 +00001296 PyModule_AddObject(m, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001297}