blob: a1142169183f3996a3c0e4a6646dc86912d01311 [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
6#include "Python.h"
7#include "structseq.h"
8#include "structmember.h"
9#include <ctype.h>
10
Bob Ippolitod3611eb2006-05-23 19:31:23 +000011static PyTypeObject PyStructType;
Bob Ippolito232f3c92006-05-23 19:12:41 +000012
13/* compatibility macros */
14#if (PY_VERSION_HEX < 0x02050000)
15typedef int Py_ssize_t;
16#endif
17
Martin Blais2856e5f2006-05-26 12:03:27 +000018
Bob Ippolito1d2b0e32006-05-26 14:29:35 +000019/* PY_USE_INT_WHEN_POSSIBLE is a flag that changes the
Bob Ippolito94f68ee2006-05-25 18:44:50 +000020 struct API to return int instead of long when possible. This is
21 often a significant performance improvement. */
Bob Ippolito94f68ee2006-05-25 18:44:50 +000022#define PY_USE_INT_WHEN_POSSIBLE 1
Bob Ippolito232f3c92006-05-23 19:12:41 +000023
Bob Ippolitoe27337b2006-05-26 13:15:44 +000024/* PY_STRUCT_RANGE_CHECKING performs range checking on all arguments
25 to be packed. This will break some incorrect code that happened
26 to accidentally do the right thing anyway (such as binhex). */
27#define PY_STRUCT_RANGE_CHECKING 1
Bob Ippolito232f3c92006-05-23 19:12:41 +000028
29/* The translation function for each format character is table driven */
Bob Ippolito232f3c92006-05-23 19:12:41 +000030typedef struct _formatdef {
31 char format;
32 int size;
33 int alignment;
34 PyObject* (*unpack)(const char *,
35 const struct _formatdef *);
36 int (*pack)(char *, PyObject *,
37 const struct _formatdef *);
38} formatdef;
39
40typedef struct _formatcode {
41 const struct _formatdef *fmtdef;
42 int offset;
Bob Ippolitoeb621272006-05-24 15:32:06 +000043 int size;
Bob Ippolito232f3c92006-05-23 19:12:41 +000044} formatcode;
45
46/* Struct object interface */
47
48typedef struct {
49 PyObject_HEAD
50 int s_size;
51 int s_len;
52 formatcode *s_codes;
53 PyObject *s_format;
54 PyObject *weakreflist; /* List of weak references */
55} PyStructObject;
56
Bob Ippolitoeb621272006-05-24 15:32:06 +000057
Bob Ippolito07c023b2006-05-23 19:32:25 +000058#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
59#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
Bob Ippolito232f3c92006-05-23 19:12:41 +000060
61
62/* Exception */
63
64static PyObject *StructError;
65
66
67/* Define various structs to figure out the alignments of types */
68
69
70typedef struct { char c; short x; } st_short;
71typedef struct { char c; int x; } st_int;
72typedef struct { char c; long x; } st_long;
73typedef struct { char c; float x; } st_float;
74typedef struct { char c; double x; } st_double;
75typedef struct { char c; void *x; } st_void_p;
76
77#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
78#define INT_ALIGN (sizeof(st_int) - sizeof(int))
79#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
80#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
81#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
82#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
83
84/* We can't support q and Q in native mode unless the compiler does;
85 in std mode, they're 8 bytes on all platforms. */
86#ifdef HAVE_LONG_LONG
87typedef struct { char c; PY_LONG_LONG x; } s_long_long;
88#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
89#endif
90
91#define STRINGIFY(x) #x
92
93#ifdef __powerc
94#pragma options align=reset
95#endif
96
97/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
98
99static PyObject *
100get_pylong(PyObject *v)
101{
102 PyNumberMethods *m;
103
104 assert(v != NULL);
105 if (PyInt_Check(v))
106 return PyLong_FromLong(PyInt_AS_LONG(v));
107 if (PyLong_Check(v)) {
108 Py_INCREF(v);
109 return v;
110 }
111 m = v->ob_type->tp_as_number;
112 if (m != NULL && m->nb_long != NULL) {
113 v = m->nb_long(v);
114 if (v == NULL)
115 return NULL;
116 if (PyLong_Check(v))
117 return v;
118 Py_DECREF(v);
119 }
120 PyErr_SetString(StructError,
121 "cannot convert argument to long");
122 return NULL;
123}
124
125/* Helper routine to get a Python integer and raise the appropriate error
126 if it isn't one */
127
128static int
129get_long(PyObject *v, long *p)
130{
131 long x = PyInt_AsLong(v);
132 if (x == -1 && PyErr_Occurred()) {
133 if (PyErr_ExceptionMatches(PyExc_TypeError))
134 PyErr_SetString(StructError,
135 "required argument is not an integer");
136 return -1;
137 }
138 *p = x;
139 return 0;
140}
141
142
143/* Same, but handling unsigned long */
144
145static int
146get_ulong(PyObject *v, unsigned long *p)
147{
148 if (PyLong_Check(v)) {
149 unsigned long x = PyLong_AsUnsignedLong(v);
150 if (x == (unsigned long)(-1) && PyErr_Occurred())
151 return -1;
152 *p = x;
153 return 0;
154 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000155 if (get_long(v, (long *)p) < 0)
156 return -1;
157 if (((long)*p) < 0) {
158 PyErr_SetString(StructError,
159 "unsigned argument is < 0");
160 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000161 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000162 return 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000163}
164
165#ifdef HAVE_LONG_LONG
166
167/* Same, but handling native long long. */
168
169static int
170get_longlong(PyObject *v, PY_LONG_LONG *p)
171{
172 PY_LONG_LONG x;
173
174 v = get_pylong(v);
175 if (v == NULL)
176 return -1;
177 assert(PyLong_Check(v));
178 x = PyLong_AsLongLong(v);
179 Py_DECREF(v);
180 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
181 return -1;
182 *p = x;
183 return 0;
184}
185
186/* Same, but handling native unsigned long long. */
187
188static int
189get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
190{
191 unsigned PY_LONG_LONG x;
192
193 v = get_pylong(v);
194 if (v == NULL)
195 return -1;
196 assert(PyLong_Check(v));
197 x = PyLong_AsUnsignedLongLong(v);
198 Py_DECREF(v);
199 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
200 return -1;
201 *p = x;
202 return 0;
203}
204
205#endif
206
207/* Floating point helpers */
208
209static PyObject *
210unpack_float(const char *p, /* start of 4-byte string */
211 int le) /* true for little-endian, false for big-endian */
212{
213 double x;
214
215 x = _PyFloat_Unpack4((unsigned char *)p, le);
216 if (x == -1.0 && PyErr_Occurred())
217 return NULL;
218 return PyFloat_FromDouble(x);
219}
220
221static PyObject *
222unpack_double(const char *p, /* start of 8-byte string */
223 int le) /* true for little-endian, false for big-endian */
224{
225 double x;
226
227 x = _PyFloat_Unpack8((unsigned char *)p, le);
228 if (x == -1.0 && PyErr_Occurred())
229 return NULL;
230 return PyFloat_FromDouble(x);
231}
232
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000233#ifdef PY_STRUCT_RANGE_CHECKING
234/* Helper to format the range error exceptions */
235static int
236_range_error(char format, int size, int is_unsigned)
237{
238 if (is_unsigned == 0) {
239 long smallest = 0, largest = 0;
240 int i = size * 8;
241 while (--i > 0) {
242 smallest = (smallest * 2) - 1;
243 largest = (largest * 2) + 1;
244 }
245 PyErr_Format(StructError,
246 "'%c' format requires %ld <= number <= %ld",
247 format,
248 smallest,
249 largest);
250 } else {
251 unsigned long largest = 0;
252 int i = size * 8;
253 while (--i >= 0)
254 largest = (largest * 2) + 1;
255 PyErr_Format(StructError,
256 "'%c' format requires 0 <= number <= %lu",
257 format,
258 largest);
259 }
260 return -1;
261}
262#endif
263
264
Bob Ippolito232f3c92006-05-23 19:12:41 +0000265
266/* A large number of small routines follow, with names of the form
267
268 [bln][up]_TYPE
269
270 [bln] distiguishes among big-endian, little-endian and native.
271 [pu] distiguishes between pack (to struct) and unpack (from struct).
272 TYPE is one of char, byte, ubyte, etc.
273*/
274
275/* Native mode routines. ****************************************************/
276/* NOTE:
277 In all n[up]_<type> routines handling types larger than 1 byte, there is
278 *no* guarantee that the p pointer is properly aligned for each type,
279 therefore memcpy is called. An intermediate variable is used to
280 compensate for big-endian architectures.
281 Normally both the intermediate variable and the memcpy call will be
282 skipped by C optimisation in little-endian architectures (gcc >= 2.91
283 does this). */
284
285static PyObject *
286nu_char(const char *p, const formatdef *f)
287{
288 return PyString_FromStringAndSize(p, 1);
289}
290
291static PyObject *
292nu_byte(const char *p, const formatdef *f)
293{
294 return PyInt_FromLong((long) *(signed char *)p);
295}
296
297static PyObject *
298nu_ubyte(const char *p, const formatdef *f)
299{
300 return PyInt_FromLong((long) *(unsigned char *)p);
301}
302
303static PyObject *
304nu_short(const char *p, const formatdef *f)
305{
306 short x;
307 memcpy((char *)&x, p, sizeof x);
308 return PyInt_FromLong((long)x);
309}
310
311static PyObject *
312nu_ushort(const char *p, const formatdef *f)
313{
314 unsigned short x;
315 memcpy((char *)&x, p, sizeof x);
316 return PyInt_FromLong((long)x);
317}
318
319static PyObject *
320nu_int(const char *p, const formatdef *f)
321{
322 int x;
323 memcpy((char *)&x, p, sizeof x);
324 return PyInt_FromLong((long)x);
325}
326
327static PyObject *
328nu_uint(const char *p, const formatdef *f)
329{
330 unsigned int x;
331 memcpy((char *)&x, p, sizeof x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000332#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000333 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000334 return PyInt_FromLong((long)x);
335#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000336 return PyLong_FromUnsignedLong((unsigned long)x);
337}
338
339static PyObject *
340nu_long(const char *p, const formatdef *f)
341{
342 long x;
343 memcpy((char *)&x, p, sizeof x);
344 return PyInt_FromLong(x);
345}
346
347static PyObject *
348nu_ulong(const char *p, const formatdef *f)
349{
350 unsigned long x;
351 memcpy((char *)&x, p, sizeof x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000352#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000353 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000354 return PyInt_FromLong((long)x);
355#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000356 return PyLong_FromUnsignedLong(x);
357}
358
359/* Native mode doesn't support q or Q unless the platform C supports
360 long long (or, on Windows, __int64). */
361
362#ifdef HAVE_LONG_LONG
363
364static PyObject *
365nu_longlong(const char *p, const formatdef *f)
366{
367 PY_LONG_LONG x;
368 memcpy((char *)&x, p, sizeof x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000369#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000370 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000371 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
372#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000373 return PyLong_FromLongLong(x);
374}
375
376static PyObject *
377nu_ulonglong(const char *p, const formatdef *f)
378{
379 unsigned PY_LONG_LONG x;
380 memcpy((char *)&x, p, sizeof x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000381#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000382 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000383 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
384#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000385 return PyLong_FromUnsignedLongLong(x);
386}
387
388#endif
389
390static PyObject *
391nu_float(const char *p, const formatdef *f)
392{
393 float x;
394 memcpy((char *)&x, p, sizeof x);
395 return PyFloat_FromDouble((double)x);
396}
397
398static PyObject *
399nu_double(const char *p, const formatdef *f)
400{
401 double x;
402 memcpy((char *)&x, p, sizeof x);
403 return PyFloat_FromDouble(x);
404}
405
406static PyObject *
407nu_void_p(const char *p, const formatdef *f)
408{
409 void *x;
410 memcpy((char *)&x, p, sizeof x);
411 return PyLong_FromVoidPtr(x);
412}
413
414static int
415np_byte(char *p, PyObject *v, const formatdef *f)
416{
417 long x;
418 if (get_long(v, &x) < 0)
419 return -1;
420 if (x < -128 || x > 127){
421 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000422 "byte format requires -128 <= number <= 127");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000423 return -1;
424 }
425 *p = (char)x;
426 return 0;
427}
428
429static int
430np_ubyte(char *p, PyObject *v, const formatdef *f)
431{
432 long x;
433 if (get_long(v, &x) < 0)
434 return -1;
435 if (x < 0 || x > 255){
436 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000437 "ubyte format requires 0 <= number <= 255");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000438 return -1;
439 }
440 *p = (char)x;
441 return 0;
442}
443
444static int
445np_char(char *p, PyObject *v, const formatdef *f)
446{
447 if (!PyString_Check(v) || PyString_Size(v) != 1) {
448 PyErr_SetString(StructError,
449 "char format require string of length 1");
450 return -1;
451 }
452 *p = *PyString_AsString(v);
453 return 0;
454}
455
456static int
457np_short(char *p, PyObject *v, const formatdef *f)
458{
459 long x;
460 short y;
461 if (get_long(v, &x) < 0)
462 return -1;
463 if (x < SHRT_MIN || x > SHRT_MAX){
464 PyErr_SetString(StructError,
465 "short format requires " STRINGIFY(SHRT_MIN)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000466 " <= number <= " STRINGIFY(SHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000467 return -1;
468 }
469 y = (short)x;
470 memcpy(p, (char *)&y, sizeof y);
471 return 0;
472}
473
474static int
475np_ushort(char *p, PyObject *v, const formatdef *f)
476{
477 long x;
478 unsigned short y;
479 if (get_long(v, &x) < 0)
480 return -1;
481 if (x < 0 || x > USHRT_MAX){
482 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000483 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000484 return -1;
485 }
486 y = (unsigned short)x;
487 memcpy(p, (char *)&y, sizeof y);
488 return 0;
489}
490
491static int
492np_int(char *p, PyObject *v, const formatdef *f)
493{
494 long x;
495 int y;
496 if (get_long(v, &x) < 0)
497 return -1;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000498#if defined(PY_STRUCT_RANGE_CHECKING) && (SIZEOF_LONG > SIZEOF_INT)
499 if (x < INT_MIN || x > INT_MAX)
500 return _range_error(f->format, sizeof(y), 0);
501#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000502 y = (int)x;
503 memcpy(p, (char *)&y, sizeof y);
504 return 0;
505}
506
507static int
508np_uint(char *p, PyObject *v, const formatdef *f)
509{
510 unsigned long x;
511 unsigned int y;
512 if (get_ulong(v, &x) < 0)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000513#ifdef PY_STRUCT_RANGE_CHECKING
514 return _range_error(f->format, sizeof(y), 1);
515#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000516 return -1;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000517#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000518 y = (unsigned int)x;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000519#if defined(PY_STRUCT_RANGE_CHECKING) && (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolito685dda82006-05-26 14:23:21 +0000520 if (x > UINT_MAX)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000521 return _range_error(f->format, sizeof(y), 1);
522#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000523 memcpy(p, (char *)&y, sizeof y);
524 return 0;
525}
526
527static int
528np_long(char *p, PyObject *v, const formatdef *f)
529{
530 long x;
531 if (get_long(v, &x) < 0)
532 return -1;
533 memcpy(p, (char *)&x, sizeof x);
534 return 0;
535}
536
537static int
538np_ulong(char *p, PyObject *v, const formatdef *f)
539{
540 unsigned long x;
541 if (get_ulong(v, &x) < 0)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000542#ifdef PY_STRUCT_RANGE_CHECKING
543 return _range_error(f->format, sizeof(x), 1);
544#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000545 return -1;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000546#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000547 memcpy(p, (char *)&x, sizeof x);
548 return 0;
549}
550
551#ifdef HAVE_LONG_LONG
552
553static int
554np_longlong(char *p, PyObject *v, const formatdef *f)
555{
556 PY_LONG_LONG x;
557 if (get_longlong(v, &x) < 0)
558 return -1;
559 memcpy(p, (char *)&x, sizeof x);
560 return 0;
561}
562
563static int
564np_ulonglong(char *p, PyObject *v, const formatdef *f)
565{
566 unsigned PY_LONG_LONG x;
567 if (get_ulonglong(v, &x) < 0)
568 return -1;
569 memcpy(p, (char *)&x, sizeof x);
570 return 0;
571}
572#endif
573
574static int
575np_float(char *p, PyObject *v, const formatdef *f)
576{
577 float x = (float)PyFloat_AsDouble(v);
578 if (x == -1 && PyErr_Occurred()) {
579 PyErr_SetString(StructError,
580 "required argument is not a float");
581 return -1;
582 }
583 memcpy(p, (char *)&x, sizeof x);
584 return 0;
585}
586
587static int
588np_double(char *p, PyObject *v, const formatdef *f)
589{
590 double x = PyFloat_AsDouble(v);
591 if (x == -1 && PyErr_Occurred()) {
592 PyErr_SetString(StructError,
593 "required argument is not a float");
594 return -1;
595 }
596 memcpy(p, (char *)&x, sizeof(double));
597 return 0;
598}
599
600static int
601np_void_p(char *p, PyObject *v, const formatdef *f)
602{
603 void *x;
604
605 v = get_pylong(v);
606 if (v == NULL)
607 return -1;
608 assert(PyLong_Check(v));
609 x = PyLong_AsVoidPtr(v);
610 Py_DECREF(v);
611 if (x == NULL && PyErr_Occurred())
612 return -1;
613 memcpy(p, (char *)&x, sizeof x);
614 return 0;
615}
616
617static formatdef native_table[] = {
618 {'x', sizeof(char), 0, NULL},
619 {'b', sizeof(char), 0, nu_byte, np_byte},
620 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
621 {'c', sizeof(char), 0, nu_char, np_char},
622 {'s', sizeof(char), 0, NULL},
623 {'p', sizeof(char), 0, NULL},
624 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
625 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
626 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
627 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
628 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
629 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000630#ifdef HAVE_LONG_LONG
631 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
632 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
633#endif
Bob Ippolitoa99865b2006-05-25 19:56:56 +0000634 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
635 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
636 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000637 {0}
638};
639
640/* Big-endian routines. *****************************************************/
641
642static PyObject *
643bu_int(const char *p, const formatdef *f)
644{
645 long x = 0;
646 int i = f->size;
647 do {
648 x = (x<<8) | (*p++ & 0xFF);
649 } while (--i > 0);
650 /* Extend the sign bit. */
651 if (SIZEOF_LONG > f->size)
652 x |= -(x & (1L << (8*f->size - 1)));
653 return PyInt_FromLong(x);
654}
655
656static PyObject *
657bu_uint(const char *p, const formatdef *f)
658{
659 unsigned long x = 0;
660 int i = f->size;
661 do {
662 x = (x<<8) | (*p++ & 0xFF);
663 } while (--i > 0);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000664#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000665 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000666 return PyInt_FromLong((long)x);
Bob Ippolito3b0cae92006-05-25 19:15:27 +0000667#else
668 if (SIZEOF_LONG > f->size)
669 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000670#endif
671 return PyLong_FromUnsignedLong(x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000672}
673
674static PyObject *
675bu_longlong(const char *p, const formatdef *f)
676{
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000677#if HAVE_LONG_LONG
678 PY_LONG_LONG x = 0;
679 int i = f->size;
680 do {
681 x = (x<<8) | (*p++ & 0xFF);
682 } while (--i > 0);
683 /* Extend the sign bit. */
684 if (SIZEOF_LONG_LONG > f->size)
685 x |= -(x & (1L << (8 * f->size - 1)));
686#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000687 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000688 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
689#endif
690 return PyLong_FromLongLong(x);
691#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000692 return _PyLong_FromByteArray((const unsigned char *)p,
693 8,
694 0, /* little-endian */
695 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000696#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000697}
698
699static PyObject *
700bu_ulonglong(const char *p, const formatdef *f)
701{
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000702#if HAVE_LONG_LONG
703 unsigned PY_LONG_LONG x = 0;
704 int i = f->size;
705 do {
706 x = (x<<8) | (*p++ & 0xFF);
707 } while (--i > 0);
708#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000709 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000710 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
711#endif
712 return PyLong_FromUnsignedLongLong(x);
713#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000714 return _PyLong_FromByteArray((const unsigned char *)p,
715 8,
716 0, /* little-endian */
717 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000718#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000719}
720
721static PyObject *
722bu_float(const char *p, const formatdef *f)
723{
724 return unpack_float(p, 0);
725}
726
727static PyObject *
728bu_double(const char *p, const formatdef *f)
729{
730 return unpack_double(p, 0);
731}
732
733static int
734bp_int(char *p, PyObject *v, const formatdef *f)
735{
736 long x;
737 int i;
738 if (get_long(v, &x) < 0)
739 return -1;
740 i = f->size;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000741#ifdef PY_STRUCT_RANGE_CHECKING
742 if (i != SIZEOF_LONG && (
743 (i == 2 && (x < -32768 || x > 32767))
744#if SIZEOF_LONG != 4
745 || (i == 4) && (x < -2147483648L || x > -2147483647L)
746#endif
747 ))
748 return _range_error(f->format, i, 0);
749#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000750 do {
751 p[--i] = (char)x;
752 x >>= 8;
753 } while (i > 0);
754 return 0;
755}
756
757static int
758bp_uint(char *p, PyObject *v, const formatdef *f)
759{
760 unsigned long x;
761 int i;
762 if (get_ulong(v, &x) < 0)
763 return -1;
764 i = f->size;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000765#ifdef PY_STRUCT_RANGE_CHECKING
Bob Ippolito0cbf2c52006-05-26 16:23:28 +0000766 if (i != SIZEOF_LONG && x >= (1 << (((unsigned int)i) * 8)))
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000767 return _range_error(f->format, f->size, 1);
768#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000769 do {
770 p[--i] = (char)x;
771 x >>= 8;
772 } while (i > 0);
773 return 0;
774}
775
776static int
777bp_longlong(char *p, PyObject *v, const formatdef *f)
778{
779 int res;
780 v = get_pylong(v);
781 if (v == NULL)
782 return -1;
783 res = _PyLong_AsByteArray((PyLongObject *)v,
784 (unsigned char *)p,
785 8,
786 0, /* little_endian */
787 1 /* signed */);
788 Py_DECREF(v);
789 return res;
790}
791
792static int
793bp_ulonglong(char *p, PyObject *v, const formatdef *f)
794{
795 int res;
796 v = get_pylong(v);
797 if (v == NULL)
798 return -1;
799 res = _PyLong_AsByteArray((PyLongObject *)v,
800 (unsigned char *)p,
801 8,
802 0, /* little_endian */
803 0 /* signed */);
804 Py_DECREF(v);
805 return res;
806}
807
808static int
809bp_float(char *p, PyObject *v, const formatdef *f)
810{
811 double x = PyFloat_AsDouble(v);
812 if (x == -1 && PyErr_Occurred()) {
813 PyErr_SetString(StructError,
814 "required argument is not a float");
815 return -1;
816 }
817 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
818}
819
820static int
821bp_double(char *p, PyObject *v, const formatdef *f)
822{
823 double x = PyFloat_AsDouble(v);
824 if (x == -1 && PyErr_Occurred()) {
825 PyErr_SetString(StructError,
826 "required argument is not a float");
827 return -1;
828 }
829 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
830}
831
832static formatdef bigendian_table[] = {
833 {'x', 1, 0, NULL},
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000834 {'b', 1, 0, nu_byte, np_byte},
835 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000836 {'c', 1, 0, nu_char, np_char},
837 {'s', 1, 0, NULL},
838 {'p', 1, 0, NULL},
839 {'h', 2, 0, bu_int, bp_int},
840 {'H', 2, 0, bu_uint, bp_uint},
841 {'i', 4, 0, bu_int, bp_int},
842 {'I', 4, 0, bu_uint, bp_uint},
843 {'l', 4, 0, bu_int, bp_int},
844 {'L', 4, 0, bu_uint, bp_uint},
845 {'q', 8, 0, bu_longlong, bp_longlong},
846 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
847 {'f', 4, 0, bu_float, bp_float},
848 {'d', 8, 0, bu_double, bp_double},
849 {0}
850};
851
852/* Little-endian routines. *****************************************************/
853
854static PyObject *
855lu_int(const char *p, const formatdef *f)
856{
857 long x = 0;
858 int i = f->size;
859 do {
860 x = (x<<8) | (p[--i] & 0xFF);
861 } while (i > 0);
862 /* Extend the sign bit. */
863 if (SIZEOF_LONG > f->size)
864 x |= -(x & (1L << (8*f->size - 1)));
865 return PyInt_FromLong(x);
866}
867
868static PyObject *
869lu_uint(const char *p, const formatdef *f)
870{
871 unsigned long x = 0;
872 int i = f->size;
873 do {
874 x = (x<<8) | (p[--i] & 0xFF);
875 } while (i > 0);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000876#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000877 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000878 return PyInt_FromLong((long)x);
Bob Ippolito3b0cae92006-05-25 19:15:27 +0000879#else
880 if (SIZEOF_LONG > f->size)
881 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000882#endif
883 return PyLong_FromUnsignedLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000884}
885
886static PyObject *
887lu_longlong(const char *p, const formatdef *f)
888{
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000889#if HAVE_LONG_LONG
890 PY_LONG_LONG x = 0;
891 int i = f->size;
892 do {
893 x = (x<<8) | (p[--i] & 0xFF);
894 } while (i > 0);
895 /* Extend the sign bit. */
896 if (SIZEOF_LONG_LONG > f->size)
897 x |= -(x & (1L << (8 * f->size - 1)));
898#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000899 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000900 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
901#endif
902 return PyLong_FromLongLong(x);
903#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000904 return _PyLong_FromByteArray((const unsigned char *)p,
905 8,
906 1, /* little-endian */
907 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000908#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000909}
910
911static PyObject *
912lu_ulonglong(const char *p, const formatdef *f)
913{
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000914#if HAVE_LONG_LONG
915 unsigned PY_LONG_LONG x = 0;
916 int i = f->size;
917 do {
918 x = (x<<8) | (p[--i] & 0xFF);
919 } while (i > 0);
920#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000921 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000922 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
923#endif
924 return PyLong_FromUnsignedLongLong(x);
925#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000926 return _PyLong_FromByteArray((const unsigned char *)p,
927 8,
928 1, /* little-endian */
929 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000930#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000931}
932
933static PyObject *
934lu_float(const char *p, const formatdef *f)
935{
936 return unpack_float(p, 1);
937}
938
939static PyObject *
940lu_double(const char *p, const formatdef *f)
941{
942 return unpack_double(p, 1);
943}
944
945static int
946lp_int(char *p, PyObject *v, const formatdef *f)
947{
948 long x;
949 int i;
950 if (get_long(v, &x) < 0)
951 return -1;
952 i = f->size;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000953#ifdef PY_STRUCT_RANGE_CHECKING
954 if (i != SIZEOF_LONG && (
955 (i == 2 && (x < -32768 || x > 32767))
956#if SIZEOF_LONG != 4
957 || (i == 4) && (x < -2147483648L || x > -2147483647L)
958#endif
959 ))
960 return _range_error(f->format, i, 0);
961#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000962 do {
963 *p++ = (char)x;
964 x >>= 8;
965 } while (--i > 0);
966 return 0;
967}
968
969static int
970lp_uint(char *p, PyObject *v, const formatdef *f)
971{
972 unsigned long x;
973 int i;
974 if (get_ulong(v, &x) < 0)
975 return -1;
976 i = f->size;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000977#ifdef PY_STRUCT_RANGE_CHECKING
Bob Ippolito0cbf2c52006-05-26 16:23:28 +0000978 if (i != SIZEOF_LONG && x >= (1 << (((unsigned int)i) * 8)))
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000979 return _range_error(f->format, f->size, 1);
980#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000981 do {
982 *p++ = (char)x;
983 x >>= 8;
984 } while (--i > 0);
985 return 0;
986}
987
988static int
989lp_longlong(char *p, PyObject *v, const formatdef *f)
990{
991 int res;
992 v = get_pylong(v);
993 if (v == NULL)
994 return -1;
995 res = _PyLong_AsByteArray((PyLongObject*)v,
996 (unsigned char *)p,
997 8,
998 1, /* little_endian */
999 1 /* signed */);
1000 Py_DECREF(v);
1001 return res;
1002}
1003
1004static int
1005lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1006{
1007 int res;
1008 v = get_pylong(v);
1009 if (v == NULL)
1010 return -1;
1011 res = _PyLong_AsByteArray((PyLongObject*)v,
1012 (unsigned char *)p,
1013 8,
1014 1, /* little_endian */
1015 0 /* signed */);
1016 Py_DECREF(v);
1017 return res;
1018}
1019
1020static int
1021lp_float(char *p, PyObject *v, const formatdef *f)
1022{
1023 double x = PyFloat_AsDouble(v);
1024 if (x == -1 && PyErr_Occurred()) {
1025 PyErr_SetString(StructError,
1026 "required argument is not a float");
1027 return -1;
1028 }
1029 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1030}
1031
1032static int
1033lp_double(char *p, PyObject *v, const formatdef *f)
1034{
1035 double x = PyFloat_AsDouble(v);
1036 if (x == -1 && PyErr_Occurred()) {
1037 PyErr_SetString(StructError,
1038 "required argument is not a float");
1039 return -1;
1040 }
1041 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1042}
1043
1044static formatdef lilendian_table[] = {
1045 {'x', 1, 0, NULL},
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001046 {'b', 1, 0, nu_byte, np_byte},
1047 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001048 {'c', 1, 0, nu_char, np_char},
1049 {'s', 1, 0, NULL},
1050 {'p', 1, 0, NULL},
1051 {'h', 2, 0, lu_int, lp_int},
1052 {'H', 2, 0, lu_uint, lp_uint},
1053 {'i', 4, 0, lu_int, lp_int},
1054 {'I', 4, 0, lu_uint, lp_uint},
1055 {'l', 4, 0, lu_int, lp_int},
1056 {'L', 4, 0, lu_uint, lp_uint},
1057 {'q', 8, 0, lu_longlong, lp_longlong},
1058 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1059 {'f', 4, 0, lu_float, lp_float},
1060 {'d', 8, 0, lu_double, lp_double},
1061 {0}
1062};
1063
1064
1065static const formatdef *
1066whichtable(char **pfmt)
1067{
1068 const char *fmt = (*pfmt)++; /* May be backed out of later */
1069 switch (*fmt) {
1070 case '<':
1071 return lilendian_table;
1072 case '>':
1073 case '!': /* Network byte order is big-endian */
1074 return bigendian_table;
1075 case '=': { /* Host byte order -- different from native in aligment! */
1076 int n = 1;
1077 char *p = (char *) &n;
1078 if (*p == 1)
1079 return lilendian_table;
1080 else
1081 return bigendian_table;
1082 }
1083 default:
1084 --*pfmt; /* Back out of pointer increment */
1085 /* Fall through */
1086 case '@':
1087 return native_table;
1088 }
1089}
1090
1091
1092/* Get the table entry for a format code */
1093
1094static const formatdef *
1095getentry(int c, const formatdef *f)
1096{
1097 for (; f->format != '\0'; f++) {
1098 if (f->format == c) {
1099 return f;
1100 }
1101 }
1102 PyErr_SetString(StructError, "bad char in struct format");
1103 return NULL;
1104}
1105
1106
1107/* Align a size according to a format code */
1108
1109static int
1110align(int size, int c, const formatdef *e)
1111{
1112 if (e->format == c) {
1113 if (e->alignment) {
1114 size = ((size + e->alignment - 1)
1115 / e->alignment)
1116 * e->alignment;
1117 }
1118 }
1119 return size;
1120}
1121
1122
1123/* calculate the size of a format string */
1124
1125static int
1126prepare_s(PyStructObject *self)
1127{
1128 const formatdef *f;
1129 const formatdef *e;
1130 formatcode *codes;
1131
1132 const char *s;
1133 const char *fmt;
1134 char c;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001135 int size, len, num, itemsize, x;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001136
1137 fmt = PyString_AS_STRING(self->s_format);
1138
1139 f = whichtable((char **)&fmt);
1140
1141 s = fmt;
1142 size = 0;
1143 len = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001144 while ((c = *s++) != '\0') {
1145 if (isspace(Py_CHARMASK(c)))
1146 continue;
1147 if ('0' <= c && c <= '9') {
1148 num = c - '0';
1149 while ('0' <= (c = *s++) && c <= '9') {
1150 x = num*10 + (c - '0');
1151 if (x/10 != num) {
1152 PyErr_SetString(
1153 StructError,
1154 "overflow in item count");
1155 return -1;
1156 }
1157 num = x;
1158 }
1159 if (c == '\0')
1160 break;
1161 }
1162 else
1163 num = 1;
1164
1165 e = getentry(c, f);
1166 if (e == NULL)
1167 return -1;
1168
1169 switch (c) {
1170 case 's': /* fall through */
1171 case 'p': len++; break;
1172 case 'x': break;
1173 default: len += num; break;
1174 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001175
1176 itemsize = e->size;
1177 size = align(size, c, e);
1178 x = num * itemsize;
1179 size += x;
1180 if (x/itemsize != num || size < 0) {
1181 PyErr_SetString(StructError,
1182 "total struct size too long");
1183 return -1;
1184 }
1185 }
1186
1187 self->s_size = size;
1188 self->s_len = len;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001189 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
Bob Ippolito232f3c92006-05-23 19:12:41 +00001190 if (codes == NULL) {
1191 PyErr_NoMemory();
1192 return -1;
1193 }
1194 self->s_codes = codes;
1195
1196 s = fmt;
1197 size = 0;
1198 while ((c = *s++) != '\0') {
1199 if (isspace(Py_CHARMASK(c)))
1200 continue;
1201 if ('0' <= c && c <= '9') {
1202 num = c - '0';
1203 while ('0' <= (c = *s++) && c <= '9')
1204 num = num*10 + (c - '0');
1205 if (c == '\0')
1206 break;
1207 }
1208 else
1209 num = 1;
1210
1211 e = getentry(c, f);
1212
1213 size = align(size, c, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001214 if (c == 's' || c == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001215 codes->offset = size;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001216 codes->size = num;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001217 codes->fmtdef = e;
1218 codes++;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001219 size += num;
1220 } else if (c == 'x') {
1221 size += num;
1222 } else {
1223 while (--num >= 0) {
1224 codes->offset = size;
1225 codes->size = e->size;
1226 codes->fmtdef = e;
1227 codes++;
1228 size += e->size;
1229 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001230 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001231 }
1232 codes->fmtdef = NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001233 codes->offset = size;
1234 codes->size = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001235
1236 return 0;
1237}
1238
1239static PyObject *
1240s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1241{
1242 PyObject *self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001243
1244 assert(type != NULL && type->tp_alloc != NULL);
1245
1246 self = type->tp_alloc(type, 0);
1247 if (self != NULL) {
1248 PyStructObject *s = (PyStructObject*)self;
1249 Py_INCREF(Py_None);
1250 s->s_format = Py_None;
1251 s->s_codes = NULL;
1252 s->s_size = -1;
1253 s->s_len = -1;
1254 }
1255 return self;
1256}
1257
1258static int
1259s_init(PyObject *self, PyObject *args, PyObject *kwds)
1260{
1261 PyStructObject *soself = (PyStructObject *)self;
1262 PyObject *o_format = NULL;
1263 int ret = 0;
1264 static char *kwlist[] = {"format", 0};
1265
1266 assert(PyStruct_Check(self));
1267
1268 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1269 &o_format))
1270 return -1;
1271
1272 Py_INCREF(o_format);
1273 Py_XDECREF(soself->s_format);
1274 soself->s_format = o_format;
1275
1276 ret = prepare_s(soself);
1277 return ret;
1278}
1279
1280static void
1281s_dealloc(PyStructObject *s)
1282{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001283 if (s->weakreflist != NULL)
1284 PyObject_ClearWeakRefs((PyObject *)s);
1285 if (s->s_codes != NULL) {
1286 PyMem_FREE(s->s_codes);
1287 }
1288 Py_XDECREF(s->s_format);
1289 s->ob_type->tp_free((PyObject *)s);
1290}
1291
Bob Ippolitoeb621272006-05-24 15:32:06 +00001292static PyObject *
1293s_unpack_internal(PyStructObject *soself, char *startfrom) {
1294 formatcode *code;
1295 Py_ssize_t i = 0;
1296 PyObject *result = PyTuple_New(soself->s_len);
1297 if (result == NULL)
1298 return NULL;
1299
1300 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1301 PyObject *v;
1302 const formatdef *e = code->fmtdef;
1303 const char *res = startfrom + code->offset;
1304 if (e->format == 's') {
1305 v = PyString_FromStringAndSize(res, code->size);
1306 if (v == NULL)
1307 goto fail;
1308 PyTuple_SET_ITEM(result, i++, v);
1309 } else if (e->format == 'p') {
1310 Py_ssize_t n = *(unsigned char*)res;
1311 if (n >= code->size)
1312 n = code->size - 1;
1313 v = PyString_FromStringAndSize(res + 1, n);
1314 if (v == NULL)
1315 goto fail;
1316 PyTuple_SET_ITEM(result, i++, v);
1317 } else {
1318 v = e->unpack(res, e);
1319 if (v == NULL)
1320 goto fail;
1321 PyTuple_SET_ITEM(result, i++, v);
1322 }
1323 }
1324
1325 return result;
1326fail:
1327 Py_DECREF(result);
1328 return NULL;
1329};
1330
1331
Bob Ippolito232f3c92006-05-23 19:12:41 +00001332PyDoc_STRVAR(s_unpack__doc__,
1333"unpack(str) -> (v1, v2, ...)\n\
1334\n\
1335Return tuple containing values unpacked according to this Struct's format.\n\
1336Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1337strings.");
1338
1339static PyObject *
1340s_unpack(PyObject *self, PyObject *inputstr)
1341{
Bob Ippolitoeb621272006-05-24 15:32:06 +00001342 PyStructObject *soself = (PyStructObject *)self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001343 assert(PyStruct_Check(self));
1344 assert(soself->s_codes != NULL);
1345 if (inputstr == NULL || !PyString_Check(inputstr) ||
Bob Ippolitoeb621272006-05-24 15:32:06 +00001346 PyString_GET_SIZE(inputstr) != soself->s_size) {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001347 PyErr_Format(StructError,
1348 "unpack requires a string argument of length %d", soself->s_size);
1349 return NULL;
1350 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001351 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1352}
1353
1354PyDoc_STRVAR(s_unpack_from__doc__,
1355"unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1356\n\
1357Return tuple containing values unpacked according to this Struct's format.\n\
1358Unlike unpack, unpack_from can unpack values from any object supporting\n\
1359the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1360See struct.__doc__ for more on format strings.");
1361
1362static PyObject *
1363s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1364{
1365 static char *kwlist[] = {"buffer", "offset", 0};
1366#if (PY_VERSION_HEX < 0x02050000)
1367 static char *fmt = "z#|i:unpack_from";
1368#else
1369 static char *fmt = "z#|n:unpack_from";
1370#endif
1371 Py_ssize_t buffer_len = 0, offset = 0;
1372 char *buffer = NULL;
1373 PyStructObject *soself = (PyStructObject *)self;
1374 assert(PyStruct_Check(self));
1375 assert(soself->s_codes != NULL);
1376
1377 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1378 &buffer, &buffer_len, &offset))
1379 return NULL;
1380
1381 if (buffer == NULL) {
1382 PyErr_Format(StructError,
1383 "unpack_from requires a buffer argument");
Bob Ippolito232f3c92006-05-23 19:12:41 +00001384 return NULL;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001385 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001386
1387 if (offset < 0)
1388 offset += buffer_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001389
Bob Ippolitoeb621272006-05-24 15:32:06 +00001390 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1391 PyErr_Format(StructError,
1392 "unpack_from requires a buffer of at least %d bytes",
1393 soself->s_size);
1394 return NULL;
1395 }
1396 return s_unpack_internal(soself, buffer + offset);
1397}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001398
Bob Ippolito232f3c92006-05-23 19:12:41 +00001399
Martin Blais2856e5f2006-05-26 12:03:27 +00001400/*
1401 * Guts of the pack function.
1402 *
1403 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1404 * argument for where to start processing the arguments for packing, and a
1405 * character buffer for writing the packed string. The caller must insure
1406 * that the buffer may contain the required length for packing the arguments.
1407 * 0 is returned on success, 1 is returned if there is an error.
1408 *
1409 */
1410static int
1411s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001412{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001413 formatcode *code;
1414 Py_ssize_t i;
Martin Blais2856e5f2006-05-26 12:03:27 +00001415
1416 memset(buf, '\0', soself->s_size);
1417 i = offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001418 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1419 Py_ssize_t n;
1420 PyObject *v;
1421 const formatdef *e = code->fmtdef;
Martin Blais2856e5f2006-05-26 12:03:27 +00001422 char *res = buf + code->offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001423 if (e->format == 's') {
1424 v = PyTuple_GET_ITEM(args, i++);
1425 if (!PyString_Check(v)) {
1426 PyErr_SetString(StructError,
1427 "argument for 's' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001428 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001429 }
1430 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001431 if (n > code->size)
1432 n = code->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001433 if (n > 0)
1434 memcpy(res, PyString_AS_STRING(v), n);
1435 } else if (e->format == 'p') {
1436 v = PyTuple_GET_ITEM(args, i++);
1437 if (!PyString_Check(v)) {
1438 PyErr_SetString(StructError,
1439 "argument for 'p' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001440 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001441 }
1442 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001443 if (n > (code->size - 1))
1444 n = code->size - 1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001445 if (n > 0)
1446 memcpy(res + 1, PyString_AS_STRING(v), n);
1447 if (n > 255)
1448 n = 255;
1449 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1450 } else {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001451 v = PyTuple_GET_ITEM(args, i++);
1452 if (e->pack(res, v, e) < 0)
Martin Blais2856e5f2006-05-26 12:03:27 +00001453 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001454 }
1455 }
1456
Martin Blais2856e5f2006-05-26 12:03:27 +00001457 /* Success */
1458 return 0;
1459}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001460
Martin Blais2856e5f2006-05-26 12:03:27 +00001461
1462PyDoc_STRVAR(s_pack__doc__,
1463"pack(v1, v2, ...) -> string\n\
1464\n\
1465Return a string containing values v1, v2, ... packed according to this\n\
1466Struct's format. See struct.__doc__ for more on format strings.");
1467
1468static PyObject *
1469s_pack(PyObject *self, PyObject *args)
1470{
1471 PyStructObject *soself;
1472 PyObject *result;
1473
1474 /* Validate arguments. */
1475 soself = (PyStructObject *)self;
1476 assert(PyStruct_Check(self));
1477 assert(soself->s_codes != NULL);
1478 if (args == NULL || !PyTuple_Check(args) ||
1479 PyTuple_GET_SIZE(args) != soself->s_len)
1480 {
1481 PyErr_Format(StructError,
1482 "pack requires exactly %d arguments", soself->s_len);
1483 return NULL;
1484 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001485
Martin Blais2856e5f2006-05-26 12:03:27 +00001486 /* Allocate a new string */
1487 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1488 if (result == NULL)
1489 return NULL;
1490
1491 /* Call the guts */
1492 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1493 Py_DECREF(result);
1494 return NULL;
1495 }
1496
1497 return result;
1498}
1499
1500PyDoc_STRVAR(s_pack_to__doc__,
1501"pack_to(buffer, offset, v1, v2, ...)\n\
1502\n\
1503Pack the values v2, v2, ... according to this Struct's format, write \n\
1504the packed bytes into the given buffer at the given offset. Note that \n\
1505the offset is not an optional argument. See struct.__doc__ for \n\
1506more on format strings.");
1507
1508static PyObject *
1509s_pack_to(PyObject *self, PyObject *args)
1510{
1511 PyStructObject *soself;
1512 char *buffer;
1513 Py_ssize_t buffer_len, offset;
1514
1515 /* Validate arguments. +1 is for the first arg as buffer. */
1516 soself = (PyStructObject *)self;
1517 assert(PyStruct_Check(self));
1518 assert(soself->s_codes != NULL);
1519 if (args == NULL || !PyTuple_Check(args) ||
1520 PyTuple_GET_SIZE(args) != (soself->s_len + 2))
1521 {
1522 PyErr_Format(StructError,
1523 "pack_to requires exactly %d arguments",
1524 (soself->s_len + 2));
1525 return NULL;
1526 }
1527
1528 /* Extract a writable memory buffer from the first argument */
1529 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1530 (void**)&buffer, &buffer_len) == -1 ) {
1531 return NULL;
1532 }
1533 assert( buffer_len >= 0 );
1534
1535 /* Extract the offset from the first argument */
1536 offset = PyInt_AsLong(PyTuple_GET_ITEM(args, 1));
1537
1538 /* Support negative offsets. */
1539 if (offset < 0)
1540 offset += buffer_len;
1541
1542 /* Check boundaries */
1543 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1544 PyErr_Format(StructError,
1545 "pack_to requires a buffer of at least %d bytes",
1546 soself->s_size);
1547 return NULL;
1548 }
1549
1550 /* Call the guts */
1551 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1552 return NULL;
1553 }
1554
1555 return Py_None;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001556}
1557
1558
1559/* List of functions */
1560
1561static struct PyMethodDef s_methods[] = {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001562 {"pack", (PyCFunction)s_pack, METH_VARARGS, s_pack__doc__},
Martin Blais2856e5f2006-05-26 12:03:27 +00001563 {"pack_to", (PyCFunction)s_pack_to, METH_VARARGS, s_pack_to__doc__},
Bob Ippolitoeb621272006-05-24 15:32:06 +00001564 {"unpack", (PyCFunction)s_unpack, METH_O, s_unpack__doc__},
1565 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001566 {NULL, NULL} /* sentinel */
1567};
1568
1569PyDoc_STRVAR(s__doc__, "Compiled struct object");
1570
1571#define OFF(x) offsetof(PyStructObject, x)
1572
1573static PyMemberDef s_memberlist[] = {
1574 {"format", T_OBJECT, OFF(s_format), RO,
1575 "struct format string"},
1576 {"size", T_INT, OFF(s_size), RO,
1577 "struct size in bytes"},
1578 {"_len", T_INT, OFF(s_len), RO,
1579 "number of items expected in tuple"},
1580 {NULL} /* Sentinel */
1581};
1582
1583
1584static
1585PyTypeObject PyStructType = {
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001586 PyObject_HEAD_INIT(NULL)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001587 0,
1588 "Struct",
1589 sizeof(PyStructObject),
1590 0,
1591 (destructor)s_dealloc, /* tp_dealloc */
1592 0, /* tp_print */
1593 0, /* tp_getattr */
1594 0, /* tp_setattr */
1595 0, /* tp_compare */
1596 0, /* tp_repr */
1597 0, /* tp_as_number */
1598 0, /* tp_as_sequence */
1599 0, /* tp_as_mapping */
1600 0, /* tp_hash */
1601 0, /* tp_call */
1602 0, /* tp_str */
1603 PyObject_GenericGetAttr, /* tp_getattro */
1604 PyObject_GenericSetAttr, /* tp_setattro */
1605 0, /* tp_as_buffer */
1606 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
1607 s__doc__, /* tp_doc */
1608 0, /* tp_traverse */
1609 0, /* tp_clear */
1610 0, /* tp_richcompare */
1611 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1612 0, /* tp_iter */
1613 0, /* tp_iternext */
1614 s_methods, /* tp_methods */
1615 s_memberlist, /* tp_members */
1616 0, /* tp_getset */
1617 0, /* tp_base */
1618 0, /* tp_dict */
1619 0, /* tp_descr_get */
1620 0, /* tp_descr_set */
1621 0, /* tp_dictoffset */
1622 s_init, /* tp_init */
1623 PyType_GenericAlloc, /* tp_alloc */
1624 s_new, /* tp_new */
1625 PyObject_Del, /* tp_free */
1626};
1627
1628/* Module initialization */
1629
1630PyMODINIT_FUNC
1631init_struct(void)
1632{
1633 PyObject *m = Py_InitModule("_struct", NULL);
1634 if (m == NULL)
1635 return;
1636
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001637 PyStructType.ob_type = &PyType_Type;
1638 if (PyType_Ready(&PyStructType) < 0)
1639 return;
1640
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001641 /* Check endian and swap in faster functions */
1642 {
1643 int one = 1;
1644 formatdef *native = native_table;
1645 formatdef *other, *ptr;
1646 if ((int)*(unsigned char*)&one)
1647 other = lilendian_table;
1648 else
1649 other = bigendian_table;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001650 /* Scan through the native table, find a matching
1651 entry in the endian table and swap in the
1652 native implementations whenever possible
1653 (64-bit platforms may not have "standard" sizes) */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001654 while (native->format != '\0' && other->format != '\0') {
1655 ptr = other;
1656 while (ptr->format != '\0') {
1657 if (ptr->format == native->format) {
Bob Ippolito964e02a2006-05-25 21:09:45 +00001658 /* Match faster when formats are
1659 listed in the same order */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001660 if (ptr == other)
1661 other++;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001662 /* Only use the trick if the
1663 size matches */
1664 if (ptr->size != native->size)
1665 break;
1666 /* Skip float and double, could be
1667 "unknown" float format */
1668 if (ptr->format == 'd' || ptr->format == 'f')
1669 break;
1670 ptr->pack = native->pack;
1671 ptr->unpack = native->unpack;
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001672 break;
1673 }
1674 ptr++;
1675 }
1676 native++;
1677 }
1678 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001679
Bob Ippolito232f3c92006-05-23 19:12:41 +00001680 /* Add some symbolic constants to the module */
1681 if (StructError == NULL) {
1682 StructError = PyErr_NewException("struct.error", NULL, NULL);
1683 if (StructError == NULL)
1684 return;
1685 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001686
Bob Ippolito232f3c92006-05-23 19:12:41 +00001687 Py_INCREF(StructError);
1688 PyModule_AddObject(m, "error", StructError);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001689
Bob Ippolito232f3c92006-05-23 19:12:41 +00001690 Py_INCREF((PyObject*)&PyStructType);
1691 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
1692}