blob: 66b3ac31d9f45cf742ff0bf4dce9928445713a6b [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);
Tim Petersda9c5b32001-06-13 01:26:35 +0000877 if (v == NULL)
878 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000879 res = _PyLong_AsByteArray((PyLongObject *)v,
880 (unsigned char *)p,
881 8,
882 0, /* little_endian */
883 1 /* signed */);
884 Py_DECREF(v);
885 return res;
886}
887
888static int
889bp_ulonglong(char *p, PyObject *v, const formatdef *f)
890{
891 int res;
892 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000893 if (v == NULL)
894 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000895 res = _PyLong_AsByteArray((PyLongObject *)v,
896 (unsigned char *)p,
897 8,
898 0, /* little_endian */
899 0 /* signed */);
900 Py_DECREF(v);
901 return res;
902}
903
904static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000905bp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000906{
907 double x = PyFloat_AsDouble(v);
908 if (x == -1 && PyErr_Occurred()) {
909 PyErr_SetString(StructError,
910 "required argument is not a float");
911 return -1;
912 }
913 return pack_float(x, p, 1);
914}
915
916static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000917bp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000918{
919 double x = PyFloat_AsDouble(v);
920 if (x == -1 && PyErr_Occurred()) {
921 PyErr_SetString(StructError,
922 "required argument is not a float");
923 return -1;
924 }
925 return pack_double(x, p, 1);
926}
927
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000928static formatdef bigendian_table[] = {
929 {'x', 1, 0, NULL},
930 {'b', 1, 0, bu_int, bp_int},
931 {'B', 1, 0, bu_uint, bp_int},
932 {'c', 1, 0, nu_char, np_char},
933 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000934 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000935 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000936 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000937 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000938 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000939 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000940 {'L', 4, 0, bu_uint, bp_uint},
Tim Peters7a3bfc32001-06-12 01:22:22 +0000941 {'q', 8, 0, bu_longlong, bp_longlong},
942 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
Guido van Rossum74679b41997-01-02 22:21:36 +0000943 {'f', 4, 0, bu_float, bp_float},
944 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000945 {0}
946};
947
Tim Peters7a3bfc32001-06-12 01:22:22 +0000948/* Little-endian routines. *****************************************************/
949
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000950static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000951lu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000952{
953 long x = 0;
954 int i = f->size;
955 do {
956 x = (x<<8) | (p[--i] & 0xFF);
957 } while (i > 0);
Tim Petersf0e717b2001-04-08 23:39:38 +0000958 /* Extend the sign bit. */
959 if (SIZEOF_LONG > f->size)
960 x |= -(x & (1L << (8*f->size - 1)));
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000961 return PyInt_FromLong(x);
962}
963
964static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000965lu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000966{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000967 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000968 int i = f->size;
969 do {
970 x = (x<<8) | (p[--i] & 0xFF);
971 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000972 if (f->size >= 4)
973 return PyLong_FromUnsignedLong(x);
974 else
975 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000976}
977
Guido van Rossum74679b41997-01-02 22:21:36 +0000978static PyObject *
Tim Peters7a3bfc32001-06-12 01:22:22 +0000979lu_longlong(const char *p, const formatdef *f)
980{
981 return _PyLong_FromByteArray((const unsigned char *)p,
982 8,
983 1, /* little-endian */
984 1 /* signed */);
985}
986
987static PyObject *
988lu_ulonglong(const char *p, const formatdef *f)
989{
990 return _PyLong_FromByteArray((const unsigned char *)p,
991 8,
992 1, /* little-endian */
993 0 /* signed */);
994}
995
996static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000997lu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000998{
999 return unpack_float(p+3, -1);
1000}
1001
1002static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001003lu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +00001004{
1005 return unpack_double(p+7, -1);
1006}
1007
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001008static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001009lp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001010{
1011 long x;
1012 int i;
1013 if (get_long(v, &x) < 0)
1014 return -1;
1015 i = f->size;
1016 do {
Guido van Rossum7844e381997-04-11 20:44:04 +00001017 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001018 x >>= 8;
1019 } while (--i > 0);
1020 return 0;
1021}
1022
Guido van Rossum60c50611996-12-31 16:29:52 +00001023static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001024lp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +00001025{
1026 unsigned long x;
1027 int i;
1028 if (get_ulong(v, &x) < 0)
1029 return -1;
1030 i = f->size;
1031 do {
Guido van Rossum7844e381997-04-11 20:44:04 +00001032 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +00001033 x >>= 8;
1034 } while (--i > 0);
1035 return 0;
1036}
1037
Guido van Rossum74679b41997-01-02 22:21:36 +00001038static int
Tim Peters7a3bfc32001-06-12 01:22:22 +00001039lp_longlong(char *p, PyObject *v, const formatdef *f)
1040{
1041 int res;
1042 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +00001043 if (v == NULL)
1044 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +00001045 res = _PyLong_AsByteArray((PyLongObject*)v,
1046 (unsigned char *)p,
1047 8,
1048 1, /* little_endian */
1049 1 /* signed */);
1050 Py_DECREF(v);
1051 return res;
1052}
1053
1054static int
1055lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1056{
1057 int res;
1058 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +00001059 if (v == NULL)
1060 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +00001061 res = _PyLong_AsByteArray((PyLongObject*)v,
1062 (unsigned char *)p,
1063 8,
1064 1, /* little_endian */
1065 0 /* signed */);
1066 Py_DECREF(v);
1067 return res;
1068}
1069
1070static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001071lp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +00001072{
1073 double x = PyFloat_AsDouble(v);
1074 if (x == -1 && PyErr_Occurred()) {
1075 PyErr_SetString(StructError,
1076 "required argument is not a float");
1077 return -1;
1078 }
1079 return pack_float(x, p+3, -1);
1080}
1081
1082static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001083lp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +00001084{
1085 double x = PyFloat_AsDouble(v);
1086 if (x == -1 && PyErr_Occurred()) {
1087 PyErr_SetString(StructError,
1088 "required argument is not a float");
1089 return -1;
1090 }
1091 return pack_double(x, p+7, -1);
1092}
1093
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001094static formatdef lilendian_table[] = {
1095 {'x', 1, 0, NULL},
1096 {'b', 1, 0, lu_int, lp_int},
1097 {'B', 1, 0, lu_uint, lp_int},
1098 {'c', 1, 0, nu_char, np_char},
1099 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001100 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001101 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +00001102 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001103 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +00001104 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001105 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +00001106 {'L', 4, 0, lu_uint, lp_uint},
Tim Peters7a3bfc32001-06-12 01:22:22 +00001107 {'q', 8, 0, lu_longlong, lp_longlong},
1108 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
Guido van Rossum74679b41997-01-02 22:21:36 +00001109 {'f', 4, 0, lu_float, lp_float},
1110 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001111 {0}
1112};
1113
1114
1115static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001116whichtable(char **pfmt)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001117{
1118 const char *fmt = (*pfmt)++; /* May be backed out of later */
1119 switch (*fmt) {
1120 case '<':
1121 return lilendian_table;
1122 case '>':
1123 case '!': /* Network byte order is big-endian */
1124 return bigendian_table;
1125 case '=': { /* Host byte order -- different from native in aligment! */
1126 int n = 1;
1127 char *p = (char *) &n;
1128 if (*p == 1)
1129 return lilendian_table;
1130 else
1131 return bigendian_table;
1132 }
1133 default:
1134 --*pfmt; /* Back out of pointer increment */
1135 /* Fall through */
1136 case '@':
1137 return native_table;
1138 }
1139}
1140
1141
1142/* Get the table entry for a format code */
1143
1144static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001145getentry(int c, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001146{
1147 for (; f->format != '\0'; f++) {
1148 if (f->format == c) {
1149 return f;
1150 }
1151 }
1152 PyErr_SetString(StructError, "bad char in struct format");
1153 return NULL;
1154}
1155
1156
Guido van Rossum02975121992-08-17 08:55:12 +00001157/* Align a size according to a format code */
1158
1159static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001160align(int size, int c, const formatdef *e)
Guido van Rossum02975121992-08-17 08:55:12 +00001161{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001162 if (e->format == c) {
1163 if (e->alignment) {
1164 size = ((size + e->alignment - 1)
1165 / e->alignment)
1166 * e->alignment;
1167 }
Guido van Rossum02975121992-08-17 08:55:12 +00001168 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001169 return size;
Guido van Rossum02975121992-08-17 08:55:12 +00001170}
1171
1172
1173/* calculate the size of a format string */
1174
1175static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001176calcsize(const char *fmt, const formatdef *f)
Guido van Rossum02975121992-08-17 08:55:12 +00001177{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001178 const formatdef *e;
1179 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +00001180 char c;
1181 int size, num, itemsize, x;
1182
1183 s = fmt;
1184 size = 0;
1185 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001186 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001187 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001188 if ('0' <= c && c <= '9') {
1189 num = c - '0';
1190 while ('0' <= (c = *s++) && c <= '9') {
1191 x = num*10 + (c - '0');
1192 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001193 PyErr_SetString(
1194 StructError,
1195 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +00001196 return -1;
1197 }
1198 num = x;
1199 }
1200 if (c == '\0')
1201 break;
1202 }
1203 else
1204 num = 1;
Tim Peters2d4e0772001-06-11 16:57:33 +00001205
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001206 e = getentry(c, f);
1207 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +00001208 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001209 itemsize = e->size;
1210 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +00001211 x = num * itemsize;
1212 size += x;
1213 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001214 PyErr_SetString(StructError,
1215 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +00001216 return -1;
1217 }
Guido van Rossum02975121992-08-17 08:55:12 +00001218 }
1219
1220 return size;
1221}
1222
1223
Guido van Rossum414fd481997-12-19 04:24:24 +00001224static char calcsize__doc__[] = "\
1225calcsize(fmt) -> int\n\
1226Return size of C struct described by format string fmt.\n\
1227See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001228
Barry Warsaw30695fa1996-12-12 23:32:31 +00001229static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001230struct_calcsize(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001231{
1232 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001233 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001234 int size;
1235
Guido van Rossum43713e52000-02-29 13:59:29 +00001236 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001237 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001238 f = whichtable(&fmt);
1239 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001240 if (size < 0)
1241 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001242 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001243}
1244
1245
Guido van Rossum414fd481997-12-19 04:24:24 +00001246static char pack__doc__[] = "\
1247pack(fmt, v1, v2, ...) -> string\n\
1248Return string containing values v1, v2, ... packed according to fmt.\n\
1249See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001250
Barry Warsaw30695fa1996-12-12 23:32:31 +00001251static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001252struct_pack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001253{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001254 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001255 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001256 char *fmt;
1257 int size, num;
1258 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001259 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001260 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001261
Barry Warsaw30695fa1996-12-12 23:32:31 +00001262 if (args == NULL || !PyTuple_Check(args) ||
1263 (n = PyTuple_Size(args)) < 1)
1264 {
Tim Peters2d4e0772001-06-11 16:57:33 +00001265 PyErr_SetString(PyExc_TypeError,
Fred Drake137507e2000-06-01 02:02:46 +00001266 "struct.pack requires at least one argument");
Guido van Rossum02975121992-08-17 08:55:12 +00001267 return NULL;
1268 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001269 format = PyTuple_GetItem(args, 0);
1270 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001271 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001272 f = whichtable(&fmt);
1273 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001274 if (size < 0)
1275 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001276 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001277 if (result == NULL)
1278 return NULL;
1279
1280 s = fmt;
1281 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001282 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001283
1284 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001285 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001286 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001287 if ('0' <= c && c <= '9') {
1288 num = c - '0';
1289 while ('0' <= (c = *s++) && c <= '9')
1290 num = num*10 + (c - '0');
1291 if (c == '\0')
1292 break;
1293 }
1294 else
1295 num = 1;
1296
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001297 e = getentry(c, f);
1298 if (e == NULL)
1299 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001300 nres = restart + align((int)(res-restart), c, e);
1301 /* Fill padd bytes with zeros */
1302 while (res < nres)
1303 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001304 if (num == 0 && c != 's')
1305 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001306 do {
1307 if (c == 'x') {
1308 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001309 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001310 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001311 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001312 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001313 if (i >= n) {
1314 PyErr_SetString(StructError,
1315 "insufficient arguments to pack");
1316 goto fail;
1317 }
1318 v = PyTuple_GetItem(args, i++);
1319 if (v == NULL)
1320 goto fail;
1321 if (c == 's') {
1322 /* num is string size, not repeat count */
1323 int n;
1324 if (!PyString_Check(v)) {
1325 PyErr_SetString(StructError,
1326 "argument for 's' must be a string");
1327 goto fail;
1328 }
1329 n = PyString_Size(v);
1330 if (n > num)
1331 n = num;
1332 if (n > 0)
1333 memcpy(res, PyString_AsString(v), n);
1334 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001335 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001336 res += num;
1337 break;
1338 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001339 else if (c == 'p') {
1340 /* num is string size + 1,
1341 to fit in the count byte */
1342 int n;
1343 num--; /* now num is max string size */
1344 if (!PyString_Check(v)) {
1345 PyErr_SetString(StructError,
1346 "argument for 'p' must be a string");
1347 goto fail;
1348 }
1349 n = PyString_Size(v);
1350 if (n > num)
1351 n = num;
1352 if (n > 0)
1353 memcpy(res+1, PyString_AsString(v), n);
1354 if (n < num)
1355 /* no real need, just to be nice */
1356 memset(res+1+n, '\0', num-n);
1357 *res++ = n; /* store the length byte */
1358 res += num;
1359 break;
1360 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001361 else {
1362 if (e->pack(res, v, e) < 0)
1363 goto fail;
1364 res += e->size;
1365 }
1366 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001367 }
1368
1369 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001370 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001371 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001372 goto fail;
1373 }
1374
1375 return result;
1376
1377 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001378 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001379 return NULL;
1380}
1381
1382
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001383static char unpack__doc__[] = "\
1384unpack(fmt, string) -> (v1, v2, ...)\n\
1385Unpack the string, containing packed C structure data, according\n\
1386to fmt. Requires len(string)==calcsize(fmt).\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001387See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001388
Barry Warsaw30695fa1996-12-12 23:32:31 +00001389static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001390struct_unpack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001391{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001392 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001393 char *str, *start, *fmt, *s;
1394 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001395 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001396 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001397
Guido van Rossum43713e52000-02-29 13:59:29 +00001398 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001399 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001400 f = whichtable(&fmt);
1401 size = calcsize(fmt, f);
1402 if (size < 0)
1403 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001404 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001405 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001406 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001407 return NULL;
1408 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001409 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001410 if (res == NULL)
1411 return NULL;
1412 str = start;
1413 s = fmt;
1414 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001415 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001416 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001417 if ('0' <= c && c <= '9') {
1418 num = c - '0';
1419 while ('0' <= (c = *s++) && c <= '9')
1420 num = num*10 + (c - '0');
1421 if (c == '\0')
1422 break;
1423 }
1424 else
1425 num = 1;
1426
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001427 e = getentry(c, f);
1428 if (e == NULL)
1429 goto fail;
1430 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001431 if (num == 0 && c != 's')
1432 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001433
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001434 do {
1435 if (c == 'x') {
1436 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001437 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001438 }
1439 if (c == 's') {
1440 /* num is string size, not repeat count */
1441 v = PyString_FromStringAndSize(str, num);
1442 if (v == NULL)
1443 goto fail;
1444 str += num;
1445 num = 0;
1446 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001447 else if (c == 'p') {
1448 /* num is string buffer size,
1449 not repeat count */
1450 int n = *(unsigned char*)str;
1451 /* first byte (unsigned) is string size */
1452 if (n >= num)
1453 n = num-1;
1454 v = PyString_FromStringAndSize(str+1, n);
1455 if (v == NULL)
1456 goto fail;
1457 str += num;
1458 num = 0;
1459 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001460 else {
1461 v = e->unpack(str, e);
1462 if (v == NULL)
1463 goto fail;
1464 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001465 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001466 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001467 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001468 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001469 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001470 }
1471
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001472 v = PyList_AsTuple(res);
1473 Py_DECREF(res);
1474 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001475
1476 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001477 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001478 return NULL;
1479}
1480
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001481
Guido van Rossum02975121992-08-17 08:55:12 +00001482/* List of functions */
1483
Barry Warsaw30695fa1996-12-12 23:32:31 +00001484static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001485 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1486 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1487 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001488 {NULL, NULL} /* sentinel */
1489};
1490
1491
1492/* Module initialization */
1493
Guido van Rossum3886bb61998-12-04 18:50:17 +00001494DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001495initstruct(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001496{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001497 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001498
1499 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001500 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1501 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001502
1503 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001504 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001505 StructError = PyErr_NewException("struct.error", NULL, NULL);
1506 if (StructError == NULL)
1507 return;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001508 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001509}