blob: f66ee18bc49fd6baab418524ca998fae6ab3f901 [file] [log] [blame]
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001/* struct module -- pack values into and (out of) bytes objects */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002
3/* New version supporting byte order, alignment and size options,
4 character strings, and unsigned numbers */
5
6#define PY_SSIZE_T_CLEAN
7
8#include "Python.h"
Thomas Wouters477c8d52006-05-27 19:21:47 +00009#include "structmember.h"
10#include <ctype.h>
11
Victor Stinner3f2d1012017-02-02 12:09:30 +010012/*[clinic input]
13class Struct "PyStructObject *" "&PyStructType"
14[clinic start generated code]*/
15/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/
16
Thomas Wouters477c8d52006-05-27 19:21:47 +000017static PyTypeObject PyStructType;
18
Thomas Wouters477c8d52006-05-27 19:21:47 +000019/* The translation function for each format character is table driven */
20typedef struct _formatdef {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000021 char format;
22 Py_ssize_t size;
23 Py_ssize_t alignment;
24 PyObject* (*unpack)(const char *,
25 const struct _formatdef *);
26 int (*pack)(char *, PyObject *,
27 const struct _formatdef *);
Thomas Wouters477c8d52006-05-27 19:21:47 +000028} formatdef;
29
30typedef struct _formatcode {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000031 const struct _formatdef *fmtdef;
32 Py_ssize_t offset;
33 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +030034 Py_ssize_t repeat;
Thomas Wouters477c8d52006-05-27 19:21:47 +000035} formatcode;
36
37/* Struct object interface */
38
39typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040 PyObject_HEAD
41 Py_ssize_t s_size;
42 Py_ssize_t s_len;
43 formatcode *s_codes;
44 PyObject *s_format;
45 PyObject *weakreflist; /* List of weak references */
Thomas Wouters477c8d52006-05-27 19:21:47 +000046} PyStructObject;
47
48
49#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
Christian Heimes90aa7642007-12-19 02:45:37 +000050#define PyStruct_CheckExact(op) (Py_TYPE(op) == &PyStructType)
Thomas Wouters477c8d52006-05-27 19:21:47 +000051
52
53/* Exception */
54
55static PyObject *StructError;
56
57
58/* Define various structs to figure out the alignments of types */
59
60
61typedef struct { char c; short x; } st_short;
62typedef struct { char c; int x; } st_int;
63typedef struct { char c; long x; } st_long;
64typedef struct { char c; float x; } st_float;
65typedef struct { char c; double x; } st_double;
66typedef struct { char c; void *x; } st_void_p;
Antoine Pitrou45d9c912011-10-06 15:27:40 +020067typedef struct { char c; size_t x; } st_size_t;
Benjamin Petersona9296e72016-09-07 11:06:17 -070068typedef struct { char c; _Bool x; } st_bool;
Thomas Wouters477c8d52006-05-27 19:21:47 +000069
70#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
71#define INT_ALIGN (sizeof(st_int) - sizeof(int))
72#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
73#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
74#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
75#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
Antoine Pitrou45d9c912011-10-06 15:27:40 +020076#define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t))
Benjamin Petersona9296e72016-09-07 11:06:17 -070077#define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool))
Thomas Wouters477c8d52006-05-27 19:21:47 +000078
79/* We can't support q and Q in native mode unless the compiler does;
80 in std mode, they're 8 bytes on all platforms. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -070081typedef struct { char c; long long x; } s_long_long;
82#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long))
Thomas Wouters477c8d52006-05-27 19:21:47 +000083
Thomas Wouters477c8d52006-05-27 19:21:47 +000084#ifdef __powerc
85#pragma options align=reset
86#endif
87
Serhiy Storchakaa5a55902017-02-04 11:14:52 +020088/*[python input]
89class cache_struct_converter(CConverter):
90 type = 'PyStructObject *'
91 converter = 'cache_struct_converter'
92 c_default = "NULL"
93
94 def cleanup(self):
95 return "Py_XDECREF(%s);\n" % self.name
96[python start generated code]*/
97/*[python end generated code: output=da39a3ee5e6b4b0d input=49957cca130ffb63]*/
98
99static int cache_struct_converter(PyObject *, PyObject **);
100
Victor Stinner3f2d1012017-02-02 12:09:30 +0100101#include "clinic/_struct.c.h"
102
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000103/* Helper for integer format codes: converts an arbitrary Python object to a
104 PyLongObject if possible, otherwise fails. Caller should decref. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000105
106static PyObject *
107get_pylong(PyObject *v)
108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 assert(v != NULL);
110 if (!PyLong_Check(v)) {
111 /* Not an integer; try to use __index__ to convert. */
112 if (PyIndex_Check(v)) {
113 v = PyNumber_Index(v);
114 if (v == NULL)
115 return NULL;
116 }
117 else {
118 PyErr_SetString(StructError,
119 "required argument is not an integer");
120 return NULL;
121 }
122 }
123 else
124 Py_INCREF(v);
Mark Dickinsonea835e72009-04-19 20:40:33 +0000125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000126 assert(PyLong_Check(v));
127 return v;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000128}
129
Mark Dickinsonea835e72009-04-19 20:40:33 +0000130/* Helper routine to get a C long and raise the appropriate error if it isn't
131 one */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000132
133static int
134get_long(PyObject *v, long *p)
135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000136 long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 v = get_pylong(v);
139 if (v == NULL)
140 return -1;
141 assert(PyLong_Check(v));
142 x = PyLong_AsLong(v);
143 Py_DECREF(v);
144 if (x == (long)-1 && PyErr_Occurred()) {
145 if (PyErr_ExceptionMatches(PyExc_OverflowError))
146 PyErr_SetString(StructError,
147 "argument out of range");
148 return -1;
149 }
150 *p = x;
151 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000152}
153
154
155/* Same, but handling unsigned long */
156
157static int
158get_ulong(PyObject *v, unsigned long *p)
159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 unsigned long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 v = get_pylong(v);
163 if (v == NULL)
164 return -1;
165 assert(PyLong_Check(v));
166 x = PyLong_AsUnsignedLong(v);
167 Py_DECREF(v);
168 if (x == (unsigned long)-1 && PyErr_Occurred()) {
169 if (PyErr_ExceptionMatches(PyExc_OverflowError))
170 PyErr_SetString(StructError,
171 "argument out of range");
172 return -1;
173 }
174 *p = x;
175 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000176}
177
Thomas Wouters477c8d52006-05-27 19:21:47 +0000178/* Same, but handling native long long. */
179
180static int
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700181get_longlong(PyObject *v, long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000182{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700183 long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 v = get_pylong(v);
186 if (v == NULL)
187 return -1;
188 assert(PyLong_Check(v));
189 x = PyLong_AsLongLong(v);
190 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700191 if (x == (long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 if (PyErr_ExceptionMatches(PyExc_OverflowError))
193 PyErr_SetString(StructError,
194 "argument out of range");
195 return -1;
196 }
197 *p = x;
198 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000199}
200
201/* Same, but handling native unsigned long long. */
202
203static int
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700204get_ulonglong(PyObject *v, unsigned long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000205{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700206 unsigned long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 v = get_pylong(v);
209 if (v == NULL)
210 return -1;
211 assert(PyLong_Check(v));
212 x = PyLong_AsUnsignedLongLong(v);
213 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700214 if (x == (unsigned long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 if (PyErr_ExceptionMatches(PyExc_OverflowError))
216 PyErr_SetString(StructError,
217 "argument out of range");
218 return -1;
219 }
220 *p = x;
221 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000222}
223
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200224/* Same, but handling Py_ssize_t */
225
226static int
227get_ssize_t(PyObject *v, Py_ssize_t *p)
228{
229 Py_ssize_t x;
230
231 v = get_pylong(v);
232 if (v == NULL)
233 return -1;
234 assert(PyLong_Check(v));
235 x = PyLong_AsSsize_t(v);
236 Py_DECREF(v);
237 if (x == (Py_ssize_t)-1 && PyErr_Occurred()) {
238 if (PyErr_ExceptionMatches(PyExc_OverflowError))
239 PyErr_SetString(StructError,
240 "argument out of range");
241 return -1;
242 }
243 *p = x;
244 return 0;
245}
246
247/* Same, but handling size_t */
248
249static int
250get_size_t(PyObject *v, size_t *p)
251{
252 size_t x;
253
254 v = get_pylong(v);
255 if (v == NULL)
256 return -1;
257 assert(PyLong_Check(v));
258 x = PyLong_AsSize_t(v);
259 Py_DECREF(v);
260 if (x == (size_t)-1 && PyErr_Occurred()) {
261 if (PyErr_ExceptionMatches(PyExc_OverflowError))
262 PyErr_SetString(StructError,
263 "argument out of range");
264 return -1;
265 }
266 *p = x;
267 return 0;
268}
269
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000270
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000271#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
272
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000273
Thomas Wouters477c8d52006-05-27 19:21:47 +0000274/* Floating point helpers */
275
276static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100277unpack_halffloat(const char *p, /* start of 2-byte string */
278 int le) /* true for little-endian, false for big-endian */
279{
280 double x;
281
282 x = _PyFloat_Unpack2((unsigned char *)p, le);
283 if (x == -1.0 && PyErr_Occurred()) {
284 return NULL;
285 }
286 return PyFloat_FromDouble(x);
287}
288
289static int
290pack_halffloat(char *p, /* start of 2-byte string */
291 PyObject *v, /* value to pack */
292 int le) /* true for little-endian, false for big-endian */
293{
294 double x = PyFloat_AsDouble(v);
295 if (x == -1.0 && PyErr_Occurred()) {
296 PyErr_SetString(StructError,
297 "required argument is not a float");
298 return -1;
299 }
300 return _PyFloat_Pack2(x, (unsigned char *)p, le);
301}
302
303static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000304unpack_float(const char *p, /* start of 4-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000306{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 x = _PyFloat_Unpack4((unsigned char *)p, le);
310 if (x == -1.0 && PyErr_Occurred())
311 return NULL;
312 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000313}
314
315static PyObject *
316unpack_double(const char *p, /* start of 8-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 x = _PyFloat_Unpack8((unsigned char *)p, le);
322 if (x == -1.0 && PyErr_Occurred())
323 return NULL;
324 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325}
326
327/* Helper to format the range error exceptions */
328static int
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000329_range_error(const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 /* ulargest is the largest unsigned value with f->size bytes.
332 * Note that the simpler:
333 * ((size_t)1 << (f->size * 8)) - 1
334 * doesn't work when f->size == sizeof(size_t) because C doesn't
335 * define what happens when a left shift count is >= the number of
336 * bits in the integer being shifted; e.g., on some boxes it doesn't
337 * shift at all when they're equal.
338 */
339 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
340 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
341 if (is_unsigned)
342 PyErr_Format(StructError,
343 "'%c' format requires 0 <= number <= %zu",
344 f->format,
345 ulargest);
346 else {
347 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
348 PyErr_Format(StructError,
349 "'%c' format requires %zd <= number <= %zd",
350 f->format,
351 ~ largest,
352 largest);
353 }
Mark Dickinsonae681df2009-03-21 10:26:31 +0000354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000356}
357
358
359
360/* A large number of small routines follow, with names of the form
361
362 [bln][up]_TYPE
363
364 [bln] distiguishes among big-endian, little-endian and native.
365 [pu] distiguishes between pack (to struct) and unpack (from struct).
366 TYPE is one of char, byte, ubyte, etc.
367*/
368
369/* Native mode routines. ****************************************************/
370/* NOTE:
371 In all n[up]_<type> routines handling types larger than 1 byte, there is
372 *no* guarantee that the p pointer is properly aligned for each type,
373 therefore memcpy is called. An intermediate variable is used to
374 compensate for big-endian architectures.
375 Normally both the intermediate variable and the memcpy call will be
376 skipped by C optimisation in little-endian architectures (gcc >= 2.91
377 does this). */
378
379static PyObject *
380nu_char(const char *p, const formatdef *f)
381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 return PyBytes_FromStringAndSize(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000383}
384
385static PyObject *
386nu_byte(const char *p, const formatdef *f)
387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 return PyLong_FromLong((long) *(signed char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000389}
390
391static PyObject *
392nu_ubyte(const char *p, const formatdef *f)
393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 return PyLong_FromLong((long) *(unsigned char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000395}
396
397static PyObject *
398nu_short(const char *p, const formatdef *f)
399{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 short x;
401 memcpy((char *)&x, p, sizeof x);
402 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000403}
404
405static PyObject *
406nu_ushort(const char *p, const formatdef *f)
407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 unsigned short x;
409 memcpy((char *)&x, p, sizeof x);
410 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000411}
412
413static PyObject *
414nu_int(const char *p, const formatdef *f)
415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 int x;
417 memcpy((char *)&x, p, sizeof x);
418 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000419}
420
421static PyObject *
422nu_uint(const char *p, const formatdef *f)
423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 unsigned int x;
425 memcpy((char *)&x, p, sizeof x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000426#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000428#else
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 if (x <= ((unsigned int)LONG_MAX))
430 return PyLong_FromLong((long)x);
431 return PyLong_FromUnsignedLong((unsigned long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000432#endif
433}
434
435static PyObject *
436nu_long(const char *p, const formatdef *f)
437{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 long x;
439 memcpy((char *)&x, p, sizeof x);
440 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000441}
442
443static PyObject *
444nu_ulong(const char *p, const formatdef *f)
445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 unsigned long x;
447 memcpy((char *)&x, p, sizeof x);
448 if (x <= LONG_MAX)
449 return PyLong_FromLong((long)x);
450 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000451}
452
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200453static PyObject *
454nu_ssize_t(const char *p, const formatdef *f)
455{
456 Py_ssize_t x;
457 memcpy((char *)&x, p, sizeof x);
458 return PyLong_FromSsize_t(x);
459}
460
461static PyObject *
462nu_size_t(const char *p, const formatdef *f)
463{
464 size_t x;
465 memcpy((char *)&x, p, sizeof x);
466 return PyLong_FromSize_t(x);
467}
468
469
Thomas Wouters477c8d52006-05-27 19:21:47 +0000470/* Native mode doesn't support q or Q unless the platform C supports
471 long long (or, on Windows, __int64). */
472
Thomas Wouters477c8d52006-05-27 19:21:47 +0000473static PyObject *
474nu_longlong(const char *p, const formatdef *f)
475{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700476 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 memcpy((char *)&x, p, sizeof x);
478 if (x >= LONG_MIN && x <= LONG_MAX)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700479 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, long long, long));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000481}
482
483static PyObject *
484nu_ulonglong(const char *p, const formatdef *f)
485{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700486 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 memcpy((char *)&x, p, sizeof x);
488 if (x <= LONG_MAX)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700489 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned long long, long));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000491}
492
Thomas Wouters477c8d52006-05-27 19:21:47 +0000493static PyObject *
Thomas Woutersb2137042007-02-01 18:02:27 +0000494nu_bool(const char *p, const formatdef *f)
495{
Benjamin Petersona9296e72016-09-07 11:06:17 -0700496 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 memcpy((char *)&x, p, sizeof x);
498 return PyBool_FromLong(x != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000499}
500
501
502static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100503nu_halffloat(const char *p, const formatdef *f)
504{
505#if PY_LITTLE_ENDIAN
506 return unpack_halffloat(p, 1);
507#else
508 return unpack_halffloat(p, 0);
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700509#endif
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100510}
511
512static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000513nu_float(const char *p, const formatdef *f)
514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 float x;
516 memcpy((char *)&x, p, sizeof x);
517 return PyFloat_FromDouble((double)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000518}
519
520static PyObject *
521nu_double(const char *p, const formatdef *f)
522{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 double x;
524 memcpy((char *)&x, p, sizeof x);
525 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000526}
527
528static PyObject *
529nu_void_p(const char *p, const formatdef *f)
530{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 void *x;
532 memcpy((char *)&x, p, sizeof x);
533 return PyLong_FromVoidPtr(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000534}
535
536static int
537np_byte(char *p, PyObject *v, const formatdef *f)
538{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 long x;
540 if (get_long(v, &x) < 0)
541 return -1;
542 if (x < -128 || x > 127){
543 PyErr_SetString(StructError,
544 "byte format requires -128 <= number <= 127");
545 return -1;
546 }
547 *p = (char)x;
548 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000549}
550
551static int
552np_ubyte(char *p, PyObject *v, const formatdef *f)
553{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 long x;
555 if (get_long(v, &x) < 0)
556 return -1;
557 if (x < 0 || x > 255){
558 PyErr_SetString(StructError,
559 "ubyte format requires 0 <= number <= 255");
560 return -1;
561 }
562 *p = (char)x;
563 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000564}
565
566static int
567np_char(char *p, PyObject *v, const formatdef *f)
568{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
570 PyErr_SetString(StructError,
Victor Stinnerda9ec992010-12-28 13:26:42 +0000571 "char format requires a bytes object of length 1");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000572 return -1;
573 }
574 *p = *PyBytes_AsString(v);
575 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000576}
577
578static int
579np_short(char *p, PyObject *v, const formatdef *f)
580{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 long x;
582 short y;
583 if (get_long(v, &x) < 0)
584 return -1;
585 if (x < SHRT_MIN || x > SHRT_MAX){
586 PyErr_SetString(StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200587 "short format requires " Py_STRINGIFY(SHRT_MIN)
588 " <= number <= " Py_STRINGIFY(SHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 return -1;
590 }
591 y = (short)x;
592 memcpy(p, (char *)&y, sizeof y);
593 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000594}
595
596static int
597np_ushort(char *p, PyObject *v, const formatdef *f)
598{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 long x;
600 unsigned short y;
601 if (get_long(v, &x) < 0)
602 return -1;
603 if (x < 0 || x > USHRT_MAX){
604 PyErr_SetString(StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200605 "ushort format requires 0 <= number <= "
606 Py_STRINGIFY(USHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 return -1;
608 }
609 y = (unsigned short)x;
610 memcpy(p, (char *)&y, sizeof y);
611 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000612}
613
614static int
615np_int(char *p, PyObject *v, const formatdef *f)
616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 long x;
618 int y;
619 if (get_long(v, &x) < 0)
620 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000621#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
623 RANGE_ERROR(x, f, 0, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000624#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 y = (int)x;
626 memcpy(p, (char *)&y, sizeof y);
627 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000628}
629
630static int
631np_uint(char *p, PyObject *v, const formatdef *f)
632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 unsigned long x;
634 unsigned int y;
635 if (get_ulong(v, &x) < 0)
636 return -1;
637 y = (unsigned int)x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000638#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 if (x > ((unsigned long)UINT_MAX))
640 RANGE_ERROR(y, f, 1, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000641#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 memcpy(p, (char *)&y, sizeof y);
643 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000644}
645
646static int
647np_long(char *p, PyObject *v, const formatdef *f)
648{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000649 long x;
650 if (get_long(v, &x) < 0)
651 return -1;
652 memcpy(p, (char *)&x, sizeof x);
653 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000654}
655
656static int
657np_ulong(char *p, PyObject *v, const formatdef *f)
658{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000659 unsigned long x;
660 if (get_ulong(v, &x) < 0)
661 return -1;
662 memcpy(p, (char *)&x, sizeof x);
663 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000664}
665
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200666static int
667np_ssize_t(char *p, PyObject *v, const formatdef *f)
668{
669 Py_ssize_t x;
670 if (get_ssize_t(v, &x) < 0)
671 return -1;
672 memcpy(p, (char *)&x, sizeof x);
673 return 0;
674}
675
676static int
677np_size_t(char *p, PyObject *v, const formatdef *f)
678{
679 size_t x;
680 if (get_size_t(v, &x) < 0)
681 return -1;
682 memcpy(p, (char *)&x, sizeof x);
683 return 0;
684}
685
Thomas Wouters477c8d52006-05-27 19:21:47 +0000686static int
687np_longlong(char *p, PyObject *v, const formatdef *f)
688{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700689 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000690 if (get_longlong(v, &x) < 0)
691 return -1;
692 memcpy(p, (char *)&x, sizeof x);
693 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000694}
695
696static int
697np_ulonglong(char *p, PyObject *v, const formatdef *f)
698{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700699 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 if (get_ulonglong(v, &x) < 0)
701 return -1;
702 memcpy(p, (char *)&x, sizeof x);
703 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000704}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000705
Thomas Woutersb2137042007-02-01 18:02:27 +0000706
707static int
708np_bool(char *p, PyObject *v, const formatdef *f)
709{
Benjamin Petersonde73c452010-07-07 18:54:59 +0000710 int y;
Benjamin Petersona9296e72016-09-07 11:06:17 -0700711 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000713 if (y < 0)
714 return -1;
715 x = y;
716 memcpy(p, (char *)&x, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000718}
719
Thomas Wouters477c8d52006-05-27 19:21:47 +0000720static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100721np_halffloat(char *p, PyObject *v, const formatdef *f)
722{
723#if PY_LITTLE_ENDIAN
724 return pack_halffloat(p, v, 1);
725#else
726 return pack_halffloat(p, v, 0);
727#endif
728}
729
730static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000731np_float(char *p, PyObject *v, const formatdef *f)
732{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 float x = (float)PyFloat_AsDouble(v);
734 if (x == -1 && PyErr_Occurred()) {
735 PyErr_SetString(StructError,
736 "required argument is not a float");
737 return -1;
738 }
739 memcpy(p, (char *)&x, sizeof x);
740 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000741}
742
743static int
744np_double(char *p, PyObject *v, const formatdef *f)
745{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 double x = PyFloat_AsDouble(v);
747 if (x == -1 && PyErr_Occurred()) {
748 PyErr_SetString(StructError,
749 "required argument is not a float");
750 return -1;
751 }
752 memcpy(p, (char *)&x, sizeof(double));
753 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000754}
755
756static int
757np_void_p(char *p, PyObject *v, const formatdef *f)
758{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 void *x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000760
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 v = get_pylong(v);
762 if (v == NULL)
763 return -1;
764 assert(PyLong_Check(v));
765 x = PyLong_AsVoidPtr(v);
766 Py_DECREF(v);
767 if (x == NULL && PyErr_Occurred())
768 return -1;
769 memcpy(p, (char *)&x, sizeof x);
770 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000771}
772
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200773static const formatdef native_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000774 {'x', sizeof(char), 0, NULL},
775 {'b', sizeof(char), 0, nu_byte, np_byte},
776 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
777 {'c', sizeof(char), 0, nu_char, np_char},
778 {'s', sizeof(char), 0, NULL},
779 {'p', sizeof(char), 0, NULL},
780 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
781 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
782 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
783 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
784 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
785 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200786 {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t},
787 {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t},
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700788 {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong},
789 {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Benjamin Petersona9296e72016-09-07 11:06:17 -0700790 {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100791 {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
793 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
794 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
795 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000796};
797
798/* Big-endian routines. *****************************************************/
799
800static PyObject *
801bu_int(const char *p, const formatdef *f)
802{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000803 long x = 0;
804 Py_ssize_t i = f->size;
805 const unsigned char *bytes = (const unsigned char *)p;
806 do {
807 x = (x<<8) | *bytes++;
808 } while (--i > 0);
809 /* Extend the sign bit. */
810 if (SIZEOF_LONG > f->size)
811 x |= -(x & (1L << ((8 * f->size) - 1)));
812 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000813}
814
815static PyObject *
816bu_uint(const char *p, const formatdef *f)
817{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000818 unsigned long x = 0;
819 Py_ssize_t i = f->size;
820 const unsigned char *bytes = (const unsigned char *)p;
821 do {
822 x = (x<<8) | *bytes++;
823 } while (--i > 0);
824 if (x <= LONG_MAX)
825 return PyLong_FromLong((long)x);
826 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000827}
828
829static PyObject *
830bu_longlong(const char *p, const formatdef *f)
831{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700832 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000833 Py_ssize_t i = f->size;
834 const unsigned char *bytes = (const unsigned char *)p;
835 do {
836 x = (x<<8) | *bytes++;
837 } while (--i > 0);
838 /* Extend the sign bit. */
839 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700840 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 if (x >= LONG_MIN && x <= LONG_MAX)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700842 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, long long, long));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000843 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000844}
845
846static PyObject *
847bu_ulonglong(const char *p, const formatdef *f)
848{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700849 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850 Py_ssize_t i = f->size;
851 const unsigned char *bytes = (const unsigned char *)p;
852 do {
853 x = (x<<8) | *bytes++;
854 } while (--i > 0);
855 if (x <= LONG_MAX)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700856 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned long long, long));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000858}
859
860static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100861bu_halffloat(const char *p, const formatdef *f)
862{
863 return unpack_halffloat(p, 0);
864}
865
866static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000867bu_float(const char *p, const formatdef *f)
868{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000869 return unpack_float(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000870}
871
872static PyObject *
873bu_double(const char *p, const formatdef *f)
874{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000875 return unpack_double(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000876}
877
Thomas Woutersb2137042007-02-01 18:02:27 +0000878static PyObject *
879bu_bool(const char *p, const formatdef *f)
880{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000881 char x;
882 memcpy((char *)&x, p, sizeof x);
883 return PyBool_FromLong(x != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000884}
885
Thomas Wouters477c8d52006-05-27 19:21:47 +0000886static int
887bp_int(char *p, PyObject *v, const formatdef *f)
888{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 long x;
890 Py_ssize_t i;
891 if (get_long(v, &x) < 0)
892 return -1;
893 i = f->size;
894 if (i != SIZEOF_LONG) {
895 if ((i == 2) && (x < -32768 || x > 32767))
896 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000897#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000898 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
899 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000900#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 }
902 do {
903 p[--i] = (char)x;
904 x >>= 8;
905 } while (i > 0);
906 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000907}
908
909static int
910bp_uint(char *p, PyObject *v, const formatdef *f)
911{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000912 unsigned long x;
913 Py_ssize_t i;
914 if (get_ulong(v, &x) < 0)
915 return -1;
916 i = f->size;
917 if (i != SIZEOF_LONG) {
918 unsigned long maxint = 1;
919 maxint <<= (unsigned long)(i * 8);
920 if (x >= maxint)
921 RANGE_ERROR(x, f, 1, maxint - 1);
922 }
923 do {
924 p[--i] = (char)x;
925 x >>= 8;
926 } while (i > 0);
927 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000928}
929
930static int
931bp_longlong(char *p, PyObject *v, const formatdef *f)
932{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 int res;
934 v = get_pylong(v);
935 if (v == NULL)
936 return -1;
937 res = _PyLong_AsByteArray((PyLongObject *)v,
938 (unsigned char *)p,
939 8,
940 0, /* little_endian */
941 1 /* signed */);
942 Py_DECREF(v);
943 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000944}
945
946static int
947bp_ulonglong(char *p, PyObject *v, const formatdef *f)
948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 int res;
950 v = get_pylong(v);
951 if (v == NULL)
952 return -1;
953 res = _PyLong_AsByteArray((PyLongObject *)v,
954 (unsigned char *)p,
955 8,
956 0, /* little_endian */
957 0 /* signed */);
958 Py_DECREF(v);
959 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000960}
961
962static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100963bp_halffloat(char *p, PyObject *v, const formatdef *f)
964{
965 return pack_halffloat(p, v, 0);
966}
967
968static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000969bp_float(char *p, PyObject *v, const formatdef *f)
970{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 double x = PyFloat_AsDouble(v);
972 if (x == -1 && PyErr_Occurred()) {
973 PyErr_SetString(StructError,
974 "required argument is not a float");
975 return -1;
976 }
977 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000978}
979
980static int
981bp_double(char *p, PyObject *v, const formatdef *f)
982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 double x = PyFloat_AsDouble(v);
984 if (x == -1 && PyErr_Occurred()) {
985 PyErr_SetString(StructError,
986 "required argument is not a float");
987 return -1;
988 }
989 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000990}
991
Thomas Woutersb2137042007-02-01 18:02:27 +0000992static int
993bp_bool(char *p, PyObject *v, const formatdef *f)
994{
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000995 int y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000996 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000997 if (y < 0)
998 return -1;
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000999 *p = (char)y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +00001001}
1002
Thomas Wouters477c8d52006-05-27 19:21:47 +00001003static formatdef bigendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 {'x', 1, 0, NULL},
1005 {'b', 1, 0, nu_byte, np_byte},
1006 {'B', 1, 0, nu_ubyte, np_ubyte},
1007 {'c', 1, 0, nu_char, np_char},
1008 {'s', 1, 0, NULL},
1009 {'p', 1, 0, NULL},
1010 {'h', 2, 0, bu_int, bp_int},
1011 {'H', 2, 0, bu_uint, bp_uint},
1012 {'i', 4, 0, bu_int, bp_int},
1013 {'I', 4, 0, bu_uint, bp_uint},
1014 {'l', 4, 0, bu_int, bp_int},
1015 {'L', 4, 0, bu_uint, bp_uint},
1016 {'q', 8, 0, bu_longlong, bp_longlong},
1017 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
1018 {'?', 1, 0, bu_bool, bp_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001019 {'e', 2, 0, bu_halffloat, bp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 {'f', 4, 0, bu_float, bp_float},
1021 {'d', 8, 0, bu_double, bp_double},
1022 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001023};
1024
1025/* Little-endian routines. *****************************************************/
1026
1027static PyObject *
1028lu_int(const char *p, const formatdef *f)
1029{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 long x = 0;
1031 Py_ssize_t i = f->size;
1032 const unsigned char *bytes = (const unsigned char *)p;
1033 do {
1034 x = (x<<8) | bytes[--i];
1035 } while (i > 0);
1036 /* Extend the sign bit. */
1037 if (SIZEOF_LONG > f->size)
1038 x |= -(x & (1L << ((8 * f->size) - 1)));
1039 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001040}
1041
1042static PyObject *
1043lu_uint(const char *p, const formatdef *f)
1044{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 unsigned long x = 0;
1046 Py_ssize_t i = f->size;
1047 const unsigned char *bytes = (const unsigned char *)p;
1048 do {
1049 x = (x<<8) | bytes[--i];
1050 } while (i > 0);
1051 if (x <= LONG_MAX)
1052 return PyLong_FromLong((long)x);
1053 return PyLong_FromUnsignedLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001054}
1055
1056static PyObject *
1057lu_longlong(const char *p, const formatdef *f)
1058{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001059 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 Py_ssize_t i = f->size;
1061 const unsigned char *bytes = (const unsigned char *)p;
1062 do {
1063 x = (x<<8) | bytes[--i];
1064 } while (i > 0);
1065 /* Extend the sign bit. */
1066 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001067 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 if (x >= LONG_MIN && x <= LONG_MAX)
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001069 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, long long, long));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001071}
1072
1073static PyObject *
1074lu_ulonglong(const char *p, const formatdef *f)
1075{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001076 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 Py_ssize_t i = f->size;
1078 const unsigned char *bytes = (const unsigned char *)p;
1079 do {
1080 x = (x<<8) | bytes[--i];
1081 } while (i > 0);
1082 if (x <= LONG_MAX)
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001083 return PyLong_FromLong(Py_SAFE_DOWNCAST(x, unsigned long long, long));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001084 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001085}
1086
1087static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001088lu_halffloat(const char *p, const formatdef *f)
1089{
1090 return unpack_halffloat(p, 1);
1091}
1092
1093static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001094lu_float(const char *p, const formatdef *f)
1095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 return unpack_float(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001097}
1098
1099static PyObject *
1100lu_double(const char *p, const formatdef *f)
1101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 return unpack_double(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001103}
1104
1105static int
1106lp_int(char *p, PyObject *v, const formatdef *f)
1107{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 long x;
1109 Py_ssize_t i;
1110 if (get_long(v, &x) < 0)
1111 return -1;
1112 i = f->size;
1113 if (i != SIZEOF_LONG) {
1114 if ((i == 2) && (x < -32768 || x > 32767))
1115 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001116#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
1118 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001119#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 }
1121 do {
1122 *p++ = (char)x;
1123 x >>= 8;
1124 } while (--i > 0);
1125 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001126}
1127
1128static int
1129lp_uint(char *p, PyObject *v, const formatdef *f)
1130{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 unsigned long x;
1132 Py_ssize_t i;
1133 if (get_ulong(v, &x) < 0)
1134 return -1;
1135 i = f->size;
1136 if (i != SIZEOF_LONG) {
1137 unsigned long maxint = 1;
1138 maxint <<= (unsigned long)(i * 8);
1139 if (x >= maxint)
1140 RANGE_ERROR(x, f, 1, maxint - 1);
1141 }
1142 do {
1143 *p++ = (char)x;
1144 x >>= 8;
1145 } while (--i > 0);
1146 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001147}
1148
1149static int
1150lp_longlong(char *p, PyObject *v, const formatdef *f)
1151{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 int res;
1153 v = get_pylong(v);
1154 if (v == NULL)
1155 return -1;
1156 res = _PyLong_AsByteArray((PyLongObject*)v,
1157 (unsigned char *)p,
1158 8,
1159 1, /* little_endian */
1160 1 /* signed */);
1161 Py_DECREF(v);
1162 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001163}
1164
1165static int
1166lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1167{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 int res;
1169 v = get_pylong(v);
1170 if (v == NULL)
1171 return -1;
1172 res = _PyLong_AsByteArray((PyLongObject*)v,
1173 (unsigned char *)p,
1174 8,
1175 1, /* little_endian */
1176 0 /* signed */);
1177 Py_DECREF(v);
1178 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001179}
1180
1181static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001182lp_halffloat(char *p, PyObject *v, const formatdef *f)
1183{
1184 return pack_halffloat(p, v, 1);
1185}
1186
1187static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001188lp_float(char *p, PyObject *v, const formatdef *f)
1189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 double x = PyFloat_AsDouble(v);
1191 if (x == -1 && PyErr_Occurred()) {
1192 PyErr_SetString(StructError,
1193 "required argument is not a float");
1194 return -1;
1195 }
1196 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001197}
1198
1199static int
1200lp_double(char *p, PyObject *v, const formatdef *f)
1201{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 double x = PyFloat_AsDouble(v);
1203 if (x == -1 && PyErr_Occurred()) {
1204 PyErr_SetString(StructError,
1205 "required argument is not a float");
1206 return -1;
1207 }
1208 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001209}
1210
1211static formatdef lilendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 {'x', 1, 0, NULL},
1213 {'b', 1, 0, nu_byte, np_byte},
1214 {'B', 1, 0, nu_ubyte, np_ubyte},
1215 {'c', 1, 0, nu_char, np_char},
1216 {'s', 1, 0, NULL},
1217 {'p', 1, 0, NULL},
1218 {'h', 2, 0, lu_int, lp_int},
1219 {'H', 2, 0, lu_uint, lp_uint},
1220 {'i', 4, 0, lu_int, lp_int},
1221 {'I', 4, 0, lu_uint, lp_uint},
1222 {'l', 4, 0, lu_int, lp_int},
1223 {'L', 4, 0, lu_uint, lp_uint},
1224 {'q', 8, 0, lu_longlong, lp_longlong},
1225 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1226 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1227 but potentially different from native rep -- reuse bx_bool funcs. */
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001228 {'e', 2, 0, lu_halffloat, lp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 {'f', 4, 0, lu_float, lp_float},
1230 {'d', 8, 0, lu_double, lp_double},
1231 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001232};
1233
1234
1235static const formatdef *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001236whichtable(const char **pfmt)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001237{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 const char *fmt = (*pfmt)++; /* May be backed out of later */
1239 switch (*fmt) {
1240 case '<':
1241 return lilendian_table;
1242 case '>':
1243 case '!': /* Network byte order is big-endian */
1244 return bigendian_table;
Ezio Melotti42da6632011-03-15 05:18:48 +02001245 case '=': { /* Host byte order -- different from native in alignment! */
Christian Heimes743e0cd2012-10-17 23:52:17 +02001246#if PY_LITTLE_ENDIAN
1247 return lilendian_table;
1248#else
1249 return bigendian_table;
1250#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 }
1252 default:
1253 --*pfmt; /* Back out of pointer increment */
1254 /* Fall through */
1255 case '@':
1256 return native_table;
1257 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001258}
1259
1260
1261/* Get the table entry for a format code */
1262
1263static const formatdef *
1264getentry(int c, const formatdef *f)
1265{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 for (; f->format != '\0'; f++) {
1267 if (f->format == c) {
1268 return f;
1269 }
1270 }
1271 PyErr_SetString(StructError, "bad char in struct format");
1272 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001273}
1274
1275
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001276/* Align a size according to a format code. Return -1 on overflow. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001277
Mark Dickinsoneac0e682010-06-11 19:05:08 +00001278static Py_ssize_t
Thomas Wouters477c8d52006-05-27 19:21:47 +00001279align(Py_ssize_t size, char c, const formatdef *e)
1280{
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001281 Py_ssize_t extra;
1282
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001283 if (e->format == c) {
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001284 if (e->alignment && size > 0) {
1285 extra = (e->alignment - 1) - (size - 1) % (e->alignment);
1286 if (extra > PY_SSIZE_T_MAX - size)
1287 return -1;
1288 size += extra;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 }
1290 }
1291 return size;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001292}
1293
Antoine Pitrou9f146812013-04-27 00:20:04 +02001294/*
1295 * Struct object implementation.
1296 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001297
1298/* calculate the size of a format string */
1299
1300static int
1301prepare_s(PyStructObject *self)
1302{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 const formatdef *f;
1304 const formatdef *e;
1305 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 const char *s;
1308 const char *fmt;
1309 char c;
Victor Stinner706768c2014-08-16 01:03:39 +02001310 Py_ssize_t size, len, num, itemsize;
1311 size_t ncodes;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 fmt = PyBytes_AS_STRING(self->s_format);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001314
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001315 f = whichtable(&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 s = fmt;
1318 size = 0;
1319 len = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001320 ncodes = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 while ((c = *s++) != '\0') {
Antoine Pitrou4de74572013-02-09 23:11:27 +01001322 if (Py_ISSPACE(Py_CHARMASK(c)))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 continue;
1324 if ('0' <= c && c <= '9') {
1325 num = c - '0';
1326 while ('0' <= (c = *s++) && c <= '9') {
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001327 /* overflow-safe version of
1328 if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1329 if (num >= PY_SSIZE_T_MAX / 10 && (
1330 num > PY_SSIZE_T_MAX / 10 ||
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001331 (c - '0') > PY_SSIZE_T_MAX % 10))
1332 goto overflow;
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001333 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 }
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001335 if (c == '\0') {
1336 PyErr_SetString(StructError,
1337 "repeat count given without format specifier");
1338 return -1;
1339 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 }
1341 else
1342 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 e = getentry(c, f);
1345 if (e == NULL)
1346 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 switch (c) {
1349 case 's': /* fall through */
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001350 case 'p': len++; ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 case 'x': break;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001352 default: len += num; if (num) ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 itemsize = e->size;
1356 size = align(size, c, e);
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001357 if (size == -1)
1358 goto overflow;
1359
1360 /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1361 if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1362 goto overflow;
1363 size += num * itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 /* check for overflow */
Victor Stinner706768c2014-08-16 01:03:39 +02001367 if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 PyErr_NoMemory();
1369 return -1;
1370 }
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +00001371
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 self->s_size = size;
1373 self->s_len = len;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001374 codes = PyMem_MALLOC((ncodes + 1) * sizeof(formatcode));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 if (codes == NULL) {
1376 PyErr_NoMemory();
1377 return -1;
1378 }
Mark Dickinsoncf28b952010-07-29 21:41:59 +00001379 /* Free any s_codes value left over from a previous initialization. */
1380 if (self->s_codes != NULL)
1381 PyMem_FREE(self->s_codes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 s = fmt;
1385 size = 0;
1386 while ((c = *s++) != '\0') {
Antoine Pitrou4de74572013-02-09 23:11:27 +01001387 if (Py_ISSPACE(Py_CHARMASK(c)))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001388 continue;
1389 if ('0' <= c && c <= '9') {
1390 num = c - '0';
1391 while ('0' <= (c = *s++) && c <= '9')
1392 num = num*10 + (c - '0');
1393 if (c == '\0')
1394 break;
1395 }
1396 else
1397 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001398
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 size = align(size, c, e);
1402 if (c == 's' || c == 'p') {
1403 codes->offset = size;
1404 codes->size = num;
1405 codes->fmtdef = e;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001406 codes->repeat = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 codes++;
1408 size += num;
1409 } else if (c == 'x') {
1410 size += num;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001411 } else if (num) {
1412 codes->offset = size;
1413 codes->size = e->size;
1414 codes->fmtdef = e;
1415 codes->repeat = num;
1416 codes++;
1417 size += e->size * num;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 }
1419 }
1420 codes->fmtdef = NULL;
1421 codes->offset = size;
1422 codes->size = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001423 codes->repeat = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 return 0;
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001426
1427 overflow:
1428 PyErr_SetString(StructError,
1429 "total struct size too long");
1430 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001431}
1432
1433static PyObject *
1434s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1435{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 PyObject *self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001437
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001438 assert(type != NULL && type->tp_alloc != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001439
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001440 self = type->tp_alloc(type, 0);
1441 if (self != NULL) {
1442 PyStructObject *s = (PyStructObject*)self;
1443 Py_INCREF(Py_None);
1444 s->s_format = Py_None;
1445 s->s_codes = NULL;
1446 s->s_size = -1;
1447 s->s_len = -1;
1448 }
1449 return self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001450}
1451
Victor Stinner3f2d1012017-02-02 12:09:30 +01001452/*[clinic input]
1453Struct.__init__
1454
1455 format: object
1456
1457Create a compiled struct object.
1458
1459Return a new Struct object which writes and reads binary data according to
1460the format string.
1461
1462See help(struct) for more on format strings.
1463[clinic start generated code]*/
1464
Thomas Wouters477c8d52006-05-27 19:21:47 +00001465static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001466Struct___init___impl(PyStructObject *self, PyObject *format)
1467/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001468{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 int ret = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001470
Victor Stinner3f2d1012017-02-02 12:09:30 +01001471 if (PyUnicode_Check(format)) {
1472 format = PyUnicode_AsASCIIString(format);
1473 if (format == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 return -1;
1475 }
1476 /* XXX support buffer interface, too */
1477 else {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001478 Py_INCREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001480
Victor Stinner3f2d1012017-02-02 12:09:30 +01001481 if (!PyBytes_Check(format)) {
1482 Py_DECREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 PyErr_Format(PyExc_TypeError,
Victor Stinnerda9ec992010-12-28 13:26:42 +00001484 "Struct() argument 1 must be a bytes object, not %.200s",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001485 Py_TYPE(format)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 return -1;
1487 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001488
Victor Stinner3f2d1012017-02-02 12:09:30 +01001489 Py_XSETREF(self->s_format, format);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001490
Victor Stinner3f2d1012017-02-02 12:09:30 +01001491 ret = prepare_s(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 return ret;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001493}
1494
1495static void
1496s_dealloc(PyStructObject *s)
1497{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 if (s->weakreflist != NULL)
1499 PyObject_ClearWeakRefs((PyObject *)s);
1500 if (s->s_codes != NULL) {
1501 PyMem_FREE(s->s_codes);
1502 }
1503 Py_XDECREF(s->s_format);
1504 Py_TYPE(s)->tp_free((PyObject *)s);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001505}
1506
1507static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001508s_unpack_internal(PyStructObject *soself, const char *startfrom) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 formatcode *code;
1510 Py_ssize_t i = 0;
1511 PyObject *result = PyTuple_New(soself->s_len);
1512 if (result == NULL)
1513 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 const formatdef *e = code->fmtdef;
1517 const char *res = startfrom + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001518 Py_ssize_t j = code->repeat;
1519 while (j--) {
1520 PyObject *v;
1521 if (e->format == 's') {
1522 v = PyBytes_FromStringAndSize(res, code->size);
1523 } else if (e->format == 'p') {
1524 Py_ssize_t n = *(unsigned char*)res;
1525 if (n >= code->size)
1526 n = code->size - 1;
1527 v = PyBytes_FromStringAndSize(res + 1, n);
1528 } else {
1529 v = e->unpack(res, e);
1530 }
1531 if (v == NULL)
1532 goto fail;
1533 PyTuple_SET_ITEM(result, i++, v);
1534 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001536 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001537
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001539fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 Py_DECREF(result);
1541 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001542}
1543
1544
Victor Stinner3f2d1012017-02-02 12:09:30 +01001545/*[clinic input]
1546Struct.unpack
1547
1548 buffer: Py_buffer
1549 /
1550
1551Return a tuple containing unpacked values.
1552
1553Unpack according to the format string Struct.format. The buffer's size
1554in bytes must be Struct.size.
1555
1556See help(struct) for more on format strings.
1557[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001558
1559static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001560Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1561/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001562{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001563 assert(self->s_codes != NULL);
1564 if (buffer->len != self->s_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 PyErr_Format(StructError,
Victor Stinnerda9ec992010-12-28 13:26:42 +00001566 "unpack requires a bytes object of length %zd",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001567 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 return NULL;
1569 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001570 return s_unpack_internal(self, buffer->buf);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001571}
1572
Victor Stinner3f2d1012017-02-02 12:09:30 +01001573/*[clinic input]
1574Struct.unpack_from
1575
1576 buffer: Py_buffer
1577 offset: Py_ssize_t = 0
1578
1579Return a tuple containing unpacked values.
1580
1581Values are unpacked according to the format string Struct.format.
1582
1583The buffer's size in bytes, minus offset, must be at least Struct.size.
1584
1585See help(struct) for more on format strings.
1586[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001587
1588static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001589Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1590 Py_ssize_t offset)
1591/*[clinic end generated code: output=57fac875e0977316 input=97ade52422f8962f]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001592{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001593 assert(self->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001594
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001595 if (offset < 0)
Victor Stinner3f2d1012017-02-02 12:09:30 +01001596 offset += buffer->len;
1597 if (offset < 0 || buffer->len - offset < self->s_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001598 PyErr_Format(StructError,
1599 "unpack_from requires a buffer of at least %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001600 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 return NULL;
1602 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001603 return s_unpack_internal(self, (char*)buffer->buf + offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001604}
1605
1606
Victor Stinner3f2d1012017-02-02 12:09:30 +01001607
Antoine Pitrou9f146812013-04-27 00:20:04 +02001608/* Unpack iterator type */
1609
1610typedef struct {
1611 PyObject_HEAD
1612 PyStructObject *so;
1613 Py_buffer buf;
1614 Py_ssize_t index;
1615} unpackiterobject;
1616
1617static void
1618unpackiter_dealloc(unpackiterobject *self)
1619{
1620 Py_XDECREF(self->so);
1621 PyBuffer_Release(&self->buf);
1622 PyObject_GC_Del(self);
1623}
1624
1625static int
1626unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1627{
1628 Py_VISIT(self->so);
1629 Py_VISIT(self->buf.obj);
1630 return 0;
1631}
1632
1633static PyObject *
1634unpackiter_len(unpackiterobject *self)
1635{
1636 Py_ssize_t len;
1637 if (self->so == NULL)
1638 len = 0;
1639 else
1640 len = (self->buf.len - self->index) / self->so->s_size;
1641 return PyLong_FromSsize_t(len);
1642}
1643
1644static PyMethodDef unpackiter_methods[] = {
1645 {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1646 {NULL, NULL} /* sentinel */
1647};
1648
1649static PyObject *
1650unpackiter_iternext(unpackiterobject *self)
1651{
1652 PyObject *result;
1653 if (self->so == NULL)
1654 return NULL;
1655 if (self->index >= self->buf.len) {
1656 /* Iterator exhausted */
1657 Py_CLEAR(self->so);
1658 PyBuffer_Release(&self->buf);
1659 return NULL;
1660 }
1661 assert(self->index + self->so->s_size <= self->buf.len);
1662 result = s_unpack_internal(self->so,
1663 (char*) self->buf.buf + self->index);
1664 self->index += self->so->s_size;
1665 return result;
1666}
1667
doko@ubuntu.com46c5deb2013-11-23 16:07:55 +01001668static PyTypeObject unpackiter_type = {
Zachary Ware854adb12016-10-02 00:33:39 -05001669 PyVarObject_HEAD_INIT(NULL, 0)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001670 "unpack_iterator", /* tp_name */
1671 sizeof(unpackiterobject), /* tp_basicsize */
1672 0, /* tp_itemsize */
1673 (destructor)unpackiter_dealloc, /* tp_dealloc */
1674 0, /* tp_print */
1675 0, /* tp_getattr */
1676 0, /* tp_setattr */
1677 0, /* tp_reserved */
1678 0, /* tp_repr */
1679 0, /* tp_as_number */
1680 0, /* tp_as_sequence */
1681 0, /* tp_as_mapping */
1682 0, /* tp_hash */
1683 0, /* tp_call */
1684 0, /* tp_str */
1685 PyObject_GenericGetAttr, /* tp_getattro */
1686 0, /* tp_setattro */
1687 0, /* tp_as_buffer */
1688 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1689 0, /* tp_doc */
1690 (traverseproc)unpackiter_traverse, /* tp_traverse */
1691 0, /* tp_clear */
1692 0, /* tp_richcompare */
1693 0, /* tp_weaklistoffset */
1694 PyObject_SelfIter, /* tp_iter */
1695 (iternextfunc)unpackiter_iternext, /* tp_iternext */
1696 unpackiter_methods /* tp_methods */
1697};
1698
Victor Stinner3f2d1012017-02-02 12:09:30 +01001699/*[clinic input]
1700Struct.iter_unpack
1701
1702 buffer: object
1703 /
1704
1705Return an iterator yielding tuples.
1706
1707Tuples are unpacked from the given bytes source, like a repeated
1708invocation of unpack_from().
1709
1710Requires that the bytes length be a multiple of the struct size.
1711[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001712
1713static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001714Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1715/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001716{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001717 unpackiterobject *iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001718
Victor Stinner3f2d1012017-02-02 12:09:30 +01001719 assert(self->s_codes != NULL);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001720
Victor Stinner3f2d1012017-02-02 12:09:30 +01001721 if (self->s_size == 0) {
Antoine Pitrou9f146812013-04-27 00:20:04 +02001722 PyErr_Format(StructError,
1723 "cannot iteratively unpack with a struct of length 0");
1724 return NULL;
1725 }
1726
Victor Stinner3f2d1012017-02-02 12:09:30 +01001727 iter = (unpackiterobject *) PyType_GenericAlloc(&unpackiter_type, 0);
1728 if (iter == NULL)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001729 return NULL;
1730
Victor Stinner3f2d1012017-02-02 12:09:30 +01001731 if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1732 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001733 return NULL;
1734 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001735 if (iter->buf.len % self->s_size != 0) {
Antoine Pitrou9f146812013-04-27 00:20:04 +02001736 PyErr_Format(StructError,
1737 "iterative unpacking requires a bytes length "
1738 "multiple of %zd",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001739 self->s_size);
1740 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001741 return NULL;
1742 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001743 Py_INCREF(self);
1744 iter->so = self;
1745 iter->index = 0;
1746 return (PyObject *)iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001747}
1748
1749
Thomas Wouters477c8d52006-05-27 19:21:47 +00001750/*
1751 * Guts of the pack function.
1752 *
1753 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1754 * argument for where to start processing the arguments for packing, and a
1755 * character buffer for writing the packed string. The caller must insure
1756 * that the buffer may contain the required length for packing the arguments.
1757 * 0 is returned on success, 1 is returned if there is an error.
1758 *
1759 */
1760static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001761s_pack_internal(PyStructObject *soself, PyObject **args, int offset, char* buf)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001762{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001763 formatcode *code;
1764 /* XXX(nnorwitz): why does i need to be a local? can we use
1765 the offset parameter or do we need the wider width? */
1766 Py_ssize_t i;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001768 memset(buf, '\0', soself->s_size);
1769 i = offset;
1770 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 const formatdef *e = code->fmtdef;
1772 char *res = buf + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001773 Py_ssize_t j = code->repeat;
1774 while (j--) {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001775 PyObject *v = args[i++];
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001776 if (e->format == 's') {
1777 Py_ssize_t n;
1778 int isstring;
1779 void *p;
1780 isstring = PyBytes_Check(v);
1781 if (!isstring && !PyByteArray_Check(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001782 PyErr_SetString(StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001783 "argument for 's' must be a bytes object");
1784 return -1;
1785 }
1786 if (isstring) {
1787 n = PyBytes_GET_SIZE(v);
1788 p = PyBytes_AS_STRING(v);
1789 }
1790 else {
1791 n = PyByteArray_GET_SIZE(v);
1792 p = PyByteArray_AS_STRING(v);
1793 }
1794 if (n > code->size)
1795 n = code->size;
1796 if (n > 0)
1797 memcpy(res, p, n);
1798 } else if (e->format == 'p') {
1799 Py_ssize_t n;
1800 int isstring;
1801 void *p;
1802 isstring = PyBytes_Check(v);
1803 if (!isstring && !PyByteArray_Check(v)) {
1804 PyErr_SetString(StructError,
1805 "argument for 'p' must be a bytes object");
1806 return -1;
1807 }
1808 if (isstring) {
1809 n = PyBytes_GET_SIZE(v);
1810 p = PyBytes_AS_STRING(v);
1811 }
1812 else {
1813 n = PyByteArray_GET_SIZE(v);
1814 p = PyByteArray_AS_STRING(v);
1815 }
1816 if (n > (code->size - 1))
1817 n = code->size - 1;
1818 if (n > 0)
1819 memcpy(res + 1, p, n);
1820 if (n > 255)
1821 n = 255;
1822 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1823 } else {
1824 if (e->pack(res, v, e) < 0) {
1825 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1826 PyErr_SetString(StructError,
Serhiy Storchaka46e1ce22013-08-27 20:17:03 +03001827 "int too large to convert");
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001828 return -1;
1829 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 }
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001831 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 }
1833 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 /* Success */
1836 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001837}
1838
1839
1840PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001841"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001842\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001843Return a bytes object containing values v1, v2, ... packed according\n\
1844to the format string S.format. See help(struct) for more on format\n\
1845strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001846
1847static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001848s_pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001849{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 PyStructObject *soself;
1851 PyObject *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001852
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001853 /* Validate arguments. */
1854 soself = (PyStructObject *)self;
1855 assert(PyStruct_Check(self));
1856 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001857 if (nargs != soself->s_len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001858 {
1859 PyErr_Format(StructError,
Victor Stinner3f2d1012017-02-02 12:09:30 +01001860 "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1861 return NULL;
1862 }
1863 if (!_PyArg_NoStackKeywords("pack", kwnames)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 return NULL;
1865 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 /* Allocate a new string */
1868 result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size);
1869 if (result == NULL)
1870 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001871
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 /* Call the guts */
1873 if ( s_pack_internal(soself, args, 0, PyBytes_AS_STRING(result)) != 0 ) {
1874 Py_DECREF(result);
1875 return NULL;
1876 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001877
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001878 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001879}
1880
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001881PyDoc_STRVAR(s_pack_into__doc__,
1882"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001883\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001884Pack the values v1, v2, ... according to the format string S.format\n\
1885and write the packed bytes into the writable buffer buf starting at\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00001886offset. Note that the offset is a required argument. See\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001887help(struct) for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001888
1889static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001890s_pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001891{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 PyStructObject *soself;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001893 Py_buffer buffer;
1894 Py_ssize_t offset;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 /* Validate arguments. +1 is for the first arg as buffer. */
1897 soself = (PyStructObject *)self;
1898 assert(PyStruct_Check(self));
1899 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001900 if (nargs != (soself->s_len + 2))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001902 if (nargs == 0) {
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001903 PyErr_Format(StructError,
1904 "pack_into expected buffer argument");
1905 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001906 else if (nargs == 1) {
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001907 PyErr_Format(StructError,
1908 "pack_into expected offset argument");
1909 }
1910 else {
1911 PyErr_Format(StructError,
1912 "pack_into expected %zd items for packing (got %zd)",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001913 soself->s_len, (nargs - 2));
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001914 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 return NULL;
1916 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001917 if (!_PyArg_NoStackKeywords("pack_into", kwnames)) {
1918 return NULL;
1919 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001920
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001921 /* Extract a writable memory buffer from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001922 if (!PyArg_Parse(args[0], "w*", &buffer))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001923 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001924 assert(buffer.len >= 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 /* Extract the offset from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001927 offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001928 if (offset == -1 && PyErr_Occurred()) {
1929 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001931 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 /* Support negative offsets. */
1934 if (offset < 0)
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001935 offset += buffer.len;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001936
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 /* Check boundaries */
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001938 if (offset < 0 || (buffer.len - offset) < soself->s_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 PyErr_Format(StructError,
1940 "pack_into requires a buffer of at least %zd bytes",
1941 soself->s_size);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001942 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 return NULL;
1944 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 /* Call the guts */
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001947 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
1948 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001949 return NULL;
1950 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001951
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001952 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001953 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001954}
1955
1956static PyObject *
1957s_get_format(PyStructObject *self, void *unused)
1958{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 Py_INCREF(self->s_format);
1960 return self->s_format;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001961}
1962
1963static PyObject *
1964s_get_size(PyStructObject *self, void *unused)
1965{
Christian Heimes217cfd12007-12-02 14:31:20 +00001966 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001967}
1968
Meador Ingeb14d8c92012-07-23 10:01:29 -05001969PyDoc_STRVAR(s_sizeof__doc__,
1970"S.__sizeof__() -> size of S in memory, in bytes");
1971
1972static PyObject *
Meador Inge90bc2dbc2012-07-28 22:16:39 -05001973s_sizeof(PyStructObject *self, void *unused)
Meador Ingeb14d8c92012-07-23 10:01:29 -05001974{
1975 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001976 formatcode *code;
Meador Ingeb14d8c92012-07-23 10:01:29 -05001977
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001978 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001979 for (code = self->s_codes; code->fmtdef != NULL; code++)
1980 size += sizeof(formatcode);
Meador Ingeb14d8c92012-07-23 10:01:29 -05001981 return PyLong_FromSsize_t(size);
1982}
1983
Thomas Wouters477c8d52006-05-27 19:21:47 +00001984/* List of functions */
1985
1986static struct PyMethodDef s_methods[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001987 STRUCT_ITER_UNPACK_METHODDEF
1988 {"pack", (PyCFunction)s_pack, METH_FASTCALL, s_pack__doc__},
1989 {"pack_into", (PyCFunction)s_pack_into, METH_FASTCALL, s_pack_into__doc__},
1990 STRUCT_UNPACK_METHODDEF
1991 STRUCT_UNPACK_FROM_METHODDEF
Meador Ingeb14d8c92012-07-23 10:01:29 -05001992 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001993 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001994};
1995
Thomas Wouters477c8d52006-05-27 19:21:47 +00001996#define OFF(x) offsetof(PyStructObject, x)
1997
1998static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001999 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
2000 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
2001 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002002};
2003
2004static
2005PyTypeObject PyStructType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 PyVarObject_HEAD_INIT(NULL, 0)
2007 "Struct",
2008 sizeof(PyStructObject),
2009 0,
2010 (destructor)s_dealloc, /* tp_dealloc */
2011 0, /* tp_print */
2012 0, /* tp_getattr */
2013 0, /* tp_setattr */
2014 0, /* tp_reserved */
2015 0, /* tp_repr */
2016 0, /* tp_as_number */
2017 0, /* tp_as_sequence */
2018 0, /* tp_as_mapping */
2019 0, /* tp_hash */
2020 0, /* tp_call */
2021 0, /* tp_str */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002022 PyObject_GenericGetAttr, /* tp_getattro */
2023 PyObject_GenericSetAttr, /* tp_setattro */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 0, /* tp_as_buffer */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002025 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2026 Struct___init____doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 0, /* tp_traverse */
2028 0, /* tp_clear */
2029 0, /* tp_richcompare */
2030 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
2031 0, /* tp_iter */
2032 0, /* tp_iternext */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002033 s_methods, /* tp_methods */
2034 NULL, /* tp_members */
2035 s_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002036 0, /* tp_base */
2037 0, /* tp_dict */
2038 0, /* tp_descr_get */
2039 0, /* tp_descr_set */
2040 0, /* tp_dictoffset */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002041 Struct___init__, /* tp_init */
2042 PyType_GenericAlloc, /* tp_alloc */
2043 s_new, /* tp_new */
2044 PyObject_Del, /* tp_free */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002045};
2046
Christian Heimesa34706f2008-01-04 03:06:10 +00002047
2048/* ---- Standalone functions ---- */
2049
2050#define MAXCACHE 100
2051static PyObject *cache = NULL;
2052
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002053static int
2054cache_struct_converter(PyObject *fmt, PyObject **ptr)
Christian Heimesa34706f2008-01-04 03:06:10 +00002055{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 PyObject * s_object;
Christian Heimesa34706f2008-01-04 03:06:10 +00002057
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002058 if (fmt == NULL) {
2059 Py_DECREF(*ptr);
2060 return 1;
2061 }
2062
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002063 if (cache == NULL) {
2064 cache = PyDict_New();
2065 if (cache == NULL)
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002066 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002068
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002069 s_object = PyDict_GetItem(cache, fmt);
2070 if (s_object != NULL) {
2071 Py_INCREF(s_object);
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002072 *ptr = s_object;
2073 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002074 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002075
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01002076 s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 if (s_object != NULL) {
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02002078 if (PyDict_GET_SIZE(cache) >= MAXCACHE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002079 PyDict_Clear(cache);
2080 /* Attempt to cache the result */
2081 if (PyDict_SetItem(cache, fmt, s_object) == -1)
2082 PyErr_Clear();
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002083 *ptr = s_object;
2084 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002086 return 0;
Christian Heimesa34706f2008-01-04 03:06:10 +00002087}
2088
Victor Stinner3f2d1012017-02-02 12:09:30 +01002089/*[clinic input]
2090_clearcache
2091
2092Clear the internal cache.
2093[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002094
2095static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002096_clearcache_impl(PyObject *module)
2097/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002098{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 Py_CLEAR(cache);
2100 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00002101}
2102
Victor Stinner3f2d1012017-02-02 12:09:30 +01002103
2104/*[clinic input]
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002105calcsize -> Py_ssize_t
Victor Stinner3f2d1012017-02-02 12:09:30 +01002106
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002107 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002108 /
2109
2110Return size in bytes of the struct described by the format string.
2111[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002112
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002113static Py_ssize_t
2114calcsize_impl(PyObject *module, PyStructObject *s_object)
2115/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002116{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002117 return s_object->s_size;
Christian Heimesa34706f2008-01-04 03:06:10 +00002118}
2119
2120PyDoc_STRVAR(pack_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002121"pack(format, v1, v2, ...) -> bytes\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002122\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002123Return a bytes object containing the values v1, v2, ... packed according\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002124to the format string. See help(struct) for more on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002125
2126static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002127pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
Christian Heimesa34706f2008-01-04 03:06:10 +00002128{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002129 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002130 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002131
Victor Stinner3f2d1012017-02-02 12:09:30 +01002132 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 PyErr_SetString(PyExc_TypeError, "missing format argument");
2134 return NULL;
2135 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002136 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002137
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002138 if (!cache_struct_converter(format, &s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 return NULL;
2140 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002141 result = s_pack(s_object, args + 1, nargs - 1, kwnames);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002142 Py_DECREF(s_object);
2143 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002144}
2145
2146PyDoc_STRVAR(pack_into_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002147"pack_into(format, buffer, offset, v1, v2, ...)\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002148\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002149Pack the values v1, v2, ... according to the format string and write\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002150the packed bytes into the writable buffer buf starting at offset. Note\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002151that the offset is a required argument. See help(struct) for more\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002152on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002153
2154static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002155pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
Christian Heimesa34706f2008-01-04 03:06:10 +00002156{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002157 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002158 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002159
Victor Stinner3f2d1012017-02-02 12:09:30 +01002160 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 PyErr_SetString(PyExc_TypeError, "missing format argument");
2162 return NULL;
2163 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002164 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002165
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002166 if (!cache_struct_converter(format, &s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002167 return NULL;
2168 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002169 result = s_pack_into(s_object, args + 1, nargs - 1, kwnames);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002170 Py_DECREF(s_object);
2171 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002172}
2173
Victor Stinner3f2d1012017-02-02 12:09:30 +01002174/*[clinic input]
2175unpack
2176
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002177 format as s_object: cache_struct
Victor Stinnerc0f59ad2017-02-02 14:24:16 +01002178 buffer: Py_buffer
Victor Stinner3f2d1012017-02-02 12:09:30 +01002179 /
2180
2181Return a tuple containing values unpacked according to the format string.
2182
2183The buffer's size in bytes must be calcsize(format).
2184
2185See help(struct) for more on format strings.
2186[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002187
2188static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002189unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2190/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002191{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002192 return Struct_unpack_impl(s_object, buffer);
Christian Heimesa34706f2008-01-04 03:06:10 +00002193}
2194
Victor Stinner3f2d1012017-02-02 12:09:30 +01002195/*[clinic input]
2196unpack_from
2197
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002198 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002199 /
2200 buffer: Py_buffer
2201 offset: Py_ssize_t = 0
2202
2203Return a tuple containing values unpacked according to the format string.
2204
2205The buffer's size, minus offset, must be at least calcsize(format).
2206
2207See help(struct) for more on format strings.
2208[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002209
2210static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002211unpack_from_impl(PyObject *module, PyStructObject *s_object,
2212 Py_buffer *buffer, Py_ssize_t offset)
2213/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002214{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002215 return Struct_unpack_from_impl(s_object, buffer, offset);
Christian Heimesa34706f2008-01-04 03:06:10 +00002216}
2217
Victor Stinner3f2d1012017-02-02 12:09:30 +01002218/*[clinic input]
2219iter_unpack
2220
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002221 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002222 buffer: object
2223 /
2224
2225Return an iterator yielding tuples unpacked from the given bytes.
2226
2227The bytes are unpacked according to the format string, like
2228a repeated invocation of unpack_from().
2229
2230Requires that the bytes length be a multiple of the format struct size.
2231[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002232
2233static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002234iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2235 PyObject *buffer)
2236/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002237{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002238 return Struct_iter_unpack(s_object, buffer);
Antoine Pitrou9f146812013-04-27 00:20:04 +02002239}
2240
Christian Heimesa34706f2008-01-04 03:06:10 +00002241static struct PyMethodDef module_functions[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002242 _CLEARCACHE_METHODDEF
2243 CALCSIZE_METHODDEF
2244 ITER_UNPACK_METHODDEF
2245 {"pack", (PyCFunction)pack, METH_FASTCALL, pack_doc},
2246 {"pack_into", (PyCFunction)pack_into, METH_FASTCALL, pack_into_doc},
2247 UNPACK_METHODDEF
2248 UNPACK_FROM_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002249 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00002250};
2251
2252
Thomas Wouters477c8d52006-05-27 19:21:47 +00002253/* Module initialization */
2254
Christian Heimesa34706f2008-01-04 03:06:10 +00002255PyDoc_STRVAR(module_doc,
2256"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002257Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002258and also as format strings (explained below) to describe the layout of data\n\
2259in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002260\n\
2261The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002262 @: native order, size & alignment (default)\n\
2263 =: native order, std. size & alignment\n\
2264 <: little-endian, std. size & alignment\n\
2265 >: big-endian, std. size & alignment\n\
2266 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002267\n\
2268The remaining chars indicate types of args and must match exactly;\n\
2269these can be preceded by a decimal repeat count:\n\
2270 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002271 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002272 h:short; H:unsigned short; i:int; I:unsigned int;\n\
Mark Dickinson7c4e4092016-09-03 17:21:29 +01002273 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002274Special cases (preceding decimal count indicates length):\n\
2275 s:string (array of char); p: pascal string (with count byte).\n\
Antoine Pitrou45d9c912011-10-06 15:27:40 +02002276Special cases (only available in native format):\n\
2277 n:ssize_t; N:size_t;\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002278 P:an integer type that is wide enough to hold a pointer.\n\
2279Special case (not in native mode unless 'long long' in platform C):\n\
2280 q:long long; Q:unsigned long long\n\
2281Whitespace between formats is ignored.\n\
2282\n\
2283The variable struct.error is an exception raised on errors.\n");
2284
Martin v. Löwis1a214512008-06-11 05:26:20 +00002285
2286static struct PyModuleDef _structmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002287 PyModuleDef_HEAD_INIT,
2288 "_struct",
2289 module_doc,
2290 -1,
2291 module_functions,
2292 NULL,
2293 NULL,
2294 NULL,
2295 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002296};
2297
Thomas Wouters477c8d52006-05-27 19:21:47 +00002298PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002299PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002300{
Mark Dickinson06817852010-06-12 09:25:13 +00002301 PyObject *m;
Christian Heimesa34706f2008-01-04 03:06:10 +00002302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002303 m = PyModule_Create(&_structmodule);
2304 if (m == NULL)
2305 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002307 Py_TYPE(&PyStructType) = &PyType_Type;
2308 if (PyType_Ready(&PyStructType) < 0)
2309 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002310
Zachary Ware99f11b42016-10-04 01:20:21 -05002311 if (PyType_Ready(&unpackiter_type) < 0)
2312 return NULL;
2313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002314 /* Check endian and swap in faster functions */
2315 {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002316 const formatdef *native = native_table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002317 formatdef *other, *ptr;
Christian Heimes743e0cd2012-10-17 23:52:17 +02002318#if PY_LITTLE_ENDIAN
2319 other = lilendian_table;
2320#else
2321 other = bigendian_table;
2322#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002323 /* Scan through the native table, find a matching
2324 entry in the endian table and swap in the
2325 native implementations whenever possible
2326 (64-bit platforms may not have "standard" sizes) */
2327 while (native->format != '\0' && other->format != '\0') {
2328 ptr = other;
2329 while (ptr->format != '\0') {
2330 if (ptr->format == native->format) {
2331 /* Match faster when formats are
2332 listed in the same order */
2333 if (ptr == other)
2334 other++;
2335 /* Only use the trick if the
2336 size matches */
2337 if (ptr->size != native->size)
2338 break;
2339 /* Skip float and double, could be
2340 "unknown" float format */
2341 if (ptr->format == 'd' || ptr->format == 'f')
2342 break;
2343 ptr->pack = native->pack;
2344 ptr->unpack = native->unpack;
2345 break;
2346 }
2347 ptr++;
2348 }
2349 native++;
2350 }
2351 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 /* Add some symbolic constants to the module */
2354 if (StructError == NULL) {
2355 StructError = PyErr_NewException("struct.error", NULL, NULL);
2356 if (StructError == NULL)
2357 return NULL;
2358 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002360 Py_INCREF(StructError);
2361 PyModule_AddObject(m, "error", StructError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 Py_INCREF((PyObject*)&PyStructType);
2364 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002366 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002367}