blob: cb2e5380d592cd77f60d361d54568ecdb7d0f566 [file] [log] [blame]
Thomas Wouters477c8d52006-05-27 19:21:47 +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#define PY_SSIZE_T_CLEAN
7
8#include "Python.h"
9#include "structseq.h"
10#include "structmember.h"
11#include <ctype.h>
12
13static PyTypeObject PyStructType;
14
15/* compatibility macros */
16#if (PY_VERSION_HEX < 0x02050000)
17typedef int Py_ssize_t;
18#endif
19
20/* The translation function for each format character is table driven */
21typedef struct _formatdef {
22 char format;
23 Py_ssize_t size;
24 Py_ssize_t alignment;
25 PyObject* (*unpack)(const char *,
26 const struct _formatdef *);
27 int (*pack)(char *, PyObject *,
28 const struct _formatdef *);
29} formatdef;
30
31typedef struct _formatcode {
32 const struct _formatdef *fmtdef;
33 Py_ssize_t offset;
34 Py_ssize_t size;
35} formatcode;
36
37/* Struct object interface */
38
39typedef struct {
40 PyObject_HEAD
41 Py_ssize_t s_size;
42 Py_ssize_t s_len;
43 formatcode *s_codes;
44 PyObject *s_format;
45 PyObject *weakreflist; /* List of weak references */
46} PyStructObject;
47
48
49#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
50#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
51
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 if (get_long(v, (long *)p) < 0)
147 return -1;
148 if (((long)*p) < 0) {
149 PyErr_SetString(StructError,
150 "unsigned argument is < 0");
151 return -1;
152 }
153 return 0;
154}
155
156#ifdef HAVE_LONG_LONG
157
158/* Same, but handling native long long. */
159
160static int
161get_longlong(PyObject *v, PY_LONG_LONG *p)
162{
163 PY_LONG_LONG x;
164
165 v = get_pylong(v);
166 if (v == NULL)
167 return -1;
168 assert(PyLong_Check(v));
169 x = PyLong_AsLongLong(v);
170 Py_DECREF(v);
171 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
172 return -1;
173 *p = x;
174 return 0;
175}
176
177/* Same, but handling native unsigned long long. */
178
179static int
180get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
181{
182 unsigned PY_LONG_LONG x;
183
184 v = get_pylong(v);
185 if (v == NULL)
186 return -1;
187 assert(PyLong_Check(v));
188 x = PyLong_AsUnsignedLongLong(v);
189 Py_DECREF(v);
190 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
191 return -1;
192 *p = x;
193 return 0;
194}
195
196#endif
197
198/* Floating point helpers */
199
200static PyObject *
201unpack_float(const char *p, /* start of 4-byte string */
202 int le) /* true for little-endian, false for big-endian */
203{
204 double x;
205
206 x = _PyFloat_Unpack4((unsigned char *)p, le);
207 if (x == -1.0 && PyErr_Occurred())
208 return NULL;
209 return PyFloat_FromDouble(x);
210}
211
212static PyObject *
213unpack_double(const char *p, /* start of 8-byte string */
214 int le) /* true for little-endian, false for big-endian */
215{
216 double x;
217
218 x = _PyFloat_Unpack8((unsigned char *)p, le);
219 if (x == -1.0 && PyErr_Occurred())
220 return NULL;
221 return PyFloat_FromDouble(x);
222}
223
224/* Helper to format the range error exceptions */
225static int
226_range_error(char format, Py_ssize_t size, int is_unsigned)
227{
228 if (is_unsigned == 0) {
229 long smallest = 0, largest = 0;
230 Py_ssize_t i = size * 8;
231 while (--i > 0) {
232 smallest = (smallest * 2) - 1;
233 largest = (largest * 2) + 1;
234 }
235 PyErr_Format(StructError,
236 "'%c' format requires %ld <= number <= %ld",
237 format,
238 smallest,
239 largest);
240 } else {
241 unsigned long largest = 0;
242 Py_ssize_t i = size * 8;
243 while (--i >= 0)
244 largest = (largest * 2) + 1;
245 PyErr_Format(StructError,
246 "'%c' format requires 0 <= number <= %lu",
247 format,
248 largest);
249 }
250 return -1;
251}
252
253
254
255/* A large number of small routines follow, with names of the form
256
257 [bln][up]_TYPE
258
259 [bln] distiguishes among big-endian, little-endian and native.
260 [pu] distiguishes between pack (to struct) and unpack (from struct).
261 TYPE is one of char, byte, ubyte, etc.
262*/
263
264/* Native mode routines. ****************************************************/
265/* NOTE:
266 In all n[up]_<type> routines handling types larger than 1 byte, there is
267 *no* guarantee that the p pointer is properly aligned for each type,
268 therefore memcpy is called. An intermediate variable is used to
269 compensate for big-endian architectures.
270 Normally both the intermediate variable and the memcpy call will be
271 skipped by C optimisation in little-endian architectures (gcc >= 2.91
272 does this). */
273
274static PyObject *
275nu_char(const char *p, const formatdef *f)
276{
277 return PyString_FromStringAndSize(p, 1);
278}
279
280static PyObject *
281nu_byte(const char *p, const formatdef *f)
282{
283 return PyInt_FromLong((long) *(signed char *)p);
284}
285
286static PyObject *
287nu_ubyte(const char *p, const formatdef *f)
288{
289 return PyInt_FromLong((long) *(unsigned char *)p);
290}
291
292static PyObject *
293nu_short(const char *p, const formatdef *f)
294{
295 short x;
296 memcpy((char *)&x, p, sizeof x);
297 return PyInt_FromLong((long)x);
298}
299
300static PyObject *
301nu_ushort(const char *p, const formatdef *f)
302{
303 unsigned short x;
304 memcpy((char *)&x, p, sizeof x);
305 return PyInt_FromLong((long)x);
306}
307
308static PyObject *
309nu_int(const char *p, const formatdef *f)
310{
311 int x;
312 memcpy((char *)&x, p, sizeof x);
313 return PyInt_FromLong((long)x);
314}
315
316static PyObject *
317nu_uint(const char *p, const formatdef *f)
318{
319 unsigned int x;
320 memcpy((char *)&x, p, sizeof x);
321#if (SIZEOF_LONG > SIZEOF_INT)
322 return PyInt_FromLong((long)x);
323#else
324 if (x <= ((unsigned int)LONG_MAX))
325 return PyInt_FromLong((long)x);
326 return PyLong_FromUnsignedLong((unsigned long)x);
327#endif
328}
329
330static PyObject *
331nu_long(const char *p, const formatdef *f)
332{
333 long x;
334 memcpy((char *)&x, p, sizeof x);
335 return PyInt_FromLong(x);
336}
337
338static PyObject *
339nu_ulong(const char *p, const formatdef *f)
340{
341 unsigned long x;
342 memcpy((char *)&x, p, sizeof x);
343 if (x <= LONG_MAX)
344 return PyInt_FromLong((long)x);
345 return PyLong_FromUnsignedLong(x);
346}
347
348/* Native mode doesn't support q or Q unless the platform C supports
349 long long (or, on Windows, __int64). */
350
351#ifdef HAVE_LONG_LONG
352
353static PyObject *
354nu_longlong(const char *p, const formatdef *f)
355{
356 PY_LONG_LONG x;
357 memcpy((char *)&x, p, sizeof x);
358 if (x >= LONG_MIN && x <= LONG_MAX)
359 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
360 return PyLong_FromLongLong(x);
361}
362
363static PyObject *
364nu_ulonglong(const char *p, const formatdef *f)
365{
366 unsigned PY_LONG_LONG x;
367 memcpy((char *)&x, p, sizeof x);
368 if (x <= LONG_MAX)
369 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
370 return PyLong_FromUnsignedLongLong(x);
371}
372
373#endif
374
375static PyObject *
376nu_float(const char *p, const formatdef *f)
377{
378 float x;
379 memcpy((char *)&x, p, sizeof x);
380 return PyFloat_FromDouble((double)x);
381}
382
383static PyObject *
384nu_double(const char *p, const formatdef *f)
385{
386 double x;
387 memcpy((char *)&x, p, sizeof x);
388 return PyFloat_FromDouble(x);
389}
390
391static PyObject *
392nu_void_p(const char *p, const formatdef *f)
393{
394 void *x;
395 memcpy((char *)&x, p, sizeof x);
396 return PyLong_FromVoidPtr(x);
397}
398
399static int
400np_byte(char *p, PyObject *v, const formatdef *f)
401{
402 long x;
403 if (get_long(v, &x) < 0)
404 return -1;
405 if (x < -128 || x > 127){
406 PyErr_SetString(StructError,
407 "byte format requires -128 <= number <= 127");
408 return -1;
409 }
410 *p = (char)x;
411 return 0;
412}
413
414static int
415np_ubyte(char *p, PyObject *v, const formatdef *f)
416{
417 long x;
418 if (get_long(v, &x) < 0)
419 return -1;
420 if (x < 0 || x > 255){
421 PyErr_SetString(StructError,
422 "ubyte format requires 0 <= number <= 255");
423 return -1;
424 }
425 *p = (char)x;
426 return 0;
427}
428
429static int
430np_char(char *p, PyObject *v, const formatdef *f)
431{
432 if (!PyString_Check(v) || PyString_Size(v) != 1) {
433 PyErr_SetString(StructError,
434 "char format require string of length 1");
435 return -1;
436 }
437 *p = *PyString_AsString(v);
438 return 0;
439}
440
441static int
442np_short(char *p, PyObject *v, const formatdef *f)
443{
444 long x;
445 short y;
446 if (get_long(v, &x) < 0)
447 return -1;
448 if (x < SHRT_MIN || x > SHRT_MAX){
449 PyErr_SetString(StructError,
450 "short format requires " STRINGIFY(SHRT_MIN)
451 " <= number <= " STRINGIFY(SHRT_MAX));
452 return -1;
453 }
454 y = (short)x;
455 memcpy(p, (char *)&y, sizeof y);
456 return 0;
457}
458
459static int
460np_ushort(char *p, PyObject *v, const formatdef *f)
461{
462 long x;
463 unsigned short y;
464 if (get_long(v, &x) < 0)
465 return -1;
466 if (x < 0 || x > USHRT_MAX){
467 PyErr_SetString(StructError,
468 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
469 return -1;
470 }
471 y = (unsigned short)x;
472 memcpy(p, (char *)&y, sizeof y);
473 return 0;
474}
475
476static int
477np_int(char *p, PyObject *v, const formatdef *f)
478{
479 long x;
480 int y;
481 if (get_long(v, &x) < 0)
482 return -1;
483#if (SIZEOF_LONG > SIZEOF_INT)
484 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
485 return _range_error(f->format, sizeof(y), 0);
486#endif
487 y = (int)x;
488 memcpy(p, (char *)&y, sizeof y);
489 return 0;
490}
491
492static int
493np_uint(char *p, PyObject *v, const formatdef *f)
494{
495 unsigned long x;
496 unsigned int y;
497 if (get_ulong(v, &x) < 0)
498 return _range_error(f->format, sizeof(y), 1);
499 y = (unsigned int)x;
500#if (SIZEOF_LONG > SIZEOF_INT)
501 if (x > ((unsigned long)UINT_MAX))
502 return _range_error(f->format, sizeof(y), 1);
503#endif
504 memcpy(p, (char *)&y, sizeof y);
505 return 0;
506}
507
508static int
509np_long(char *p, PyObject *v, const formatdef *f)
510{
511 long x;
512 if (get_long(v, &x) < 0)
513 return -1;
514 memcpy(p, (char *)&x, sizeof x);
515 return 0;
516}
517
518static int
519np_ulong(char *p, PyObject *v, const formatdef *f)
520{
521 unsigned long x;
522 if (get_ulong(v, &x) < 0)
523 return _range_error(f->format, sizeof(x), 1);
524 memcpy(p, (char *)&x, sizeof x);
525 return 0;
526}
527
528#ifdef HAVE_LONG_LONG
529
530static int
531np_longlong(char *p, PyObject *v, const formatdef *f)
532{
533 PY_LONG_LONG x;
534 if (get_longlong(v, &x) < 0)
535 return -1;
536 memcpy(p, (char *)&x, sizeof x);
537 return 0;
538}
539
540static int
541np_ulonglong(char *p, PyObject *v, const formatdef *f)
542{
543 unsigned PY_LONG_LONG x;
544 if (get_ulonglong(v, &x) < 0)
545 return -1;
546 memcpy(p, (char *)&x, sizeof x);
547 return 0;
548}
549#endif
550
551static int
552np_float(char *p, PyObject *v, const formatdef *f)
553{
554 float x = (float)PyFloat_AsDouble(v);
555 if (x == -1 && PyErr_Occurred()) {
556 PyErr_SetString(StructError,
557 "required argument is not a float");
558 return -1;
559 }
560 memcpy(p, (char *)&x, sizeof x);
561 return 0;
562}
563
564static int
565np_double(char *p, PyObject *v, const formatdef *f)
566{
567 double x = PyFloat_AsDouble(v);
568 if (x == -1 && PyErr_Occurred()) {
569 PyErr_SetString(StructError,
570 "required argument is not a float");
571 return -1;
572 }
573 memcpy(p, (char *)&x, sizeof(double));
574 return 0;
575}
576
577static int
578np_void_p(char *p, PyObject *v, const formatdef *f)
579{
580 void *x;
581
582 v = get_pylong(v);
583 if (v == NULL)
584 return -1;
585 assert(PyLong_Check(v));
586 x = PyLong_AsVoidPtr(v);
587 Py_DECREF(v);
588 if (x == NULL && PyErr_Occurred())
589 return -1;
590 memcpy(p, (char *)&x, sizeof x);
591 return 0;
592}
593
594static formatdef native_table[] = {
595 {'x', sizeof(char), 0, NULL},
596 {'b', sizeof(char), 0, nu_byte, np_byte},
597 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
598 {'c', sizeof(char), 0, nu_char, np_char},
599 {'s', sizeof(char), 0, NULL},
600 {'p', sizeof(char), 0, NULL},
601 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
602 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
603 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
604 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
605 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
606 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
607#ifdef HAVE_LONG_LONG
608 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
609 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
610#endif
611 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
612 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
613 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
614 {0}
615};
616
617/* Big-endian routines. *****************************************************/
618
619static PyObject *
620bu_int(const char *p, const formatdef *f)
621{
622 long x = 0;
623 Py_ssize_t i = f->size;
624 do {
625 x = (x<<8) | (*p++ & 0xFF);
626 } while (--i > 0);
627 /* Extend the sign bit. */
628 if (SIZEOF_LONG > f->size)
629 x |= -(x & (1L << ((8 * f->size) - 1)));
630 return PyInt_FromLong(x);
631}
632
633static PyObject *
634bu_uint(const char *p, const formatdef *f)
635{
636 unsigned long x = 0;
637 Py_ssize_t i = f->size;
638 do {
639 x = (x<<8) | (*p++ & 0xFF);
640 } while (--i > 0);
641 if (x <= LONG_MAX)
642 return PyInt_FromLong((long)x);
643 return PyLong_FromUnsignedLong(x);
644}
645
646static PyObject *
647bu_longlong(const char *p, const formatdef *f)
648{
649#ifdef HAVE_LONG_LONG
650 PY_LONG_LONG x = 0;
651 Py_ssize_t i = f->size;
652 do {
653 x = (x<<8) | (*p++ & 0xFF);
654 } while (--i > 0);
655 /* Extend the sign bit. */
656 if (SIZEOF_LONG_LONG > f->size)
657 x |= -(x & (1L << ((8 * f->size) - 1)));
658 if (x >= LONG_MIN && x <= LONG_MAX)
659 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
660 return PyLong_FromLongLong(x);
661#else
662 return _PyLong_FromByteArray((const unsigned char *)p,
663 8,
664 0, /* little-endian */
665 1 /* signed */);
666#endif
667}
668
669static PyObject *
670bu_ulonglong(const char *p, const formatdef *f)
671{
672#ifdef HAVE_LONG_LONG
673 unsigned PY_LONG_LONG x = 0;
674 Py_ssize_t i = f->size;
675 do {
676 x = (x<<8) | (*p++ & 0xFF);
677 } while (--i > 0);
678 if (x <= LONG_MAX)
679 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
680 return PyLong_FromUnsignedLongLong(x);
681#else
682 return _PyLong_FromByteArray((const unsigned char *)p,
683 8,
684 0, /* little-endian */
685 0 /* signed */);
686#endif
687}
688
689static PyObject *
690bu_float(const char *p, const formatdef *f)
691{
692 return unpack_float(p, 0);
693}
694
695static PyObject *
696bu_double(const char *p, const formatdef *f)
697{
698 return unpack_double(p, 0);
699}
700
701static int
702bp_int(char *p, PyObject *v, const formatdef *f)
703{
704 long x;
705 Py_ssize_t i;
706 if (get_long(v, &x) < 0)
707 return -1;
708 i = f->size;
709 if (i != SIZEOF_LONG) {
710 if ((i == 2) && (x < -32768 || x > 32767))
711 return _range_error(f->format, i, 0);
712#if (SIZEOF_LONG != 4)
713 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
714 return _range_error(f->format, i, 0);
715#endif
716 }
717 do {
718 p[--i] = (char)x;
719 x >>= 8;
720 } while (i > 0);
721 return 0;
722}
723
724static int
725bp_uint(char *p, PyObject *v, const formatdef *f)
726{
727 unsigned long x;
728 Py_ssize_t i;
729 if (get_ulong(v, &x) < 0)
730 return -1;
731 i = f->size;
732 if (i != SIZEOF_LONG) {
733 unsigned long maxint = 1;
734 maxint <<= (unsigned long)(i * 8);
735 if (x >= maxint)
736 return _range_error(f->format, f->size, 1);
737 }
738 do {
739 p[--i] = (char)x;
740 x >>= 8;
741 } while (i > 0);
742 return 0;
743}
744
745static int
746bp_longlong(char *p, PyObject *v, const formatdef *f)
747{
748 int res;
749 v = get_pylong(v);
750 if (v == NULL)
751 return -1;
752 res = _PyLong_AsByteArray((PyLongObject *)v,
753 (unsigned char *)p,
754 8,
755 0, /* little_endian */
756 1 /* signed */);
757 Py_DECREF(v);
758 return res;
759}
760
761static int
762bp_ulonglong(char *p, PyObject *v, const formatdef *f)
763{
764 int res;
765 v = get_pylong(v);
766 if (v == NULL)
767 return -1;
768 res = _PyLong_AsByteArray((PyLongObject *)v,
769 (unsigned char *)p,
770 8,
771 0, /* little_endian */
772 0 /* signed */);
773 Py_DECREF(v);
774 return res;
775}
776
777static int
778bp_float(char *p, PyObject *v, const formatdef *f)
779{
780 double x = PyFloat_AsDouble(v);
781 if (x == -1 && PyErr_Occurred()) {
782 PyErr_SetString(StructError,
783 "required argument is not a float");
784 return -1;
785 }
786 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
787}
788
789static int
790bp_double(char *p, PyObject *v, const formatdef *f)
791{
792 double x = PyFloat_AsDouble(v);
793 if (x == -1 && PyErr_Occurred()) {
794 PyErr_SetString(StructError,
795 "required argument is not a float");
796 return -1;
797 }
798 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
799}
800
801static formatdef bigendian_table[] = {
802 {'x', 1, 0, NULL},
803 {'b', 1, 0, nu_byte, np_byte},
804 {'B', 1, 0, nu_ubyte, np_ubyte},
805 {'c', 1, 0, nu_char, np_char},
806 {'s', 1, 0, NULL},
807 {'p', 1, 0, NULL},
808 {'h', 2, 0, bu_int, bp_int},
809 {'H', 2, 0, bu_uint, bp_uint},
810 {'i', 4, 0, bu_int, bp_int},
811 {'I', 4, 0, bu_uint, bp_uint},
812 {'l', 4, 0, bu_int, bp_int},
813 {'L', 4, 0, bu_uint, bp_uint},
814 {'q', 8, 0, bu_longlong, bp_longlong},
815 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
816 {'f', 4, 0, bu_float, bp_float},
817 {'d', 8, 0, bu_double, bp_double},
818 {0}
819};
820
821/* Little-endian routines. *****************************************************/
822
823static PyObject *
824lu_int(const char *p, const formatdef *f)
825{
826 long x = 0;
827 Py_ssize_t i = f->size;
828 do {
829 x = (x<<8) | (p[--i] & 0xFF);
830 } while (i > 0);
831 /* Extend the sign bit. */
832 if (SIZEOF_LONG > f->size)
833 x |= -(x & (1L << ((8 * f->size) - 1)));
834 return PyInt_FromLong(x);
835}
836
837static PyObject *
838lu_uint(const char *p, const formatdef *f)
839{
840 unsigned long x = 0;
841 Py_ssize_t i = f->size;
842 do {
843 x = (x<<8) | (p[--i] & 0xFF);
844 } while (i > 0);
845 if (x <= LONG_MAX)
846 return PyInt_FromLong((long)x);
847 return PyLong_FromUnsignedLong((long)x);
848}
849
850static PyObject *
851lu_longlong(const char *p, const formatdef *f)
852{
853#ifdef HAVE_LONG_LONG
854 PY_LONG_LONG x = 0;
855 Py_ssize_t i = f->size;
856 do {
857 x = (x<<8) | (p[--i] & 0xFF);
858 } while (i > 0);
859 /* Extend the sign bit. */
860 if (SIZEOF_LONG_LONG > f->size)
861 x |= -(x & (1L << ((8 * f->size) - 1)));
862 if (x >= LONG_MIN && x <= LONG_MAX)
863 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
864 return PyLong_FromLongLong(x);
865#else
866 return _PyLong_FromByteArray((const unsigned char *)p,
867 8,
868 1, /* little-endian */
869 1 /* signed */);
870#endif
871}
872
873static PyObject *
874lu_ulonglong(const char *p, const formatdef *f)
875{
876#ifdef HAVE_LONG_LONG
877 unsigned PY_LONG_LONG x = 0;
878 Py_ssize_t i = f->size;
879 do {
880 x = (x<<8) | (p[--i] & 0xFF);
881 } while (i > 0);
882 if (x <= LONG_MAX)
883 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
884 return PyLong_FromUnsignedLongLong(x);
885#else
886 return _PyLong_FromByteArray((const unsigned char *)p,
887 8,
888 1, /* little-endian */
889 0 /* signed */);
890#endif
891}
892
893static PyObject *
894lu_float(const char *p, const formatdef *f)
895{
896 return unpack_float(p, 1);
897}
898
899static PyObject *
900lu_double(const char *p, const formatdef *f)
901{
902 return unpack_double(p, 1);
903}
904
905static int
906lp_int(char *p, PyObject *v, const formatdef *f)
907{
908 long x;
909 Py_ssize_t i;
910 if (get_long(v, &x) < 0)
911 return -1;
912 i = f->size;
913 if (i != SIZEOF_LONG) {
914 if ((i == 2) && (x < -32768 || x > 32767))
915 return _range_error(f->format, i, 0);
916#if (SIZEOF_LONG != 4)
917 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
918 return _range_error(f->format, i, 0);
919#endif
920 }
921 do {
922 *p++ = (char)x;
923 x >>= 8;
924 } while (--i > 0);
925 return 0;
926}
927
928static int
929lp_uint(char *p, PyObject *v, const formatdef *f)
930{
931 unsigned long x;
932 Py_ssize_t i;
933 if (get_ulong(v, &x) < 0)
934 return -1;
935 i = f->size;
936 if (i != SIZEOF_LONG) {
937 unsigned long maxint = 1;
938 maxint <<= (unsigned long)(i * 8);
939 if (x >= maxint)
940 return _range_error(f->format, f->size, 1);
941 }
942 do {
943 *p++ = (char)x;
944 x >>= 8;
945 } while (--i > 0);
946 return 0;
947}
948
949static int
950lp_longlong(char *p, PyObject *v, const formatdef *f)
951{
952 int res;
953 v = get_pylong(v);
954 if (v == NULL)
955 return -1;
956 res = _PyLong_AsByteArray((PyLongObject*)v,
957 (unsigned char *)p,
958 8,
959 1, /* little_endian */
960 1 /* signed */);
961 Py_DECREF(v);
962 return res;
963}
964
965static int
966lp_ulonglong(char *p, PyObject *v, const formatdef *f)
967{
968 int res;
969 v = get_pylong(v);
970 if (v == NULL)
971 return -1;
972 res = _PyLong_AsByteArray((PyLongObject*)v,
973 (unsigned char *)p,
974 8,
975 1, /* little_endian */
976 0 /* signed */);
977 Py_DECREF(v);
978 return res;
979}
980
981static int
982lp_float(char *p, PyObject *v, const formatdef *f)
983{
984 double x = PyFloat_AsDouble(v);
985 if (x == -1 && PyErr_Occurred()) {
986 PyErr_SetString(StructError,
987 "required argument is not a float");
988 return -1;
989 }
990 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
991}
992
993static int
994lp_double(char *p, PyObject *v, const formatdef *f)
995{
996 double x = PyFloat_AsDouble(v);
997 if (x == -1 && PyErr_Occurred()) {
998 PyErr_SetString(StructError,
999 "required argument is not a float");
1000 return -1;
1001 }
1002 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1003}
1004
1005static formatdef lilendian_table[] = {
1006 {'x', 1, 0, NULL},
1007 {'b', 1, 0, nu_byte, np_byte},
1008 {'B', 1, 0, nu_ubyte, np_ubyte},
1009 {'c', 1, 0, nu_char, np_char},
1010 {'s', 1, 0, NULL},
1011 {'p', 1, 0, NULL},
1012 {'h', 2, 0, lu_int, lp_int},
1013 {'H', 2, 0, lu_uint, lp_uint},
1014 {'i', 4, 0, lu_int, lp_int},
1015 {'I', 4, 0, lu_uint, lp_uint},
1016 {'l', 4, 0, lu_int, lp_int},
1017 {'L', 4, 0, lu_uint, lp_uint},
1018 {'q', 8, 0, lu_longlong, lp_longlong},
1019 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1020 {'f', 4, 0, lu_float, lp_float},
1021 {'d', 8, 0, lu_double, lp_double},
1022 {0}
1023};
1024
1025
1026static const formatdef *
1027whichtable(char **pfmt)
1028{
1029 const char *fmt = (*pfmt)++; /* May be backed out of later */
1030 switch (*fmt) {
1031 case '<':
1032 return lilendian_table;
1033 case '>':
1034 case '!': /* Network byte order is big-endian */
1035 return bigendian_table;
1036 case '=': { /* Host byte order -- different from native in aligment! */
1037 int n = 1;
1038 char *p = (char *) &n;
1039 if (*p == 1)
1040 return lilendian_table;
1041 else
1042 return bigendian_table;
1043 }
1044 default:
1045 --*pfmt; /* Back out of pointer increment */
1046 /* Fall through */
1047 case '@':
1048 return native_table;
1049 }
1050}
1051
1052
1053/* Get the table entry for a format code */
1054
1055static const formatdef *
1056getentry(int c, const formatdef *f)
1057{
1058 for (; f->format != '\0'; f++) {
1059 if (f->format == c) {
1060 return f;
1061 }
1062 }
1063 PyErr_SetString(StructError, "bad char in struct format");
1064 return NULL;
1065}
1066
1067
1068/* Align a size according to a format code */
1069
1070static int
1071align(Py_ssize_t size, char c, const formatdef *e)
1072{
1073 if (e->format == c) {
1074 if (e->alignment) {
1075 size = ((size + e->alignment - 1)
1076 / e->alignment)
1077 * e->alignment;
1078 }
1079 }
1080 return size;
1081}
1082
1083
1084/* calculate the size of a format string */
1085
1086static int
1087prepare_s(PyStructObject *self)
1088{
1089 const formatdef *f;
1090 const formatdef *e;
1091 formatcode *codes;
1092
1093 const char *s;
1094 const char *fmt;
1095 char c;
1096 Py_ssize_t size, len, num, itemsize, x;
1097
1098 fmt = PyString_AS_STRING(self->s_format);
1099
1100 f = whichtable((char **)&fmt);
1101
1102 s = fmt;
1103 size = 0;
1104 len = 0;
1105 while ((c = *s++) != '\0') {
1106 if (isspace(Py_CHARMASK(c)))
1107 continue;
1108 if ('0' <= c && c <= '9') {
1109 num = c - '0';
1110 while ('0' <= (c = *s++) && c <= '9') {
1111 x = num*10 + (c - '0');
1112 if (x/10 != num) {
1113 PyErr_SetString(
1114 StructError,
1115 "overflow in item count");
1116 return -1;
1117 }
1118 num = x;
1119 }
1120 if (c == '\0')
1121 break;
1122 }
1123 else
1124 num = 1;
1125
1126 e = getentry(c, f);
1127 if (e == NULL)
1128 return -1;
1129
1130 switch (c) {
1131 case 's': /* fall through */
1132 case 'p': len++; break;
1133 case 'x': break;
1134 default: len += num; break;
1135 }
1136
1137 itemsize = e->size;
1138 size = align(size, c, e);
1139 x = num * itemsize;
1140 size += x;
1141 if (x/itemsize != num || size < 0) {
1142 PyErr_SetString(StructError,
1143 "total struct size too long");
1144 return -1;
1145 }
1146 }
1147
1148 self->s_size = size;
1149 self->s_len = len;
1150 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
1151 if (codes == NULL) {
1152 PyErr_NoMemory();
1153 return -1;
1154 }
1155 self->s_codes = codes;
1156
1157 s = fmt;
1158 size = 0;
1159 while ((c = *s++) != '\0') {
1160 if (isspace(Py_CHARMASK(c)))
1161 continue;
1162 if ('0' <= c && c <= '9') {
1163 num = c - '0';
1164 while ('0' <= (c = *s++) && c <= '9')
1165 num = num*10 + (c - '0');
1166 if (c == '\0')
1167 break;
1168 }
1169 else
1170 num = 1;
1171
1172 e = getentry(c, f);
1173
1174 size = align(size, c, e);
1175 if (c == 's' || c == 'p') {
1176 codes->offset = size;
1177 codes->size = num;
1178 codes->fmtdef = e;
1179 codes++;
1180 size += num;
1181 } else if (c == 'x') {
1182 size += num;
1183 } else {
1184 while (--num >= 0) {
1185 codes->offset = size;
1186 codes->size = e->size;
1187 codes->fmtdef = e;
1188 codes++;
1189 size += e->size;
1190 }
1191 }
1192 }
1193 codes->fmtdef = NULL;
1194 codes->offset = size;
1195 codes->size = 0;
1196
1197 return 0;
1198}
1199
1200static PyObject *
1201s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1202{
1203 PyObject *self;
1204
1205 assert(type != NULL && type->tp_alloc != NULL);
1206
1207 self = type->tp_alloc(type, 0);
1208 if (self != NULL) {
1209 PyStructObject *s = (PyStructObject*)self;
1210 Py_INCREF(Py_None);
1211 s->s_format = Py_None;
1212 s->s_codes = NULL;
1213 s->s_size = -1;
1214 s->s_len = -1;
1215 }
1216 return self;
1217}
1218
1219static int
1220s_init(PyObject *self, PyObject *args, PyObject *kwds)
1221{
1222 PyStructObject *soself = (PyStructObject *)self;
1223 PyObject *o_format = NULL;
1224 int ret = 0;
1225 static char *kwlist[] = {"format", 0};
1226
1227 assert(PyStruct_Check(self));
1228
1229 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1230 &o_format))
1231 return -1;
1232
1233 Py_INCREF(o_format);
1234 Py_XDECREF(soself->s_format);
1235 soself->s_format = o_format;
1236
1237 ret = prepare_s(soself);
1238 return ret;
1239}
1240
1241static void
1242s_dealloc(PyStructObject *s)
1243{
1244 if (s->weakreflist != NULL)
1245 PyObject_ClearWeakRefs((PyObject *)s);
1246 if (s->s_codes != NULL) {
1247 PyMem_FREE(s->s_codes);
1248 }
1249 Py_XDECREF(s->s_format);
1250 s->ob_type->tp_free((PyObject *)s);
1251}
1252
1253static PyObject *
1254s_unpack_internal(PyStructObject *soself, char *startfrom) {
1255 formatcode *code;
1256 Py_ssize_t i = 0;
1257 PyObject *result = PyTuple_New(soself->s_len);
1258 if (result == NULL)
1259 return NULL;
1260
1261 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1262 PyObject *v;
1263 const formatdef *e = code->fmtdef;
1264 const char *res = startfrom + code->offset;
1265 if (e->format == 's') {
1266 v = PyString_FromStringAndSize(res, code->size);
1267 if (v == NULL)
1268 goto fail;
1269 PyTuple_SET_ITEM(result, i++, v);
1270 } else if (e->format == 'p') {
1271 Py_ssize_t n = *(unsigned char*)res;
1272 if (n >= code->size)
1273 n = code->size - 1;
1274 v = PyString_FromStringAndSize(res + 1, n);
1275 if (v == NULL)
1276 goto fail;
1277 PyTuple_SET_ITEM(result, i++, v);
1278 } else {
1279 v = e->unpack(res, e);
1280 if (v == NULL)
1281 goto fail;
1282 PyTuple_SET_ITEM(result, i++, v);
1283 }
1284 }
1285
1286 return result;
1287fail:
1288 Py_DECREF(result);
1289 return NULL;
1290}
1291
1292
1293PyDoc_STRVAR(s_unpack__doc__,
1294"S.unpack(str) -> (v1, v2, ...)\n\
1295\n\
1296Return tuple containing values unpacked according to this Struct's format.\n\
1297Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1298strings.");
1299
1300static PyObject *
1301s_unpack(PyObject *self, PyObject *inputstr)
1302{
1303 PyStructObject *soself = (PyStructObject *)self;
1304 assert(PyStruct_Check(self));
1305 assert(soself->s_codes != NULL);
1306 if (inputstr == NULL || !PyString_Check(inputstr) ||
1307 PyString_GET_SIZE(inputstr) != soself->s_size) {
1308 PyErr_Format(StructError,
1309 "unpack requires a string argument of length %zd", soself->s_size);
1310 return NULL;
1311 }
1312 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1313}
1314
1315PyDoc_STRVAR(s_unpack_from__doc__,
1316"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
1317\n\
1318Return tuple containing values unpacked according to this Struct's format.\n\
1319Unlike unpack, unpack_from can unpack values from any object supporting\n\
1320the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1321See struct.__doc__ for more on format strings.");
1322
1323static PyObject *
1324s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1325{
1326 static char *kwlist[] = {"buffer", "offset", 0};
1327#if (PY_VERSION_HEX < 0x02050000)
1328 static char *fmt = "z#|i:unpack_from";
1329#else
1330 static char *fmt = "z#|n:unpack_from";
1331#endif
1332 Py_ssize_t buffer_len = 0, offset = 0;
1333 char *buffer = NULL;
1334 PyStructObject *soself = (PyStructObject *)self;
1335 assert(PyStruct_Check(self));
1336 assert(soself->s_codes != NULL);
1337
1338 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1339 &buffer, &buffer_len, &offset))
1340 return NULL;
1341
1342 if (buffer == NULL) {
1343 PyErr_Format(StructError,
1344 "unpack_from requires a buffer argument");
1345 return NULL;
1346 }
1347
1348 if (offset < 0)
1349 offset += buffer_len;
1350
1351 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1352 PyErr_Format(StructError,
1353 "unpack_from requires a buffer of at least %zd bytes",
1354 soself->s_size);
1355 return NULL;
1356 }
1357 return s_unpack_internal(soself, buffer + offset);
1358}
1359
1360
1361/*
1362 * Guts of the pack function.
1363 *
1364 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1365 * argument for where to start processing the arguments for packing, and a
1366 * character buffer for writing the packed string. The caller must insure
1367 * that the buffer may contain the required length for packing the arguments.
1368 * 0 is returned on success, 1 is returned if there is an error.
1369 *
1370 */
1371static int
1372s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
1373{
1374 formatcode *code;
1375 Py_ssize_t i;
1376
1377 memset(buf, '\0', soself->s_size);
1378 i = offset;
1379 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1380 Py_ssize_t n;
1381 PyObject *v;
1382 const formatdef *e = code->fmtdef;
1383 char *res = buf + code->offset;
1384 if (e->format == 's') {
1385 v = PyTuple_GET_ITEM(args, i++);
1386 if (!PyString_Check(v)) {
1387 PyErr_SetString(StructError,
1388 "argument for 's' must be a string");
1389 return -1;
1390 }
1391 n = PyString_GET_SIZE(v);
1392 if (n > code->size)
1393 n = code->size;
1394 if (n > 0)
1395 memcpy(res, PyString_AS_STRING(v), n);
1396 } else if (e->format == 'p') {
1397 v = PyTuple_GET_ITEM(args, i++);
1398 if (!PyString_Check(v)) {
1399 PyErr_SetString(StructError,
1400 "argument for 'p' must be a string");
1401 return -1;
1402 }
1403 n = PyString_GET_SIZE(v);
1404 if (n > (code->size - 1))
1405 n = code->size - 1;
1406 if (n > 0)
1407 memcpy(res + 1, PyString_AS_STRING(v), n);
1408 if (n > 255)
1409 n = 255;
1410 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1411 } else {
1412 v = PyTuple_GET_ITEM(args, i++);
1413 if (e->pack(res, v, e) < 0)
1414 return -1;
1415 }
1416 }
1417
1418 /* Success */
1419 return 0;
1420}
1421
1422
1423PyDoc_STRVAR(s_pack__doc__,
1424"S.pack(v1, v2, ...) -> string\n\
1425\n\
1426Return a string containing values v1, v2, ... packed according to this\n\
1427Struct's format. See struct.__doc__ for more on format strings.");
1428
1429static PyObject *
1430s_pack(PyObject *self, PyObject *args)
1431{
1432 PyStructObject *soself;
1433 PyObject *result;
1434
1435 /* Validate arguments. */
1436 soself = (PyStructObject *)self;
1437 assert(PyStruct_Check(self));
1438 assert(soself->s_codes != NULL);
1439 if (args == NULL || !PyTuple_Check(args) ||
1440 PyTuple_GET_SIZE(args) != soself->s_len)
1441 {
1442 PyErr_Format(StructError,
1443 "pack requires exactly %zd arguments", soself->s_len);
1444 return NULL;
1445 }
1446
1447 /* Allocate a new string */
1448 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1449 if (result == NULL)
1450 return NULL;
1451
1452 /* Call the guts */
1453 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1454 Py_DECREF(result);
1455 return NULL;
1456 }
1457
1458 return result;
1459}
1460
1461PyDoc_STRVAR(s_pack_to__doc__,
1462"S.pack_to(buffer, offset, v1, v2, ...)\n\
1463\n\
1464Pack the values v2, v2, ... according to this Struct's format, write \n\
1465the packed bytes into the writable buffer buf starting at offset. Note\n\
1466that the offset is not an optional argument. See struct.__doc__ for \n\
1467more on format strings.");
1468
1469static PyObject *
1470s_pack_to(PyObject *self, PyObject *args)
1471{
1472 PyStructObject *soself;
1473 char *buffer;
1474 Py_ssize_t buffer_len, offset;
1475
1476 /* Validate arguments. +1 is for the first arg as buffer. */
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 + 2))
1482 {
1483 PyErr_Format(StructError,
1484 "pack_to requires exactly %zd arguments",
1485 (soself->s_len + 2));
1486 return NULL;
1487 }
1488
1489 /* Extract a writable memory buffer from the first argument */
1490 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1491 (void**)&buffer, &buffer_len) == -1 ) {
1492 return NULL;
1493 }
1494 assert( buffer_len >= 0 );
1495
1496 /* Extract the offset from the first argument */
1497 offset = PyInt_AsLong(PyTuple_GET_ITEM(args, 1));
1498
1499 /* Support negative offsets. */
1500 if (offset < 0)
1501 offset += buffer_len;
1502
1503 /* Check boundaries */
1504 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1505 PyErr_Format(StructError,
1506 "pack_to requires a buffer of at least %zd bytes",
1507 soself->s_size);
1508 return NULL;
1509 }
1510
1511 /* Call the guts */
1512 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1513 return NULL;
1514 }
1515
1516 return Py_None;
1517}
1518
1519static PyObject *
1520s_get_format(PyStructObject *self, void *unused)
1521{
1522 Py_INCREF(self->s_format);
1523 return self->s_format;
1524}
1525
1526static PyObject *
1527s_get_size(PyStructObject *self, void *unused)
1528{
1529 return PyInt_FromSsize_t(self->s_size);
1530}
1531
1532/* List of functions */
1533
1534static struct PyMethodDef s_methods[] = {
1535 {"pack", (PyCFunction)s_pack, METH_VARARGS, s_pack__doc__},
1536 {"pack_to", (PyCFunction)s_pack_to, METH_VARARGS, s_pack_to__doc__},
1537 {"unpack", (PyCFunction)s_unpack, METH_O, s_unpack__doc__},
1538 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
1539 {NULL, NULL} /* sentinel */
1540};
1541
1542PyDoc_STRVAR(s__doc__, "Compiled struct object");
1543
1544#define OFF(x) offsetof(PyStructObject, x)
1545
1546static PyGetSetDef s_getsetlist[] = {
1547 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1548 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1549 {NULL} /* sentinel */
1550};
1551
1552static
1553PyTypeObject PyStructType = {
1554 PyObject_HEAD_INIT(NULL)
1555 0,
1556 "Struct",
1557 sizeof(PyStructObject),
1558 0,
1559 (destructor)s_dealloc, /* tp_dealloc */
1560 0, /* tp_print */
1561 0, /* tp_getattr */
1562 0, /* tp_setattr */
1563 0, /* tp_compare */
1564 0, /* tp_repr */
1565 0, /* tp_as_number */
1566 0, /* tp_as_sequence */
1567 0, /* tp_as_mapping */
1568 0, /* tp_hash */
1569 0, /* tp_call */
1570 0, /* tp_str */
1571 PyObject_GenericGetAttr, /* tp_getattro */
1572 PyObject_GenericSetAttr, /* tp_setattro */
1573 0, /* tp_as_buffer */
1574 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1575 s__doc__, /* tp_doc */
1576 0, /* tp_traverse */
1577 0, /* tp_clear */
1578 0, /* tp_richcompare */
1579 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1580 0, /* tp_iter */
1581 0, /* tp_iternext */
1582 s_methods, /* tp_methods */
1583 NULL, /* tp_members */
1584 s_getsetlist, /* tp_getset */
1585 0, /* tp_base */
1586 0, /* tp_dict */
1587 0, /* tp_descr_get */
1588 0, /* tp_descr_set */
1589 0, /* tp_dictoffset */
1590 s_init, /* tp_init */
1591 PyType_GenericAlloc,/* tp_alloc */
1592 s_new, /* tp_new */
1593 PyObject_Del, /* tp_free */
1594};
1595
1596/* Module initialization */
1597
1598PyMODINIT_FUNC
1599init_struct(void)
1600{
1601 PyObject *m = Py_InitModule("_struct", NULL);
1602 if (m == NULL)
1603 return;
1604
1605 PyStructType.ob_type = &PyType_Type;
1606 if (PyType_Ready(&PyStructType) < 0)
1607 return;
1608
1609 /* Check endian and swap in faster functions */
1610 {
1611 int one = 1;
1612 formatdef *native = native_table;
1613 formatdef *other, *ptr;
1614 if ((int)*(unsigned char*)&one)
1615 other = lilendian_table;
1616 else
1617 other = bigendian_table;
1618 /* Scan through the native table, find a matching
1619 entry in the endian table and swap in the
1620 native implementations whenever possible
1621 (64-bit platforms may not have "standard" sizes) */
1622 while (native->format != '\0' && other->format != '\0') {
1623 ptr = other;
1624 while (ptr->format != '\0') {
1625 if (ptr->format == native->format) {
1626 /* Match faster when formats are
1627 listed in the same order */
1628 if (ptr == other)
1629 other++;
1630 /* Only use the trick if the
1631 size matches */
1632 if (ptr->size != native->size)
1633 break;
1634 /* Skip float and double, could be
1635 "unknown" float format */
1636 if (ptr->format == 'd' || ptr->format == 'f')
1637 break;
1638 ptr->pack = native->pack;
1639 ptr->unpack = native->unpack;
1640 break;
1641 }
1642 ptr++;
1643 }
1644 native++;
1645 }
1646 }
1647
1648 /* Add some symbolic constants to the module */
1649 if (StructError == NULL) {
1650 StructError = PyErr_NewException("struct.error", NULL, NULL);
1651 if (StructError == NULL)
1652 return;
1653 }
1654
1655 Py_INCREF(StructError);
1656 PyModule_AddObject(m, "error", StructError);
1657
1658 Py_INCREF((PyObject*)&PyStructType);
1659 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
1660}