blob: 41183fa26b5bcb0db970c223fb981b10500f78a2 [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 Ippolitoe6c9f982006-08-04 23:59:21 +000034/* If PY_STRUCT_FLOAT_COERCE is defined, the struct module will allow float
35 arguments for integer formats with a warning for backwards
36 compatibility. */
37
38#define PY_STRUCT_FLOAT_COERCE 1
39
40#ifdef PY_STRUCT_FLOAT_COERCE
41#define FLOAT_COERCE "integer argument expected, got float"
42#endif
43
44
Bob Ippolito232f3c92006-05-23 19:12:41 +000045/* The translation function for each format character is table driven */
Bob Ippolito232f3c92006-05-23 19:12:41 +000046typedef struct _formatdef {
47 char format;
Bob Ippolitoaa70a172006-05-26 20:25:23 +000048 Py_ssize_t size;
49 Py_ssize_t alignment;
Bob Ippolito232f3c92006-05-23 19:12:41 +000050 PyObject* (*unpack)(const char *,
51 const struct _formatdef *);
52 int (*pack)(char *, PyObject *,
53 const struct _formatdef *);
54} formatdef;
55
56typedef struct _formatcode {
57 const struct _formatdef *fmtdef;
Bob Ippolitoaa70a172006-05-26 20:25:23 +000058 Py_ssize_t offset;
59 Py_ssize_t size;
Bob Ippolito232f3c92006-05-23 19:12:41 +000060} formatcode;
61
62/* Struct object interface */
63
64typedef struct {
65 PyObject_HEAD
Bob Ippolitoaa70a172006-05-26 20:25:23 +000066 Py_ssize_t s_size;
67 Py_ssize_t s_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +000068 formatcode *s_codes;
69 PyObject *s_format;
70 PyObject *weakreflist; /* List of weak references */
71} PyStructObject;
72
Bob Ippolitoeb621272006-05-24 15:32:06 +000073
Bob Ippolito07c023b2006-05-23 19:32:25 +000074#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
75#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
Bob Ippolito232f3c92006-05-23 19:12:41 +000076
77
78/* Exception */
79
80static PyObject *StructError;
81
82
83/* Define various structs to figure out the alignments of types */
84
85
86typedef struct { char c; short x; } st_short;
87typedef struct { char c; int x; } st_int;
88typedef struct { char c; long x; } st_long;
89typedef struct { char c; float x; } st_float;
90typedef struct { char c; double x; } st_double;
91typedef struct { char c; void *x; } st_void_p;
92
93#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
94#define INT_ALIGN (sizeof(st_int) - sizeof(int))
95#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
96#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
97#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
98#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
99
100/* We can't support q and Q in native mode unless the compiler does;
101 in std mode, they're 8 bytes on all platforms. */
102#ifdef HAVE_LONG_LONG
103typedef struct { char c; PY_LONG_LONG x; } s_long_long;
104#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
105#endif
106
107#define STRINGIFY(x) #x
108
109#ifdef __powerc
110#pragma options align=reset
111#endif
112
113/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
114
115static PyObject *
116get_pylong(PyObject *v)
117{
118 PyNumberMethods *m;
119
120 assert(v != NULL);
121 if (PyInt_Check(v))
122 return PyLong_FromLong(PyInt_AS_LONG(v));
123 if (PyLong_Check(v)) {
124 Py_INCREF(v);
125 return v;
126 }
127 m = v->ob_type->tp_as_number;
128 if (m != NULL && m->nb_long != NULL) {
129 v = m->nb_long(v);
130 if (v == NULL)
131 return NULL;
132 if (PyLong_Check(v))
133 return v;
134 Py_DECREF(v);
135 }
136 PyErr_SetString(StructError,
137 "cannot convert argument to long");
138 return NULL;
139}
140
141/* Helper routine to get a Python integer and raise the appropriate error
142 if it isn't one */
143
144static int
145get_long(PyObject *v, long *p)
146{
147 long x = PyInt_AsLong(v);
148 if (x == -1 && PyErr_Occurred()) {
Bob Ippolitoe6c9f982006-08-04 23:59:21 +0000149#ifdef PY_STRUCT_FLOAT_COERCE
150 if (PyFloat_Check(v)) {
151 PyObject *o;
152 int res;
153 PyErr_Clear();
154 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
155 return -1;
156 o = PyNumber_Int(v);
157 if (o == NULL)
158 return -1;
159 res = get_long(o, p);
160 Py_DECREF(o);
161 return res;
162 }
163#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000164 if (PyErr_ExceptionMatches(PyExc_TypeError))
165 PyErr_SetString(StructError,
166 "required argument is not an integer");
167 return -1;
168 }
169 *p = x;
170 return 0;
171}
172
173
174/* Same, but handling unsigned long */
175
176static int
177get_ulong(PyObject *v, unsigned long *p)
178{
179 if (PyLong_Check(v)) {
180 unsigned long x = PyLong_AsUnsignedLong(v);
181 if (x == (unsigned long)(-1) && PyErr_Occurred())
182 return -1;
183 *p = x;
184 return 0;
185 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000186 if (get_long(v, (long *)p) < 0)
187 return -1;
188 if (((long)*p) < 0) {
189 PyErr_SetString(StructError,
190 "unsigned argument is < 0");
191 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000192 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000193 return 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000194}
195
196#ifdef HAVE_LONG_LONG
197
198/* Same, but handling native long long. */
199
200static int
201get_longlong(PyObject *v, PY_LONG_LONG *p)
202{
203 PY_LONG_LONG x;
204
205 v = get_pylong(v);
206 if (v == NULL)
207 return -1;
208 assert(PyLong_Check(v));
209 x = PyLong_AsLongLong(v);
210 Py_DECREF(v);
211 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
212 return -1;
213 *p = x;
214 return 0;
215}
216
217/* Same, but handling native unsigned long long. */
218
219static int
220get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
221{
222 unsigned PY_LONG_LONG x;
223
224 v = get_pylong(v);
225 if (v == NULL)
226 return -1;
227 assert(PyLong_Check(v));
228 x = PyLong_AsUnsignedLongLong(v);
229 Py_DECREF(v);
230 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
231 return -1;
232 *p = x;
233 return 0;
234}
235
236#endif
237
Bob Ippolito4182a752006-05-30 17:37:54 +0000238#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000239
240/* Helper routine to get a Python integer and raise the appropriate error
241 if it isn't one */
242
Neal Norwitz07aadb12006-07-30 06:55:48 +0000243#define INT_OVERFLOW "struct integer overflow masking is deprecated"
244
Bob Ippolito2fd39772006-05-29 22:55:48 +0000245static int
246get_wrapped_long(PyObject *v, long *p)
247{
248 if (get_long(v, p) < 0) {
Neal Norwitz3c5431e2006-06-11 05:45:25 +0000249 if (PyLong_Check(v) &&
250 PyErr_ExceptionMatches(PyExc_OverflowError)) {
Bob Ippolito2fd39772006-05-29 22:55:48 +0000251 PyObject *wrapped;
252 long x;
253 PyErr_Clear();
Bob Ippolitoe6c9f982006-08-04 23:59:21 +0000254#ifdef PY_STRUCT_FLOAT_COERCE
255 if (PyFloat_Check(v)) {
256 PyObject *o;
257 int res;
258 PyErr_Clear();
259 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
260 return -1;
261 o = PyNumber_Int(v);
262 if (o == NULL)
263 return -1;
264 res = get_wrapped_long(o, p);
265 Py_DECREF(o);
266 return res;
267 }
268#endif
Neal Norwitz07aadb12006-07-30 06:55:48 +0000269 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0)
Bob Ippolito2fd39772006-05-29 22:55:48 +0000270 return -1;
271 wrapped = PyNumber_And(v, pylong_ulong_mask);
272 if (wrapped == NULL)
273 return -1;
274 x = (long)PyLong_AsUnsignedLong(wrapped);
275 Py_DECREF(wrapped);
276 if (x == -1 && PyErr_Occurred())
277 return -1;
278 *p = x;
279 } else {
280 return -1;
281 }
282 }
283 return 0;
284}
285
286static int
287get_wrapped_ulong(PyObject *v, unsigned long *p)
288{
289 long x = (long)PyLong_AsUnsignedLong(v);
290 if (x == -1 && PyErr_Occurred()) {
291 PyObject *wrapped;
292 PyErr_Clear();
Bob Ippolitoe6c9f982006-08-04 23:59:21 +0000293#ifdef PY_STRUCT_FLOAT_COERCE
294 if (PyFloat_Check(v)) {
295 PyObject *o;
296 int res;
297 PyErr_Clear();
298 if (PyErr_WarnEx(PyExc_DeprecationWarning, FLOAT_COERCE, 2) < 0)
299 return -1;
300 o = PyNumber_Int(v);
301 if (o == NULL)
302 return -1;
303 res = get_wrapped_ulong(o, p);
304 Py_DECREF(o);
305 return res;
306 }
307#endif
Bob Ippolito2fd39772006-05-29 22:55:48 +0000308 wrapped = PyNumber_And(v, pylong_ulong_mask);
309 if (wrapped == NULL)
310 return -1;
Neal Norwitz07aadb12006-07-30 06:55:48 +0000311 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) {
Bob Ippolito2fd39772006-05-29 22:55:48 +0000312 Py_DECREF(wrapped);
313 return -1;
314 }
315 x = (long)PyLong_AsUnsignedLong(wrapped);
316 Py_DECREF(wrapped);
317 if (x == -1 && PyErr_Occurred())
318 return -1;
319 }
320 *p = (unsigned long)x;
321 return 0;
322}
323
324#define RANGE_ERROR(x, f, flag, mask) \
325 do { \
326 if (_range_error(f, flag) < 0) \
327 return -1; \
328 else \
329 (x) &= (mask); \
330 } while (0)
331
332#else
333
334#define get_wrapped_long get_long
335#define get_wrapped_ulong get_ulong
336#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
337
338#endif
339
Bob Ippolito232f3c92006-05-23 19:12:41 +0000340/* Floating point helpers */
341
342static PyObject *
343unpack_float(const char *p, /* start of 4-byte string */
344 int le) /* true for little-endian, false for big-endian */
345{
346 double x;
347
348 x = _PyFloat_Unpack4((unsigned char *)p, le);
349 if (x == -1.0 && PyErr_Occurred())
350 return NULL;
351 return PyFloat_FromDouble(x);
352}
353
354static PyObject *
355unpack_double(const char *p, /* start of 8-byte string */
356 int le) /* true for little-endian, false for big-endian */
357{
358 double x;
359
360 x = _PyFloat_Unpack8((unsigned char *)p, le);
361 if (x == -1.0 && PyErr_Occurred())
362 return NULL;
363 return PyFloat_FromDouble(x);
364}
365
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000366/* Helper to format the range error exceptions */
367static int
Armin Rigo162997e2006-05-29 17:59:47 +0000368_range_error(const formatdef *f, int is_unsigned)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000369{
Tim Petersd6a6f022006-05-31 15:33:22 +0000370 /* ulargest is the largest unsigned value with f->size bytes.
371 * Note that the simpler:
372 * ((size_t)1 << (f->size * 8)) - 1
Tim Peters72270c22006-05-31 15:34:37 +0000373 * doesn't work when f->size == sizeof(size_t) because C doesn't
374 * define what happens when a left shift count is >= the number of
375 * bits in the integer being shifted; e.g., on some boxes it doesn't
376 * shift at all when they're equal.
Tim Petersd6a6f022006-05-31 15:33:22 +0000377 */
378 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
379 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
380 if (is_unsigned)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000381 PyErr_Format(StructError,
Neal Norwitz971ea112006-05-31 07:43:27 +0000382 "'%c' format requires 0 <= number <= %zu",
Bob Ippolito28b26862006-05-29 15:47:29 +0000383 f->format,
Tim Petersd6a6f022006-05-31 15:33:22 +0000384 ulargest);
385 else {
386 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
387 PyErr_Format(StructError,
388 "'%c' format requires %zd <= number <= %zd",
389 f->format,
390 ~ largest,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000391 largest);
392 }
Bob Ippolito4182a752006-05-30 17:37:54 +0000393#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000394 {
395 PyObject *ptype, *pvalue, *ptraceback;
396 PyObject *msg;
397 int rval;
398 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
399 assert(pvalue != NULL);
400 msg = PyObject_Str(pvalue);
401 Py_XDECREF(ptype);
402 Py_XDECREF(pvalue);
403 Py_XDECREF(ptraceback);
404 if (msg == NULL)
405 return -1;
Neal Norwitz07aadb12006-07-30 06:55:48 +0000406 rval = PyErr_WarnEx(PyExc_DeprecationWarning,
407 PyString_AS_STRING(msg), 2);
Bob Ippolito2fd39772006-05-29 22:55:48 +0000408 Py_DECREF(msg);
409 if (rval == 0)
410 return 0;
411 }
412#endif
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000413 return -1;
414}
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000415
416
Bob Ippolito232f3c92006-05-23 19:12:41 +0000417
418/* A large number of small routines follow, with names of the form
419
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000420 [bln][up]_TYPE
Bob Ippolito232f3c92006-05-23 19:12:41 +0000421
422 [bln] distiguishes among big-endian, little-endian and native.
423 [pu] distiguishes between pack (to struct) and unpack (from struct).
424 TYPE is one of char, byte, ubyte, etc.
425*/
426
427/* Native mode routines. ****************************************************/
428/* NOTE:
429 In all n[up]_<type> routines handling types larger than 1 byte, there is
430 *no* guarantee that the p pointer is properly aligned for each type,
431 therefore memcpy is called. An intermediate variable is used to
432 compensate for big-endian architectures.
433 Normally both the intermediate variable and the memcpy call will be
434 skipped by C optimisation in little-endian architectures (gcc >= 2.91
435 does this). */
436
437static PyObject *
438nu_char(const char *p, const formatdef *f)
439{
440 return PyString_FromStringAndSize(p, 1);
441}
442
443static PyObject *
444nu_byte(const char *p, const formatdef *f)
445{
446 return PyInt_FromLong((long) *(signed char *)p);
447}
448
449static PyObject *
450nu_ubyte(const char *p, const formatdef *f)
451{
452 return PyInt_FromLong((long) *(unsigned char *)p);
453}
454
455static PyObject *
456nu_short(const char *p, const formatdef *f)
457{
458 short x;
459 memcpy((char *)&x, p, sizeof x);
460 return PyInt_FromLong((long)x);
461}
462
463static PyObject *
464nu_ushort(const char *p, const formatdef *f)
465{
466 unsigned short x;
467 memcpy((char *)&x, p, sizeof x);
468 return PyInt_FromLong((long)x);
469}
470
471static PyObject *
472nu_int(const char *p, const formatdef *f)
473{
474 int x;
475 memcpy((char *)&x, p, sizeof x);
476 return PyInt_FromLong((long)x);
477}
478
479static PyObject *
480nu_uint(const char *p, const formatdef *f)
481{
482 unsigned int x;
483 memcpy((char *)&x, p, sizeof x);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000484#if (SIZEOF_LONG > SIZEOF_INT)
485 return PyInt_FromLong((long)x);
486#else
487 if (x <= ((unsigned int)LONG_MAX))
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000488 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000489 return PyLong_FromUnsignedLong((unsigned long)x);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000490#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000491}
492
493static PyObject *
494nu_long(const char *p, const formatdef *f)
495{
496 long x;
497 memcpy((char *)&x, p, sizeof x);
498 return PyInt_FromLong(x);
499}
500
501static PyObject *
502nu_ulong(const char *p, const formatdef *f)
503{
504 unsigned long x;
505 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000506 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000507 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000508 return PyLong_FromUnsignedLong(x);
509}
510
511/* Native mode doesn't support q or Q unless the platform C supports
512 long long (or, on Windows, __int64). */
513
514#ifdef HAVE_LONG_LONG
515
516static PyObject *
517nu_longlong(const char *p, const formatdef *f)
518{
519 PY_LONG_LONG x;
520 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000521 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000522 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000523 return PyLong_FromLongLong(x);
524}
525
526static PyObject *
527nu_ulonglong(const char *p, const formatdef *f)
528{
529 unsigned PY_LONG_LONG x;
530 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000531 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000532 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000533 return PyLong_FromUnsignedLongLong(x);
534}
535
536#endif
537
538static PyObject *
539nu_float(const char *p, const formatdef *f)
540{
541 float x;
542 memcpy((char *)&x, p, sizeof x);
543 return PyFloat_FromDouble((double)x);
544}
545
546static PyObject *
547nu_double(const char *p, const formatdef *f)
548{
549 double x;
550 memcpy((char *)&x, p, sizeof x);
551 return PyFloat_FromDouble(x);
552}
553
554static PyObject *
555nu_void_p(const char *p, const formatdef *f)
556{
557 void *x;
558 memcpy((char *)&x, p, sizeof x);
559 return PyLong_FromVoidPtr(x);
560}
561
562static int
563np_byte(char *p, PyObject *v, const formatdef *f)
564{
565 long x;
566 if (get_long(v, &x) < 0)
567 return -1;
568 if (x < -128 || x > 127){
569 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000570 "byte format requires -128 <= number <= 127");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000571 return -1;
572 }
573 *p = (char)x;
574 return 0;
575}
576
577static int
578np_ubyte(char *p, PyObject *v, const formatdef *f)
579{
580 long x;
581 if (get_long(v, &x) < 0)
582 return -1;
583 if (x < 0 || x > 255){
584 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000585 "ubyte format requires 0 <= number <= 255");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000586 return -1;
587 }
588 *p = (char)x;
589 return 0;
590}
591
592static int
593np_char(char *p, PyObject *v, const formatdef *f)
594{
595 if (!PyString_Check(v) || PyString_Size(v) != 1) {
596 PyErr_SetString(StructError,
597 "char format require string of length 1");
598 return -1;
599 }
600 *p = *PyString_AsString(v);
601 return 0;
602}
603
604static int
605np_short(char *p, PyObject *v, const formatdef *f)
606{
607 long x;
608 short y;
609 if (get_long(v, &x) < 0)
610 return -1;
611 if (x < SHRT_MIN || x > SHRT_MAX){
612 PyErr_SetString(StructError,
613 "short format requires " STRINGIFY(SHRT_MIN)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000614 " <= number <= " STRINGIFY(SHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000615 return -1;
616 }
617 y = (short)x;
618 memcpy(p, (char *)&y, sizeof y);
619 return 0;
620}
621
622static int
623np_ushort(char *p, PyObject *v, const formatdef *f)
624{
625 long x;
626 unsigned short y;
627 if (get_long(v, &x) < 0)
628 return -1;
629 if (x < 0 || x > USHRT_MAX){
630 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000631 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000632 return -1;
633 }
634 y = (unsigned short)x;
635 memcpy(p, (char *)&y, sizeof y);
636 return 0;
637}
638
639static int
640np_int(char *p, PyObject *v, const formatdef *f)
641{
642 long x;
643 int y;
644 if (get_long(v, &x) < 0)
645 return -1;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000646#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000647 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Bob Ippolito28b26862006-05-29 15:47:29 +0000648 return _range_error(f, 0);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000649#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000650 y = (int)x;
651 memcpy(p, (char *)&y, sizeof y);
652 return 0;
653}
654
655static int
656np_uint(char *p, PyObject *v, const formatdef *f)
657{
658 unsigned long x;
659 unsigned int y;
660 if (get_ulong(v, &x) < 0)
Bob Ippolito28b26862006-05-29 15:47:29 +0000661 return _range_error(f, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000662 y = (unsigned int)x;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000663#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000664 if (x > ((unsigned long)UINT_MAX))
Bob Ippolito28b26862006-05-29 15:47:29 +0000665 return _range_error(f, 1);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000666#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000667 memcpy(p, (char *)&y, sizeof y);
668 return 0;
669}
670
671static int
672np_long(char *p, PyObject *v, const formatdef *f)
673{
674 long x;
675 if (get_long(v, &x) < 0)
676 return -1;
677 memcpy(p, (char *)&x, sizeof x);
678 return 0;
679}
680
681static int
682np_ulong(char *p, PyObject *v, const formatdef *f)
683{
684 unsigned long x;
685 if (get_ulong(v, &x) < 0)
Bob Ippolito28b26862006-05-29 15:47:29 +0000686 return _range_error(f, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000687 memcpy(p, (char *)&x, sizeof x);
688 return 0;
689}
690
691#ifdef HAVE_LONG_LONG
692
693static int
694np_longlong(char *p, PyObject *v, const formatdef *f)
695{
696 PY_LONG_LONG x;
697 if (get_longlong(v, &x) < 0)
698 return -1;
699 memcpy(p, (char *)&x, sizeof x);
700 return 0;
701}
702
703static int
704np_ulonglong(char *p, PyObject *v, const formatdef *f)
705{
706 unsigned PY_LONG_LONG x;
707 if (get_ulonglong(v, &x) < 0)
708 return -1;
709 memcpy(p, (char *)&x, sizeof x);
710 return 0;
711}
712#endif
713
714static int
715np_float(char *p, PyObject *v, const formatdef *f)
716{
717 float x = (float)PyFloat_AsDouble(v);
718 if (x == -1 && PyErr_Occurred()) {
719 PyErr_SetString(StructError,
720 "required argument is not a float");
721 return -1;
722 }
723 memcpy(p, (char *)&x, sizeof x);
724 return 0;
725}
726
727static int
728np_double(char *p, PyObject *v, const formatdef *f)
729{
730 double x = PyFloat_AsDouble(v);
731 if (x == -1 && PyErr_Occurred()) {
732 PyErr_SetString(StructError,
733 "required argument is not a float");
734 return -1;
735 }
736 memcpy(p, (char *)&x, sizeof(double));
737 return 0;
738}
739
740static int
741np_void_p(char *p, PyObject *v, const formatdef *f)
742{
743 void *x;
744
745 v = get_pylong(v);
746 if (v == NULL)
747 return -1;
748 assert(PyLong_Check(v));
749 x = PyLong_AsVoidPtr(v);
750 Py_DECREF(v);
751 if (x == NULL && PyErr_Occurred())
752 return -1;
753 memcpy(p, (char *)&x, sizeof x);
754 return 0;
755}
756
757static formatdef native_table[] = {
758 {'x', sizeof(char), 0, NULL},
759 {'b', sizeof(char), 0, nu_byte, np_byte},
760 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
761 {'c', sizeof(char), 0, nu_char, np_char},
762 {'s', sizeof(char), 0, NULL},
763 {'p', sizeof(char), 0, NULL},
764 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
765 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
766 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
767 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
768 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
769 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000770#ifdef HAVE_LONG_LONG
771 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
772 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
773#endif
Bob Ippolitoa99865b2006-05-25 19:56:56 +0000774 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
775 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
776 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000777 {0}
778};
779
780/* Big-endian routines. *****************************************************/
781
782static PyObject *
783bu_int(const char *p, const formatdef *f)
784{
785 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000786 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000787 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000788 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000789 x = (x<<8) | *bytes++;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000790 } while (--i > 0);
791 /* Extend the sign bit. */
792 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000793 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000794 return PyInt_FromLong(x);
795}
796
797static PyObject *
798bu_uint(const char *p, const formatdef *f)
799{
800 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000801 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000802 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000803 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000804 x = (x<<8) | *bytes++;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000805 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000806 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000807 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000808 return PyLong_FromUnsignedLong(x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000809}
810
811static PyObject *
812bu_longlong(const char *p, const formatdef *f)
813{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000814#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000815 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000816 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000817 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000818 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000819 x = (x<<8) | *bytes++;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000820 } while (--i > 0);
821 /* Extend the sign bit. */
822 if (SIZEOF_LONG_LONG > f->size)
Kristján Valur Jónsson2c8851e2006-10-07 14:56:30 +0000823 x |= -(x & ( (PY_LONG_LONG)1 << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000824 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000825 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000826 return PyLong_FromLongLong(x);
827#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000828 return _PyLong_FromByteArray((const unsigned char *)p,
829 8,
830 0, /* little-endian */
831 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000832#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000833}
834
835static PyObject *
836bu_ulonglong(const char *p, const formatdef *f)
837{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000838#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000839 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000840 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000841 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000842 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000843 x = (x<<8) | *bytes++;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000844 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000845 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000846 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000847 return PyLong_FromUnsignedLongLong(x);
848#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000849 return _PyLong_FromByteArray((const unsigned char *)p,
850 8,
851 0, /* little-endian */
852 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000853#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000854}
855
856static PyObject *
857bu_float(const char *p, const formatdef *f)
858{
859 return unpack_float(p, 0);
860}
861
862static PyObject *
863bu_double(const char *p, const formatdef *f)
864{
865 return unpack_double(p, 0);
866}
867
868static int
869bp_int(char *p, PyObject *v, const formatdef *f)
870{
871 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000872 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +0000873 if (get_wrapped_long(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000874 return -1;
875 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000876 if (i != SIZEOF_LONG) {
877 if ((i == 2) && (x < -32768 || x > 32767))
Bob Ippolito2fd39772006-05-29 22:55:48 +0000878 RANGE_ERROR(x, f, 0, 0xffffL);
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000879#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000880 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Bob Ippolito2fd39772006-05-29 22:55:48 +0000881 RANGE_ERROR(x, f, 0, 0xffffffffL);
882#endif
Bob Ippolito4182a752006-05-30 17:37:54 +0000883#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000884 else if ((i == 1) && (x < -128 || x > 127))
885 RANGE_ERROR(x, f, 0, 0xffL);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000886#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000887 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000888 do {
889 p[--i] = (char)x;
890 x >>= 8;
891 } while (i > 0);
892 return 0;
893}
894
895static int
896bp_uint(char *p, PyObject *v, const formatdef *f)
897{
898 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000899 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +0000900 if (get_wrapped_ulong(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000901 return -1;
902 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000903 if (i != SIZEOF_LONG) {
904 unsigned long maxint = 1;
905 maxint <<= (unsigned long)(i * 8);
906 if (x >= maxint)
Bob Ippolito2fd39772006-05-29 22:55:48 +0000907 RANGE_ERROR(x, f, 1, maxint - 1);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000908 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000909 do {
910 p[--i] = (char)x;
911 x >>= 8;
912 } while (i > 0);
913 return 0;
914}
915
916static int
917bp_longlong(char *p, PyObject *v, const formatdef *f)
918{
919 int res;
920 v = get_pylong(v);
921 if (v == NULL)
922 return -1;
923 res = _PyLong_AsByteArray((PyLongObject *)v,
924 (unsigned char *)p,
925 8,
926 0, /* little_endian */
927 1 /* signed */);
928 Py_DECREF(v);
929 return res;
930}
931
932static int
933bp_ulonglong(char *p, PyObject *v, const formatdef *f)
934{
935 int res;
936 v = get_pylong(v);
937 if (v == NULL)
938 return -1;
939 res = _PyLong_AsByteArray((PyLongObject *)v,
940 (unsigned char *)p,
941 8,
942 0, /* little_endian */
943 0 /* signed */);
944 Py_DECREF(v);
945 return res;
946}
947
948static int
949bp_float(char *p, PyObject *v, const formatdef *f)
950{
951 double x = PyFloat_AsDouble(v);
952 if (x == -1 && PyErr_Occurred()) {
953 PyErr_SetString(StructError,
954 "required argument is not a float");
955 return -1;
956 }
957 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
958}
959
960static int
961bp_double(char *p, PyObject *v, const formatdef *f)
962{
963 double x = PyFloat_AsDouble(v);
964 if (x == -1 && PyErr_Occurred()) {
965 PyErr_SetString(StructError,
966 "required argument is not a float");
967 return -1;
968 }
969 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
970}
971
972static formatdef bigendian_table[] = {
973 {'x', 1, 0, NULL},
Bob Ippolito4182a752006-05-30 17:37:54 +0000974#ifdef PY_STRUCT_OVERFLOW_MASKING
975 /* Native packers do range checking without overflow masking. */
Bob Ippolito2fd39772006-05-29 22:55:48 +0000976 {'b', 1, 0, nu_byte, bp_int},
977 {'B', 1, 0, nu_ubyte, bp_uint},
978#else
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000979 {'b', 1, 0, nu_byte, np_byte},
980 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito2fd39772006-05-29 22:55:48 +0000981#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000982 {'c', 1, 0, nu_char, np_char},
983 {'s', 1, 0, NULL},
984 {'p', 1, 0, NULL},
985 {'h', 2, 0, bu_int, bp_int},
986 {'H', 2, 0, bu_uint, bp_uint},
987 {'i', 4, 0, bu_int, bp_int},
988 {'I', 4, 0, bu_uint, bp_uint},
989 {'l', 4, 0, bu_int, bp_int},
990 {'L', 4, 0, bu_uint, bp_uint},
991 {'q', 8, 0, bu_longlong, bp_longlong},
992 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
993 {'f', 4, 0, bu_float, bp_float},
994 {'d', 8, 0, bu_double, bp_double},
995 {0}
996};
997
998/* Little-endian routines. *****************************************************/
999
1000static PyObject *
1001lu_int(const char *p, const formatdef *f)
1002{
1003 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001004 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +00001005 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001006 do {
Bob Ippolito28b26862006-05-29 15:47:29 +00001007 x = (x<<8) | bytes[--i];
Bob Ippolito232f3c92006-05-23 19:12:41 +00001008 } while (i > 0);
1009 /* Extend the sign bit. */
1010 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001011 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +00001012 return PyInt_FromLong(x);
1013}
1014
1015static PyObject *
1016lu_uint(const char *p, const formatdef *f)
1017{
1018 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001019 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +00001020 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001021 do {
Bob Ippolito28b26862006-05-29 15:47:29 +00001022 x = (x<<8) | bytes[--i];
Bob Ippolito232f3c92006-05-23 19:12:41 +00001023 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001024 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001025 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001026 return PyLong_FromUnsignedLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001027}
1028
1029static PyObject *
1030lu_longlong(const char *p, const formatdef *f)
1031{
Bob Ippolito90bd0a52006-05-27 11:47:12 +00001032#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001033 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001034 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +00001035 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001036 do {
Bob Ippolito28b26862006-05-29 15:47:29 +00001037 x = (x<<8) | bytes[--i];
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001038 } while (i > 0);
1039 /* Extend the sign bit. */
1040 if (SIZEOF_LONG_LONG > f->size)
Kristján Valur Jónsson2c8851e2006-10-07 14:56:30 +00001041 x |= -(x & ( (PY_LONG_LONG)1 << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +00001042 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001043 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001044 return PyLong_FromLongLong(x);
1045#else
Bob Ippolito232f3c92006-05-23 19:12:41 +00001046 return _PyLong_FromByteArray((const unsigned char *)p,
1047 8,
1048 1, /* little-endian */
1049 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001050#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001051}
1052
1053static PyObject *
1054lu_ulonglong(const char *p, const formatdef *f)
1055{
Bob Ippolito90bd0a52006-05-27 11:47:12 +00001056#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001057 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001058 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +00001059 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001060 do {
Bob Ippolito28b26862006-05-29 15:47:29 +00001061 x = (x<<8) | bytes[--i];
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001062 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001063 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001064 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001065 return PyLong_FromUnsignedLongLong(x);
1066#else
Bob Ippolito232f3c92006-05-23 19:12:41 +00001067 return _PyLong_FromByteArray((const unsigned char *)p,
1068 8,
1069 1, /* little-endian */
1070 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001071#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001072}
1073
1074static PyObject *
1075lu_float(const char *p, const formatdef *f)
1076{
1077 return unpack_float(p, 1);
1078}
1079
1080static PyObject *
1081lu_double(const char *p, const formatdef *f)
1082{
1083 return unpack_double(p, 1);
1084}
1085
1086static int
1087lp_int(char *p, PyObject *v, const formatdef *f)
1088{
1089 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001090 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001091 if (get_wrapped_long(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001092 return -1;
1093 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001094 if (i != SIZEOF_LONG) {
1095 if ((i == 2) && (x < -32768 || x > 32767))
Bob Ippolito2fd39772006-05-29 22:55:48 +00001096 RANGE_ERROR(x, f, 0, 0xffffL);
Bob Ippolito90bd0a52006-05-27 11:47:12 +00001097#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001098 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Bob Ippolito2fd39772006-05-29 22:55:48 +00001099 RANGE_ERROR(x, f, 0, 0xffffffffL);
1100#endif
Bob Ippolito4182a752006-05-30 17:37:54 +00001101#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +00001102 else if ((i == 1) && (x < -128 || x > 127))
1103 RANGE_ERROR(x, f, 0, 0xffL);
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001104#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001105 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001106 do {
1107 *p++ = (char)x;
1108 x >>= 8;
1109 } while (--i > 0);
1110 return 0;
1111}
1112
1113static int
1114lp_uint(char *p, PyObject *v, const formatdef *f)
1115{
1116 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001117 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001118 if (get_wrapped_ulong(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001119 return -1;
1120 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001121 if (i != SIZEOF_LONG) {
1122 unsigned long maxint = 1;
1123 maxint <<= (unsigned long)(i * 8);
1124 if (x >= maxint)
Bob Ippolito2fd39772006-05-29 22:55:48 +00001125 RANGE_ERROR(x, f, 1, maxint - 1);
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001126 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001127 do {
1128 *p++ = (char)x;
1129 x >>= 8;
1130 } while (--i > 0);
1131 return 0;
1132}
1133
1134static int
1135lp_longlong(char *p, PyObject *v, const formatdef *f)
1136{
1137 int res;
1138 v = get_pylong(v);
1139 if (v == NULL)
1140 return -1;
1141 res = _PyLong_AsByteArray((PyLongObject*)v,
1142 (unsigned char *)p,
1143 8,
1144 1, /* little_endian */
1145 1 /* signed */);
1146 Py_DECREF(v);
1147 return res;
1148}
1149
1150static int
1151lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1152{
1153 int res;
1154 v = get_pylong(v);
1155 if (v == NULL)
1156 return -1;
1157 res = _PyLong_AsByteArray((PyLongObject*)v,
1158 (unsigned char *)p,
1159 8,
1160 1, /* little_endian */
1161 0 /* signed */);
1162 Py_DECREF(v);
1163 return res;
1164}
1165
1166static int
1167lp_float(char *p, PyObject *v, const formatdef *f)
1168{
1169 double x = PyFloat_AsDouble(v);
1170 if (x == -1 && PyErr_Occurred()) {
1171 PyErr_SetString(StructError,
1172 "required argument is not a float");
1173 return -1;
1174 }
1175 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1176}
1177
1178static int
1179lp_double(char *p, PyObject *v, const formatdef *f)
1180{
1181 double x = PyFloat_AsDouble(v);
1182 if (x == -1 && PyErr_Occurred()) {
1183 PyErr_SetString(StructError,
1184 "required argument is not a float");
1185 return -1;
1186 }
1187 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1188}
1189
1190static formatdef lilendian_table[] = {
1191 {'x', 1, 0, NULL},
Bob Ippolito4182a752006-05-30 17:37:54 +00001192#ifdef PY_STRUCT_OVERFLOW_MASKING
1193 /* Native packers do range checking without overflow masking. */
Bob Ippolito2fd39772006-05-29 22:55:48 +00001194 {'b', 1, 0, nu_byte, lp_int},
1195 {'B', 1, 0, nu_ubyte, lp_uint},
1196#else
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001197 {'b', 1, 0, nu_byte, np_byte},
1198 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito2fd39772006-05-29 22:55:48 +00001199#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001200 {'c', 1, 0, nu_char, np_char},
1201 {'s', 1, 0, NULL},
1202 {'p', 1, 0, NULL},
1203 {'h', 2, 0, lu_int, lp_int},
1204 {'H', 2, 0, lu_uint, lp_uint},
1205 {'i', 4, 0, lu_int, lp_int},
1206 {'I', 4, 0, lu_uint, lp_uint},
1207 {'l', 4, 0, lu_int, lp_int},
1208 {'L', 4, 0, lu_uint, lp_uint},
1209 {'q', 8, 0, lu_longlong, lp_longlong},
1210 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1211 {'f', 4, 0, lu_float, lp_float},
1212 {'d', 8, 0, lu_double, lp_double},
1213 {0}
1214};
1215
1216
1217static const formatdef *
1218whichtable(char **pfmt)
1219{
1220 const char *fmt = (*pfmt)++; /* May be backed out of later */
1221 switch (*fmt) {
1222 case '<':
1223 return lilendian_table;
1224 case '>':
1225 case '!': /* Network byte order is big-endian */
1226 return bigendian_table;
1227 case '=': { /* Host byte order -- different from native in aligment! */
1228 int n = 1;
1229 char *p = (char *) &n;
1230 if (*p == 1)
1231 return lilendian_table;
1232 else
1233 return bigendian_table;
1234 }
1235 default:
1236 --*pfmt; /* Back out of pointer increment */
1237 /* Fall through */
1238 case '@':
1239 return native_table;
1240 }
1241}
1242
1243
1244/* Get the table entry for a format code */
1245
1246static const formatdef *
1247getentry(int c, const formatdef *f)
1248{
1249 for (; f->format != '\0'; f++) {
1250 if (f->format == c) {
1251 return f;
1252 }
1253 }
1254 PyErr_SetString(StructError, "bad char in struct format");
1255 return NULL;
1256}
1257
1258
1259/* Align a size according to a format code */
1260
1261static int
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001262align(Py_ssize_t size, char c, const formatdef *e)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001263{
1264 if (e->format == c) {
1265 if (e->alignment) {
1266 size = ((size + e->alignment - 1)
1267 / e->alignment)
1268 * e->alignment;
1269 }
1270 }
1271 return size;
1272}
1273
1274
1275/* calculate the size of a format string */
1276
1277static int
1278prepare_s(PyStructObject *self)
1279{
1280 const formatdef *f;
1281 const formatdef *e;
1282 formatcode *codes;
Tim Petersc2b550e2006-05-31 14:28:07 +00001283
Bob Ippolito232f3c92006-05-23 19:12:41 +00001284 const char *s;
1285 const char *fmt;
1286 char c;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001287 Py_ssize_t size, len, num, itemsize, x;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001288
1289 fmt = PyString_AS_STRING(self->s_format);
1290
1291 f = whichtable((char **)&fmt);
Tim Petersc2b550e2006-05-31 14:28:07 +00001292
Bob Ippolito232f3c92006-05-23 19:12:41 +00001293 s = fmt;
1294 size = 0;
1295 len = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001296 while ((c = *s++) != '\0') {
1297 if (isspace(Py_CHARMASK(c)))
1298 continue;
1299 if ('0' <= c && c <= '9') {
1300 num = c - '0';
1301 while ('0' <= (c = *s++) && c <= '9') {
1302 x = num*10 + (c - '0');
1303 if (x/10 != num) {
1304 PyErr_SetString(
1305 StructError,
1306 "overflow in item count");
1307 return -1;
1308 }
1309 num = x;
1310 }
1311 if (c == '\0')
1312 break;
1313 }
1314 else
1315 num = 1;
1316
1317 e = getentry(c, f);
1318 if (e == NULL)
1319 return -1;
Tim Petersc2b550e2006-05-31 14:28:07 +00001320
Bob Ippolito232f3c92006-05-23 19:12:41 +00001321 switch (c) {
1322 case 's': /* fall through */
1323 case 'p': len++; break;
1324 case 'x': break;
1325 default: len += num; break;
1326 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001327
1328 itemsize = e->size;
1329 size = align(size, c, e);
1330 x = num * itemsize;
1331 size += x;
1332 if (x/itemsize != num || size < 0) {
1333 PyErr_SetString(StructError,
1334 "total struct size too long");
1335 return -1;
1336 }
1337 }
1338
Martin v. Löwis73c01d42008-02-14 11:26:18 +00001339 /* check for overflow */
1340 if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {
1341 PyErr_NoMemory();
1342 return -1;
1343 }
1344
Bob Ippolito232f3c92006-05-23 19:12:41 +00001345 self->s_size = size;
1346 self->s_len = len;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001347 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
Bob Ippolito232f3c92006-05-23 19:12:41 +00001348 if (codes == NULL) {
1349 PyErr_NoMemory();
1350 return -1;
1351 }
1352 self->s_codes = codes;
Tim Petersc2b550e2006-05-31 14:28:07 +00001353
Bob Ippolito232f3c92006-05-23 19:12:41 +00001354 s = fmt;
1355 size = 0;
1356 while ((c = *s++) != '\0') {
1357 if (isspace(Py_CHARMASK(c)))
1358 continue;
1359 if ('0' <= c && c <= '9') {
1360 num = c - '0';
1361 while ('0' <= (c = *s++) && c <= '9')
1362 num = num*10 + (c - '0');
1363 if (c == '\0')
1364 break;
1365 }
1366 else
1367 num = 1;
1368
1369 e = getentry(c, f);
Tim Petersc2b550e2006-05-31 14:28:07 +00001370
Bob Ippolito232f3c92006-05-23 19:12:41 +00001371 size = align(size, c, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001372 if (c == 's' || c == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001373 codes->offset = size;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001374 codes->size = num;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001375 codes->fmtdef = e;
1376 codes++;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001377 size += num;
1378 } else if (c == 'x') {
1379 size += num;
1380 } else {
1381 while (--num >= 0) {
1382 codes->offset = size;
1383 codes->size = e->size;
1384 codes->fmtdef = e;
1385 codes++;
1386 size += e->size;
1387 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001388 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001389 }
1390 codes->fmtdef = NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001391 codes->offset = size;
1392 codes->size = 0;
Tim Petersc2b550e2006-05-31 14:28:07 +00001393
Bob Ippolito232f3c92006-05-23 19:12:41 +00001394 return 0;
1395}
1396
1397static PyObject *
1398s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1399{
1400 PyObject *self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001401
1402 assert(type != NULL && type->tp_alloc != NULL);
1403
1404 self = type->tp_alloc(type, 0);
1405 if (self != NULL) {
1406 PyStructObject *s = (PyStructObject*)self;
1407 Py_INCREF(Py_None);
1408 s->s_format = Py_None;
1409 s->s_codes = NULL;
1410 s->s_size = -1;
1411 s->s_len = -1;
1412 }
1413 return self;
1414}
1415
1416static int
1417s_init(PyObject *self, PyObject *args, PyObject *kwds)
1418{
1419 PyStructObject *soself = (PyStructObject *)self;
1420 PyObject *o_format = NULL;
1421 int ret = 0;
1422 static char *kwlist[] = {"format", 0};
1423
1424 assert(PyStruct_Check(self));
1425
1426 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1427 &o_format))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001428 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001429
1430 Py_INCREF(o_format);
1431 Py_XDECREF(soself->s_format);
1432 soself->s_format = o_format;
Tim Petersc2b550e2006-05-31 14:28:07 +00001433
Bob Ippolito232f3c92006-05-23 19:12:41 +00001434 ret = prepare_s(soself);
1435 return ret;
1436}
1437
1438static void
1439s_dealloc(PyStructObject *s)
1440{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001441 if (s->weakreflist != NULL)
1442 PyObject_ClearWeakRefs((PyObject *)s);
1443 if (s->s_codes != NULL) {
1444 PyMem_FREE(s->s_codes);
1445 }
1446 Py_XDECREF(s->s_format);
1447 s->ob_type->tp_free((PyObject *)s);
1448}
1449
Bob Ippolitoeb621272006-05-24 15:32:06 +00001450static PyObject *
1451s_unpack_internal(PyStructObject *soself, char *startfrom) {
1452 formatcode *code;
1453 Py_ssize_t i = 0;
1454 PyObject *result = PyTuple_New(soself->s_len);
1455 if (result == NULL)
1456 return NULL;
1457
1458 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1459 PyObject *v;
1460 const formatdef *e = code->fmtdef;
1461 const char *res = startfrom + code->offset;
1462 if (e->format == 's') {
1463 v = PyString_FromStringAndSize(res, code->size);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001464 } else if (e->format == 'p') {
1465 Py_ssize_t n = *(unsigned char*)res;
1466 if (n >= code->size)
1467 n = code->size - 1;
1468 v = PyString_FromStringAndSize(res + 1, n);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001469 } else {
1470 v = e->unpack(res, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001471 }
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001472 if (v == NULL)
1473 goto fail;
1474 PyTuple_SET_ITEM(result, i++, v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001475 }
1476
1477 return result;
1478fail:
1479 Py_DECREF(result);
1480 return NULL;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001481}
Bob Ippolitoeb621272006-05-24 15:32:06 +00001482
1483
Bob Ippolito232f3c92006-05-23 19:12:41 +00001484PyDoc_STRVAR(s_unpack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001485"S.unpack(str) -> (v1, v2, ...)\n\
Bob Ippolito232f3c92006-05-23 19:12:41 +00001486\n\
1487Return tuple containing values unpacked according to this Struct's format.\n\
1488Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1489strings.");
1490
1491static PyObject *
1492s_unpack(PyObject *self, PyObject *inputstr)
1493{
Raymond Hettinger3608f052007-04-04 20:32:03 +00001494 char *start;
Neal Norwitzef4364f2007-04-05 05:06:49 +00001495 Py_ssize_t len;
Raymond Hettingerb2064d72007-04-04 21:57:12 +00001496 PyObject *args=NULL, *result;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001497 PyStructObject *soself = (PyStructObject *)self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001498 assert(PyStruct_Check(self));
Tim Petersc2b550e2006-05-31 14:28:07 +00001499 assert(soself->s_codes != NULL);
Raymond Hettingerb2064d72007-04-04 21:57:12 +00001500 if (inputstr == NULL)
1501 goto fail;
1502 if (PyString_Check(inputstr) &&
Raymond Hettinger3608f052007-04-04 20:32:03 +00001503 PyString_GET_SIZE(inputstr) == soself->s_size) {
1504 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1505 }
1506 args = PyTuple_Pack(1, inputstr);
1507 if (args == NULL)
1508 return NULL;
Raymond Hettingerb2064d72007-04-04 21:57:12 +00001509 if (!PyArg_ParseTuple(args, "s#:unpack", &start, &len))
1510 goto fail;
1511 if (soself->s_size != len)
1512 goto fail;
1513 result = s_unpack_internal(soself, start);
Raymond Hettinger3608f052007-04-04 20:32:03 +00001514 Py_DECREF(args);
Raymond Hettingerb2064d72007-04-04 21:57:12 +00001515 return result;
1516
1517fail:
1518 Py_XDECREF(args);
1519 PyErr_Format(StructError,
1520 "unpack requires a string argument of length %zd",
1521 soself->s_size);
1522 return NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001523}
1524
1525PyDoc_STRVAR(s_unpack_from__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001526"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
Bob Ippolitoeb621272006-05-24 15:32:06 +00001527\n\
1528Return tuple containing values unpacked according to this Struct's format.\n\
1529Unlike unpack, unpack_from can unpack values from any object supporting\n\
1530the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1531See struct.__doc__ for more on format strings.");
1532
1533static PyObject *
1534s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1535{
1536 static char *kwlist[] = {"buffer", "offset", 0};
1537#if (PY_VERSION_HEX < 0x02050000)
1538 static char *fmt = "z#|i:unpack_from";
1539#else
1540 static char *fmt = "z#|n:unpack_from";
1541#endif
1542 Py_ssize_t buffer_len = 0, offset = 0;
1543 char *buffer = NULL;
1544 PyStructObject *soself = (PyStructObject *)self;
1545 assert(PyStruct_Check(self));
1546 assert(soself->s_codes != NULL);
1547
1548 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1549 &buffer, &buffer_len, &offset))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001550 return NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001551
1552 if (buffer == NULL) {
1553 PyErr_Format(StructError,
1554 "unpack_from requires a buffer argument");
Bob Ippolito232f3c92006-05-23 19:12:41 +00001555 return NULL;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001556 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001557
Bob Ippolitoeb621272006-05-24 15:32:06 +00001558 if (offset < 0)
1559 offset += buffer_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001560
Bob Ippolitoeb621272006-05-24 15:32:06 +00001561 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1562 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001563 "unpack_from requires a buffer of at least %zd bytes",
Bob Ippolitoeb621272006-05-24 15:32:06 +00001564 soself->s_size);
1565 return NULL;
1566 }
1567 return s_unpack_internal(soself, buffer + offset);
1568}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001569
Bob Ippolito232f3c92006-05-23 19:12:41 +00001570
Martin Blais2856e5f2006-05-26 12:03:27 +00001571/*
1572 * Guts of the pack function.
1573 *
1574 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1575 * argument for where to start processing the arguments for packing, and a
1576 * character buffer for writing the packed string. The caller must insure
1577 * that the buffer may contain the required length for packing the arguments.
1578 * 0 is returned on success, 1 is returned if there is an error.
1579 *
1580 */
1581static int
1582s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001583{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001584 formatcode *code;
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001585 /* XXX(nnorwitz): why does i need to be a local? can we use
1586 the offset parameter or do we need the wider width? */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001587 Py_ssize_t i;
Martin Blais2856e5f2006-05-26 12:03:27 +00001588
1589 memset(buf, '\0', soself->s_size);
1590 i = offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001591 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1592 Py_ssize_t n;
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001593 PyObject *v = PyTuple_GET_ITEM(args, i++);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001594 const formatdef *e = code->fmtdef;
Martin Blais2856e5f2006-05-26 12:03:27 +00001595 char *res = buf + code->offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001596 if (e->format == 's') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001597 if (!PyString_Check(v)) {
1598 PyErr_SetString(StructError,
1599 "argument for 's' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001600 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001601 }
1602 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001603 if (n > code->size)
1604 n = code->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001605 if (n > 0)
1606 memcpy(res, PyString_AS_STRING(v), n);
1607 } else if (e->format == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001608 if (!PyString_Check(v)) {
1609 PyErr_SetString(StructError,
1610 "argument for 'p' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001611 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001612 }
1613 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001614 if (n > (code->size - 1))
1615 n = code->size - 1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001616 if (n > 0)
1617 memcpy(res + 1, PyString_AS_STRING(v), n);
1618 if (n > 255)
1619 n = 255;
1620 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1621 } else {
Bob Ippolito2fd39772006-05-29 22:55:48 +00001622 if (e->pack(res, v, e) < 0) {
1623 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1624 PyErr_SetString(StructError,
1625 "long too large to convert to int");
Martin Blais2856e5f2006-05-26 12:03:27 +00001626 return -1;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001627 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001628 }
1629 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001630
Martin Blais2856e5f2006-05-26 12:03:27 +00001631 /* Success */
1632 return 0;
1633}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001634
Martin Blais2856e5f2006-05-26 12:03:27 +00001635
1636PyDoc_STRVAR(s_pack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001637"S.pack(v1, v2, ...) -> string\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001638\n\
1639Return a string containing values v1, v2, ... packed according to this\n\
1640Struct's format. See struct.__doc__ for more on format strings.");
1641
1642static PyObject *
1643s_pack(PyObject *self, PyObject *args)
1644{
1645 PyStructObject *soself;
1646 PyObject *result;
1647
1648 /* Validate arguments. */
1649 soself = (PyStructObject *)self;
1650 assert(PyStruct_Check(self));
1651 assert(soself->s_codes != NULL);
Martin Blaisaf2ae722006-06-04 13:49:49 +00001652 if (PyTuple_GET_SIZE(args) != soself->s_len)
Martin Blais2856e5f2006-05-26 12:03:27 +00001653 {
1654 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001655 "pack requires exactly %zd arguments", soself->s_len);
Martin Blais2856e5f2006-05-26 12:03:27 +00001656 return NULL;
1657 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001658
Martin Blais2856e5f2006-05-26 12:03:27 +00001659 /* Allocate a new string */
1660 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1661 if (result == NULL)
1662 return NULL;
Tim Petersc2b550e2006-05-31 14:28:07 +00001663
Martin Blais2856e5f2006-05-26 12:03:27 +00001664 /* Call the guts */
1665 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1666 Py_DECREF(result);
1667 return NULL;
1668 }
1669
1670 return result;
1671}
1672
Martin Blaisaf2ae722006-06-04 13:49:49 +00001673PyDoc_STRVAR(s_pack_into__doc__,
1674"S.pack_into(buffer, offset, v1, v2, ...)\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001675\n\
Martin Blaisaf2ae722006-06-04 13:49:49 +00001676Pack the values v1, v2, ... according to this Struct's format, write \n\
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001677the packed bytes into the writable buffer buf starting at offset. Note\n\
1678that the offset is not an optional argument. See struct.__doc__ for \n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001679more on format strings.");
1680
1681static PyObject *
Martin Blaisaf2ae722006-06-04 13:49:49 +00001682s_pack_into(PyObject *self, PyObject *args)
Martin Blais2856e5f2006-05-26 12:03:27 +00001683{
1684 PyStructObject *soself;
1685 char *buffer;
1686 Py_ssize_t buffer_len, offset;
1687
1688 /* Validate arguments. +1 is for the first arg as buffer. */
1689 soself = (PyStructObject *)self;
1690 assert(PyStruct_Check(self));
1691 assert(soself->s_codes != NULL);
Martin Blaisaf2ae722006-06-04 13:49:49 +00001692 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Martin Blais2856e5f2006-05-26 12:03:27 +00001693 {
1694 PyErr_Format(StructError,
Martin Blaisaf2ae722006-06-04 13:49:49 +00001695 "pack_into requires exactly %zd arguments",
Martin Blais2856e5f2006-05-26 12:03:27 +00001696 (soself->s_len + 2));
1697 return NULL;
1698 }
1699
1700 /* Extract a writable memory buffer from the first argument */
Tim Petersc2b550e2006-05-31 14:28:07 +00001701 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1702 (void**)&buffer, &buffer_len) == -1 ) {
Martin Blais2856e5f2006-05-26 12:03:27 +00001703 return NULL;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001704 }
1705 assert( buffer_len >= 0 );
Martin Blais2856e5f2006-05-26 12:03:27 +00001706
1707 /* Extract the offset from the first argument */
Martin Blaisaf2ae722006-06-04 13:49:49 +00001708 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Martin Blais2856e5f2006-05-26 12:03:27 +00001709
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001710 /* Support negative offsets. */
Martin Blais2856e5f2006-05-26 12:03:27 +00001711 if (offset < 0)
1712 offset += buffer_len;
1713
1714 /* Check boundaries */
1715 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1716 PyErr_Format(StructError,
Martin Blaisaf2ae722006-06-04 13:49:49 +00001717 "pack_into requires a buffer of at least %zd bytes",
Martin Blais2856e5f2006-05-26 12:03:27 +00001718 soself->s_size);
1719 return NULL;
1720 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001721
Martin Blais2856e5f2006-05-26 12:03:27 +00001722 /* Call the guts */
1723 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1724 return NULL;
1725 }
1726
Georg Brandlc26025c2006-05-28 21:42:54 +00001727 Py_RETURN_NONE;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001728}
1729
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001730static PyObject *
1731s_get_format(PyStructObject *self, void *unused)
1732{
1733 Py_INCREF(self->s_format);
1734 return self->s_format;
1735}
1736
1737static PyObject *
1738s_get_size(PyStructObject *self, void *unused)
1739{
1740 return PyInt_FromSsize_t(self->s_size);
1741}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001742
1743/* List of functions */
1744
1745static struct PyMethodDef s_methods[] = {
Martin Blaisaf2ae722006-06-04 13:49:49 +00001746 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1747 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1748 {"unpack", s_unpack, METH_O, s_unpack__doc__},
Tim Peters5ec2e852006-06-04 15:49:07 +00001749 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS,
1750 s_unpack_from__doc__},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001751 {NULL, NULL} /* sentinel */
1752};
1753
1754PyDoc_STRVAR(s__doc__, "Compiled struct object");
1755
1756#define OFF(x) offsetof(PyStructObject, x)
1757
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001758static PyGetSetDef s_getsetlist[] = {
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001759 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1760 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001761 {NULL} /* sentinel */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001762};
1763
Bob Ippolito232f3c92006-05-23 19:12:41 +00001764static
1765PyTypeObject PyStructType = {
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001766 PyObject_HEAD_INIT(NULL)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001767 0,
1768 "Struct",
1769 sizeof(PyStructObject),
1770 0,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001771 (destructor)s_dealloc, /* tp_dealloc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001772 0, /* tp_print */
1773 0, /* tp_getattr */
1774 0, /* tp_setattr */
1775 0, /* tp_compare */
1776 0, /* tp_repr */
1777 0, /* tp_as_number */
1778 0, /* tp_as_sequence */
1779 0, /* tp_as_mapping */
1780 0, /* tp_hash */
1781 0, /* tp_call */
1782 0, /* tp_str */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001783 PyObject_GenericGetAttr, /* tp_getattro */
1784 PyObject_GenericSetAttr, /* tp_setattro */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001785 0, /* tp_as_buffer */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001786 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1787 s__doc__, /* tp_doc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001788 0, /* tp_traverse */
1789 0, /* tp_clear */
1790 0, /* tp_richcompare */
1791 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1792 0, /* tp_iter */
1793 0, /* tp_iternext */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001794 s_methods, /* tp_methods */
1795 NULL, /* tp_members */
1796 s_getsetlist, /* tp_getset */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001797 0, /* tp_base */
1798 0, /* tp_dict */
1799 0, /* tp_descr_get */
1800 0, /* tp_descr_set */
1801 0, /* tp_dictoffset */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001802 s_init, /* tp_init */
1803 PyType_GenericAlloc,/* tp_alloc */
1804 s_new, /* tp_new */
1805 PyObject_Del, /* tp_free */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001806};
1807
1808/* Module initialization */
1809
1810PyMODINIT_FUNC
1811init_struct(void)
1812{
1813 PyObject *m = Py_InitModule("_struct", NULL);
1814 if (m == NULL)
1815 return;
1816
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001817 PyStructType.ob_type = &PyType_Type;
1818 if (PyType_Ready(&PyStructType) < 0)
1819 return;
1820
Bob Ippolito4182a752006-05-30 17:37:54 +00001821#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +00001822 if (pyint_zero == NULL) {
1823 pyint_zero = PyInt_FromLong(0);
1824 if (pyint_zero == NULL)
1825 return;
1826 }
1827 if (pylong_ulong_mask == NULL) {
1828#if (SIZEOF_LONG == 4)
1829 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1830#else
1831 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1832#endif
1833 if (pylong_ulong_mask == NULL)
1834 return;
1835 }
1836
Tim Petersc2b550e2006-05-31 14:28:07 +00001837#else
Bob Ippolito4182a752006-05-30 17:37:54 +00001838 /* This speed trick can't be used until overflow masking goes away, because
1839 native endian always raises exceptions instead of overflow masking. */
Tim Petersc2b550e2006-05-31 14:28:07 +00001840
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001841 /* Check endian and swap in faster functions */
1842 {
1843 int one = 1;
1844 formatdef *native = native_table;
1845 formatdef *other, *ptr;
1846 if ((int)*(unsigned char*)&one)
1847 other = lilendian_table;
1848 else
1849 other = bigendian_table;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001850 /* Scan through the native table, find a matching
1851 entry in the endian table and swap in the
1852 native implementations whenever possible
1853 (64-bit platforms may not have "standard" sizes) */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001854 while (native->format != '\0' && other->format != '\0') {
1855 ptr = other;
1856 while (ptr->format != '\0') {
1857 if (ptr->format == native->format) {
Bob Ippolito964e02a2006-05-25 21:09:45 +00001858 /* Match faster when formats are
1859 listed in the same order */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001860 if (ptr == other)
1861 other++;
Tim Petersc2b550e2006-05-31 14:28:07 +00001862 /* Only use the trick if the
Bob Ippolito964e02a2006-05-25 21:09:45 +00001863 size matches */
1864 if (ptr->size != native->size)
1865 break;
1866 /* Skip float and double, could be
1867 "unknown" float format */
1868 if (ptr->format == 'd' || ptr->format == 'f')
1869 break;
1870 ptr->pack = native->pack;
1871 ptr->unpack = native->unpack;
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001872 break;
1873 }
1874 ptr++;
1875 }
1876 native++;
1877 }
1878 }
Bob Ippolito2fd39772006-05-29 22:55:48 +00001879#endif
Tim Petersc2b550e2006-05-31 14:28:07 +00001880
Bob Ippolito232f3c92006-05-23 19:12:41 +00001881 /* Add some symbolic constants to the module */
1882 if (StructError == NULL) {
1883 StructError = PyErr_NewException("struct.error", NULL, NULL);
1884 if (StructError == NULL)
1885 return;
1886 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001887
Bob Ippolito232f3c92006-05-23 19:12:41 +00001888 Py_INCREF(StructError);
1889 PyModule_AddObject(m, "error", StructError);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001890
Bob Ippolito232f3c92006-05-23 19:12:41 +00001891 Py_INCREF((PyObject*)&PyStructType);
1892 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Tim Petersc2b550e2006-05-31 14:28:07 +00001893
Bob Ippolito2fd39772006-05-29 22:55:48 +00001894 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
Bob Ippolito4182a752006-05-30 17:37:54 +00001895#ifdef PY_STRUCT_OVERFLOW_MASKING
1896 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
Bob Ippolito2fd39772006-05-29 22:55:48 +00001897#endif
Bob Ippolitoe6c9f982006-08-04 23:59:21 +00001898#ifdef PY_STRUCT_FLOAT_COERCE
1899 PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
1900#endif
1901
Bob Ippolito232f3c92006-05-23 19:12:41 +00001902}