blob: 04d7f8e1871925f5f22817cecbd63df4e696757f [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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 return PyLong_FromUnsignedLong((unsigned long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000427}
428
429static PyObject *
430nu_long(const char *p, const formatdef *f)
431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 long x;
433 memcpy((char *)&x, p, sizeof x);
434 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000435}
436
437static PyObject *
438nu_ulong(const char *p, const formatdef *f)
439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 unsigned long x;
441 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000443}
444
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200445static PyObject *
446nu_ssize_t(const char *p, const formatdef *f)
447{
448 Py_ssize_t x;
449 memcpy((char *)&x, p, sizeof x);
450 return PyLong_FromSsize_t(x);
451}
452
453static PyObject *
454nu_size_t(const char *p, const formatdef *f)
455{
456 size_t x;
457 memcpy((char *)&x, p, sizeof x);
458 return PyLong_FromSize_t(x);
459}
460
Thomas Wouters477c8d52006-05-27 19:21:47 +0000461static PyObject *
462nu_longlong(const char *p, const formatdef *f)
463{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700464 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000467}
468
469static PyObject *
470nu_ulonglong(const char *p, const formatdef *f)
471{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700472 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000475}
476
Thomas Wouters477c8d52006-05-27 19:21:47 +0000477static PyObject *
Thomas Woutersb2137042007-02-01 18:02:27 +0000478nu_bool(const char *p, const formatdef *f)
479{
Benjamin Petersona9296e72016-09-07 11:06:17 -0700480 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 memcpy((char *)&x, p, sizeof x);
482 return PyBool_FromLong(x != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000483}
484
485
486static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100487nu_halffloat(const char *p, const formatdef *f)
488{
489#if PY_LITTLE_ENDIAN
490 return unpack_halffloat(p, 1);
491#else
492 return unpack_halffloat(p, 0);
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700493#endif
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100494}
495
496static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000497nu_float(const char *p, const formatdef *f)
498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 float x;
500 memcpy((char *)&x, p, sizeof x);
501 return PyFloat_FromDouble((double)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000502}
503
504static PyObject *
505nu_double(const char *p, const formatdef *f)
506{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 double x;
508 memcpy((char *)&x, p, sizeof x);
509 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000510}
511
512static PyObject *
513nu_void_p(const char *p, const formatdef *f)
514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 void *x;
516 memcpy((char *)&x, p, sizeof x);
517 return PyLong_FromVoidPtr(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000518}
519
520static int
521np_byte(char *p, PyObject *v, const formatdef *f)
522{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 long x;
524 if (get_long(v, &x) < 0)
525 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800526 if (x < -128 || x > 127) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 PyErr_SetString(StructError,
528 "byte format requires -128 <= number <= 127");
529 return -1;
530 }
531 *p = (char)x;
532 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000533}
534
535static int
536np_ubyte(char *p, PyObject *v, const formatdef *f)
537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 long x;
539 if (get_long(v, &x) < 0)
540 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800541 if (x < 0 || x > 255) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 PyErr_SetString(StructError,
543 "ubyte format requires 0 <= number <= 255");
544 return -1;
545 }
Xiang Zhang981096f2017-05-15 12:04:26 +0800546 *(unsigned char *)p = (unsigned char)x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000548}
549
550static int
551np_char(char *p, PyObject *v, const formatdef *f)
552{
Xiang Zhang96f50282017-05-15 11:53:51 +0800553 if (!PyBytes_Check(v) || PyBytes_GET_SIZE(v) != 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 PyErr_SetString(StructError,
Victor Stinnerda9ec992010-12-28 13:26:42 +0000555 "char format requires a bytes object of length 1");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 return -1;
557 }
Xiang Zhang96f50282017-05-15 11:53:51 +0800558 *p = *PyBytes_AS_STRING(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000560}
561
562static int
563np_short(char *p, PyObject *v, const formatdef *f)
564{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 long x;
566 short y;
567 if (get_long(v, &x) < 0)
568 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800569 if (x < SHRT_MIN || x > SHRT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 PyErr_SetString(StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200571 "short format requires " Py_STRINGIFY(SHRT_MIN)
572 " <= number <= " Py_STRINGIFY(SHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 return -1;
574 }
575 y = (short)x;
576 memcpy(p, (char *)&y, sizeof y);
577 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000578}
579
580static int
581np_ushort(char *p, PyObject *v, const formatdef *f)
582{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 long x;
584 unsigned short y;
585 if (get_long(v, &x) < 0)
586 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800587 if (x < 0 || x > USHRT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 PyErr_SetString(StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200589 "ushort format requires 0 <= number <= "
590 Py_STRINGIFY(USHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 return -1;
592 }
593 y = (unsigned short)x;
594 memcpy(p, (char *)&y, sizeof y);
595 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000596}
597
598static int
599np_int(char *p, PyObject *v, const formatdef *f)
600{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 long x;
602 int y;
603 if (get_long(v, &x) < 0)
604 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000605#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
607 RANGE_ERROR(x, f, 0, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000608#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 y = (int)x;
610 memcpy(p, (char *)&y, sizeof y);
611 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000612}
613
614static int
615np_uint(char *p, PyObject *v, const formatdef *f)
616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 unsigned long x;
618 unsigned int y;
619 if (get_ulong(v, &x) < 0)
620 return -1;
621 y = (unsigned int)x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000622#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 if (x > ((unsigned long)UINT_MAX))
624 RANGE_ERROR(y, f, 1, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000625#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 memcpy(p, (char *)&y, sizeof y);
627 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000628}
629
630static int
631np_long(char *p, PyObject *v, const formatdef *f)
632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 long x;
634 if (get_long(v, &x) < 0)
635 return -1;
636 memcpy(p, (char *)&x, sizeof x);
637 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000638}
639
640static int
641np_ulong(char *p, PyObject *v, const formatdef *f)
642{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 unsigned long x;
644 if (get_ulong(v, &x) < 0)
645 return -1;
646 memcpy(p, (char *)&x, sizeof x);
647 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000648}
649
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200650static int
651np_ssize_t(char *p, PyObject *v, const formatdef *f)
652{
653 Py_ssize_t x;
654 if (get_ssize_t(v, &x) < 0)
655 return -1;
656 memcpy(p, (char *)&x, sizeof x);
657 return 0;
658}
659
660static int
661np_size_t(char *p, PyObject *v, const formatdef *f)
662{
663 size_t x;
664 if (get_size_t(v, &x) < 0)
665 return -1;
666 memcpy(p, (char *)&x, sizeof x);
667 return 0;
668}
669
Thomas Wouters477c8d52006-05-27 19:21:47 +0000670static int
671np_longlong(char *p, PyObject *v, const formatdef *f)
672{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700673 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 if (get_longlong(v, &x) < 0)
675 return -1;
676 memcpy(p, (char *)&x, sizeof x);
677 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000678}
679
680static int
681np_ulonglong(char *p, PyObject *v, const formatdef *f)
682{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700683 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000684 if (get_ulonglong(v, &x) < 0)
685 return -1;
686 memcpy(p, (char *)&x, sizeof x);
687 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000688}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000689
Thomas Woutersb2137042007-02-01 18:02:27 +0000690
691static int
692np_bool(char *p, PyObject *v, const formatdef *f)
693{
Benjamin Petersonde73c452010-07-07 18:54:59 +0000694 int y;
Benjamin Petersona9296e72016-09-07 11:06:17 -0700695 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000697 if (y < 0)
698 return -1;
699 x = y;
700 memcpy(p, (char *)&x, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000702}
703
Thomas Wouters477c8d52006-05-27 19:21:47 +0000704static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100705np_halffloat(char *p, PyObject *v, const formatdef *f)
706{
707#if PY_LITTLE_ENDIAN
708 return pack_halffloat(p, v, 1);
709#else
710 return pack_halffloat(p, v, 0);
711#endif
712}
713
714static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000715np_float(char *p, PyObject *v, const formatdef *f)
716{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 float x = (float)PyFloat_AsDouble(v);
718 if (x == -1 && PyErr_Occurred()) {
719 PyErr_SetString(StructError,
720 "required argument is not a float");
721 return -1;
722 }
723 memcpy(p, (char *)&x, sizeof x);
724 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000725}
726
727static int
728np_double(char *p, PyObject *v, const formatdef *f)
729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 double x = PyFloat_AsDouble(v);
731 if (x == -1 && PyErr_Occurred()) {
732 PyErr_SetString(StructError,
733 "required argument is not a float");
734 return -1;
735 }
736 memcpy(p, (char *)&x, sizeof(double));
737 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000738}
739
740static int
741np_void_p(char *p, PyObject *v, const formatdef *f)
742{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 void *x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 v = get_pylong(v);
746 if (v == NULL)
747 return -1;
748 assert(PyLong_Check(v));
749 x = PyLong_AsVoidPtr(v);
750 Py_DECREF(v);
751 if (x == NULL && PyErr_Occurred())
752 return -1;
753 memcpy(p, (char *)&x, sizeof x);
754 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000755}
756
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200757static const formatdef native_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 {'x', sizeof(char), 0, NULL},
759 {'b', sizeof(char), 0, nu_byte, np_byte},
760 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
761 {'c', sizeof(char), 0, nu_char, np_char},
762 {'s', sizeof(char), 0, NULL},
763 {'p', sizeof(char), 0, NULL},
764 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
765 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
766 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
767 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
768 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
769 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200770 {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t},
771 {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t},
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700772 {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong},
773 {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Benjamin Petersona9296e72016-09-07 11:06:17 -0700774 {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100775 {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
777 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
778 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
779 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000780};
781
782/* Big-endian routines. *****************************************************/
783
784static PyObject *
785bu_int(const char *p, const formatdef *f)
786{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 long x = 0;
788 Py_ssize_t i = f->size;
789 const unsigned char *bytes = (const unsigned char *)p;
790 do {
791 x = (x<<8) | *bytes++;
792 } while (--i > 0);
793 /* Extend the sign bit. */
794 if (SIZEOF_LONG > f->size)
795 x |= -(x & (1L << ((8 * f->size) - 1)));
796 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000797}
798
799static PyObject *
800bu_uint(const char *p, const formatdef *f)
801{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 unsigned long x = 0;
803 Py_ssize_t i = f->size;
804 const unsigned char *bytes = (const unsigned char *)p;
805 do {
806 x = (x<<8) | *bytes++;
807 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000809}
810
811static PyObject *
812bu_longlong(const char *p, const formatdef *f)
813{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700814 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 Py_ssize_t i = f->size;
816 const unsigned char *bytes = (const unsigned char *)p;
817 do {
818 x = (x<<8) | *bytes++;
819 } while (--i > 0);
820 /* Extend the sign bit. */
821 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700822 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000823 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000824}
825
826static PyObject *
827bu_ulonglong(const char *p, const formatdef *f)
828{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700829 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000830 Py_ssize_t i = f->size;
831 const unsigned char *bytes = (const unsigned char *)p;
832 do {
833 x = (x<<8) | *bytes++;
834 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000836}
837
838static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100839bu_halffloat(const char *p, const formatdef *f)
840{
841 return unpack_halffloat(p, 0);
842}
843
844static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000845bu_float(const char *p, const formatdef *f)
846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847 return unpack_float(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000848}
849
850static PyObject *
851bu_double(const char *p, const formatdef *f)
852{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 return unpack_double(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000854}
855
Thomas Woutersb2137042007-02-01 18:02:27 +0000856static PyObject *
857bu_bool(const char *p, const formatdef *f)
858{
Xiang Zhang96f50282017-05-15 11:53:51 +0800859 return PyBool_FromLong(*p != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000860}
861
Thomas Wouters477c8d52006-05-27 19:21:47 +0000862static int
863bp_int(char *p, PyObject *v, const formatdef *f)
864{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 long x;
866 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800867 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 if (get_long(v, &x) < 0)
869 return -1;
870 i = f->size;
871 if (i != SIZEOF_LONG) {
872 if ((i == 2) && (x < -32768 || x > 32767))
873 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000874#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000875 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
876 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000877#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000878 }
879 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800880 q[--i] = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000881 x >>= 8;
882 } while (i > 0);
883 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000884}
885
886static int
887bp_uint(char *p, PyObject *v, const formatdef *f)
888{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 unsigned long x;
890 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800891 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 if (get_ulong(v, &x) < 0)
893 return -1;
894 i = f->size;
895 if (i != SIZEOF_LONG) {
896 unsigned long maxint = 1;
897 maxint <<= (unsigned long)(i * 8);
898 if (x >= maxint)
899 RANGE_ERROR(x, f, 1, maxint - 1);
900 }
901 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800902 q[--i] = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 x >>= 8;
904 } while (i > 0);
905 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000906}
907
908static int
909bp_longlong(char *p, PyObject *v, const formatdef *f)
910{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 int res;
912 v = get_pylong(v);
913 if (v == NULL)
914 return -1;
915 res = _PyLong_AsByteArray((PyLongObject *)v,
916 (unsigned char *)p,
917 8,
918 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800919 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 Py_DECREF(v);
921 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000922}
923
924static int
925bp_ulonglong(char *p, PyObject *v, const formatdef *f)
926{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 int res;
928 v = get_pylong(v);
929 if (v == NULL)
930 return -1;
931 res = _PyLong_AsByteArray((PyLongObject *)v,
932 (unsigned char *)p,
933 8,
934 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800935 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000936 Py_DECREF(v);
937 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000938}
939
940static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100941bp_halffloat(char *p, PyObject *v, const formatdef *f)
942{
943 return pack_halffloat(p, v, 0);
944}
945
946static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000947bp_float(char *p, PyObject *v, const formatdef *f)
948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 double x = PyFloat_AsDouble(v);
950 if (x == -1 && PyErr_Occurred()) {
951 PyErr_SetString(StructError,
952 "required argument is not a float");
953 return -1;
954 }
955 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000956}
957
958static int
959bp_double(char *p, PyObject *v, const formatdef *f)
960{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 double x = PyFloat_AsDouble(v);
962 if (x == -1 && PyErr_Occurred()) {
963 PyErr_SetString(StructError,
964 "required argument is not a float");
965 return -1;
966 }
967 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000968}
969
Thomas Woutersb2137042007-02-01 18:02:27 +0000970static int
971bp_bool(char *p, PyObject *v, const formatdef *f)
972{
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000973 int y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000975 if (y < 0)
976 return -1;
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000977 *p = (char)y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000979}
980
Thomas Wouters477c8d52006-05-27 19:21:47 +0000981static formatdef bigendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 {'x', 1, 0, NULL},
983 {'b', 1, 0, nu_byte, np_byte},
984 {'B', 1, 0, nu_ubyte, np_ubyte},
985 {'c', 1, 0, nu_char, np_char},
986 {'s', 1, 0, NULL},
987 {'p', 1, 0, NULL},
988 {'h', 2, 0, bu_int, bp_int},
989 {'H', 2, 0, bu_uint, bp_uint},
990 {'i', 4, 0, bu_int, bp_int},
991 {'I', 4, 0, bu_uint, bp_uint},
992 {'l', 4, 0, bu_int, bp_int},
993 {'L', 4, 0, bu_uint, bp_uint},
994 {'q', 8, 0, bu_longlong, bp_longlong},
995 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
996 {'?', 1, 0, bu_bool, bp_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100997 {'e', 2, 0, bu_halffloat, bp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000998 {'f', 4, 0, bu_float, bp_float},
999 {'d', 8, 0, bu_double, bp_double},
1000 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001001};
1002
1003/* Little-endian routines. *****************************************************/
1004
1005static PyObject *
1006lu_int(const char *p, const formatdef *f)
1007{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 long x = 0;
1009 Py_ssize_t i = f->size;
1010 const unsigned char *bytes = (const unsigned char *)p;
1011 do {
1012 x = (x<<8) | bytes[--i];
1013 } while (i > 0);
1014 /* Extend the sign bit. */
1015 if (SIZEOF_LONG > f->size)
1016 x |= -(x & (1L << ((8 * f->size) - 1)));
1017 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001018}
1019
1020static PyObject *
1021lu_uint(const char *p, const formatdef *f)
1022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 unsigned long x = 0;
1024 Py_ssize_t i = f->size;
1025 const unsigned char *bytes = (const unsigned char *)p;
1026 do {
1027 x = (x<<8) | bytes[--i];
1028 } while (i > 0);
Xiang Zhang96f50282017-05-15 11:53:51 +08001029 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001030}
1031
1032static PyObject *
1033lu_longlong(const char *p, const formatdef *f)
1034{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001035 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 Py_ssize_t i = f->size;
1037 const unsigned char *bytes = (const unsigned char *)p;
1038 do {
1039 x = (x<<8) | bytes[--i];
1040 } while (i > 0);
1041 /* Extend the sign bit. */
1042 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001043 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001045}
1046
1047static PyObject *
1048lu_ulonglong(const char *p, const formatdef *f)
1049{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001050 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 Py_ssize_t i = f->size;
1052 const unsigned char *bytes = (const unsigned char *)p;
1053 do {
1054 x = (x<<8) | bytes[--i];
1055 } while (i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001057}
1058
1059static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001060lu_halffloat(const char *p, const formatdef *f)
1061{
1062 return unpack_halffloat(p, 1);
1063}
1064
1065static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001066lu_float(const char *p, const formatdef *f)
1067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 return unpack_float(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001069}
1070
1071static PyObject *
1072lu_double(const char *p, const formatdef *f)
1073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 return unpack_double(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001075}
1076
1077static int
1078lp_int(char *p, PyObject *v, const formatdef *f)
1079{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 long x;
1081 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001082 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 if (get_long(v, &x) < 0)
1084 return -1;
1085 i = f->size;
1086 if (i != SIZEOF_LONG) {
1087 if ((i == 2) && (x < -32768 || x > 32767))
1088 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001089#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
1091 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001092#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 }
1094 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001095 *q++ = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 x >>= 8;
1097 } while (--i > 0);
1098 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001099}
1100
1101static int
1102lp_uint(char *p, PyObject *v, const formatdef *f)
1103{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 unsigned long x;
1105 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001106 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 if (get_ulong(v, &x) < 0)
1108 return -1;
1109 i = f->size;
1110 if (i != SIZEOF_LONG) {
1111 unsigned long maxint = 1;
1112 maxint <<= (unsigned long)(i * 8);
1113 if (x >= maxint)
1114 RANGE_ERROR(x, f, 1, maxint - 1);
1115 }
1116 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001117 *q++ = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 x >>= 8;
1119 } while (--i > 0);
1120 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001121}
1122
1123static int
1124lp_longlong(char *p, PyObject *v, const formatdef *f)
1125{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 int res;
1127 v = get_pylong(v);
1128 if (v == NULL)
1129 return -1;
1130 res = _PyLong_AsByteArray((PyLongObject*)v,
1131 (unsigned char *)p,
1132 8,
1133 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001134 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 Py_DECREF(v);
1136 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001137}
1138
1139static int
1140lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1141{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 int res;
1143 v = get_pylong(v);
1144 if (v == NULL)
1145 return -1;
1146 res = _PyLong_AsByteArray((PyLongObject*)v,
1147 (unsigned char *)p,
1148 8,
1149 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001150 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 Py_DECREF(v);
1152 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001153}
1154
1155static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001156lp_halffloat(char *p, PyObject *v, const formatdef *f)
1157{
1158 return pack_halffloat(p, v, 1);
1159}
1160
1161static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001162lp_float(char *p, PyObject *v, const formatdef *f)
1163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 double x = PyFloat_AsDouble(v);
1165 if (x == -1 && PyErr_Occurred()) {
1166 PyErr_SetString(StructError,
1167 "required argument is not a float");
1168 return -1;
1169 }
1170 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001171}
1172
1173static int
1174lp_double(char *p, PyObject *v, const formatdef *f)
1175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 double x = PyFloat_AsDouble(v);
1177 if (x == -1 && PyErr_Occurred()) {
1178 PyErr_SetString(StructError,
1179 "required argument is not a float");
1180 return -1;
1181 }
1182 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001183}
1184
1185static formatdef lilendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 {'x', 1, 0, NULL},
1187 {'b', 1, 0, nu_byte, np_byte},
1188 {'B', 1, 0, nu_ubyte, np_ubyte},
1189 {'c', 1, 0, nu_char, np_char},
1190 {'s', 1, 0, NULL},
1191 {'p', 1, 0, NULL},
1192 {'h', 2, 0, lu_int, lp_int},
1193 {'H', 2, 0, lu_uint, lp_uint},
1194 {'i', 4, 0, lu_int, lp_int},
1195 {'I', 4, 0, lu_uint, lp_uint},
1196 {'l', 4, 0, lu_int, lp_int},
1197 {'L', 4, 0, lu_uint, lp_uint},
1198 {'q', 8, 0, lu_longlong, lp_longlong},
1199 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1200 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1201 but potentially different from native rep -- reuse bx_bool funcs. */
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001202 {'e', 2, 0, lu_halffloat, lp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 {'f', 4, 0, lu_float, lp_float},
1204 {'d', 8, 0, lu_double, lp_double},
1205 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001206};
1207
1208
1209static const formatdef *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001210whichtable(const char **pfmt)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001211{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 const char *fmt = (*pfmt)++; /* May be backed out of later */
1213 switch (*fmt) {
1214 case '<':
1215 return lilendian_table;
1216 case '>':
1217 case '!': /* Network byte order is big-endian */
1218 return bigendian_table;
Ezio Melotti42da6632011-03-15 05:18:48 +02001219 case '=': { /* Host byte order -- different from native in alignment! */
Christian Heimes743e0cd2012-10-17 23:52:17 +02001220#if PY_LITTLE_ENDIAN
1221 return lilendian_table;
1222#else
1223 return bigendian_table;
1224#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 }
1226 default:
1227 --*pfmt; /* Back out of pointer increment */
1228 /* Fall through */
1229 case '@':
1230 return native_table;
1231 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001232}
1233
1234
1235/* Get the table entry for a format code */
1236
1237static const formatdef *
1238getentry(int c, const formatdef *f)
1239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 for (; f->format != '\0'; f++) {
1241 if (f->format == c) {
1242 return f;
1243 }
1244 }
1245 PyErr_SetString(StructError, "bad char in struct format");
1246 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001247}
1248
1249
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001250/* Align a size according to a format code. Return -1 on overflow. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001251
Mark Dickinsoneac0e682010-06-11 19:05:08 +00001252static Py_ssize_t
Thomas Wouters477c8d52006-05-27 19:21:47 +00001253align(Py_ssize_t size, char c, const formatdef *e)
1254{
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001255 Py_ssize_t extra;
1256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 if (e->format == c) {
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001258 if (e->alignment && size > 0) {
1259 extra = (e->alignment - 1) - (size - 1) % (e->alignment);
1260 if (extra > PY_SSIZE_T_MAX - size)
1261 return -1;
1262 size += extra;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 }
1264 }
1265 return size;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001266}
1267
Antoine Pitrou9f146812013-04-27 00:20:04 +02001268/*
1269 * Struct object implementation.
1270 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001271
1272/* calculate the size of a format string */
1273
1274static int
1275prepare_s(PyStructObject *self)
1276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 const formatdef *f;
1278 const formatdef *e;
1279 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 const char *s;
1282 const char *fmt;
1283 char c;
Victor Stinner706768c2014-08-16 01:03:39 +02001284 Py_ssize_t size, len, num, itemsize;
1285 size_t ncodes;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 fmt = PyBytes_AS_STRING(self->s_format);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001288
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001289 f = whichtable(&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 s = fmt;
1292 size = 0;
1293 len = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001294 ncodes = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 while ((c = *s++) != '\0') {
Antoine Pitrou4de74572013-02-09 23:11:27 +01001296 if (Py_ISSPACE(Py_CHARMASK(c)))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 continue;
1298 if ('0' <= c && c <= '9') {
1299 num = c - '0';
1300 while ('0' <= (c = *s++) && c <= '9') {
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001301 /* overflow-safe version of
1302 if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1303 if (num >= PY_SSIZE_T_MAX / 10 && (
1304 num > PY_SSIZE_T_MAX / 10 ||
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001305 (c - '0') > PY_SSIZE_T_MAX % 10))
1306 goto overflow;
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001307 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 }
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001309 if (c == '\0') {
1310 PyErr_SetString(StructError,
1311 "repeat count given without format specifier");
1312 return -1;
1313 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 }
1315 else
1316 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 e = getentry(c, f);
1319 if (e == NULL)
1320 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 switch (c) {
1323 case 's': /* fall through */
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001324 case 'p': len++; ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 case 'x': break;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001326 default: len += num; if (num) ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 itemsize = e->size;
1330 size = align(size, c, e);
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001331 if (size == -1)
1332 goto overflow;
1333
1334 /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1335 if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1336 goto overflow;
1337 size += num * itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 /* check for overflow */
Victor Stinner706768c2014-08-16 01:03:39 +02001341 if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 PyErr_NoMemory();
1343 return -1;
1344 }
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +00001345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 self->s_size = size;
1347 self->s_len = len;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001348 codes = PyMem_MALLOC((ncodes + 1) * sizeof(formatcode));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 if (codes == NULL) {
1350 PyErr_NoMemory();
1351 return -1;
1352 }
Mark Dickinsoncf28b952010-07-29 21:41:59 +00001353 /* Free any s_codes value left over from a previous initialization. */
1354 if (self->s_codes != NULL)
1355 PyMem_FREE(self->s_codes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 s = fmt;
1359 size = 0;
1360 while ((c = *s++) != '\0') {
Antoine Pitrou4de74572013-02-09 23:11:27 +01001361 if (Py_ISSPACE(Py_CHARMASK(c)))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 continue;
1363 if ('0' <= c && c <= '9') {
1364 num = c - '0';
1365 while ('0' <= (c = *s++) && c <= '9')
1366 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 }
1368 else
1369 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 size = align(size, c, e);
1374 if (c == 's' || c == 'p') {
1375 codes->offset = size;
1376 codes->size = num;
1377 codes->fmtdef = e;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001378 codes->repeat = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 codes++;
1380 size += num;
1381 } else if (c == 'x') {
1382 size += num;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001383 } else if (num) {
1384 codes->offset = size;
1385 codes->size = e->size;
1386 codes->fmtdef = e;
1387 codes->repeat = num;
1388 codes++;
1389 size += e->size * num;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 }
1391 }
1392 codes->fmtdef = NULL;
1393 codes->offset = size;
1394 codes->size = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001395 codes->repeat = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 return 0;
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001398
1399 overflow:
1400 PyErr_SetString(StructError,
1401 "total struct size too long");
1402 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001403}
1404
1405static PyObject *
1406s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 PyObject *self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 assert(type != NULL && type->tp_alloc != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 self = type->tp_alloc(type, 0);
1413 if (self != NULL) {
1414 PyStructObject *s = (PyStructObject*)self;
1415 Py_INCREF(Py_None);
1416 s->s_format = Py_None;
1417 s->s_codes = NULL;
1418 s->s_size = -1;
1419 s->s_len = -1;
1420 }
1421 return self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001422}
1423
Victor Stinner3f2d1012017-02-02 12:09:30 +01001424/*[clinic input]
1425Struct.__init__
1426
1427 format: object
1428
1429Create a compiled struct object.
1430
1431Return a new Struct object which writes and reads binary data according to
1432the format string.
1433
1434See help(struct) for more on format strings.
1435[clinic start generated code]*/
1436
Thomas Wouters477c8d52006-05-27 19:21:47 +00001437static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001438Struct___init___impl(PyStructObject *self, PyObject *format)
1439/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001440{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 int ret = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001442
Victor Stinner3f2d1012017-02-02 12:09:30 +01001443 if (PyUnicode_Check(format)) {
1444 format = PyUnicode_AsASCIIString(format);
1445 if (format == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 return -1;
1447 }
1448 /* XXX support buffer interface, too */
1449 else {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001450 Py_INCREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001452
Victor Stinner3f2d1012017-02-02 12:09:30 +01001453 if (!PyBytes_Check(format)) {
1454 Py_DECREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 PyErr_Format(PyExc_TypeError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001456 "Struct() argument 1 must be a str or bytes object, "
1457 "not %.200s",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001458 Py_TYPE(format)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 return -1;
1460 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001461
Xiang Zhang96f50282017-05-15 11:53:51 +08001462 Py_SETREF(self->s_format, format);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001463
Victor Stinner3f2d1012017-02-02 12:09:30 +01001464 ret = prepare_s(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 return ret;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001466}
1467
1468static void
1469s_dealloc(PyStructObject *s)
1470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 if (s->weakreflist != NULL)
1472 PyObject_ClearWeakRefs((PyObject *)s);
1473 if (s->s_codes != NULL) {
1474 PyMem_FREE(s->s_codes);
1475 }
Xiang Zhang96f50282017-05-15 11:53:51 +08001476 Py_DECREF(s->s_format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 Py_TYPE(s)->tp_free((PyObject *)s);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001478}
1479
1480static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001481s_unpack_internal(PyStructObject *soself, const char *startfrom) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 formatcode *code;
1483 Py_ssize_t i = 0;
1484 PyObject *result = PyTuple_New(soself->s_len);
1485 if (result == NULL)
1486 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 const formatdef *e = code->fmtdef;
1490 const char *res = startfrom + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001491 Py_ssize_t j = code->repeat;
1492 while (j--) {
1493 PyObject *v;
1494 if (e->format == 's') {
1495 v = PyBytes_FromStringAndSize(res, code->size);
1496 } else if (e->format == 'p') {
1497 Py_ssize_t n = *(unsigned char*)res;
1498 if (n >= code->size)
1499 n = code->size - 1;
1500 v = PyBytes_FromStringAndSize(res + 1, n);
1501 } else {
1502 v = e->unpack(res, e);
1503 }
1504 if (v == NULL)
1505 goto fail;
1506 PyTuple_SET_ITEM(result, i++, v);
1507 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001512fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 Py_DECREF(result);
1514 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001515}
1516
1517
Victor Stinner3f2d1012017-02-02 12:09:30 +01001518/*[clinic input]
1519Struct.unpack
1520
1521 buffer: Py_buffer
1522 /
1523
1524Return a tuple containing unpacked values.
1525
1526Unpack according to the format string Struct.format. The buffer's size
1527in bytes must be Struct.size.
1528
1529See help(struct) for more on format strings.
1530[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001531
1532static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001533Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1534/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001536 assert(self->s_codes != NULL);
1537 if (buffer->len != self->s_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 PyErr_Format(StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001539 "unpack requires a buffer of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001540 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 return NULL;
1542 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001543 return s_unpack_internal(self, buffer->buf);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544}
1545
Victor Stinner3f2d1012017-02-02 12:09:30 +01001546/*[clinic input]
1547Struct.unpack_from
1548
1549 buffer: Py_buffer
1550 offset: Py_ssize_t = 0
1551
1552Return a tuple containing unpacked values.
1553
1554Values are unpacked according to the format string Struct.format.
1555
1556The buffer's size in bytes, minus offset, must be at least Struct.size.
1557
1558See help(struct) for more on format strings.
1559[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001560
1561static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001562Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1563 Py_ssize_t offset)
1564/*[clinic end generated code: output=57fac875e0977316 input=97ade52422f8962f]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001565{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001566 assert(self->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001567
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001568 if (offset < 0)
Victor Stinner3f2d1012017-02-02 12:09:30 +01001569 offset += buffer->len;
1570 if (offset < 0 || buffer->len - offset < self->s_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001571 PyErr_Format(StructError,
1572 "unpack_from requires a buffer of at least %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001573 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 return NULL;
1575 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001576 return s_unpack_internal(self, (char*)buffer->buf + offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001577}
1578
1579
Victor Stinner3f2d1012017-02-02 12:09:30 +01001580
Antoine Pitrou9f146812013-04-27 00:20:04 +02001581/* Unpack iterator type */
1582
1583typedef struct {
1584 PyObject_HEAD
1585 PyStructObject *so;
1586 Py_buffer buf;
1587 Py_ssize_t index;
1588} unpackiterobject;
1589
1590static void
1591unpackiter_dealloc(unpackiterobject *self)
1592{
INADA Naokia6296d32017-08-24 14:55:17 +09001593 /* bpo-31095: UnTrack is needed before calling any callbacks */
1594 PyObject_GC_UnTrack(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001595 Py_XDECREF(self->so);
1596 PyBuffer_Release(&self->buf);
1597 PyObject_GC_Del(self);
1598}
1599
1600static int
1601unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1602{
1603 Py_VISIT(self->so);
1604 Py_VISIT(self->buf.obj);
1605 return 0;
1606}
1607
1608static PyObject *
1609unpackiter_len(unpackiterobject *self)
1610{
1611 Py_ssize_t len;
1612 if (self->so == NULL)
1613 len = 0;
1614 else
1615 len = (self->buf.len - self->index) / self->so->s_size;
1616 return PyLong_FromSsize_t(len);
1617}
1618
1619static PyMethodDef unpackiter_methods[] = {
1620 {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1621 {NULL, NULL} /* sentinel */
1622};
1623
1624static PyObject *
1625unpackiter_iternext(unpackiterobject *self)
1626{
1627 PyObject *result;
1628 if (self->so == NULL)
1629 return NULL;
1630 if (self->index >= self->buf.len) {
1631 /* Iterator exhausted */
1632 Py_CLEAR(self->so);
1633 PyBuffer_Release(&self->buf);
1634 return NULL;
1635 }
1636 assert(self->index + self->so->s_size <= self->buf.len);
1637 result = s_unpack_internal(self->so,
1638 (char*) self->buf.buf + self->index);
1639 self->index += self->so->s_size;
1640 return result;
1641}
1642
doko@ubuntu.com46c5deb2013-11-23 16:07:55 +01001643static PyTypeObject unpackiter_type = {
Zachary Ware854adb12016-10-02 00:33:39 -05001644 PyVarObject_HEAD_INIT(NULL, 0)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001645 "unpack_iterator", /* tp_name */
1646 sizeof(unpackiterobject), /* tp_basicsize */
1647 0, /* tp_itemsize */
1648 (destructor)unpackiter_dealloc, /* tp_dealloc */
1649 0, /* tp_print */
1650 0, /* tp_getattr */
1651 0, /* tp_setattr */
1652 0, /* tp_reserved */
1653 0, /* tp_repr */
1654 0, /* tp_as_number */
1655 0, /* tp_as_sequence */
1656 0, /* tp_as_mapping */
1657 0, /* tp_hash */
1658 0, /* tp_call */
1659 0, /* tp_str */
1660 PyObject_GenericGetAttr, /* tp_getattro */
1661 0, /* tp_setattro */
1662 0, /* tp_as_buffer */
1663 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1664 0, /* tp_doc */
1665 (traverseproc)unpackiter_traverse, /* tp_traverse */
1666 0, /* tp_clear */
1667 0, /* tp_richcompare */
1668 0, /* tp_weaklistoffset */
1669 PyObject_SelfIter, /* tp_iter */
1670 (iternextfunc)unpackiter_iternext, /* tp_iternext */
1671 unpackiter_methods /* tp_methods */
1672};
1673
Victor Stinner3f2d1012017-02-02 12:09:30 +01001674/*[clinic input]
1675Struct.iter_unpack
1676
1677 buffer: object
1678 /
1679
1680Return an iterator yielding tuples.
1681
1682Tuples are unpacked from the given bytes source, like a repeated
1683invocation of unpack_from().
1684
1685Requires that the bytes length be a multiple of the struct size.
1686[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001687
1688static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001689Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1690/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001691{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001692 unpackiterobject *iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001693
Victor Stinner3f2d1012017-02-02 12:09:30 +01001694 assert(self->s_codes != NULL);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001695
Victor Stinner3f2d1012017-02-02 12:09:30 +01001696 if (self->s_size == 0) {
Antoine Pitrou9f146812013-04-27 00:20:04 +02001697 PyErr_Format(StructError,
1698 "cannot iteratively unpack with a struct of length 0");
1699 return NULL;
1700 }
1701
Victor Stinner3f2d1012017-02-02 12:09:30 +01001702 iter = (unpackiterobject *) PyType_GenericAlloc(&unpackiter_type, 0);
1703 if (iter == NULL)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001704 return NULL;
1705
Victor Stinner3f2d1012017-02-02 12:09:30 +01001706 if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1707 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001708 return NULL;
1709 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001710 if (iter->buf.len % self->s_size != 0) {
Antoine Pitrou9f146812013-04-27 00:20:04 +02001711 PyErr_Format(StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001712 "iterative unpacking requires a buffer of "
1713 "a multiple of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001714 self->s_size);
1715 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001716 return NULL;
1717 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001718 Py_INCREF(self);
1719 iter->so = self;
1720 iter->index = 0;
1721 return (PyObject *)iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001722}
1723
1724
Thomas Wouters477c8d52006-05-27 19:21:47 +00001725/*
1726 * Guts of the pack function.
1727 *
1728 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1729 * argument for where to start processing the arguments for packing, and a
1730 * character buffer for writing the packed string. The caller must insure
1731 * that the buffer may contain the required length for packing the arguments.
1732 * 0 is returned on success, 1 is returned if there is an error.
1733 *
1734 */
1735static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001736s_pack_internal(PyStructObject *soself, PyObject **args, int offset, char* buf)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001738 formatcode *code;
1739 /* XXX(nnorwitz): why does i need to be a local? can we use
1740 the offset parameter or do we need the wider width? */
1741 Py_ssize_t i;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001742
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001743 memset(buf, '\0', soself->s_size);
1744 i = offset;
1745 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001746 const formatdef *e = code->fmtdef;
1747 char *res = buf + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001748 Py_ssize_t j = code->repeat;
1749 while (j--) {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001750 PyObject *v = args[i++];
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001751 if (e->format == 's') {
1752 Py_ssize_t n;
1753 int isstring;
1754 void *p;
1755 isstring = PyBytes_Check(v);
1756 if (!isstring && !PyByteArray_Check(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001757 PyErr_SetString(StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001758 "argument for 's' must be a bytes object");
1759 return -1;
1760 }
1761 if (isstring) {
1762 n = PyBytes_GET_SIZE(v);
1763 p = PyBytes_AS_STRING(v);
1764 }
1765 else {
1766 n = PyByteArray_GET_SIZE(v);
1767 p = PyByteArray_AS_STRING(v);
1768 }
1769 if (n > code->size)
1770 n = code->size;
1771 if (n > 0)
1772 memcpy(res, p, n);
1773 } else if (e->format == 'p') {
1774 Py_ssize_t n;
1775 int isstring;
1776 void *p;
1777 isstring = PyBytes_Check(v);
1778 if (!isstring && !PyByteArray_Check(v)) {
1779 PyErr_SetString(StructError,
1780 "argument for 'p' must be a bytes object");
1781 return -1;
1782 }
1783 if (isstring) {
1784 n = PyBytes_GET_SIZE(v);
1785 p = PyBytes_AS_STRING(v);
1786 }
1787 else {
1788 n = PyByteArray_GET_SIZE(v);
1789 p = PyByteArray_AS_STRING(v);
1790 }
1791 if (n > (code->size - 1))
1792 n = code->size - 1;
1793 if (n > 0)
1794 memcpy(res + 1, p, n);
1795 if (n > 255)
1796 n = 255;
1797 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1798 } else {
1799 if (e->pack(res, v, e) < 0) {
1800 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1801 PyErr_SetString(StructError,
Serhiy Storchaka46e1ce22013-08-27 20:17:03 +03001802 "int too large to convert");
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001803 return -1;
1804 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 }
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001806 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001807 }
1808 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001809
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001810 /* Success */
1811 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001812}
1813
1814
1815PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001816"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001817\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001818Return a bytes object containing values v1, v2, ... packed according\n\
1819to the format string S.format. See help(struct) for more on format\n\
1820strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001821
1822static PyObject *
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03001823s_pack(PyObject *self, PyObject **args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001824{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001825 PyStructObject *soself;
1826 PyObject *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 /* Validate arguments. */
1829 soself = (PyStructObject *)self;
1830 assert(PyStruct_Check(self));
1831 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001832 if (nargs != soself->s_len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 {
1834 PyErr_Format(StructError,
Victor Stinner3f2d1012017-02-02 12:09:30 +01001835 "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1836 return NULL;
1837 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001838
Xiang Zhang96f50282017-05-15 11:53:51 +08001839 /* Allocate a new buffer */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001840 result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size);
1841 if (result == NULL)
1842 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001843
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 /* Call the guts */
1845 if ( s_pack_internal(soself, args, 0, PyBytes_AS_STRING(result)) != 0 ) {
1846 Py_DECREF(result);
1847 return NULL;
1848 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001851}
1852
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001853PyDoc_STRVAR(s_pack_into__doc__,
1854"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001855\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001856Pack the values v1, v2, ... according to the format string S.format\n\
1857and write the packed bytes into the writable buffer buf starting at\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00001858offset. Note that the offset is a required argument. See\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001859help(struct) for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001860
1861static PyObject *
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03001862s_pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001863{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 PyStructObject *soself;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001865 Py_buffer buffer;
1866 Py_ssize_t offset;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 /* Validate arguments. +1 is for the first arg as buffer. */
1869 soself = (PyStructObject *)self;
1870 assert(PyStruct_Check(self));
1871 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001872 if (nargs != (soself->s_len + 2))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001874 if (nargs == 0) {
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001875 PyErr_Format(StructError,
1876 "pack_into expected buffer argument");
1877 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001878 else if (nargs == 1) {
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001879 PyErr_Format(StructError,
1880 "pack_into expected offset argument");
1881 }
1882 else {
1883 PyErr_Format(StructError,
1884 "pack_into expected %zd items for packing (got %zd)",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001885 soself->s_len, (nargs - 2));
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001886 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 return NULL;
1888 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001889
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 /* Extract a writable memory buffer from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001891 if (!PyArg_Parse(args[0], "w*", &buffer))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001893 assert(buffer.len >= 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 /* Extract the offset from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001896 offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001897 if (offset == -1 && PyErr_Occurred()) {
1898 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001899 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001900 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 /* Support negative offsets. */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001903 if (offset < 0) {
1904 /* Check that negative offset is low enough to fit data */
1905 if (offset + soself->s_size > 0) {
1906 PyErr_Format(StructError,
1907 "no space to pack %zd bytes at offset %zd",
1908 soself->s_size,
1909 offset);
1910 PyBuffer_Release(&buffer);
1911 return NULL;
1912 }
1913
1914 /* Check that negative offset is not crossing buffer boundary */
1915 if (offset + buffer.len < 0) {
1916 PyErr_Format(StructError,
1917 "offset %zd out of range for %zd-byte buffer",
1918 offset,
1919 buffer.len);
1920 PyBuffer_Release(&buffer);
1921 return NULL;
1922 }
1923
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001924 offset += buffer.len;
Andrew Nesterf78b1192017-04-04 13:46:25 +03001925 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 /* Check boundaries */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001928 if ((buffer.len - offset) < soself->s_size) {
Johan Liuaead53b2017-06-02 14:33:04 +08001929 assert(offset >= 0);
1930 assert(soself->s_size >= 0);
1931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 PyErr_Format(StructError,
Johan Liuaead53b2017-06-02 14:33:04 +08001933 "pack_into requires a buffer of at least %zu bytes for "
Andrew Nesterf78b1192017-04-04 13:46:25 +03001934 "packing %zd bytes at offset %zd "
1935 "(actual buffer size is %zd)",
Johan Liuaead53b2017-06-02 14:33:04 +08001936 (size_t)soself->s_size + (size_t)offset,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001937 soself->s_size,
1938 offset,
1939 buffer.len);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001940 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001941 return NULL;
1942 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001944 /* Call the guts */
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001945 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
1946 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001947 return NULL;
1948 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001949
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001950 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001952}
1953
1954static PyObject *
1955s_get_format(PyStructObject *self, void *unused)
1956{
Victor Stinnerf87b85f2017-06-23 15:11:12 +02001957 return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
1958 PyBytes_GET_SIZE(self->s_format));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001959}
1960
1961static PyObject *
1962s_get_size(PyStructObject *self, void *unused)
1963{
Christian Heimes217cfd12007-12-02 14:31:20 +00001964 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001965}
1966
Meador Ingeb14d8c92012-07-23 10:01:29 -05001967PyDoc_STRVAR(s_sizeof__doc__,
1968"S.__sizeof__() -> size of S in memory, in bytes");
1969
1970static PyObject *
Meador Inge90bc2dbc2012-07-28 22:16:39 -05001971s_sizeof(PyStructObject *self, void *unused)
Meador Ingeb14d8c92012-07-23 10:01:29 -05001972{
1973 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001974 formatcode *code;
Meador Ingeb14d8c92012-07-23 10:01:29 -05001975
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001976 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001977 for (code = self->s_codes; code->fmtdef != NULL; code++)
1978 size += sizeof(formatcode);
Meador Ingeb14d8c92012-07-23 10:01:29 -05001979 return PyLong_FromSsize_t(size);
1980}
1981
Thomas Wouters477c8d52006-05-27 19:21:47 +00001982/* List of functions */
1983
1984static struct PyMethodDef s_methods[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001985 STRUCT_ITER_UNPACK_METHODDEF
1986 {"pack", (PyCFunction)s_pack, METH_FASTCALL, s_pack__doc__},
1987 {"pack_into", (PyCFunction)s_pack_into, METH_FASTCALL, s_pack_into__doc__},
1988 STRUCT_UNPACK_METHODDEF
1989 STRUCT_UNPACK_FROM_METHODDEF
Meador Ingeb14d8c92012-07-23 10:01:29 -05001990 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001992};
1993
Thomas Wouters477c8d52006-05-27 19:21:47 +00001994#define OFF(x) offsetof(PyStructObject, x)
1995
1996static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001997 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1998 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1999 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002000};
2001
2002static
2003PyTypeObject PyStructType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002004 PyVarObject_HEAD_INIT(NULL, 0)
2005 "Struct",
2006 sizeof(PyStructObject),
2007 0,
2008 (destructor)s_dealloc, /* tp_dealloc */
2009 0, /* tp_print */
2010 0, /* tp_getattr */
2011 0, /* tp_setattr */
2012 0, /* tp_reserved */
2013 0, /* tp_repr */
2014 0, /* tp_as_number */
2015 0, /* tp_as_sequence */
2016 0, /* tp_as_mapping */
2017 0, /* tp_hash */
2018 0, /* tp_call */
2019 0, /* tp_str */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002020 PyObject_GenericGetAttr, /* tp_getattro */
2021 PyObject_GenericSetAttr, /* tp_setattro */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002022 0, /* tp_as_buffer */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002023 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2024 Struct___init____doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002025 0, /* tp_traverse */
2026 0, /* tp_clear */
2027 0, /* tp_richcompare */
2028 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
2029 0, /* tp_iter */
2030 0, /* tp_iternext */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002031 s_methods, /* tp_methods */
2032 NULL, /* tp_members */
2033 s_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 0, /* tp_base */
2035 0, /* tp_dict */
2036 0, /* tp_descr_get */
2037 0, /* tp_descr_set */
2038 0, /* tp_dictoffset */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002039 Struct___init__, /* tp_init */
2040 PyType_GenericAlloc, /* tp_alloc */
2041 s_new, /* tp_new */
2042 PyObject_Del, /* tp_free */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002043};
2044
Christian Heimesa34706f2008-01-04 03:06:10 +00002045
2046/* ---- Standalone functions ---- */
2047
2048#define MAXCACHE 100
2049static PyObject *cache = NULL;
2050
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002051static int
2052cache_struct_converter(PyObject *fmt, PyObject **ptr)
Christian Heimesa34706f2008-01-04 03:06:10 +00002053{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002054 PyObject * s_object;
Christian Heimesa34706f2008-01-04 03:06:10 +00002055
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002056 if (fmt == NULL) {
2057 Py_DECREF(*ptr);
Serhiy Storchaka40db90c2017-04-20 21:19:31 +03002058 *ptr = NULL;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002059 return 1;
2060 }
2061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002062 if (cache == NULL) {
2063 cache = PyDict_New();
2064 if (cache == NULL)
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002065 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002068 s_object = PyDict_GetItem(cache, fmt);
2069 if (s_object != NULL) {
2070 Py_INCREF(s_object);
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002071 *ptr = s_object;
2072 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002074
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01002075 s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 if (s_object != NULL) {
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02002077 if (PyDict_GET_SIZE(cache) >= MAXCACHE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002078 PyDict_Clear(cache);
2079 /* Attempt to cache the result */
2080 if (PyDict_SetItem(cache, fmt, s_object) == -1)
2081 PyErr_Clear();
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002082 *ptr = s_object;
2083 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002085 return 0;
Christian Heimesa34706f2008-01-04 03:06:10 +00002086}
2087
Victor Stinner3f2d1012017-02-02 12:09:30 +01002088/*[clinic input]
2089_clearcache
2090
2091Clear the internal cache.
2092[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002093
2094static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002095_clearcache_impl(PyObject *module)
2096/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002097{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002098 Py_CLEAR(cache);
2099 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00002100}
2101
Victor Stinner3f2d1012017-02-02 12:09:30 +01002102
2103/*[clinic input]
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002104calcsize -> Py_ssize_t
Victor Stinner3f2d1012017-02-02 12:09:30 +01002105
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002106 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002107 /
2108
2109Return size in bytes of the struct described by the format string.
2110[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002111
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002112static Py_ssize_t
2113calcsize_impl(PyObject *module, PyStructObject *s_object)
2114/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002115{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002116 return s_object->s_size;
Christian Heimesa34706f2008-01-04 03:06:10 +00002117}
2118
2119PyDoc_STRVAR(pack_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002120"pack(format, v1, v2, ...) -> bytes\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002121\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002122Return a bytes object containing the values v1, v2, ... packed according\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002123to the format string. See help(struct) for more on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002124
2125static PyObject *
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002126pack(PyObject *self, PyObject **args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002127{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002128 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002129 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002130
Victor Stinner3f2d1012017-02-02 12:09:30 +01002131 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002132 PyErr_SetString(PyExc_TypeError, "missing format argument");
2133 return NULL;
2134 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002135 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002136
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002137 if (!cache_struct_converter(format, &s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002138 return NULL;
2139 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002140 result = s_pack(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002141 Py_DECREF(s_object);
2142 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002143}
2144
2145PyDoc_STRVAR(pack_into_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002146"pack_into(format, buffer, offset, v1, v2, ...)\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002147\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002148Pack the values v1, v2, ... according to the format string and write\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002149the packed bytes into the writable buffer buf starting at offset. Note\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002150that the offset is a required argument. See help(struct) for more\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002151on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002152
2153static PyObject *
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002154pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs)
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 Storchaka6969eaf2017-07-03 21:20:15 +03002168 result = s_pack_into(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 Py_DECREF(s_object);
2170 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002171}
2172
Victor Stinner3f2d1012017-02-02 12:09:30 +01002173/*[clinic input]
2174unpack
2175
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002176 format as s_object: cache_struct
Victor Stinnerc0f59ad2017-02-02 14:24:16 +01002177 buffer: Py_buffer
Victor Stinner3f2d1012017-02-02 12:09:30 +01002178 /
2179
2180Return a tuple containing values unpacked according to the format string.
2181
2182The buffer's size in bytes must be calcsize(format).
2183
2184See help(struct) for more on format strings.
2185[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002186
2187static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002188unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2189/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002190{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002191 return Struct_unpack_impl(s_object, buffer);
Christian Heimesa34706f2008-01-04 03:06:10 +00002192}
2193
Victor Stinner3f2d1012017-02-02 12:09:30 +01002194/*[clinic input]
2195unpack_from
2196
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002197 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002198 /
2199 buffer: Py_buffer
2200 offset: Py_ssize_t = 0
2201
2202Return a tuple containing values unpacked according to the format string.
2203
2204The buffer's size, minus offset, must be at least calcsize(format).
2205
2206See help(struct) for more on format strings.
2207[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002208
2209static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002210unpack_from_impl(PyObject *module, PyStructObject *s_object,
2211 Py_buffer *buffer, Py_ssize_t offset)
2212/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002213{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002214 return Struct_unpack_from_impl(s_object, buffer, offset);
Christian Heimesa34706f2008-01-04 03:06:10 +00002215}
2216
Victor Stinner3f2d1012017-02-02 12:09:30 +01002217/*[clinic input]
2218iter_unpack
2219
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002220 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002221 buffer: object
2222 /
2223
2224Return an iterator yielding tuples unpacked from the given bytes.
2225
2226The bytes are unpacked according to the format string, like
2227a repeated invocation of unpack_from().
2228
2229Requires that the bytes length be a multiple of the format struct size.
2230[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002231
2232static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002233iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2234 PyObject *buffer)
2235/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002236{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002237 return Struct_iter_unpack(s_object, buffer);
Antoine Pitrou9f146812013-04-27 00:20:04 +02002238}
2239
Christian Heimesa34706f2008-01-04 03:06:10 +00002240static struct PyMethodDef module_functions[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002241 _CLEARCACHE_METHODDEF
2242 CALCSIZE_METHODDEF
2243 ITER_UNPACK_METHODDEF
2244 {"pack", (PyCFunction)pack, METH_FASTCALL, pack_doc},
2245 {"pack_into", (PyCFunction)pack_into, METH_FASTCALL, pack_into_doc},
2246 UNPACK_METHODDEF
2247 UNPACK_FROM_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002248 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00002249};
2250
2251
Thomas Wouters477c8d52006-05-27 19:21:47 +00002252/* Module initialization */
2253
Christian Heimesa34706f2008-01-04 03:06:10 +00002254PyDoc_STRVAR(module_doc,
2255"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002256Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002257and also as format strings (explained below) to describe the layout of data\n\
2258in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002259\n\
2260The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002261 @: native order, size & alignment (default)\n\
2262 =: native order, std. size & alignment\n\
2263 <: little-endian, std. size & alignment\n\
2264 >: big-endian, std. size & alignment\n\
2265 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002266\n\
2267The remaining chars indicate types of args and must match exactly;\n\
2268these can be preceded by a decimal repeat count:\n\
2269 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002270 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002271 h:short; H:unsigned short; i:int; I:unsigned int;\n\
Mark Dickinson7c4e4092016-09-03 17:21:29 +01002272 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002273Special cases (preceding decimal count indicates length):\n\
2274 s:string (array of char); p: pascal string (with count byte).\n\
Antoine Pitrou45d9c912011-10-06 15:27:40 +02002275Special cases (only available in native format):\n\
2276 n:ssize_t; N:size_t;\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002277 P:an integer type that is wide enough to hold a pointer.\n\
2278Special case (not in native mode unless 'long long' in platform C):\n\
2279 q:long long; Q:unsigned long long\n\
2280Whitespace between formats is ignored.\n\
2281\n\
2282The variable struct.error is an exception raised on errors.\n");
2283
Martin v. Löwis1a214512008-06-11 05:26:20 +00002284
2285static struct PyModuleDef _structmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002286 PyModuleDef_HEAD_INIT,
2287 "_struct",
2288 module_doc,
2289 -1,
2290 module_functions,
2291 NULL,
2292 NULL,
2293 NULL,
2294 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002295};
2296
Thomas Wouters477c8d52006-05-27 19:21:47 +00002297PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002298PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002299{
Mark Dickinson06817852010-06-12 09:25:13 +00002300 PyObject *m;
Christian Heimesa34706f2008-01-04 03:06:10 +00002301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002302 m = PyModule_Create(&_structmodule);
2303 if (m == NULL)
2304 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002306 Py_TYPE(&PyStructType) = &PyType_Type;
2307 if (PyType_Ready(&PyStructType) < 0)
2308 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002309
Zachary Ware99f11b42016-10-04 01:20:21 -05002310 if (PyType_Ready(&unpackiter_type) < 0)
2311 return NULL;
2312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002313 /* Check endian and swap in faster functions */
2314 {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002315 const formatdef *native = native_table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002316 formatdef *other, *ptr;
Christian Heimes743e0cd2012-10-17 23:52:17 +02002317#if PY_LITTLE_ENDIAN
2318 other = lilendian_table;
2319#else
2320 other = bigendian_table;
2321#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002322 /* Scan through the native table, find a matching
2323 entry in the endian table and swap in the
2324 native implementations whenever possible
2325 (64-bit platforms may not have "standard" sizes) */
2326 while (native->format != '\0' && other->format != '\0') {
2327 ptr = other;
2328 while (ptr->format != '\0') {
2329 if (ptr->format == native->format) {
2330 /* Match faster when formats are
2331 listed in the same order */
2332 if (ptr == other)
2333 other++;
2334 /* Only use the trick if the
2335 size matches */
2336 if (ptr->size != native->size)
2337 break;
2338 /* Skip float and double, could be
2339 "unknown" float format */
2340 if (ptr->format == 'd' || ptr->format == 'f')
2341 break;
2342 ptr->pack = native->pack;
2343 ptr->unpack = native->unpack;
2344 break;
2345 }
2346 ptr++;
2347 }
2348 native++;
2349 }
2350 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002351
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002352 /* Add some symbolic constants to the module */
2353 if (StructError == NULL) {
2354 StructError = PyErr_NewException("struct.error", NULL, NULL);
2355 if (StructError == NULL)
2356 return NULL;
2357 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002359 Py_INCREF(StructError);
2360 PyModule_AddObject(m, "error", StructError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002362 Py_INCREF((PyObject*)&PyStructType);
2363 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002365 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002366}