blob: 0f070b318d368ca023199cf2c8a096eff804646b [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 {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000017 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 *);
Thomas Wouters477c8d52006-05-27 19:21:47 +000024} formatdef;
25
26typedef struct _formatcode {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000027 const struct _formatdef *fmtdef;
28 Py_ssize_t offset;
29 Py_ssize_t size;
Thomas Wouters477c8d52006-05-27 19:21:47 +000030} formatcode;
31
32/* Struct object interface */
33
34typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000035 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 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000041} 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{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000098 assert(v != NULL);
99 if (!PyLong_Check(v)) {
100 /* 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 }
106 else {
107 PyErr_SetString(StructError,
108 "required argument is not an integer");
109 return NULL;
110 }
111 }
112 else
113 Py_INCREF(v);
Mark Dickinsonea835e72009-04-19 20:40:33 +0000114
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 assert(PyLong_Check(v));
116 return v;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000117}
118
Mark Dickinsonea835e72009-04-19 20:40:33 +0000119/* Helper routine to get a C long and raise the appropriate error if it isn't
120 one */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000121
122static int
123get_long(PyObject *v, long *p)
124{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 v = get_pylong(v);
128 if (v == NULL)
129 return -1;
130 assert(PyLong_Check(v));
131 x = PyLong_AsLong(v);
132 Py_DECREF(v);
133 if (x == (long)-1 && PyErr_Occurred()) {
134 if (PyErr_ExceptionMatches(PyExc_OverflowError))
135 PyErr_SetString(StructError,
136 "argument out of range");
137 return -1;
138 }
139 *p = x;
140 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000141}
142
143
144/* Same, but handling unsigned long */
145
146static int
147get_ulong(PyObject *v, unsigned long *p)
148{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 unsigned long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 v = get_pylong(v);
152 if (v == NULL)
153 return -1;
154 assert(PyLong_Check(v));
155 x = PyLong_AsUnsignedLong(v);
156 Py_DECREF(v);
157 if (x == (unsigned long)-1 && PyErr_Occurred()) {
158 if (PyErr_ExceptionMatches(PyExc_OverflowError))
159 PyErr_SetString(StructError,
160 "argument out of range");
161 return -1;
162 }
163 *p = x;
164 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000165}
166
167#ifdef HAVE_LONG_LONG
168
169/* Same, but handling native long long. */
170
171static int
172get_longlong(PyObject *v, PY_LONG_LONG *p)
173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 PY_LONG_LONG x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000175
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 v = get_pylong(v);
177 if (v == NULL)
178 return -1;
179 assert(PyLong_Check(v));
180 x = PyLong_AsLongLong(v);
181 Py_DECREF(v);
182 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred()) {
183 if (PyErr_ExceptionMatches(PyExc_OverflowError))
184 PyErr_SetString(StructError,
185 "argument out of range");
186 return -1;
187 }
188 *p = x;
189 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000190}
191
192/* Same, but handling native unsigned long long. */
193
194static int
195get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 unsigned PY_LONG_LONG x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 v = get_pylong(v);
200 if (v == NULL)
201 return -1;
202 assert(PyLong_Check(v));
203 x = PyLong_AsUnsignedLongLong(v);
204 Py_DECREF(v);
205 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred()) {
206 if (PyErr_ExceptionMatches(PyExc_OverflowError))
207 PyErr_SetString(StructError,
208 "argument out of range");
209 return -1;
210 }
211 *p = x;
212 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000213}
214
215#endif
216
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000217
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000218#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
219
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000220
Thomas Wouters477c8d52006-05-27 19:21:47 +0000221/* Floating point helpers */
222
223static PyObject *
224unpack_float(const char *p, /* start of 4-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000226{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 x = _PyFloat_Unpack4((unsigned char *)p, le);
230 if (x == -1.0 && PyErr_Occurred())
231 return NULL;
232 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000233}
234
235static PyObject *
236unpack_double(const char *p, /* start of 8-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000238{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000239 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000240
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000241 x = _PyFloat_Unpack8((unsigned char *)p, le);
242 if (x == -1.0 && PyErr_Occurred())
243 return NULL;
244 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000245}
246
247/* Helper to format the range error exceptions */
248static int
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000249_range_error(const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000250{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 /* ulargest is the largest unsigned value with f->size bytes.
252 * Note that the simpler:
253 * ((size_t)1 << (f->size * 8)) - 1
254 * doesn't work when f->size == sizeof(size_t) because C doesn't
255 * define what happens when a left shift count is >= the number of
256 * bits in the integer being shifted; e.g., on some boxes it doesn't
257 * shift at all when they're equal.
258 */
259 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
260 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
261 if (is_unsigned)
262 PyErr_Format(StructError,
263 "'%c' format requires 0 <= number <= %zu",
264 f->format,
265 ulargest);
266 else {
267 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
268 PyErr_Format(StructError,
269 "'%c' format requires %zd <= number <= %zd",
270 f->format,
271 ~ largest,
272 largest);
273 }
Mark Dickinsonae681df2009-03-21 10:26:31 +0000274
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000275 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000276}
277
278
279
280/* A large number of small routines follow, with names of the form
281
282 [bln][up]_TYPE
283
284 [bln] distiguishes among big-endian, little-endian and native.
285 [pu] distiguishes between pack (to struct) and unpack (from struct).
286 TYPE is one of char, byte, ubyte, etc.
287*/
288
289/* Native mode routines. ****************************************************/
290/* NOTE:
291 In all n[up]_<type> routines handling types larger than 1 byte, there is
292 *no* guarantee that the p pointer is properly aligned for each type,
293 therefore memcpy is called. An intermediate variable is used to
294 compensate for big-endian architectures.
295 Normally both the intermediate variable and the memcpy call will be
296 skipped by C optimisation in little-endian architectures (gcc >= 2.91
297 does this). */
298
299static PyObject *
300nu_char(const char *p, const formatdef *f)
301{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 return PyBytes_FromStringAndSize(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000303}
304
305static PyObject *
306nu_byte(const char *p, const formatdef *f)
307{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 return PyLong_FromLong((long) *(signed char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000309}
310
311static PyObject *
312nu_ubyte(const char *p, const formatdef *f)
313{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 return PyLong_FromLong((long) *(unsigned char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000315}
316
317static PyObject *
318nu_short(const char *p, const formatdef *f)
319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 short x;
321 memcpy((char *)&x, p, sizeof x);
322 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000323}
324
325static PyObject *
326nu_ushort(const char *p, const formatdef *f)
327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 unsigned short x;
329 memcpy((char *)&x, p, sizeof x);
330 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000331}
332
333static PyObject *
334nu_int(const char *p, const formatdef *f)
335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 int x;
337 memcpy((char *)&x, p, sizeof x);
338 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000339}
340
341static PyObject *
342nu_uint(const char *p, const formatdef *f)
343{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000344 unsigned int x;
345 memcpy((char *)&x, p, sizeof x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000346#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000348#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 if (x <= ((unsigned int)LONG_MAX))
350 return PyLong_FromLong((long)x);
351 return PyLong_FromUnsignedLong((unsigned long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000352#endif
353}
354
355static PyObject *
356nu_long(const char *p, const formatdef *f)
357{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 long x;
359 memcpy((char *)&x, p, sizeof x);
360 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000361}
362
363static PyObject *
364nu_ulong(const char *p, const formatdef *f)
365{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 unsigned long x;
367 memcpy((char *)&x, p, sizeof x);
368 if (x <= LONG_MAX)
369 return PyLong_FromLong((long)x);
370 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000371}
372
373/* Native mode doesn't support q or Q unless the platform C supports
374 long long (or, on Windows, __int64). */
375
376#ifdef HAVE_LONG_LONG
377
378static PyObject *
379nu_longlong(const char *p, const formatdef *f)
380{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 PY_LONG_LONG x;
382 memcpy((char *)&x, p, sizeof x);
383 if (x >= LONG_MIN && x <= LONG_MAX)
384 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
385 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000386}
387
388static PyObject *
389nu_ulonglong(const char *p, const formatdef *f)
390{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000391 unsigned PY_LONG_LONG x;
392 memcpy((char *)&x, p, sizeof x);
393 if (x <= LONG_MAX)
394 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
395 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000396}
397
398#endif
399
400static PyObject *
Thomas Woutersb2137042007-02-01 18:02:27 +0000401nu_bool(const char *p, const formatdef *f)
402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 BOOL_TYPE x;
404 memcpy((char *)&x, p, sizeof x);
405 return PyBool_FromLong(x != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000406}
407
408
409static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000410nu_float(const char *p, const formatdef *f)
411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 float x;
413 memcpy((char *)&x, p, sizeof x);
414 return PyFloat_FromDouble((double)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000415}
416
417static PyObject *
418nu_double(const char *p, const formatdef *f)
419{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 double x;
421 memcpy((char *)&x, p, sizeof x);
422 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000423}
424
425static PyObject *
426nu_void_p(const char *p, const formatdef *f)
427{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 void *x;
429 memcpy((char *)&x, p, sizeof x);
430 return PyLong_FromVoidPtr(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000431}
432
433static int
434np_byte(char *p, PyObject *v, const formatdef *f)
435{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000436 long x;
437 if (get_long(v, &x) < 0)
438 return -1;
439 if (x < -128 || x > 127){
440 PyErr_SetString(StructError,
441 "byte format requires -128 <= number <= 127");
442 return -1;
443 }
444 *p = (char)x;
445 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000446}
447
448static int
449np_ubyte(char *p, PyObject *v, const formatdef *f)
450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 long x;
452 if (get_long(v, &x) < 0)
453 return -1;
454 if (x < 0 || x > 255){
455 PyErr_SetString(StructError,
456 "ubyte format requires 0 <= number <= 255");
457 return -1;
458 }
459 *p = (char)x;
460 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000461}
462
463static int
464np_char(char *p, PyObject *v, const formatdef *f)
465{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 if (PyUnicode_Check(v)) {
467 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
468 if (v == NULL)
469 return -1;
470 }
471 if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
472 PyErr_SetString(StructError,
473 "char format requires bytes or string of length 1");
474 return -1;
475 }
476 *p = *PyBytes_AsString(v);
477 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000478}
479
480static int
481np_short(char *p, PyObject *v, const formatdef *f)
482{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000483 long x;
484 short y;
485 if (get_long(v, &x) < 0)
486 return -1;
487 if (x < SHRT_MIN || x > SHRT_MAX){
488 PyErr_SetString(StructError,
489 "short format requires " STRINGIFY(SHRT_MIN)
490 " <= number <= " STRINGIFY(SHRT_MAX));
491 return -1;
492 }
493 y = (short)x;
494 memcpy(p, (char *)&y, sizeof y);
495 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000496}
497
498static int
499np_ushort(char *p, PyObject *v, const formatdef *f)
500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 long x;
502 unsigned short y;
503 if (get_long(v, &x) < 0)
504 return -1;
505 if (x < 0 || x > USHRT_MAX){
506 PyErr_SetString(StructError,
507 "ushort format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
508 return -1;
509 }
510 y = (unsigned short)x;
511 memcpy(p, (char *)&y, sizeof y);
512 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000513}
514
515static int
516np_int(char *p, PyObject *v, const formatdef *f)
517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 long x;
519 int y;
520 if (get_long(v, &x) < 0)
521 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000522#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
524 RANGE_ERROR(x, f, 0, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000525#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 y = (int)x;
527 memcpy(p, (char *)&y, sizeof y);
528 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000529}
530
531static int
532np_uint(char *p, PyObject *v, const formatdef *f)
533{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 unsigned long x;
535 unsigned int y;
536 if (get_ulong(v, &x) < 0)
537 return -1;
538 y = (unsigned int)x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000539#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 if (x > ((unsigned long)UINT_MAX))
541 RANGE_ERROR(y, f, 1, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000542#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 memcpy(p, (char *)&y, sizeof y);
544 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000545}
546
547static int
548np_long(char *p, PyObject *v, const formatdef *f)
549{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 long x;
551 if (get_long(v, &x) < 0)
552 return -1;
553 memcpy(p, (char *)&x, sizeof x);
554 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000555}
556
557static int
558np_ulong(char *p, PyObject *v, const formatdef *f)
559{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 unsigned long x;
561 if (get_ulong(v, &x) < 0)
562 return -1;
563 memcpy(p, (char *)&x, sizeof x);
564 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000565}
566
567#ifdef HAVE_LONG_LONG
568
569static int
570np_longlong(char *p, PyObject *v, const formatdef *f)
571{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000572 PY_LONG_LONG x;
573 if (get_longlong(v, &x) < 0)
574 return -1;
575 memcpy(p, (char *)&x, sizeof x);
576 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000577}
578
579static int
580np_ulonglong(char *p, PyObject *v, const formatdef *f)
581{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 unsigned PY_LONG_LONG x;
583 if (get_ulonglong(v, &x) < 0)
584 return -1;
585 memcpy(p, (char *)&x, sizeof x);
586 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000587}
588#endif
589
Thomas Woutersb2137042007-02-01 18:02:27 +0000590
591static int
592np_bool(char *p, PyObject *v, const formatdef *f)
593{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 BOOL_TYPE y;
595 y = PyObject_IsTrue(v);
596 memcpy(p, (char *)&y, sizeof y);
597 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000598}
599
Thomas Wouters477c8d52006-05-27 19:21:47 +0000600static int
601np_float(char *p, PyObject *v, const formatdef *f)
602{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 float x = (float)PyFloat_AsDouble(v);
604 if (x == -1 && PyErr_Occurred()) {
605 PyErr_SetString(StructError,
606 "required argument is not a float");
607 return -1;
608 }
609 memcpy(p, (char *)&x, sizeof x);
610 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000611}
612
613static int
614np_double(char *p, PyObject *v, const formatdef *f)
615{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000616 double x = PyFloat_AsDouble(v);
617 if (x == -1 && PyErr_Occurred()) {
618 PyErr_SetString(StructError,
619 "required argument is not a float");
620 return -1;
621 }
622 memcpy(p, (char *)&x, sizeof(double));
623 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000624}
625
626static int
627np_void_p(char *p, PyObject *v, const formatdef *f)
628{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 void *x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 v = get_pylong(v);
632 if (v == NULL)
633 return -1;
634 assert(PyLong_Check(v));
635 x = PyLong_AsVoidPtr(v);
636 Py_DECREF(v);
637 if (x == NULL && PyErr_Occurred())
638 return -1;
639 memcpy(p, (char *)&x, sizeof x);
640 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000641}
642
643static formatdef native_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 {'x', sizeof(char), 0, NULL},
645 {'b', sizeof(char), 0, nu_byte, np_byte},
646 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
647 {'c', sizeof(char), 0, nu_char, np_char},
648 {'s', sizeof(char), 0, NULL},
649 {'p', sizeof(char), 0, NULL},
650 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
651 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
652 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
653 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
654 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
655 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000656#ifdef HAVE_LONG_LONG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000657 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
658 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000659#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000660 {'?', sizeof(BOOL_TYPE), BOOL_ALIGN, nu_bool, np_bool},
661 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
662 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
663 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
664 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000665};
666
667/* Big-endian routines. *****************************************************/
668
669static PyObject *
670bu_int(const char *p, const formatdef *f)
671{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000672 long x = 0;
673 Py_ssize_t i = f->size;
674 const unsigned char *bytes = (const unsigned char *)p;
675 do {
676 x = (x<<8) | *bytes++;
677 } while (--i > 0);
678 /* Extend the sign bit. */
679 if (SIZEOF_LONG > f->size)
680 x |= -(x & (1L << ((8 * f->size) - 1)));
681 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000682}
683
684static PyObject *
685bu_uint(const char *p, const formatdef *f)
686{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000687 unsigned long x = 0;
688 Py_ssize_t i = f->size;
689 const unsigned char *bytes = (const unsigned char *)p;
690 do {
691 x = (x<<8) | *bytes++;
692 } while (--i > 0);
693 if (x <= LONG_MAX)
694 return PyLong_FromLong((long)x);
695 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000696}
697
698static PyObject *
699bu_longlong(const char *p, const formatdef *f)
700{
701#ifdef HAVE_LONG_LONG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 PY_LONG_LONG x = 0;
703 Py_ssize_t i = f->size;
704 const unsigned char *bytes = (const unsigned char *)p;
705 do {
706 x = (x<<8) | *bytes++;
707 } while (--i > 0);
708 /* Extend the sign bit. */
709 if (SIZEOF_LONG_LONG > f->size)
710 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
711 if (x >= LONG_MIN && x <= LONG_MAX)
712 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
713 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000714#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 return _PyLong_FromByteArray((const unsigned char *)p,
716 8,
717 0, /* little-endian */
718 1 /* signed */);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000719#endif
720}
721
722static PyObject *
723bu_ulonglong(const char *p, const formatdef *f)
724{
725#ifdef HAVE_LONG_LONG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000726 unsigned PY_LONG_LONG x = 0;
727 Py_ssize_t i = f->size;
728 const unsigned char *bytes = (const unsigned char *)p;
729 do {
730 x = (x<<8) | *bytes++;
731 } while (--i > 0);
732 if (x <= LONG_MAX)
733 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
734 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000735#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 return _PyLong_FromByteArray((const unsigned char *)p,
737 8,
738 0, /* little-endian */
739 0 /* signed */);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000740#endif
741}
742
743static PyObject *
744bu_float(const char *p, const formatdef *f)
745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 return unpack_float(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000747}
748
749static PyObject *
750bu_double(const char *p, const formatdef *f)
751{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 return unpack_double(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000753}
754
Thomas Woutersb2137042007-02-01 18:02:27 +0000755static PyObject *
756bu_bool(const char *p, const formatdef *f)
757{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 char x;
759 memcpy((char *)&x, p, sizeof x);
760 return PyBool_FromLong(x != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000761}
762
Thomas Wouters477c8d52006-05-27 19:21:47 +0000763static int
764bp_int(char *p, PyObject *v, const formatdef *f)
765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000766 long x;
767 Py_ssize_t i;
768 if (get_long(v, &x) < 0)
769 return -1;
770 i = f->size;
771 if (i != SIZEOF_LONG) {
772 if ((i == 2) && (x < -32768 || x > 32767))
773 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000774#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000775 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
776 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000777#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778 }
779 do {
780 p[--i] = (char)x;
781 x >>= 8;
782 } while (i > 0);
783 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000784}
785
786static int
787bp_uint(char *p, PyObject *v, const formatdef *f)
788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 unsigned long x;
790 Py_ssize_t i;
791 if (get_ulong(v, &x) < 0)
792 return -1;
793 i = f->size;
794 if (i != SIZEOF_LONG) {
795 unsigned long maxint = 1;
796 maxint <<= (unsigned long)(i * 8);
797 if (x >= maxint)
798 RANGE_ERROR(x, f, 1, maxint - 1);
799 }
800 do {
801 p[--i] = (char)x;
802 x >>= 8;
803 } while (i > 0);
804 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000805}
806
807static int
808bp_longlong(char *p, PyObject *v, const formatdef *f)
809{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000810 int res;
811 v = get_pylong(v);
812 if (v == NULL)
813 return -1;
814 res = _PyLong_AsByteArray((PyLongObject *)v,
815 (unsigned char *)p,
816 8,
817 0, /* little_endian */
818 1 /* signed */);
819 Py_DECREF(v);
820 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000821}
822
823static int
824bp_ulonglong(char *p, PyObject *v, const formatdef *f)
825{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 int res;
827 v = get_pylong(v);
828 if (v == NULL)
829 return -1;
830 res = _PyLong_AsByteArray((PyLongObject *)v,
831 (unsigned char *)p,
832 8,
833 0, /* little_endian */
834 0 /* signed */);
835 Py_DECREF(v);
836 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000837}
838
839static int
840bp_float(char *p, PyObject *v, const formatdef *f)
841{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000842 double x = PyFloat_AsDouble(v);
843 if (x == -1 && PyErr_Occurred()) {
844 PyErr_SetString(StructError,
845 "required argument is not a float");
846 return -1;
847 }
848 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000849}
850
851static int
852bp_double(char *p, PyObject *v, const formatdef *f)
853{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 double x = PyFloat_AsDouble(v);
855 if (x == -1 && PyErr_Occurred()) {
856 PyErr_SetString(StructError,
857 "required argument is not a float");
858 return -1;
859 }
860 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000861}
862
Thomas Woutersb2137042007-02-01 18:02:27 +0000863static int
864bp_bool(char *p, PyObject *v, const formatdef *f)
865{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000866 char y;
867 y = PyObject_IsTrue(v);
868 memcpy(p, (char *)&y, sizeof y);
869 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000870}
871
Thomas Wouters477c8d52006-05-27 19:21:47 +0000872static formatdef bigendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 {'x', 1, 0, NULL},
874 {'b', 1, 0, nu_byte, np_byte},
875 {'B', 1, 0, nu_ubyte, np_ubyte},
876 {'c', 1, 0, nu_char, np_char},
877 {'s', 1, 0, NULL},
878 {'p', 1, 0, NULL},
879 {'h', 2, 0, bu_int, bp_int},
880 {'H', 2, 0, bu_uint, bp_uint},
881 {'i', 4, 0, bu_int, bp_int},
882 {'I', 4, 0, bu_uint, bp_uint},
883 {'l', 4, 0, bu_int, bp_int},
884 {'L', 4, 0, bu_uint, bp_uint},
885 {'q', 8, 0, bu_longlong, bp_longlong},
886 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
887 {'?', 1, 0, bu_bool, bp_bool},
888 {'f', 4, 0, bu_float, bp_float},
889 {'d', 8, 0, bu_double, bp_double},
890 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000891};
892
893/* Little-endian routines. *****************************************************/
894
895static PyObject *
896lu_int(const char *p, const formatdef *f)
897{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 long x = 0;
899 Py_ssize_t i = f->size;
900 const unsigned char *bytes = (const unsigned char *)p;
901 do {
902 x = (x<<8) | bytes[--i];
903 } while (i > 0);
904 /* Extend the sign bit. */
905 if (SIZEOF_LONG > f->size)
906 x |= -(x & (1L << ((8 * f->size) - 1)));
907 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000908}
909
910static PyObject *
911lu_uint(const char *p, const formatdef *f)
912{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000913 unsigned long x = 0;
914 Py_ssize_t i = f->size;
915 const unsigned char *bytes = (const unsigned char *)p;
916 do {
917 x = (x<<8) | bytes[--i];
918 } while (i > 0);
919 if (x <= LONG_MAX)
920 return PyLong_FromLong((long)x);
921 return PyLong_FromUnsignedLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000922}
923
924static PyObject *
925lu_longlong(const char *p, const formatdef *f)
926{
927#ifdef HAVE_LONG_LONG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 PY_LONG_LONG x = 0;
929 Py_ssize_t i = f->size;
930 const unsigned char *bytes = (const unsigned char *)p;
931 do {
932 x = (x<<8) | bytes[--i];
933 } while (i > 0);
934 /* Extend the sign bit. */
935 if (SIZEOF_LONG_LONG > f->size)
936 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
937 if (x >= LONG_MIN && x <= LONG_MAX)
938 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
939 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000940#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 return _PyLong_FromByteArray((const unsigned char *)p,
942 8,
943 1, /* little-endian */
944 1 /* signed */);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000945#endif
946}
947
948static PyObject *
949lu_ulonglong(const char *p, const formatdef *f)
950{
951#ifdef HAVE_LONG_LONG
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 unsigned PY_LONG_LONG x = 0;
953 Py_ssize_t i = f->size;
954 const unsigned char *bytes = (const unsigned char *)p;
955 do {
956 x = (x<<8) | bytes[--i];
957 } while (i > 0);
958 if (x <= LONG_MAX)
959 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
960 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000961#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 return _PyLong_FromByteArray((const unsigned char *)p,
963 8,
964 1, /* little-endian */
965 0 /* signed */);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000966#endif
967}
968
969static PyObject *
970lu_float(const char *p, const formatdef *f)
971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 return unpack_float(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000973}
974
975static PyObject *
976lu_double(const char *p, const formatdef *f)
977{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 return unpack_double(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000979}
980
981static int
982lp_int(char *p, PyObject *v, const formatdef *f)
983{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 long x;
985 Py_ssize_t i;
986 if (get_long(v, &x) < 0)
987 return -1;
988 i = f->size;
989 if (i != SIZEOF_LONG) {
990 if ((i == 2) && (x < -32768 || x > 32767))
991 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000992#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
994 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000995#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000996 }
997 do {
998 *p++ = (char)x;
999 x >>= 8;
1000 } while (--i > 0);
1001 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001002}
1003
1004static int
1005lp_uint(char *p, PyObject *v, const formatdef *f)
1006{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 unsigned long x;
1008 Py_ssize_t i;
1009 if (get_ulong(v, &x) < 0)
1010 return -1;
1011 i = f->size;
1012 if (i != SIZEOF_LONG) {
1013 unsigned long maxint = 1;
1014 maxint <<= (unsigned long)(i * 8);
1015 if (x >= maxint)
1016 RANGE_ERROR(x, f, 1, maxint - 1);
1017 }
1018 do {
1019 *p++ = (char)x;
1020 x >>= 8;
1021 } while (--i > 0);
1022 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001023}
1024
1025static int
1026lp_longlong(char *p, PyObject *v, const formatdef *f)
1027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 int res;
1029 v = get_pylong(v);
1030 if (v == NULL)
1031 return -1;
1032 res = _PyLong_AsByteArray((PyLongObject*)v,
1033 (unsigned char *)p,
1034 8,
1035 1, /* little_endian */
1036 1 /* signed */);
1037 Py_DECREF(v);
1038 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001039}
1040
1041static int
1042lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1043{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 int res;
1045 v = get_pylong(v);
1046 if (v == NULL)
1047 return -1;
1048 res = _PyLong_AsByteArray((PyLongObject*)v,
1049 (unsigned char *)p,
1050 8,
1051 1, /* little_endian */
1052 0 /* signed */);
1053 Py_DECREF(v);
1054 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001055}
1056
1057static int
1058lp_float(char *p, PyObject *v, const formatdef *f)
1059{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 double x = PyFloat_AsDouble(v);
1061 if (x == -1 && PyErr_Occurred()) {
1062 PyErr_SetString(StructError,
1063 "required argument is not a float");
1064 return -1;
1065 }
1066 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001067}
1068
1069static int
1070lp_double(char *p, PyObject *v, const formatdef *f)
1071{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 double x = PyFloat_AsDouble(v);
1073 if (x == -1 && PyErr_Occurred()) {
1074 PyErr_SetString(StructError,
1075 "required argument is not a float");
1076 return -1;
1077 }
1078 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001079}
1080
1081static formatdef lilendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001082 {'x', 1, 0, NULL},
1083 {'b', 1, 0, nu_byte, np_byte},
1084 {'B', 1, 0, nu_ubyte, np_ubyte},
1085 {'c', 1, 0, nu_char, np_char},
1086 {'s', 1, 0, NULL},
1087 {'p', 1, 0, NULL},
1088 {'h', 2, 0, lu_int, lp_int},
1089 {'H', 2, 0, lu_uint, lp_uint},
1090 {'i', 4, 0, lu_int, lp_int},
1091 {'I', 4, 0, lu_uint, lp_uint},
1092 {'l', 4, 0, lu_int, lp_int},
1093 {'L', 4, 0, lu_uint, lp_uint},
1094 {'q', 8, 0, lu_longlong, lp_longlong},
1095 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1096 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1097 but potentially different from native rep -- reuse bx_bool funcs. */
1098 {'f', 4, 0, lu_float, lp_float},
1099 {'d', 8, 0, lu_double, lp_double},
1100 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001101};
1102
1103
1104static const formatdef *
1105whichtable(char **pfmt)
1106{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 const char *fmt = (*pfmt)++; /* May be backed out of later */
1108 switch (*fmt) {
1109 case '<':
1110 return lilendian_table;
1111 case '>':
1112 case '!': /* Network byte order is big-endian */
1113 return bigendian_table;
1114 case '=': { /* Host byte order -- different from native in aligment! */
1115 int n = 1;
1116 char *p = (char *) &n;
1117 if (*p == 1)
1118 return lilendian_table;
1119 else
1120 return bigendian_table;
1121 }
1122 default:
1123 --*pfmt; /* Back out of pointer increment */
1124 /* Fall through */
1125 case '@':
1126 return native_table;
1127 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001128}
1129
1130
1131/* Get the table entry for a format code */
1132
1133static const formatdef *
1134getentry(int c, const formatdef *f)
1135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 for (; f->format != '\0'; f++) {
1137 if (f->format == c) {
1138 return f;
1139 }
1140 }
1141 PyErr_SetString(StructError, "bad char in struct format");
1142 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001143}
1144
1145
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001146/* Align a size according to a format code. Return -1 on overflow. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001147
Mark Dickinsoneac0e682010-06-11 19:05:08 +00001148static Py_ssize_t
Thomas Wouters477c8d52006-05-27 19:21:47 +00001149align(Py_ssize_t size, char c, const formatdef *e)
1150{
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001151 Py_ssize_t extra;
1152
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 if (e->format == c) {
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001154 if (e->alignment && size > 0) {
1155 extra = (e->alignment - 1) - (size - 1) % (e->alignment);
1156 if (extra > PY_SSIZE_T_MAX - size)
1157 return -1;
1158 size += extra;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 }
1160 }
1161 return size;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001162}
1163
1164
1165/* calculate the size of a format string */
1166
1167static int
1168prepare_s(PyStructObject *self)
1169{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 const formatdef *f;
1171 const formatdef *e;
1172 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001173
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001174 const char *s;
1175 const char *fmt;
1176 char c;
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001177 Py_ssize_t size, len, num, itemsize;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001178
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001179 fmt = PyBytes_AS_STRING(self->s_format);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001180
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 f = whichtable((char **)&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001182
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 s = fmt;
1184 size = 0;
1185 len = 0;
1186 while ((c = *s++) != '\0') {
1187 if (isspace(Py_CHARMASK(c)))
1188 continue;
1189 if ('0' <= c && c <= '9') {
1190 num = c - '0';
1191 while ('0' <= (c = *s++) && c <= '9') {
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001192 /* overflow-safe version of
1193 if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1194 if (num >= PY_SSIZE_T_MAX / 10 && (
1195 num > PY_SSIZE_T_MAX / 10 ||
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001196 (c - '0') > PY_SSIZE_T_MAX % 10))
1197 goto overflow;
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001198 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 }
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001200 if (c == '\0') {
1201 PyErr_SetString(StructError,
1202 "repeat count given without format specifier");
1203 return -1;
1204 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 }
1206 else
1207 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 e = getentry(c, f);
1210 if (e == NULL)
1211 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 switch (c) {
1214 case 's': /* fall through */
1215 case 'p': len++; break;
1216 case 'x': break;
1217 default: len += num; break;
1218 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001219
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 itemsize = e->size;
1221 size = align(size, c, e);
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001222 if (size == -1)
1223 goto overflow;
1224
1225 /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1226 if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1227 goto overflow;
1228 size += num * itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 /* check for overflow */
1232 if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {
1233 PyErr_NoMemory();
1234 return -1;
1235 }
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +00001236
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 self->s_size = size;
1238 self->s_len = len;
1239 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1240 if (codes == NULL) {
1241 PyErr_NoMemory();
1242 return -1;
1243 }
1244 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001245
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 s = fmt;
1247 size = 0;
1248 while ((c = *s++) != '\0') {
1249 if (isspace(Py_CHARMASK(c)))
1250 continue;
1251 if ('0' <= c && c <= '9') {
1252 num = c - '0';
1253 while ('0' <= (c = *s++) && c <= '9')
1254 num = num*10 + (c - '0');
1255 if (c == '\0')
1256 break;
1257 }
1258 else
1259 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001260
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 size = align(size, c, e);
1264 if (c == 's' || c == 'p') {
1265 codes->offset = size;
1266 codes->size = num;
1267 codes->fmtdef = e;
1268 codes++;
1269 size += num;
1270 } else if (c == 'x') {
1271 size += num;
1272 } else {
1273 while (--num >= 0) {
1274 codes->offset = size;
1275 codes->size = e->size;
1276 codes->fmtdef = e;
1277 codes++;
1278 size += e->size;
1279 }
1280 }
1281 }
1282 codes->fmtdef = NULL;
1283 codes->offset = size;
1284 codes->size = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 return 0;
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001287
1288 overflow:
1289 PyErr_SetString(StructError,
1290 "total struct size too long");
1291 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001292}
1293
1294static PyObject *
1295s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1296{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 PyObject *self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 assert(type != NULL && type->tp_alloc != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 self = type->tp_alloc(type, 0);
1302 if (self != NULL) {
1303 PyStructObject *s = (PyStructObject*)self;
1304 Py_INCREF(Py_None);
1305 s->s_format = Py_None;
1306 s->s_codes = NULL;
1307 s->s_size = -1;
1308 s->s_len = -1;
1309 }
1310 return self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001311}
1312
1313static int
1314s_init(PyObject *self, PyObject *args, PyObject *kwds)
1315{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 PyStructObject *soself = (PyStructObject *)self;
1317 PyObject *o_format = NULL;
1318 int ret = 0;
1319 static char *kwlist[] = {"format", 0};
Thomas Wouters477c8d52006-05-27 19:21:47 +00001320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 assert(PyStruct_Check(self));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Struct", kwlist,
1324 &o_format))
1325 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 if (PyUnicode_Check(o_format)) {
1328 o_format = PyUnicode_AsASCIIString(o_format);
1329 if (o_format == NULL)
1330 return -1;
1331 }
1332 /* XXX support buffer interface, too */
1333 else {
1334 Py_INCREF(o_format);
1335 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001336
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 if (!PyBytes_Check(o_format)) {
1338 Py_DECREF(o_format);
1339 PyErr_Format(PyExc_TypeError,
1340 "Struct() argument 1 must be bytes, not %.200s",
1341 Py_TYPE(o_format)->tp_name);
1342 return -1;
1343 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 Py_CLEAR(soself->s_format);
1346 soself->s_format = o_format;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 ret = prepare_s(soself);
1349 return ret;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001350}
1351
1352static void
1353s_dealloc(PyStructObject *s)
1354{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 if (s->weakreflist != NULL)
1356 PyObject_ClearWeakRefs((PyObject *)s);
1357 if (s->s_codes != NULL) {
1358 PyMem_FREE(s->s_codes);
1359 }
1360 Py_XDECREF(s->s_format);
1361 Py_TYPE(s)->tp_free((PyObject *)s);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001362}
1363
1364static PyObject *
1365s_unpack_internal(PyStructObject *soself, char *startfrom) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 formatcode *code;
1367 Py_ssize_t i = 0;
1368 PyObject *result = PyTuple_New(soself->s_len);
1369 if (result == NULL)
1370 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1373 PyObject *v;
1374 const formatdef *e = code->fmtdef;
1375 const char *res = startfrom + code->offset;
1376 if (e->format == 's') {
1377 v = PyBytes_FromStringAndSize(res, code->size);
1378 } else if (e->format == 'p') {
1379 Py_ssize_t n = *(unsigned char*)res;
1380 if (n >= code->size)
1381 n = code->size - 1;
1382 v = PyBytes_FromStringAndSize(res + 1, n);
1383 } else {
1384 v = e->unpack(res, e);
1385 }
1386 if (v == NULL)
1387 goto fail;
1388 PyTuple_SET_ITEM(result, i++, v);
1389 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001392fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001393 Py_DECREF(result);
1394 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001395}
1396
1397
1398PyDoc_STRVAR(s_unpack__doc__,
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001399"S.unpack(buffer) -> (v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001400\n\
Mark Dickinsond80a8ee2010-06-12 15:19:23 +00001401Return tuple containing values unpacked according to this Struct's format.\n\
1402Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\
1403strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001404
1405static PyObject *
Guido van Rossum98297ee2007-11-06 21:34:58 +00001406s_unpack(PyObject *self, PyObject *input)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 Py_buffer vbuf;
1409 PyObject *result;
1410 PyStructObject *soself = (PyStructObject *)self;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 assert(PyStruct_Check(self));
1413 assert(soself->s_codes != NULL);
1414 if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0)
1415 return NULL;
1416 if (vbuf.len != soself->s_size) {
1417 PyErr_Format(StructError,
1418 "unpack requires a bytes argument of length %zd",
1419 soself->s_size);
1420 PyBuffer_Release(&vbuf);
1421 return NULL;
1422 }
1423 result = s_unpack_internal(soself, vbuf.buf);
1424 PyBuffer_Release(&vbuf);
1425 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001426}
1427
1428PyDoc_STRVAR(s_unpack_from__doc__,
Mark Dickinsond80a8ee2010-06-12 15:19:23 +00001429"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001430\n\
Mark Dickinsond80a8ee2010-06-12 15:19:23 +00001431Return tuple containing values unpacked according to this Struct's format.\n\
1432Unlike unpack, unpack_from can unpack values from any object supporting\n\
1433the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1434See struct.__doc__ for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001435
1436static PyObject *
1437s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1438{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 static char *kwlist[] = {"buffer", "offset", 0};
Guido van Rossum98297ee2007-11-06 21:34:58 +00001440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 PyObject *input;
1442 Py_ssize_t offset = 0;
1443 Py_buffer vbuf;
1444 PyObject *result;
1445 PyStructObject *soself = (PyStructObject *)self;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001446
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 assert(PyStruct_Check(self));
1448 assert(soself->s_codes != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 if (!PyArg_ParseTupleAndKeywords(args, kwds,
1451 "O|n:unpack_from", kwlist,
1452 &input, &offset))
1453 return NULL;
1454 if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0)
1455 return NULL;
1456 if (offset < 0)
1457 offset += vbuf.len;
1458 if (offset < 0 || vbuf.len - offset < soself->s_size) {
1459 PyErr_Format(StructError,
1460 "unpack_from requires a buffer of at least %zd bytes",
1461 soself->s_size);
1462 PyBuffer_Release(&vbuf);
1463 return NULL;
1464 }
1465 result = s_unpack_internal(soself, (char*)vbuf.buf + offset);
1466 PyBuffer_Release(&vbuf);
1467 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001468}
1469
1470
1471/*
1472 * Guts of the pack function.
1473 *
1474 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1475 * argument for where to start processing the arguments for packing, and a
1476 * character buffer for writing the packed string. The caller must insure
1477 * that the buffer may contain the required length for packing the arguments.
1478 * 0 is returned on success, 1 is returned if there is an error.
1479 *
1480 */
1481static int
1482s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1483{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 formatcode *code;
1485 /* XXX(nnorwitz): why does i need to be a local? can we use
1486 the offset parameter or do we need the wider width? */
1487 Py_ssize_t i;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001488
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 memset(buf, '\0', soself->s_size);
1490 i = offset;
1491 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1492 Py_ssize_t n;
1493 PyObject *v = PyTuple_GET_ITEM(args, i++);
1494 const formatdef *e = code->fmtdef;
1495 char *res = buf + code->offset;
1496 if (e->format == 's') {
1497 int isstring;
1498 void *p;
1499 if (PyUnicode_Check(v)) {
1500 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
1501 if (v == NULL)
1502 return -1;
1503 }
1504 isstring = PyBytes_Check(v);
1505 if (!isstring && !PyByteArray_Check(v)) {
1506 PyErr_SetString(StructError,
1507 "argument for 's' must be a bytes or string");
1508 return -1;
1509 }
1510 if (isstring) {
1511 n = PyBytes_GET_SIZE(v);
1512 p = PyBytes_AS_STRING(v);
1513 }
1514 else {
1515 n = PyByteArray_GET_SIZE(v);
1516 p = PyByteArray_AS_STRING(v);
1517 }
1518 if (n > code->size)
1519 n = code->size;
1520 if (n > 0)
1521 memcpy(res, p, n);
1522 } else if (e->format == 'p') {
1523 int isstring;
1524 void *p;
1525 if (PyUnicode_Check(v)) {
1526 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
1527 if (v == NULL)
1528 return -1;
1529 }
1530 isstring = PyBytes_Check(v);
1531 if (!isstring && !PyByteArray_Check(v)) {
1532 PyErr_SetString(StructError,
1533 "argument for 'p' must be a bytes or string");
1534 return -1;
1535 }
1536 if (isstring) {
1537 n = PyBytes_GET_SIZE(v);
1538 p = PyBytes_AS_STRING(v);
1539 }
1540 else {
1541 n = PyByteArray_GET_SIZE(v);
1542 p = PyByteArray_AS_STRING(v);
1543 }
1544 if (n > (code->size - 1))
1545 n = code->size - 1;
1546 if (n > 0)
1547 memcpy(res + 1, p, n);
1548 if (n > 255)
1549 n = 255;
1550 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1551 } else {
1552 if (e->pack(res, v, e) < 0) {
1553 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1554 PyErr_SetString(StructError,
1555 "long too large to convert to int");
1556 return -1;
1557 }
1558 }
1559 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 /* Success */
1562 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001563}
1564
1565
1566PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001567"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001568\n\
Mark Dickinsond80a8ee2010-06-12 15:19:23 +00001569Return a bytes containing values v1, v2, ... packed according to this\n\
1570Struct's format. See struct.__doc__ for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001571
1572static PyObject *
1573s_pack(PyObject *self, PyObject *args)
1574{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 PyStructObject *soself;
1576 PyObject *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 /* Validate arguments. */
1579 soself = (PyStructObject *)self;
1580 assert(PyStruct_Check(self));
1581 assert(soself->s_codes != NULL);
1582 if (PyTuple_GET_SIZE(args) != soself->s_len)
1583 {
1584 PyErr_Format(StructError,
1585 "pack requires exactly %zd arguments", soself->s_len);
1586 return NULL;
1587 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001588
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 /* Allocate a new string */
1590 result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size);
1591 if (result == NULL)
1592 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001593
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001594 /* Call the guts */
1595 if ( s_pack_internal(soself, args, 0, PyBytes_AS_STRING(result)) != 0 ) {
1596 Py_DECREF(result);
1597 return NULL;
1598 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001599
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001600 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001601}
1602
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001603PyDoc_STRVAR(s_pack_into__doc__,
1604"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001605\n\
Mark Dickinsond80a8ee2010-06-12 15:19:23 +00001606Pack the values v1, v2, ... according to this Struct's format, write \n\
1607the packed bytes into the writable buffer buf starting at offset. Note\n\
1608that the offset is not an optional argument. See struct.__doc__ for \n\
1609more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001610
1611static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001612s_pack_into(PyObject *self, PyObject *args)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001613{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 PyStructObject *soself;
1615 char *buffer;
1616 Py_ssize_t buffer_len, offset;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001617
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 /* Validate arguments. +1 is for the first arg as buffer. */
1619 soself = (PyStructObject *)self;
1620 assert(PyStruct_Check(self));
1621 assert(soself->s_codes != NULL);
1622 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
1623 {
1624 PyErr_Format(StructError,
1625 "pack_into requires exactly %zd arguments",
1626 (soself->s_len + 2));
1627 return NULL;
1628 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 /* Extract a writable memory buffer from the first argument */
1631 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1632 (void**)&buffer, &buffer_len) == -1 ) {
1633 return NULL;
1634 }
1635 assert( buffer_len >= 0 );
Thomas Wouters477c8d52006-05-27 19:21:47 +00001636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 /* Extract the offset from the first argument */
1638 offset = PyNumber_AsSsize_t(PyTuple_GET_ITEM(args, 1), PyExc_IndexError);
1639 if (offset == -1 && PyErr_Occurred())
1640 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001641
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001642 /* Support negative offsets. */
1643 if (offset < 0)
1644 offset += buffer_len;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 /* Check boundaries */
1647 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1648 PyErr_Format(StructError,
1649 "pack_into requires a buffer of at least %zd bytes",
1650 soself->s_size);
1651 return NULL;
1652 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001653
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001654 /* Call the guts */
1655 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1656 return NULL;
1657 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001658
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001659 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001660}
1661
1662static PyObject *
1663s_get_format(PyStructObject *self, void *unused)
1664{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001665 Py_INCREF(self->s_format);
1666 return self->s_format;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001667}
1668
1669static PyObject *
1670s_get_size(PyStructObject *self, void *unused)
1671{
Christian Heimes217cfd12007-12-02 14:31:20 +00001672 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001673}
1674
1675/* List of functions */
1676
1677static struct PyMethodDef s_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001678 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1679 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1680 {"unpack", s_unpack, METH_O, s_unpack__doc__},
1681 {"unpack_from", (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS,
1682 s_unpack_from__doc__},
1683 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001684};
1685
1686PyDoc_STRVAR(s__doc__, "Compiled struct object");
1687
1688#define OFF(x) offsetof(PyStructObject, x)
1689
1690static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001691 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1692 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1693 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001694};
1695
1696static
1697PyTypeObject PyStructType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001698 PyVarObject_HEAD_INIT(NULL, 0)
1699 "Struct",
1700 sizeof(PyStructObject),
1701 0,
1702 (destructor)s_dealloc, /* tp_dealloc */
1703 0, /* tp_print */
1704 0, /* tp_getattr */
1705 0, /* tp_setattr */
1706 0, /* tp_reserved */
1707 0, /* tp_repr */
1708 0, /* tp_as_number */
1709 0, /* tp_as_sequence */
1710 0, /* tp_as_mapping */
1711 0, /* tp_hash */
1712 0, /* tp_call */
1713 0, /* tp_str */
1714 PyObject_GenericGetAttr, /* tp_getattro */
1715 PyObject_GenericSetAttr, /* tp_setattro */
1716 0, /* tp_as_buffer */
1717 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
1718 s__doc__, /* tp_doc */
1719 0, /* tp_traverse */
1720 0, /* tp_clear */
1721 0, /* tp_richcompare */
1722 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1723 0, /* tp_iter */
1724 0, /* tp_iternext */
1725 s_methods, /* tp_methods */
1726 NULL, /* tp_members */
1727 s_getsetlist, /* tp_getset */
1728 0, /* tp_base */
1729 0, /* tp_dict */
1730 0, /* tp_descr_get */
1731 0, /* tp_descr_set */
1732 0, /* tp_dictoffset */
1733 s_init, /* tp_init */
1734 PyType_GenericAlloc,/* tp_alloc */
1735 s_new, /* tp_new */
1736 PyObject_Del, /* tp_free */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001737};
1738
Christian Heimesa34706f2008-01-04 03:06:10 +00001739
1740/* ---- Standalone functions ---- */
1741
1742#define MAXCACHE 100
1743static PyObject *cache = NULL;
1744
1745static PyObject *
1746cache_struct(PyObject *fmt)
1747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001748 PyObject * s_object;
Christian Heimesa34706f2008-01-04 03:06:10 +00001749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001750 if (cache == NULL) {
1751 cache = PyDict_New();
1752 if (cache == NULL)
1753 return NULL;
1754 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 s_object = PyDict_GetItem(cache, fmt);
1757 if (s_object != NULL) {
1758 Py_INCREF(s_object);
1759 return s_object;
1760 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001761
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001762 s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
1763 if (s_object != NULL) {
1764 if (PyDict_Size(cache) >= MAXCACHE)
1765 PyDict_Clear(cache);
1766 /* Attempt to cache the result */
1767 if (PyDict_SetItem(cache, fmt, s_object) == -1)
1768 PyErr_Clear();
1769 }
1770 return s_object;
Christian Heimesa34706f2008-01-04 03:06:10 +00001771}
1772
1773PyDoc_STRVAR(clearcache_doc,
1774"Clear the internal cache.");
1775
1776static PyObject *
1777clearcache(PyObject *self)
1778{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001779 Py_CLEAR(cache);
1780 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00001781}
1782
1783PyDoc_STRVAR(calcsize_doc,
1784"Return size of C struct described by format string fmt.");
1785
1786static PyObject *
1787calcsize(PyObject *self, PyObject *fmt)
1788{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001789 Py_ssize_t n;
1790 PyObject *s_object = cache_struct(fmt);
1791 if (s_object == NULL)
1792 return NULL;
1793 n = ((PyStructObject *)s_object)->s_size;
1794 Py_DECREF(s_object);
1795 return PyLong_FromSsize_t(n);
Christian Heimesa34706f2008-01-04 03:06:10 +00001796}
1797
1798PyDoc_STRVAR(pack_doc,
Mark Dickinsond80a8ee2010-06-12 15:19:23 +00001799"Return bytes containing values v1, v2, ... packed according to fmt.");
Christian Heimesa34706f2008-01-04 03:06:10 +00001800
1801static PyObject *
1802pack(PyObject *self, PyObject *args)
1803{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001804 PyObject *s_object, *fmt, *newargs, *result;
1805 Py_ssize_t n = PyTuple_GET_SIZE(args);
Christian Heimesa34706f2008-01-04 03:06:10 +00001806
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001807 if (n == 0) {
1808 PyErr_SetString(PyExc_TypeError, "missing format argument");
1809 return NULL;
1810 }
1811 fmt = PyTuple_GET_ITEM(args, 0);
1812 newargs = PyTuple_GetSlice(args, 1, n);
1813 if (newargs == NULL)
1814 return NULL;
Christian Heimesa34706f2008-01-04 03:06:10 +00001815
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001816 s_object = cache_struct(fmt);
1817 if (s_object == NULL) {
1818 Py_DECREF(newargs);
1819 return NULL;
1820 }
1821 result = s_pack(s_object, newargs);
1822 Py_DECREF(newargs);
1823 Py_DECREF(s_object);
1824 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00001825}
1826
1827PyDoc_STRVAR(pack_into_doc,
Mark Dickinsond80a8ee2010-06-12 15:19:23 +00001828"Pack the values v1, v2, ... according to fmt.\n\
1829Write the packed bytes into the writable buffer buf starting at offset.");
Christian Heimesa34706f2008-01-04 03:06:10 +00001830
1831static PyObject *
1832pack_into(PyObject *self, PyObject *args)
1833{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 PyObject *s_object, *fmt, *newargs, *result;
1835 Py_ssize_t n = PyTuple_GET_SIZE(args);
Christian Heimesa34706f2008-01-04 03:06:10 +00001836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 if (n == 0) {
1838 PyErr_SetString(PyExc_TypeError, "missing format argument");
1839 return NULL;
1840 }
1841 fmt = PyTuple_GET_ITEM(args, 0);
1842 newargs = PyTuple_GetSlice(args, 1, n);
1843 if (newargs == NULL)
1844 return NULL;
Christian Heimesa34706f2008-01-04 03:06:10 +00001845
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001846 s_object = cache_struct(fmt);
1847 if (s_object == NULL) {
1848 Py_DECREF(newargs);
1849 return NULL;
1850 }
1851 result = s_pack_into(s_object, newargs);
1852 Py_DECREF(newargs);
1853 Py_DECREF(s_object);
1854 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00001855}
1856
1857PyDoc_STRVAR(unpack_doc,
Mark Dickinsond80a8ee2010-06-12 15:19:23 +00001858"Unpack the bytes containing packed C structure data, according to fmt.\n\
1859Requires len(bytes) == calcsize(fmt).");
Christian Heimesa34706f2008-01-04 03:06:10 +00001860
1861static PyObject *
1862unpack(PyObject *self, PyObject *args)
1863{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 PyObject *s_object, *fmt, *inputstr, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00001865
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr))
1867 return NULL;
Christian Heimesa34706f2008-01-04 03:06:10 +00001868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 s_object = cache_struct(fmt);
1870 if (s_object == NULL)
1871 return NULL;
1872 result = s_unpack(s_object, inputstr);
1873 Py_DECREF(s_object);
1874 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00001875}
1876
1877PyDoc_STRVAR(unpack_from_doc,
Mark Dickinsond80a8ee2010-06-12 15:19:23 +00001878"Unpack the buffer, containing packed C structure data, according to\n\
1879fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).");
Christian Heimesa34706f2008-01-04 03:06:10 +00001880
1881static PyObject *
1882unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1883{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 PyObject *s_object, *fmt, *newargs, *result;
1885 Py_ssize_t n = PyTuple_GET_SIZE(args);
Christian Heimesa34706f2008-01-04 03:06:10 +00001886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 if (n == 0) {
1888 PyErr_SetString(PyExc_TypeError, "missing format argument");
1889 return NULL;
1890 }
1891 fmt = PyTuple_GET_ITEM(args, 0);
1892 newargs = PyTuple_GetSlice(args, 1, n);
1893 if (newargs == NULL)
1894 return NULL;
Christian Heimesa34706f2008-01-04 03:06:10 +00001895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 s_object = cache_struct(fmt);
1897 if (s_object == NULL) {
1898 Py_DECREF(newargs);
1899 return NULL;
1900 }
1901 result = s_unpack_from(s_object, newargs, kwds);
1902 Py_DECREF(newargs);
1903 Py_DECREF(s_object);
1904 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00001905}
1906
1907static struct PyMethodDef module_functions[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 {"_clearcache", (PyCFunction)clearcache, METH_NOARGS, clearcache_doc},
1909 {"calcsize", calcsize, METH_O, calcsize_doc},
1910 {"pack", pack, METH_VARARGS, pack_doc},
1911 {"pack_into", pack_into, METH_VARARGS, pack_into_doc},
1912 {"unpack", unpack, METH_VARARGS, unpack_doc},
1913 {"unpack_from", (PyCFunction)unpack_from,
1914 METH_VARARGS|METH_KEYWORDS, unpack_from_doc},
1915 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00001916};
1917
1918
Thomas Wouters477c8d52006-05-27 19:21:47 +00001919/* Module initialization */
1920
Christian Heimesa34706f2008-01-04 03:06:10 +00001921PyDoc_STRVAR(module_doc,
1922"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001923Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00001924and also as format strings (explained below) to describe the layout of data\n\
1925in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00001926\n\
1927The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00001928 @: native order, size & alignment (default)\n\
1929 =: native order, std. size & alignment\n\
1930 <: little-endian, std. size & alignment\n\
1931 >: big-endian, std. size & alignment\n\
1932 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00001933\n\
1934The remaining chars indicate types of args and must match exactly;\n\
1935these can be preceded by a decimal repeat count:\n\
1936 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00001937 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00001938 h:short; H:unsigned short; i:int; I:unsigned int;\n\
1939 l:long; L:unsigned long; f:float; d:double.\n\
1940Special cases (preceding decimal count indicates length):\n\
1941 s:string (array of char); p: pascal string (with count byte).\n\
1942Special case (only available in native format):\n\
1943 P:an integer type that is wide enough to hold a pointer.\n\
1944Special case (not in native mode unless 'long long' in platform C):\n\
1945 q:long long; Q:unsigned long long\n\
1946Whitespace between formats is ignored.\n\
1947\n\
1948The variable struct.error is an exception raised on errors.\n");
1949
Martin v. Löwis1a214512008-06-11 05:26:20 +00001950
1951static struct PyModuleDef _structmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 PyModuleDef_HEAD_INIT,
1953 "_struct",
1954 module_doc,
1955 -1,
1956 module_functions,
1957 NULL,
1958 NULL,
1959 NULL,
1960 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001961};
1962
Thomas Wouters477c8d52006-05-27 19:21:47 +00001963PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001964PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001965{
Mark Dickinson06817852010-06-12 09:25:13 +00001966 PyObject *m;
Christian Heimesa34706f2008-01-04 03:06:10 +00001967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 m = PyModule_Create(&_structmodule);
1969 if (m == NULL)
1970 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 Py_TYPE(&PyStructType) = &PyType_Type;
1973 if (PyType_Ready(&PyStructType) < 0)
1974 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 /* Check endian and swap in faster functions */
1977 {
1978 int one = 1;
1979 formatdef *native = native_table;
1980 formatdef *other, *ptr;
1981 if ((int)*(unsigned char*)&one)
1982 other = lilendian_table;
1983 else
1984 other = bigendian_table;
1985 /* Scan through the native table, find a matching
1986 entry in the endian table and swap in the
1987 native implementations whenever possible
1988 (64-bit platforms may not have "standard" sizes) */
1989 while (native->format != '\0' && other->format != '\0') {
1990 ptr = other;
1991 while (ptr->format != '\0') {
1992 if (ptr->format == native->format) {
1993 /* Match faster when formats are
1994 listed in the same order */
1995 if (ptr == other)
1996 other++;
1997 /* Only use the trick if the
1998 size matches */
1999 if (ptr->size != native->size)
2000 break;
2001 /* Skip float and double, could be
2002 "unknown" float format */
2003 if (ptr->format == 'd' || ptr->format == 'f')
2004 break;
2005 ptr->pack = native->pack;
2006 ptr->unpack = native->unpack;
2007 break;
2008 }
2009 ptr++;
2010 }
2011 native++;
2012 }
2013 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002014
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002015 /* Add some symbolic constants to the module */
2016 if (StructError == NULL) {
2017 StructError = PyErr_NewException("struct.error", NULL, NULL);
2018 if (StructError == NULL)
2019 return NULL;
2020 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002021
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 Py_INCREF(StructError);
2023 PyModule_AddObject(m, "error", StructError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002024
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 Py_INCREF((PyObject*)&PyStructType);
2026 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002028 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002029}