blob: 3774dfd6b9e07ead626b52497212f4a56ab2c4b9 [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
Neal Norwitz07aadb12006-07-30 06:55:48 +0000217#define INT_OVERFLOW "struct integer overflow masking is deprecated"
218
Bob Ippolito2fd39772006-05-29 22:55:48 +0000219static int
220get_wrapped_long(PyObject *v, long *p)
221{
222 if (get_long(v, p) < 0) {
Neal Norwitz3c5431e2006-06-11 05:45:25 +0000223 if (PyLong_Check(v) &&
224 PyErr_ExceptionMatches(PyExc_OverflowError)) {
Bob Ippolito2fd39772006-05-29 22:55:48 +0000225 PyObject *wrapped;
226 long x;
227 PyErr_Clear();
Neal Norwitz07aadb12006-07-30 06:55:48 +0000228 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0)
Bob Ippolito2fd39772006-05-29 22:55:48 +0000229 return -1;
230 wrapped = PyNumber_And(v, pylong_ulong_mask);
231 if (wrapped == NULL)
232 return -1;
233 x = (long)PyLong_AsUnsignedLong(wrapped);
234 Py_DECREF(wrapped);
235 if (x == -1 && PyErr_Occurred())
236 return -1;
237 *p = x;
238 } else {
239 return -1;
240 }
241 }
242 return 0;
243}
244
245static int
246get_wrapped_ulong(PyObject *v, unsigned long *p)
247{
248 long x = (long)PyLong_AsUnsignedLong(v);
249 if (x == -1 && PyErr_Occurred()) {
250 PyObject *wrapped;
251 PyErr_Clear();
252 wrapped = PyNumber_And(v, pylong_ulong_mask);
253 if (wrapped == NULL)
254 return -1;
Neal Norwitz07aadb12006-07-30 06:55:48 +0000255 if (PyErr_WarnEx(PyExc_DeprecationWarning, INT_OVERFLOW, 2) < 0) {
Bob Ippolito2fd39772006-05-29 22:55:48 +0000256 Py_DECREF(wrapped);
257 return -1;
258 }
259 x = (long)PyLong_AsUnsignedLong(wrapped);
260 Py_DECREF(wrapped);
261 if (x == -1 && PyErr_Occurred())
262 return -1;
263 }
264 *p = (unsigned long)x;
265 return 0;
266}
267
268#define RANGE_ERROR(x, f, flag, mask) \
269 do { \
270 if (_range_error(f, flag) < 0) \
271 return -1; \
272 else \
273 (x) &= (mask); \
274 } while (0)
275
276#else
277
278#define get_wrapped_long get_long
279#define get_wrapped_ulong get_ulong
280#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
281
282#endif
283
Bob Ippolito232f3c92006-05-23 19:12:41 +0000284/* Floating point helpers */
285
286static PyObject *
287unpack_float(const char *p, /* start of 4-byte string */
288 int le) /* true for little-endian, false for big-endian */
289{
290 double x;
291
292 x = _PyFloat_Unpack4((unsigned char *)p, le);
293 if (x == -1.0 && PyErr_Occurred())
294 return NULL;
295 return PyFloat_FromDouble(x);
296}
297
298static PyObject *
299unpack_double(const char *p, /* start of 8-byte string */
300 int le) /* true for little-endian, false for big-endian */
301{
302 double x;
303
304 x = _PyFloat_Unpack8((unsigned char *)p, le);
305 if (x == -1.0 && PyErr_Occurred())
306 return NULL;
307 return PyFloat_FromDouble(x);
308}
309
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000310/* Helper to format the range error exceptions */
311static int
Armin Rigo162997e2006-05-29 17:59:47 +0000312_range_error(const formatdef *f, int is_unsigned)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000313{
Tim Petersd6a6f022006-05-31 15:33:22 +0000314 /* ulargest is the largest unsigned value with f->size bytes.
315 * Note that the simpler:
316 * ((size_t)1 << (f->size * 8)) - 1
Tim Peters72270c22006-05-31 15:34:37 +0000317 * doesn't work when f->size == sizeof(size_t) because C doesn't
318 * define what happens when a left shift count is >= the number of
319 * bits in the integer being shifted; e.g., on some boxes it doesn't
320 * shift at all when they're equal.
Tim Petersd6a6f022006-05-31 15:33:22 +0000321 */
322 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
323 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
324 if (is_unsigned)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000325 PyErr_Format(StructError,
Neal Norwitz971ea112006-05-31 07:43:27 +0000326 "'%c' format requires 0 <= number <= %zu",
Bob Ippolito28b26862006-05-29 15:47:29 +0000327 f->format,
Tim Petersd6a6f022006-05-31 15:33:22 +0000328 ulargest);
329 else {
330 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
331 PyErr_Format(StructError,
332 "'%c' format requires %zd <= number <= %zd",
333 f->format,
334 ~ largest,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000335 largest);
336 }
Bob Ippolito4182a752006-05-30 17:37:54 +0000337#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000338 {
339 PyObject *ptype, *pvalue, *ptraceback;
340 PyObject *msg;
341 int rval;
342 PyErr_Fetch(&ptype, &pvalue, &ptraceback);
343 assert(pvalue != NULL);
344 msg = PyObject_Str(pvalue);
345 Py_XDECREF(ptype);
346 Py_XDECREF(pvalue);
347 Py_XDECREF(ptraceback);
348 if (msg == NULL)
349 return -1;
Neal Norwitz07aadb12006-07-30 06:55:48 +0000350 rval = PyErr_WarnEx(PyExc_DeprecationWarning,
351 PyString_AS_STRING(msg), 2);
Bob Ippolito2fd39772006-05-29 22:55:48 +0000352 Py_DECREF(msg);
353 if (rval == 0)
354 return 0;
355 }
356#endif
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000357 return -1;
358}
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000359
360
Bob Ippolito232f3c92006-05-23 19:12:41 +0000361
362/* A large number of small routines follow, with names of the form
363
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000364 [bln][up]_TYPE
Bob Ippolito232f3c92006-05-23 19:12:41 +0000365
366 [bln] distiguishes among big-endian, little-endian and native.
367 [pu] distiguishes between pack (to struct) and unpack (from struct).
368 TYPE is one of char, byte, ubyte, etc.
369*/
370
371/* Native mode routines. ****************************************************/
372/* NOTE:
373 In all n[up]_<type> routines handling types larger than 1 byte, there is
374 *no* guarantee that the p pointer is properly aligned for each type,
375 therefore memcpy is called. An intermediate variable is used to
376 compensate for big-endian architectures.
377 Normally both the intermediate variable and the memcpy call will be
378 skipped by C optimisation in little-endian architectures (gcc >= 2.91
379 does this). */
380
381static PyObject *
382nu_char(const char *p, const formatdef *f)
383{
384 return PyString_FromStringAndSize(p, 1);
385}
386
387static PyObject *
388nu_byte(const char *p, const formatdef *f)
389{
390 return PyInt_FromLong((long) *(signed char *)p);
391}
392
393static PyObject *
394nu_ubyte(const char *p, const formatdef *f)
395{
396 return PyInt_FromLong((long) *(unsigned char *)p);
397}
398
399static PyObject *
400nu_short(const char *p, const formatdef *f)
401{
402 short x;
403 memcpy((char *)&x, p, sizeof x);
404 return PyInt_FromLong((long)x);
405}
406
407static PyObject *
408nu_ushort(const char *p, const formatdef *f)
409{
410 unsigned short x;
411 memcpy((char *)&x, p, sizeof x);
412 return PyInt_FromLong((long)x);
413}
414
415static PyObject *
416nu_int(const char *p, const formatdef *f)
417{
418 int x;
419 memcpy((char *)&x, p, sizeof x);
420 return PyInt_FromLong((long)x);
421}
422
423static PyObject *
424nu_uint(const char *p, const formatdef *f)
425{
426 unsigned int x;
427 memcpy((char *)&x, p, sizeof x);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000428#if (SIZEOF_LONG > SIZEOF_INT)
429 return PyInt_FromLong((long)x);
430#else
431 if (x <= ((unsigned int)LONG_MAX))
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000432 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000433 return PyLong_FromUnsignedLong((unsigned long)x);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000434#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000435}
436
437static PyObject *
438nu_long(const char *p, const formatdef *f)
439{
440 long x;
441 memcpy((char *)&x, p, sizeof x);
442 return PyInt_FromLong(x);
443}
444
445static PyObject *
446nu_ulong(const char *p, const formatdef *f)
447{
448 unsigned long x;
449 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000450 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000451 return PyInt_FromLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000452 return PyLong_FromUnsignedLong(x);
453}
454
455/* Native mode doesn't support q or Q unless the platform C supports
456 long long (or, on Windows, __int64). */
457
458#ifdef HAVE_LONG_LONG
459
460static PyObject *
461nu_longlong(const char *p, const formatdef *f)
462{
463 PY_LONG_LONG x;
464 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000465 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000466 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000467 return PyLong_FromLongLong(x);
468}
469
470static PyObject *
471nu_ulonglong(const char *p, const formatdef *f)
472{
473 unsigned PY_LONG_LONG x;
474 memcpy((char *)&x, p, sizeof x);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000475 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000476 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000477 return PyLong_FromUnsignedLongLong(x);
478}
479
480#endif
481
482static PyObject *
483nu_float(const char *p, const formatdef *f)
484{
485 float x;
486 memcpy((char *)&x, p, sizeof x);
487 return PyFloat_FromDouble((double)x);
488}
489
490static PyObject *
491nu_double(const char *p, const formatdef *f)
492{
493 double x;
494 memcpy((char *)&x, p, sizeof x);
495 return PyFloat_FromDouble(x);
496}
497
498static PyObject *
499nu_void_p(const char *p, const formatdef *f)
500{
501 void *x;
502 memcpy((char *)&x, p, sizeof x);
503 return PyLong_FromVoidPtr(x);
504}
505
506static int
507np_byte(char *p, PyObject *v, const formatdef *f)
508{
509 long x;
510 if (get_long(v, &x) < 0)
511 return -1;
512 if (x < -128 || x > 127){
513 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000514 "byte format requires -128 <= number <= 127");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000515 return -1;
516 }
517 *p = (char)x;
518 return 0;
519}
520
521static int
522np_ubyte(char *p, PyObject *v, const formatdef *f)
523{
524 long x;
525 if (get_long(v, &x) < 0)
526 return -1;
527 if (x < 0 || x > 255){
528 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000529 "ubyte format requires 0 <= number <= 255");
Bob Ippolito232f3c92006-05-23 19:12:41 +0000530 return -1;
531 }
532 *p = (char)x;
533 return 0;
534}
535
536static int
537np_char(char *p, PyObject *v, const formatdef *f)
538{
539 if (!PyString_Check(v) || PyString_Size(v) != 1) {
540 PyErr_SetString(StructError,
541 "char format require string of length 1");
542 return -1;
543 }
544 *p = *PyString_AsString(v);
545 return 0;
546}
547
548static int
549np_short(char *p, PyObject *v, const formatdef *f)
550{
551 long x;
552 short y;
553 if (get_long(v, &x) < 0)
554 return -1;
555 if (x < SHRT_MIN || x > SHRT_MAX){
556 PyErr_SetString(StructError,
557 "short format requires " STRINGIFY(SHRT_MIN)
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000558 " <= number <= " STRINGIFY(SHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000559 return -1;
560 }
561 y = (short)x;
562 memcpy(p, (char *)&y, sizeof y);
563 return 0;
564}
565
566static int
567np_ushort(char *p, PyObject *v, const formatdef *f)
568{
569 long x;
570 unsigned short y;
571 if (get_long(v, &x) < 0)
572 return -1;
573 if (x < 0 || x > USHRT_MAX){
574 PyErr_SetString(StructError,
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000575 "short format requires 0 <= number <= " STRINGIFY(USHRT_MAX));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000576 return -1;
577 }
578 y = (unsigned short)x;
579 memcpy(p, (char *)&y, sizeof y);
580 return 0;
581}
582
583static int
584np_int(char *p, PyObject *v, const formatdef *f)
585{
586 long x;
587 int y;
588 if (get_long(v, &x) < 0)
589 return -1;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000590#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000591 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Bob Ippolito28b26862006-05-29 15:47:29 +0000592 return _range_error(f, 0);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000593#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000594 y = (int)x;
595 memcpy(p, (char *)&y, sizeof y);
596 return 0;
597}
598
599static int
600np_uint(char *p, PyObject *v, const formatdef *f)
601{
602 unsigned long x;
603 unsigned int y;
604 if (get_ulong(v, &x) < 0)
Bob Ippolito28b26862006-05-29 15:47:29 +0000605 return _range_error(f, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000606 y = (unsigned int)x;
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000607#if (SIZEOF_LONG > SIZEOF_INT)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000608 if (x > ((unsigned long)UINT_MAX))
Bob Ippolito28b26862006-05-29 15:47:29 +0000609 return _range_error(f, 1);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000610#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000611 memcpy(p, (char *)&y, sizeof y);
612 return 0;
613}
614
615static int
616np_long(char *p, PyObject *v, const formatdef *f)
617{
618 long x;
619 if (get_long(v, &x) < 0)
620 return -1;
621 memcpy(p, (char *)&x, sizeof x);
622 return 0;
623}
624
625static int
626np_ulong(char *p, PyObject *v, const formatdef *f)
627{
628 unsigned long x;
629 if (get_ulong(v, &x) < 0)
Bob Ippolito28b26862006-05-29 15:47:29 +0000630 return _range_error(f, 1);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000631 memcpy(p, (char *)&x, sizeof x);
632 return 0;
633}
634
635#ifdef HAVE_LONG_LONG
636
637static int
638np_longlong(char *p, PyObject *v, const formatdef *f)
639{
640 PY_LONG_LONG x;
641 if (get_longlong(v, &x) < 0)
642 return -1;
643 memcpy(p, (char *)&x, sizeof x);
644 return 0;
645}
646
647static int
648np_ulonglong(char *p, PyObject *v, const formatdef *f)
649{
650 unsigned PY_LONG_LONG x;
651 if (get_ulonglong(v, &x) < 0)
652 return -1;
653 memcpy(p, (char *)&x, sizeof x);
654 return 0;
655}
656#endif
657
658static int
659np_float(char *p, PyObject *v, const formatdef *f)
660{
661 float x = (float)PyFloat_AsDouble(v);
662 if (x == -1 && PyErr_Occurred()) {
663 PyErr_SetString(StructError,
664 "required argument is not a float");
665 return -1;
666 }
667 memcpy(p, (char *)&x, sizeof x);
668 return 0;
669}
670
671static int
672np_double(char *p, PyObject *v, const formatdef *f)
673{
674 double x = PyFloat_AsDouble(v);
675 if (x == -1 && PyErr_Occurred()) {
676 PyErr_SetString(StructError,
677 "required argument is not a float");
678 return -1;
679 }
680 memcpy(p, (char *)&x, sizeof(double));
681 return 0;
682}
683
684static int
685np_void_p(char *p, PyObject *v, const formatdef *f)
686{
687 void *x;
688
689 v = get_pylong(v);
690 if (v == NULL)
691 return -1;
692 assert(PyLong_Check(v));
693 x = PyLong_AsVoidPtr(v);
694 Py_DECREF(v);
695 if (x == NULL && PyErr_Occurred())
696 return -1;
697 memcpy(p, (char *)&x, sizeof x);
698 return 0;
699}
700
701static formatdef native_table[] = {
702 {'x', sizeof(char), 0, NULL},
703 {'b', sizeof(char), 0, nu_byte, np_byte},
704 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
705 {'c', sizeof(char), 0, nu_char, np_char},
706 {'s', sizeof(char), 0, NULL},
707 {'p', sizeof(char), 0, NULL},
708 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
709 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
710 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
711 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
712 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
713 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000714#ifdef HAVE_LONG_LONG
715 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},
716 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
717#endif
Bob Ippolitoa99865b2006-05-25 19:56:56 +0000718 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
719 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
720 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Bob Ippolito232f3c92006-05-23 19:12:41 +0000721 {0}
722};
723
724/* Big-endian routines. *****************************************************/
725
726static PyObject *
727bu_int(const char *p, const formatdef *f)
728{
729 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000730 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000731 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000732 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000733 x = (x<<8) | *bytes++;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000734 } while (--i > 0);
735 /* Extend the sign bit. */
736 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000737 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000738 return PyInt_FromLong(x);
739}
740
741static PyObject *
742bu_uint(const char *p, const formatdef *f)
743{
744 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000745 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000746 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000747 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000748 x = (x<<8) | *bytes++;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000749 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000750 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000751 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000752 return PyLong_FromUnsignedLong(x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000753}
754
755static PyObject *
756bu_longlong(const char *p, const formatdef *f)
757{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000758#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000759 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000760 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000761 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000762 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000763 x = (x<<8) | *bytes++;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000764 } while (--i > 0);
765 /* Extend the sign bit. */
766 if (SIZEOF_LONG_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000767 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000768 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000769 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000770 return PyLong_FromLongLong(x);
771#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000772 return _PyLong_FromByteArray((const unsigned char *)p,
773 8,
774 0, /* little-endian */
775 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000776#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000777}
778
779static PyObject *
780bu_ulonglong(const char *p, const formatdef *f)
781{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000782#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000783 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000784 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000785 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000786 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000787 x = (x<<8) | *bytes++;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000788 } while (--i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000789 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000790 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000791 return PyLong_FromUnsignedLongLong(x);
792#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000793 return _PyLong_FromByteArray((const unsigned char *)p,
794 8,
795 0, /* little-endian */
796 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000797#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000798}
799
800static PyObject *
801bu_float(const char *p, const formatdef *f)
802{
803 return unpack_float(p, 0);
804}
805
806static PyObject *
807bu_double(const char *p, const formatdef *f)
808{
809 return unpack_double(p, 0);
810}
811
812static int
813bp_int(char *p, PyObject *v, const formatdef *f)
814{
815 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000816 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +0000817 if (get_wrapped_long(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000818 return -1;
819 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000820 if (i != SIZEOF_LONG) {
821 if ((i == 2) && (x < -32768 || x > 32767))
Bob Ippolito2fd39772006-05-29 22:55:48 +0000822 RANGE_ERROR(x, f, 0, 0xffffL);
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000823#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000824 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Bob Ippolito2fd39772006-05-29 22:55:48 +0000825 RANGE_ERROR(x, f, 0, 0xffffffffL);
826#endif
Bob Ippolito4182a752006-05-30 17:37:54 +0000827#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +0000828 else if ((i == 1) && (x < -128 || x > 127))
829 RANGE_ERROR(x, f, 0, 0xffL);
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000830#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000831 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000832 do {
833 p[--i] = (char)x;
834 x >>= 8;
835 } while (i > 0);
836 return 0;
837}
838
839static int
840bp_uint(char *p, PyObject *v, const formatdef *f)
841{
842 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000843 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +0000844 if (get_wrapped_ulong(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000845 return -1;
846 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000847 if (i != SIZEOF_LONG) {
848 unsigned long maxint = 1;
849 maxint <<= (unsigned long)(i * 8);
850 if (x >= maxint)
Bob Ippolito2fd39772006-05-29 22:55:48 +0000851 RANGE_ERROR(x, f, 1, maxint - 1);
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000852 }
Bob Ippolito232f3c92006-05-23 19:12:41 +0000853 do {
854 p[--i] = (char)x;
855 x >>= 8;
856 } while (i > 0);
857 return 0;
858}
859
860static int
861bp_longlong(char *p, PyObject *v, const formatdef *f)
862{
863 int res;
864 v = get_pylong(v);
865 if (v == NULL)
866 return -1;
867 res = _PyLong_AsByteArray((PyLongObject *)v,
868 (unsigned char *)p,
869 8,
870 0, /* little_endian */
871 1 /* signed */);
872 Py_DECREF(v);
873 return res;
874}
875
876static int
877bp_ulonglong(char *p, PyObject *v, const formatdef *f)
878{
879 int res;
880 v = get_pylong(v);
881 if (v == NULL)
882 return -1;
883 res = _PyLong_AsByteArray((PyLongObject *)v,
884 (unsigned char *)p,
885 8,
886 0, /* little_endian */
887 0 /* signed */);
888 Py_DECREF(v);
889 return res;
890}
891
892static int
893bp_float(char *p, PyObject *v, const formatdef *f)
894{
895 double x = PyFloat_AsDouble(v);
896 if (x == -1 && PyErr_Occurred()) {
897 PyErr_SetString(StructError,
898 "required argument is not a float");
899 return -1;
900 }
901 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
902}
903
904static int
905bp_double(char *p, PyObject *v, const formatdef *f)
906{
907 double x = PyFloat_AsDouble(v);
908 if (x == -1 && PyErr_Occurred()) {
909 PyErr_SetString(StructError,
910 "required argument is not a float");
911 return -1;
912 }
913 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
914}
915
916static formatdef bigendian_table[] = {
917 {'x', 1, 0, NULL},
Bob Ippolito4182a752006-05-30 17:37:54 +0000918#ifdef PY_STRUCT_OVERFLOW_MASKING
919 /* Native packers do range checking without overflow masking. */
Bob Ippolito2fd39772006-05-29 22:55:48 +0000920 {'b', 1, 0, nu_byte, bp_int},
921 {'B', 1, 0, nu_ubyte, bp_uint},
922#else
Bob Ippolitoe27337b2006-05-26 13:15:44 +0000923 {'b', 1, 0, nu_byte, np_byte},
924 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito2fd39772006-05-29 22:55:48 +0000925#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000926 {'c', 1, 0, nu_char, np_char},
927 {'s', 1, 0, NULL},
928 {'p', 1, 0, NULL},
929 {'h', 2, 0, bu_int, bp_int},
930 {'H', 2, 0, bu_uint, bp_uint},
931 {'i', 4, 0, bu_int, bp_int},
932 {'I', 4, 0, bu_uint, bp_uint},
933 {'l', 4, 0, bu_int, bp_int},
934 {'L', 4, 0, bu_uint, bp_uint},
935 {'q', 8, 0, bu_longlong, bp_longlong},
936 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
937 {'f', 4, 0, bu_float, bp_float},
938 {'d', 8, 0, bu_double, bp_double},
939 {0}
940};
941
942/* Little-endian routines. *****************************************************/
943
944static PyObject *
945lu_int(const char *p, const formatdef *f)
946{
947 long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000948 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000949 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000950 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000951 x = (x<<8) | bytes[--i];
Bob Ippolito232f3c92006-05-23 19:12:41 +0000952 } while (i > 0);
953 /* Extend the sign bit. */
954 if (SIZEOF_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000955 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito232f3c92006-05-23 19:12:41 +0000956 return PyInt_FromLong(x);
957}
958
959static PyObject *
960lu_uint(const char *p, const formatdef *f)
961{
962 unsigned long x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000963 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000964 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito232f3c92006-05-23 19:12:41 +0000965 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000966 x = (x<<8) | bytes[--i];
Bob Ippolito232f3c92006-05-23 19:12:41 +0000967 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +0000968 if (x <= LONG_MAX)
Bob Ippolito232f3c92006-05-23 19:12:41 +0000969 return PyInt_FromLong((long)x);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000970 return PyLong_FromUnsignedLong((long)x);
Bob Ippolito232f3c92006-05-23 19:12:41 +0000971}
972
973static PyObject *
974lu_longlong(const char *p, const formatdef *f)
975{
Bob Ippolito90bd0a52006-05-27 11:47:12 +0000976#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000977 PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +0000978 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +0000979 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000980 do {
Bob Ippolito28b26862006-05-29 15:47:29 +0000981 x = (x<<8) | bytes[--i];
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000982 } while (i > 0);
983 /* Extend the sign bit. */
984 if (SIZEOF_LONG_LONG > f->size)
Bob Ippolitocd51ca52006-05-27 15:53:49 +0000985 x |= -(x & (1L << ((8 * f->size) - 1)));
Bob Ippolito04ab9942006-05-25 19:33:38 +0000986 if (x >= LONG_MIN && x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000987 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000988 return PyLong_FromLongLong(x);
989#else
Bob Ippolito232f3c92006-05-23 19:12:41 +0000990 return _PyLong_FromByteArray((const unsigned char *)p,
991 8,
992 1, /* little-endian */
993 1 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +0000994#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +0000995}
996
997static PyObject *
998lu_ulonglong(const char *p, const formatdef *f)
999{
Bob Ippolito90bd0a52006-05-27 11:47:12 +00001000#ifdef HAVE_LONG_LONG
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001001 unsigned PY_LONG_LONG x = 0;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001002 Py_ssize_t i = f->size;
Bob Ippolito28b26862006-05-29 15:47:29 +00001003 const unsigned char *bytes = (const unsigned char *)p;
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001004 do {
Bob Ippolito28b26862006-05-29 15:47:29 +00001005 x = (x<<8) | bytes[--i];
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001006 } while (i > 0);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001007 if (x <= LONG_MAX)
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001008 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001009 return PyLong_FromUnsignedLongLong(x);
1010#else
Bob Ippolito232f3c92006-05-23 19:12:41 +00001011 return _PyLong_FromByteArray((const unsigned char *)p,
1012 8,
1013 1, /* little-endian */
1014 0 /* signed */);
Bob Ippolito94f68ee2006-05-25 18:44:50 +00001015#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001016}
1017
1018static PyObject *
1019lu_float(const char *p, const formatdef *f)
1020{
1021 return unpack_float(p, 1);
1022}
1023
1024static PyObject *
1025lu_double(const char *p, const formatdef *f)
1026{
1027 return unpack_double(p, 1);
1028}
1029
1030static int
1031lp_int(char *p, PyObject *v, const formatdef *f)
1032{
1033 long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001034 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001035 if (get_wrapped_long(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001036 return -1;
1037 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001038 if (i != SIZEOF_LONG) {
1039 if ((i == 2) && (x < -32768 || x > 32767))
Bob Ippolito2fd39772006-05-29 22:55:48 +00001040 RANGE_ERROR(x, f, 0, 0xffffL);
Bob Ippolito90bd0a52006-05-27 11:47:12 +00001041#if (SIZEOF_LONG != 4)
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001042 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Bob Ippolito2fd39772006-05-29 22:55:48 +00001043 RANGE_ERROR(x, f, 0, 0xffffffffL);
1044#endif
Bob Ippolito4182a752006-05-30 17:37:54 +00001045#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +00001046 else if ((i == 1) && (x < -128 || x > 127))
1047 RANGE_ERROR(x, f, 0, 0xffL);
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001048#endif
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001049 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001050 do {
1051 *p++ = (char)x;
1052 x >>= 8;
1053 } while (--i > 0);
1054 return 0;
1055}
1056
1057static int
1058lp_uint(char *p, PyObject *v, const formatdef *f)
1059{
1060 unsigned long x;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001061 Py_ssize_t i;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001062 if (get_wrapped_ulong(v, &x) < 0)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001063 return -1;
1064 i = f->size;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001065 if (i != SIZEOF_LONG) {
1066 unsigned long maxint = 1;
1067 maxint <<= (unsigned long)(i * 8);
1068 if (x >= maxint)
Bob Ippolito2fd39772006-05-29 22:55:48 +00001069 RANGE_ERROR(x, f, 1, maxint - 1);
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001070 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001071 do {
1072 *p++ = (char)x;
1073 x >>= 8;
1074 } while (--i > 0);
1075 return 0;
1076}
1077
1078static int
1079lp_longlong(char *p, PyObject *v, const formatdef *f)
1080{
1081 int res;
1082 v = get_pylong(v);
1083 if (v == NULL)
1084 return -1;
1085 res = _PyLong_AsByteArray((PyLongObject*)v,
1086 (unsigned char *)p,
1087 8,
1088 1, /* little_endian */
1089 1 /* signed */);
1090 Py_DECREF(v);
1091 return res;
1092}
1093
1094static int
1095lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1096{
1097 int res;
1098 v = get_pylong(v);
1099 if (v == NULL)
1100 return -1;
1101 res = _PyLong_AsByteArray((PyLongObject*)v,
1102 (unsigned char *)p,
1103 8,
1104 1, /* little_endian */
1105 0 /* signed */);
1106 Py_DECREF(v);
1107 return res;
1108}
1109
1110static int
1111lp_float(char *p, PyObject *v, const formatdef *f)
1112{
1113 double x = PyFloat_AsDouble(v);
1114 if (x == -1 && PyErr_Occurred()) {
1115 PyErr_SetString(StructError,
1116 "required argument is not a float");
1117 return -1;
1118 }
1119 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
1120}
1121
1122static int
1123lp_double(char *p, PyObject *v, const formatdef *f)
1124{
1125 double x = PyFloat_AsDouble(v);
1126 if (x == -1 && PyErr_Occurred()) {
1127 PyErr_SetString(StructError,
1128 "required argument is not a float");
1129 return -1;
1130 }
1131 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
1132}
1133
1134static formatdef lilendian_table[] = {
1135 {'x', 1, 0, NULL},
Bob Ippolito4182a752006-05-30 17:37:54 +00001136#ifdef PY_STRUCT_OVERFLOW_MASKING
1137 /* Native packers do range checking without overflow masking. */
Bob Ippolito2fd39772006-05-29 22:55:48 +00001138 {'b', 1, 0, nu_byte, lp_int},
1139 {'B', 1, 0, nu_ubyte, lp_uint},
1140#else
Bob Ippolitoe27337b2006-05-26 13:15:44 +00001141 {'b', 1, 0, nu_byte, np_byte},
1142 {'B', 1, 0, nu_ubyte, np_ubyte},
Bob Ippolito2fd39772006-05-29 22:55:48 +00001143#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001144 {'c', 1, 0, nu_char, np_char},
1145 {'s', 1, 0, NULL},
1146 {'p', 1, 0, NULL},
1147 {'h', 2, 0, lu_int, lp_int},
1148 {'H', 2, 0, lu_uint, lp_uint},
1149 {'i', 4, 0, lu_int, lp_int},
1150 {'I', 4, 0, lu_uint, lp_uint},
1151 {'l', 4, 0, lu_int, lp_int},
1152 {'L', 4, 0, lu_uint, lp_uint},
1153 {'q', 8, 0, lu_longlong, lp_longlong},
1154 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1155 {'f', 4, 0, lu_float, lp_float},
1156 {'d', 8, 0, lu_double, lp_double},
1157 {0}
1158};
1159
1160
1161static const formatdef *
1162whichtable(char **pfmt)
1163{
1164 const char *fmt = (*pfmt)++; /* May be backed out of later */
1165 switch (*fmt) {
1166 case '<':
1167 return lilendian_table;
1168 case '>':
1169 case '!': /* Network byte order is big-endian */
1170 return bigendian_table;
1171 case '=': { /* Host byte order -- different from native in aligment! */
1172 int n = 1;
1173 char *p = (char *) &n;
1174 if (*p == 1)
1175 return lilendian_table;
1176 else
1177 return bigendian_table;
1178 }
1179 default:
1180 --*pfmt; /* Back out of pointer increment */
1181 /* Fall through */
1182 case '@':
1183 return native_table;
1184 }
1185}
1186
1187
1188/* Get the table entry for a format code */
1189
1190static const formatdef *
1191getentry(int c, const formatdef *f)
1192{
1193 for (; f->format != '\0'; f++) {
1194 if (f->format == c) {
1195 return f;
1196 }
1197 }
1198 PyErr_SetString(StructError, "bad char in struct format");
1199 return NULL;
1200}
1201
1202
1203/* Align a size according to a format code */
1204
1205static int
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001206align(Py_ssize_t size, char c, const formatdef *e)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001207{
1208 if (e->format == c) {
1209 if (e->alignment) {
1210 size = ((size + e->alignment - 1)
1211 / e->alignment)
1212 * e->alignment;
1213 }
1214 }
1215 return size;
1216}
1217
1218
1219/* calculate the size of a format string */
1220
1221static int
1222prepare_s(PyStructObject *self)
1223{
1224 const formatdef *f;
1225 const formatdef *e;
1226 formatcode *codes;
Tim Petersc2b550e2006-05-31 14:28:07 +00001227
Bob Ippolito232f3c92006-05-23 19:12:41 +00001228 const char *s;
1229 const char *fmt;
1230 char c;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001231 Py_ssize_t size, len, num, itemsize, x;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001232
1233 fmt = PyString_AS_STRING(self->s_format);
1234
1235 f = whichtable((char **)&fmt);
Tim Petersc2b550e2006-05-31 14:28:07 +00001236
Bob Ippolito232f3c92006-05-23 19:12:41 +00001237 s = fmt;
1238 size = 0;
1239 len = 0;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001240 while ((c = *s++) != '\0') {
1241 if (isspace(Py_CHARMASK(c)))
1242 continue;
1243 if ('0' <= c && c <= '9') {
1244 num = c - '0';
1245 while ('0' <= (c = *s++) && c <= '9') {
1246 x = num*10 + (c - '0');
1247 if (x/10 != num) {
1248 PyErr_SetString(
1249 StructError,
1250 "overflow in item count");
1251 return -1;
1252 }
1253 num = x;
1254 }
1255 if (c == '\0')
1256 break;
1257 }
1258 else
1259 num = 1;
1260
1261 e = getentry(c, f);
1262 if (e == NULL)
1263 return -1;
Tim Petersc2b550e2006-05-31 14:28:07 +00001264
Bob Ippolito232f3c92006-05-23 19:12:41 +00001265 switch (c) {
1266 case 's': /* fall through */
1267 case 'p': len++; break;
1268 case 'x': break;
1269 default: len += num; break;
1270 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001271
1272 itemsize = e->size;
1273 size = align(size, c, e);
1274 x = num * itemsize;
1275 size += x;
1276 if (x/itemsize != num || size < 0) {
1277 PyErr_SetString(StructError,
1278 "total struct size too long");
1279 return -1;
1280 }
1281 }
1282
1283 self->s_size = size;
1284 self->s_len = len;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001285 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));
Bob Ippolito232f3c92006-05-23 19:12:41 +00001286 if (codes == NULL) {
1287 PyErr_NoMemory();
1288 return -1;
1289 }
1290 self->s_codes = codes;
Tim Petersc2b550e2006-05-31 14:28:07 +00001291
Bob Ippolito232f3c92006-05-23 19:12:41 +00001292 s = fmt;
1293 size = 0;
1294 while ((c = *s++) != '\0') {
1295 if (isspace(Py_CHARMASK(c)))
1296 continue;
1297 if ('0' <= c && c <= '9') {
1298 num = c - '0';
1299 while ('0' <= (c = *s++) && c <= '9')
1300 num = num*10 + (c - '0');
1301 if (c == '\0')
1302 break;
1303 }
1304 else
1305 num = 1;
1306
1307 e = getentry(c, f);
Tim Petersc2b550e2006-05-31 14:28:07 +00001308
Bob Ippolito232f3c92006-05-23 19:12:41 +00001309 size = align(size, c, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001310 if (c == 's' || c == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001311 codes->offset = size;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001312 codes->size = num;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001313 codes->fmtdef = e;
1314 codes++;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001315 size += num;
1316 } else if (c == 'x') {
1317 size += num;
1318 } else {
1319 while (--num >= 0) {
1320 codes->offset = size;
1321 codes->size = e->size;
1322 codes->fmtdef = e;
1323 codes++;
1324 size += e->size;
1325 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001326 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001327 }
1328 codes->fmtdef = NULL;
Bob Ippolitoeb621272006-05-24 15:32:06 +00001329 codes->offset = size;
1330 codes->size = 0;
Tim Petersc2b550e2006-05-31 14:28:07 +00001331
Bob Ippolito232f3c92006-05-23 19:12:41 +00001332 return 0;
1333}
1334
1335static PyObject *
1336s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1337{
1338 PyObject *self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001339
1340 assert(type != NULL && type->tp_alloc != NULL);
1341
1342 self = type->tp_alloc(type, 0);
1343 if (self != NULL) {
1344 PyStructObject *s = (PyStructObject*)self;
1345 Py_INCREF(Py_None);
1346 s->s_format = Py_None;
1347 s->s_codes = NULL;
1348 s->s_size = -1;
1349 s->s_len = -1;
1350 }
1351 return self;
1352}
1353
1354static int
1355s_init(PyObject *self, PyObject *args, PyObject *kwds)
1356{
1357 PyStructObject *soself = (PyStructObject *)self;
1358 PyObject *o_format = NULL;
1359 int ret = 0;
1360 static char *kwlist[] = {"format", 0};
1361
1362 assert(PyStruct_Check(self));
1363
1364 if (!PyArg_ParseTupleAndKeywords(args, kwds, "S:Struct", kwlist,
1365 &o_format))
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001366 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001367
1368 Py_INCREF(o_format);
1369 Py_XDECREF(soself->s_format);
1370 soself->s_format = o_format;
Tim Petersc2b550e2006-05-31 14:28:07 +00001371
Bob Ippolito232f3c92006-05-23 19:12:41 +00001372 ret = prepare_s(soself);
1373 return ret;
1374}
1375
1376static void
1377s_dealloc(PyStructObject *s)
1378{
Bob Ippolito232f3c92006-05-23 19:12:41 +00001379 if (s->weakreflist != NULL)
1380 PyObject_ClearWeakRefs((PyObject *)s);
1381 if (s->s_codes != NULL) {
1382 PyMem_FREE(s->s_codes);
1383 }
1384 Py_XDECREF(s->s_format);
1385 s->ob_type->tp_free((PyObject *)s);
1386}
1387
Bob Ippolitoeb621272006-05-24 15:32:06 +00001388static PyObject *
1389s_unpack_internal(PyStructObject *soself, char *startfrom) {
1390 formatcode *code;
1391 Py_ssize_t i = 0;
1392 PyObject *result = PyTuple_New(soself->s_len);
1393 if (result == NULL)
1394 return NULL;
1395
1396 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1397 PyObject *v;
1398 const formatdef *e = code->fmtdef;
1399 const char *res = startfrom + code->offset;
1400 if (e->format == 's') {
1401 v = PyString_FromStringAndSize(res, code->size);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001402 } else if (e->format == 'p') {
1403 Py_ssize_t n = *(unsigned char*)res;
1404 if (n >= code->size)
1405 n = code->size - 1;
1406 v = PyString_FromStringAndSize(res + 1, n);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001407 } else {
1408 v = e->unpack(res, e);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001409 }
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001410 if (v == NULL)
1411 goto fail;
1412 PyTuple_SET_ITEM(result, i++, v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001413 }
1414
1415 return result;
1416fail:
1417 Py_DECREF(result);
1418 return NULL;
Bob Ippolitocd51ca52006-05-27 15:53:49 +00001419}
Bob Ippolitoeb621272006-05-24 15:32:06 +00001420
1421
Bob Ippolito232f3c92006-05-23 19:12:41 +00001422PyDoc_STRVAR(s_unpack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001423"S.unpack(str) -> (v1, v2, ...)\n\
Bob Ippolito232f3c92006-05-23 19:12:41 +00001424\n\
1425Return tuple containing values unpacked according to this Struct's format.\n\
1426Requires len(str) == self.size. See struct.__doc__ for more on format\n\
1427strings.");
1428
1429static PyObject *
1430s_unpack(PyObject *self, PyObject *inputstr)
1431{
Bob Ippolitoeb621272006-05-24 15:32:06 +00001432 PyStructObject *soself = (PyStructObject *)self;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001433 assert(PyStruct_Check(self));
Tim Petersc2b550e2006-05-31 14:28:07 +00001434 assert(soself->s_codes != NULL);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001435 if (inputstr == NULL || !PyString_Check(inputstr) ||
Bob Ippolitoeb621272006-05-24 15:32:06 +00001436 PyString_GET_SIZE(inputstr) != soself->s_size) {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001437 PyErr_Format(StructError,
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001438 "unpack requires a string argument of length %zd",
1439 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 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001477
Bob Ippolitoeb621272006-05-24 15:32:06 +00001478 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;
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001505 /* XXX(nnorwitz): why does i need to be a local? can we use
1506 the offset parameter or do we need the wider width? */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001507 Py_ssize_t i;
Martin Blais2856e5f2006-05-26 12:03:27 +00001508
1509 memset(buf, '\0', soself->s_size);
1510 i = offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001511 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
1512 Py_ssize_t n;
Neal Norwitz3c5431e2006-06-11 05:45:25 +00001513 PyObject *v = PyTuple_GET_ITEM(args, i++);
Bob Ippolito232f3c92006-05-23 19:12:41 +00001514 const formatdef *e = code->fmtdef;
Martin Blais2856e5f2006-05-26 12:03:27 +00001515 char *res = buf + code->offset;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001516 if (e->format == 's') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001517 if (!PyString_Check(v)) {
1518 PyErr_SetString(StructError,
1519 "argument for 's' must be a string");
Martin Blais2856e5f2006-05-26 12:03:27 +00001520 return -1;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001521 }
1522 n = PyString_GET_SIZE(v);
Bob Ippolitoeb621272006-05-24 15:32:06 +00001523 if (n > code->size)
1524 n = code->size;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001525 if (n > 0)
1526 memcpy(res, PyString_AS_STRING(v), n);
1527 } else if (e->format == 'p') {
Bob Ippolito232f3c92006-05-23 19:12:41 +00001528 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 Ippolito2fd39772006-05-29 22:55:48 +00001542 if (e->pack(res, v, e) < 0) {
1543 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1544 PyErr_SetString(StructError,
1545 "long too large to convert to int");
Martin Blais2856e5f2006-05-26 12:03:27 +00001546 return -1;
Bob Ippolito2fd39772006-05-29 22:55:48 +00001547 }
Bob Ippolito232f3c92006-05-23 19:12:41 +00001548 }
1549 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001550
Martin Blais2856e5f2006-05-26 12:03:27 +00001551 /* Success */
1552 return 0;
1553}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001554
Martin Blais2856e5f2006-05-26 12:03:27 +00001555
1556PyDoc_STRVAR(s_pack__doc__,
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001557"S.pack(v1, v2, ...) -> string\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001558\n\
1559Return a string containing values v1, v2, ... packed according to this\n\
1560Struct's format. See struct.__doc__ for more on format strings.");
1561
1562static PyObject *
1563s_pack(PyObject *self, PyObject *args)
1564{
1565 PyStructObject *soself;
1566 PyObject *result;
1567
1568 /* Validate arguments. */
1569 soself = (PyStructObject *)self;
1570 assert(PyStruct_Check(self));
1571 assert(soself->s_codes != NULL);
Martin Blaisaf2ae722006-06-04 13:49:49 +00001572 if (PyTuple_GET_SIZE(args) != soself->s_len)
Martin Blais2856e5f2006-05-26 12:03:27 +00001573 {
1574 PyErr_Format(StructError,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001575 "pack requires exactly %zd arguments", soself->s_len);
Martin Blais2856e5f2006-05-26 12:03:27 +00001576 return NULL;
1577 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001578
Martin Blais2856e5f2006-05-26 12:03:27 +00001579 /* Allocate a new string */
1580 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);
1581 if (result == NULL)
1582 return NULL;
Tim Petersc2b550e2006-05-31 14:28:07 +00001583
Martin Blais2856e5f2006-05-26 12:03:27 +00001584 /* Call the guts */
1585 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {
1586 Py_DECREF(result);
1587 return NULL;
1588 }
1589
1590 return result;
1591}
1592
Martin Blaisaf2ae722006-06-04 13:49:49 +00001593PyDoc_STRVAR(s_pack_into__doc__,
1594"S.pack_into(buffer, offset, v1, v2, ...)\n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001595\n\
Martin Blaisaf2ae722006-06-04 13:49:49 +00001596Pack the values v1, v2, ... according to this Struct's format, write \n\
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001597the packed bytes into the writable buffer buf starting at offset. Note\n\
1598that the offset is not an optional argument. See struct.__doc__ for \n\
Martin Blais2856e5f2006-05-26 12:03:27 +00001599more on format strings.");
1600
1601static PyObject *
Martin Blaisaf2ae722006-06-04 13:49:49 +00001602s_pack_into(PyObject *self, PyObject *args)
Martin Blais2856e5f2006-05-26 12:03:27 +00001603{
1604 PyStructObject *soself;
1605 char *buffer;
1606 Py_ssize_t buffer_len, offset;
1607
1608 /* Validate arguments. +1 is for the first arg as buffer. */
1609 soself = (PyStructObject *)self;
1610 assert(PyStruct_Check(self));
1611 assert(soself->s_codes != NULL);
Martin Blaisaf2ae722006-06-04 13:49:49 +00001612 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))
Martin Blais2856e5f2006-05-26 12:03:27 +00001613 {
1614 PyErr_Format(StructError,
Martin Blaisaf2ae722006-06-04 13:49:49 +00001615 "pack_into requires exactly %zd arguments",
Martin Blais2856e5f2006-05-26 12:03:27 +00001616 (soself->s_len + 2));
1617 return NULL;
1618 }
1619
1620 /* Extract a writable memory buffer from the first argument */
Tim Petersc2b550e2006-05-31 14:28:07 +00001621 if ( PyObject_AsWriteBuffer(PyTuple_GET_ITEM(args, 0),
1622 (void**)&buffer, &buffer_len) == -1 ) {
Martin Blais2856e5f2006-05-26 12:03:27 +00001623 return NULL;
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001624 }
1625 assert( buffer_len >= 0 );
Martin Blais2856e5f2006-05-26 12:03:27 +00001626
1627 /* Extract the offset from the first argument */
Martin Blaisaf2ae722006-06-04 13:49:49 +00001628 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));
Martin Blais2856e5f2006-05-26 12:03:27 +00001629
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001630 /* Support negative offsets. */
Martin Blais2856e5f2006-05-26 12:03:27 +00001631 if (offset < 0)
1632 offset += buffer_len;
1633
1634 /* Check boundaries */
1635 if (offset < 0 || (buffer_len - offset) < soself->s_size) {
1636 PyErr_Format(StructError,
Martin Blaisaf2ae722006-06-04 13:49:49 +00001637 "pack_into requires a buffer of at least %zd bytes",
Martin Blais2856e5f2006-05-26 12:03:27 +00001638 soself->s_size);
1639 return NULL;
1640 }
Tim Petersc2b550e2006-05-31 14:28:07 +00001641
Martin Blais2856e5f2006-05-26 12:03:27 +00001642 /* Call the guts */
1643 if ( s_pack_internal(soself, args, 2, buffer + offset) != 0 ) {
1644 return NULL;
1645 }
1646
Georg Brandlc26025c2006-05-28 21:42:54 +00001647 Py_RETURN_NONE;
Bob Ippolito232f3c92006-05-23 19:12:41 +00001648}
1649
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001650static PyObject *
1651s_get_format(PyStructObject *self, void *unused)
1652{
1653 Py_INCREF(self->s_format);
1654 return self->s_format;
1655}
1656
1657static PyObject *
1658s_get_size(PyStructObject *self, void *unused)
1659{
1660 return PyInt_FromSsize_t(self->s_size);
1661}
Bob Ippolito232f3c92006-05-23 19:12:41 +00001662
1663/* List of functions */
1664
1665static struct PyMethodDef s_methods[] = {
Martin Blaisaf2ae722006-06-04 13:49:49 +00001666 {"pack", s_pack, METH_VARARGS, s_pack__doc__},
1667 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},
1668 {"unpack", s_unpack, METH_O, s_unpack__doc__},
Tim Peters5ec2e852006-06-04 15:49:07 +00001669 {"unpack_from", (PyCFunction)s_unpack_from, METH_KEYWORDS,
1670 s_unpack_from__doc__},
Bob Ippolito232f3c92006-05-23 19:12:41 +00001671 {NULL, NULL} /* sentinel */
1672};
1673
1674PyDoc_STRVAR(s__doc__, "Compiled struct object");
1675
1676#define OFF(x) offsetof(PyStructObject, x)
1677
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001678static PyGetSetDef s_getsetlist[] = {
Bob Ippolito1fcdc232006-05-27 12:11:36 +00001679 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1680 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001681 {NULL} /* sentinel */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001682};
1683
Bob Ippolito232f3c92006-05-23 19:12:41 +00001684static
1685PyTypeObject PyStructType = {
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001686 PyObject_HEAD_INIT(NULL)
Bob Ippolito232f3c92006-05-23 19:12:41 +00001687 0,
1688 "Struct",
1689 sizeof(PyStructObject),
1690 0,
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001691 (destructor)s_dealloc, /* tp_dealloc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001692 0, /* tp_print */
1693 0, /* tp_getattr */
1694 0, /* tp_setattr */
1695 0, /* tp_compare */
1696 0, /* tp_repr */
1697 0, /* tp_as_number */
1698 0, /* tp_as_sequence */
1699 0, /* tp_as_mapping */
1700 0, /* tp_hash */
1701 0, /* tp_call */
1702 0, /* tp_str */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001703 PyObject_GenericGetAttr, /* tp_getattro */
1704 PyObject_GenericSetAttr, /* tp_setattro */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001705 0, /* tp_as_buffer */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001706 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */
1707 s__doc__, /* tp_doc */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001708 0, /* tp_traverse */
1709 0, /* tp_clear */
1710 0, /* tp_richcompare */
1711 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
1712 0, /* tp_iter */
1713 0, /* tp_iternext */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001714 s_methods, /* tp_methods */
1715 NULL, /* tp_members */
1716 s_getsetlist, /* tp_getset */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001717 0, /* tp_base */
1718 0, /* tp_dict */
1719 0, /* tp_descr_get */
1720 0, /* tp_descr_set */
1721 0, /* tp_dictoffset */
Bob Ippolitoaa70a172006-05-26 20:25:23 +00001722 s_init, /* tp_init */
1723 PyType_GenericAlloc,/* tp_alloc */
1724 s_new, /* tp_new */
1725 PyObject_Del, /* tp_free */
Bob Ippolito232f3c92006-05-23 19:12:41 +00001726};
1727
1728/* Module initialization */
1729
1730PyMODINIT_FUNC
1731init_struct(void)
1732{
1733 PyObject *m = Py_InitModule("_struct", NULL);
1734 if (m == NULL)
1735 return;
1736
Bob Ippolito3fc2bb92006-05-25 19:03:19 +00001737 PyStructType.ob_type = &PyType_Type;
1738 if (PyType_Ready(&PyStructType) < 0)
1739 return;
1740
Bob Ippolito4182a752006-05-30 17:37:54 +00001741#ifdef PY_STRUCT_OVERFLOW_MASKING
Bob Ippolito2fd39772006-05-29 22:55:48 +00001742 if (pyint_zero == NULL) {
1743 pyint_zero = PyInt_FromLong(0);
1744 if (pyint_zero == NULL)
1745 return;
1746 }
1747 if (pylong_ulong_mask == NULL) {
1748#if (SIZEOF_LONG == 4)
1749 pylong_ulong_mask = PyLong_FromString("FFFFFFFF", NULL, 16);
1750#else
1751 pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
1752#endif
1753 if (pylong_ulong_mask == NULL)
1754 return;
1755 }
1756
Tim Petersc2b550e2006-05-31 14:28:07 +00001757#else
Bob Ippolito4182a752006-05-30 17:37:54 +00001758 /* This speed trick can't be used until overflow masking goes away, because
1759 native endian always raises exceptions instead of overflow masking. */
Tim Petersc2b550e2006-05-31 14:28:07 +00001760
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001761 /* Check endian and swap in faster functions */
1762 {
1763 int one = 1;
1764 formatdef *native = native_table;
1765 formatdef *other, *ptr;
1766 if ((int)*(unsigned char*)&one)
1767 other = lilendian_table;
1768 else
1769 other = bigendian_table;
Bob Ippolito964e02a2006-05-25 21:09:45 +00001770 /* Scan through the native table, find a matching
1771 entry in the endian table and swap in the
1772 native implementations whenever possible
1773 (64-bit platforms may not have "standard" sizes) */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001774 while (native->format != '\0' && other->format != '\0') {
1775 ptr = other;
1776 while (ptr->format != '\0') {
1777 if (ptr->format == native->format) {
Bob Ippolito964e02a2006-05-25 21:09:45 +00001778 /* Match faster when formats are
1779 listed in the same order */
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001780 if (ptr == other)
1781 other++;
Tim Petersc2b550e2006-05-31 14:28:07 +00001782 /* Only use the trick if the
Bob Ippolito964e02a2006-05-25 21:09:45 +00001783 size matches */
1784 if (ptr->size != native->size)
1785 break;
1786 /* Skip float and double, could be
1787 "unknown" float format */
1788 if (ptr->format == 'd' || ptr->format == 'f')
1789 break;
1790 ptr->pack = native->pack;
1791 ptr->unpack = native->unpack;
Bob Ippolitoa99865b2006-05-25 19:56:56 +00001792 break;
1793 }
1794 ptr++;
1795 }
1796 native++;
1797 }
1798 }
Bob Ippolito2fd39772006-05-29 22:55:48 +00001799#endif
Tim Petersc2b550e2006-05-31 14:28:07 +00001800
Bob Ippolito232f3c92006-05-23 19:12:41 +00001801 /* Add some symbolic constants to the module */
1802 if (StructError == NULL) {
1803 StructError = PyErr_NewException("struct.error", NULL, NULL);
1804 if (StructError == NULL)
1805 return;
1806 }
Bob Ippolito04ab9942006-05-25 19:33:38 +00001807
Bob Ippolito232f3c92006-05-23 19:12:41 +00001808 Py_INCREF(StructError);
1809 PyModule_AddObject(m, "error", StructError);
Bob Ippolito04ab9942006-05-25 19:33:38 +00001810
Bob Ippolito232f3c92006-05-23 19:12:41 +00001811 Py_INCREF((PyObject*)&PyStructType);
1812 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Tim Petersc2b550e2006-05-31 14:28:07 +00001813
Bob Ippolito2fd39772006-05-29 22:55:48 +00001814 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);
Bob Ippolito4182a752006-05-30 17:37:54 +00001815#ifdef PY_STRUCT_OVERFLOW_MASKING
1816 PyModule_AddIntConstant(m, "_PY_STRUCT_OVERFLOW_MASKING", 1);
Bob Ippolito2fd39772006-05-29 22:55:48 +00001817#endif
Bob Ippolito232f3c92006-05-23 19:12:41 +00001818}