blob: e21487d05c691657b9e5707d04c7eeb609d59882 [file] [log] [blame]
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001/* struct module -- pack values into and (out of) bytes objects */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002
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
Thomas Wouters477c8d52006-05-27 19:21:47 +000015/* The translation function for each format character is table driven */
16typedef struct _formatdef {
17 char format;
18 Py_ssize_t size;
19 Py_ssize_t alignment;
20 PyObject* (*unpack)(const char *,
21 const struct _formatdef *);
22 int (*pack)(char *, PyObject *,
23 const struct _formatdef *);
24} formatdef;
25
26typedef struct _formatcode {
27 const struct _formatdef *fmtdef;
28 Py_ssize_t offset;
29 Py_ssize_t size;
30} formatcode;
31
32/* Struct object interface */
33
34typedef struct {
35 PyObject_HEAD
36 Py_ssize_t s_size;
37 Py_ssize_t s_len;
38 formatcode *s_codes;
39 PyObject *s_format;
40 PyObject *weakreflist; /* List of weak references */
41} PyStructObject;
42
43
44#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
Christian Heimes90aa7642007-12-19 02:45:37 +000045#define PyStruct_CheckExact(op) (Py_TYPE(op) == &PyStructType)
Thomas Wouters477c8d52006-05-27 19:21:47 +000046
47
48/* Exception */
49
50static PyObject *StructError;
51
52
53/* Define various structs to figure out the alignments of types */
54
55
56typedef struct { char c; short x; } st_short;
57typedef struct { char c; int x; } st_int;
58typedef struct { char c; long x; } st_long;
59typedef struct { char c; float x; } st_float;
60typedef struct { char c; double x; } st_double;
61typedef struct { char c; void *x; } st_void_p;
62
63#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
64#define INT_ALIGN (sizeof(st_int) - sizeof(int))
65#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
66#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
67#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
68#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
69
70/* We can't support q and Q in native mode unless the compiler does;
71 in std mode, they're 8 bytes on all platforms. */
72#ifdef HAVE_LONG_LONG
73typedef struct { char c; PY_LONG_LONG x; } s_long_long;
74#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
75#endif
76
Thomas Woutersb2137042007-02-01 18:02:27 +000077#ifdef HAVE_C99_BOOL
78#define BOOL_TYPE _Bool
79typedef struct { char c; _Bool x; } s_bool;
80#define BOOL_ALIGN (sizeof(s_bool) - sizeof(BOOL_TYPE))
81#else
82#define BOOL_TYPE char
83#define BOOL_ALIGN 0
84#endif
85
Thomas Wouters477c8d52006-05-27 19:21:47 +000086#define STRINGIFY(x) #x
87
88#ifdef __powerc
89#pragma options align=reset
90#endif
91
Mark Dickinson055a3fb2010-04-03 15:26:31 +000092/* Helper for integer format codes: converts an arbitrary Python object to a
93 PyLongObject if possible, otherwise fails. Caller should decref. */
Thomas Wouters477c8d52006-05-27 19:21:47 +000094
95static PyObject *
96get_pylong(PyObject *v)
97{
Thomas Wouters477c8d52006-05-27 19:21:47 +000098 assert(v != NULL);
Mark Dickinsonea835e72009-04-19 20:40:33 +000099 if (!PyLong_Check(v)) {
Mark Dickinsonc5935772010-04-03 15:54:36 +0000100 /* Not an integer; try to use __index__ to convert. */
101 if (PyIndex_Check(v)) {
102 v = PyNumber_Index(v);
103 if (v == NULL)
104 return NULL;
105 if (!PyLong_Check(v)) {
106 PyErr_SetString(PyExc_TypeError,
107 "__index__ method "
108 "returned non-integer");
109 return NULL;
110 }
111 }
112 else {
113 PyErr_SetString(StructError,
114 "required argument is not an integer");
115 return NULL;
116 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000117 }
Mark Dickinsonc5935772010-04-03 15:54:36 +0000118 else
119 Py_INCREF(v);
Mark Dickinsonea835e72009-04-19 20:40:33 +0000120
Mark Dickinsonea835e72009-04-19 20:40:33 +0000121 return v;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000122}
123
Mark Dickinsonea835e72009-04-19 20:40:33 +0000124/* Helper routine to get a C long and raise the appropriate error if it isn't
125 one */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000126
127static int
128get_long(PyObject *v, long *p)
129{
Mark Dickinsonea835e72009-04-19 20:40:33 +0000130 long x;
131
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000132 v = get_pylong(v);
133 if (v == NULL)
Mark Dickinsonea835e72009-04-19 20:40:33 +0000134 return -1;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000135 assert(PyLong_Check(v));
Mark Dickinsonea835e72009-04-19 20:40:33 +0000136 x = PyLong_AsLong(v);
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000137 Py_DECREF(v);
138 if (x == (long)-1 && PyErr_Occurred()) {
Mark Dickinsonea835e72009-04-19 20:40:33 +0000139 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000140 PyErr_SetString(StructError,
Mark Dickinsonea835e72009-04-19 20:40:33 +0000141 "argument out of range");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000142 return -1;
143 }
144 *p = x;
145 return 0;
146}
147
148
149/* Same, but handling unsigned long */
150
151static int
152get_ulong(PyObject *v, unsigned long *p)
153{
Mark Dickinsonea835e72009-04-19 20:40:33 +0000154 unsigned long x;
155
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000156 v = get_pylong(v);
157 if (v == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000158 return -1;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000159 assert(PyLong_Check(v));
Mark Dickinsonea835e72009-04-19 20:40:33 +0000160 x = PyLong_AsUnsignedLong(v);
161 if (x == (unsigned long)-1 && PyErr_Occurred()) {
162 if (PyErr_ExceptionMatches(PyExc_OverflowError))
163 PyErr_SetString(StructError,
164 "argument out of range");
165 return -1;
166 }
167 *p = x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000168 return 0;
169}
170
171#ifdef HAVE_LONG_LONG
172
173/* Same, but handling native long long. */
174
175static int
176get_longlong(PyObject *v, PY_LONG_LONG *p)
177{
178 PY_LONG_LONG x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000179
180 v = get_pylong(v);
181 if (v == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000182 return -1;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000183 assert(PyLong_Check(v));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000184 x = PyLong_AsLongLong(v);
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000185 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred()) {
Mark Dickinsonea835e72009-04-19 20:40:33 +0000186 if (PyErr_ExceptionMatches(PyExc_OverflowError))
187 PyErr_SetString(StructError,
188 "argument out of range");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000189 return -1;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000190 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000191 *p = x;
192 return 0;
193}
194
195/* Same, but handling native unsigned long long. */
196
197static int
198get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
199{
200 unsigned PY_LONG_LONG x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000201
202 v = get_pylong(v);
203 if (v == NULL)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000204 return -1;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000205 assert(PyLong_Check(v));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000206 x = PyLong_AsUnsignedLongLong(v);
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000207 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) {
Mark Dickinsonea835e72009-04-19 20:40:33 +0000208 if (PyErr_ExceptionMatches(PyExc_OverflowError))
209 PyErr_SetString(StructError,
210 "argument out of range");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000211 return -1;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000212 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000213 *p = x;
214 return 0;
215}
216
217#endif
218
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000219
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000220#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
221
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000222
Thomas Wouters477c8d52006-05-27 19:21:47 +0000223/* Floating point helpers */
224
225static PyObject *
226unpack_float(const char *p, /* start of 4-byte string */
227 int le) /* true for little-endian, false for big-endian */
228{
229 double x;
230
231 x = _PyFloat_Unpack4((unsigned char *)p, le);
232 if (x == -1.0 && PyErr_Occurred())
233 return NULL;
234 return PyFloat_FromDouble(x);
235}
236
237static PyObject *
238unpack_double(const char *p, /* start of 8-byte string */
239 int le) /* true for little-endian, false for big-endian */
240{
241 double x;
242
243 x = _PyFloat_Unpack8((unsigned char *)p, le);
244 if (x == -1.0 && PyErr_Occurred())
245 return NULL;
246 return PyFloat_FromDouble(x);
247}
248
249/* Helper to format the range error exceptions */
250static int
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000251_range_error(const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000252{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000253 /* ulargest is the largest unsigned value with f->size bytes.
254 * Note that the simpler:
255 * ((size_t)1 << (f->size * 8)) - 1
256 * doesn't work when f->size == sizeof(size_t) because C doesn't
257 * define what happens when a left shift count is >= the number of
258 * bits in the integer being shifted; e.g., on some boxes it doesn't
259 * shift at all when they're equal.
260 */
261 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
262 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
263 if (is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000264 PyErr_Format(StructError,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000265 "'%c' format requires 0 <= number <= %zu",
266 f->format,
267 ulargest);
268 else {
269 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000270 PyErr_Format(StructError,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000271 "'%c' format requires %zd <= number <= %zd",
272 f->format,
273 ~ largest,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000274 largest);
275 }
Mark Dickinsonae681df2009-03-21 10:26:31 +0000276
Thomas Wouters477c8d52006-05-27 19:21:47 +0000277 return -1;
278}
279
280
281
282/* A large number of small routines follow, with names of the form
283
284 [bln][up]_TYPE
285
286 [bln] distiguishes among big-endian, little-endian and native.
287 [pu] distiguishes between pack (to struct) and unpack (from struct).
288 TYPE is one of char, byte, ubyte, etc.
289*/
290
291/* Native mode routines. ****************************************************/
292/* NOTE:
293 In all n[up]_<type> routines handling types larger than 1 byte, there is
294 *no* guarantee that the p pointer is properly aligned for each type,
295 therefore memcpy is called. An intermediate variable is used to
296 compensate for big-endian architectures.
297 Normally both the intermediate variable and the memcpy call will be
298 skipped by C optimisation in little-endian architectures (gcc >= 2.91
299 does this). */
300
301static PyObject *
302nu_char(const char *p, const formatdef *f)
303{
Christian Heimes72b710a2008-05-26 13:28:38 +0000304 return PyBytes_FromStringAndSize(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000305}
306
307static PyObject *
308nu_byte(const char *p, const formatdef *f)
309{
Christian Heimes217cfd12007-12-02 14:31:20 +0000310 return PyLong_FromLong((long) *(signed char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000311}
312
313static PyObject *
314nu_ubyte(const char *p, const formatdef *f)
315{
Christian Heimes217cfd12007-12-02 14:31:20 +0000316 return PyLong_FromLong((long) *(unsigned char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000317}
318
319static PyObject *
320nu_short(const char *p, const formatdef *f)
321{
322 short x;
323 memcpy((char *)&x, p, sizeof x);
Christian Heimes217cfd12007-12-02 14:31:20 +0000324 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325}
326
327static PyObject *
328nu_ushort(const char *p, const formatdef *f)
329{
330 unsigned short x;
331 memcpy((char *)&x, p, sizeof x);
Christian Heimes217cfd12007-12-02 14:31:20 +0000332 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000333}
334
335static PyObject *
336nu_int(const char *p, const formatdef *f)
337{
338 int x;
339 memcpy((char *)&x, p, sizeof x);
Christian Heimes217cfd12007-12-02 14:31:20 +0000340 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000341}
342
343static PyObject *
344nu_uint(const char *p, const formatdef *f)
345{
346 unsigned int x;
347 memcpy((char *)&x, p, sizeof x);
348#if (SIZEOF_LONG > SIZEOF_INT)
Christian Heimes217cfd12007-12-02 14:31:20 +0000349 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000350#else
351 if (x <= ((unsigned int)LONG_MAX))
Christian Heimes217cfd12007-12-02 14:31:20 +0000352 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000353 return PyLong_FromUnsignedLong((unsigned long)x);
354#endif
355}
356
357static PyObject *
358nu_long(const char *p, const formatdef *f)
359{
360 long x;
361 memcpy((char *)&x, p, sizeof x);
Christian Heimes217cfd12007-12-02 14:31:20 +0000362 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000363}
364
365static PyObject *
366nu_ulong(const char *p, const formatdef *f)
367{
368 unsigned long x;
369 memcpy((char *)&x, p, sizeof x);
370 if (x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000371 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000372 return PyLong_FromUnsignedLong(x);
373}
374
375/* Native mode doesn't support q or Q unless the platform C supports
376 long long (or, on Windows, __int64). */
377
378#ifdef HAVE_LONG_LONG
379
380static PyObject *
381nu_longlong(const char *p, const formatdef *f)
382{
383 PY_LONG_LONG x;
384 memcpy((char *)&x, p, sizeof x);
385 if (x >= LONG_MIN && x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000386 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000387 return PyLong_FromLongLong(x);
388}
389
390static PyObject *
391nu_ulonglong(const char *p, const formatdef *f)
392{
393 unsigned PY_LONG_LONG x;
394 memcpy((char *)&x, p, sizeof x);
395 if (x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000396 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000397 return PyLong_FromUnsignedLongLong(x);
398}
399
400#endif
401
402static PyObject *
Thomas Woutersb2137042007-02-01 18:02:27 +0000403nu_bool(const char *p, const formatdef *f)
404{
405 BOOL_TYPE x;
406 memcpy((char *)&x, p, sizeof x);
407 return PyBool_FromLong(x != 0);
408}
409
410
411static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000412nu_float(const char *p, const formatdef *f)
413{
414 float x;
415 memcpy((char *)&x, p, sizeof x);
416 return PyFloat_FromDouble((double)x);
417}
418
419static PyObject *
420nu_double(const char *p, const formatdef *f)
421{
422 double x;
423 memcpy((char *)&x, p, sizeof x);
424 return PyFloat_FromDouble(x);
425}
426
427static PyObject *
428nu_void_p(const char *p, const formatdef *f)
429{
430 void *x;
431 memcpy((char *)&x, p, sizeof x);
432 return PyLong_FromVoidPtr(x);
433}
434
435static int
436np_byte(char *p, PyObject *v, const formatdef *f)
437{
438 long x;
439 if (get_long(v, &x) < 0)
440 return -1;
441 if (x < -128 || x > 127){
442 PyErr_SetString(StructError,
443 "byte format requires -128 <= number <= 127");
444 return -1;
445 }
446 *p = (char)x;
447 return 0;
448}
449
450static int
451np_ubyte(char *p, PyObject *v, const formatdef *f)
452{
453 long x;
454 if (get_long(v, &x) < 0)
455 return -1;
456 if (x < 0 || x > 255){
457 PyErr_SetString(StructError,
458 "ubyte format requires 0 <= number <= 255");
459 return -1;
460 }
461 *p = (char)x;
462 return 0;
463}
464
465static int
466np_char(char *p, PyObject *v, const formatdef *f)
467{
Guido van Rossume625fd52007-05-27 09:19:04 +0000468 if (PyUnicode_Check(v)) {
469 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
470 if (v == NULL)
471 return -1;
472 }
Christian Heimes72b710a2008-05-26 13:28:38 +0000473 if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000474 PyErr_SetString(StructError,
Benjamin Peterson4ae19462008-07-31 15:03:40 +0000475 "char format requires bytes or string of length 1");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000476 return -1;
477 }
Christian Heimes72b710a2008-05-26 13:28:38 +0000478 *p = *PyBytes_AsString(v);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000479 return 0;
480}
481
482static int
483np_short(char *p, PyObject *v, const formatdef *f)
484{
485 long x;
486 short y;
487 if (get_long(v, &x) < 0)
488 return -1;
489 if (x < SHRT_MIN || x > SHRT_MAX){
490 PyErr_SetString(StructError,
491 "short format requires " STRINGIFY(SHRT_MIN)
492 " <= number <= " STRINGIFY(SHRT_MAX));
493 return -1;
494 }
495 y = (short)x;
496 memcpy(p, (char *)&y, sizeof y);
497 return 0;
498}
499
500static int
501np_ushort(char *p, PyObject *v, const formatdef *f)
502{
503 long x;
504 unsigned short y;
505 if (get_long(v, &x) < 0)
506 return -1;
507 if (x < 0 || x > USHRT_MAX){
508 PyErr_SetString(StructError,
Mark Dickinsond99620d2009-07-07 10:21:03 +0000509 "ushort format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000510 return -1;
511 }
512 y = (unsigned short)x;
513 memcpy(p, (char *)&y, sizeof y);
514 return 0;
515}
516
517static int
518np_int(char *p, PyObject *v, const formatdef *f)
519{
520 long x;
521 int y;
522 if (get_long(v, &x) < 0)
523 return -1;
524#if (SIZEOF_LONG > SIZEOF_INT)
525 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Georg Brandlb1441c72009-01-03 22:33:39 +0000526 RANGE_ERROR(x, f, 0, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000527#endif
528 y = (int)x;
529 memcpy(p, (char *)&y, sizeof y);
530 return 0;
531}
532
533static int
534np_uint(char *p, PyObject *v, const formatdef *f)
535{
536 unsigned long x;
537 unsigned int y;
Mark Dickinsonae681df2009-03-21 10:26:31 +0000538 if (get_ulong(v, &x) < 0)
Georg Brandlb1441c72009-01-03 22:33:39 +0000539 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000540 y = (unsigned int)x;
541#if (SIZEOF_LONG > SIZEOF_INT)
542 if (x > ((unsigned long)UINT_MAX))
Georg Brandlb1441c72009-01-03 22:33:39 +0000543 RANGE_ERROR(y, f, 1, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000544#endif
545 memcpy(p, (char *)&y, sizeof y);
546 return 0;
547}
548
549static int
550np_long(char *p, PyObject *v, const formatdef *f)
551{
552 long x;
553 if (get_long(v, &x) < 0)
554 return -1;
555 memcpy(p, (char *)&x, sizeof x);
556 return 0;
557}
558
559static int
560np_ulong(char *p, PyObject *v, const formatdef *f)
561{
562 unsigned long x;
Mark Dickinsonae681df2009-03-21 10:26:31 +0000563 if (get_ulong(v, &x) < 0)
Georg Brandlb1441c72009-01-03 22:33:39 +0000564 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000565 memcpy(p, (char *)&x, sizeof x);
566 return 0;
567}
568
569#ifdef HAVE_LONG_LONG
570
571static int
572np_longlong(char *p, PyObject *v, const formatdef *f)
573{
574 PY_LONG_LONG x;
575 if (get_longlong(v, &x) < 0)
576 return -1;
577 memcpy(p, (char *)&x, sizeof x);
578 return 0;
579}
580
581static int
582np_ulonglong(char *p, PyObject *v, const formatdef *f)
583{
584 unsigned PY_LONG_LONG x;
585 if (get_ulonglong(v, &x) < 0)
586 return -1;
587 memcpy(p, (char *)&x, sizeof x);
588 return 0;
589}
590#endif
591
Thomas Woutersb2137042007-02-01 18:02:27 +0000592
593static int
594np_bool(char *p, PyObject *v, const formatdef *f)
595{
596 BOOL_TYPE y;
597 y = PyObject_IsTrue(v);
598 memcpy(p, (char *)&y, sizeof y);
599 return 0;
600}
601
Thomas Wouters477c8d52006-05-27 19:21:47 +0000602static int
603np_float(char *p, PyObject *v, const formatdef *f)
604{
605 float x = (float)PyFloat_AsDouble(v);
606 if (x == -1 && PyErr_Occurred()) {
607 PyErr_SetString(StructError,
608 "required argument is not a float");
609 return -1;
610 }
611 memcpy(p, (char *)&x, sizeof x);
612 return 0;
613}
614
615static int
616np_double(char *p, PyObject *v, const formatdef *f)
617{
618 double x = PyFloat_AsDouble(v);
619 if (x == -1 && PyErr_Occurred()) {
620 PyErr_SetString(StructError,
621 "required argument is not a float");
622 return -1;
623 }
624 memcpy(p, (char *)&x, sizeof(double));
625 return 0;
626}
627
628static int
629np_void_p(char *p, PyObject *v, const formatdef *f)
630{
631 void *x;
632
633 v = get_pylong(v);
634 if (v == NULL)
635 return -1;
636 assert(PyLong_Check(v));
637 x = PyLong_AsVoidPtr(v);
638 Py_DECREF(v);
639 if (x == NULL && PyErr_Occurred())
640 return -1;
641 memcpy(p, (char *)&x, sizeof x);
642 return 0;
643}
644
645static formatdef native_table[] = {
646 {'x', sizeof(char), 0, NULL},
647 {'b', sizeof(char), 0, nu_byte, np_byte},
648 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
649 {'c', sizeof(char), 0, nu_char, np_char},
650 {'s', sizeof(char), 0, NULL},
651 {'p', sizeof(char), 0, NULL},
652 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
653 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
654 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
655 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
656 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
657 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
658#ifdef HAVE_LONG_LONG
659 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
660 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
661#endif
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000662 {'?', sizeof(BOOL_TYPE), BOOL_ALIGN, nu_bool, np_bool},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000663 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
664 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
665 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
666 {0}
667};
668
669/* Big-endian routines. *****************************************************/
670
671static PyObject *
672bu_int(const char *p, const formatdef *f)
673{
674 long x = 0;
675 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000676 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000677 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000678 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000679 } while (--i > 0);
680 /* Extend the sign bit. */
681 if (SIZEOF_LONG > f->size)
682 x |= -(x & (1L << ((8 * f->size) - 1)));
Christian Heimes217cfd12007-12-02 14:31:20 +0000683 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000684}
685
686static PyObject *
687bu_uint(const char *p, const formatdef *f)
688{
689 unsigned long x = 0;
690 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000691 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000692 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000693 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000694 } while (--i > 0);
695 if (x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000696 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000697 return PyLong_FromUnsignedLong(x);
698}
699
700static PyObject *
701bu_longlong(const char *p, const formatdef *f)
702{
703#ifdef HAVE_LONG_LONG
704 PY_LONG_LONG x = 0;
705 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000706 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000707 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000708 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000709 } while (--i > 0);
710 /* Extend the sign bit. */
711 if (SIZEOF_LONG_LONG > f->size)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000712 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000713 if (x >= LONG_MIN && x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000714 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000715 return PyLong_FromLongLong(x);
716#else
717 return _PyLong_FromByteArray((const unsigned char *)p,
718 8,
719 0, /* little-endian */
720 1 /* signed */);
721#endif
722}
723
724static PyObject *
725bu_ulonglong(const char *p, const formatdef *f)
726{
727#ifdef HAVE_LONG_LONG
728 unsigned PY_LONG_LONG x = 0;
729 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000730 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000731 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000732 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000733 } while (--i > 0);
734 if (x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000735 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000736 return PyLong_FromUnsignedLongLong(x);
737#else
738 return _PyLong_FromByteArray((const unsigned char *)p,
739 8,
740 0, /* little-endian */
741 0 /* signed */);
742#endif
743}
744
745static PyObject *
746bu_float(const char *p, const formatdef *f)
747{
748 return unpack_float(p, 0);
749}
750
751static PyObject *
752bu_double(const char *p, const formatdef *f)
753{
754 return unpack_double(p, 0);
755}
756
Thomas Woutersb2137042007-02-01 18:02:27 +0000757static PyObject *
758bu_bool(const char *p, const formatdef *f)
759{
760 char x;
761 memcpy((char *)&x, p, sizeof x);
762 return PyBool_FromLong(x != 0);
763}
764
Thomas Wouters477c8d52006-05-27 19:21:47 +0000765static int
766bp_int(char *p, PyObject *v, const formatdef *f)
767{
768 long x;
769 Py_ssize_t i;
Mark Dickinsonae681df2009-03-21 10:26:31 +0000770 if (get_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000771 return -1;
772 i = f->size;
773 if (i != SIZEOF_LONG) {
774 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000775 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000776#if (SIZEOF_LONG != 4)
777 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000778 RANGE_ERROR(x, f, 0, 0xffffffffL);
779#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000780 }
781 do {
782 p[--i] = (char)x;
783 x >>= 8;
784 } while (i > 0);
785 return 0;
786}
787
788static int
789bp_uint(char *p, PyObject *v, const formatdef *f)
790{
791 unsigned long x;
792 Py_ssize_t i;
Mark Dickinsonae681df2009-03-21 10:26:31 +0000793 if (get_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000794 return -1;
795 i = f->size;
796 if (i != SIZEOF_LONG) {
797 unsigned long maxint = 1;
798 maxint <<= (unsigned long)(i * 8);
799 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000800 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000801 }
802 do {
803 p[--i] = (char)x;
804 x >>= 8;
805 } while (i > 0);
806 return 0;
807}
808
809static int
810bp_longlong(char *p, PyObject *v, const formatdef *f)
811{
812 int res;
813 v = get_pylong(v);
814 if (v == NULL)
815 return -1;
816 res = _PyLong_AsByteArray((PyLongObject *)v,
817 (unsigned char *)p,
818 8,
819 0, /* little_endian */
820 1 /* signed */);
821 Py_DECREF(v);
822 return res;
823}
824
825static int
826bp_ulonglong(char *p, PyObject *v, const formatdef *f)
827{
828 int res;
829 v = get_pylong(v);
830 if (v == NULL)
831 return -1;
832 res = _PyLong_AsByteArray((PyLongObject *)v,
833 (unsigned char *)p,
834 8,
835 0, /* little_endian */
836 0 /* signed */);
837 Py_DECREF(v);
838 return res;
839}
840
841static int
842bp_float(char *p, PyObject *v, const formatdef *f)
843{
844 double x = PyFloat_AsDouble(v);
845 if (x == -1 && PyErr_Occurred()) {
846 PyErr_SetString(StructError,
847 "required argument is not a float");
848 return -1;
849 }
850 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
851}
852
853static int
854bp_double(char *p, PyObject *v, const formatdef *f)
855{
856 double x = PyFloat_AsDouble(v);
857 if (x == -1 && PyErr_Occurred()) {
858 PyErr_SetString(StructError,
859 "required argument is not a float");
860 return -1;
861 }
862 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
863}
864
Thomas Woutersb2137042007-02-01 18:02:27 +0000865static int
866bp_bool(char *p, PyObject *v, const formatdef *f)
867{
868 char y;
869 y = PyObject_IsTrue(v);
870 memcpy(p, (char *)&y, sizeof y);
871 return 0;
872}
873
Thomas Wouters477c8d52006-05-27 19:21:47 +0000874static formatdef bigendian_table[] = {
875 {'x', 1, 0, NULL},
876 {'b', 1, 0, nu_byte, np_byte},
877 {'B', 1, 0, nu_ubyte, np_ubyte},
878 {'c', 1, 0, nu_char, np_char},
879 {'s', 1, 0, NULL},
880 {'p', 1, 0, NULL},
881 {'h', 2, 0, bu_int, bp_int},
882 {'H', 2, 0, bu_uint, bp_uint},
883 {'i', 4, 0, bu_int, bp_int},
884 {'I', 4, 0, bu_uint, bp_uint},
885 {'l', 4, 0, bu_int, bp_int},
886 {'L', 4, 0, bu_uint, bp_uint},
887 {'q', 8, 0, bu_longlong, bp_longlong},
888 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000889 {'?', 1, 0, bu_bool, bp_bool},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000890 {'f', 4, 0, bu_float, bp_float},
891 {'d', 8, 0, bu_double, bp_double},
892 {0}
893};
894
895/* Little-endian routines. *****************************************************/
896
897static PyObject *
898lu_int(const char *p, const formatdef *f)
899{
900 long x = 0;
901 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000902 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000903 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000904 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000905 } while (i > 0);
906 /* Extend the sign bit. */
907 if (SIZEOF_LONG > f->size)
908 x |= -(x & (1L << ((8 * f->size) - 1)));
Christian Heimes217cfd12007-12-02 14:31:20 +0000909 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000910}
911
912static PyObject *
913lu_uint(const char *p, const formatdef *f)
914{
915 unsigned long x = 0;
916 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000917 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000918 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000919 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000920 } while (i > 0);
921 if (x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000922 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000923 return PyLong_FromUnsignedLong((long)x);
924}
925
926static PyObject *
927lu_longlong(const char *p, const formatdef *f)
928{
929#ifdef HAVE_LONG_LONG
930 PY_LONG_LONG x = 0;
931 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000932 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000933 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000934 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000935 } while (i > 0);
936 /* Extend the sign bit. */
937 if (SIZEOF_LONG_LONG > f->size)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000938 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000939 if (x >= LONG_MIN && x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000940 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000941 return PyLong_FromLongLong(x);
942#else
943 return _PyLong_FromByteArray((const unsigned char *)p,
944 8,
945 1, /* little-endian */
946 1 /* signed */);
947#endif
948}
949
950static PyObject *
951lu_ulonglong(const char *p, const formatdef *f)
952{
953#ifdef HAVE_LONG_LONG
954 unsigned PY_LONG_LONG x = 0;
955 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000956 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000957 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000958 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +0000959 } while (i > 0);
960 if (x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000961 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000962 return PyLong_FromUnsignedLongLong(x);
963#else
964 return _PyLong_FromByteArray((const unsigned char *)p,
965 8,
966 1, /* little-endian */
967 0 /* signed */);
968#endif
969}
970
971static PyObject *
972lu_float(const char *p, const formatdef *f)
973{
974 return unpack_float(p, 1);
975}
976
977static PyObject *
978lu_double(const char *p, const formatdef *f)
979{
980 return unpack_double(p, 1);
981}
982
983static int
984lp_int(char *p, PyObject *v, const formatdef *f)
985{
986 long x;
987 Py_ssize_t i;
Mark Dickinsonae681df2009-03-21 10:26:31 +0000988 if (get_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000989 return -1;
990 i = f->size;
991 if (i != SIZEOF_LONG) {
992 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000993 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000994#if (SIZEOF_LONG != 4)
995 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000996 RANGE_ERROR(x, f, 0, 0xffffffffL);
997#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000998 }
999 do {
1000 *p++ = (char)x;
1001 x >>= 8;
1002 } while (--i > 0);
1003 return 0;
1004}
1005
1006static int
1007lp_uint(char *p, PyObject *v, const formatdef *f)
1008{
1009 unsigned long x;
1010 Py_ssize_t i;
Mark Dickinsonae681df2009-03-21 10:26:31 +00001011 if (get_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001012 return -1;
1013 i = f->size;
1014 if (i != SIZEOF_LONG) {
1015 unsigned long maxint = 1;
1016 maxint <<= (unsigned long)(i * 8);
1017 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001018 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001019 }
1020 do {
1021 *p++ = (char)x;
1022 x >>= 8;
1023 } while (--i > 0);
1024 return 0;
1025}
1026
1027static int
1028lp_longlong(char *p, PyObject *v, const formatdef *f)
1029{
1030 int res;
1031 v = get_pylong(v);
1032 if (v == NULL)
1033 return -1;
1034 res = _PyLong_AsByteArray((PyLongObject*)v,
1035 (unsigned char *)p,
1036 8,
1037 1, /* little_endian */
1038 1 /* signed */);
1039 Py_DECREF(v);
1040 return res;
1041}
1042
1043static int
1044lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1045{
1046 int res;
1047 v = get_pylong(v);
1048 if (v == NULL)
1049 return -1;
1050 res = _PyLong_AsByteArray((PyLongObject*)v,
1051 (unsigned char *)p,
1052 8,
1053 1, /* little_endian */
1054 0 /* signed */);
1055 Py_DECREF(v);
1056 return res;
1057}
1058
1059static int
1060lp_float(char *p, PyObject *v, const formatdef *f)
1061{
1062 double x = PyFloat_AsDouble(v);
1063 if (x == -1 && PyErr_Occurred()) {
1064 PyErr_SetString(StructError,
1065 "required argument is not a float");
1066 return -1;
1067 }
1068 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1069}
1070
1071static int
1072lp_double(char *p, PyObject *v, const formatdef *f)
1073{
1074 double x = PyFloat_AsDouble(v);
1075 if (x == -1 && PyErr_Occurred()) {
1076 PyErr_SetString(StructError,
1077 "required argument is not a float");
1078 return -1;
1079 }
1080 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1081}
1082
1083static formatdef lilendian_table[] = {
1084 {'x', 1, 0, NULL},
1085 {'b', 1, 0, nu_byte, np_byte},
1086 {'B', 1, 0, nu_ubyte, np_ubyte},
1087 {'c', 1, 0, nu_char, np_char},
1088 {'s', 1, 0, NULL},
1089 {'p', 1, 0, NULL},
1090 {'h', 2, 0, lu_int, lp_int},
1091 {'H', 2, 0, lu_uint, lp_uint},
1092 {'i', 4, 0, lu_int, lp_int},
1093 {'I', 4, 0, lu_uint, lp_uint},
1094 {'l', 4, 0, lu_int, lp_int},
1095 {'L', 4, 0, lu_uint, lp_uint},
1096 {'q', 8, 0, lu_longlong, lp_longlong},
1097 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001098 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
Thomas Woutersb2137042007-02-01 18:02:27 +00001099 but potentially different from native rep -- reuse bx_bool funcs. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001100 {'f', 4, 0, lu_float, lp_float},
1101 {'d', 8, 0, lu_double, lp_double},
1102 {0}
1103};
1104
1105
1106static const formatdef *
1107whichtable(char **pfmt)
1108{
1109 const char *fmt = (*pfmt)++; /* May be backed out of later */
1110 switch (*fmt) {
1111 case '<':
1112 return lilendian_table;
1113 case '>':
1114 case '!': /* Network byte order is big-endian */
1115 return bigendian_table;
1116 case '=': { /* Host byte order -- different from native in aligment! */
1117 int n = 1;
1118 char *p = (char *) &n;
1119 if (*p == 1)
1120 return lilendian_table;
1121 else
1122 return bigendian_table;
1123 }
1124 default:
1125 --*pfmt; /* Back out of pointer increment */
1126 /* Fall through */
1127 case '@':
1128 return native_table;
1129 }
1130}
1131
1132
1133/* Get the table entry for a format code */
1134
1135static const formatdef *
1136getentry(int c, const formatdef *f)
1137{
1138 for (; f->format != '\0'; f++) {
1139 if (f->format == c) {
1140 return f;
1141 }
1142 }
1143 PyErr_SetString(StructError, "bad char in struct format");
1144 return NULL;
1145}
1146
1147
1148/* Align a size according to a format code */
1149
1150static int
1151align(Py_ssize_t size, char c, const formatdef *e)
1152{
1153 if (e->format == c) {
1154 if (e->alignment) {
1155 size = ((size + e->alignment - 1)
1156 / e->alignment)
1157 * e->alignment;
1158 }
1159 }
1160 return size;
1161}
1162
1163
1164/* calculate the size of a format string */
1165
1166static int
1167prepare_s(PyStructObject *self)
1168{
1169 const formatdef *f;
1170 const formatdef *e;
1171 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001172
Thomas Wouters477c8d52006-05-27 19:21:47 +00001173 const char *s;
1174 const char *fmt;
1175 char c;
1176 Py_ssize_t size, len, num, itemsize, x;
1177
Christian Heimes72b710a2008-05-26 13:28:38 +00001178 fmt = PyBytes_AS_STRING(self->s_format);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001179
1180 f = whichtable((char **)&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001181
Thomas Wouters477c8d52006-05-27 19:21:47 +00001182 s = fmt;
1183 size = 0;
1184 len = 0;
1185 while ((c = *s++) != '\0') {
1186 if (isspace(Py_CHARMASK(c)))
1187 continue;
1188 if ('0' <= c && c <= '9') {
1189 num = c - '0';
1190 while ('0' <= (c = *s++) && c <= '9') {
1191 x = num*10 + (c - '0');
1192 if (x/10 != num) {
1193 PyErr_SetString(
1194 StructError,
1195 "overflow in item count");
1196 return -1;
1197 }
1198 num = x;
1199 }
1200 if (c == '\0')
1201 break;
1202 }
1203 else
1204 num = 1;
1205
1206 e = getentry(c, f);
1207 if (e == NULL)
1208 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001209
Thomas Wouters477c8d52006-05-27 19:21:47 +00001210 switch (c) {
1211 case 's': /* fall through */
1212 case 'p': len++; break;
1213 case 'x': break;
1214 default: len += num; break;
1215 }
1216
1217 itemsize = e->size;
1218 size = align(size, c, e);
1219 x = num * itemsize;
1220 size += x;
1221 if (x/itemsize != num || size < 0) {
1222 PyErr_SetString(StructError,
1223 "total struct size too long");
1224 return -1;
1225 }
1226 }
1227
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +00001228 /* check for overflow */
1229 if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {
1230 PyErr_NoMemory();
1231 return -1;
1232 }
1233
Thomas Wouters477c8d52006-05-27 19:21:47 +00001234 self->s_size = size;
1235 self->s_len = len;
1236 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1237 if (codes == NULL) {
1238 PyErr_NoMemory();
1239 return -1;
1240 }
1241 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001242
Thomas Wouters477c8d52006-05-27 19:21:47 +00001243 s = fmt;
1244 size = 0;
1245 while ((c = *s++) != '\0') {
1246 if (isspace(Py_CHARMASK(c)))
1247 continue;
1248 if ('0' <= c && c <= '9') {
1249 num = c - '0';
1250 while ('0' <= (c = *s++) && c <= '9')
1251 num = num*10 + (c - '0');
1252 if (c == '\0')
1253 break;
1254 }
1255 else
1256 num = 1;
1257
1258 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001259
Thomas Wouters477c8d52006-05-27 19:21:47 +00001260 size = align(size, c, e);
1261 if (c == 's' || c == 'p') {
1262 codes->offset = size;
1263 codes->size = num;
1264 codes->fmtdef = e;
1265 codes++;
1266 size += num;
1267 } else if (c == 'x') {
1268 size += num;
1269 } else {
1270 while (--num >= 0) {
1271 codes->offset = size;
1272 codes->size = e->size;
1273 codes->fmtdef = e;
1274 codes++;
1275 size += e->size;
1276 }
1277 }
1278 }
1279 codes->fmtdef = NULL;
1280 codes->offset = size;
1281 codes->size = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001282
Thomas Wouters477c8d52006-05-27 19:21:47 +00001283 return 0;
1284}
1285
1286static PyObject *
1287s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1288{
1289 PyObject *self;
1290
1291 assert(type != NULL && type->tp_alloc != NULL);
1292
1293 self = type->tp_alloc(type, 0);
1294 if (self != NULL) {
1295 PyStructObject *s = (PyStructObject*)self;
1296 Py_INCREF(Py_None);
1297 s->s_format = Py_None;
1298 s->s_codes = NULL;
1299 s->s_size = -1;
1300 s->s_len = -1;
1301 }
1302 return self;
1303}
1304
1305static int
1306s_init(PyObject *self, PyObject *args, PyObject *kwds)
1307{
1308 PyStructObject *soself = (PyStructObject *)self;
1309 PyObject *o_format = NULL;
1310 int ret = 0;
1311 static char *kwlist[] = {"format", 0};
1312
1313 assert(PyStruct_Check(self));
1314
Christian Heimesa34706f2008-01-04 03:06:10 +00001315 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Struct", kwlist,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001316 &o_format))
1317 return -1;
1318
Christian Heimesa34706f2008-01-04 03:06:10 +00001319 if (PyUnicode_Check(o_format)) {
1320 o_format = PyUnicode_AsASCIIString(o_format);
1321 if (o_format == NULL)
1322 return -1;
1323 }
1324 /* XXX support buffer interface, too */
1325 else {
1326 Py_INCREF(o_format);
1327 }
1328
Christian Heimes72b710a2008-05-26 13:28:38 +00001329 if (!PyBytes_Check(o_format)) {
Christian Heimesa34706f2008-01-04 03:06:10 +00001330 Py_DECREF(o_format);
1331 PyErr_Format(PyExc_TypeError,
1332 "Struct() argument 1 must be bytes, not %.200s",
1333 Py_TYPE(o_format)->tp_name);
1334 return -1;
1335 }
1336
Christian Heimes18c66892008-02-17 13:31:39 +00001337 Py_CLEAR(soself->s_format);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001338 soself->s_format = o_format;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001339
Thomas Wouters477c8d52006-05-27 19:21:47 +00001340 ret = prepare_s(soself);
1341 return ret;
1342}
1343
1344static void
1345s_dealloc(PyStructObject *s)
1346{
1347 if (s->weakreflist != NULL)
1348 PyObject_ClearWeakRefs((PyObject *)s);
1349 if (s->s_codes != NULL) {
1350 PyMem_FREE(s->s_codes);
1351 }
1352 Py_XDECREF(s->s_format);
Christian Heimes90aa7642007-12-19 02:45:37 +00001353 Py_TYPE(s)->tp_free((PyObject *)s);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001354}
1355
1356static PyObject *
1357s_unpack_internal(PyStructObject *soself, char *startfrom) {
1358 formatcode *code;
1359 Py_ssize_t i = 0;
1360 PyObject *result = PyTuple_New(soself->s_len);
1361 if (result == NULL)
1362 return NULL;
1363
1364 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1365 PyObject *v;
1366 const formatdef *e = code->fmtdef;
1367 const char *res = startfrom + code->offset;
1368 if (e->format == 's') {
Christian Heimes72b710a2008-05-26 13:28:38 +00001369 v = PyBytes_FromStringAndSize(res, code->size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001370 } else if (e->format == 'p') {
1371 Py_ssize_t n = *(unsigned char*)res;
1372 if (n >= code->size)
1373 n = code->size - 1;
Christian Heimes72b710a2008-05-26 13:28:38 +00001374 v = PyBytes_FromStringAndSize(res + 1, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001375 } else {
1376 v = e->unpack(res, e);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001377 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001378 if (v == NULL)
1379 goto fail;
1380 PyTuple_SET_ITEM(result, i++, v);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001381 }
1382
1383 return result;
1384fail:
1385 Py_DECREF(result);
1386 return NULL;
1387}
1388
1389
1390PyDoc_STRVAR(s_unpack__doc__,
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001391"S.unpack(buffer) -> (v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001392\n\
1393Return tuple containing values unpacked according to this Struct's format.\n\
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001394Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001395strings.");
1396
1397static PyObject *
Guido van Rossum98297ee2007-11-06 21:34:58 +00001398s_unpack(PyObject *self, PyObject *input)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001399{
Guido van Rossum98297ee2007-11-06 21:34:58 +00001400 Py_buffer vbuf;
1401 PyObject *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001402 PyStructObject *soself = (PyStructObject *)self;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001403
Thomas Wouters477c8d52006-05-27 19:21:47 +00001404 assert(PyStruct_Check(self));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001405 assert(soself->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001406 if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001407 return NULL;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001408 if (vbuf.len != soself->s_size) {
1409 PyErr_Format(StructError,
1410 "unpack requires a bytes argument of length %zd",
1411 soself->s_size);
Martin v. Löwis423be952008-08-13 15:53:07 +00001412 PyBuffer_Release(&vbuf);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001413 return NULL;
1414 }
1415 result = s_unpack_internal(soself, vbuf.buf);
Martin v. Löwis423be952008-08-13 15:53:07 +00001416 PyBuffer_Release(&vbuf);
Guido van Rossumd8faa362007-04-27 19:54:29 +00001417 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001418}
1419
1420PyDoc_STRVAR(s_unpack_from__doc__,
1421"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1422\n\
1423Return tuple containing values unpacked according to this Struct's format.\n\
1424Unlike unpack, unpack_from can unpack values from any object supporting\n\
1425the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1426See struct.__doc__ for more on format strings.");
1427
1428static PyObject *
1429s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1430{
1431 static char *kwlist[] = {"buffer", "offset", 0};
Guido van Rossum98297ee2007-11-06 21:34:58 +00001432
1433 PyObject *input;
1434 Py_ssize_t offset = 0;
1435 Py_buffer vbuf;
1436 PyObject *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001437 PyStructObject *soself = (PyStructObject *)self;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001438
Thomas Wouters477c8d52006-05-27 19:21:47 +00001439 assert(PyStruct_Check(self));
1440 assert(soself->s_codes != NULL);
1441
Guido van Rossum98297ee2007-11-06 21:34:58 +00001442 if (!PyArg_ParseTupleAndKeywords(args, kwds,
1443 "O|n:unpack_from", kwlist,
1444 &input, &offset))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001445 return NULL;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001446 if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001447 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001448 if (offset < 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001449 offset += vbuf.len;
1450 if (offset < 0 || vbuf.len - offset < soself->s_size) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001451 PyErr_Format(StructError,
1452 "unpack_from requires a buffer of at least %zd bytes",
1453 soself->s_size);
Martin v. Löwis423be952008-08-13 15:53:07 +00001454 PyBuffer_Release(&vbuf);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001455 return NULL;
1456 }
Guido van Rossum98297ee2007-11-06 21:34:58 +00001457 result = s_unpack_internal(soself, (char*)vbuf.buf + offset);
Martin v. Löwis423be952008-08-13 15:53:07 +00001458 PyBuffer_Release(&vbuf);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001459 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001460}
1461
1462
1463/*
1464 * Guts of the pack function.
1465 *
1466 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1467 * argument for where to start processing the arguments for packing, and a
1468 * character buffer for writing the packed string. The caller must insure
1469 * that the buffer may contain the required length for packing the arguments.
1470 * 0 is returned on success, 1 is returned if there is an error.
1471 *
1472 */
1473static int
1474s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1475{
1476 formatcode *code;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001477 /* XXX(nnorwitz): why does i need to be a local? can we use
1478 the offset parameter or do we need the wider width? */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001479 Py_ssize_t i;
1480
1481 memset(buf, '\0', soself->s_size);
1482 i = offset;
1483 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1484 Py_ssize_t n;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001485 PyObject *v = PyTuple_GET_ITEM(args, i++);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001486 const formatdef *e = code->fmtdef;
1487 char *res = buf + code->offset;
1488 if (e->format == 's') {
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001489 int isstring;
1490 void *p;
1491 if (PyUnicode_Check(v)) {
1492 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
1493 if (v == NULL)
1494 return -1;
1495 }
Christian Heimes72b710a2008-05-26 13:28:38 +00001496 isstring = PyBytes_Check(v);
Christian Heimes9c4756e2008-05-26 13:22:05 +00001497 if (!isstring && !PyByteArray_Check(v)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001498 PyErr_SetString(StructError,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001499 "argument for 's' must be a bytes or string");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001500 return -1;
1501 }
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001502 if (isstring) {
Christian Heimes72b710a2008-05-26 13:28:38 +00001503 n = PyBytes_GET_SIZE(v);
1504 p = PyBytes_AS_STRING(v);
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001505 }
1506 else {
Christian Heimes9c4756e2008-05-26 13:22:05 +00001507 n = PyByteArray_GET_SIZE(v);
1508 p = PyByteArray_AS_STRING(v);
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001509 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510 if (n > code->size)
1511 n = code->size;
1512 if (n > 0)
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001513 memcpy(res, p, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001514 } else if (e->format == 'p') {
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001515 int isstring;
1516 void *p;
1517 if (PyUnicode_Check(v)) {
1518 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
1519 if (v == NULL)
1520 return -1;
1521 }
Christian Heimes72b710a2008-05-26 13:28:38 +00001522 isstring = PyBytes_Check(v);
Christian Heimes9c4756e2008-05-26 13:22:05 +00001523 if (!isstring && !PyByteArray_Check(v)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001524 PyErr_SetString(StructError,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001525 "argument for 'p' must be a bytes or string");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001526 return -1;
1527 }
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001528 if (isstring) {
Christian Heimes72b710a2008-05-26 13:28:38 +00001529 n = PyBytes_GET_SIZE(v);
1530 p = PyBytes_AS_STRING(v);
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001531 }
1532 else {
Christian Heimes9c4756e2008-05-26 13:22:05 +00001533 n = PyByteArray_GET_SIZE(v);
1534 p = PyByteArray_AS_STRING(v);
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001535 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001536 if (n > (code->size - 1))
1537 n = code->size - 1;
1538 if (n > 0)
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001539 memcpy(res + 1, p, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001540 if (n > 255)
1541 n = 255;
1542 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1543 } else {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001544 if (e->pack(res, v, e) < 0) {
1545 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1546 PyErr_SetString(StructError,
1547 "long too large to convert to int");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001548 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001549 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001550 }
1551 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001552
Thomas Wouters477c8d52006-05-27 19:21:47 +00001553 /* Success */
1554 return 0;
1555}
1556
1557
1558PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001559"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001560\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001561Return a bytes containing values v1, v2, ... packed according to this\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001562Struct's format. See struct.__doc__ for more on format strings.");
1563
1564static PyObject *
1565s_pack(PyObject *self, PyObject *args)
1566{
1567 PyStructObject *soself;
1568 PyObject *result;
1569
1570 /* Validate arguments. */
1571 soself = (PyStructObject *)self;
1572 assert(PyStruct_Check(self));
1573 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001574 if (PyTuple_GET_SIZE(args) != soself->s_len)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001575 {
1576 PyErr_Format(StructError,
1577 "pack requires exactly %zd arguments", soself->s_len);
1578 return NULL;
1579 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001580
Thomas Wouters477c8d52006-05-27 19:21:47 +00001581 /* Allocate a new string */
Christian Heimes72b710a2008-05-26 13:28:38 +00001582 result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001583 if (result == NULL)
1584 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001585
Thomas Wouters477c8d52006-05-27 19:21:47 +00001586 /* Call the guts */
Christian Heimes72b710a2008-05-26 13:28:38 +00001587 if ( s_pack_internal(soself, args, 0, PyBytes_AS_STRING(result)) != 0 ) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001588 Py_DECREF(result);
1589 return NULL;
1590 }
1591
1592 return result;
1593}
1594
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001595PyDoc_STRVAR(s_pack_into__doc__,
1596"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001597\n\
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001598Pack the values v1, v2, ... according to this Struct's format, write \n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001599the packed bytes into the writable buffer buf starting at offset. Note\n\
1600that the offset is not an optional argument. See struct.__doc__ for \n\
1601more on format strings.");
1602
1603static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001604s_pack_into(PyObject *self, PyObject *args)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001605{
1606 PyStructObject *soself;
1607 char *buffer;
1608 Py_ssize_t buffer_len, offset;
1609
1610 /* Validate arguments. +1 is for the first arg as buffer. */
1611 soself = (PyStructObject *)self;
1612 assert(PyStruct_Check(self));
1613 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001614 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001615 {
1616 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001617 "pack_into requires exactly %zd arguments",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001618 (soself->s_len + 2));
1619 return NULL;
1620 }
1621
1622 /* Extract a writable memory buffer from the first argument */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001623 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1624 (void**)&buffer, &buffer_len) == -1 ) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001625 return NULL;
1626 }
1627 assert( buffer_len >= 0 );
1628
1629 /* Extract the offset from the first argument */
Georg Brandl75c3d6f2009-02-13 11:01:07 +00001630 offset = PyNumber_AsSsize_t(PyTuple_GET_ITEM(args, 1), PyExc_IndexError);
Benjamin Petersona8a93042008-09-30 02:18:09 +00001631 if (offset == -1 && PyErr_Occurred())
1632 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001633
1634 /* Support negative offsets. */
1635 if (offset < 0)
1636 offset += buffer_len;
1637
1638 /* Check boundaries */
1639 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1640 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001641 "pack_into requires a buffer of at least %zd bytes",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001642 soself->s_size);
1643 return NULL;
1644 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001645
Thomas Wouters477c8d52006-05-27 19:21:47 +00001646 /* Call the guts */
1647 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1648 return NULL;
1649 }
1650
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001651 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001652}
1653
1654static PyObject *
1655s_get_format(PyStructObject *self, void *unused)
1656{
1657 Py_INCREF(self->s_format);
1658 return self->s_format;
1659}
1660
1661static PyObject *
1662s_get_size(PyStructObject *self, void *unused)
1663{
Christian Heimes217cfd12007-12-02 14:31:20 +00001664 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001665}
1666
1667/* List of functions */
1668
1669static struct PyMethodDef s_methods[] = {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001670 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1671 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1672 {"unpack", s_unpack, METH_O, s_unpack__doc__},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00001673 {"unpack_from", (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001674 s_unpack_from__doc__},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001675 {NULL, NULL} /* sentinel */
1676};
1677
1678PyDoc_STRVAR(s__doc__, "Compiled struct object");
1679
1680#define OFF(x) offsetof(PyStructObject, x)
1681
1682static PyGetSetDef s_getsetlist[] = {
1683 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1684 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1685 {NULL} /* sentinel */
1686};
1687
1688static
1689PyTypeObject PyStructType = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001690 PyVarObject_HEAD_INIT(NULL, 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001691 "Struct",
1692 sizeof(PyStructObject),
1693 0,
1694 (destructor)s_dealloc, /* tp_dealloc */
1695 0, /* tp_print */
1696 0, /* tp_getattr */
1697 0, /* tp_setattr */
Mark Dickinsone94c6792009-02-02 20:36:42 +00001698 0, /* tp_reserved */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001699 0, /* tp_repr */
1700 0, /* tp_as_number */
1701 0, /* tp_as_sequence */
1702 0, /* tp_as_mapping */
1703 0, /* tp_hash */
1704 0, /* tp_call */
1705 0, /* tp_str */
1706 PyObject_GenericGetAttr, /* tp_getattro */
1707 PyObject_GenericSetAttr, /* tp_setattro */
1708 0, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +00001709 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001710 s__doc__, /* tp_doc */
1711 0, /* tp_traverse */
1712 0, /* tp_clear */
1713 0, /* tp_richcompare */
1714 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1715 0, /* tp_iter */
1716 0, /* tp_iternext */
1717 s_methods, /* tp_methods */
1718 NULL, /* tp_members */
1719 s_getsetlist, /* tp_getset */
1720 0, /* tp_base */
1721 0, /* tp_dict */
1722 0, /* tp_descr_get */
1723 0, /* tp_descr_set */
1724 0, /* tp_dictoffset */
1725 s_init, /* tp_init */
1726 PyType_GenericAlloc,/* tp_alloc */
1727 s_new, /* tp_new */
1728 PyObject_Del, /* tp_free */
1729};
1730
Christian Heimesa34706f2008-01-04 03:06:10 +00001731
1732/* ---- Standalone functions ---- */
1733
1734#define MAXCACHE 100
1735static PyObject *cache = NULL;
1736
1737static PyObject *
1738cache_struct(PyObject *fmt)
1739{
1740 PyObject * s_object;
1741
1742 if (cache == NULL) {
1743 cache = PyDict_New();
1744 if (cache == NULL)
1745 return NULL;
1746 }
1747
1748 s_object = PyDict_GetItem(cache, fmt);
1749 if (s_object != NULL) {
1750 Py_INCREF(s_object);
1751 return s_object;
1752 }
1753
1754 s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
1755 if (s_object != NULL) {
1756 if (PyDict_Size(cache) >= MAXCACHE)
1757 PyDict_Clear(cache);
1758 /* Attempt to cache the result */
1759 if (PyDict_SetItem(cache, fmt, s_object) == -1)
1760 PyErr_Clear();
1761 }
1762 return s_object;
1763}
1764
1765PyDoc_STRVAR(clearcache_doc,
1766"Clear the internal cache.");
1767
1768static PyObject *
1769clearcache(PyObject *self)
1770{
Christian Heimes679db4a2008-01-18 09:56:22 +00001771 Py_CLEAR(cache);
Christian Heimesa34706f2008-01-04 03:06:10 +00001772 Py_RETURN_NONE;
1773}
1774
1775PyDoc_STRVAR(calcsize_doc,
1776"Return size of C struct described by format string fmt.");
1777
1778static PyObject *
1779calcsize(PyObject *self, PyObject *fmt)
1780{
1781 Py_ssize_t n;
1782 PyObject *s_object = cache_struct(fmt);
1783 if (s_object == NULL)
1784 return NULL;
1785 n = ((PyStructObject *)s_object)->s_size;
1786 Py_DECREF(s_object);
1787 return PyLong_FromSsize_t(n);
1788}
1789
1790PyDoc_STRVAR(pack_doc,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001791"Return bytes containing values v1, v2, ... packed according to fmt.");
Christian Heimesa34706f2008-01-04 03:06:10 +00001792
1793static PyObject *
1794pack(PyObject *self, PyObject *args)
1795{
1796 PyObject *s_object, *fmt, *newargs, *result;
1797 Py_ssize_t n = PyTuple_GET_SIZE(args);
1798
1799 if (n == 0) {
1800 PyErr_SetString(PyExc_TypeError, "missing format argument");
1801 return NULL;
1802 }
1803 fmt = PyTuple_GET_ITEM(args, 0);
1804 newargs = PyTuple_GetSlice(args, 1, n);
1805 if (newargs == NULL)
1806 return NULL;
1807
1808 s_object = cache_struct(fmt);
1809 if (s_object == NULL) {
1810 Py_DECREF(newargs);
1811 return NULL;
1812 }
1813 result = s_pack(s_object, newargs);
1814 Py_DECREF(newargs);
1815 Py_DECREF(s_object);
1816 return result;
1817}
1818
1819PyDoc_STRVAR(pack_into_doc,
1820"Pack the values v1, v2, ... according to fmt.\n\
1821Write the packed bytes into the writable buffer buf starting at offset.");
1822
1823static PyObject *
1824pack_into(PyObject *self, PyObject *args)
1825{
1826 PyObject *s_object, *fmt, *newargs, *result;
1827 Py_ssize_t n = PyTuple_GET_SIZE(args);
1828
1829 if (n == 0) {
1830 PyErr_SetString(PyExc_TypeError, "missing format argument");
1831 return NULL;
1832 }
1833 fmt = PyTuple_GET_ITEM(args, 0);
1834 newargs = PyTuple_GetSlice(args, 1, n);
1835 if (newargs == NULL)
1836 return NULL;
1837
1838 s_object = cache_struct(fmt);
1839 if (s_object == NULL) {
1840 Py_DECREF(newargs);
1841 return NULL;
1842 }
1843 result = s_pack_into(s_object, newargs);
1844 Py_DECREF(newargs);
1845 Py_DECREF(s_object);
1846 return result;
1847}
1848
1849PyDoc_STRVAR(unpack_doc,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001850"Unpack the bytes containing packed C structure data, according to fmt.\n\
1851Requires len(bytes) == calcsize(fmt).");
Christian Heimesa34706f2008-01-04 03:06:10 +00001852
1853static PyObject *
1854unpack(PyObject *self, PyObject *args)
1855{
1856 PyObject *s_object, *fmt, *inputstr, *result;
1857
1858 if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr))
1859 return NULL;
1860
1861 s_object = cache_struct(fmt);
1862 if (s_object == NULL)
1863 return NULL;
1864 result = s_unpack(s_object, inputstr);
1865 Py_DECREF(s_object);
1866 return result;
1867}
1868
1869PyDoc_STRVAR(unpack_from_doc,
1870"Unpack the buffer, containing packed C structure data, according to\n\
1871fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).");
1872
1873static PyObject *
1874unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1875{
1876 PyObject *s_object, *fmt, *newargs, *result;
1877 Py_ssize_t n = PyTuple_GET_SIZE(args);
1878
1879 if (n == 0) {
1880 PyErr_SetString(PyExc_TypeError, "missing format argument");
1881 return NULL;
1882 }
1883 fmt = PyTuple_GET_ITEM(args, 0);
1884 newargs = PyTuple_GetSlice(args, 1, n);
1885 if (newargs == NULL)
1886 return NULL;
1887
1888 s_object = cache_struct(fmt);
1889 if (s_object == NULL) {
1890 Py_DECREF(newargs);
1891 return NULL;
1892 }
1893 result = s_unpack_from(s_object, newargs, kwds);
1894 Py_DECREF(newargs);
1895 Py_DECREF(s_object);
1896 return result;
1897}
1898
1899static struct PyMethodDef module_functions[] = {
1900 {"_clearcache", (PyCFunction)clearcache, METH_NOARGS, clearcache_doc},
1901 {"calcsize", calcsize, METH_O, calcsize_doc},
1902 {"pack", pack, METH_VARARGS, pack_doc},
1903 {"pack_into", pack_into, METH_VARARGS, pack_into_doc},
1904 {"unpack", unpack, METH_VARARGS, unpack_doc},
1905 {"unpack_from", (PyCFunction)unpack_from,
1906 METH_VARARGS|METH_KEYWORDS, unpack_from_doc},
1907 {NULL, NULL} /* sentinel */
1908};
1909
1910
Thomas Wouters477c8d52006-05-27 19:21:47 +00001911/* Module initialization */
1912
Christian Heimesa34706f2008-01-04 03:06:10 +00001913PyDoc_STRVAR(module_doc,
1914"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001915Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00001916and also as format strings (explained below) to describe the layout of data\n\
1917in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00001918\n\
1919The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00001920 @: native order, size & alignment (default)\n\
1921 =: native order, std. size & alignment\n\
1922 <: little-endian, std. size & alignment\n\
1923 >: big-endian, std. size & alignment\n\
1924 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00001925\n\
1926The remaining chars indicate types of args and must match exactly;\n\
1927these can be preceded by a decimal repeat count:\n\
1928 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00001929 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00001930 h:short; H:unsigned short; i:int; I:unsigned int;\n\
1931 l:long; L:unsigned long; f:float; d:double.\n\
1932Special cases (preceding decimal count indicates length):\n\
1933 s:string (array of char); p: pascal string (with count byte).\n\
1934Special case (only available in native format):\n\
1935 P:an integer type that is wide enough to hold a pointer.\n\
1936Special case (not in native mode unless 'long long' in platform C):\n\
1937 q:long long; Q:unsigned long long\n\
1938Whitespace between formats is ignored.\n\
1939\n\
1940The variable struct.error is an exception raised on errors.\n");
1941
Martin v. Löwis1a214512008-06-11 05:26:20 +00001942
1943static struct PyModuleDef _structmodule = {
1944 PyModuleDef_HEAD_INIT,
1945 "_struct",
1946 module_doc,
1947 -1,
1948 module_functions,
1949 NULL,
1950 NULL,
1951 NULL,
1952 NULL
1953};
1954
Thomas Wouters477c8d52006-05-27 19:21:47 +00001955PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001956PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001957{
Christian Heimesa34706f2008-01-04 03:06:10 +00001958 PyObject *ver, *m;
1959
Mark Dickinsonea835e72009-04-19 20:40:33 +00001960 ver = PyBytes_FromString("0.3");
Christian Heimesa34706f2008-01-04 03:06:10 +00001961 if (ver == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001962 return NULL;
Christian Heimesa34706f2008-01-04 03:06:10 +00001963
Martin v. Löwis1a214512008-06-11 05:26:20 +00001964 m = PyModule_Create(&_structmodule);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001965 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001966 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001967
Christian Heimes90aa7642007-12-19 02:45:37 +00001968 Py_TYPE(&PyStructType) = &PyType_Type;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001969 if (PyType_Ready(&PyStructType) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00001970 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001971
1972 /* Check endian and swap in faster functions */
1973 {
1974 int one = 1;
1975 formatdef *native = native_table;
1976 formatdef *other, *ptr;
1977 if ((int)*(unsigned char*)&one)
1978 other = lilendian_table;
1979 else
1980 other = bigendian_table;
1981 /* Scan through the native table, find a matching
1982 entry in the endian table and swap in the
1983 native implementations whenever possible
1984 (64-bit platforms may not have "standard" sizes) */
1985 while (native->format != '\0' && other->format != '\0') {
1986 ptr = other;
1987 while (ptr->format != '\0') {
1988 if (ptr->format == native->format) {
1989 /* Match faster when formats are
1990 listed in the same order */
1991 if (ptr == other)
1992 other++;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001993 /* Only use the trick if the
Thomas Wouters477c8d52006-05-27 19:21:47 +00001994 size matches */
1995 if (ptr->size != native->size)
1996 break;
1997 /* Skip float and double, could be
1998 "unknown" float format */
1999 if (ptr->format == 'd' || ptr->format == 'f')
2000 break;
2001 ptr->pack = native->pack;
2002 ptr->unpack = native->unpack;
2003 break;
2004 }
2005 ptr++;
2006 }
2007 native++;
2008 }
2009 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002010
Thomas Wouters477c8d52006-05-27 19:21:47 +00002011 /* Add some symbolic constants to the module */
2012 if (StructError == NULL) {
2013 StructError = PyErr_NewException("struct.error", NULL, NULL);
2014 if (StructError == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002015 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002016 }
2017
2018 Py_INCREF(StructError);
2019 PyModule_AddObject(m, "error", StructError);
2020
2021 Py_INCREF((PyObject*)&PyStructType);
2022 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002023
Christian Heimesa34706f2008-01-04 03:06:10 +00002024 PyModule_AddObject(m, "__version__", ver);
2025
Martin v. Löwis1a214512008-06-11 05:26:20 +00002026 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002027}