blob: 6d7a58ed4638646808a35c9a5c6bc3f606267a1f [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 Ippolito94f68ee2006-05-25 18:44:50 +000019/* PY_USE_INT_WHEN_POSSIBLE is an experimental flag that changes the
20 struct API to return int instead of long when possible. This is
21 often a significant performance improvement. */
22/*
23#define PY_USE_INT_WHEN_POSSIBLE 1
24*/
Bob Ippolito232f3c92006-05-23 19:12:41 +000025
Bob Ippolitoe27337b2006-05-26 13:15:44 +000026/* PY_STRUCT_RANGE_CHECKING performs range checking on all arguments
27 to be packed. This will break some incorrect code that happened
28 to accidentally do the right thing anyway (such as binhex). */
29#define PY_STRUCT_RANGE_CHECKING 1
Bob Ippolito232f3c92006-05-23 19:12:41 +000030
31/* The translation function for each format character is table driven */
Bob Ippolito232f3c92006-05-23 19:12:41 +000032typedef struct _formatdef {
33 char format;
34 int size;
35 int alignment;
36 PyObject* (*unpack)(const char *,
37 const struct _formatdef *);
38 int (*pack)(char *, PyObject *,
39 const struct _formatdef *);
40} formatdef;
41
42typedef struct _formatcode {
43 const struct _formatdef *fmtdef;
44 int offset;
Bob Ippolitoeb621272006-05-24 15:32:06 +000045 int size;
Bob Ippolito232f3c92006-05-23 19:12:41 +000046} formatcode;
47
48/* Struct object interface */
49
50typedef struct {
51 PyObject_HEAD
52 int s_size;
53 int s_len;
54 formatcode *s_codes;
55 PyObject *s_format;
56 PyObject *weakreflist; /* List of weak references */
57} PyStructObject;
58
Bob Ippolitoeb621272006-05-24 15:32:06 +000059
Bob Ippolito07c023b2006-05-23 19:32:25 +000060#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
61#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
Bob Ippolito232f3c92006-05-23 19:12:41 +000062
63
64/* Exception */
65
66static PyObject *StructError;
67
68
69/* Define various structs to figure out the alignments of types */
70
71
72typedef struct { char c; short x; } st_short;
73typedef struct { char c; int x; } st_int;
74typedef struct { char c; long x; } st_long;
75typedef struct { char c; float x; } st_float;
76typedef struct { char c; double x; } st_double;
77typedef struct { char c; void *x; } st_void_p;
78
79#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
80#define INT_ALIGN (sizeof(st_int) - sizeof(int))
81#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
82#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
83#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
84#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
85
86/* We can't support q and Q in native mode unless the compiler does;
87 in std mode, they're 8 bytes on all platforms. */
88#ifdef HAVE_LONG_LONG
89typedef struct { char c; PY_LONG_LONG x; } s_long_long;
90#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
91#endif
92
93#define STRINGIFY(x) #x
94
95#ifdef __powerc
96#pragma options align=reset
97#endif
98
99/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
100
101static PyObject *
102get_pylong(PyObject *v)
103{
104 PyNumberMethods *m;
105
106 assert(v != NULL);
107 if (PyInt_Check(v))
108 return PyLong_FromLong(PyInt_AS_LONG(v));
109 if (PyLong_Check(v)) {
110 Py_INCREF(v);
111 return v;
112 }
113 m = v->ob_type->tp_as_number;
114 if (m != NULL && m->nb_long != NULL) {
115 v = m->nb_long(v);
116 if (v == NULL)
117 return NULL;
118 if (PyLong_Check(v))
119 return v;
120 Py_DECREF(v);
121 }
122 PyErr_SetString(StructError,
123 "cannot convert argument to long");
124 return NULL;
125}
126
127/* Helper routine to get a Python integer and raise the appropriate error
128 if it isn't one */
129
130static int
131get_long(PyObject *v, long *p)
132{
133 long x = PyInt_AsLong(v);
134 if (x == -1 && PyErr_Occurred()) {
135 if (PyErr_ExceptionMatches(PyExc_TypeError))
136 PyErr_SetString(StructError,
137 "required argument is not an integer");
138 return -1;
139 }
140 *p = x;
141 return 0;
142}
143
144
145/* Same, but handling unsigned long */
146
147static int
148get_ulong(PyObject *v, unsigned long *p)
149{
150 if (PyLong_Check(v)) {
151 unsigned long x = PyLong_AsUnsignedLong(v);
152 if (x == (unsigned long)(-1) && PyErr_Occurred())
153 return -1;
154 *p = x;
155 return 0;
156 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000157 if (get_long(v, (long *)p) < 0)
158 return -1;
159 if (((long)*p) < 0) {
160 PyErr_SetString(StructError,
161 "unsigned argument is < 0");
162 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000163 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000164 return 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000165}
166
167#ifdef HAVE_LONG_LONG
168
169/* Same, but handling native long long. */
170
171static int
172get_longlong(PyObject *v, PY_LONG_LONG *p)
173{
174 PY_LONG_LONG x;
175
176 v = get_pylong(v);
177 if (v == NULL)
178 return -1;
179 assert(PyLong_Check(v));
180 x = PyLong_AsLongLong(v);
181 Py_DECREF(v);
182 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
183 return -1;
184 *p = x;
185 return 0;
186}
187
188/* Same, but handling native unsigned long long. */
189
190static int
191get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
192{
193 unsigned PY_LONG_LONG x;
194
195 v = get_pylong(v);
196 if (v == NULL)
197 return -1;
198 assert(PyLong_Check(v));
199 x = PyLong_AsUnsignedLongLong(v);
200 Py_DECREF(v);
201 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
202 return -1;
203 *p = x;
204 return 0;
205}
206
207#endif
208
209/* Floating point helpers */
210
211static PyObject *
212unpack_float(const char *p, /* start of 4-byte string */
213 int le) /* true for little-endian, false for big-endian */
214{
215 double x;
216
217 x = _PyFloat_Unpack4((unsigned char *)p, le);
218 if (x == -1.0 && PyErr_Occurred())
219 return NULL;
220 return PyFloat_FromDouble(x);
221}
222
223static PyObject *
224unpack_double(const char *p, /* start of 8-byte string */
225 int le) /* true for little-endian, false for big-endian */
226{
227 double x;
228
229 x = _PyFloat_Unpack8((unsigned char *)p, le);
230 if (x == -1.0 && PyErr_Occurred())
231 return NULL;
232 return PyFloat_FromDouble(x);
233}
234
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000235#ifdef PY_STRUCT_RANGE_CHECKING
236/* Helper to format the range error exceptions */
237static int
238_range_error(char format, int size, int is_unsigned)
239{
240 if (is_unsigned == 0) {
241 long smallest = 0, largest = 0;
242 int i = size * 8;
243 while (--i > 0) {
244 smallest = (smallest * 2) - 1;
245 largest = (largest * 2) + 1;
246 }
247 PyErr_Format(StructError,
248 "'%c' format requires %ld <= number <= %ld",
249 format,
250 smallest,
251 largest);
252 } else {
253 unsigned long largest = 0;
254 int i = size * 8;
255 while (--i >= 0)
256 largest = (largest * 2) + 1;
257 PyErr_Format(StructError,
258 "'%c' format requires 0 <= number <= %lu",
259 format,
260 largest);
261 }
262 return -1;
263}
264#endif
265
266
Bob Ippolito232f3c92006-05-23 19:12:41 +0000267
268/* A large number of small routines follow, with names of the form
269
270 [bln][up]_TYPE
271
272 [bln] distiguishes among big-endian, little-endian and native.
273 [pu] distiguishes between pack (to struct) and unpack (from struct).
274 TYPE is one of char, byte, ubyte, etc.
275*/
276
277/* Native mode routines. ****************************************************/
278/* NOTE:
279 In all n[up]_<type> routines handling types larger than 1 byte, there is
280 *no* guarantee that the p pointer is properly aligned for each type,
281 therefore memcpy is called. An intermediate variable is used to
282 compensate for big-endian architectures.
283 Normally both the intermediate variable and the memcpy call will be
284 skipped by C optimisation in little-endian architectures (gcc >= 2.91
285 does this). */
286
287static PyObject *
288nu_char(const char *p, const formatdef *f)
289{
290 return PyString_FromStringAndSize(p, 1);
291}
292
293static PyObject *
294nu_byte(const char *p, const formatdef *f)
295{
296 return PyInt_FromLong((long) *(signed char *)p);
297}
298
299static PyObject *
300nu_ubyte(const char *p, const formatdef *f)
301{
302 return PyInt_FromLong((long) *(unsigned char *)p);
303}
304
305static PyObject *
306nu_short(const char *p, const formatdef *f)
307{
308 short x;
309 memcpy((char *)&x, p, sizeof x);
310 return PyInt_FromLong((long)x);
311}
312
313static PyObject *
314nu_ushort(const char *p, const formatdef *f)
315{
316 unsigned short x;
317 memcpy((char *)&x, p, sizeof x);
318 return PyInt_FromLong((long)x);
319}
320
321static PyObject *
322nu_int(const char *p, const formatdef *f)
323{
324 int x;
325 memcpy((char *)&x, p, sizeof x);
326 return PyInt_FromLong((long)x);
327}
328
329static PyObject *
330nu_uint(const char *p, const formatdef *f)
331{
332 unsigned int x;
333 memcpy((char *)&x, p, sizeof x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000334#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000335 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000336 return PyInt_FromLong((long)x);
337#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000338 return PyLong_FromUnsignedLong((unsigned long)x);
339}
340
341static PyObject *
342nu_long(const char *p, const formatdef *f)
343{
344 long x;
345 memcpy((char *)&x, p, sizeof x);
346 return PyInt_FromLong(x);
347}
348
349static PyObject *
350nu_ulong(const char *p, const formatdef *f)
351{
352 unsigned long x;
353 memcpy((char *)&x, p, sizeof x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000354#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000355 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000356 return PyInt_FromLong((long)x);
357#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000358 return PyLong_FromUnsignedLong(x);
359}
360
361/* Native mode doesn't support q or Q unless the platform C supports
362 long long (or, on Windows, __int64). */
363
364#ifdef HAVE_LONG_LONG
365
366static PyObject *
367nu_longlong(const char *p, const formatdef *f)
368{
369 PY_LONG_LONG x;
370 memcpy((char *)&x, p, sizeof x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000371#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000372 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000373 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
374#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000375 return PyLong_FromLongLong(x);
376}
377
378static PyObject *
379nu_ulonglong(const char *p, const formatdef *f)
380{
381 unsigned PY_LONG_LONG x;
382 memcpy((char *)&x, p, sizeof x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000383#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000384 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000385 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
386#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000387 return PyLong_FromUnsignedLongLong(x);
388}
389
390#endif
391
392static PyObject *
393nu_float(const char *p, const formatdef *f)
394{
395 float x;
396 memcpy((char *)&x, p, sizeof x);
397 return PyFloat_FromDouble((double)x);
398}
399
400static PyObject *
401nu_double(const char *p, const formatdef *f)
402{
403 double x;
404 memcpy((char *)&x, p, sizeof x);
405 return PyFloat_FromDouble(x);
406}
407
408static PyObject *
409nu_void_p(const char *p, const formatdef *f)
410{
411 void *x;
412 memcpy((char *)&x, p, sizeof x);
413 return PyLong_FromVoidPtr(x);
414}
415
416static int
417np_byte(char *p, PyObject *v, const formatdef *f)
418{
419 long x;
420 if (get_long(v, &x) < 0)
421 return -1;
422 if (x < -128 || x > 127){
423 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000424 "byte format requires -128 <= number <= 127");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000425 return -1;
426 }
427 *p = (char)x;
428 return 0;
429}
430
431static int
432np_ubyte(char *p, PyObject *v, const formatdef *f)
433{
434 long x;
435 if (get_long(v, &x) < 0)
436 return -1;
437 if (x < 0 || x > 255){
438 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000439 "ubyte format requires 0 <= number <= 255");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000440 return -1;
441 }
442 *p = (char)x;
443 return 0;
444}
445
446static int
447np_char(char *p, PyObject *v, const formatdef *f)
448{
449 if (!PyString_Check(v) || PyString_Size(v) != 1) {
450 PyErr_SetString(StructError,
451 "char format require string of length 1");
452 return -1;
453 }
454 *p = *PyString_AsString(v);
455 return 0;
456}
457
458static int
459np_short(char *p, PyObject *v, const formatdef *f)
460{
461 long x;
462 short y;
463 if (get_long(v, &x) < 0)
464 return -1;
465 if (x < SHRT_MIN || x > SHRT_MAX){
466 PyErr_SetString(StructError,
467 "short format requires " STRINGIFY(SHRT_MIN)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000468 " <= number <= " STRINGIFY(SHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000469 return -1;
470 }
471 y = (short)x;
472 memcpy(p, (char *)&y, sizeof y);
473 return 0;
474}
475
476static int
477np_ushort(char *p, PyObject *v, const formatdef *f)
478{
479 long x;
480 unsigned short y;
481 if (get_long(v, &x) < 0)
482 return -1;
483 if (x < 0 || x > USHRT_MAX){
484 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000485 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000486 return -1;
487 }
488 y = (unsigned short)x;
489 memcpy(p, (char *)&y, sizeof y);
490 return 0;
491}
492
493static int
494np_int(char *p, PyObject *v, const formatdef *f)
495{
496 long x;
497 int y;
498 if (get_long(v, &x) < 0)
499 return -1;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000500#if defined(PY_STRUCT_RANGE_CHECKING) && (SIZEOF_LONG > SIZEOF_INT)
501 if (x < INT_MIN || x > INT_MAX)
502 return _range_error(f->format, sizeof(y), 0);
503#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000504 y = (int)x;
505 memcpy(p, (char *)&y, sizeof y);
506 return 0;
507}
508
509static int
510np_uint(char *p, PyObject *v, const formatdef *f)
511{
512 unsigned long x;
513 unsigned int y;
514 if (get_ulong(v, &x) < 0)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000515#ifdef PY_STRUCT_RANGE_CHECKING
516 return _range_error(f->format, sizeof(y), 1);
517#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000518 return -1;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000519#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000520 y = (unsigned int)x;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000521#if defined(PY_STRUCT_RANGE_CHECKING) && (SIZEOF_LONG > SIZEOF_INT)
522 if (x < UINT_MIN || x > UINT_MAX)
523 return _range_error(f->format, sizeof(y), 1);
524#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000525 memcpy(p, (char *)&y, sizeof y);
526 return 0;
527}
528
529static int
530np_long(char *p, PyObject *v, const formatdef *f)
531{
532 long x;
533 if (get_long(v, &x) < 0)
534 return -1;
535 memcpy(p, (char *)&x, sizeof x);
536 return 0;
537}
538
539static int
540np_ulong(char *p, PyObject *v, const formatdef *f)
541{
542 unsigned long x;
543 if (get_ulong(v, &x) < 0)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000544#ifdef PY_STRUCT_RANGE_CHECKING
545 return _range_error(f->format, sizeof(x), 1);
546#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000547 return -1;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000548#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000549 memcpy(p, (char *)&x, sizeof x);
550 return 0;
551}
552
553#ifdef HAVE_LONG_LONG
554
555static int
556np_longlong(char *p, PyObject *v, const formatdef *f)
557{
558 PY_LONG_LONG x;
559 if (get_longlong(v, &x) < 0)
560 return -1;
561 memcpy(p, (char *)&x, sizeof x);
562 return 0;
563}
564
565static int
566np_ulonglong(char *p, PyObject *v, const formatdef *f)
567{
568 unsigned PY_LONG_LONG x;
569 if (get_ulonglong(v, &x) < 0)
570 return -1;
571 memcpy(p, (char *)&x, sizeof x);
572 return 0;
573}
574#endif
575
576static int
577np_float(char *p, PyObject *v, const formatdef *f)
578{
579 float x = (float)PyFloat_AsDouble(v);
580 if (x == -1 && PyErr_Occurred()) {
581 PyErr_SetString(StructError,
582 "required argument is not a float");
583 return -1;
584 }
585 memcpy(p, (char *)&x, sizeof x);
586 return 0;
587}
588
589static int
590np_double(char *p, PyObject *v, const formatdef *f)
591{
592 double x = PyFloat_AsDouble(v);
593 if (x == -1 && PyErr_Occurred()) {
594 PyErr_SetString(StructError,
595 "required argument is not a float");
596 return -1;
597 }
598 memcpy(p, (char *)&x, sizeof(double));
599 return 0;
600}
601
602static int
603np_void_p(char *p, PyObject *v, const formatdef *f)
604{
605 void *x;
606
607 v = get_pylong(v);
608 if (v == NULL)
609 return -1;
610 assert(PyLong_Check(v));
611 x = PyLong_AsVoidPtr(v);
612 Py_DECREF(v);
613 if (x == NULL && PyErr_Occurred())
614 return -1;
615 memcpy(p, (char *)&x, sizeof x);
616 return 0;
617}
618
619static formatdef native_table[] = {
620 {'x', sizeof(char), 0, NULL},
621 {'b', sizeof(char), 0, nu_byte, np_byte},
622 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
623 {'c', sizeof(char), 0, nu_char, np_char},
624 {'s', sizeof(char), 0, NULL},
625 {'p', sizeof(char), 0, NULL},
626 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
627 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
628 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
629 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
630 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
631 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000632#ifdef HAVE_LONG_LONG
633 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
634 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
635#endif
Bob Ippolitoa99865b2006-05-25 19:56:56 +0000636 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
637 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
638 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000639 {0}
640};
641
642/* Big-endian routines. *****************************************************/
643
644static PyObject *
645bu_int(const char *p, const formatdef *f)
646{
647 long x = 0;
648 int i = f->size;
649 do {
650 x = (x<<8) | (*p++ & 0xFF);
651 } while (--i > 0);
652 /* Extend the sign bit. */
653 if (SIZEOF_LONG > f->size)
654 x |= -(x & (1L << (8*f->size - 1)));
655 return PyInt_FromLong(x);
656}
657
658static PyObject *
659bu_uint(const char *p, const formatdef *f)
660{
661 unsigned long x = 0;
662 int i = f->size;
663 do {
664 x = (x<<8) | (*p++ & 0xFF);
665 } while (--i > 0);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000666#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000667 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000668 return PyInt_FromLong((long)x);
Bob Ippolito3b0cae92006-05-25 19:15:27 +0000669#else
670 if (SIZEOF_LONG > f->size)
671 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000672#endif
673 return PyLong_FromUnsignedLong(x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000674}
675
676static PyObject *
677bu_longlong(const char *p, const formatdef *f)
678{
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000679#if HAVE_LONG_LONG
680 PY_LONG_LONG x = 0;
681 int i = f->size;
682 do {
683 x = (x<<8) | (*p++ & 0xFF);
684 } while (--i > 0);
685 /* Extend the sign bit. */
686 if (SIZEOF_LONG_LONG > f->size)
687 x |= -(x & (1L << (8 * f->size - 1)));
688#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000689 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000690 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
691#endif
692 return PyLong_FromLongLong(x);
693#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000694 return _PyLong_FromByteArray((const unsigned char *)p,
695 8,
696 0, /* little-endian */
697 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000698#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000699}
700
701static PyObject *
702bu_ulonglong(const char *p, const formatdef *f)
703{
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000704#if HAVE_LONG_LONG
705 unsigned PY_LONG_LONG x = 0;
706 int i = f->size;
707 do {
708 x = (x<<8) | (*p++ & 0xFF);
709 } while (--i > 0);
710#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000711 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000712 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
713#endif
714 return PyLong_FromUnsignedLongLong(x);
715#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000716 return _PyLong_FromByteArray((const unsigned char *)p,
717 8,
718 0, /* little-endian */
719 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000720#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000721}
722
723static PyObject *
724bu_float(const char *p, const formatdef *f)
725{
726 return unpack_float(p, 0);
727}
728
729static PyObject *
730bu_double(const char *p, const formatdef *f)
731{
732 return unpack_double(p, 0);
733}
734
735static int
736bp_int(char *p, PyObject *v, const formatdef *f)
737{
738 long x;
739 int i;
740 if (get_long(v, &x) < 0)
741 return -1;
742 i = f->size;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000743#ifdef PY_STRUCT_RANGE_CHECKING
744 if (i != SIZEOF_LONG && (
745 (i == 2 && (x < -32768 || x > 32767))
746#if SIZEOF_LONG != 4
747 || (i == 4) && (x < -2147483648L || x > -2147483647L)
748#endif
749 ))
750 return _range_error(f->format, i, 0);
751#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000752 do {
753 p[--i] = (char)x;
754 x >>= 8;
755 } while (i > 0);
756 return 0;
757}
758
759static int
760bp_uint(char *p, PyObject *v, const formatdef *f)
761{
762 unsigned long x;
763 int i;
764 if (get_ulong(v, &x) < 0)
765 return -1;
766 i = f->size;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000767#ifdef PY_STRUCT_RANGE_CHECKING
768 if (i != SIZEOF_LONG && x >= (1 << (i * 8)))
769 return _range_error(f->format, f->size, 1);
770#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000771 do {
772 p[--i] = (char)x;
773 x >>= 8;
774 } while (i > 0);
775 return 0;
776}
777
778static int
779bp_longlong(char *p, PyObject *v, const formatdef *f)
780{
781 int res;
782 v = get_pylong(v);
783 if (v == NULL)
784 return -1;
785 res = _PyLong_AsByteArray((PyLongObject *)v,
786 (unsigned char *)p,
787 8,
788 0, /* little_endian */
789 1 /* signed */);
790 Py_DECREF(v);
791 return res;
792}
793
794static int
795bp_ulonglong(char *p, PyObject *v, const formatdef *f)
796{
797 int res;
798 v = get_pylong(v);
799 if (v == NULL)
800 return -1;
801 res = _PyLong_AsByteArray((PyLongObject *)v,
802 (unsigned char *)p,
803 8,
804 0, /* little_endian */
805 0 /* signed */);
806 Py_DECREF(v);
807 return res;
808}
809
810static int
811bp_float(char *p, PyObject *v, const formatdef *f)
812{
813 double x = PyFloat_AsDouble(v);
814 if (x == -1 && PyErr_Occurred()) {
815 PyErr_SetString(StructError,
816 "required argument is not a float");
817 return -1;
818 }
819 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
820}
821
822static int
823bp_double(char *p, PyObject *v, const formatdef *f)
824{
825 double x = PyFloat_AsDouble(v);
826 if (x == -1 && PyErr_Occurred()) {
827 PyErr_SetString(StructError,
828 "required argument is not a float");
829 return -1;
830 }
831 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
832}
833
834static formatdef bigendian_table[] = {
835 {'x', 1, 0, NULL},
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000836 {'b', 1, 0, nu_byte, np_byte},
837 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000838 {'c', 1, 0, nu_char, np_char},
839 {'s', 1, 0, NULL},
840 {'p', 1, 0, NULL},
841 {'h', 2, 0, bu_int, bp_int},
842 {'H', 2, 0, bu_uint, bp_uint},
843 {'i', 4, 0, bu_int, bp_int},
844 {'I', 4, 0, bu_uint, bp_uint},
845 {'l', 4, 0, bu_int, bp_int},
846 {'L', 4, 0, bu_uint, bp_uint},
847 {'q', 8, 0, bu_longlong, bp_longlong},
848 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
849 {'f', 4, 0, bu_float, bp_float},
850 {'d', 8, 0, bu_double, bp_double},
851 {0}
852};
853
854/* Little-endian routines. *****************************************************/
855
856static PyObject *
857lu_int(const char *p, const formatdef *f)
858{
859 long x = 0;
860 int i = f->size;
861 do {
862 x = (x<<8) | (p[--i] & 0xFF);
863 } while (i > 0);
864 /* Extend the sign bit. */
865 if (SIZEOF_LONG > f->size)
866 x |= -(x & (1L << (8*f->size - 1)));
867 return PyInt_FromLong(x);
868}
869
870static PyObject *
871lu_uint(const char *p, const formatdef *f)
872{
873 unsigned long x = 0;
874 int i = f->size;
875 do {
876 x = (x<<8) | (p[--i] & 0xFF);
877 } while (i > 0);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000878#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000879 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000880 return PyInt_FromLong((long)x);
Bob Ippolito3b0cae92006-05-25 19:15:27 +0000881#else
882 if (SIZEOF_LONG > f->size)
883 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000884#endif
885 return PyLong_FromUnsignedLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000886}
887
888static PyObject *
889lu_longlong(const char *p, const formatdef *f)
890{
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000891#if HAVE_LONG_LONG
892 PY_LONG_LONG x = 0;
893 int i = f->size;
894 do {
895 x = (x<<8) | (p[--i] & 0xFF);
896 } while (i > 0);
897 /* Extend the sign bit. */
898 if (SIZEOF_LONG_LONG > f->size)
899 x |= -(x & (1L << (8 * f->size - 1)));
900#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000901 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000902 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
903#endif
904 return PyLong_FromLongLong(x);
905#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000906 return _PyLong_FromByteArray((const unsigned char *)p,
907 8,
908 1, /* little-endian */
909 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000910#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000911}
912
913static PyObject *
914lu_ulonglong(const char *p, const formatdef *f)
915{
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000916#if HAVE_LONG_LONG
917 unsigned PY_LONG_LONG x = 0;
918 int i = f->size;
919 do {
920 x = (x<<8) | (p[--i] & 0xFF);
921 } while (i > 0);
922#ifdef PY_USE_INT_WHEN_POSSIBLE
Bob Ippolito04ab9942006-05-25 19:33:38 +0000923 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000924 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
925#endif
926 return PyLong_FromUnsignedLongLong(x);
927#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000928 return _PyLong_FromByteArray((const unsigned char *)p,
929 8,
930 1, /* little-endian */
931 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000932#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000933}
934
935static PyObject *
936lu_float(const char *p, const formatdef *f)
937{
938 return unpack_float(p, 1);
939}
940
941static PyObject *
942lu_double(const char *p, const formatdef *f)
943{
944 return unpack_double(p, 1);
945}
946
947static int
948lp_int(char *p, PyObject *v, const formatdef *f)
949{
950 long x;
951 int i;
952 if (get_long(v, &x) < 0)
953 return -1;
954 i = f->size;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000955#ifdef PY_STRUCT_RANGE_CHECKING
956 if (i != SIZEOF_LONG && (
957 (i == 2 && (x < -32768 || x > 32767))
958#if SIZEOF_LONG != 4
959 || (i == 4) && (x < -2147483648L || x > -2147483647L)
960#endif
961 ))
962 return _range_error(f->format, i, 0);
963#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000964 do {
965 *p++ = (char)x;
966 x >>= 8;
967 } while (--i > 0);
968 return 0;
969}
970
971static int
972lp_uint(char *p, PyObject *v, const formatdef *f)
973{
974 unsigned long x;
975 int i;
976 if (get_ulong(v, &x) < 0)
977 return -1;
978 i = f->size;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000979#ifdef PY_STRUCT_RANGE_CHECKING
980 if (i != SIZEOF_LONG && x >= (1 << (i * 8)))
981 return _range_error(f->format, f->size, 1);
982#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000983 do {
984 *p++ = (char)x;
985 x >>= 8;
986 } while (--i > 0);
987 return 0;
988}
989
990static int
991lp_longlong(char *p, PyObject *v, const formatdef *f)
992{
993 int res;
994 v = get_pylong(v);
995 if (v == NULL)
996 return -1;
997 res = _PyLong_AsByteArray((PyLongObject*)v,
998 (unsigned char *)p,
999 8,
1000 1, /* little_endian */
1001 1 /* signed */);
1002 Py_DECREF(v);
1003 return res;
1004}
1005
1006static int
1007lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1008{
1009 int res;
1010 v = get_pylong(v);
1011 if (v == NULL)
1012 return -1;
1013 res = _PyLong_AsByteArray((PyLongObject*)v,
1014 (unsigned char *)p,
1015 8,
1016 1, /* little_endian */
1017 0 /* signed */);
1018 Py_DECREF(v);
1019 return res;
1020}
1021
1022static int
1023lp_float(char *p, PyObject *v, const formatdef *f)
1024{
1025 double x = PyFloat_AsDouble(v);
1026 if (x == -1 && PyErr_Occurred()) {
1027 PyErr_SetString(StructError,
1028 "required argument is not a float");
1029 return -1;
1030 }
1031 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1032}
1033
1034static int
1035lp_double(char *p, PyObject *v, const formatdef *f)
1036{
1037 double x = PyFloat_AsDouble(v);
1038 if (x == -1 && PyErr_Occurred()) {
1039 PyErr_SetString(StructError,
1040 "required argument is not a float");
1041 return -1;
1042 }
1043 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1044}
1045
1046static formatdef lilendian_table[] = {
1047 {'x', 1, 0, NULL},
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001048 {'b', 1, 0, nu_byte, np_byte},
1049 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001050 {'c', 1, 0, nu_char, np_char},
1051 {'s', 1, 0, NULL},
1052 {'p', 1, 0, NULL},
1053 {'h', 2, 0, lu_int, lp_int},
1054 {'H', 2, 0, lu_uint, lp_uint},
1055 {'i', 4, 0, lu_int, lp_int},
1056 {'I', 4, 0, lu_uint, lp_uint},
1057 {'l', 4, 0, lu_int, lp_int},
1058 {'L', 4, 0, lu_uint, lp_uint},
1059 {'q', 8, 0, lu_longlong, lp_longlong},
1060 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1061 {'f', 4, 0, lu_float, lp_float},
1062 {'d', 8, 0, lu_double, lp_double},
1063 {0}
1064};
1065
1066
1067static const formatdef *
1068whichtable(char **pfmt)
1069{
1070 const char *fmt = (*pfmt)++; /* May be backed out of later */
1071 switch (*fmt) {
1072 case '<':
1073 return lilendian_table;
1074 case '>':
1075 case '!': /* Network byte order is big-endian */
1076 return bigendian_table;
1077 case '=': { /* Host byte order -- different from native in aligment! */
1078 int n = 1;
1079 char *p = (char *) &n;
1080 if (*p == 1)
1081 return lilendian_table;
1082 else
1083 return bigendian_table;
1084 }
1085 default:
1086 --*pfmt; /* Back out of pointer increment */
1087 /* Fall through */
1088 case '@':
1089 return native_table;
1090 }
1091}
1092
1093
1094/* Get the table entry for a format code */
1095
1096static const formatdef *
1097getentry(int c, const formatdef *f)
1098{
1099 for (; f->format != '\0'; f++) {
1100 if (f->format == c) {
1101 return f;
1102 }
1103 }
1104 PyErr_SetString(StructError, "bad char in struct format");
1105 return NULL;
1106}
1107
1108
1109/* Align a size according to a format code */
1110
1111static int
1112align(int size, int c, const formatdef *e)
1113{
1114 if (e->format == c) {
1115 if (e->alignment) {
1116 size = ((size + e->alignment - 1)
1117 / e->alignment)
1118 * e->alignment;
1119 }
1120 }
1121 return size;
1122}
1123
1124
1125/* calculate the size of a format string */
1126
1127static int
1128prepare_s(PyStructObject *self)
1129{
1130 const formatdef *f;
1131 const formatdef *e;
1132 formatcode *codes;
1133
1134 const char *s;
1135 const char *fmt;
1136 char c;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001137 int size, len, num, itemsize, x;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001138
1139 fmt = PyString_AS_STRING(self->s_format);
1140
1141 f = whichtable((char **)&fmt);
1142
1143 s = fmt;
1144 size = 0;
1145 len = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001146 while ((c = *s++) != '\0') {
1147 if (isspace(Py_CHARMASK(c)))
1148 continue;
1149 if ('0' <= c && c <= '9') {
1150 num = c - '0';
1151 while ('0' <= (c = *s++) && c <= '9') {
1152 x = num*10 + (c - '0');
1153 if (x/10 != num) {
1154 PyErr_SetString(
1155 StructError,
1156 "overflow in item count");
1157 return -1;
1158 }
1159 num = x;
1160 }
1161 if (c == '\0')
1162 break;
1163 }
1164 else
1165 num = 1;
1166
1167 e = getentry(c, f);
1168 if (e == NULL)
1169 return -1;
1170
1171 switch (c) {
1172 case 's': /* fall through */
1173 case 'p': len++; break;
1174 case 'x': break;
1175 default: len += num; break;
1176 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001177
1178 itemsize = e->size;
1179 size = align(size, c, e);
1180 x = num * itemsize;
1181 size += x;
1182 if (x/itemsize != num || size < 0) {
1183 PyErr_SetString(StructError,
1184 "total struct size too long");
1185 return -1;
1186 }
1187 }
1188
1189 self->s_size = size;
1190 self->s_len = len;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001191 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
Bob Ippolito232f3c92006-05-23 19:12:41 +00001192 if (codes == NULL) {
1193 PyErr_NoMemory();
1194 return -1;
1195 }
1196 self->s_codes = codes;
1197
1198 s = fmt;
1199 size = 0;
1200 while ((c = *s++) != '\0') {
1201 if (isspace(Py_CHARMASK(c)))
1202 continue;
1203 if ('0' <= c && c <= '9') {
1204 num = c - '0';
1205 while ('0' <= (c = *s++) && c <= '9')
1206 num = num*10 + (c - '0');
1207 if (c == '\0')
1208 break;
1209 }
1210 else
1211 num = 1;
1212
1213 e = getentry(c, f);
1214
1215 size = align(size, c, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001216 if (c == 's' || c == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001217 codes->offset = size;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001218 codes->size = num;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001219 codes->fmtdef = e;
1220 codes++;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001221 size += num;
1222 } else if (c == 'x') {
1223 size += num;
1224 } else {
1225 while (--num >= 0) {
1226 codes->offset = size;
1227 codes->size = e->size;
1228 codes->fmtdef = e;
1229 codes++;
1230 size += e->size;
1231 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001232 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001233 }
1234 codes->fmtdef = NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001235 codes->offset = size;
1236 codes->size = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001237
1238 return 0;
1239}
1240
1241static PyObject *
1242s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1243{
1244 PyObject *self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001245
1246 assert(type != NULL && type->tp_alloc != NULL);
1247
1248 self = type->tp_alloc(type, 0);
1249 if (self != NULL) {
1250 PyStructObject *s = (PyStructObject*)self;
1251 Py_INCREF(Py_None);
1252 s->s_format = Py_None;
1253 s->s_codes = NULL;
1254 s->s_size = -1;
1255 s->s_len = -1;
1256 }
1257 return self;
1258}
1259
1260static int
1261s_init(PyObject *self, PyObject *args, PyObject *kwds)
1262{
1263 PyStructObject *soself = (PyStructObject *)self;
1264 PyObject *o_format = NULL;
1265 int ret = 0;
1266 static char *kwlist[] = {"format", 0};
1267
1268 assert(PyStruct_Check(self));
1269
1270 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1271 &o_format))
1272 return -1;
1273
1274 Py_INCREF(o_format);
1275 Py_XDECREF(soself->s_format);
1276 soself->s_format = o_format;
1277
1278 ret = prepare_s(soself);
1279 return ret;
1280}
1281
1282static void
1283s_dealloc(PyStructObject *s)
1284{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001285 if (s->weakreflist != NULL)
1286 PyObject_ClearWeakRefs((PyObject *)s);
1287 if (s->s_codes != NULL) {
1288 PyMem_FREE(s->s_codes);
1289 }
1290 Py_XDECREF(s->s_format);
1291 s->ob_type->tp_free((PyObject *)s);
1292}
1293
Bob Ippolitoeb621272006-05-24 15:32:06 +00001294static PyObject *
1295s_unpack_internal(PyStructObject *soself, char *startfrom) {
1296 formatcode *code;
1297 Py_ssize_t i = 0;
1298 PyObject *result = PyTuple_New(soself->s_len);
1299 if (result == NULL)
1300 return NULL;
1301
1302 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1303 PyObject *v;
1304 const formatdef *e = code->fmtdef;
1305 const char *res = startfrom + code->offset;
1306 if (e->format == 's') {
1307 v = PyString_FromStringAndSize(res, code->size);
1308 if (v == NULL)
1309 goto fail;
1310 PyTuple_SET_ITEM(result, i++, v);
1311 } else if (e->format == 'p') {
1312 Py_ssize_t n = *(unsigned char*)res;
1313 if (n >= code->size)
1314 n = code->size - 1;
1315 v = PyString_FromStringAndSize(res + 1, n);
1316 if (v == NULL)
1317 goto fail;
1318 PyTuple_SET_ITEM(result, i++, v);
1319 } else {
1320 v = e->unpack(res, e);
1321 if (v == NULL)
1322 goto fail;
1323 PyTuple_SET_ITEM(result, i++, v);
1324 }
1325 }
1326
1327 return result;
1328fail:
1329 Py_DECREF(result);
1330 return NULL;
1331};
1332
1333
Bob Ippolito232f3c92006-05-23 19:12:41 +00001334PyDoc_STRVAR(s_unpack__doc__,
1335"unpack(str) -> (v1, v2, ...)\n\
1336\n\
1337Return tuple containing values unpacked according to this Struct's format.\n\
1338Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1339strings.");
1340
1341static PyObject *
1342s_unpack(PyObject *self, PyObject *inputstr)
1343{
Bob Ippolitoeb621272006-05-24 15:32:06 +00001344 PyStructObject *soself = (PyStructObject *)self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001345 assert(PyStruct_Check(self));
1346 assert(soself->s_codes != NULL);
1347 if (inputstr == NULL || !PyString_Check(inputstr) ||
Bob Ippolitoeb621272006-05-24 15:32:06 +00001348 PyString_GET_SIZE(inputstr) != soself->s_size) {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001349 PyErr_Format(StructError,
1350 "unpack requires a string argument of length %d", soself->s_size);
1351 return NULL;
1352 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001353 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1354}
1355
1356PyDoc_STRVAR(s_unpack_from__doc__,
1357"unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1358\n\
1359Return tuple containing values unpacked according to this Struct's format.\n\
1360Unlike unpack, unpack_from can unpack values from any object supporting\n\
1361the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1362See struct.__doc__ for more on format strings.");
1363
1364static PyObject *
1365s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1366{
1367 static char *kwlist[] = {"buffer", "offset", 0};
1368#if (PY_VERSION_HEX < 0x02050000)
1369 static char *fmt = "z#|i:unpack_from";
1370#else
1371 static char *fmt = "z#|n:unpack_from";
1372#endif
1373 Py_ssize_t buffer_len = 0, offset = 0;
1374 char *buffer = NULL;
1375 PyStructObject *soself = (PyStructObject *)self;
1376 assert(PyStruct_Check(self));
1377 assert(soself->s_codes != NULL);
1378
1379 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1380 &buffer, &buffer_len, &offset))
1381 return NULL;
1382
1383 if (buffer == NULL) {
1384 PyErr_Format(StructError,
1385 "unpack_from requires a buffer argument");
Bob Ippolito232f3c92006-05-23 19:12:41 +00001386 return NULL;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001387 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001388
1389 if (offset < 0)
1390 offset += buffer_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001391
Bob Ippolitoeb621272006-05-24 15:32:06 +00001392 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1393 PyErr_Format(StructError,
1394 "unpack_from requires a buffer of at least %d bytes",
1395 soself->s_size);
1396 return NULL;
1397 }
1398 return s_unpack_internal(soself, buffer + offset);
1399}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001400
Bob Ippolito232f3c92006-05-23 19:12:41 +00001401
Martin Blais2856e5f2006-05-26 12:03:27 +00001402/*
1403 * Guts of the pack function.
1404 *
1405 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1406 * argument for where to start processing the arguments for packing, and a
1407 * character buffer for writing the packed string. The caller must insure
1408 * that the buffer may contain the required length for packing the arguments.
1409 * 0 is returned on success, 1 is returned if there is an error.
1410 *
1411 */
1412static int
1413s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001414{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001415 formatcode *code;
1416 Py_ssize_t i;
Martin Blais2856e5f2006-05-26 12:03:27 +00001417
1418 memset(buf, '\0', soself->s_size);
1419 i = offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001420 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1421 Py_ssize_t n;
1422 PyObject *v;
1423 const formatdef *e = code->fmtdef;
Martin Blais2856e5f2006-05-26 12:03:27 +00001424 char *res = buf + code->offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001425 if (e->format == 's') {
1426 v = PyTuple_GET_ITEM(args, i++);
1427 if (!PyString_Check(v)) {
1428 PyErr_SetString(StructError,
1429 "argument for 's' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001430 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001431 }
1432 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001433 if (n > code->size)
1434 n = code->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001435 if (n > 0)
1436 memcpy(res, PyString_AS_STRING(v), n);
1437 } else if (e->format == 'p') {
1438 v = PyTuple_GET_ITEM(args, i++);
1439 if (!PyString_Check(v)) {
1440 PyErr_SetString(StructError,
1441 "argument for 'p' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001442 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001443 }
1444 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001445 if (n > (code->size - 1))
1446 n = code->size - 1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001447 if (n > 0)
1448 memcpy(res + 1, PyString_AS_STRING(v), n);
1449 if (n > 255)
1450 n = 255;
1451 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1452 } else {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001453 v = PyTuple_GET_ITEM(args, i++);
1454 if (e->pack(res, v, e) < 0)
Martin Blais2856e5f2006-05-26 12:03:27 +00001455 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001456 }
1457 }
1458
Martin Blais2856e5f2006-05-26 12:03:27 +00001459 /* Success */
1460 return 0;
1461}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001462
Martin Blais2856e5f2006-05-26 12:03:27 +00001463
1464PyDoc_STRVAR(s_pack__doc__,
1465"pack(v1, v2, ...) -> string\n\
1466\n\
1467Return a string containing values v1, v2, ... packed according to this\n\
1468Struct's format. See struct.__doc__ for more on format strings.");
1469
1470static PyObject *
1471s_pack(PyObject *self, PyObject *args)
1472{
1473 PyStructObject *soself;
1474 PyObject *result;
1475
1476 /* Validate arguments. */
1477 soself = (PyStructObject *)self;
1478 assert(PyStruct_Check(self));
1479 assert(soself->s_codes != NULL);
1480 if (args == NULL || !PyTuple_Check(args) ||
1481 PyTuple_GET_SIZE(args) != soself->s_len)
1482 {
1483 PyErr_Format(StructError,
1484 "pack requires exactly %d arguments", soself->s_len);
1485 return NULL;
1486 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001487
Martin Blais2856e5f2006-05-26 12:03:27 +00001488 /* Allocate a new string */
1489 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1490 if (result == NULL)
1491 return NULL;
1492
1493 /* Call the guts */
1494 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1495 Py_DECREF(result);
1496 return NULL;
1497 }
1498
1499 return result;
1500}
1501
1502PyDoc_STRVAR(s_pack_to__doc__,
1503"pack_to(buffer, offset, v1, v2, ...)\n\
1504\n\
1505Pack the values v2, v2, ... according to this Struct's format, write \n\
1506the packed bytes into the given buffer at the given offset. Note that \n\
1507the offset is not an optional argument. See struct.__doc__ for \n\
1508more on format strings.");
1509
1510static PyObject *
1511s_pack_to(PyObject *self, PyObject *args)
1512{
1513 PyStructObject *soself;
1514 char *buffer;
1515 Py_ssize_t buffer_len, offset;
1516
1517 /* Validate arguments. +1 is for the first arg as buffer. */
1518 soself = (PyStructObject *)self;
1519 assert(PyStruct_Check(self));
1520 assert(soself->s_codes != NULL);
1521 if (args == NULL || !PyTuple_Check(args) ||
1522 PyTuple_GET_SIZE(args) != (soself->s_len + 2))
1523 {
1524 PyErr_Format(StructError,
1525 "pack_to requires exactly %d arguments",
1526 (soself->s_len + 2));
1527 return NULL;
1528 }
1529
1530 /* Extract a writable memory buffer from the first argument */
1531 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1532 (void**)&buffer, &buffer_len) == -1 ) {
1533 return NULL;
1534 }
1535 assert( buffer_len >= 0 );
1536
1537 /* Extract the offset from the first argument */
1538 offset = PyInt_AsLong(PyTuple_GET_ITEM(args, 1));
1539
1540 /* Support negative offsets. */
1541 if (offset < 0)
1542 offset += buffer_len;
1543
1544 /* Check boundaries */
1545 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1546 PyErr_Format(StructError,
1547 "pack_to requires a buffer of at least %d bytes",
1548 soself->s_size);
1549 return NULL;
1550 }
1551
1552 /* Call the guts */
1553 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1554 return NULL;
1555 }
1556
1557 return Py_None;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001558}
1559
1560
1561/* List of functions */
1562
1563static struct PyMethodDef s_methods[] = {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001564 {"pack", (PyCFunction)s_pack, METH_VARARGS, s_pack__doc__},
Martin Blais2856e5f2006-05-26 12:03:27 +00001565 {"pack_to", (PyCFunction)s_pack_to, METH_VARARGS, s_pack_to__doc__},
Bob Ippolitoeb621272006-05-24 15:32:06 +00001566 {"unpack", (PyCFunction)s_unpack, METH_O, s_unpack__doc__},
1567 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001568 {NULL, NULL} /* sentinel */
1569};
1570
1571PyDoc_STRVAR(s__doc__, "Compiled struct object");
1572
1573#define OFF(x) offsetof(PyStructObject, x)
1574
1575static PyMemberDef s_memberlist[] = {
1576 {"format", T_OBJECT, OFF(s_format), RO,
1577 "struct format string"},
1578 {"size", T_INT, OFF(s_size), RO,
1579 "struct size in bytes"},
1580 {"_len", T_INT, OFF(s_len), RO,
1581 "number of items expected in tuple"},
1582 {NULL} /* Sentinel */
1583};
1584
1585
1586static
1587PyTypeObject PyStructType = {
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001588 PyObject_HEAD_INIT(NULL)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001589 0,
1590 "Struct",
1591 sizeof(PyStructObject),
1592 0,
1593 (destructor)s_dealloc, /* tp_dealloc */
1594 0, /* tp_print */
1595 0, /* tp_getattr */
1596 0, /* tp_setattr */
1597 0, /* tp_compare */
1598 0, /* tp_repr */
1599 0, /* tp_as_number */
1600 0, /* tp_as_sequence */
1601 0, /* tp_as_mapping */
1602 0, /* tp_hash */
1603 0, /* tp_call */
1604 0, /* tp_str */
1605 PyObject_GenericGetAttr, /* tp_getattro */
1606 PyObject_GenericSetAttr, /* tp_setattro */
1607 0, /* tp_as_buffer */
1608 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
1609 s__doc__, /* tp_doc */
1610 0, /* tp_traverse */
1611 0, /* tp_clear */
1612 0, /* tp_richcompare */
1613 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1614 0, /* tp_iter */
1615 0, /* tp_iternext */
1616 s_methods, /* tp_methods */
1617 s_memberlist, /* tp_members */
1618 0, /* tp_getset */
1619 0, /* tp_base */
1620 0, /* tp_dict */
1621 0, /* tp_descr_get */
1622 0, /* tp_descr_set */
1623 0, /* tp_dictoffset */
1624 s_init, /* tp_init */
1625 PyType_GenericAlloc, /* tp_alloc */
1626 s_new, /* tp_new */
1627 PyObject_Del, /* tp_free */
1628};
1629
1630/* Module initialization */
1631
1632PyMODINIT_FUNC
1633init_struct(void)
1634{
1635 PyObject *m = Py_InitModule("_struct", NULL);
1636 if (m == NULL)
1637 return;
1638
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001639 PyStructType.ob_type = &PyType_Type;
1640 if (PyType_Ready(&PyStructType) < 0)
1641 return;
1642
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001643 /* Check endian and swap in faster functions */
1644 {
1645 int one = 1;
1646 formatdef *native = native_table;
1647 formatdef *other, *ptr;
1648 if ((int)*(unsigned char*)&one)
1649 other = lilendian_table;
1650 else
1651 other = bigendian_table;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001652 /* Scan through the native table, find a matching
1653 entry in the endian table and swap in the
1654 native implementations whenever possible
1655 (64-bit platforms may not have "standard" sizes) */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001656 while (native->format != '\0' && other->format != '\0') {
1657 ptr = other;
1658 while (ptr->format != '\0') {
1659 if (ptr->format == native->format) {
Bob Ippolito964e02a2006-05-25 21:09:45 +00001660 /* Match faster when formats are
1661 listed in the same order */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001662 if (ptr == other)
1663 other++;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001664 /* Only use the trick if the
1665 size matches */
1666 if (ptr->size != native->size)
1667 break;
1668 /* Skip float and double, could be
1669 "unknown" float format */
1670 if (ptr->format == 'd' || ptr->format == 'f')
1671 break;
1672 ptr->pack = native->pack;
1673 ptr->unpack = native->unpack;
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001674 break;
1675 }
1676 ptr++;
1677 }
1678 native++;
1679 }
1680 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001681
Bob Ippolito232f3c92006-05-23 19:12:41 +00001682 /* Add some symbolic constants to the module */
1683 if (StructError == NULL) {
1684 StructError = PyErr_NewException("struct.error", NULL, NULL);
1685 if (StructError == NULL)
1686 return;
1687 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001688
Bob Ippolito232f3c92006-05-23 19:12:41 +00001689 Py_INCREF(StructError);
1690 PyModule_AddObject(m, "error", StructError);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001691
Bob Ippolito232f3c92006-05-23 19:12:41 +00001692 Py_INCREF((PyObject*)&PyStructType);
1693 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
1694}