blob: cb2e5380d592cd77f60d361d54568ecdb7d0f566 [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 Ippolitoaa70a172006-05-26 20:25:23 +0000226_range_error(char format, Py_ssize_t size, int is_unsigned)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000227{
228 if (is_unsigned == 0) {
229 long smallest = 0, largest = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000230 Py_ssize_t i = 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",
237 format,
238 smallest,
239 largest);
240 } else {
241 unsigned long largest = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000242 Py_ssize_t i = 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",
247 format,
248 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 Ippolitoe27337b2006-05-26 13:15:44 +0000485 return _range_error(f->format, sizeof(y), 0);
486#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 Ippolitoe27337b2006-05-26 13:15:44 +0000498 return _range_error(f->format, sizeof(y), 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 Ippolitoe27337b2006-05-26 13:15:44 +0000502 return _range_error(f->format, sizeof(y), 1);
503#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 Ippolitoe27337b2006-05-26 13:15:44 +0000523 return _range_error(f->format, sizeof(x), 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 Ippolito232f3c92006-05-23 19:12:41 +0000624 do {
625 x = (x<<8) | (*p++ & 0xFF);
626 } while (--i > 0);
627 /* Extend the sign bit. */
628 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000629 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000630 return PyInt_FromLong(x);
631}
632
633static PyObject *
634bu_uint(const char *p, const formatdef *f)
635{
636 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000637 Py_ssize_t i = f->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000638 do {
639 x = (x<<8) | (*p++ & 0xFF);
640 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000641 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000642 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000643 return PyLong_FromUnsignedLong(x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000644}
645
646static PyObject *
647bu_longlong(const char *p, const formatdef *f)
648{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000649#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000650 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000651 Py_ssize_t i = f->size;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000652 do {
653 x = (x<<8) | (*p++ & 0xFF);
654 } while (--i > 0);
655 /* Extend the sign bit. */
656 if (SIZEOF_LONG_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000657 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000658 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000659 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000660 return PyLong_FromLongLong(x);
661#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000662 return _PyLong_FromByteArray((const unsigned char *)p,
663 8,
664 0, /* little-endian */
665 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000666#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000667}
668
669static PyObject *
670bu_ulonglong(const char *p, const formatdef *f)
671{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000672#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000673 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000674 Py_ssize_t i = f->size;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000675 do {
676 x = (x<<8) | (*p++ & 0xFF);
677 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000678 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000679 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000680 return PyLong_FromUnsignedLongLong(x);
681#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000682 return _PyLong_FromByteArray((const unsigned char *)p,
683 8,
684 0, /* little-endian */
685 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000686#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000687}
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;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000705 Py_ssize_t i;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000706 if (get_long(v, &x) < 0)
707 return -1;
708 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000709 if (i != SIZEOF_LONG) {
710 if ((i == 2) && (x < -32768 || x > 32767))
711 return _range_error(f->format, i, 0);
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000712#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000713 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
714 return _range_error(f->format, i, 0);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000715#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000716 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000717 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;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000728 Py_ssize_t i;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000729 if (get_ulong(v, &x) < 0)
730 return -1;
731 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000732 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 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000738 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},
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000803 {'b', 1, 0, nu_byte, np_byte},
804 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000805 {'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;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000827 Py_ssize_t i = f->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000828 do {
829 x = (x<<8) | (p[--i] & 0xFF);
830 } while (i > 0);
831 /* Extend the sign bit. */
832 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000833 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000834 return PyInt_FromLong(x);
835}
836
837static PyObject *
838lu_uint(const char *p, const formatdef *f)
839{
840 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000841 Py_ssize_t i = f->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000842 do {
843 x = (x<<8) | (p[--i] & 0xFF);
844 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000845 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000846 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000847 return PyLong_FromUnsignedLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000848}
849
850static PyObject *
851lu_longlong(const char *p, const formatdef *f)
852{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000853#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000854 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000855 Py_ssize_t i = f->size;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000856 do {
857 x = (x<<8) | (p[--i] & 0xFF);
858 } while (i > 0);
859 /* Extend the sign bit. */
860 if (SIZEOF_LONG_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000861 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000862 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000863 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000864 return PyLong_FromLongLong(x);
865#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000866 return _PyLong_FromByteArray((const unsigned char *)p,
867 8,
868 1, /* little-endian */
869 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000870#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000871}
872
873static PyObject *
874lu_ulonglong(const char *p, const formatdef *f)
875{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000876#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000877 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000878 Py_ssize_t i = f->size;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000879 do {
880 x = (x<<8) | (p[--i] & 0xFF);
881 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000882 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000883 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000884 return PyLong_FromUnsignedLongLong(x);
885#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000886 return _PyLong_FromByteArray((const unsigned char *)p,
887 8,
888 1, /* little-endian */
889 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000890#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000891}
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;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000909 Py_ssize_t i;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000910 if (get_long(v, &x) < 0)
911 return -1;
912 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000913 if (i != SIZEOF_LONG) {
914 if ((i == 2) && (x < -32768 || x > 32767))
915 return _range_error(f->format, i, 0);
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000916#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000917 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
918 return _range_error(f->format, i, 0);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000919#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000920 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000921 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;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000932 Py_ssize_t i;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000933 if (get_ulong(v, &x) < 0)
934 return -1;
935 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000936 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 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000942 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},
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001007 {'b', 1, 0, nu_byte, np_byte},
1008 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001009 {'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
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001071align(Py_ssize_t size, char c, const formatdef *e)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001072{
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;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001096 Py_ssize_t size, len, num, itemsize, x;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001097
1098 fmt = PyString_AS_STRING(self->s_format);
1099
1100 f = whichtable((char **)&fmt);
1101
1102 s = fmt;
1103 size = 0;
1104 len = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001105 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 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001136
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;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001150 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
Bob Ippolito232f3c92006-05-23 19:12:41 +00001151 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);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001175 if (c == 's' || c == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001176 codes->offset = size;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001177 codes->size = num;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001178 codes->fmtdef = e;
1179 codes++;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001180 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 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001191 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001192 }
1193 codes->fmtdef = NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001194 codes->offset = size;
1195 codes->size = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001196
1197 return 0;
1198}
1199
1200static PyObject *
1201s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1202{
1203 PyObject *self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001204
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))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001231 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001232
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{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001244 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
Bob Ippolitoeb621272006-05-24 15:32:06 +00001253static 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;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001290}
Bob Ippolitoeb621272006-05-24 15:32:06 +00001291
1292
Bob Ippolito232f3c92006-05-23 19:12:41 +00001293PyDoc_STRVAR(s_unpack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001294"S.unpack(str) -> (v1, v2, ...)\n\
Bob Ippolito232f3c92006-05-23 19:12:41 +00001295\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{
Bob Ippolitoeb621272006-05-24 15:32:06 +00001303 PyStructObject *soself = (PyStructObject *)self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001304 assert(PyStruct_Check(self));
1305 assert(soself->s_codes != NULL);
1306 if (inputstr == NULL || !PyString_Check(inputstr) ||
Bob Ippolitoeb621272006-05-24 15:32:06 +00001307 PyString_GET_SIZE(inputstr) != soself->s_size) {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001308 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001309 "unpack requires a string argument of length %zd", soself->s_size);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001310 return NULL;
1311 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001312 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1313}
1314
1315PyDoc_STRVAR(s_unpack_from__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001316"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
Bob Ippolitoeb621272006-05-24 15:32:06 +00001317\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))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001340 return NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001341
1342 if (buffer == NULL) {
1343 PyErr_Format(StructError,
1344 "unpack_from requires a buffer argument");
Bob Ippolito232f3c92006-05-23 19:12:41 +00001345 return NULL;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001346 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001347
1348 if (offset < 0)
1349 offset += buffer_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001350
Bob Ippolitoeb621272006-05-24 15:32:06 +00001351 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1352 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001353 "unpack_from requires a buffer of at least %zd bytes",
Bob Ippolitoeb621272006-05-24 15:32:06 +00001354 soself->s_size);
1355 return NULL;
1356 }
1357 return s_unpack_internal(soself, buffer + offset);
1358}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001359
Bob Ippolito232f3c92006-05-23 19:12:41 +00001360
Martin Blais2856e5f2006-05-26 12:03:27 +00001361/*
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)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001373{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001374 formatcode *code;
1375 Py_ssize_t i;
Martin Blais2856e5f2006-05-26 12:03:27 +00001376
1377 memset(buf, '\0', soself->s_size);
1378 i = offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001379 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1380 Py_ssize_t n;
1381 PyObject *v;
1382 const formatdef *e = code->fmtdef;
Martin Blais2856e5f2006-05-26 12:03:27 +00001383 char *res = buf + code->offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001384 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");
Martin Blais2856e5f2006-05-26 12:03:27 +00001389 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001390 }
1391 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001392 if (n > code->size)
1393 n = code->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001394 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");
Martin Blais2856e5f2006-05-26 12:03:27 +00001401 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001402 }
1403 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001404 if (n > (code->size - 1))
1405 n = code->size - 1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001406 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 {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001412 v = PyTuple_GET_ITEM(args, i++);
1413 if (e->pack(res, v, e) < 0)
Martin Blais2856e5f2006-05-26 12:03:27 +00001414 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001415 }
1416 }
1417
Martin Blais2856e5f2006-05-26 12:03:27 +00001418 /* Success */
1419 return 0;
1420}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001421
Martin Blais2856e5f2006-05-26 12:03:27 +00001422
1423PyDoc_STRVAR(s_pack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001424"S.pack(v1, v2, ...) -> string\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001425\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,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001443 "pack requires exactly %zd arguments", soself->s_len);
Martin Blais2856e5f2006-05-26 12:03:27 +00001444 return NULL;
1445 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001446
Martin Blais2856e5f2006-05-26 12:03:27 +00001447 /* 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__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001462"S.pack_to(buffer, offset, v1, v2, ...)\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001463\n\
1464Pack the values v2, v2, ... according to this Struct's format, write \n\
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001465the 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\
Martin Blais2856e5f2006-05-26 12:03:27 +00001467more 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,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001484 "pack_to requires exactly %zd arguments",
Martin Blais2856e5f2006-05-26 12:03:27 +00001485 (soself->s_len + 2));
1486 return NULL;
1487 }
1488
1489 /* Extract a writable memory buffer from the first argument */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001490 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1491 (void**)&buffer, &buffer_len) == -1 ) {
Martin Blais2856e5f2006-05-26 12:03:27 +00001492 return NULL;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001493 }
1494 assert( buffer_len >= 0 );
Martin Blais2856e5f2006-05-26 12:03:27 +00001495
1496 /* Extract the offset from the first argument */
1497 offset = PyInt_AsLong(PyTuple_GET_ITEM(args, 1));
1498
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001499 /* Support negative offsets. */
Martin Blais2856e5f2006-05-26 12:03:27 +00001500 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,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001506 "pack_to requires a buffer of at least %zd bytes",
Martin Blais2856e5f2006-05-26 12:03:27 +00001507 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;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001517}
1518
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001519static 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}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001531
1532/* List of functions */
1533
1534static struct PyMethodDef s_methods[] = {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001535 {"pack", (PyCFunction)s_pack, METH_VARARGS, s_pack__doc__},
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001536 {"pack_to", (PyCFunction)s_pack_to, METH_VARARGS, s_pack_to__doc__},
Bob Ippolitoeb621272006-05-24 15:32:06 +00001537 {"unpack", (PyCFunction)s_unpack, METH_O, s_unpack__doc__},
1538 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001539 {NULL, NULL} /* sentinel */
1540};
1541
1542PyDoc_STRVAR(s__doc__, "Compiled struct object");
1543
1544#define OFF(x) offsetof(PyStructObject, x)
1545
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001546static PyGetSetDef s_getsetlist[] = {
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001547 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1548 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001549 {NULL} /* sentinel */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001550};
1551
Bob Ippolito232f3c92006-05-23 19:12:41 +00001552static
1553PyTypeObject PyStructType = {
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001554 PyObject_HEAD_INIT(NULL)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001555 0,
1556 "Struct",
1557 sizeof(PyStructObject),
1558 0,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001559 (destructor)s_dealloc, /* tp_dealloc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001560 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 */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001571 PyObject_GenericGetAttr, /* tp_getattro */
1572 PyObject_GenericSetAttr, /* tp_setattro */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001573 0, /* tp_as_buffer */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001574 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1575 s__doc__, /* tp_doc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001576 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 */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001582 s_methods, /* tp_methods */
1583 NULL, /* tp_members */
1584 s_getsetlist, /* tp_getset */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001585 0, /* tp_base */
1586 0, /* tp_dict */
1587 0, /* tp_descr_get */
1588 0, /* tp_descr_set */
1589 0, /* tp_dictoffset */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001590 s_init, /* tp_init */
1591 PyType_GenericAlloc,/* tp_alloc */
1592 s_new, /* tp_new */
1593 PyObject_Del, /* tp_free */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001594};
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
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001605 PyStructType.ob_type = &PyType_Type;
1606 if (PyType_Ready(&PyStructType) < 0)
1607 return;
1608
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001609 /* 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;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001618 /* 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) */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001622 while (native->format != '\0' && other->format != '\0') {
1623 ptr = other;
1624 while (ptr->format != '\0') {
1625 if (ptr->format == native->format) {
Bob Ippolito964e02a2006-05-25 21:09:45 +00001626 /* Match faster when formats are
1627 listed in the same order */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001628 if (ptr == other)
1629 other++;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001630 /* 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;
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001640 break;
1641 }
1642 ptr++;
1643 }
1644 native++;
1645 }
1646 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001647
Bob Ippolito232f3c92006-05-23 19:12:41 +00001648 /* 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 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001654
Bob Ippolito232f3c92006-05-23 19:12:41 +00001655 Py_INCREF(StructError);
1656 PyModule_AddObject(m, "error", StructError);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001657
Bob Ippolito232f3c92006-05-23 19:12:41 +00001658 Py_INCREF((PyObject*)&PyStructType);
1659 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
1660}