blob: 2ab81ade8910bf817775fd52e4f90776fd381ca5 [file] [log] [blame]
Bob Ippolito232f3c92006-05-23 19:12:41 +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
Bob Ippolitoaa70a172006-05-26 20:25:23 +00006#define PY_SSIZE_T_CLEAN
7
Bob Ippolito232f3c92006-05-23 19:12:41 +00008#include "Python.h"
9#include "structseq.h"
10#include "structmember.h"
11#include <ctype.h>
12
Bob Ippolitod3611eb2006-05-23 19:31:23 +000013static PyTypeObject PyStructType;
Bob Ippolito232f3c92006-05-23 19:12:41 +000014
15/* compatibility macros */
16#if (PY_VERSION_HEX < 0x02050000)
17typedef int Py_ssize_t;
18#endif
19
Bob Ippolito4182a752006-05-30 17:37:54 +000020/* If PY_STRUCT_OVERFLOW_MASKING is defined, the struct module will wrap all input
Bob Ippolito2fd39772006-05-29 22:55:48 +000021 numbers for explicit endians such that they fit in the given type, much
22 like explicit casting in C. A warning will be raised if the number did
23 not originally fit within the range of the requested type. If it is
24 not defined, then all range errors and overflow will be struct.error
25 exceptions. */
26
Bob Ippolito4182a752006-05-30 17:37:54 +000027#define PY_STRUCT_OVERFLOW_MASKING 1
Bob Ippolito2fd39772006-05-29 22:55:48 +000028
Bob Ippolito4182a752006-05-30 17:37:54 +000029#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +000030static PyObject *pylong_ulong_mask = NULL;
31static PyObject *pyint_zero = NULL;
32#endif
33
Bob Ippolito232f3c92006-05-23 19:12:41 +000034/* The translation function for each format character is table driven */
Bob Ippolito232f3c92006-05-23 19:12:41 +000035typedef struct _formatdef {
36 char format;
Bob Ippolitoaa70a172006-05-26 20:25:23 +000037 Py_ssize_t size;
38 Py_ssize_t alignment;
Bob Ippolito232f3c92006-05-23 19:12:41 +000039 PyObject* (*unpack)(const char *,
40 const struct _formatdef *);
41 int (*pack)(char *, PyObject *,
42 const struct _formatdef *);
43} formatdef;
44
45typedef struct _formatcode {
46 const struct _formatdef *fmtdef;
Bob Ippolitoaa70a172006-05-26 20:25:23 +000047 Py_ssize_t offset;
48 Py_ssize_t size;
Bob Ippolito232f3c92006-05-23 19:12:41 +000049} formatcode;
50
51/* Struct object interface */
52
53typedef struct {
54 PyObject_HEAD
Bob Ippolitoaa70a172006-05-26 20:25:23 +000055 Py_ssize_t s_size;
56 Py_ssize_t s_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +000057 formatcode *s_codes;
58 PyObject *s_format;
59 PyObject *weakreflist; /* List of weak references */
60} PyStructObject;
61
Bob Ippolitoeb621272006-05-24 15:32:06 +000062
Bob Ippolito07c023b2006-05-23 19:32:25 +000063#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
64#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
Bob Ippolito232f3c92006-05-23 19:12:41 +000065
66
67/* Exception */
68
69static PyObject *StructError;
70
71
72/* Define various structs to figure out the alignments of types */
73
74
75typedef struct { char c; short x; } st_short;
76typedef struct { char c; int x; } st_int;
77typedef struct { char c; long x; } st_long;
78typedef struct { char c; float x; } st_float;
79typedef struct { char c; double x; } st_double;
80typedef struct { char c; void *x; } st_void_p;
81
82#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
83#define INT_ALIGN (sizeof(st_int) - sizeof(int))
84#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
85#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
86#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
87#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
88
89/* We can't support q and Q in native mode unless the compiler does;
90 in std mode, they're 8 bytes on all platforms. */
91#ifdef HAVE_LONG_LONG
92typedef struct { char c; PY_LONG_LONG x; } s_long_long;
93#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
94#endif
95
96#define STRINGIFY(x) #x
97
98#ifdef __powerc
99#pragma options align=reset
100#endif
101
102/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
103
104static PyObject *
105get_pylong(PyObject *v)
106{
107 PyNumberMethods *m;
108
109 assert(v != NULL);
110 if (PyInt_Check(v))
111 return PyLong_FromLong(PyInt_AS_LONG(v));
112 if (PyLong_Check(v)) {
113 Py_INCREF(v);
114 return v;
115 }
116 m = v->ob_type->tp_as_number;
117 if (m != NULL && m->nb_long != NULL) {
118 v = m->nb_long(v);
119 if (v == NULL)
120 return NULL;
121 if (PyLong_Check(v))
122 return v;
123 Py_DECREF(v);
124 }
125 PyErr_SetString(StructError,
126 "cannot convert argument to long");
127 return NULL;
128}
129
130/* Helper routine to get a Python integer and raise the appropriate error
131 if it isn't one */
132
133static int
134get_long(PyObject *v, long *p)
135{
136 long x = PyInt_AsLong(v);
137 if (x == -1 && PyErr_Occurred()) {
138 if (PyErr_ExceptionMatches(PyExc_TypeError))
139 PyErr_SetString(StructError,
140 "required argument is not an integer");
141 return -1;
142 }
143 *p = x;
144 return 0;
145}
146
147
148/* Same, but handling unsigned long */
149
150static int
151get_ulong(PyObject *v, unsigned long *p)
152{
153 if (PyLong_Check(v)) {
154 unsigned long x = PyLong_AsUnsignedLong(v);
155 if (x == (unsigned long)(-1) && PyErr_Occurred())
156 return -1;
157 *p = x;
158 return 0;
159 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000160 if (get_long(v, (long *)p) < 0)
161 return -1;
162 if (((long)*p) < 0) {
163 PyErr_SetString(StructError,
164 "unsigned argument is < 0");
165 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000166 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000167 return 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000168}
169
170#ifdef HAVE_LONG_LONG
171
172/* Same, but handling native long long. */
173
174static int
175get_longlong(PyObject *v, PY_LONG_LONG *p)
176{
177 PY_LONG_LONG x;
178
179 v = get_pylong(v);
180 if (v == NULL)
181 return -1;
182 assert(PyLong_Check(v));
183 x = PyLong_AsLongLong(v);
184 Py_DECREF(v);
185 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
186 return -1;
187 *p = x;
188 return 0;
189}
190
191/* Same, but handling native unsigned long long. */
192
193static int
194get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
195{
196 unsigned PY_LONG_LONG x;
197
198 v = get_pylong(v);
199 if (v == NULL)
200 return -1;
201 assert(PyLong_Check(v));
202 x = PyLong_AsUnsignedLongLong(v);
203 Py_DECREF(v);
204 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
205 return -1;
206 *p = x;
207 return 0;
208}
209
210#endif
211
Bob Ippolito4182a752006-05-30 17:37:54 +0000212#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000213
214/* Helper routine to get a Python integer and raise the appropriate error
215 if it isn't one */
216
217static int
218get_wrapped_long(PyObject *v, long *p)
219{
220 if (get_long(v, p) < 0) {
221 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError)) {
222 PyObject *wrapped;
223 long x;
224 PyErr_Clear();
Bob Ippolito4182a752006-05-30 17:37:54 +0000225 if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0)
Bob Ippolito2fd39772006-05-29 22:55:48 +0000226 return -1;
227 wrapped = PyNumber_And(v, pylong_ulong_mask);
228 if (wrapped == NULL)
229 return -1;
230 x = (long)PyLong_AsUnsignedLong(wrapped);
231 Py_DECREF(wrapped);
232 if (x == -1 && PyErr_Occurred())
233 return -1;
234 *p = x;
235 } else {
236 return -1;
237 }
238 }
239 return 0;
240}
241
242static int
243get_wrapped_ulong(PyObject *v, unsigned long *p)
244{
245 long x = (long)PyLong_AsUnsignedLong(v);
246 if (x == -1 && PyErr_Occurred()) {
247 PyObject *wrapped;
248 PyErr_Clear();
249 wrapped = PyNumber_And(v, pylong_ulong_mask);
250 if (wrapped == NULL)
251 return -1;
Bob Ippolito4182a752006-05-30 17:37:54 +0000252 if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0) {
Bob Ippolito2fd39772006-05-29 22:55:48 +0000253 Py_DECREF(wrapped);
254 return -1;
255 }
256 x = (long)PyLong_AsUnsignedLong(wrapped);
257 Py_DECREF(wrapped);
258 if (x == -1 && PyErr_Occurred())
259 return -1;
260 }
261 *p = (unsigned long)x;
262 return 0;
263}
264
265#define RANGE_ERROR(x, f, flag, mask) \
266 do { \
267 if (_range_error(f, flag) < 0) \
268 return -1; \
269 else \
270 (x) &= (mask); \
271 } while (0)
272
273#else
274
275#define get_wrapped_long get_long
276#define get_wrapped_ulong get_ulong
277#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
278
279#endif
280
Bob Ippolito232f3c92006-05-23 19:12:41 +0000281/* Floating point helpers */
282
283static PyObject *
284unpack_float(const char *p, /* start of 4-byte string */
285 int le) /* true for little-endian, false for big-endian */
286{
287 double x;
288
289 x = _PyFloat_Unpack4((unsigned char *)p, le);
290 if (x == -1.0 && PyErr_Occurred())
291 return NULL;
292 return PyFloat_FromDouble(x);
293}
294
295static PyObject *
296unpack_double(const char *p, /* start of 8-byte string */
297 int le) /* true for little-endian, false for big-endian */
298{
299 double x;
300
301 x = _PyFloat_Unpack8((unsigned char *)p, le);
302 if (x == -1.0 && PyErr_Occurred())
303 return NULL;
304 return PyFloat_FromDouble(x);
305}
306
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000307/* Helper to format the range error exceptions */
308static int
Armin Rigo162997e2006-05-29 17:59:47 +0000309_range_error(const formatdef *f, int is_unsigned)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000310{
Tim Petersd6a6f022006-05-31 15:33:22 +0000311 /* ulargest is the largest unsigned value with f->size bytes.
312 * Note that the simpler:
313 * ((size_t)1 << (f->size * 8)) - 1
Tim Peters72270c22006-05-31 15:34:37 +0000314 * doesn't work when f->size == sizeof(size_t) because C doesn't
315 * define what happens when a left shift count is >= the number of
316 * bits in the integer being shifted; e.g., on some boxes it doesn't
317 * shift at all when they're equal.
Tim Petersd6a6f022006-05-31 15:33:22 +0000318 */
319 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
320 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
321 if (is_unsigned)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000322 PyErr_Format(StructError,
Neal Norwitz971ea112006-05-31 07:43:27 +0000323 "'%c' format requires 0 <= number <= %zu",
Bob Ippolito28b26862006-05-29 15:47:29 +0000324 f->format,
Tim Petersd6a6f022006-05-31 15:33:22 +0000325 ulargest);
326 else {
327 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
328 PyErr_Format(StructError,
329 "'%c' format requires %zd <= number <= %zd",
330 f->format,
331 ~ largest,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000332 largest);
333 }
Bob Ippolito4182a752006-05-30 17:37:54 +0000334#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000335 {
336 PyObject *ptype, *pvalue, *ptraceback;
337 PyObject *msg;
338 int rval;
339 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
340 assert(pvalue != NULL);
341 msg = PyObject_Str(pvalue);
342 Py_XDECREF(ptype);
343 Py_XDECREF(pvalue);
344 Py_XDECREF(ptraceback);
345 if (msg == NULL)
346 return -1;
Tim Petersd6a6f022006-05-31 15:33:22 +0000347 rval = PyErr_Warn(PyExc_DeprecationWarning,
348 PyString_AS_STRING(msg));
Bob Ippolito2fd39772006-05-29 22:55:48 +0000349 Py_DECREF(msg);
350 if (rval == 0)
351 return 0;
352 }
353#endif
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000354 return -1;
355}
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000356
357
Bob Ippolito232f3c92006-05-23 19:12:41 +0000358
359/* A large number of small routines follow, with names of the form
360
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000361 [bln][up]_TYPE
Bob Ippolito232f3c92006-05-23 19:12:41 +0000362
363 [bln] distiguishes among big-endian, little-endian and native.
364 [pu] distiguishes between pack (to struct) and unpack (from struct).
365 TYPE is one of char, byte, ubyte, etc.
366*/
367
368/* Native mode routines. ****************************************************/
369/* NOTE:
370 In all n[up]_<type> routines handling types larger than 1 byte, there is
371 *no* guarantee that the p pointer is properly aligned for each type,
372 therefore memcpy is called. An intermediate variable is used to
373 compensate for big-endian architectures.
374 Normally both the intermediate variable and the memcpy call will be
375 skipped by C optimisation in little-endian architectures (gcc >= 2.91
376 does this). */
377
378static PyObject *
379nu_char(const char *p, const formatdef *f)
380{
381 return PyString_FromStringAndSize(p, 1);
382}
383
384static PyObject *
385nu_byte(const char *p, const formatdef *f)
386{
387 return PyInt_FromLong((long) *(signed char *)p);
388}
389
390static PyObject *
391nu_ubyte(const char *p, const formatdef *f)
392{
393 return PyInt_FromLong((long) *(unsigned char *)p);
394}
395
396static PyObject *
397nu_short(const char *p, const formatdef *f)
398{
399 short x;
400 memcpy((char *)&x, p, sizeof x);
401 return PyInt_FromLong((long)x);
402}
403
404static PyObject *
405nu_ushort(const char *p, const formatdef *f)
406{
407 unsigned short x;
408 memcpy((char *)&x, p, sizeof x);
409 return PyInt_FromLong((long)x);
410}
411
412static PyObject *
413nu_int(const char *p, const formatdef *f)
414{
415 int x;
416 memcpy((char *)&x, p, sizeof x);
417 return PyInt_FromLong((long)x);
418}
419
420static PyObject *
421nu_uint(const char *p, const formatdef *f)
422{
423 unsigned int x;
424 memcpy((char *)&x, p, sizeof x);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000425#if (SIZEOF_LONG > SIZEOF_INT)
426 return PyInt_FromLong((long)x);
427#else
428 if (x <= ((unsigned int)LONG_MAX))
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000429 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000430 return PyLong_FromUnsignedLong((unsigned long)x);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000431#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000432}
433
434static PyObject *
435nu_long(const char *p, const formatdef *f)
436{
437 long x;
438 memcpy((char *)&x, p, sizeof x);
439 return PyInt_FromLong(x);
440}
441
442static PyObject *
443nu_ulong(const char *p, const formatdef *f)
444{
445 unsigned long x;
446 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000447 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000448 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000449 return PyLong_FromUnsignedLong(x);
450}
451
452/* Native mode doesn't support q or Q unless the platform C supports
453 long long (or, on Windows, __int64). */
454
455#ifdef HAVE_LONG_LONG
456
457static PyObject *
458nu_longlong(const char *p, const formatdef *f)
459{
460 PY_LONG_LONG x;
461 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000462 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000463 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000464 return PyLong_FromLongLong(x);
465}
466
467static PyObject *
468nu_ulonglong(const char *p, const formatdef *f)
469{
470 unsigned PY_LONG_LONG x;
471 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000472 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000473 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000474 return PyLong_FromUnsignedLongLong(x);
475}
476
477#endif
478
479static PyObject *
480nu_float(const char *p, const formatdef *f)
481{
482 float x;
483 memcpy((char *)&x, p, sizeof x);
484 return PyFloat_FromDouble((double)x);
485}
486
487static PyObject *
488nu_double(const char *p, const formatdef *f)
489{
490 double x;
491 memcpy((char *)&x, p, sizeof x);
492 return PyFloat_FromDouble(x);
493}
494
495static PyObject *
496nu_void_p(const char *p, const formatdef *f)
497{
498 void *x;
499 memcpy((char *)&x, p, sizeof x);
500 return PyLong_FromVoidPtr(x);
501}
502
503static int
504np_byte(char *p, PyObject *v, const formatdef *f)
505{
506 long x;
507 if (get_long(v, &x) < 0)
508 return -1;
509 if (x < -128 || x > 127){
510 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000511 "byte format requires -128 <= number <= 127");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000512 return -1;
513 }
514 *p = (char)x;
515 return 0;
516}
517
518static int
519np_ubyte(char *p, PyObject *v, const formatdef *f)
520{
521 long x;
522 if (get_long(v, &x) < 0)
523 return -1;
524 if (x < 0 || x > 255){
525 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000526 "ubyte format requires 0 <= number <= 255");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000527 return -1;
528 }
529 *p = (char)x;
530 return 0;
531}
532
533static int
534np_char(char *p, PyObject *v, const formatdef *f)
535{
536 if (!PyString_Check(v) || PyString_Size(v) != 1) {
537 PyErr_SetString(StructError,
538 "char format require string of length 1");
539 return -1;
540 }
541 *p = *PyString_AsString(v);
542 return 0;
543}
544
545static int
546np_short(char *p, PyObject *v, const formatdef *f)
547{
548 long x;
549 short y;
550 if (get_long(v, &x) < 0)
551 return -1;
552 if (x < SHRT_MIN || x > SHRT_MAX){
553 PyErr_SetString(StructError,
554 "short format requires " STRINGIFY(SHRT_MIN)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000555 " <= number <= " STRINGIFY(SHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000556 return -1;
557 }
558 y = (short)x;
559 memcpy(p, (char *)&y, sizeof y);
560 return 0;
561}
562
563static int
564np_ushort(char *p, PyObject *v, const formatdef *f)
565{
566 long x;
567 unsigned short y;
568 if (get_long(v, &x) < 0)
569 return -1;
570 if (x < 0 || x > USHRT_MAX){
571 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000572 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000573 return -1;
574 }
575 y = (unsigned short)x;
576 memcpy(p, (char *)&y, sizeof y);
577 return 0;
578}
579
580static int
581np_int(char *p, PyObject *v, const formatdef *f)
582{
583 long x;
584 int y;
585 if (get_long(v, &x) < 0)
586 return -1;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000587#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000588 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Bob Ippolito28b26862006-05-29 15:47:29 +0000589 return _range_error(f, 0);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000590#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000591 y = (int)x;
592 memcpy(p, (char *)&y, sizeof y);
593 return 0;
594}
595
596static int
597np_uint(char *p, PyObject *v, const formatdef *f)
598{
599 unsigned long x;
600 unsigned int y;
601 if (get_ulong(v, &x) < 0)
Bob Ippolito28b26862006-05-29 15:47:29 +0000602 return _range_error(f, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000603 y = (unsigned int)x;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000604#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000605 if (x > ((unsigned long)UINT_MAX))
Bob Ippolito28b26862006-05-29 15:47:29 +0000606 return _range_error(f, 1);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000607#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000608 memcpy(p, (char *)&y, sizeof y);
609 return 0;
610}
611
612static int
613np_long(char *p, PyObject *v, const formatdef *f)
614{
615 long x;
616 if (get_long(v, &x) < 0)
617 return -1;
618 memcpy(p, (char *)&x, sizeof x);
619 return 0;
620}
621
622static int
623np_ulong(char *p, PyObject *v, const formatdef *f)
624{
625 unsigned long x;
626 if (get_ulong(v, &x) < 0)
Bob Ippolito28b26862006-05-29 15:47:29 +0000627 return _range_error(f, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000628 memcpy(p, (char *)&x, sizeof x);
629 return 0;
630}
631
632#ifdef HAVE_LONG_LONG
633
634static int
635np_longlong(char *p, PyObject *v, const formatdef *f)
636{
637 PY_LONG_LONG x;
638 if (get_longlong(v, &x) < 0)
639 return -1;
640 memcpy(p, (char *)&x, sizeof x);
641 return 0;
642}
643
644static int
645np_ulonglong(char *p, PyObject *v, const formatdef *f)
646{
647 unsigned PY_LONG_LONG x;
648 if (get_ulonglong(v, &x) < 0)
649 return -1;
650 memcpy(p, (char *)&x, sizeof x);
651 return 0;
652}
653#endif
654
655static int
656np_float(char *p, PyObject *v, const formatdef *f)
657{
658 float x = (float)PyFloat_AsDouble(v);
659 if (x == -1 && PyErr_Occurred()) {
660 PyErr_SetString(StructError,
661 "required argument is not a float");
662 return -1;
663 }
664 memcpy(p, (char *)&x, sizeof x);
665 return 0;
666}
667
668static int
669np_double(char *p, PyObject *v, const formatdef *f)
670{
671 double x = PyFloat_AsDouble(v);
672 if (x == -1 && PyErr_Occurred()) {
673 PyErr_SetString(StructError,
674 "required argument is not a float");
675 return -1;
676 }
677 memcpy(p, (char *)&x, sizeof(double));
678 return 0;
679}
680
681static int
682np_void_p(char *p, PyObject *v, const formatdef *f)
683{
684 void *x;
685
686 v = get_pylong(v);
687 if (v == NULL)
688 return -1;
689 assert(PyLong_Check(v));
690 x = PyLong_AsVoidPtr(v);
691 Py_DECREF(v);
692 if (x == NULL && PyErr_Occurred())
693 return -1;
694 memcpy(p, (char *)&x, sizeof x);
695 return 0;
696}
697
698static formatdef native_table[] = {
699 {'x', sizeof(char), 0, NULL},
700 {'b', sizeof(char), 0, nu_byte, np_byte},
701 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
702 {'c', sizeof(char), 0, nu_char, np_char},
703 {'s', sizeof(char), 0, NULL},
704 {'p', sizeof(char), 0, NULL},
705 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
706 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
707 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
708 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
709 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
710 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000711#ifdef HAVE_LONG_LONG
712 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
713 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
714#endif
Bob Ippolitoa99865b2006-05-25 19:56:56 +0000715 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
716 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
717 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000718 {0}
719};
720
721/* Big-endian routines. *****************************************************/
722
723static PyObject *
724bu_int(const char *p, const formatdef *f)
725{
726 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000727 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000728 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000729 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000730 x = (x<<8) | *bytes++;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000731 } while (--i > 0);
732 /* Extend the sign bit. */
733 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000734 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000735 return PyInt_FromLong(x);
736}
737
738static PyObject *
739bu_uint(const char *p, const formatdef *f)
740{
741 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000742 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000743 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000744 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000745 x = (x<<8) | *bytes++;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000746 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000747 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000748 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000749 return PyLong_FromUnsignedLong(x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000750}
751
752static PyObject *
753bu_longlong(const char *p, const formatdef *f)
754{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000755#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000756 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000757 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000758 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000759 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000760 x = (x<<8) | *bytes++;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000761 } while (--i > 0);
762 /* Extend the sign bit. */
763 if (SIZEOF_LONG_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000764 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000765 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000766 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000767 return PyLong_FromLongLong(x);
768#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000769 return _PyLong_FromByteArray((const unsigned char *)p,
770 8,
771 0, /* little-endian */
772 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000773#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000774}
775
776static PyObject *
777bu_ulonglong(const char *p, const formatdef *f)
778{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000779#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000780 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000781 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000782 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000783 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000784 x = (x<<8) | *bytes++;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000785 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000786 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000787 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000788 return PyLong_FromUnsignedLongLong(x);
789#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000790 return _PyLong_FromByteArray((const unsigned char *)p,
791 8,
792 0, /* little-endian */
793 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000794#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000795}
796
797static PyObject *
798bu_float(const char *p, const formatdef *f)
799{
800 return unpack_float(p, 0);
801}
802
803static PyObject *
804bu_double(const char *p, const formatdef *f)
805{
806 return unpack_double(p, 0);
807}
808
809static int
810bp_int(char *p, PyObject *v, const formatdef *f)
811{
812 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000813 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +0000814 if (get_wrapped_long(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000815 return -1;
816 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000817 if (i != SIZEOF_LONG) {
818 if ((i == 2) && (x < -32768 || x > 32767))
Bob Ippolito2fd39772006-05-29 22:55:48 +0000819 RANGE_ERROR(x, f, 0, 0xffffL);
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000820#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000821 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Bob Ippolito2fd39772006-05-29 22:55:48 +0000822 RANGE_ERROR(x, f, 0, 0xffffffffL);
823#endif
Bob Ippolito4182a752006-05-30 17:37:54 +0000824#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000825 else if ((i == 1) && (x < -128 || x > 127))
826 RANGE_ERROR(x, f, 0, 0xffL);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000827#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000828 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000829 do {
830 p[--i] = (char)x;
831 x >>= 8;
832 } while (i > 0);
833 return 0;
834}
835
836static int
837bp_uint(char *p, PyObject *v, const formatdef *f)
838{
839 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000840 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +0000841 if (get_wrapped_ulong(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000842 return -1;
843 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000844 if (i != SIZEOF_LONG) {
845 unsigned long maxint = 1;
846 maxint <<= (unsigned long)(i * 8);
847 if (x >= maxint)
Bob Ippolito2fd39772006-05-29 22:55:48 +0000848 RANGE_ERROR(x, f, 1, maxint - 1);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000849 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000850 do {
851 p[--i] = (char)x;
852 x >>= 8;
853 } while (i > 0);
854 return 0;
855}
856
857static int
858bp_longlong(char *p, PyObject *v, const formatdef *f)
859{
860 int res;
861 v = get_pylong(v);
862 if (v == NULL)
863 return -1;
864 res = _PyLong_AsByteArray((PyLongObject *)v,
865 (unsigned char *)p,
866 8,
867 0, /* little_endian */
868 1 /* signed */);
869 Py_DECREF(v);
870 return res;
871}
872
873static int
874bp_ulonglong(char *p, PyObject *v, const formatdef *f)
875{
876 int res;
877 v = get_pylong(v);
878 if (v == NULL)
879 return -1;
880 res = _PyLong_AsByteArray((PyLongObject *)v,
881 (unsigned char *)p,
882 8,
883 0, /* little_endian */
884 0 /* signed */);
885 Py_DECREF(v);
886 return res;
887}
888
889static int
890bp_float(char *p, PyObject *v, const formatdef *f)
891{
892 double x = PyFloat_AsDouble(v);
893 if (x == -1 && PyErr_Occurred()) {
894 PyErr_SetString(StructError,
895 "required argument is not a float");
896 return -1;
897 }
898 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
899}
900
901static int
902bp_double(char *p, PyObject *v, const formatdef *f)
903{
904 double x = PyFloat_AsDouble(v);
905 if (x == -1 && PyErr_Occurred()) {
906 PyErr_SetString(StructError,
907 "required argument is not a float");
908 return -1;
909 }
910 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
911}
912
913static formatdef bigendian_table[] = {
914 {'x', 1, 0, NULL},
Bob Ippolito4182a752006-05-30 17:37:54 +0000915#ifdef PY_STRUCT_OVERFLOW_MASKING
916 /* Native packers do range checking without overflow masking. */
Bob Ippolito2fd39772006-05-29 22:55:48 +0000917 {'b', 1, 0, nu_byte, bp_int},
918 {'B', 1, 0, nu_ubyte, bp_uint},
919#else
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000920 {'b', 1, 0, nu_byte, np_byte},
921 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito2fd39772006-05-29 22:55:48 +0000922#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000923 {'c', 1, 0, nu_char, np_char},
924 {'s', 1, 0, NULL},
925 {'p', 1, 0, NULL},
926 {'h', 2, 0, bu_int, bp_int},
927 {'H', 2, 0, bu_uint, bp_uint},
928 {'i', 4, 0, bu_int, bp_int},
929 {'I', 4, 0, bu_uint, bp_uint},
930 {'l', 4, 0, bu_int, bp_int},
931 {'L', 4, 0, bu_uint, bp_uint},
932 {'q', 8, 0, bu_longlong, bp_longlong},
933 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
934 {'f', 4, 0, bu_float, bp_float},
935 {'d', 8, 0, bu_double, bp_double},
936 {0}
937};
938
939/* Little-endian routines. *****************************************************/
940
941static PyObject *
942lu_int(const char *p, const formatdef *f)
943{
944 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000945 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000946 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000947 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000948 x = (x<<8) | bytes[--i];
Bob Ippolito232f3c92006-05-23 19:12:41 +0000949 } while (i > 0);
950 /* Extend the sign bit. */
951 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000952 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000953 return PyInt_FromLong(x);
954}
955
956static PyObject *
957lu_uint(const char *p, const formatdef *f)
958{
959 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000960 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000961 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000962 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000963 x = (x<<8) | bytes[--i];
Bob Ippolito232f3c92006-05-23 19:12:41 +0000964 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000965 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000966 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000967 return PyLong_FromUnsignedLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000968}
969
970static PyObject *
971lu_longlong(const char *p, const formatdef *f)
972{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000973#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000974 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000975 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000976 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000977 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000978 x = (x<<8) | bytes[--i];
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000979 } while (i > 0);
980 /* Extend the sign bit. */
981 if (SIZEOF_LONG_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000982 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000983 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000984 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000985 return PyLong_FromLongLong(x);
986#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000987 return _PyLong_FromByteArray((const unsigned char *)p,
988 8,
989 1, /* little-endian */
990 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000991#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000992}
993
994static PyObject *
995lu_ulonglong(const char *p, const formatdef *f)
996{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000997#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000998 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000999 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +00001000 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001001 do {
Bob Ippolito28b26862006-05-29 15:47:29 +00001002 x = (x<<8) | bytes[--i];
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001003 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001004 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001005 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001006 return PyLong_FromUnsignedLongLong(x);
1007#else
Bob Ippolito232f3c92006-05-23 19:12:41 +00001008 return _PyLong_FromByteArray((const unsigned char *)p,
1009 8,
1010 1, /* little-endian */
1011 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001012#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001013}
1014
1015static PyObject *
1016lu_float(const char *p, const formatdef *f)
1017{
1018 return unpack_float(p, 1);
1019}
1020
1021static PyObject *
1022lu_double(const char *p, const formatdef *f)
1023{
1024 return unpack_double(p, 1);
1025}
1026
1027static int
1028lp_int(char *p, PyObject *v, const formatdef *f)
1029{
1030 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001031 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001032 if (get_wrapped_long(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001033 return -1;
1034 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001035 if (i != SIZEOF_LONG) {
1036 if ((i == 2) && (x < -32768 || x > 32767))
Bob Ippolito2fd39772006-05-29 22:55:48 +00001037 RANGE_ERROR(x, f, 0, 0xffffL);
Bob Ippolito90bd0a52006-05-27 11:47:12 +00001038#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001039 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Bob Ippolito2fd39772006-05-29 22:55:48 +00001040 RANGE_ERROR(x, f, 0, 0xffffffffL);
1041#endif
Bob Ippolito4182a752006-05-30 17:37:54 +00001042#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +00001043 else if ((i == 1) && (x < -128 || x > 127))
1044 RANGE_ERROR(x, f, 0, 0xffL);
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001045#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001046 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001047 do {
1048 *p++ = (char)x;
1049 x >>= 8;
1050 } while (--i > 0);
1051 return 0;
1052}
1053
1054static int
1055lp_uint(char *p, PyObject *v, const formatdef *f)
1056{
1057 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001058 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001059 if (get_wrapped_ulong(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001060 return -1;
1061 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001062 if (i != SIZEOF_LONG) {
1063 unsigned long maxint = 1;
1064 maxint <<= (unsigned long)(i * 8);
1065 if (x >= maxint)
Bob Ippolito2fd39772006-05-29 22:55:48 +00001066 RANGE_ERROR(x, f, 1, maxint - 1);
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001067 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001068 do {
1069 *p++ = (char)x;
1070 x >>= 8;
1071 } while (--i > 0);
1072 return 0;
1073}
1074
1075static int
1076lp_longlong(char *p, PyObject *v, const formatdef *f)
1077{
1078 int res;
1079 v = get_pylong(v);
1080 if (v == NULL)
1081 return -1;
1082 res = _PyLong_AsByteArray((PyLongObject*)v,
1083 (unsigned char *)p,
1084 8,
1085 1, /* little_endian */
1086 1 /* signed */);
1087 Py_DECREF(v);
1088 return res;
1089}
1090
1091static int
1092lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1093{
1094 int res;
1095 v = get_pylong(v);
1096 if (v == NULL)
1097 return -1;
1098 res = _PyLong_AsByteArray((PyLongObject*)v,
1099 (unsigned char *)p,
1100 8,
1101 1, /* little_endian */
1102 0 /* signed */);
1103 Py_DECREF(v);
1104 return res;
1105}
1106
1107static int
1108lp_float(char *p, PyObject *v, const formatdef *f)
1109{
1110 double x = PyFloat_AsDouble(v);
1111 if (x == -1 && PyErr_Occurred()) {
1112 PyErr_SetString(StructError,
1113 "required argument is not a float");
1114 return -1;
1115 }
1116 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1117}
1118
1119static int
1120lp_double(char *p, PyObject *v, const formatdef *f)
1121{
1122 double x = PyFloat_AsDouble(v);
1123 if (x == -1 && PyErr_Occurred()) {
1124 PyErr_SetString(StructError,
1125 "required argument is not a float");
1126 return -1;
1127 }
1128 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1129}
1130
1131static formatdef lilendian_table[] = {
1132 {'x', 1, 0, NULL},
Bob Ippolito4182a752006-05-30 17:37:54 +00001133#ifdef PY_STRUCT_OVERFLOW_MASKING
1134 /* Native packers do range checking without overflow masking. */
Bob Ippolito2fd39772006-05-29 22:55:48 +00001135 {'b', 1, 0, nu_byte, lp_int},
1136 {'B', 1, 0, nu_ubyte, lp_uint},
1137#else
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001138 {'b', 1, 0, nu_byte, np_byte},
1139 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito2fd39772006-05-29 22:55:48 +00001140#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001141 {'c', 1, 0, nu_char, np_char},
1142 {'s', 1, 0, NULL},
1143 {'p', 1, 0, NULL},
1144 {'h', 2, 0, lu_int, lp_int},
1145 {'H', 2, 0, lu_uint, lp_uint},
1146 {'i', 4, 0, lu_int, lp_int},
1147 {'I', 4, 0, lu_uint, lp_uint},
1148 {'l', 4, 0, lu_int, lp_int},
1149 {'L', 4, 0, lu_uint, lp_uint},
1150 {'q', 8, 0, lu_longlong, lp_longlong},
1151 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1152 {'f', 4, 0, lu_float, lp_float},
1153 {'d', 8, 0, lu_double, lp_double},
1154 {0}
1155};
1156
1157
1158static const formatdef *
1159whichtable(char **pfmt)
1160{
1161 const char *fmt = (*pfmt)++; /* May be backed out of later */
1162 switch (*fmt) {
1163 case '<':
1164 return lilendian_table;
1165 case '>':
1166 case '!': /* Network byte order is big-endian */
1167 return bigendian_table;
1168 case '=': { /* Host byte order -- different from native in aligment! */
1169 int n = 1;
1170 char *p = (char *) &n;
1171 if (*p == 1)
1172 return lilendian_table;
1173 else
1174 return bigendian_table;
1175 }
1176 default:
1177 --*pfmt; /* Back out of pointer increment */
1178 /* Fall through */
1179 case '@':
1180 return native_table;
1181 }
1182}
1183
1184
1185/* Get the table entry for a format code */
1186
1187static const formatdef *
1188getentry(int c, const formatdef *f)
1189{
1190 for (; f->format != '\0'; f++) {
1191 if (f->format == c) {
1192 return f;
1193 }
1194 }
1195 PyErr_SetString(StructError, "bad char in struct format");
1196 return NULL;
1197}
1198
1199
1200/* Align a size according to a format code */
1201
1202static int
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001203align(Py_ssize_t size, char c, const formatdef *e)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001204{
1205 if (e->format == c) {
1206 if (e->alignment) {
1207 size = ((size + e->alignment - 1)
1208 / e->alignment)
1209 * e->alignment;
1210 }
1211 }
1212 return size;
1213}
1214
1215
1216/* calculate the size of a format string */
1217
1218static int
1219prepare_s(PyStructObject *self)
1220{
1221 const formatdef *f;
1222 const formatdef *e;
1223 formatcode *codes;
Tim Petersc2b550e2006-05-31 14:28:07 +00001224
Bob Ippolito232f3c92006-05-23 19:12:41 +00001225 const char *s;
1226 const char *fmt;
1227 char c;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001228 Py_ssize_t size, len, num, itemsize, x;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001229
1230 fmt = PyString_AS_STRING(self->s_format);
1231
1232 f = whichtable((char **)&fmt);
Tim Petersc2b550e2006-05-31 14:28:07 +00001233
Bob Ippolito232f3c92006-05-23 19:12:41 +00001234 s = fmt;
1235 size = 0;
1236 len = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001237 while ((c = *s++) != '\0') {
1238 if (isspace(Py_CHARMASK(c)))
1239 continue;
1240 if ('0' <= c && c <= '9') {
1241 num = c - '0';
1242 while ('0' <= (c = *s++) && c <= '9') {
1243 x = num*10 + (c - '0');
1244 if (x/10 != num) {
1245 PyErr_SetString(
1246 StructError,
1247 "overflow in item count");
1248 return -1;
1249 }
1250 num = x;
1251 }
1252 if (c == '\0')
1253 break;
1254 }
1255 else
1256 num = 1;
1257
1258 e = getentry(c, f);
1259 if (e == NULL)
1260 return -1;
Tim Petersc2b550e2006-05-31 14:28:07 +00001261
Bob Ippolito232f3c92006-05-23 19:12:41 +00001262 switch (c) {
1263 case 's': /* fall through */
1264 case 'p': len++; break;
1265 case 'x': break;
1266 default: len += num; break;
1267 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001268
1269 itemsize = e->size;
1270 size = align(size, c, e);
1271 x = num * itemsize;
1272 size += x;
1273 if (x/itemsize != num || size < 0) {
1274 PyErr_SetString(StructError,
1275 "total struct size too long");
1276 return -1;
1277 }
1278 }
1279
1280 self->s_size = size;
1281 self->s_len = len;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001282 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
Bob Ippolito232f3c92006-05-23 19:12:41 +00001283 if (codes == NULL) {
1284 PyErr_NoMemory();
1285 return -1;
1286 }
1287 self->s_codes = codes;
Tim Petersc2b550e2006-05-31 14:28:07 +00001288
Bob Ippolito232f3c92006-05-23 19:12:41 +00001289 s = fmt;
1290 size = 0;
1291 while ((c = *s++) != '\0') {
1292 if (isspace(Py_CHARMASK(c)))
1293 continue;
1294 if ('0' <= c && c <= '9') {
1295 num = c - '0';
1296 while ('0' <= (c = *s++) && c <= '9')
1297 num = num*10 + (c - '0');
1298 if (c == '\0')
1299 break;
1300 }
1301 else
1302 num = 1;
1303
1304 e = getentry(c, f);
Tim Petersc2b550e2006-05-31 14:28:07 +00001305
Bob Ippolito232f3c92006-05-23 19:12:41 +00001306 size = align(size, c, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001307 if (c == 's' || c == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001308 codes->offset = size;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001309 codes->size = num;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001310 codes->fmtdef = e;
1311 codes++;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001312 size += num;
1313 } else if (c == 'x') {
1314 size += num;
1315 } else {
1316 while (--num >= 0) {
1317 codes->offset = size;
1318 codes->size = e->size;
1319 codes->fmtdef = e;
1320 codes++;
1321 size += e->size;
1322 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001323 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001324 }
1325 codes->fmtdef = NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001326 codes->offset = size;
1327 codes->size = 0;
Tim Petersc2b550e2006-05-31 14:28:07 +00001328
Bob Ippolito232f3c92006-05-23 19:12:41 +00001329 return 0;
1330}
1331
1332static PyObject *
1333s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1334{
1335 PyObject *self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001336
1337 assert(type != NULL && type->tp_alloc != NULL);
1338
1339 self = type->tp_alloc(type, 0);
1340 if (self != NULL) {
1341 PyStructObject *s = (PyStructObject*)self;
1342 Py_INCREF(Py_None);
1343 s->s_format = Py_None;
1344 s->s_codes = NULL;
1345 s->s_size = -1;
1346 s->s_len = -1;
1347 }
1348 return self;
1349}
1350
1351static int
1352s_init(PyObject *self, PyObject *args, PyObject *kwds)
1353{
1354 PyStructObject *soself = (PyStructObject *)self;
1355 PyObject *o_format = NULL;
1356 int ret = 0;
1357 static char *kwlist[] = {"format", 0};
1358
1359 assert(PyStruct_Check(self));
1360
1361 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1362 &o_format))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001363 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001364
1365 Py_INCREF(o_format);
1366 Py_XDECREF(soself->s_format);
1367 soself->s_format = o_format;
Tim Petersc2b550e2006-05-31 14:28:07 +00001368
Bob Ippolito232f3c92006-05-23 19:12:41 +00001369 ret = prepare_s(soself);
1370 return ret;
1371}
1372
1373static void
1374s_dealloc(PyStructObject *s)
1375{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001376 if (s->weakreflist != NULL)
1377 PyObject_ClearWeakRefs((PyObject *)s);
1378 if (s->s_codes != NULL) {
1379 PyMem_FREE(s->s_codes);
1380 }
1381 Py_XDECREF(s->s_format);
1382 s->ob_type->tp_free((PyObject *)s);
1383}
1384
Bob Ippolitoeb621272006-05-24 15:32:06 +00001385static PyObject *
1386s_unpack_internal(PyStructObject *soself, char *startfrom) {
1387 formatcode *code;
1388 Py_ssize_t i = 0;
1389 PyObject *result = PyTuple_New(soself->s_len);
1390 if (result == NULL)
1391 return NULL;
1392
1393 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1394 PyObject *v;
1395 const formatdef *e = code->fmtdef;
1396 const char *res = startfrom + code->offset;
1397 if (e->format == 's') {
1398 v = PyString_FromStringAndSize(res, code->size);
1399 if (v == NULL)
1400 goto fail;
1401 PyTuple_SET_ITEM(result, i++, v);
1402 } else if (e->format == 'p') {
1403 Py_ssize_t n = *(unsigned char*)res;
1404 if (n >= code->size)
1405 n = code->size - 1;
1406 v = PyString_FromStringAndSize(res + 1, n);
1407 if (v == NULL)
1408 goto fail;
1409 PyTuple_SET_ITEM(result, i++, v);
1410 } else {
1411 v = e->unpack(res, e);
1412 if (v == NULL)
1413 goto fail;
1414 PyTuple_SET_ITEM(result, i++, v);
1415 }
1416 }
1417
1418 return result;
1419fail:
1420 Py_DECREF(result);
1421 return NULL;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001422}
Bob Ippolitoeb621272006-05-24 15:32:06 +00001423
1424
Bob Ippolito232f3c92006-05-23 19:12:41 +00001425PyDoc_STRVAR(s_unpack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001426"S.unpack(str) -> (v1, v2, ...)\n\
Bob Ippolito232f3c92006-05-23 19:12:41 +00001427\n\
1428Return tuple containing values unpacked according to this Struct's format.\n\
1429Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1430strings.");
1431
1432static PyObject *
1433s_unpack(PyObject *self, PyObject *inputstr)
1434{
Bob Ippolitoeb621272006-05-24 15:32:06 +00001435 PyStructObject *soself = (PyStructObject *)self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001436 assert(PyStruct_Check(self));
Tim Petersc2b550e2006-05-31 14:28:07 +00001437 assert(soself->s_codes != NULL);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001438 if (inputstr == NULL || !PyString_Check(inputstr) ||
Bob Ippolitoeb621272006-05-24 15:32:06 +00001439 PyString_GET_SIZE(inputstr) != soself->s_size) {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001440 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001441 "unpack requires a string argument of length %zd", soself->s_size);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001442 return NULL;
1443 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001444 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1445}
1446
1447PyDoc_STRVAR(s_unpack_from__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001448"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
Bob Ippolitoeb621272006-05-24 15:32:06 +00001449\n\
1450Return tuple containing values unpacked according to this Struct's format.\n\
1451Unlike unpack, unpack_from can unpack values from any object supporting\n\
1452the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1453See struct.__doc__ for more on format strings.");
1454
1455static PyObject *
1456s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1457{
1458 static char *kwlist[] = {"buffer", "offset", 0};
1459#if (PY_VERSION_HEX < 0x02050000)
1460 static char *fmt = "z#|i:unpack_from";
1461#else
1462 static char *fmt = "z#|n:unpack_from";
1463#endif
1464 Py_ssize_t buffer_len = 0, offset = 0;
1465 char *buffer = NULL;
1466 PyStructObject *soself = (PyStructObject *)self;
1467 assert(PyStruct_Check(self));
1468 assert(soself->s_codes != NULL);
1469
1470 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1471 &buffer, &buffer_len, &offset))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001472 return NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001473
1474 if (buffer == NULL) {
1475 PyErr_Format(StructError,
1476 "unpack_from requires a buffer argument");
Bob Ippolito232f3c92006-05-23 19:12:41 +00001477 return NULL;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001478 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001479
Bob Ippolitoeb621272006-05-24 15:32:06 +00001480 if (offset < 0)
1481 offset += buffer_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001482
Bob Ippolitoeb621272006-05-24 15:32:06 +00001483 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1484 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001485 "unpack_from requires a buffer of at least %zd bytes",
Bob Ippolitoeb621272006-05-24 15:32:06 +00001486 soself->s_size);
1487 return NULL;
1488 }
1489 return s_unpack_internal(soself, buffer + offset);
1490}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001491
Bob Ippolito232f3c92006-05-23 19:12:41 +00001492
Martin Blais2856e5f2006-05-26 12:03:27 +00001493/*
1494 * Guts of the pack function.
1495 *
1496 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1497 * argument for where to start processing the arguments for packing, and a
1498 * character buffer for writing the packed string. The caller must insure
1499 * that the buffer may contain the required length for packing the arguments.
1500 * 0 is returned on success, 1 is returned if there is an error.
1501 *
1502 */
1503static int
1504s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001505{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001506 formatcode *code;
1507 Py_ssize_t i;
Martin Blais2856e5f2006-05-26 12:03:27 +00001508
1509 memset(buf, '\0', soself->s_size);
1510 i = offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001511 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1512 Py_ssize_t n;
1513 PyObject *v;
1514 const formatdef *e = code->fmtdef;
Martin Blais2856e5f2006-05-26 12:03:27 +00001515 char *res = buf + code->offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001516 if (e->format == 's') {
1517 v = PyTuple_GET_ITEM(args, i++);
1518 if (!PyString_Check(v)) {
1519 PyErr_SetString(StructError,
1520 "argument for 's' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001521 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001522 }
1523 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001524 if (n > code->size)
1525 n = code->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001526 if (n > 0)
1527 memcpy(res, PyString_AS_STRING(v), n);
1528 } else if (e->format == 'p') {
1529 v = PyTuple_GET_ITEM(args, i++);
1530 if (!PyString_Check(v)) {
1531 PyErr_SetString(StructError,
1532 "argument for 'p' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001533 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001534 }
1535 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001536 if (n > (code->size - 1))
1537 n = code->size - 1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001538 if (n > 0)
1539 memcpy(res + 1, PyString_AS_STRING(v), n);
1540 if (n > 255)
1541 n = 255;
1542 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1543 } else {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001544 v = PyTuple_GET_ITEM(args, i++);
Bob Ippolito2fd39772006-05-29 22:55:48 +00001545 if (e->pack(res, v, e) < 0) {
1546 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1547 PyErr_SetString(StructError,
1548 "long too large to convert to int");
Martin Blais2856e5f2006-05-26 12:03:27 +00001549 return -1;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001550 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001551 }
1552 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001553
Martin Blais2856e5f2006-05-26 12:03:27 +00001554 /* Success */
1555 return 0;
1556}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001557
Martin Blais2856e5f2006-05-26 12:03:27 +00001558
1559PyDoc_STRVAR(s_pack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001560"S.pack(v1, v2, ...) -> string\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001561\n\
1562Return a string containing values v1, v2, ... packed according to this\n\
1563Struct's format. See struct.__doc__ for more on format strings.");
1564
1565static PyObject *
1566s_pack(PyObject *self, PyObject *args)
1567{
1568 PyStructObject *soself;
1569 PyObject *result;
1570
1571 /* Validate arguments. */
1572 soself = (PyStructObject *)self;
1573 assert(PyStruct_Check(self));
1574 assert(soself->s_codes != NULL);
Martin Blaisaf2ae722006-06-04 13:49:49 +00001575 if (PyTuple_GET_SIZE(args) != soself->s_len)
Martin Blais2856e5f2006-05-26 12:03:27 +00001576 {
1577 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001578 "pack requires exactly %zd arguments", soself->s_len);
Martin Blais2856e5f2006-05-26 12:03:27 +00001579 return NULL;
1580 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001581
Martin Blais2856e5f2006-05-26 12:03:27 +00001582 /* Allocate a new string */
1583 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1584 if (result == NULL)
1585 return NULL;
Tim Petersc2b550e2006-05-31 14:28:07 +00001586
Martin Blais2856e5f2006-05-26 12:03:27 +00001587 /* Call the guts */
1588 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1589 Py_DECREF(result);
1590 return NULL;
1591 }
1592
1593 return result;
1594}
1595
Martin Blaisaf2ae722006-06-04 13:49:49 +00001596PyDoc_STRVAR(s_pack_into__doc__,
1597"S.pack_into(buffer, offset, v1, v2, ...)\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001598\n\
Martin Blaisaf2ae722006-06-04 13:49:49 +00001599Pack the values v1, v2, ... according to this Struct's format, write \n\
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001600the packed bytes into the writable buffer buf starting at offset. Note\n\
1601that the offset is not an optional argument. See struct.__doc__ for \n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001602more on format strings.");
1603
1604static PyObject *
Martin Blaisaf2ae722006-06-04 13:49:49 +00001605s_pack_into(PyObject *self, PyObject *args)
Martin Blais2856e5f2006-05-26 12:03:27 +00001606{
1607 PyStructObject *soself;
1608 char *buffer;
1609 Py_ssize_t buffer_len, offset;
1610
1611 /* Validate arguments. +1 is for the first arg as buffer. */
1612 soself = (PyStructObject *)self;
1613 assert(PyStruct_Check(self));
1614 assert(soself->s_codes != NULL);
Martin Blaisaf2ae722006-06-04 13:49:49 +00001615 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Martin Blais2856e5f2006-05-26 12:03:27 +00001616 {
1617 PyErr_Format(StructError,
Martin Blaisaf2ae722006-06-04 13:49:49 +00001618 "pack_into requires exactly %zd arguments",
Martin Blais2856e5f2006-05-26 12:03:27 +00001619 (soself->s_len + 2));
1620 return NULL;
1621 }
1622
1623 /* Extract a writable memory buffer from the first argument */
Tim Petersc2b550e2006-05-31 14:28:07 +00001624 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1625 (void**)&buffer, &buffer_len) == -1 ) {
Martin Blais2856e5f2006-05-26 12:03:27 +00001626 return NULL;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001627 }
1628 assert( buffer_len >= 0 );
Martin Blais2856e5f2006-05-26 12:03:27 +00001629
1630 /* Extract the offset from the first argument */
Martin Blaisaf2ae722006-06-04 13:49:49 +00001631 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Martin Blais2856e5f2006-05-26 12:03:27 +00001632
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001633 /* Support negative offsets. */
Martin Blais2856e5f2006-05-26 12:03:27 +00001634 if (offset < 0)
1635 offset += buffer_len;
1636
1637 /* Check boundaries */
1638 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1639 PyErr_Format(StructError,
Martin Blaisaf2ae722006-06-04 13:49:49 +00001640 "pack_into requires a buffer of at least %zd bytes",
Martin Blais2856e5f2006-05-26 12:03:27 +00001641 soself->s_size);
1642 return NULL;
1643 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001644
Martin Blais2856e5f2006-05-26 12:03:27 +00001645 /* Call the guts */
1646 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1647 return NULL;
1648 }
1649
Georg Brandlc26025c2006-05-28 21:42:54 +00001650 Py_RETURN_NONE;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001651}
1652
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001653static PyObject *
1654s_get_format(PyStructObject *self, void *unused)
1655{
1656 Py_INCREF(self->s_format);
1657 return self->s_format;
1658}
1659
1660static PyObject *
1661s_get_size(PyStructObject *self, void *unused)
1662{
1663 return PyInt_FromSsize_t(self->s_size);
1664}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001665
1666/* List of functions */
1667
1668static struct PyMethodDef s_methods[] = {
Martin Blaisaf2ae722006-06-04 13:49:49 +00001669 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1670 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1671 {"unpack", s_unpack, METH_O, s_unpack__doc__},
1672 {"unpack_from", s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001673 {NULL, NULL} /* sentinel */
1674};
1675
1676PyDoc_STRVAR(s__doc__, "Compiled struct object");
1677
1678#define OFF(x) offsetof(PyStructObject, x)
1679
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001680static PyGetSetDef s_getsetlist[] = {
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001681 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1682 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001683 {NULL} /* sentinel */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001684};
1685
Bob Ippolito232f3c92006-05-23 19:12:41 +00001686static
1687PyTypeObject PyStructType = {
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001688 PyObject_HEAD_INIT(NULL)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001689 0,
1690 "Struct",
1691 sizeof(PyStructObject),
1692 0,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001693 (destructor)s_dealloc, /* tp_dealloc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001694 0, /* tp_print */
1695 0, /* tp_getattr */
1696 0, /* tp_setattr */
1697 0, /* tp_compare */
1698 0, /* tp_repr */
1699 0, /* tp_as_number */
1700 0, /* tp_as_sequence */
1701 0, /* tp_as_mapping */
1702 0, /* tp_hash */
1703 0, /* tp_call */
1704 0, /* tp_str */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001705 PyObject_GenericGetAttr, /* tp_getattro */
1706 PyObject_GenericSetAttr, /* tp_setattro */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001707 0, /* tp_as_buffer */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001708 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1709 s__doc__, /* tp_doc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001710 0, /* tp_traverse */
1711 0, /* tp_clear */
1712 0, /* tp_richcompare */
1713 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1714 0, /* tp_iter */
1715 0, /* tp_iternext */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001716 s_methods, /* tp_methods */
1717 NULL, /* tp_members */
1718 s_getsetlist, /* tp_getset */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001719 0, /* tp_base */
1720 0, /* tp_dict */
1721 0, /* tp_descr_get */
1722 0, /* tp_descr_set */
1723 0, /* tp_dictoffset */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001724 s_init, /* tp_init */
1725 PyType_GenericAlloc,/* tp_alloc */
1726 s_new, /* tp_new */
1727 PyObject_Del, /* tp_free */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001728};
1729
1730/* Module initialization */
1731
1732PyMODINIT_FUNC
1733init_struct(void)
1734{
1735 PyObject *m = Py_InitModule("_struct", NULL);
1736 if (m == NULL)
1737 return;
1738
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001739 PyStructType.ob_type = &PyType_Type;
1740 if (PyType_Ready(&PyStructType) < 0)
1741 return;
1742
Bob Ippolito4182a752006-05-30 17:37:54 +00001743#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +00001744 if (pyint_zero == NULL) {
1745 pyint_zero = PyInt_FromLong(0);
1746 if (pyint_zero == NULL)
1747 return;
1748 }
1749 if (pylong_ulong_mask == NULL) {
1750#if (SIZEOF_LONG == 4)
1751 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1752#else
1753 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1754#endif
1755 if (pylong_ulong_mask == NULL)
1756 return;
1757 }
1758
Tim Petersc2b550e2006-05-31 14:28:07 +00001759#else
Bob Ippolito4182a752006-05-30 17:37:54 +00001760 /* This speed trick can't be used until overflow masking goes away, because
1761 native endian always raises exceptions instead of overflow masking. */
Tim Petersc2b550e2006-05-31 14:28:07 +00001762
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001763 /* Check endian and swap in faster functions */
1764 {
1765 int one = 1;
1766 formatdef *native = native_table;
1767 formatdef *other, *ptr;
1768 if ((int)*(unsigned char*)&one)
1769 other = lilendian_table;
1770 else
1771 other = bigendian_table;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001772 /* Scan through the native table, find a matching
1773 entry in the endian table and swap in the
1774 native implementations whenever possible
1775 (64-bit platforms may not have "standard" sizes) */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001776 while (native->format != '\0' && other->format != '\0') {
1777 ptr = other;
1778 while (ptr->format != '\0') {
1779 if (ptr->format == native->format) {
Bob Ippolito964e02a2006-05-25 21:09:45 +00001780 /* Match faster when formats are
1781 listed in the same order */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001782 if (ptr == other)
1783 other++;
Tim Petersc2b550e2006-05-31 14:28:07 +00001784 /* Only use the trick if the
Bob Ippolito964e02a2006-05-25 21:09:45 +00001785 size matches */
1786 if (ptr->size != native->size)
1787 break;
1788 /* Skip float and double, could be
1789 "unknown" float format */
1790 if (ptr->format == 'd' || ptr->format == 'f')
1791 break;
1792 ptr->pack = native->pack;
1793 ptr->unpack = native->unpack;
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001794 break;
1795 }
1796 ptr++;
1797 }
1798 native++;
1799 }
1800 }
Bob Ippolito2fd39772006-05-29 22:55:48 +00001801#endif
Tim Petersc2b550e2006-05-31 14:28:07 +00001802
Bob Ippolito232f3c92006-05-23 19:12:41 +00001803 /* Add some symbolic constants to the module */
1804 if (StructError == NULL) {
1805 StructError = PyErr_NewException("struct.error", NULL, NULL);
1806 if (StructError == NULL)
1807 return;
1808 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001809
Bob Ippolito232f3c92006-05-23 19:12:41 +00001810 Py_INCREF(StructError);
1811 PyModule_AddObject(m, "error", StructError);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001812
Bob Ippolito232f3c92006-05-23 19:12:41 +00001813 Py_INCREF((PyObject*)&PyStructType);
1814 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Tim Petersc2b550e2006-05-31 14:28:07 +00001815
Bob Ippolito2fd39772006-05-29 22:55:48 +00001816 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
Bob Ippolito4182a752006-05-30 17:37:54 +00001817#ifdef PY_STRUCT_OVERFLOW_MASKING
1818 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
Bob Ippolito2fd39772006-05-29 22:55:48 +00001819#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001820}