blob: 518a57e2695b2e8157ccd0a4e0f1947016e3c43e [file] [log] [blame]
Thomas Wouters477c8d52006-05-27 19:21:47 +00001/* struct module -- pack values into and (out of) strings */
2
3/* New version supporting byte order, alignment and size options,
4 character strings, and unsigned numbers */
5
6#define PY_SSIZE_T_CLEAN
7
8#include "Python.h"
9#include "structseq.h"
10#include "structmember.h"
11#include <ctype.h>
12
13static PyTypeObject PyStructType;
14
15/* compatibility macros */
16#if (PY_VERSION_HEX < 0x02050000)
17typedef int Py_ssize_t;
18#endif
19
Thomas Wouters4d70c3d2006-06-08 14:42:34 +000020/* If PY_STRUCT_OVERFLOW_MASKING is defined, the struct module will wrap all input
21 numbers for explicit endians such that they fit in the given type, much
22 like explicit casting in C. A warning will be raised if the number did
23 not originally fit within the range of the requested type. If it is
24 not defined, then all range errors and overflow will be struct.error
25 exceptions. */
26
27#define PY_STRUCT_OVERFLOW_MASKING 1
28
29#ifdef PY_STRUCT_OVERFLOW_MASKING
30static PyObject *pylong_ulong_mask = NULL;
31static PyObject *pyint_zero = NULL;
32#endif
33
Thomas Wouters0e3f5912006-08-11 14:57:12 +000034/* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float
35 arguments for integer formats with a warning for backwards
36 compatibility. */
37
38#define PY_STRUCT_FLOAT_COERCE 1
39
40#ifdef PY_STRUCT_FLOAT_COERCE
41#define FLOAT_COERCE "integer argument expected, got float"
42#endif
43
44
Thomas Wouters477c8d52006-05-27 19:21:47 +000045/* The translation function for each format character is table driven */
46typedef struct _formatdef {
47 char format;
48 Py_ssize_t size;
49 Py_ssize_t alignment;
50 PyObject* (*unpack)(const char *,
51 const struct _formatdef *);
52 int (*pack)(char *, PyObject *,
53 const struct _formatdef *);
54} formatdef;
55
56typedef struct _formatcode {
57 const struct _formatdef *fmtdef;
58 Py_ssize_t offset;
59 Py_ssize_t size;
60} formatcode;
61
62/* Struct object interface */
63
64typedef struct {
65 PyObject_HEAD
66 Py_ssize_t s_size;
67 Py_ssize_t s_len;
68 formatcode *s_codes;
69 PyObject *s_format;
70 PyObject *weakreflist; /* List of weak references */
71} PyStructObject;
72
73
74#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
75#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
76
77
78/* Exception */
79
80static PyObject *StructError;
81
82
83/* Define various structs to figure out the alignments of types */
84
85
86typedef struct { char c; short x; } st_short;
87typedef struct { char c; int x; } st_int;
88typedef struct { char c; long x; } st_long;
89typedef struct { char c; float x; } st_float;
90typedef struct { char c; double x; } st_double;
91typedef struct { char c; void *x; } st_void_p;
92
93#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
94#define INT_ALIGN (sizeof(st_int) - sizeof(int))
95#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
96#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
97#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
98#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
99
100/* We can't support q and Q in native mode unless the compiler does;
101 in std mode, they're 8 bytes on all platforms. */
102#ifdef HAVE_LONG_LONG
103typedef struct { char c; PY_LONG_LONG x; } s_long_long;
104#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
105#endif
106
107#define STRINGIFY(x) #x
108
109#ifdef __powerc
110#pragma options align=reset
111#endif
112
113/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
114
115static PyObject *
116get_pylong(PyObject *v)
117{
118 PyNumberMethods *m;
119
120 assert(v != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000121 if (PyLong_Check(v)) {
122 Py_INCREF(v);
123 return v;
124 }
125 m = v->ob_type->tp_as_number;
126 if (m != NULL && m->nb_long != NULL) {
127 v = m->nb_long(v);
128 if (v == NULL)
129 return NULL;
130 if (PyLong_Check(v))
131 return v;
132 Py_DECREF(v);
133 }
134 PyErr_SetString(StructError,
135 "cannot convert argument to long");
136 return NULL;
137}
138
139/* Helper routine to get a Python integer and raise the appropriate error
140 if it isn't one */
141
142static int
143get_long(PyObject *v, long *p)
144{
145 long x = PyInt_AsLong(v);
146 if (x == -1 && PyErr_Occurred()) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000147#ifdef PY_STRUCT_FLOAT_COERCE
148 if (PyFloat_Check(v)) {
149 PyObject *o;
150 int res;
151 PyErr_Clear();
152 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
153 return -1;
154 o = PyNumber_Int(v);
155 if (o == NULL)
156 return -1;
157 res = get_long(o, p);
158 Py_DECREF(o);
159 return res;
160 }
161#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000162 if (PyErr_ExceptionMatches(PyExc_TypeError))
163 PyErr_SetString(StructError,
164 "required argument is not an integer");
165 return -1;
166 }
167 *p = x;
168 return 0;
169}
170
171
172/* Same, but handling unsigned long */
173
174static int
175get_ulong(PyObject *v, unsigned long *p)
176{
177 if (PyLong_Check(v)) {
178 unsigned long x = PyLong_AsUnsignedLong(v);
179 if (x == (unsigned long)(-1) && PyErr_Occurred())
180 return -1;
181 *p = x;
182 return 0;
183 }
184 if (get_long(v, (long *)p) < 0)
185 return -1;
186 if (((long)*p) < 0) {
187 PyErr_SetString(StructError,
188 "unsigned argument is < 0");
189 return -1;
190 }
191 return 0;
192}
193
194#ifdef HAVE_LONG_LONG
195
196/* Same, but handling native long long. */
197
198static int
199get_longlong(PyObject *v, PY_LONG_LONG *p)
200{
201 PY_LONG_LONG x;
202
203 v = get_pylong(v);
204 if (v == NULL)
205 return -1;
206 assert(PyLong_Check(v));
207 x = PyLong_AsLongLong(v);
208 Py_DECREF(v);
209 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
210 return -1;
211 *p = x;
212 return 0;
213}
214
215/* Same, but handling native unsigned long long. */
216
217static int
218get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
219{
220 unsigned PY_LONG_LONG x;
221
222 v = get_pylong(v);
223 if (v == NULL)
224 return -1;
225 assert(PyLong_Check(v));
226 x = PyLong_AsUnsignedLongLong(v);
227 Py_DECREF(v);
228 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
229 return -1;
230 *p = x;
231 return 0;
232}
233
234#endif
235
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000236#ifdef PY_STRUCT_OVERFLOW_MASKING
237
238/* Helper routine to get a Python integer and raise the appropriate error
239 if it isn't one */
240
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000241#define INT_OVERFLOW "struct integer overflow masking is deprecated"
242
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000243static int
244get_wrapped_long(PyObject *v, long *p)
245{
246 if (get_long(v, p) < 0) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000247 if (PyLong_Check(v) &&
248 PyErr_ExceptionMatches(PyExc_OverflowError)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000249 PyObject *wrapped;
250 long x;
251 PyErr_Clear();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000252#ifdef PY_STRUCT_FLOAT_COERCE
253 if (PyFloat_Check(v)) {
254 PyObject *o;
255 int res;
256 PyErr_Clear();
257 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
258 return -1;
259 o = PyNumber_Int(v);
260 if (o == NULL)
261 return -1;
262 res = get_wrapped_long(o, p);
263 Py_DECREF(o);
264 return res;
265 }
266#endif
267 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000268 return -1;
269 wrapped = PyNumber_And(v, pylong_ulong_mask);
270 if (wrapped == NULL)
271 return -1;
272 x = (long)PyLong_AsUnsignedLong(wrapped);
273 Py_DECREF(wrapped);
274 if (x == -1 && PyErr_Occurred())
275 return -1;
276 *p = x;
277 } else {
278 return -1;
279 }
280 }
281 return 0;
282}
283
284static int
285get_wrapped_ulong(PyObject *v, unsigned long *p)
286{
287 long x = (long)PyLong_AsUnsignedLong(v);
288 if (x == -1 && PyErr_Occurred()) {
289 PyObject *wrapped;
290 PyErr_Clear();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000291#ifdef PY_STRUCT_FLOAT_COERCE
292 if (PyFloat_Check(v)) {
293 PyObject *o;
294 int res;
295 PyErr_Clear();
296 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
297 return -1;
298 o = PyNumber_Int(v);
299 if (o == NULL)
300 return -1;
301 res = get_wrapped_ulong(o, p);
302 Py_DECREF(o);
303 return res;
304 }
305#endif
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000306 wrapped = PyNumber_And(v, pylong_ulong_mask);
307 if (wrapped == NULL)
308 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000309 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000310 Py_DECREF(wrapped);
311 return -1;
312 }
313 x = (long)PyLong_AsUnsignedLong(wrapped);
314 Py_DECREF(wrapped);
315 if (x == -1 && PyErr_Occurred())
316 return -1;
317 }
318 *p = (unsigned long)x;
319 return 0;
320}
321
322#define RANGE_ERROR(x, f, flag, mask) \
323 do { \
324 if (_range_error(f, flag) < 0) \
325 return -1; \
326 else \
327 (x) &= (mask); \
328 } while (0)
329
330#else
331
332#define get_wrapped_long get_long
333#define get_wrapped_ulong get_ulong
334#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
335
336#endif
337
Thomas Wouters477c8d52006-05-27 19:21:47 +0000338/* Floating point helpers */
339
340static PyObject *
341unpack_float(const char *p, /* start of 4-byte string */
342 int le) /* true for little-endian, false for big-endian */
343{
344 double x;
345
346 x = _PyFloat_Unpack4((unsigned char *)p, le);
347 if (x == -1.0 && PyErr_Occurred())
348 return NULL;
349 return PyFloat_FromDouble(x);
350}
351
352static PyObject *
353unpack_double(const char *p, /* start of 8-byte string */
354 int le) /* true for little-endian, false for big-endian */
355{
356 double x;
357
358 x = _PyFloat_Unpack8((unsigned char *)p, le);
359 if (x == -1.0 && PyErr_Occurred())
360 return NULL;
361 return PyFloat_FromDouble(x);
362}
363
364/* Helper to format the range error exceptions */
365static int
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000366_range_error(const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000367{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000368 /* ulargest is the largest unsigned value with f->size bytes.
369 * Note that the simpler:
370 * ((size_t)1 << (f->size * 8)) - 1
371 * doesn't work when f->size == sizeof(size_t) because C doesn't
372 * define what happens when a left shift count is >= the number of
373 * bits in the integer being shifted; e.g., on some boxes it doesn't
374 * shift at all when they're equal.
375 */
376 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
377 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
378 if (is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000379 PyErr_Format(StructError,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000380 "'%c' format requires 0 <= number <= %zu",
381 f->format,
382 ulargest);
383 else {
384 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000385 PyErr_Format(StructError,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000386 "'%c' format requires %zd <= number <= %zd",
387 f->format,
388 ~ largest,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000389 largest);
390 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000391#ifdef PY_STRUCT_OVERFLOW_MASKING
392 {
393 PyObject *ptype, *pvalue, *ptraceback;
394 PyObject *msg;
395 int rval;
396 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
397 assert(pvalue != NULL);
398 msg = PyObject_Str(pvalue);
399 Py_XDECREF(ptype);
400 Py_XDECREF(pvalue);
401 Py_XDECREF(ptraceback);
402 if (msg == NULL)
403 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000404 rval = PyErr_WarnEx(PyExc_DeprecationWarning,
405 PyString_AS_STRING(msg), 2);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000406 Py_DECREF(msg);
407 if (rval == 0)
408 return 0;
409 }
410#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000411 return -1;
412}
413
414
415
416/* A large number of small routines follow, with names of the form
417
418 [bln][up]_TYPE
419
420 [bln] distiguishes among big-endian, little-endian and native.
421 [pu] distiguishes between pack (to struct) and unpack (from struct).
422 TYPE is one of char, byte, ubyte, etc.
423*/
424
425/* Native mode routines. ****************************************************/
426/* NOTE:
427 In all n[up]_<type> routines handling types larger than 1 byte, there is
428 *no* guarantee that the p pointer is properly aligned for each type,
429 therefore memcpy is called. An intermediate variable is used to
430 compensate for big-endian architectures.
431 Normally both the intermediate variable and the memcpy call will be
432 skipped by C optimisation in little-endian architectures (gcc >= 2.91
433 does this). */
434
435static PyObject *
436nu_char(const char *p, const formatdef *f)
437{
438 return PyString_FromStringAndSize(p, 1);
439}
440
441static PyObject *
442nu_byte(const char *p, const formatdef *f)
443{
444 return PyInt_FromLong((long) *(signed char *)p);
445}
446
447static PyObject *
448nu_ubyte(const char *p, const formatdef *f)
449{
450 return PyInt_FromLong((long) *(unsigned char *)p);
451}
452
453static PyObject *
454nu_short(const char *p, const formatdef *f)
455{
456 short x;
457 memcpy((char *)&x, p, sizeof x);
458 return PyInt_FromLong((long)x);
459}
460
461static PyObject *
462nu_ushort(const char *p, const formatdef *f)
463{
464 unsigned short x;
465 memcpy((char *)&x, p, sizeof x);
466 return PyInt_FromLong((long)x);
467}
468
469static PyObject *
470nu_int(const char *p, const formatdef *f)
471{
472 int x;
473 memcpy((char *)&x, p, sizeof x);
474 return PyInt_FromLong((long)x);
475}
476
477static PyObject *
478nu_uint(const char *p, const formatdef *f)
479{
480 unsigned int x;
481 memcpy((char *)&x, p, sizeof x);
482#if (SIZEOF_LONG > SIZEOF_INT)
483 return PyInt_FromLong((long)x);
484#else
485 if (x <= ((unsigned int)LONG_MAX))
486 return PyInt_FromLong((long)x);
487 return PyLong_FromUnsignedLong((unsigned long)x);
488#endif
489}
490
491static PyObject *
492nu_long(const char *p, const formatdef *f)
493{
494 long x;
495 memcpy((char *)&x, p, sizeof x);
496 return PyInt_FromLong(x);
497}
498
499static PyObject *
500nu_ulong(const char *p, const formatdef *f)
501{
502 unsigned long x;
503 memcpy((char *)&x, p, sizeof x);
504 if (x <= LONG_MAX)
505 return PyInt_FromLong((long)x);
506 return PyLong_FromUnsignedLong(x);
507}
508
509/* Native mode doesn't support q or Q unless the platform C supports
510 long long (or, on Windows, __int64). */
511
512#ifdef HAVE_LONG_LONG
513
514static PyObject *
515nu_longlong(const char *p, const formatdef *f)
516{
517 PY_LONG_LONG x;
518 memcpy((char *)&x, p, sizeof x);
519 if (x >= LONG_MIN && x <= LONG_MAX)
520 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
521 return PyLong_FromLongLong(x);
522}
523
524static PyObject *
525nu_ulonglong(const char *p, const formatdef *f)
526{
527 unsigned PY_LONG_LONG x;
528 memcpy((char *)&x, p, sizeof x);
529 if (x <= LONG_MAX)
530 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
531 return PyLong_FromUnsignedLongLong(x);
532}
533
534#endif
535
536static PyObject *
537nu_float(const char *p, const formatdef *f)
538{
539 float x;
540 memcpy((char *)&x, p, sizeof x);
541 return PyFloat_FromDouble((double)x);
542}
543
544static PyObject *
545nu_double(const char *p, const formatdef *f)
546{
547 double x;
548 memcpy((char *)&x, p, sizeof x);
549 return PyFloat_FromDouble(x);
550}
551
552static PyObject *
553nu_void_p(const char *p, const formatdef *f)
554{
555 void *x;
556 memcpy((char *)&x, p, sizeof x);
557 return PyLong_FromVoidPtr(x);
558}
559
560static int
561np_byte(char *p, PyObject *v, const formatdef *f)
562{
563 long x;
564 if (get_long(v, &x) < 0)
565 return -1;
566 if (x < -128 || x > 127){
567 PyErr_SetString(StructError,
568 "byte format requires -128 <= number <= 127");
569 return -1;
570 }
571 *p = (char)x;
572 return 0;
573}
574
575static int
576np_ubyte(char *p, PyObject *v, const formatdef *f)
577{
578 long x;
579 if (get_long(v, &x) < 0)
580 return -1;
581 if (x < 0 || x > 255){
582 PyErr_SetString(StructError,
583 "ubyte format requires 0 <= number <= 255");
584 return -1;
585 }
586 *p = (char)x;
587 return 0;
588}
589
590static int
591np_char(char *p, PyObject *v, const formatdef *f)
592{
593 if (!PyString_Check(v) || PyString_Size(v) != 1) {
594 PyErr_SetString(StructError,
595 "char format require string of length 1");
596 return -1;
597 }
598 *p = *PyString_AsString(v);
599 return 0;
600}
601
602static int
603np_short(char *p, PyObject *v, const formatdef *f)
604{
605 long x;
606 short y;
607 if (get_long(v, &x) < 0)
608 return -1;
609 if (x < SHRT_MIN || x > SHRT_MAX){
610 PyErr_SetString(StructError,
611 "short format requires " STRINGIFY(SHRT_MIN)
612 " <= number <= " STRINGIFY(SHRT_MAX));
613 return -1;
614 }
615 y = (short)x;
616 memcpy(p, (char *)&y, sizeof y);
617 return 0;
618}
619
620static int
621np_ushort(char *p, PyObject *v, const formatdef *f)
622{
623 long x;
624 unsigned short y;
625 if (get_long(v, &x) < 0)
626 return -1;
627 if (x < 0 || x > USHRT_MAX){
628 PyErr_SetString(StructError,
629 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
630 return -1;
631 }
632 y = (unsigned short)x;
633 memcpy(p, (char *)&y, sizeof y);
634 return 0;
635}
636
637static int
638np_int(char *p, PyObject *v, const formatdef *f)
639{
640 long x;
641 int y;
642 if (get_long(v, &x) < 0)
643 return -1;
644#if (SIZEOF_LONG > SIZEOF_INT)
645 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000646 return _range_error(f, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000647#endif
648 y = (int)x;
649 memcpy(p, (char *)&y, sizeof y);
650 return 0;
651}
652
653static int
654np_uint(char *p, PyObject *v, const formatdef *f)
655{
656 unsigned long x;
657 unsigned int y;
658 if (get_ulong(v, &x) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000659 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000660 y = (unsigned int)x;
661#if (SIZEOF_LONG > SIZEOF_INT)
662 if (x > ((unsigned long)UINT_MAX))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000663 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000664#endif
665 memcpy(p, (char *)&y, sizeof y);
666 return 0;
667}
668
669static int
670np_long(char *p, PyObject *v, const formatdef *f)
671{
672 long x;
673 if (get_long(v, &x) < 0)
674 return -1;
675 memcpy(p, (char *)&x, sizeof x);
676 return 0;
677}
678
679static int
680np_ulong(char *p, PyObject *v, const formatdef *f)
681{
682 unsigned long x;
683 if (get_ulong(v, &x) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000684 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000685 memcpy(p, (char *)&x, sizeof x);
686 return 0;
687}
688
689#ifdef HAVE_LONG_LONG
690
691static int
692np_longlong(char *p, PyObject *v, const formatdef *f)
693{
694 PY_LONG_LONG x;
695 if (get_longlong(v, &x) < 0)
696 return -1;
697 memcpy(p, (char *)&x, sizeof x);
698 return 0;
699}
700
701static int
702np_ulonglong(char *p, PyObject *v, const formatdef *f)
703{
704 unsigned PY_LONG_LONG x;
705 if (get_ulonglong(v, &x) < 0)
706 return -1;
707 memcpy(p, (char *)&x, sizeof x);
708 return 0;
709}
710#endif
711
712static int
713np_float(char *p, PyObject *v, const formatdef *f)
714{
715 float x = (float)PyFloat_AsDouble(v);
716 if (x == -1 && PyErr_Occurred()) {
717 PyErr_SetString(StructError,
718 "required argument is not a float");
719 return -1;
720 }
721 memcpy(p, (char *)&x, sizeof x);
722 return 0;
723}
724
725static int
726np_double(char *p, PyObject *v, const formatdef *f)
727{
728 double x = PyFloat_AsDouble(v);
729 if (x == -1 && PyErr_Occurred()) {
730 PyErr_SetString(StructError,
731 "required argument is not a float");
732 return -1;
733 }
734 memcpy(p, (char *)&x, sizeof(double));
735 return 0;
736}
737
738static int
739np_void_p(char *p, PyObject *v, const formatdef *f)
740{
741 void *x;
742
743 v = get_pylong(v);
744 if (v == NULL)
745 return -1;
746 assert(PyLong_Check(v));
747 x = PyLong_AsVoidPtr(v);
748 Py_DECREF(v);
749 if (x == NULL && PyErr_Occurred())
750 return -1;
751 memcpy(p, (char *)&x, sizeof x);
752 return 0;
753}
754
755static formatdef native_table[] = {
756 {'x', sizeof(char), 0, NULL},
757 {'b', sizeof(char), 0, nu_byte, np_byte},
758 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
759 {'c', sizeof(char), 0, nu_char, np_char},
760 {'s', sizeof(char), 0, NULL},
761 {'p', sizeof(char), 0, NULL},
762 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
763 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
764 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
765 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
766 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
767 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
768#ifdef HAVE_LONG_LONG
769 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
770 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
771#endif
772 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
773 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
774 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
775 {0}
776};
777
778/* Big-endian routines. *****************************************************/
779
780static PyObject *
781bu_int(const char *p, const formatdef *f)
782{
783 long x = 0;
784 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000785 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000786 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000787 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000788 } while (--i > 0);
789 /* Extend the sign bit. */
790 if (SIZEOF_LONG > f->size)
791 x |= -(x & (1L << ((8 * f->size) - 1)));
792 return PyInt_FromLong(x);
793}
794
795static PyObject *
796bu_uint(const char *p, const formatdef *f)
797{
798 unsigned long x = 0;
799 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000800 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000801 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000802 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000803 } while (--i > 0);
804 if (x <= LONG_MAX)
805 return PyInt_FromLong((long)x);
806 return PyLong_FromUnsignedLong(x);
807}
808
809static PyObject *
810bu_longlong(const char *p, const formatdef *f)
811{
812#ifdef HAVE_LONG_LONG
813 PY_LONG_LONG x = 0;
814 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000815 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000816 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000817 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000818 } while (--i > 0);
819 /* Extend the sign bit. */
820 if (SIZEOF_LONG_LONG > f->size)
821 x |= -(x & (1L << ((8 * f->size) - 1)));
822 if (x >= LONG_MIN && x <= LONG_MAX)
823 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
824 return PyLong_FromLongLong(x);
825#else
826 return _PyLong_FromByteArray((const unsigned char *)p,
827 8,
828 0, /* little-endian */
829 1 /* signed */);
830#endif
831}
832
833static PyObject *
834bu_ulonglong(const char *p, const formatdef *f)
835{
836#ifdef HAVE_LONG_LONG
837 unsigned PY_LONG_LONG x = 0;
838 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000839 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000840 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000841 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000842 } while (--i > 0);
843 if (x <= LONG_MAX)
844 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
845 return PyLong_FromUnsignedLongLong(x);
846#else
847 return _PyLong_FromByteArray((const unsigned char *)p,
848 8,
849 0, /* little-endian */
850 0 /* signed */);
851#endif
852}
853
854static PyObject *
855bu_float(const char *p, const formatdef *f)
856{
857 return unpack_float(p, 0);
858}
859
860static PyObject *
861bu_double(const char *p, const formatdef *f)
862{
863 return unpack_double(p, 0);
864}
865
866static int
867bp_int(char *p, PyObject *v, const formatdef *f)
868{
869 long x;
870 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000871 if (get_wrapped_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000872 return -1;
873 i = f->size;
874 if (i != SIZEOF_LONG) {
875 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000876 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000877#if (SIZEOF_LONG != 4)
878 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000879 RANGE_ERROR(x, f, 0, 0xffffffffL);
880#endif
881#ifdef PY_STRUCT_OVERFLOW_MASKING
882 else if ((i == 1) && (x < -128 || x > 127))
883 RANGE_ERROR(x, f, 0, 0xffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000884#endif
885 }
886 do {
887 p[--i] = (char)x;
888 x >>= 8;
889 } while (i > 0);
890 return 0;
891}
892
893static int
894bp_uint(char *p, PyObject *v, const formatdef *f)
895{
896 unsigned long x;
897 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000898 if (get_wrapped_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000899 return -1;
900 i = f->size;
901 if (i != SIZEOF_LONG) {
902 unsigned long maxint = 1;
903 maxint <<= (unsigned long)(i * 8);
904 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000905 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000906 }
907 do {
908 p[--i] = (char)x;
909 x >>= 8;
910 } while (i > 0);
911 return 0;
912}
913
914static int
915bp_longlong(char *p, PyObject *v, const formatdef *f)
916{
917 int res;
918 v = get_pylong(v);
919 if (v == NULL)
920 return -1;
921 res = _PyLong_AsByteArray((PyLongObject *)v,
922 (unsigned char *)p,
923 8,
924 0, /* little_endian */
925 1 /* signed */);
926 Py_DECREF(v);
927 return res;
928}
929
930static int
931bp_ulonglong(char *p, PyObject *v, const formatdef *f)
932{
933 int res;
934 v = get_pylong(v);
935 if (v == NULL)
936 return -1;
937 res = _PyLong_AsByteArray((PyLongObject *)v,
938 (unsigned char *)p,
939 8,
940 0, /* little_endian */
941 0 /* signed */);
942 Py_DECREF(v);
943 return res;
944}
945
946static int
947bp_float(char *p, PyObject *v, const formatdef *f)
948{
949 double x = PyFloat_AsDouble(v);
950 if (x == -1 && PyErr_Occurred()) {
951 PyErr_SetString(StructError,
952 "required argument is not a float");
953 return -1;
954 }
955 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
956}
957
958static int
959bp_double(char *p, PyObject *v, const formatdef *f)
960{
961 double x = PyFloat_AsDouble(v);
962 if (x == -1 && PyErr_Occurred()) {
963 PyErr_SetString(StructError,
964 "required argument is not a float");
965 return -1;
966 }
967 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
968}
969
970static formatdef bigendian_table[] = {
971 {'x', 1, 0, NULL},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000972#ifdef PY_STRUCT_OVERFLOW_MASKING
973 /* Native packers do range checking without overflow masking. */
974 {'b', 1, 0, nu_byte, bp_int},
975 {'B', 1, 0, nu_ubyte, bp_uint},
976#else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000977 {'b', 1, 0, nu_byte, np_byte},
978 {'B', 1, 0, nu_ubyte, np_ubyte},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000979#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000980 {'c', 1, 0, nu_char, np_char},
981 {'s', 1, 0, NULL},
982 {'p', 1, 0, NULL},
983 {'h', 2, 0, bu_int, bp_int},
984 {'H', 2, 0, bu_uint, bp_uint},
985 {'i', 4, 0, bu_int, bp_int},
986 {'I', 4, 0, bu_uint, bp_uint},
987 {'l', 4, 0, bu_int, bp_int},
988 {'L', 4, 0, bu_uint, bp_uint},
989 {'q', 8, 0, bu_longlong, bp_longlong},
990 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
991 {'f', 4, 0, bu_float, bp_float},
992 {'d', 8, 0, bu_double, bp_double},
993 {0}
994};
995
996/* Little-endian routines. *****************************************************/
997
998static PyObject *
999lu_int(const char *p, const formatdef *f)
1000{
1001 long x = 0;
1002 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001003 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001004 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001005 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001006 } while (i > 0);
1007 /* Extend the sign bit. */
1008 if (SIZEOF_LONG > f->size)
1009 x |= -(x & (1L << ((8 * f->size) - 1)));
1010 return PyInt_FromLong(x);
1011}
1012
1013static PyObject *
1014lu_uint(const char *p, const formatdef *f)
1015{
1016 unsigned long x = 0;
1017 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001018 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001019 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001020 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001021 } while (i > 0);
1022 if (x <= LONG_MAX)
1023 return PyInt_FromLong((long)x);
1024 return PyLong_FromUnsignedLong((long)x);
1025}
1026
1027static PyObject *
1028lu_longlong(const char *p, const formatdef *f)
1029{
1030#ifdef HAVE_LONG_LONG
1031 PY_LONG_LONG x = 0;
1032 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001033 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001034 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001035 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001036 } while (i > 0);
1037 /* Extend the sign bit. */
1038 if (SIZEOF_LONG_LONG > f->size)
1039 x |= -(x & (1L << ((8 * f->size) - 1)));
1040 if (x >= LONG_MIN && x <= LONG_MAX)
1041 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
1042 return PyLong_FromLongLong(x);
1043#else
1044 return _PyLong_FromByteArray((const unsigned char *)p,
1045 8,
1046 1, /* little-endian */
1047 1 /* signed */);
1048#endif
1049}
1050
1051static PyObject *
1052lu_ulonglong(const char *p, const formatdef *f)
1053{
1054#ifdef HAVE_LONG_LONG
1055 unsigned PY_LONG_LONG x = 0;
1056 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001057 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001058 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001059 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001060 } while (i > 0);
1061 if (x <= LONG_MAX)
1062 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
1063 return PyLong_FromUnsignedLongLong(x);
1064#else
1065 return _PyLong_FromByteArray((const unsigned char *)p,
1066 8,
1067 1, /* little-endian */
1068 0 /* signed */);
1069#endif
1070}
1071
1072static PyObject *
1073lu_float(const char *p, const formatdef *f)
1074{
1075 return unpack_float(p, 1);
1076}
1077
1078static PyObject *
1079lu_double(const char *p, const formatdef *f)
1080{
1081 return unpack_double(p, 1);
1082}
1083
1084static int
1085lp_int(char *p, PyObject *v, const formatdef *f)
1086{
1087 long x;
1088 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001089 if (get_wrapped_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001090 return -1;
1091 i = f->size;
1092 if (i != SIZEOF_LONG) {
1093 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001094 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001095#if (SIZEOF_LONG != 4)
1096 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001097 RANGE_ERROR(x, f, 0, 0xffffffffL);
1098#endif
1099#ifdef PY_STRUCT_OVERFLOW_MASKING
1100 else if ((i == 1) && (x < -128 || x > 127))
1101 RANGE_ERROR(x, f, 0, 0xffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001102#endif
1103 }
1104 do {
1105 *p++ = (char)x;
1106 x >>= 8;
1107 } while (--i > 0);
1108 return 0;
1109}
1110
1111static int
1112lp_uint(char *p, PyObject *v, const formatdef *f)
1113{
1114 unsigned long x;
1115 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001116 if (get_wrapped_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001117 return -1;
1118 i = f->size;
1119 if (i != SIZEOF_LONG) {
1120 unsigned long maxint = 1;
1121 maxint <<= (unsigned long)(i * 8);
1122 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001123 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001124 }
1125 do {
1126 *p++ = (char)x;
1127 x >>= 8;
1128 } while (--i > 0);
1129 return 0;
1130}
1131
1132static int
1133lp_longlong(char *p, PyObject *v, const formatdef *f)
1134{
1135 int res;
1136 v = get_pylong(v);
1137 if (v == NULL)
1138 return -1;
1139 res = _PyLong_AsByteArray((PyLongObject*)v,
1140 (unsigned char *)p,
1141 8,
1142 1, /* little_endian */
1143 1 /* signed */);
1144 Py_DECREF(v);
1145 return res;
1146}
1147
1148static int
1149lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1150{
1151 int res;
1152 v = get_pylong(v);
1153 if (v == NULL)
1154 return -1;
1155 res = _PyLong_AsByteArray((PyLongObject*)v,
1156 (unsigned char *)p,
1157 8,
1158 1, /* little_endian */
1159 0 /* signed */);
1160 Py_DECREF(v);
1161 return res;
1162}
1163
1164static int
1165lp_float(char *p, PyObject *v, const formatdef *f)
1166{
1167 double x = PyFloat_AsDouble(v);
1168 if (x == -1 && PyErr_Occurred()) {
1169 PyErr_SetString(StructError,
1170 "required argument is not a float");
1171 return -1;
1172 }
1173 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1174}
1175
1176static int
1177lp_double(char *p, PyObject *v, const formatdef *f)
1178{
1179 double x = PyFloat_AsDouble(v);
1180 if (x == -1 && PyErr_Occurred()) {
1181 PyErr_SetString(StructError,
1182 "required argument is not a float");
1183 return -1;
1184 }
1185 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1186}
1187
1188static formatdef lilendian_table[] = {
1189 {'x', 1, 0, NULL},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001190#ifdef PY_STRUCT_OVERFLOW_MASKING
1191 /* Native packers do range checking without overflow masking. */
1192 {'b', 1, 0, nu_byte, lp_int},
1193 {'B', 1, 0, nu_ubyte, lp_uint},
1194#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001195 {'b', 1, 0, nu_byte, np_byte},
1196 {'B', 1, 0, nu_ubyte, np_ubyte},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001197#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001198 {'c', 1, 0, nu_char, np_char},
1199 {'s', 1, 0, NULL},
1200 {'p', 1, 0, NULL},
1201 {'h', 2, 0, lu_int, lp_int},
1202 {'H', 2, 0, lu_uint, lp_uint},
1203 {'i', 4, 0, lu_int, lp_int},
1204 {'I', 4, 0, lu_uint, lp_uint},
1205 {'l', 4, 0, lu_int, lp_int},
1206 {'L', 4, 0, lu_uint, lp_uint},
1207 {'q', 8, 0, lu_longlong, lp_longlong},
1208 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1209 {'f', 4, 0, lu_float, lp_float},
1210 {'d', 8, 0, lu_double, lp_double},
1211 {0}
1212};
1213
1214
1215static const formatdef *
1216whichtable(char **pfmt)
1217{
1218 const char *fmt = (*pfmt)++; /* May be backed out of later */
1219 switch (*fmt) {
1220 case '<':
1221 return lilendian_table;
1222 case '>':
1223 case '!': /* Network byte order is big-endian */
1224 return bigendian_table;
1225 case '=': { /* Host byte order -- different from native in aligment! */
1226 int n = 1;
1227 char *p = (char *) &n;
1228 if (*p == 1)
1229 return lilendian_table;
1230 else
1231 return bigendian_table;
1232 }
1233 default:
1234 --*pfmt; /* Back out of pointer increment */
1235 /* Fall through */
1236 case '@':
1237 return native_table;
1238 }
1239}
1240
1241
1242/* Get the table entry for a format code */
1243
1244static const formatdef *
1245getentry(int c, const formatdef *f)
1246{
1247 for (; f->format != '\0'; f++) {
1248 if (f->format == c) {
1249 return f;
1250 }
1251 }
1252 PyErr_SetString(StructError, "bad char in struct format");
1253 return NULL;
1254}
1255
1256
1257/* Align a size according to a format code */
1258
1259static int
1260align(Py_ssize_t size, char c, const formatdef *e)
1261{
1262 if (e->format == c) {
1263 if (e->alignment) {
1264 size = ((size + e->alignment - 1)
1265 / e->alignment)
1266 * e->alignment;
1267 }
1268 }
1269 return size;
1270}
1271
1272
1273/* calculate the size of a format string */
1274
1275static int
1276prepare_s(PyStructObject *self)
1277{
1278 const formatdef *f;
1279 const formatdef *e;
1280 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001281
Thomas Wouters477c8d52006-05-27 19:21:47 +00001282 const char *s;
1283 const char *fmt;
1284 char c;
1285 Py_ssize_t size, len, num, itemsize, x;
1286
1287 fmt = PyString_AS_STRING(self->s_format);
1288
1289 f = whichtable((char **)&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001290
Thomas Wouters477c8d52006-05-27 19:21:47 +00001291 s = fmt;
1292 size = 0;
1293 len = 0;
1294 while ((c = *s++) != '\0') {
1295 if (isspace(Py_CHARMASK(c)))
1296 continue;
1297 if ('0' <= c && c <= '9') {
1298 num = c - '0';
1299 while ('0' <= (c = *s++) && c <= '9') {
1300 x = num*10 + (c - '0');
1301 if (x/10 != num) {
1302 PyErr_SetString(
1303 StructError,
1304 "overflow in item count");
1305 return -1;
1306 }
1307 num = x;
1308 }
1309 if (c == '\0')
1310 break;
1311 }
1312 else
1313 num = 1;
1314
1315 e = getentry(c, f);
1316 if (e == NULL)
1317 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001318
Thomas Wouters477c8d52006-05-27 19:21:47 +00001319 switch (c) {
1320 case 's': /* fall through */
1321 case 'p': len++; break;
1322 case 'x': break;
1323 default: len += num; break;
1324 }
1325
1326 itemsize = e->size;
1327 size = align(size, c, e);
1328 x = num * itemsize;
1329 size += x;
1330 if (x/itemsize != num || size < 0) {
1331 PyErr_SetString(StructError,
1332 "total struct size too long");
1333 return -1;
1334 }
1335 }
1336
1337 self->s_size = size;
1338 self->s_len = len;
1339 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1340 if (codes == NULL) {
1341 PyErr_NoMemory();
1342 return -1;
1343 }
1344 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001345
Thomas Wouters477c8d52006-05-27 19:21:47 +00001346 s = fmt;
1347 size = 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 num = num*10 + (c - '0');
1355 if (c == '\0')
1356 break;
1357 }
1358 else
1359 num = 1;
1360
1361 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001362
Thomas Wouters477c8d52006-05-27 19:21:47 +00001363 size = align(size, c, e);
1364 if (c == 's' || c == 'p') {
1365 codes->offset = size;
1366 codes->size = num;
1367 codes->fmtdef = e;
1368 codes++;
1369 size += num;
1370 } else if (c == 'x') {
1371 size += num;
1372 } else {
1373 while (--num >= 0) {
1374 codes->offset = size;
1375 codes->size = e->size;
1376 codes->fmtdef = e;
1377 codes++;
1378 size += e->size;
1379 }
1380 }
1381 }
1382 codes->fmtdef = NULL;
1383 codes->offset = size;
1384 codes->size = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001385
Thomas Wouters477c8d52006-05-27 19:21:47 +00001386 return 0;
1387}
1388
1389static PyObject *
1390s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1391{
1392 PyObject *self;
1393
1394 assert(type != NULL && type->tp_alloc != NULL);
1395
1396 self = type->tp_alloc(type, 0);
1397 if (self != NULL) {
1398 PyStructObject *s = (PyStructObject*)self;
1399 Py_INCREF(Py_None);
1400 s->s_format = Py_None;
1401 s->s_codes = NULL;
1402 s->s_size = -1;
1403 s->s_len = -1;
1404 }
1405 return self;
1406}
1407
1408static int
1409s_init(PyObject *self, PyObject *args, PyObject *kwds)
1410{
1411 PyStructObject *soself = (PyStructObject *)self;
1412 PyObject *o_format = NULL;
1413 int ret = 0;
1414 static char *kwlist[] = {"format", 0};
1415
1416 assert(PyStruct_Check(self));
1417
1418 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1419 &o_format))
1420 return -1;
1421
1422 Py_INCREF(o_format);
1423 Py_XDECREF(soself->s_format);
1424 soself->s_format = o_format;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001425
Thomas Wouters477c8d52006-05-27 19:21:47 +00001426 ret = prepare_s(soself);
1427 return ret;
1428}
1429
1430static void
1431s_dealloc(PyStructObject *s)
1432{
1433 if (s->weakreflist != NULL)
1434 PyObject_ClearWeakRefs((PyObject *)s);
1435 if (s->s_codes != NULL) {
1436 PyMem_FREE(s->s_codes);
1437 }
1438 Py_XDECREF(s->s_format);
1439 s->ob_type->tp_free((PyObject *)s);
1440}
1441
1442static PyObject *
1443s_unpack_internal(PyStructObject *soself, char *startfrom) {
1444 formatcode *code;
1445 Py_ssize_t i = 0;
1446 PyObject *result = PyTuple_New(soself->s_len);
1447 if (result == NULL)
1448 return NULL;
1449
1450 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1451 PyObject *v;
1452 const formatdef *e = code->fmtdef;
1453 const char *res = startfrom + code->offset;
1454 if (e->format == 's') {
1455 v = PyString_FromStringAndSize(res, code->size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001456 } else if (e->format == 'p') {
1457 Py_ssize_t n = *(unsigned char*)res;
1458 if (n >= code->size)
1459 n = code->size - 1;
1460 v = PyString_FromStringAndSize(res + 1, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001461 } else {
1462 v = e->unpack(res, e);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001463 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001464 if (v == NULL)
1465 goto fail;
1466 PyTuple_SET_ITEM(result, i++, v);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001467 }
1468
1469 return result;
1470fail:
1471 Py_DECREF(result);
1472 return NULL;
1473}
1474
1475
1476PyDoc_STRVAR(s_unpack__doc__,
1477"S.unpack(str) -> (v1, v2, ...)\n\
1478\n\
1479Return tuple containing values unpacked according to this Struct's format.\n\
1480Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1481strings.");
1482
1483static PyObject *
1484s_unpack(PyObject *self, PyObject *inputstr)
1485{
1486 PyStructObject *soself = (PyStructObject *)self;
1487 assert(PyStruct_Check(self));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001488 assert(soself->s_codes != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001489 if (inputstr == NULL || !PyString_Check(inputstr) ||
1490 PyString_GET_SIZE(inputstr) != soself->s_size) {
1491 PyErr_Format(StructError,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001492 "unpack requires a string argument of length %zd",
1493 soself->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001494 return NULL;
1495 }
1496 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1497}
1498
1499PyDoc_STRVAR(s_unpack_from__doc__,
1500"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1501\n\
1502Return tuple containing values unpacked according to this Struct's format.\n\
1503Unlike unpack, unpack_from can unpack values from any object supporting\n\
1504the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1505See struct.__doc__ for more on format strings.");
1506
1507static PyObject *
1508s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1509{
1510 static char *kwlist[] = {"buffer", "offset", 0};
1511#if (PY_VERSION_HEX < 0x02050000)
1512 static char *fmt = "z#|i:unpack_from";
1513#else
1514 static char *fmt = "z#|n:unpack_from";
1515#endif
1516 Py_ssize_t buffer_len = 0, offset = 0;
1517 char *buffer = NULL;
1518 PyStructObject *soself = (PyStructObject *)self;
1519 assert(PyStruct_Check(self));
1520 assert(soself->s_codes != NULL);
1521
1522 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1523 &buffer, &buffer_len, &offset))
1524 return NULL;
1525
1526 if (buffer == NULL) {
1527 PyErr_Format(StructError,
1528 "unpack_from requires a buffer argument");
1529 return NULL;
1530 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001531
Thomas Wouters477c8d52006-05-27 19:21:47 +00001532 if (offset < 0)
1533 offset += buffer_len;
1534
1535 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1536 PyErr_Format(StructError,
1537 "unpack_from requires a buffer of at least %zd bytes",
1538 soself->s_size);
1539 return NULL;
1540 }
1541 return s_unpack_internal(soself, buffer + offset);
1542}
1543
1544
1545/*
1546 * Guts of the pack function.
1547 *
1548 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1549 * argument for where to start processing the arguments for packing, and a
1550 * character buffer for writing the packed string. The caller must insure
1551 * that the buffer may contain the required length for packing the arguments.
1552 * 0 is returned on success, 1 is returned if there is an error.
1553 *
1554 */
1555static int
1556s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1557{
1558 formatcode *code;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001559 /* XXX(nnorwitz): why does i need to be a local? can we use
1560 the offset parameter or do we need the wider width? */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001561 Py_ssize_t i;
1562
1563 memset(buf, '\0', soself->s_size);
1564 i = offset;
1565 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1566 Py_ssize_t n;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001567 PyObject *v = PyTuple_GET_ITEM(args, i++);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001568 const formatdef *e = code->fmtdef;
1569 char *res = buf + code->offset;
1570 if (e->format == 's') {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001571 if (!PyString_Check(v)) {
1572 PyErr_SetString(StructError,
1573 "argument for 's' must be a string");
1574 return -1;
1575 }
1576 n = PyString_GET_SIZE(v);
1577 if (n > code->size)
1578 n = code->size;
1579 if (n > 0)
1580 memcpy(res, PyString_AS_STRING(v), n);
1581 } else if (e->format == 'p') {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001582 if (!PyString_Check(v)) {
1583 PyErr_SetString(StructError,
1584 "argument for 'p' must be a string");
1585 return -1;
1586 }
1587 n = PyString_GET_SIZE(v);
1588 if (n > (code->size - 1))
1589 n = code->size - 1;
1590 if (n > 0)
1591 memcpy(res + 1, PyString_AS_STRING(v), n);
1592 if (n > 255)
1593 n = 255;
1594 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1595 } else {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001596 if (e->pack(res, v, e) < 0) {
1597 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1598 PyErr_SetString(StructError,
1599 "long too large to convert to int");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001600 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001601 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001602 }
1603 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001604
Thomas Wouters477c8d52006-05-27 19:21:47 +00001605 /* Success */
1606 return 0;
1607}
1608
1609
1610PyDoc_STRVAR(s_pack__doc__,
1611"S.pack(v1, v2, ...) -> string\n\
1612\n\
1613Return a string containing values v1, v2, ... packed according to this\n\
1614Struct's format. See struct.__doc__ for more on format strings.");
1615
1616static PyObject *
1617s_pack(PyObject *self, PyObject *args)
1618{
1619 PyStructObject *soself;
1620 PyObject *result;
1621
1622 /* Validate arguments. */
1623 soself = (PyStructObject *)self;
1624 assert(PyStruct_Check(self));
1625 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001626 if (PyTuple_GET_SIZE(args) != soself->s_len)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001627 {
1628 PyErr_Format(StructError,
1629 "pack requires exactly %zd arguments", soself->s_len);
1630 return NULL;
1631 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001632
Thomas Wouters477c8d52006-05-27 19:21:47 +00001633 /* Allocate a new string */
1634 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1635 if (result == NULL)
1636 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001637
Thomas Wouters477c8d52006-05-27 19:21:47 +00001638 /* Call the guts */
1639 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1640 Py_DECREF(result);
1641 return NULL;
1642 }
1643
1644 return result;
1645}
1646
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001647PyDoc_STRVAR(s_pack_into__doc__,
1648"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001649\n\
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001650Pack the values v1, v2, ... according to this Struct's format, write \n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001651the packed bytes into the writable buffer buf starting at offset. Note\n\
1652that the offset is not an optional argument. See struct.__doc__ for \n\
1653more on format strings.");
1654
1655static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001656s_pack_into(PyObject *self, PyObject *args)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001657{
1658 PyStructObject *soself;
1659 char *buffer;
1660 Py_ssize_t buffer_len, offset;
1661
1662 /* Validate arguments. +1 is for the first arg as buffer. */
1663 soself = (PyStructObject *)self;
1664 assert(PyStruct_Check(self));
1665 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001666 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001667 {
1668 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001669 "pack_into requires exactly %zd arguments",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001670 (soself->s_len + 2));
1671 return NULL;
1672 }
1673
1674 /* Extract a writable memory buffer from the first argument */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001675 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1676 (void**)&buffer, &buffer_len) == -1 ) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001677 return NULL;
1678 }
1679 assert( buffer_len >= 0 );
1680
1681 /* Extract the offset from the first argument */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001682 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001683
1684 /* Support negative offsets. */
1685 if (offset < 0)
1686 offset += buffer_len;
1687
1688 /* Check boundaries */
1689 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1690 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001691 "pack_into requires a buffer of at least %zd bytes",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001692 soself->s_size);
1693 return NULL;
1694 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001695
Thomas Wouters477c8d52006-05-27 19:21:47 +00001696 /* Call the guts */
1697 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1698 return NULL;
1699 }
1700
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001701 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001702}
1703
1704static PyObject *
1705s_get_format(PyStructObject *self, void *unused)
1706{
1707 Py_INCREF(self->s_format);
1708 return self->s_format;
1709}
1710
1711static PyObject *
1712s_get_size(PyStructObject *self, void *unused)
1713{
1714 return PyInt_FromSsize_t(self->s_size);
1715}
1716
1717/* List of functions */
1718
1719static struct PyMethodDef s_methods[] = {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001720 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1721 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1722 {"unpack", s_unpack, METH_O, s_unpack__doc__},
1723 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS,
1724 s_unpack_from__doc__},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001725 {NULL, NULL} /* sentinel */
1726};
1727
1728PyDoc_STRVAR(s__doc__, "Compiled struct object");
1729
1730#define OFF(x) offsetof(PyStructObject, x)
1731
1732static PyGetSetDef s_getsetlist[] = {
1733 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1734 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1735 {NULL} /* sentinel */
1736};
1737
1738static
1739PyTypeObject PyStructType = {
1740 PyObject_HEAD_INIT(NULL)
1741 0,
1742 "Struct",
1743 sizeof(PyStructObject),
1744 0,
1745 (destructor)s_dealloc, /* tp_dealloc */
1746 0, /* tp_print */
1747 0, /* tp_getattr */
1748 0, /* tp_setattr */
1749 0, /* tp_compare */
1750 0, /* tp_repr */
1751 0, /* tp_as_number */
1752 0, /* tp_as_sequence */
1753 0, /* tp_as_mapping */
1754 0, /* tp_hash */
1755 0, /* tp_call */
1756 0, /* tp_str */
1757 PyObject_GenericGetAttr, /* tp_getattro */
1758 PyObject_GenericSetAttr, /* tp_setattro */
1759 0, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +00001760 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001761 s__doc__, /* tp_doc */
1762 0, /* tp_traverse */
1763 0, /* tp_clear */
1764 0, /* tp_richcompare */
1765 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1766 0, /* tp_iter */
1767 0, /* tp_iternext */
1768 s_methods, /* tp_methods */
1769 NULL, /* tp_members */
1770 s_getsetlist, /* tp_getset */
1771 0, /* tp_base */
1772 0, /* tp_dict */
1773 0, /* tp_descr_get */
1774 0, /* tp_descr_set */
1775 0, /* tp_dictoffset */
1776 s_init, /* tp_init */
1777 PyType_GenericAlloc,/* tp_alloc */
1778 s_new, /* tp_new */
1779 PyObject_Del, /* tp_free */
1780};
1781
1782/* Module initialization */
1783
1784PyMODINIT_FUNC
1785init_struct(void)
1786{
1787 PyObject *m = Py_InitModule("_struct", NULL);
1788 if (m == NULL)
1789 return;
1790
1791 PyStructType.ob_type = &PyType_Type;
1792 if (PyType_Ready(&PyStructType) < 0)
1793 return;
1794
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001795#ifdef PY_STRUCT_OVERFLOW_MASKING
1796 if (pyint_zero == NULL) {
1797 pyint_zero = PyInt_FromLong(0);
1798 if (pyint_zero == NULL)
1799 return;
1800 }
1801 if (pylong_ulong_mask == NULL) {
1802#if (SIZEOF_LONG == 4)
1803 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1804#else
1805 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1806#endif
1807 if (pylong_ulong_mask == NULL)
1808 return;
1809 }
1810
1811#else
1812 /* This speed trick can't be used until overflow masking goes away, because
1813 native endian always raises exceptions instead of overflow masking. */
1814
Thomas Wouters477c8d52006-05-27 19:21:47 +00001815 /* Check endian and swap in faster functions */
1816 {
1817 int one = 1;
1818 formatdef *native = native_table;
1819 formatdef *other, *ptr;
1820 if ((int)*(unsigned char*)&one)
1821 other = lilendian_table;
1822 else
1823 other = bigendian_table;
1824 /* Scan through the native table, find a matching
1825 entry in the endian table and swap in the
1826 native implementations whenever possible
1827 (64-bit platforms may not have "standard" sizes) */
1828 while (native->format != '\0' && other->format != '\0') {
1829 ptr = other;
1830 while (ptr->format != '\0') {
1831 if (ptr->format == native->format) {
1832 /* Match faster when formats are
1833 listed in the same order */
1834 if (ptr == other)
1835 other++;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001836 /* Only use the trick if the
Thomas Wouters477c8d52006-05-27 19:21:47 +00001837 size matches */
1838 if (ptr->size != native->size)
1839 break;
1840 /* Skip float and double, could be
1841 "unknown" float format */
1842 if (ptr->format == 'd' || ptr->format == 'f')
1843 break;
1844 ptr->pack = native->pack;
1845 ptr->unpack = native->unpack;
1846 break;
1847 }
1848 ptr++;
1849 }
1850 native++;
1851 }
1852 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001853#endif
1854
Thomas Wouters477c8d52006-05-27 19:21:47 +00001855 /* Add some symbolic constants to the module */
1856 if (StructError == NULL) {
1857 StructError = PyErr_NewException("struct.error", NULL, NULL);
1858 if (StructError == NULL)
1859 return;
1860 }
1861
1862 Py_INCREF(StructError);
1863 PyModule_AddObject(m, "error", StructError);
1864
1865 Py_INCREF((PyObject*)&PyStructType);
1866 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001867
1868 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
1869#ifdef PY_STRUCT_OVERFLOW_MASKING
1870 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
1871#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001872#ifdef PY_STRUCT_FLOAT_COERCE
1873 PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
1874#endif
1875
Thomas Wouters477c8d52006-05-27 19:21:47 +00001876}