blob: 6a3c11f4e6f714a5ee6e8ca0b5f326f02bb6c68d [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 Ippolito4182a752006-05-30 17:37:54 +000020/* If PY_STRUCT_OVERFLOW_MASKING is defined, the struct module will wrap all input
Bob Ippolito2fd39772006-05-29 22:55:48 +000021 numbers for explicit endians such that they fit in the given type, much
22 like explicit casting in C. A warning will be raised if the number did
23 not originally fit within the range of the requested type. If it is
24 not defined, then all range errors and overflow will be struct.error
25 exceptions. */
26
Bob Ippolito4182a752006-05-30 17:37:54 +000027#define PY_STRUCT_OVERFLOW_MASKING 1
Bob Ippolito2fd39772006-05-29 22:55:48 +000028
Bob Ippolito4182a752006-05-30 17:37:54 +000029#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +000030static PyObject *pylong_ulong_mask = NULL;
31static PyObject *pyint_zero = NULL;
32#endif
33
Bob Ippolito232f3c92006-05-23 19:12:41 +000034/* The translation function for each format character is table driven */
Bob Ippolito232f3c92006-05-23 19:12:41 +000035typedef struct _formatdef {
36 char format;
Bob Ippolitoaa70a172006-05-26 20:25:23 +000037 Py_ssize_t size;
38 Py_ssize_t alignment;
Bob Ippolito232f3c92006-05-23 19:12:41 +000039 PyObject* (*unpack)(const char *,
40 const struct _formatdef *);
41 int (*pack)(char *, PyObject *,
42 const struct _formatdef *);
43} formatdef;
44
45typedef struct _formatcode {
46 const struct _formatdef *fmtdef;
Bob Ippolitoaa70a172006-05-26 20:25:23 +000047 Py_ssize_t offset;
48 Py_ssize_t size;
Bob Ippolito232f3c92006-05-23 19:12:41 +000049} formatcode;
50
51/* Struct object interface */
52
53typedef struct {
54 PyObject_HEAD
Bob Ippolitoaa70a172006-05-26 20:25:23 +000055 Py_ssize_t s_size;
56 Py_ssize_t s_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +000057 formatcode *s_codes;
58 PyObject *s_format;
59 PyObject *weakreflist; /* List of weak references */
60} PyStructObject;
61
Bob Ippolitoeb621272006-05-24 15:32:06 +000062
Bob Ippolito07c023b2006-05-23 19:32:25 +000063#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
64#define PyStruct_CheckExact(op) ((op)->ob_type == &PyStructType)
Bob Ippolito232f3c92006-05-23 19:12:41 +000065
66
67/* Exception */
68
69static PyObject *StructError;
70
71
72/* Define various structs to figure out the alignments of types */
73
74
75typedef struct { char c; short x; } st_short;
76typedef struct { char c; int x; } st_int;
77typedef struct { char c; long x; } st_long;
78typedef struct { char c; float x; } st_float;
79typedef struct { char c; double x; } st_double;
80typedef struct { char c; void *x; } st_void_p;
81
82#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
83#define INT_ALIGN (sizeof(st_int) - sizeof(int))
84#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
85#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
86#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
87#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
88
89/* We can't support q and Q in native mode unless the compiler does;
90 in std mode, they're 8 bytes on all platforms. */
91#ifdef HAVE_LONG_LONG
92typedef struct { char c; PY_LONG_LONG x; } s_long_long;
93#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))
94#endif
95
96#define STRINGIFY(x) #x
97
98#ifdef __powerc
99#pragma options align=reset
100#endif
101
102/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */
103
104static PyObject *
105get_pylong(PyObject *v)
106{
107 PyNumberMethods *m;
108
109 assert(v != NULL);
110 if (PyInt_Check(v))
111 return PyLong_FromLong(PyInt_AS_LONG(v));
112 if (PyLong_Check(v)) {
113 Py_INCREF(v);
114 return v;
115 }
116 m = v->ob_type->tp_as_number;
117 if (m != NULL && m->nb_long != NULL) {
118 v = m->nb_long(v);
119 if (v == NULL)
120 return NULL;
121 if (PyLong_Check(v))
122 return v;
123 Py_DECREF(v);
124 }
125 PyErr_SetString(StructError,
126 "cannot convert argument to long");
127 return NULL;
128}
129
130/* Helper routine to get a Python integer and raise the appropriate error
131 if it isn't one */
132
133static int
134get_long(PyObject *v, long *p)
135{
136 long x = PyInt_AsLong(v);
137 if (x == -1 && PyErr_Occurred()) {
138 if (PyErr_ExceptionMatches(PyExc_TypeError))
139 PyErr_SetString(StructError,
140 "required argument is not an integer");
141 return -1;
142 }
143 *p = x;
144 return 0;
145}
146
147
148/* Same, but handling unsigned long */
149
150static int
151get_ulong(PyObject *v, unsigned long *p)
152{
153 if (PyLong_Check(v)) {
154 unsigned long x = PyLong_AsUnsignedLong(v);
155 if (x == (unsigned long)(-1) && PyErr_Occurred())
156 return -1;
157 *p = x;
158 return 0;
159 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000160 if (get_long(v, (long *)p) < 0)
161 return -1;
162 if (((long)*p) < 0) {
163 PyErr_SetString(StructError,
164 "unsigned argument is < 0");
165 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000166 }
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000167 return 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000168}
169
170#ifdef HAVE_LONG_LONG
171
172/* Same, but handling native long long. */
173
174static int
175get_longlong(PyObject *v, PY_LONG_LONG *p)
176{
177 PY_LONG_LONG x;
178
179 v = get_pylong(v);
180 if (v == NULL)
181 return -1;
182 assert(PyLong_Check(v));
183 x = PyLong_AsLongLong(v);
184 Py_DECREF(v);
185 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())
186 return -1;
187 *p = x;
188 return 0;
189}
190
191/* Same, but handling native unsigned long long. */
192
193static int
194get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
195{
196 unsigned PY_LONG_LONG x;
197
198 v = get_pylong(v);
199 if (v == NULL)
200 return -1;
201 assert(PyLong_Check(v));
202 x = PyLong_AsUnsignedLongLong(v);
203 Py_DECREF(v);
204 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())
205 return -1;
206 *p = x;
207 return 0;
208}
209
210#endif
211
Bob Ippolito4182a752006-05-30 17:37:54 +0000212#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000213
214/* Helper routine to get a Python integer and raise the appropriate error
215 if it isn't one */
216
217static int
218get_wrapped_long(PyObject *v, long *p)
219{
220 if (get_long(v, p) < 0) {
221 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError)) {
222 PyObject *wrapped;
223 long x;
224 PyErr_Clear();
Bob Ippolito4182a752006-05-30 17:37:54 +0000225 if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0)
Bob Ippolito2fd39772006-05-29 22:55:48 +0000226 return -1;
227 wrapped = PyNumber_And(v, pylong_ulong_mask);
228 if (wrapped == NULL)
229 return -1;
230 x = (long)PyLong_AsUnsignedLong(wrapped);
231 Py_DECREF(wrapped);
232 if (x == -1 && PyErr_Occurred())
233 return -1;
234 *p = x;
235 } else {
236 return -1;
237 }
238 }
239 return 0;
240}
241
242static int
243get_wrapped_ulong(PyObject *v, unsigned long *p)
244{
245 long x = (long)PyLong_AsUnsignedLong(v);
246 if (x == -1 && PyErr_Occurred()) {
247 PyObject *wrapped;
248 PyErr_Clear();
249 wrapped = PyNumber_And(v, pylong_ulong_mask);
250 if (wrapped == NULL)
251 return -1;
Bob Ippolito4182a752006-05-30 17:37:54 +0000252 if (PyErr_Warn(PyExc_DeprecationWarning, "struct integer overflow masking is deprecated") < 0) {
Bob Ippolito2fd39772006-05-29 22:55:48 +0000253 Py_DECREF(wrapped);
254 return -1;
255 }
256 x = (long)PyLong_AsUnsignedLong(wrapped);
257 Py_DECREF(wrapped);
258 if (x == -1 && PyErr_Occurred())
259 return -1;
260 }
261 *p = (unsigned long)x;
262 return 0;
263}
264
265#define RANGE_ERROR(x, f, flag, mask) \
266 do { \
267 if (_range_error(f, flag) < 0) \
268 return -1; \
269 else \
270 (x) &= (mask); \
271 } while (0)
272
273#else
274
275#define get_wrapped_long get_long
276#define get_wrapped_ulong get_ulong
277#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
278
279#endif
280
Bob Ippolito232f3c92006-05-23 19:12:41 +0000281/* Floating point helpers */
282
283static PyObject *
284unpack_float(const char *p, /* start of 4-byte string */
285 int le) /* true for little-endian, false for big-endian */
286{
287 double x;
288
289 x = _PyFloat_Unpack4((unsigned char *)p, le);
290 if (x == -1.0 && PyErr_Occurred())
291 return NULL;
292 return PyFloat_FromDouble(x);
293}
294
295static PyObject *
296unpack_double(const char *p, /* start of 8-byte string */
297 int le) /* true for little-endian, false for big-endian */
298{
299 double x;
300
301 x = _PyFloat_Unpack8((unsigned char *)p, le);
302 if (x == -1.0 && PyErr_Occurred())
303 return NULL;
304 return PyFloat_FromDouble(x);
305}
306
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000307/* Helper to format the range error exceptions */
308static int
Armin Rigo162997e2006-05-29 17:59:47 +0000309_range_error(const formatdef *f, int is_unsigned)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000310{
311 if (is_unsigned == 0) {
Neal Norwitz971ea112006-05-31 07:43:27 +0000312 Py_ssize_t smallest, largest = 0;
Bob Ippolito28b26862006-05-29 15:47:29 +0000313 Py_ssize_t i = f->size * 8;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000314 while (--i > 0) {
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000315 largest = (largest * 2) + 1;
316 }
Neal Norwitz971ea112006-05-31 07:43:27 +0000317 smallest = -largest - 1;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000318 PyErr_Format(StructError,
Neal Norwitz971ea112006-05-31 07:43:27 +0000319 "'%c' format requires %zd <= number <= %zd",
Bob Ippolito28b26862006-05-29 15:47:29 +0000320 f->format,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000321 smallest,
322 largest);
323 } else {
Neal Norwitz971ea112006-05-31 07:43:27 +0000324 size_t largest = 0;
Bob Ippolito28b26862006-05-29 15:47:29 +0000325 Py_ssize_t i = f->size * 8;
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000326 while (--i >= 0)
327 largest = (largest * 2) + 1;
328 PyErr_Format(StructError,
Neal Norwitz971ea112006-05-31 07:43:27 +0000329 "'%c' format requires 0 <= number <= %zu",
Bob Ippolito28b26862006-05-29 15:47:29 +0000330 f->format,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000331 largest);
332 }
Bob Ippolito4182a752006-05-30 17:37:54 +0000333#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000334 {
335 PyObject *ptype, *pvalue, *ptraceback;
336 PyObject *msg;
337 int rval;
338 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
339 assert(pvalue != NULL);
340 msg = PyObject_Str(pvalue);
341 Py_XDECREF(ptype);
342 Py_XDECREF(pvalue);
343 Py_XDECREF(ptraceback);
344 if (msg == NULL)
345 return -1;
346 rval = PyErr_Warn(PyExc_DeprecationWarning, PyString_AS_STRING(msg));
347 Py_DECREF(msg);
348 if (rval == 0)
349 return 0;
350 }
351#endif
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000352 return -1;
353}
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000354
355
Bob Ippolito232f3c92006-05-23 19:12:41 +0000356
357/* A large number of small routines follow, with names of the form
358
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000359 [bln][up]_TYPE
Bob Ippolito232f3c92006-05-23 19:12:41 +0000360
361 [bln] distiguishes among big-endian, little-endian and native.
362 [pu] distiguishes between pack (to struct) and unpack (from struct).
363 TYPE is one of char, byte, ubyte, etc.
364*/
365
366/* Native mode routines. ****************************************************/
367/* NOTE:
368 In all n[up]_<type> routines handling types larger than 1 byte, there is
369 *no* guarantee that the p pointer is properly aligned for each type,
370 therefore memcpy is called. An intermediate variable is used to
371 compensate for big-endian architectures.
372 Normally both the intermediate variable and the memcpy call will be
373 skipped by C optimisation in little-endian architectures (gcc >= 2.91
374 does this). */
375
376static PyObject *
377nu_char(const char *p, const formatdef *f)
378{
379 return PyString_FromStringAndSize(p, 1);
380}
381
382static PyObject *
383nu_byte(const char *p, const formatdef *f)
384{
385 return PyInt_FromLong((long) *(signed char *)p);
386}
387
388static PyObject *
389nu_ubyte(const char *p, const formatdef *f)
390{
391 return PyInt_FromLong((long) *(unsigned char *)p);
392}
393
394static PyObject *
395nu_short(const char *p, const formatdef *f)
396{
397 short x;
398 memcpy((char *)&x, p, sizeof x);
399 return PyInt_FromLong((long)x);
400}
401
402static PyObject *
403nu_ushort(const char *p, const formatdef *f)
404{
405 unsigned short x;
406 memcpy((char *)&x, p, sizeof x);
407 return PyInt_FromLong((long)x);
408}
409
410static PyObject *
411nu_int(const char *p, const formatdef *f)
412{
413 int x;
414 memcpy((char *)&x, p, sizeof x);
415 return PyInt_FromLong((long)x);
416}
417
418static PyObject *
419nu_uint(const char *p, const formatdef *f)
420{
421 unsigned int x;
422 memcpy((char *)&x, p, sizeof x);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000423#if (SIZEOF_LONG > SIZEOF_INT)
424 return PyInt_FromLong((long)x);
425#else
426 if (x <= ((unsigned int)LONG_MAX))
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000427 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000428 return PyLong_FromUnsignedLong((unsigned long)x);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000429#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000430}
431
432static PyObject *
433nu_long(const char *p, const formatdef *f)
434{
435 long x;
436 memcpy((char *)&x, p, sizeof x);
437 return PyInt_FromLong(x);
438}
439
440static PyObject *
441nu_ulong(const char *p, const formatdef *f)
442{
443 unsigned long x;
444 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000445 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000446 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000447 return PyLong_FromUnsignedLong(x);
448}
449
450/* Native mode doesn't support q or Q unless the platform C supports
451 long long (or, on Windows, __int64). */
452
453#ifdef HAVE_LONG_LONG
454
455static PyObject *
456nu_longlong(const char *p, const formatdef *f)
457{
458 PY_LONG_LONG x;
459 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000460 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000461 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000462 return PyLong_FromLongLong(x);
463}
464
465static PyObject *
466nu_ulonglong(const char *p, const formatdef *f)
467{
468 unsigned PY_LONG_LONG x;
469 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000470 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000471 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000472 return PyLong_FromUnsignedLongLong(x);
473}
474
475#endif
476
477static PyObject *
478nu_float(const char *p, const formatdef *f)
479{
480 float x;
481 memcpy((char *)&x, p, sizeof x);
482 return PyFloat_FromDouble((double)x);
483}
484
485static PyObject *
486nu_double(const char *p, const formatdef *f)
487{
488 double x;
489 memcpy((char *)&x, p, sizeof x);
490 return PyFloat_FromDouble(x);
491}
492
493static PyObject *
494nu_void_p(const char *p, const formatdef *f)
495{
496 void *x;
497 memcpy((char *)&x, p, sizeof x);
498 return PyLong_FromVoidPtr(x);
499}
500
501static int
502np_byte(char *p, PyObject *v, const formatdef *f)
503{
504 long x;
505 if (get_long(v, &x) < 0)
506 return -1;
507 if (x < -128 || x > 127){
508 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000509 "byte format requires -128 <= number <= 127");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000510 return -1;
511 }
512 *p = (char)x;
513 return 0;
514}
515
516static int
517np_ubyte(char *p, PyObject *v, const formatdef *f)
518{
519 long x;
520 if (get_long(v, &x) < 0)
521 return -1;
522 if (x < 0 || x > 255){
523 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000524 "ubyte format requires 0 <= number <= 255");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000525 return -1;
526 }
527 *p = (char)x;
528 return 0;
529}
530
531static int
532np_char(char *p, PyObject *v, const formatdef *f)
533{
534 if (!PyString_Check(v) || PyString_Size(v) != 1) {
535 PyErr_SetString(StructError,
536 "char format require string of length 1");
537 return -1;
538 }
539 *p = *PyString_AsString(v);
540 return 0;
541}
542
543static int
544np_short(char *p, PyObject *v, const formatdef *f)
545{
546 long x;
547 short y;
548 if (get_long(v, &x) < 0)
549 return -1;
550 if (x < SHRT_MIN || x > SHRT_MAX){
551 PyErr_SetString(StructError,
552 "short format requires " STRINGIFY(SHRT_MIN)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000553 " <= number <= " STRINGIFY(SHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000554 return -1;
555 }
556 y = (short)x;
557 memcpy(p, (char *)&y, sizeof y);
558 return 0;
559}
560
561static int
562np_ushort(char *p, PyObject *v, const formatdef *f)
563{
564 long x;
565 unsigned short y;
566 if (get_long(v, &x) < 0)
567 return -1;
568 if (x < 0 || x > USHRT_MAX){
569 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000570 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000571 return -1;
572 }
573 y = (unsigned short)x;
574 memcpy(p, (char *)&y, sizeof y);
575 return 0;
576}
577
578static int
579np_int(char *p, PyObject *v, const formatdef *f)
580{
581 long x;
582 int y;
583 if (get_long(v, &x) < 0)
584 return -1;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000585#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000586 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Bob Ippolito28b26862006-05-29 15:47:29 +0000587 return _range_error(f, 0);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000588#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000589 y = (int)x;
590 memcpy(p, (char *)&y, sizeof y);
591 return 0;
592}
593
594static int
595np_uint(char *p, PyObject *v, const formatdef *f)
596{
597 unsigned long x;
598 unsigned int y;
599 if (get_ulong(v, &x) < 0)
Bob Ippolito28b26862006-05-29 15:47:29 +0000600 return _range_error(f, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000601 y = (unsigned int)x;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000602#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000603 if (x > ((unsigned long)UINT_MAX))
Bob Ippolito28b26862006-05-29 15:47:29 +0000604 return _range_error(f, 1);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000605#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000606 memcpy(p, (char *)&y, sizeof y);
607 return 0;
608}
609
610static int
611np_long(char *p, PyObject *v, const formatdef *f)
612{
613 long x;
614 if (get_long(v, &x) < 0)
615 return -1;
616 memcpy(p, (char *)&x, sizeof x);
617 return 0;
618}
619
620static int
621np_ulong(char *p, PyObject *v, const formatdef *f)
622{
623 unsigned long x;
624 if (get_ulong(v, &x) < 0)
Bob Ippolito28b26862006-05-29 15:47:29 +0000625 return _range_error(f, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000626 memcpy(p, (char *)&x, sizeof x);
627 return 0;
628}
629
630#ifdef HAVE_LONG_LONG
631
632static int
633np_longlong(char *p, PyObject *v, const formatdef *f)
634{
635 PY_LONG_LONG x;
636 if (get_longlong(v, &x) < 0)
637 return -1;
638 memcpy(p, (char *)&x, sizeof x);
639 return 0;
640}
641
642static int
643np_ulonglong(char *p, PyObject *v, const formatdef *f)
644{
645 unsigned PY_LONG_LONG x;
646 if (get_ulonglong(v, &x) < 0)
647 return -1;
648 memcpy(p, (char *)&x, sizeof x);
649 return 0;
650}
651#endif
652
653static int
654np_float(char *p, PyObject *v, const formatdef *f)
655{
656 float x = (float)PyFloat_AsDouble(v);
657 if (x == -1 && PyErr_Occurred()) {
658 PyErr_SetString(StructError,
659 "required argument is not a float");
660 return -1;
661 }
662 memcpy(p, (char *)&x, sizeof x);
663 return 0;
664}
665
666static int
667np_double(char *p, PyObject *v, const formatdef *f)
668{
669 double x = PyFloat_AsDouble(v);
670 if (x == -1 && PyErr_Occurred()) {
671 PyErr_SetString(StructError,
672 "required argument is not a float");
673 return -1;
674 }
675 memcpy(p, (char *)&x, sizeof(double));
676 return 0;
677}
678
679static int
680np_void_p(char *p, PyObject *v, const formatdef *f)
681{
682 void *x;
683
684 v = get_pylong(v);
685 if (v == NULL)
686 return -1;
687 assert(PyLong_Check(v));
688 x = PyLong_AsVoidPtr(v);
689 Py_DECREF(v);
690 if (x == NULL && PyErr_Occurred())
691 return -1;
692 memcpy(p, (char *)&x, sizeof x);
693 return 0;
694}
695
696static formatdef native_table[] = {
697 {'x', sizeof(char), 0, NULL},
698 {'b', sizeof(char), 0, nu_byte, np_byte},
699 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
700 {'c', sizeof(char), 0, nu_char, np_char},
701 {'s', sizeof(char), 0, NULL},
702 {'p', sizeof(char), 0, NULL},
703 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
704 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
705 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
706 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
707 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
708 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000709#ifdef HAVE_LONG_LONG
710 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
711 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
712#endif
Bob Ippolitoa99865b2006-05-25 19:56:56 +0000713 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
714 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
715 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000716 {0}
717};
718
719/* Big-endian routines. *****************************************************/
720
721static PyObject *
722bu_int(const char *p, const formatdef *f)
723{
724 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000725 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000726 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000727 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000728 x = (x<<8) | *bytes++;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000729 } while (--i > 0);
730 /* Extend the sign bit. */
731 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000732 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000733 return PyInt_FromLong(x);
734}
735
736static PyObject *
737bu_uint(const char *p, const formatdef *f)
738{
739 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000740 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000741 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000742 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000743 x = (x<<8) | *bytes++;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000744 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000745 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000746 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000747 return PyLong_FromUnsignedLong(x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000748}
749
750static PyObject *
751bu_longlong(const char *p, const formatdef *f)
752{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000753#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000754 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000755 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000756 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000757 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000758 x = (x<<8) | *bytes++;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000759 } while (--i > 0);
760 /* Extend the sign bit. */
761 if (SIZEOF_LONG_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000762 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000763 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000764 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000765 return PyLong_FromLongLong(x);
766#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000767 return _PyLong_FromByteArray((const unsigned char *)p,
768 8,
769 0, /* little-endian */
770 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000771#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000772}
773
774static PyObject *
775bu_ulonglong(const char *p, const formatdef *f)
776{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000777#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000778 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000779 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000780 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000781 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000782 x = (x<<8) | *bytes++;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000783 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000784 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000785 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000786 return PyLong_FromUnsignedLongLong(x);
787#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000788 return _PyLong_FromByteArray((const unsigned char *)p,
789 8,
790 0, /* little-endian */
791 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000792#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000793}
794
795static PyObject *
796bu_float(const char *p, const formatdef *f)
797{
798 return unpack_float(p, 0);
799}
800
801static PyObject *
802bu_double(const char *p, const formatdef *f)
803{
804 return unpack_double(p, 0);
805}
806
807static int
808bp_int(char *p, PyObject *v, const formatdef *f)
809{
810 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000811 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +0000812 if (get_wrapped_long(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000813 return -1;
814 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000815 if (i != SIZEOF_LONG) {
816 if ((i == 2) && (x < -32768 || x > 32767))
Bob Ippolito2fd39772006-05-29 22:55:48 +0000817 RANGE_ERROR(x, f, 0, 0xffffL);
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000818#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000819 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Bob Ippolito2fd39772006-05-29 22:55:48 +0000820 RANGE_ERROR(x, f, 0, 0xffffffffL);
821#endif
Bob Ippolito4182a752006-05-30 17:37:54 +0000822#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000823 else if ((i == 1) && (x < -128 || x > 127))
824 RANGE_ERROR(x, f, 0, 0xffL);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000825#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000826 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000827 do {
828 p[--i] = (char)x;
829 x >>= 8;
830 } while (i > 0);
831 return 0;
832}
833
834static int
835bp_uint(char *p, PyObject *v, const formatdef *f)
836{
837 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000838 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +0000839 if (get_wrapped_ulong(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000840 return -1;
841 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000842 if (i != SIZEOF_LONG) {
843 unsigned long maxint = 1;
844 maxint <<= (unsigned long)(i * 8);
845 if (x >= maxint)
Bob Ippolito2fd39772006-05-29 22:55:48 +0000846 RANGE_ERROR(x, f, 1, maxint - 1);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000847 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000848 do {
849 p[--i] = (char)x;
850 x >>= 8;
851 } while (i > 0);
852 return 0;
853}
854
855static int
856bp_longlong(char *p, PyObject *v, const formatdef *f)
857{
858 int res;
859 v = get_pylong(v);
860 if (v == NULL)
861 return -1;
862 res = _PyLong_AsByteArray((PyLongObject *)v,
863 (unsigned char *)p,
864 8,
865 0, /* little_endian */
866 1 /* signed */);
867 Py_DECREF(v);
868 return res;
869}
870
871static int
872bp_ulonglong(char *p, PyObject *v, const formatdef *f)
873{
874 int res;
875 v = get_pylong(v);
876 if (v == NULL)
877 return -1;
878 res = _PyLong_AsByteArray((PyLongObject *)v,
879 (unsigned char *)p,
880 8,
881 0, /* little_endian */
882 0 /* signed */);
883 Py_DECREF(v);
884 return res;
885}
886
887static int
888bp_float(char *p, PyObject *v, const formatdef *f)
889{
890 double x = PyFloat_AsDouble(v);
891 if (x == -1 && PyErr_Occurred()) {
892 PyErr_SetString(StructError,
893 "required argument is not a float");
894 return -1;
895 }
896 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
897}
898
899static int
900bp_double(char *p, PyObject *v, const formatdef *f)
901{
902 double x = PyFloat_AsDouble(v);
903 if (x == -1 && PyErr_Occurred()) {
904 PyErr_SetString(StructError,
905 "required argument is not a float");
906 return -1;
907 }
908 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
909}
910
911static formatdef bigendian_table[] = {
912 {'x', 1, 0, NULL},
Bob Ippolito4182a752006-05-30 17:37:54 +0000913#ifdef PY_STRUCT_OVERFLOW_MASKING
914 /* Native packers do range checking without overflow masking. */
Bob Ippolito2fd39772006-05-29 22:55:48 +0000915 {'b', 1, 0, nu_byte, bp_int},
916 {'B', 1, 0, nu_ubyte, bp_uint},
917#else
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000918 {'b', 1, 0, nu_byte, np_byte},
919 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito2fd39772006-05-29 22:55:48 +0000920#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000921 {'c', 1, 0, nu_char, np_char},
922 {'s', 1, 0, NULL},
923 {'p', 1, 0, NULL},
924 {'h', 2, 0, bu_int, bp_int},
925 {'H', 2, 0, bu_uint, bp_uint},
926 {'i', 4, 0, bu_int, bp_int},
927 {'I', 4, 0, bu_uint, bp_uint},
928 {'l', 4, 0, bu_int, bp_int},
929 {'L', 4, 0, bu_uint, bp_uint},
930 {'q', 8, 0, bu_longlong, bp_longlong},
931 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
932 {'f', 4, 0, bu_float, bp_float},
933 {'d', 8, 0, bu_double, bp_double},
934 {0}
935};
936
937/* Little-endian routines. *****************************************************/
938
939static PyObject *
940lu_int(const char *p, const formatdef *f)
941{
942 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000943 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000944 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000945 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000946 x = (x<<8) | bytes[--i];
Bob Ippolito232f3c92006-05-23 19:12:41 +0000947 } while (i > 0);
948 /* Extend the sign bit. */
949 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000950 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000951 return PyInt_FromLong(x);
952}
953
954static PyObject *
955lu_uint(const char *p, const formatdef *f)
956{
957 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000958 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000959 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000960 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000961 x = (x<<8) | bytes[--i];
Bob Ippolito232f3c92006-05-23 19:12:41 +0000962 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000963 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000964 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000965 return PyLong_FromUnsignedLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000966}
967
968static PyObject *
969lu_longlong(const char *p, const formatdef *f)
970{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000971#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000972 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000973 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000974 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000975 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000976 x = (x<<8) | bytes[--i];
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000977 } while (i > 0);
978 /* Extend the sign bit. */
979 if (SIZEOF_LONG_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000980 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000981 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000982 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000983 return PyLong_FromLongLong(x);
984#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000985 return _PyLong_FromByteArray((const unsigned char *)p,
986 8,
987 1, /* little-endian */
988 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000989#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000990}
991
992static PyObject *
993lu_ulonglong(const char *p, const formatdef *f)
994{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000995#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000996 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000997 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000998 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000999 do {
Bob Ippolito28b26862006-05-29 15:47:29 +00001000 x = (x<<8) | bytes[--i];
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001001 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001002 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001003 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001004 return PyLong_FromUnsignedLongLong(x);
1005#else
Bob Ippolito232f3c92006-05-23 19:12:41 +00001006 return _PyLong_FromByteArray((const unsigned char *)p,
1007 8,
1008 1, /* little-endian */
1009 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001010#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001011}
1012
1013static PyObject *
1014lu_float(const char *p, const formatdef *f)
1015{
1016 return unpack_float(p, 1);
1017}
1018
1019static PyObject *
1020lu_double(const char *p, const formatdef *f)
1021{
1022 return unpack_double(p, 1);
1023}
1024
1025static int
1026lp_int(char *p, PyObject *v, const formatdef *f)
1027{
1028 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001029 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001030 if (get_wrapped_long(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001031 return -1;
1032 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001033 if (i != SIZEOF_LONG) {
1034 if ((i == 2) && (x < -32768 || x > 32767))
Bob Ippolito2fd39772006-05-29 22:55:48 +00001035 RANGE_ERROR(x, f, 0, 0xffffL);
Bob Ippolito90bd0a52006-05-27 11:47:12 +00001036#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001037 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Bob Ippolito2fd39772006-05-29 22:55:48 +00001038 RANGE_ERROR(x, f, 0, 0xffffffffL);
1039#endif
Bob Ippolito4182a752006-05-30 17:37:54 +00001040#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +00001041 else if ((i == 1) && (x < -128 || x > 127))
1042 RANGE_ERROR(x, f, 0, 0xffL);
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001043#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001044 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001045 do {
1046 *p++ = (char)x;
1047 x >>= 8;
1048 } while (--i > 0);
1049 return 0;
1050}
1051
1052static int
1053lp_uint(char *p, PyObject *v, const formatdef *f)
1054{
1055 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001056 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001057 if (get_wrapped_ulong(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001058 return -1;
1059 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001060 if (i != SIZEOF_LONG) {
1061 unsigned long maxint = 1;
1062 maxint <<= (unsigned long)(i * 8);
1063 if (x >= maxint)
Bob Ippolito2fd39772006-05-29 22:55:48 +00001064 RANGE_ERROR(x, f, 1, maxint - 1);
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001065 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001066 do {
1067 *p++ = (char)x;
1068 x >>= 8;
1069 } while (--i > 0);
1070 return 0;
1071}
1072
1073static int
1074lp_longlong(char *p, PyObject *v, const formatdef *f)
1075{
1076 int res;
1077 v = get_pylong(v);
1078 if (v == NULL)
1079 return -1;
1080 res = _PyLong_AsByteArray((PyLongObject*)v,
1081 (unsigned char *)p,
1082 8,
1083 1, /* little_endian */
1084 1 /* signed */);
1085 Py_DECREF(v);
1086 return res;
1087}
1088
1089static int
1090lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1091{
1092 int res;
1093 v = get_pylong(v);
1094 if (v == NULL)
1095 return -1;
1096 res = _PyLong_AsByteArray((PyLongObject*)v,
1097 (unsigned char *)p,
1098 8,
1099 1, /* little_endian */
1100 0 /* signed */);
1101 Py_DECREF(v);
1102 return res;
1103}
1104
1105static int
1106lp_float(char *p, PyObject *v, const formatdef *f)
1107{
1108 double x = PyFloat_AsDouble(v);
1109 if (x == -1 && PyErr_Occurred()) {
1110 PyErr_SetString(StructError,
1111 "required argument is not a float");
1112 return -1;
1113 }
1114 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1115}
1116
1117static int
1118lp_double(char *p, PyObject *v, const formatdef *f)
1119{
1120 double x = PyFloat_AsDouble(v);
1121 if (x == -1 && PyErr_Occurred()) {
1122 PyErr_SetString(StructError,
1123 "required argument is not a float");
1124 return -1;
1125 }
1126 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1127}
1128
1129static formatdef lilendian_table[] = {
1130 {'x', 1, 0, NULL},
Bob Ippolito4182a752006-05-30 17:37:54 +00001131#ifdef PY_STRUCT_OVERFLOW_MASKING
1132 /* Native packers do range checking without overflow masking. */
Bob Ippolito2fd39772006-05-29 22:55:48 +00001133 {'b', 1, 0, nu_byte, lp_int},
1134 {'B', 1, 0, nu_ubyte, lp_uint},
1135#else
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001136 {'b', 1, 0, nu_byte, np_byte},
1137 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito2fd39772006-05-29 22:55:48 +00001138#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001139 {'c', 1, 0, nu_char, np_char},
1140 {'s', 1, 0, NULL},
1141 {'p', 1, 0, NULL},
1142 {'h', 2, 0, lu_int, lp_int},
1143 {'H', 2, 0, lu_uint, lp_uint},
1144 {'i', 4, 0, lu_int, lp_int},
1145 {'I', 4, 0, lu_uint, lp_uint},
1146 {'l', 4, 0, lu_int, lp_int},
1147 {'L', 4, 0, lu_uint, lp_uint},
1148 {'q', 8, 0, lu_longlong, lp_longlong},
1149 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1150 {'f', 4, 0, lu_float, lp_float},
1151 {'d', 8, 0, lu_double, lp_double},
1152 {0}
1153};
1154
1155
1156static const formatdef *
1157whichtable(char **pfmt)
1158{
1159 const char *fmt = (*pfmt)++; /* May be backed out of later */
1160 switch (*fmt) {
1161 case '<':
1162 return lilendian_table;
1163 case '>':
1164 case '!': /* Network byte order is big-endian */
1165 return bigendian_table;
1166 case '=': { /* Host byte order -- different from native in aligment! */
1167 int n = 1;
1168 char *p = (char *) &n;
1169 if (*p == 1)
1170 return lilendian_table;
1171 else
1172 return bigendian_table;
1173 }
1174 default:
1175 --*pfmt; /* Back out of pointer increment */
1176 /* Fall through */
1177 case '@':
1178 return native_table;
1179 }
1180}
1181
1182
1183/* Get the table entry for a format code */
1184
1185static const formatdef *
1186getentry(int c, const formatdef *f)
1187{
1188 for (; f->format != '\0'; f++) {
1189 if (f->format == c) {
1190 return f;
1191 }
1192 }
1193 PyErr_SetString(StructError, "bad char in struct format");
1194 return NULL;
1195}
1196
1197
1198/* Align a size according to a format code */
1199
1200static int
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001201align(Py_ssize_t size, char c, const formatdef *e)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001202{
1203 if (e->format == c) {
1204 if (e->alignment) {
1205 size = ((size + e->alignment - 1)
1206 / e->alignment)
1207 * e->alignment;
1208 }
1209 }
1210 return size;
1211}
1212
1213
1214/* calculate the size of a format string */
1215
1216static int
1217prepare_s(PyStructObject *self)
1218{
1219 const formatdef *f;
1220 const formatdef *e;
1221 formatcode *codes;
1222
1223 const char *s;
1224 const char *fmt;
1225 char c;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001226 Py_ssize_t size, len, num, itemsize, x;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001227
1228 fmt = PyString_AS_STRING(self->s_format);
1229
1230 f = whichtable((char **)&fmt);
1231
1232 s = fmt;
1233 size = 0;
1234 len = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001235 while ((c = *s++) != '\0') {
1236 if (isspace(Py_CHARMASK(c)))
1237 continue;
1238 if ('0' <= c && c <= '9') {
1239 num = c - '0';
1240 while ('0' <= (c = *s++) && c <= '9') {
1241 x = num*10 + (c - '0');
1242 if (x/10 != num) {
1243 PyErr_SetString(
1244 StructError,
1245 "overflow in item count");
1246 return -1;
1247 }
1248 num = x;
1249 }
1250 if (c == '\0')
1251 break;
1252 }
1253 else
1254 num = 1;
1255
1256 e = getentry(c, f);
1257 if (e == NULL)
1258 return -1;
1259
1260 switch (c) {
1261 case 's': /* fall through */
1262 case 'p': len++; break;
1263 case 'x': break;
1264 default: len += num; break;
1265 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001266
1267 itemsize = e->size;
1268 size = align(size, c, e);
1269 x = num * itemsize;
1270 size += x;
1271 if (x/itemsize != num || size < 0) {
1272 PyErr_SetString(StructError,
1273 "total struct size too long");
1274 return -1;
1275 }
1276 }
1277
1278 self->s_size = size;
1279 self->s_len = len;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001280 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
Bob Ippolito232f3c92006-05-23 19:12:41 +00001281 if (codes == NULL) {
1282 PyErr_NoMemory();
1283 return -1;
1284 }
1285 self->s_codes = codes;
1286
1287 s = fmt;
1288 size = 0;
1289 while ((c = *s++) != '\0') {
1290 if (isspace(Py_CHARMASK(c)))
1291 continue;
1292 if ('0' <= c && c <= '9') {
1293 num = c - '0';
1294 while ('0' <= (c = *s++) && c <= '9')
1295 num = num*10 + (c - '0');
1296 if (c == '\0')
1297 break;
1298 }
1299 else
1300 num = 1;
1301
1302 e = getentry(c, f);
1303
1304 size = align(size, c, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001305 if (c == 's' || c == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001306 codes->offset = size;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001307 codes->size = num;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001308 codes->fmtdef = e;
1309 codes++;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001310 size += num;
1311 } else if (c == 'x') {
1312 size += num;
1313 } else {
1314 while (--num >= 0) {
1315 codes->offset = size;
1316 codes->size = e->size;
1317 codes->fmtdef = e;
1318 codes++;
1319 size += e->size;
1320 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001321 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001322 }
1323 codes->fmtdef = NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001324 codes->offset = size;
1325 codes->size = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001326
1327 return 0;
1328}
1329
1330static PyObject *
1331s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1332{
1333 PyObject *self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001334
1335 assert(type != NULL && type->tp_alloc != NULL);
1336
1337 self = type->tp_alloc(type, 0);
1338 if (self != NULL) {
1339 PyStructObject *s = (PyStructObject*)self;
1340 Py_INCREF(Py_None);
1341 s->s_format = Py_None;
1342 s->s_codes = NULL;
1343 s->s_size = -1;
1344 s->s_len = -1;
1345 }
1346 return self;
1347}
1348
1349static int
1350s_init(PyObject *self, PyObject *args, PyObject *kwds)
1351{
1352 PyStructObject *soself = (PyStructObject *)self;
1353 PyObject *o_format = NULL;
1354 int ret = 0;
1355 static char *kwlist[] = {"format", 0};
1356
1357 assert(PyStruct_Check(self));
1358
1359 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1360 &o_format))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001361 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001362
1363 Py_INCREF(o_format);
1364 Py_XDECREF(soself->s_format);
1365 soself->s_format = o_format;
1366
1367 ret = prepare_s(soself);
1368 return ret;
1369}
1370
1371static void
1372s_dealloc(PyStructObject *s)
1373{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001374 if (s->weakreflist != NULL)
1375 PyObject_ClearWeakRefs((PyObject *)s);
1376 if (s->s_codes != NULL) {
1377 PyMem_FREE(s->s_codes);
1378 }
1379 Py_XDECREF(s->s_format);
1380 s->ob_type->tp_free((PyObject *)s);
1381}
1382
Bob Ippolitoeb621272006-05-24 15:32:06 +00001383static PyObject *
1384s_unpack_internal(PyStructObject *soself, char *startfrom) {
1385 formatcode *code;
1386 Py_ssize_t i = 0;
1387 PyObject *result = PyTuple_New(soself->s_len);
1388 if (result == NULL)
1389 return NULL;
1390
1391 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1392 PyObject *v;
1393 const formatdef *e = code->fmtdef;
1394 const char *res = startfrom + code->offset;
1395 if (e->format == 's') {
1396 v = PyString_FromStringAndSize(res, code->size);
1397 if (v == NULL)
1398 goto fail;
1399 PyTuple_SET_ITEM(result, i++, v);
1400 } else if (e->format == 'p') {
1401 Py_ssize_t n = *(unsigned char*)res;
1402 if (n >= code->size)
1403 n = code->size - 1;
1404 v = PyString_FromStringAndSize(res + 1, n);
1405 if (v == NULL)
1406 goto fail;
1407 PyTuple_SET_ITEM(result, i++, v);
1408 } else {
1409 v = e->unpack(res, e);
1410 if (v == NULL)
1411 goto fail;
1412 PyTuple_SET_ITEM(result, i++, v);
1413 }
1414 }
1415
1416 return result;
1417fail:
1418 Py_DECREF(result);
1419 return NULL;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001420}
Bob Ippolitoeb621272006-05-24 15:32:06 +00001421
1422
Bob Ippolito232f3c92006-05-23 19:12:41 +00001423PyDoc_STRVAR(s_unpack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001424"S.unpack(str) -> (v1, v2, ...)\n\
Bob Ippolito232f3c92006-05-23 19:12:41 +00001425\n\
1426Return tuple containing values unpacked according to this Struct's format.\n\
1427Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1428strings.");
1429
1430static PyObject *
1431s_unpack(PyObject *self, PyObject *inputstr)
1432{
Bob Ippolitoeb621272006-05-24 15:32:06 +00001433 PyStructObject *soself = (PyStructObject *)self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001434 assert(PyStruct_Check(self));
1435 assert(soself->s_codes != NULL);
1436 if (inputstr == NULL || !PyString_Check(inputstr) ||
Bob Ippolitoeb621272006-05-24 15:32:06 +00001437 PyString_GET_SIZE(inputstr) != soself->s_size) {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001438 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001439 "unpack requires a string argument of length %zd", soself->s_size);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001440 return NULL;
1441 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001442 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));
1443}
1444
1445PyDoc_STRVAR(s_unpack_from__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001446"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\
Bob Ippolitoeb621272006-05-24 15:32:06 +00001447\n\
1448Return tuple containing values unpacked according to this Struct's format.\n\
1449Unlike unpack, unpack_from can unpack values from any object supporting\n\
1450the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\
1451See struct.__doc__ for more on format strings.");
1452
1453static PyObject *
1454s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)
1455{
1456 static char *kwlist[] = {"buffer", "offset", 0};
1457#if (PY_VERSION_HEX < 0x02050000)
1458 static char *fmt = "z#|i:unpack_from";
1459#else
1460 static char *fmt = "z#|n:unpack_from";
1461#endif
1462 Py_ssize_t buffer_len = 0, offset = 0;
1463 char *buffer = NULL;
1464 PyStructObject *soself = (PyStructObject *)self;
1465 assert(PyStruct_Check(self));
1466 assert(soself->s_codes != NULL);
1467
1468 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,
1469 &buffer, &buffer_len, &offset))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001470 return NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001471
1472 if (buffer == NULL) {
1473 PyErr_Format(StructError,
1474 "unpack_from requires a buffer argument");
Bob Ippolito232f3c92006-05-23 19:12:41 +00001475 return NULL;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001476 }
Bob Ippolitoeb621272006-05-24 15:32:06 +00001477
1478 if (offset < 0)
1479 offset += buffer_len;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001480
Bob Ippolitoeb621272006-05-24 15:32:06 +00001481 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1482 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001483 "unpack_from requires a buffer of at least %zd bytes",
Bob Ippolitoeb621272006-05-24 15:32:06 +00001484 soself->s_size);
1485 return NULL;
1486 }
1487 return s_unpack_internal(soself, buffer + offset);
1488}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001489
Bob Ippolito232f3c92006-05-23 19:12:41 +00001490
Martin Blais2856e5f2006-05-26 12:03:27 +00001491/*
1492 * Guts of the pack function.
1493 *
1494 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1495 * argument for where to start processing the arguments for packing, and a
1496 * character buffer for writing the packed string. The caller must insure
1497 * that the buffer may contain the required length for packing the arguments.
1498 * 0 is returned on success, 1 is returned if there is an error.
1499 *
1500 */
1501static int
1502s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001503{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001504 formatcode *code;
1505 Py_ssize_t i;
Martin Blais2856e5f2006-05-26 12:03:27 +00001506
1507 memset(buf, '\0', soself->s_size);
1508 i = offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001509 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1510 Py_ssize_t n;
1511 PyObject *v;
1512 const formatdef *e = code->fmtdef;
Martin Blais2856e5f2006-05-26 12:03:27 +00001513 char *res = buf + code->offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001514 if (e->format == 's') {
1515 v = PyTuple_GET_ITEM(args, i++);
1516 if (!PyString_Check(v)) {
1517 PyErr_SetString(StructError,
1518 "argument for 's' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001519 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001520 }
1521 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001522 if (n > code->size)
1523 n = code->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001524 if (n > 0)
1525 memcpy(res, PyString_AS_STRING(v), n);
1526 } else if (e->format == 'p') {
1527 v = PyTuple_GET_ITEM(args, i++);
1528 if (!PyString_Check(v)) {
1529 PyErr_SetString(StructError,
1530 "argument for 'p' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001531 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001532 }
1533 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001534 if (n > (code->size - 1))
1535 n = code->size - 1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001536 if (n > 0)
1537 memcpy(res + 1, PyString_AS_STRING(v), n);
1538 if (n > 255)
1539 n = 255;
1540 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1541 } else {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001542 v = PyTuple_GET_ITEM(args, i++);
Bob Ippolito2fd39772006-05-29 22:55:48 +00001543 if (e->pack(res, v, e) < 0) {
1544 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1545 PyErr_SetString(StructError,
1546 "long too large to convert to int");
Martin Blais2856e5f2006-05-26 12:03:27 +00001547 return -1;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001548 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001549 }
1550 }
1551
Martin Blais2856e5f2006-05-26 12:03:27 +00001552 /* Success */
1553 return 0;
1554}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001555
Martin Blais2856e5f2006-05-26 12:03:27 +00001556
1557PyDoc_STRVAR(s_pack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001558"S.pack(v1, v2, ...) -> string\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001559\n\
1560Return a string containing values v1, v2, ... packed according to this\n\
1561Struct's format. See struct.__doc__ for more on format strings.");
1562
1563static PyObject *
1564s_pack(PyObject *self, PyObject *args)
1565{
1566 PyStructObject *soself;
1567 PyObject *result;
1568
1569 /* Validate arguments. */
1570 soself = (PyStructObject *)self;
1571 assert(PyStruct_Check(self));
1572 assert(soself->s_codes != NULL);
1573 if (args == NULL || !PyTuple_Check(args) ||
1574 PyTuple_GET_SIZE(args) != soself->s_len)
1575 {
1576 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001577 "pack requires exactly %zd arguments", soself->s_len);
Martin Blais2856e5f2006-05-26 12:03:27 +00001578 return NULL;
1579 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001580
Martin Blais2856e5f2006-05-26 12:03:27 +00001581 /* Allocate a new string */
1582 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1583 if (result == NULL)
1584 return NULL;
1585
1586 /* Call the guts */
1587 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1588 Py_DECREF(result);
1589 return NULL;
1590 }
1591
1592 return result;
1593}
1594
1595PyDoc_STRVAR(s_pack_to__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001596"S.pack_to(buffer, offset, v1, v2, ...)\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001597\n\
1598Pack the values v2, v2, ... according to this Struct's format, write \n\
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001599the packed bytes into the writable buffer buf starting at offset. Note\n\
1600that the offset is not an optional argument. See struct.__doc__ for \n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001601more on format strings.");
1602
1603static PyObject *
1604s_pack_to(PyObject *self, PyObject *args)
1605{
1606 PyStructObject *soself;
1607 char *buffer;
1608 Py_ssize_t buffer_len, offset;
1609
1610 /* Validate arguments. +1 is for the first arg as buffer. */
1611 soself = (PyStructObject *)self;
1612 assert(PyStruct_Check(self));
1613 assert(soself->s_codes != NULL);
1614 if (args == NULL || !PyTuple_Check(args) ||
1615 PyTuple_GET_SIZE(args) != (soself->s_len + 2))
1616 {
1617 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001618 "pack_to requires exactly %zd arguments",
Martin Blais2856e5f2006-05-26 12:03:27 +00001619 (soself->s_len + 2));
1620 return NULL;
1621 }
1622
1623 /* Extract a writable memory buffer from the first argument */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001624 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1625 (void**)&buffer, &buffer_len) == -1 ) {
Martin Blais2856e5f2006-05-26 12:03:27 +00001626 return NULL;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001627 }
1628 assert( buffer_len >= 0 );
Martin Blais2856e5f2006-05-26 12:03:27 +00001629
1630 /* Extract the offset from the first argument */
1631 offset = PyInt_AsLong(PyTuple_GET_ITEM(args, 1));
1632
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001633 /* Support negative offsets. */
Martin Blais2856e5f2006-05-26 12:03:27 +00001634 if (offset < 0)
1635 offset += buffer_len;
1636
1637 /* Check boundaries */
1638 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1639 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001640 "pack_to requires a buffer of at least %zd bytes",
Martin Blais2856e5f2006-05-26 12:03:27 +00001641 soself->s_size);
1642 return NULL;
1643 }
1644
1645 /* Call the guts */
1646 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1647 return NULL;
1648 }
1649
Georg Brandlc26025c2006-05-28 21:42:54 +00001650 Py_RETURN_NONE;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001651}
1652
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001653static PyObject *
1654s_get_format(PyStructObject *self, void *unused)
1655{
1656 Py_INCREF(self->s_format);
1657 return self->s_format;
1658}
1659
1660static PyObject *
1661s_get_size(PyStructObject *self, void *unused)
1662{
1663 return PyInt_FromSsize_t(self->s_size);
1664}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001665
1666/* List of functions */
1667
1668static struct PyMethodDef s_methods[] = {
Bob Ippolitoeb621272006-05-24 15:32:06 +00001669 {"pack", (PyCFunction)s_pack, METH_VARARGS, s_pack__doc__},
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001670 {"pack_to", (PyCFunction)s_pack_to, METH_VARARGS, s_pack_to__doc__},
Bob Ippolitoeb621272006-05-24 15:32:06 +00001671 {"unpack", (PyCFunction)s_unpack, METH_O, s_unpack__doc__},
1672 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS, s_unpack_from__doc__},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001673 {NULL, NULL} /* sentinel */
1674};
1675
1676PyDoc_STRVAR(s__doc__, "Compiled struct object");
1677
1678#define OFF(x) offsetof(PyStructObject, x)
1679
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001680static PyGetSetDef s_getsetlist[] = {
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001681 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1682 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001683 {NULL} /* sentinel */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001684};
1685
Bob Ippolito232f3c92006-05-23 19:12:41 +00001686static
1687PyTypeObject PyStructType = {
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001688 PyObject_HEAD_INIT(NULL)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001689 0,
1690 "Struct",
1691 sizeof(PyStructObject),
1692 0,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001693 (destructor)s_dealloc, /* tp_dealloc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001694 0, /* tp_print */
1695 0, /* tp_getattr */
1696 0, /* tp_setattr */
1697 0, /* tp_compare */
1698 0, /* tp_repr */
1699 0, /* tp_as_number */
1700 0, /* tp_as_sequence */
1701 0, /* tp_as_mapping */
1702 0, /* tp_hash */
1703 0, /* tp_call */
1704 0, /* tp_str */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001705 PyObject_GenericGetAttr, /* tp_getattro */
1706 PyObject_GenericSetAttr, /* tp_setattro */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001707 0, /* tp_as_buffer */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001708 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1709 s__doc__, /* tp_doc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001710 0, /* tp_traverse */
1711 0, /* tp_clear */
1712 0, /* tp_richcompare */
1713 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1714 0, /* tp_iter */
1715 0, /* tp_iternext */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001716 s_methods, /* tp_methods */
1717 NULL, /* tp_members */
1718 s_getsetlist, /* tp_getset */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001719 0, /* tp_base */
1720 0, /* tp_dict */
1721 0, /* tp_descr_get */
1722 0, /* tp_descr_set */
1723 0, /* tp_dictoffset */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001724 s_init, /* tp_init */
1725 PyType_GenericAlloc,/* tp_alloc */
1726 s_new, /* tp_new */
1727 PyObject_Del, /* tp_free */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001728};
1729
1730/* Module initialization */
1731
1732PyMODINIT_FUNC
1733init_struct(void)
1734{
1735 PyObject *m = Py_InitModule("_struct", NULL);
1736 if (m == NULL)
1737 return;
1738
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001739 PyStructType.ob_type = &PyType_Type;
1740 if (PyType_Ready(&PyStructType) < 0)
1741 return;
1742
Bob Ippolito4182a752006-05-30 17:37:54 +00001743#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +00001744 if (pyint_zero == NULL) {
1745 pyint_zero = PyInt_FromLong(0);
1746 if (pyint_zero == NULL)
1747 return;
1748 }
1749 if (pylong_ulong_mask == NULL) {
1750#if (SIZEOF_LONG == 4)
1751 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1752#else
1753 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1754#endif
1755 if (pylong_ulong_mask == NULL)
1756 return;
1757 }
1758
1759#else
Bob Ippolito4182a752006-05-30 17:37:54 +00001760 /* This speed trick can't be used until overflow masking goes away, because
1761 native endian always raises exceptions instead of overflow masking. */
Bob Ippolito2fd39772006-05-29 22:55:48 +00001762
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001763 /* Check endian and swap in faster functions */
1764 {
1765 int one = 1;
1766 formatdef *native = native_table;
1767 formatdef *other, *ptr;
1768 if ((int)*(unsigned char*)&one)
1769 other = lilendian_table;
1770 else
1771 other = bigendian_table;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001772 /* Scan through the native table, find a matching
1773 entry in the endian table and swap in the
1774 native implementations whenever possible
1775 (64-bit platforms may not have "standard" sizes) */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001776 while (native->format != '\0' && other->format != '\0') {
1777 ptr = other;
1778 while (ptr->format != '\0') {
1779 if (ptr->format == native->format) {
Bob Ippolito964e02a2006-05-25 21:09:45 +00001780 /* Match faster when formats are
1781 listed in the same order */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001782 if (ptr == other)
1783 other++;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001784 /* Only use the trick if the
1785 size matches */
1786 if (ptr->size != native->size)
1787 break;
1788 /* Skip float and double, could be
1789 "unknown" float format */
1790 if (ptr->format == 'd' || ptr->format == 'f')
1791 break;
1792 ptr->pack = native->pack;
1793 ptr->unpack = native->unpack;
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001794 break;
1795 }
1796 ptr++;
1797 }
1798 native++;
1799 }
1800 }
Bob Ippolito2fd39772006-05-29 22:55:48 +00001801#endif
Bob Ippolito04ab9942006-05-25 19:33:38 +00001802
Bob Ippolito232f3c92006-05-23 19:12:41 +00001803 /* Add some symbolic constants to the module */
1804 if (StructError == NULL) {
1805 StructError = PyErr_NewException("struct.error", NULL, NULL);
1806 if (StructError == NULL)
1807 return;
1808 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001809
Bob Ippolito232f3c92006-05-23 19:12:41 +00001810 Py_INCREF(StructError);
1811 PyModule_AddObject(m, "error", StructError);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001812
Bob Ippolito232f3c92006-05-23 19:12:41 +00001813 Py_INCREF((PyObject*)&PyStructType);
1814 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Bob Ippolito2fd39772006-05-29 22:55:48 +00001815
1816 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
Bob Ippolito4182a752006-05-30 17:37:54 +00001817#ifdef PY_STRUCT_OVERFLOW_MASKING
1818 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
Bob Ippolito2fd39772006-05-29 22:55:48 +00001819#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001820}