blob: a614be89d2303641e368863362ad30a56cab2d33 [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. */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001934 if (offset < 0) {
1935 /* Check that negative offset is low enough to fit data */
1936 if (offset + soself->s_size > 0) {
1937 PyErr_Format(StructError,
1938 "no space to pack %zd bytes at offset %zd",
1939 soself->s_size,
1940 offset);
1941 PyBuffer_Release(&buffer);
1942 return NULL;
1943 }
1944
1945 /* Check that negative offset is not crossing buffer boundary */
1946 if (offset + buffer.len < 0) {
1947 PyErr_Format(StructError,
1948 "offset %zd out of range for %zd-byte buffer",
1949 offset,
1950 buffer.len);
1951 PyBuffer_Release(&buffer);
1952 return NULL;
1953 }
1954
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001955 offset += buffer.len;
Andrew Nesterf78b1192017-04-04 13:46:25 +03001956 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001957
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001958 /* Check boundaries */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001959 if ((buffer.len - offset) < soself->s_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960 PyErr_Format(StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001961 "pack_into requires a buffer of at least %zd bytes for "
1962 "packing %zd bytes at offset %zd "
1963 "(actual buffer size is %zd)",
1964 soself->s_size + offset,
1965 soself->s_size,
1966 offset,
1967 buffer.len);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001968 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001969 return NULL;
1970 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001971
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001972 /* Call the guts */
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001973 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
1974 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001975 return NULL;
1976 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001977
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001978 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001980}
1981
1982static PyObject *
1983s_get_format(PyStructObject *self, void *unused)
1984{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 Py_INCREF(self->s_format);
1986 return self->s_format;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001987}
1988
1989static PyObject *
1990s_get_size(PyStructObject *self, void *unused)
1991{
Christian Heimes217cfd12007-12-02 14:31:20 +00001992 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001993}
1994
Meador Ingeb14d8c92012-07-23 10:01:29 -05001995PyDoc_STRVAR(s_sizeof__doc__,
1996"S.__sizeof__() -> size of S in memory, in bytes");
1997
1998static PyObject *
Meador Inge90bc2dbc2012-07-28 22:16:39 -05001999s_sizeof(PyStructObject *self, void *unused)
Meador Ingeb14d8c92012-07-23 10:01:29 -05002000{
2001 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002002 formatcode *code;
Meador Ingeb14d8c92012-07-23 10:01:29 -05002003
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002004 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002005 for (code = self->s_codes; code->fmtdef != NULL; code++)
2006 size += sizeof(formatcode);
Meador Ingeb14d8c92012-07-23 10:01:29 -05002007 return PyLong_FromSsize_t(size);
2008}
2009
Thomas Wouters477c8d52006-05-27 19:21:47 +00002010/* List of functions */
2011
2012static struct PyMethodDef s_methods[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002013 STRUCT_ITER_UNPACK_METHODDEF
2014 {"pack", (PyCFunction)s_pack, METH_FASTCALL, s_pack__doc__},
2015 {"pack_into", (PyCFunction)s_pack_into, METH_FASTCALL, s_pack_into__doc__},
2016 STRUCT_UNPACK_METHODDEF
2017 STRUCT_UNPACK_FROM_METHODDEF
Meador Ingeb14d8c92012-07-23 10:01:29 -05002018 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002019 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002020};
2021
Thomas Wouters477c8d52006-05-27 19:21:47 +00002022#define OFF(x) offsetof(PyStructObject, x)
2023
2024static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
2026 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
2027 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002028};
2029
2030static
2031PyTypeObject PyStructType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002032 PyVarObject_HEAD_INIT(NULL, 0)
2033 "Struct",
2034 sizeof(PyStructObject),
2035 0,
2036 (destructor)s_dealloc, /* tp_dealloc */
2037 0, /* tp_print */
2038 0, /* tp_getattr */
2039 0, /* tp_setattr */
2040 0, /* tp_reserved */
2041 0, /* tp_repr */
2042 0, /* tp_as_number */
2043 0, /* tp_as_sequence */
2044 0, /* tp_as_mapping */
2045 0, /* tp_hash */
2046 0, /* tp_call */
2047 0, /* tp_str */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002048 PyObject_GenericGetAttr, /* tp_getattro */
2049 PyObject_GenericSetAttr, /* tp_setattro */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002050 0, /* tp_as_buffer */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002051 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2052 Struct___init____doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002053 0, /* tp_traverse */
2054 0, /* tp_clear */
2055 0, /* tp_richcompare */
2056 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
2057 0, /* tp_iter */
2058 0, /* tp_iternext */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002059 s_methods, /* tp_methods */
2060 NULL, /* tp_members */
2061 s_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002062 0, /* tp_base */
2063 0, /* tp_dict */
2064 0, /* tp_descr_get */
2065 0, /* tp_descr_set */
2066 0, /* tp_dictoffset */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002067 Struct___init__, /* tp_init */
2068 PyType_GenericAlloc, /* tp_alloc */
2069 s_new, /* tp_new */
2070 PyObject_Del, /* tp_free */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002071};
2072
Christian Heimesa34706f2008-01-04 03:06:10 +00002073
2074/* ---- Standalone functions ---- */
2075
2076#define MAXCACHE 100
2077static PyObject *cache = NULL;
2078
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002079static int
2080cache_struct_converter(PyObject *fmt, PyObject **ptr)
Christian Heimesa34706f2008-01-04 03:06:10 +00002081{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 PyObject * s_object;
Christian Heimesa34706f2008-01-04 03:06:10 +00002083
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002084 if (fmt == NULL) {
2085 Py_DECREF(*ptr);
Serhiy Storchaka40db90c2017-04-20 21:19:31 +03002086 *ptr = NULL;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002087 return 1;
2088 }
2089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002090 if (cache == NULL) {
2091 cache = PyDict_New();
2092 if (cache == NULL)
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002093 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 s_object = PyDict_GetItem(cache, fmt);
2097 if (s_object != NULL) {
2098 Py_INCREF(s_object);
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002099 *ptr = s_object;
2100 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002102
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01002103 s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002104 if (s_object != NULL) {
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02002105 if (PyDict_GET_SIZE(cache) >= MAXCACHE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 PyDict_Clear(cache);
2107 /* Attempt to cache the result */
2108 if (PyDict_SetItem(cache, fmt, s_object) == -1)
2109 PyErr_Clear();
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002110 *ptr = s_object;
2111 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002112 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002113 return 0;
Christian Heimesa34706f2008-01-04 03:06:10 +00002114}
2115
Victor Stinner3f2d1012017-02-02 12:09:30 +01002116/*[clinic input]
2117_clearcache
2118
2119Clear the internal cache.
2120[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002121
2122static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002123_clearcache_impl(PyObject *module)
2124/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002125{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002126 Py_CLEAR(cache);
2127 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00002128}
2129
Victor Stinner3f2d1012017-02-02 12:09:30 +01002130
2131/*[clinic input]
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002132calcsize -> Py_ssize_t
Victor Stinner3f2d1012017-02-02 12:09:30 +01002133
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002134 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002135 /
2136
2137Return size in bytes of the struct described by the format string.
2138[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002139
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002140static Py_ssize_t
2141calcsize_impl(PyObject *module, PyStructObject *s_object)
2142/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002143{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002144 return s_object->s_size;
Christian Heimesa34706f2008-01-04 03:06:10 +00002145}
2146
2147PyDoc_STRVAR(pack_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002148"pack(format, v1, v2, ...) -> bytes\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002149\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002150Return a bytes object containing the values v1, v2, ... packed according\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002151to the format string. See help(struct) for more on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002152
2153static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002154pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
Christian Heimesa34706f2008-01-04 03:06:10 +00002155{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002156 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002157 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002158
Victor Stinner3f2d1012017-02-02 12:09:30 +01002159 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002160 PyErr_SetString(PyExc_TypeError, "missing format argument");
2161 return NULL;
2162 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002163 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002164
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002165 if (!cache_struct_converter(format, &s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 return NULL;
2167 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002168 result = s_pack(s_object, args + 1, nargs - 1, kwnames);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 Py_DECREF(s_object);
2170 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002171}
2172
2173PyDoc_STRVAR(pack_into_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002174"pack_into(format, buffer, offset, v1, v2, ...)\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002175\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002176Pack the values v1, v2, ... according to the format string and write\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002177the packed bytes into the writable buffer buf starting at offset. Note\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002178that the offset is a required argument. See help(struct) for more\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002179on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002180
2181static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002182pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
Christian Heimesa34706f2008-01-04 03:06:10 +00002183{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002184 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002185 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002186
Victor Stinner3f2d1012017-02-02 12:09:30 +01002187 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002188 PyErr_SetString(PyExc_TypeError, "missing format argument");
2189 return NULL;
2190 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002191 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002192
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002193 if (!cache_struct_converter(format, &s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 return NULL;
2195 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002196 result = s_pack_into(s_object, args + 1, nargs - 1, kwnames);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 Py_DECREF(s_object);
2198 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002199}
2200
Victor Stinner3f2d1012017-02-02 12:09:30 +01002201/*[clinic input]
2202unpack
2203
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002204 format as s_object: cache_struct
Victor Stinnerc0f59ad2017-02-02 14:24:16 +01002205 buffer: Py_buffer
Victor Stinner3f2d1012017-02-02 12:09:30 +01002206 /
2207
2208Return a tuple containing values unpacked according to the format string.
2209
2210The buffer's size in bytes must be calcsize(format).
2211
2212See help(struct) for more on format strings.
2213[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002214
2215static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002216unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2217/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002218{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002219 return Struct_unpack_impl(s_object, buffer);
Christian Heimesa34706f2008-01-04 03:06:10 +00002220}
2221
Victor Stinner3f2d1012017-02-02 12:09:30 +01002222/*[clinic input]
2223unpack_from
2224
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002225 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002226 /
2227 buffer: Py_buffer
2228 offset: Py_ssize_t = 0
2229
2230Return a tuple containing values unpacked according to the format string.
2231
2232The buffer's size, minus offset, must be at least calcsize(format).
2233
2234See help(struct) for more on format strings.
2235[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002236
2237static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002238unpack_from_impl(PyObject *module, PyStructObject *s_object,
2239 Py_buffer *buffer, Py_ssize_t offset)
2240/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002241{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002242 return Struct_unpack_from_impl(s_object, buffer, offset);
Christian Heimesa34706f2008-01-04 03:06:10 +00002243}
2244
Victor Stinner3f2d1012017-02-02 12:09:30 +01002245/*[clinic input]
2246iter_unpack
2247
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002248 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002249 buffer: object
2250 /
2251
2252Return an iterator yielding tuples unpacked from the given bytes.
2253
2254The bytes are unpacked according to the format string, like
2255a repeated invocation of unpack_from().
2256
2257Requires that the bytes length be a multiple of the format struct size.
2258[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002259
2260static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002261iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2262 PyObject *buffer)
2263/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002264{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002265 return Struct_iter_unpack(s_object, buffer);
Antoine Pitrou9f146812013-04-27 00:20:04 +02002266}
2267
Christian Heimesa34706f2008-01-04 03:06:10 +00002268static struct PyMethodDef module_functions[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002269 _CLEARCACHE_METHODDEF
2270 CALCSIZE_METHODDEF
2271 ITER_UNPACK_METHODDEF
2272 {"pack", (PyCFunction)pack, METH_FASTCALL, pack_doc},
2273 {"pack_into", (PyCFunction)pack_into, METH_FASTCALL, pack_into_doc},
2274 UNPACK_METHODDEF
2275 UNPACK_FROM_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002276 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00002277};
2278
2279
Thomas Wouters477c8d52006-05-27 19:21:47 +00002280/* Module initialization */
2281
Christian Heimesa34706f2008-01-04 03:06:10 +00002282PyDoc_STRVAR(module_doc,
2283"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002284Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002285and also as format strings (explained below) to describe the layout of data\n\
2286in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002287\n\
2288The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002289 @: native order, size & alignment (default)\n\
2290 =: native order, std. size & alignment\n\
2291 <: little-endian, std. size & alignment\n\
2292 >: big-endian, std. size & alignment\n\
2293 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002294\n\
2295The remaining chars indicate types of args and must match exactly;\n\
2296these can be preceded by a decimal repeat count:\n\
2297 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002298 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002299 h:short; H:unsigned short; i:int; I:unsigned int;\n\
Mark Dickinson7c4e4092016-09-03 17:21:29 +01002300 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002301Special cases (preceding decimal count indicates length):\n\
2302 s:string (array of char); p: pascal string (with count byte).\n\
Antoine Pitrou45d9c912011-10-06 15:27:40 +02002303Special cases (only available in native format):\n\
2304 n:ssize_t; N:size_t;\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002305 P:an integer type that is wide enough to hold a pointer.\n\
2306Special case (not in native mode unless 'long long' in platform C):\n\
2307 q:long long; Q:unsigned long long\n\
2308Whitespace between formats is ignored.\n\
2309\n\
2310The variable struct.error is an exception raised on errors.\n");
2311
Martin v. Löwis1a214512008-06-11 05:26:20 +00002312
2313static struct PyModuleDef _structmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002314 PyModuleDef_HEAD_INIT,
2315 "_struct",
2316 module_doc,
2317 -1,
2318 module_functions,
2319 NULL,
2320 NULL,
2321 NULL,
2322 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002323};
2324
Thomas Wouters477c8d52006-05-27 19:21:47 +00002325PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002326PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002327{
Mark Dickinson06817852010-06-12 09:25:13 +00002328 PyObject *m;
Christian Heimesa34706f2008-01-04 03:06:10 +00002329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002330 m = PyModule_Create(&_structmodule);
2331 if (m == NULL)
2332 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002334 Py_TYPE(&PyStructType) = &PyType_Type;
2335 if (PyType_Ready(&PyStructType) < 0)
2336 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002337
Zachary Ware99f11b42016-10-04 01:20:21 -05002338 if (PyType_Ready(&unpackiter_type) < 0)
2339 return NULL;
2340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002341 /* Check endian and swap in faster functions */
2342 {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002343 const formatdef *native = native_table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002344 formatdef *other, *ptr;
Christian Heimes743e0cd2012-10-17 23:52:17 +02002345#if PY_LITTLE_ENDIAN
2346 other = lilendian_table;
2347#else
2348 other = bigendian_table;
2349#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002350 /* Scan through the native table, find a matching
2351 entry in the endian table and swap in the
2352 native implementations whenever possible
2353 (64-bit platforms may not have "standard" sizes) */
2354 while (native->format != '\0' && other->format != '\0') {
2355 ptr = other;
2356 while (ptr->format != '\0') {
2357 if (ptr->format == native->format) {
2358 /* Match faster when formats are
2359 listed in the same order */
2360 if (ptr == other)
2361 other++;
2362 /* Only use the trick if the
2363 size matches */
2364 if (ptr->size != native->size)
2365 break;
2366 /* Skip float and double, could be
2367 "unknown" float format */
2368 if (ptr->format == 'd' || ptr->format == 'f')
2369 break;
2370 ptr->pack = native->pack;
2371 ptr->unpack = native->unpack;
2372 break;
2373 }
2374 ptr++;
2375 }
2376 native++;
2377 }
2378 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002380 /* Add some symbolic constants to the module */
2381 if (StructError == NULL) {
2382 StructError = PyErr_NewException("struct.error", NULL, NULL);
2383 if (StructError == NULL)
2384 return NULL;
2385 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 Py_INCREF(StructError);
2388 PyModule_AddObject(m, "error", StructError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002389
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002390 Py_INCREF((PyObject*)&PyStructType);
2391 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002393 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002394}