blob: 61436f92a8b82696d4d18c5dccd793a47ae84b28 [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{
Tim Peters3dac5592001-07-18 20:47:31 +0000550 /* p may not be properly aligned */
551 LONG_LONG x;
552 memcpy(&x, p, sizeof(LONG_LONG));
553 return PyLong_FromLongLong(x);
Tim Peters7b9542a2001-06-10 23:40:19 +0000554}
555
556static PyObject *
557nu_ulonglong(const char *p, const formatdef *f)
558{
Tim Peters3dac5592001-07-18 20:47:31 +0000559 /* p may not be properly aligned */
560 unsigned LONG_LONG x;
561 memcpy(&x, p, sizeof(unsigned LONG_LONG));
562 return PyLong_FromUnsignedLongLong(x);
Tim Peters7b9542a2001-06-10 23:40:19 +0000563}
Tim Peters7b9542a2001-06-10 23:40:19 +0000564#endif
565
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000566static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000567nu_float(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000568{
569 float x;
570 memcpy((char *)&x, p, sizeof(float));
571 return PyFloat_FromDouble((double)x);
572}
573
574static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000575nu_double(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000576{
577 double x;
578 memcpy((char *)&x, p, sizeof(double));
579 return PyFloat_FromDouble(x);
580}
581
Guido van Rossum78694d91998-09-18 14:14:13 +0000582static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000583nu_void_p(const char *p, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000584{
585 return PyLong_FromVoidPtr(*(void **)p);
586}
587
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000588static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000589np_byte(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000590{
591 long x;
592 if (get_long(v, &x) < 0)
593 return -1;
Martin v. Löwis66de5492000-09-15 07:31:57 +0000594 if (x < -128 || x > 127){
595 PyErr_SetString(StructError,
596 "byte format requires -128<=number<=127");
597 return -1;
598 }
599 *p = (char)x;
600 return 0;
601}
602
603static int
604np_ubyte(char *p, PyObject *v, const formatdef *f)
605{
606 long x;
607 if (get_long(v, &x) < 0)
608 return -1;
609 if (x < 0 || x > 255){
610 PyErr_SetString(StructError,
611 "ubyte format requires 0<=number<=255");
612 return -1;
613 }
Guido van Rossum7844e381997-04-11 20:44:04 +0000614 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000615 return 0;
616}
617
618static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000619np_char(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000620{
621 if (!PyString_Check(v) || PyString_Size(v) != 1) {
622 PyErr_SetString(StructError,
623 "char format require string of length 1");
624 return -1;
625 }
626 *p = *PyString_AsString(v);
627 return 0;
628}
629
630static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000631np_short(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000632{
633 long x;
634 if (get_long(v, &x) < 0)
635 return -1;
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000636 if (x < SHRT_MIN || x > SHRT_MAX){
Martin v. Löwis66de5492000-09-15 07:31:57 +0000637 PyErr_SetString(StructError,
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000638 "short format requires " STRINGIFY(SHRT_MIN)
639 "<=number<=" STRINGIFY(SHRT_MAX));
Martin v. Löwis66de5492000-09-15 07:31:57 +0000640 return -1;
641 }
Guido van Rossum7844e381997-04-11 20:44:04 +0000642 * (short *)p = (short)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000643 return 0;
644}
645
646static int
Martin v. Löwis66de5492000-09-15 07:31:57 +0000647np_ushort(char *p, PyObject *v, const formatdef *f)
648{
649 long x;
650 if (get_long(v, &x) < 0)
651 return -1;
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000652 if (x < 0 || x > USHRT_MAX){
Martin v. Löwis66de5492000-09-15 07:31:57 +0000653 PyErr_SetString(StructError,
Martin v. Löwis2af72d52000-09-15 08:10:33 +0000654 "short format requires 0<=number<=" STRINGIFY(USHRT_MAX));
Martin v. Löwis66de5492000-09-15 07:31:57 +0000655 return -1;
656 }
657 * (unsigned short *)p = (unsigned short)x;
658 return 0;
659}
660
661static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000662np_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000663{
664 long x;
665 if (get_long(v, &x) < 0)
666 return -1;
667 * (int *)p = x;
668 return 0;
669}
670
671static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000672np_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000673{
674 unsigned long x;
675 if (get_ulong(v, &x) < 0)
676 return -1;
677 * (unsigned int *)p = x;
678 return 0;
679}
680
681static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000682np_long(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000683{
684 long x;
685 if (get_long(v, &x) < 0)
686 return -1;
687 * (long *)p = x;
688 return 0;
689}
690
691static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000692np_ulong(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000693{
694 unsigned long x;
695 if (get_ulong(v, &x) < 0)
696 return -1;
697 * (unsigned long *)p = x;
698 return 0;
699}
700
Tim Peters7b9542a2001-06-10 23:40:19 +0000701#ifdef HAVE_LONG_LONG
702
703static int
704np_longlong(char *p, PyObject *v, const formatdef *f)
705{
706 LONG_LONG x;
707 if (get_longlong(v, &x) < 0)
708 return -1;
Tim Peters3dac5592001-07-18 20:47:31 +0000709 memcpy(p, &x, sizeof(LONG_LONG));
Tim Peters7b9542a2001-06-10 23:40:19 +0000710 return 0;
711}
712
713static int
714np_ulonglong(char *p, PyObject *v, const formatdef *f)
715{
716 unsigned LONG_LONG x;
717 if (get_ulonglong(v, &x) < 0)
718 return -1;
Tim Peters3dac5592001-07-18 20:47:31 +0000719 memcpy(p, &x, sizeof(unsigned LONG_LONG));
Tim Peters7b9542a2001-06-10 23:40:19 +0000720 return 0;
721}
Tim Peters7b9542a2001-06-10 23:40:19 +0000722#endif
723
Guido van Rossum60c50611996-12-31 16:29:52 +0000724static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000725np_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000726{
727 float x = (float)PyFloat_AsDouble(v);
728 if (x == -1 && PyErr_Occurred()) {
729 PyErr_SetString(StructError,
730 "required argument is not a float");
731 return -1;
732 }
733 memcpy(p, (char *)&x, sizeof(float));
734 return 0;
735}
736
737static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000738np_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000739{
740 double x = PyFloat_AsDouble(v);
741 if (x == -1 && PyErr_Occurred()) {
742 PyErr_SetString(StructError,
743 "required argument is not a float");
744 return -1;
745 }
746 memcpy(p, (char *)&x, sizeof(double));
747 return 0;
748}
749
Guido van Rossum78694d91998-09-18 14:14:13 +0000750static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000751np_void_p(char *p, PyObject *v, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000752{
753 void *x = PyLong_AsVoidPtr(v);
754 if (x == NULL && PyErr_Occurred()) {
755 /* ### hrm. PyLong_AsVoidPtr raises SystemError */
756 if (PyErr_ExceptionMatches(PyExc_TypeError))
757 PyErr_SetString(StructError,
758 "required argument is not an integer");
759 return -1;
760 }
761 *(void **)p = x;
762 return 0;
763}
764
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000765static formatdef native_table[] = {
766 {'x', sizeof(char), 0, NULL},
767 {'b', sizeof(char), 0, nu_byte, np_byte},
Martin v. Löwis66de5492000-09-15 07:31:57 +0000768 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000769 {'c', sizeof(char), 0, nu_char, np_char},
770 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000771 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000772 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
Martin v. Löwis66de5492000-09-15 07:31:57 +0000773 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000774 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000775 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000776 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000777 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000778 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
779 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
Guido van Rossum78694d91998-09-18 14:14:13 +0000780 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Tim Peters7b9542a2001-06-10 23:40:19 +0000781#ifdef HAVE_LONG_LONG
782 {'q', sizeof(LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
783 {'Q', sizeof(LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Tim Peters7b9542a2001-06-10 23:40:19 +0000784#endif
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000785 {0}
786};
787
Tim Peters7a3bfc32001-06-12 01:22:22 +0000788/* Big-endian routines. *****************************************************/
789
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000790static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000791bu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000792{
793 long x = 0;
794 int i = f->size;
795 do {
796 x = (x<<8) | (*p++ & 0xFF);
797 } while (--i > 0);
Tim Petersf0e717b2001-04-08 23:39:38 +0000798 /* Extend the sign bit. */
799 if (SIZEOF_LONG > f->size)
800 x |= -(x & (1L << (8*f->size - 1)));
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000801 return PyInt_FromLong(x);
802}
803
804static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000805bu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000806{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000807 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000808 int i = f->size;
809 do {
810 x = (x<<8) | (*p++ & 0xFF);
811 } while (--i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000812 if (f->size >= 4)
813 return PyLong_FromUnsignedLong(x);
814 else
815 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000816}
817
Guido van Rossum74679b41997-01-02 22:21:36 +0000818static PyObject *
Tim Peters7a3bfc32001-06-12 01:22:22 +0000819bu_longlong(const char *p, const formatdef *f)
820{
821 return _PyLong_FromByteArray((const unsigned char *)p,
822 8,
823 0, /* little-endian */
824 1 /* signed */);
825}
826
827static PyObject *
828bu_ulonglong(const char *p, const formatdef *f)
829{
830 return _PyLong_FromByteArray((const unsigned char *)p,
831 8,
832 0, /* little-endian */
833 0 /* signed */);
834}
835
836static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000837bu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000838{
839 return unpack_float(p, 1);
840}
841
842static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000843bu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000844{
845 return unpack_double(p, 1);
846}
847
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000848static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000849bp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000850{
851 long x;
852 int i;
853 if (get_long(v, &x) < 0)
854 return -1;
855 i = f->size;
856 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000857 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000858 x >>= 8;
859 } while (i > 0);
860 return 0;
861}
862
Guido van Rossum60c50611996-12-31 16:29:52 +0000863static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000864bp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000865{
866 unsigned long x;
867 int i;
868 if (get_ulong(v, &x) < 0)
869 return -1;
870 i = f->size;
871 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000872 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000873 x >>= 8;
874 } while (i > 0);
875 return 0;
876}
877
Guido van Rossum74679b41997-01-02 22:21:36 +0000878static int
Tim Peters7a3bfc32001-06-12 01:22:22 +0000879bp_longlong(char *p, PyObject *v, const formatdef *f)
880{
881 int res;
882 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000883 if (v == NULL)
884 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000885 res = _PyLong_AsByteArray((PyLongObject *)v,
886 (unsigned char *)p,
887 8,
888 0, /* little_endian */
889 1 /* signed */);
890 Py_DECREF(v);
891 return res;
892}
893
894static int
895bp_ulonglong(char *p, PyObject *v, const formatdef *f)
896{
897 int res;
898 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +0000899 if (v == NULL)
900 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +0000901 res = _PyLong_AsByteArray((PyLongObject *)v,
902 (unsigned char *)p,
903 8,
904 0, /* little_endian */
905 0 /* signed */);
906 Py_DECREF(v);
907 return res;
908}
909
910static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000911bp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000912{
913 double x = PyFloat_AsDouble(v);
914 if (x == -1 && PyErr_Occurred()) {
915 PyErr_SetString(StructError,
916 "required argument is not a float");
917 return -1;
918 }
919 return pack_float(x, p, 1);
920}
921
922static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000923bp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000924{
925 double x = PyFloat_AsDouble(v);
926 if (x == -1 && PyErr_Occurred()) {
927 PyErr_SetString(StructError,
928 "required argument is not a float");
929 return -1;
930 }
931 return pack_double(x, p, 1);
932}
933
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000934static formatdef bigendian_table[] = {
935 {'x', 1, 0, NULL},
936 {'b', 1, 0, bu_int, bp_int},
937 {'B', 1, 0, bu_uint, bp_int},
938 {'c', 1, 0, nu_char, np_char},
939 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000940 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000941 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000942 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000943 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000944 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000945 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000946 {'L', 4, 0, bu_uint, bp_uint},
Tim Peters7a3bfc32001-06-12 01:22:22 +0000947 {'q', 8, 0, bu_longlong, bp_longlong},
948 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
Guido van Rossum74679b41997-01-02 22:21:36 +0000949 {'f', 4, 0, bu_float, bp_float},
950 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000951 {0}
952};
953
Tim Peters7a3bfc32001-06-12 01:22:22 +0000954/* Little-endian routines. *****************************************************/
955
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000956static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000957lu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000958{
959 long x = 0;
960 int i = f->size;
961 do {
962 x = (x<<8) | (p[--i] & 0xFF);
963 } while (i > 0);
Tim Petersf0e717b2001-04-08 23:39:38 +0000964 /* Extend the sign bit. */
965 if (SIZEOF_LONG > f->size)
966 x |= -(x & (1L << (8*f->size - 1)));
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000967 return PyInt_FromLong(x);
968}
969
970static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000971lu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000972{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000973 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000974 int i = f->size;
975 do {
976 x = (x<<8) | (p[--i] & 0xFF);
977 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000978 if (f->size >= 4)
979 return PyLong_FromUnsignedLong(x);
980 else
981 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000982}
983
Guido van Rossum74679b41997-01-02 22:21:36 +0000984static PyObject *
Tim Peters7a3bfc32001-06-12 01:22:22 +0000985lu_longlong(const char *p, const formatdef *f)
986{
987 return _PyLong_FromByteArray((const unsigned char *)p,
988 8,
989 1, /* little-endian */
990 1 /* signed */);
991}
992
993static PyObject *
994lu_ulonglong(const char *p, const formatdef *f)
995{
996 return _PyLong_FromByteArray((const unsigned char *)p,
997 8,
998 1, /* little-endian */
999 0 /* signed */);
1000}
1001
1002static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001003lu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +00001004{
1005 return unpack_float(p+3, -1);
1006}
1007
1008static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001009lu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +00001010{
1011 return unpack_double(p+7, -1);
1012}
1013
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001014static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001015lp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001016{
1017 long x;
1018 int i;
1019 if (get_long(v, &x) < 0)
1020 return -1;
1021 i = f->size;
1022 do {
Guido van Rossum7844e381997-04-11 20:44:04 +00001023 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001024 x >>= 8;
1025 } while (--i > 0);
1026 return 0;
1027}
1028
Guido van Rossum60c50611996-12-31 16:29:52 +00001029static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001030lp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +00001031{
1032 unsigned long x;
1033 int i;
1034 if (get_ulong(v, &x) < 0)
1035 return -1;
1036 i = f->size;
1037 do {
Guido van Rossum7844e381997-04-11 20:44:04 +00001038 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +00001039 x >>= 8;
1040 } while (--i > 0);
1041 return 0;
1042}
1043
Guido van Rossum74679b41997-01-02 22:21:36 +00001044static int
Tim Peters7a3bfc32001-06-12 01:22:22 +00001045lp_longlong(char *p, PyObject *v, const formatdef *f)
1046{
1047 int res;
1048 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +00001049 if (v == NULL)
1050 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +00001051 res = _PyLong_AsByteArray((PyLongObject*)v,
1052 (unsigned char *)p,
1053 8,
1054 1, /* little_endian */
1055 1 /* signed */);
1056 Py_DECREF(v);
1057 return res;
1058}
1059
1060static int
1061lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1062{
1063 int res;
1064 v = get_pylong(v);
Tim Petersda9c5b32001-06-13 01:26:35 +00001065 if (v == NULL)
1066 return -1;
Tim Peters7a3bfc32001-06-12 01:22:22 +00001067 res = _PyLong_AsByteArray((PyLongObject*)v,
1068 (unsigned char *)p,
1069 8,
1070 1, /* little_endian */
1071 0 /* signed */);
1072 Py_DECREF(v);
1073 return res;
1074}
1075
1076static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001077lp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +00001078{
1079 double x = PyFloat_AsDouble(v);
1080 if (x == -1 && PyErr_Occurred()) {
1081 PyErr_SetString(StructError,
1082 "required argument is not a float");
1083 return -1;
1084 }
1085 return pack_float(x, p+3, -1);
1086}
1087
1088static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001089lp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +00001090{
1091 double x = PyFloat_AsDouble(v);
1092 if (x == -1 && PyErr_Occurred()) {
1093 PyErr_SetString(StructError,
1094 "required argument is not a float");
1095 return -1;
1096 }
1097 return pack_double(x, p+7, -1);
1098}
1099
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001100static formatdef lilendian_table[] = {
1101 {'x', 1, 0, NULL},
1102 {'b', 1, 0, lu_int, lp_int},
1103 {'B', 1, 0, lu_uint, lp_int},
1104 {'c', 1, 0, nu_char, np_char},
1105 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001106 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001107 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +00001108 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001109 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +00001110 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001111 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +00001112 {'L', 4, 0, lu_uint, lp_uint},
Tim Peters7a3bfc32001-06-12 01:22:22 +00001113 {'q', 8, 0, lu_longlong, lp_longlong},
1114 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
Guido van Rossum74679b41997-01-02 22:21:36 +00001115 {'f', 4, 0, lu_float, lp_float},
1116 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001117 {0}
1118};
1119
1120
1121static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001122whichtable(char **pfmt)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001123{
1124 const char *fmt = (*pfmt)++; /* May be backed out of later */
1125 switch (*fmt) {
1126 case '<':
1127 return lilendian_table;
1128 case '>':
1129 case '!': /* Network byte order is big-endian */
1130 return bigendian_table;
1131 case '=': { /* Host byte order -- different from native in aligment! */
1132 int n = 1;
1133 char *p = (char *) &n;
1134 if (*p == 1)
1135 return lilendian_table;
1136 else
1137 return bigendian_table;
1138 }
1139 default:
1140 --*pfmt; /* Back out of pointer increment */
1141 /* Fall through */
1142 case '@':
1143 return native_table;
1144 }
1145}
1146
1147
1148/* Get the table entry for a format code */
1149
1150static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001151getentry(int c, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001152{
1153 for (; f->format != '\0'; f++) {
1154 if (f->format == c) {
1155 return f;
1156 }
1157 }
1158 PyErr_SetString(StructError, "bad char in struct format");
1159 return NULL;
1160}
1161
1162
Guido van Rossum02975121992-08-17 08:55:12 +00001163/* Align a size according to a format code */
1164
1165static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001166align(int size, int c, const formatdef *e)
Guido van Rossum02975121992-08-17 08:55:12 +00001167{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001168 if (e->format == c) {
1169 if (e->alignment) {
1170 size = ((size + e->alignment - 1)
1171 / e->alignment)
1172 * e->alignment;
1173 }
Guido van Rossum02975121992-08-17 08:55:12 +00001174 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001175 return size;
Guido van Rossum02975121992-08-17 08:55:12 +00001176}
1177
1178
1179/* calculate the size of a format string */
1180
1181static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001182calcsize(const char *fmt, const formatdef *f)
Guido van Rossum02975121992-08-17 08:55:12 +00001183{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001184 const formatdef *e;
1185 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +00001186 char c;
1187 int size, num, itemsize, x;
1188
1189 s = fmt;
1190 size = 0;
1191 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001192 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001193 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001194 if ('0' <= c && c <= '9') {
1195 num = c - '0';
1196 while ('0' <= (c = *s++) && c <= '9') {
1197 x = num*10 + (c - '0');
1198 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001199 PyErr_SetString(
1200 StructError,
1201 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +00001202 return -1;
1203 }
1204 num = x;
1205 }
1206 if (c == '\0')
1207 break;
1208 }
1209 else
1210 num = 1;
Tim Peters2d4e0772001-06-11 16:57:33 +00001211
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001212 e = getentry(c, f);
1213 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +00001214 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001215 itemsize = e->size;
1216 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +00001217 x = num * itemsize;
1218 size += x;
1219 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001220 PyErr_SetString(StructError,
1221 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +00001222 return -1;
1223 }
Guido van Rossum02975121992-08-17 08:55:12 +00001224 }
1225
1226 return size;
1227}
1228
1229
Guido van Rossum414fd481997-12-19 04:24:24 +00001230static char calcsize__doc__[] = "\
1231calcsize(fmt) -> int\n\
1232Return size of C struct described by format string fmt.\n\
1233See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001234
Barry Warsaw30695fa1996-12-12 23:32:31 +00001235static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001236struct_calcsize(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001237{
1238 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001239 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001240 int size;
1241
Guido van Rossum43713e52000-02-29 13:59:29 +00001242 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001243 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001244 f = whichtable(&fmt);
1245 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001246 if (size < 0)
1247 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001248 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001249}
1250
1251
Guido van Rossum414fd481997-12-19 04:24:24 +00001252static char pack__doc__[] = "\
1253pack(fmt, v1, v2, ...) -> string\n\
1254Return string containing values v1, v2, ... packed according to fmt.\n\
1255See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001256
Barry Warsaw30695fa1996-12-12 23:32:31 +00001257static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001258struct_pack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001259{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001260 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001261 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001262 char *fmt;
1263 int size, num;
1264 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001265 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001266 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001267
Barry Warsaw30695fa1996-12-12 23:32:31 +00001268 if (args == NULL || !PyTuple_Check(args) ||
1269 (n = PyTuple_Size(args)) < 1)
1270 {
Tim Peters2d4e0772001-06-11 16:57:33 +00001271 PyErr_SetString(PyExc_TypeError,
Fred Drake137507e2000-06-01 02:02:46 +00001272 "struct.pack requires at least one argument");
Guido van Rossum02975121992-08-17 08:55:12 +00001273 return NULL;
1274 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001275 format = PyTuple_GetItem(args, 0);
1276 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001277 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001278 f = whichtable(&fmt);
1279 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001280 if (size < 0)
1281 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001282 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001283 if (result == NULL)
1284 return NULL;
1285
1286 s = fmt;
1287 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001288 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001289
1290 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001291 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001292 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001293 if ('0' <= c && c <= '9') {
1294 num = c - '0';
1295 while ('0' <= (c = *s++) && c <= '9')
1296 num = num*10 + (c - '0');
1297 if (c == '\0')
1298 break;
1299 }
1300 else
1301 num = 1;
1302
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001303 e = getentry(c, f);
1304 if (e == NULL)
1305 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001306 nres = restart + align((int)(res-restart), c, e);
1307 /* Fill padd bytes with zeros */
1308 while (res < nres)
1309 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001310 if (num == 0 && c != 's')
1311 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001312 do {
1313 if (c == 'x') {
1314 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001315 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001316 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001317 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001318 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001319 if (i >= n) {
1320 PyErr_SetString(StructError,
1321 "insufficient arguments to pack");
1322 goto fail;
1323 }
1324 v = PyTuple_GetItem(args, i++);
1325 if (v == NULL)
1326 goto fail;
1327 if (c == 's') {
1328 /* num is string size, not repeat count */
1329 int n;
1330 if (!PyString_Check(v)) {
1331 PyErr_SetString(StructError,
1332 "argument for 's' must be a string");
1333 goto fail;
1334 }
1335 n = PyString_Size(v);
1336 if (n > num)
1337 n = num;
1338 if (n > 0)
1339 memcpy(res, PyString_AsString(v), n);
1340 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001341 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001342 res += num;
1343 break;
1344 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001345 else if (c == 'p') {
1346 /* num is string size + 1,
1347 to fit in the count byte */
1348 int n;
1349 num--; /* now num is max string size */
1350 if (!PyString_Check(v)) {
1351 PyErr_SetString(StructError,
1352 "argument for 'p' must be a string");
1353 goto fail;
1354 }
1355 n = PyString_Size(v);
1356 if (n > num)
1357 n = num;
1358 if (n > 0)
1359 memcpy(res+1, PyString_AsString(v), n);
1360 if (n < num)
1361 /* no real need, just to be nice */
1362 memset(res+1+n, '\0', num-n);
Tim Peters0891ac02001-09-15 02:35:15 +00001363 if (n > 255)
1364 n = 255;
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001365 *res++ = n; /* store the length byte */
1366 res += num;
1367 break;
1368 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001369 else {
1370 if (e->pack(res, v, e) < 0)
1371 goto fail;
1372 res += e->size;
1373 }
1374 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001375 }
1376
1377 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001378 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001379 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001380 goto fail;
1381 }
1382
1383 return result;
1384
1385 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001386 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001387 return NULL;
1388}
1389
1390
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001391static char unpack__doc__[] = "\
1392unpack(fmt, string) -> (v1, v2, ...)\n\
1393Unpack the string, containing packed C structure data, according\n\
1394to fmt. Requires len(string)==calcsize(fmt).\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001395See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001396
Barry Warsaw30695fa1996-12-12 23:32:31 +00001397static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001398struct_unpack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001399{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001400 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001401 char *str, *start, *fmt, *s;
1402 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001403 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001404 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001405
Guido van Rossum43713e52000-02-29 13:59:29 +00001406 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001407 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001408 f = whichtable(&fmt);
1409 size = calcsize(fmt, f);
1410 if (size < 0)
1411 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001412 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001413 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001414 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001415 return NULL;
1416 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001417 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001418 if (res == NULL)
1419 return NULL;
1420 str = start;
1421 s = fmt;
1422 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001423 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001424 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001425 if ('0' <= c && c <= '9') {
1426 num = c - '0';
1427 while ('0' <= (c = *s++) && c <= '9')
1428 num = num*10 + (c - '0');
1429 if (c == '\0')
1430 break;
1431 }
1432 else
1433 num = 1;
1434
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001435 e = getentry(c, f);
1436 if (e == NULL)
1437 goto fail;
1438 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001439 if (num == 0 && c != 's')
1440 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001441
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001442 do {
1443 if (c == 'x') {
1444 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001445 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001446 }
1447 if (c == 's') {
1448 /* num is string size, not repeat count */
1449 v = PyString_FromStringAndSize(str, num);
1450 if (v == NULL)
1451 goto fail;
1452 str += num;
1453 num = 0;
1454 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001455 else if (c == 'p') {
1456 /* num is string buffer size,
1457 not repeat count */
1458 int n = *(unsigned char*)str;
1459 /* first byte (unsigned) is string size */
1460 if (n >= num)
1461 n = num-1;
1462 v = PyString_FromStringAndSize(str+1, n);
1463 if (v == NULL)
1464 goto fail;
1465 str += num;
1466 num = 0;
1467 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001468 else {
1469 v = e->unpack(str, e);
1470 if (v == NULL)
1471 goto fail;
1472 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001473 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001474 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001475 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001476 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001477 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001478 }
1479
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001480 v = PyList_AsTuple(res);
1481 Py_DECREF(res);
1482 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001483
1484 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001485 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001486 return NULL;
1487}
1488
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001489
Guido van Rossum02975121992-08-17 08:55:12 +00001490/* List of functions */
1491
Barry Warsaw30695fa1996-12-12 23:32:31 +00001492static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001493 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1494 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1495 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001496 {NULL, NULL} /* sentinel */
1497};
1498
1499
1500/* Module initialization */
1501
Guido van Rossum3886bb61998-12-04 18:50:17 +00001502DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001503initstruct(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001504{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001505 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001506
1507 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001508 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1509 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001510
1511 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001512 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001513 StructError = PyErr_NewException("struct.error", NULL, NULL);
1514 if (StructError == NULL)
1515 return;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001516 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001517}