blob: 4a8886f8be9ac0e132e79187775c677122e36605 [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001
2/* struct module -- pack values into and (out of) strings */
3
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00004/* New version supporting byte order, alignment and size options,
5 character strings, and unsigned numbers */
6
Guido van Rossum414fd481997-12-19 04:24:24 +00007static char struct__doc__[] = "\
8Functions to convert between Python values and C structs.\n\
9Python strings are used to hold the data representing the C struct\n\
10and also as format strings to describe the layout of data in the C struct.\n\
11\n\
Tim Petersbe800852001-06-11 16:45:33 +000012The optional first format char indicates byte order, size and alignment:\n\
13 @: native order, size & alignment (default)\n\
14 =: native order, std. size & alignment\n\
15 <: little-endian, std. size & alignment\n\
16 >: big-endian, std. size & alignment\n\
17 !: same as >\n\
Guido van Rossum414fd481997-12-19 04:24:24 +000018\n\
19The remaining chars indicate types of args and must match exactly;\n\
20these can be preceded by a decimal repeat count:\n\
21 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
22 h:short; H:unsigned short; i:int; I:unsigned int;\n\
23 l:long; L:unsigned long; f:float; d:double.\n\
24Special cases (preceding decimal count indicates length):\n\
Tim Peters7b9542a2001-06-10 23:40:19 +000025 s:string (array of char); p: pascal string (with count byte).\n\
Guido van Rossum78694d91998-09-18 14:14:13 +000026Special case (only available in native format):\n\
27 P:an integer type that is wide enough to hold a pointer.\n\
Tim Peters7b9542a2001-06-10 23:40:19 +000028Special case (not in native mode unless 'long long' in platform C):\n\
29 q:long long; Q:unsigned long long\n\
Guido van Rossum414fd481997-12-19 04:24:24 +000030Whitespace between formats is ignored.\n\
31\n\
32The variable struct.error is an exception raised on errors.";
33
Barry Warsaw30695fa1996-12-12 23:32:31 +000034#include "Python.h"
Guido van Rossum02975121992-08-17 08:55:12 +000035
Guido van Rossume20aef51997-08-26 20:39:54 +000036#include <ctype.h>
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000037
38
39/* Exception */
40
Barry Warsaw30695fa1996-12-12 23:32:31 +000041static PyObject *StructError;
Guido van Rossum02975121992-08-17 08:55:12 +000042
43
44/* Define various structs to figure out the alignments of types */
45
Jack Jansen971e1df1995-02-02 14:29:10 +000046#ifdef __MWERKS__
47/*
48** XXXX We have a problem here. There are no unique alignment rules
Tim Peters2d4e0772001-06-11 16:57:33 +000049** on the PowerPC mac.
Jack Jansen971e1df1995-02-02 14:29:10 +000050*/
51#ifdef __powerc
52#pragma options align=mac68k
53#endif
54#endif /* __MWERKS__ */
55
Guido van Rossum02975121992-08-17 08:55:12 +000056typedef struct { char c; short x; } s_short;
57typedef struct { char c; int x; } s_int;
58typedef struct { char c; long x; } s_long;
59typedef struct { char c; float x; } s_float;
60typedef struct { char c; double x; } s_double;
Guido van Rossum78694d91998-09-18 14:14:13 +000061typedef struct { char c; void *x; } s_void_p;
Guido van Rossum02975121992-08-17 08:55:12 +000062
63#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
64#define INT_ALIGN (sizeof(s_int) - sizeof(int))
65#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
66#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
67#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
Guido van Rossum78694d91998-09-18 14:14:13 +000068#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void *))
Guido van Rossum02975121992-08-17 08:55:12 +000069
Tim Peters7b9542a2001-06-10 23:40:19 +000070/* We can't support q and Q in native mode unless the compiler does;
71 in std mode, they're 8 bytes on all platforms. */
72#ifdef HAVE_LONG_LONG
73typedef struct { char c; LONG_LONG x; } s_long_long;
74#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(LONG_LONG))
Tim Peters7b9542a2001-06-10 23:40:19 +000075#endif
76
Martin v. Löwis2af72d52000-09-15 08:10:33 +000077#define STRINGIFY(x) #x
78
Jack Jansen971e1df1995-02-02 14:29:10 +000079#ifdef __powerc
80#pragma options align=reset
81#endif
82
Tim Peters7a3bfc32001-06-12 01:22:22 +000083/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
84
85static PyObject *
86get_pylong(PyObject *v)
87{
88 PyNumberMethods *m;
89
90 assert(v != NULL);
91 if (PyInt_Check(v))
92 return PyLong_FromLong(PyInt_AS_LONG(v));
93 if (PyLong_Check(v)) {
94 Py_INCREF(v);
95 return v;
96 }
97 m = v->ob_type->tp_as_number;
98 if (m != NULL && m->nb_long != NULL) {
99 v = m->nb_long(v);
100 if (v == NULL)
101 return NULL;
102 if (PyLong_Check(v))
103 return v;
104 Py_DECREF(v);
105 }
106 PyErr_SetString(StructError,
107 "cannot convert argument to long");
108 return NULL;
109}
110
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000111/* Helper routine to get a Python integer and raise the appropriate error
112 if it isn't one */
113
114static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000115get_long(PyObject *v, long *p)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000116{
117 long x = PyInt_AsLong(v);
118 if (x == -1 && PyErr_Occurred()) {
Fred Draked3dbb381998-05-28 04:35:49 +0000119 if (PyErr_ExceptionMatches(PyExc_TypeError))
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000120 PyErr_SetString(StructError,
121 "required argument is not an integer");
122 return -1;
123 }
124 *p = x;
125 return 0;
126}
127
128
Guido van Rossum60c50611996-12-31 16:29:52 +0000129/* Same, but handling unsigned long */
130
131static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000132get_ulong(PyObject *v, unsigned long *p)
Guido van Rossum60c50611996-12-31 16:29:52 +0000133{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000134 if (PyLong_Check(v)) {
135 unsigned long x = PyLong_AsUnsignedLong(v);
136 if (x == (unsigned long)(-1) && PyErr_Occurred())
Guido van Rossum60c50611996-12-31 16:29:52 +0000137 return -1;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000138 *p = x;
139 return 0;
Guido van Rossum60c50611996-12-31 16:29:52 +0000140 }
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000141 else {
142 return get_long(v, (long *)p);
143 }
Guido van Rossum60c50611996-12-31 16:29:52 +0000144}
145
Tim Peters7b9542a2001-06-10 23:40:19 +0000146#ifdef HAVE_LONG_LONG
147
148/* Same, but handling native long long. */
149
150static int
151get_longlong(PyObject *v, LONG_LONG *p)
152{
153 LONG_LONG x;
Tim Peters7b9542a2001-06-10 23:40:19 +0000154
Tim Peters7a3bfc32001-06-12 01:22:22 +0000155 v = get_pylong(v);
156 if (v == NULL)
157 return -1;
Tim Peters7b9542a2001-06-10 23:40:19 +0000158 assert(PyLong_Check(v));
159 x = PyLong_AsLongLong(v);
Tim Peters7a3bfc32001-06-12 01:22:22 +0000160 Py_DECREF(v);
Tim Peters7b9542a2001-06-10 23:40:19 +0000161 if (x == (LONG_LONG)-1 && PyErr_Occurred())
162 return -1;
163 *p = x;
164 return 0;
165}
166
167/* Same, but handling native unsigned long long. */
168
169static int
170get_ulonglong(PyObject *v, unsigned LONG_LONG *p)
171{
172 unsigned LONG_LONG x;
Tim Peters7b9542a2001-06-10 23:40:19 +0000173
Tim Peters7a3bfc32001-06-12 01:22:22 +0000174 v = get_pylong(v);
175 if (v == NULL)
176 return -1;
Tim Peters7b9542a2001-06-10 23:40:19 +0000177 assert(PyLong_Check(v));
178 x = PyLong_AsUnsignedLongLong(v);
Tim Peters7a3bfc32001-06-12 01:22:22 +0000179 Py_DECREF(v);
Tim Peters7b9542a2001-06-10 23:40:19 +0000180 if (x == (unsigned LONG_LONG)-1 && PyErr_Occurred())
181 return -1;
182 *p = x;
183 return 0;
184}
185
186#endif
Guido van Rossum60c50611996-12-31 16:29:52 +0000187
Guido van Rossum74679b41997-01-02 22:21:36 +0000188/* Floating point helpers */
189
190/* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
191 Point Arithmetic). See the following URL:
192 http://www.psc.edu/general/software/packages/ieee/ieee.html */
193
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000194/* XXX Inf/NaN are not handled quite right (but underflow is!) */
Guido van Rossum74679b41997-01-02 22:21:36 +0000195
196static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000197pack_float(double x, /* The number to pack */
198 char *p, /* Where to pack the high order byte */
199 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000200{
201 int s;
202 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000203 double f;
204 long fbits;
Guido van Rossum74679b41997-01-02 22:21:36 +0000205
206 if (x < 0) {
207 s = 1;
208 x = -x;
209 }
210 else
211 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000212
213 f = frexp(x, &e);
214
215 /* Normalize f to be in the range [1.0, 2.0) */
216 if (0.5 <= f && f < 1.0) {
217 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000218 e--;
219 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000220 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000221 e = 0;
222 }
223 else {
224 PyErr_SetString(PyExc_SystemError,
225 "frexp() result out of range");
226 return -1;
227 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000228
229 if (e >= 128) {
230 /* XXX 128 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000231 PyErr_SetString(PyExc_OverflowError,
232 "float too large to pack with f format");
233 return -1;
234 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000235 else if (e < -126) {
236 /* Gradual underflow */
237 f = ldexp(f, 126 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000238 e = 0;
239 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000240 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000241 e += 127;
242 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000243 }
244
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000245 f *= 8388608.0; /* 2**23 */
246 fbits = (long) floor(f + 0.5); /* Round */
247
Guido van Rossum74679b41997-01-02 22:21:36 +0000248 /* First byte */
249 *p = (s<<7) | (e>>1);
250 p += incr;
251
252 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000253 *p = (char) (((e&1)<<7) | (fbits>>16));
Guido van Rossum74679b41997-01-02 22:21:36 +0000254 p += incr;
255
256 /* Third byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000257 *p = (fbits>>8) & 0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000258 p += incr;
259
260 /* Fourth byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000261 *p = fbits&0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000262
263 /* Done */
264 return 0;
265}
266
267static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000268pack_double(double x, /* The number to pack */
269 char *p, /* Where to pack the high order byte */
270 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000271{
272 int s;
273 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000274 double f;
Guido van Rossum74679b41997-01-02 22:21:36 +0000275 long fhi, flo;
276
277 if (x < 0) {
278 s = 1;
279 x = -x;
280 }
281 else
282 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000283
284 f = frexp(x, &e);
285
286 /* Normalize f to be in the range [1.0, 2.0) */
287 if (0.5 <= f && f < 1.0) {
288 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000289 e--;
290 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000291 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000292 e = 0;
293 }
294 else {
295 PyErr_SetString(PyExc_SystemError,
296 "frexp() result out of range");
297 return -1;
298 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000299
300 if (e >= 1024) {
301 /* XXX 1024 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000302 PyErr_SetString(PyExc_OverflowError,
303 "float too large to pack with d format");
304 return -1;
305 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000306 else if (e < -1022) {
307 /* Gradual underflow */
308 f = ldexp(f, 1022 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000309 e = 0;
310 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000311 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000312 e += 1023;
313 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000314 }
315
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000316 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
317 f *= 268435456.0; /* 2**28 */
318 fhi = (long) floor(f); /* Truncate */
319 f -= (double)fhi;
320 f *= 16777216.0; /* 2**24 */
321 flo = (long) floor(f + 0.5); /* Round */
322
Guido van Rossum74679b41997-01-02 22:21:36 +0000323 /* First byte */
324 *p = (s<<7) | (e>>4);
325 p += incr;
326
327 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000328 *p = (char) (((e&0xF)<<4) | (fhi>>24));
Guido van Rossum74679b41997-01-02 22:21:36 +0000329 p += incr;
330
331 /* Third byte */
332 *p = (fhi>>16) & 0xFF;
333 p += incr;
334
335 /* Fourth byte */
336 *p = (fhi>>8) & 0xFF;
337 p += incr;
338
339 /* Fifth byte */
340 *p = fhi & 0xFF;
341 p += incr;
342
343 /* Sixth byte */
344 *p = (flo>>16) & 0xFF;
345 p += incr;
346
347 /* Seventh byte */
348 *p = (flo>>8) & 0xFF;
349 p += incr;
350
351 /* Eighth byte */
352 *p = flo & 0xFF;
353 p += incr;
354
355 /* Done */
356 return 0;
357}
358
359static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000360unpack_float(const char *p, /* Where the high order byte is */
361 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000362{
363 int s;
364 int e;
365 long f;
366 double x;
367
368 /* First byte */
369 s = (*p>>7) & 1;
370 e = (*p & 0x7F) << 1;
371 p += incr;
372
373 /* Second byte */
374 e |= (*p>>7) & 1;
375 f = (*p & 0x7F) << 16;
376 p += incr;
377
378 /* Third byte */
379 f |= (*p & 0xFF) << 8;
380 p += incr;
381
382 /* Fourth byte */
383 f |= *p & 0xFF;
384
385 x = (double)f / 8388608.0;
386
387 /* XXX This sadly ignores Inf/NaN issues */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000388 if (e == 0)
389 e = -126;
390 else {
391 x += 1.0;
392 e -= 127;
393 }
394 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000395
396 if (s)
397 x = -x;
398
399 return PyFloat_FromDouble(x);
400}
401
402static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000403unpack_double(const char *p, /* Where the high order byte is */
404 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000405{
406 int s;
407 int e;
408 long fhi, flo;
409 double x;
410
411 /* First byte */
412 s = (*p>>7) & 1;
413 e = (*p & 0x7F) << 4;
414 p += incr;
415
416 /* Second byte */
417 e |= (*p>>4) & 0xF;
418 fhi = (*p & 0xF) << 24;
419 p += incr;
420
421 /* Third byte */
422 fhi |= (*p & 0xFF) << 16;
423 p += incr;
424
425 /* Fourth byte */
426 fhi |= (*p & 0xFF) << 8;
427 p += incr;
428
429 /* Fifth byte */
430 fhi |= *p & 0xFF;
431 p += incr;
432
433 /* Sixth byte */
434 flo = (*p & 0xFF) << 16;
435 p += incr;
436
437 /* Seventh byte */
438 flo |= (*p & 0xFF) << 8;
439 p += incr;
440
441 /* Eighth byte */
442 flo |= *p & 0xFF;
443 p += incr;
444
445 x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
446 x /= 268435456.0; /* 2**28 */
447
448 /* XXX This sadly ignores Inf/NaN */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000449 if (e == 0)
450 e = -1022;
451 else {
452 x += 1.0;
453 e -= 1023;
454 }
455 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000456
457 if (s)
458 x = -x;
459
460 return PyFloat_FromDouble(x);
461}
462
463
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000464/* The translation function for each format character is table driven */
465
466typedef struct _formatdef {
467 char format;
468 int size;
469 int alignment;
Tim Petersdbd9ba62000-07-09 03:09:57 +0000470 PyObject* (*unpack)(const char *,
471 const struct _formatdef *);
472 int (*pack)(char *, PyObject *,
473 const struct _formatdef *);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000474} formatdef;
475
Tim Peters7b9542a2001-06-10 23:40:19 +0000476/* A large number of small routines follow, with names of the form
477
478 [bln][up]_TYPE
479
480 [bln] distiguishes among big-endian, little-endian and native.
481 [pu] distiguishes between pack (to struct) and unpack (from struct).
482 TYPE is one of char, byte, ubyte, etc.
483*/
484
Tim Peters7a3bfc32001-06-12 01:22:22 +0000485/* Native mode routines. ****************************************************/
Tim Peters7b9542a2001-06-10 23:40:19 +0000486
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000487static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000488nu_char(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000489{
490 return PyString_FromStringAndSize(p, 1);
491}
492
493static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000494nu_byte(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000495{
496 return PyInt_FromLong((long) *(signed char *)p);
497}
498
499static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000500nu_ubyte(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000501{
502 return PyInt_FromLong((long) *(unsigned char *)p);
503}
504
505static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000506nu_short(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000507{
508 return PyInt_FromLong((long) *(short *)p);
509}
510
511static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000512nu_ushort(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000513{
514 return PyInt_FromLong((long) *(unsigned short *)p);
515}
516
517static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000518nu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000519{
520 return PyInt_FromLong((long) *(int *)p);
521}
522
523static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000524nu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000525{
526 unsigned int x = *(unsigned int *)p;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000527 return PyLong_FromUnsignedLong((unsigned long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000528}
529
530static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000531nu_long(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000532{
533 return PyInt_FromLong(*(long *)p);
534}
535
536static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000537nu_ulong(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000538{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000539 return PyLong_FromUnsignedLong(*(unsigned long *)p);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000540}
541
Tim Peters7b9542a2001-06-10 23:40:19 +0000542/* Native mode doesn't support q or Q unless the platform C supports
543 long long (or, on Windows, __int64). */
544
545#ifdef HAVE_LONG_LONG
546
547static PyObject *
548nu_longlong(const char *p, const formatdef *f)
549{
550 return PyLong_FromLongLong(*(LONG_LONG *)p);
551}
552
553static PyObject *
554nu_ulonglong(const char *p, const formatdef *f)
555{
556 return PyLong_FromUnsignedLongLong(*(unsigned LONG_LONG *)p);
557}
Tim Peters7b9542a2001-06-10 23:40:19 +0000558#endif
559
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000560static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000561nu_float(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000562{
563 float x;
564 memcpy((char *)&x, p, sizeof(float));
565 return PyFloat_FromDouble((double)x);
566}
567
568static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000569nu_double(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000570{
571 double x;
572 memcpy((char *)&x, p, sizeof(double));
573 return PyFloat_FromDouble(x);
574}
575
Guido van Rossum78694d91998-09-18 14:14:13 +0000576static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000577nu_void_p(const char *p, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000578{
579 return PyLong_FromVoidPtr(*(void **)p);
580}
581
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000582static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000583np_byte(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000584{
585 long x;
586 if (get_long(v, &x) < 0)
587 return -1;
Martin v. Löwis66de5492000-09-15 07:31:57 +0000588 if (x < -128 || x > 127){
589 PyErr_SetString(StructError,
590 "byte format requires -128<=number<=127");
591 return -1;
592 }
593 *p = (char)x;
594 return 0;
595}
596
597static int
598np_ubyte(char *p, PyObject *v, const formatdef *f)
599{
600 long x;
601 if (get_long(v, &x) < 0)
602 return -1;
603 if (x < 0 || x > 255){
604 PyErr_SetString(StructError,
605 "ubyte format requires 0<=number<=255");
606 return -1;
607 }
Guido van Rossum7844e381997-04-11 20:44:04 +0000608 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000609 return 0;
610}
611
612static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000613np_char(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000614{
615 if (!PyString_Check(v) || PyString_Size(v) != 1) {
616 PyErr_SetString(StructError,
617 "char format require string of length 1");
618 return -1;
619 }
620 *p = *PyString_AsString(v);
621 return 0;
622}
623
624static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000625np_short(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000626{
627 long x;
628 if (get_long(v, &x) < 0)
629 return -1;
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000630 if (x < SHRT_MIN || x > SHRT_MAX){
Martin v. Löwis66de5492000-09-15 07:31:57 +0000631 PyErr_SetString(StructError,
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000632 "short format requires " STRINGIFY(SHRT_MIN)
633 "<=number<=" STRINGIFY(SHRT_MAX));
Martin v. Löwis66de5492000-09-15 07:31:57 +0000634 return -1;
635 }
Guido van Rossum7844e381997-04-11 20:44:04 +0000636 * (short *)p = (short)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000637 return 0;
638}
639
640static int
Martin v. Löwis66de5492000-09-15 07:31:57 +0000641np_ushort(char *p, PyObject *v, const formatdef *f)
642{
643 long x;
644 if (get_long(v, &x) < 0)
645 return -1;
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000646 if (x < 0 || x > USHRT_MAX){
Martin v. Löwis66de5492000-09-15 07:31:57 +0000647 PyErr_SetString(StructError,
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000648 "short format requires 0<=number<=" STRINGIFY(USHRT_MAX));
Martin v. Löwis66de5492000-09-15 07:31:57 +0000649 return -1;
650 }
651 * (unsigned short *)p = (unsigned short)x;
652 return 0;
653}
654
655static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000656np_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000657{
658 long x;
659 if (get_long(v, &x) < 0)
660 return -1;
661 * (int *)p = x;
662 return 0;
663}
664
665static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000666np_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000667{
668 unsigned long x;
669 if (get_ulong(v, &x) < 0)
670 return -1;
671 * (unsigned int *)p = x;
672 return 0;
673}
674
675static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000676np_long(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000677{
678 long x;
679 if (get_long(v, &x) < 0)
680 return -1;
681 * (long *)p = x;
682 return 0;
683}
684
685static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000686np_ulong(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000687{
688 unsigned long x;
689 if (get_ulong(v, &x) < 0)
690 return -1;
691 * (unsigned long *)p = x;
692 return 0;
693}
694
Tim Peters7b9542a2001-06-10 23:40:19 +0000695#ifdef HAVE_LONG_LONG
696
697static int
698np_longlong(char *p, PyObject *v, const formatdef *f)
699{
700 LONG_LONG x;
701 if (get_longlong(v, &x) < 0)
702 return -1;
703 * (LONG_LONG *)p = x;
704 return 0;
705}
706
707static int
708np_ulonglong(char *p, PyObject *v, const formatdef *f)
709{
710 unsigned LONG_LONG x;
711 if (get_ulonglong(v, &x) < 0)
712 return -1;
713 * (unsigned LONG_LONG *)p = x;
714 return 0;
715}
Tim Peters7b9542a2001-06-10 23:40:19 +0000716#endif
717
Guido van Rossum60c50611996-12-31 16:29:52 +0000718static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000719np_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000720{
721 float x = (float)PyFloat_AsDouble(v);
722 if (x == -1 && PyErr_Occurred()) {
723 PyErr_SetString(StructError,
724 "required argument is not a float");
725 return -1;
726 }
727 memcpy(p, (char *)&x, sizeof(float));
728 return 0;
729}
730
731static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000732np_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000733{
734 double x = PyFloat_AsDouble(v);
735 if (x == -1 && PyErr_Occurred()) {
736 PyErr_SetString(StructError,
737 "required argument is not a float");
738 return -1;
739 }
740 memcpy(p, (char *)&x, sizeof(double));
741 return 0;
742}
743
Guido van Rossum78694d91998-09-18 14:14:13 +0000744static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000745np_void_p(char *p, PyObject *v, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000746{
747 void *x = PyLong_AsVoidPtr(v);
748 if (x == NULL && PyErr_Occurred()) {
749 /* ### hrm. PyLong_AsVoidPtr raises SystemError */
750 if (PyErr_ExceptionMatches(PyExc_TypeError))
751 PyErr_SetString(StructError,
752 "required argument is not an integer");
753 return -1;
754 }
755 *(void **)p = x;
756 return 0;
757}
758
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000759static formatdef native_table[] = {
760 {'x', sizeof(char), 0, NULL},
761 {'b', sizeof(char), 0, nu_byte, np_byte},
Martin v. Löwis66de5492000-09-15 07:31:57 +0000762 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000763 {'c', sizeof(char), 0, nu_char, np_char},
764 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000765 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000766 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
Martin v. Löwis66de5492000-09-15 07:31:57 +0000767 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000768 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000769 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000770 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000771 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000772 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
773 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
Guido van Rossum78694d91998-09-18 14:14:13 +0000774 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Tim Peters7b9542a2001-06-10 23:40:19 +0000775#ifdef HAVE_LONG_LONG
776 {'q', sizeof(LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
777 {'Q', sizeof(LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Tim Peters7b9542a2001-06-10 23:40:19 +0000778#endif
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000779 {0}
780};
781
Tim Peters7a3bfc32001-06-12 01:22:22 +0000782/* Big-endian routines. *****************************************************/
783
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000784static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000785bu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000786{
787 long x = 0;
788 int i = f->size;
789 do {
790 x = (x<<8) | (*p++ & 0xFF);
791 } while (--i > 0);
Tim Petersf0e717b2001-04-08 23:39:38 +0000792 /* Extend the sign bit. */
793 if (SIZEOF_LONG > f->size)
794 x |= -(x & (1L << (8*f->size - 1)));
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000795 return PyInt_FromLong(x);
796}
797
798static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000799bu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000800{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000801 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000802 int i = f->size;
803 do {
804 x = (x<<8) | (*p++ & 0xFF);
805 } while (--i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000806 if (f->size >= 4)
807 return PyLong_FromUnsignedLong(x);
808 else
809 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000810}
811
Guido van Rossum74679b41997-01-02 22:21:36 +0000812static PyObject *
Tim Peters7a3bfc32001-06-12 01:22:22 +0000813bu_longlong(const char *p, const formatdef *f)
814{
815 return _PyLong_FromByteArray((const unsigned char *)p,
816 8,
817 0, /* little-endian */
818 1 /* signed */);
819}
820
821static PyObject *
822bu_ulonglong(const char *p, const formatdef *f)
823{
824 return _PyLong_FromByteArray((const unsigned char *)p,
825 8,
826 0, /* little-endian */
827 0 /* signed */);
828}
829
830static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000831bu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000832{
833 return unpack_float(p, 1);
834}
835
836static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000837bu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000838{
839 return unpack_double(p, 1);
840}
841
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000842static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000843bp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000844{
845 long x;
846 int i;
847 if (get_long(v, &x) < 0)
848 return -1;
849 i = f->size;
850 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000851 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000852 x >>= 8;
853 } while (i > 0);
854 return 0;
855}
856
Guido van Rossum60c50611996-12-31 16:29:52 +0000857static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000858bp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000859{
860 unsigned long x;
861 int i;
862 if (get_ulong(v, &x) < 0)
863 return -1;
864 i = f->size;
865 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000866 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000867 x >>= 8;
868 } while (i > 0);
869 return 0;
870}
871
Guido van Rossum74679b41997-01-02 22:21:36 +0000872static int
Tim Peters7a3bfc32001-06-12 01:22:22 +0000873bp_longlong(char *p, PyObject *v, const formatdef *f)
874{
875 int res;
876 v = get_pylong(v);
877 res = _PyLong_AsByteArray((PyLongObject *)v,
878 (unsigned char *)p,
879 8,
880 0, /* little_endian */
881 1 /* signed */);
882 Py_DECREF(v);
883 return res;
884}
885
886static int
887bp_ulonglong(char *p, PyObject *v, const formatdef *f)
888{
889 int res;
890 v = get_pylong(v);
891 res = _PyLong_AsByteArray((PyLongObject *)v,
892 (unsigned char *)p,
893 8,
894 0, /* little_endian */
895 0 /* signed */);
896 Py_DECREF(v);
897 return res;
898}
899
900static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000901bp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000902{
903 double x = PyFloat_AsDouble(v);
904 if (x == -1 && PyErr_Occurred()) {
905 PyErr_SetString(StructError,
906 "required argument is not a float");
907 return -1;
908 }
909 return pack_float(x, p, 1);
910}
911
912static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000913bp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000914{
915 double x = PyFloat_AsDouble(v);
916 if (x == -1 && PyErr_Occurred()) {
917 PyErr_SetString(StructError,
918 "required argument is not a float");
919 return -1;
920 }
921 return pack_double(x, p, 1);
922}
923
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000924static formatdef bigendian_table[] = {
925 {'x', 1, 0, NULL},
926 {'b', 1, 0, bu_int, bp_int},
927 {'B', 1, 0, bu_uint, bp_int},
928 {'c', 1, 0, nu_char, np_char},
929 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000930 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000931 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000932 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000933 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000934 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000935 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000936 {'L', 4, 0, bu_uint, bp_uint},
Tim Peters7a3bfc32001-06-12 01:22:22 +0000937 {'q', 8, 0, bu_longlong, bp_longlong},
938 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
Guido van Rossum74679b41997-01-02 22:21:36 +0000939 {'f', 4, 0, bu_float, bp_float},
940 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000941 {0}
942};
943
Tim Peters7a3bfc32001-06-12 01:22:22 +0000944/* Little-endian routines. *****************************************************/
945
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000946static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000947lu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000948{
949 long x = 0;
950 int i = f->size;
951 do {
952 x = (x<<8) | (p[--i] & 0xFF);
953 } while (i > 0);
Tim Petersf0e717b2001-04-08 23:39:38 +0000954 /* Extend the sign bit. */
955 if (SIZEOF_LONG > f->size)
956 x |= -(x & (1L << (8*f->size - 1)));
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000957 return PyInt_FromLong(x);
958}
959
960static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000961lu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000962{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000963 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000964 int i = f->size;
965 do {
966 x = (x<<8) | (p[--i] & 0xFF);
967 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000968 if (f->size >= 4)
969 return PyLong_FromUnsignedLong(x);
970 else
971 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000972}
973
Guido van Rossum74679b41997-01-02 22:21:36 +0000974static PyObject *
Tim Peters7a3bfc32001-06-12 01:22:22 +0000975lu_longlong(const char *p, const formatdef *f)
976{
977 return _PyLong_FromByteArray((const unsigned char *)p,
978 8,
979 1, /* little-endian */
980 1 /* signed */);
981}
982
983static PyObject *
984lu_ulonglong(const char *p, const formatdef *f)
985{
986 return _PyLong_FromByteArray((const unsigned char *)p,
987 8,
988 1, /* little-endian */
989 0 /* signed */);
990}
991
992static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000993lu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000994{
995 return unpack_float(p+3, -1);
996}
997
998static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000999lu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +00001000{
1001 return unpack_double(p+7, -1);
1002}
1003
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001004static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001005lp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001006{
1007 long x;
1008 int i;
1009 if (get_long(v, &x) < 0)
1010 return -1;
1011 i = f->size;
1012 do {
Guido van Rossum7844e381997-04-11 20:44:04 +00001013 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001014 x >>= 8;
1015 } while (--i > 0);
1016 return 0;
1017}
1018
Guido van Rossum60c50611996-12-31 16:29:52 +00001019static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001020lp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +00001021{
1022 unsigned long x;
1023 int i;
1024 if (get_ulong(v, &x) < 0)
1025 return -1;
1026 i = f->size;
1027 do {
Guido van Rossum7844e381997-04-11 20:44:04 +00001028 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +00001029 x >>= 8;
1030 } while (--i > 0);
1031 return 0;
1032}
1033
Guido van Rossum74679b41997-01-02 22:21:36 +00001034static int
Tim Peters7a3bfc32001-06-12 01:22:22 +00001035lp_longlong(char *p, PyObject *v, const formatdef *f)
1036{
1037 int res;
1038 v = get_pylong(v);
1039 res = _PyLong_AsByteArray((PyLongObject*)v,
1040 (unsigned char *)p,
1041 8,
1042 1, /* little_endian */
1043 1 /* signed */);
1044 Py_DECREF(v);
1045 return res;
1046}
1047
1048static int
1049lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1050{
1051 int res;
1052 v = get_pylong(v);
1053 res = _PyLong_AsByteArray((PyLongObject*)v,
1054 (unsigned char *)p,
1055 8,
1056 1, /* little_endian */
1057 0 /* signed */);
1058 Py_DECREF(v);
1059 return res;
1060}
1061
1062static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001063lp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +00001064{
1065 double x = PyFloat_AsDouble(v);
1066 if (x == -1 && PyErr_Occurred()) {
1067 PyErr_SetString(StructError,
1068 "required argument is not a float");
1069 return -1;
1070 }
1071 return pack_float(x, p+3, -1);
1072}
1073
1074static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001075lp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +00001076{
1077 double x = PyFloat_AsDouble(v);
1078 if (x == -1 && PyErr_Occurred()) {
1079 PyErr_SetString(StructError,
1080 "required argument is not a float");
1081 return -1;
1082 }
1083 return pack_double(x, p+7, -1);
1084}
1085
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001086static formatdef lilendian_table[] = {
1087 {'x', 1, 0, NULL},
1088 {'b', 1, 0, lu_int, lp_int},
1089 {'B', 1, 0, lu_uint, lp_int},
1090 {'c', 1, 0, nu_char, np_char},
1091 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001092 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001093 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +00001094 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001095 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +00001096 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001097 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +00001098 {'L', 4, 0, lu_uint, lp_uint},
Tim Peters7a3bfc32001-06-12 01:22:22 +00001099 {'q', 8, 0, lu_longlong, lp_longlong},
1100 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
Guido van Rossum74679b41997-01-02 22:21:36 +00001101 {'f', 4, 0, lu_float, lp_float},
1102 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001103 {0}
1104};
1105
1106
1107static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001108whichtable(char **pfmt)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001109{
1110 const char *fmt = (*pfmt)++; /* May be backed out of later */
1111 switch (*fmt) {
1112 case '<':
1113 return lilendian_table;
1114 case '>':
1115 case '!': /* Network byte order is big-endian */
1116 return bigendian_table;
1117 case '=': { /* Host byte order -- different from native in aligment! */
1118 int n = 1;
1119 char *p = (char *) &n;
1120 if (*p == 1)
1121 return lilendian_table;
1122 else
1123 return bigendian_table;
1124 }
1125 default:
1126 --*pfmt; /* Back out of pointer increment */
1127 /* Fall through */
1128 case '@':
1129 return native_table;
1130 }
1131}
1132
1133
1134/* Get the table entry for a format code */
1135
1136static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001137getentry(int c, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001138{
1139 for (; f->format != '\0'; f++) {
1140 if (f->format == c) {
1141 return f;
1142 }
1143 }
1144 PyErr_SetString(StructError, "bad char in struct format");
1145 return NULL;
1146}
1147
1148
Guido van Rossum02975121992-08-17 08:55:12 +00001149/* Align a size according to a format code */
1150
1151static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001152align(int size, int c, const formatdef *e)
Guido van Rossum02975121992-08-17 08:55:12 +00001153{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001154 if (e->format == c) {
1155 if (e->alignment) {
1156 size = ((size + e->alignment - 1)
1157 / e->alignment)
1158 * e->alignment;
1159 }
Guido van Rossum02975121992-08-17 08:55:12 +00001160 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001161 return size;
Guido van Rossum02975121992-08-17 08:55:12 +00001162}
1163
1164
1165/* calculate the size of a format string */
1166
1167static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001168calcsize(const char *fmt, const formatdef *f)
Guido van Rossum02975121992-08-17 08:55:12 +00001169{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001170 const formatdef *e;
1171 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +00001172 char c;
1173 int size, num, itemsize, x;
1174
1175 s = fmt;
1176 size = 0;
1177 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001178 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001179 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001180 if ('0' <= c && c <= '9') {
1181 num = c - '0';
1182 while ('0' <= (c = *s++) && c <= '9') {
1183 x = num*10 + (c - '0');
1184 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001185 PyErr_SetString(
1186 StructError,
1187 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +00001188 return -1;
1189 }
1190 num = x;
1191 }
1192 if (c == '\0')
1193 break;
1194 }
1195 else
1196 num = 1;
Tim Peters2d4e0772001-06-11 16:57:33 +00001197
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001198 e = getentry(c, f);
1199 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +00001200 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001201 itemsize = e->size;
1202 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +00001203 x = num * itemsize;
1204 size += x;
1205 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001206 PyErr_SetString(StructError,
1207 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +00001208 return -1;
1209 }
Guido van Rossum02975121992-08-17 08:55:12 +00001210 }
1211
1212 return size;
1213}
1214
1215
Guido van Rossum414fd481997-12-19 04:24:24 +00001216static char calcsize__doc__[] = "\
1217calcsize(fmt) -> int\n\
1218Return size of C struct described by format string fmt.\n\
1219See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001220
Barry Warsaw30695fa1996-12-12 23:32:31 +00001221static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001222struct_calcsize(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001223{
1224 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001225 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001226 int size;
1227
Guido van Rossum43713e52000-02-29 13:59:29 +00001228 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001229 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001230 f = whichtable(&fmt);
1231 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001232 if (size < 0)
1233 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001234 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001235}
1236
1237
Guido van Rossum414fd481997-12-19 04:24:24 +00001238static char pack__doc__[] = "\
1239pack(fmt, v1, v2, ...) -> string\n\
1240Return string containing values v1, v2, ... packed according to fmt.\n\
1241See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001242
Barry Warsaw30695fa1996-12-12 23:32:31 +00001243static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001244struct_pack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001245{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001246 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001247 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001248 char *fmt;
1249 int size, num;
1250 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001251 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001252 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001253
Barry Warsaw30695fa1996-12-12 23:32:31 +00001254 if (args == NULL || !PyTuple_Check(args) ||
1255 (n = PyTuple_Size(args)) < 1)
1256 {
Tim Peters2d4e0772001-06-11 16:57:33 +00001257 PyErr_SetString(PyExc_TypeError,
Fred Drake137507e2000-06-01 02:02:46 +00001258 "struct.pack requires at least one argument");
Guido van Rossum02975121992-08-17 08:55:12 +00001259 return NULL;
1260 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001261 format = PyTuple_GetItem(args, 0);
1262 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001263 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001264 f = whichtable(&fmt);
1265 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001266 if (size < 0)
1267 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001268 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001269 if (result == NULL)
1270 return NULL;
1271
1272 s = fmt;
1273 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001274 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001275
1276 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001277 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001278 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001279 if ('0' <= c && c <= '9') {
1280 num = c - '0';
1281 while ('0' <= (c = *s++) && c <= '9')
1282 num = num*10 + (c - '0');
1283 if (c == '\0')
1284 break;
1285 }
1286 else
1287 num = 1;
1288
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001289 e = getentry(c, f);
1290 if (e == NULL)
1291 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001292 nres = restart + align((int)(res-restart), c, e);
1293 /* Fill padd bytes with zeros */
1294 while (res < nres)
1295 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001296 if (num == 0 && c != 's')
1297 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001298 do {
1299 if (c == 'x') {
1300 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001301 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001302 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001303 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001304 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001305 if (i >= n) {
1306 PyErr_SetString(StructError,
1307 "insufficient arguments to pack");
1308 goto fail;
1309 }
1310 v = PyTuple_GetItem(args, i++);
1311 if (v == NULL)
1312 goto fail;
1313 if (c == 's') {
1314 /* num is string size, not repeat count */
1315 int n;
1316 if (!PyString_Check(v)) {
1317 PyErr_SetString(StructError,
1318 "argument for 's' must be a string");
1319 goto fail;
1320 }
1321 n = PyString_Size(v);
1322 if (n > num)
1323 n = num;
1324 if (n > 0)
1325 memcpy(res, PyString_AsString(v), n);
1326 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001327 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001328 res += num;
1329 break;
1330 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001331 else if (c == 'p') {
1332 /* num is string size + 1,
1333 to fit in the count byte */
1334 int n;
1335 num--; /* now num is max string size */
1336 if (!PyString_Check(v)) {
1337 PyErr_SetString(StructError,
1338 "argument for 'p' must be a string");
1339 goto fail;
1340 }
1341 n = PyString_Size(v);
1342 if (n > num)
1343 n = num;
1344 if (n > 0)
1345 memcpy(res+1, PyString_AsString(v), n);
1346 if (n < num)
1347 /* no real need, just to be nice */
1348 memset(res+1+n, '\0', num-n);
1349 *res++ = n; /* store the length byte */
1350 res += num;
1351 break;
1352 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001353 else {
1354 if (e->pack(res, v, e) < 0)
1355 goto fail;
1356 res += e->size;
1357 }
1358 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001359 }
1360
1361 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001362 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001363 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001364 goto fail;
1365 }
1366
1367 return result;
1368
1369 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001370 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001371 return NULL;
1372}
1373
1374
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001375static char unpack__doc__[] = "\
1376unpack(fmt, string) -> (v1, v2, ...)\n\
1377Unpack the string, containing packed C structure data, according\n\
1378to fmt. Requires len(string)==calcsize(fmt).\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001379See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001380
Barry Warsaw30695fa1996-12-12 23:32:31 +00001381static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001382struct_unpack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001383{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001384 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001385 char *str, *start, *fmt, *s;
1386 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001387 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001388 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001389
Guido van Rossum43713e52000-02-29 13:59:29 +00001390 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001391 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001392 f = whichtable(&fmt);
1393 size = calcsize(fmt, f);
1394 if (size < 0)
1395 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001396 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001397 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001398 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001399 return NULL;
1400 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001401 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001402 if (res == NULL)
1403 return NULL;
1404 str = start;
1405 s = fmt;
1406 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001407 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001408 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001409 if ('0' <= c && c <= '9') {
1410 num = c - '0';
1411 while ('0' <= (c = *s++) && c <= '9')
1412 num = num*10 + (c - '0');
1413 if (c == '\0')
1414 break;
1415 }
1416 else
1417 num = 1;
1418
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001419 e = getentry(c, f);
1420 if (e == NULL)
1421 goto fail;
1422 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001423 if (num == 0 && c != 's')
1424 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001425
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001426 do {
1427 if (c == 'x') {
1428 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001429 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001430 }
1431 if (c == 's') {
1432 /* num is string size, not repeat count */
1433 v = PyString_FromStringAndSize(str, num);
1434 if (v == NULL)
1435 goto fail;
1436 str += num;
1437 num = 0;
1438 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001439 else if (c == 'p') {
1440 /* num is string buffer size,
1441 not repeat count */
1442 int n = *(unsigned char*)str;
1443 /* first byte (unsigned) is string size */
1444 if (n >= num)
1445 n = num-1;
1446 v = PyString_FromStringAndSize(str+1, n);
1447 if (v == NULL)
1448 goto fail;
1449 str += num;
1450 num = 0;
1451 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001452 else {
1453 v = e->unpack(str, e);
1454 if (v == NULL)
1455 goto fail;
1456 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001457 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001458 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001459 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001460 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001461 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001462 }
1463
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001464 v = PyList_AsTuple(res);
1465 Py_DECREF(res);
1466 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001467
1468 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001469 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001470 return NULL;
1471}
1472
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001473
Guido van Rossum02975121992-08-17 08:55:12 +00001474/* List of functions */
1475
Barry Warsaw30695fa1996-12-12 23:32:31 +00001476static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001477 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1478 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1479 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001480 {NULL, NULL} /* sentinel */
1481};
1482
1483
1484/* Module initialization */
1485
Guido van Rossum3886bb61998-12-04 18:50:17 +00001486DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001487initstruct(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001488{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001489 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001490
1491 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001492 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1493 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001494
1495 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001496 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001497 StructError = PyErr_NewException("struct.error", NULL, NULL);
1498 if (StructError == NULL)
1499 return;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001500 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001501}