blob: 7d0467d71dccb73015c6ac170a5f740ab61b2643 [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
18
19
20/* The translation function for each format character is table driven */
21
22typedef struct _formatdef {
23 char format;
24 int size;
25 int alignment;
26 PyObject* (*unpack)(const char *,
27 const struct _formatdef *);
28 int (*pack)(char *, PyObject *,
29 const struct _formatdef *);
30} formatdef;
31
32typedef struct _formatcode {
33 const struct _formatdef *fmtdef;
34 int offset;
35 int repeat;
36} formatcode;
37
38/* Struct object interface */
39
40typedef struct {
41 PyObject_HEAD
42 int s_size;
43 int s_len;
44 formatcode *s_codes;
45 PyObject *s_format;
46 PyObject *weakreflist; /* List of weak references */
47} PyStructObject;
48
Bob Ippolito07c023b2006-05-23 19:32:25 +000049#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
50#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
Bob Ippolito232f3c92006-05-23 19:12:41 +000051
52
53/* Exception */
54
55static PyObject *StructError;
56
57
58/* Define various structs to figure out the alignments of types */
59
60
61typedef struct { char c; short x; } st_short;
62typedef struct { char c; int x; } st_int;
63typedef struct { char c; long x; } st_long;
64typedef struct { char c; float x; } st_float;
65typedef struct { char c; double x; } st_double;
66typedef struct { char c; void *x; } st_void_p;
67
68#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
69#define INT_ALIGN (sizeof(st_int) - sizeof(int))
70#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
71#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
72#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
73#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
74
75/* We can't support q and Q in native mode unless the compiler does;
76 in std mode, they're 8 bytes on all platforms. */
77#ifdef HAVE_LONG_LONG
78typedef struct { char c; PY_LONG_LONG x; } s_long_long;
79#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
80#endif
81
82#define STRINGIFY(x) #x
83
84#ifdef __powerc
85#pragma options align=reset
86#endif
87
88/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
89
90static PyObject *
91get_pylong(PyObject *v)
92{
93 PyNumberMethods *m;
94
95 assert(v != NULL);
96 if (PyInt_Check(v))
97 return PyLong_FromLong(PyInt_AS_LONG(v));
98 if (PyLong_Check(v)) {
99 Py_INCREF(v);
100 return v;
101 }
102 m = v->ob_type->tp_as_number;
103 if (m != NULL && m->nb_long != NULL) {
104 v = m->nb_long(v);
105 if (v == NULL)
106 return NULL;
107 if (PyLong_Check(v))
108 return v;
109 Py_DECREF(v);
110 }
111 PyErr_SetString(StructError,
112 "cannot convert argument to long");
113 return NULL;
114}
115
116/* Helper routine to get a Python integer and raise the appropriate error
117 if it isn't one */
118
119static int
120get_long(PyObject *v, long *p)
121{
122 long x = PyInt_AsLong(v);
123 if (x == -1 && PyErr_Occurred()) {
124 if (PyErr_ExceptionMatches(PyExc_TypeError))
125 PyErr_SetString(StructError,
126 "required argument is not an integer");
127 return -1;
128 }
129 *p = x;
130 return 0;
131}
132
133
134/* Same, but handling unsigned long */
135
136static int
137get_ulong(PyObject *v, unsigned long *p)
138{
139 if (PyLong_Check(v)) {
140 unsigned long x = PyLong_AsUnsignedLong(v);
141 if (x == (unsigned long)(-1) && PyErr_Occurred())
142 return -1;
143 *p = x;
144 return 0;
145 }
146 else {
147 return get_long(v, (long *)p);
148 }
149}
150
151#ifdef HAVE_LONG_LONG
152
153/* Same, but handling native long long. */
154
155static int
156get_longlong(PyObject *v, PY_LONG_LONG *p)
157{
158 PY_LONG_LONG x;
159
160 v = get_pylong(v);
161 if (v == NULL)
162 return -1;
163 assert(PyLong_Check(v));
164 x = PyLong_AsLongLong(v);
165 Py_DECREF(v);
166 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
167 return -1;
168 *p = x;
169 return 0;
170}
171
172/* Same, but handling native unsigned long long. */
173
174static int
175get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
176{
177 unsigned PY_LONG_LONG x;
178
179 v = get_pylong(v);
180 if (v == NULL)
181 return -1;
182 assert(PyLong_Check(v));
183 x = PyLong_AsUnsignedLongLong(v);
184 Py_DECREF(v);
185 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
186 return -1;
187 *p = x;
188 return 0;
189}
190
191#endif
192
193/* Floating point helpers */
194
195static PyObject *
196unpack_float(const char *p, /* start of 4-byte string */
197 int le) /* true for little-endian, false for big-endian */
198{
199 double x;
200
201 x = _PyFloat_Unpack4((unsigned char *)p, le);
202 if (x == -1.0 && PyErr_Occurred())
203 return NULL;
204 return PyFloat_FromDouble(x);
205}
206
207static PyObject *
208unpack_double(const char *p, /* start of 8-byte string */
209 int le) /* true for little-endian, false for big-endian */
210{
211 double x;
212
213 x = _PyFloat_Unpack8((unsigned char *)p, le);
214 if (x == -1.0 && PyErr_Occurred())
215 return NULL;
216 return PyFloat_FromDouble(x);
217}
218
219
220/* A large number of small routines follow, with names of the form
221
222 [bln][up]_TYPE
223
224 [bln] distiguishes among big-endian, little-endian and native.
225 [pu] distiguishes between pack (to struct) and unpack (from struct).
226 TYPE is one of char, byte, ubyte, etc.
227*/
228
229/* Native mode routines. ****************************************************/
230/* NOTE:
231 In all n[up]_<type> routines handling types larger than 1 byte, there is
232 *no* guarantee that the p pointer is properly aligned for each type,
233 therefore memcpy is called. An intermediate variable is used to
234 compensate for big-endian architectures.
235 Normally both the intermediate variable and the memcpy call will be
236 skipped by C optimisation in little-endian architectures (gcc >= 2.91
237 does this). */
238
239static PyObject *
240nu_char(const char *p, const formatdef *f)
241{
242 return PyString_FromStringAndSize(p, 1);
243}
244
245static PyObject *
246nu_byte(const char *p, const formatdef *f)
247{
248 return PyInt_FromLong((long) *(signed char *)p);
249}
250
251static PyObject *
252nu_ubyte(const char *p, const formatdef *f)
253{
254 return PyInt_FromLong((long) *(unsigned char *)p);
255}
256
257static PyObject *
258nu_short(const char *p, const formatdef *f)
259{
260 short x;
261 memcpy((char *)&x, p, sizeof x);
262 return PyInt_FromLong((long)x);
263}
264
265static PyObject *
266nu_ushort(const char *p, const formatdef *f)
267{
268 unsigned short x;
269 memcpy((char *)&x, p, sizeof x);
270 return PyInt_FromLong((long)x);
271}
272
273static PyObject *
274nu_int(const char *p, const formatdef *f)
275{
276 int x;
277 memcpy((char *)&x, p, sizeof x);
278 return PyInt_FromLong((long)x);
279}
280
281static PyObject *
282nu_uint(const char *p, const formatdef *f)
283{
284 unsigned int x;
285 memcpy((char *)&x, p, sizeof x);
286 return PyLong_FromUnsignedLong((unsigned long)x);
287}
288
289static PyObject *
290nu_long(const char *p, const formatdef *f)
291{
292 long x;
293 memcpy((char *)&x, p, sizeof x);
294 return PyInt_FromLong(x);
295}
296
297static PyObject *
298nu_ulong(const char *p, const formatdef *f)
299{
300 unsigned long x;
301 memcpy((char *)&x, p, sizeof x);
302 return PyLong_FromUnsignedLong(x);
303}
304
305/* Native mode doesn't support q or Q unless the platform C supports
306 long long (or, on Windows, __int64). */
307
308#ifdef HAVE_LONG_LONG
309
310static PyObject *
311nu_longlong(const char *p, const formatdef *f)
312{
313 PY_LONG_LONG x;
314 memcpy((char *)&x, p, sizeof x);
315 return PyLong_FromLongLong(x);
316}
317
318static PyObject *
319nu_ulonglong(const char *p, const formatdef *f)
320{
321 unsigned PY_LONG_LONG x;
322 memcpy((char *)&x, p, sizeof x);
323 return PyLong_FromUnsignedLongLong(x);
324}
325
326#endif
327
328static PyObject *
329nu_float(const char *p, const formatdef *f)
330{
331 float x;
332 memcpy((char *)&x, p, sizeof x);
333 return PyFloat_FromDouble((double)x);
334}
335
336static PyObject *
337nu_double(const char *p, const formatdef *f)
338{
339 double x;
340 memcpy((char *)&x, p, sizeof x);
341 return PyFloat_FromDouble(x);
342}
343
344static PyObject *
345nu_void_p(const char *p, const formatdef *f)
346{
347 void *x;
348 memcpy((char *)&x, p, sizeof x);
349 return PyLong_FromVoidPtr(x);
350}
351
352static int
353np_byte(char *p, PyObject *v, const formatdef *f)
354{
355 long x;
356 if (get_long(v, &x) < 0)
357 return -1;
358 if (x < -128 || x > 127){
359 PyErr_SetString(StructError,
360 "byte format requires -128<=number<=127");
361 return -1;
362 }
363 *p = (char)x;
364 return 0;
365}
366
367static int
368np_ubyte(char *p, PyObject *v, const formatdef *f)
369{
370 long x;
371 if (get_long(v, &x) < 0)
372 return -1;
373 if (x < 0 || x > 255){
374 PyErr_SetString(StructError,
375 "ubyte format requires 0<=number<=255");
376 return -1;
377 }
378 *p = (char)x;
379 return 0;
380}
381
382static int
383np_char(char *p, PyObject *v, const formatdef *f)
384{
385 if (!PyString_Check(v) || PyString_Size(v) != 1) {
386 PyErr_SetString(StructError,
387 "char format require string of length 1");
388 return -1;
389 }
390 *p = *PyString_AsString(v);
391 return 0;
392}
393
394static int
395np_short(char *p, PyObject *v, const formatdef *f)
396{
397 long x;
398 short y;
399 if (get_long(v, &x) < 0)
400 return -1;
401 if (x < SHRT_MIN || x > SHRT_MAX){
402 PyErr_SetString(StructError,
403 "short format requires " STRINGIFY(SHRT_MIN)
404 "<=number<=" STRINGIFY(SHRT_MAX));
405 return -1;
406 }
407 y = (short)x;
408 memcpy(p, (char *)&y, sizeof y);
409 return 0;
410}
411
412static int
413np_ushort(char *p, PyObject *v, const formatdef *f)
414{
415 long x;
416 unsigned short y;
417 if (get_long(v, &x) < 0)
418 return -1;
419 if (x < 0 || x > USHRT_MAX){
420 PyErr_SetString(StructError,
421 "short format requires 0<=number<=" STRINGIFY(USHRT_MAX));
422 return -1;
423 }
424 y = (unsigned short)x;
425 memcpy(p, (char *)&y, sizeof y);
426 return 0;
427}
428
429static int
430np_int(char *p, PyObject *v, const formatdef *f)
431{
432 long x;
433 int y;
434 if (get_long(v, &x) < 0)
435 return -1;
436 y = (int)x;
437 memcpy(p, (char *)&y, sizeof y);
438 return 0;
439}
440
441static int
442np_uint(char *p, PyObject *v, const formatdef *f)
443{
444 unsigned long x;
445 unsigned int y;
446 if (get_ulong(v, &x) < 0)
447 return -1;
448 y = (unsigned int)x;
449 memcpy(p, (char *)&y, sizeof y);
450 return 0;
451}
452
453static int
454np_long(char *p, PyObject *v, const formatdef *f)
455{
456 long x;
457 if (get_long(v, &x) < 0)
458 return -1;
459 memcpy(p, (char *)&x, sizeof x);
460 return 0;
461}
462
463static int
464np_ulong(char *p, PyObject *v, const formatdef *f)
465{
466 unsigned long x;
467 if (get_ulong(v, &x) < 0)
468 return -1;
469 memcpy(p, (char *)&x, sizeof x);
470 return 0;
471}
472
473#ifdef HAVE_LONG_LONG
474
475static int
476np_longlong(char *p, PyObject *v, const formatdef *f)
477{
478 PY_LONG_LONG x;
479 if (get_longlong(v, &x) < 0)
480 return -1;
481 memcpy(p, (char *)&x, sizeof x);
482 return 0;
483}
484
485static int
486np_ulonglong(char *p, PyObject *v, const formatdef *f)
487{
488 unsigned PY_LONG_LONG x;
489 if (get_ulonglong(v, &x) < 0)
490 return -1;
491 memcpy(p, (char *)&x, sizeof x);
492 return 0;
493}
494#endif
495
496static int
497np_float(char *p, PyObject *v, const formatdef *f)
498{
499 float x = (float)PyFloat_AsDouble(v);
500 if (x == -1 && PyErr_Occurred()) {
501 PyErr_SetString(StructError,
502 "required argument is not a float");
503 return -1;
504 }
505 memcpy(p, (char *)&x, sizeof x);
506 return 0;
507}
508
509static int
510np_double(char *p, PyObject *v, const formatdef *f)
511{
512 double x = PyFloat_AsDouble(v);
513 if (x == -1 && PyErr_Occurred()) {
514 PyErr_SetString(StructError,
515 "required argument is not a float");
516 return -1;
517 }
518 memcpy(p, (char *)&x, sizeof(double));
519 return 0;
520}
521
522static int
523np_void_p(char *p, PyObject *v, const formatdef *f)
524{
525 void *x;
526
527 v = get_pylong(v);
528 if (v == NULL)
529 return -1;
530 assert(PyLong_Check(v));
531 x = PyLong_AsVoidPtr(v);
532 Py_DECREF(v);
533 if (x == NULL && PyErr_Occurred())
534 return -1;
535 memcpy(p, (char *)&x, sizeof x);
536 return 0;
537}
538
539static formatdef native_table[] = {
540 {'x', sizeof(char), 0, NULL},
541 {'b', sizeof(char), 0, nu_byte, np_byte},
542 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
543 {'c', sizeof(char), 0, nu_char, np_char},
544 {'s', sizeof(char), 0, NULL},
545 {'p', sizeof(char), 0, NULL},
546 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
547 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
548 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
549 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
550 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
551 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
552 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
553 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
554 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
555#ifdef HAVE_LONG_LONG
556 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
557 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
558#endif
559 {0}
560};
561
562/* Big-endian routines. *****************************************************/
563
564static PyObject *
565bu_int(const char *p, const formatdef *f)
566{
567 long x = 0;
568 int i = f->size;
569 do {
570 x = (x<<8) | (*p++ & 0xFF);
571 } while (--i > 0);
572 /* Extend the sign bit. */
573 if (SIZEOF_LONG > f->size)
574 x |= -(x & (1L << (8*f->size - 1)));
575 return PyInt_FromLong(x);
576}
577
578static PyObject *
579bu_uint(const char *p, const formatdef *f)
580{
581 unsigned long x = 0;
582 int i = f->size;
583 do {
584 x = (x<<8) | (*p++ & 0xFF);
585 } while (--i > 0);
586 if (f->size >= 4)
587 return PyLong_FromUnsignedLong(x);
588 else
589 return PyInt_FromLong((long)x);
590}
591
592static PyObject *
593bu_longlong(const char *p, const formatdef *f)
594{
595 return _PyLong_FromByteArray((const unsigned char *)p,
596 8,
597 0, /* little-endian */
598 1 /* signed */);
599}
600
601static PyObject *
602bu_ulonglong(const char *p, const formatdef *f)
603{
604 return _PyLong_FromByteArray((const unsigned char *)p,
605 8,
606 0, /* little-endian */
607 0 /* signed */);
608}
609
610static PyObject *
611bu_float(const char *p, const formatdef *f)
612{
613 return unpack_float(p, 0);
614}
615
616static PyObject *
617bu_double(const char *p, const formatdef *f)
618{
619 return unpack_double(p, 0);
620}
621
622static int
623bp_int(char *p, PyObject *v, const formatdef *f)
624{
625 long x;
626 int i;
627 if (get_long(v, &x) < 0)
628 return -1;
629 i = f->size;
630 do {
631 p[--i] = (char)x;
632 x >>= 8;
633 } while (i > 0);
634 return 0;
635}
636
637static int
638bp_uint(char *p, PyObject *v, const formatdef *f)
639{
640 unsigned long x;
641 int i;
642 if (get_ulong(v, &x) < 0)
643 return -1;
644 i = f->size;
645 do {
646 p[--i] = (char)x;
647 x >>= 8;
648 } while (i > 0);
649 return 0;
650}
651
652static int
653bp_longlong(char *p, PyObject *v, const formatdef *f)
654{
655 int res;
656 v = get_pylong(v);
657 if (v == NULL)
658 return -1;
659 res = _PyLong_AsByteArray((PyLongObject *)v,
660 (unsigned char *)p,
661 8,
662 0, /* little_endian */
663 1 /* signed */);
664 Py_DECREF(v);
665 return res;
666}
667
668static int
669bp_ulonglong(char *p, PyObject *v, const formatdef *f)
670{
671 int res;
672 v = get_pylong(v);
673 if (v == NULL)
674 return -1;
675 res = _PyLong_AsByteArray((PyLongObject *)v,
676 (unsigned char *)p,
677 8,
678 0, /* little_endian */
679 0 /* signed */);
680 Py_DECREF(v);
681 return res;
682}
683
684static int
685bp_float(char *p, PyObject *v, const formatdef *f)
686{
687 double x = PyFloat_AsDouble(v);
688 if (x == -1 && PyErr_Occurred()) {
689 PyErr_SetString(StructError,
690 "required argument is not a float");
691 return -1;
692 }
693 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
694}
695
696static int
697bp_double(char *p, PyObject *v, const formatdef *f)
698{
699 double x = PyFloat_AsDouble(v);
700 if (x == -1 && PyErr_Occurred()) {
701 PyErr_SetString(StructError,
702 "required argument is not a float");
703 return -1;
704 }
705 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
706}
707
708static formatdef bigendian_table[] = {
709 {'x', 1, 0, NULL},
710 {'b', 1, 0, bu_int, bp_int},
711 {'B', 1, 0, bu_uint, bp_int},
712 {'c', 1, 0, nu_char, np_char},
713 {'s', 1, 0, NULL},
714 {'p', 1, 0, NULL},
715 {'h', 2, 0, bu_int, bp_int},
716 {'H', 2, 0, bu_uint, bp_uint},
717 {'i', 4, 0, bu_int, bp_int},
718 {'I', 4, 0, bu_uint, bp_uint},
719 {'l', 4, 0, bu_int, bp_int},
720 {'L', 4, 0, bu_uint, bp_uint},
721 {'q', 8, 0, bu_longlong, bp_longlong},
722 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
723 {'f', 4, 0, bu_float, bp_float},
724 {'d', 8, 0, bu_double, bp_double},
725 {0}
726};
727
728/* Little-endian routines. *****************************************************/
729
730static PyObject *
731lu_int(const char *p, const formatdef *f)
732{
733 long x = 0;
734 int i = f->size;
735 do {
736 x = (x<<8) | (p[--i] & 0xFF);
737 } while (i > 0);
738 /* Extend the sign bit. */
739 if (SIZEOF_LONG > f->size)
740 x |= -(x & (1L << (8*f->size - 1)));
741 return PyInt_FromLong(x);
742}
743
744static PyObject *
745lu_uint(const char *p, const formatdef *f)
746{
747 unsigned long x = 0;
748 int i = f->size;
749 do {
750 x = (x<<8) | (p[--i] & 0xFF);
751 } while (i > 0);
752 if (f->size >= 4)
753 return PyLong_FromUnsignedLong(x);
754 else
755 return PyInt_FromLong((long)x);
756}
757
758static PyObject *
759lu_longlong(const char *p, const formatdef *f)
760{
761 return _PyLong_FromByteArray((const unsigned char *)p,
762 8,
763 1, /* little-endian */
764 1 /* signed */);
765}
766
767static PyObject *
768lu_ulonglong(const char *p, const formatdef *f)
769{
770 return _PyLong_FromByteArray((const unsigned char *)p,
771 8,
772 1, /* little-endian */
773 0 /* signed */);
774}
775
776static PyObject *
777lu_float(const char *p, const formatdef *f)
778{
779 return unpack_float(p, 1);
780}
781
782static PyObject *
783lu_double(const char *p, const formatdef *f)
784{
785 return unpack_double(p, 1);
786}
787
788static int
789lp_int(char *p, PyObject *v, const formatdef *f)
790{
791 long x;
792 int i;
793 if (get_long(v, &x) < 0)
794 return -1;
795 i = f->size;
796 do {
797 *p++ = (char)x;
798 x >>= 8;
799 } while (--i > 0);
800 return 0;
801}
802
803static int
804lp_uint(char *p, PyObject *v, const formatdef *f)
805{
806 unsigned long x;
807 int i;
808 if (get_ulong(v, &x) < 0)
809 return -1;
810 i = f->size;
811 do {
812 *p++ = (char)x;
813 x >>= 8;
814 } while (--i > 0);
815 return 0;
816}
817
818static int
819lp_longlong(char *p, PyObject *v, const formatdef *f)
820{
821 int res;
822 v = get_pylong(v);
823 if (v == NULL)
824 return -1;
825 res = _PyLong_AsByteArray((PyLongObject*)v,
826 (unsigned char *)p,
827 8,
828 1, /* little_endian */
829 1 /* signed */);
830 Py_DECREF(v);
831 return res;
832}
833
834static int
835lp_ulonglong(char *p, PyObject *v, const formatdef *f)
836{
837 int res;
838 v = get_pylong(v);
839 if (v == NULL)
840 return -1;
841 res = _PyLong_AsByteArray((PyLongObject*)v,
842 (unsigned char *)p,
843 8,
844 1, /* little_endian */
845 0 /* signed */);
846 Py_DECREF(v);
847 return res;
848}
849
850static int
851lp_float(char *p, PyObject *v, const formatdef *f)
852{
853 double x = PyFloat_AsDouble(v);
854 if (x == -1 && PyErr_Occurred()) {
855 PyErr_SetString(StructError,
856 "required argument is not a float");
857 return -1;
858 }
859 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
860}
861
862static int
863lp_double(char *p, PyObject *v, const formatdef *f)
864{
865 double x = PyFloat_AsDouble(v);
866 if (x == -1 && PyErr_Occurred()) {
867 PyErr_SetString(StructError,
868 "required argument is not a float");
869 return -1;
870 }
871 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
872}
873
874static formatdef lilendian_table[] = {
875 {'x', 1, 0, NULL},
876 {'b', 1, 0, lu_int, lp_int},
877 {'B', 1, 0, lu_uint, lp_int},
878 {'c', 1, 0, nu_char, np_char},
879 {'s', 1, 0, NULL},
880 {'p', 1, 0, NULL},
881 {'h', 2, 0, lu_int, lp_int},
882 {'H', 2, 0, lu_uint, lp_uint},
883 {'i', 4, 0, lu_int, lp_int},
884 {'I', 4, 0, lu_uint, lp_uint},
885 {'l', 4, 0, lu_int, lp_int},
886 {'L', 4, 0, lu_uint, lp_uint},
887 {'q', 8, 0, lu_longlong, lp_longlong},
888 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
889 {'f', 4, 0, lu_float, lp_float},
890 {'d', 8, 0, lu_double, lp_double},
891 {0}
892};
893
894
895static const formatdef *
896whichtable(char **pfmt)
897{
898 const char *fmt = (*pfmt)++; /* May be backed out of later */
899 switch (*fmt) {
900 case '<':
901 return lilendian_table;
902 case '>':
903 case '!': /* Network byte order is big-endian */
904 return bigendian_table;
905 case '=': { /* Host byte order -- different from native in aligment! */
906 int n = 1;
907 char *p = (char *) &n;
908 if (*p == 1)
909 return lilendian_table;
910 else
911 return bigendian_table;
912 }
913 default:
914 --*pfmt; /* Back out of pointer increment */
915 /* Fall through */
916 case '@':
917 return native_table;
918 }
919}
920
921
922/* Get the table entry for a format code */
923
924static const formatdef *
925getentry(int c, const formatdef *f)
926{
927 for (; f->format != '\0'; f++) {
928 if (f->format == c) {
929 return f;
930 }
931 }
932 PyErr_SetString(StructError, "bad char in struct format");
933 return NULL;
934}
935
936
937/* Align a size according to a format code */
938
939static int
940align(int size, int c, const formatdef *e)
941{
942 if (e->format == c) {
943 if (e->alignment) {
944 size = ((size + e->alignment - 1)
945 / e->alignment)
946 * e->alignment;
947 }
948 }
949 return size;
950}
951
952
953/* calculate the size of a format string */
954
955static int
956prepare_s(PyStructObject *self)
957{
958 const formatdef *f;
959 const formatdef *e;
960 formatcode *codes;
961
962 const char *s;
963 const char *fmt;
964 char c;
965 int size, len, numcodes, num, itemsize, x;
966
967 fmt = PyString_AS_STRING(self->s_format);
968
969 f = whichtable((char **)&fmt);
970
971 s = fmt;
972 size = 0;
973 len = 0;
974 numcodes = 0;
975 while ((c = *s++) != '\0') {
976 if (isspace(Py_CHARMASK(c)))
977 continue;
978 if ('0' <= c && c <= '9') {
979 num = c - '0';
980 while ('0' <= (c = *s++) && c <= '9') {
981 x = num*10 + (c - '0');
982 if (x/10 != num) {
983 PyErr_SetString(
984 StructError,
985 "overflow in item count");
986 return -1;
987 }
988 num = x;
989 }
990 if (c == '\0')
991 break;
992 }
993 else
994 num = 1;
995
996 e = getentry(c, f);
997 if (e == NULL)
998 return -1;
999
1000 switch (c) {
1001 case 's': /* fall through */
1002 case 'p': len++; break;
1003 case 'x': break;
1004 default: len += num; break;
1005 }
1006 if (c != 'x') numcodes++;
1007
1008 itemsize = e->size;
1009 size = align(size, c, e);
1010 x = num * itemsize;
1011 size += x;
1012 if (x/itemsize != num || size < 0) {
1013 PyErr_SetString(StructError,
1014 "total struct size too long");
1015 return -1;
1016 }
1017 }
1018
1019 self->s_size = size;
1020 self->s_len = len;
1021 codes = PyMem_MALLOC((numcodes + 1) * sizeof(formatcode));
1022 if (codes == NULL) {
1023 PyErr_NoMemory();
1024 return -1;
1025 }
1026 self->s_codes = codes;
1027
1028 s = fmt;
1029 size = 0;
1030 while ((c = *s++) != '\0') {
1031 if (isspace(Py_CHARMASK(c)))
1032 continue;
1033 if ('0' <= c && c <= '9') {
1034 num = c - '0';
1035 while ('0' <= (c = *s++) && c <= '9')
1036 num = num*10 + (c - '0');
1037 if (c == '\0')
1038 break;
1039 }
1040 else
1041 num = 1;
1042
1043 e = getentry(c, f);
1044
1045 size = align(size, c, e);
1046 if (c != 'x') {
1047 codes->offset = size;
1048 codes->repeat = num;
1049 codes->fmtdef = e;
1050 codes++;
1051 }
1052 size += num * e->size;
1053 }
1054 codes->fmtdef = NULL;
1055 codes->offset = -1;
1056 codes->repeat = -1;
1057
1058 return 0;
1059}
1060
1061static PyObject *
1062s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1063{
1064 PyObject *self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001065
1066 assert(type != NULL && type->tp_alloc != NULL);
1067
1068 self = type->tp_alloc(type, 0);
1069 if (self != NULL) {
1070 PyStructObject *s = (PyStructObject*)self;
1071 Py_INCREF(Py_None);
1072 s->s_format = Py_None;
1073 s->s_codes = NULL;
1074 s->s_size = -1;
1075 s->s_len = -1;
1076 }
1077 return self;
1078}
1079
1080static int
1081s_init(PyObject *self, PyObject *args, PyObject *kwds)
1082{
1083 PyStructObject *soself = (PyStructObject *)self;
1084 PyObject *o_format = NULL;
1085 int ret = 0;
1086 static char *kwlist[] = {"format", 0};
1087
1088 assert(PyStruct_Check(self));
1089
1090 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1091 &o_format))
1092 return -1;
1093
1094 Py_INCREF(o_format);
1095 Py_XDECREF(soself->s_format);
1096 soself->s_format = o_format;
1097
1098 ret = prepare_s(soself);
1099 return ret;
1100}
1101
1102static void
1103s_dealloc(PyStructObject *s)
1104{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001105 if (s->weakreflist != NULL)
1106 PyObject_ClearWeakRefs((PyObject *)s);
1107 if (s->s_codes != NULL) {
1108 PyMem_FREE(s->s_codes);
1109 }
1110 Py_XDECREF(s->s_format);
1111 s->ob_type->tp_free((PyObject *)s);
1112}
1113
1114PyDoc_STRVAR(s_unpack__doc__,
1115"unpack(str) -> (v1, v2, ...)\n\
1116\n\
1117Return tuple containing values unpacked according to this Struct's format.\n\
1118Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1119strings.");
1120
1121static PyObject *
1122s_unpack(PyObject *self, PyObject *inputstr)
1123{
1124 PyStructObject *soself;
1125 PyObject *result;
1126 char *restart;
1127 formatcode *code;
1128 Py_ssize_t i;
1129
1130 soself = (PyStructObject *)self;
1131 assert(PyStruct_Check(self));
1132 assert(soself->s_codes != NULL);
1133 if (inputstr == NULL || !PyString_Check(inputstr) ||
1134 PyString_GET_SIZE(inputstr) != soself->s_size) {
1135 PyErr_Format(StructError,
1136 "unpack requires a string argument of length %d", soself->s_size);
1137 return NULL;
1138 }
1139 result = PyTuple_New(soself->s_len);
1140 if (result == NULL)
1141 return NULL;
1142
1143
1144 restart = PyString_AS_STRING(inputstr);
1145 i = 0;
1146 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1147 Py_ssize_t n;
1148 PyObject *v;
1149 const formatdef *e = code->fmtdef;
1150 const char *res = restart + code->offset;
1151 if (e->format == 's') {
1152 v = PyString_FromStringAndSize(res, code->repeat);
1153 if (v == NULL)
1154 goto fail;
1155 PyTuple_SET_ITEM(result, i++, v);
1156 } else if (e->format == 'p') {
1157 n = *(unsigned char*)res;
1158 if (n >= code->repeat)
1159 n = code->repeat - 1;
1160 v = PyString_FromStringAndSize(res + 1, n);
1161 if (v == NULL)
1162 goto fail;
1163 PyTuple_SET_ITEM(result, i++, v);
1164 } else {
1165 for (n = 0; n < code->repeat; n++) {
1166 v = e->unpack(res, e);
1167 if (v == NULL)
1168 goto fail;
1169 PyTuple_SET_ITEM(result, i++, v);
1170 res += e->size;
1171 }
1172 }
1173 }
1174
1175 return result;
1176fail:
1177 Py_DECREF(result);
1178 return NULL;
1179};
1180
1181
1182PyDoc_STRVAR(s_pack__doc__,
1183"pack(v1, v2, ...) -> string\n\
1184\n\
1185Return a string containing values v1, v2, ... packed according to this\n\
1186Struct's format. See struct.__doc__ for more on format strings.");
1187
1188static PyObject *
1189s_pack(PyObject *self, PyObject *args)
1190{
1191 PyStructObject *soself;
1192 PyObject *result;
1193 char *restart;
1194 formatcode *code;
1195 Py_ssize_t i;
1196
1197 soself = (PyStructObject *)self;
1198 assert(PyStruct_Check(self));
1199 assert(soself->s_codes != NULL);
1200 if (args == NULL || !PyTuple_Check(args) ||
1201 PyTuple_GET_SIZE(args) != soself->s_len)
1202 {
1203 PyErr_Format(StructError,
1204 "pack requires exactly %d arguments", soself->s_len);
1205 return NULL;
1206 }
1207
1208 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1209 if (result == NULL)
1210 return NULL;
1211
1212 restart = PyString_AS_STRING(result);
1213 memset(restart, '\0', soself->s_size);
1214 i = 0;
1215 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1216 Py_ssize_t n;
1217 PyObject *v;
1218 const formatdef *e = code->fmtdef;
1219 char *res = restart + code->offset;
1220 if (e->format == 's') {
1221 v = PyTuple_GET_ITEM(args, i++);
1222 if (!PyString_Check(v)) {
1223 PyErr_SetString(StructError,
1224 "argument for 's' must be a string");
1225 goto fail;
1226 }
1227 n = PyString_GET_SIZE(v);
1228 if (n > code->repeat)
1229 n = code->repeat;
1230 if (n > 0)
1231 memcpy(res, PyString_AS_STRING(v), n);
1232 } else if (e->format == 'p') {
1233 v = PyTuple_GET_ITEM(args, i++);
1234 if (!PyString_Check(v)) {
1235 PyErr_SetString(StructError,
1236 "argument for 'p' must be a string");
1237 goto fail;
1238 }
1239 n = PyString_GET_SIZE(v);
1240 if (n > (code->repeat - 1))
1241 n = code->repeat - 1;
1242 if (n > 0)
1243 memcpy(res + 1, PyString_AS_STRING(v), n);
1244 if (n > 255)
1245 n = 255;
1246 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1247 } else {
1248 for (n = 0; n < code->repeat; n++) {
1249 v = PyTuple_GET_ITEM(args, i++);
1250 if (e->pack(res, v, e) < 0)
1251 goto fail;
1252 res += e->size;
1253 }
1254 }
1255 }
1256
1257 return result;
1258
1259fail:
1260 Py_DECREF(result);
1261 return NULL;
1262
1263}
1264
1265
1266/* List of functions */
1267
1268static struct PyMethodDef s_methods[] = {
1269 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1270 {"unpack", s_unpack, METH_O, s_unpack__doc__},
1271 {NULL, NULL} /* sentinel */
1272};
1273
1274PyDoc_STRVAR(s__doc__, "Compiled struct object");
1275
1276#define OFF(x) offsetof(PyStructObject, x)
1277
1278static PyMemberDef s_memberlist[] = {
1279 {"format", T_OBJECT, OFF(s_format), RO,
1280 "struct format string"},
1281 {"size", T_INT, OFF(s_size), RO,
1282 "struct size in bytes"},
1283 {"_len", T_INT, OFF(s_len), RO,
1284 "number of items expected in tuple"},
1285 {NULL} /* Sentinel */
1286};
1287
1288
1289static
1290PyTypeObject PyStructType = {
1291 PyObject_HEAD_INIT(&PyType_Type)
1292 0,
1293 "Struct",
1294 sizeof(PyStructObject),
1295 0,
1296 (destructor)s_dealloc, /* tp_dealloc */
1297 0, /* tp_print */
1298 0, /* tp_getattr */
1299 0, /* tp_setattr */
1300 0, /* tp_compare */
1301 0, /* tp_repr */
1302 0, /* tp_as_number */
1303 0, /* tp_as_sequence */
1304 0, /* tp_as_mapping */
1305 0, /* tp_hash */
1306 0, /* tp_call */
1307 0, /* tp_str */
1308 PyObject_GenericGetAttr, /* tp_getattro */
1309 PyObject_GenericSetAttr, /* tp_setattro */
1310 0, /* tp_as_buffer */
1311 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
1312 s__doc__, /* tp_doc */
1313 0, /* tp_traverse */
1314 0, /* tp_clear */
1315 0, /* tp_richcompare */
1316 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1317 0, /* tp_iter */
1318 0, /* tp_iternext */
1319 s_methods, /* tp_methods */
1320 s_memberlist, /* tp_members */
1321 0, /* tp_getset */
1322 0, /* tp_base */
1323 0, /* tp_dict */
1324 0, /* tp_descr_get */
1325 0, /* tp_descr_set */
1326 0, /* tp_dictoffset */
1327 s_init, /* tp_init */
1328 PyType_GenericAlloc, /* tp_alloc */
1329 s_new, /* tp_new */
1330 PyObject_Del, /* tp_free */
1331};
1332
1333/* Module initialization */
1334
1335PyMODINIT_FUNC
1336init_struct(void)
1337{
1338 PyObject *m = Py_InitModule("_struct", NULL);
1339 if (m == NULL)
1340 return;
1341
1342 /* Add some symbolic constants to the module */
1343 if (StructError == NULL) {
1344 StructError = PyErr_NewException("struct.error", NULL, NULL);
1345 if (StructError == NULL)
1346 return;
1347 }
1348 Py_INCREF(StructError);
1349 PyModule_AddObject(m, "error", StructError);
1350 Py_INCREF((PyObject*)&PyStructType);
1351 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
1352}