blob: 3a44bde4f0c734c7ba82ad43aff7e4ca4f20b1c0 [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 Wouters477c8d52006-05-27 19:21:47 +000034/* The translation function for each format character is table driven */
35typedef struct _formatdef {
36 char format;
37 Py_ssize_t size;
38 Py_ssize_t alignment;
39 PyObject* (*unpack)(const char *,
40 const struct _formatdef *);
41 int (*pack)(char *, PyObject *,
42 const struct _formatdef *);
43} formatdef;
44
45typedef struct _formatcode {
46 const struct _formatdef *fmtdef;
47 Py_ssize_t offset;
48 Py_ssize_t size;
49} formatcode;
50
51/* Struct object interface */
52
53typedef struct {
54 PyObject_HEAD
55 Py_ssize_t s_size;
56 Py_ssize_t s_len;
57 formatcode *s_codes;
58 PyObject *s_format;
59 PyObject *weakreflist; /* List of weak references */
60} PyStructObject;
61
62
63#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
64#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
65
66
67/* Exception */
68
69static PyObject *StructError;
70
71
72/* Define various structs to figure out the alignments of types */
73
74
75typedef struct { char c; short x; } st_short;
76typedef struct { char c; int x; } st_int;
77typedef struct { char c; long x; } st_long;
78typedef struct { char c; float x; } st_float;
79typedef struct { char c; double x; } st_double;
80typedef struct { char c; void *x; } st_void_p;
81
82#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
83#define INT_ALIGN (sizeof(st_int) - sizeof(int))
84#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
85#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
86#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
87#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
88
89/* We can't support q and Q in native mode unless the compiler does;
90 in std mode, they're 8 bytes on all platforms. */
91#ifdef HAVE_LONG_LONG
92typedef struct { char c; PY_LONG_LONG x; } s_long_long;
93#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
94#endif
95
96#define STRINGIFY(x) #x
97
98#ifdef __powerc
99#pragma options align=reset
100#endif
101
102/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
103
104static PyObject *
105get_pylong(PyObject *v)
106{
107 PyNumberMethods *m;
108
109 assert(v != NULL);
110 if (PyInt_Check(v))
111 return PyLong_FromLong(PyInt_AS_LONG(v));
112 if (PyLong_Check(v)) {
113 Py_INCREF(v);
114 return v;
115 }
116 m = v->ob_type->tp_as_number;
117 if (m != NULL && m->nb_long != NULL) {
118 v = m->nb_long(v);
119 if (v == NULL)
120 return NULL;
121 if (PyLong_Check(v))
122 return v;
123 Py_DECREF(v);
124 }
125 PyErr_SetString(StructError,
126 "cannot convert argument to long");
127 return NULL;
128}
129
130/* Helper routine to get a Python integer and raise the appropriate error
131 if it isn't one */
132
133static int
134get_long(PyObject *v, long *p)
135{
136 long x = PyInt_AsLong(v);
137 if (x == -1 && PyErr_Occurred()) {
138 if (PyErr_ExceptionMatches(PyExc_TypeError))
139 PyErr_SetString(StructError,
140 "required argument is not an integer");
141 return -1;
142 }
143 *p = x;
144 return 0;
145}
146
147
148/* Same, but handling unsigned long */
149
150static int
151get_ulong(PyObject *v, unsigned long *p)
152{
153 if (PyLong_Check(v)) {
154 unsigned long x = PyLong_AsUnsignedLong(v);
155 if (x == (unsigned long)(-1) && PyErr_Occurred())
156 return -1;
157 *p = x;
158 return 0;
159 }
160 if (get_long(v, (long *)p) < 0)
161 return -1;
162 if (((long)*p) < 0) {
163 PyErr_SetString(StructError,
164 "unsigned argument is < 0");
165 return -1;
166 }
167 return 0;
168}
169
170#ifdef HAVE_LONG_LONG
171
172/* Same, but handling native long long. */
173
174static int
175get_longlong(PyObject *v, PY_LONG_LONG *p)
176{
177 PY_LONG_LONG x;
178
179 v = get_pylong(v);
180 if (v == NULL)
181 return -1;
182 assert(PyLong_Check(v));
183 x = PyLong_AsLongLong(v);
184 Py_DECREF(v);
185 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
186 return -1;
187 *p = x;
188 return 0;
189}
190
191/* Same, but handling native unsigned long long. */
192
193static int
194get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
195{
196 unsigned PY_LONG_LONG x;
197
198 v = get_pylong(v);
199 if (v == NULL)
200 return -1;
201 assert(PyLong_Check(v));
202 x = PyLong_AsUnsignedLongLong(v);
203 Py_DECREF(v);
204 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
205 return -1;
206 *p = x;
207 return 0;
208}
209
210#endif
211
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000212#ifdef PY_STRUCT_OVERFLOW_MASKING
213
214/* Helper routine to get a Python integer and raise the appropriate error
215 if it isn't one */
216
217static int
218get_wrapped_long(PyObject *v, long *p)
219{
220 if (get_long(v, p) < 0) {
221 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError)) {
222 PyObject *wrapped;
223 long x;
224 PyErr_Clear();
225 if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0)
226 return -1;
227 wrapped = PyNumber_And(v, pylong_ulong_mask);
228 if (wrapped == NULL)
229 return -1;
230 x = (long)PyLong_AsUnsignedLong(wrapped);
231 Py_DECREF(wrapped);
232 if (x == -1 && PyErr_Occurred())
233 return -1;
234 *p = x;
235 } else {
236 return -1;
237 }
238 }
239 return 0;
240}
241
242static int
243get_wrapped_ulong(PyObject *v, unsigned long *p)
244{
245 long x = (long)PyLong_AsUnsignedLong(v);
246 if (x == -1 && PyErr_Occurred()) {
247 PyObject *wrapped;
248 PyErr_Clear();
249 wrapped = PyNumber_And(v, pylong_ulong_mask);
250 if (wrapped == NULL)
251 return -1;
252 if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0) {
253 Py_DECREF(wrapped);
254 return -1;
255 }
256 x = (long)PyLong_AsUnsignedLong(wrapped);
257 Py_DECREF(wrapped);
258 if (x == -1 && PyErr_Occurred())
259 return -1;
260 }
261 *p = (unsigned long)x;
262 return 0;
263}
264
265#define RANGE_ERROR(x, f, flag, mask) \
266 do { \
267 if (_range_error(f, flag) < 0) \
268 return -1; \
269 else \
270 (x) &= (mask); \
271 } while (0)
272
273#else
274
275#define get_wrapped_long get_long
276#define get_wrapped_ulong get_ulong
277#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
278
279#endif
280
Thomas Wouters477c8d52006-05-27 19:21:47 +0000281/* Floating point helpers */
282
283static PyObject *
284unpack_float(const char *p, /* start of 4-byte string */
285 int le) /* true for little-endian, false for big-endian */
286{
287 double x;
288
289 x = _PyFloat_Unpack4((unsigned char *)p, le);
290 if (x == -1.0 && PyErr_Occurred())
291 return NULL;
292 return PyFloat_FromDouble(x);
293}
294
295static PyObject *
296unpack_double(const char *p, /* start of 8-byte string */
297 int le) /* true for little-endian, false for big-endian */
298{
299 double x;
300
301 x = _PyFloat_Unpack8((unsigned char *)p, le);
302 if (x == -1.0 && PyErr_Occurred())
303 return NULL;
304 return PyFloat_FromDouble(x);
305}
306
307/* Helper to format the range error exceptions */
308static int
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000309_range_error(const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000310{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000311 /* ulargest is the largest unsigned value with f->size bytes.
312 * Note that the simpler:
313 * ((size_t)1 << (f->size * 8)) - 1
314 * doesn't work when f->size == sizeof(size_t) because C doesn't
315 * define what happens when a left shift count is >= the number of
316 * bits in the integer being shifted; e.g., on some boxes it doesn't
317 * shift at all when they're equal.
318 */
319 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
320 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
321 if (is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000322 PyErr_Format(StructError,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000323 "'%c' format requires 0 <= number <= %zu",
324 f->format,
325 ulargest);
326 else {
327 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328 PyErr_Format(StructError,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000329 "'%c' format requires %zd <= number <= %zd",
330 f->format,
331 ~ largest,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000332 largest);
333 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000334#ifdef PY_STRUCT_OVERFLOW_MASKING
335 {
336 PyObject *ptype, *pvalue, *ptraceback;
337 PyObject *msg;
338 int rval;
339 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
340 assert(pvalue != NULL);
341 msg = PyObject_Str(pvalue);
342 Py_XDECREF(ptype);
343 Py_XDECREF(pvalue);
344 Py_XDECREF(ptraceback);
345 if (msg == NULL)
346 return -1;
347 rval = PyErr_Warn(PyExc_DeprecationWarning,
348 PyString_AS_STRING(msg));
349 Py_DECREF(msg);
350 if (rval == 0)
351 return 0;
352 }
353#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000354 return -1;
355}
356
357
358
359/* A large number of small routines follow, with names of the form
360
361 [bln][up]_TYPE
362
363 [bln] distiguishes among big-endian, little-endian and native.
364 [pu] distiguishes between pack (to struct) and unpack (from struct).
365 TYPE is one of char, byte, ubyte, etc.
366*/
367
368/* Native mode routines. ****************************************************/
369/* NOTE:
370 In all n[up]_<type> routines handling types larger than 1 byte, there is
371 *no* guarantee that the p pointer is properly aligned for each type,
372 therefore memcpy is called. An intermediate variable is used to
373 compensate for big-endian architectures.
374 Normally both the intermediate variable and the memcpy call will be
375 skipped by C optimisation in little-endian architectures (gcc >= 2.91
376 does this). */
377
378static PyObject *
379nu_char(const char *p, const formatdef *f)
380{
381 return PyString_FromStringAndSize(p, 1);
382}
383
384static PyObject *
385nu_byte(const char *p, const formatdef *f)
386{
387 return PyInt_FromLong((long) *(signed char *)p);
388}
389
390static PyObject *
391nu_ubyte(const char *p, const formatdef *f)
392{
393 return PyInt_FromLong((long) *(unsigned char *)p);
394}
395
396static PyObject *
397nu_short(const char *p, const formatdef *f)
398{
399 short x;
400 memcpy((char *)&x, p, sizeof x);
401 return PyInt_FromLong((long)x);
402}
403
404static PyObject *
405nu_ushort(const char *p, const formatdef *f)
406{
407 unsigned short x;
408 memcpy((char *)&x, p, sizeof x);
409 return PyInt_FromLong((long)x);
410}
411
412static PyObject *
413nu_int(const char *p, const formatdef *f)
414{
415 int x;
416 memcpy((char *)&x, p, sizeof x);
417 return PyInt_FromLong((long)x);
418}
419
420static PyObject *
421nu_uint(const char *p, const formatdef *f)
422{
423 unsigned int x;
424 memcpy((char *)&x, p, sizeof x);
425#if (SIZEOF_LONG > SIZEOF_INT)
426 return PyInt_FromLong((long)x);
427#else
428 if (x <= ((unsigned int)LONG_MAX))
429 return PyInt_FromLong((long)x);
430 return PyLong_FromUnsignedLong((unsigned long)x);
431#endif
432}
433
434static PyObject *
435nu_long(const char *p, const formatdef *f)
436{
437 long x;
438 memcpy((char *)&x, p, sizeof x);
439 return PyInt_FromLong(x);
440}
441
442static PyObject *
443nu_ulong(const char *p, const formatdef *f)
444{
445 unsigned long x;
446 memcpy((char *)&x, p, sizeof x);
447 if (x <= LONG_MAX)
448 return PyInt_FromLong((long)x);
449 return PyLong_FromUnsignedLong(x);
450}
451
452/* Native mode doesn't support q or Q unless the platform C supports
453 long long (or, on Windows, __int64). */
454
455#ifdef HAVE_LONG_LONG
456
457static PyObject *
458nu_longlong(const char *p, const formatdef *f)
459{
460 PY_LONG_LONG x;
461 memcpy((char *)&x, p, sizeof x);
462 if (x >= LONG_MIN && x <= LONG_MAX)
463 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
464 return PyLong_FromLongLong(x);
465}
466
467static PyObject *
468nu_ulonglong(const char *p, const formatdef *f)
469{
470 unsigned PY_LONG_LONG x;
471 memcpy((char *)&x, p, sizeof x);
472 if (x <= LONG_MAX)
473 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
474 return PyLong_FromUnsignedLongLong(x);
475}
476
477#endif
478
479static PyObject *
480nu_float(const char *p, const formatdef *f)
481{
482 float x;
483 memcpy((char *)&x, p, sizeof x);
484 return PyFloat_FromDouble((double)x);
485}
486
487static PyObject *
488nu_double(const char *p, const formatdef *f)
489{
490 double x;
491 memcpy((char *)&x, p, sizeof x);
492 return PyFloat_FromDouble(x);
493}
494
495static PyObject *
496nu_void_p(const char *p, const formatdef *f)
497{
498 void *x;
499 memcpy((char *)&x, p, sizeof x);
500 return PyLong_FromVoidPtr(x);
501}
502
503static int
504np_byte(char *p, PyObject *v, const formatdef *f)
505{
506 long x;
507 if (get_long(v, &x) < 0)
508 return -1;
509 if (x < -128 || x > 127){
510 PyErr_SetString(StructError,
511 "byte format requires -128 <= number <= 127");
512 return -1;
513 }
514 *p = (char)x;
515 return 0;
516}
517
518static int
519np_ubyte(char *p, PyObject *v, const formatdef *f)
520{
521 long x;
522 if (get_long(v, &x) < 0)
523 return -1;
524 if (x < 0 || x > 255){
525 PyErr_SetString(StructError,
526 "ubyte format requires 0 <= number <= 255");
527 return -1;
528 }
529 *p = (char)x;
530 return 0;
531}
532
533static int
534np_char(char *p, PyObject *v, const formatdef *f)
535{
536 if (!PyString_Check(v) || PyString_Size(v) != 1) {
537 PyErr_SetString(StructError,
538 "char format require string of length 1");
539 return -1;
540 }
541 *p = *PyString_AsString(v);
542 return 0;
543}
544
545static int
546np_short(char *p, PyObject *v, const formatdef *f)
547{
548 long x;
549 short y;
550 if (get_long(v, &x) < 0)
551 return -1;
552 if (x < SHRT_MIN || x > SHRT_MAX){
553 PyErr_SetString(StructError,
554 "short format requires " STRINGIFY(SHRT_MIN)
555 " <= number <= " STRINGIFY(SHRT_MAX));
556 return -1;
557 }
558 y = (short)x;
559 memcpy(p, (char *)&y, sizeof y);
560 return 0;
561}
562
563static int
564np_ushort(char *p, PyObject *v, const formatdef *f)
565{
566 long x;
567 unsigned short y;
568 if (get_long(v, &x) < 0)
569 return -1;
570 if (x < 0 || x > USHRT_MAX){
571 PyErr_SetString(StructError,
572 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
573 return -1;
574 }
575 y = (unsigned short)x;
576 memcpy(p, (char *)&y, sizeof y);
577 return 0;
578}
579
580static int
581np_int(char *p, PyObject *v, const formatdef *f)
582{
583 long x;
584 int y;
585 if (get_long(v, &x) < 0)
586 return -1;
587#if (SIZEOF_LONG > SIZEOF_INT)
588 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000589 return _range_error(f, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000590#endif
591 y = (int)x;
592 memcpy(p, (char *)&y, sizeof y);
593 return 0;
594}
595
596static int
597np_uint(char *p, PyObject *v, const formatdef *f)
598{
599 unsigned long x;
600 unsigned int y;
601 if (get_ulong(v, &x) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000602 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000603 y = (unsigned int)x;
604#if (SIZEOF_LONG > SIZEOF_INT)
605 if (x > ((unsigned long)UINT_MAX))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000606 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000607#endif
608 memcpy(p, (char *)&y, sizeof y);
609 return 0;
610}
611
612static int
613np_long(char *p, PyObject *v, const formatdef *f)
614{
615 long x;
616 if (get_long(v, &x) < 0)
617 return -1;
618 memcpy(p, (char *)&x, sizeof x);
619 return 0;
620}
621
622static int
623np_ulong(char *p, PyObject *v, const formatdef *f)
624{
625 unsigned long x;
626 if (get_ulong(v, &x) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000627 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000628 memcpy(p, (char *)&x, sizeof x);
629 return 0;
630}
631
632#ifdef HAVE_LONG_LONG
633
634static int
635np_longlong(char *p, PyObject *v, const formatdef *f)
636{
637 PY_LONG_LONG x;
638 if (get_longlong(v, &x) < 0)
639 return -1;
640 memcpy(p, (char *)&x, sizeof x);
641 return 0;
642}
643
644static int
645np_ulonglong(char *p, PyObject *v, const formatdef *f)
646{
647 unsigned PY_LONG_LONG x;
648 if (get_ulonglong(v, &x) < 0)
649 return -1;
650 memcpy(p, (char *)&x, sizeof x);
651 return 0;
652}
653#endif
654
655static int
656np_float(char *p, PyObject *v, const formatdef *f)
657{
658 float x = (float)PyFloat_AsDouble(v);
659 if (x == -1 && PyErr_Occurred()) {
660 PyErr_SetString(StructError,
661 "required argument is not a float");
662 return -1;
663 }
664 memcpy(p, (char *)&x, sizeof x);
665 return 0;
666}
667
668static int
669np_double(char *p, PyObject *v, const formatdef *f)
670{
671 double x = PyFloat_AsDouble(v);
672 if (x == -1 && PyErr_Occurred()) {
673 PyErr_SetString(StructError,
674 "required argument is not a float");
675 return -1;
676 }
677 memcpy(p, (char *)&x, sizeof(double));
678 return 0;
679}
680
681static int
682np_void_p(char *p, PyObject *v, const formatdef *f)
683{
684 void *x;
685
686 v = get_pylong(v);
687 if (v == NULL)
688 return -1;
689 assert(PyLong_Check(v));
690 x = PyLong_AsVoidPtr(v);
691 Py_DECREF(v);
692 if (x == NULL && PyErr_Occurred())
693 return -1;
694 memcpy(p, (char *)&x, sizeof x);
695 return 0;
696}
697
698static formatdef native_table[] = {
699 {'x', sizeof(char), 0, NULL},
700 {'b', sizeof(char), 0, nu_byte, np_byte},
701 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
702 {'c', sizeof(char), 0, nu_char, np_char},
703 {'s', sizeof(char), 0, NULL},
704 {'p', sizeof(char), 0, NULL},
705 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
706 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
707 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
708 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
709 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
710 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
711#ifdef HAVE_LONG_LONG
712 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
713 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
714#endif
715 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
716 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
717 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
718 {0}
719};
720
721/* Big-endian routines. *****************************************************/
722
723static PyObject *
724bu_int(const char *p, const formatdef *f)
725{
726 long x = 0;
727 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000728 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000729 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000730 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000731 } while (--i > 0);
732 /* Extend the sign bit. */
733 if (SIZEOF_LONG > f->size)
734 x |= -(x & (1L << ((8 * f->size) - 1)));
735 return PyInt_FromLong(x);
736}
737
738static PyObject *
739bu_uint(const char *p, const formatdef *f)
740{
741 unsigned long x = 0;
742 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000743 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000744 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000745 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000746 } while (--i > 0);
747 if (x <= LONG_MAX)
748 return PyInt_FromLong((long)x);
749 return PyLong_FromUnsignedLong(x);
750}
751
752static PyObject *
753bu_longlong(const char *p, const formatdef *f)
754{
755#ifdef HAVE_LONG_LONG
756 PY_LONG_LONG x = 0;
757 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000758 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000759 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000760 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000761 } while (--i > 0);
762 /* Extend the sign bit. */
763 if (SIZEOF_LONG_LONG > f->size)
764 x |= -(x & (1L << ((8 * f->size) - 1)));
765 if (x >= LONG_MIN && x <= LONG_MAX)
766 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
767 return PyLong_FromLongLong(x);
768#else
769 return _PyLong_FromByteArray((const unsigned char *)p,
770 8,
771 0, /* little-endian */
772 1 /* signed */);
773#endif
774}
775
776static PyObject *
777bu_ulonglong(const char *p, const formatdef *f)
778{
779#ifdef HAVE_LONG_LONG
780 unsigned PY_LONG_LONG x = 0;
781 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000782 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000783 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000784 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000785 } while (--i > 0);
786 if (x <= LONG_MAX)
787 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
788 return PyLong_FromUnsignedLongLong(x);
789#else
790 return _PyLong_FromByteArray((const unsigned char *)p,
791 8,
792 0, /* little-endian */
793 0 /* signed */);
794#endif
795}
796
797static PyObject *
798bu_float(const char *p, const formatdef *f)
799{
800 return unpack_float(p, 0);
801}
802
803static PyObject *
804bu_double(const char *p, const formatdef *f)
805{
806 return unpack_double(p, 0);
807}
808
809static int
810bp_int(char *p, PyObject *v, const formatdef *f)
811{
812 long x;
813 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000814 if (get_wrapped_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000815 return -1;
816 i = f->size;
817 if (i != SIZEOF_LONG) {
818 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000819 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000820#if (SIZEOF_LONG != 4)
821 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000822 RANGE_ERROR(x, f, 0, 0xffffffffL);
823#endif
824#ifdef PY_STRUCT_OVERFLOW_MASKING
825 else if ((i == 1) && (x < -128 || x > 127))
826 RANGE_ERROR(x, f, 0, 0xffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000827#endif
828 }
829 do {
830 p[--i] = (char)x;
831 x >>= 8;
832 } while (i > 0);
833 return 0;
834}
835
836static int
837bp_uint(char *p, PyObject *v, const formatdef *f)
838{
839 unsigned long x;
840 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000841 if (get_wrapped_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000842 return -1;
843 i = f->size;
844 if (i != SIZEOF_LONG) {
845 unsigned long maxint = 1;
846 maxint <<= (unsigned long)(i * 8);
847 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000848 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000849 }
850 do {
851 p[--i] = (char)x;
852 x >>= 8;
853 } while (i > 0);
854 return 0;
855}
856
857static int
858bp_longlong(char *p, PyObject *v, const formatdef *f)
859{
860 int res;
861 v = get_pylong(v);
862 if (v == NULL)
863 return -1;
864 res = _PyLong_AsByteArray((PyLongObject *)v,
865 (unsigned char *)p,
866 8,
867 0, /* little_endian */
868 1 /* signed */);
869 Py_DECREF(v);
870 return res;
871}
872
873static int
874bp_ulonglong(char *p, PyObject *v, const formatdef *f)
875{
876 int res;
877 v = get_pylong(v);
878 if (v == NULL)
879 return -1;
880 res = _PyLong_AsByteArray((PyLongObject *)v,
881 (unsigned char *)p,
882 8,
883 0, /* little_endian */
884 0 /* signed */);
885 Py_DECREF(v);
886 return res;
887}
888
889static int
890bp_float(char *p, PyObject *v, const formatdef *f)
891{
892 double x = PyFloat_AsDouble(v);
893 if (x == -1 && PyErr_Occurred()) {
894 PyErr_SetString(StructError,
895 "required argument is not a float");
896 return -1;
897 }
898 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
899}
900
901static int
902bp_double(char *p, PyObject *v, const formatdef *f)
903{
904 double x = PyFloat_AsDouble(v);
905 if (x == -1 && PyErr_Occurred()) {
906 PyErr_SetString(StructError,
907 "required argument is not a float");
908 return -1;
909 }
910 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
911}
912
913static formatdef bigendian_table[] = {
914 {'x', 1, 0, NULL},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000915#ifdef PY_STRUCT_OVERFLOW_MASKING
916 /* Native packers do range checking without overflow masking. */
917 {'b', 1, 0, nu_byte, bp_int},
918 {'B', 1, 0, nu_ubyte, bp_uint},
919#else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000920 {'b', 1, 0, nu_byte, np_byte},
921 {'B', 1, 0, nu_ubyte, np_ubyte},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000922#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000923 {'c', 1, 0, nu_char, np_char},
924 {'s', 1, 0, NULL},
925 {'p', 1, 0, NULL},
926 {'h', 2, 0, bu_int, bp_int},
927 {'H', 2, 0, bu_uint, bp_uint},
928 {'i', 4, 0, bu_int, bp_int},
929 {'I', 4, 0, bu_uint, bp_uint},
930 {'l', 4, 0, bu_int, bp_int},
931 {'L', 4, 0, bu_uint, bp_uint},
932 {'q', 8, 0, bu_longlong, bp_longlong},
933 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
934 {'f', 4, 0, bu_float, bp_float},
935 {'d', 8, 0, bu_double, bp_double},
936 {0}
937};
938
939/* Little-endian routines. *****************************************************/
940
941static PyObject *
942lu_int(const char *p, const formatdef *f)
943{
944 long x = 0;
945 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000946 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000947 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000948 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000949 } while (i > 0);
950 /* Extend the sign bit. */
951 if (SIZEOF_LONG > f->size)
952 x |= -(x & (1L << ((8 * f->size) - 1)));
953 return PyInt_FromLong(x);
954}
955
956static PyObject *
957lu_uint(const char *p, const formatdef *f)
958{
959 unsigned long x = 0;
960 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000961 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000962 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000963 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000964 } while (i > 0);
965 if (x <= LONG_MAX)
966 return PyInt_FromLong((long)x);
967 return PyLong_FromUnsignedLong((long)x);
968}
969
970static PyObject *
971lu_longlong(const char *p, const formatdef *f)
972{
973#ifdef HAVE_LONG_LONG
974 PY_LONG_LONG x = 0;
975 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000976 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000977 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000978 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000979 } while (i > 0);
980 /* Extend the sign bit. */
981 if (SIZEOF_LONG_LONG > f->size)
982 x |= -(x & (1L << ((8 * f->size) - 1)));
983 if (x >= LONG_MIN && x <= LONG_MAX)
984 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
985 return PyLong_FromLongLong(x);
986#else
987 return _PyLong_FromByteArray((const unsigned char *)p,
988 8,
989 1, /* little-endian */
990 1 /* signed */);
991#endif
992}
993
994static PyObject *
995lu_ulonglong(const char *p, const formatdef *f)
996{
997#ifdef HAVE_LONG_LONG
998 unsigned PY_LONG_LONG x = 0;
999 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001000 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001001 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001002 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001003 } while (i > 0);
1004 if (x <= LONG_MAX)
1005 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
1006 return PyLong_FromUnsignedLongLong(x);
1007#else
1008 return _PyLong_FromByteArray((const unsigned char *)p,
1009 8,
1010 1, /* little-endian */
1011 0 /* signed */);
1012#endif
1013}
1014
1015static PyObject *
1016lu_float(const char *p, const formatdef *f)
1017{
1018 return unpack_float(p, 1);
1019}
1020
1021static PyObject *
1022lu_double(const char *p, const formatdef *f)
1023{
1024 return unpack_double(p, 1);
1025}
1026
1027static int
1028lp_int(char *p, PyObject *v, const formatdef *f)
1029{
1030 long x;
1031 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001032 if (get_wrapped_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001033 return -1;
1034 i = f->size;
1035 if (i != SIZEOF_LONG) {
1036 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001037 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001038#if (SIZEOF_LONG != 4)
1039 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001040 RANGE_ERROR(x, f, 0, 0xffffffffL);
1041#endif
1042#ifdef PY_STRUCT_OVERFLOW_MASKING
1043 else if ((i == 1) && (x < -128 || x > 127))
1044 RANGE_ERROR(x, f, 0, 0xffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001045#endif
1046 }
1047 do {
1048 *p++ = (char)x;
1049 x >>= 8;
1050 } while (--i > 0);
1051 return 0;
1052}
1053
1054static int
1055lp_uint(char *p, PyObject *v, const formatdef *f)
1056{
1057 unsigned long x;
1058 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001059 if (get_wrapped_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001060 return -1;
1061 i = f->size;
1062 if (i != SIZEOF_LONG) {
1063 unsigned long maxint = 1;
1064 maxint <<= (unsigned long)(i * 8);
1065 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001066 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001067 }
1068 do {
1069 *p++ = (char)x;
1070 x >>= 8;
1071 } while (--i > 0);
1072 return 0;
1073}
1074
1075static int
1076lp_longlong(char *p, PyObject *v, const formatdef *f)
1077{
1078 int res;
1079 v = get_pylong(v);
1080 if (v == NULL)
1081 return -1;
1082 res = _PyLong_AsByteArray((PyLongObject*)v,
1083 (unsigned char *)p,
1084 8,
1085 1, /* little_endian */
1086 1 /* signed */);
1087 Py_DECREF(v);
1088 return res;
1089}
1090
1091static int
1092lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1093{
1094 int res;
1095 v = get_pylong(v);
1096 if (v == NULL)
1097 return -1;
1098 res = _PyLong_AsByteArray((PyLongObject*)v,
1099 (unsigned char *)p,
1100 8,
1101 1, /* little_endian */
1102 0 /* signed */);
1103 Py_DECREF(v);
1104 return res;
1105}
1106
1107static int
1108lp_float(char *p, PyObject *v, const formatdef *f)
1109{
1110 double x = PyFloat_AsDouble(v);
1111 if (x == -1 && PyErr_Occurred()) {
1112 PyErr_SetString(StructError,
1113 "required argument is not a float");
1114 return -1;
1115 }
1116 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1117}
1118
1119static int
1120lp_double(char *p, PyObject *v, const formatdef *f)
1121{
1122 double x = PyFloat_AsDouble(v);
1123 if (x == -1 && PyErr_Occurred()) {
1124 PyErr_SetString(StructError,
1125 "required argument is not a float");
1126 return -1;
1127 }
1128 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1129}
1130
1131static formatdef lilendian_table[] = {
1132 {'x', 1, 0, NULL},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001133#ifdef PY_STRUCT_OVERFLOW_MASKING
1134 /* Native packers do range checking without overflow masking. */
1135 {'b', 1, 0, nu_byte, lp_int},
1136 {'B', 1, 0, nu_ubyte, lp_uint},
1137#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001138 {'b', 1, 0, nu_byte, np_byte},
1139 {'B', 1, 0, nu_ubyte, np_ubyte},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001140#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001141 {'c', 1, 0, nu_char, np_char},
1142 {'s', 1, 0, NULL},
1143 {'p', 1, 0, NULL},
1144 {'h', 2, 0, lu_int, lp_int},
1145 {'H', 2, 0, lu_uint, lp_uint},
1146 {'i', 4, 0, lu_int, lp_int},
1147 {'I', 4, 0, lu_uint, lp_uint},
1148 {'l', 4, 0, lu_int, lp_int},
1149 {'L', 4, 0, lu_uint, lp_uint},
1150 {'q', 8, 0, lu_longlong, lp_longlong},
1151 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1152 {'f', 4, 0, lu_float, lp_float},
1153 {'d', 8, 0, lu_double, lp_double},
1154 {0}
1155};
1156
1157
1158static const formatdef *
1159whichtable(char **pfmt)
1160{
1161 const char *fmt = (*pfmt)++; /* May be backed out of later */
1162 switch (*fmt) {
1163 case '<':
1164 return lilendian_table;
1165 case '>':
1166 case '!': /* Network byte order is big-endian */
1167 return bigendian_table;
1168 case '=': { /* Host byte order -- different from native in aligment! */
1169 int n = 1;
1170 char *p = (char *) &n;
1171 if (*p == 1)
1172 return lilendian_table;
1173 else
1174 return bigendian_table;
1175 }
1176 default:
1177 --*pfmt; /* Back out of pointer increment */
1178 /* Fall through */
1179 case '@':
1180 return native_table;
1181 }
1182}
1183
1184
1185/* Get the table entry for a format code */
1186
1187static const formatdef *
1188getentry(int c, const formatdef *f)
1189{
1190 for (; f->format != '\0'; f++) {
1191 if (f->format == c) {
1192 return f;
1193 }
1194 }
1195 PyErr_SetString(StructError, "bad char in struct format");
1196 return NULL;
1197}
1198
1199
1200/* Align a size according to a format code */
1201
1202static int
1203align(Py_ssize_t size, char c, const formatdef *e)
1204{
1205 if (e->format == c) {
1206 if (e->alignment) {
1207 size = ((size + e->alignment - 1)
1208 / e->alignment)
1209 * e->alignment;
1210 }
1211 }
1212 return size;
1213}
1214
1215
1216/* calculate the size of a format string */
1217
1218static int
1219prepare_s(PyStructObject *self)
1220{
1221 const formatdef *f;
1222 const formatdef *e;
1223 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001224
Thomas Wouters477c8d52006-05-27 19:21:47 +00001225 const char *s;
1226 const char *fmt;
1227 char c;
1228 Py_ssize_t size, len, num, itemsize, x;
1229
1230 fmt = PyString_AS_STRING(self->s_format);
1231
1232 f = whichtable((char **)&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001233
Thomas Wouters477c8d52006-05-27 19:21:47 +00001234 s = fmt;
1235 size = 0;
1236 len = 0;
1237 while ((c = *s++) != '\0') {
1238 if (isspace(Py_CHARMASK(c)))
1239 continue;
1240 if ('0' <= c && c <= '9') {
1241 num = c - '0';
1242 while ('0' <= (c = *s++) && c <= '9') {
1243 x = num*10 + (c - '0');
1244 if (x/10 != num) {
1245 PyErr_SetString(
1246 StructError,
1247 "overflow in item count");
1248 return -1;
1249 }
1250 num = x;
1251 }
1252 if (c == '\0')
1253 break;
1254 }
1255 else
1256 num = 1;
1257
1258 e = getentry(c, f);
1259 if (e == NULL)
1260 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001261
Thomas Wouters477c8d52006-05-27 19:21:47 +00001262 switch (c) {
1263 case 's': /* fall through */
1264 case 'p': len++; break;
1265 case 'x': break;
1266 default: len += num; break;
1267 }
1268
1269 itemsize = e->size;
1270 size = align(size, c, e);
1271 x = num * itemsize;
1272 size += x;
1273 if (x/itemsize != num || size < 0) {
1274 PyErr_SetString(StructError,
1275 "total struct size too long");
1276 return -1;
1277 }
1278 }
1279
1280 self->s_size = size;
1281 self->s_len = len;
1282 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1283 if (codes == NULL) {
1284 PyErr_NoMemory();
1285 return -1;
1286 }
1287 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001288
Thomas Wouters477c8d52006-05-27 19:21:47 +00001289 s = fmt;
1290 size = 0;
1291 while ((c = *s++) != '\0') {
1292 if (isspace(Py_CHARMASK(c)))
1293 continue;
1294 if ('0' <= c && c <= '9') {
1295 num = c - '0';
1296 while ('0' <= (c = *s++) && c <= '9')
1297 num = num*10 + (c - '0');
1298 if (c == '\0')
1299 break;
1300 }
1301 else
1302 num = 1;
1303
1304 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001305
Thomas Wouters477c8d52006-05-27 19:21:47 +00001306 size = align(size, c, e);
1307 if (c == 's' || c == 'p') {
1308 codes->offset = size;
1309 codes->size = num;
1310 codes->fmtdef = e;
1311 codes++;
1312 size += num;
1313 } else if (c == 'x') {
1314 size += num;
1315 } else {
1316 while (--num >= 0) {
1317 codes->offset = size;
1318 codes->size = e->size;
1319 codes->fmtdef = e;
1320 codes++;
1321 size += e->size;
1322 }
1323 }
1324 }
1325 codes->fmtdef = NULL;
1326 codes->offset = size;
1327 codes->size = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001328
Thomas Wouters477c8d52006-05-27 19:21:47 +00001329 return 0;
1330}
1331
1332static PyObject *
1333s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1334{
1335 PyObject *self;
1336
1337 assert(type != NULL && type->tp_alloc != NULL);
1338
1339 self = type->tp_alloc(type, 0);
1340 if (self != NULL) {
1341 PyStructObject *s = (PyStructObject*)self;
1342 Py_INCREF(Py_None);
1343 s->s_format = Py_None;
1344 s->s_codes = NULL;
1345 s->s_size = -1;
1346 s->s_len = -1;
1347 }
1348 return self;
1349}
1350
1351static int
1352s_init(PyObject *self, PyObject *args, PyObject *kwds)
1353{
1354 PyStructObject *soself = (PyStructObject *)self;
1355 PyObject *o_format = NULL;
1356 int ret = 0;
1357 static char *kwlist[] = {"format", 0};
1358
1359 assert(PyStruct_Check(self));
1360
1361 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1362 &o_format))
1363 return -1;
1364
1365 Py_INCREF(o_format);
1366 Py_XDECREF(soself->s_format);
1367 soself->s_format = o_format;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001368
Thomas Wouters477c8d52006-05-27 19:21:47 +00001369 ret = prepare_s(soself);
1370 return ret;
1371}
1372
1373static void
1374s_dealloc(PyStructObject *s)
1375{
1376 if (s->weakreflist != NULL)
1377 PyObject_ClearWeakRefs((PyObject *)s);
1378 if (s->s_codes != NULL) {
1379 PyMem_FREE(s->s_codes);
1380 }
1381 Py_XDECREF(s->s_format);
1382 s->ob_type->tp_free((PyObject *)s);
1383}
1384
1385static PyObject *
1386s_unpack_internal(PyStructObject *soself, char *startfrom) {
1387 formatcode *code;
1388 Py_ssize_t i = 0;
1389 PyObject *result = PyTuple_New(soself->s_len);
1390 if (result == NULL)
1391 return NULL;
1392
1393 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1394 PyObject *v;
1395 const formatdef *e = code->fmtdef;
1396 const char *res = startfrom + code->offset;
1397 if (e->format == 's') {
1398 v = PyString_FromStringAndSize(res, code->size);
1399 if (v == NULL)
1400 goto fail;
1401 PyTuple_SET_ITEM(result, i++, v);
1402 } else if (e->format == 'p') {
1403 Py_ssize_t n = *(unsigned char*)res;
1404 if (n >= code->size)
1405 n = code->size - 1;
1406 v = PyString_FromStringAndSize(res + 1, n);
1407 if (v == NULL)
1408 goto fail;
1409 PyTuple_SET_ITEM(result, i++, v);
1410 } else {
1411 v = e->unpack(res, e);
1412 if (v == NULL)
1413 goto fail;
1414 PyTuple_SET_ITEM(result, i++, v);
1415 }
1416 }
1417
1418 return result;
1419fail:
1420 Py_DECREF(result);
1421 return NULL;
1422}
1423
1424
1425PyDoc_STRVAR(s_unpack__doc__,
1426"S.unpack(str) -> (v1, v2, ...)\n\
1427\n\
1428Return tuple containing values unpacked according to this Struct's format.\n\
1429Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1430strings.");
1431
1432static PyObject *
1433s_unpack(PyObject *self, PyObject *inputstr)
1434{
1435 PyStructObject *soself = (PyStructObject *)self;
1436 assert(PyStruct_Check(self));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001437 assert(soself->s_codes != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001438 if (inputstr == NULL || !PyString_Check(inputstr) ||
1439 PyString_GET_SIZE(inputstr) != soself->s_size) {
1440 PyErr_Format(StructError,
1441 "unpack requires a string argument of length %zd", soself->s_size);
1442 return NULL;
1443 }
1444 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1445}
1446
1447PyDoc_STRVAR(s_unpack_from__doc__,
1448"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1449\n\
1450Return tuple containing values unpacked according to this Struct's format.\n\
1451Unlike unpack, unpack_from can unpack values from any object supporting\n\
1452the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1453See struct.__doc__ for more on format strings.");
1454
1455static PyObject *
1456s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1457{
1458 static char *kwlist[] = {"buffer", "offset", 0};
1459#if (PY_VERSION_HEX < 0x02050000)
1460 static char *fmt = "z#|i:unpack_from";
1461#else
1462 static char *fmt = "z#|n:unpack_from";
1463#endif
1464 Py_ssize_t buffer_len = 0, offset = 0;
1465 char *buffer = NULL;
1466 PyStructObject *soself = (PyStructObject *)self;
1467 assert(PyStruct_Check(self));
1468 assert(soself->s_codes != NULL);
1469
1470 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1471 &buffer, &buffer_len, &offset))
1472 return NULL;
1473
1474 if (buffer == NULL) {
1475 PyErr_Format(StructError,
1476 "unpack_from requires a buffer argument");
1477 return NULL;
1478 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001479
Thomas Wouters477c8d52006-05-27 19:21:47 +00001480 if (offset < 0)
1481 offset += buffer_len;
1482
1483 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1484 PyErr_Format(StructError,
1485 "unpack_from requires a buffer of at least %zd bytes",
1486 soself->s_size);
1487 return NULL;
1488 }
1489 return s_unpack_internal(soself, buffer + offset);
1490}
1491
1492
1493/*
1494 * Guts of the pack function.
1495 *
1496 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1497 * argument for where to start processing the arguments for packing, and a
1498 * character buffer for writing the packed string. The caller must insure
1499 * that the buffer may contain the required length for packing the arguments.
1500 * 0 is returned on success, 1 is returned if there is an error.
1501 *
1502 */
1503static int
1504s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1505{
1506 formatcode *code;
1507 Py_ssize_t i;
1508
1509 memset(buf, '\0', soself->s_size);
1510 i = offset;
1511 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1512 Py_ssize_t n;
1513 PyObject *v;
1514 const formatdef *e = code->fmtdef;
1515 char *res = buf + code->offset;
1516 if (e->format == 's') {
1517 v = PyTuple_GET_ITEM(args, i++);
1518 if (!PyString_Check(v)) {
1519 PyErr_SetString(StructError,
1520 "argument for 's' must be a string");
1521 return -1;
1522 }
1523 n = PyString_GET_SIZE(v);
1524 if (n > code->size)
1525 n = code->size;
1526 if (n > 0)
1527 memcpy(res, PyString_AS_STRING(v), n);
1528 } else if (e->format == 'p') {
1529 v = PyTuple_GET_ITEM(args, i++);
1530 if (!PyString_Check(v)) {
1531 PyErr_SetString(StructError,
1532 "argument for 'p' must be a string");
1533 return -1;
1534 }
1535 n = PyString_GET_SIZE(v);
1536 if (n > (code->size - 1))
1537 n = code->size - 1;
1538 if (n > 0)
1539 memcpy(res + 1, PyString_AS_STRING(v), n);
1540 if (n > 255)
1541 n = 255;
1542 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1543 } else {
1544 v = PyTuple_GET_ITEM(args, i++);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001545 if (e->pack(res, v, e) < 0) {
1546 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1547 PyErr_SetString(StructError,
1548 "long too large to convert to int");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001549 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001550 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001551 }
1552 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001553
Thomas Wouters477c8d52006-05-27 19:21:47 +00001554 /* Success */
1555 return 0;
1556}
1557
1558
1559PyDoc_STRVAR(s_pack__doc__,
1560"S.pack(v1, v2, ...) -> string\n\
1561\n\
1562Return a string containing values v1, v2, ... packed according to this\n\
1563Struct's format. See struct.__doc__ for more on format strings.");
1564
1565static PyObject *
1566s_pack(PyObject *self, PyObject *args)
1567{
1568 PyStructObject *soself;
1569 PyObject *result;
1570
1571 /* Validate arguments. */
1572 soself = (PyStructObject *)self;
1573 assert(PyStruct_Check(self));
1574 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001575 if (PyTuple_GET_SIZE(args) != soself->s_len)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001576 {
1577 PyErr_Format(StructError,
1578 "pack requires exactly %zd arguments", soself->s_len);
1579 return NULL;
1580 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001581
Thomas Wouters477c8d52006-05-27 19:21:47 +00001582 /* Allocate a new string */
1583 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1584 if (result == NULL)
1585 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001586
Thomas Wouters477c8d52006-05-27 19:21:47 +00001587 /* Call the guts */
1588 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1589 Py_DECREF(result);
1590 return NULL;
1591 }
1592
1593 return result;
1594}
1595
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001596PyDoc_STRVAR(s_pack_into__doc__,
1597"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001598\n\
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001599Pack the values v1, v2, ... according to this Struct's format, write \n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001600the packed bytes into the writable buffer buf starting at offset. Note\n\
1601that the offset is not an optional argument. See struct.__doc__ for \n\
1602more on format strings.");
1603
1604static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001605s_pack_into(PyObject *self, PyObject *args)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001606{
1607 PyStructObject *soself;
1608 char *buffer;
1609 Py_ssize_t buffer_len, offset;
1610
1611 /* Validate arguments. +1 is for the first arg as buffer. */
1612 soself = (PyStructObject *)self;
1613 assert(PyStruct_Check(self));
1614 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001615 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001616 {
1617 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001618 "pack_into requires exactly %zd arguments",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001619 (soself->s_len + 2));
1620 return NULL;
1621 }
1622
1623 /* Extract a writable memory buffer from the first argument */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001624 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1625 (void**)&buffer, &buffer_len) == -1 ) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001626 return NULL;
1627 }
1628 assert( buffer_len >= 0 );
1629
1630 /* Extract the offset from the first argument */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001631 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001632
1633 /* Support negative offsets. */
1634 if (offset < 0)
1635 offset += buffer_len;
1636
1637 /* Check boundaries */
1638 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1639 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001640 "pack_into requires a buffer of at least %zd bytes",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001641 soself->s_size);
1642 return NULL;
1643 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001644
Thomas Wouters477c8d52006-05-27 19:21:47 +00001645 /* Call the guts */
1646 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1647 return NULL;
1648 }
1649
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001650 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001651}
1652
1653static PyObject *
1654s_get_format(PyStructObject *self, void *unused)
1655{
1656 Py_INCREF(self->s_format);
1657 return self->s_format;
1658}
1659
1660static PyObject *
1661s_get_size(PyStructObject *self, void *unused)
1662{
1663 return PyInt_FromSsize_t(self->s_size);
1664}
1665
1666/* List of functions */
1667
1668static struct PyMethodDef s_methods[] = {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001669 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1670 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1671 {"unpack", s_unpack, METH_O, s_unpack__doc__},
1672 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS,
1673 s_unpack_from__doc__},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001674 {NULL, NULL} /* sentinel */
1675};
1676
1677PyDoc_STRVAR(s__doc__, "Compiled struct object");
1678
1679#define OFF(x) offsetof(PyStructObject, x)
1680
1681static PyGetSetDef s_getsetlist[] = {
1682 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1683 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1684 {NULL} /* sentinel */
1685};
1686
1687static
1688PyTypeObject PyStructType = {
1689 PyObject_HEAD_INIT(NULL)
1690 0,
1691 "Struct",
1692 sizeof(PyStructObject),
1693 0,
1694 (destructor)s_dealloc, /* tp_dealloc */
1695 0, /* tp_print */
1696 0, /* tp_getattr */
1697 0, /* tp_setattr */
1698 0, /* tp_compare */
1699 0, /* tp_repr */
1700 0, /* tp_as_number */
1701 0, /* tp_as_sequence */
1702 0, /* tp_as_mapping */
1703 0, /* tp_hash */
1704 0, /* tp_call */
1705 0, /* tp_str */
1706 PyObject_GenericGetAttr, /* tp_getattro */
1707 PyObject_GenericSetAttr, /* tp_setattro */
1708 0, /* tp_as_buffer */
1709 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1710 s__doc__, /* tp_doc */
1711 0, /* tp_traverse */
1712 0, /* tp_clear */
1713 0, /* tp_richcompare */
1714 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1715 0, /* tp_iter */
1716 0, /* tp_iternext */
1717 s_methods, /* tp_methods */
1718 NULL, /* tp_members */
1719 s_getsetlist, /* tp_getset */
1720 0, /* tp_base */
1721 0, /* tp_dict */
1722 0, /* tp_descr_get */
1723 0, /* tp_descr_set */
1724 0, /* tp_dictoffset */
1725 s_init, /* tp_init */
1726 PyType_GenericAlloc,/* tp_alloc */
1727 s_new, /* tp_new */
1728 PyObject_Del, /* tp_free */
1729};
1730
1731/* Module initialization */
1732
1733PyMODINIT_FUNC
1734init_struct(void)
1735{
1736 PyObject *m = Py_InitModule("_struct", NULL);
1737 if (m == NULL)
1738 return;
1739
1740 PyStructType.ob_type = &PyType_Type;
1741 if (PyType_Ready(&PyStructType) < 0)
1742 return;
1743
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001744#ifdef PY_STRUCT_OVERFLOW_MASKING
1745 if (pyint_zero == NULL) {
1746 pyint_zero = PyInt_FromLong(0);
1747 if (pyint_zero == NULL)
1748 return;
1749 }
1750 if (pylong_ulong_mask == NULL) {
1751#if (SIZEOF_LONG == 4)
1752 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1753#else
1754 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1755#endif
1756 if (pylong_ulong_mask == NULL)
1757 return;
1758 }
1759
1760#else
1761 /* This speed trick can't be used until overflow masking goes away, because
1762 native endian always raises exceptions instead of overflow masking. */
1763
Thomas Wouters477c8d52006-05-27 19:21:47 +00001764 /* Check endian and swap in faster functions */
1765 {
1766 int one = 1;
1767 formatdef *native = native_table;
1768 formatdef *other, *ptr;
1769 if ((int)*(unsigned char*)&one)
1770 other = lilendian_table;
1771 else
1772 other = bigendian_table;
1773 /* Scan through the native table, find a matching
1774 entry in the endian table and swap in the
1775 native implementations whenever possible
1776 (64-bit platforms may not have "standard" sizes) */
1777 while (native->format != '\0' && other->format != '\0') {
1778 ptr = other;
1779 while (ptr->format != '\0') {
1780 if (ptr->format == native->format) {
1781 /* Match faster when formats are
1782 listed in the same order */
1783 if (ptr == other)
1784 other++;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001785 /* Only use the trick if the
Thomas Wouters477c8d52006-05-27 19:21:47 +00001786 size matches */
1787 if (ptr->size != native->size)
1788 break;
1789 /* Skip float and double, could be
1790 "unknown" float format */
1791 if (ptr->format == 'd' || ptr->format == 'f')
1792 break;
1793 ptr->pack = native->pack;
1794 ptr->unpack = native->unpack;
1795 break;
1796 }
1797 ptr++;
1798 }
1799 native++;
1800 }
1801 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001802#endif
1803
Thomas Wouters477c8d52006-05-27 19:21:47 +00001804 /* Add some symbolic constants to the module */
1805 if (StructError == NULL) {
1806 StructError = PyErr_NewException("struct.error", NULL, NULL);
1807 if (StructError == NULL)
1808 return;
1809 }
1810
1811 Py_INCREF(StructError);
1812 PyModule_AddObject(m, "error", StructError);
1813
1814 Py_INCREF((PyObject*)&PyStructType);
1815 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001816
1817 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
1818#ifdef PY_STRUCT_OVERFLOW_MASKING
1819 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
1820#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001821}