blob: ac70f43e640ce656d7d46ceb4313b0e7b78959e9 [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 Wouters4d70c3d2006-06-08 14:42:34 +000015/* If PY_STRUCT_OVERFLOW_MASKING is defined, the struct module will wrap all input
16 numbers for explicit endians such that they fit in the given type, much
17 like explicit casting in C. A warning will be raised if the number did
18 not originally fit within the range of the requested type. If it is
19 not defined, then all range errors and overflow will be struct.error
20 exceptions. */
21
22#define PY_STRUCT_OVERFLOW_MASKING 1
23
24#ifdef PY_STRUCT_OVERFLOW_MASKING
25static PyObject *pylong_ulong_mask = NULL;
26static PyObject *pyint_zero = NULL;
27#endif
28
Thomas Wouters0e3f5912006-08-11 14:57:12 +000029/* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float
30 arguments for integer formats with a warning for backwards
31 compatibility. */
32
33#define PY_STRUCT_FLOAT_COERCE 1
34
35#ifdef PY_STRUCT_FLOAT_COERCE
36#define FLOAT_COERCE "integer argument expected, got float"
37#endif
38
39
Thomas Wouters477c8d52006-05-27 19:21:47 +000040/* The translation function for each format character is table driven */
41typedef struct _formatdef {
42 char format;
43 Py_ssize_t size;
44 Py_ssize_t alignment;
45 PyObject* (*unpack)(const char *,
46 const struct _formatdef *);
47 int (*pack)(char *, PyObject *,
48 const struct _formatdef *);
49} formatdef;
50
51typedef struct _formatcode {
52 const struct _formatdef *fmtdef;
53 Py_ssize_t offset;
54 Py_ssize_t size;
55} formatcode;
56
57/* Struct object interface */
58
59typedef struct {
60 PyObject_HEAD
61 Py_ssize_t s_size;
62 Py_ssize_t s_len;
63 formatcode *s_codes;
64 PyObject *s_format;
65 PyObject *weakreflist; /* List of weak references */
66} PyStructObject;
67
68
69#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
Christian Heimes90aa7642007-12-19 02:45:37 +000070#define PyStruct_CheckExact(op) (Py_TYPE(op) == &PyStructType)
Thomas Wouters477c8d52006-05-27 19:21:47 +000071
72
73/* Exception */
74
75static PyObject *StructError;
76
77
78/* Define various structs to figure out the alignments of types */
79
80
81typedef struct { char c; short x; } st_short;
82typedef struct { char c; int x; } st_int;
83typedef struct { char c; long x; } st_long;
84typedef struct { char c; float x; } st_float;
85typedef struct { char c; double x; } st_double;
86typedef struct { char c; void *x; } st_void_p;
87
88#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
89#define INT_ALIGN (sizeof(st_int) - sizeof(int))
90#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
91#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
92#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
93#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
94
95/* We can't support q and Q in native mode unless the compiler does;
96 in std mode, they're 8 bytes on all platforms. */
97#ifdef HAVE_LONG_LONG
98typedef struct { char c; PY_LONG_LONG x; } s_long_long;
99#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
100#endif
101
Thomas Woutersb2137042007-02-01 18:02:27 +0000102#ifdef HAVE_C99_BOOL
103#define BOOL_TYPE _Bool
104typedef struct { char c; _Bool x; } s_bool;
105#define BOOL_ALIGN (sizeof(s_bool) - sizeof(BOOL_TYPE))
106#else
107#define BOOL_TYPE char
108#define BOOL_ALIGN 0
109#endif
110
Thomas Wouters477c8d52006-05-27 19:21:47 +0000111#define STRINGIFY(x) #x
112
113#ifdef __powerc
114#pragma options align=reset
115#endif
116
117/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
118
119static PyObject *
120get_pylong(PyObject *v)
121{
122 PyNumberMethods *m;
123
124 assert(v != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000125 if (PyLong_Check(v)) {
126 Py_INCREF(v);
127 return v;
128 }
Christian Heimes90aa7642007-12-19 02:45:37 +0000129 m = Py_TYPE(v)->tp_as_number;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000130 if (m != NULL && m->nb_long != NULL) {
131 v = m->nb_long(v);
132 if (v == NULL)
133 return NULL;
134 if (PyLong_Check(v))
135 return v;
136 Py_DECREF(v);
137 }
138 PyErr_SetString(StructError,
139 "cannot convert argument to long");
140 return NULL;
141}
142
143/* Helper routine to get a Python integer and raise the appropriate error
144 if it isn't one */
145
146static int
147get_long(PyObject *v, long *p)
148{
Christian Heimes217cfd12007-12-02 14:31:20 +0000149 long x = PyLong_AsLong(v);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000150 if (x == -1 && PyErr_Occurred()) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000151#ifdef PY_STRUCT_FLOAT_COERCE
152 if (PyFloat_Check(v)) {
153 PyObject *o;
154 int res;
155 PyErr_Clear();
156 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
157 return -1;
158 o = PyNumber_Int(v);
159 if (o == NULL)
160 return -1;
161 res = get_long(o, p);
162 Py_DECREF(o);
163 return res;
164 }
165#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000166 if (PyErr_ExceptionMatches(PyExc_TypeError))
167 PyErr_SetString(StructError,
168 "required argument is not an integer");
169 return -1;
170 }
171 *p = x;
172 return 0;
173}
174
175
176/* Same, but handling unsigned long */
177
178static int
179get_ulong(PyObject *v, unsigned long *p)
180{
181 if (PyLong_Check(v)) {
182 unsigned long x = PyLong_AsUnsignedLong(v);
183 if (x == (unsigned long)(-1) && PyErr_Occurred())
184 return -1;
185 *p = x;
186 return 0;
187 }
188 if (get_long(v, (long *)p) < 0)
189 return -1;
190 if (((long)*p) < 0) {
191 PyErr_SetString(StructError,
192 "unsigned argument is < 0");
193 return -1;
194 }
195 return 0;
196}
197
198#ifdef HAVE_LONG_LONG
199
200/* Same, but handling native long long. */
201
202static int
203get_longlong(PyObject *v, PY_LONG_LONG *p)
204{
205 PY_LONG_LONG x;
206
207 v = get_pylong(v);
208 if (v == NULL)
209 return -1;
210 assert(PyLong_Check(v));
211 x = PyLong_AsLongLong(v);
212 Py_DECREF(v);
213 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
214 return -1;
215 *p = x;
216 return 0;
217}
218
219/* Same, but handling native unsigned long long. */
220
221static int
222get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
223{
224 unsigned PY_LONG_LONG x;
225
226 v = get_pylong(v);
227 if (v == NULL)
228 return -1;
229 assert(PyLong_Check(v));
230 x = PyLong_AsUnsignedLongLong(v);
231 Py_DECREF(v);
232 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
233 return -1;
234 *p = x;
235 return 0;
236}
237
238#endif
239
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000240#ifdef PY_STRUCT_OVERFLOW_MASKING
241
242/* Helper routine to get a Python integer and raise the appropriate error
243 if it isn't one */
244
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000245#define INT_OVERFLOW "struct integer overflow masking is deprecated"
246
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000247static int
248get_wrapped_long(PyObject *v, long *p)
249{
250 if (get_long(v, p) < 0) {
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000251 if (PyLong_Check(v) &&
252 PyErr_ExceptionMatches(PyExc_OverflowError)) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000253 PyObject *wrapped;
254 long x;
255 PyErr_Clear();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000256#ifdef PY_STRUCT_FLOAT_COERCE
257 if (PyFloat_Check(v)) {
258 PyObject *o;
259 int res;
260 PyErr_Clear();
261 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
262 return -1;
263 o = PyNumber_Int(v);
264 if (o == NULL)
265 return -1;
266 res = get_wrapped_long(o, p);
267 Py_DECREF(o);
268 return res;
269 }
270#endif
271 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000272 return -1;
273 wrapped = PyNumber_And(v, pylong_ulong_mask);
274 if (wrapped == NULL)
275 return -1;
276 x = (long)PyLong_AsUnsignedLong(wrapped);
277 Py_DECREF(wrapped);
278 if (x == -1 && PyErr_Occurred())
279 return -1;
280 *p = x;
281 } else {
282 return -1;
283 }
284 }
285 return 0;
286}
287
288static int
289get_wrapped_ulong(PyObject *v, unsigned long *p)
290{
291 long x = (long)PyLong_AsUnsignedLong(v);
292 if (x == -1 && PyErr_Occurred()) {
293 PyObject *wrapped;
294 PyErr_Clear();
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#ifdef PY_STRUCT_FLOAT_COERCE
296 if (PyFloat_Check(v)) {
297 PyObject *o;
298 int res;
299 PyErr_Clear();
300 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
301 return -1;
302 o = PyNumber_Int(v);
303 if (o == NULL)
304 return -1;
305 res = get_wrapped_ulong(o, p);
306 Py_DECREF(o);
307 return res;
308 }
309#endif
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000310 wrapped = PyNumber_And(v, pylong_ulong_mask);
311 if (wrapped == NULL)
312 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000313 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000314 Py_DECREF(wrapped);
315 return -1;
316 }
317 x = (long)PyLong_AsUnsignedLong(wrapped);
318 Py_DECREF(wrapped);
319 if (x == -1 && PyErr_Occurred())
320 return -1;
321 }
322 *p = (unsigned long)x;
323 return 0;
324}
325
326#define RANGE_ERROR(x, f, flag, mask) \
327 do { \
328 if (_range_error(f, flag) < 0) \
329 return -1; \
330 else \
331 (x) &= (mask); \
332 } while (0)
333
334#else
335
336#define get_wrapped_long get_long
337#define get_wrapped_ulong get_ulong
338#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
339
340#endif
341
Thomas Wouters477c8d52006-05-27 19:21:47 +0000342/* Floating point helpers */
343
344static PyObject *
345unpack_float(const char *p, /* start of 4-byte string */
346 int le) /* true for little-endian, false for big-endian */
347{
348 double x;
349
350 x = _PyFloat_Unpack4((unsigned char *)p, le);
351 if (x == -1.0 && PyErr_Occurred())
352 return NULL;
353 return PyFloat_FromDouble(x);
354}
355
356static PyObject *
357unpack_double(const char *p, /* start of 8-byte string */
358 int le) /* true for little-endian, false for big-endian */
359{
360 double x;
361
362 x = _PyFloat_Unpack8((unsigned char *)p, le);
363 if (x == -1.0 && PyErr_Occurred())
364 return NULL;
365 return PyFloat_FromDouble(x);
366}
367
368/* Helper to format the range error exceptions */
369static int
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000370_range_error(const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000371{
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000372 /* ulargest is the largest unsigned value with f->size bytes.
373 * Note that the simpler:
374 * ((size_t)1 << (f->size * 8)) - 1
375 * doesn't work when f->size == sizeof(size_t) because C doesn't
376 * define what happens when a left shift count is >= the number of
377 * bits in the integer being shifted; e.g., on some boxes it doesn't
378 * shift at all when they're equal.
379 */
380 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
381 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
382 if (is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000383 PyErr_Format(StructError,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000384 "'%c' format requires 0 <= number <= %zu",
385 f->format,
386 ulargest);
387 else {
388 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000389 PyErr_Format(StructError,
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000390 "'%c' format requires %zd <= number <= %zd",
391 f->format,
392 ~ largest,
Thomas Wouters477c8d52006-05-27 19:21:47 +0000393 largest);
394 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000395#ifdef PY_STRUCT_OVERFLOW_MASKING
396 {
397 PyObject *ptype, *pvalue, *ptraceback;
398 PyObject *msg;
399 int rval;
400 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
401 assert(pvalue != NULL);
402 msg = PyObject_Str(pvalue);
403 Py_XDECREF(ptype);
404 Py_XDECREF(pvalue);
405 Py_XDECREF(ptraceback);
406 if (msg == NULL)
407 return -1;
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000408 rval = PyErr_WarnEx(PyExc_DeprecationWarning,
Marc-André Lemburg4cc0f242008-08-07 18:54:33 +0000409 _PyUnicode_AsString(msg), 2);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000410 Py_DECREF(msg);
411 if (rval == 0)
412 return 0;
413 }
414#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +0000415 return -1;
416}
417
418
419
420/* A large number of small routines follow, with names of the form
421
422 [bln][up]_TYPE
423
424 [bln] distiguishes among big-endian, little-endian and native.
425 [pu] distiguishes between pack (to struct) and unpack (from struct).
426 TYPE is one of char, byte, ubyte, etc.
427*/
428
429/* Native mode routines. ****************************************************/
430/* NOTE:
431 In all n[up]_<type> routines handling types larger than 1 byte, there is
432 *no* guarantee that the p pointer is properly aligned for each type,
433 therefore memcpy is called. An intermediate variable is used to
434 compensate for big-endian architectures.
435 Normally both the intermediate variable and the memcpy call will be
436 skipped by C optimisation in little-endian architectures (gcc >= 2.91
437 does this). */
438
439static PyObject *
440nu_char(const char *p, const formatdef *f)
441{
Christian Heimes72b710a2008-05-26 13:28:38 +0000442 return PyBytes_FromStringAndSize(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000443}
444
445static PyObject *
446nu_byte(const char *p, const formatdef *f)
447{
Christian Heimes217cfd12007-12-02 14:31:20 +0000448 return PyLong_FromLong((long) *(signed char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000449}
450
451static PyObject *
452nu_ubyte(const char *p, const formatdef *f)
453{
Christian Heimes217cfd12007-12-02 14:31:20 +0000454 return PyLong_FromLong((long) *(unsigned char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000455}
456
457static PyObject *
458nu_short(const char *p, const formatdef *f)
459{
460 short x;
461 memcpy((char *)&x, p, sizeof x);
Christian Heimes217cfd12007-12-02 14:31:20 +0000462 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000463}
464
465static PyObject *
466nu_ushort(const char *p, const formatdef *f)
467{
468 unsigned short x;
469 memcpy((char *)&x, p, sizeof x);
Christian Heimes217cfd12007-12-02 14:31:20 +0000470 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000471}
472
473static PyObject *
474nu_int(const char *p, const formatdef *f)
475{
476 int x;
477 memcpy((char *)&x, p, sizeof x);
Christian Heimes217cfd12007-12-02 14:31:20 +0000478 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000479}
480
481static PyObject *
482nu_uint(const char *p, const formatdef *f)
483{
484 unsigned int x;
485 memcpy((char *)&x, p, sizeof x);
486#if (SIZEOF_LONG > SIZEOF_INT)
Christian Heimes217cfd12007-12-02 14:31:20 +0000487 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000488#else
489 if (x <= ((unsigned int)LONG_MAX))
Christian Heimes217cfd12007-12-02 14:31:20 +0000490 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000491 return PyLong_FromUnsignedLong((unsigned long)x);
492#endif
493}
494
495static PyObject *
496nu_long(const char *p, const formatdef *f)
497{
498 long x;
499 memcpy((char *)&x, p, sizeof x);
Christian Heimes217cfd12007-12-02 14:31:20 +0000500 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000501}
502
503static PyObject *
504nu_ulong(const char *p, const formatdef *f)
505{
506 unsigned long x;
507 memcpy((char *)&x, p, sizeof x);
508 if (x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000509 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000510 return PyLong_FromUnsignedLong(x);
511}
512
513/* Native mode doesn't support q or Q unless the platform C supports
514 long long (or, on Windows, __int64). */
515
516#ifdef HAVE_LONG_LONG
517
518static PyObject *
519nu_longlong(const char *p, const formatdef *f)
520{
521 PY_LONG_LONG x;
522 memcpy((char *)&x, p, sizeof x);
523 if (x >= LONG_MIN && x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000524 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000525 return PyLong_FromLongLong(x);
526}
527
528static PyObject *
529nu_ulonglong(const char *p, const formatdef *f)
530{
531 unsigned PY_LONG_LONG x;
532 memcpy((char *)&x, p, sizeof x);
533 if (x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000534 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000535 return PyLong_FromUnsignedLongLong(x);
536}
537
538#endif
539
540static PyObject *
Thomas Woutersb2137042007-02-01 18:02:27 +0000541nu_bool(const char *p, const formatdef *f)
542{
543 BOOL_TYPE x;
544 memcpy((char *)&x, p, sizeof x);
545 return PyBool_FromLong(x != 0);
546}
547
548
549static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000550nu_float(const char *p, const formatdef *f)
551{
552 float x;
553 memcpy((char *)&x, p, sizeof x);
554 return PyFloat_FromDouble((double)x);
555}
556
557static PyObject *
558nu_double(const char *p, const formatdef *f)
559{
560 double x;
561 memcpy((char *)&x, p, sizeof x);
562 return PyFloat_FromDouble(x);
563}
564
565static PyObject *
566nu_void_p(const char *p, const formatdef *f)
567{
568 void *x;
569 memcpy((char *)&x, p, sizeof x);
570 return PyLong_FromVoidPtr(x);
571}
572
573static int
574np_byte(char *p, PyObject *v, const formatdef *f)
575{
576 long x;
577 if (get_long(v, &x) < 0)
578 return -1;
579 if (x < -128 || x > 127){
580 PyErr_SetString(StructError,
581 "byte format requires -128 <= number <= 127");
582 return -1;
583 }
584 *p = (char)x;
585 return 0;
586}
587
588static int
589np_ubyte(char *p, PyObject *v, const formatdef *f)
590{
591 long x;
592 if (get_long(v, &x) < 0)
593 return -1;
594 if (x < 0 || x > 255){
595 PyErr_SetString(StructError,
596 "ubyte format requires 0 <= number <= 255");
597 return -1;
598 }
599 *p = (char)x;
600 return 0;
601}
602
603static int
604np_char(char *p, PyObject *v, const formatdef *f)
605{
Guido van Rossume625fd52007-05-27 09:19:04 +0000606 if (PyUnicode_Check(v)) {
607 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
608 if (v == NULL)
609 return -1;
610 }
Christian Heimes72b710a2008-05-26 13:28:38 +0000611 if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
Thomas Wouters477c8d52006-05-27 19:21:47 +0000612 PyErr_SetString(StructError,
Benjamin Peterson4ae19462008-07-31 15:03:40 +0000613 "char format requires bytes or string of length 1");
Thomas Wouters477c8d52006-05-27 19:21:47 +0000614 return -1;
615 }
Christian Heimes72b710a2008-05-26 13:28:38 +0000616 *p = *PyBytes_AsString(v);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000617 return 0;
618}
619
620static int
621np_short(char *p, PyObject *v, const formatdef *f)
622{
623 long x;
624 short y;
625 if (get_long(v, &x) < 0)
626 return -1;
627 if (x < SHRT_MIN || x > SHRT_MAX){
628 PyErr_SetString(StructError,
629 "short format requires " STRINGIFY(SHRT_MIN)
630 " <= number <= " STRINGIFY(SHRT_MAX));
631 return -1;
632 }
633 y = (short)x;
634 memcpy(p, (char *)&y, sizeof y);
635 return 0;
636}
637
638static int
639np_ushort(char *p, PyObject *v, const formatdef *f)
640{
641 long x;
642 unsigned short y;
643 if (get_long(v, &x) < 0)
644 return -1;
645 if (x < 0 || x > USHRT_MAX){
646 PyErr_SetString(StructError,
647 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
648 return -1;
649 }
650 y = (unsigned short)x;
651 memcpy(p, (char *)&y, sizeof y);
652 return 0;
653}
654
655static int
656np_int(char *p, PyObject *v, const formatdef *f)
657{
658 long x;
659 int y;
660 if (get_long(v, &x) < 0)
661 return -1;
662#if (SIZEOF_LONG > SIZEOF_INT)
663 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000664 return _range_error(f, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000665#endif
666 y = (int)x;
667 memcpy(p, (char *)&y, sizeof y);
668 return 0;
669}
670
671static int
672np_uint(char *p, PyObject *v, const formatdef *f)
673{
674 unsigned long x;
675 unsigned int y;
676 if (get_ulong(v, &x) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000677 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000678 y = (unsigned int)x;
679#if (SIZEOF_LONG > SIZEOF_INT)
680 if (x > ((unsigned long)UINT_MAX))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000681 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000682#endif
683 memcpy(p, (char *)&y, sizeof y);
684 return 0;
685}
686
687static int
688np_long(char *p, PyObject *v, const formatdef *f)
689{
690 long x;
691 if (get_long(v, &x) < 0)
692 return -1;
693 memcpy(p, (char *)&x, sizeof x);
694 return 0;
695}
696
697static int
698np_ulong(char *p, PyObject *v, const formatdef *f)
699{
700 unsigned long x;
701 if (get_ulong(v, &x) < 0)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000702 return _range_error(f, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000703 memcpy(p, (char *)&x, sizeof x);
704 return 0;
705}
706
707#ifdef HAVE_LONG_LONG
708
709static int
710np_longlong(char *p, PyObject *v, const formatdef *f)
711{
712 PY_LONG_LONG x;
713 if (get_longlong(v, &x) < 0)
714 return -1;
715 memcpy(p, (char *)&x, sizeof x);
716 return 0;
717}
718
719static int
720np_ulonglong(char *p, PyObject *v, const formatdef *f)
721{
722 unsigned PY_LONG_LONG x;
723 if (get_ulonglong(v, &x) < 0)
724 return -1;
725 memcpy(p, (char *)&x, sizeof x);
726 return 0;
727}
728#endif
729
Thomas Woutersb2137042007-02-01 18:02:27 +0000730
731static int
732np_bool(char *p, PyObject *v, const formatdef *f)
733{
734 BOOL_TYPE y;
735 y = PyObject_IsTrue(v);
736 memcpy(p, (char *)&y, sizeof y);
737 return 0;
738}
739
Thomas Wouters477c8d52006-05-27 19:21:47 +0000740static int
741np_float(char *p, PyObject *v, const formatdef *f)
742{
743 float x = (float)PyFloat_AsDouble(v);
744 if (x == -1 && PyErr_Occurred()) {
745 PyErr_SetString(StructError,
746 "required argument is not a float");
747 return -1;
748 }
749 memcpy(p, (char *)&x, sizeof x);
750 return 0;
751}
752
753static int
754np_double(char *p, PyObject *v, const formatdef *f)
755{
756 double x = PyFloat_AsDouble(v);
757 if (x == -1 && PyErr_Occurred()) {
758 PyErr_SetString(StructError,
759 "required argument is not a float");
760 return -1;
761 }
762 memcpy(p, (char *)&x, sizeof(double));
763 return 0;
764}
765
766static int
767np_void_p(char *p, PyObject *v, const formatdef *f)
768{
769 void *x;
770
771 v = get_pylong(v);
772 if (v == NULL)
773 return -1;
774 assert(PyLong_Check(v));
775 x = PyLong_AsVoidPtr(v);
776 Py_DECREF(v);
777 if (x == NULL && PyErr_Occurred())
778 return -1;
779 memcpy(p, (char *)&x, sizeof x);
780 return 0;
781}
782
783static formatdef native_table[] = {
784 {'x', sizeof(char), 0, NULL},
785 {'b', sizeof(char), 0, nu_byte, np_byte},
786 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
787 {'c', sizeof(char), 0, nu_char, np_char},
788 {'s', sizeof(char), 0, NULL},
789 {'p', sizeof(char), 0, NULL},
790 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
791 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
792 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
793 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
794 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
795 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
796#ifdef HAVE_LONG_LONG
797 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
798 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
799#endif
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000800 {'?', sizeof(BOOL_TYPE), BOOL_ALIGN, nu_bool, np_bool},
Thomas Wouters477c8d52006-05-27 19:21:47 +0000801 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
802 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
803 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
804 {0}
805};
806
807/* Big-endian routines. *****************************************************/
808
809static PyObject *
810bu_int(const char *p, const formatdef *f)
811{
812 long x = 0;
813 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000814 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000815 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000816 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000817 } while (--i > 0);
818 /* Extend the sign bit. */
819 if (SIZEOF_LONG > f->size)
820 x |= -(x & (1L << ((8 * f->size) - 1)));
Christian Heimes217cfd12007-12-02 14:31:20 +0000821 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000822}
823
824static PyObject *
825bu_uint(const char *p, const formatdef *f)
826{
827 unsigned long x = 0;
828 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000829 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000830 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000831 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000832 } while (--i > 0);
833 if (x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000834 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000835 return PyLong_FromUnsignedLong(x);
836}
837
838static PyObject *
839bu_longlong(const char *p, const formatdef *f)
840{
841#ifdef HAVE_LONG_LONG
842 PY_LONG_LONG x = 0;
843 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000844 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000845 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000846 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000847 } while (--i > 0);
848 /* Extend the sign bit. */
849 if (SIZEOF_LONG_LONG > f->size)
Guido van Rossumd8faa362007-04-27 19:54:29 +0000850 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000851 if (x >= LONG_MIN && x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000852 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000853 return PyLong_FromLongLong(x);
854#else
855 return _PyLong_FromByteArray((const unsigned char *)p,
856 8,
857 0, /* little-endian */
858 1 /* signed */);
859#endif
860}
861
862static PyObject *
863bu_ulonglong(const char *p, const formatdef *f)
864{
865#ifdef HAVE_LONG_LONG
866 unsigned PY_LONG_LONG x = 0;
867 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000868 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000869 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000870 x = (x<<8) | *bytes++;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000871 } while (--i > 0);
872 if (x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +0000873 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Thomas Wouters477c8d52006-05-27 19:21:47 +0000874 return PyLong_FromUnsignedLongLong(x);
875#else
876 return _PyLong_FromByteArray((const unsigned char *)p,
877 8,
878 0, /* little-endian */
879 0 /* signed */);
880#endif
881}
882
883static PyObject *
884bu_float(const char *p, const formatdef *f)
885{
886 return unpack_float(p, 0);
887}
888
889static PyObject *
890bu_double(const char *p, const formatdef *f)
891{
892 return unpack_double(p, 0);
893}
894
Thomas Woutersb2137042007-02-01 18:02:27 +0000895static PyObject *
896bu_bool(const char *p, const formatdef *f)
897{
898 char x;
899 memcpy((char *)&x, p, sizeof x);
900 return PyBool_FromLong(x != 0);
901}
902
Thomas Wouters477c8d52006-05-27 19:21:47 +0000903static int
904bp_int(char *p, PyObject *v, const formatdef *f)
905{
906 long x;
907 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000908 if (get_wrapped_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000909 return -1;
910 i = f->size;
911 if (i != SIZEOF_LONG) {
912 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000913 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000914#if (SIZEOF_LONG != 4)
915 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000916 RANGE_ERROR(x, f, 0, 0xffffffffL);
917#endif
918#ifdef PY_STRUCT_OVERFLOW_MASKING
919 else if ((i == 1) && (x < -128 || x > 127))
920 RANGE_ERROR(x, f, 0, 0xffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000921#endif
922 }
923 do {
924 p[--i] = (char)x;
925 x >>= 8;
926 } while (i > 0);
927 return 0;
928}
929
930static int
931bp_uint(char *p, PyObject *v, const formatdef *f)
932{
933 unsigned long x;
934 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000935 if (get_wrapped_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000936 return -1;
937 i = f->size;
938 if (i != SIZEOF_LONG) {
939 unsigned long maxint = 1;
940 maxint <<= (unsigned long)(i * 8);
941 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000942 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000943 }
944 do {
945 p[--i] = (char)x;
946 x >>= 8;
947 } while (i > 0);
948 return 0;
949}
950
951static int
952bp_longlong(char *p, PyObject *v, const formatdef *f)
953{
954 int res;
955 v = get_pylong(v);
956 if (v == NULL)
957 return -1;
958 res = _PyLong_AsByteArray((PyLongObject *)v,
959 (unsigned char *)p,
960 8,
961 0, /* little_endian */
962 1 /* signed */);
963 Py_DECREF(v);
964 return res;
965}
966
967static int
968bp_ulonglong(char *p, PyObject *v, const formatdef *f)
969{
970 int res;
971 v = get_pylong(v);
972 if (v == NULL)
973 return -1;
974 res = _PyLong_AsByteArray((PyLongObject *)v,
975 (unsigned char *)p,
976 8,
977 0, /* little_endian */
978 0 /* signed */);
979 Py_DECREF(v);
980 return res;
981}
982
983static int
984bp_float(char *p, PyObject *v, const formatdef *f)
985{
986 double x = PyFloat_AsDouble(v);
987 if (x == -1 && PyErr_Occurred()) {
988 PyErr_SetString(StructError,
989 "required argument is not a float");
990 return -1;
991 }
992 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
993}
994
995static int
996bp_double(char *p, PyObject *v, const formatdef *f)
997{
998 double x = PyFloat_AsDouble(v);
999 if (x == -1 && PyErr_Occurred()) {
1000 PyErr_SetString(StructError,
1001 "required argument is not a float");
1002 return -1;
1003 }
1004 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
1005}
1006
Thomas Woutersb2137042007-02-01 18:02:27 +00001007static int
1008bp_bool(char *p, PyObject *v, const formatdef *f)
1009{
1010 char y;
1011 y = PyObject_IsTrue(v);
1012 memcpy(p, (char *)&y, sizeof y);
1013 return 0;
1014}
1015
Thomas Wouters477c8d52006-05-27 19:21:47 +00001016static formatdef bigendian_table[] = {
1017 {'x', 1, 0, NULL},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001018#ifdef PY_STRUCT_OVERFLOW_MASKING
1019 /* Native packers do range checking without overflow masking. */
1020 {'b', 1, 0, nu_byte, bp_int},
1021 {'B', 1, 0, nu_ubyte, bp_uint},
1022#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001023 {'b', 1, 0, nu_byte, np_byte},
1024 {'B', 1, 0, nu_ubyte, np_ubyte},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001025#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001026 {'c', 1, 0, nu_char, np_char},
1027 {'s', 1, 0, NULL},
1028 {'p', 1, 0, NULL},
1029 {'h', 2, 0, bu_int, bp_int},
1030 {'H', 2, 0, bu_uint, bp_uint},
1031 {'i', 4, 0, bu_int, bp_int},
1032 {'I', 4, 0, bu_uint, bp_uint},
1033 {'l', 4, 0, bu_int, bp_int},
1034 {'L', 4, 0, bu_uint, bp_uint},
1035 {'q', 8, 0, bu_longlong, bp_longlong},
1036 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001037 {'?', 1, 0, bu_bool, bp_bool},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001038 {'f', 4, 0, bu_float, bp_float},
1039 {'d', 8, 0, bu_double, bp_double},
1040 {0}
1041};
1042
1043/* Little-endian routines. *****************************************************/
1044
1045static PyObject *
1046lu_int(const char *p, const formatdef *f)
1047{
1048 long x = 0;
1049 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001050 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001051 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001052 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001053 } while (i > 0);
1054 /* Extend the sign bit. */
1055 if (SIZEOF_LONG > f->size)
1056 x |= -(x & (1L << ((8 * f->size) - 1)));
Christian Heimes217cfd12007-12-02 14:31:20 +00001057 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001058}
1059
1060static PyObject *
1061lu_uint(const char *p, const formatdef *f)
1062{
1063 unsigned long x = 0;
1064 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001065 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001066 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001067 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001068 } while (i > 0);
1069 if (x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +00001070 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001071 return PyLong_FromUnsignedLong((long)x);
1072}
1073
1074static PyObject *
1075lu_longlong(const char *p, const formatdef *f)
1076{
1077#ifdef HAVE_LONG_LONG
1078 PY_LONG_LONG x = 0;
1079 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001080 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001081 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001082 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001083 } while (i > 0);
1084 /* Extend the sign bit. */
1085 if (SIZEOF_LONG_LONG > f->size)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001086 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001087 if (x >= LONG_MIN && x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +00001088 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001089 return PyLong_FromLongLong(x);
1090#else
1091 return _PyLong_FromByteArray((const unsigned char *)p,
1092 8,
1093 1, /* little-endian */
1094 1 /* signed */);
1095#endif
1096}
1097
1098static PyObject *
1099lu_ulonglong(const char *p, const formatdef *f)
1100{
1101#ifdef HAVE_LONG_LONG
1102 unsigned PY_LONG_LONG x = 0;
1103 Py_ssize_t i = f->size;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001104 const unsigned char *bytes = (const unsigned char *)p;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001105 do {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001106 x = (x<<8) | bytes[--i];
Thomas Wouters477c8d52006-05-27 19:21:47 +00001107 } while (i > 0);
1108 if (x <= LONG_MAX)
Christian Heimes217cfd12007-12-02 14:31:20 +00001109 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001110 return PyLong_FromUnsignedLongLong(x);
1111#else
1112 return _PyLong_FromByteArray((const unsigned char *)p,
1113 8,
1114 1, /* little-endian */
1115 0 /* signed */);
1116#endif
1117}
1118
1119static PyObject *
1120lu_float(const char *p, const formatdef *f)
1121{
1122 return unpack_float(p, 1);
1123}
1124
1125static PyObject *
1126lu_double(const char *p, const formatdef *f)
1127{
1128 return unpack_double(p, 1);
1129}
1130
1131static int
1132lp_int(char *p, PyObject *v, const formatdef *f)
1133{
1134 long x;
1135 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001136 if (get_wrapped_long(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001137 return -1;
1138 i = f->size;
1139 if (i != SIZEOF_LONG) {
1140 if ((i == 2) && (x < -32768 || x > 32767))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001141 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001142#if (SIZEOF_LONG != 4)
1143 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001144 RANGE_ERROR(x, f, 0, 0xffffffffL);
1145#endif
1146#ifdef PY_STRUCT_OVERFLOW_MASKING
1147 else if ((i == 1) && (x < -128 || x > 127))
1148 RANGE_ERROR(x, f, 0, 0xffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001149#endif
1150 }
1151 do {
1152 *p++ = (char)x;
1153 x >>= 8;
1154 } while (--i > 0);
1155 return 0;
1156}
1157
1158static int
1159lp_uint(char *p, PyObject *v, const formatdef *f)
1160{
1161 unsigned long x;
1162 Py_ssize_t i;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001163 if (get_wrapped_ulong(v, &x) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001164 return -1;
1165 i = f->size;
1166 if (i != SIZEOF_LONG) {
1167 unsigned long maxint = 1;
1168 maxint <<= (unsigned long)(i * 8);
1169 if (x >= maxint)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001170 RANGE_ERROR(x, f, 1, maxint - 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001171 }
1172 do {
1173 *p++ = (char)x;
1174 x >>= 8;
1175 } while (--i > 0);
1176 return 0;
1177}
1178
1179static int
1180lp_longlong(char *p, PyObject *v, const formatdef *f)
1181{
1182 int res;
1183 v = get_pylong(v);
1184 if (v == NULL)
1185 return -1;
1186 res = _PyLong_AsByteArray((PyLongObject*)v,
1187 (unsigned char *)p,
1188 8,
1189 1, /* little_endian */
1190 1 /* signed */);
1191 Py_DECREF(v);
1192 return res;
1193}
1194
1195static int
1196lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1197{
1198 int res;
1199 v = get_pylong(v);
1200 if (v == NULL)
1201 return -1;
1202 res = _PyLong_AsByteArray((PyLongObject*)v,
1203 (unsigned char *)p,
1204 8,
1205 1, /* little_endian */
1206 0 /* signed */);
1207 Py_DECREF(v);
1208 return res;
1209}
1210
1211static int
1212lp_float(char *p, PyObject *v, const formatdef *f)
1213{
1214 double x = PyFloat_AsDouble(v);
1215 if (x == -1 && PyErr_Occurred()) {
1216 PyErr_SetString(StructError,
1217 "required argument is not a float");
1218 return -1;
1219 }
1220 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1221}
1222
1223static int
1224lp_double(char *p, PyObject *v, const formatdef *f)
1225{
1226 double x = PyFloat_AsDouble(v);
1227 if (x == -1 && PyErr_Occurred()) {
1228 PyErr_SetString(StructError,
1229 "required argument is not a float");
1230 return -1;
1231 }
1232 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1233}
1234
1235static formatdef lilendian_table[] = {
1236 {'x', 1, 0, NULL},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001237#ifdef PY_STRUCT_OVERFLOW_MASKING
1238 /* Native packers do range checking without overflow masking. */
1239 {'b', 1, 0, nu_byte, lp_int},
1240 {'B', 1, 0, nu_ubyte, lp_uint},
1241#else
Thomas Wouters477c8d52006-05-27 19:21:47 +00001242 {'b', 1, 0, nu_byte, np_byte},
1243 {'B', 1, 0, nu_ubyte, np_ubyte},
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001244#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00001245 {'c', 1, 0, nu_char, np_char},
1246 {'s', 1, 0, NULL},
1247 {'p', 1, 0, NULL},
1248 {'h', 2, 0, lu_int, lp_int},
1249 {'H', 2, 0, lu_uint, lp_uint},
1250 {'i', 4, 0, lu_int, lp_int},
1251 {'I', 4, 0, lu_uint, lp_uint},
1252 {'l', 4, 0, lu_int, lp_int},
1253 {'L', 4, 0, lu_uint, lp_uint},
1254 {'q', 8, 0, lu_longlong, lp_longlong},
1255 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
Christian Heimesdd15f6c2008-03-16 00:07:10 +00001256 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
Thomas Woutersb2137042007-02-01 18:02:27 +00001257 but potentially different from native rep -- reuse bx_bool funcs. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001258 {'f', 4, 0, lu_float, lp_float},
1259 {'d', 8, 0, lu_double, lp_double},
1260 {0}
1261};
1262
1263
1264static const formatdef *
1265whichtable(char **pfmt)
1266{
1267 const char *fmt = (*pfmt)++; /* May be backed out of later */
1268 switch (*fmt) {
1269 case '<':
1270 return lilendian_table;
1271 case '>':
1272 case '!': /* Network byte order is big-endian */
1273 return bigendian_table;
1274 case '=': { /* Host byte order -- different from native in aligment! */
1275 int n = 1;
1276 char *p = (char *) &n;
1277 if (*p == 1)
1278 return lilendian_table;
1279 else
1280 return bigendian_table;
1281 }
1282 default:
1283 --*pfmt; /* Back out of pointer increment */
1284 /* Fall through */
1285 case '@':
1286 return native_table;
1287 }
1288}
1289
1290
1291/* Get the table entry for a format code */
1292
1293static const formatdef *
1294getentry(int c, const formatdef *f)
1295{
1296 for (; f->format != '\0'; f++) {
1297 if (f->format == c) {
1298 return f;
1299 }
1300 }
1301 PyErr_SetString(StructError, "bad char in struct format");
1302 return NULL;
1303}
1304
1305
1306/* Align a size according to a format code */
1307
1308static int
1309align(Py_ssize_t size, char c, const formatdef *e)
1310{
1311 if (e->format == c) {
1312 if (e->alignment) {
1313 size = ((size + e->alignment - 1)
1314 / e->alignment)
1315 * e->alignment;
1316 }
1317 }
1318 return size;
1319}
1320
1321
1322/* calculate the size of a format string */
1323
1324static int
1325prepare_s(PyStructObject *self)
1326{
1327 const formatdef *f;
1328 const formatdef *e;
1329 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001330
Thomas Wouters477c8d52006-05-27 19:21:47 +00001331 const char *s;
1332 const char *fmt;
1333 char c;
1334 Py_ssize_t size, len, num, itemsize, x;
1335
Christian Heimes72b710a2008-05-26 13:28:38 +00001336 fmt = PyBytes_AS_STRING(self->s_format);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001337
1338 f = whichtable((char **)&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001339
Thomas Wouters477c8d52006-05-27 19:21:47 +00001340 s = fmt;
1341 size = 0;
1342 len = 0;
1343 while ((c = *s++) != '\0') {
1344 if (isspace(Py_CHARMASK(c)))
1345 continue;
1346 if ('0' <= c && c <= '9') {
1347 num = c - '0';
1348 while ('0' <= (c = *s++) && c <= '9') {
1349 x = num*10 + (c - '0');
1350 if (x/10 != num) {
1351 PyErr_SetString(
1352 StructError,
1353 "overflow in item count");
1354 return -1;
1355 }
1356 num = x;
1357 }
1358 if (c == '\0')
1359 break;
1360 }
1361 else
1362 num = 1;
1363
1364 e = getentry(c, f);
1365 if (e == NULL)
1366 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001367
Thomas Wouters477c8d52006-05-27 19:21:47 +00001368 switch (c) {
1369 case 's': /* fall through */
1370 case 'p': len++; break;
1371 case 'x': break;
1372 default: len += num; break;
1373 }
1374
1375 itemsize = e->size;
1376 size = align(size, c, e);
1377 x = num * itemsize;
1378 size += x;
1379 if (x/itemsize != num || size < 0) {
1380 PyErr_SetString(StructError,
1381 "total struct size too long");
1382 return -1;
1383 }
1384 }
1385
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +00001386 /* check for overflow */
1387 if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {
1388 PyErr_NoMemory();
1389 return -1;
1390 }
1391
Thomas Wouters477c8d52006-05-27 19:21:47 +00001392 self->s_size = size;
1393 self->s_len = len;
1394 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1395 if (codes == NULL) {
1396 PyErr_NoMemory();
1397 return -1;
1398 }
1399 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001400
Thomas Wouters477c8d52006-05-27 19:21:47 +00001401 s = fmt;
1402 size = 0;
1403 while ((c = *s++) != '\0') {
1404 if (isspace(Py_CHARMASK(c)))
1405 continue;
1406 if ('0' <= c && c <= '9') {
1407 num = c - '0';
1408 while ('0' <= (c = *s++) && c <= '9')
1409 num = num*10 + (c - '0');
1410 if (c == '\0')
1411 break;
1412 }
1413 else
1414 num = 1;
1415
1416 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001417
Thomas Wouters477c8d52006-05-27 19:21:47 +00001418 size = align(size, c, e);
1419 if (c == 's' || c == 'p') {
1420 codes->offset = size;
1421 codes->size = num;
1422 codes->fmtdef = e;
1423 codes++;
1424 size += num;
1425 } else if (c == 'x') {
1426 size += num;
1427 } else {
1428 while (--num >= 0) {
1429 codes->offset = size;
1430 codes->size = e->size;
1431 codes->fmtdef = e;
1432 codes++;
1433 size += e->size;
1434 }
1435 }
1436 }
1437 codes->fmtdef = NULL;
1438 codes->offset = size;
1439 codes->size = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001440
Thomas Wouters477c8d52006-05-27 19:21:47 +00001441 return 0;
1442}
1443
1444static PyObject *
1445s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1446{
1447 PyObject *self;
1448
1449 assert(type != NULL && type->tp_alloc != NULL);
1450
1451 self = type->tp_alloc(type, 0);
1452 if (self != NULL) {
1453 PyStructObject *s = (PyStructObject*)self;
1454 Py_INCREF(Py_None);
1455 s->s_format = Py_None;
1456 s->s_codes = NULL;
1457 s->s_size = -1;
1458 s->s_len = -1;
1459 }
1460 return self;
1461}
1462
1463static int
1464s_init(PyObject *self, PyObject *args, PyObject *kwds)
1465{
1466 PyStructObject *soself = (PyStructObject *)self;
1467 PyObject *o_format = NULL;
1468 int ret = 0;
1469 static char *kwlist[] = {"format", 0};
1470
1471 assert(PyStruct_Check(self));
1472
Christian Heimesa34706f2008-01-04 03:06:10 +00001473 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Struct", kwlist,
Thomas Wouters477c8d52006-05-27 19:21:47 +00001474 &o_format))
1475 return -1;
1476
Christian Heimesa34706f2008-01-04 03:06:10 +00001477 if (PyUnicode_Check(o_format)) {
1478 o_format = PyUnicode_AsASCIIString(o_format);
1479 if (o_format == NULL)
1480 return -1;
1481 }
1482 /* XXX support buffer interface, too */
1483 else {
1484 Py_INCREF(o_format);
1485 }
1486
Christian Heimes72b710a2008-05-26 13:28:38 +00001487 if (!PyBytes_Check(o_format)) {
Christian Heimesa34706f2008-01-04 03:06:10 +00001488 Py_DECREF(o_format);
1489 PyErr_Format(PyExc_TypeError,
1490 "Struct() argument 1 must be bytes, not %.200s",
1491 Py_TYPE(o_format)->tp_name);
1492 return -1;
1493 }
1494
Christian Heimes18c66892008-02-17 13:31:39 +00001495 Py_CLEAR(soself->s_format);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001496 soself->s_format = o_format;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001497
Thomas Wouters477c8d52006-05-27 19:21:47 +00001498 ret = prepare_s(soself);
1499 return ret;
1500}
1501
1502static void
1503s_dealloc(PyStructObject *s)
1504{
1505 if (s->weakreflist != NULL)
1506 PyObject_ClearWeakRefs((PyObject *)s);
1507 if (s->s_codes != NULL) {
1508 PyMem_FREE(s->s_codes);
1509 }
1510 Py_XDECREF(s->s_format);
Christian Heimes90aa7642007-12-19 02:45:37 +00001511 Py_TYPE(s)->tp_free((PyObject *)s);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001512}
1513
1514static PyObject *
1515s_unpack_internal(PyStructObject *soself, char *startfrom) {
1516 formatcode *code;
1517 Py_ssize_t i = 0;
1518 PyObject *result = PyTuple_New(soself->s_len);
1519 if (result == NULL)
1520 return NULL;
1521
1522 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1523 PyObject *v;
1524 const formatdef *e = code->fmtdef;
1525 const char *res = startfrom + code->offset;
1526 if (e->format == 's') {
Christian Heimes72b710a2008-05-26 13:28:38 +00001527 v = PyBytes_FromStringAndSize(res, code->size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001528 } else if (e->format == 'p') {
1529 Py_ssize_t n = *(unsigned char*)res;
1530 if (n >= code->size)
1531 n = code->size - 1;
Christian Heimes72b710a2008-05-26 13:28:38 +00001532 v = PyBytes_FromStringAndSize(res + 1, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001533 } else {
1534 v = e->unpack(res, e);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001536 if (v == NULL)
1537 goto fail;
1538 PyTuple_SET_ITEM(result, i++, v);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001539 }
1540
1541 return result;
1542fail:
1543 Py_DECREF(result);
1544 return NULL;
1545}
1546
1547
1548PyDoc_STRVAR(s_unpack__doc__,
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001549"S.unpack(buffer) -> (v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001550\n\
1551Return tuple containing values unpacked according to this Struct's format.\n\
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001552Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001553strings.");
1554
1555static PyObject *
Guido van Rossum98297ee2007-11-06 21:34:58 +00001556s_unpack(PyObject *self, PyObject *input)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001557{
Guido van Rossum98297ee2007-11-06 21:34:58 +00001558 Py_buffer vbuf;
1559 PyObject *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001560 PyStructObject *soself = (PyStructObject *)self;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001561
Thomas Wouters477c8d52006-05-27 19:21:47 +00001562 assert(PyStruct_Check(self));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001563 assert(soself->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001564 if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001565 return NULL;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001566 if (vbuf.len != soself->s_size) {
1567 PyErr_Format(StructError,
1568 "unpack requires a bytes argument of length %zd",
1569 soself->s_size);
Martin v. Löwis423be952008-08-13 15:53:07 +00001570 PyBuffer_Release(&vbuf);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001571 return NULL;
1572 }
1573 result = s_unpack_internal(soself, vbuf.buf);
Martin v. Löwis423be952008-08-13 15:53:07 +00001574 PyBuffer_Release(&vbuf);
Guido van Rossumd8faa362007-04-27 19:54:29 +00001575 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001576}
1577
1578PyDoc_STRVAR(s_unpack_from__doc__,
1579"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1580\n\
1581Return tuple containing values unpacked according to this Struct's format.\n\
1582Unlike unpack, unpack_from can unpack values from any object supporting\n\
1583the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1584See struct.__doc__ for more on format strings.");
1585
1586static PyObject *
1587s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1588{
1589 static char *kwlist[] = {"buffer", "offset", 0};
Guido van Rossum98297ee2007-11-06 21:34:58 +00001590
1591 PyObject *input;
1592 Py_ssize_t offset = 0;
1593 Py_buffer vbuf;
1594 PyObject *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001595 PyStructObject *soself = (PyStructObject *)self;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001596
Thomas Wouters477c8d52006-05-27 19:21:47 +00001597 assert(PyStruct_Check(self));
1598 assert(soself->s_codes != NULL);
1599
Guido van Rossum98297ee2007-11-06 21:34:58 +00001600 if (!PyArg_ParseTupleAndKeywords(args, kwds,
1601 "O|n:unpack_from", kwlist,
1602 &input, &offset))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001603 return NULL;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001604 if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001605 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001606 if (offset < 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001607 offset += vbuf.len;
1608 if (offset < 0 || vbuf.len - offset < soself->s_size) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001609 PyErr_Format(StructError,
1610 "unpack_from requires a buffer of at least %zd bytes",
1611 soself->s_size);
Martin v. Löwis423be952008-08-13 15:53:07 +00001612 PyBuffer_Release(&vbuf);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001613 return NULL;
1614 }
Guido van Rossum98297ee2007-11-06 21:34:58 +00001615 result = s_unpack_internal(soself, (char*)vbuf.buf + offset);
Martin v. Löwis423be952008-08-13 15:53:07 +00001616 PyBuffer_Release(&vbuf);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001617 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001618}
1619
1620
1621/*
1622 * Guts of the pack function.
1623 *
1624 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1625 * argument for where to start processing the arguments for packing, and a
1626 * character buffer for writing the packed string. The caller must insure
1627 * that the buffer may contain the required length for packing the arguments.
1628 * 0 is returned on success, 1 is returned if there is an error.
1629 *
1630 */
1631static int
1632s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1633{
1634 formatcode *code;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001635 /* XXX(nnorwitz): why does i need to be a local? can we use
1636 the offset parameter or do we need the wider width? */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001637 Py_ssize_t i;
1638
1639 memset(buf, '\0', soself->s_size);
1640 i = offset;
1641 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1642 Py_ssize_t n;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001643 PyObject *v = PyTuple_GET_ITEM(args, i++);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001644 const formatdef *e = code->fmtdef;
1645 char *res = buf + code->offset;
1646 if (e->format == 's') {
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001647 int isstring;
1648 void *p;
1649 if (PyUnicode_Check(v)) {
1650 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
1651 if (v == NULL)
1652 return -1;
1653 }
Christian Heimes72b710a2008-05-26 13:28:38 +00001654 isstring = PyBytes_Check(v);
Christian Heimes9c4756e2008-05-26 13:22:05 +00001655 if (!isstring && !PyByteArray_Check(v)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001656 PyErr_SetString(StructError,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001657 "argument for 's' must be a bytes or string");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001658 return -1;
1659 }
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001660 if (isstring) {
Christian Heimes72b710a2008-05-26 13:28:38 +00001661 n = PyBytes_GET_SIZE(v);
1662 p = PyBytes_AS_STRING(v);
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001663 }
1664 else {
Christian Heimes9c4756e2008-05-26 13:22:05 +00001665 n = PyByteArray_GET_SIZE(v);
1666 p = PyByteArray_AS_STRING(v);
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001667 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001668 if (n > code->size)
1669 n = code->size;
1670 if (n > 0)
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001671 memcpy(res, p, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001672 } else if (e->format == 'p') {
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001673 int isstring;
1674 void *p;
1675 if (PyUnicode_Check(v)) {
1676 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
1677 if (v == NULL)
1678 return -1;
1679 }
Christian Heimes72b710a2008-05-26 13:28:38 +00001680 isstring = PyBytes_Check(v);
Christian Heimes9c4756e2008-05-26 13:22:05 +00001681 if (!isstring && !PyByteArray_Check(v)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001682 PyErr_SetString(StructError,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001683 "argument for 'p' must be a bytes or string");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001684 return -1;
1685 }
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001686 if (isstring) {
Christian Heimes72b710a2008-05-26 13:28:38 +00001687 n = PyBytes_GET_SIZE(v);
1688 p = PyBytes_AS_STRING(v);
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001689 }
1690 else {
Christian Heimes9c4756e2008-05-26 13:22:05 +00001691 n = PyByteArray_GET_SIZE(v);
1692 p = PyByteArray_AS_STRING(v);
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001693 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001694 if (n > (code->size - 1))
1695 n = code->size - 1;
1696 if (n > 0)
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001697 memcpy(res + 1, p, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001698 if (n > 255)
1699 n = 255;
1700 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1701 } else {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001702 if (e->pack(res, v, e) < 0) {
1703 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1704 PyErr_SetString(StructError,
1705 "long too large to convert to int");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001706 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001707 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001708 }
1709 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001710
Thomas Wouters477c8d52006-05-27 19:21:47 +00001711 /* Success */
1712 return 0;
1713}
1714
1715
1716PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001717"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001718\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001719Return a bytes containing values v1, v2, ... packed according to this\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001720Struct's format. See struct.__doc__ for more on format strings.");
1721
1722static PyObject *
1723s_pack(PyObject *self, PyObject *args)
1724{
1725 PyStructObject *soself;
1726 PyObject *result;
1727
1728 /* Validate arguments. */
1729 soself = (PyStructObject *)self;
1730 assert(PyStruct_Check(self));
1731 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001732 if (PyTuple_GET_SIZE(args) != soself->s_len)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001733 {
1734 PyErr_Format(StructError,
1735 "pack requires exactly %zd arguments", soself->s_len);
1736 return NULL;
1737 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001738
Thomas Wouters477c8d52006-05-27 19:21:47 +00001739 /* Allocate a new string */
Christian Heimes72b710a2008-05-26 13:28:38 +00001740 result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001741 if (result == NULL)
1742 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001743
Thomas Wouters477c8d52006-05-27 19:21:47 +00001744 /* Call the guts */
Christian Heimes72b710a2008-05-26 13:28:38 +00001745 if ( s_pack_internal(soself, args, 0, PyBytes_AS_STRING(result)) != 0 ) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001746 Py_DECREF(result);
1747 return NULL;
1748 }
1749
1750 return result;
1751}
1752
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001753PyDoc_STRVAR(s_pack_into__doc__,
1754"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001755\n\
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001756Pack the values v1, v2, ... according to this Struct's format, write \n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001757the packed bytes into the writable buffer buf starting at offset. Note\n\
1758that the offset is not an optional argument. See struct.__doc__ for \n\
1759more on format strings.");
1760
1761static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001762s_pack_into(PyObject *self, PyObject *args)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001763{
1764 PyStructObject *soself;
1765 char *buffer;
1766 Py_ssize_t buffer_len, offset;
1767
1768 /* Validate arguments. +1 is for the first arg as buffer. */
1769 soself = (PyStructObject *)self;
1770 assert(PyStruct_Check(self));
1771 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001772 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001773 {
1774 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001775 "pack_into requires exactly %zd arguments",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001776 (soself->s_len + 2));
1777 return NULL;
1778 }
1779
1780 /* Extract a writable memory buffer from the first argument */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001781 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1782 (void**)&buffer, &buffer_len) == -1 ) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001783 return NULL;
1784 }
1785 assert( buffer_len >= 0 );
1786
1787 /* Extract the offset from the first argument */
Christian Heimes217cfd12007-12-02 14:31:20 +00001788 offset = PyLong_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Benjamin Petersona8a93042008-09-30 02:18:09 +00001789 if (offset == -1 && PyErr_Occurred())
1790 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001791
1792 /* Support negative offsets. */
1793 if (offset < 0)
1794 offset += buffer_len;
1795
1796 /* Check boundaries */
1797 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1798 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001799 "pack_into requires a buffer of at least %zd bytes",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001800 soself->s_size);
1801 return NULL;
1802 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001803
Thomas Wouters477c8d52006-05-27 19:21:47 +00001804 /* Call the guts */
1805 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1806 return NULL;
1807 }
1808
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001809 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001810}
1811
1812static PyObject *
1813s_get_format(PyStructObject *self, void *unused)
1814{
1815 Py_INCREF(self->s_format);
1816 return self->s_format;
1817}
1818
1819static PyObject *
1820s_get_size(PyStructObject *self, void *unused)
1821{
Christian Heimes217cfd12007-12-02 14:31:20 +00001822 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001823}
1824
1825/* List of functions */
1826
1827static struct PyMethodDef s_methods[] = {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001828 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1829 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1830 {"unpack", s_unpack, METH_O, s_unpack__doc__},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00001831 {"unpack_from", (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001832 s_unpack_from__doc__},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001833 {NULL, NULL} /* sentinel */
1834};
1835
1836PyDoc_STRVAR(s__doc__, "Compiled struct object");
1837
1838#define OFF(x) offsetof(PyStructObject, x)
1839
1840static PyGetSetDef s_getsetlist[] = {
1841 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1842 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1843 {NULL} /* sentinel */
1844};
1845
1846static
1847PyTypeObject PyStructType = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001848 PyVarObject_HEAD_INIT(NULL, 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001849 "Struct",
1850 sizeof(PyStructObject),
1851 0,
1852 (destructor)s_dealloc, /* tp_dealloc */
1853 0, /* tp_print */
1854 0, /* tp_getattr */
1855 0, /* tp_setattr */
1856 0, /* tp_compare */
1857 0, /* tp_repr */
1858 0, /* tp_as_number */
1859 0, /* tp_as_sequence */
1860 0, /* tp_as_mapping */
1861 0, /* tp_hash */
1862 0, /* tp_call */
1863 0, /* tp_str */
1864 PyObject_GenericGetAttr, /* tp_getattro */
1865 PyObject_GenericSetAttr, /* tp_setattro */
1866 0, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +00001867 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001868 s__doc__, /* tp_doc */
1869 0, /* tp_traverse */
1870 0, /* tp_clear */
1871 0, /* tp_richcompare */
1872 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1873 0, /* tp_iter */
1874 0, /* tp_iternext */
1875 s_methods, /* tp_methods */
1876 NULL, /* tp_members */
1877 s_getsetlist, /* tp_getset */
1878 0, /* tp_base */
1879 0, /* tp_dict */
1880 0, /* tp_descr_get */
1881 0, /* tp_descr_set */
1882 0, /* tp_dictoffset */
1883 s_init, /* tp_init */
1884 PyType_GenericAlloc,/* tp_alloc */
1885 s_new, /* tp_new */
1886 PyObject_Del, /* tp_free */
1887};
1888
Christian Heimesa34706f2008-01-04 03:06:10 +00001889
1890/* ---- Standalone functions ---- */
1891
1892#define MAXCACHE 100
1893static PyObject *cache = NULL;
1894
1895static PyObject *
1896cache_struct(PyObject *fmt)
1897{
1898 PyObject * s_object;
1899
1900 if (cache == NULL) {
1901 cache = PyDict_New();
1902 if (cache == NULL)
1903 return NULL;
1904 }
1905
1906 s_object = PyDict_GetItem(cache, fmt);
1907 if (s_object != NULL) {
1908 Py_INCREF(s_object);
1909 return s_object;
1910 }
1911
1912 s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
1913 if (s_object != NULL) {
1914 if (PyDict_Size(cache) >= MAXCACHE)
1915 PyDict_Clear(cache);
1916 /* Attempt to cache the result */
1917 if (PyDict_SetItem(cache, fmt, s_object) == -1)
1918 PyErr_Clear();
1919 }
1920 return s_object;
1921}
1922
1923PyDoc_STRVAR(clearcache_doc,
1924"Clear the internal cache.");
1925
1926static PyObject *
1927clearcache(PyObject *self)
1928{
Christian Heimes679db4a2008-01-18 09:56:22 +00001929 Py_CLEAR(cache);
Christian Heimesa34706f2008-01-04 03:06:10 +00001930 Py_RETURN_NONE;
1931}
1932
1933PyDoc_STRVAR(calcsize_doc,
1934"Return size of C struct described by format string fmt.");
1935
1936static PyObject *
1937calcsize(PyObject *self, PyObject *fmt)
1938{
1939 Py_ssize_t n;
1940 PyObject *s_object = cache_struct(fmt);
1941 if (s_object == NULL)
1942 return NULL;
1943 n = ((PyStructObject *)s_object)->s_size;
1944 Py_DECREF(s_object);
1945 return PyLong_FromSsize_t(n);
1946}
1947
1948PyDoc_STRVAR(pack_doc,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001949"Return bytes containing values v1, v2, ... packed according to fmt.");
Christian Heimesa34706f2008-01-04 03:06:10 +00001950
1951static PyObject *
1952pack(PyObject *self, PyObject *args)
1953{
1954 PyObject *s_object, *fmt, *newargs, *result;
1955 Py_ssize_t n = PyTuple_GET_SIZE(args);
1956
1957 if (n == 0) {
1958 PyErr_SetString(PyExc_TypeError, "missing format argument");
1959 return NULL;
1960 }
1961 fmt = PyTuple_GET_ITEM(args, 0);
1962 newargs = PyTuple_GetSlice(args, 1, n);
1963 if (newargs == NULL)
1964 return NULL;
1965
1966 s_object = cache_struct(fmt);
1967 if (s_object == NULL) {
1968 Py_DECREF(newargs);
1969 return NULL;
1970 }
1971 result = s_pack(s_object, newargs);
1972 Py_DECREF(newargs);
1973 Py_DECREF(s_object);
1974 return result;
1975}
1976
1977PyDoc_STRVAR(pack_into_doc,
1978"Pack the values v1, v2, ... according to fmt.\n\
1979Write the packed bytes into the writable buffer buf starting at offset.");
1980
1981static PyObject *
1982pack_into(PyObject *self, PyObject *args)
1983{
1984 PyObject *s_object, *fmt, *newargs, *result;
1985 Py_ssize_t n = PyTuple_GET_SIZE(args);
1986
1987 if (n == 0) {
1988 PyErr_SetString(PyExc_TypeError, "missing format argument");
1989 return NULL;
1990 }
1991 fmt = PyTuple_GET_ITEM(args, 0);
1992 newargs = PyTuple_GetSlice(args, 1, n);
1993 if (newargs == NULL)
1994 return NULL;
1995
1996 s_object = cache_struct(fmt);
1997 if (s_object == NULL) {
1998 Py_DECREF(newargs);
1999 return NULL;
2000 }
2001 result = s_pack_into(s_object, newargs);
2002 Py_DECREF(newargs);
2003 Py_DECREF(s_object);
2004 return result;
2005}
2006
2007PyDoc_STRVAR(unpack_doc,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002008"Unpack the bytes containing packed C structure data, according to fmt.\n\
2009Requires len(bytes) == calcsize(fmt).");
Christian Heimesa34706f2008-01-04 03:06:10 +00002010
2011static PyObject *
2012unpack(PyObject *self, PyObject *args)
2013{
2014 PyObject *s_object, *fmt, *inputstr, *result;
2015
2016 if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr))
2017 return NULL;
2018
2019 s_object = cache_struct(fmt);
2020 if (s_object == NULL)
2021 return NULL;
2022 result = s_unpack(s_object, inputstr);
2023 Py_DECREF(s_object);
2024 return result;
2025}
2026
2027PyDoc_STRVAR(unpack_from_doc,
2028"Unpack the buffer, containing packed C structure data, according to\n\
2029fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).");
2030
2031static PyObject *
2032unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
2033{
2034 PyObject *s_object, *fmt, *newargs, *result;
2035 Py_ssize_t n = PyTuple_GET_SIZE(args);
2036
2037 if (n == 0) {
2038 PyErr_SetString(PyExc_TypeError, "missing format argument");
2039 return NULL;
2040 }
2041 fmt = PyTuple_GET_ITEM(args, 0);
2042 newargs = PyTuple_GetSlice(args, 1, n);
2043 if (newargs == NULL)
2044 return NULL;
2045
2046 s_object = cache_struct(fmt);
2047 if (s_object == NULL) {
2048 Py_DECREF(newargs);
2049 return NULL;
2050 }
2051 result = s_unpack_from(s_object, newargs, kwds);
2052 Py_DECREF(newargs);
2053 Py_DECREF(s_object);
2054 return result;
2055}
2056
2057static struct PyMethodDef module_functions[] = {
2058 {"_clearcache", (PyCFunction)clearcache, METH_NOARGS, clearcache_doc},
2059 {"calcsize", calcsize, METH_O, calcsize_doc},
2060 {"pack", pack, METH_VARARGS, pack_doc},
2061 {"pack_into", pack_into, METH_VARARGS, pack_into_doc},
2062 {"unpack", unpack, METH_VARARGS, unpack_doc},
2063 {"unpack_from", (PyCFunction)unpack_from,
2064 METH_VARARGS|METH_KEYWORDS, unpack_from_doc},
2065 {NULL, NULL} /* sentinel */
2066};
2067
2068
Thomas Wouters477c8d52006-05-27 19:21:47 +00002069/* Module initialization */
2070
Christian Heimesa34706f2008-01-04 03:06:10 +00002071PyDoc_STRVAR(module_doc,
2072"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002073Python bytes objects are used to hold the data representing the C struct\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002074and also as format strings to describe the layout of data in the C struct.\n\
2075\n\
2076The optional first format char indicates byte order, size and alignment:\n\
2077 @: native order, size & alignment (default)\n\
2078 =: native order, std. size & alignment\n\
2079 <: little-endian, std. size & alignment\n\
2080 >: big-endian, std. size & alignment\n\
2081 !: same as >\n\
2082\n\
2083The remaining chars indicate types of args and must match exactly;\n\
2084these can be preceded by a decimal repeat count:\n\
2085 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
2086 h:short; H:unsigned short; i:int; I:unsigned int;\n\
2087 l:long; L:unsigned long; f:float; d:double.\n\
2088Special cases (preceding decimal count indicates length):\n\
2089 s:string (array of char); p: pascal string (with count byte).\n\
2090Special case (only available in native format):\n\
2091 P:an integer type that is wide enough to hold a pointer.\n\
2092Special case (not in native mode unless 'long long' in platform C):\n\
2093 q:long long; Q:unsigned long long\n\
2094Whitespace between formats is ignored.\n\
2095\n\
2096The variable struct.error is an exception raised on errors.\n");
2097
Martin v. Löwis1a214512008-06-11 05:26:20 +00002098
2099static struct PyModuleDef _structmodule = {
2100 PyModuleDef_HEAD_INIT,
2101 "_struct",
2102 module_doc,
2103 -1,
2104 module_functions,
2105 NULL,
2106 NULL,
2107 NULL,
2108 NULL
2109};
2110
Thomas Wouters477c8d52006-05-27 19:21:47 +00002111PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002112PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002113{
Christian Heimesa34706f2008-01-04 03:06:10 +00002114 PyObject *ver, *m;
2115
Christian Heimes72b710a2008-05-26 13:28:38 +00002116 ver = PyBytes_FromString("0.2");
Christian Heimesa34706f2008-01-04 03:06:10 +00002117 if (ver == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002118 return NULL;
Christian Heimesa34706f2008-01-04 03:06:10 +00002119
Martin v. Löwis1a214512008-06-11 05:26:20 +00002120 m = PyModule_Create(&_structmodule);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002121 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002122 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002123
Christian Heimes90aa7642007-12-19 02:45:37 +00002124 Py_TYPE(&PyStructType) = &PyType_Type;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002125 if (PyType_Ready(&PyStructType) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002126 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002127
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002128#ifdef PY_STRUCT_OVERFLOW_MASKING
2129 if (pyint_zero == NULL) {
Christian Heimes217cfd12007-12-02 14:31:20 +00002130 pyint_zero = PyLong_FromLong(0);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002131 if (pyint_zero == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002132 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002133 }
2134 if (pylong_ulong_mask == NULL) {
2135#if (SIZEOF_LONG == 4)
2136 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
2137#else
2138 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
2139#endif
2140 if (pylong_ulong_mask == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002141 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002142 }
2143
2144#else
2145 /* This speed trick can't be used until overflow masking goes away, because
2146 native endian always raises exceptions instead of overflow masking. */
2147
Thomas Wouters477c8d52006-05-27 19:21:47 +00002148 /* Check endian and swap in faster functions */
2149 {
2150 int one = 1;
2151 formatdef *native = native_table;
2152 formatdef *other, *ptr;
2153 if ((int)*(unsigned char*)&one)
2154 other = lilendian_table;
2155 else
2156 other = bigendian_table;
2157 /* Scan through the native table, find a matching
2158 entry in the endian table and swap in the
2159 native implementations whenever possible
2160 (64-bit platforms may not have "standard" sizes) */
2161 while (native->format != '\0' && other->format != '\0') {
2162 ptr = other;
2163 while (ptr->format != '\0') {
2164 if (ptr->format == native->format) {
2165 /* Match faster when formats are
2166 listed in the same order */
2167 if (ptr == other)
2168 other++;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002169 /* Only use the trick if the
Thomas Wouters477c8d52006-05-27 19:21:47 +00002170 size matches */
2171 if (ptr->size != native->size)
2172 break;
2173 /* Skip float and double, could be
2174 "unknown" float format */
2175 if (ptr->format == 'd' || ptr->format == 'f')
2176 break;
2177 ptr->pack = native->pack;
2178 ptr->unpack = native->unpack;
2179 break;
2180 }
2181 ptr++;
2182 }
2183 native++;
2184 }
2185 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002186#endif
2187
Thomas Wouters477c8d52006-05-27 19:21:47 +00002188 /* Add some symbolic constants to the module */
2189 if (StructError == NULL) {
2190 StructError = PyErr_NewException("struct.error", NULL, NULL);
2191 if (StructError == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002192 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002193 }
2194
2195 Py_INCREF(StructError);
2196 PyModule_AddObject(m, "error", StructError);
2197
2198 Py_INCREF((PyObject*)&PyStructType);
2199 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002200
Christian Heimesa34706f2008-01-04 03:06:10 +00002201 PyModule_AddObject(m, "__version__", ver);
2202
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002203 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
2204#ifdef PY_STRUCT_OVERFLOW_MASKING
2205 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
2206#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002207#ifdef PY_STRUCT_FLOAT_COERCE
2208 PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
2209#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +00002210 return m;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002211
Thomas Wouters477c8d52006-05-27 19:21:47 +00002212}