blob: 5fc9991f9b9616123e8a325640e36820da4e254c [file] [log] [blame]
Thomas Wouters477c8d52006-05-27 19:21:47 +00001/* struct module -- pack values into and (out of) strings */
2
3/* New version supporting byte order, alignment and size options,
4 character strings, and unsigned numbers */
5
6#define PY_SSIZE_T_CLEAN
7
8#include "Python.h"
9#include "structseq.h"
10#include "structmember.h"
11#include <ctype.h>
12
13static PyTypeObject PyStructType;
14
15/* compatibility macros */
16#if (PY_VERSION_HEX < 0x02050000)
17typedef int Py_ssize_t;
18#endif
19
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000020/* If PY_STRUCT_OVERFLOW_MASKING is defined, the struct module will wrap all input
21 numbers for explicit endians such that they fit in the given type, much
22 like explicit casting in C. A warning will be raised if the number did
23 not originally fit within the range of the requested type. If it is
24 not defined, then all range errors and overflow will be struct.error
25 exceptions. */
26
27#define PY_STRUCT_OVERFLOW_MASKING 1
28
29#ifdef PY_STRUCT_OVERFLOW_MASKING
30static PyObject *pylong_ulong_mask = NULL;
31static PyObject *pyint_zero = NULL;
32#endif
33
Thomas Wouters0e3f5912006-08-11 14:57:12 +000034/* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float
35 arguments for integer formats with a warning for backwards
36 compatibility. */
37
38#define PY_STRUCT_FLOAT_COERCE 1
39
40#ifdef PY_STRUCT_FLOAT_COERCE
41#define FLOAT_COERCE "integer argument expected, got float"
42#endif
43
44
Thomas Wouters477c8d52006-05-27 19:21:47 +000045/* The translation function for each format character is table driven */
46typedef struct _formatdef {
47 char format;
48 Py_ssize_t size;
49 Py_ssize_t alignment;
50 PyObject* (*unpack)(const char *,
51 const struct _formatdef *);
52 int (*pack)(char *, PyObject *,
53 const struct _formatdef *);
54} formatdef;
55
56typedef struct _formatcode {
57 const struct _formatdef *fmtdef;
58 Py_ssize_t offset;
59 Py_ssize_t size;
60} formatcode;
61
62/* Struct object interface */
63
64typedef struct {
65 PyObject_HEAD
66 Py_ssize_t s_size;
67 Py_ssize_t s_len;
68 formatcode *s_codes;
69 PyObject *s_format;
70 PyObject *weakreflist; /* List of weak references */
71} PyStructObject;
72
73
74#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
75#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
76
77
78/* Exception */
79
80static PyObject *StructError;
81
82
83/* Define various structs to figure out the alignments of types */
84
85
86typedef struct { char c; short x; } st_short;
87typedef struct { char c; int x; } st_int;
88typedef struct { char c; long x; } st_long;
89typedef struct { char c; float x; } st_float;
90typedef struct { char c; double x; } st_double;
91typedef struct { char c; void *x; } st_void_p;
92
93#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
94#define INT_ALIGN (sizeof(st_int) - sizeof(int))
95#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
96#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
97#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
98#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
99
100/* We can't support q and Q in native mode unless the compiler does;
101 in std mode, they're 8 bytes on all platforms. */
102#ifdef HAVE_LONG_LONG
103typedef struct { char c; PY_LONG_LONG x; } s_long_long;
104#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
105#endif
106
Thomas Woutersb2137042007-02-01 18:02:27 +0000107#ifdef HAVE_C99_BOOL
108#define BOOL_TYPE _Bool
109typedef struct { char c; _Bool x; } s_bool;
110#define BOOL_ALIGN (sizeof(s_bool) - sizeof(BOOL_TYPE))
111#else
112#define BOOL_TYPE char
113#define BOOL_ALIGN 0
114#endif
115
Thomas Wouters477c8d52006-05-27 19:21:47 +0000116#define STRINGIFY(x) #x
117
118#ifdef __powerc
119#pragma options align=reset
120#endif
121
122/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
123
124static PyObject *
125get_pylong(PyObject *v)
126{
127 PyNumberMethods *m;
128
129 assert(v != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000130 if (PyLong_Check(v)) {
131 Py_INCREF(v);
132 return v;
133 }
134 m = v->ob_type->tp_as_number;
135 if (m != NULL && m->nb_long != NULL) {
136 v = m->nb_long(v);
137 if (v == NULL)
138 return NULL;
139 if (PyLong_Check(v))
140 return v;
141 Py_DECREF(v);
142 }
143 PyErr_SetString(StructError,
144 "cannot convert argument to long");
145 return NULL;
146}
147
148/* Helper routine to get a Python integer and raise the appropriate error
149 if it isn't one */
150
151static int
152get_long(PyObject *v, long *p)
153{
154 long x = PyInt_AsLong(v);
155 if (x == -1 && PyErr_Occurred()) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000156#ifdef PY_STRUCT_FLOAT_COERCE
157 if (PyFloat_Check(v)) {
158 PyObject *o;
159 int res;
160 PyErr_Clear();
161 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
162 return -1;
163 o = PyNumber_Int(v);
164 if (o == NULL)
165 return -1;
166 res = get_long(o, p);
167 Py_DECREF(o);
168 return res;
169 }
170#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000171 if (PyErr_ExceptionMatches(PyExc_TypeError))
172 PyErr_SetString(StructError,
173 "required argument is not an integer");
174 return -1;
175 }
176 *p = x;
177 return 0;
178}
179
180
181/* Same, but handling unsigned long */
182
183static int
184get_ulong(PyObject *v, unsigned long *p)
185{
186 if (PyLong_Check(v)) {
187 unsigned long x = PyLong_AsUnsignedLong(v);
188 if (x == (unsigned long)(-1) && PyErr_Occurred())
189 return -1;
190 *p = x;
191 return 0;
192 }
193 if (get_long(v, (long *)p) < 0)
194 return -1;
195 if (((long)*p) < 0) {
196 PyErr_SetString(StructError,
197 "unsigned argument is < 0");
198 return -1;
199 }
200 return 0;
201}
202
203#ifdef HAVE_LONG_LONG
204
205/* Same, but handling native long long. */
206
207static int
208get_longlong(PyObject *v, PY_LONG_LONG *p)
209{
210 PY_LONG_LONG x;
211
212 v = get_pylong(v);
213 if (v == NULL)
214 return -1;
215 assert(PyLong_Check(v));
216 x = PyLong_AsLongLong(v);
217 Py_DECREF(v);
218 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
219 return -1;
220 *p = x;
221 return 0;
222}
223
224/* Same, but handling native unsigned long long. */
225
226static int
227get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
228{
229 unsigned PY_LONG_LONG x;
230
231 v = get_pylong(v);
232 if (v == NULL)
233 return -1;
234 assert(PyLong_Check(v));
235 x = PyLong_AsUnsignedLongLong(v);
236 Py_DECREF(v);
237 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
238 return -1;
239 *p = x;
240 return 0;
241}
242
243#endif
244
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000245#ifdef PY_STRUCT_OVERFLOW_MASKING
246
247/* Helper routine to get a Python integer and raise the appropriate error
248 if it isn't one */
249
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000250#define INT_OVERFLOW "struct integer overflow masking is deprecated"
251
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000252static int
253get_wrapped_long(PyObject *v, long *p)
254{
255 if (get_long(v, p) < 0) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000256 if (PyLong_Check(v) &&
257 PyErr_ExceptionMatches(PyExc_OverflowError)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000258 PyObject *wrapped;
259 long x;
260 PyErr_Clear();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000261#ifdef PY_STRUCT_FLOAT_COERCE
262 if (PyFloat_Check(v)) {
263 PyObject *o;
264 int res;
265 PyErr_Clear();
266 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
267 return -1;
268 o = PyNumber_Int(v);
269 if (o == NULL)
270 return -1;
271 res = get_wrapped_long(o, p);
272 Py_DECREF(o);
273 return res;
274 }
275#endif
276 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000277 return -1;
278 wrapped = PyNumber_And(v, pylong_ulong_mask);
279 if (wrapped == NULL)
280 return -1;
281 x = (long)PyLong_AsUnsignedLong(wrapped);
282 Py_DECREF(wrapped);
283 if (x == -1 && PyErr_Occurred())
284 return -1;
285 *p = x;
286 } else {
287 return -1;
288 }
289 }
290 return 0;
291}
292
293static int
294get_wrapped_ulong(PyObject *v, unsigned long *p)
295{
296 long x = (long)PyLong_AsUnsignedLong(v);
297 if (x == -1 && PyErr_Occurred()) {
298 PyObject *wrapped;
299 PyErr_Clear();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300#ifdef PY_STRUCT_FLOAT_COERCE
301 if (PyFloat_Check(v)) {
302 PyObject *o;
303 int res;
304 PyErr_Clear();
305 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
306 return -1;
307 o = PyNumber_Int(v);
308 if (o == NULL)
309 return -1;
310 res = get_wrapped_ulong(o, p);
311 Py_DECREF(o);
312 return res;
313 }
314#endif
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000315 wrapped = PyNumber_And(v, pylong_ulong_mask);
316 if (wrapped == NULL)
317 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000318 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000319 Py_DECREF(wrapped);
320 return -1;
321 }
322 x = (long)PyLong_AsUnsignedLong(wrapped);
323 Py_DECREF(wrapped);
324 if (x == -1 && PyErr_Occurred())
325 return -1;
326 }
327 *p = (unsigned long)x;
328 return 0;
329}
330
331#define RANGE_ERROR(x, f, flag, mask) \
332 do { \
333 if (_range_error(f, flag) < 0) \
334 return -1; \
335 else \
336 (x) &= (mask); \
337 } while (0)
338
339#else
340
341#define get_wrapped_long get_long
342#define get_wrapped_ulong get_ulong
343#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
344
345#endif
346
Thomas Wouters477c8d52006-05-27 19:21:47 +0000347/* Floating point helpers */
348
349static PyObject *
350unpack_float(const char *p, /* start of 4-byte string */
351 int le) /* true for little-endian, false for big-endian */
352{
353 double x;
354
355 x = _PyFloat_Unpack4((unsigned char *)p, le);
356 if (x == -1.0 && PyErr_Occurred())
357 return NULL;
358 return PyFloat_FromDouble(x);
359}
360
361static PyObject *
362unpack_double(const char *p, /* start of 8-byte string */
363 int le) /* true for little-endian, false for big-endian */
364{
365 double x;
366
367 x = _PyFloat_Unpack8((unsigned char *)p, le);
368 if (x == -1.0 && PyErr_Occurred())
369 return NULL;
370 return PyFloat_FromDouble(x);
371}
372
373/* Helper to format the range error exceptions */
374static int
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000375_range_error(const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000376{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000377 /* ulargest is the largest unsigned value with f->size bytes.
378 * Note that the simpler:
379 * ((size_t)1 << (f->size * 8)) - 1
380 * doesn't work when f->size == sizeof(size_t) because C doesn't
381 * define what happens when a left shift count is >= the number of
382 * bits in the integer being shifted; e.g., on some boxes it doesn't
383 * shift at all when they're equal.
384 */
385 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
386 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
387 if (is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000388 PyErr_Format(StructError,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000389 "'%c' format requires 0 <= number <= %zu",
390 f->format,
391 ulargest);
392 else {
393 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000394 PyErr_Format(StructError,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000395 "'%c' format requires %zd <= number <= %zd",
396 f->format,
397 ~ largest,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000398 largest);
399 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000400#ifdef PY_STRUCT_OVERFLOW_MASKING
401 {
402 PyObject *ptype, *pvalue, *ptraceback;
403 PyObject *msg;
404 int rval;
405 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
406 assert(pvalue != NULL);
407 msg = PyObject_Str(pvalue);
408 Py_XDECREF(ptype);
409 Py_XDECREF(pvalue);
410 Py_XDECREF(ptraceback);
411 if (msg == NULL)
412 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000413 rval = PyErr_WarnEx(PyExc_DeprecationWarning,
414 PyString_AS_STRING(msg), 2);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000415 Py_DECREF(msg);
416 if (rval == 0)
417 return 0;
418 }
419#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000420 return -1;
421}
422
423
424
425/* A large number of small routines follow, with names of the form
426
427 [bln][up]_TYPE
428
429 [bln] distiguishes among big-endian, little-endian and native.
430 [pu] distiguishes between pack (to struct) and unpack (from struct).
431 TYPE is one of char, byte, ubyte, etc.
432*/
433
434/* Native mode routines. ****************************************************/
435/* NOTE:
436 In all n[up]_<type> routines handling types larger than 1 byte, there is
437 *no* guarantee that the p pointer is properly aligned for each type,
438 therefore memcpy is called. An intermediate variable is used to
439 compensate for big-endian architectures.
440 Normally both the intermediate variable and the memcpy call will be
441 skipped by C optimisation in little-endian architectures (gcc >= 2.91
442 does this). */
443
444static PyObject *
445nu_char(const char *p, const formatdef *f)
446{
447 return PyString_FromStringAndSize(p, 1);
448}
449
450static PyObject *
451nu_byte(const char *p, const formatdef *f)
452{
453 return PyInt_FromLong((long) *(signed char *)p);
454}
455
456static PyObject *
457nu_ubyte(const char *p, const formatdef *f)
458{
459 return PyInt_FromLong((long) *(unsigned char *)p);
460}
461
462static PyObject *
463nu_short(const char *p, const formatdef *f)
464{
465 short x;
466 memcpy((char *)&x, p, sizeof x);
467 return PyInt_FromLong((long)x);
468}
469
470static PyObject *
471nu_ushort(const char *p, const formatdef *f)
472{
473 unsigned short x;
474 memcpy((char *)&x, p, sizeof x);
475 return PyInt_FromLong((long)x);
476}
477
478static PyObject *
479nu_int(const char *p, const formatdef *f)
480{
481 int x;
482 memcpy((char *)&x, p, sizeof x);
483 return PyInt_FromLong((long)x);
484}
485
486static PyObject *
487nu_uint(const char *p, const formatdef *f)
488{
489 unsigned int x;
490 memcpy((char *)&x, p, sizeof x);
491#if (SIZEOF_LONG > SIZEOF_INT)
492 return PyInt_FromLong((long)x);
493#else
494 if (x <= ((unsigned int)LONG_MAX))
495 return PyInt_FromLong((long)x);
496 return PyLong_FromUnsignedLong((unsigned long)x);
497#endif
498}
499
500static PyObject *
501nu_long(const char *p, const formatdef *f)
502{
503 long x;
504 memcpy((char *)&x, p, sizeof x);
505 return PyInt_FromLong(x);
506}
507
508static PyObject *
509nu_ulong(const char *p, const formatdef *f)
510{
511 unsigned long x;
512 memcpy((char *)&x, p, sizeof x);
513 if (x <= LONG_MAX)
514 return PyInt_FromLong((long)x);
515 return PyLong_FromUnsignedLong(x);
516}
517
518/* Native mode doesn't support q or Q unless the platform C supports
519 long long (or, on Windows, __int64). */
520
521#ifdef HAVE_LONG_LONG
522
523static PyObject *
524nu_longlong(const char *p, const formatdef *f)
525{
526 PY_LONG_LONG x;
527 memcpy((char *)&x, p, sizeof x);
528 if (x >= LONG_MIN && x <= LONG_MAX)
529 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
530 return PyLong_FromLongLong(x);
531}
532
533static PyObject *
534nu_ulonglong(const char *p, const formatdef *f)
535{
536 unsigned PY_LONG_LONG x;
537 memcpy((char *)&x, p, sizeof x);
538 if (x <= LONG_MAX)
539 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
540 return PyLong_FromUnsignedLongLong(x);
541}
542
543#endif
544
545static PyObject *
Thomas Woutersb2137042007-02-01 18:02:27 +0000546nu_bool(const char *p, const formatdef *f)
547{
548 BOOL_TYPE x;
549 memcpy((char *)&x, p, sizeof x);
550 return PyBool_FromLong(x != 0);
551}
552
553
554static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000555nu_float(const char *p, const formatdef *f)
556{
557 float x;
558 memcpy((char *)&x, p, sizeof x);
559 return PyFloat_FromDouble((double)x);
560}
561
562static PyObject *
563nu_double(const char *p, const formatdef *f)
564{
565 double x;
566 memcpy((char *)&x, p, sizeof x);
567 return PyFloat_FromDouble(x);
568}
569
570static PyObject *
571nu_void_p(const char *p, const formatdef *f)
572{
573 void *x;
574 memcpy((char *)&x, p, sizeof x);
575 return PyLong_FromVoidPtr(x);
576}
577
578static int
579np_byte(char *p, PyObject *v, const formatdef *f)
580{
581 long x;
582 if (get_long(v, &x) < 0)
583 return -1;
584 if (x < -128 || x > 127){
585 PyErr_SetString(StructError,
586 "byte format requires -128 <= number <= 127");
587 return -1;
588 }
589 *p = (char)x;
590 return 0;
591}
592
593static int
594np_ubyte(char *p, PyObject *v, const formatdef *f)
595{
596 long x;
597 if (get_long(v, &x) < 0)
598 return -1;
599 if (x < 0 || x > 255){
600 PyErr_SetString(StructError,
601 "ubyte format requires 0 <= number <= 255");
602 return -1;
603 }
604 *p = (char)x;
605 return 0;
606}
607
608static int
609np_char(char *p, PyObject *v, const formatdef *f)
610{
611 if (!PyString_Check(v) || PyString_Size(v) != 1) {
612 PyErr_SetString(StructError,
613 "char format require string of length 1");
614 return -1;
615 }
616 *p = *PyString_AsString(v);
617 return 0;
618}
619
620static int
621np_short(char *p, PyObject *v, const formatdef *f)
622{
623 long x;
624 short y;
625 if (get_long(v, &x) < 0)
626 return -1;
627 if (x < SHRT_MIN || x > SHRT_MAX){
628 PyErr_SetString(StructError,
629 "short format requires " STRINGIFY(SHRT_MIN)
630 " <= number <= " STRINGIFY(SHRT_MAX));
631 return -1;
632 }
633 y = (short)x;
634 memcpy(p, (char *)&y, sizeof y);
635 return 0;
636}
637
638static int
639np_ushort(char *p, PyObject *v, const formatdef *f)
640{
641 long x;
642 unsigned short y;
643 if (get_long(v, &x) < 0)
644 return -1;
645 if (x < 0 || x > USHRT_MAX){
646 PyErr_SetString(StructError,
647 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
648 return -1;
649 }
650 y = (unsigned short)x;
651 memcpy(p, (char *)&y, sizeof y);
652 return 0;
653}
654
655static int
656np_int(char *p, PyObject *v, const formatdef *f)
657{
658 long x;
659 int y;
660 if (get_long(v, &x) < 0)
661 return -1;
662#if (SIZEOF_LONG > SIZEOF_INT)
663 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000664 return _range_error(f, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000665#endif
666 y = (int)x;
667 memcpy(p, (char *)&y, sizeof y);
668 return 0;
669}
670
671static int
672np_uint(char *p, PyObject *v, const formatdef *f)
673{
674 unsigned long x;
675 unsigned int y;
676 if (get_ulong(v, &x) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000677 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000678 y = (unsigned int)x;
679#if (SIZEOF_LONG > SIZEOF_INT)
680 if (x > ((unsigned long)UINT_MAX))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000681 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000682#endif
683 memcpy(p, (char *)&y, sizeof y);
684 return 0;
685}
686
687static int
688np_long(char *p, PyObject *v, const formatdef *f)
689{
690 long x;
691 if (get_long(v, &x) < 0)
692 return -1;
693 memcpy(p, (char *)&x, sizeof x);
694 return 0;
695}
696
697static int
698np_ulong(char *p, PyObject *v, const formatdef *f)
699{
700 unsigned long x;
701 if (get_ulong(v, &x) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000702 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000703 memcpy(p, (char *)&x, sizeof x);
704 return 0;
705}
706
707#ifdef HAVE_LONG_LONG
708
709static int
710np_longlong(char *p, PyObject *v, const formatdef *f)
711{
712 PY_LONG_LONG x;
713 if (get_longlong(v, &x) < 0)
714 return -1;
715 memcpy(p, (char *)&x, sizeof x);
716 return 0;
717}
718
719static int
720np_ulonglong(char *p, PyObject *v, const formatdef *f)
721{
722 unsigned PY_LONG_LONG x;
723 if (get_ulonglong(v, &x) < 0)
724 return -1;
725 memcpy(p, (char *)&x, sizeof x);
726 return 0;
727}
728#endif
729
Thomas Woutersb2137042007-02-01 18:02:27 +0000730
731static int
732np_bool(char *p, PyObject *v, const formatdef *f)
733{
734 BOOL_TYPE y;
735 y = PyObject_IsTrue(v);
736 memcpy(p, (char *)&y, sizeof y);
737 return 0;
738}
739
Thomas Wouters477c8d52006-05-27 19:21:47 +0000740static int
741np_float(char *p, PyObject *v, const formatdef *f)
742{
743 float x = (float)PyFloat_AsDouble(v);
744 if (x == -1 && PyErr_Occurred()) {
745 PyErr_SetString(StructError,
746 "required argument is not a float");
747 return -1;
748 }
749 memcpy(p, (char *)&x, sizeof x);
750 return 0;
751}
752
753static int
754np_double(char *p, PyObject *v, const formatdef *f)
755{
756 double x = PyFloat_AsDouble(v);
757 if (x == -1 && PyErr_Occurred()) {
758 PyErr_SetString(StructError,
759 "required argument is not a float");
760 return -1;
761 }
762 memcpy(p, (char *)&x, sizeof(double));
763 return 0;
764}
765
766static int
767np_void_p(char *p, PyObject *v, const formatdef *f)
768{
769 void *x;
770
771 v = get_pylong(v);
772 if (v == NULL)
773 return -1;
774 assert(PyLong_Check(v));
775 x = PyLong_AsVoidPtr(v);
776 Py_DECREF(v);
777 if (x == NULL && PyErr_Occurred())
778 return -1;
779 memcpy(p, (char *)&x, sizeof x);
780 return 0;
781}
782
783static formatdef native_table[] = {
784 {'x', sizeof(char), 0, NULL},
785 {'b', sizeof(char), 0, nu_byte, np_byte},
786 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
787 {'c', sizeof(char), 0, nu_char, np_char},
788 {'s', sizeof(char), 0, NULL},
789 {'p', sizeof(char), 0, NULL},
790 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
791 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
792 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
793 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
794 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
795 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
796#ifdef HAVE_LONG_LONG
797 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
798 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
799#endif
Thomas Woutersb2137042007-02-01 18:02:27 +0000800 {'t', sizeof(BOOL_TYPE), BOOL_ALIGN, nu_bool, np_bool},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000801 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
802 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
803 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
804 {0}
805};
806
807/* Big-endian routines. *****************************************************/
808
809static PyObject *
810bu_int(const char *p, const formatdef *f)
811{
812 long x = 0;
813 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000814 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000815 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000816 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000817 } while (--i > 0);
818 /* Extend the sign bit. */
819 if (SIZEOF_LONG > f->size)
820 x |= -(x & (1L << ((8 * f->size) - 1)));
821 return PyInt_FromLong(x);
822}
823
824static PyObject *
825bu_uint(const char *p, const formatdef *f)
826{
827 unsigned long x = 0;
828 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000829 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000830 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000831 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000832 } while (--i > 0);
833 if (x <= LONG_MAX)
834 return PyInt_FromLong((long)x);
835 return PyLong_FromUnsignedLong(x);
836}
837
838static PyObject *
839bu_longlong(const char *p, const formatdef *f)
840{
841#ifdef HAVE_LONG_LONG
842 PY_LONG_LONG x = 0;
843 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000844 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000845 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000846 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000847 } while (--i > 0);
848 /* Extend the sign bit. */
849 if (SIZEOF_LONG_LONG > f->size)
850 x |= -(x & (1L << ((8 * f->size) - 1)));
851 if (x >= LONG_MIN && x <= LONG_MAX)
852 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
853 return PyLong_FromLongLong(x);
854#else
855 return _PyLong_FromByteArray((const unsigned char *)p,
856 8,
857 0, /* little-endian */
858 1 /* signed */);
859#endif
860}
861
862static PyObject *
863bu_ulonglong(const char *p, const formatdef *f)
864{
865#ifdef HAVE_LONG_LONG
866 unsigned PY_LONG_LONG x = 0;
867 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000868 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000869 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000870 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000871 } while (--i > 0);
872 if (x <= LONG_MAX)
873 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
874 return PyLong_FromUnsignedLongLong(x);
875#else
876 return _PyLong_FromByteArray((const unsigned char *)p,
877 8,
878 0, /* little-endian */
879 0 /* signed */);
880#endif
881}
882
883static PyObject *
884bu_float(const char *p, const formatdef *f)
885{
886 return unpack_float(p, 0);
887}
888
889static PyObject *
890bu_double(const char *p, const formatdef *f)
891{
892 return unpack_double(p, 0);
893}
894
Thomas Woutersb2137042007-02-01 18:02:27 +0000895static PyObject *
896bu_bool(const char *p, const formatdef *f)
897{
898 char x;
899 memcpy((char *)&x, p, sizeof x);
900 return PyBool_FromLong(x != 0);
901}
902
Thomas Wouters477c8d52006-05-27 19:21:47 +0000903static int
904bp_int(char *p, PyObject *v, const formatdef *f)
905{
906 long x;
907 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000908 if (get_wrapped_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000909 return -1;
910 i = f->size;
911 if (i != SIZEOF_LONG) {
912 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000913 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000914#if (SIZEOF_LONG != 4)
915 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000916 RANGE_ERROR(x, f, 0, 0xffffffffL);
917#endif
918#ifdef PY_STRUCT_OVERFLOW_MASKING
919 else if ((i == 1) && (x < -128 || x > 127))
920 RANGE_ERROR(x, f, 0, 0xffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000921#endif
922 }
923 do {
924 p[--i] = (char)x;
925 x >>= 8;
926 } while (i > 0);
927 return 0;
928}
929
930static int
931bp_uint(char *p, PyObject *v, const formatdef *f)
932{
933 unsigned long x;
934 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000935 if (get_wrapped_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000936 return -1;
937 i = f->size;
938 if (i != SIZEOF_LONG) {
939 unsigned long maxint = 1;
940 maxint <<= (unsigned long)(i * 8);
941 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000942 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000943 }
944 do {
945 p[--i] = (char)x;
946 x >>= 8;
947 } while (i > 0);
948 return 0;
949}
950
951static int
952bp_longlong(char *p, PyObject *v, const formatdef *f)
953{
954 int res;
955 v = get_pylong(v);
956 if (v == NULL)
957 return -1;
958 res = _PyLong_AsByteArray((PyLongObject *)v,
959 (unsigned char *)p,
960 8,
961 0, /* little_endian */
962 1 /* signed */);
963 Py_DECREF(v);
964 return res;
965}
966
967static int
968bp_ulonglong(char *p, PyObject *v, const formatdef *f)
969{
970 int res;
971 v = get_pylong(v);
972 if (v == NULL)
973 return -1;
974 res = _PyLong_AsByteArray((PyLongObject *)v,
975 (unsigned char *)p,
976 8,
977 0, /* little_endian */
978 0 /* signed */);
979 Py_DECREF(v);
980 return res;
981}
982
983static int
984bp_float(char *p, PyObject *v, const formatdef *f)
985{
986 double x = PyFloat_AsDouble(v);
987 if (x == -1 && PyErr_Occurred()) {
988 PyErr_SetString(StructError,
989 "required argument is not a float");
990 return -1;
991 }
992 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
993}
994
995static int
996bp_double(char *p, PyObject *v, const formatdef *f)
997{
998 double x = PyFloat_AsDouble(v);
999 if (x == -1 && PyErr_Occurred()) {
1000 PyErr_SetString(StructError,
1001 "required argument is not a float");
1002 return -1;
1003 }
1004 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
1005}
1006
Thomas Woutersb2137042007-02-01 18:02:27 +00001007static int
1008bp_bool(char *p, PyObject *v, const formatdef *f)
1009{
1010 char y;
1011 y = PyObject_IsTrue(v);
1012 memcpy(p, (char *)&y, sizeof y);
1013 return 0;
1014}
1015
Thomas Wouters477c8d52006-05-27 19:21:47 +00001016static formatdef bigendian_table[] = {
1017 {'x', 1, 0, NULL},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001018#ifdef PY_STRUCT_OVERFLOW_MASKING
1019 /* Native packers do range checking without overflow masking. */
1020 {'b', 1, 0, nu_byte, bp_int},
1021 {'B', 1, 0, nu_ubyte, bp_uint},
1022#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001023 {'b', 1, 0, nu_byte, np_byte},
1024 {'B', 1, 0, nu_ubyte, np_ubyte},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001025#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001026 {'c', 1, 0, nu_char, np_char},
1027 {'s', 1, 0, NULL},
1028 {'p', 1, 0, NULL},
1029 {'h', 2, 0, bu_int, bp_int},
1030 {'H', 2, 0, bu_uint, bp_uint},
1031 {'i', 4, 0, bu_int, bp_int},
1032 {'I', 4, 0, bu_uint, bp_uint},
1033 {'l', 4, 0, bu_int, bp_int},
1034 {'L', 4, 0, bu_uint, bp_uint},
1035 {'q', 8, 0, bu_longlong, bp_longlong},
1036 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
Thomas Woutersb2137042007-02-01 18:02:27 +00001037 {'t', 1, 0, bu_bool, bp_bool},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001038 {'f', 4, 0, bu_float, bp_float},
1039 {'d', 8, 0, bu_double, bp_double},
1040 {0}
1041};
1042
1043/* Little-endian routines. *****************************************************/
1044
1045static PyObject *
1046lu_int(const char *p, const formatdef *f)
1047{
1048 long x = 0;
1049 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001050 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001051 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001052 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001053 } while (i > 0);
1054 /* Extend the sign bit. */
1055 if (SIZEOF_LONG > f->size)
1056 x |= -(x & (1L << ((8 * f->size) - 1)));
1057 return PyInt_FromLong(x);
1058}
1059
1060static PyObject *
1061lu_uint(const char *p, const formatdef *f)
1062{
1063 unsigned long x = 0;
1064 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001065 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001066 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001067 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001068 } while (i > 0);
1069 if (x <= LONG_MAX)
1070 return PyInt_FromLong((long)x);
1071 return PyLong_FromUnsignedLong((long)x);
1072}
1073
1074static PyObject *
1075lu_longlong(const char *p, const formatdef *f)
1076{
1077#ifdef HAVE_LONG_LONG
1078 PY_LONG_LONG x = 0;
1079 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001080 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001081 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001082 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001083 } while (i > 0);
1084 /* Extend the sign bit. */
1085 if (SIZEOF_LONG_LONG > f->size)
1086 x |= -(x & (1L << ((8 * f->size) - 1)));
1087 if (x >= LONG_MIN && x <= LONG_MAX)
1088 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
1089 return PyLong_FromLongLong(x);
1090#else
1091 return _PyLong_FromByteArray((const unsigned char *)p,
1092 8,
1093 1, /* little-endian */
1094 1 /* signed */);
1095#endif
1096}
1097
1098static PyObject *
1099lu_ulonglong(const char *p, const formatdef *f)
1100{
1101#ifdef HAVE_LONG_LONG
1102 unsigned PY_LONG_LONG x = 0;
1103 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001104 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001105 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001106 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001107 } while (i > 0);
1108 if (x <= LONG_MAX)
1109 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
1110 return PyLong_FromUnsignedLongLong(x);
1111#else
1112 return _PyLong_FromByteArray((const unsigned char *)p,
1113 8,
1114 1, /* little-endian */
1115 0 /* signed */);
1116#endif
1117}
1118
1119static PyObject *
1120lu_float(const char *p, const formatdef *f)
1121{
1122 return unpack_float(p, 1);
1123}
1124
1125static PyObject *
1126lu_double(const char *p, const formatdef *f)
1127{
1128 return unpack_double(p, 1);
1129}
1130
1131static int
1132lp_int(char *p, PyObject *v, const formatdef *f)
1133{
1134 long x;
1135 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001136 if (get_wrapped_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001137 return -1;
1138 i = f->size;
1139 if (i != SIZEOF_LONG) {
1140 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001141 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001142#if (SIZEOF_LONG != 4)
1143 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001144 RANGE_ERROR(x, f, 0, 0xffffffffL);
1145#endif
1146#ifdef PY_STRUCT_OVERFLOW_MASKING
1147 else if ((i == 1) && (x < -128 || x > 127))
1148 RANGE_ERROR(x, f, 0, 0xffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001149#endif
1150 }
1151 do {
1152 *p++ = (char)x;
1153 x >>= 8;
1154 } while (--i > 0);
1155 return 0;
1156}
1157
1158static int
1159lp_uint(char *p, PyObject *v, const formatdef *f)
1160{
1161 unsigned long x;
1162 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001163 if (get_wrapped_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001164 return -1;
1165 i = f->size;
1166 if (i != SIZEOF_LONG) {
1167 unsigned long maxint = 1;
1168 maxint <<= (unsigned long)(i * 8);
1169 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001170 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001171 }
1172 do {
1173 *p++ = (char)x;
1174 x >>= 8;
1175 } while (--i > 0);
1176 return 0;
1177}
1178
1179static int
1180lp_longlong(char *p, PyObject *v, const formatdef *f)
1181{
1182 int res;
1183 v = get_pylong(v);
1184 if (v == NULL)
1185 return -1;
1186 res = _PyLong_AsByteArray((PyLongObject*)v,
1187 (unsigned char *)p,
1188 8,
1189 1, /* little_endian */
1190 1 /* signed */);
1191 Py_DECREF(v);
1192 return res;
1193}
1194
1195static int
1196lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1197{
1198 int res;
1199 v = get_pylong(v);
1200 if (v == NULL)
1201 return -1;
1202 res = _PyLong_AsByteArray((PyLongObject*)v,
1203 (unsigned char *)p,
1204 8,
1205 1, /* little_endian */
1206 0 /* signed */);
1207 Py_DECREF(v);
1208 return res;
1209}
1210
1211static int
1212lp_float(char *p, PyObject *v, const formatdef *f)
1213{
1214 double x = PyFloat_AsDouble(v);
1215 if (x == -1 && PyErr_Occurred()) {
1216 PyErr_SetString(StructError,
1217 "required argument is not a float");
1218 return -1;
1219 }
1220 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1221}
1222
1223static int
1224lp_double(char *p, PyObject *v, const formatdef *f)
1225{
1226 double x = PyFloat_AsDouble(v);
1227 if (x == -1 && PyErr_Occurred()) {
1228 PyErr_SetString(StructError,
1229 "required argument is not a float");
1230 return -1;
1231 }
1232 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1233}
1234
1235static formatdef lilendian_table[] = {
1236 {'x', 1, 0, NULL},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001237#ifdef PY_STRUCT_OVERFLOW_MASKING
1238 /* Native packers do range checking without overflow masking. */
1239 {'b', 1, 0, nu_byte, lp_int},
1240 {'B', 1, 0, nu_ubyte, lp_uint},
1241#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001242 {'b', 1, 0, nu_byte, np_byte},
1243 {'B', 1, 0, nu_ubyte, np_ubyte},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001244#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001245 {'c', 1, 0, nu_char, np_char},
1246 {'s', 1, 0, NULL},
1247 {'p', 1, 0, NULL},
1248 {'h', 2, 0, lu_int, lp_int},
1249 {'H', 2, 0, lu_uint, lp_uint},
1250 {'i', 4, 0, lu_int, lp_int},
1251 {'I', 4, 0, lu_uint, lp_uint},
1252 {'l', 4, 0, lu_int, lp_int},
1253 {'L', 4, 0, lu_uint, lp_uint},
1254 {'q', 8, 0, lu_longlong, lp_longlong},
1255 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
Thomas Woutersb2137042007-02-01 18:02:27 +00001256 {'t', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1257 but potentially different from native rep -- reuse bx_bool funcs. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001258 {'f', 4, 0, lu_float, lp_float},
1259 {'d', 8, 0, lu_double, lp_double},
1260 {0}
1261};
1262
1263
1264static const formatdef *
1265whichtable(char **pfmt)
1266{
1267 const char *fmt = (*pfmt)++; /* May be backed out of later */
1268 switch (*fmt) {
1269 case '<':
1270 return lilendian_table;
1271 case '>':
1272 case '!': /* Network byte order is big-endian */
1273 return bigendian_table;
1274 case '=': { /* Host byte order -- different from native in aligment! */
1275 int n = 1;
1276 char *p = (char *) &n;
1277 if (*p == 1)
1278 return lilendian_table;
1279 else
1280 return bigendian_table;
1281 }
1282 default:
1283 --*pfmt; /* Back out of pointer increment */
1284 /* Fall through */
1285 case '@':
1286 return native_table;
1287 }
1288}
1289
1290
1291/* Get the table entry for a format code */
1292
1293static const formatdef *
1294getentry(int c, const formatdef *f)
1295{
1296 for (; f->format != '\0'; f++) {
1297 if (f->format == c) {
1298 return f;
1299 }
1300 }
1301 PyErr_SetString(StructError, "bad char in struct format");
1302 return NULL;
1303}
1304
1305
1306/* Align a size according to a format code */
1307
1308static int
1309align(Py_ssize_t size, char c, const formatdef *e)
1310{
1311 if (e->format == c) {
1312 if (e->alignment) {
1313 size = ((size + e->alignment - 1)
1314 / e->alignment)
1315 * e->alignment;
1316 }
1317 }
1318 return size;
1319}
1320
1321
1322/* calculate the size of a format string */
1323
1324static int
1325prepare_s(PyStructObject *self)
1326{
1327 const formatdef *f;
1328 const formatdef *e;
1329 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001330
Thomas Wouters477c8d52006-05-27 19:21:47 +00001331 const char *s;
1332 const char *fmt;
1333 char c;
1334 Py_ssize_t size, len, num, itemsize, x;
1335
1336 fmt = PyString_AS_STRING(self->s_format);
1337
1338 f = whichtable((char **)&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001339
Thomas Wouters477c8d52006-05-27 19:21:47 +00001340 s = fmt;
1341 size = 0;
1342 len = 0;
1343 while ((c = *s++) != '\0') {
1344 if (isspace(Py_CHARMASK(c)))
1345 continue;
1346 if ('0' <= c && c <= '9') {
1347 num = c - '0';
1348 while ('0' <= (c = *s++) && c <= '9') {
1349 x = num*10 + (c - '0');
1350 if (x/10 != num) {
1351 PyErr_SetString(
1352 StructError,
1353 "overflow in item count");
1354 return -1;
1355 }
1356 num = x;
1357 }
1358 if (c == '\0')
1359 break;
1360 }
1361 else
1362 num = 1;
1363
1364 e = getentry(c, f);
1365 if (e == NULL)
1366 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001367
Thomas Wouters477c8d52006-05-27 19:21:47 +00001368 switch (c) {
1369 case 's': /* fall through */
1370 case 'p': len++; break;
1371 case 'x': break;
1372 default: len += num; break;
1373 }
1374
1375 itemsize = e->size;
1376 size = align(size, c, e);
1377 x = num * itemsize;
1378 size += x;
1379 if (x/itemsize != num || size < 0) {
1380 PyErr_SetString(StructError,
1381 "total struct size too long");
1382 return -1;
1383 }
1384 }
1385
1386 self->s_size = size;
1387 self->s_len = len;
1388 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1389 if (codes == NULL) {
1390 PyErr_NoMemory();
1391 return -1;
1392 }
1393 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001394
Thomas Wouters477c8d52006-05-27 19:21:47 +00001395 s = fmt;
1396 size = 0;
1397 while ((c = *s++) != '\0') {
1398 if (isspace(Py_CHARMASK(c)))
1399 continue;
1400 if ('0' <= c && c <= '9') {
1401 num = c - '0';
1402 while ('0' <= (c = *s++) && c <= '9')
1403 num = num*10 + (c - '0');
1404 if (c == '\0')
1405 break;
1406 }
1407 else
1408 num = 1;
1409
1410 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001411
Thomas Wouters477c8d52006-05-27 19:21:47 +00001412 size = align(size, c, e);
1413 if (c == 's' || c == 'p') {
1414 codes->offset = size;
1415 codes->size = num;
1416 codes->fmtdef = e;
1417 codes++;
1418 size += num;
1419 } else if (c == 'x') {
1420 size += num;
1421 } else {
1422 while (--num >= 0) {
1423 codes->offset = size;
1424 codes->size = e->size;
1425 codes->fmtdef = e;
1426 codes++;
1427 size += e->size;
1428 }
1429 }
1430 }
1431 codes->fmtdef = NULL;
1432 codes->offset = size;
1433 codes->size = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001434
Thomas Wouters477c8d52006-05-27 19:21:47 +00001435 return 0;
1436}
1437
1438static PyObject *
1439s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1440{
1441 PyObject *self;
1442
1443 assert(type != NULL && type->tp_alloc != NULL);
1444
1445 self = type->tp_alloc(type, 0);
1446 if (self != NULL) {
1447 PyStructObject *s = (PyStructObject*)self;
1448 Py_INCREF(Py_None);
1449 s->s_format = Py_None;
1450 s->s_codes = NULL;
1451 s->s_size = -1;
1452 s->s_len = -1;
1453 }
1454 return self;
1455}
1456
1457static int
1458s_init(PyObject *self, PyObject *args, PyObject *kwds)
1459{
1460 PyStructObject *soself = (PyStructObject *)self;
1461 PyObject *o_format = NULL;
1462 int ret = 0;
1463 static char *kwlist[] = {"format", 0};
1464
1465 assert(PyStruct_Check(self));
1466
1467 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1468 &o_format))
1469 return -1;
1470
1471 Py_INCREF(o_format);
1472 Py_XDECREF(soself->s_format);
1473 soself->s_format = o_format;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001474
Thomas Wouters477c8d52006-05-27 19:21:47 +00001475 ret = prepare_s(soself);
1476 return ret;
1477}
1478
1479static void
1480s_dealloc(PyStructObject *s)
1481{
1482 if (s->weakreflist != NULL)
1483 PyObject_ClearWeakRefs((PyObject *)s);
1484 if (s->s_codes != NULL) {
1485 PyMem_FREE(s->s_codes);
1486 }
1487 Py_XDECREF(s->s_format);
1488 s->ob_type->tp_free((PyObject *)s);
1489}
1490
1491static PyObject *
1492s_unpack_internal(PyStructObject *soself, char *startfrom) {
1493 formatcode *code;
1494 Py_ssize_t i = 0;
1495 PyObject *result = PyTuple_New(soself->s_len);
1496 if (result == NULL)
1497 return NULL;
1498
1499 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1500 PyObject *v;
1501 const formatdef *e = code->fmtdef;
1502 const char *res = startfrom + code->offset;
1503 if (e->format == 's') {
1504 v = PyString_FromStringAndSize(res, code->size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001505 } else if (e->format == 'p') {
1506 Py_ssize_t n = *(unsigned char*)res;
1507 if (n >= code->size)
1508 n = code->size - 1;
1509 v = PyString_FromStringAndSize(res + 1, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510 } else {
1511 v = e->unpack(res, e);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001512 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001513 if (v == NULL)
1514 goto fail;
1515 PyTuple_SET_ITEM(result, i++, v);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001516 }
1517
1518 return result;
1519fail:
1520 Py_DECREF(result);
1521 return NULL;
1522}
1523
1524
1525PyDoc_STRVAR(s_unpack__doc__,
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001526"S.unpack(buffer) -> (v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001527\n\
1528Return tuple containing values unpacked according to this Struct's format.\n\
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001529Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001530strings.");
1531
1532static PyObject *
1533s_unpack(PyObject *self, PyObject *inputstr)
1534{
1535 PyStructObject *soself = (PyStructObject *)self;
1536 assert(PyStruct_Check(self));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001537 assert(soself->s_codes != NULL);
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001538 if (inputstr != NULL && PyBytes_Check(inputstr) &&
1539 PyBytes_GET_SIZE(inputstr) == soself->s_size) {
1540 return s_unpack_internal(soself, PyBytes_AS_STRING(inputstr));
1541 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001542 if (inputstr == NULL || !PyString_Check(inputstr) ||
1543 PyString_GET_SIZE(inputstr) != soself->s_size) {
1544 PyErr_Format(StructError,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001545 "unpack requires a string argument of length %zd",
1546 soself->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001547 return NULL;
1548 }
1549 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1550}
1551
1552PyDoc_STRVAR(s_unpack_from__doc__,
1553"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1554\n\
1555Return tuple containing values unpacked according to this Struct's format.\n\
1556Unlike unpack, unpack_from can unpack values from any object supporting\n\
1557the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1558See struct.__doc__ for more on format strings.");
1559
1560static PyObject *
1561s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1562{
1563 static char *kwlist[] = {"buffer", "offset", 0};
1564#if (PY_VERSION_HEX < 0x02050000)
1565 static char *fmt = "z#|i:unpack_from";
1566#else
1567 static char *fmt = "z#|n:unpack_from";
1568#endif
1569 Py_ssize_t buffer_len = 0, offset = 0;
1570 char *buffer = NULL;
1571 PyStructObject *soself = (PyStructObject *)self;
1572 assert(PyStruct_Check(self));
1573 assert(soself->s_codes != NULL);
1574
1575 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1576 &buffer, &buffer_len, &offset))
1577 return NULL;
1578
1579 if (buffer == NULL) {
1580 PyErr_Format(StructError,
1581 "unpack_from requires a buffer argument");
1582 return NULL;
1583 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001584
Thomas Wouters477c8d52006-05-27 19:21:47 +00001585 if (offset < 0)
1586 offset += buffer_len;
1587
1588 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1589 PyErr_Format(StructError,
1590 "unpack_from requires a buffer of at least %zd bytes",
1591 soself->s_size);
1592 return NULL;
1593 }
1594 return s_unpack_internal(soself, buffer + offset);
1595}
1596
1597
1598/*
1599 * Guts of the pack function.
1600 *
1601 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1602 * argument for where to start processing the arguments for packing, and a
1603 * character buffer for writing the packed string. The caller must insure
1604 * that the buffer may contain the required length for packing the arguments.
1605 * 0 is returned on success, 1 is returned if there is an error.
1606 *
1607 */
1608static int
1609s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1610{
1611 formatcode *code;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001612 /* XXX(nnorwitz): why does i need to be a local? can we use
1613 the offset parameter or do we need the wider width? */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001614 Py_ssize_t i;
1615
1616 memset(buf, '\0', soself->s_size);
1617 i = offset;
1618 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1619 Py_ssize_t n;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001620 PyObject *v = PyTuple_GET_ITEM(args, i++);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001621 const formatdef *e = code->fmtdef;
1622 char *res = buf + code->offset;
1623 if (e->format == 's') {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001624 if (!PyString_Check(v)) {
1625 PyErr_SetString(StructError,
1626 "argument for 's' must be a string");
1627 return -1;
1628 }
1629 n = PyString_GET_SIZE(v);
1630 if (n > code->size)
1631 n = code->size;
1632 if (n > 0)
1633 memcpy(res, PyString_AS_STRING(v), n);
1634 } else if (e->format == 'p') {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001635 if (!PyString_Check(v)) {
1636 PyErr_SetString(StructError,
1637 "argument for 'p' must be a string");
1638 return -1;
1639 }
1640 n = PyString_GET_SIZE(v);
1641 if (n > (code->size - 1))
1642 n = code->size - 1;
1643 if (n > 0)
1644 memcpy(res + 1, PyString_AS_STRING(v), n);
1645 if (n > 255)
1646 n = 255;
1647 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1648 } else {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001649 if (e->pack(res, v, e) < 0) {
1650 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1651 PyErr_SetString(StructError,
1652 "long too large to convert to int");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001653 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001654 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001655 }
1656 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001657
Thomas Wouters477c8d52006-05-27 19:21:47 +00001658 /* Success */
1659 return 0;
1660}
1661
1662
1663PyDoc_STRVAR(s_pack__doc__,
1664"S.pack(v1, v2, ...) -> string\n\
1665\n\
1666Return a string containing values v1, v2, ... packed according to this\n\
1667Struct's format. See struct.__doc__ for more on format strings.");
1668
1669static PyObject *
1670s_pack(PyObject *self, PyObject *args)
1671{
1672 PyStructObject *soself;
1673 PyObject *result;
1674
1675 /* Validate arguments. */
1676 soself = (PyStructObject *)self;
1677 assert(PyStruct_Check(self));
1678 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001679 if (PyTuple_GET_SIZE(args) != soself->s_len)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001680 {
1681 PyErr_Format(StructError,
1682 "pack requires exactly %zd arguments", soself->s_len);
1683 return NULL;
1684 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001685
Thomas Wouters477c8d52006-05-27 19:21:47 +00001686 /* Allocate a new string */
1687 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1688 if (result == NULL)
1689 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001690
Thomas Wouters477c8d52006-05-27 19:21:47 +00001691 /* Call the guts */
1692 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1693 Py_DECREF(result);
1694 return NULL;
1695 }
1696
1697 return result;
1698}
1699
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001700PyDoc_STRVAR(s_pack_into__doc__,
1701"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001702\n\
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001703Pack the values v1, v2, ... according to this Struct's format, write \n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001704the packed bytes into the writable buffer buf starting at offset. Note\n\
1705that the offset is not an optional argument. See struct.__doc__ for \n\
1706more on format strings.");
1707
1708static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001709s_pack_into(PyObject *self, PyObject *args)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001710{
1711 PyStructObject *soself;
1712 char *buffer;
1713 Py_ssize_t buffer_len, offset;
1714
1715 /* Validate arguments. +1 is for the first arg as buffer. */
1716 soself = (PyStructObject *)self;
1717 assert(PyStruct_Check(self));
1718 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001719 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001720 {
1721 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001722 "pack_into requires exactly %zd arguments",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001723 (soself->s_len + 2));
1724 return NULL;
1725 }
1726
1727 /* Extract a writable memory buffer from the first argument */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001728 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1729 (void**)&buffer, &buffer_len) == -1 ) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001730 return NULL;
1731 }
1732 assert( buffer_len >= 0 );
1733
1734 /* Extract the offset from the first argument */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001735 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001736
1737 /* Support negative offsets. */
1738 if (offset < 0)
1739 offset += buffer_len;
1740
1741 /* Check boundaries */
1742 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1743 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001744 "pack_into requires a buffer of at least %zd bytes",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001745 soself->s_size);
1746 return NULL;
1747 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001748
Thomas Wouters477c8d52006-05-27 19:21:47 +00001749 /* Call the guts */
1750 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1751 return NULL;
1752 }
1753
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001754 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001755}
1756
1757static PyObject *
1758s_get_format(PyStructObject *self, void *unused)
1759{
1760 Py_INCREF(self->s_format);
1761 return self->s_format;
1762}
1763
1764static PyObject *
1765s_get_size(PyStructObject *self, void *unused)
1766{
1767 return PyInt_FromSsize_t(self->s_size);
1768}
1769
1770/* List of functions */
1771
1772static struct PyMethodDef s_methods[] = {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001773 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1774 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1775 {"unpack", s_unpack, METH_O, s_unpack__doc__},
1776 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS,
1777 s_unpack_from__doc__},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001778 {NULL, NULL} /* sentinel */
1779};
1780
1781PyDoc_STRVAR(s__doc__, "Compiled struct object");
1782
1783#define OFF(x) offsetof(PyStructObject, x)
1784
1785static PyGetSetDef s_getsetlist[] = {
1786 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1787 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1788 {NULL} /* sentinel */
1789};
1790
1791static
1792PyTypeObject PyStructType = {
1793 PyObject_HEAD_INIT(NULL)
1794 0,
1795 "Struct",
1796 sizeof(PyStructObject),
1797 0,
1798 (destructor)s_dealloc, /* tp_dealloc */
1799 0, /* tp_print */
1800 0, /* tp_getattr */
1801 0, /* tp_setattr */
1802 0, /* tp_compare */
1803 0, /* tp_repr */
1804 0, /* tp_as_number */
1805 0, /* tp_as_sequence */
1806 0, /* tp_as_mapping */
1807 0, /* tp_hash */
1808 0, /* tp_call */
1809 0, /* tp_str */
1810 PyObject_GenericGetAttr, /* tp_getattro */
1811 PyObject_GenericSetAttr, /* tp_setattro */
1812 0, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +00001813 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001814 s__doc__, /* tp_doc */
1815 0, /* tp_traverse */
1816 0, /* tp_clear */
1817 0, /* tp_richcompare */
1818 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1819 0, /* tp_iter */
1820 0, /* tp_iternext */
1821 s_methods, /* tp_methods */
1822 NULL, /* tp_members */
1823 s_getsetlist, /* tp_getset */
1824 0, /* tp_base */
1825 0, /* tp_dict */
1826 0, /* tp_descr_get */
1827 0, /* tp_descr_set */
1828 0, /* tp_dictoffset */
1829 s_init, /* tp_init */
1830 PyType_GenericAlloc,/* tp_alloc */
1831 s_new, /* tp_new */
1832 PyObject_Del, /* tp_free */
1833};
1834
1835/* Module initialization */
1836
1837PyMODINIT_FUNC
1838init_struct(void)
1839{
1840 PyObject *m = Py_InitModule("_struct", NULL);
1841 if (m == NULL)
1842 return;
1843
1844 PyStructType.ob_type = &PyType_Type;
1845 if (PyType_Ready(&PyStructType) < 0)
1846 return;
1847
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001848#ifdef PY_STRUCT_OVERFLOW_MASKING
1849 if (pyint_zero == NULL) {
1850 pyint_zero = PyInt_FromLong(0);
1851 if (pyint_zero == NULL)
1852 return;
1853 }
1854 if (pylong_ulong_mask == NULL) {
1855#if (SIZEOF_LONG == 4)
1856 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1857#else
1858 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1859#endif
1860 if (pylong_ulong_mask == NULL)
1861 return;
1862 }
1863
1864#else
1865 /* This speed trick can't be used until overflow masking goes away, because
1866 native endian always raises exceptions instead of overflow masking. */
1867
Thomas Wouters477c8d52006-05-27 19:21:47 +00001868 /* Check endian and swap in faster functions */
1869 {
1870 int one = 1;
1871 formatdef *native = native_table;
1872 formatdef *other, *ptr;
1873 if ((int)*(unsigned char*)&one)
1874 other = lilendian_table;
1875 else
1876 other = bigendian_table;
1877 /* Scan through the native table, find a matching
1878 entry in the endian table and swap in the
1879 native implementations whenever possible
1880 (64-bit platforms may not have "standard" sizes) */
1881 while (native->format != '\0' && other->format != '\0') {
1882 ptr = other;
1883 while (ptr->format != '\0') {
1884 if (ptr->format == native->format) {
1885 /* Match faster when formats are
1886 listed in the same order */
1887 if (ptr == other)
1888 other++;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001889 /* Only use the trick if the
Thomas Wouters477c8d52006-05-27 19:21:47 +00001890 size matches */
1891 if (ptr->size != native->size)
1892 break;
1893 /* Skip float and double, could be
1894 "unknown" float format */
1895 if (ptr->format == 'd' || ptr->format == 'f')
1896 break;
1897 ptr->pack = native->pack;
1898 ptr->unpack = native->unpack;
1899 break;
1900 }
1901 ptr++;
1902 }
1903 native++;
1904 }
1905 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001906#endif
1907
Thomas Wouters477c8d52006-05-27 19:21:47 +00001908 /* Add some symbolic constants to the module */
1909 if (StructError == NULL) {
1910 StructError = PyErr_NewException("struct.error", NULL, NULL);
1911 if (StructError == NULL)
1912 return;
1913 }
1914
1915 Py_INCREF(StructError);
1916 PyModule_AddObject(m, "error", StructError);
1917
1918 Py_INCREF((PyObject*)&PyStructType);
1919 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001920
1921 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
1922#ifdef PY_STRUCT_OVERFLOW_MASKING
1923 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
1924#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001925#ifdef PY_STRUCT_FLOAT_COERCE
1926 PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
1927#endif
1928
Thomas Wouters477c8d52006-05-27 19:21:47 +00001929}