blob: b78231f4d3cfcb85d3e3bcd19f03160ad8d775d6 [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
Guido van Rossume2ae77b2001-10-24 20:42:55 +000045typedef struct { char c; short x; } st_short;
46typedef struct { char c; int x; } st_int;
47typedef struct { char c; long x; } st_long;
48typedef struct { char c; float x; } st_float;
49typedef struct { char c; double x; } st_double;
50typedef struct { char c; void *x; } st_void_p;
Guido van Rossum02975121992-08-17 08:55:12 +000051
Guido van Rossume2ae77b2001-10-24 20:42:55 +000052#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 *))
Guido van Rossum02975121992-08-17 08:55:12 +000058
Tim Peters7b9542a2001-06-10 23:40:19 +000059/* 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
Martin v. Löwisb9a0f912003-03-29 10:06:18 +000062typedef struct { char c; PY_LONG_LONG x; } s_long_long;
63#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
Tim Peters7b9542a2001-06-10 23:40:19 +000064#endif
65
Martin v. Löwis2af72d52000-09-15 08:10:33 +000066#define STRINGIFY(x) #x
67
Jack Jansen971e1df1995-02-02 14:29:10 +000068#ifdef __powerc
69#pragma options align=reset
70#endif
71
Tim Peters7a3bfc32001-06-12 01:22:22 +000072/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
73
74static PyObject *
75get_pylong(PyObject *v)
76{
77 PyNumberMethods *m;
78
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;
85 }
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);
94 }
95 PyErr_SetString(StructError,
96 "cannot convert argument to long");
97 return NULL;
98}
99
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000100/* Helper routine to get a Python integer and raise the appropriate error
101 if it isn't one */
102
103static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000104get_long(PyObject *v, long *p)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000105{
106 long x = PyInt_AsLong(v);
107 if (x == -1 && PyErr_Occurred()) {
Fred Draked3dbb381998-05-28 04:35:49 +0000108 if (PyErr_ExceptionMatches(PyExc_TypeError))
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000109 PyErr_SetString(StructError,
110 "required argument is not an integer");
111 return -1;
112 }
113 *p = x;
114 return 0;
115}
116
117
Guido van Rossum60c50611996-12-31 16:29:52 +0000118/* Same, but handling unsigned long */
119
120static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000121get_ulong(PyObject *v, unsigned long *p)
Guido van Rossum60c50611996-12-31 16:29:52 +0000122{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000123 if (PyLong_Check(v)) {
124 unsigned long x = PyLong_AsUnsignedLong(v);
125 if (x == (unsigned long)(-1) && PyErr_Occurred())
Guido van Rossum60c50611996-12-31 16:29:52 +0000126 return -1;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000127 *p = x;
128 return 0;
Guido van Rossum60c50611996-12-31 16:29:52 +0000129 }
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000130 else {
131 return get_long(v, (long *)p);
132 }
Guido van Rossum60c50611996-12-31 16:29:52 +0000133}
134
Tim Peters7b9542a2001-06-10 23:40:19 +0000135#ifdef HAVE_LONG_LONG
136
137/* Same, but handling native long long. */
138
139static int
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000140get_longlong(PyObject *v, PY_LONG_LONG *p)
Tim Peters7b9542a2001-06-10 23:40:19 +0000141{
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000142 PY_LONG_LONG x;
Tim Peters7b9542a2001-06-10 23:40:19 +0000143
Tim Peters7a3bfc32001-06-12 01:22:22 +0000144 v = get_pylong(v);
145 if (v == NULL)
146 return -1;
Tim Peters7b9542a2001-06-10 23:40:19 +0000147 assert(PyLong_Check(v));
148 x = PyLong_AsLongLong(v);
Tim Peters7a3bfc32001-06-12 01:22:22 +0000149 Py_DECREF(v);
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000150 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
Tim Peters7b9542a2001-06-10 23:40:19 +0000151 return -1;
152 *p = x;
153 return 0;
154}
155
156/* Same, but handling native unsigned long long. */
157
158static int
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000159get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
Tim Peters7b9542a2001-06-10 23:40:19 +0000160{
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000161 unsigned PY_LONG_LONG x;
Tim Peters7b9542a2001-06-10 23:40:19 +0000162
Tim Peters7a3bfc32001-06-12 01:22:22 +0000163 v = get_pylong(v);
164 if (v == NULL)
165 return -1;
Tim Peters7b9542a2001-06-10 23:40:19 +0000166 assert(PyLong_Check(v));
167 x = PyLong_AsUnsignedLongLong(v);
Tim Peters7a3bfc32001-06-12 01:22:22 +0000168 Py_DECREF(v);
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000169 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
Tim Peters7b9542a2001-06-10 23:40:19 +0000170 return -1;
171 *p = x;
172 return 0;
173}
174
175#endif
Guido van Rossum60c50611996-12-31 16:29:52 +0000176
Guido van Rossum74679b41997-01-02 22:21:36 +0000177/* Floating point helpers */
178
Guido van Rossum74679b41997-01-02 22:21:36 +0000179static PyObject *
Tim Peters9905b942003-03-20 20:53:32 +0000180unpack_float(const char *p, /* start of 4-byte string */
181 int le) /* true for little-endian, false for big-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000182{
Guido van Rossum74679b41997-01-02 22:21:36 +0000183 double x;
184
Tim Peters9905b942003-03-20 20:53:32 +0000185 x = _PyFloat_Unpack4((unsigned char *)p, le);
186 if (x == -1.0 && PyErr_Occurred())
187 return NULL;
Guido van Rossum74679b41997-01-02 22:21:36 +0000188 return PyFloat_FromDouble(x);
189}
190
191static PyObject *
Tim Peters9905b942003-03-20 20:53:32 +0000192unpack_double(const char *p, /* start of 8-byte string */
193 int le) /* true for little-endian, false for big-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000194{
Guido van Rossum74679b41997-01-02 22:21:36 +0000195 double x;
196
Tim Peters9905b942003-03-20 20:53:32 +0000197 x = _PyFloat_Unpack8((unsigned char *)p, le);
198 if (x == -1.0 && PyErr_Occurred())
199 return NULL;
Guido van Rossum74679b41997-01-02 22:21:36 +0000200 return PyFloat_FromDouble(x);
201}
202
203
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000204/* The translation function for each format character is table driven */
205
206typedef struct _formatdef {
207 char format;
208 int size;
209 int alignment;
Tim Petersdbd9ba62000-07-09 03:09:57 +0000210 PyObject* (*unpack)(const char *,
211 const struct _formatdef *);
212 int (*pack)(char *, PyObject *,
213 const struct _formatdef *);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000214} formatdef;
215
Tim Peters7b9542a2001-06-10 23:40:19 +0000216/* A large number of small routines follow, with names of the form
217
218 [bln][up]_TYPE
219
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.
223*/
224
Tim Peters7a3bfc32001-06-12 01:22:22 +0000225/* Native mode routines. ****************************************************/
Guido van Rossum960bc542002-09-03 18:42:21 +0000226/* 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). */
Tim Peters7b9542a2001-06-10 23:40:19 +0000234
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000235static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000236nu_char(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000237{
238 return PyString_FromStringAndSize(p, 1);
239}
240
241static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000242nu_byte(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000243{
244 return PyInt_FromLong((long) *(signed char *)p);
245}
246
247static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000248nu_ubyte(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000249{
250 return PyInt_FromLong((long) *(unsigned char *)p);
251}
252
253static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000254nu_short(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000255{
Guido van Rossum960bc542002-09-03 18:42:21 +0000256 short x;
257 memcpy((char *)&x, p, sizeof x);
258 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000259}
260
261static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000262nu_ushort(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000263{
Guido van Rossum960bc542002-09-03 18:42:21 +0000264 unsigned short x;
265 memcpy((char *)&x, p, sizeof x);
266 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000267}
268
269static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000270nu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000271{
Guido van Rossum960bc542002-09-03 18:42:21 +0000272 int x;
273 memcpy((char *)&x, p, sizeof x);
274 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000275}
276
277static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000278nu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000279{
Guido van Rossum960bc542002-09-03 18:42:21 +0000280 unsigned int x;
281 memcpy((char *)&x, p, sizeof x);
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000282 return PyLong_FromUnsignedLong((unsigned long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000283}
284
285static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000286nu_long(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000287{
Guido van Rossum960bc542002-09-03 18:42:21 +0000288 long x;
289 memcpy((char *)&x, p, sizeof x);
290 return PyInt_FromLong(x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000291}
292
293static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000294nu_ulong(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000295{
Guido van Rossum960bc542002-09-03 18:42:21 +0000296 unsigned long x;
297 memcpy((char *)&x, p, sizeof x);
298 return PyLong_FromUnsignedLong(x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000299}
300
Tim Peters7b9542a2001-06-10 23:40:19 +0000301/* Native mode doesn't support q or Q unless the platform C supports
302 long long (or, on Windows, __int64). */
303
304#ifdef HAVE_LONG_LONG
305
306static PyObject *
307nu_longlong(const char *p, const formatdef *f)
308{
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000309 PY_LONG_LONG x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000310 memcpy((char *)&x, p, sizeof x);
Tim Peters3dac5592001-07-18 20:47:31 +0000311 return PyLong_FromLongLong(x);
Tim Peters7b9542a2001-06-10 23:40:19 +0000312}
313
314static PyObject *
315nu_ulonglong(const char *p, const formatdef *f)
316{
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000317 unsigned PY_LONG_LONG x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000318 memcpy((char *)&x, p, sizeof x);
Tim Peters3dac5592001-07-18 20:47:31 +0000319 return PyLong_FromUnsignedLongLong(x);
Tim Peters7b9542a2001-06-10 23:40:19 +0000320}
Guido van Rossum960bc542002-09-03 18:42:21 +0000321
Tim Peters7b9542a2001-06-10 23:40:19 +0000322#endif
323
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000324static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000325nu_float(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000326{
327 float x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000328 memcpy((char *)&x, p, sizeof x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000329 return PyFloat_FromDouble((double)x);
330}
331
332static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000333nu_double(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000334{
335 double x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000336 memcpy((char *)&x, p, sizeof x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000337 return PyFloat_FromDouble(x);
338}
339
Guido van Rossum78694d91998-09-18 14:14:13 +0000340static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000341nu_void_p(const char *p, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000342{
Guido van Rossum960bc542002-09-03 18:42:21 +0000343 void *x;
344 memcpy((char *)&x, p, sizeof x);
345 return PyLong_FromVoidPtr(x);
Guido van Rossum78694d91998-09-18 14:14:13 +0000346}
347
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000348static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000349np_byte(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000350{
351 long x;
352 if (get_long(v, &x) < 0)
353 return -1;
Martin v. Löwis66de5492000-09-15 07:31:57 +0000354 if (x < -128 || x > 127){
355 PyErr_SetString(StructError,
356 "byte format requires -128<=number<=127");
357 return -1;
358 }
359 *p = (char)x;
360 return 0;
361}
362
363static int
364np_ubyte(char *p, PyObject *v, const formatdef *f)
365{
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;
373 }
Guido van Rossum7844e381997-04-11 20:44:04 +0000374 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000375 return 0;
376}
377
378static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000379np_char(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000380{
381 if (!PyString_Check(v) || PyString_Size(v) != 1) {
382 PyErr_SetString(StructError,
383 "char format require string of length 1");
384 return -1;
385 }
386 *p = *PyString_AsString(v);
387 return 0;
388}
389
390static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000391np_short(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000392{
393 long x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000394 short y;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000395 if (get_long(v, &x) < 0)
396 return -1;
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000397 if (x < SHRT_MIN || x > SHRT_MAX){
Martin v. Löwis66de5492000-09-15 07:31:57 +0000398 PyErr_SetString(StructError,
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000399 "short format requires " STRINGIFY(SHRT_MIN)
Guido van Rossum960bc542002-09-03 18:42:21 +0000400 "<=number<=" STRINGIFY(SHRT_MAX));
Martin v. Löwis66de5492000-09-15 07:31:57 +0000401 return -1;
402 }
Guido van Rossum960bc542002-09-03 18:42:21 +0000403 y = (short)x;
404 memcpy(p, (char *)&y, sizeof y);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000405 return 0;
406}
407
408static int
Martin v. Löwis66de5492000-09-15 07:31:57 +0000409np_ushort(char *p, PyObject *v, const formatdef *f)
410{
411 long x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000412 unsigned short y;
Martin v. Löwis66de5492000-09-15 07:31:57 +0000413 if (get_long(v, &x) < 0)
414 return -1;
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000415 if (x < 0 || x > USHRT_MAX){
Martin v. Löwis66de5492000-09-15 07:31:57 +0000416 PyErr_SetString(StructError,
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000417 "short format requires 0<=number<=" STRINGIFY(USHRT_MAX));
Martin v. Löwis66de5492000-09-15 07:31:57 +0000418 return -1;
419 }
Guido van Rossum960bc542002-09-03 18:42:21 +0000420 y = (unsigned short)x;
421 memcpy(p, (char *)&y, sizeof y);
Martin v. Löwis66de5492000-09-15 07:31:57 +0000422 return 0;
423}
424
425static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000426np_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000427{
428 long x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000429 int y;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000430 if (get_long(v, &x) < 0)
431 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000432 y = (int)x;
433 memcpy(p, (char *)&y, sizeof y);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000434 return 0;
435}
436
437static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000438np_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000439{
440 unsigned long x;
Guido van Rossum960bc542002-09-03 18:42:21 +0000441 unsigned int y;
Guido van Rossum60c50611996-12-31 16:29:52 +0000442 if (get_ulong(v, &x) < 0)
443 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000444 y = (unsigned int)x;
445 memcpy(p, (char *)&y, sizeof y);
Guido van Rossum60c50611996-12-31 16:29:52 +0000446 return 0;
447}
448
449static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000450np_long(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000451{
452 long x;
453 if (get_long(v, &x) < 0)
454 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000455 memcpy(p, (char *)&x, sizeof x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000456 return 0;
457}
458
459static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000460np_ulong(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000461{
462 unsigned long x;
463 if (get_ulong(v, &x) < 0)
464 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000465 memcpy(p, (char *)&x, sizeof x);
Guido van Rossum60c50611996-12-31 16:29:52 +0000466 return 0;
467}
468
Tim Peters7b9542a2001-06-10 23:40:19 +0000469#ifdef HAVE_LONG_LONG
470
471static int
472np_longlong(char *p, PyObject *v, const formatdef *f)
473{
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000474 PY_LONG_LONG x;
Tim Peters7b9542a2001-06-10 23:40:19 +0000475 if (get_longlong(v, &x) < 0)
476 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000477 memcpy(p, (char *)&x, sizeof x);
Tim Peters7b9542a2001-06-10 23:40:19 +0000478 return 0;
479}
480
481static int
482np_ulonglong(char *p, PyObject *v, const formatdef *f)
483{
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000484 unsigned PY_LONG_LONG x;
Tim Peters7b9542a2001-06-10 23:40:19 +0000485 if (get_ulonglong(v, &x) < 0)
486 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000487 memcpy(p, (char *)&x, sizeof x);
Tim Peters7b9542a2001-06-10 23:40:19 +0000488 return 0;
489}
Tim Peters7b9542a2001-06-10 23:40:19 +0000490#endif
491
Guido van Rossum60c50611996-12-31 16:29:52 +0000492static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000493np_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000494{
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;
500 }
Guido van Rossum960bc542002-09-03 18:42:21 +0000501 memcpy(p, (char *)&x, sizeof x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000502 return 0;
503}
504
505static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000506np_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000507{
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;
513 }
514 memcpy(p, (char *)&x, sizeof(double));
515 return 0;
516}
517
Guido van Rossum78694d91998-09-18 14:14:13 +0000518static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000519np_void_p(char *p, PyObject *v, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000520{
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;
528 }
Guido van Rossum960bc542002-09-03 18:42:21 +0000529 memcpy(p, (char *)&x, sizeof x);
Guido van Rossum78694d91998-09-18 14:14:13 +0000530 return 0;
531}
532
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000533static formatdef native_table[] = {
534 {'x', sizeof(char), 0, NULL},
535 {'b', sizeof(char), 0, nu_byte, np_byte},
Martin v. Löwis66de5492000-09-15 07:31:57 +0000536 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000537 {'c', sizeof(char), 0, nu_char, np_char},
538 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000539 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000540 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
Martin v. Löwis66de5492000-09-15 07:31:57 +0000541 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000542 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000543 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000544 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000545 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000546 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
547 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
Guido van Rossum78694d91998-09-18 14:14:13 +0000548 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Tim Peters7b9542a2001-06-10 23:40:19 +0000549#ifdef HAVE_LONG_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000550 {'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},
Tim Peters7b9542a2001-06-10 23:40:19 +0000552#endif
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000553 {0}
554};
555
Tim Peters7a3bfc32001-06-12 01:22:22 +0000556/* Big-endian routines. *****************************************************/
557
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000558static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000559bu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000560{
561 long x = 0;
562 int i = f->size;
563 do {
564 x = (x<<8) | (*p++ & 0xFF);
565 } while (--i > 0);
Tim Petersf0e717b2001-04-08 23:39:38 +0000566 /* Extend the sign bit. */
567 if (SIZEOF_LONG > f->size)
568 x |= -(x & (1L << (8*f->size - 1)));
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000569 return PyInt_FromLong(x);
570}
571
572static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000573bu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000574{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000575 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000576 int i = f->size;
577 do {
578 x = (x<<8) | (*p++ & 0xFF);
579 } while (--i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000580 if (f->size >= 4)
581 return PyLong_FromUnsignedLong(x);
582 else
583 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000584}
585
Guido van Rossum74679b41997-01-02 22:21:36 +0000586static PyObject *
Tim Peters7a3bfc32001-06-12 01:22:22 +0000587bu_longlong(const char *p, const formatdef *f)
588{
589 return _PyLong_FromByteArray((const unsigned char *)p,
590 8,
591 0, /* little-endian */
592 1 /* signed */);
593}
594
595static PyObject *
596bu_ulonglong(const char *p, const formatdef *f)
597{
598 return _PyLong_FromByteArray((const unsigned char *)p,
599 8,
600 0, /* little-endian */
601 0 /* signed */);
602}
603
604static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000605bu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000606{
Tim Peters9905b942003-03-20 20:53:32 +0000607 return unpack_float(p, 0);
Guido van Rossum74679b41997-01-02 22:21:36 +0000608}
609
610static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000611bu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000612{
Tim Peters9905b942003-03-20 20:53:32 +0000613 return unpack_double(p, 0);
Guido van Rossum74679b41997-01-02 22:21:36 +0000614}
615
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000616static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000617bp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000618{
619 long x;
620 int i;
621 if (get_long(v, &x) < 0)
622 return -1;
623 i = f->size;
624 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000625 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000626 x >>= 8;
627 } while (i > 0);
628 return 0;
629}
630
Guido van Rossum60c50611996-12-31 16:29:52 +0000631static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000632bp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000633{
634 unsigned long x;
635 int i;
636 if (get_ulong(v, &x) < 0)
637 return -1;
638 i = f->size;
639 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000640 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000641 x >>= 8;
642 } while (i > 0);
643 return 0;
644}
645
Guido van Rossum74679b41997-01-02 22:21:36 +0000646static int
Tim Peters7a3bfc32001-06-12 01:22:22 +0000647bp_longlong(char *p, PyObject *v, const formatdef *f)
648{
649 int res;
650 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000651 if (v == NULL)
652 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000653 res = _PyLong_AsByteArray((PyLongObject *)v,
654 (unsigned char *)p,
655 8,
656 0, /* little_endian */
657 1 /* signed */);
658 Py_DECREF(v);
659 return res;
660}
661
662static int
663bp_ulonglong(char *p, PyObject *v, const formatdef *f)
664{
665 int res;
666 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000667 if (v == NULL)
668 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000669 res = _PyLong_AsByteArray((PyLongObject *)v,
670 (unsigned char *)p,
671 8,
672 0, /* little_endian */
673 0 /* signed */);
674 Py_DECREF(v);
675 return res;
676}
677
678static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000679bp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000680{
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;
686 }
Tim Peters9905b942003-03-20 20:53:32 +0000687 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
Guido van Rossum74679b41997-01-02 22:21:36 +0000688}
689
690static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000691bp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000692{
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;
698 }
Tim Peters9905b942003-03-20 20:53:32 +0000699 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
Guido van Rossum74679b41997-01-02 22:21:36 +0000700}
701
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000702static 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},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000708 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000709 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000710 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000711 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000712 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000713 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000714 {'L', 4, 0, bu_uint, bp_uint},
Tim Peters7a3bfc32001-06-12 01:22:22 +0000715 {'q', 8, 0, bu_longlong, bp_longlong},
716 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
Guido van Rossum74679b41997-01-02 22:21:36 +0000717 {'f', 4, 0, bu_float, bp_float},
718 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000719 {0}
720};
721
Tim Peters7a3bfc32001-06-12 01:22:22 +0000722/* Little-endian routines. *****************************************************/
723
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000724static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000725lu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000726{
727 long x = 0;
728 int i = f->size;
729 do {
730 x = (x<<8) | (p[--i] & 0xFF);
731 } while (i > 0);
Tim Petersf0e717b2001-04-08 23:39:38 +0000732 /* Extend the sign bit. */
733 if (SIZEOF_LONG > f->size)
734 x |= -(x & (1L << (8*f->size - 1)));
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000735 return PyInt_FromLong(x);
736}
737
738static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000739lu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000740{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000741 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000742 int i = f->size;
743 do {
744 x = (x<<8) | (p[--i] & 0xFF);
745 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000746 if (f->size >= 4)
747 return PyLong_FromUnsignedLong(x);
748 else
749 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000750}
751
Guido van Rossum74679b41997-01-02 22:21:36 +0000752static PyObject *
Tim Peters7a3bfc32001-06-12 01:22:22 +0000753lu_longlong(const char *p, const formatdef *f)
754{
755 return _PyLong_FromByteArray((const unsigned char *)p,
756 8,
757 1, /* little-endian */
758 1 /* signed */);
759}
760
761static PyObject *
762lu_ulonglong(const char *p, const formatdef *f)
763{
764 return _PyLong_FromByteArray((const unsigned char *)p,
765 8,
766 1, /* little-endian */
767 0 /* signed */);
768}
769
770static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000771lu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000772{
Tim Peters9905b942003-03-20 20:53:32 +0000773 return unpack_float(p, 1);
Guido van Rossum74679b41997-01-02 22:21:36 +0000774}
775
776static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000777lu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000778{
Tim Peters9905b942003-03-20 20:53:32 +0000779 return unpack_double(p, 1);
Guido van Rossum74679b41997-01-02 22:21:36 +0000780}
781
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000782static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000783lp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000784{
785 long x;
786 int i;
787 if (get_long(v, &x) < 0)
788 return -1;
789 i = f->size;
790 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000791 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000792 x >>= 8;
793 } while (--i > 0);
794 return 0;
795}
796
Guido van Rossum60c50611996-12-31 16:29:52 +0000797static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000798lp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000799{
800 unsigned long x;
801 int i;
802 if (get_ulong(v, &x) < 0)
803 return -1;
804 i = f->size;
805 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000806 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000807 x >>= 8;
808 } while (--i > 0);
809 return 0;
810}
811
Guido van Rossum74679b41997-01-02 22:21:36 +0000812static int
Tim Peters7a3bfc32001-06-12 01:22:22 +0000813lp_longlong(char *p, PyObject *v, const formatdef *f)
814{
815 int res;
816 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000817 if (v == NULL)
818 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000819 res = _PyLong_AsByteArray((PyLongObject*)v,
820 (unsigned char *)p,
821 8,
822 1, /* little_endian */
823 1 /* signed */);
824 Py_DECREF(v);
825 return res;
826}
827
828static int
829lp_ulonglong(char *p, PyObject *v, const formatdef *f)
830{
831 int res;
832 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000833 if (v == NULL)
834 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000835 res = _PyLong_AsByteArray((PyLongObject*)v,
836 (unsigned char *)p,
837 8,
838 1, /* little_endian */
839 0 /* signed */);
840 Py_DECREF(v);
841 return res;
842}
843
844static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000845lp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000846{
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;
852 }
Tim Peters9905b942003-03-20 20:53:32 +0000853 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
Guido van Rossum74679b41997-01-02 22:21:36 +0000854}
855
856static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000857lp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000858{
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;
864 }
Tim Peters9905b942003-03-20 20:53:32 +0000865 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
Guido van Rossum74679b41997-01-02 22:21:36 +0000866}
867
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000868static 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},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000874 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000875 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000876 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000877 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000878 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000879 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000880 {'L', 4, 0, lu_uint, lp_uint},
Tim Peters7a3bfc32001-06-12 01:22:22 +0000881 {'q', 8, 0, lu_longlong, lp_longlong},
882 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
Guido van Rossum74679b41997-01-02 22:21:36 +0000883 {'f', 4, 0, lu_float, lp_float},
884 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000885 {0}
886};
887
888
889static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000890whichtable(char **pfmt)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000891{
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;
906 }
907 default:
908 --*pfmt; /* Back out of pointer increment */
909 /* Fall through */
910 case '@':
911 return native_table;
912 }
913}
914
915
916/* Get the table entry for a format code */
917
918static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000919getentry(int c, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000920{
921 for (; f->format != '\0'; f++) {
922 if (f->format == c) {
923 return f;
924 }
925 }
926 PyErr_SetString(StructError, "bad char in struct format");
927 return NULL;
928}
929
930
Guido van Rossum02975121992-08-17 08:55:12 +0000931/* Align a size according to a format code */
932
933static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000934align(int size, int c, const formatdef *e)
Guido van Rossum02975121992-08-17 08:55:12 +0000935{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000936 if (e->format == c) {
937 if (e->alignment) {
938 size = ((size + e->alignment - 1)
939 / e->alignment)
940 * e->alignment;
941 }
Guido van Rossum02975121992-08-17 08:55:12 +0000942 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000943 return size;
Guido van Rossum02975121992-08-17 08:55:12 +0000944}
945
946
947/* calculate the size of a format string */
948
949static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000950calcsize(const char *fmt, const formatdef *f)
Guido van Rossum02975121992-08-17 08:55:12 +0000951{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000952 const formatdef *e;
953 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +0000954 char c;
955 int size, num, itemsize, x;
956
957 s = fmt;
958 size = 0;
959 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +0000960 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +0000961 continue;
Guido van Rossum02975121992-08-17 08:55:12 +0000962 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) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000967 PyErr_SetString(
968 StructError,
969 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +0000970 return -1;
971 }
972 num = x;
973 }
974 if (c == '\0')
975 break;
976 }
977 else
978 num = 1;
Tim Peters2d4e0772001-06-11 16:57:33 +0000979
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000980 e = getentry(c, f);
981 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +0000982 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000983 itemsize = e->size;
984 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +0000985 x = num * itemsize;
986 size += x;
987 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +0000988 PyErr_SetString(StructError,
Guido van Rossum960bc542002-09-03 18:42:21 +0000989 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000990 return -1;
991 }
Guido van Rossum02975121992-08-17 08:55:12 +0000992 }
993
994 return size;
995}
996
997
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +0000998PyDoc_STRVAR(calcsize__doc__,
999"calcsize(fmt) -> int\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001000Return size of C struct described by format string fmt.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001001See struct.__doc__ for more on format strings.");
Guido van Rossum02975121992-08-17 08:55:12 +00001002
Barry Warsaw30695fa1996-12-12 23:32:31 +00001003static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001004struct_calcsize(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001005{
1006 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001007 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001008 int size;
1009
Guido van Rossum43713e52000-02-29 13:59:29 +00001010 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001011 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001012 f = whichtable(&fmt);
1013 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001014 if (size < 0)
1015 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001016 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001017}
1018
1019
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001020PyDoc_STRVAR(pack__doc__,
1021"pack(fmt, v1, v2, ...) -> string\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001022Return string containing values v1, v2, ... packed according to fmt.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001023See struct.__doc__ for more on format strings.");
Guido van Rossum02975121992-08-17 08:55:12 +00001024
Barry Warsaw30695fa1996-12-12 23:32:31 +00001025static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001026struct_pack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001027{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001028 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001029 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001030 char *fmt;
1031 int size, num;
1032 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001033 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001034 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001035
Barry Warsaw30695fa1996-12-12 23:32:31 +00001036 if (args == NULL || !PyTuple_Check(args) ||
1037 (n = PyTuple_Size(args)) < 1)
Guido van Rossum960bc542002-09-03 18:42:21 +00001038 {
Tim Peters2d4e0772001-06-11 16:57:33 +00001039 PyErr_SetString(PyExc_TypeError,
Fred Drake137507e2000-06-01 02:02:46 +00001040 "struct.pack requires at least one argument");
Guido van Rossum02975121992-08-17 08:55:12 +00001041 return NULL;
1042 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001043 format = PyTuple_GetItem(args, 0);
Neal Norwitz187ae562002-04-02 18:17:57 +00001044 fmt = PyString_AsString(format);
1045 if (!fmt)
Guido van Rossum02975121992-08-17 08:55:12 +00001046 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001047 f = whichtable(&fmt);
1048 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001049 if (size < 0)
1050 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001051 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001052 if (result == NULL)
1053 return NULL;
1054
1055 s = fmt;
1056 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001057 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001058
1059 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001060 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001061 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001062 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;
1068 }
1069 else
1070 num = 1;
1071
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001072 e = getentry(c, f);
1073 if (e == NULL)
1074 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001075 nres = restart + align((int)(res-restart), c, e);
1076 /* Fill padd bytes with zeros */
1077 while (res < nres)
1078 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001079 if (num == 0 && c != 's')
1080 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001081 do {
1082 if (c == 'x') {
1083 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001084 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001085 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001086 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001087 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001088 if (i >= n) {
1089 PyErr_SetString(StructError,
1090 "insufficient arguments to pack");
1091 goto fail;
1092 }
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;
1103 }
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)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001110 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001111 res += num;
1112 break;
1113 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001114 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;
1123 }
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);
Tim Peters0891ac02001-09-15 02:35:15 +00001132 if (n > 255)
1133 n = 255;
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001134 *res++ = n; /* store the length byte */
1135 res += num;
1136 break;
1137 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001138 else {
1139 if (e->pack(res, v, e) < 0)
1140 goto fail;
1141 res += e->size;
1142 }
1143 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001144 }
1145
1146 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001147 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001148 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001149 goto fail;
1150 }
1151
1152 return result;
1153
1154 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001155 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001156 return NULL;
1157}
1158
1159
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001160PyDoc_STRVAR(unpack__doc__,
1161"unpack(fmt, string) -> (v1, v2, ...)\n\
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001162Unpack the string, containing packed C structure data, according\n\
1163to fmt. Requires len(string)==calcsize(fmt).\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001164See struct.__doc__ for more on format strings.");
Guido van Rossum02975121992-08-17 08:55:12 +00001165
Barry Warsaw30695fa1996-12-12 23:32:31 +00001166static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001167struct_unpack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001168{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001169 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001170 char *str, *start, *fmt, *s;
1171 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001172 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001173 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001174
Guido van Rossum43713e52000-02-29 13:59:29 +00001175 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001176 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001177 f = whichtable(&fmt);
1178 size = calcsize(fmt, f);
1179 if (size < 0)
1180 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001181 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001182 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001183 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001184 return NULL;
1185 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001186 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001187 if (res == NULL)
1188 return NULL;
1189 str = start;
1190 s = fmt;
1191 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001192 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001193 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001194 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;
1200 }
1201 else
1202 num = 1;
1203
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001204 e = getentry(c, f);
1205 if (e == NULL)
1206 goto fail;
1207 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001208 if (num == 0 && c != 's')
1209 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001210
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001211 do {
1212 if (c == 'x') {
1213 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001214 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001215 }
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;
1223 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001224 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;
1236 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001237 else {
1238 v = e->unpack(str, e);
1239 if (v == NULL)
1240 goto fail;
1241 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001242 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001243 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001244 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001245 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001246 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001247 }
1248
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001249 v = PyList_AsTuple(res);
1250 Py_DECREF(res);
1251 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001252
1253 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001254 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001255 return NULL;
1256}
1257
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001258
Guido van Rossum02975121992-08-17 08:55:12 +00001259/* List of functions */
1260
Barry Warsaw30695fa1996-12-12 23:32:31 +00001261static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001262 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1263 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1264 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001265 {NULL, NULL} /* sentinel */
1266};
1267
1268
1269/* Module initialization */
1270
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001271PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001272initstruct(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001273{
Fred Drake78f6c862002-02-14 07:11:23 +00001274 PyObject *m;
Guido van Rossum02975121992-08-17 08:55:12 +00001275
1276 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001277 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1278 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001279
1280 /* Add some symbolic constants to the module */
Fred Drake78f6c862002-02-14 07:11:23 +00001281 if (StructError == NULL) {
1282 StructError = PyErr_NewException("struct.error", NULL, NULL);
1283 if (StructError == NULL)
1284 return;
1285 }
1286 Py_INCREF(StructError);
Fred Drake2eeec9b2002-02-14 07:16:30 +00001287 PyModule_AddObject(m, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001288}