blob: 3418c307be89f41f040dba8244d7679e044a61b9 [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__,
1526"S.unpack(str) -> (v1, v2, ...)\n\
1527\n\
1528Return tuple containing values unpacked according to this Struct's format.\n\
1529Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1530strings.");
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);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001538 if (inputstr == NULL || !PyString_Check(inputstr) ||
1539 PyString_GET_SIZE(inputstr) != soself->s_size) {
1540 PyErr_Format(StructError,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001541 "unpack requires a string argument of length %zd",
1542 soself->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001543 return NULL;
1544 }
1545 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1546}
1547
1548PyDoc_STRVAR(s_unpack_from__doc__,
1549"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1550\n\
1551Return tuple containing values unpacked according to this Struct's format.\n\
1552Unlike unpack, unpack_from can unpack values from any object supporting\n\
1553the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1554See struct.__doc__ for more on format strings.");
1555
1556static PyObject *
1557s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1558{
1559 static char *kwlist[] = {"buffer", "offset", 0};
1560#if (PY_VERSION_HEX < 0x02050000)
1561 static char *fmt = "z#|i:unpack_from";
1562#else
1563 static char *fmt = "z#|n:unpack_from";
1564#endif
1565 Py_ssize_t buffer_len = 0, offset = 0;
1566 char *buffer = NULL;
1567 PyStructObject *soself = (PyStructObject *)self;
1568 assert(PyStruct_Check(self));
1569 assert(soself->s_codes != NULL);
1570
1571 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1572 &buffer, &buffer_len, &offset))
1573 return NULL;
1574
1575 if (buffer == NULL) {
1576 PyErr_Format(StructError,
1577 "unpack_from requires a buffer argument");
1578 return NULL;
1579 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001580
Thomas Wouters477c8d52006-05-27 19:21:47 +00001581 if (offset < 0)
1582 offset += buffer_len;
1583
1584 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1585 PyErr_Format(StructError,
1586 "unpack_from requires a buffer of at least %zd bytes",
1587 soself->s_size);
1588 return NULL;
1589 }
1590 return s_unpack_internal(soself, buffer + offset);
1591}
1592
1593
1594/*
1595 * Guts of the pack function.
1596 *
1597 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1598 * argument for where to start processing the arguments for packing, and a
1599 * character buffer for writing the packed string. The caller must insure
1600 * that the buffer may contain the required length for packing the arguments.
1601 * 0 is returned on success, 1 is returned if there is an error.
1602 *
1603 */
1604static int
1605s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1606{
1607 formatcode *code;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001608 /* XXX(nnorwitz): why does i need to be a local? can we use
1609 the offset parameter or do we need the wider width? */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001610 Py_ssize_t i;
1611
1612 memset(buf, '\0', soself->s_size);
1613 i = offset;
1614 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1615 Py_ssize_t n;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001616 PyObject *v = PyTuple_GET_ITEM(args, i++);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001617 const formatdef *e = code->fmtdef;
1618 char *res = buf + code->offset;
1619 if (e->format == 's') {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001620 if (!PyString_Check(v)) {
1621 PyErr_SetString(StructError,
1622 "argument for 's' must be a string");
1623 return -1;
1624 }
1625 n = PyString_GET_SIZE(v);
1626 if (n > code->size)
1627 n = code->size;
1628 if (n > 0)
1629 memcpy(res, PyString_AS_STRING(v), n);
1630 } else if (e->format == 'p') {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001631 if (!PyString_Check(v)) {
1632 PyErr_SetString(StructError,
1633 "argument for 'p' must be a string");
1634 return -1;
1635 }
1636 n = PyString_GET_SIZE(v);
1637 if (n > (code->size - 1))
1638 n = code->size - 1;
1639 if (n > 0)
1640 memcpy(res + 1, PyString_AS_STRING(v), n);
1641 if (n > 255)
1642 n = 255;
1643 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1644 } else {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001645 if (e->pack(res, v, e) < 0) {
1646 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1647 PyErr_SetString(StructError,
1648 "long too large to convert to int");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001649 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001650 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001651 }
1652 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001653
Thomas Wouters477c8d52006-05-27 19:21:47 +00001654 /* Success */
1655 return 0;
1656}
1657
1658
1659PyDoc_STRVAR(s_pack__doc__,
1660"S.pack(v1, v2, ...) -> string\n\
1661\n\
1662Return a string containing values v1, v2, ... packed according to this\n\
1663Struct's format. See struct.__doc__ for more on format strings.");
1664
1665static PyObject *
1666s_pack(PyObject *self, PyObject *args)
1667{
1668 PyStructObject *soself;
1669 PyObject *result;
1670
1671 /* Validate arguments. */
1672 soself = (PyStructObject *)self;
1673 assert(PyStruct_Check(self));
1674 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001675 if (PyTuple_GET_SIZE(args) != soself->s_len)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001676 {
1677 PyErr_Format(StructError,
1678 "pack requires exactly %zd arguments", soself->s_len);
1679 return NULL;
1680 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001681
Thomas Wouters477c8d52006-05-27 19:21:47 +00001682 /* Allocate a new string */
1683 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1684 if (result == NULL)
1685 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001686
Thomas Wouters477c8d52006-05-27 19:21:47 +00001687 /* Call the guts */
1688 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1689 Py_DECREF(result);
1690 return NULL;
1691 }
1692
1693 return result;
1694}
1695
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001696PyDoc_STRVAR(s_pack_into__doc__,
1697"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001698\n\
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001699Pack the values v1, v2, ... according to this Struct's format, write \n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001700the packed bytes into the writable buffer buf starting at offset. Note\n\
1701that the offset is not an optional argument. See struct.__doc__ for \n\
1702more on format strings.");
1703
1704static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001705s_pack_into(PyObject *self, PyObject *args)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001706{
1707 PyStructObject *soself;
1708 char *buffer;
1709 Py_ssize_t buffer_len, offset;
1710
1711 /* Validate arguments. +1 is for the first arg as buffer. */
1712 soself = (PyStructObject *)self;
1713 assert(PyStruct_Check(self));
1714 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001715 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001716 {
1717 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001718 "pack_into requires exactly %zd arguments",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001719 (soself->s_len + 2));
1720 return NULL;
1721 }
1722
1723 /* Extract a writable memory buffer from the first argument */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001724 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1725 (void**)&buffer, &buffer_len) == -1 ) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001726 return NULL;
1727 }
1728 assert( buffer_len >= 0 );
1729
1730 /* Extract the offset from the first argument */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001731 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001732
1733 /* Support negative offsets. */
1734 if (offset < 0)
1735 offset += buffer_len;
1736
1737 /* Check boundaries */
1738 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1739 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001740 "pack_into requires a buffer of at least %zd bytes",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001741 soself->s_size);
1742 return NULL;
1743 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001744
Thomas Wouters477c8d52006-05-27 19:21:47 +00001745 /* Call the guts */
1746 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1747 return NULL;
1748 }
1749
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001750 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001751}
1752
1753static PyObject *
1754s_get_format(PyStructObject *self, void *unused)
1755{
1756 Py_INCREF(self->s_format);
1757 return self->s_format;
1758}
1759
1760static PyObject *
1761s_get_size(PyStructObject *self, void *unused)
1762{
1763 return PyInt_FromSsize_t(self->s_size);
1764}
1765
1766/* List of functions */
1767
1768static struct PyMethodDef s_methods[] = {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001769 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1770 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1771 {"unpack", s_unpack, METH_O, s_unpack__doc__},
1772 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS,
1773 s_unpack_from__doc__},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001774 {NULL, NULL} /* sentinel */
1775};
1776
1777PyDoc_STRVAR(s__doc__, "Compiled struct object");
1778
1779#define OFF(x) offsetof(PyStructObject, x)
1780
1781static PyGetSetDef s_getsetlist[] = {
1782 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1783 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1784 {NULL} /* sentinel */
1785};
1786
1787static
1788PyTypeObject PyStructType = {
1789 PyObject_HEAD_INIT(NULL)
1790 0,
1791 "Struct",
1792 sizeof(PyStructObject),
1793 0,
1794 (destructor)s_dealloc, /* tp_dealloc */
1795 0, /* tp_print */
1796 0, /* tp_getattr */
1797 0, /* tp_setattr */
1798 0, /* tp_compare */
1799 0, /* tp_repr */
1800 0, /* tp_as_number */
1801 0, /* tp_as_sequence */
1802 0, /* tp_as_mapping */
1803 0, /* tp_hash */
1804 0, /* tp_call */
1805 0, /* tp_str */
1806 PyObject_GenericGetAttr, /* tp_getattro */
1807 PyObject_GenericSetAttr, /* tp_setattro */
1808 0, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +00001809 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001810 s__doc__, /* tp_doc */
1811 0, /* tp_traverse */
1812 0, /* tp_clear */
1813 0, /* tp_richcompare */
1814 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1815 0, /* tp_iter */
1816 0, /* tp_iternext */
1817 s_methods, /* tp_methods */
1818 NULL, /* tp_members */
1819 s_getsetlist, /* tp_getset */
1820 0, /* tp_base */
1821 0, /* tp_dict */
1822 0, /* tp_descr_get */
1823 0, /* tp_descr_set */
1824 0, /* tp_dictoffset */
1825 s_init, /* tp_init */
1826 PyType_GenericAlloc,/* tp_alloc */
1827 s_new, /* tp_new */
1828 PyObject_Del, /* tp_free */
1829};
1830
1831/* Module initialization */
1832
1833PyMODINIT_FUNC
1834init_struct(void)
1835{
1836 PyObject *m = Py_InitModule("_struct", NULL);
1837 if (m == NULL)
1838 return;
1839
1840 PyStructType.ob_type = &PyType_Type;
1841 if (PyType_Ready(&PyStructType) < 0)
1842 return;
1843
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001844#ifdef PY_STRUCT_OVERFLOW_MASKING
1845 if (pyint_zero == NULL) {
1846 pyint_zero = PyInt_FromLong(0);
1847 if (pyint_zero == NULL)
1848 return;
1849 }
1850 if (pylong_ulong_mask == NULL) {
1851#if (SIZEOF_LONG == 4)
1852 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1853#else
1854 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1855#endif
1856 if (pylong_ulong_mask == NULL)
1857 return;
1858 }
1859
1860#else
1861 /* This speed trick can't be used until overflow masking goes away, because
1862 native endian always raises exceptions instead of overflow masking. */
1863
Thomas Wouters477c8d52006-05-27 19:21:47 +00001864 /* Check endian and swap in faster functions */
1865 {
1866 int one = 1;
1867 formatdef *native = native_table;
1868 formatdef *other, *ptr;
1869 if ((int)*(unsigned char*)&one)
1870 other = lilendian_table;
1871 else
1872 other = bigendian_table;
1873 /* Scan through the native table, find a matching
1874 entry in the endian table and swap in the
1875 native implementations whenever possible
1876 (64-bit platforms may not have "standard" sizes) */
1877 while (native->format != '\0' && other->format != '\0') {
1878 ptr = other;
1879 while (ptr->format != '\0') {
1880 if (ptr->format == native->format) {
1881 /* Match faster when formats are
1882 listed in the same order */
1883 if (ptr == other)
1884 other++;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001885 /* Only use the trick if the
Thomas Wouters477c8d52006-05-27 19:21:47 +00001886 size matches */
1887 if (ptr->size != native->size)
1888 break;
1889 /* Skip float and double, could be
1890 "unknown" float format */
1891 if (ptr->format == 'd' || ptr->format == 'f')
1892 break;
1893 ptr->pack = native->pack;
1894 ptr->unpack = native->unpack;
1895 break;
1896 }
1897 ptr++;
1898 }
1899 native++;
1900 }
1901 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001902#endif
1903
Thomas Wouters477c8d52006-05-27 19:21:47 +00001904 /* Add some symbolic constants to the module */
1905 if (StructError == NULL) {
1906 StructError = PyErr_NewException("struct.error", NULL, NULL);
1907 if (StructError == NULL)
1908 return;
1909 }
1910
1911 Py_INCREF(StructError);
1912 PyModule_AddObject(m, "error", StructError);
1913
1914 Py_INCREF((PyObject*)&PyStructType);
1915 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001916
1917 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
1918#ifdef PY_STRUCT_OVERFLOW_MASKING
1919 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
1920#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001921#ifdef PY_STRUCT_FLOAT_COERCE
1922 PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
1923#endif
1924
Thomas Wouters477c8d52006-05-27 19:21:47 +00001925}