blob: 33134e920b7e33eb17317848389da0db4c1a12c1 [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{
Armin Rigo9f904392004-09-27 19:27:51 +0000521 void *x;
522
523 v = get_pylong(v);
524 if (v == NULL)
Guido van Rossum78694d91998-09-18 14:14:13 +0000525 return -1;
Armin Rigo9f904392004-09-27 19:27:51 +0000526 assert(PyLong_Check(v));
527 x = PyLong_AsVoidPtr(v);
528 Py_DECREF(v);
529 if (x == NULL && PyErr_Occurred())
530 return -1;
Guido van Rossum960bc542002-09-03 18:42:21 +0000531 memcpy(p, (char *)&x, sizeof x);
Guido van Rossum78694d91998-09-18 14:14:13 +0000532 return 0;
533}
534
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000535static formatdef native_table[] = {
536 {'x', sizeof(char), 0, NULL},
537 {'b', sizeof(char), 0, nu_byte, np_byte},
Martin v. Löwis66de5492000-09-15 07:31:57 +0000538 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000539 {'c', sizeof(char), 0, nu_char, np_char},
540 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000541 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000542 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
Martin v. Löwis66de5492000-09-15 07:31:57 +0000543 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000544 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000545 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000546 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000547 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000548 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
549 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
Guido van Rossum78694d91998-09-18 14:14:13 +0000550 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Tim Peters7b9542a2001-06-10 23:40:19 +0000551#ifdef HAVE_LONG_LONG
Martin v. Löwisb9a0f912003-03-29 10:06:18 +0000552 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
553 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Tim Peters7b9542a2001-06-10 23:40:19 +0000554#endif
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000555 {0}
556};
557
Tim Peters7a3bfc32001-06-12 01:22:22 +0000558/* Big-endian routines. *****************************************************/
559
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000560static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000561bu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000562{
563 long x = 0;
564 int i = f->size;
565 do {
566 x = (x<<8) | (*p++ & 0xFF);
567 } while (--i > 0);
Tim Petersf0e717b2001-04-08 23:39:38 +0000568 /* Extend the sign bit. */
569 if (SIZEOF_LONG > f->size)
570 x |= -(x & (1L << (8*f->size - 1)));
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000571 return PyInt_FromLong(x);
572}
573
574static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000575bu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000576{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000577 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000578 int i = f->size;
579 do {
580 x = (x<<8) | (*p++ & 0xFF);
581 } while (--i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000582 if (f->size >= 4)
583 return PyLong_FromUnsignedLong(x);
584 else
585 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000586}
587
Guido van Rossum74679b41997-01-02 22:21:36 +0000588static PyObject *
Tim Peters7a3bfc32001-06-12 01:22:22 +0000589bu_longlong(const char *p, const formatdef *f)
590{
591 return _PyLong_FromByteArray((const unsigned char *)p,
592 8,
593 0, /* little-endian */
594 1 /* signed */);
595}
596
597static PyObject *
598bu_ulonglong(const char *p, const formatdef *f)
599{
600 return _PyLong_FromByteArray((const unsigned char *)p,
601 8,
602 0, /* little-endian */
603 0 /* signed */);
604}
605
606static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000607bu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000608{
Tim Peters9905b942003-03-20 20:53:32 +0000609 return unpack_float(p, 0);
Guido van Rossum74679b41997-01-02 22:21:36 +0000610}
611
612static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000613bu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000614{
Tim Peters9905b942003-03-20 20:53:32 +0000615 return unpack_double(p, 0);
Guido van Rossum74679b41997-01-02 22:21:36 +0000616}
617
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000618static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000619bp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000620{
621 long x;
622 int i;
623 if (get_long(v, &x) < 0)
624 return -1;
625 i = f->size;
626 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000627 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000628 x >>= 8;
629 } while (i > 0);
630 return 0;
631}
632
Guido van Rossum60c50611996-12-31 16:29:52 +0000633static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000634bp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000635{
636 unsigned long x;
637 int i;
638 if (get_ulong(v, &x) < 0)
639 return -1;
640 i = f->size;
641 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000642 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000643 x >>= 8;
644 } while (i > 0);
645 return 0;
646}
647
Guido van Rossum74679b41997-01-02 22:21:36 +0000648static int
Tim Peters7a3bfc32001-06-12 01:22:22 +0000649bp_longlong(char *p, PyObject *v, const formatdef *f)
650{
651 int res;
652 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000653 if (v == NULL)
654 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000655 res = _PyLong_AsByteArray((PyLongObject *)v,
656 (unsigned char *)p,
657 8,
658 0, /* little_endian */
659 1 /* signed */);
660 Py_DECREF(v);
661 return res;
662}
663
664static int
665bp_ulonglong(char *p, PyObject *v, const formatdef *f)
666{
667 int res;
668 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000669 if (v == NULL)
670 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000671 res = _PyLong_AsByteArray((PyLongObject *)v,
672 (unsigned char *)p,
673 8,
674 0, /* little_endian */
675 0 /* signed */);
676 Py_DECREF(v);
677 return res;
678}
679
680static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000681bp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000682{
683 double x = PyFloat_AsDouble(v);
684 if (x == -1 && PyErr_Occurred()) {
685 PyErr_SetString(StructError,
686 "required argument is not a float");
687 return -1;
688 }
Tim Peters9905b942003-03-20 20:53:32 +0000689 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
Guido van Rossum74679b41997-01-02 22:21:36 +0000690}
691
692static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000693bp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000694{
695 double x = PyFloat_AsDouble(v);
696 if (x == -1 && PyErr_Occurred()) {
697 PyErr_SetString(StructError,
698 "required argument is not a float");
699 return -1;
700 }
Tim Peters9905b942003-03-20 20:53:32 +0000701 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
Guido van Rossum74679b41997-01-02 22:21:36 +0000702}
703
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000704static formatdef bigendian_table[] = {
705 {'x', 1, 0, NULL},
706 {'b', 1, 0, bu_int, bp_int},
707 {'B', 1, 0, bu_uint, bp_int},
708 {'c', 1, 0, nu_char, np_char},
709 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000710 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000711 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000712 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000713 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000714 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000715 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000716 {'L', 4, 0, bu_uint, bp_uint},
Tim Peters7a3bfc32001-06-12 01:22:22 +0000717 {'q', 8, 0, bu_longlong, bp_longlong},
718 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
Guido van Rossum74679b41997-01-02 22:21:36 +0000719 {'f', 4, 0, bu_float, bp_float},
720 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000721 {0}
722};
723
Tim Peters7a3bfc32001-06-12 01:22:22 +0000724/* Little-endian routines. *****************************************************/
725
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000726static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000727lu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000728{
729 long x = 0;
730 int i = f->size;
731 do {
732 x = (x<<8) | (p[--i] & 0xFF);
733 } while (i > 0);
Tim Petersf0e717b2001-04-08 23:39:38 +0000734 /* Extend the sign bit. */
735 if (SIZEOF_LONG > f->size)
736 x |= -(x & (1L << (8*f->size - 1)));
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000737 return PyInt_FromLong(x);
738}
739
740static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000741lu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000742{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000743 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000744 int i = f->size;
745 do {
746 x = (x<<8) | (p[--i] & 0xFF);
747 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000748 if (f->size >= 4)
749 return PyLong_FromUnsignedLong(x);
750 else
751 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000752}
753
Guido van Rossum74679b41997-01-02 22:21:36 +0000754static PyObject *
Tim Peters7a3bfc32001-06-12 01:22:22 +0000755lu_longlong(const char *p, const formatdef *f)
756{
757 return _PyLong_FromByteArray((const unsigned char *)p,
758 8,
759 1, /* little-endian */
760 1 /* signed */);
761}
762
763static PyObject *
764lu_ulonglong(const char *p, const formatdef *f)
765{
766 return _PyLong_FromByteArray((const unsigned char *)p,
767 8,
768 1, /* little-endian */
769 0 /* signed */);
770}
771
772static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000773lu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000774{
Tim Peters9905b942003-03-20 20:53:32 +0000775 return unpack_float(p, 1);
Guido van Rossum74679b41997-01-02 22:21:36 +0000776}
777
778static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000779lu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000780{
Tim Peters9905b942003-03-20 20:53:32 +0000781 return unpack_double(p, 1);
Guido van Rossum74679b41997-01-02 22:21:36 +0000782}
783
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000784static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000785lp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000786{
787 long x;
788 int i;
789 if (get_long(v, &x) < 0)
790 return -1;
791 i = f->size;
792 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000793 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000794 x >>= 8;
795 } while (--i > 0);
796 return 0;
797}
798
Guido van Rossum60c50611996-12-31 16:29:52 +0000799static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000800lp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000801{
802 unsigned long x;
803 int i;
804 if (get_ulong(v, &x) < 0)
805 return -1;
806 i = f->size;
807 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000808 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000809 x >>= 8;
810 } while (--i > 0);
811 return 0;
812}
813
Guido van Rossum74679b41997-01-02 22:21:36 +0000814static int
Tim Peters7a3bfc32001-06-12 01:22:22 +0000815lp_longlong(char *p, PyObject *v, const formatdef *f)
816{
817 int res;
818 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000819 if (v == NULL)
820 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000821 res = _PyLong_AsByteArray((PyLongObject*)v,
822 (unsigned char *)p,
823 8,
824 1, /* little_endian */
825 1 /* signed */);
826 Py_DECREF(v);
827 return res;
828}
829
830static int
831lp_ulonglong(char *p, PyObject *v, const formatdef *f)
832{
833 int res;
834 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000835 if (v == NULL)
836 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000837 res = _PyLong_AsByteArray((PyLongObject*)v,
838 (unsigned char *)p,
839 8,
840 1, /* little_endian */
841 0 /* signed */);
842 Py_DECREF(v);
843 return res;
844}
845
846static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000847lp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000848{
849 double x = PyFloat_AsDouble(v);
850 if (x == -1 && PyErr_Occurred()) {
851 PyErr_SetString(StructError,
852 "required argument is not a float");
853 return -1;
854 }
Tim Peters9905b942003-03-20 20:53:32 +0000855 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
Guido van Rossum74679b41997-01-02 22:21:36 +0000856}
857
858static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000859lp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000860{
861 double x = PyFloat_AsDouble(v);
862 if (x == -1 && PyErr_Occurred()) {
863 PyErr_SetString(StructError,
864 "required argument is not a float");
865 return -1;
866 }
Tim Peters9905b942003-03-20 20:53:32 +0000867 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
Guido van Rossum74679b41997-01-02 22:21:36 +0000868}
869
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000870static formatdef lilendian_table[] = {
871 {'x', 1, 0, NULL},
872 {'b', 1, 0, lu_int, lp_int},
873 {'B', 1, 0, lu_uint, lp_int},
874 {'c', 1, 0, nu_char, np_char},
875 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000876 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000877 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000878 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000879 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000880 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000881 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000882 {'L', 4, 0, lu_uint, lp_uint},
Tim Peters7a3bfc32001-06-12 01:22:22 +0000883 {'q', 8, 0, lu_longlong, lp_longlong},
884 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
Guido van Rossum74679b41997-01-02 22:21:36 +0000885 {'f', 4, 0, lu_float, lp_float},
886 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000887 {0}
888};
889
890
891static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000892whichtable(char **pfmt)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000893{
894 const char *fmt = (*pfmt)++; /* May be backed out of later */
895 switch (*fmt) {
896 case '<':
897 return lilendian_table;
898 case '>':
899 case '!': /* Network byte order is big-endian */
900 return bigendian_table;
901 case '=': { /* Host byte order -- different from native in aligment! */
902 int n = 1;
903 char *p = (char *) &n;
904 if (*p == 1)
905 return lilendian_table;
906 else
907 return bigendian_table;
908 }
909 default:
910 --*pfmt; /* Back out of pointer increment */
911 /* Fall through */
912 case '@':
913 return native_table;
914 }
915}
916
917
918/* Get the table entry for a format code */
919
920static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000921getentry(int c, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000922{
923 for (; f->format != '\0'; f++) {
924 if (f->format == c) {
925 return f;
926 }
927 }
928 PyErr_SetString(StructError, "bad char in struct format");
929 return NULL;
930}
931
932
Guido van Rossum02975121992-08-17 08:55:12 +0000933/* Align a size according to a format code */
934
935static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000936align(int size, int c, const formatdef *e)
Guido van Rossum02975121992-08-17 08:55:12 +0000937{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000938 if (e->format == c) {
939 if (e->alignment) {
940 size = ((size + e->alignment - 1)
941 / e->alignment)
942 * e->alignment;
943 }
Guido van Rossum02975121992-08-17 08:55:12 +0000944 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000945 return size;
Guido van Rossum02975121992-08-17 08:55:12 +0000946}
947
948
949/* calculate the size of a format string */
950
951static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000952calcsize(const char *fmt, const formatdef *f)
Guido van Rossum02975121992-08-17 08:55:12 +0000953{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000954 const formatdef *e;
955 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +0000956 char c;
957 int size, num, itemsize, x;
958
959 s = fmt;
960 size = 0;
961 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +0000962 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +0000963 continue;
Guido van Rossum02975121992-08-17 08:55:12 +0000964 if ('0' <= c && c <= '9') {
965 num = c - '0';
966 while ('0' <= (c = *s++) && c <= '9') {
967 x = num*10 + (c - '0');
968 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000969 PyErr_SetString(
970 StructError,
971 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +0000972 return -1;
973 }
974 num = x;
975 }
976 if (c == '\0')
977 break;
978 }
979 else
980 num = 1;
Tim Peters2d4e0772001-06-11 16:57:33 +0000981
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000982 e = getentry(c, f);
983 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +0000984 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000985 itemsize = e->size;
986 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +0000987 x = num * itemsize;
988 size += x;
989 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +0000990 PyErr_SetString(StructError,
Guido van Rossum960bc542002-09-03 18:42:21 +0000991 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000992 return -1;
993 }
Guido van Rossum02975121992-08-17 08:55:12 +0000994 }
995
996 return size;
997}
998
999
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001000PyDoc_STRVAR(calcsize__doc__,
1001"calcsize(fmt) -> int\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001002Return size of C struct described by format string fmt.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001003See struct.__doc__ for more on format strings.");
Guido van Rossum02975121992-08-17 08:55:12 +00001004
Barry Warsaw30695fa1996-12-12 23:32:31 +00001005static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001006struct_calcsize(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001007{
1008 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001009 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001010 int size;
1011
Guido van Rossum43713e52000-02-29 13:59:29 +00001012 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001013 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001014 f = whichtable(&fmt);
1015 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001016 if (size < 0)
1017 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001018 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001019}
1020
1021
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001022PyDoc_STRVAR(pack__doc__,
1023"pack(fmt, v1, v2, ...) -> string\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001024Return string containing values v1, v2, ... packed according to fmt.\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001025See struct.__doc__ for more on format strings.");
Guido van Rossum02975121992-08-17 08:55:12 +00001026
Barry Warsaw30695fa1996-12-12 23:32:31 +00001027static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001028struct_pack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001029{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001030 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001031 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001032 char *fmt;
1033 int size, num;
1034 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001035 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001036 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001037
Barry Warsaw30695fa1996-12-12 23:32:31 +00001038 if (args == NULL || !PyTuple_Check(args) ||
1039 (n = PyTuple_Size(args)) < 1)
Guido van Rossum960bc542002-09-03 18:42:21 +00001040 {
Tim Peters2d4e0772001-06-11 16:57:33 +00001041 PyErr_SetString(PyExc_TypeError,
Fred Drake137507e2000-06-01 02:02:46 +00001042 "struct.pack requires at least one argument");
Guido van Rossum02975121992-08-17 08:55:12 +00001043 return NULL;
1044 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001045 format = PyTuple_GetItem(args, 0);
Neal Norwitz187ae562002-04-02 18:17:57 +00001046 fmt = PyString_AsString(format);
1047 if (!fmt)
Guido van Rossum02975121992-08-17 08:55:12 +00001048 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001049 f = whichtable(&fmt);
1050 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001051 if (size < 0)
1052 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001053 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001054 if (result == NULL)
1055 return NULL;
1056
1057 s = fmt;
1058 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001059 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001060
1061 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001062 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001063 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001064 if ('0' <= c && c <= '9') {
1065 num = c - '0';
1066 while ('0' <= (c = *s++) && c <= '9')
1067 num = num*10 + (c - '0');
1068 if (c == '\0')
1069 break;
1070 }
1071 else
1072 num = 1;
1073
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001074 e = getentry(c, f);
1075 if (e == NULL)
1076 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001077 nres = restart + align((int)(res-restart), c, e);
1078 /* Fill padd bytes with zeros */
1079 while (res < nres)
1080 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001081 if (num == 0 && c != 's')
1082 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001083 do {
1084 if (c == 'x') {
1085 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001086 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001087 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001088 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001089 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001090 if (i >= n) {
1091 PyErr_SetString(StructError,
1092 "insufficient arguments to pack");
1093 goto fail;
1094 }
1095 v = PyTuple_GetItem(args, i++);
1096 if (v == NULL)
1097 goto fail;
1098 if (c == 's') {
1099 /* num is string size, not repeat count */
1100 int n;
1101 if (!PyString_Check(v)) {
1102 PyErr_SetString(StructError,
1103 "argument for 's' must be a string");
1104 goto fail;
1105 }
1106 n = PyString_Size(v);
1107 if (n > num)
1108 n = num;
1109 if (n > 0)
1110 memcpy(res, PyString_AsString(v), n);
1111 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001112 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001113 res += num;
1114 break;
1115 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001116 else if (c == 'p') {
1117 /* num is string size + 1,
1118 to fit in the count byte */
1119 int n;
1120 num--; /* now num is max string size */
1121 if (!PyString_Check(v)) {
1122 PyErr_SetString(StructError,
1123 "argument for 'p' must be a string");
1124 goto fail;
1125 }
1126 n = PyString_Size(v);
1127 if (n > num)
1128 n = num;
1129 if (n > 0)
1130 memcpy(res+1, PyString_AsString(v), n);
1131 if (n < num)
1132 /* no real need, just to be nice */
1133 memset(res+1+n, '\0', num-n);
Tim Peters0891ac02001-09-15 02:35:15 +00001134 if (n > 255)
1135 n = 255;
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001136 *res++ = n; /* store the length byte */
1137 res += num;
1138 break;
1139 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001140 else {
1141 if (e->pack(res, v, e) < 0)
1142 goto fail;
1143 res += e->size;
1144 }
1145 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001146 }
1147
1148 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001149 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001150 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001151 goto fail;
1152 }
1153
1154 return result;
1155
1156 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001157 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001158 return NULL;
1159}
1160
1161
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001162PyDoc_STRVAR(unpack__doc__,
1163"unpack(fmt, string) -> (v1, v2, ...)\n\
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001164Unpack the string, containing packed C structure data, according\n\
1165to fmt. Requires len(string)==calcsize(fmt).\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001166See struct.__doc__ for more on format strings.");
Guido van Rossum02975121992-08-17 08:55:12 +00001167
Barry Warsaw30695fa1996-12-12 23:32:31 +00001168static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001169struct_unpack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001170{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001171 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001172 char *str, *start, *fmt, *s;
1173 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001174 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001175 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001176
Guido van Rossum43713e52000-02-29 13:59:29 +00001177 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001178 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001179 f = whichtable(&fmt);
1180 size = calcsize(fmt, f);
1181 if (size < 0)
1182 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001183 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001184 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001185 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001186 return NULL;
1187 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001188 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001189 if (res == NULL)
1190 return NULL;
1191 str = start;
1192 s = fmt;
1193 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001194 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001195 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001196 if ('0' <= c && c <= '9') {
1197 num = c - '0';
1198 while ('0' <= (c = *s++) && c <= '9')
1199 num = num*10 + (c - '0');
1200 if (c == '\0')
1201 break;
1202 }
1203 else
1204 num = 1;
1205
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001206 e = getentry(c, f);
1207 if (e == NULL)
1208 goto fail;
1209 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001210 if (num == 0 && c != 's')
1211 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001212
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001213 do {
1214 if (c == 'x') {
1215 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001216 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001217 }
1218 if (c == 's') {
1219 /* num is string size, not repeat count */
1220 v = PyString_FromStringAndSize(str, num);
1221 if (v == NULL)
1222 goto fail;
1223 str += num;
1224 num = 0;
1225 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001226 else if (c == 'p') {
1227 /* num is string buffer size,
1228 not repeat count */
1229 int n = *(unsigned char*)str;
1230 /* first byte (unsigned) is string size */
1231 if (n >= num)
1232 n = num-1;
1233 v = PyString_FromStringAndSize(str+1, n);
1234 if (v == NULL)
1235 goto fail;
1236 str += num;
1237 num = 0;
1238 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001239 else {
1240 v = e->unpack(str, e);
1241 if (v == NULL)
1242 goto fail;
1243 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001244 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001245 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001246 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001247 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001248 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001249 }
1250
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001251 v = PyList_AsTuple(res);
1252 Py_DECREF(res);
1253 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001254
1255 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001256 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001257 return NULL;
1258}
1259
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001260
Guido van Rossum02975121992-08-17 08:55:12 +00001261/* List of functions */
1262
Barry Warsaw30695fa1996-12-12 23:32:31 +00001263static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001264 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1265 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1266 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001267 {NULL, NULL} /* sentinel */
1268};
1269
1270
1271/* Module initialization */
1272
Mark Hammondfe51c6d2002-08-02 02:27:13 +00001273PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001274initstruct(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001275{
Fred Drake78f6c862002-02-14 07:11:23 +00001276 PyObject *m;
Guido van Rossum02975121992-08-17 08:55:12 +00001277
1278 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001279 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1280 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001281
1282 /* Add some symbolic constants to the module */
Fred Drake78f6c862002-02-14 07:11:23 +00001283 if (StructError == NULL) {
1284 StructError = PyErr_NewException("struct.error", NULL, NULL);
1285 if (StructError == NULL)
1286 return;
1287 }
1288 Py_INCREF(StructError);
Fred Drake2eeec9b2002-02-14 07:16:30 +00001289 PyModule_AddObject(m, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001290}