blob: 6be4557acf9258aa8d23a9c87ad6bec1cc7e88fb [file] [log] [blame]
Thomas Wouters477c8d52006-05-27 19:21:47 +00001/* struct module -- pack values into and (out of) strings */
2
3/* New version supporting byte order, alignment and size options,
4 character strings, and unsigned numbers */
5
6#define PY_SSIZE_T_CLEAN
7
8#include "Python.h"
9#include "structseq.h"
10#include "structmember.h"
11#include <ctype.h>
12
13static PyTypeObject PyStructType;
14
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,
Guido van Rossum98297ee2007-11-06 21:34:58 +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,
Guido van Rossume625fd52007-05-27 09:19:04 +0000613 "char format requires 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);
1570 PyObject_ReleaseBuffer(input, &vbuf);
1571 return NULL;
1572 }
1573 result = s_unpack_internal(soself, vbuf.buf);
1574 PyObject_ReleaseBuffer(input, &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);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001612 PyObject_ReleaseBuffer(input, &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);
1616 PyObject_ReleaseBuffer(input, &vbuf);
1617 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,
1657 "argument for 's' must be a string");
1658 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,
1683 "argument for 'p' must be a string");
1684 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__,
1717"S.pack(v1, v2, ...) -> string\n\
1718\n\
1719Return a string containing values v1, v2, ... packed according to this\n\
1720Struct'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));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001789
1790 /* Support negative offsets. */
1791 if (offset < 0)
1792 offset += buffer_len;
1793
1794 /* Check boundaries */
1795 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1796 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001797 "pack_into requires a buffer of at least %zd bytes",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001798 soself->s_size);
1799 return NULL;
1800 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001801
Thomas Wouters477c8d52006-05-27 19:21:47 +00001802 /* Call the guts */
1803 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1804 return NULL;
1805 }
1806
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001807 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001808}
1809
1810static PyObject *
1811s_get_format(PyStructObject *self, void *unused)
1812{
1813 Py_INCREF(self->s_format);
1814 return self->s_format;
1815}
1816
1817static PyObject *
1818s_get_size(PyStructObject *self, void *unused)
1819{
Christian Heimes217cfd12007-12-02 14:31:20 +00001820 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001821}
1822
1823/* List of functions */
1824
1825static struct PyMethodDef s_methods[] = {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001826 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1827 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1828 {"unpack", s_unpack, METH_O, s_unpack__doc__},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00001829 {"unpack_from", (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001830 s_unpack_from__doc__},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001831 {NULL, NULL} /* sentinel */
1832};
1833
1834PyDoc_STRVAR(s__doc__, "Compiled struct object");
1835
1836#define OFF(x) offsetof(PyStructObject, x)
1837
1838static PyGetSetDef s_getsetlist[] = {
1839 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1840 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1841 {NULL} /* sentinel */
1842};
1843
1844static
1845PyTypeObject PyStructType = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001846 PyVarObject_HEAD_INIT(NULL, 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001847 "Struct",
1848 sizeof(PyStructObject),
1849 0,
1850 (destructor)s_dealloc, /* tp_dealloc */
1851 0, /* tp_print */
1852 0, /* tp_getattr */
1853 0, /* tp_setattr */
1854 0, /* tp_compare */
1855 0, /* tp_repr */
1856 0, /* tp_as_number */
1857 0, /* tp_as_sequence */
1858 0, /* tp_as_mapping */
1859 0, /* tp_hash */
1860 0, /* tp_call */
1861 0, /* tp_str */
1862 PyObject_GenericGetAttr, /* tp_getattro */
1863 PyObject_GenericSetAttr, /* tp_setattro */
1864 0, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +00001865 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001866 s__doc__, /* tp_doc */
1867 0, /* tp_traverse */
1868 0, /* tp_clear */
1869 0, /* tp_richcompare */
1870 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1871 0, /* tp_iter */
1872 0, /* tp_iternext */
1873 s_methods, /* tp_methods */
1874 NULL, /* tp_members */
1875 s_getsetlist, /* tp_getset */
1876 0, /* tp_base */
1877 0, /* tp_dict */
1878 0, /* tp_descr_get */
1879 0, /* tp_descr_set */
1880 0, /* tp_dictoffset */
1881 s_init, /* tp_init */
1882 PyType_GenericAlloc,/* tp_alloc */
1883 s_new, /* tp_new */
1884 PyObject_Del, /* tp_free */
1885};
1886
Christian Heimesa34706f2008-01-04 03:06:10 +00001887
1888/* ---- Standalone functions ---- */
1889
1890#define MAXCACHE 100
1891static PyObject *cache = NULL;
1892
1893static PyObject *
1894cache_struct(PyObject *fmt)
1895{
1896 PyObject * s_object;
1897
1898 if (cache == NULL) {
1899 cache = PyDict_New();
1900 if (cache == NULL)
1901 return NULL;
1902 }
1903
1904 s_object = PyDict_GetItem(cache, fmt);
1905 if (s_object != NULL) {
1906 Py_INCREF(s_object);
1907 return s_object;
1908 }
1909
1910 s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
1911 if (s_object != NULL) {
1912 if (PyDict_Size(cache) >= MAXCACHE)
1913 PyDict_Clear(cache);
1914 /* Attempt to cache the result */
1915 if (PyDict_SetItem(cache, fmt, s_object) == -1)
1916 PyErr_Clear();
1917 }
1918 return s_object;
1919}
1920
1921PyDoc_STRVAR(clearcache_doc,
1922"Clear the internal cache.");
1923
1924static PyObject *
1925clearcache(PyObject *self)
1926{
Christian Heimes679db4a2008-01-18 09:56:22 +00001927 Py_CLEAR(cache);
Christian Heimesa34706f2008-01-04 03:06:10 +00001928 Py_RETURN_NONE;
1929}
1930
1931PyDoc_STRVAR(calcsize_doc,
1932"Return size of C struct described by format string fmt.");
1933
1934static PyObject *
1935calcsize(PyObject *self, PyObject *fmt)
1936{
1937 Py_ssize_t n;
1938 PyObject *s_object = cache_struct(fmt);
1939 if (s_object == NULL)
1940 return NULL;
1941 n = ((PyStructObject *)s_object)->s_size;
1942 Py_DECREF(s_object);
1943 return PyLong_FromSsize_t(n);
1944}
1945
1946PyDoc_STRVAR(pack_doc,
1947"Return string containing values v1, v2, ... packed according to fmt.");
1948
1949static PyObject *
1950pack(PyObject *self, PyObject *args)
1951{
1952 PyObject *s_object, *fmt, *newargs, *result;
1953 Py_ssize_t n = PyTuple_GET_SIZE(args);
1954
1955 if (n == 0) {
1956 PyErr_SetString(PyExc_TypeError, "missing format argument");
1957 return NULL;
1958 }
1959 fmt = PyTuple_GET_ITEM(args, 0);
1960 newargs = PyTuple_GetSlice(args, 1, n);
1961 if (newargs == NULL)
1962 return NULL;
1963
1964 s_object = cache_struct(fmt);
1965 if (s_object == NULL) {
1966 Py_DECREF(newargs);
1967 return NULL;
1968 }
1969 result = s_pack(s_object, newargs);
1970 Py_DECREF(newargs);
1971 Py_DECREF(s_object);
1972 return result;
1973}
1974
1975PyDoc_STRVAR(pack_into_doc,
1976"Pack the values v1, v2, ... according to fmt.\n\
1977Write the packed bytes into the writable buffer buf starting at offset.");
1978
1979static PyObject *
1980pack_into(PyObject *self, PyObject *args)
1981{
1982 PyObject *s_object, *fmt, *newargs, *result;
1983 Py_ssize_t n = PyTuple_GET_SIZE(args);
1984
1985 if (n == 0) {
1986 PyErr_SetString(PyExc_TypeError, "missing format argument");
1987 return NULL;
1988 }
1989 fmt = PyTuple_GET_ITEM(args, 0);
1990 newargs = PyTuple_GetSlice(args, 1, n);
1991 if (newargs == NULL)
1992 return NULL;
1993
1994 s_object = cache_struct(fmt);
1995 if (s_object == NULL) {
1996 Py_DECREF(newargs);
1997 return NULL;
1998 }
1999 result = s_pack_into(s_object, newargs);
2000 Py_DECREF(newargs);
2001 Py_DECREF(s_object);
2002 return result;
2003}
2004
2005PyDoc_STRVAR(unpack_doc,
2006"Unpack the string containing packed C structure data, according to fmt.\n\
2007Requires len(string) == calcsize(fmt).");
2008
2009static PyObject *
2010unpack(PyObject *self, PyObject *args)
2011{
2012 PyObject *s_object, *fmt, *inputstr, *result;
2013
2014 if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr))
2015 return NULL;
2016
2017 s_object = cache_struct(fmt);
2018 if (s_object == NULL)
2019 return NULL;
2020 result = s_unpack(s_object, inputstr);
2021 Py_DECREF(s_object);
2022 return result;
2023}
2024
2025PyDoc_STRVAR(unpack_from_doc,
2026"Unpack the buffer, containing packed C structure data, according to\n\
2027fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).");
2028
2029static PyObject *
2030unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
2031{
2032 PyObject *s_object, *fmt, *newargs, *result;
2033 Py_ssize_t n = PyTuple_GET_SIZE(args);
2034
2035 if (n == 0) {
2036 PyErr_SetString(PyExc_TypeError, "missing format argument");
2037 return NULL;
2038 }
2039 fmt = PyTuple_GET_ITEM(args, 0);
2040 newargs = PyTuple_GetSlice(args, 1, n);
2041 if (newargs == NULL)
2042 return NULL;
2043
2044 s_object = cache_struct(fmt);
2045 if (s_object == NULL) {
2046 Py_DECREF(newargs);
2047 return NULL;
2048 }
2049 result = s_unpack_from(s_object, newargs, kwds);
2050 Py_DECREF(newargs);
2051 Py_DECREF(s_object);
2052 return result;
2053}
2054
2055static struct PyMethodDef module_functions[] = {
2056 {"_clearcache", (PyCFunction)clearcache, METH_NOARGS, clearcache_doc},
2057 {"calcsize", calcsize, METH_O, calcsize_doc},
2058 {"pack", pack, METH_VARARGS, pack_doc},
2059 {"pack_into", pack_into, METH_VARARGS, pack_into_doc},
2060 {"unpack", unpack, METH_VARARGS, unpack_doc},
2061 {"unpack_from", (PyCFunction)unpack_from,
2062 METH_VARARGS|METH_KEYWORDS, unpack_from_doc},
2063 {NULL, NULL} /* sentinel */
2064};
2065
2066
Thomas Wouters477c8d52006-05-27 19:21:47 +00002067/* Module initialization */
2068
Christian Heimesa34706f2008-01-04 03:06:10 +00002069PyDoc_STRVAR(module_doc,
2070"Functions to convert between Python values and C structs.\n\
2071Python strings are used to hold the data representing the C struct\n\
2072and also as format strings to describe the layout of data in the C struct.\n\
2073\n\
2074The optional first format char indicates byte order, size and alignment:\n\
2075 @: native order, size & alignment (default)\n\
2076 =: native order, std. size & alignment\n\
2077 <: little-endian, std. size & alignment\n\
2078 >: big-endian, std. size & alignment\n\
2079 !: same as >\n\
2080\n\
2081The remaining chars indicate types of args and must match exactly;\n\
2082these can be preceded by a decimal repeat count:\n\
2083 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
2084 h:short; H:unsigned short; i:int; I:unsigned int;\n\
2085 l:long; L:unsigned long; f:float; d:double.\n\
2086Special cases (preceding decimal count indicates length):\n\
2087 s:string (array of char); p: pascal string (with count byte).\n\
2088Special case (only available in native format):\n\
2089 P:an integer type that is wide enough to hold a pointer.\n\
2090Special case (not in native mode unless 'long long' in platform C):\n\
2091 q:long long; Q:unsigned long long\n\
2092Whitespace between formats is ignored.\n\
2093\n\
2094The variable struct.error is an exception raised on errors.\n");
2095
Martin v. Löwis1a214512008-06-11 05:26:20 +00002096
2097static struct PyModuleDef _structmodule = {
2098 PyModuleDef_HEAD_INIT,
2099 "_struct",
2100 module_doc,
2101 -1,
2102 module_functions,
2103 NULL,
2104 NULL,
2105 NULL,
2106 NULL
2107};
2108
Thomas Wouters477c8d52006-05-27 19:21:47 +00002109PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002110PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002111{
Christian Heimesa34706f2008-01-04 03:06:10 +00002112 PyObject *ver, *m;
2113
Christian Heimes72b710a2008-05-26 13:28:38 +00002114 ver = PyBytes_FromString("0.2");
Christian Heimesa34706f2008-01-04 03:06:10 +00002115 if (ver == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002116 return NULL;
Christian Heimesa34706f2008-01-04 03:06:10 +00002117
Martin v. Löwis1a214512008-06-11 05:26:20 +00002118 m = PyModule_Create(&_structmodule);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002119 if (m == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002120 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002121
Christian Heimes90aa7642007-12-19 02:45:37 +00002122 Py_TYPE(&PyStructType) = &PyType_Type;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002123 if (PyType_Ready(&PyStructType) < 0)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002124 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002125
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002126#ifdef PY_STRUCT_OVERFLOW_MASKING
2127 if (pyint_zero == NULL) {
Christian Heimes217cfd12007-12-02 14:31:20 +00002128 pyint_zero = PyLong_FromLong(0);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002129 if (pyint_zero == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002130 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002131 }
2132 if (pylong_ulong_mask == NULL) {
2133#if (SIZEOF_LONG == 4)
2134 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
2135#else
2136 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
2137#endif
2138 if (pylong_ulong_mask == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002139 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002140 }
2141
2142#else
2143 /* This speed trick can't be used until overflow masking goes away, because
2144 native endian always raises exceptions instead of overflow masking. */
2145
Thomas Wouters477c8d52006-05-27 19:21:47 +00002146 /* Check endian and swap in faster functions */
2147 {
2148 int one = 1;
2149 formatdef *native = native_table;
2150 formatdef *other, *ptr;
2151 if ((int)*(unsigned char*)&one)
2152 other = lilendian_table;
2153 else
2154 other = bigendian_table;
2155 /* Scan through the native table, find a matching
2156 entry in the endian table and swap in the
2157 native implementations whenever possible
2158 (64-bit platforms may not have "standard" sizes) */
2159 while (native->format != '\0' && other->format != '\0') {
2160 ptr = other;
2161 while (ptr->format != '\0') {
2162 if (ptr->format == native->format) {
2163 /* Match faster when formats are
2164 listed in the same order */
2165 if (ptr == other)
2166 other++;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002167 /* Only use the trick if the
Thomas Wouters477c8d52006-05-27 19:21:47 +00002168 size matches */
2169 if (ptr->size != native->size)
2170 break;
2171 /* Skip float and double, could be
2172 "unknown" float format */
2173 if (ptr->format == 'd' || ptr->format == 'f')
2174 break;
2175 ptr->pack = native->pack;
2176 ptr->unpack = native->unpack;
2177 break;
2178 }
2179 ptr++;
2180 }
2181 native++;
2182 }
2183 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002184#endif
2185
Thomas Wouters477c8d52006-05-27 19:21:47 +00002186 /* Add some symbolic constants to the module */
2187 if (StructError == NULL) {
2188 StructError = PyErr_NewException("struct.error", NULL, NULL);
2189 if (StructError == NULL)
Martin v. Löwis1a214512008-06-11 05:26:20 +00002190 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002191 }
2192
2193 Py_INCREF(StructError);
2194 PyModule_AddObject(m, "error", StructError);
2195
2196 Py_INCREF((PyObject*)&PyStructType);
2197 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002198
Christian Heimesa34706f2008-01-04 03:06:10 +00002199 PyModule_AddObject(m, "__version__", ver);
2200
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002201 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
2202#ifdef PY_STRUCT_OVERFLOW_MASKING
2203 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
2204#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002205#ifdef PY_STRUCT_FLOAT_COERCE
2206 PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
2207#endif
Martin v. Löwis1a214512008-06-11 05:26:20 +00002208 return m;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00002209
Thomas Wouters477c8d52006-05-27 19:21:47 +00002210}