blob: 7e30892680bec565f3dba63b1be0d1e1f1d47058 [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) {
Neal Norwitz3c5431e2006-06-11 05:45:25 +0000221 if (PyLong_Check(v) &&
222 PyErr_ExceptionMatches(PyExc_OverflowError)) {
Bob Ippolito2fd39772006-05-29 22:55:48 +0000223 PyObject *wrapped;
224 long x;
225 PyErr_Clear();
Bob Ippolito4182a752006-05-30 17:37:54 +0000226 if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0)
Bob Ippolito2fd39772006-05-29 22:55:48 +0000227 return -1;
228 wrapped = PyNumber_And(v, pylong_ulong_mask);
229 if (wrapped == NULL)
230 return -1;
231 x = (long)PyLong_AsUnsignedLong(wrapped);
232 Py_DECREF(wrapped);
233 if (x == -1 && PyErr_Occurred())
234 return -1;
235 *p = x;
236 } else {
237 return -1;
238 }
239 }
240 return 0;
241}
242
243static int
244get_wrapped_ulong(PyObject *v, unsigned long *p)
245{
246 long x = (long)PyLong_AsUnsignedLong(v);
247 if (x == -1 && PyErr_Occurred()) {
248 PyObject *wrapped;
249 PyErr_Clear();
250 wrapped = PyNumber_And(v, pylong_ulong_mask);
251 if (wrapped == NULL)
252 return -1;
Bob Ippolito4182a752006-05-30 17:37:54 +0000253 if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0) {
Bob Ippolito2fd39772006-05-29 22:55:48 +0000254 Py_DECREF(wrapped);
255 return -1;
256 }
257 x = (long)PyLong_AsUnsignedLong(wrapped);
258 Py_DECREF(wrapped);
259 if (x == -1 && PyErr_Occurred())
260 return -1;
261 }
262 *p = (unsigned long)x;
263 return 0;
264}
265
266#define RANGE_ERROR(x, f, flag, mask) \
267 do { \
268 if (_range_error(f, flag) < 0) \
269 return -1; \
270 else \
271 (x) &= (mask); \
272 } while (0)
273
274#else
275
276#define get_wrapped_long get_long
277#define get_wrapped_ulong get_ulong
278#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
279
280#endif
281
Bob Ippolito232f3c92006-05-23 19:12:41 +0000282/* Floating point helpers */
283
284static PyObject *
285unpack_float(const char *p, /* start of 4-byte string */
286 int le) /* true for little-endian, false for big-endian */
287{
288 double x;
289
290 x = _PyFloat_Unpack4((unsigned char *)p, le);
291 if (x == -1.0 && PyErr_Occurred())
292 return NULL;
293 return PyFloat_FromDouble(x);
294}
295
296static PyObject *
297unpack_double(const char *p, /* start of 8-byte string */
298 int le) /* true for little-endian, false for big-endian */
299{
300 double x;
301
302 x = _PyFloat_Unpack8((unsigned char *)p, le);
303 if (x == -1.0 && PyErr_Occurred())
304 return NULL;
305 return PyFloat_FromDouble(x);
306}
307
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000308/* Helper to format the range error exceptions */
309static int
Armin Rigo162997e2006-05-29 17:59:47 +0000310_range_error(const formatdef *f, int is_unsigned)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000311{
Tim Petersd6a6f022006-05-31 15:33:22 +0000312 /* ulargest is the largest unsigned value with f->size bytes.
313 * Note that the simpler:
314 * ((size_t)1 << (f->size * 8)) - 1
Tim Peters72270c22006-05-31 15:34:37 +0000315 * doesn't work when f->size == sizeof(size_t) because C doesn't
316 * define what happens when a left shift count is >= the number of
317 * bits in the integer being shifted; e.g., on some boxes it doesn't
318 * shift at all when they're equal.
Tim Petersd6a6f022006-05-31 15:33:22 +0000319 */
320 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
321 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
322 if (is_unsigned)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000323 PyErr_Format(StructError,
Neal Norwitz971ea112006-05-31 07:43:27 +0000324 "'%c' format requires 0 <= number <= %zu",
Bob Ippolito28b26862006-05-29 15:47:29 +0000325 f->format,
Tim Petersd6a6f022006-05-31 15:33:22 +0000326 ulargest);
327 else {
328 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
329 PyErr_Format(StructError,
330 "'%c' format requires %zd <= number <= %zd",
331 f->format,
332 ~ largest,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000333 largest);
334 }
Bob Ippolito4182a752006-05-30 17:37:54 +0000335#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000336 {
337 PyObject *ptype, *pvalue, *ptraceback;
338 PyObject *msg;
339 int rval;
340 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
341 assert(pvalue != NULL);
342 msg = PyObject_Str(pvalue);
343 Py_XDECREF(ptype);
344 Py_XDECREF(pvalue);
345 Py_XDECREF(ptraceback);
346 if (msg == NULL)
347 return -1;
Tim Petersd6a6f022006-05-31 15:33:22 +0000348 rval = PyErr_Warn(PyExc_DeprecationWarning,
349 PyString_AS_STRING(msg));
Bob Ippolito2fd39772006-05-29 22:55:48 +0000350 Py_DECREF(msg);
351 if (rval == 0)
352 return 0;
353 }
354#endif
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000355 return -1;
356}
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000357
358
Bob Ippolito232f3c92006-05-23 19:12:41 +0000359
360/* A large number of small routines follow, with names of the form
361
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000362 [bln][up]_TYPE
Bob Ippolito232f3c92006-05-23 19:12:41 +0000363
364 [bln] distiguishes among big-endian, little-endian and native.
365 [pu] distiguishes between pack (to struct) and unpack (from struct).
366 TYPE is one of char, byte, ubyte, etc.
367*/
368
369/* Native mode routines. ****************************************************/
370/* NOTE:
371 In all n[up]_<type> routines handling types larger than 1 byte, there is
372 *no* guarantee that the p pointer is properly aligned for each type,
373 therefore memcpy is called. An intermediate variable is used to
374 compensate for big-endian architectures.
375 Normally both the intermediate variable and the memcpy call will be
376 skipped by C optimisation in little-endian architectures (gcc >= 2.91
377 does this). */
378
379static PyObject *
380nu_char(const char *p, const formatdef *f)
381{
382 return PyString_FromStringAndSize(p, 1);
383}
384
385static PyObject *
386nu_byte(const char *p, const formatdef *f)
387{
388 return PyInt_FromLong((long) *(signed char *)p);
389}
390
391static PyObject *
392nu_ubyte(const char *p, const formatdef *f)
393{
394 return PyInt_FromLong((long) *(unsigned char *)p);
395}
396
397static PyObject *
398nu_short(const char *p, const formatdef *f)
399{
400 short x;
401 memcpy((char *)&x, p, sizeof x);
402 return PyInt_FromLong((long)x);
403}
404
405static PyObject *
406nu_ushort(const char *p, const formatdef *f)
407{
408 unsigned short x;
409 memcpy((char *)&x, p, sizeof x);
410 return PyInt_FromLong((long)x);
411}
412
413static PyObject *
414nu_int(const char *p, const formatdef *f)
415{
416 int x;
417 memcpy((char *)&x, p, sizeof x);
418 return PyInt_FromLong((long)x);
419}
420
421static PyObject *
422nu_uint(const char *p, const formatdef *f)
423{
424 unsigned int x;
425 memcpy((char *)&x, p, sizeof x);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000426#if (SIZEOF_LONG > SIZEOF_INT)
427 return PyInt_FromLong((long)x);
428#else
429 if (x <= ((unsigned int)LONG_MAX))
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000430 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000431 return PyLong_FromUnsignedLong((unsigned long)x);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000432#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000433}
434
435static PyObject *
436nu_long(const char *p, const formatdef *f)
437{
438 long x;
439 memcpy((char *)&x, p, sizeof x);
440 return PyInt_FromLong(x);
441}
442
443static PyObject *
444nu_ulong(const char *p, const formatdef *f)
445{
446 unsigned long x;
447 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000448 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000449 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000450 return PyLong_FromUnsignedLong(x);
451}
452
453/* Native mode doesn't support q or Q unless the platform C supports
454 long long (or, on Windows, __int64). */
455
456#ifdef HAVE_LONG_LONG
457
458static PyObject *
459nu_longlong(const char *p, const formatdef *f)
460{
461 PY_LONG_LONG x;
462 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000463 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000464 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000465 return PyLong_FromLongLong(x);
466}
467
468static PyObject *
469nu_ulonglong(const char *p, const formatdef *f)
470{
471 unsigned PY_LONG_LONG x;
472 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000473 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000474 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000475 return PyLong_FromUnsignedLongLong(x);
476}
477
478#endif
479
480static PyObject *
481nu_float(const char *p, const formatdef *f)
482{
483 float x;
484 memcpy((char *)&x, p, sizeof x);
485 return PyFloat_FromDouble((double)x);
486}
487
488static PyObject *
489nu_double(const char *p, const formatdef *f)
490{
491 double x;
492 memcpy((char *)&x, p, sizeof x);
493 return PyFloat_FromDouble(x);
494}
495
496static PyObject *
497nu_void_p(const char *p, const formatdef *f)
498{
499 void *x;
500 memcpy((char *)&x, p, sizeof x);
501 return PyLong_FromVoidPtr(x);
502}
503
504static int
505np_byte(char *p, PyObject *v, const formatdef *f)
506{
507 long x;
508 if (get_long(v, &x) < 0)
509 return -1;
510 if (x < -128 || x > 127){
511 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000512 "byte format requires -128 <= number <= 127");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000513 return -1;
514 }
515 *p = (char)x;
516 return 0;
517}
518
519static int
520np_ubyte(char *p, PyObject *v, const formatdef *f)
521{
522 long x;
523 if (get_long(v, &x) < 0)
524 return -1;
525 if (x < 0 || x > 255){
526 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000527 "ubyte format requires 0 <= number <= 255");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000528 return -1;
529 }
530 *p = (char)x;
531 return 0;
532}
533
534static int
535np_char(char *p, PyObject *v, const formatdef *f)
536{
537 if (!PyString_Check(v) || PyString_Size(v) != 1) {
538 PyErr_SetString(StructError,
539 "char format require string of length 1");
540 return -1;
541 }
542 *p = *PyString_AsString(v);
543 return 0;
544}
545
546static int
547np_short(char *p, PyObject *v, const formatdef *f)
548{
549 long x;
550 short y;
551 if (get_long(v, &x) < 0)
552 return -1;
553 if (x < SHRT_MIN || x > SHRT_MAX){
554 PyErr_SetString(StructError,
555 "short format requires " STRINGIFY(SHRT_MIN)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000556 " <= number <= " STRINGIFY(SHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000557 return -1;
558 }
559 y = (short)x;
560 memcpy(p, (char *)&y, sizeof y);
561 return 0;
562}
563
564static int
565np_ushort(char *p, PyObject *v, const formatdef *f)
566{
567 long x;
568 unsigned short y;
569 if (get_long(v, &x) < 0)
570 return -1;
571 if (x < 0 || x > USHRT_MAX){
572 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000573 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000574 return -1;
575 }
576 y = (unsigned short)x;
577 memcpy(p, (char *)&y, sizeof y);
578 return 0;
579}
580
581static int
582np_int(char *p, PyObject *v, const formatdef *f)
583{
584 long x;
585 int y;
586 if (get_long(v, &x) < 0)
587 return -1;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000588#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000589 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Bob Ippolito28b26862006-05-29 15:47:29 +0000590 return _range_error(f, 0);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000591#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000592 y = (int)x;
593 memcpy(p, (char *)&y, sizeof y);
594 return 0;
595}
596
597static int
598np_uint(char *p, PyObject *v, const formatdef *f)
599{
600 unsigned long x;
601 unsigned int y;
602 if (get_ulong(v, &x) < 0)
Bob Ippolito28b26862006-05-29 15:47:29 +0000603 return _range_error(f, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000604 y = (unsigned int)x;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000605#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000606 if (x > ((unsigned long)UINT_MAX))
Bob Ippolito28b26862006-05-29 15:47:29 +0000607 return _range_error(f, 1);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000608#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000609 memcpy(p, (char *)&y, sizeof y);
610 return 0;
611}
612
613static int
614np_long(char *p, PyObject *v, const formatdef *f)
615{
616 long x;
617 if (get_long(v, &x) < 0)
618 return -1;
619 memcpy(p, (char *)&x, sizeof x);
620 return 0;
621}
622
623static int
624np_ulong(char *p, PyObject *v, const formatdef *f)
625{
626 unsigned long x;
627 if (get_ulong(v, &x) < 0)
Bob Ippolito28b26862006-05-29 15:47:29 +0000628 return _range_error(f, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000629 memcpy(p, (char *)&x, sizeof x);
630 return 0;
631}
632
633#ifdef HAVE_LONG_LONG
634
635static int
636np_longlong(char *p, PyObject *v, const formatdef *f)
637{
638 PY_LONG_LONG x;
639 if (get_longlong(v, &x) < 0)
640 return -1;
641 memcpy(p, (char *)&x, sizeof x);
642 return 0;
643}
644
645static int
646np_ulonglong(char *p, PyObject *v, const formatdef *f)
647{
648 unsigned PY_LONG_LONG x;
649 if (get_ulonglong(v, &x) < 0)
650 return -1;
651 memcpy(p, (char *)&x, sizeof x);
652 return 0;
653}
654#endif
655
656static int
657np_float(char *p, PyObject *v, const formatdef *f)
658{
659 float x = (float)PyFloat_AsDouble(v);
660 if (x == -1 && PyErr_Occurred()) {
661 PyErr_SetString(StructError,
662 "required argument is not a float");
663 return -1;
664 }
665 memcpy(p, (char *)&x, sizeof x);
666 return 0;
667}
668
669static int
670np_double(char *p, PyObject *v, const formatdef *f)
671{
672 double x = PyFloat_AsDouble(v);
673 if (x == -1 && PyErr_Occurred()) {
674 PyErr_SetString(StructError,
675 "required argument is not a float");
676 return -1;
677 }
678 memcpy(p, (char *)&x, sizeof(double));
679 return 0;
680}
681
682static int
683np_void_p(char *p, PyObject *v, const formatdef *f)
684{
685 void *x;
686
687 v = get_pylong(v);
688 if (v == NULL)
689 return -1;
690 assert(PyLong_Check(v));
691 x = PyLong_AsVoidPtr(v);
692 Py_DECREF(v);
693 if (x == NULL && PyErr_Occurred())
694 return -1;
695 memcpy(p, (char *)&x, sizeof x);
696 return 0;
697}
698
699static formatdef native_table[] = {
700 {'x', sizeof(char), 0, NULL},
701 {'b', sizeof(char), 0, nu_byte, np_byte},
702 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
703 {'c', sizeof(char), 0, nu_char, np_char},
704 {'s', sizeof(char), 0, NULL},
705 {'p', sizeof(char), 0, NULL},
706 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
707 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
708 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
709 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
710 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
711 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000712#ifdef HAVE_LONG_LONG
713 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
714 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
715#endif
Bob Ippolitoa99865b2006-05-25 19:56:56 +0000716 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
717 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
718 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000719 {0}
720};
721
722/* Big-endian routines. *****************************************************/
723
724static PyObject *
725bu_int(const char *p, const formatdef *f)
726{
727 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000728 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000729 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000730 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000731 x = (x<<8) | *bytes++;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000732 } while (--i > 0);
733 /* Extend the sign bit. */
734 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000735 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000736 return PyInt_FromLong(x);
737}
738
739static PyObject *
740bu_uint(const char *p, const formatdef *f)
741{
742 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000743 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000744 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000745 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000746 x = (x<<8) | *bytes++;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000747 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000748 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000749 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000750 return PyLong_FromUnsignedLong(x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000751}
752
753static PyObject *
754bu_longlong(const char *p, const formatdef *f)
755{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000756#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000757 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000758 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000759 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000760 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000761 x = (x<<8) | *bytes++;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000762 } while (--i > 0);
763 /* Extend the sign bit. */
764 if (SIZEOF_LONG_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000765 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000766 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000767 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000768 return PyLong_FromLongLong(x);
769#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000770 return _PyLong_FromByteArray((const unsigned char *)p,
771 8,
772 0, /* little-endian */
773 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000774#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000775}
776
777static PyObject *
778bu_ulonglong(const char *p, const formatdef *f)
779{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000780#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000781 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000782 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000783 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000784 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000785 x = (x<<8) | *bytes++;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000786 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000787 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000788 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000789 return PyLong_FromUnsignedLongLong(x);
790#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000791 return _PyLong_FromByteArray((const unsigned char *)p,
792 8,
793 0, /* little-endian */
794 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000795#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000796}
797
798static PyObject *
799bu_float(const char *p, const formatdef *f)
800{
801 return unpack_float(p, 0);
802}
803
804static PyObject *
805bu_double(const char *p, const formatdef *f)
806{
807 return unpack_double(p, 0);
808}
809
810static int
811bp_int(char *p, PyObject *v, const formatdef *f)
812{
813 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000814 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +0000815 if (get_wrapped_long(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000816 return -1;
817 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000818 if (i != SIZEOF_LONG) {
819 if ((i == 2) && (x < -32768 || x > 32767))
Bob Ippolito2fd39772006-05-29 22:55:48 +0000820 RANGE_ERROR(x, f, 0, 0xffffL);
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000821#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000822 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Bob Ippolito2fd39772006-05-29 22:55:48 +0000823 RANGE_ERROR(x, f, 0, 0xffffffffL);
824#endif
Bob Ippolito4182a752006-05-30 17:37:54 +0000825#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000826 else if ((i == 1) && (x < -128 || x > 127))
827 RANGE_ERROR(x, f, 0, 0xffL);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000828#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000829 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000830 do {
831 p[--i] = (char)x;
832 x >>= 8;
833 } while (i > 0);
834 return 0;
835}
836
837static int
838bp_uint(char *p, PyObject *v, const formatdef *f)
839{
840 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000841 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +0000842 if (get_wrapped_ulong(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000843 return -1;
844 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000845 if (i != SIZEOF_LONG) {
846 unsigned long maxint = 1;
847 maxint <<= (unsigned long)(i * 8);
848 if (x >= maxint)
Bob Ippolito2fd39772006-05-29 22:55:48 +0000849 RANGE_ERROR(x, f, 1, maxint - 1);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000850 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000851 do {
852 p[--i] = (char)x;
853 x >>= 8;
854 } while (i > 0);
855 return 0;
856}
857
858static int
859bp_longlong(char *p, PyObject *v, const formatdef *f)
860{
861 int res;
862 v = get_pylong(v);
863 if (v == NULL)
864 return -1;
865 res = _PyLong_AsByteArray((PyLongObject *)v,
866 (unsigned char *)p,
867 8,
868 0, /* little_endian */
869 1 /* signed */);
870 Py_DECREF(v);
871 return res;
872}
873
874static int
875bp_ulonglong(char *p, PyObject *v, const formatdef *f)
876{
877 int res;
878 v = get_pylong(v);
879 if (v == NULL)
880 return -1;
881 res = _PyLong_AsByteArray((PyLongObject *)v,
882 (unsigned char *)p,
883 8,
884 0, /* little_endian */
885 0 /* signed */);
886 Py_DECREF(v);
887 return res;
888}
889
890static int
891bp_float(char *p, PyObject *v, const formatdef *f)
892{
893 double x = PyFloat_AsDouble(v);
894 if (x == -1 && PyErr_Occurred()) {
895 PyErr_SetString(StructError,
896 "required argument is not a float");
897 return -1;
898 }
899 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
900}
901
902static int
903bp_double(char *p, PyObject *v, const formatdef *f)
904{
905 double x = PyFloat_AsDouble(v);
906 if (x == -1 && PyErr_Occurred()) {
907 PyErr_SetString(StructError,
908 "required argument is not a float");
909 return -1;
910 }
911 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
912}
913
914static formatdef bigendian_table[] = {
915 {'x', 1, 0, NULL},
Bob Ippolito4182a752006-05-30 17:37:54 +0000916#ifdef PY_STRUCT_OVERFLOW_MASKING
917 /* Native packers do range checking without overflow masking. */
Bob Ippolito2fd39772006-05-29 22:55:48 +0000918 {'b', 1, 0, nu_byte, bp_int},
919 {'B', 1, 0, nu_ubyte, bp_uint},
920#else
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000921 {'b', 1, 0, nu_byte, np_byte},
922 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito2fd39772006-05-29 22:55:48 +0000923#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000924 {'c', 1, 0, nu_char, np_char},
925 {'s', 1, 0, NULL},
926 {'p', 1, 0, NULL},
927 {'h', 2, 0, bu_int, bp_int},
928 {'H', 2, 0, bu_uint, bp_uint},
929 {'i', 4, 0, bu_int, bp_int},
930 {'I', 4, 0, bu_uint, bp_uint},
931 {'l', 4, 0, bu_int, bp_int},
932 {'L', 4, 0, bu_uint, bp_uint},
933 {'q', 8, 0, bu_longlong, bp_longlong},
934 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
935 {'f', 4, 0, bu_float, bp_float},
936 {'d', 8, 0, bu_double, bp_double},
937 {0}
938};
939
940/* Little-endian routines. *****************************************************/
941
942static PyObject *
943lu_int(const char *p, const formatdef *f)
944{
945 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000946 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000947 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000948 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000949 x = (x<<8) | bytes[--i];
Bob Ippolito232f3c92006-05-23 19:12:41 +0000950 } while (i > 0);
951 /* Extend the sign bit. */
952 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000953 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000954 return PyInt_FromLong(x);
955}
956
957static PyObject *
958lu_uint(const char *p, const formatdef *f)
959{
960 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000961 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000962 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000963 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000964 x = (x<<8) | bytes[--i];
Bob Ippolito232f3c92006-05-23 19:12:41 +0000965 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000966 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000967 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000968 return PyLong_FromUnsignedLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000969}
970
971static PyObject *
972lu_longlong(const char *p, const formatdef *f)
973{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000974#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000975 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000976 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000977 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000978 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000979 x = (x<<8) | bytes[--i];
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000980 } while (i > 0);
981 /* Extend the sign bit. */
982 if (SIZEOF_LONG_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000983 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000984 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000985 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000986 return PyLong_FromLongLong(x);
987#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000988 return _PyLong_FromByteArray((const unsigned char *)p,
989 8,
990 1, /* little-endian */
991 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000992#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000993}
994
995static PyObject *
996lu_ulonglong(const char *p, const formatdef *f)
997{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000998#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000999 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001000 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +00001001 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001002 do {
Bob Ippolito28b26862006-05-29 15:47:29 +00001003 x = (x<<8) | bytes[--i];
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001004 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001005 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001006 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001007 return PyLong_FromUnsignedLongLong(x);
1008#else
Bob Ippolito232f3c92006-05-23 19:12:41 +00001009 return _PyLong_FromByteArray((const unsigned char *)p,
1010 8,
1011 1, /* little-endian */
1012 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001013#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001014}
1015
1016static PyObject *
1017lu_float(const char *p, const formatdef *f)
1018{
1019 return unpack_float(p, 1);
1020}
1021
1022static PyObject *
1023lu_double(const char *p, const formatdef *f)
1024{
1025 return unpack_double(p, 1);
1026}
1027
1028static int
1029lp_int(char *p, PyObject *v, const formatdef *f)
1030{
1031 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001032 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001033 if (get_wrapped_long(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001034 return -1;
1035 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001036 if (i != SIZEOF_LONG) {
1037 if ((i == 2) && (x < -32768 || x > 32767))
Bob Ippolito2fd39772006-05-29 22:55:48 +00001038 RANGE_ERROR(x, f, 0, 0xffffL);
Bob Ippolito90bd0a52006-05-27 11:47:12 +00001039#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001040 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Bob Ippolito2fd39772006-05-29 22:55:48 +00001041 RANGE_ERROR(x, f, 0, 0xffffffffL);
1042#endif
Bob Ippolito4182a752006-05-30 17:37:54 +00001043#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +00001044 else if ((i == 1) && (x < -128 || x > 127))
1045 RANGE_ERROR(x, f, 0, 0xffL);
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001046#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001047 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001048 do {
1049 *p++ = (char)x;
1050 x >>= 8;
1051 } while (--i > 0);
1052 return 0;
1053}
1054
1055static int
1056lp_uint(char *p, PyObject *v, const formatdef *f)
1057{
1058 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001059 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001060 if (get_wrapped_ulong(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001061 return -1;
1062 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001063 if (i != SIZEOF_LONG) {
1064 unsigned long maxint = 1;
1065 maxint <<= (unsigned long)(i * 8);
1066 if (x >= maxint)
Bob Ippolito2fd39772006-05-29 22:55:48 +00001067 RANGE_ERROR(x, f, 1, maxint - 1);
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001068 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001069 do {
1070 *p++ = (char)x;
1071 x >>= 8;
1072 } while (--i > 0);
1073 return 0;
1074}
1075
1076static int
1077lp_longlong(char *p, PyObject *v, const formatdef *f)
1078{
1079 int res;
1080 v = get_pylong(v);
1081 if (v == NULL)
1082 return -1;
1083 res = _PyLong_AsByteArray((PyLongObject*)v,
1084 (unsigned char *)p,
1085 8,
1086 1, /* little_endian */
1087 1 /* signed */);
1088 Py_DECREF(v);
1089 return res;
1090}
1091
1092static int
1093lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1094{
1095 int res;
1096 v = get_pylong(v);
1097 if (v == NULL)
1098 return -1;
1099 res = _PyLong_AsByteArray((PyLongObject*)v,
1100 (unsigned char *)p,
1101 8,
1102 1, /* little_endian */
1103 0 /* signed */);
1104 Py_DECREF(v);
1105 return res;
1106}
1107
1108static int
1109lp_float(char *p, PyObject *v, const formatdef *f)
1110{
1111 double x = PyFloat_AsDouble(v);
1112 if (x == -1 && PyErr_Occurred()) {
1113 PyErr_SetString(StructError,
1114 "required argument is not a float");
1115 return -1;
1116 }
1117 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1118}
1119
1120static int
1121lp_double(char *p, PyObject *v, const formatdef *f)
1122{
1123 double x = PyFloat_AsDouble(v);
1124 if (x == -1 && PyErr_Occurred()) {
1125 PyErr_SetString(StructError,
1126 "required argument is not a float");
1127 return -1;
1128 }
1129 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1130}
1131
1132static formatdef lilendian_table[] = {
1133 {'x', 1, 0, NULL},
Bob Ippolito4182a752006-05-30 17:37:54 +00001134#ifdef PY_STRUCT_OVERFLOW_MASKING
1135 /* Native packers do range checking without overflow masking. */
Bob Ippolito2fd39772006-05-29 22:55:48 +00001136 {'b', 1, 0, nu_byte, lp_int},
1137 {'B', 1, 0, nu_ubyte, lp_uint},
1138#else
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001139 {'b', 1, 0, nu_byte, np_byte},
1140 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito2fd39772006-05-29 22:55:48 +00001141#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001142 {'c', 1, 0, nu_char, np_char},
1143 {'s', 1, 0, NULL},
1144 {'p', 1, 0, NULL},
1145 {'h', 2, 0, lu_int, lp_int},
1146 {'H', 2, 0, lu_uint, lp_uint},
1147 {'i', 4, 0, lu_int, lp_int},
1148 {'I', 4, 0, lu_uint, lp_uint},
1149 {'l', 4, 0, lu_int, lp_int},
1150 {'L', 4, 0, lu_uint, lp_uint},
1151 {'q', 8, 0, lu_longlong, lp_longlong},
1152 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1153 {'f', 4, 0, lu_float, lp_float},
1154 {'d', 8, 0, lu_double, lp_double},
1155 {0}
1156};
1157
1158
1159static const formatdef *
1160whichtable(char **pfmt)
1161{
1162 const char *fmt = (*pfmt)++; /* May be backed out of later */
1163 switch (*fmt) {
1164 case '<':
1165 return lilendian_table;
1166 case '>':
1167 case '!': /* Network byte order is big-endian */
1168 return bigendian_table;
1169 case '=': { /* Host byte order -- different from native in aligment! */
1170 int n = 1;
1171 char *p = (char *) &n;
1172 if (*p == 1)
1173 return lilendian_table;
1174 else
1175 return bigendian_table;
1176 }
1177 default:
1178 --*pfmt; /* Back out of pointer increment */
1179 /* Fall through */
1180 case '@':
1181 return native_table;
1182 }
1183}
1184
1185
1186/* Get the table entry for a format code */
1187
1188static const formatdef *
1189getentry(int c, const formatdef *f)
1190{
1191 for (; f->format != '\0'; f++) {
1192 if (f->format == c) {
1193 return f;
1194 }
1195 }
1196 PyErr_SetString(StructError, "bad char in struct format");
1197 return NULL;
1198}
1199
1200
1201/* Align a size according to a format code */
1202
1203static int
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001204align(Py_ssize_t size, char c, const formatdef *e)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001205{
1206 if (e->format == c) {
1207 if (e->alignment) {
1208 size = ((size + e->alignment - 1)
1209 / e->alignment)
1210 * e->alignment;
1211 }
1212 }
1213 return size;
1214}
1215
1216
1217/* calculate the size of a format string */
1218
1219static int
1220prepare_s(PyStructObject *self)
1221{
1222 const formatdef *f;
1223 const formatdef *e;
1224 formatcode *codes;
Tim Petersc2b550e2006-05-31 14:28:07 +00001225
Bob Ippolito232f3c92006-05-23 19:12:41 +00001226 const char *s;
1227 const char *fmt;
1228 char c;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001229 Py_ssize_t size, len, num, itemsize, x;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001230
1231 fmt = PyString_AS_STRING(self->s_format);
1232
1233 f = whichtable((char **)&fmt);
Tim Petersc2b550e2006-05-31 14:28:07 +00001234
Bob Ippolito232f3c92006-05-23 19:12:41 +00001235 s = fmt;
1236 size = 0;
1237 len = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001238 while ((c = *s++) != '\0') {
1239 if (isspace(Py_CHARMASK(c)))
1240 continue;
1241 if ('0' <= c && c <= '9') {
1242 num = c - '0';
1243 while ('0' <= (c = *s++) && c <= '9') {
1244 x = num*10 + (c - '0');
1245 if (x/10 != num) {
1246 PyErr_SetString(
1247 StructError,
1248 "overflow in item count");
1249 return -1;
1250 }
1251 num = x;
1252 }
1253 if (c == '\0')
1254 break;
1255 }
1256 else
1257 num = 1;
1258
1259 e = getentry(c, f);
1260 if (e == NULL)
1261 return -1;
Tim Petersc2b550e2006-05-31 14:28:07 +00001262
Bob Ippolito232f3c92006-05-23 19:12:41 +00001263 switch (c) {
1264 case 's': /* fall through */
1265 case 'p': len++; break;
1266 case 'x': break;
1267 default: len += num; break;
1268 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001269
1270 itemsize = e->size;
1271 size = align(size, c, e);
1272 x = num * itemsize;
1273 size += x;
1274 if (x/itemsize != num || size < 0) {
1275 PyErr_SetString(StructError,
1276 "total struct size too long");
1277 return -1;
1278 }
1279 }
1280
1281 self->s_size = size;
1282 self->s_len = len;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001283 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
Bob Ippolito232f3c92006-05-23 19:12:41 +00001284 if (codes == NULL) {
1285 PyErr_NoMemory();
1286 return -1;
1287 }
1288 self->s_codes = codes;
Tim Petersc2b550e2006-05-31 14:28:07 +00001289
Bob Ippolito232f3c92006-05-23 19:12:41 +00001290 s = fmt;
1291 size = 0;
1292 while ((c = *s++) != '\0') {
1293 if (isspace(Py_CHARMASK(c)))
1294 continue;
1295 if ('0' <= c && c <= '9') {
1296 num = c - '0';
1297 while ('0' <= (c = *s++) && c <= '9')
1298 num = num*10 + (c - '0');
1299 if (c == '\0')
1300 break;
1301 }
1302 else
1303 num = 1;
1304
1305 e = getentry(c, f);
Tim Petersc2b550e2006-05-31 14:28:07 +00001306
Bob Ippolito232f3c92006-05-23 19:12:41 +00001307 size = align(size, c, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001308 if (c == 's' || c == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001309 codes->offset = size;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001310 codes->size = num;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001311 codes->fmtdef = e;
1312 codes++;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001313 size += num;
1314 } else if (c == 'x') {
1315 size += num;
1316 } else {
1317 while (--num >= 0) {
1318 codes->offset = size;
1319 codes->size = e->size;
1320 codes->fmtdef = e;
1321 codes++;
1322 size += e->size;
1323 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001324 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001325 }
1326 codes->fmtdef = NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001327 codes->offset = size;
1328 codes->size = 0;
Tim Petersc2b550e2006-05-31 14:28:07 +00001329
Bob Ippolito232f3c92006-05-23 19:12:41 +00001330 return 0;
1331}
1332
1333static PyObject *
1334s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1335{
1336 PyObject *self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001337
1338 assert(type != NULL && type->tp_alloc != NULL);
1339
1340 self = type->tp_alloc(type, 0);
1341 if (self != NULL) {
1342 PyStructObject *s = (PyStructObject*)self;
1343 Py_INCREF(Py_None);
1344 s->s_format = Py_None;
1345 s->s_codes = NULL;
1346 s->s_size = -1;
1347 s->s_len = -1;
1348 }
1349 return self;
1350}
1351
1352static int
1353s_init(PyObject *self, PyObject *args, PyObject *kwds)
1354{
1355 PyStructObject *soself = (PyStructObject *)self;
1356 PyObject *o_format = NULL;
1357 int ret = 0;
1358 static char *kwlist[] = {"format", 0};
1359
1360 assert(PyStruct_Check(self));
1361
1362 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1363 &o_format))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001364 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001365
1366 Py_INCREF(o_format);
1367 Py_XDECREF(soself->s_format);
1368 soself->s_format = o_format;
Tim Petersc2b550e2006-05-31 14:28:07 +00001369
Bob Ippolito232f3c92006-05-23 19:12:41 +00001370 ret = prepare_s(soself);
1371 return ret;
1372}
1373
1374static void
1375s_dealloc(PyStructObject *s)
1376{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001377 if (s->weakreflist != NULL)
1378 PyObject_ClearWeakRefs((PyObject *)s);
1379 if (s->s_codes != NULL) {
1380 PyMem_FREE(s->s_codes);
1381 }
1382 Py_XDECREF(s->s_format);
1383 s->ob_type->tp_free((PyObject *)s);
1384}
1385
Bob Ippolitoeb621272006-05-24 15:32:06 +00001386static PyObject *
1387s_unpack_internal(PyStructObject *soself, char *startfrom) {
1388 formatcode *code;
1389 Py_ssize_t i = 0;
1390 PyObject *result = PyTuple_New(soself->s_len);
1391 if (result == NULL)
1392 return NULL;
1393
1394 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1395 PyObject *v;
1396 const formatdef *e = code->fmtdef;
1397 const char *res = startfrom + code->offset;
1398 if (e->format == 's') {
1399 v = PyString_FromStringAndSize(res, code->size);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001400 } else if (e->format == 'p') {
1401 Py_ssize_t n = *(unsigned char*)res;
1402 if (n >= code->size)
1403 n = code->size - 1;
1404 v = PyString_FromStringAndSize(res + 1, n);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001405 } else {
1406 v = e->unpack(res, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001407 }
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001408 if (v == NULL)
1409 goto fail;
1410 PyTuple_SET_ITEM(result, i++, v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001411 }
1412
1413 return result;
1414fail:
1415 Py_DECREF(result);
1416 return NULL;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001417}
Bob Ippolitoeb621272006-05-24 15:32:06 +00001418
1419
Bob Ippolito232f3c92006-05-23 19:12:41 +00001420PyDoc_STRVAR(s_unpack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001421"S.unpack(str) -> (v1, v2, ...)\n\
Bob Ippolito232f3c92006-05-23 19:12:41 +00001422\n\
1423Return tuple containing values unpacked according to this Struct's format.\n\
1424Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1425strings.");
1426
1427static PyObject *
1428s_unpack(PyObject *self, PyObject *inputstr)
1429{
Bob Ippolitoeb621272006-05-24 15:32:06 +00001430 PyStructObject *soself = (PyStructObject *)self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001431 assert(PyStruct_Check(self));
Tim Petersc2b550e2006-05-31 14:28:07 +00001432 assert(soself->s_codes != NULL);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001433 if (inputstr == NULL || !PyString_Check(inputstr) ||
Bob Ippolitoeb621272006-05-24 15:32:06 +00001434 PyString_GET_SIZE(inputstr) != soself->s_size) {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001435 PyErr_Format(StructError,
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001436 "unpack requires a string argument of length %zd",
1437 soself->s_size);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001438 return NULL;
1439 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001440 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1441}
1442
1443PyDoc_STRVAR(s_unpack_from__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001444"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
Bob Ippolitoeb621272006-05-24 15:32:06 +00001445\n\
1446Return tuple containing values unpacked according to this Struct's format.\n\
1447Unlike unpack, unpack_from can unpack values from any object supporting\n\
1448the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1449See struct.__doc__ for more on format strings.");
1450
1451static PyObject *
1452s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1453{
1454 static char *kwlist[] = {"buffer", "offset", 0};
1455#if (PY_VERSION_HEX < 0x02050000)
1456 static char *fmt = "z#|i:unpack_from";
1457#else
1458 static char *fmt = "z#|n:unpack_from";
1459#endif
1460 Py_ssize_t buffer_len = 0, offset = 0;
1461 char *buffer = NULL;
1462 PyStructObject *soself = (PyStructObject *)self;
1463 assert(PyStruct_Check(self));
1464 assert(soself->s_codes != NULL);
1465
1466 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1467 &buffer, &buffer_len, &offset))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001468 return NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001469
1470 if (buffer == NULL) {
1471 PyErr_Format(StructError,
1472 "unpack_from requires a buffer argument");
Bob Ippolito232f3c92006-05-23 19:12:41 +00001473 return NULL;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001474 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001475
Bob Ippolitoeb621272006-05-24 15:32:06 +00001476 if (offset < 0)
1477 offset += buffer_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001478
Bob Ippolitoeb621272006-05-24 15:32:06 +00001479 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1480 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001481 "unpack_from requires a buffer of at least %zd bytes",
Bob Ippolitoeb621272006-05-24 15:32:06 +00001482 soself->s_size);
1483 return NULL;
1484 }
1485 return s_unpack_internal(soself, buffer + offset);
1486}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001487
Bob Ippolito232f3c92006-05-23 19:12:41 +00001488
Martin Blais2856e5f2006-05-26 12:03:27 +00001489/*
1490 * Guts of the pack function.
1491 *
1492 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1493 * argument for where to start processing the arguments for packing, and a
1494 * character buffer for writing the packed string. The caller must insure
1495 * that the buffer may contain the required length for packing the arguments.
1496 * 0 is returned on success, 1 is returned if there is an error.
1497 *
1498 */
1499static int
1500s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001501{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001502 formatcode *code;
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001503 /* XXX(nnorwitz): why does i need to be a local? can we use
1504 the offset parameter or do we need the wider width? */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001505 Py_ssize_t i;
Martin Blais2856e5f2006-05-26 12:03:27 +00001506
1507 memset(buf, '\0', soself->s_size);
1508 i = offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001509 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1510 Py_ssize_t n;
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001511 PyObject *v = PyTuple_GET_ITEM(args, i++);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001512 const formatdef *e = code->fmtdef;
Martin Blais2856e5f2006-05-26 12:03:27 +00001513 char *res = buf + code->offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001514 if (e->format == 's') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001515 if (!PyString_Check(v)) {
1516 PyErr_SetString(StructError,
1517 "argument for 's' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001518 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001519 }
1520 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001521 if (n > code->size)
1522 n = code->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001523 if (n > 0)
1524 memcpy(res, PyString_AS_STRING(v), n);
1525 } else if (e->format == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001526 if (!PyString_Check(v)) {
1527 PyErr_SetString(StructError,
1528 "argument for 'p' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001529 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001530 }
1531 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001532 if (n > (code->size - 1))
1533 n = code->size - 1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001534 if (n > 0)
1535 memcpy(res + 1, PyString_AS_STRING(v), n);
1536 if (n > 255)
1537 n = 255;
1538 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1539 } else {
Bob Ippolito2fd39772006-05-29 22:55:48 +00001540 if (e->pack(res, v, e) < 0) {
1541 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1542 PyErr_SetString(StructError,
1543 "long too large to convert to int");
Martin Blais2856e5f2006-05-26 12:03:27 +00001544 return -1;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001545 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001546 }
1547 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001548
Martin Blais2856e5f2006-05-26 12:03:27 +00001549 /* Success */
1550 return 0;
1551}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001552
Martin Blais2856e5f2006-05-26 12:03:27 +00001553
1554PyDoc_STRVAR(s_pack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001555"S.pack(v1, v2, ...) -> string\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001556\n\
1557Return a string containing values v1, v2, ... packed according to this\n\
1558Struct's format. See struct.__doc__ for more on format strings.");
1559
1560static PyObject *
1561s_pack(PyObject *self, PyObject *args)
1562{
1563 PyStructObject *soself;
1564 PyObject *result;
1565
1566 /* Validate arguments. */
1567 soself = (PyStructObject *)self;
1568 assert(PyStruct_Check(self));
1569 assert(soself->s_codes != NULL);
Martin Blaisaf2ae722006-06-04 13:49:49 +00001570 if (PyTuple_GET_SIZE(args) != soself->s_len)
Martin Blais2856e5f2006-05-26 12:03:27 +00001571 {
1572 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001573 "pack requires exactly %zd arguments", soself->s_len);
Martin Blais2856e5f2006-05-26 12:03:27 +00001574 return NULL;
1575 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001576
Martin Blais2856e5f2006-05-26 12:03:27 +00001577 /* Allocate a new string */
1578 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1579 if (result == NULL)
1580 return NULL;
Tim Petersc2b550e2006-05-31 14:28:07 +00001581
Martin Blais2856e5f2006-05-26 12:03:27 +00001582 /* Call the guts */
1583 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1584 Py_DECREF(result);
1585 return NULL;
1586 }
1587
1588 return result;
1589}
1590
Martin Blaisaf2ae722006-06-04 13:49:49 +00001591PyDoc_STRVAR(s_pack_into__doc__,
1592"S.pack_into(buffer, offset, v1, v2, ...)\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001593\n\
Martin Blaisaf2ae722006-06-04 13:49:49 +00001594Pack the values v1, v2, ... according to this Struct's format, write \n\
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001595the packed bytes into the writable buffer buf starting at offset. Note\n\
1596that the offset is not an optional argument. See struct.__doc__ for \n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001597more on format strings.");
1598
1599static PyObject *
Martin Blaisaf2ae722006-06-04 13:49:49 +00001600s_pack_into(PyObject *self, PyObject *args)
Martin Blais2856e5f2006-05-26 12:03:27 +00001601{
1602 PyStructObject *soself;
1603 char *buffer;
1604 Py_ssize_t buffer_len, offset;
1605
1606 /* Validate arguments. +1 is for the first arg as buffer. */
1607 soself = (PyStructObject *)self;
1608 assert(PyStruct_Check(self));
1609 assert(soself->s_codes != NULL);
Martin Blaisaf2ae722006-06-04 13:49:49 +00001610 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Martin Blais2856e5f2006-05-26 12:03:27 +00001611 {
1612 PyErr_Format(StructError,
Martin Blaisaf2ae722006-06-04 13:49:49 +00001613 "pack_into requires exactly %zd arguments",
Martin Blais2856e5f2006-05-26 12:03:27 +00001614 (soself->s_len + 2));
1615 return NULL;
1616 }
1617
1618 /* Extract a writable memory buffer from the first argument */
Tim Petersc2b550e2006-05-31 14:28:07 +00001619 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1620 (void**)&buffer, &buffer_len) == -1 ) {
Martin Blais2856e5f2006-05-26 12:03:27 +00001621 return NULL;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001622 }
1623 assert( buffer_len >= 0 );
Martin Blais2856e5f2006-05-26 12:03:27 +00001624
1625 /* Extract the offset from the first argument */
Martin Blaisaf2ae722006-06-04 13:49:49 +00001626 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Martin Blais2856e5f2006-05-26 12:03:27 +00001627
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001628 /* Support negative offsets. */
Martin Blais2856e5f2006-05-26 12:03:27 +00001629 if (offset < 0)
1630 offset += buffer_len;
1631
1632 /* Check boundaries */
1633 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1634 PyErr_Format(StructError,
Martin Blaisaf2ae722006-06-04 13:49:49 +00001635 "pack_into requires a buffer of at least %zd bytes",
Martin Blais2856e5f2006-05-26 12:03:27 +00001636 soself->s_size);
1637 return NULL;
1638 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001639
Martin Blais2856e5f2006-05-26 12:03:27 +00001640 /* Call the guts */
1641 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1642 return NULL;
1643 }
1644
Georg Brandlc26025c2006-05-28 21:42:54 +00001645 Py_RETURN_NONE;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001646}
1647
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001648static PyObject *
1649s_get_format(PyStructObject *self, void *unused)
1650{
1651 Py_INCREF(self->s_format);
1652 return self->s_format;
1653}
1654
1655static PyObject *
1656s_get_size(PyStructObject *self, void *unused)
1657{
1658 return PyInt_FromSsize_t(self->s_size);
1659}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001660
1661/* List of functions */
1662
1663static struct PyMethodDef s_methods[] = {
Martin Blaisaf2ae722006-06-04 13:49:49 +00001664 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1665 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1666 {"unpack", s_unpack, METH_O, s_unpack__doc__},
Tim Peters5ec2e852006-06-04 15:49:07 +00001667 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS,
1668 s_unpack_from__doc__},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001669 {NULL, NULL} /* sentinel */
1670};
1671
1672PyDoc_STRVAR(s__doc__, "Compiled struct object");
1673
1674#define OFF(x) offsetof(PyStructObject, x)
1675
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001676static PyGetSetDef s_getsetlist[] = {
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001677 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1678 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001679 {NULL} /* sentinel */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001680};
1681
Bob Ippolito232f3c92006-05-23 19:12:41 +00001682static
1683PyTypeObject PyStructType = {
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001684 PyObject_HEAD_INIT(NULL)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001685 0,
1686 "Struct",
1687 sizeof(PyStructObject),
1688 0,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001689 (destructor)s_dealloc, /* tp_dealloc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001690 0, /* tp_print */
1691 0, /* tp_getattr */
1692 0, /* tp_setattr */
1693 0, /* tp_compare */
1694 0, /* tp_repr */
1695 0, /* tp_as_number */
1696 0, /* tp_as_sequence */
1697 0, /* tp_as_mapping */
1698 0, /* tp_hash */
1699 0, /* tp_call */
1700 0, /* tp_str */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001701 PyObject_GenericGetAttr, /* tp_getattro */
1702 PyObject_GenericSetAttr, /* tp_setattro */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001703 0, /* tp_as_buffer */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001704 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1705 s__doc__, /* tp_doc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001706 0, /* tp_traverse */
1707 0, /* tp_clear */
1708 0, /* tp_richcompare */
1709 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1710 0, /* tp_iter */
1711 0, /* tp_iternext */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001712 s_methods, /* tp_methods */
1713 NULL, /* tp_members */
1714 s_getsetlist, /* tp_getset */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001715 0, /* tp_base */
1716 0, /* tp_dict */
1717 0, /* tp_descr_get */
1718 0, /* tp_descr_set */
1719 0, /* tp_dictoffset */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001720 s_init, /* tp_init */
1721 PyType_GenericAlloc,/* tp_alloc */
1722 s_new, /* tp_new */
1723 PyObject_Del, /* tp_free */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001724};
1725
1726/* Module initialization */
1727
1728PyMODINIT_FUNC
1729init_struct(void)
1730{
1731 PyObject *m = Py_InitModule("_struct", NULL);
1732 if (m == NULL)
1733 return;
1734
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001735 PyStructType.ob_type = &PyType_Type;
1736 if (PyType_Ready(&PyStructType) < 0)
1737 return;
1738
Bob Ippolito4182a752006-05-30 17:37:54 +00001739#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +00001740 if (pyint_zero == NULL) {
1741 pyint_zero = PyInt_FromLong(0);
1742 if (pyint_zero == NULL)
1743 return;
1744 }
1745 if (pylong_ulong_mask == NULL) {
1746#if (SIZEOF_LONG == 4)
1747 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1748#else
1749 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1750#endif
1751 if (pylong_ulong_mask == NULL)
1752 return;
1753 }
1754
Tim Petersc2b550e2006-05-31 14:28:07 +00001755#else
Bob Ippolito4182a752006-05-30 17:37:54 +00001756 /* This speed trick can't be used until overflow masking goes away, because
1757 native endian always raises exceptions instead of overflow masking. */
Tim Petersc2b550e2006-05-31 14:28:07 +00001758
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001759 /* Check endian and swap in faster functions */
1760 {
1761 int one = 1;
1762 formatdef *native = native_table;
1763 formatdef *other, *ptr;
1764 if ((int)*(unsigned char*)&one)
1765 other = lilendian_table;
1766 else
1767 other = bigendian_table;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001768 /* Scan through the native table, find a matching
1769 entry in the endian table and swap in the
1770 native implementations whenever possible
1771 (64-bit platforms may not have "standard" sizes) */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001772 while (native->format != '\0' && other->format != '\0') {
1773 ptr = other;
1774 while (ptr->format != '\0') {
1775 if (ptr->format == native->format) {
Bob Ippolito964e02a2006-05-25 21:09:45 +00001776 /* Match faster when formats are
1777 listed in the same order */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001778 if (ptr == other)
1779 other++;
Tim Petersc2b550e2006-05-31 14:28:07 +00001780 /* Only use the trick if the
Bob Ippolito964e02a2006-05-25 21:09:45 +00001781 size matches */
1782 if (ptr->size != native->size)
1783 break;
1784 /* Skip float and double, could be
1785 "unknown" float format */
1786 if (ptr->format == 'd' || ptr->format == 'f')
1787 break;
1788 ptr->pack = native->pack;
1789 ptr->unpack = native->unpack;
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001790 break;
1791 }
1792 ptr++;
1793 }
1794 native++;
1795 }
1796 }
Bob Ippolito2fd39772006-05-29 22:55:48 +00001797#endif
Tim Petersc2b550e2006-05-31 14:28:07 +00001798
Bob Ippolito232f3c92006-05-23 19:12:41 +00001799 /* Add some symbolic constants to the module */
1800 if (StructError == NULL) {
1801 StructError = PyErr_NewException("struct.error", NULL, NULL);
1802 if (StructError == NULL)
1803 return;
1804 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001805
Bob Ippolito232f3c92006-05-23 19:12:41 +00001806 Py_INCREF(StructError);
1807 PyModule_AddObject(m, "error", StructError);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001808
Bob Ippolito232f3c92006-05-23 19:12:41 +00001809 Py_INCREF((PyObject*)&PyStructType);
1810 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Tim Petersc2b550e2006-05-31 14:28:07 +00001811
Bob Ippolito2fd39772006-05-29 22:55:48 +00001812 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
Bob Ippolito4182a752006-05-30 17:37:54 +00001813#ifdef PY_STRUCT_OVERFLOW_MASKING
1814 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
Bob Ippolito2fd39772006-05-29 22:55:48 +00001815#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001816}