blob: f360dad21e41a693f42622eaffd66640765301fa [file] [log] [blame]
Bob Ippolito232f3c92006-05-23 19:12:41 +00001/* struct module -- pack values into and (out of) strings */
2
3/* New version supporting byte order, alignment and size options,
4 character strings, and unsigned numbers */
5
Bob Ippolitoaa70a172006-05-26 20:25:23 +00006#define PY_SSIZE_T_CLEAN
7
Bob Ippolito232f3c92006-05-23 19:12:41 +00008#include "Python.h"
9#include "structseq.h"
10#include "structmember.h"
11#include <ctype.h>
12
Bob Ippolitod3611eb2006-05-23 19:31:23 +000013static PyTypeObject PyStructType;
Bob Ippolito232f3c92006-05-23 19:12:41 +000014
15/* compatibility macros */
16#if (PY_VERSION_HEX < 0x02050000)
17typedef int Py_ssize_t;
18#endif
19
Bob Ippolito232f3c92006-05-23 19:12:41 +000020/* The translation function for each format character is table driven */
Bob Ippolito232f3c92006-05-23 19:12:41 +000021typedef struct _formatdef {
22 char format;
Bob Ippolitoaa70a172006-05-26 20:25:23 +000023 Py_ssize_t size;
24 Py_ssize_t alignment;
Bob Ippolito232f3c92006-05-23 19:12:41 +000025 PyObject* (*unpack)(const char *,
26 const struct _formatdef *);
27 int (*pack)(char *, PyObject *,
28 const struct _formatdef *);
29} formatdef;
30
31typedef struct _formatcode {
32 const struct _formatdef *fmtdef;
Bob Ippolitoaa70a172006-05-26 20:25:23 +000033 Py_ssize_t offset;
34 Py_ssize_t size;
Bob Ippolito232f3c92006-05-23 19:12:41 +000035} formatcode;
36
37/* Struct object interface */
38
39typedef struct {
40 PyObject_HEAD
Bob Ippolitoaa70a172006-05-26 20:25:23 +000041 Py_ssize_t s_size;
42 Py_ssize_t s_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +000043 formatcode *s_codes;
44 PyObject *s_format;
45 PyObject *weakreflist; /* List of weak references */
46} PyStructObject;
47
Bob Ippolitoeb621272006-05-24 15:32:06 +000048
Bob Ippolito07c023b2006-05-23 19:32:25 +000049#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
50#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
Bob Ippolito232f3c92006-05-23 19:12:41 +000051
52
53/* Exception */
54
55static PyObject *StructError;
56
57
58/* Define various structs to figure out the alignments of types */
59
60
61typedef struct { char c; short x; } st_short;
62typedef struct { char c; int x; } st_int;
63typedef struct { char c; long x; } st_long;
64typedef struct { char c; float x; } st_float;
65typedef struct { char c; double x; } st_double;
66typedef struct { char c; void *x; } st_void_p;
67
68#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
69#define INT_ALIGN (sizeof(st_int) - sizeof(int))
70#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
71#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
72#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
73#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
74
75/* We can't support q and Q in native mode unless the compiler does;
76 in std mode, they're 8 bytes on all platforms. */
77#ifdef HAVE_LONG_LONG
78typedef struct { char c; PY_LONG_LONG x; } s_long_long;
79#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
80#endif
81
82#define STRINGIFY(x) #x
83
84#ifdef __powerc
85#pragma options align=reset
86#endif
87
88/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
89
90static PyObject *
91get_pylong(PyObject *v)
92{
93 PyNumberMethods *m;
94
95 assert(v != NULL);
96 if (PyInt_Check(v))
97 return PyLong_FromLong(PyInt_AS_LONG(v));
98 if (PyLong_Check(v)) {
99 Py_INCREF(v);
100 return v;
101 }
102 m = v->ob_type->tp_as_number;
103 if (m != NULL && m->nb_long != NULL) {
104 v = m->nb_long(v);
105 if (v == NULL)
106 return NULL;
107 if (PyLong_Check(v))
108 return v;
109 Py_DECREF(v);
110 }
111 PyErr_SetString(StructError,
112 "cannot convert argument to long");
113 return NULL;
114}
115
116/* Helper routine to get a Python integer and raise the appropriate error
117 if it isn't one */
118
119static int
120get_long(PyObject *v, long *p)
121{
122 long x = PyInt_AsLong(v);
123 if (x == -1 && PyErr_Occurred()) {
124 if (PyErr_ExceptionMatches(PyExc_TypeError))
125 PyErr_SetString(StructError,
126 "required argument is not an integer");
127 return -1;
128 }
129 *p = x;
130 return 0;
131}
132
133
134/* Same, but handling unsigned long */
135
136static int
137get_ulong(PyObject *v, unsigned long *p)
138{
139 if (PyLong_Check(v)) {
140 unsigned long x = PyLong_AsUnsignedLong(v);
141 if (x == (unsigned long)(-1) && PyErr_Occurred())
142 return -1;
143 *p = x;
144 return 0;
145 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000146 if (get_long(v, (long *)p) < 0)
147 return -1;
148 if (((long)*p) < 0) {
149 PyErr_SetString(StructError,
150 "unsigned argument is < 0");
151 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000152 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000153 return 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000154}
155
156#ifdef HAVE_LONG_LONG
157
158/* Same, but handling native long long. */
159
160static int
161get_longlong(PyObject *v, PY_LONG_LONG *p)
162{
163 PY_LONG_LONG x;
164
165 v = get_pylong(v);
166 if (v == NULL)
167 return -1;
168 assert(PyLong_Check(v));
169 x = PyLong_AsLongLong(v);
170 Py_DECREF(v);
171 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
172 return -1;
173 *p = x;
174 return 0;
175}
176
177/* Same, but handling native unsigned long long. */
178
179static int
180get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
181{
182 unsigned PY_LONG_LONG x;
183
184 v = get_pylong(v);
185 if (v == NULL)
186 return -1;
187 assert(PyLong_Check(v));
188 x = PyLong_AsUnsignedLongLong(v);
189 Py_DECREF(v);
190 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
191 return -1;
192 *p = x;
193 return 0;
194}
195
196#endif
197
198/* Floating point helpers */
199
200static PyObject *
201unpack_float(const char *p, /* start of 4-byte string */
202 int le) /* true for little-endian, false for big-endian */
203{
204 double x;
205
206 x = _PyFloat_Unpack4((unsigned char *)p, le);
207 if (x == -1.0 && PyErr_Occurred())
208 return NULL;
209 return PyFloat_FromDouble(x);
210}
211
212static PyObject *
213unpack_double(const char *p, /* start of 8-byte string */
214 int le) /* true for little-endian, false for big-endian */
215{
216 double x;
217
218 x = _PyFloat_Unpack8((unsigned char *)p, le);
219 if (x == -1.0 && PyErr_Occurred())
220 return NULL;
221 return PyFloat_FromDouble(x);
222}
223
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000224/* Helper to format the range error exceptions */
225static int
Bob Ippolito28b26862006-05-29 15:47:29 +0000226_range_error(formatdef *f, int is_unsigned)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000227{
228 if (is_unsigned == 0) {
229 long smallest = 0, largest = 0;
Bob Ippolito28b26862006-05-29 15:47:29 +0000230 Py_ssize_t i = f->size * 8;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000231 while (--i > 0) {
232 smallest = (smallest * 2) - 1;
233 largest = (largest * 2) + 1;
234 }
235 PyErr_Format(StructError,
236 "'%c' format requires %ld <= number <= %ld",
Bob Ippolito28b26862006-05-29 15:47:29 +0000237 f->format,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000238 smallest,
239 largest);
240 } else {
241 unsigned long largest = 0;
Bob Ippolito28b26862006-05-29 15:47:29 +0000242 Py_ssize_t i = f->size * 8;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000243 while (--i >= 0)
244 largest = (largest * 2) + 1;
245 PyErr_Format(StructError,
246 "'%c' format requires 0 <= number <= %lu",
Bob Ippolito28b26862006-05-29 15:47:29 +0000247 f->format,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000248 largest);
249 }
250 return -1;
251}
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000252
253
Bob Ippolito232f3c92006-05-23 19:12:41 +0000254
255/* A large number of small routines follow, with names of the form
256
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000257 [bln][up]_TYPE
Bob Ippolito232f3c92006-05-23 19:12:41 +0000258
259 [bln] distiguishes among big-endian, little-endian and native.
260 [pu] distiguishes between pack (to struct) and unpack (from struct).
261 TYPE is one of char, byte, ubyte, etc.
262*/
263
264/* Native mode routines. ****************************************************/
265/* NOTE:
266 In all n[up]_<type> routines handling types larger than 1 byte, there is
267 *no* guarantee that the p pointer is properly aligned for each type,
268 therefore memcpy is called. An intermediate variable is used to
269 compensate for big-endian architectures.
270 Normally both the intermediate variable and the memcpy call will be
271 skipped by C optimisation in little-endian architectures (gcc >= 2.91
272 does this). */
273
274static PyObject *
275nu_char(const char *p, const formatdef *f)
276{
277 return PyString_FromStringAndSize(p, 1);
278}
279
280static PyObject *
281nu_byte(const char *p, const formatdef *f)
282{
283 return PyInt_FromLong((long) *(signed char *)p);
284}
285
286static PyObject *
287nu_ubyte(const char *p, const formatdef *f)
288{
289 return PyInt_FromLong((long) *(unsigned char *)p);
290}
291
292static PyObject *
293nu_short(const char *p, const formatdef *f)
294{
295 short x;
296 memcpy((char *)&x, p, sizeof x);
297 return PyInt_FromLong((long)x);
298}
299
300static PyObject *
301nu_ushort(const char *p, const formatdef *f)
302{
303 unsigned short x;
304 memcpy((char *)&x, p, sizeof x);
305 return PyInt_FromLong((long)x);
306}
307
308static PyObject *
309nu_int(const char *p, const formatdef *f)
310{
311 int x;
312 memcpy((char *)&x, p, sizeof x);
313 return PyInt_FromLong((long)x);
314}
315
316static PyObject *
317nu_uint(const char *p, const formatdef *f)
318{
319 unsigned int x;
320 memcpy((char *)&x, p, sizeof x);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000321#if (SIZEOF_LONG > SIZEOF_INT)
322 return PyInt_FromLong((long)x);
323#else
324 if (x <= ((unsigned int)LONG_MAX))
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000325 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000326 return PyLong_FromUnsignedLong((unsigned long)x);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000327#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000328}
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);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000343 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000344 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000345 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);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000358 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000359 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000360 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);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000368 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000369 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000370 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,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000407 "byte format requires -128 <= number <= 127");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000408 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,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000422 "ubyte format requires 0 <= number <= 255");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000423 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)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000451 " <= number <= " STRINGIFY(SHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000452 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,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000468 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000469 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;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000483#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000484 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Bob Ippolito28b26862006-05-29 15:47:29 +0000485 return _range_error(f, 0);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000486#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000487 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)
Bob Ippolito28b26862006-05-29 15:47:29 +0000498 return _range_error(f, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000499 y = (unsigned int)x;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000500#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000501 if (x > ((unsigned long)UINT_MAX))
Bob Ippolito28b26862006-05-29 15:47:29 +0000502 return _range_error(f, 1);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000503#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000504 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)
Bob Ippolito28b26862006-05-29 15:47:29 +0000523 return _range_error(f, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000524 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},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000607#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
Bob Ippolitoa99865b2006-05-25 19:56:56 +0000611 {'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},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000614 {0}
615};
616
617/* Big-endian routines. *****************************************************/
618
619static PyObject *
620bu_int(const char *p, const formatdef *f)
621{
622 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000623 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000624 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000625 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000626 x = (x<<8) | *bytes++;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000627 } while (--i > 0);
628 /* Extend the sign bit. */
629 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000630 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000631 return PyInt_FromLong(x);
632}
633
634static PyObject *
635bu_uint(const char *p, const formatdef *f)
636{
637 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000638 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000639 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000640 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000641 x = (x<<8) | *bytes++;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000642 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000643 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000644 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000645 return PyLong_FromUnsignedLong(x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000646}
647
648static PyObject *
649bu_longlong(const char *p, const formatdef *f)
650{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000651#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000652 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000653 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000654 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000655 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000656 x = (x<<8) | *bytes++;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000657 } while (--i > 0);
658 /* Extend the sign bit. */
659 if (SIZEOF_LONG_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000660 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000661 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000662 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000663 return PyLong_FromLongLong(x);
664#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000665 return _PyLong_FromByteArray((const unsigned char *)p,
666 8,
667 0, /* little-endian */
668 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000669#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000670}
671
672static PyObject *
673bu_ulonglong(const char *p, const formatdef *f)
674{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000675#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000676 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000677 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000678 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000679 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000680 x = (x<<8) | *bytes++;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000681 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000682 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000683 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000684 return PyLong_FromUnsignedLongLong(x);
685#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000686 return _PyLong_FromByteArray((const unsigned char *)p,
687 8,
688 0, /* little-endian */
689 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000690#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000691}
692
693static PyObject *
694bu_float(const char *p, const formatdef *f)
695{
696 return unpack_float(p, 0);
697}
698
699static PyObject *
700bu_double(const char *p, const formatdef *f)
701{
702 return unpack_double(p, 0);
703}
704
705static int
706bp_int(char *p, PyObject *v, const formatdef *f)
707{
708 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000709 Py_ssize_t i;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000710 if (get_long(v, &x) < 0)
711 return -1;
712 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000713 if (i != SIZEOF_LONG) {
714 if ((i == 2) && (x < -32768 || x > 32767))
Bob Ippolito28b26862006-05-29 15:47:29 +0000715 return _range_error(f, 0);
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000716#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000717 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Bob Ippolito28b26862006-05-29 15:47:29 +0000718 return _range_error(f, 0);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000719#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000720 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000721 do {
722 p[--i] = (char)x;
723 x >>= 8;
724 } while (i > 0);
725 return 0;
726}
727
728static int
729bp_uint(char *p, PyObject *v, const formatdef *f)
730{
731 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000732 Py_ssize_t i;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000733 if (get_ulong(v, &x) < 0)
734 return -1;
735 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000736 if (i != SIZEOF_LONG) {
737 unsigned long maxint = 1;
738 maxint <<= (unsigned long)(i * 8);
739 if (x >= maxint)
Bob Ippolito28b26862006-05-29 15:47:29 +0000740 return _range_error(f, 1);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000741 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000742 do {
743 p[--i] = (char)x;
744 x >>= 8;
745 } while (i > 0);
746 return 0;
747}
748
749static int
750bp_longlong(char *p, PyObject *v, const formatdef *f)
751{
752 int res;
753 v = get_pylong(v);
754 if (v == NULL)
755 return -1;
756 res = _PyLong_AsByteArray((PyLongObject *)v,
757 (unsigned char *)p,
758 8,
759 0, /* little_endian */
760 1 /* signed */);
761 Py_DECREF(v);
762 return res;
763}
764
765static int
766bp_ulonglong(char *p, PyObject *v, const formatdef *f)
767{
768 int res;
769 v = get_pylong(v);
770 if (v == NULL)
771 return -1;
772 res = _PyLong_AsByteArray((PyLongObject *)v,
773 (unsigned char *)p,
774 8,
775 0, /* little_endian */
776 0 /* signed */);
777 Py_DECREF(v);
778 return res;
779}
780
781static int
782bp_float(char *p, PyObject *v, const formatdef *f)
783{
784 double x = PyFloat_AsDouble(v);
785 if (x == -1 && PyErr_Occurred()) {
786 PyErr_SetString(StructError,
787 "required argument is not a float");
788 return -1;
789 }
790 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
791}
792
793static int
794bp_double(char *p, PyObject *v, const formatdef *f)
795{
796 double x = PyFloat_AsDouble(v);
797 if (x == -1 && PyErr_Occurred()) {
798 PyErr_SetString(StructError,
799 "required argument is not a float");
800 return -1;
801 }
802 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
803}
804
805static formatdef bigendian_table[] = {
806 {'x', 1, 0, NULL},
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000807 {'b', 1, 0, nu_byte, np_byte},
808 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000809 {'c', 1, 0, nu_char, np_char},
810 {'s', 1, 0, NULL},
811 {'p', 1, 0, NULL},
812 {'h', 2, 0, bu_int, bp_int},
813 {'H', 2, 0, bu_uint, bp_uint},
814 {'i', 4, 0, bu_int, bp_int},
815 {'I', 4, 0, bu_uint, bp_uint},
816 {'l', 4, 0, bu_int, bp_int},
817 {'L', 4, 0, bu_uint, bp_uint},
818 {'q', 8, 0, bu_longlong, bp_longlong},
819 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
820 {'f', 4, 0, bu_float, bp_float},
821 {'d', 8, 0, bu_double, bp_double},
822 {0}
823};
824
825/* Little-endian routines. *****************************************************/
826
827static PyObject *
828lu_int(const char *p, const formatdef *f)
829{
830 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000831 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000832 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000833 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000834 x = (x<<8) | bytes[--i];
Bob Ippolito232f3c92006-05-23 19:12:41 +0000835 } while (i > 0);
836 /* Extend the sign bit. */
837 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000838 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000839 return PyInt_FromLong(x);
840}
841
842static PyObject *
843lu_uint(const char *p, const formatdef *f)
844{
845 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000846 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000847 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000848 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000849 x = (x<<8) | bytes[--i];
Bob Ippolito232f3c92006-05-23 19:12:41 +0000850 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000851 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000852 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000853 return PyLong_FromUnsignedLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000854}
855
856static PyObject *
857lu_longlong(const char *p, const formatdef *f)
858{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000859#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000860 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000861 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000862 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000863 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000864 x = (x<<8) | bytes[--i];
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000865 } while (i > 0);
866 /* Extend the sign bit. */
867 if (SIZEOF_LONG_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000868 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000869 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000870 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000871 return PyLong_FromLongLong(x);
872#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000873 return _PyLong_FromByteArray((const unsigned char *)p,
874 8,
875 1, /* little-endian */
876 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000877#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000878}
879
880static PyObject *
881lu_ulonglong(const char *p, const formatdef *f)
882{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000883#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000884 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000885 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000886 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000887 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000888 x = (x<<8) | bytes[--i];
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000889 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000890 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000891 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000892 return PyLong_FromUnsignedLongLong(x);
893#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000894 return _PyLong_FromByteArray((const unsigned char *)p,
895 8,
896 1, /* little-endian */
897 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000898#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000899}
900
901static PyObject *
902lu_float(const char *p, const formatdef *f)
903{
904 return unpack_float(p, 1);
905}
906
907static PyObject *
908lu_double(const char *p, const formatdef *f)
909{
910 return unpack_double(p, 1);
911}
912
913static int
914lp_int(char *p, PyObject *v, const formatdef *f)
915{
916 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000917 Py_ssize_t i;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000918 if (get_long(v, &x) < 0)
919 return -1;
920 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000921 if (i != SIZEOF_LONG) {
922 if ((i == 2) && (x < -32768 || x > 32767))
Bob Ippolito28b26862006-05-29 15:47:29 +0000923 return _range_error(f, 0);
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000924#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000925 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Bob Ippolito28b26862006-05-29 15:47:29 +0000926 return _range_error(f, 0);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000927#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000928 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000929 do {
930 *p++ = (char)x;
931 x >>= 8;
932 } while (--i > 0);
933 return 0;
934}
935
936static int
937lp_uint(char *p, PyObject *v, const formatdef *f)
938{
939 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000940 Py_ssize_t i;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000941 if (get_ulong(v, &x) < 0)
942 return -1;
943 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000944 if (i != SIZEOF_LONG) {
945 unsigned long maxint = 1;
946 maxint <<= (unsigned long)(i * 8);
947 if (x >= maxint)
Bob Ippolito28b26862006-05-29 15:47:29 +0000948 return _range_error(f, 1);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000949 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000950 do {
951 *p++ = (char)x;
952 x >>= 8;
953 } while (--i > 0);
954 return 0;
955}
956
957static int
958lp_longlong(char *p, PyObject *v, const formatdef *f)
959{
960 int res;
961 v = get_pylong(v);
962 if (v == NULL)
963 return -1;
964 res = _PyLong_AsByteArray((PyLongObject*)v,
965 (unsigned char *)p,
966 8,
967 1, /* little_endian */
968 1 /* signed */);
969 Py_DECREF(v);
970 return res;
971}
972
973static int
974lp_ulonglong(char *p, PyObject *v, const formatdef *f)
975{
976 int res;
977 v = get_pylong(v);
978 if (v == NULL)
979 return -1;
980 res = _PyLong_AsByteArray((PyLongObject*)v,
981 (unsigned char *)p,
982 8,
983 1, /* little_endian */
984 0 /* signed */);
985 Py_DECREF(v);
986 return res;
987}
988
989static int
990lp_float(char *p, PyObject *v, const formatdef *f)
991{
992 double x = PyFloat_AsDouble(v);
993 if (x == -1 && PyErr_Occurred()) {
994 PyErr_SetString(StructError,
995 "required argument is not a float");
996 return -1;
997 }
998 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
999}
1000
1001static int
1002lp_double(char *p, PyObject *v, const formatdef *f)
1003{
1004 double x = PyFloat_AsDouble(v);
1005 if (x == -1 && PyErr_Occurred()) {
1006 PyErr_SetString(StructError,
1007 "required argument is not a float");
1008 return -1;
1009 }
1010 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1011}
1012
1013static formatdef lilendian_table[] = {
1014 {'x', 1, 0, NULL},
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001015 {'b', 1, 0, nu_byte, np_byte},
1016 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001017 {'c', 1, 0, nu_char, np_char},
1018 {'s', 1, 0, NULL},
1019 {'p', 1, 0, NULL},
1020 {'h', 2, 0, lu_int, lp_int},
1021 {'H', 2, 0, lu_uint, lp_uint},
1022 {'i', 4, 0, lu_int, lp_int},
1023 {'I', 4, 0, lu_uint, lp_uint},
1024 {'l', 4, 0, lu_int, lp_int},
1025 {'L', 4, 0, lu_uint, lp_uint},
1026 {'q', 8, 0, lu_longlong, lp_longlong},
1027 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1028 {'f', 4, 0, lu_float, lp_float},
1029 {'d', 8, 0, lu_double, lp_double},
1030 {0}
1031};
1032
1033
1034static const formatdef *
1035whichtable(char **pfmt)
1036{
1037 const char *fmt = (*pfmt)++; /* May be backed out of later */
1038 switch (*fmt) {
1039 case '<':
1040 return lilendian_table;
1041 case '>':
1042 case '!': /* Network byte order is big-endian */
1043 return bigendian_table;
1044 case '=': { /* Host byte order -- different from native in aligment! */
1045 int n = 1;
1046 char *p = (char *) &n;
1047 if (*p == 1)
1048 return lilendian_table;
1049 else
1050 return bigendian_table;
1051 }
1052 default:
1053 --*pfmt; /* Back out of pointer increment */
1054 /* Fall through */
1055 case '@':
1056 return native_table;
1057 }
1058}
1059
1060
1061/* Get the table entry for a format code */
1062
1063static const formatdef *
1064getentry(int c, const formatdef *f)
1065{
1066 for (; f->format != '\0'; f++) {
1067 if (f->format == c) {
1068 return f;
1069 }
1070 }
1071 PyErr_SetString(StructError, "bad char in struct format");
1072 return NULL;
1073}
1074
1075
1076/* Align a size according to a format code */
1077
1078static int
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001079align(Py_ssize_t size, char c, const formatdef *e)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001080{
1081 if (e->format == c) {
1082 if (e->alignment) {
1083 size = ((size + e->alignment - 1)
1084 / e->alignment)
1085 * e->alignment;
1086 }
1087 }
1088 return size;
1089}
1090
1091
1092/* calculate the size of a format string */
1093
1094static int
1095prepare_s(PyStructObject *self)
1096{
1097 const formatdef *f;
1098 const formatdef *e;
1099 formatcode *codes;
1100
1101 const char *s;
1102 const char *fmt;
1103 char c;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001104 Py_ssize_t size, len, num, itemsize, x;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001105
1106 fmt = PyString_AS_STRING(self->s_format);
1107
1108 f = whichtable((char **)&fmt);
1109
1110 s = fmt;
1111 size = 0;
1112 len = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001113 while ((c = *s++) != '\0') {
1114 if (isspace(Py_CHARMASK(c)))
1115 continue;
1116 if ('0' <= c && c <= '9') {
1117 num = c - '0';
1118 while ('0' <= (c = *s++) && c <= '9') {
1119 x = num*10 + (c - '0');
1120 if (x/10 != num) {
1121 PyErr_SetString(
1122 StructError,
1123 "overflow in item count");
1124 return -1;
1125 }
1126 num = x;
1127 }
1128 if (c == '\0')
1129 break;
1130 }
1131 else
1132 num = 1;
1133
1134 e = getentry(c, f);
1135 if (e == NULL)
1136 return -1;
1137
1138 switch (c) {
1139 case 's': /* fall through */
1140 case 'p': len++; break;
1141 case 'x': break;
1142 default: len += num; break;
1143 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001144
1145 itemsize = e->size;
1146 size = align(size, c, e);
1147 x = num * itemsize;
1148 size += x;
1149 if (x/itemsize != num || size < 0) {
1150 PyErr_SetString(StructError,
1151 "total struct size too long");
1152 return -1;
1153 }
1154 }
1155
1156 self->s_size = size;
1157 self->s_len = len;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001158 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
Bob Ippolito232f3c92006-05-23 19:12:41 +00001159 if (codes == NULL) {
1160 PyErr_NoMemory();
1161 return -1;
1162 }
1163 self->s_codes = codes;
1164
1165 s = fmt;
1166 size = 0;
1167 while ((c = *s++) != '\0') {
1168 if (isspace(Py_CHARMASK(c)))
1169 continue;
1170 if ('0' <= c && c <= '9') {
1171 num = c - '0';
1172 while ('0' <= (c = *s++) && c <= '9')
1173 num = num*10 + (c - '0');
1174 if (c == '\0')
1175 break;
1176 }
1177 else
1178 num = 1;
1179
1180 e = getentry(c, f);
1181
1182 size = align(size, c, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001183 if (c == 's' || c == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001184 codes->offset = size;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001185 codes->size = num;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001186 codes->fmtdef = e;
1187 codes++;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001188 size += num;
1189 } else if (c == 'x') {
1190 size += num;
1191 } else {
1192 while (--num >= 0) {
1193 codes->offset = size;
1194 codes->size = e->size;
1195 codes->fmtdef = e;
1196 codes++;
1197 size += e->size;
1198 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001199 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001200 }
1201 codes->fmtdef = NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001202 codes->offset = size;
1203 codes->size = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001204
1205 return 0;
1206}
1207
1208static PyObject *
1209s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1210{
1211 PyObject *self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001212
1213 assert(type != NULL && type->tp_alloc != NULL);
1214
1215 self = type->tp_alloc(type, 0);
1216 if (self != NULL) {
1217 PyStructObject *s = (PyStructObject*)self;
1218 Py_INCREF(Py_None);
1219 s->s_format = Py_None;
1220 s->s_codes = NULL;
1221 s->s_size = -1;
1222 s->s_len = -1;
1223 }
1224 return self;
1225}
1226
1227static int
1228s_init(PyObject *self, PyObject *args, PyObject *kwds)
1229{
1230 PyStructObject *soself = (PyStructObject *)self;
1231 PyObject *o_format = NULL;
1232 int ret = 0;
1233 static char *kwlist[] = {"format", 0};
1234
1235 assert(PyStruct_Check(self));
1236
1237 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1238 &o_format))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001239 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001240
1241 Py_INCREF(o_format);
1242 Py_XDECREF(soself->s_format);
1243 soself->s_format = o_format;
1244
1245 ret = prepare_s(soself);
1246 return ret;
1247}
1248
1249static void
1250s_dealloc(PyStructObject *s)
1251{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001252 if (s->weakreflist != NULL)
1253 PyObject_ClearWeakRefs((PyObject *)s);
1254 if (s->s_codes != NULL) {
1255 PyMem_FREE(s->s_codes);
1256 }
1257 Py_XDECREF(s->s_format);
1258 s->ob_type->tp_free((PyObject *)s);
1259}
1260
Bob Ippolitoeb621272006-05-24 15:32:06 +00001261static PyObject *
1262s_unpack_internal(PyStructObject *soself, char *startfrom) {
1263 formatcode *code;
1264 Py_ssize_t i = 0;
1265 PyObject *result = PyTuple_New(soself->s_len);
1266 if (result == NULL)
1267 return NULL;
1268
1269 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1270 PyObject *v;
1271 const formatdef *e = code->fmtdef;
1272 const char *res = startfrom + code->offset;
1273 if (e->format == 's') {
1274 v = PyString_FromStringAndSize(res, code->size);
1275 if (v == NULL)
1276 goto fail;
1277 PyTuple_SET_ITEM(result, i++, v);
1278 } else if (e->format == 'p') {
1279 Py_ssize_t n = *(unsigned char*)res;
1280 if (n >= code->size)
1281 n = code->size - 1;
1282 v = PyString_FromStringAndSize(res + 1, n);
1283 if (v == NULL)
1284 goto fail;
1285 PyTuple_SET_ITEM(result, i++, v);
1286 } else {
1287 v = e->unpack(res, e);
1288 if (v == NULL)
1289 goto fail;
1290 PyTuple_SET_ITEM(result, i++, v);
1291 }
1292 }
1293
1294 return result;
1295fail:
1296 Py_DECREF(result);
1297 return NULL;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001298}
Bob Ippolitoeb621272006-05-24 15:32:06 +00001299
1300
Bob Ippolito232f3c92006-05-23 19:12:41 +00001301PyDoc_STRVAR(s_unpack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001302"S.unpack(str) -> (v1, v2, ...)\n\
Bob Ippolito232f3c92006-05-23 19:12:41 +00001303\n\
1304Return tuple containing values unpacked according to this Struct's format.\n\
1305Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1306strings.");
1307
1308static PyObject *
1309s_unpack(PyObject *self, PyObject *inputstr)
1310{
Bob Ippolitoeb621272006-05-24 15:32:06 +00001311 PyStructObject *soself = (PyStructObject *)self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001312 assert(PyStruct_Check(self));
1313 assert(soself->s_codes != NULL);
1314 if (inputstr == NULL || !PyString_Check(inputstr) ||
Bob Ippolitoeb621272006-05-24 15:32:06 +00001315 PyString_GET_SIZE(inputstr) != soself->s_size) {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001316 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001317 "unpack requires a string argument of length %zd", soself->s_size);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001318 return NULL;
1319 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001320 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1321}
1322
1323PyDoc_STRVAR(s_unpack_from__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001324"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
Bob Ippolitoeb621272006-05-24 15:32:06 +00001325\n\
1326Return tuple containing values unpacked according to this Struct's format.\n\
1327Unlike unpack, unpack_from can unpack values from any object supporting\n\
1328the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1329See struct.__doc__ for more on format strings.");
1330
1331static PyObject *
1332s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1333{
1334 static char *kwlist[] = {"buffer", "offset", 0};
1335#if (PY_VERSION_HEX < 0x02050000)
1336 static char *fmt = "z#|i:unpack_from";
1337#else
1338 static char *fmt = "z#|n:unpack_from";
1339#endif
1340 Py_ssize_t buffer_len = 0, offset = 0;
1341 char *buffer = NULL;
1342 PyStructObject *soself = (PyStructObject *)self;
1343 assert(PyStruct_Check(self));
1344 assert(soself->s_codes != NULL);
1345
1346 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1347 &buffer, &buffer_len, &offset))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001348 return NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001349
1350 if (buffer == NULL) {
1351 PyErr_Format(StructError,
1352 "unpack_from requires a buffer argument");
Bob Ippolito232f3c92006-05-23 19:12:41 +00001353 return NULL;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001354 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001355
1356 if (offset < 0)
1357 offset += buffer_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001358
Bob Ippolitoeb621272006-05-24 15:32:06 +00001359 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1360 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001361 "unpack_from requires a buffer of at least %zd bytes",
Bob Ippolitoeb621272006-05-24 15:32:06 +00001362 soself->s_size);
1363 return NULL;
1364 }
1365 return s_unpack_internal(soself, buffer + offset);
1366}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001367
Bob Ippolito232f3c92006-05-23 19:12:41 +00001368
Martin Blais2856e5f2006-05-26 12:03:27 +00001369/*
1370 * Guts of the pack function.
1371 *
1372 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1373 * argument for where to start processing the arguments for packing, and a
1374 * character buffer for writing the packed string. The caller must insure
1375 * that the buffer may contain the required length for packing the arguments.
1376 * 0 is returned on success, 1 is returned if there is an error.
1377 *
1378 */
1379static int
1380s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001381{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001382 formatcode *code;
1383 Py_ssize_t i;
Martin Blais2856e5f2006-05-26 12:03:27 +00001384
1385 memset(buf, '\0', soself->s_size);
1386 i = offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001387 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1388 Py_ssize_t n;
1389 PyObject *v;
1390 const formatdef *e = code->fmtdef;
Martin Blais2856e5f2006-05-26 12:03:27 +00001391 char *res = buf + code->offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001392 if (e->format == 's') {
1393 v = PyTuple_GET_ITEM(args, i++);
1394 if (!PyString_Check(v)) {
1395 PyErr_SetString(StructError,
1396 "argument for 's' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001397 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001398 }
1399 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001400 if (n > code->size)
1401 n = code->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001402 if (n > 0)
1403 memcpy(res, PyString_AS_STRING(v), n);
1404 } else if (e->format == 'p') {
1405 v = PyTuple_GET_ITEM(args, i++);
1406 if (!PyString_Check(v)) {
1407 PyErr_SetString(StructError,
1408 "argument for 'p' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001409 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001410 }
1411 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001412 if (n > (code->size - 1))
1413 n = code->size - 1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001414 if (n > 0)
1415 memcpy(res + 1, PyString_AS_STRING(v), n);
1416 if (n > 255)
1417 n = 255;
1418 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1419 } else {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001420 v = PyTuple_GET_ITEM(args, i++);
1421 if (e->pack(res, v, e) < 0)
Martin Blais2856e5f2006-05-26 12:03:27 +00001422 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001423 }
1424 }
1425
Martin Blais2856e5f2006-05-26 12:03:27 +00001426 /* Success */
1427 return 0;
1428}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001429
Martin Blais2856e5f2006-05-26 12:03:27 +00001430
1431PyDoc_STRVAR(s_pack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001432"S.pack(v1, v2, ...) -> string\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001433\n\
1434Return a string containing values v1, v2, ... packed according to this\n\
1435Struct's format. See struct.__doc__ for more on format strings.");
1436
1437static PyObject *
1438s_pack(PyObject *self, PyObject *args)
1439{
1440 PyStructObject *soself;
1441 PyObject *result;
1442
1443 /* Validate arguments. */
1444 soself = (PyStructObject *)self;
1445 assert(PyStruct_Check(self));
1446 assert(soself->s_codes != NULL);
1447 if (args == NULL || !PyTuple_Check(args) ||
1448 PyTuple_GET_SIZE(args) != soself->s_len)
1449 {
1450 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001451 "pack requires exactly %zd arguments", soself->s_len);
Martin Blais2856e5f2006-05-26 12:03:27 +00001452 return NULL;
1453 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001454
Martin Blais2856e5f2006-05-26 12:03:27 +00001455 /* Allocate a new string */
1456 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1457 if (result == NULL)
1458 return NULL;
1459
1460 /* Call the guts */
1461 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1462 Py_DECREF(result);
1463 return NULL;
1464 }
1465
1466 return result;
1467}
1468
1469PyDoc_STRVAR(s_pack_to__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001470"S.pack_to(buffer, offset, v1, v2, ...)\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001471\n\
1472Pack the values v2, v2, ... according to this Struct's format, write \n\
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001473the packed bytes into the writable buffer buf starting at offset. Note\n\
1474that the offset is not an optional argument. See struct.__doc__ for \n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001475more on format strings.");
1476
1477static PyObject *
1478s_pack_to(PyObject *self, PyObject *args)
1479{
1480 PyStructObject *soself;
1481 char *buffer;
1482 Py_ssize_t buffer_len, offset;
1483
1484 /* Validate arguments. +1 is for the first arg as buffer. */
1485 soself = (PyStructObject *)self;
1486 assert(PyStruct_Check(self));
1487 assert(soself->s_codes != NULL);
1488 if (args == NULL || !PyTuple_Check(args) ||
1489 PyTuple_GET_SIZE(args) != (soself->s_len + 2))
1490 {
1491 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001492 "pack_to requires exactly %zd arguments",
Martin Blais2856e5f2006-05-26 12:03:27 +00001493 (soself->s_len + 2));
1494 return NULL;
1495 }
1496
1497 /* Extract a writable memory buffer from the first argument */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001498 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1499 (void**)&buffer, &buffer_len) == -1 ) {
Martin Blais2856e5f2006-05-26 12:03:27 +00001500 return NULL;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001501 }
1502 assert( buffer_len >= 0 );
Martin Blais2856e5f2006-05-26 12:03:27 +00001503
1504 /* Extract the offset from the first argument */
1505 offset = PyInt_AsLong(PyTuple_GET_ITEM(args, 1));
1506
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001507 /* Support negative offsets. */
Martin Blais2856e5f2006-05-26 12:03:27 +00001508 if (offset < 0)
1509 offset += buffer_len;
1510
1511 /* Check boundaries */
1512 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1513 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001514 "pack_to requires a buffer of at least %zd bytes",
Martin Blais2856e5f2006-05-26 12:03:27 +00001515 soself->s_size);
1516 return NULL;
1517 }
1518
1519 /* Call the guts */
1520 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1521 return NULL;
1522 }
1523
Georg Brandlc26025c2006-05-28 21:42:54 +00001524 Py_RETURN_NONE;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001525}
1526
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001527static PyObject *
1528s_get_format(PyStructObject *self, void *unused)
1529{
1530 Py_INCREF(self->s_format);
1531 return self->s_format;
1532}
1533
1534static PyObject *
1535s_get_size(PyStructObject *self, void *unused)
1536{
1537 return PyInt_FromSsize_t(self->s_size);
1538}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001539
1540/* List of functions */
1541
1542static struct PyMethodDef s_methods[] = {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001543 {"pack", (PyCFunction)s_pack, METH_VARARGS, s_pack__doc__},
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001544 {"pack_to", (PyCFunction)s_pack_to, METH_VARARGS, s_pack_to__doc__},
Bob Ippolitoeb621272006-05-24 15:32:06 +00001545 {"unpack", (PyCFunction)s_unpack, METH_O, s_unpack__doc__},
1546 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001547 {NULL, NULL} /* sentinel */
1548};
1549
1550PyDoc_STRVAR(s__doc__, "Compiled struct object");
1551
1552#define OFF(x) offsetof(PyStructObject, x)
1553
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001554static PyGetSetDef s_getsetlist[] = {
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001555 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1556 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001557 {NULL} /* sentinel */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001558};
1559
Bob Ippolito232f3c92006-05-23 19:12:41 +00001560static
1561PyTypeObject PyStructType = {
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001562 PyObject_HEAD_INIT(NULL)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001563 0,
1564 "Struct",
1565 sizeof(PyStructObject),
1566 0,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001567 (destructor)s_dealloc, /* tp_dealloc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001568 0, /* tp_print */
1569 0, /* tp_getattr */
1570 0, /* tp_setattr */
1571 0, /* tp_compare */
1572 0, /* tp_repr */
1573 0, /* tp_as_number */
1574 0, /* tp_as_sequence */
1575 0, /* tp_as_mapping */
1576 0, /* tp_hash */
1577 0, /* tp_call */
1578 0, /* tp_str */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001579 PyObject_GenericGetAttr, /* tp_getattro */
1580 PyObject_GenericSetAttr, /* tp_setattro */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001581 0, /* tp_as_buffer */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001582 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1583 s__doc__, /* tp_doc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001584 0, /* tp_traverse */
1585 0, /* tp_clear */
1586 0, /* tp_richcompare */
1587 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1588 0, /* tp_iter */
1589 0, /* tp_iternext */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001590 s_methods, /* tp_methods */
1591 NULL, /* tp_members */
1592 s_getsetlist, /* tp_getset */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001593 0, /* tp_base */
1594 0, /* tp_dict */
1595 0, /* tp_descr_get */
1596 0, /* tp_descr_set */
1597 0, /* tp_dictoffset */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001598 s_init, /* tp_init */
1599 PyType_GenericAlloc,/* tp_alloc */
1600 s_new, /* tp_new */
1601 PyObject_Del, /* tp_free */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001602};
1603
1604/* Module initialization */
1605
1606PyMODINIT_FUNC
1607init_struct(void)
1608{
1609 PyObject *m = Py_InitModule("_struct", NULL);
1610 if (m == NULL)
1611 return;
1612
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001613 PyStructType.ob_type = &PyType_Type;
1614 if (PyType_Ready(&PyStructType) < 0)
1615 return;
1616
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001617 /* Check endian and swap in faster functions */
1618 {
1619 int one = 1;
1620 formatdef *native = native_table;
1621 formatdef *other, *ptr;
1622 if ((int)*(unsigned char*)&one)
1623 other = lilendian_table;
1624 else
1625 other = bigendian_table;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001626 /* Scan through the native table, find a matching
1627 entry in the endian table and swap in the
1628 native implementations whenever possible
1629 (64-bit platforms may not have "standard" sizes) */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001630 while (native->format != '\0' && other->format != '\0') {
1631 ptr = other;
1632 while (ptr->format != '\0') {
1633 if (ptr->format == native->format) {
Bob Ippolito964e02a2006-05-25 21:09:45 +00001634 /* Match faster when formats are
1635 listed in the same order */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001636 if (ptr == other)
1637 other++;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001638 /* Only use the trick if the
1639 size matches */
1640 if (ptr->size != native->size)
1641 break;
1642 /* Skip float and double, could be
1643 "unknown" float format */
1644 if (ptr->format == 'd' || ptr->format == 'f')
1645 break;
1646 ptr->pack = native->pack;
1647 ptr->unpack = native->unpack;
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001648 break;
1649 }
1650 ptr++;
1651 }
1652 native++;
1653 }
1654 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001655
Bob Ippolito232f3c92006-05-23 19:12:41 +00001656 /* Add some symbolic constants to the module */
1657 if (StructError == NULL) {
1658 StructError = PyErr_NewException("struct.error", NULL, NULL);
1659 if (StructError == NULL)
1660 return;
1661 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001662
Bob Ippolito232f3c92006-05-23 19:12:41 +00001663 Py_INCREF(StructError);
1664 PyModule_AddObject(m, "error", StructError);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001665
Bob Ippolito232f3c92006-05-23 19:12:41 +00001666 Py_INCREF((PyObject*)&PyStructType);
1667 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
1668}