blob: 22d0e030cfcfe828847d3af2dff86dd37b5c5f51 [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)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000823 x |= -(x & (1L << ((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)
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001041 x |= -(x & (1L << ((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
1339 self->s_size = size;
1340 self->s_len = len;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001341 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
Bob Ippolito232f3c92006-05-23 19:12:41 +00001342 if (codes == NULL) {
1343 PyErr_NoMemory();
1344 return -1;
1345 }
1346 self->s_codes = codes;
Tim Petersc2b550e2006-05-31 14:28:07 +00001347
Bob Ippolito232f3c92006-05-23 19:12:41 +00001348 s = fmt;
1349 size = 0;
1350 while ((c = *s++) != '\0') {
1351 if (isspace(Py_CHARMASK(c)))
1352 continue;
1353 if ('0' <= c && c <= '9') {
1354 num = c - '0';
1355 while ('0' <= (c = *s++) && c <= '9')
1356 num = num*10 + (c - '0');
1357 if (c == '\0')
1358 break;
1359 }
1360 else
1361 num = 1;
1362
1363 e = getentry(c, f);
Tim Petersc2b550e2006-05-31 14:28:07 +00001364
Bob Ippolito232f3c92006-05-23 19:12:41 +00001365 size = align(size, c, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001366 if (c == 's' || c == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001367 codes->offset = size;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001368 codes->size = num;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001369 codes->fmtdef = e;
1370 codes++;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001371 size += num;
1372 } else if (c == 'x') {
1373 size += num;
1374 } else {
1375 while (--num >= 0) {
1376 codes->offset = size;
1377 codes->size = e->size;
1378 codes->fmtdef = e;
1379 codes++;
1380 size += e->size;
1381 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001382 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001383 }
1384 codes->fmtdef = NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001385 codes->offset = size;
1386 codes->size = 0;
Tim Petersc2b550e2006-05-31 14:28:07 +00001387
Bob Ippolito232f3c92006-05-23 19:12:41 +00001388 return 0;
1389}
1390
1391static PyObject *
1392s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1393{
1394 PyObject *self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001395
1396 assert(type != NULL && type->tp_alloc != NULL);
1397
1398 self = type->tp_alloc(type, 0);
1399 if (self != NULL) {
1400 PyStructObject *s = (PyStructObject*)self;
1401 Py_INCREF(Py_None);
1402 s->s_format = Py_None;
1403 s->s_codes = NULL;
1404 s->s_size = -1;
1405 s->s_len = -1;
1406 }
1407 return self;
1408}
1409
1410static int
1411s_init(PyObject *self, PyObject *args, PyObject *kwds)
1412{
1413 PyStructObject *soself = (PyStructObject *)self;
1414 PyObject *o_format = NULL;
1415 int ret = 0;
1416 static char *kwlist[] = {"format", 0};
1417
1418 assert(PyStruct_Check(self));
1419
1420 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1421 &o_format))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001422 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001423
1424 Py_INCREF(o_format);
1425 Py_XDECREF(soself->s_format);
1426 soself->s_format = o_format;
Tim Petersc2b550e2006-05-31 14:28:07 +00001427
Bob Ippolito232f3c92006-05-23 19:12:41 +00001428 ret = prepare_s(soself);
1429 return ret;
1430}
1431
1432static void
1433s_dealloc(PyStructObject *s)
1434{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001435 if (s->weakreflist != NULL)
1436 PyObject_ClearWeakRefs((PyObject *)s);
1437 if (s->s_codes != NULL) {
1438 PyMem_FREE(s->s_codes);
1439 }
1440 Py_XDECREF(s->s_format);
1441 s->ob_type->tp_free((PyObject *)s);
1442}
1443
Bob Ippolitoeb621272006-05-24 15:32:06 +00001444static PyObject *
1445s_unpack_internal(PyStructObject *soself, char *startfrom) {
1446 formatcode *code;
1447 Py_ssize_t i = 0;
1448 PyObject *result = PyTuple_New(soself->s_len);
1449 if (result == NULL)
1450 return NULL;
1451
1452 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1453 PyObject *v;
1454 const formatdef *e = code->fmtdef;
1455 const char *res = startfrom + code->offset;
1456 if (e->format == 's') {
1457 v = PyString_FromStringAndSize(res, code->size);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001458 } else if (e->format == 'p') {
1459 Py_ssize_t n = *(unsigned char*)res;
1460 if (n >= code->size)
1461 n = code->size - 1;
1462 v = PyString_FromStringAndSize(res + 1, n);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001463 } else {
1464 v = e->unpack(res, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001465 }
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001466 if (v == NULL)
1467 goto fail;
1468 PyTuple_SET_ITEM(result, i++, v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001469 }
1470
1471 return result;
1472fail:
1473 Py_DECREF(result);
1474 return NULL;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001475}
Bob Ippolitoeb621272006-05-24 15:32:06 +00001476
1477
Bob Ippolito232f3c92006-05-23 19:12:41 +00001478PyDoc_STRVAR(s_unpack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001479"S.unpack(str) -> (v1, v2, ...)\n\
Bob Ippolito232f3c92006-05-23 19:12:41 +00001480\n\
1481Return tuple containing values unpacked according to this Struct's format.\n\
1482Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1483strings.");
1484
1485static PyObject *
1486s_unpack(PyObject *self, PyObject *inputstr)
1487{
Bob Ippolitoeb621272006-05-24 15:32:06 +00001488 PyStructObject *soself = (PyStructObject *)self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001489 assert(PyStruct_Check(self));
Tim Petersc2b550e2006-05-31 14:28:07 +00001490 assert(soself->s_codes != NULL);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001491 if (inputstr == NULL || !PyString_Check(inputstr) ||
Bob Ippolitoeb621272006-05-24 15:32:06 +00001492 PyString_GET_SIZE(inputstr) != soself->s_size) {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001493 PyErr_Format(StructError,
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001494 "unpack requires a string argument of length %zd",
1495 soself->s_size);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001496 return NULL;
1497 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001498 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1499}
1500
1501PyDoc_STRVAR(s_unpack_from__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001502"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
Bob Ippolitoeb621272006-05-24 15:32:06 +00001503\n\
1504Return tuple containing values unpacked according to this Struct's format.\n\
1505Unlike unpack, unpack_from can unpack values from any object supporting\n\
1506the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1507See struct.__doc__ for more on format strings.");
1508
1509static PyObject *
1510s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1511{
1512 static char *kwlist[] = {"buffer", "offset", 0};
1513#if (PY_VERSION_HEX < 0x02050000)
1514 static char *fmt = "z#|i:unpack_from";
1515#else
1516 static char *fmt = "z#|n:unpack_from";
1517#endif
1518 Py_ssize_t buffer_len = 0, offset = 0;
1519 char *buffer = NULL;
1520 PyStructObject *soself = (PyStructObject *)self;
1521 assert(PyStruct_Check(self));
1522 assert(soself->s_codes != NULL);
1523
1524 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1525 &buffer, &buffer_len, &offset))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001526 return NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001527
1528 if (buffer == NULL) {
1529 PyErr_Format(StructError,
1530 "unpack_from requires a buffer argument");
Bob Ippolito232f3c92006-05-23 19:12:41 +00001531 return NULL;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001532 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001533
Bob Ippolitoeb621272006-05-24 15:32:06 +00001534 if (offset < 0)
1535 offset += buffer_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001536
Bob Ippolitoeb621272006-05-24 15:32:06 +00001537 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1538 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001539 "unpack_from requires a buffer of at least %zd bytes",
Bob Ippolitoeb621272006-05-24 15:32:06 +00001540 soself->s_size);
1541 return NULL;
1542 }
1543 return s_unpack_internal(soself, buffer + offset);
1544}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001545
Bob Ippolito232f3c92006-05-23 19:12:41 +00001546
Martin Blais2856e5f2006-05-26 12:03:27 +00001547/*
1548 * Guts of the pack function.
1549 *
1550 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1551 * argument for where to start processing the arguments for packing, and a
1552 * character buffer for writing the packed string. The caller must insure
1553 * that the buffer may contain the required length for packing the arguments.
1554 * 0 is returned on success, 1 is returned if there is an error.
1555 *
1556 */
1557static int
1558s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001559{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001560 formatcode *code;
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001561 /* XXX(nnorwitz): why does i need to be a local? can we use
1562 the offset parameter or do we need the wider width? */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001563 Py_ssize_t i;
Martin Blais2856e5f2006-05-26 12:03:27 +00001564
1565 memset(buf, '\0', soself->s_size);
1566 i = offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001567 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1568 Py_ssize_t n;
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001569 PyObject *v = PyTuple_GET_ITEM(args, i++);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001570 const formatdef *e = code->fmtdef;
Martin Blais2856e5f2006-05-26 12:03:27 +00001571 char *res = buf + code->offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001572 if (e->format == 's') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001573 if (!PyString_Check(v)) {
1574 PyErr_SetString(StructError,
1575 "argument for 's' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001576 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001577 }
1578 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001579 if (n > code->size)
1580 n = code->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001581 if (n > 0)
1582 memcpy(res, PyString_AS_STRING(v), n);
1583 } else if (e->format == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001584 if (!PyString_Check(v)) {
1585 PyErr_SetString(StructError,
1586 "argument for 'p' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001587 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001588 }
1589 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001590 if (n > (code->size - 1))
1591 n = code->size - 1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001592 if (n > 0)
1593 memcpy(res + 1, PyString_AS_STRING(v), n);
1594 if (n > 255)
1595 n = 255;
1596 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1597 } else {
Bob Ippolito2fd39772006-05-29 22:55:48 +00001598 if (e->pack(res, v, e) < 0) {
1599 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1600 PyErr_SetString(StructError,
1601 "long too large to convert to int");
Martin Blais2856e5f2006-05-26 12:03:27 +00001602 return -1;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001603 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001604 }
1605 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001606
Martin Blais2856e5f2006-05-26 12:03:27 +00001607 /* Success */
1608 return 0;
1609}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001610
Martin Blais2856e5f2006-05-26 12:03:27 +00001611
1612PyDoc_STRVAR(s_pack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001613"S.pack(v1, v2, ...) -> string\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001614\n\
1615Return a string containing values v1, v2, ... packed according to this\n\
1616Struct's format. See struct.__doc__ for more on format strings.");
1617
1618static PyObject *
1619s_pack(PyObject *self, PyObject *args)
1620{
1621 PyStructObject *soself;
1622 PyObject *result;
1623
1624 /* Validate arguments. */
1625 soself = (PyStructObject *)self;
1626 assert(PyStruct_Check(self));
1627 assert(soself->s_codes != NULL);
Martin Blaisaf2ae722006-06-04 13:49:49 +00001628 if (PyTuple_GET_SIZE(args) != soself->s_len)
Martin Blais2856e5f2006-05-26 12:03:27 +00001629 {
1630 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001631 "pack requires exactly %zd arguments", soself->s_len);
Martin Blais2856e5f2006-05-26 12:03:27 +00001632 return NULL;
1633 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001634
Martin Blais2856e5f2006-05-26 12:03:27 +00001635 /* Allocate a new string */
1636 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1637 if (result == NULL)
1638 return NULL;
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, 0, PyString_AS_STRING(result)) != 0 ) {
1642 Py_DECREF(result);
1643 return NULL;
1644 }
1645
1646 return result;
1647}
1648
Martin Blaisaf2ae722006-06-04 13:49:49 +00001649PyDoc_STRVAR(s_pack_into__doc__,
1650"S.pack_into(buffer, offset, v1, v2, ...)\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001651\n\
Martin Blaisaf2ae722006-06-04 13:49:49 +00001652Pack the values v1, v2, ... according to this Struct's format, write \n\
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001653the packed bytes into the writable buffer buf starting at offset. Note\n\
1654that the offset is not an optional argument. See struct.__doc__ for \n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001655more on format strings.");
1656
1657static PyObject *
Martin Blaisaf2ae722006-06-04 13:49:49 +00001658s_pack_into(PyObject *self, PyObject *args)
Martin Blais2856e5f2006-05-26 12:03:27 +00001659{
1660 PyStructObject *soself;
1661 char *buffer;
1662 Py_ssize_t buffer_len, offset;
1663
1664 /* Validate arguments. +1 is for the first arg as buffer. */
1665 soself = (PyStructObject *)self;
1666 assert(PyStruct_Check(self));
1667 assert(soself->s_codes != NULL);
Martin Blaisaf2ae722006-06-04 13:49:49 +00001668 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Martin Blais2856e5f2006-05-26 12:03:27 +00001669 {
1670 PyErr_Format(StructError,
Martin Blaisaf2ae722006-06-04 13:49:49 +00001671 "pack_into requires exactly %zd arguments",
Martin Blais2856e5f2006-05-26 12:03:27 +00001672 (soself->s_len + 2));
1673 return NULL;
1674 }
1675
1676 /* Extract a writable memory buffer from the first argument */
Tim Petersc2b550e2006-05-31 14:28:07 +00001677 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1678 (void**)&buffer, &buffer_len) == -1 ) {
Martin Blais2856e5f2006-05-26 12:03:27 +00001679 return NULL;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001680 }
1681 assert( buffer_len >= 0 );
Martin Blais2856e5f2006-05-26 12:03:27 +00001682
1683 /* Extract the offset from the first argument */
Martin Blaisaf2ae722006-06-04 13:49:49 +00001684 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Martin Blais2856e5f2006-05-26 12:03:27 +00001685
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001686 /* Support negative offsets. */
Martin Blais2856e5f2006-05-26 12:03:27 +00001687 if (offset < 0)
1688 offset += buffer_len;
1689
1690 /* Check boundaries */
1691 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1692 PyErr_Format(StructError,
Martin Blaisaf2ae722006-06-04 13:49:49 +00001693 "pack_into requires a buffer of at least %zd bytes",
Martin Blais2856e5f2006-05-26 12:03:27 +00001694 soself->s_size);
1695 return NULL;
1696 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001697
Martin Blais2856e5f2006-05-26 12:03:27 +00001698 /* Call the guts */
1699 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1700 return NULL;
1701 }
1702
Georg Brandlc26025c2006-05-28 21:42:54 +00001703 Py_RETURN_NONE;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001704}
1705
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001706static PyObject *
1707s_get_format(PyStructObject *self, void *unused)
1708{
1709 Py_INCREF(self->s_format);
1710 return self->s_format;
1711}
1712
1713static PyObject *
1714s_get_size(PyStructObject *self, void *unused)
1715{
1716 return PyInt_FromSsize_t(self->s_size);
1717}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001718
1719/* List of functions */
1720
1721static struct PyMethodDef s_methods[] = {
Martin Blaisaf2ae722006-06-04 13:49:49 +00001722 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1723 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1724 {"unpack", s_unpack, METH_O, s_unpack__doc__},
Tim Peters5ec2e852006-06-04 15:49:07 +00001725 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS,
1726 s_unpack_from__doc__},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001727 {NULL, NULL} /* sentinel */
1728};
1729
1730PyDoc_STRVAR(s__doc__, "Compiled struct object");
1731
1732#define OFF(x) offsetof(PyStructObject, x)
1733
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001734static PyGetSetDef s_getsetlist[] = {
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001735 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1736 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001737 {NULL} /* sentinel */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001738};
1739
Bob Ippolito232f3c92006-05-23 19:12:41 +00001740static
1741PyTypeObject PyStructType = {
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001742 PyObject_HEAD_INIT(NULL)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001743 0,
1744 "Struct",
1745 sizeof(PyStructObject),
1746 0,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001747 (destructor)s_dealloc, /* tp_dealloc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001748 0, /* tp_print */
1749 0, /* tp_getattr */
1750 0, /* tp_setattr */
1751 0, /* tp_compare */
1752 0, /* tp_repr */
1753 0, /* tp_as_number */
1754 0, /* tp_as_sequence */
1755 0, /* tp_as_mapping */
1756 0, /* tp_hash */
1757 0, /* tp_call */
1758 0, /* tp_str */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001759 PyObject_GenericGetAttr, /* tp_getattro */
1760 PyObject_GenericSetAttr, /* tp_setattro */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001761 0, /* tp_as_buffer */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001762 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1763 s__doc__, /* tp_doc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001764 0, /* tp_traverse */
1765 0, /* tp_clear */
1766 0, /* tp_richcompare */
1767 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1768 0, /* tp_iter */
1769 0, /* tp_iternext */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001770 s_methods, /* tp_methods */
1771 NULL, /* tp_members */
1772 s_getsetlist, /* tp_getset */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001773 0, /* tp_base */
1774 0, /* tp_dict */
1775 0, /* tp_descr_get */
1776 0, /* tp_descr_set */
1777 0, /* tp_dictoffset */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001778 s_init, /* tp_init */
1779 PyType_GenericAlloc,/* tp_alloc */
1780 s_new, /* tp_new */
1781 PyObject_Del, /* tp_free */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001782};
1783
1784/* Module initialization */
1785
1786PyMODINIT_FUNC
1787init_struct(void)
1788{
1789 PyObject *m = Py_InitModule("_struct", NULL);
1790 if (m == NULL)
1791 return;
1792
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001793 PyStructType.ob_type = &PyType_Type;
1794 if (PyType_Ready(&PyStructType) < 0)
1795 return;
1796
Bob Ippolito4182a752006-05-30 17:37:54 +00001797#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +00001798 if (pyint_zero == NULL) {
1799 pyint_zero = PyInt_FromLong(0);
1800 if (pyint_zero == NULL)
1801 return;
1802 }
1803 if (pylong_ulong_mask == NULL) {
1804#if (SIZEOF_LONG == 4)
1805 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1806#else
1807 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1808#endif
1809 if (pylong_ulong_mask == NULL)
1810 return;
1811 }
1812
Tim Petersc2b550e2006-05-31 14:28:07 +00001813#else
Bob Ippolito4182a752006-05-30 17:37:54 +00001814 /* This speed trick can't be used until overflow masking goes away, because
1815 native endian always raises exceptions instead of overflow masking. */
Tim Petersc2b550e2006-05-31 14:28:07 +00001816
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001817 /* Check endian and swap in faster functions */
1818 {
1819 int one = 1;
1820 formatdef *native = native_table;
1821 formatdef *other, *ptr;
1822 if ((int)*(unsigned char*)&one)
1823 other = lilendian_table;
1824 else
1825 other = bigendian_table;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001826 /* Scan through the native table, find a matching
1827 entry in the endian table and swap in the
1828 native implementations whenever possible
1829 (64-bit platforms may not have "standard" sizes) */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001830 while (native->format != '\0' && other->format != '\0') {
1831 ptr = other;
1832 while (ptr->format != '\0') {
1833 if (ptr->format == native->format) {
Bob Ippolito964e02a2006-05-25 21:09:45 +00001834 /* Match faster when formats are
1835 listed in the same order */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001836 if (ptr == other)
1837 other++;
Tim Petersc2b550e2006-05-31 14:28:07 +00001838 /* Only use the trick if the
Bob Ippolito964e02a2006-05-25 21:09:45 +00001839 size matches */
1840 if (ptr->size != native->size)
1841 break;
1842 /* Skip float and double, could be
1843 "unknown" float format */
1844 if (ptr->format == 'd' || ptr->format == 'f')
1845 break;
1846 ptr->pack = native->pack;
1847 ptr->unpack = native->unpack;
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001848 break;
1849 }
1850 ptr++;
1851 }
1852 native++;
1853 }
1854 }
Bob Ippolito2fd39772006-05-29 22:55:48 +00001855#endif
Tim Petersc2b550e2006-05-31 14:28:07 +00001856
Bob Ippolito232f3c92006-05-23 19:12:41 +00001857 /* Add some symbolic constants to the module */
1858 if (StructError == NULL) {
1859 StructError = PyErr_NewException("struct.error", NULL, NULL);
1860 if (StructError == NULL)
1861 return;
1862 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001863
Bob Ippolito232f3c92006-05-23 19:12:41 +00001864 Py_INCREF(StructError);
1865 PyModule_AddObject(m, "error", StructError);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001866
Bob Ippolito232f3c92006-05-23 19:12:41 +00001867 Py_INCREF((PyObject*)&PyStructType);
1868 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Tim Petersc2b550e2006-05-31 14:28:07 +00001869
Bob Ippolito2fd39772006-05-29 22:55:48 +00001870 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
Bob Ippolito4182a752006-05-30 17:37:54 +00001871#ifdef PY_STRUCT_OVERFLOW_MASKING
1872 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
Bob Ippolito2fd39772006-05-29 22:55:48 +00001873#endif
Bob Ippolitoe6c9f982006-08-04 23:59:21 +00001874#ifdef PY_STRUCT_FLOAT_COERCE
1875 PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
1876#endif
1877
Bob Ippolito232f3c92006-05-23 19:12:41 +00001878}