blob: 84aa82843c997ee940fcaee6e569214614ed461c [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)
Martin v. Löwis9f2e3462007-07-21 17:22:18 +000075#define PyStruct_CheckExact(op) (Py_Type(op) == &PyStructType)
Thomas Wouters477c8d52006-05-27 19:21:47 +000076
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 }
Martin v. Löwis9f2e3462007-07-21 17:22:18 +0000134 m = Py_Type(v)->tp_as_number;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000135 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{
Guido van Rossume625fd52007-05-27 09:19:04 +0000611 if (PyUnicode_Check(v)) {
612 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
613 if (v == NULL)
614 return -1;
615 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000616 if (!PyString_Check(v) || PyString_Size(v) != 1) {
617 PyErr_SetString(StructError,
Guido van Rossume625fd52007-05-27 09:19:04 +0000618 "char format requires string of length 1");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000619 return -1;
620 }
621 *p = *PyString_AsString(v);
622 return 0;
623}
624
625static int
626np_short(char *p, PyObject *v, const formatdef *f)
627{
628 long x;
629 short y;
630 if (get_long(v, &x) < 0)
631 return -1;
632 if (x < SHRT_MIN || x > SHRT_MAX){
633 PyErr_SetString(StructError,
634 "short format requires " STRINGIFY(SHRT_MIN)
635 " <= number <= " STRINGIFY(SHRT_MAX));
636 return -1;
637 }
638 y = (short)x;
639 memcpy(p, (char *)&y, sizeof y);
640 return 0;
641}
642
643static int
644np_ushort(char *p, PyObject *v, const formatdef *f)
645{
646 long x;
647 unsigned short y;
648 if (get_long(v, &x) < 0)
649 return -1;
650 if (x < 0 || x > USHRT_MAX){
651 PyErr_SetString(StructError,
652 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
653 return -1;
654 }
655 y = (unsigned short)x;
656 memcpy(p, (char *)&y, sizeof y);
657 return 0;
658}
659
660static int
661np_int(char *p, PyObject *v, const formatdef *f)
662{
663 long x;
664 int y;
665 if (get_long(v, &x) < 0)
666 return -1;
667#if (SIZEOF_LONG > SIZEOF_INT)
668 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000669 return _range_error(f, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000670#endif
671 y = (int)x;
672 memcpy(p, (char *)&y, sizeof y);
673 return 0;
674}
675
676static int
677np_uint(char *p, PyObject *v, const formatdef *f)
678{
679 unsigned long x;
680 unsigned int y;
681 if (get_ulong(v, &x) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000682 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000683 y = (unsigned int)x;
684#if (SIZEOF_LONG > SIZEOF_INT)
685 if (x > ((unsigned long)UINT_MAX))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000686 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000687#endif
688 memcpy(p, (char *)&y, sizeof y);
689 return 0;
690}
691
692static int
693np_long(char *p, PyObject *v, const formatdef *f)
694{
695 long x;
696 if (get_long(v, &x) < 0)
697 return -1;
698 memcpy(p, (char *)&x, sizeof x);
699 return 0;
700}
701
702static int
703np_ulong(char *p, PyObject *v, const formatdef *f)
704{
705 unsigned long x;
706 if (get_ulong(v, &x) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000707 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000708 memcpy(p, (char *)&x, sizeof x);
709 return 0;
710}
711
712#ifdef HAVE_LONG_LONG
713
714static int
715np_longlong(char *p, PyObject *v, const formatdef *f)
716{
717 PY_LONG_LONG x;
718 if (get_longlong(v, &x) < 0)
719 return -1;
720 memcpy(p, (char *)&x, sizeof x);
721 return 0;
722}
723
724static int
725np_ulonglong(char *p, PyObject *v, const formatdef *f)
726{
727 unsigned PY_LONG_LONG x;
728 if (get_ulonglong(v, &x) < 0)
729 return -1;
730 memcpy(p, (char *)&x, sizeof x);
731 return 0;
732}
733#endif
734
Thomas Woutersb2137042007-02-01 18:02:27 +0000735
736static int
737np_bool(char *p, PyObject *v, const formatdef *f)
738{
739 BOOL_TYPE y;
740 y = PyObject_IsTrue(v);
741 memcpy(p, (char *)&y, sizeof y);
742 return 0;
743}
744
Thomas Wouters477c8d52006-05-27 19:21:47 +0000745static int
746np_float(char *p, PyObject *v, const formatdef *f)
747{
748 float x = (float)PyFloat_AsDouble(v);
749 if (x == -1 && PyErr_Occurred()) {
750 PyErr_SetString(StructError,
751 "required argument is not a float");
752 return -1;
753 }
754 memcpy(p, (char *)&x, sizeof x);
755 return 0;
756}
757
758static int
759np_double(char *p, PyObject *v, const formatdef *f)
760{
761 double x = PyFloat_AsDouble(v);
762 if (x == -1 && PyErr_Occurred()) {
763 PyErr_SetString(StructError,
764 "required argument is not a float");
765 return -1;
766 }
767 memcpy(p, (char *)&x, sizeof(double));
768 return 0;
769}
770
771static int
772np_void_p(char *p, PyObject *v, const formatdef *f)
773{
774 void *x;
775
776 v = get_pylong(v);
777 if (v == NULL)
778 return -1;
779 assert(PyLong_Check(v));
780 x = PyLong_AsVoidPtr(v);
781 Py_DECREF(v);
782 if (x == NULL && PyErr_Occurred())
783 return -1;
784 memcpy(p, (char *)&x, sizeof x);
785 return 0;
786}
787
788static formatdef native_table[] = {
789 {'x', sizeof(char), 0, NULL},
790 {'b', sizeof(char), 0, nu_byte, np_byte},
791 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
792 {'c', sizeof(char), 0, nu_char, np_char},
793 {'s', sizeof(char), 0, NULL},
794 {'p', sizeof(char), 0, NULL},
795 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
796 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
797 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
798 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
799 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
800 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
801#ifdef HAVE_LONG_LONG
802 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
803 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
804#endif
Thomas Woutersb2137042007-02-01 18:02:27 +0000805 {'t', sizeof(BOOL_TYPE), BOOL_ALIGN, nu_bool, np_bool},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000806 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
807 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
808 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
809 {0}
810};
811
812/* Big-endian routines. *****************************************************/
813
814static PyObject *
815bu_int(const char *p, const formatdef *f)
816{
817 long x = 0;
818 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000819 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000820 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000821 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000822 } while (--i > 0);
823 /* Extend the sign bit. */
824 if (SIZEOF_LONG > f->size)
825 x |= -(x & (1L << ((8 * f->size) - 1)));
826 return PyInt_FromLong(x);
827}
828
829static PyObject *
830bu_uint(const char *p, const formatdef *f)
831{
832 unsigned long x = 0;
833 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000834 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000835 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000836 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000837 } while (--i > 0);
838 if (x <= LONG_MAX)
839 return PyInt_FromLong((long)x);
840 return PyLong_FromUnsignedLong(x);
841}
842
843static PyObject *
844bu_longlong(const char *p, const formatdef *f)
845{
846#ifdef HAVE_LONG_LONG
847 PY_LONG_LONG x = 0;
848 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000849 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000850 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000851 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000852 } while (--i > 0);
853 /* Extend the sign bit. */
854 if (SIZEOF_LONG_LONG > f->size)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000855 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000856 if (x >= LONG_MIN && x <= LONG_MAX)
857 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
858 return PyLong_FromLongLong(x);
859#else
860 return _PyLong_FromByteArray((const unsigned char *)p,
861 8,
862 0, /* little-endian */
863 1 /* signed */);
864#endif
865}
866
867static PyObject *
868bu_ulonglong(const char *p, const formatdef *f)
869{
870#ifdef HAVE_LONG_LONG
871 unsigned PY_LONG_LONG x = 0;
872 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000873 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000874 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000875 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000876 } while (--i > 0);
877 if (x <= LONG_MAX)
878 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
879 return PyLong_FromUnsignedLongLong(x);
880#else
881 return _PyLong_FromByteArray((const unsigned char *)p,
882 8,
883 0, /* little-endian */
884 0 /* signed */);
885#endif
886}
887
888static PyObject *
889bu_float(const char *p, const formatdef *f)
890{
891 return unpack_float(p, 0);
892}
893
894static PyObject *
895bu_double(const char *p, const formatdef *f)
896{
897 return unpack_double(p, 0);
898}
899
Thomas Woutersb2137042007-02-01 18:02:27 +0000900static PyObject *
901bu_bool(const char *p, const formatdef *f)
902{
903 char x;
904 memcpy((char *)&x, p, sizeof x);
905 return PyBool_FromLong(x != 0);
906}
907
Thomas Wouters477c8d52006-05-27 19:21:47 +0000908static int
909bp_int(char *p, PyObject *v, const formatdef *f)
910{
911 long x;
912 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000913 if (get_wrapped_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000914 return -1;
915 i = f->size;
916 if (i != SIZEOF_LONG) {
917 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000918 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000919#if (SIZEOF_LONG != 4)
920 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000921 RANGE_ERROR(x, f, 0, 0xffffffffL);
922#endif
923#ifdef PY_STRUCT_OVERFLOW_MASKING
924 else if ((i == 1) && (x < -128 || x > 127))
925 RANGE_ERROR(x, f, 0, 0xffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000926#endif
927 }
928 do {
929 p[--i] = (char)x;
930 x >>= 8;
931 } while (i > 0);
932 return 0;
933}
934
935static int
936bp_uint(char *p, PyObject *v, const formatdef *f)
937{
938 unsigned long x;
939 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000940 if (get_wrapped_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000941 return -1;
942 i = f->size;
943 if (i != SIZEOF_LONG) {
944 unsigned long maxint = 1;
945 maxint <<= (unsigned long)(i * 8);
946 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000947 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000948 }
949 do {
950 p[--i] = (char)x;
951 x >>= 8;
952 } while (i > 0);
953 return 0;
954}
955
956static int
957bp_longlong(char *p, PyObject *v, const formatdef *f)
958{
959 int res;
960 v = get_pylong(v);
961 if (v == NULL)
962 return -1;
963 res = _PyLong_AsByteArray((PyLongObject *)v,
964 (unsigned char *)p,
965 8,
966 0, /* little_endian */
967 1 /* signed */);
968 Py_DECREF(v);
969 return res;
970}
971
972static int
973bp_ulonglong(char *p, PyObject *v, const formatdef *f)
974{
975 int res;
976 v = get_pylong(v);
977 if (v == NULL)
978 return -1;
979 res = _PyLong_AsByteArray((PyLongObject *)v,
980 (unsigned char *)p,
981 8,
982 0, /* little_endian */
983 0 /* signed */);
984 Py_DECREF(v);
985 return res;
986}
987
988static int
989bp_float(char *p, PyObject *v, const formatdef *f)
990{
991 double x = PyFloat_AsDouble(v);
992 if (x == -1 && PyErr_Occurred()) {
993 PyErr_SetString(StructError,
994 "required argument is not a float");
995 return -1;
996 }
997 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
998}
999
1000static int
1001bp_double(char *p, PyObject *v, const formatdef *f)
1002{
1003 double x = PyFloat_AsDouble(v);
1004 if (x == -1 && PyErr_Occurred()) {
1005 PyErr_SetString(StructError,
1006 "required argument is not a float");
1007 return -1;
1008 }
1009 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
1010}
1011
Thomas Woutersb2137042007-02-01 18:02:27 +00001012static int
1013bp_bool(char *p, PyObject *v, const formatdef *f)
1014{
1015 char y;
1016 y = PyObject_IsTrue(v);
1017 memcpy(p, (char *)&y, sizeof y);
1018 return 0;
1019}
1020
Thomas Wouters477c8d52006-05-27 19:21:47 +00001021static formatdef bigendian_table[] = {
1022 {'x', 1, 0, NULL},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001023#ifdef PY_STRUCT_OVERFLOW_MASKING
1024 /* Native packers do range checking without overflow masking. */
1025 {'b', 1, 0, nu_byte, bp_int},
1026 {'B', 1, 0, nu_ubyte, bp_uint},
1027#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001028 {'b', 1, 0, nu_byte, np_byte},
1029 {'B', 1, 0, nu_ubyte, np_ubyte},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001030#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001031 {'c', 1, 0, nu_char, np_char},
1032 {'s', 1, 0, NULL},
1033 {'p', 1, 0, NULL},
1034 {'h', 2, 0, bu_int, bp_int},
1035 {'H', 2, 0, bu_uint, bp_uint},
1036 {'i', 4, 0, bu_int, bp_int},
1037 {'I', 4, 0, bu_uint, bp_uint},
1038 {'l', 4, 0, bu_int, bp_int},
1039 {'L', 4, 0, bu_uint, bp_uint},
1040 {'q', 8, 0, bu_longlong, bp_longlong},
1041 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
Thomas Woutersb2137042007-02-01 18:02:27 +00001042 {'t', 1, 0, bu_bool, bp_bool},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001043 {'f', 4, 0, bu_float, bp_float},
1044 {'d', 8, 0, bu_double, bp_double},
1045 {0}
1046};
1047
1048/* Little-endian routines. *****************************************************/
1049
1050static PyObject *
1051lu_int(const char *p, const formatdef *f)
1052{
1053 long x = 0;
1054 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001055 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001056 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001057 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001058 } while (i > 0);
1059 /* Extend the sign bit. */
1060 if (SIZEOF_LONG > f->size)
1061 x |= -(x & (1L << ((8 * f->size) - 1)));
1062 return PyInt_FromLong(x);
1063}
1064
1065static PyObject *
1066lu_uint(const char *p, const formatdef *f)
1067{
1068 unsigned long x = 0;
1069 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001070 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001071 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001072 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001073 } while (i > 0);
1074 if (x <= LONG_MAX)
1075 return PyInt_FromLong((long)x);
1076 return PyLong_FromUnsignedLong((long)x);
1077}
1078
1079static PyObject *
1080lu_longlong(const char *p, const formatdef *f)
1081{
1082#ifdef HAVE_LONG_LONG
1083 PY_LONG_LONG x = 0;
1084 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001085 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001086 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001087 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001088 } while (i > 0);
1089 /* Extend the sign bit. */
1090 if (SIZEOF_LONG_LONG > f->size)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001091 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001092 if (x >= LONG_MIN && x <= LONG_MAX)
1093 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
1094 return PyLong_FromLongLong(x);
1095#else
1096 return _PyLong_FromByteArray((const unsigned char *)p,
1097 8,
1098 1, /* little-endian */
1099 1 /* signed */);
1100#endif
1101}
1102
1103static PyObject *
1104lu_ulonglong(const char *p, const formatdef *f)
1105{
1106#ifdef HAVE_LONG_LONG
1107 unsigned PY_LONG_LONG x = 0;
1108 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001109 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001110 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001111 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001112 } while (i > 0);
1113 if (x <= LONG_MAX)
1114 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
1115 return PyLong_FromUnsignedLongLong(x);
1116#else
1117 return _PyLong_FromByteArray((const unsigned char *)p,
1118 8,
1119 1, /* little-endian */
1120 0 /* signed */);
1121#endif
1122}
1123
1124static PyObject *
1125lu_float(const char *p, const formatdef *f)
1126{
1127 return unpack_float(p, 1);
1128}
1129
1130static PyObject *
1131lu_double(const char *p, const formatdef *f)
1132{
1133 return unpack_double(p, 1);
1134}
1135
1136static int
1137lp_int(char *p, PyObject *v, const formatdef *f)
1138{
1139 long x;
1140 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001141 if (get_wrapped_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001142 return -1;
1143 i = f->size;
1144 if (i != SIZEOF_LONG) {
1145 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001146 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001147#if (SIZEOF_LONG != 4)
1148 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001149 RANGE_ERROR(x, f, 0, 0xffffffffL);
1150#endif
1151#ifdef PY_STRUCT_OVERFLOW_MASKING
1152 else if ((i == 1) && (x < -128 || x > 127))
1153 RANGE_ERROR(x, f, 0, 0xffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001154#endif
1155 }
1156 do {
1157 *p++ = (char)x;
1158 x >>= 8;
1159 } while (--i > 0);
1160 return 0;
1161}
1162
1163static int
1164lp_uint(char *p, PyObject *v, const formatdef *f)
1165{
1166 unsigned long x;
1167 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001168 if (get_wrapped_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001169 return -1;
1170 i = f->size;
1171 if (i != SIZEOF_LONG) {
1172 unsigned long maxint = 1;
1173 maxint <<= (unsigned long)(i * 8);
1174 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001175 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001176 }
1177 do {
1178 *p++ = (char)x;
1179 x >>= 8;
1180 } while (--i > 0);
1181 return 0;
1182}
1183
1184static int
1185lp_longlong(char *p, PyObject *v, const formatdef *f)
1186{
1187 int res;
1188 v = get_pylong(v);
1189 if (v == NULL)
1190 return -1;
1191 res = _PyLong_AsByteArray((PyLongObject*)v,
1192 (unsigned char *)p,
1193 8,
1194 1, /* little_endian */
1195 1 /* signed */);
1196 Py_DECREF(v);
1197 return res;
1198}
1199
1200static int
1201lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1202{
1203 int res;
1204 v = get_pylong(v);
1205 if (v == NULL)
1206 return -1;
1207 res = _PyLong_AsByteArray((PyLongObject*)v,
1208 (unsigned char *)p,
1209 8,
1210 1, /* little_endian */
1211 0 /* signed */);
1212 Py_DECREF(v);
1213 return res;
1214}
1215
1216static int
1217lp_float(char *p, PyObject *v, const formatdef *f)
1218{
1219 double x = PyFloat_AsDouble(v);
1220 if (x == -1 && PyErr_Occurred()) {
1221 PyErr_SetString(StructError,
1222 "required argument is not a float");
1223 return -1;
1224 }
1225 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1226}
1227
1228static int
1229lp_double(char *p, PyObject *v, const formatdef *f)
1230{
1231 double x = PyFloat_AsDouble(v);
1232 if (x == -1 && PyErr_Occurred()) {
1233 PyErr_SetString(StructError,
1234 "required argument is not a float");
1235 return -1;
1236 }
1237 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1238}
1239
1240static formatdef lilendian_table[] = {
1241 {'x', 1, 0, NULL},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001242#ifdef PY_STRUCT_OVERFLOW_MASKING
1243 /* Native packers do range checking without overflow masking. */
1244 {'b', 1, 0, nu_byte, lp_int},
1245 {'B', 1, 0, nu_ubyte, lp_uint},
1246#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001247 {'b', 1, 0, nu_byte, np_byte},
1248 {'B', 1, 0, nu_ubyte, np_ubyte},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001249#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001250 {'c', 1, 0, nu_char, np_char},
1251 {'s', 1, 0, NULL},
1252 {'p', 1, 0, NULL},
1253 {'h', 2, 0, lu_int, lp_int},
1254 {'H', 2, 0, lu_uint, lp_uint},
1255 {'i', 4, 0, lu_int, lp_int},
1256 {'I', 4, 0, lu_uint, lp_uint},
1257 {'l', 4, 0, lu_int, lp_int},
1258 {'L', 4, 0, lu_uint, lp_uint},
1259 {'q', 8, 0, lu_longlong, lp_longlong},
1260 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
Thomas Woutersb2137042007-02-01 18:02:27 +00001261 {'t', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1262 but potentially different from native rep -- reuse bx_bool funcs. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001263 {'f', 4, 0, lu_float, lp_float},
1264 {'d', 8, 0, lu_double, lp_double},
1265 {0}
1266};
1267
1268
1269static const formatdef *
1270whichtable(char **pfmt)
1271{
1272 const char *fmt = (*pfmt)++; /* May be backed out of later */
1273 switch (*fmt) {
1274 case '<':
1275 return lilendian_table;
1276 case '>':
1277 case '!': /* Network byte order is big-endian */
1278 return bigendian_table;
1279 case '=': { /* Host byte order -- different from native in aligment! */
1280 int n = 1;
1281 char *p = (char *) &n;
1282 if (*p == 1)
1283 return lilendian_table;
1284 else
1285 return bigendian_table;
1286 }
1287 default:
1288 --*pfmt; /* Back out of pointer increment */
1289 /* Fall through */
1290 case '@':
1291 return native_table;
1292 }
1293}
1294
1295
1296/* Get the table entry for a format code */
1297
1298static const formatdef *
1299getentry(int c, const formatdef *f)
1300{
1301 for (; f->format != '\0'; f++) {
1302 if (f->format == c) {
1303 return f;
1304 }
1305 }
1306 PyErr_SetString(StructError, "bad char in struct format");
1307 return NULL;
1308}
1309
1310
1311/* Align a size according to a format code */
1312
1313static int
1314align(Py_ssize_t size, char c, const formatdef *e)
1315{
1316 if (e->format == c) {
1317 if (e->alignment) {
1318 size = ((size + e->alignment - 1)
1319 / e->alignment)
1320 * e->alignment;
1321 }
1322 }
1323 return size;
1324}
1325
1326
1327/* calculate the size of a format string */
1328
1329static int
1330prepare_s(PyStructObject *self)
1331{
1332 const formatdef *f;
1333 const formatdef *e;
1334 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001335
Thomas Wouters477c8d52006-05-27 19:21:47 +00001336 const char *s;
1337 const char *fmt;
1338 char c;
1339 Py_ssize_t size, len, num, itemsize, x;
1340
1341 fmt = PyString_AS_STRING(self->s_format);
1342
1343 f = whichtable((char **)&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001344
Thomas Wouters477c8d52006-05-27 19:21:47 +00001345 s = fmt;
1346 size = 0;
1347 len = 0;
1348 while ((c = *s++) != '\0') {
1349 if (isspace(Py_CHARMASK(c)))
1350 continue;
1351 if ('0' <= c && c <= '9') {
1352 num = c - '0';
1353 while ('0' <= (c = *s++) && c <= '9') {
1354 x = num*10 + (c - '0');
1355 if (x/10 != num) {
1356 PyErr_SetString(
1357 StructError,
1358 "overflow in item count");
1359 return -1;
1360 }
1361 num = x;
1362 }
1363 if (c == '\0')
1364 break;
1365 }
1366 else
1367 num = 1;
1368
1369 e = getentry(c, f);
1370 if (e == NULL)
1371 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001372
Thomas Wouters477c8d52006-05-27 19:21:47 +00001373 switch (c) {
1374 case 's': /* fall through */
1375 case 'p': len++; break;
1376 case 'x': break;
1377 default: len += num; break;
1378 }
1379
1380 itemsize = e->size;
1381 size = align(size, c, e);
1382 x = num * itemsize;
1383 size += x;
1384 if (x/itemsize != num || size < 0) {
1385 PyErr_SetString(StructError,
1386 "total struct size too long");
1387 return -1;
1388 }
1389 }
1390
1391 self->s_size = size;
1392 self->s_len = len;
1393 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1394 if (codes == NULL) {
1395 PyErr_NoMemory();
1396 return -1;
1397 }
1398 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001399
Thomas Wouters477c8d52006-05-27 19:21:47 +00001400 s = fmt;
1401 size = 0;
1402 while ((c = *s++) != '\0') {
1403 if (isspace(Py_CHARMASK(c)))
1404 continue;
1405 if ('0' <= c && c <= '9') {
1406 num = c - '0';
1407 while ('0' <= (c = *s++) && c <= '9')
1408 num = num*10 + (c - '0');
1409 if (c == '\0')
1410 break;
1411 }
1412 else
1413 num = 1;
1414
1415 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001416
Thomas Wouters477c8d52006-05-27 19:21:47 +00001417 size = align(size, c, e);
1418 if (c == 's' || c == 'p') {
1419 codes->offset = size;
1420 codes->size = num;
1421 codes->fmtdef = e;
1422 codes++;
1423 size += num;
1424 } else if (c == 'x') {
1425 size += num;
1426 } else {
1427 while (--num >= 0) {
1428 codes->offset = size;
1429 codes->size = e->size;
1430 codes->fmtdef = e;
1431 codes++;
1432 size += e->size;
1433 }
1434 }
1435 }
1436 codes->fmtdef = NULL;
1437 codes->offset = size;
1438 codes->size = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001439
Thomas Wouters477c8d52006-05-27 19:21:47 +00001440 return 0;
1441}
1442
1443static PyObject *
1444s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1445{
1446 PyObject *self;
1447
1448 assert(type != NULL && type->tp_alloc != NULL);
1449
1450 self = type->tp_alloc(type, 0);
1451 if (self != NULL) {
1452 PyStructObject *s = (PyStructObject*)self;
1453 Py_INCREF(Py_None);
1454 s->s_format = Py_None;
1455 s->s_codes = NULL;
1456 s->s_size = -1;
1457 s->s_len = -1;
1458 }
1459 return self;
1460}
1461
1462static int
1463s_init(PyObject *self, PyObject *args, PyObject *kwds)
1464{
1465 PyStructObject *soself = (PyStructObject *)self;
1466 PyObject *o_format = NULL;
1467 int ret = 0;
1468 static char *kwlist[] = {"format", 0};
1469
1470 assert(PyStruct_Check(self));
1471
1472 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1473 &o_format))
1474 return -1;
1475
1476 Py_INCREF(o_format);
1477 Py_XDECREF(soself->s_format);
1478 soself->s_format = o_format;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001479
Thomas Wouters477c8d52006-05-27 19:21:47 +00001480 ret = prepare_s(soself);
1481 return ret;
1482}
1483
1484static void
1485s_dealloc(PyStructObject *s)
1486{
1487 if (s->weakreflist != NULL)
1488 PyObject_ClearWeakRefs((PyObject *)s);
1489 if (s->s_codes != NULL) {
1490 PyMem_FREE(s->s_codes);
1491 }
1492 Py_XDECREF(s->s_format);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001493 Py_Type(s)->tp_free((PyObject *)s);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001494}
1495
1496static PyObject *
1497s_unpack_internal(PyStructObject *soself, char *startfrom) {
1498 formatcode *code;
1499 Py_ssize_t i = 0;
1500 PyObject *result = PyTuple_New(soself->s_len);
1501 if (result == NULL)
1502 return NULL;
1503
1504 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1505 PyObject *v;
1506 const formatdef *e = code->fmtdef;
1507 const char *res = startfrom + code->offset;
1508 if (e->format == 's') {
1509 v = PyString_FromStringAndSize(res, code->size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510 } else if (e->format == 'p') {
1511 Py_ssize_t n = *(unsigned char*)res;
1512 if (n >= code->size)
1513 n = code->size - 1;
1514 v = PyString_FromStringAndSize(res + 1, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001515 } else {
1516 v = e->unpack(res, e);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001517 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001518 if (v == NULL)
1519 goto fail;
1520 PyTuple_SET_ITEM(result, i++, v);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001521 }
1522
1523 return result;
1524fail:
1525 Py_DECREF(result);
1526 return NULL;
1527}
1528
1529
1530PyDoc_STRVAR(s_unpack__doc__,
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001531"S.unpack(buffer) -> (v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001532\n\
1533Return tuple containing values unpacked according to this Struct's format.\n\
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001534Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535strings.");
1536
1537static PyObject *
1538s_unpack(PyObject *self, PyObject *inputstr)
1539{
Guido van Rossumd8faa362007-04-27 19:54:29 +00001540 char *start;
1541 Py_ssize_t len;
1542 PyObject *args=NULL, *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001543 PyStructObject *soself = (PyStructObject *)self;
1544 assert(PyStruct_Check(self));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001545 assert(soself->s_codes != NULL);
Guido van Rossumd8faa362007-04-27 19:54:29 +00001546 if (inputstr == NULL)
1547 goto fail;
1548 if (PyString_Check(inputstr) &&
1549 PyString_GET_SIZE(inputstr) == soself->s_size) {
1550 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001551 }
Guido van Rossumd8faa362007-04-27 19:54:29 +00001552 args = PyTuple_Pack(1, inputstr);
1553 if (args == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001554 return NULL;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001555 if (!PyArg_ParseTuple(args, "s#:unpack", &start, &len))
1556 goto fail;
1557 if (soself->s_size != len)
1558 goto fail;
1559 result = s_unpack_internal(soself, start);
1560 Py_DECREF(args);
1561 return result;
1562
1563fail:
1564 Py_XDECREF(args);
1565 PyErr_Format(StructError,
1566 "unpack requires a string argument of length %zd",
1567 soself->s_size);
1568 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001569}
1570
1571PyDoc_STRVAR(s_unpack_from__doc__,
1572"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1573\n\
1574Return tuple containing values unpacked according to this Struct's format.\n\
1575Unlike unpack, unpack_from can unpack values from any object supporting\n\
1576the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1577See struct.__doc__ for more on format strings.");
1578
1579static PyObject *
1580s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1581{
1582 static char *kwlist[] = {"buffer", "offset", 0};
1583#if (PY_VERSION_HEX < 0x02050000)
1584 static char *fmt = "z#|i:unpack_from";
1585#else
1586 static char *fmt = "z#|n:unpack_from";
1587#endif
1588 Py_ssize_t buffer_len = 0, offset = 0;
1589 char *buffer = NULL;
1590 PyStructObject *soself = (PyStructObject *)self;
1591 assert(PyStruct_Check(self));
1592 assert(soself->s_codes != NULL);
1593
1594 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1595 &buffer, &buffer_len, &offset))
1596 return NULL;
1597
1598 if (buffer == NULL) {
1599 PyErr_Format(StructError,
1600 "unpack_from requires a buffer argument");
1601 return NULL;
1602 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001603
Thomas Wouters477c8d52006-05-27 19:21:47 +00001604 if (offset < 0)
1605 offset += buffer_len;
1606
1607 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1608 PyErr_Format(StructError,
1609 "unpack_from requires a buffer of at least %zd bytes",
1610 soself->s_size);
1611 return NULL;
1612 }
1613 return s_unpack_internal(soself, buffer + offset);
1614}
1615
1616
1617/*
1618 * Guts of the pack function.
1619 *
1620 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1621 * argument for where to start processing the arguments for packing, and a
1622 * character buffer for writing the packed string. The caller must insure
1623 * that the buffer may contain the required length for packing the arguments.
1624 * 0 is returned on success, 1 is returned if there is an error.
1625 *
1626 */
1627static int
1628s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1629{
1630 formatcode *code;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001631 /* XXX(nnorwitz): why does i need to be a local? can we use
1632 the offset parameter or do we need the wider width? */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001633 Py_ssize_t i;
1634
1635 memset(buf, '\0', soself->s_size);
1636 i = offset;
1637 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1638 Py_ssize_t n;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001639 PyObject *v = PyTuple_GET_ITEM(args, i++);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001640 const formatdef *e = code->fmtdef;
1641 char *res = buf + code->offset;
1642 if (e->format == 's') {
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001643 int isstring;
1644 void *p;
1645 if (PyUnicode_Check(v)) {
1646 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
1647 if (v == NULL)
1648 return -1;
1649 }
1650 isstring = PyString_Check(v);
1651 if (!isstring && !PyBytes_Check(v)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001652 PyErr_SetString(StructError,
1653 "argument for 's' must be a string");
1654 return -1;
1655 }
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001656 if (isstring) {
1657 n = PyString_GET_SIZE(v);
1658 p = PyString_AS_STRING(v);
1659 }
1660 else {
1661 n = PyBytes_GET_SIZE(v);
1662 p = PyBytes_AS_STRING(v);
1663 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001664 if (n > code->size)
1665 n = code->size;
1666 if (n > 0)
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001667 memcpy(res, p, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001668 } else if (e->format == 'p') {
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001669 int isstring;
1670 void *p;
1671 if (PyUnicode_Check(v)) {
1672 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
1673 if (v == NULL)
1674 return -1;
1675 }
1676 isstring = PyString_Check(v);
1677 if (!isstring && !PyBytes_Check(v)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001678 PyErr_SetString(StructError,
1679 "argument for 'p' must be a string");
1680 return -1;
1681 }
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001682 if (isstring) {
1683 n = PyString_GET_SIZE(v);
1684 p = PyString_AS_STRING(v);
1685 }
1686 else {
1687 n = PyBytes_GET_SIZE(v);
1688 p = PyBytes_AS_STRING(v);
1689 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001690 if (n > (code->size - 1))
1691 n = code->size - 1;
1692 if (n > 0)
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001693 memcpy(res + 1, p, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001694 if (n > 255)
1695 n = 255;
1696 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1697 } else {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001698 if (e->pack(res, v, e) < 0) {
1699 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1700 PyErr_SetString(StructError,
1701 "long too large to convert to int");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001702 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001703 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001704 }
1705 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001706
Thomas Wouters477c8d52006-05-27 19:21:47 +00001707 /* Success */
1708 return 0;
1709}
1710
1711
1712PyDoc_STRVAR(s_pack__doc__,
1713"S.pack(v1, v2, ...) -> string\n\
1714\n\
1715Return a string containing values v1, v2, ... packed according to this\n\
1716Struct's format. See struct.__doc__ for more on format strings.");
1717
1718static PyObject *
1719s_pack(PyObject *self, PyObject *args)
1720{
1721 PyStructObject *soself;
1722 PyObject *result;
1723
1724 /* Validate arguments. */
1725 soself = (PyStructObject *)self;
1726 assert(PyStruct_Check(self));
1727 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001728 if (PyTuple_GET_SIZE(args) != soself->s_len)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001729 {
1730 PyErr_Format(StructError,
1731 "pack requires exactly %zd arguments", soself->s_len);
1732 return NULL;
1733 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001734
Thomas Wouters477c8d52006-05-27 19:21:47 +00001735 /* Allocate a new string */
1736 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1737 if (result == NULL)
1738 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001739
Thomas Wouters477c8d52006-05-27 19:21:47 +00001740 /* Call the guts */
1741 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1742 Py_DECREF(result);
1743 return NULL;
1744 }
1745
1746 return result;
1747}
1748
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001749PyDoc_STRVAR(s_pack_into__doc__,
1750"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001751\n\
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001752Pack the values v1, v2, ... according to this Struct's format, write \n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001753the packed bytes into the writable buffer buf starting at offset. Note\n\
1754that the offset is not an optional argument. See struct.__doc__ for \n\
1755more on format strings.");
1756
1757static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001758s_pack_into(PyObject *self, PyObject *args)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001759{
1760 PyStructObject *soself;
1761 char *buffer;
1762 Py_ssize_t buffer_len, offset;
1763
1764 /* Validate arguments. +1 is for the first arg as buffer. */
1765 soself = (PyStructObject *)self;
1766 assert(PyStruct_Check(self));
1767 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001768 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001769 {
1770 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001771 "pack_into requires exactly %zd arguments",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001772 (soself->s_len + 2));
1773 return NULL;
1774 }
1775
1776 /* Extract a writable memory buffer from the first argument */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001777 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1778 (void**)&buffer, &buffer_len) == -1 ) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001779 return NULL;
1780 }
1781 assert( buffer_len >= 0 );
1782
1783 /* Extract the offset from the first argument */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001784 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001785
1786 /* Support negative offsets. */
1787 if (offset < 0)
1788 offset += buffer_len;
1789
1790 /* Check boundaries */
1791 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1792 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001793 "pack_into requires a buffer of at least %zd bytes",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001794 soself->s_size);
1795 return NULL;
1796 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001797
Thomas Wouters477c8d52006-05-27 19:21:47 +00001798 /* Call the guts */
1799 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1800 return NULL;
1801 }
1802
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001803 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001804}
1805
1806static PyObject *
1807s_get_format(PyStructObject *self, void *unused)
1808{
1809 Py_INCREF(self->s_format);
1810 return self->s_format;
1811}
1812
1813static PyObject *
1814s_get_size(PyStructObject *self, void *unused)
1815{
1816 return PyInt_FromSsize_t(self->s_size);
1817}
1818
1819/* List of functions */
1820
1821static struct PyMethodDef s_methods[] = {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001822 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1823 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1824 {"unpack", s_unpack, METH_O, s_unpack__doc__},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00001825 {"unpack_from", (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001826 s_unpack_from__doc__},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001827 {NULL, NULL} /* sentinel */
1828};
1829
1830PyDoc_STRVAR(s__doc__, "Compiled struct object");
1831
1832#define OFF(x) offsetof(PyStructObject, x)
1833
1834static PyGetSetDef s_getsetlist[] = {
1835 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1836 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1837 {NULL} /* sentinel */
1838};
1839
1840static
1841PyTypeObject PyStructType = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001842 PyVarObject_HEAD_INIT(NULL, 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001843 "Struct",
1844 sizeof(PyStructObject),
1845 0,
1846 (destructor)s_dealloc, /* tp_dealloc */
1847 0, /* tp_print */
1848 0, /* tp_getattr */
1849 0, /* tp_setattr */
1850 0, /* tp_compare */
1851 0, /* tp_repr */
1852 0, /* tp_as_number */
1853 0, /* tp_as_sequence */
1854 0, /* tp_as_mapping */
1855 0, /* tp_hash */
1856 0, /* tp_call */
1857 0, /* tp_str */
1858 PyObject_GenericGetAttr, /* tp_getattro */
1859 PyObject_GenericSetAttr, /* tp_setattro */
1860 0, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +00001861 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001862 s__doc__, /* tp_doc */
1863 0, /* tp_traverse */
1864 0, /* tp_clear */
1865 0, /* tp_richcompare */
1866 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1867 0, /* tp_iter */
1868 0, /* tp_iternext */
1869 s_methods, /* tp_methods */
1870 NULL, /* tp_members */
1871 s_getsetlist, /* tp_getset */
1872 0, /* tp_base */
1873 0, /* tp_dict */
1874 0, /* tp_descr_get */
1875 0, /* tp_descr_set */
1876 0, /* tp_dictoffset */
1877 s_init, /* tp_init */
1878 PyType_GenericAlloc,/* tp_alloc */
1879 s_new, /* tp_new */
1880 PyObject_Del, /* tp_free */
1881};
1882
1883/* Module initialization */
1884
1885PyMODINIT_FUNC
1886init_struct(void)
1887{
1888 PyObject *m = Py_InitModule("_struct", NULL);
1889 if (m == NULL)
1890 return;
1891
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001892 Py_Type(&PyStructType) = &PyType_Type;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001893 if (PyType_Ready(&PyStructType) < 0)
1894 return;
1895
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001896#ifdef PY_STRUCT_OVERFLOW_MASKING
1897 if (pyint_zero == NULL) {
1898 pyint_zero = PyInt_FromLong(0);
1899 if (pyint_zero == NULL)
1900 return;
1901 }
1902 if (pylong_ulong_mask == NULL) {
1903#if (SIZEOF_LONG == 4)
1904 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1905#else
1906 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1907#endif
1908 if (pylong_ulong_mask == NULL)
1909 return;
1910 }
1911
1912#else
1913 /* This speed trick can't be used until overflow masking goes away, because
1914 native endian always raises exceptions instead of overflow masking. */
1915
Thomas Wouters477c8d52006-05-27 19:21:47 +00001916 /* Check endian and swap in faster functions */
1917 {
1918 int one = 1;
1919 formatdef *native = native_table;
1920 formatdef *other, *ptr;
1921 if ((int)*(unsigned char*)&one)
1922 other = lilendian_table;
1923 else
1924 other = bigendian_table;
1925 /* Scan through the native table, find a matching
1926 entry in the endian table and swap in the
1927 native implementations whenever possible
1928 (64-bit platforms may not have "standard" sizes) */
1929 while (native->format != '\0' && other->format != '\0') {
1930 ptr = other;
1931 while (ptr->format != '\0') {
1932 if (ptr->format == native->format) {
1933 /* Match faster when formats are
1934 listed in the same order */
1935 if (ptr == other)
1936 other++;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001937 /* Only use the trick if the
Thomas Wouters477c8d52006-05-27 19:21:47 +00001938 size matches */
1939 if (ptr->size != native->size)
1940 break;
1941 /* Skip float and double, could be
1942 "unknown" float format */
1943 if (ptr->format == 'd' || ptr->format == 'f')
1944 break;
1945 ptr->pack = native->pack;
1946 ptr->unpack = native->unpack;
1947 break;
1948 }
1949 ptr++;
1950 }
1951 native++;
1952 }
1953 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001954#endif
1955
Thomas Wouters477c8d52006-05-27 19:21:47 +00001956 /* Add some symbolic constants to the module */
1957 if (StructError == NULL) {
1958 StructError = PyErr_NewException("struct.error", NULL, NULL);
1959 if (StructError == NULL)
1960 return;
1961 }
1962
1963 Py_INCREF(StructError);
1964 PyModule_AddObject(m, "error", StructError);
1965
1966 Py_INCREF((PyObject*)&PyStructType);
1967 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001968
1969 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
1970#ifdef PY_STRUCT_OVERFLOW_MASKING
1971 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
1972#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001973#ifdef PY_STRUCT_FLOAT_COERCE
1974 PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
1975#endif
1976
Thomas Wouters477c8d52006-05-27 19:21:47 +00001977}