blob: 8d0a3bcc7428aa765fbef4ee4b87c5dbeb050164 [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);
121 if (PyInt_Check(v))
122 return PyLong_FromLong(PyInt_AS_LONG(v));
123 if (PyLong_Check(v)) {
124 Py_INCREF(v);
125 return v;
126 }
127 m = v->ob_type->tp_as_number;
128 if (m != NULL && m->nb_long != NULL) {
129 v = m->nb_long(v);
130 if (v == NULL)
131 return NULL;
132 if (PyLong_Check(v))
133 return v;
134 Py_DECREF(v);
135 }
136 PyErr_SetString(StructError,
137 "cannot convert argument to long");
138 return NULL;
139}
140
141/* Helper routine to get a Python integer and raise the appropriate error
142 if it isn't one */
143
144static int
145get_long(PyObject *v, long *p)
146{
147 long x = PyInt_AsLong(v);
148 if (x == -1 && PyErr_Occurred()) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000149#ifdef PY_STRUCT_FLOAT_COERCE
150 if (PyFloat_Check(v)) {
151 PyObject *o;
152 int res;
153 PyErr_Clear();
154 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
155 return -1;
156 o = PyNumber_Int(v);
157 if (o == NULL)
158 return -1;
159 res = get_long(o, p);
160 Py_DECREF(o);
161 return res;
162 }
163#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000164 if (PyErr_ExceptionMatches(PyExc_TypeError))
165 PyErr_SetString(StructError,
166 "required argument is not an integer");
167 return -1;
168 }
169 *p = x;
170 return 0;
171}
172
173
174/* Same, but handling unsigned long */
175
176static int
177get_ulong(PyObject *v, unsigned long *p)
178{
179 if (PyLong_Check(v)) {
180 unsigned long x = PyLong_AsUnsignedLong(v);
181 if (x == (unsigned long)(-1) && PyErr_Occurred())
182 return -1;
183 *p = x;
184 return 0;
185 }
186 if (get_long(v, (long *)p) < 0)
187 return -1;
188 if (((long)*p) < 0) {
189 PyErr_SetString(StructError,
190 "unsigned argument is < 0");
191 return -1;
192 }
193 return 0;
194}
195
196#ifdef HAVE_LONG_LONG
197
198/* Same, but handling native long long. */
199
200static int
201get_longlong(PyObject *v, PY_LONG_LONG *p)
202{
203 PY_LONG_LONG x;
204
205 v = get_pylong(v);
206 if (v == NULL)
207 return -1;
208 assert(PyLong_Check(v));
209 x = PyLong_AsLongLong(v);
210 Py_DECREF(v);
211 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
212 return -1;
213 *p = x;
214 return 0;
215}
216
217/* Same, but handling native unsigned long long. */
218
219static int
220get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
221{
222 unsigned PY_LONG_LONG x;
223
224 v = get_pylong(v);
225 if (v == NULL)
226 return -1;
227 assert(PyLong_Check(v));
228 x = PyLong_AsUnsignedLongLong(v);
229 Py_DECREF(v);
230 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
231 return -1;
232 *p = x;
233 return 0;
234}
235
236#endif
237
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000238#ifdef PY_STRUCT_OVERFLOW_MASKING
239
240/* Helper routine to get a Python integer and raise the appropriate error
241 if it isn't one */
242
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000243#define INT_OVERFLOW "struct integer overflow masking is deprecated"
244
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000245static int
246get_wrapped_long(PyObject *v, long *p)
247{
248 if (get_long(v, p) < 0) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000249 if (PyLong_Check(v) &&
250 PyErr_ExceptionMatches(PyExc_OverflowError)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000251 PyObject *wrapped;
252 long x;
253 PyErr_Clear();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000254#ifdef PY_STRUCT_FLOAT_COERCE
255 if (PyFloat_Check(v)) {
256 PyObject *o;
257 int res;
258 PyErr_Clear();
259 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
260 return -1;
261 o = PyNumber_Int(v);
262 if (o == NULL)
263 return -1;
264 res = get_wrapped_long(o, p);
265 Py_DECREF(o);
266 return res;
267 }
268#endif
269 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000270 return -1;
271 wrapped = PyNumber_And(v, pylong_ulong_mask);
272 if (wrapped == NULL)
273 return -1;
274 x = (long)PyLong_AsUnsignedLong(wrapped);
275 Py_DECREF(wrapped);
276 if (x == -1 && PyErr_Occurred())
277 return -1;
278 *p = x;
279 } else {
280 return -1;
281 }
282 }
283 return 0;
284}
285
286static int
287get_wrapped_ulong(PyObject *v, unsigned long *p)
288{
289 long x = (long)PyLong_AsUnsignedLong(v);
290 if (x == -1 && PyErr_Occurred()) {
291 PyObject *wrapped;
292 PyErr_Clear();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000293#ifdef PY_STRUCT_FLOAT_COERCE
294 if (PyFloat_Check(v)) {
295 PyObject *o;
296 int res;
297 PyErr_Clear();
298 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
299 return -1;
300 o = PyNumber_Int(v);
301 if (o == NULL)
302 return -1;
303 res = get_wrapped_ulong(o, p);
304 Py_DECREF(o);
305 return res;
306 }
307#endif
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000308 wrapped = PyNumber_And(v, pylong_ulong_mask);
309 if (wrapped == NULL)
310 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000311 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000312 Py_DECREF(wrapped);
313 return -1;
314 }
315 x = (long)PyLong_AsUnsignedLong(wrapped);
316 Py_DECREF(wrapped);
317 if (x == -1 && PyErr_Occurred())
318 return -1;
319 }
320 *p = (unsigned long)x;
321 return 0;
322}
323
324#define RANGE_ERROR(x, f, flag, mask) \
325 do { \
326 if (_range_error(f, flag) < 0) \
327 return -1; \
328 else \
329 (x) &= (mask); \
330 } while (0)
331
332#else
333
334#define get_wrapped_long get_long
335#define get_wrapped_ulong get_ulong
336#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
337
338#endif
339
Thomas Wouters477c8d52006-05-27 19:21:47 +0000340/* Floating point helpers */
341
342static PyObject *
343unpack_float(const char *p, /* start of 4-byte string */
344 int le) /* true for little-endian, false for big-endian */
345{
346 double x;
347
348 x = _PyFloat_Unpack4((unsigned char *)p, le);
349 if (x == -1.0 && PyErr_Occurred())
350 return NULL;
351 return PyFloat_FromDouble(x);
352}
353
354static PyObject *
355unpack_double(const char *p, /* start of 8-byte string */
356 int le) /* true for little-endian, false for big-endian */
357{
358 double x;
359
360 x = _PyFloat_Unpack8((unsigned char *)p, le);
361 if (x == -1.0 && PyErr_Occurred())
362 return NULL;
363 return PyFloat_FromDouble(x);
364}
365
366/* Helper to format the range error exceptions */
367static int
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000368_range_error(const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000369{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000370 /* ulargest is the largest unsigned value with f->size bytes.
371 * Note that the simpler:
372 * ((size_t)1 << (f->size * 8)) - 1
373 * doesn't work when f->size == sizeof(size_t) because C doesn't
374 * define what happens when a left shift count is >= the number of
375 * bits in the integer being shifted; e.g., on some boxes it doesn't
376 * shift at all when they're equal.
377 */
378 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
379 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
380 if (is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000381 PyErr_Format(StructError,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000382 "'%c' format requires 0 <= number <= %zu",
383 f->format,
384 ulargest);
385 else {
386 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000387 PyErr_Format(StructError,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000388 "'%c' format requires %zd <= number <= %zd",
389 f->format,
390 ~ largest,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000391 largest);
392 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000393#ifdef PY_STRUCT_OVERFLOW_MASKING
394 {
395 PyObject *ptype, *pvalue, *ptraceback;
396 PyObject *msg;
397 int rval;
398 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
399 assert(pvalue != NULL);
400 msg = PyObject_Str(pvalue);
401 Py_XDECREF(ptype);
402 Py_XDECREF(pvalue);
403 Py_XDECREF(ptraceback);
404 if (msg == NULL)
405 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000406 rval = PyErr_WarnEx(PyExc_DeprecationWarning,
407 PyString_AS_STRING(msg), 2);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000408 Py_DECREF(msg);
409 if (rval == 0)
410 return 0;
411 }
412#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000413 return -1;
414}
415
416
417
418/* A large number of small routines follow, with names of the form
419
420 [bln][up]_TYPE
421
422 [bln] distiguishes among big-endian, little-endian and native.
423 [pu] distiguishes between pack (to struct) and unpack (from struct).
424 TYPE is one of char, byte, ubyte, etc.
425*/
426
427/* Native mode routines. ****************************************************/
428/* NOTE:
429 In all n[up]_<type> routines handling types larger than 1 byte, there is
430 *no* guarantee that the p pointer is properly aligned for each type,
431 therefore memcpy is called. An intermediate variable is used to
432 compensate for big-endian architectures.
433 Normally both the intermediate variable and the memcpy call will be
434 skipped by C optimisation in little-endian architectures (gcc >= 2.91
435 does this). */
436
437static PyObject *
438nu_char(const char *p, const formatdef *f)
439{
440 return PyString_FromStringAndSize(p, 1);
441}
442
443static PyObject *
444nu_byte(const char *p, const formatdef *f)
445{
446 return PyInt_FromLong((long) *(signed char *)p);
447}
448
449static PyObject *
450nu_ubyte(const char *p, const formatdef *f)
451{
452 return PyInt_FromLong((long) *(unsigned char *)p);
453}
454
455static PyObject *
456nu_short(const char *p, const formatdef *f)
457{
458 short x;
459 memcpy((char *)&x, p, sizeof x);
460 return PyInt_FromLong((long)x);
461}
462
463static PyObject *
464nu_ushort(const char *p, const formatdef *f)
465{
466 unsigned short x;
467 memcpy((char *)&x, p, sizeof x);
468 return PyInt_FromLong((long)x);
469}
470
471static PyObject *
472nu_int(const char *p, const formatdef *f)
473{
474 int x;
475 memcpy((char *)&x, p, sizeof x);
476 return PyInt_FromLong((long)x);
477}
478
479static PyObject *
480nu_uint(const char *p, const formatdef *f)
481{
482 unsigned int x;
483 memcpy((char *)&x, p, sizeof x);
484#if (SIZEOF_LONG > SIZEOF_INT)
485 return PyInt_FromLong((long)x);
486#else
487 if (x <= ((unsigned int)LONG_MAX))
488 return PyInt_FromLong((long)x);
489 return PyLong_FromUnsignedLong((unsigned long)x);
490#endif
491}
492
493static PyObject *
494nu_long(const char *p, const formatdef *f)
495{
496 long x;
497 memcpy((char *)&x, p, sizeof x);
498 return PyInt_FromLong(x);
499}
500
501static PyObject *
502nu_ulong(const char *p, const formatdef *f)
503{
504 unsigned long x;
505 memcpy((char *)&x, p, sizeof x);
506 if (x <= LONG_MAX)
507 return PyInt_FromLong((long)x);
508 return PyLong_FromUnsignedLong(x);
509}
510
511/* Native mode doesn't support q or Q unless the platform C supports
512 long long (or, on Windows, __int64). */
513
514#ifdef HAVE_LONG_LONG
515
516static PyObject *
517nu_longlong(const char *p, const formatdef *f)
518{
519 PY_LONG_LONG x;
520 memcpy((char *)&x, p, sizeof x);
521 if (x >= LONG_MIN && x <= LONG_MAX)
522 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
523 return PyLong_FromLongLong(x);
524}
525
526static PyObject *
527nu_ulonglong(const char *p, const formatdef *f)
528{
529 unsigned PY_LONG_LONG x;
530 memcpy((char *)&x, p, sizeof x);
531 if (x <= LONG_MAX)
532 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
533 return PyLong_FromUnsignedLongLong(x);
534}
535
536#endif
537
538static PyObject *
539nu_float(const char *p, const formatdef *f)
540{
541 float x;
542 memcpy((char *)&x, p, sizeof x);
543 return PyFloat_FromDouble((double)x);
544}
545
546static PyObject *
547nu_double(const char *p, const formatdef *f)
548{
549 double x;
550 memcpy((char *)&x, p, sizeof x);
551 return PyFloat_FromDouble(x);
552}
553
554static PyObject *
555nu_void_p(const char *p, const formatdef *f)
556{
557 void *x;
558 memcpy((char *)&x, p, sizeof x);
559 return PyLong_FromVoidPtr(x);
560}
561
562static int
563np_byte(char *p, PyObject *v, const formatdef *f)
564{
565 long x;
566 if (get_long(v, &x) < 0)
567 return -1;
568 if (x < -128 || x > 127){
569 PyErr_SetString(StructError,
570 "byte format requires -128 <= number <= 127");
571 return -1;
572 }
573 *p = (char)x;
574 return 0;
575}
576
577static int
578np_ubyte(char *p, PyObject *v, const formatdef *f)
579{
580 long x;
581 if (get_long(v, &x) < 0)
582 return -1;
583 if (x < 0 || x > 255){
584 PyErr_SetString(StructError,
585 "ubyte format requires 0 <= number <= 255");
586 return -1;
587 }
588 *p = (char)x;
589 return 0;
590}
591
592static int
593np_char(char *p, PyObject *v, const formatdef *f)
594{
595 if (!PyString_Check(v) || PyString_Size(v) != 1) {
596 PyErr_SetString(StructError,
597 "char format require string of length 1");
598 return -1;
599 }
600 *p = *PyString_AsString(v);
601 return 0;
602}
603
604static int
605np_short(char *p, PyObject *v, const formatdef *f)
606{
607 long x;
608 short y;
609 if (get_long(v, &x) < 0)
610 return -1;
611 if (x < SHRT_MIN || x > SHRT_MAX){
612 PyErr_SetString(StructError,
613 "short format requires " STRINGIFY(SHRT_MIN)
614 " <= number <= " STRINGIFY(SHRT_MAX));
615 return -1;
616 }
617 y = (short)x;
618 memcpy(p, (char *)&y, sizeof y);
619 return 0;
620}
621
622static int
623np_ushort(char *p, PyObject *v, const formatdef *f)
624{
625 long x;
626 unsigned short y;
627 if (get_long(v, &x) < 0)
628 return -1;
629 if (x < 0 || x > USHRT_MAX){
630 PyErr_SetString(StructError,
631 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
632 return -1;
633 }
634 y = (unsigned short)x;
635 memcpy(p, (char *)&y, sizeof y);
636 return 0;
637}
638
639static int
640np_int(char *p, PyObject *v, const formatdef *f)
641{
642 long x;
643 int y;
644 if (get_long(v, &x) < 0)
645 return -1;
646#if (SIZEOF_LONG > SIZEOF_INT)
647 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000648 return _range_error(f, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000649#endif
650 y = (int)x;
651 memcpy(p, (char *)&y, sizeof y);
652 return 0;
653}
654
655static int
656np_uint(char *p, PyObject *v, const formatdef *f)
657{
658 unsigned long x;
659 unsigned int y;
660 if (get_ulong(v, &x) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000661 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000662 y = (unsigned int)x;
663#if (SIZEOF_LONG > SIZEOF_INT)
664 if (x > ((unsigned long)UINT_MAX))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000665 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000666#endif
667 memcpy(p, (char *)&y, sizeof y);
668 return 0;
669}
670
671static int
672np_long(char *p, PyObject *v, const formatdef *f)
673{
674 long x;
675 if (get_long(v, &x) < 0)
676 return -1;
677 memcpy(p, (char *)&x, sizeof x);
678 return 0;
679}
680
681static int
682np_ulong(char *p, PyObject *v, const formatdef *f)
683{
684 unsigned long x;
685 if (get_ulong(v, &x) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000686 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000687 memcpy(p, (char *)&x, sizeof x);
688 return 0;
689}
690
691#ifdef HAVE_LONG_LONG
692
693static int
694np_longlong(char *p, PyObject *v, const formatdef *f)
695{
696 PY_LONG_LONG x;
697 if (get_longlong(v, &x) < 0)
698 return -1;
699 memcpy(p, (char *)&x, sizeof x);
700 return 0;
701}
702
703static int
704np_ulonglong(char *p, PyObject *v, const formatdef *f)
705{
706 unsigned PY_LONG_LONG x;
707 if (get_ulonglong(v, &x) < 0)
708 return -1;
709 memcpy(p, (char *)&x, sizeof x);
710 return 0;
711}
712#endif
713
714static int
715np_float(char *p, PyObject *v, const formatdef *f)
716{
717 float x = (float)PyFloat_AsDouble(v);
718 if (x == -1 && PyErr_Occurred()) {
719 PyErr_SetString(StructError,
720 "required argument is not a float");
721 return -1;
722 }
723 memcpy(p, (char *)&x, sizeof x);
724 return 0;
725}
726
727static int
728np_double(char *p, PyObject *v, const formatdef *f)
729{
730 double x = PyFloat_AsDouble(v);
731 if (x == -1 && PyErr_Occurred()) {
732 PyErr_SetString(StructError,
733 "required argument is not a float");
734 return -1;
735 }
736 memcpy(p, (char *)&x, sizeof(double));
737 return 0;
738}
739
740static int
741np_void_p(char *p, PyObject *v, const formatdef *f)
742{
743 void *x;
744
745 v = get_pylong(v);
746 if (v == NULL)
747 return -1;
748 assert(PyLong_Check(v));
749 x = PyLong_AsVoidPtr(v);
750 Py_DECREF(v);
751 if (x == NULL && PyErr_Occurred())
752 return -1;
753 memcpy(p, (char *)&x, sizeof x);
754 return 0;
755}
756
757static formatdef native_table[] = {
758 {'x', sizeof(char), 0, NULL},
759 {'b', sizeof(char), 0, nu_byte, np_byte},
760 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
761 {'c', sizeof(char), 0, nu_char, np_char},
762 {'s', sizeof(char), 0, NULL},
763 {'p', sizeof(char), 0, NULL},
764 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
765 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
766 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
767 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
768 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
769 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
770#ifdef HAVE_LONG_LONG
771 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
772 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
773#endif
774 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
775 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
776 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
777 {0}
778};
779
780/* Big-endian routines. *****************************************************/
781
782static PyObject *
783bu_int(const char *p, const formatdef *f)
784{
785 long x = 0;
786 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000787 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000788 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000789 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000790 } while (--i > 0);
791 /* Extend the sign bit. */
792 if (SIZEOF_LONG > f->size)
793 x |= -(x & (1L << ((8 * f->size) - 1)));
794 return PyInt_FromLong(x);
795}
796
797static PyObject *
798bu_uint(const char *p, const formatdef *f)
799{
800 unsigned long x = 0;
801 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000802 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000803 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000804 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000805 } while (--i > 0);
806 if (x <= LONG_MAX)
807 return PyInt_FromLong((long)x);
808 return PyLong_FromUnsignedLong(x);
809}
810
811static PyObject *
812bu_longlong(const char *p, const formatdef *f)
813{
814#ifdef HAVE_LONG_LONG
815 PY_LONG_LONG x = 0;
816 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000817 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000818 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000819 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000820 } while (--i > 0);
821 /* Extend the sign bit. */
822 if (SIZEOF_LONG_LONG > f->size)
823 x |= -(x & (1L << ((8 * f->size) - 1)));
824 if (x >= LONG_MIN && x <= LONG_MAX)
825 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
826 return PyLong_FromLongLong(x);
827#else
828 return _PyLong_FromByteArray((const unsigned char *)p,
829 8,
830 0, /* little-endian */
831 1 /* signed */);
832#endif
833}
834
835static PyObject *
836bu_ulonglong(const char *p, const formatdef *f)
837{
838#ifdef HAVE_LONG_LONG
839 unsigned PY_LONG_LONG x = 0;
840 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000841 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000842 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000843 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000844 } while (--i > 0);
845 if (x <= LONG_MAX)
846 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
847 return PyLong_FromUnsignedLongLong(x);
848#else
849 return _PyLong_FromByteArray((const unsigned char *)p,
850 8,
851 0, /* little-endian */
852 0 /* signed */);
853#endif
854}
855
856static PyObject *
857bu_float(const char *p, const formatdef *f)
858{
859 return unpack_float(p, 0);
860}
861
862static PyObject *
863bu_double(const char *p, const formatdef *f)
864{
865 return unpack_double(p, 0);
866}
867
868static int
869bp_int(char *p, PyObject *v, const formatdef *f)
870{
871 long x;
872 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000873 if (get_wrapped_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000874 return -1;
875 i = f->size;
876 if (i != SIZEOF_LONG) {
877 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000878 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000879#if (SIZEOF_LONG != 4)
880 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000881 RANGE_ERROR(x, f, 0, 0xffffffffL);
882#endif
883#ifdef PY_STRUCT_OVERFLOW_MASKING
884 else if ((i == 1) && (x < -128 || x > 127))
885 RANGE_ERROR(x, f, 0, 0xffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000886#endif
887 }
888 do {
889 p[--i] = (char)x;
890 x >>= 8;
891 } while (i > 0);
892 return 0;
893}
894
895static int
896bp_uint(char *p, PyObject *v, const formatdef *f)
897{
898 unsigned long x;
899 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000900 if (get_wrapped_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000901 return -1;
902 i = f->size;
903 if (i != SIZEOF_LONG) {
904 unsigned long maxint = 1;
905 maxint <<= (unsigned long)(i * 8);
906 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000907 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000908 }
909 do {
910 p[--i] = (char)x;
911 x >>= 8;
912 } while (i > 0);
913 return 0;
914}
915
916static int
917bp_longlong(char *p, PyObject *v, const formatdef *f)
918{
919 int res;
920 v = get_pylong(v);
921 if (v == NULL)
922 return -1;
923 res = _PyLong_AsByteArray((PyLongObject *)v,
924 (unsigned char *)p,
925 8,
926 0, /* little_endian */
927 1 /* signed */);
928 Py_DECREF(v);
929 return res;
930}
931
932static int
933bp_ulonglong(char *p, PyObject *v, const formatdef *f)
934{
935 int res;
936 v = get_pylong(v);
937 if (v == NULL)
938 return -1;
939 res = _PyLong_AsByteArray((PyLongObject *)v,
940 (unsigned char *)p,
941 8,
942 0, /* little_endian */
943 0 /* signed */);
944 Py_DECREF(v);
945 return res;
946}
947
948static int
949bp_float(char *p, PyObject *v, const formatdef *f)
950{
951 double x = PyFloat_AsDouble(v);
952 if (x == -1 && PyErr_Occurred()) {
953 PyErr_SetString(StructError,
954 "required argument is not a float");
955 return -1;
956 }
957 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
958}
959
960static int
961bp_double(char *p, PyObject *v, const formatdef *f)
962{
963 double x = PyFloat_AsDouble(v);
964 if (x == -1 && PyErr_Occurred()) {
965 PyErr_SetString(StructError,
966 "required argument is not a float");
967 return -1;
968 }
969 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
970}
971
972static formatdef bigendian_table[] = {
973 {'x', 1, 0, NULL},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000974#ifdef PY_STRUCT_OVERFLOW_MASKING
975 /* Native packers do range checking without overflow masking. */
976 {'b', 1, 0, nu_byte, bp_int},
977 {'B', 1, 0, nu_ubyte, bp_uint},
978#else
Thomas Wouters477c8d52006-05-27 19:21:47 +0000979 {'b', 1, 0, nu_byte, np_byte},
980 {'B', 1, 0, nu_ubyte, np_ubyte},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000981#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000982 {'c', 1, 0, nu_char, np_char},
983 {'s', 1, 0, NULL},
984 {'p', 1, 0, NULL},
985 {'h', 2, 0, bu_int, bp_int},
986 {'H', 2, 0, bu_uint, bp_uint},
987 {'i', 4, 0, bu_int, bp_int},
988 {'I', 4, 0, bu_uint, bp_uint},
989 {'l', 4, 0, bu_int, bp_int},
990 {'L', 4, 0, bu_uint, bp_uint},
991 {'q', 8, 0, bu_longlong, bp_longlong},
992 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
993 {'f', 4, 0, bu_float, bp_float},
994 {'d', 8, 0, bu_double, bp_double},
995 {0}
996};
997
998/* Little-endian routines. *****************************************************/
999
1000static PyObject *
1001lu_int(const char *p, const formatdef *f)
1002{
1003 long x = 0;
1004 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001005 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001006 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001007 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001008 } while (i > 0);
1009 /* Extend the sign bit. */
1010 if (SIZEOF_LONG > f->size)
1011 x |= -(x & (1L << ((8 * f->size) - 1)));
1012 return PyInt_FromLong(x);
1013}
1014
1015static PyObject *
1016lu_uint(const char *p, const formatdef *f)
1017{
1018 unsigned long x = 0;
1019 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001020 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001021 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001022 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001023 } while (i > 0);
1024 if (x <= LONG_MAX)
1025 return PyInt_FromLong((long)x);
1026 return PyLong_FromUnsignedLong((long)x);
1027}
1028
1029static PyObject *
1030lu_longlong(const char *p, const formatdef *f)
1031{
1032#ifdef HAVE_LONG_LONG
1033 PY_LONG_LONG x = 0;
1034 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001035 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001036 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001037 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001038 } while (i > 0);
1039 /* Extend the sign bit. */
1040 if (SIZEOF_LONG_LONG > f->size)
1041 x |= -(x & (1L << ((8 * f->size) - 1)));
1042 if (x >= LONG_MIN && x <= LONG_MAX)
1043 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
1044 return PyLong_FromLongLong(x);
1045#else
1046 return _PyLong_FromByteArray((const unsigned char *)p,
1047 8,
1048 1, /* little-endian */
1049 1 /* signed */);
1050#endif
1051}
1052
1053static PyObject *
1054lu_ulonglong(const char *p, const formatdef *f)
1055{
1056#ifdef HAVE_LONG_LONG
1057 unsigned PY_LONG_LONG x = 0;
1058 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001059 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001060 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001061 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001062 } while (i > 0);
1063 if (x <= LONG_MAX)
1064 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
1065 return PyLong_FromUnsignedLongLong(x);
1066#else
1067 return _PyLong_FromByteArray((const unsigned char *)p,
1068 8,
1069 1, /* little-endian */
1070 0 /* signed */);
1071#endif
1072}
1073
1074static PyObject *
1075lu_float(const char *p, const formatdef *f)
1076{
1077 return unpack_float(p, 1);
1078}
1079
1080static PyObject *
1081lu_double(const char *p, const formatdef *f)
1082{
1083 return unpack_double(p, 1);
1084}
1085
1086static int
1087lp_int(char *p, PyObject *v, const formatdef *f)
1088{
1089 long x;
1090 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001091 if (get_wrapped_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001092 return -1;
1093 i = f->size;
1094 if (i != SIZEOF_LONG) {
1095 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001096 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001097#if (SIZEOF_LONG != 4)
1098 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001099 RANGE_ERROR(x, f, 0, 0xffffffffL);
1100#endif
1101#ifdef PY_STRUCT_OVERFLOW_MASKING
1102 else if ((i == 1) && (x < -128 || x > 127))
1103 RANGE_ERROR(x, f, 0, 0xffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001104#endif
1105 }
1106 do {
1107 *p++ = (char)x;
1108 x >>= 8;
1109 } while (--i > 0);
1110 return 0;
1111}
1112
1113static int
1114lp_uint(char *p, PyObject *v, const formatdef *f)
1115{
1116 unsigned long x;
1117 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001118 if (get_wrapped_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001119 return -1;
1120 i = f->size;
1121 if (i != SIZEOF_LONG) {
1122 unsigned long maxint = 1;
1123 maxint <<= (unsigned long)(i * 8);
1124 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001125 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001126 }
1127 do {
1128 *p++ = (char)x;
1129 x >>= 8;
1130 } while (--i > 0);
1131 return 0;
1132}
1133
1134static int
1135lp_longlong(char *p, PyObject *v, const formatdef *f)
1136{
1137 int res;
1138 v = get_pylong(v);
1139 if (v == NULL)
1140 return -1;
1141 res = _PyLong_AsByteArray((PyLongObject*)v,
1142 (unsigned char *)p,
1143 8,
1144 1, /* little_endian */
1145 1 /* signed */);
1146 Py_DECREF(v);
1147 return res;
1148}
1149
1150static int
1151lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1152{
1153 int res;
1154 v = get_pylong(v);
1155 if (v == NULL)
1156 return -1;
1157 res = _PyLong_AsByteArray((PyLongObject*)v,
1158 (unsigned char *)p,
1159 8,
1160 1, /* little_endian */
1161 0 /* signed */);
1162 Py_DECREF(v);
1163 return res;
1164}
1165
1166static int
1167lp_float(char *p, PyObject *v, const formatdef *f)
1168{
1169 double x = PyFloat_AsDouble(v);
1170 if (x == -1 && PyErr_Occurred()) {
1171 PyErr_SetString(StructError,
1172 "required argument is not a float");
1173 return -1;
1174 }
1175 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1176}
1177
1178static int
1179lp_double(char *p, PyObject *v, const formatdef *f)
1180{
1181 double x = PyFloat_AsDouble(v);
1182 if (x == -1 && PyErr_Occurred()) {
1183 PyErr_SetString(StructError,
1184 "required argument is not a float");
1185 return -1;
1186 }
1187 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1188}
1189
1190static formatdef lilendian_table[] = {
1191 {'x', 1, 0, NULL},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001192#ifdef PY_STRUCT_OVERFLOW_MASKING
1193 /* Native packers do range checking without overflow masking. */
1194 {'b', 1, 0, nu_byte, lp_int},
1195 {'B', 1, 0, nu_ubyte, lp_uint},
1196#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001197 {'b', 1, 0, nu_byte, np_byte},
1198 {'B', 1, 0, nu_ubyte, np_ubyte},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001199#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001200 {'c', 1, 0, nu_char, np_char},
1201 {'s', 1, 0, NULL},
1202 {'p', 1, 0, NULL},
1203 {'h', 2, 0, lu_int, lp_int},
1204 {'H', 2, 0, lu_uint, lp_uint},
1205 {'i', 4, 0, lu_int, lp_int},
1206 {'I', 4, 0, lu_uint, lp_uint},
1207 {'l', 4, 0, lu_int, lp_int},
1208 {'L', 4, 0, lu_uint, lp_uint},
1209 {'q', 8, 0, lu_longlong, lp_longlong},
1210 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1211 {'f', 4, 0, lu_float, lp_float},
1212 {'d', 8, 0, lu_double, lp_double},
1213 {0}
1214};
1215
1216
1217static const formatdef *
1218whichtable(char **pfmt)
1219{
1220 const char *fmt = (*pfmt)++; /* May be backed out of later */
1221 switch (*fmt) {
1222 case '<':
1223 return lilendian_table;
1224 case '>':
1225 case '!': /* Network byte order is big-endian */
1226 return bigendian_table;
1227 case '=': { /* Host byte order -- different from native in aligment! */
1228 int n = 1;
1229 char *p = (char *) &n;
1230 if (*p == 1)
1231 return lilendian_table;
1232 else
1233 return bigendian_table;
1234 }
1235 default:
1236 --*pfmt; /* Back out of pointer increment */
1237 /* Fall through */
1238 case '@':
1239 return native_table;
1240 }
1241}
1242
1243
1244/* Get the table entry for a format code */
1245
1246static const formatdef *
1247getentry(int c, const formatdef *f)
1248{
1249 for (; f->format != '\0'; f++) {
1250 if (f->format == c) {
1251 return f;
1252 }
1253 }
1254 PyErr_SetString(StructError, "bad char in struct format");
1255 return NULL;
1256}
1257
1258
1259/* Align a size according to a format code */
1260
1261static int
1262align(Py_ssize_t size, char c, const formatdef *e)
1263{
1264 if (e->format == c) {
1265 if (e->alignment) {
1266 size = ((size + e->alignment - 1)
1267 / e->alignment)
1268 * e->alignment;
1269 }
1270 }
1271 return size;
1272}
1273
1274
1275/* calculate the size of a format string */
1276
1277static int
1278prepare_s(PyStructObject *self)
1279{
1280 const formatdef *f;
1281 const formatdef *e;
1282 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001283
Thomas Wouters477c8d52006-05-27 19:21:47 +00001284 const char *s;
1285 const char *fmt;
1286 char c;
1287 Py_ssize_t size, len, num, itemsize, x;
1288
1289 fmt = PyString_AS_STRING(self->s_format);
1290
1291 f = whichtable((char **)&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001292
Thomas Wouters477c8d52006-05-27 19:21:47 +00001293 s = fmt;
1294 size = 0;
1295 len = 0;
1296 while ((c = *s++) != '\0') {
1297 if (isspace(Py_CHARMASK(c)))
1298 continue;
1299 if ('0' <= c && c <= '9') {
1300 num = c - '0';
1301 while ('0' <= (c = *s++) && c <= '9') {
1302 x = num*10 + (c - '0');
1303 if (x/10 != num) {
1304 PyErr_SetString(
1305 StructError,
1306 "overflow in item count");
1307 return -1;
1308 }
1309 num = x;
1310 }
1311 if (c == '\0')
1312 break;
1313 }
1314 else
1315 num = 1;
1316
1317 e = getentry(c, f);
1318 if (e == NULL)
1319 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001320
Thomas Wouters477c8d52006-05-27 19:21:47 +00001321 switch (c) {
1322 case 's': /* fall through */
1323 case 'p': len++; break;
1324 case 'x': break;
1325 default: len += num; break;
1326 }
1327
1328 itemsize = e->size;
1329 size = align(size, c, e);
1330 x = num * itemsize;
1331 size += x;
1332 if (x/itemsize != num || size < 0) {
1333 PyErr_SetString(StructError,
1334 "total struct size too long");
1335 return -1;
1336 }
1337 }
1338
1339 self->s_size = size;
1340 self->s_len = len;
1341 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1342 if (codes == NULL) {
1343 PyErr_NoMemory();
1344 return -1;
1345 }
1346 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001347
Thomas Wouters477c8d52006-05-27 19:21:47 +00001348 s = fmt;
1349 size = 0;
1350 while ((c = *s++) != '\0') {
1351 if (isspace(Py_CHARMASK(c)))
1352 continue;
1353 if ('0' <= c && c <= '9') {
1354 num = c - '0';
1355 while ('0' <= (c = *s++) && c <= '9')
1356 num = num*10 + (c - '0');
1357 if (c == '\0')
1358 break;
1359 }
1360 else
1361 num = 1;
1362
1363 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001364
Thomas Wouters477c8d52006-05-27 19:21:47 +00001365 size = align(size, c, e);
1366 if (c == 's' || c == 'p') {
1367 codes->offset = size;
1368 codes->size = num;
1369 codes->fmtdef = e;
1370 codes++;
1371 size += num;
1372 } else if (c == 'x') {
1373 size += num;
1374 } else {
1375 while (--num >= 0) {
1376 codes->offset = size;
1377 codes->size = e->size;
1378 codes->fmtdef = e;
1379 codes++;
1380 size += e->size;
1381 }
1382 }
1383 }
1384 codes->fmtdef = NULL;
1385 codes->offset = size;
1386 codes->size = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001387
Thomas Wouters477c8d52006-05-27 19:21:47 +00001388 return 0;
1389}
1390
1391static PyObject *
1392s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1393{
1394 PyObject *self;
1395
1396 assert(type != NULL && type->tp_alloc != NULL);
1397
1398 self = type->tp_alloc(type, 0);
1399 if (self != NULL) {
1400 PyStructObject *s = (PyStructObject*)self;
1401 Py_INCREF(Py_None);
1402 s->s_format = Py_None;
1403 s->s_codes = NULL;
1404 s->s_size = -1;
1405 s->s_len = -1;
1406 }
1407 return self;
1408}
1409
1410static int
1411s_init(PyObject *self, PyObject *args, PyObject *kwds)
1412{
1413 PyStructObject *soself = (PyStructObject *)self;
1414 PyObject *o_format = NULL;
1415 int ret = 0;
1416 static char *kwlist[] = {"format", 0};
1417
1418 assert(PyStruct_Check(self));
1419
1420 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1421 &o_format))
1422 return -1;
1423
1424 Py_INCREF(o_format);
1425 Py_XDECREF(soself->s_format);
1426 soself->s_format = o_format;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001427
Thomas Wouters477c8d52006-05-27 19:21:47 +00001428 ret = prepare_s(soself);
1429 return ret;
1430}
1431
1432static void
1433s_dealloc(PyStructObject *s)
1434{
1435 if (s->weakreflist != NULL)
1436 PyObject_ClearWeakRefs((PyObject *)s);
1437 if (s->s_codes != NULL) {
1438 PyMem_FREE(s->s_codes);
1439 }
1440 Py_XDECREF(s->s_format);
1441 s->ob_type->tp_free((PyObject *)s);
1442}
1443
1444static PyObject *
1445s_unpack_internal(PyStructObject *soself, char *startfrom) {
1446 formatcode *code;
1447 Py_ssize_t i = 0;
1448 PyObject *result = PyTuple_New(soself->s_len);
1449 if (result == NULL)
1450 return NULL;
1451
1452 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1453 PyObject *v;
1454 const formatdef *e = code->fmtdef;
1455 const char *res = startfrom + code->offset;
1456 if (e->format == 's') {
1457 v = PyString_FromStringAndSize(res, code->size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001458 } else if (e->format == 'p') {
1459 Py_ssize_t n = *(unsigned char*)res;
1460 if (n >= code->size)
1461 n = code->size - 1;
1462 v = PyString_FromStringAndSize(res + 1, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001463 } else {
1464 v = e->unpack(res, e);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001465 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001466 if (v == NULL)
1467 goto fail;
1468 PyTuple_SET_ITEM(result, i++, v);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001469 }
1470
1471 return result;
1472fail:
1473 Py_DECREF(result);
1474 return NULL;
1475}
1476
1477
1478PyDoc_STRVAR(s_unpack__doc__,
1479"S.unpack(str) -> (v1, v2, ...)\n\
1480\n\
1481Return tuple containing values unpacked according to this Struct's format.\n\
1482Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1483strings.");
1484
1485static PyObject *
1486s_unpack(PyObject *self, PyObject *inputstr)
1487{
1488 PyStructObject *soself = (PyStructObject *)self;
1489 assert(PyStruct_Check(self));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001490 assert(soself->s_codes != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001491 if (inputstr == NULL || !PyString_Check(inputstr) ||
1492 PyString_GET_SIZE(inputstr) != soself->s_size) {
1493 PyErr_Format(StructError,
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001494 "unpack requires a string argument of length %zd",
1495 soself->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001496 return NULL;
1497 }
1498 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1499}
1500
1501PyDoc_STRVAR(s_unpack_from__doc__,
1502"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1503\n\
1504Return tuple containing values unpacked according to this Struct's format.\n\
1505Unlike unpack, unpack_from can unpack values from any object supporting\n\
1506the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1507See struct.__doc__ for more on format strings.");
1508
1509static PyObject *
1510s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1511{
1512 static char *kwlist[] = {"buffer", "offset", 0};
1513#if (PY_VERSION_HEX < 0x02050000)
1514 static char *fmt = "z#|i:unpack_from";
1515#else
1516 static char *fmt = "z#|n:unpack_from";
1517#endif
1518 Py_ssize_t buffer_len = 0, offset = 0;
1519 char *buffer = NULL;
1520 PyStructObject *soself = (PyStructObject *)self;
1521 assert(PyStruct_Check(self));
1522 assert(soself->s_codes != NULL);
1523
1524 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1525 &buffer, &buffer_len, &offset))
1526 return NULL;
1527
1528 if (buffer == NULL) {
1529 PyErr_Format(StructError,
1530 "unpack_from requires a buffer argument");
1531 return NULL;
1532 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001533
Thomas Wouters477c8d52006-05-27 19:21:47 +00001534 if (offset < 0)
1535 offset += buffer_len;
1536
1537 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1538 PyErr_Format(StructError,
1539 "unpack_from requires a buffer of at least %zd bytes",
1540 soself->s_size);
1541 return NULL;
1542 }
1543 return s_unpack_internal(soself, buffer + offset);
1544}
1545
1546
1547/*
1548 * Guts of the pack function.
1549 *
1550 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1551 * argument for where to start processing the arguments for packing, and a
1552 * character buffer for writing the packed string. The caller must insure
1553 * that the buffer may contain the required length for packing the arguments.
1554 * 0 is returned on success, 1 is returned if there is an error.
1555 *
1556 */
1557static int
1558s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1559{
1560 formatcode *code;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001561 /* XXX(nnorwitz): why does i need to be a local? can we use
1562 the offset parameter or do we need the wider width? */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001563 Py_ssize_t i;
1564
1565 memset(buf, '\0', soself->s_size);
1566 i = offset;
1567 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1568 Py_ssize_t n;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001569 PyObject *v = PyTuple_GET_ITEM(args, i++);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001570 const formatdef *e = code->fmtdef;
1571 char *res = buf + code->offset;
1572 if (e->format == 's') {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001573 if (!PyString_Check(v)) {
1574 PyErr_SetString(StructError,
1575 "argument for 's' must be a string");
1576 return -1;
1577 }
1578 n = PyString_GET_SIZE(v);
1579 if (n > code->size)
1580 n = code->size;
1581 if (n > 0)
1582 memcpy(res, PyString_AS_STRING(v), n);
1583 } else if (e->format == 'p') {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001584 if (!PyString_Check(v)) {
1585 PyErr_SetString(StructError,
1586 "argument for 'p' must be a string");
1587 return -1;
1588 }
1589 n = PyString_GET_SIZE(v);
1590 if (n > (code->size - 1))
1591 n = code->size - 1;
1592 if (n > 0)
1593 memcpy(res + 1, PyString_AS_STRING(v), n);
1594 if (n > 255)
1595 n = 255;
1596 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1597 } else {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001598 if (e->pack(res, v, e) < 0) {
1599 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1600 PyErr_SetString(StructError,
1601 "long too large to convert to int");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001602 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001603 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001604 }
1605 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001606
Thomas Wouters477c8d52006-05-27 19:21:47 +00001607 /* Success */
1608 return 0;
1609}
1610
1611
1612PyDoc_STRVAR(s_pack__doc__,
1613"S.pack(v1, v2, ...) -> string\n\
1614\n\
1615Return a string containing values v1, v2, ... packed according to this\n\
1616Struct's format. See struct.__doc__ for more on format strings.");
1617
1618static PyObject *
1619s_pack(PyObject *self, PyObject *args)
1620{
1621 PyStructObject *soself;
1622 PyObject *result;
1623
1624 /* Validate arguments. */
1625 soself = (PyStructObject *)self;
1626 assert(PyStruct_Check(self));
1627 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001628 if (PyTuple_GET_SIZE(args) != soself->s_len)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001629 {
1630 PyErr_Format(StructError,
1631 "pack requires exactly %zd arguments", soself->s_len);
1632 return NULL;
1633 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001634
Thomas Wouters477c8d52006-05-27 19:21:47 +00001635 /* Allocate a new string */
1636 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1637 if (result == NULL)
1638 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001639
Thomas Wouters477c8d52006-05-27 19:21:47 +00001640 /* Call the guts */
1641 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1642 Py_DECREF(result);
1643 return NULL;
1644 }
1645
1646 return result;
1647}
1648
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001649PyDoc_STRVAR(s_pack_into__doc__,
1650"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001651\n\
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001652Pack the values v1, v2, ... according to this Struct's format, write \n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001653the packed bytes into the writable buffer buf starting at offset. Note\n\
1654that the offset is not an optional argument. See struct.__doc__ for \n\
1655more on format strings.");
1656
1657static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001658s_pack_into(PyObject *self, PyObject *args)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001659{
1660 PyStructObject *soself;
1661 char *buffer;
1662 Py_ssize_t buffer_len, offset;
1663
1664 /* Validate arguments. +1 is for the first arg as buffer. */
1665 soself = (PyStructObject *)self;
1666 assert(PyStruct_Check(self));
1667 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001668 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001669 {
1670 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001671 "pack_into requires exactly %zd arguments",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001672 (soself->s_len + 2));
1673 return NULL;
1674 }
1675
1676 /* Extract a writable memory buffer from the first argument */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001677 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1678 (void**)&buffer, &buffer_len) == -1 ) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001679 return NULL;
1680 }
1681 assert( buffer_len >= 0 );
1682
1683 /* Extract the offset from the first argument */
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001684 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001685
1686 /* Support negative offsets. */
1687 if (offset < 0)
1688 offset += buffer_len;
1689
1690 /* Check boundaries */
1691 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1692 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001693 "pack_into requires a buffer of at least %zd bytes",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001694 soself->s_size);
1695 return NULL;
1696 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001697
Thomas Wouters477c8d52006-05-27 19:21:47 +00001698 /* Call the guts */
1699 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1700 return NULL;
1701 }
1702
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001703 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001704}
1705
1706static PyObject *
1707s_get_format(PyStructObject *self, void *unused)
1708{
1709 Py_INCREF(self->s_format);
1710 return self->s_format;
1711}
1712
1713static PyObject *
1714s_get_size(PyStructObject *self, void *unused)
1715{
1716 return PyInt_FromSsize_t(self->s_size);
1717}
1718
1719/* List of functions */
1720
1721static struct PyMethodDef s_methods[] = {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001722 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1723 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1724 {"unpack", s_unpack, METH_O, s_unpack__doc__},
1725 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS,
1726 s_unpack_from__doc__},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001727 {NULL, NULL} /* sentinel */
1728};
1729
1730PyDoc_STRVAR(s__doc__, "Compiled struct object");
1731
1732#define OFF(x) offsetof(PyStructObject, x)
1733
1734static PyGetSetDef s_getsetlist[] = {
1735 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1736 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1737 {NULL} /* sentinel */
1738};
1739
1740static
1741PyTypeObject PyStructType = {
1742 PyObject_HEAD_INIT(NULL)
1743 0,
1744 "Struct",
1745 sizeof(PyStructObject),
1746 0,
1747 (destructor)s_dealloc, /* tp_dealloc */
1748 0, /* tp_print */
1749 0, /* tp_getattr */
1750 0, /* tp_setattr */
1751 0, /* tp_compare */
1752 0, /* tp_repr */
1753 0, /* tp_as_number */
1754 0, /* tp_as_sequence */
1755 0, /* tp_as_mapping */
1756 0, /* tp_hash */
1757 0, /* tp_call */
1758 0, /* tp_str */
1759 PyObject_GenericGetAttr, /* tp_getattro */
1760 PyObject_GenericSetAttr, /* tp_setattro */
1761 0, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +00001762 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001763 s__doc__, /* tp_doc */
1764 0, /* tp_traverse */
1765 0, /* tp_clear */
1766 0, /* tp_richcompare */
1767 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1768 0, /* tp_iter */
1769 0, /* tp_iternext */
1770 s_methods, /* tp_methods */
1771 NULL, /* tp_members */
1772 s_getsetlist, /* tp_getset */
1773 0, /* tp_base */
1774 0, /* tp_dict */
1775 0, /* tp_descr_get */
1776 0, /* tp_descr_set */
1777 0, /* tp_dictoffset */
1778 s_init, /* tp_init */
1779 PyType_GenericAlloc,/* tp_alloc */
1780 s_new, /* tp_new */
1781 PyObject_Del, /* tp_free */
1782};
1783
1784/* Module initialization */
1785
1786PyMODINIT_FUNC
1787init_struct(void)
1788{
1789 PyObject *m = Py_InitModule("_struct", NULL);
1790 if (m == NULL)
1791 return;
1792
1793 PyStructType.ob_type = &PyType_Type;
1794 if (PyType_Ready(&PyStructType) < 0)
1795 return;
1796
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001797#ifdef PY_STRUCT_OVERFLOW_MASKING
1798 if (pyint_zero == NULL) {
1799 pyint_zero = PyInt_FromLong(0);
1800 if (pyint_zero == NULL)
1801 return;
1802 }
1803 if (pylong_ulong_mask == NULL) {
1804#if (SIZEOF_LONG == 4)
1805 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1806#else
1807 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1808#endif
1809 if (pylong_ulong_mask == NULL)
1810 return;
1811 }
1812
1813#else
1814 /* This speed trick can't be used until overflow masking goes away, because
1815 native endian always raises exceptions instead of overflow masking. */
1816
Thomas Wouters477c8d52006-05-27 19:21:47 +00001817 /* Check endian and swap in faster functions */
1818 {
1819 int one = 1;
1820 formatdef *native = native_table;
1821 formatdef *other, *ptr;
1822 if ((int)*(unsigned char*)&one)
1823 other = lilendian_table;
1824 else
1825 other = bigendian_table;
1826 /* Scan through the native table, find a matching
1827 entry in the endian table and swap in the
1828 native implementations whenever possible
1829 (64-bit platforms may not have "standard" sizes) */
1830 while (native->format != '\0' && other->format != '\0') {
1831 ptr = other;
1832 while (ptr->format != '\0') {
1833 if (ptr->format == native->format) {
1834 /* Match faster when formats are
1835 listed in the same order */
1836 if (ptr == other)
1837 other++;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001838 /* Only use the trick if the
Thomas Wouters477c8d52006-05-27 19:21:47 +00001839 size matches */
1840 if (ptr->size != native->size)
1841 break;
1842 /* Skip float and double, could be
1843 "unknown" float format */
1844 if (ptr->format == 'd' || ptr->format == 'f')
1845 break;
1846 ptr->pack = native->pack;
1847 ptr->unpack = native->unpack;
1848 break;
1849 }
1850 ptr++;
1851 }
1852 native++;
1853 }
1854 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001855#endif
1856
Thomas Wouters477c8d52006-05-27 19:21:47 +00001857 /* Add some symbolic constants to the module */
1858 if (StructError == NULL) {
1859 StructError = PyErr_NewException("struct.error", NULL, NULL);
1860 if (StructError == NULL)
1861 return;
1862 }
1863
1864 Py_INCREF(StructError);
1865 PyModule_AddObject(m, "error", StructError);
1866
1867 Py_INCREF((PyObject*)&PyStructType);
1868 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001869
1870 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
1871#ifdef PY_STRUCT_OVERFLOW_MASKING
1872 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
1873#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001874#ifdef PY_STRUCT_FLOAT_COERCE
1875 PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
1876#endif
1877
Thomas Wouters477c8d52006-05-27 19:21:47 +00001878}