blob: dd92e0c56e394c59263d4d03345f853abe41f8c9 [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)
Martin v. Löwis9f2e3462007-07-21 17:22:18 +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 }
Martin v. Löwis9f2e3462007-07-21 17:22:18 +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{
442 return PyString_FromStringAndSize(p, 1);
443}
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 }
Thomas Wouters477c8d52006-05-27 19:21:47 +0000611 if (!PyString_Check(v) || PyString_Size(v) != 1) {
612 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 }
616 *p = *PyString_AsString(v);
617 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
Thomas Woutersb2137042007-02-01 18:02:27 +0000800 {'t', 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},
Thomas Woutersb2137042007-02-01 18:02:27 +00001037 {'t', 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},
Thomas Woutersb2137042007-02-01 18:02:27 +00001256 {'t', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1257 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
1336 fmt = PyString_AS_STRING(self->s_format);
1337
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
1386 self->s_size = size;
1387 self->s_len = len;
1388 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1389 if (codes == NULL) {
1390 PyErr_NoMemory();
1391 return -1;
1392 }
1393 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001394
Thomas Wouters477c8d52006-05-27 19:21:47 +00001395 s = fmt;
1396 size = 0;
1397 while ((c = *s++) != '\0') {
1398 if (isspace(Py_CHARMASK(c)))
1399 continue;
1400 if ('0' <= c && c <= '9') {
1401 num = c - '0';
1402 while ('0' <= (c = *s++) && c <= '9')
1403 num = num*10 + (c - '0');
1404 if (c == '\0')
1405 break;
1406 }
1407 else
1408 num = 1;
1409
1410 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001411
Thomas Wouters477c8d52006-05-27 19:21:47 +00001412 size = align(size, c, e);
1413 if (c == 's' || c == 'p') {
1414 codes->offset = size;
1415 codes->size = num;
1416 codes->fmtdef = e;
1417 codes++;
1418 size += num;
1419 } else if (c == 'x') {
1420 size += num;
1421 } else {
1422 while (--num >= 0) {
1423 codes->offset = size;
1424 codes->size = e->size;
1425 codes->fmtdef = e;
1426 codes++;
1427 size += e->size;
1428 }
1429 }
1430 }
1431 codes->fmtdef = NULL;
1432 codes->offset = size;
1433 codes->size = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001434
Thomas Wouters477c8d52006-05-27 19:21:47 +00001435 return 0;
1436}
1437
1438static PyObject *
1439s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1440{
1441 PyObject *self;
1442
1443 assert(type != NULL && type->tp_alloc != NULL);
1444
1445 self = type->tp_alloc(type, 0);
1446 if (self != NULL) {
1447 PyStructObject *s = (PyStructObject*)self;
1448 Py_INCREF(Py_None);
1449 s->s_format = Py_None;
1450 s->s_codes = NULL;
1451 s->s_size = -1;
1452 s->s_len = -1;
1453 }
1454 return self;
1455}
1456
1457static int
1458s_init(PyObject *self, PyObject *args, PyObject *kwds)
1459{
1460 PyStructObject *soself = (PyStructObject *)self;
1461 PyObject *o_format = NULL;
1462 int ret = 0;
1463 static char *kwlist[] = {"format", 0};
1464
1465 assert(PyStruct_Check(self));
1466
1467 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1468 &o_format))
1469 return -1;
1470
1471 Py_INCREF(o_format);
1472 Py_XDECREF(soself->s_format);
1473 soself->s_format = o_format;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001474
Thomas Wouters477c8d52006-05-27 19:21:47 +00001475 ret = prepare_s(soself);
1476 return ret;
1477}
1478
1479static void
1480s_dealloc(PyStructObject *s)
1481{
1482 if (s->weakreflist != NULL)
1483 PyObject_ClearWeakRefs((PyObject *)s);
1484 if (s->s_codes != NULL) {
1485 PyMem_FREE(s->s_codes);
1486 }
1487 Py_XDECREF(s->s_format);
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001488 Py_Type(s)->tp_free((PyObject *)s);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001489}
1490
1491static PyObject *
1492s_unpack_internal(PyStructObject *soself, char *startfrom) {
1493 formatcode *code;
1494 Py_ssize_t i = 0;
1495 PyObject *result = PyTuple_New(soself->s_len);
1496 if (result == NULL)
1497 return NULL;
1498
1499 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1500 PyObject *v;
1501 const formatdef *e = code->fmtdef;
1502 const char *res = startfrom + code->offset;
1503 if (e->format == 's') {
1504 v = PyString_FromStringAndSize(res, code->size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001505 } else if (e->format == 'p') {
1506 Py_ssize_t n = *(unsigned char*)res;
1507 if (n >= code->size)
1508 n = code->size - 1;
1509 v = PyString_FromStringAndSize(res + 1, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510 } else {
1511 v = e->unpack(res, e);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001512 }
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001513 if (v == NULL)
1514 goto fail;
1515 PyTuple_SET_ITEM(result, i++, v);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001516 }
1517
1518 return result;
1519fail:
1520 Py_DECREF(result);
1521 return NULL;
1522}
1523
1524
1525PyDoc_STRVAR(s_unpack__doc__,
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001526"S.unpack(buffer) -> (v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001527\n\
1528Return tuple containing values unpacked according to this Struct's format.\n\
Guido van Rossum913dd0b2007-04-13 03:33:53 +00001529Requires len(buffer) == self.size. See struct.__doc__ for more on format\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001530strings.");
1531
1532static PyObject *
Guido van Rossum98297ee2007-11-06 21:34:58 +00001533s_unpack(PyObject *self, PyObject *input)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001534{
Guido van Rossum98297ee2007-11-06 21:34:58 +00001535 Py_buffer vbuf;
1536 PyObject *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001537 PyStructObject *soself = (PyStructObject *)self;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001538
Thomas Wouters477c8d52006-05-27 19:21:47 +00001539 assert(PyStruct_Check(self));
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001540 assert(soself->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001541 if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001542 return NULL;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001543 if (vbuf.len != soself->s_size) {
1544 PyErr_Format(StructError,
1545 "unpack requires a bytes argument of length %zd",
1546 soself->s_size);
1547 PyObject_ReleaseBuffer(input, &vbuf);
1548 return NULL;
1549 }
1550 result = s_unpack_internal(soself, vbuf.buf);
1551 PyObject_ReleaseBuffer(input, &vbuf);
Guido van Rossumd8faa362007-04-27 19:54:29 +00001552 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001553}
1554
1555PyDoc_STRVAR(s_unpack_from__doc__,
1556"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1557\n\
1558Return tuple containing values unpacked according to this Struct's format.\n\
1559Unlike unpack, unpack_from can unpack values from any object supporting\n\
1560the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1561See struct.__doc__ for more on format strings.");
1562
1563static PyObject *
1564s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1565{
1566 static char *kwlist[] = {"buffer", "offset", 0};
Guido van Rossum98297ee2007-11-06 21:34:58 +00001567
1568 PyObject *input;
1569 Py_ssize_t offset = 0;
1570 Py_buffer vbuf;
1571 PyObject *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001572 PyStructObject *soself = (PyStructObject *)self;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001573
Thomas Wouters477c8d52006-05-27 19:21:47 +00001574 assert(PyStruct_Check(self));
1575 assert(soself->s_codes != NULL);
1576
Guido van Rossum98297ee2007-11-06 21:34:58 +00001577 if (!PyArg_ParseTupleAndKeywords(args, kwds,
1578 "O|n:unpack_from", kwlist,
1579 &input, &offset))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001580 return NULL;
Guido van Rossum98297ee2007-11-06 21:34:58 +00001581 if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001582 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001583 if (offset < 0)
Guido van Rossum98297ee2007-11-06 21:34:58 +00001584 offset += vbuf.len;
1585 if (offset < 0 || vbuf.len - offset < soself->s_size) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001586 PyErr_Format(StructError,
1587 "unpack_from requires a buffer of at least %zd bytes",
1588 soself->s_size);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001589 PyObject_ReleaseBuffer(input, &vbuf);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001590 return NULL;
1591 }
Guido van Rossum98297ee2007-11-06 21:34:58 +00001592 result = s_unpack_internal(soself, (char*)vbuf.buf + offset);
1593 PyObject_ReleaseBuffer(input, &vbuf);
1594 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001595}
1596
1597
1598/*
1599 * Guts of the pack function.
1600 *
1601 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1602 * argument for where to start processing the arguments for packing, and a
1603 * character buffer for writing the packed string. The caller must insure
1604 * that the buffer may contain the required length for packing the arguments.
1605 * 0 is returned on success, 1 is returned if there is an error.
1606 *
1607 */
1608static int
1609s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1610{
1611 formatcode *code;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001612 /* XXX(nnorwitz): why does i need to be a local? can we use
1613 the offset parameter or do we need the wider width? */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001614 Py_ssize_t i;
1615
1616 memset(buf, '\0', soself->s_size);
1617 i = offset;
1618 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1619 Py_ssize_t n;
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001620 PyObject *v = PyTuple_GET_ITEM(args, i++);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001621 const formatdef *e = code->fmtdef;
1622 char *res = buf + code->offset;
1623 if (e->format == 's') {
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001624 int isstring;
1625 void *p;
1626 if (PyUnicode_Check(v)) {
1627 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
1628 if (v == NULL)
1629 return -1;
1630 }
1631 isstring = PyString_Check(v);
1632 if (!isstring && !PyBytes_Check(v)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001633 PyErr_SetString(StructError,
1634 "argument for 's' must be a string");
1635 return -1;
1636 }
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001637 if (isstring) {
1638 n = PyString_GET_SIZE(v);
1639 p = PyString_AS_STRING(v);
1640 }
1641 else {
1642 n = PyBytes_GET_SIZE(v);
1643 p = PyBytes_AS_STRING(v);
1644 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001645 if (n > code->size)
1646 n = code->size;
1647 if (n > 0)
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001648 memcpy(res, p, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001649 } else if (e->format == 'p') {
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001650 int isstring;
1651 void *p;
1652 if (PyUnicode_Check(v)) {
1653 v = _PyUnicode_AsDefaultEncodedString(v, NULL);
1654 if (v == NULL)
1655 return -1;
1656 }
1657 isstring = PyString_Check(v);
1658 if (!isstring && !PyBytes_Check(v)) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001659 PyErr_SetString(StructError,
1660 "argument for 'p' must be a string");
1661 return -1;
1662 }
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001663 if (isstring) {
1664 n = PyString_GET_SIZE(v);
1665 p = PyString_AS_STRING(v);
1666 }
1667 else {
1668 n = PyBytes_GET_SIZE(v);
1669 p = PyBytes_AS_STRING(v);
1670 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001671 if (n > (code->size - 1))
1672 n = code->size - 1;
1673 if (n > 0)
Guido van Rossumd6ca5462007-05-22 01:29:33 +00001674 memcpy(res + 1, p, n);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001675 if (n > 255)
1676 n = 255;
1677 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1678 } else {
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001679 if (e->pack(res, v, e) < 0) {
1680 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1681 PyErr_SetString(StructError,
1682 "long too large to convert to int");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001683 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001684 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001685 }
1686 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001687
Thomas Wouters477c8d52006-05-27 19:21:47 +00001688 /* Success */
1689 return 0;
1690}
1691
1692
1693PyDoc_STRVAR(s_pack__doc__,
1694"S.pack(v1, v2, ...) -> string\n\
1695\n\
1696Return a string containing values v1, v2, ... packed according to this\n\
1697Struct's format. See struct.__doc__ for more on format strings.");
1698
1699static PyObject *
1700s_pack(PyObject *self, PyObject *args)
1701{
1702 PyStructObject *soself;
1703 PyObject *result;
1704
1705 /* Validate arguments. */
1706 soself = (PyStructObject *)self;
1707 assert(PyStruct_Check(self));
1708 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001709 if (PyTuple_GET_SIZE(args) != soself->s_len)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001710 {
1711 PyErr_Format(StructError,
1712 "pack requires exactly %zd arguments", soself->s_len);
1713 return NULL;
1714 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001715
Thomas Wouters477c8d52006-05-27 19:21:47 +00001716 /* Allocate a new string */
1717 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1718 if (result == NULL)
1719 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001720
Thomas Wouters477c8d52006-05-27 19:21:47 +00001721 /* Call the guts */
1722 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1723 Py_DECREF(result);
1724 return NULL;
1725 }
1726
1727 return result;
1728}
1729
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001730PyDoc_STRVAR(s_pack_into__doc__,
1731"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001732\n\
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001733Pack the values v1, v2, ... according to this Struct's format, write \n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001734the packed bytes into the writable buffer buf starting at offset. Note\n\
1735that the offset is not an optional argument. See struct.__doc__ for \n\
1736more on format strings.");
1737
1738static PyObject *
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001739s_pack_into(PyObject *self, PyObject *args)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001740{
1741 PyStructObject *soself;
1742 char *buffer;
1743 Py_ssize_t buffer_len, offset;
1744
1745 /* Validate arguments. +1 is for the first arg as buffer. */
1746 soself = (PyStructObject *)self;
1747 assert(PyStruct_Check(self));
1748 assert(soself->s_codes != NULL);
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001749 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Thomas Wouters477c8d52006-05-27 19:21:47 +00001750 {
1751 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001752 "pack_into requires exactly %zd arguments",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001753 (soself->s_len + 2));
1754 return NULL;
1755 }
1756
1757 /* Extract a writable memory buffer from the first argument */
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001758 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1759 (void**)&buffer, &buffer_len) == -1 ) {
Thomas Wouters477c8d52006-05-27 19:21:47 +00001760 return NULL;
1761 }
1762 assert( buffer_len >= 0 );
1763
1764 /* Extract the offset from the first argument */
Christian Heimes217cfd12007-12-02 14:31:20 +00001765 offset = PyLong_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001766
1767 /* Support negative offsets. */
1768 if (offset < 0)
1769 offset += buffer_len;
1770
1771 /* Check boundaries */
1772 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1773 PyErr_Format(StructError,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001774 "pack_into requires a buffer of at least %zd bytes",
Thomas Wouters477c8d52006-05-27 19:21:47 +00001775 soself->s_size);
1776 return NULL;
1777 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001778
Thomas Wouters477c8d52006-05-27 19:21:47 +00001779 /* Call the guts */
1780 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1781 return NULL;
1782 }
1783
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001784 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001785}
1786
1787static PyObject *
1788s_get_format(PyStructObject *self, void *unused)
1789{
1790 Py_INCREF(self->s_format);
1791 return self->s_format;
1792}
1793
1794static PyObject *
1795s_get_size(PyStructObject *self, void *unused)
1796{
Christian Heimes217cfd12007-12-02 14:31:20 +00001797 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001798}
1799
1800/* List of functions */
1801
1802static struct PyMethodDef s_methods[] = {
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001803 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1804 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1805 {"unpack", s_unpack, METH_O, s_unpack__doc__},
Guido van Rossumd59da4b2007-05-22 18:11:13 +00001806 {"unpack_from", (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS,
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001807 s_unpack_from__doc__},
Thomas Wouters477c8d52006-05-27 19:21:47 +00001808 {NULL, NULL} /* sentinel */
1809};
1810
1811PyDoc_STRVAR(s__doc__, "Compiled struct object");
1812
1813#define OFF(x) offsetof(PyStructObject, x)
1814
1815static PyGetSetDef s_getsetlist[] = {
1816 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1817 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1818 {NULL} /* sentinel */
1819};
1820
1821static
1822PyTypeObject PyStructType = {
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001823 PyVarObject_HEAD_INIT(NULL, 0)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001824 "Struct",
1825 sizeof(PyStructObject),
1826 0,
1827 (destructor)s_dealloc, /* tp_dealloc */
1828 0, /* tp_print */
1829 0, /* tp_getattr */
1830 0, /* tp_setattr */
1831 0, /* tp_compare */
1832 0, /* tp_repr */
1833 0, /* tp_as_number */
1834 0, /* tp_as_sequence */
1835 0, /* tp_as_mapping */
1836 0, /* tp_hash */
1837 0, /* tp_call */
1838 0, /* tp_str */
1839 PyObject_GenericGetAttr, /* tp_getattro */
1840 PyObject_GenericSetAttr, /* tp_setattro */
1841 0, /* tp_as_buffer */
Guido van Rossum3cf5b1e2006-07-27 21:53:35 +00001842 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001843 s__doc__, /* tp_doc */
1844 0, /* tp_traverse */
1845 0, /* tp_clear */
1846 0, /* tp_richcompare */
1847 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1848 0, /* tp_iter */
1849 0, /* tp_iternext */
1850 s_methods, /* tp_methods */
1851 NULL, /* tp_members */
1852 s_getsetlist, /* tp_getset */
1853 0, /* tp_base */
1854 0, /* tp_dict */
1855 0, /* tp_descr_get */
1856 0, /* tp_descr_set */
1857 0, /* tp_dictoffset */
1858 s_init, /* tp_init */
1859 PyType_GenericAlloc,/* tp_alloc */
1860 s_new, /* tp_new */
1861 PyObject_Del, /* tp_free */
1862};
1863
1864/* Module initialization */
1865
1866PyMODINIT_FUNC
1867init_struct(void)
1868{
1869 PyObject *m = Py_InitModule("_struct", NULL);
1870 if (m == NULL)
1871 return;
1872
Martin v. Löwis9f2e3462007-07-21 17:22:18 +00001873 Py_Type(&PyStructType) = &PyType_Type;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001874 if (PyType_Ready(&PyStructType) < 0)
1875 return;
1876
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001877#ifdef PY_STRUCT_OVERFLOW_MASKING
1878 if (pyint_zero == NULL) {
Christian Heimes217cfd12007-12-02 14:31:20 +00001879 pyint_zero = PyLong_FromLong(0);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001880 if (pyint_zero == NULL)
1881 return;
1882 }
1883 if (pylong_ulong_mask == NULL) {
1884#if (SIZEOF_LONG == 4)
1885 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1886#else
1887 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1888#endif
1889 if (pylong_ulong_mask == NULL)
1890 return;
1891 }
1892
1893#else
1894 /* This speed trick can't be used until overflow masking goes away, because
1895 native endian always raises exceptions instead of overflow masking. */
1896
Thomas Wouters477c8d52006-05-27 19:21:47 +00001897 /* Check endian and swap in faster functions */
1898 {
1899 int one = 1;
1900 formatdef *native = native_table;
1901 formatdef *other, *ptr;
1902 if ((int)*(unsigned char*)&one)
1903 other = lilendian_table;
1904 else
1905 other = bigendian_table;
1906 /* Scan through the native table, find a matching
1907 entry in the endian table and swap in the
1908 native implementations whenever possible
1909 (64-bit platforms may not have "standard" sizes) */
1910 while (native->format != '\0' && other->format != '\0') {
1911 ptr = other;
1912 while (ptr->format != '\0') {
1913 if (ptr->format == native->format) {
1914 /* Match faster when formats are
1915 listed in the same order */
1916 if (ptr == other)
1917 other++;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001918 /* Only use the trick if the
Thomas Wouters477c8d52006-05-27 19:21:47 +00001919 size matches */
1920 if (ptr->size != native->size)
1921 break;
1922 /* Skip float and double, could be
1923 "unknown" float format */
1924 if (ptr->format == 'd' || ptr->format == 'f')
1925 break;
1926 ptr->pack = native->pack;
1927 ptr->unpack = native->unpack;
1928 break;
1929 }
1930 ptr++;
1931 }
1932 native++;
1933 }
1934 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001935#endif
1936
Thomas Wouters477c8d52006-05-27 19:21:47 +00001937 /* Add some symbolic constants to the module */
1938 if (StructError == NULL) {
1939 StructError = PyErr_NewException("struct.error", NULL, NULL);
1940 if (StructError == NULL)
1941 return;
1942 }
1943
1944 Py_INCREF(StructError);
1945 PyModule_AddObject(m, "error", StructError);
1946
1947 Py_INCREF((PyObject*)&PyStructType);
1948 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001949
1950 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
1951#ifdef PY_STRUCT_OVERFLOW_MASKING
1952 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
1953#endif
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001954#ifdef PY_STRUCT_FLOAT_COERCE
1955 PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
1956#endif
1957
Thomas Wouters477c8d52006-05-27 19:21:47 +00001958}