blob: 026fec1c1bfe9d817482dfde9d6e9b3c986a51b4 [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 Ippolito232f3c92006-05-23 19:12:41 +000020/* The translation function for each format character is table driven */
Bob Ippolito232f3c92006-05-23 19:12:41 +000021typedef struct _formatdef {
22 char format;
Bob Ippolitoaa70a172006-05-26 20:25:23 +000023 Py_ssize_t size;
24 Py_ssize_t alignment;
Bob Ippolito232f3c92006-05-23 19:12:41 +000025 PyObject* (*unpack)(const char *,
26 const struct _formatdef *);
27 int (*pack)(char *, PyObject *,
28 const struct _formatdef *);
29} formatdef;
30
31typedef struct _formatcode {
32 const struct _formatdef *fmtdef;
Bob Ippolitoaa70a172006-05-26 20:25:23 +000033 Py_ssize_t offset;
34 Py_ssize_t size;
Bob Ippolito232f3c92006-05-23 19:12:41 +000035} formatcode;
36
37/* Struct object interface */
38
39typedef struct {
40 PyObject_HEAD
Bob Ippolitoaa70a172006-05-26 20:25:23 +000041 Py_ssize_t s_size;
42 Py_ssize_t s_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +000043 formatcode *s_codes;
44 PyObject *s_format;
45 PyObject *weakreflist; /* List of weak references */
46} PyStructObject;
47
Bob Ippolitoeb621272006-05-24 15:32:06 +000048
Bob Ippolito07c023b2006-05-23 19:32:25 +000049#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
50#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
Bob Ippolito232f3c92006-05-23 19:12:41 +000051
52
53/* Exception */
54
55static PyObject *StructError;
56
57
58/* Define various structs to figure out the alignments of types */
59
60
61typedef struct { char c; short x; } st_short;
62typedef struct { char c; int x; } st_int;
63typedef struct { char c; long x; } st_long;
64typedef struct { char c; float x; } st_float;
65typedef struct { char c; double x; } st_double;
66typedef struct { char c; void *x; } st_void_p;
67
68#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
69#define INT_ALIGN (sizeof(st_int) - sizeof(int))
70#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
71#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
72#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
73#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
74
75/* We can't support q and Q in native mode unless the compiler does;
76 in std mode, they're 8 bytes on all platforms. */
77#ifdef HAVE_LONG_LONG
78typedef struct { char c; PY_LONG_LONG x; } s_long_long;
79#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
80#endif
81
82#define STRINGIFY(x) #x
83
84#ifdef __powerc
85#pragma options align=reset
86#endif
87
88/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
89
90static PyObject *
91get_pylong(PyObject *v)
92{
93 PyNumberMethods *m;
94
95 assert(v != NULL);
96 if (PyInt_Check(v))
97 return PyLong_FromLong(PyInt_AS_LONG(v));
98 if (PyLong_Check(v)) {
99 Py_INCREF(v);
100 return v;
101 }
102 m = v->ob_type->tp_as_number;
103 if (m != NULL && m->nb_long != NULL) {
104 v = m->nb_long(v);
105 if (v == NULL)
106 return NULL;
107 if (PyLong_Check(v))
108 return v;
109 Py_DECREF(v);
110 }
111 PyErr_SetString(StructError,
112 "cannot convert argument to long");
113 return NULL;
114}
115
116/* Helper routine to get a Python integer and raise the appropriate error
117 if it isn't one */
118
119static int
120get_long(PyObject *v, long *p)
121{
122 long x = PyInt_AsLong(v);
123 if (x == -1 && PyErr_Occurred()) {
124 if (PyErr_ExceptionMatches(PyExc_TypeError))
125 PyErr_SetString(StructError,
126 "required argument is not an integer");
127 return -1;
128 }
129 *p = x;
130 return 0;
131}
132
133
134/* Same, but handling unsigned long */
135
136static int
137get_ulong(PyObject *v, unsigned long *p)
138{
139 if (PyLong_Check(v)) {
140 unsigned long x = PyLong_AsUnsignedLong(v);
141 if (x == (unsigned long)(-1) && PyErr_Occurred())
142 return -1;
143 *p = x;
144 return 0;
145 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000146 if (get_long(v, (long *)p) < 0)
147 return -1;
148 if (((long)*p) < 0) {
149 PyErr_SetString(StructError,
150 "unsigned argument is < 0");
151 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000152 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000153 return 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000154}
155
156#ifdef HAVE_LONG_LONG
157
158/* Same, but handling native long long. */
159
160static int
161get_longlong(PyObject *v, PY_LONG_LONG *p)
162{
163 PY_LONG_LONG x;
164
165 v = get_pylong(v);
166 if (v == NULL)
167 return -1;
168 assert(PyLong_Check(v));
169 x = PyLong_AsLongLong(v);
170 Py_DECREF(v);
171 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
172 return -1;
173 *p = x;
174 return 0;
175}
176
177/* Same, but handling native unsigned long long. */
178
179static int
180get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
181{
182 unsigned PY_LONG_LONG x;
183
184 v = get_pylong(v);
185 if (v == NULL)
186 return -1;
187 assert(PyLong_Check(v));
188 x = PyLong_AsUnsignedLongLong(v);
189 Py_DECREF(v);
190 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
191 return -1;
192 *p = x;
193 return 0;
194}
195
196#endif
197
198/* Floating point helpers */
199
200static PyObject *
201unpack_float(const char *p, /* start of 4-byte string */
202 int le) /* true for little-endian, false for big-endian */
203{
204 double x;
205
206 x = _PyFloat_Unpack4((unsigned char *)p, le);
207 if (x == -1.0 && PyErr_Occurred())
208 return NULL;
209 return PyFloat_FromDouble(x);
210}
211
212static PyObject *
213unpack_double(const char *p, /* start of 8-byte string */
214 int le) /* true for little-endian, false for big-endian */
215{
216 double x;
217
218 x = _PyFloat_Unpack8((unsigned char *)p, le);
219 if (x == -1.0 && PyErr_Occurred())
220 return NULL;
221 return PyFloat_FromDouble(x);
222}
223
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000224/* Helper to format the range error exceptions */
225static int
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000226_range_error(char format, Py_ssize_t size, int is_unsigned)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000227{
228 if (is_unsigned == 0) {
229 long smallest = 0, largest = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000230 Py_ssize_t i = size * 8;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000231 while (--i > 0) {
232 smallest = (smallest * 2) - 1;
233 largest = (largest * 2) + 1;
234 }
235 PyErr_Format(StructError,
236 "'%c' format requires %ld <= number <= %ld",
237 format,
238 smallest,
239 largest);
240 } else {
241 unsigned long largest = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000242 Py_ssize_t i = size * 8;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000243 while (--i >= 0)
244 largest = (largest * 2) + 1;
245 PyErr_Format(StructError,
246 "'%c' format requires 0 <= number <= %lu",
247 format,
248 largest);
249 }
250 return -1;
251}
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000252
253
Bob Ippolito232f3c92006-05-23 19:12:41 +0000254
255/* A large number of small routines follow, with names of the form
256
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000257 [bln][up]_TYPE
Bob Ippolito232f3c92006-05-23 19:12:41 +0000258
259 [bln] distiguishes among big-endian, little-endian and native.
260 [pu] distiguishes between pack (to struct) and unpack (from struct).
261 TYPE is one of char, byte, ubyte, etc.
262*/
263
264/* Native mode routines. ****************************************************/
265/* NOTE:
266 In all n[up]_<type> routines handling types larger than 1 byte, there is
267 *no* guarantee that the p pointer is properly aligned for each type,
268 therefore memcpy is called. An intermediate variable is used to
269 compensate for big-endian architectures.
270 Normally both the intermediate variable and the memcpy call will be
271 skipped by C optimisation in little-endian architectures (gcc >= 2.91
272 does this). */
273
274static PyObject *
275nu_char(const char *p, const formatdef *f)
276{
277 return PyString_FromStringAndSize(p, 1);
278}
279
280static PyObject *
281nu_byte(const char *p, const formatdef *f)
282{
283 return PyInt_FromLong((long) *(signed char *)p);
284}
285
286static PyObject *
287nu_ubyte(const char *p, const formatdef *f)
288{
289 return PyInt_FromLong((long) *(unsigned char *)p);
290}
291
292static PyObject *
293nu_short(const char *p, const formatdef *f)
294{
295 short x;
296 memcpy((char *)&x, p, sizeof x);
297 return PyInt_FromLong((long)x);
298}
299
300static PyObject *
301nu_ushort(const char *p, const formatdef *f)
302{
303 unsigned short x;
304 memcpy((char *)&x, p, sizeof x);
305 return PyInt_FromLong((long)x);
306}
307
308static PyObject *
309nu_int(const char *p, const formatdef *f)
310{
311 int x;
312 memcpy((char *)&x, p, sizeof x);
313 return PyInt_FromLong((long)x);
314}
315
316static PyObject *
317nu_uint(const char *p, const formatdef *f)
318{
319 unsigned int x;
320 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000321 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000322 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000323 return PyLong_FromUnsignedLong((unsigned long)x);
324}
325
326static PyObject *
327nu_long(const char *p, const formatdef *f)
328{
329 long x;
330 memcpy((char *)&x, p, sizeof x);
331 return PyInt_FromLong(x);
332}
333
334static PyObject *
335nu_ulong(const char *p, const formatdef *f)
336{
337 unsigned long x;
338 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000339 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000340 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000341 return PyLong_FromUnsignedLong(x);
342}
343
344/* Native mode doesn't support q or Q unless the platform C supports
345 long long (or, on Windows, __int64). */
346
347#ifdef HAVE_LONG_LONG
348
349static PyObject *
350nu_longlong(const char *p, const formatdef *f)
351{
352 PY_LONG_LONG x;
353 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000354 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000355 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000356 return PyLong_FromLongLong(x);
357}
358
359static PyObject *
360nu_ulonglong(const char *p, const formatdef *f)
361{
362 unsigned PY_LONG_LONG x;
363 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000364 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000365 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000366 return PyLong_FromUnsignedLongLong(x);
367}
368
369#endif
370
371static PyObject *
372nu_float(const char *p, const formatdef *f)
373{
374 float x;
375 memcpy((char *)&x, p, sizeof x);
376 return PyFloat_FromDouble((double)x);
377}
378
379static PyObject *
380nu_double(const char *p, const formatdef *f)
381{
382 double x;
383 memcpy((char *)&x, p, sizeof x);
384 return PyFloat_FromDouble(x);
385}
386
387static PyObject *
388nu_void_p(const char *p, const formatdef *f)
389{
390 void *x;
391 memcpy((char *)&x, p, sizeof x);
392 return PyLong_FromVoidPtr(x);
393}
394
395static int
396np_byte(char *p, PyObject *v, const formatdef *f)
397{
398 long x;
399 if (get_long(v, &x) < 0)
400 return -1;
401 if (x < -128 || x > 127){
402 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000403 "byte format requires -128 <= number <= 127");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000404 return -1;
405 }
406 *p = (char)x;
407 return 0;
408}
409
410static int
411np_ubyte(char *p, PyObject *v, const formatdef *f)
412{
413 long x;
414 if (get_long(v, &x) < 0)
415 return -1;
416 if (x < 0 || x > 255){
417 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000418 "ubyte format requires 0 <= number <= 255");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000419 return -1;
420 }
421 *p = (char)x;
422 return 0;
423}
424
425static int
426np_char(char *p, PyObject *v, const formatdef *f)
427{
428 if (!PyString_Check(v) || PyString_Size(v) != 1) {
429 PyErr_SetString(StructError,
430 "char format require string of length 1");
431 return -1;
432 }
433 *p = *PyString_AsString(v);
434 return 0;
435}
436
437static int
438np_short(char *p, PyObject *v, const formatdef *f)
439{
440 long x;
441 short y;
442 if (get_long(v, &x) < 0)
443 return -1;
444 if (x < SHRT_MIN || x > SHRT_MAX){
445 PyErr_SetString(StructError,
446 "short format requires " STRINGIFY(SHRT_MIN)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000447 " <= number <= " STRINGIFY(SHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000448 return -1;
449 }
450 y = (short)x;
451 memcpy(p, (char *)&y, sizeof y);
452 return 0;
453}
454
455static int
456np_ushort(char *p, PyObject *v, const formatdef *f)
457{
458 long x;
459 unsigned short y;
460 if (get_long(v, &x) < 0)
461 return -1;
462 if (x < 0 || x > USHRT_MAX){
463 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000464 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000465 return -1;
466 }
467 y = (unsigned short)x;
468 memcpy(p, (char *)&y, sizeof y);
469 return 0;
470}
471
472static int
473np_int(char *p, PyObject *v, const formatdef *f)
474{
475 long x;
476 int y;
477 if (get_long(v, &x) < 0)
478 return -1;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000479#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000480 if (x < INT_MIN || x > INT_MAX)
481 return _range_error(f->format, sizeof(y), 0);
482#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000483 y = (int)x;
484 memcpy(p, (char *)&y, sizeof y);
485 return 0;
486}
487
488static int
489np_uint(char *p, PyObject *v, const formatdef *f)
490{
491 unsigned long x;
492 unsigned int y;
493 if (get_ulong(v, &x) < 0)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000494 return _range_error(f->format, sizeof(y), 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000495 y = (unsigned int)x;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000496#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolito685dda82006-05-26 14:23:21 +0000497 if (x > UINT_MAX)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000498 return _range_error(f->format, sizeof(y), 1);
499#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000500 memcpy(p, (char *)&y, sizeof y);
501 return 0;
502}
503
504static int
505np_long(char *p, PyObject *v, const formatdef *f)
506{
507 long x;
508 if (get_long(v, &x) < 0)
509 return -1;
510 memcpy(p, (char *)&x, sizeof x);
511 return 0;
512}
513
514static int
515np_ulong(char *p, PyObject *v, const formatdef *f)
516{
517 unsigned long x;
518 if (get_ulong(v, &x) < 0)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000519 return _range_error(f->format, sizeof(x), 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000520 memcpy(p, (char *)&x, sizeof x);
521 return 0;
522}
523
524#ifdef HAVE_LONG_LONG
525
526static int
527np_longlong(char *p, PyObject *v, const formatdef *f)
528{
529 PY_LONG_LONG x;
530 if (get_longlong(v, &x) < 0)
531 return -1;
532 memcpy(p, (char *)&x, sizeof x);
533 return 0;
534}
535
536static int
537np_ulonglong(char *p, PyObject *v, const formatdef *f)
538{
539 unsigned PY_LONG_LONG x;
540 if (get_ulonglong(v, &x) < 0)
541 return -1;
542 memcpy(p, (char *)&x, sizeof x);
543 return 0;
544}
545#endif
546
547static int
548np_float(char *p, PyObject *v, const formatdef *f)
549{
550 float x = (float)PyFloat_AsDouble(v);
551 if (x == -1 && PyErr_Occurred()) {
552 PyErr_SetString(StructError,
553 "required argument is not a float");
554 return -1;
555 }
556 memcpy(p, (char *)&x, sizeof x);
557 return 0;
558}
559
560static int
561np_double(char *p, PyObject *v, const formatdef *f)
562{
563 double x = PyFloat_AsDouble(v);
564 if (x == -1 && PyErr_Occurred()) {
565 PyErr_SetString(StructError,
566 "required argument is not a float");
567 return -1;
568 }
569 memcpy(p, (char *)&x, sizeof(double));
570 return 0;
571}
572
573static int
574np_void_p(char *p, PyObject *v, const formatdef *f)
575{
576 void *x;
577
578 v = get_pylong(v);
579 if (v == NULL)
580 return -1;
581 assert(PyLong_Check(v));
582 x = PyLong_AsVoidPtr(v);
583 Py_DECREF(v);
584 if (x == NULL && PyErr_Occurred())
585 return -1;
586 memcpy(p, (char *)&x, sizeof x);
587 return 0;
588}
589
590static formatdef native_table[] = {
591 {'x', sizeof(char), 0, NULL},
592 {'b', sizeof(char), 0, nu_byte, np_byte},
593 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
594 {'c', sizeof(char), 0, nu_char, np_char},
595 {'s', sizeof(char), 0, NULL},
596 {'p', sizeof(char), 0, NULL},
597 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
598 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
599 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
600 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
601 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
602 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000603#ifdef HAVE_LONG_LONG
604 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
605 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
606#endif
Bob Ippolitoa99865b2006-05-25 19:56:56 +0000607 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
608 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
609 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000610 {0}
611};
612
613/* Big-endian routines. *****************************************************/
614
615static PyObject *
616bu_int(const char *p, const formatdef *f)
617{
618 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000619 Py_ssize_t i = f->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000620 do {
621 x = (x<<8) | (*p++ & 0xFF);
622 } while (--i > 0);
623 /* Extend the sign bit. */
624 if (SIZEOF_LONG > f->size)
625 x |= -(x & (1L << (8*f->size - 1)));
626 return PyInt_FromLong(x);
627}
628
629static PyObject *
630bu_uint(const char *p, const formatdef *f)
631{
632 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000633 Py_ssize_t i = f->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000634 do {
635 x = (x<<8) | (*p++ & 0xFF);
636 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000637 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000638 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000639 return PyLong_FromUnsignedLong(x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000640}
641
642static PyObject *
643bu_longlong(const char *p, const formatdef *f)
644{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000645#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000646 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000647 Py_ssize_t i = f->size;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000648 do {
649 x = (x<<8) | (*p++ & 0xFF);
650 } while (--i > 0);
651 /* Extend the sign bit. */
652 if (SIZEOF_LONG_LONG > f->size)
653 x |= -(x & (1L << (8 * f->size - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000654 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000655 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000656 return PyLong_FromLongLong(x);
657#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000658 return _PyLong_FromByteArray((const unsigned char *)p,
659 8,
660 0, /* little-endian */
661 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000662#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000663}
664
665static PyObject *
666bu_ulonglong(const char *p, const formatdef *f)
667{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000668#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000669 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000670 Py_ssize_t i = f->size;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000671 do {
672 x = (x<<8) | (*p++ & 0xFF);
673 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000674 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000675 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000676 return PyLong_FromUnsignedLongLong(x);
677#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000678 return _PyLong_FromByteArray((const unsigned char *)p,
679 8,
680 0, /* little-endian */
681 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000682#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000683}
684
685static PyObject *
686bu_float(const char *p, const formatdef *f)
687{
688 return unpack_float(p, 0);
689}
690
691static PyObject *
692bu_double(const char *p, const formatdef *f)
693{
694 return unpack_double(p, 0);
695}
696
697static int
698bp_int(char *p, PyObject *v, const formatdef *f)
699{
700 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000701 Py_ssize_t i;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000702 if (get_long(v, &x) < 0)
703 return -1;
704 i = f->size;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000705 if (i != SIZEOF_LONG && (
706 (i == 2 && (x < -32768 || x > 32767))
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000707#if (SIZEOF_LONG != 4)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000708 || (i == 4) && (x < -2147483648L || x > -2147483647L)
709#endif
710 ))
711 return _range_error(f->format, i, 0);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000712 do {
713 p[--i] = (char)x;
714 x >>= 8;
715 } while (i > 0);
716 return 0;
717}
718
719static int
720bp_uint(char *p, PyObject *v, const formatdef *f)
721{
722 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000723 Py_ssize_t i;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000724 if (get_ulong(v, &x) < 0)
725 return -1;
726 i = f->size;
Tim Peters735ae482006-05-26 16:49:28 +0000727 if (i != SIZEOF_LONG && x >= (1U << (((unsigned int)i) * 8)))
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000728 return _range_error(f->format, f->size, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000729 do {
730 p[--i] = (char)x;
731 x >>= 8;
732 } while (i > 0);
733 return 0;
734}
735
736static int
737bp_longlong(char *p, PyObject *v, const formatdef *f)
738{
739 int res;
740 v = get_pylong(v);
741 if (v == NULL)
742 return -1;
743 res = _PyLong_AsByteArray((PyLongObject *)v,
744 (unsigned char *)p,
745 8,
746 0, /* little_endian */
747 1 /* signed */);
748 Py_DECREF(v);
749 return res;
750}
751
752static int
753bp_ulonglong(char *p, PyObject *v, const formatdef *f)
754{
755 int res;
756 v = get_pylong(v);
757 if (v == NULL)
758 return -1;
759 res = _PyLong_AsByteArray((PyLongObject *)v,
760 (unsigned char *)p,
761 8,
762 0, /* little_endian */
763 0 /* signed */);
764 Py_DECREF(v);
765 return res;
766}
767
768static int
769bp_float(char *p, PyObject *v, const formatdef *f)
770{
771 double x = PyFloat_AsDouble(v);
772 if (x == -1 && PyErr_Occurred()) {
773 PyErr_SetString(StructError,
774 "required argument is not a float");
775 return -1;
776 }
777 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
778}
779
780static int
781bp_double(char *p, PyObject *v, const formatdef *f)
782{
783 double x = PyFloat_AsDouble(v);
784 if (x == -1 && PyErr_Occurred()) {
785 PyErr_SetString(StructError,
786 "required argument is not a float");
787 return -1;
788 }
789 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
790}
791
792static formatdef bigendian_table[] = {
793 {'x', 1, 0, NULL},
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000794 {'b', 1, 0, nu_byte, np_byte},
795 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000796 {'c', 1, 0, nu_char, np_char},
797 {'s', 1, 0, NULL},
798 {'p', 1, 0, NULL},
799 {'h', 2, 0, bu_int, bp_int},
800 {'H', 2, 0, bu_uint, bp_uint},
801 {'i', 4, 0, bu_int, bp_int},
802 {'I', 4, 0, bu_uint, bp_uint},
803 {'l', 4, 0, bu_int, bp_int},
804 {'L', 4, 0, bu_uint, bp_uint},
805 {'q', 8, 0, bu_longlong, bp_longlong},
806 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
807 {'f', 4, 0, bu_float, bp_float},
808 {'d', 8, 0, bu_double, bp_double},
809 {0}
810};
811
812/* Little-endian routines. *****************************************************/
813
814static PyObject *
815lu_int(const char *p, const formatdef *f)
816{
817 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000818 Py_ssize_t i = f->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000819 do {
820 x = (x<<8) | (p[--i] & 0xFF);
821 } while (i > 0);
822 /* Extend the sign bit. */
823 if (SIZEOF_LONG > f->size)
824 x |= -(x & (1L << (8*f->size - 1)));
825 return PyInt_FromLong(x);
826}
827
828static PyObject *
829lu_uint(const char *p, const formatdef *f)
830{
831 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000832 Py_ssize_t i = f->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000833 do {
834 x = (x<<8) | (p[--i] & 0xFF);
835 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000836 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000837 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000838 return PyLong_FromUnsignedLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000839}
840
841static PyObject *
842lu_longlong(const char *p, const formatdef *f)
843{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000844#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000845 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000846 Py_ssize_t i = f->size;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000847 do {
848 x = (x<<8) | (p[--i] & 0xFF);
849 } while (i > 0);
850 /* Extend the sign bit. */
851 if (SIZEOF_LONG_LONG > f->size)
852 x |= -(x & (1L << (8 * f->size - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000853 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000854 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000855 return PyLong_FromLongLong(x);
856#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000857 return _PyLong_FromByteArray((const unsigned char *)p,
858 8,
859 1, /* little-endian */
860 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000861#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000862}
863
864static PyObject *
865lu_ulonglong(const char *p, const formatdef *f)
866{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000867#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000868 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000869 Py_ssize_t i = f->size;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000870 do {
871 x = (x<<8) | (p[--i] & 0xFF);
872 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000873 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000874 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000875 return PyLong_FromUnsignedLongLong(x);
876#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000877 return _PyLong_FromByteArray((const unsigned char *)p,
878 8,
879 1, /* little-endian */
880 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000881#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000882}
883
884static PyObject *
885lu_float(const char *p, const formatdef *f)
886{
887 return unpack_float(p, 1);
888}
889
890static PyObject *
891lu_double(const char *p, const formatdef *f)
892{
893 return unpack_double(p, 1);
894}
895
896static int
897lp_int(char *p, PyObject *v, const formatdef *f)
898{
899 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000900 Py_ssize_t i;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000901 if (get_long(v, &x) < 0)
902 return -1;
903 i = f->size;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000904 if (i != SIZEOF_LONG && (
905 (i == 2 && (x < -32768 || x > 32767))
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000906#if (SIZEOF_LONG != 4)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000907 || (i == 4) && (x < -2147483648L || x > -2147483647L)
908#endif
909 ))
910 return _range_error(f->format, i, 0);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000911 do {
912 *p++ = (char)x;
913 x >>= 8;
914 } while (--i > 0);
915 return 0;
916}
917
918static int
919lp_uint(char *p, PyObject *v, const formatdef *f)
920{
921 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000922 Py_ssize_t i;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000923 if (get_ulong(v, &x) < 0)
924 return -1;
925 i = f->size;
Tim Peters735ae482006-05-26 16:49:28 +0000926 if (i != SIZEOF_LONG && x >= (1U << (((unsigned int)i) * 8)))
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000927 return _range_error(f->format, f->size, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000928 do {
929 *p++ = (char)x;
930 x >>= 8;
931 } while (--i > 0);
932 return 0;
933}
934
935static int
936lp_longlong(char *p, PyObject *v, const formatdef *f)
937{
938 int res;
939 v = get_pylong(v);
940 if (v == NULL)
941 return -1;
942 res = _PyLong_AsByteArray((PyLongObject*)v,
943 (unsigned char *)p,
944 8,
945 1, /* little_endian */
946 1 /* signed */);
947 Py_DECREF(v);
948 return res;
949}
950
951static int
952lp_ulonglong(char *p, PyObject *v, const formatdef *f)
953{
954 int res;
955 v = get_pylong(v);
956 if (v == NULL)
957 return -1;
958 res = _PyLong_AsByteArray((PyLongObject*)v,
959 (unsigned char *)p,
960 8,
961 1, /* little_endian */
962 0 /* signed */);
963 Py_DECREF(v);
964 return res;
965}
966
967static int
968lp_float(char *p, PyObject *v, const formatdef *f)
969{
970 double x = PyFloat_AsDouble(v);
971 if (x == -1 && PyErr_Occurred()) {
972 PyErr_SetString(StructError,
973 "required argument is not a float");
974 return -1;
975 }
976 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
977}
978
979static int
980lp_double(char *p, PyObject *v, const formatdef *f)
981{
982 double x = PyFloat_AsDouble(v);
983 if (x == -1 && PyErr_Occurred()) {
984 PyErr_SetString(StructError,
985 "required argument is not a float");
986 return -1;
987 }
988 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
989}
990
991static formatdef lilendian_table[] = {
992 {'x', 1, 0, NULL},
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000993 {'b', 1, 0, nu_byte, np_byte},
994 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000995 {'c', 1, 0, nu_char, np_char},
996 {'s', 1, 0, NULL},
997 {'p', 1, 0, NULL},
998 {'h', 2, 0, lu_int, lp_int},
999 {'H', 2, 0, lu_uint, lp_uint},
1000 {'i', 4, 0, lu_int, lp_int},
1001 {'I', 4, 0, lu_uint, lp_uint},
1002 {'l', 4, 0, lu_int, lp_int},
1003 {'L', 4, 0, lu_uint, lp_uint},
1004 {'q', 8, 0, lu_longlong, lp_longlong},
1005 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1006 {'f', 4, 0, lu_float, lp_float},
1007 {'d', 8, 0, lu_double, lp_double},
1008 {0}
1009};
1010
1011
1012static const formatdef *
1013whichtable(char **pfmt)
1014{
1015 const char *fmt = (*pfmt)++; /* May be backed out of later */
1016 switch (*fmt) {
1017 case '<':
1018 return lilendian_table;
1019 case '>':
1020 case '!': /* Network byte order is big-endian */
1021 return bigendian_table;
1022 case '=': { /* Host byte order -- different from native in aligment! */
1023 int n = 1;
1024 char *p = (char *) &n;
1025 if (*p == 1)
1026 return lilendian_table;
1027 else
1028 return bigendian_table;
1029 }
1030 default:
1031 --*pfmt; /* Back out of pointer increment */
1032 /* Fall through */
1033 case '@':
1034 return native_table;
1035 }
1036}
1037
1038
1039/* Get the table entry for a format code */
1040
1041static const formatdef *
1042getentry(int c, const formatdef *f)
1043{
1044 for (; f->format != '\0'; f++) {
1045 if (f->format == c) {
1046 return f;
1047 }
1048 }
1049 PyErr_SetString(StructError, "bad char in struct format");
1050 return NULL;
1051}
1052
1053
1054/* Align a size according to a format code */
1055
1056static int
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001057align(Py_ssize_t size, char c, const formatdef *e)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001058{
1059 if (e->format == c) {
1060 if (e->alignment) {
1061 size = ((size + e->alignment - 1)
1062 / e->alignment)
1063 * e->alignment;
1064 }
1065 }
1066 return size;
1067}
1068
1069
1070/* calculate the size of a format string */
1071
1072static int
1073prepare_s(PyStructObject *self)
1074{
1075 const formatdef *f;
1076 const formatdef *e;
1077 formatcode *codes;
1078
1079 const char *s;
1080 const char *fmt;
1081 char c;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001082 Py_ssize_t size, len, num, itemsize, x;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001083
1084 fmt = PyString_AS_STRING(self->s_format);
1085
1086 f = whichtable((char **)&fmt);
1087
1088 s = fmt;
1089 size = 0;
1090 len = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001091 while ((c = *s++) != '\0') {
1092 if (isspace(Py_CHARMASK(c)))
1093 continue;
1094 if ('0' <= c && c <= '9') {
1095 num = c - '0';
1096 while ('0' <= (c = *s++) && c <= '9') {
1097 x = num*10 + (c - '0');
1098 if (x/10 != num) {
1099 PyErr_SetString(
1100 StructError,
1101 "overflow in item count");
1102 return -1;
1103 }
1104 num = x;
1105 }
1106 if (c == '\0')
1107 break;
1108 }
1109 else
1110 num = 1;
1111
1112 e = getentry(c, f);
1113 if (e == NULL)
1114 return -1;
1115
1116 switch (c) {
1117 case 's': /* fall through */
1118 case 'p': len++; break;
1119 case 'x': break;
1120 default: len += num; break;
1121 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001122
1123 itemsize = e->size;
1124 size = align(size, c, e);
1125 x = num * itemsize;
1126 size += x;
1127 if (x/itemsize != num || size < 0) {
1128 PyErr_SetString(StructError,
1129 "total struct size too long");
1130 return -1;
1131 }
1132 }
1133
1134 self->s_size = size;
1135 self->s_len = len;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001136 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
Bob Ippolito232f3c92006-05-23 19:12:41 +00001137 if (codes == NULL) {
1138 PyErr_NoMemory();
1139 return -1;
1140 }
1141 self->s_codes = codes;
1142
1143 s = fmt;
1144 size = 0;
1145 while ((c = *s++) != '\0') {
1146 if (isspace(Py_CHARMASK(c)))
1147 continue;
1148 if ('0' <= c && c <= '9') {
1149 num = c - '0';
1150 while ('0' <= (c = *s++) && c <= '9')
1151 num = num*10 + (c - '0');
1152 if (c == '\0')
1153 break;
1154 }
1155 else
1156 num = 1;
1157
1158 e = getentry(c, f);
1159
1160 size = align(size, c, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001161 if (c == 's' || c == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001162 codes->offset = size;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001163 codes->size = num;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001164 codes->fmtdef = e;
1165 codes++;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001166 size += num;
1167 } else if (c == 'x') {
1168 size += num;
1169 } else {
1170 while (--num >= 0) {
1171 codes->offset = size;
1172 codes->size = e->size;
1173 codes->fmtdef = e;
1174 codes++;
1175 size += e->size;
1176 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001177 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001178 }
1179 codes->fmtdef = NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001180 codes->offset = size;
1181 codes->size = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001182
1183 return 0;
1184}
1185
1186static PyObject *
1187s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1188{
1189 PyObject *self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001190
1191 assert(type != NULL && type->tp_alloc != NULL);
1192
1193 self = type->tp_alloc(type, 0);
1194 if (self != NULL) {
1195 PyStructObject *s = (PyStructObject*)self;
1196 Py_INCREF(Py_None);
1197 s->s_format = Py_None;
1198 s->s_codes = NULL;
1199 s->s_size = -1;
1200 s->s_len = -1;
1201 }
1202 return self;
1203}
1204
1205static int
1206s_init(PyObject *self, PyObject *args, PyObject *kwds)
1207{
1208 PyStructObject *soself = (PyStructObject *)self;
1209 PyObject *o_format = NULL;
1210 int ret = 0;
1211 static char *kwlist[] = {"format", 0};
1212
1213 assert(PyStruct_Check(self));
1214
1215 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1216 &o_format))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001217 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001218
1219 Py_INCREF(o_format);
1220 Py_XDECREF(soself->s_format);
1221 soself->s_format = o_format;
1222
1223 ret = prepare_s(soself);
1224 return ret;
1225}
1226
1227static void
1228s_dealloc(PyStructObject *s)
1229{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001230 if (s->weakreflist != NULL)
1231 PyObject_ClearWeakRefs((PyObject *)s);
1232 if (s->s_codes != NULL) {
1233 PyMem_FREE(s->s_codes);
1234 }
1235 Py_XDECREF(s->s_format);
1236 s->ob_type->tp_free((PyObject *)s);
1237}
1238
Bob Ippolitoeb621272006-05-24 15:32:06 +00001239static PyObject *
1240s_unpack_internal(PyStructObject *soself, char *startfrom) {
1241 formatcode *code;
1242 Py_ssize_t i = 0;
1243 PyObject *result = PyTuple_New(soself->s_len);
1244 if (result == NULL)
1245 return NULL;
1246
1247 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1248 PyObject *v;
1249 const formatdef *e = code->fmtdef;
1250 const char *res = startfrom + code->offset;
1251 if (e->format == 's') {
1252 v = PyString_FromStringAndSize(res, code->size);
1253 if (v == NULL)
1254 goto fail;
1255 PyTuple_SET_ITEM(result, i++, v);
1256 } else if (e->format == 'p') {
1257 Py_ssize_t n = *(unsigned char*)res;
1258 if (n >= code->size)
1259 n = code->size - 1;
1260 v = PyString_FromStringAndSize(res + 1, n);
1261 if (v == NULL)
1262 goto fail;
1263 PyTuple_SET_ITEM(result, i++, v);
1264 } else {
1265 v = e->unpack(res, e);
1266 if (v == NULL)
1267 goto fail;
1268 PyTuple_SET_ITEM(result, i++, v);
1269 }
1270 }
1271
1272 return result;
1273fail:
1274 Py_DECREF(result);
1275 return NULL;
1276};
1277
1278
Bob Ippolito232f3c92006-05-23 19:12:41 +00001279PyDoc_STRVAR(s_unpack__doc__,
1280"unpack(str) -> (v1, v2, ...)\n\
1281\n\
1282Return tuple containing values unpacked according to this Struct's format.\n\
1283Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1284strings.");
1285
1286static PyObject *
1287s_unpack(PyObject *self, PyObject *inputstr)
1288{
Bob Ippolitoeb621272006-05-24 15:32:06 +00001289 PyStructObject *soself = (PyStructObject *)self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001290 assert(PyStruct_Check(self));
1291 assert(soself->s_codes != NULL);
1292 if (inputstr == NULL || !PyString_Check(inputstr) ||
Bob Ippolitoeb621272006-05-24 15:32:06 +00001293 PyString_GET_SIZE(inputstr) != soself->s_size) {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001294 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001295 "unpack requires a string argument of length %zd", soself->s_size);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001296 return NULL;
1297 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001298 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1299}
1300
1301PyDoc_STRVAR(s_unpack_from__doc__,
1302"unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1303\n\
1304Return tuple containing values unpacked according to this Struct's format.\n\
1305Unlike unpack, unpack_from can unpack values from any object supporting\n\
1306the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1307See struct.__doc__ for more on format strings.");
1308
1309static PyObject *
1310s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1311{
1312 static char *kwlist[] = {"buffer", "offset", 0};
1313#if (PY_VERSION_HEX < 0x02050000)
1314 static char *fmt = "z#|i:unpack_from";
1315#else
1316 static char *fmt = "z#|n:unpack_from";
1317#endif
1318 Py_ssize_t buffer_len = 0, offset = 0;
1319 char *buffer = NULL;
1320 PyStructObject *soself = (PyStructObject *)self;
1321 assert(PyStruct_Check(self));
1322 assert(soself->s_codes != NULL);
1323
1324 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1325 &buffer, &buffer_len, &offset))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001326 return NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001327
1328 if (buffer == NULL) {
1329 PyErr_Format(StructError,
1330 "unpack_from requires a buffer argument");
Bob Ippolito232f3c92006-05-23 19:12:41 +00001331 return NULL;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001332 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001333
1334 if (offset < 0)
1335 offset += buffer_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001336
Bob Ippolitoeb621272006-05-24 15:32:06 +00001337 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1338 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001339 "unpack_from requires a buffer of at least %zd bytes",
Bob Ippolitoeb621272006-05-24 15:32:06 +00001340 soself->s_size);
1341 return NULL;
1342 }
1343 return s_unpack_internal(soself, buffer + offset);
1344}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001345
Bob Ippolito232f3c92006-05-23 19:12:41 +00001346
Martin Blais2856e5f2006-05-26 12:03:27 +00001347/*
1348 * Guts of the pack function.
1349 *
1350 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1351 * argument for where to start processing the arguments for packing, and a
1352 * character buffer for writing the packed string. The caller must insure
1353 * that the buffer may contain the required length for packing the arguments.
1354 * 0 is returned on success, 1 is returned if there is an error.
1355 *
1356 */
1357static int
1358s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001359{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001360 formatcode *code;
1361 Py_ssize_t i;
Martin Blais2856e5f2006-05-26 12:03:27 +00001362
1363 memset(buf, '\0', soself->s_size);
1364 i = offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001365 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1366 Py_ssize_t n;
1367 PyObject *v;
1368 const formatdef *e = code->fmtdef;
Martin Blais2856e5f2006-05-26 12:03:27 +00001369 char *res = buf + code->offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001370 if (e->format == 's') {
1371 v = PyTuple_GET_ITEM(args, i++);
1372 if (!PyString_Check(v)) {
1373 PyErr_SetString(StructError,
1374 "argument for 's' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001375 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001376 }
1377 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001378 if (n > code->size)
1379 n = code->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001380 if (n > 0)
1381 memcpy(res, PyString_AS_STRING(v), n);
1382 } else if (e->format == 'p') {
1383 v = PyTuple_GET_ITEM(args, i++);
1384 if (!PyString_Check(v)) {
1385 PyErr_SetString(StructError,
1386 "argument for 'p' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001387 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001388 }
1389 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001390 if (n > (code->size - 1))
1391 n = code->size - 1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001392 if (n > 0)
1393 memcpy(res + 1, PyString_AS_STRING(v), n);
1394 if (n > 255)
1395 n = 255;
1396 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1397 } else {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001398 v = PyTuple_GET_ITEM(args, i++);
1399 if (e->pack(res, v, e) < 0)
Martin Blais2856e5f2006-05-26 12:03:27 +00001400 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001401 }
1402 }
1403
Martin Blais2856e5f2006-05-26 12:03:27 +00001404 /* Success */
1405 return 0;
1406}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001407
Martin Blais2856e5f2006-05-26 12:03:27 +00001408
1409PyDoc_STRVAR(s_pack__doc__,
1410"pack(v1, v2, ...) -> string\n\
1411\n\
1412Return a string containing values v1, v2, ... packed according to this\n\
1413Struct's format. See struct.__doc__ for more on format strings.");
1414
1415static PyObject *
1416s_pack(PyObject *self, PyObject *args)
1417{
1418 PyStructObject *soself;
1419 PyObject *result;
1420
1421 /* Validate arguments. */
1422 soself = (PyStructObject *)self;
1423 assert(PyStruct_Check(self));
1424 assert(soself->s_codes != NULL);
1425 if (args == NULL || !PyTuple_Check(args) ||
1426 PyTuple_GET_SIZE(args) != soself->s_len)
1427 {
1428 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001429 "pack requires exactly %zd arguments", soself->s_len);
Martin Blais2856e5f2006-05-26 12:03:27 +00001430 return NULL;
1431 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001432
Martin Blais2856e5f2006-05-26 12:03:27 +00001433 /* Allocate a new string */
1434 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1435 if (result == NULL)
1436 return NULL;
1437
1438 /* Call the guts */
1439 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1440 Py_DECREF(result);
1441 return NULL;
1442 }
1443
1444 return result;
1445}
1446
1447PyDoc_STRVAR(s_pack_to__doc__,
1448"pack_to(buffer, offset, v1, v2, ...)\n\
1449\n\
1450Pack the values v2, v2, ... according to this Struct's format, write \n\
1451the packed bytes into the given buffer at the given offset. Note that \n\
1452the offset is not an optional argument. See struct.__doc__ for \n\
1453more on format strings.");
1454
1455static PyObject *
1456s_pack_to(PyObject *self, PyObject *args)
1457{
1458 PyStructObject *soself;
1459 char *buffer;
1460 Py_ssize_t buffer_len, offset;
1461
1462 /* Validate arguments. +1 is for the first arg as buffer. */
1463 soself = (PyStructObject *)self;
1464 assert(PyStruct_Check(self));
1465 assert(soself->s_codes != NULL);
1466 if (args == NULL || !PyTuple_Check(args) ||
1467 PyTuple_GET_SIZE(args) != (soself->s_len + 2))
1468 {
1469 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001470 "pack_to requires exactly %zd arguments",
Martin Blais2856e5f2006-05-26 12:03:27 +00001471 (soself->s_len + 2));
1472 return NULL;
1473 }
1474
1475 /* Extract a writable memory buffer from the first argument */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001476 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1477 (void**)&buffer, &buffer_len) == -1 ) {
Martin Blais2856e5f2006-05-26 12:03:27 +00001478 return NULL;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001479 }
1480 assert( buffer_len >= 0 );
Martin Blais2856e5f2006-05-26 12:03:27 +00001481
1482 /* Extract the offset from the first argument */
1483 offset = PyInt_AsLong(PyTuple_GET_ITEM(args, 1));
1484
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001485 /* Support negative offsets. */
Martin Blais2856e5f2006-05-26 12:03:27 +00001486 if (offset < 0)
1487 offset += buffer_len;
1488
1489 /* Check boundaries */
1490 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1491 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001492 "pack_to requires a buffer of at least %zd bytes",
Martin Blais2856e5f2006-05-26 12:03:27 +00001493 soself->s_size);
1494 return NULL;
1495 }
1496
1497 /* Call the guts */
1498 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1499 return NULL;
1500 }
1501
1502 return Py_None;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001503}
1504
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001505static PyObject *
1506s_get_format(PyStructObject *self, void *unused)
1507{
1508 Py_INCREF(self->s_format);
1509 return self->s_format;
1510}
1511
1512static PyObject *
1513s_get_size(PyStructObject *self, void *unused)
1514{
1515 return PyInt_FromSsize_t(self->s_size);
1516}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001517
1518/* List of functions */
1519
1520static struct PyMethodDef s_methods[] = {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001521 {"pack", (PyCFunction)s_pack, METH_VARARGS, s_pack__doc__},
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001522 {"pack_to", (PyCFunction)s_pack_to, METH_VARARGS, s_pack_to__doc__},
Bob Ippolitoeb621272006-05-24 15:32:06 +00001523 {"unpack", (PyCFunction)s_unpack, METH_O, s_unpack__doc__},
1524 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001525 {NULL, NULL} /* sentinel */
1526};
1527
1528PyDoc_STRVAR(s__doc__, "Compiled struct object");
1529
1530#define OFF(x) offsetof(PyStructObject, x)
1531
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001532static PyGetSetDef s_getsetlist[] = {
1533 {"format", (getter)s_get_format, (setter)NULL, "buffer's capacity", NULL},
1534 {"size", (getter)s_get_size, (setter)NULL, "buffer's position", NULL},
1535 {NULL} /* sentinel */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001536};
1537
Bob Ippolito232f3c92006-05-23 19:12:41 +00001538static
1539PyTypeObject PyStructType = {
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001540 PyObject_HEAD_INIT(NULL)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001541 0,
1542 "Struct",
1543 sizeof(PyStructObject),
1544 0,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001545 (destructor)s_dealloc, /* tp_dealloc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001546 0, /* tp_print */
1547 0, /* tp_getattr */
1548 0, /* tp_setattr */
1549 0, /* tp_compare */
1550 0, /* tp_repr */
1551 0, /* tp_as_number */
1552 0, /* tp_as_sequence */
1553 0, /* tp_as_mapping */
1554 0, /* tp_hash */
1555 0, /* tp_call */
1556 0, /* tp_str */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001557 PyObject_GenericGetAttr, /* tp_getattro */
1558 PyObject_GenericSetAttr, /* tp_setattro */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001559 0, /* tp_as_buffer */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001560 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1561 s__doc__, /* tp_doc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001562 0, /* tp_traverse */
1563 0, /* tp_clear */
1564 0, /* tp_richcompare */
1565 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1566 0, /* tp_iter */
1567 0, /* tp_iternext */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001568 s_methods, /* tp_methods */
1569 NULL, /* tp_members */
1570 s_getsetlist, /* tp_getset */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001571 0, /* tp_base */
1572 0, /* tp_dict */
1573 0, /* tp_descr_get */
1574 0, /* tp_descr_set */
1575 0, /* tp_dictoffset */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001576 s_init, /* tp_init */
1577 PyType_GenericAlloc,/* tp_alloc */
1578 s_new, /* tp_new */
1579 PyObject_Del, /* tp_free */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001580};
1581
1582/* Module initialization */
1583
1584PyMODINIT_FUNC
1585init_struct(void)
1586{
1587 PyObject *m = Py_InitModule("_struct", NULL);
1588 if (m == NULL)
1589 return;
1590
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001591 PyStructType.ob_type = &PyType_Type;
1592 if (PyType_Ready(&PyStructType) < 0)
1593 return;
1594
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001595 /* Check endian and swap in faster functions */
1596 {
1597 int one = 1;
1598 formatdef *native = native_table;
1599 formatdef *other, *ptr;
1600 if ((int)*(unsigned char*)&one)
1601 other = lilendian_table;
1602 else
1603 other = bigendian_table;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001604 /* Scan through the native table, find a matching
1605 entry in the endian table and swap in the
1606 native implementations whenever possible
1607 (64-bit platforms may not have "standard" sizes) */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001608 while (native->format != '\0' && other->format != '\0') {
1609 ptr = other;
1610 while (ptr->format != '\0') {
1611 if (ptr->format == native->format) {
Bob Ippolito964e02a2006-05-25 21:09:45 +00001612 /* Match faster when formats are
1613 listed in the same order */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001614 if (ptr == other)
1615 other++;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001616 /* Only use the trick if the
1617 size matches */
1618 if (ptr->size != native->size)
1619 break;
1620 /* Skip float and double, could be
1621 "unknown" float format */
1622 if (ptr->format == 'd' || ptr->format == 'f')
1623 break;
1624 ptr->pack = native->pack;
1625 ptr->unpack = native->unpack;
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001626 break;
1627 }
1628 ptr++;
1629 }
1630 native++;
1631 }
1632 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001633
Bob Ippolito232f3c92006-05-23 19:12:41 +00001634 /* Add some symbolic constants to the module */
1635 if (StructError == NULL) {
1636 StructError = PyErr_NewException("struct.error", NULL, NULL);
1637 if (StructError == NULL)
1638 return;
1639 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001640
Bob Ippolito232f3c92006-05-23 19:12:41 +00001641 Py_INCREF(StructError);
1642 PyModule_AddObject(m, "error", StructError);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001643
Bob Ippolito232f3c92006-05-23 19:12:41 +00001644 Py_INCREF((PyObject*)&PyStructType);
1645 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
1646}