blob: 69a1e996d05d3ded56e6d8a8e0050ca0ed9be18a [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,
Victor Stinnerda9ec992010-12-28 13:26:42 +00001456 "Struct() argument 1 must be a bytes object, not %.200s",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001457 Py_TYPE(format)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 return -1;
1459 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001460
Xiang Zhang96f50282017-05-15 11:53:51 +08001461 Py_SETREF(self->s_format, format);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001462
Victor Stinner3f2d1012017-02-02 12:09:30 +01001463 ret = prepare_s(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 return ret;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001465}
1466
1467static void
1468s_dealloc(PyStructObject *s)
1469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 if (s->weakreflist != NULL)
1471 PyObject_ClearWeakRefs((PyObject *)s);
1472 if (s->s_codes != NULL) {
1473 PyMem_FREE(s->s_codes);
1474 }
Xiang Zhang96f50282017-05-15 11:53:51 +08001475 Py_DECREF(s->s_format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 Py_TYPE(s)->tp_free((PyObject *)s);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001477}
1478
1479static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001480s_unpack_internal(PyStructObject *soself, const char *startfrom) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 formatcode *code;
1482 Py_ssize_t i = 0;
1483 PyObject *result = PyTuple_New(soself->s_len);
1484 if (result == NULL)
1485 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001486
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 const formatdef *e = code->fmtdef;
1489 const char *res = startfrom + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001490 Py_ssize_t j = code->repeat;
1491 while (j--) {
1492 PyObject *v;
1493 if (e->format == 's') {
1494 v = PyBytes_FromStringAndSize(res, code->size);
1495 } else if (e->format == 'p') {
1496 Py_ssize_t n = *(unsigned char*)res;
1497 if (n >= code->size)
1498 n = code->size - 1;
1499 v = PyBytes_FromStringAndSize(res + 1, n);
1500 } else {
1501 v = e->unpack(res, e);
1502 }
1503 if (v == NULL)
1504 goto fail;
1505 PyTuple_SET_ITEM(result, i++, v);
1506 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001507 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001511fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 Py_DECREF(result);
1513 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001514}
1515
1516
Victor Stinner3f2d1012017-02-02 12:09:30 +01001517/*[clinic input]
1518Struct.unpack
1519
1520 buffer: Py_buffer
1521 /
1522
1523Return a tuple containing unpacked values.
1524
1525Unpack according to the format string Struct.format. The buffer's size
1526in bytes must be Struct.size.
1527
1528See help(struct) for more on format strings.
1529[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001530
1531static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001532Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1533/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001534{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001535 assert(self->s_codes != NULL);
1536 if (buffer->len != self->s_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 PyErr_Format(StructError,
Victor Stinnerda9ec992010-12-28 13:26:42 +00001538 "unpack requires a bytes object of length %zd",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001539 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001540 return NULL;
1541 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001542 return s_unpack_internal(self, buffer->buf);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001543}
1544
Victor Stinner3f2d1012017-02-02 12:09:30 +01001545/*[clinic input]
1546Struct.unpack_from
1547
1548 buffer: Py_buffer
1549 offset: Py_ssize_t = 0
1550
1551Return a tuple containing unpacked values.
1552
1553Values are unpacked according to the format string Struct.format.
1554
1555The buffer's size in bytes, minus offset, must be at least Struct.size.
1556
1557See help(struct) for more on format strings.
1558[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001559
1560static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001561Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1562 Py_ssize_t offset)
1563/*[clinic end generated code: output=57fac875e0977316 input=97ade52422f8962f]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001564{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001565 assert(self->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 if (offset < 0)
Victor Stinner3f2d1012017-02-02 12:09:30 +01001568 offset += buffer->len;
1569 if (offset < 0 || buffer->len - offset < self->s_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 PyErr_Format(StructError,
1571 "unpack_from requires a buffer of at least %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001572 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 return NULL;
1574 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001575 return s_unpack_internal(self, (char*)buffer->buf + offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001576}
1577
1578
Victor Stinner3f2d1012017-02-02 12:09:30 +01001579
Antoine Pitrou9f146812013-04-27 00:20:04 +02001580/* Unpack iterator type */
1581
1582typedef struct {
1583 PyObject_HEAD
1584 PyStructObject *so;
1585 Py_buffer buf;
1586 Py_ssize_t index;
1587} unpackiterobject;
1588
1589static void
1590unpackiter_dealloc(unpackiterobject *self)
1591{
INADA Naokia6296d32017-08-24 14:55:17 +09001592 /* bpo-31095: UnTrack is needed before calling any callbacks */
1593 PyObject_GC_UnTrack(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001594 Py_XDECREF(self->so);
1595 PyBuffer_Release(&self->buf);
1596 PyObject_GC_Del(self);
1597}
1598
1599static int
1600unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1601{
1602 Py_VISIT(self->so);
1603 Py_VISIT(self->buf.obj);
1604 return 0;
1605}
1606
1607static PyObject *
1608unpackiter_len(unpackiterobject *self)
1609{
1610 Py_ssize_t len;
1611 if (self->so == NULL)
1612 len = 0;
1613 else
1614 len = (self->buf.len - self->index) / self->so->s_size;
1615 return PyLong_FromSsize_t(len);
1616}
1617
1618static PyMethodDef unpackiter_methods[] = {
1619 {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1620 {NULL, NULL} /* sentinel */
1621};
1622
1623static PyObject *
1624unpackiter_iternext(unpackiterobject *self)
1625{
1626 PyObject *result;
1627 if (self->so == NULL)
1628 return NULL;
1629 if (self->index >= self->buf.len) {
1630 /* Iterator exhausted */
1631 Py_CLEAR(self->so);
1632 PyBuffer_Release(&self->buf);
1633 return NULL;
1634 }
1635 assert(self->index + self->so->s_size <= self->buf.len);
1636 result = s_unpack_internal(self->so,
1637 (char*) self->buf.buf + self->index);
1638 self->index += self->so->s_size;
1639 return result;
1640}
1641
doko@ubuntu.com46c5deb2013-11-23 16:07:55 +01001642static PyTypeObject unpackiter_type = {
Zachary Ware854adb12016-10-02 00:33:39 -05001643 PyVarObject_HEAD_INIT(NULL, 0)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001644 "unpack_iterator", /* tp_name */
1645 sizeof(unpackiterobject), /* tp_basicsize */
1646 0, /* tp_itemsize */
1647 (destructor)unpackiter_dealloc, /* tp_dealloc */
1648 0, /* tp_print */
1649 0, /* tp_getattr */
1650 0, /* tp_setattr */
1651 0, /* tp_reserved */
1652 0, /* tp_repr */
1653 0, /* tp_as_number */
1654 0, /* tp_as_sequence */
1655 0, /* tp_as_mapping */
1656 0, /* tp_hash */
1657 0, /* tp_call */
1658 0, /* tp_str */
1659 PyObject_GenericGetAttr, /* tp_getattro */
1660 0, /* tp_setattro */
1661 0, /* tp_as_buffer */
1662 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1663 0, /* tp_doc */
1664 (traverseproc)unpackiter_traverse, /* tp_traverse */
1665 0, /* tp_clear */
1666 0, /* tp_richcompare */
1667 0, /* tp_weaklistoffset */
1668 PyObject_SelfIter, /* tp_iter */
1669 (iternextfunc)unpackiter_iternext, /* tp_iternext */
1670 unpackiter_methods /* tp_methods */
1671};
1672
Victor Stinner3f2d1012017-02-02 12:09:30 +01001673/*[clinic input]
1674Struct.iter_unpack
1675
1676 buffer: object
1677 /
1678
1679Return an iterator yielding tuples.
1680
1681Tuples are unpacked from the given bytes source, like a repeated
1682invocation of unpack_from().
1683
1684Requires that the bytes length be a multiple of the struct size.
1685[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001686
1687static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001688Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1689/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001690{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001691 unpackiterobject *iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001692
Victor Stinner3f2d1012017-02-02 12:09:30 +01001693 assert(self->s_codes != NULL);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001694
Victor Stinner3f2d1012017-02-02 12:09:30 +01001695 if (self->s_size == 0) {
Antoine Pitrou9f146812013-04-27 00:20:04 +02001696 PyErr_Format(StructError,
1697 "cannot iteratively unpack with a struct of length 0");
1698 return NULL;
1699 }
1700
Victor Stinner3f2d1012017-02-02 12:09:30 +01001701 iter = (unpackiterobject *) PyType_GenericAlloc(&unpackiter_type, 0);
1702 if (iter == NULL)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001703 return NULL;
1704
Victor Stinner3f2d1012017-02-02 12:09:30 +01001705 if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1706 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001707 return NULL;
1708 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001709 if (iter->buf.len % self->s_size != 0) {
Antoine Pitrou9f146812013-04-27 00:20:04 +02001710 PyErr_Format(StructError,
1711 "iterative unpacking requires a bytes length "
1712 "multiple of %zd",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001713 self->s_size);
1714 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001715 return NULL;
1716 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001717 Py_INCREF(self);
1718 iter->so = self;
1719 iter->index = 0;
1720 return (PyObject *)iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001721}
1722
1723
Thomas Wouters477c8d52006-05-27 19:21:47 +00001724/*
1725 * Guts of the pack function.
1726 *
1727 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1728 * argument for where to start processing the arguments for packing, and a
1729 * character buffer for writing the packed string. The caller must insure
1730 * that the buffer may contain the required length for packing the arguments.
1731 * 0 is returned on success, 1 is returned if there is an error.
1732 *
1733 */
1734static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001735s_pack_internal(PyStructObject *soself, PyObject **args, int offset, char* buf)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001736{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001737 formatcode *code;
1738 /* XXX(nnorwitz): why does i need to be a local? can we use
1739 the offset parameter or do we need the wider width? */
1740 Py_ssize_t i;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001741
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001742 memset(buf, '\0', soself->s_size);
1743 i = offset;
1744 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001745 const formatdef *e = code->fmtdef;
1746 char *res = buf + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001747 Py_ssize_t j = code->repeat;
1748 while (j--) {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001749 PyObject *v = args[i++];
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001750 if (e->format == 's') {
1751 Py_ssize_t n;
1752 int isstring;
1753 void *p;
1754 isstring = PyBytes_Check(v);
1755 if (!isstring && !PyByteArray_Check(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001756 PyErr_SetString(StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001757 "argument for 's' must be a bytes object");
1758 return -1;
1759 }
1760 if (isstring) {
1761 n = PyBytes_GET_SIZE(v);
1762 p = PyBytes_AS_STRING(v);
1763 }
1764 else {
1765 n = PyByteArray_GET_SIZE(v);
1766 p = PyByteArray_AS_STRING(v);
1767 }
1768 if (n > code->size)
1769 n = code->size;
1770 if (n > 0)
1771 memcpy(res, p, n);
1772 } else if (e->format == 'p') {
1773 Py_ssize_t n;
1774 int isstring;
1775 void *p;
1776 isstring = PyBytes_Check(v);
1777 if (!isstring && !PyByteArray_Check(v)) {
1778 PyErr_SetString(StructError,
1779 "argument for 'p' must be a bytes object");
1780 return -1;
1781 }
1782 if (isstring) {
1783 n = PyBytes_GET_SIZE(v);
1784 p = PyBytes_AS_STRING(v);
1785 }
1786 else {
1787 n = PyByteArray_GET_SIZE(v);
1788 p = PyByteArray_AS_STRING(v);
1789 }
1790 if (n > (code->size - 1))
1791 n = code->size - 1;
1792 if (n > 0)
1793 memcpy(res + 1, p, n);
1794 if (n > 255)
1795 n = 255;
1796 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1797 } else {
1798 if (e->pack(res, v, e) < 0) {
1799 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1800 PyErr_SetString(StructError,
Serhiy Storchaka46e1ce22013-08-27 20:17:03 +03001801 "int too large to convert");
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001802 return -1;
1803 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001804 }
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001805 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001806 }
1807 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001808
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001809 /* Success */
1810 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001811}
1812
1813
1814PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001815"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001816\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001817Return a bytes object containing values v1, v2, ... packed according\n\
1818to the format string S.format. See help(struct) for more on format\n\
1819strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001820
1821static PyObject *
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03001822s_pack(PyObject *self, PyObject **args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001823{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001824 PyStructObject *soself;
1825 PyObject *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001826
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001827 /* Validate arguments. */
1828 soself = (PyStructObject *)self;
1829 assert(PyStruct_Check(self));
1830 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001831 if (nargs != soself->s_len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 {
1833 PyErr_Format(StructError,
Victor Stinner3f2d1012017-02-02 12:09:30 +01001834 "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1835 return NULL;
1836 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001837
Xiang Zhang96f50282017-05-15 11:53:51 +08001838 /* Allocate a new buffer */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size);
1840 if (result == NULL)
1841 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001842
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001843 /* Call the guts */
1844 if ( s_pack_internal(soself, args, 0, PyBytes_AS_STRING(result)) != 0 ) {
1845 Py_DECREF(result);
1846 return NULL;
1847 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001848
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001849 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001850}
1851
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001852PyDoc_STRVAR(s_pack_into__doc__,
1853"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001854\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001855Pack the values v1, v2, ... according to the format string S.format\n\
1856and write the packed bytes into the writable buffer buf starting at\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00001857offset. Note that the offset is a required argument. See\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001858help(struct) for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001859
1860static PyObject *
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03001861s_pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001862{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 PyStructObject *soself;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001864 Py_buffer buffer;
1865 Py_ssize_t offset;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 /* Validate arguments. +1 is for the first arg as buffer. */
1868 soself = (PyStructObject *)self;
1869 assert(PyStruct_Check(self));
1870 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001871 if (nargs != (soself->s_len + 2))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001872 {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001873 if (nargs == 0) {
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001874 PyErr_Format(StructError,
1875 "pack_into expected buffer argument");
1876 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001877 else if (nargs == 1) {
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001878 PyErr_Format(StructError,
1879 "pack_into expected offset argument");
1880 }
1881 else {
1882 PyErr_Format(StructError,
1883 "pack_into expected %zd items for packing (got %zd)",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001884 soself->s_len, (nargs - 2));
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001885 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001886 return NULL;
1887 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001888
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001889 /* Extract a writable memory buffer from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001890 if (!PyArg_Parse(args[0], "w*", &buffer))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001892 assert(buffer.len >= 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001893
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001894 /* Extract the offset from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001895 offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001896 if (offset == -1 && PyErr_Occurred()) {
1897 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001898 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001899 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001901 /* Support negative offsets. */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001902 if (offset < 0) {
1903 /* Check that negative offset is low enough to fit data */
1904 if (offset + soself->s_size > 0) {
1905 PyErr_Format(StructError,
1906 "no space to pack %zd bytes at offset %zd",
1907 soself->s_size,
1908 offset);
1909 PyBuffer_Release(&buffer);
1910 return NULL;
1911 }
1912
1913 /* Check that negative offset is not crossing buffer boundary */
1914 if (offset + buffer.len < 0) {
1915 PyErr_Format(StructError,
1916 "offset %zd out of range for %zd-byte buffer",
1917 offset,
1918 buffer.len);
1919 PyBuffer_Release(&buffer);
1920 return NULL;
1921 }
1922
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001923 offset += buffer.len;
Andrew Nesterf78b1192017-04-04 13:46:25 +03001924 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001925
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 /* Check boundaries */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001927 if ((buffer.len - offset) < soself->s_size) {
Johan Liuaead53b2017-06-02 14:33:04 +08001928 assert(offset >= 0);
1929 assert(soself->s_size >= 0);
1930
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 PyErr_Format(StructError,
Johan Liuaead53b2017-06-02 14:33:04 +08001932 "pack_into requires a buffer of at least %zu bytes for "
Andrew Nesterf78b1192017-04-04 13:46:25 +03001933 "packing %zd bytes at offset %zd "
1934 "(actual buffer size is %zd)",
Johan Liuaead53b2017-06-02 14:33:04 +08001935 (size_t)soself->s_size + (size_t)offset,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001936 soself->s_size,
1937 offset,
1938 buffer.len);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001939 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 return NULL;
1941 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 /* Call the guts */
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001944 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
1945 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 return NULL;
1947 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001948
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001949 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001951}
1952
1953static PyObject *
1954s_get_format(PyStructObject *self, void *unused)
1955{
Victor Stinnerf87b85f2017-06-23 15:11:12 +02001956 return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
1957 PyBytes_GET_SIZE(self->s_format));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001958}
1959
1960static PyObject *
1961s_get_size(PyStructObject *self, void *unused)
1962{
Christian Heimes217cfd12007-12-02 14:31:20 +00001963 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001964}
1965
Meador Ingeb14d8c92012-07-23 10:01:29 -05001966PyDoc_STRVAR(s_sizeof__doc__,
1967"S.__sizeof__() -> size of S in memory, in bytes");
1968
1969static PyObject *
Meador Inge90bc2dbc2012-07-28 22:16:39 -05001970s_sizeof(PyStructObject *self, void *unused)
Meador Ingeb14d8c92012-07-23 10:01:29 -05001971{
1972 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001973 formatcode *code;
Meador Ingeb14d8c92012-07-23 10:01:29 -05001974
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001975 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001976 for (code = self->s_codes; code->fmtdef != NULL; code++)
1977 size += sizeof(formatcode);
Meador Ingeb14d8c92012-07-23 10:01:29 -05001978 return PyLong_FromSsize_t(size);
1979}
1980
Thomas Wouters477c8d52006-05-27 19:21:47 +00001981/* List of functions */
1982
1983static struct PyMethodDef s_methods[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001984 STRUCT_ITER_UNPACK_METHODDEF
1985 {"pack", (PyCFunction)s_pack, METH_FASTCALL, s_pack__doc__},
1986 {"pack_into", (PyCFunction)s_pack_into, METH_FASTCALL, s_pack_into__doc__},
1987 STRUCT_UNPACK_METHODDEF
1988 STRUCT_UNPACK_FROM_METHODDEF
Meador Ingeb14d8c92012-07-23 10:01:29 -05001989 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001990 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001991};
1992
Thomas Wouters477c8d52006-05-27 19:21:47 +00001993#define OFF(x) offsetof(PyStructObject, x)
1994
1995static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001996 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
1997 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
1998 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001999};
2000
2001static
2002PyTypeObject PyStructType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002003 PyVarObject_HEAD_INIT(NULL, 0)
2004 "Struct",
2005 sizeof(PyStructObject),
2006 0,
2007 (destructor)s_dealloc, /* tp_dealloc */
2008 0, /* tp_print */
2009 0, /* tp_getattr */
2010 0, /* tp_setattr */
2011 0, /* tp_reserved */
2012 0, /* tp_repr */
2013 0, /* tp_as_number */
2014 0, /* tp_as_sequence */
2015 0, /* tp_as_mapping */
2016 0, /* tp_hash */
2017 0, /* tp_call */
2018 0, /* tp_str */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002019 PyObject_GenericGetAttr, /* tp_getattro */
2020 PyObject_GenericSetAttr, /* tp_setattro */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002021 0, /* tp_as_buffer */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002022 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2023 Struct___init____doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 0, /* tp_traverse */
2025 0, /* tp_clear */
2026 0, /* tp_richcompare */
2027 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
2028 0, /* tp_iter */
2029 0, /* tp_iternext */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002030 s_methods, /* tp_methods */
2031 NULL, /* tp_members */
2032 s_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002033 0, /* tp_base */
2034 0, /* tp_dict */
2035 0, /* tp_descr_get */
2036 0, /* tp_descr_set */
2037 0, /* tp_dictoffset */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002038 Struct___init__, /* tp_init */
2039 PyType_GenericAlloc, /* tp_alloc */
2040 s_new, /* tp_new */
2041 PyObject_Del, /* tp_free */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002042};
2043
Christian Heimesa34706f2008-01-04 03:06:10 +00002044
2045/* ---- Standalone functions ---- */
2046
2047#define MAXCACHE 100
2048static PyObject *cache = NULL;
2049
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002050static int
2051cache_struct_converter(PyObject *fmt, PyObject **ptr)
Christian Heimesa34706f2008-01-04 03:06:10 +00002052{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002053 PyObject * s_object;
Christian Heimesa34706f2008-01-04 03:06:10 +00002054
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002055 if (fmt == NULL) {
2056 Py_DECREF(*ptr);
Serhiy Storchaka40db90c2017-04-20 21:19:31 +03002057 *ptr = NULL;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002058 return 1;
2059 }
2060
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 if (cache == NULL) {
2062 cache = PyDict_New();
2063 if (cache == NULL)
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002064 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002065 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 s_object = PyDict_GetItem(cache, fmt);
2068 if (s_object != NULL) {
2069 Py_INCREF(s_object);
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002070 *ptr = s_object;
2071 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002072 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002073
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01002074 s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002075 if (s_object != NULL) {
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02002076 if (PyDict_GET_SIZE(cache) >= MAXCACHE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 PyDict_Clear(cache);
2078 /* Attempt to cache the result */
2079 if (PyDict_SetItem(cache, fmt, s_object) == -1)
2080 PyErr_Clear();
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002081 *ptr = s_object;
2082 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002083 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002084 return 0;
Christian Heimesa34706f2008-01-04 03:06:10 +00002085}
2086
Victor Stinner3f2d1012017-02-02 12:09:30 +01002087/*[clinic input]
2088_clearcache
2089
2090Clear the internal cache.
2091[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002092
2093static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002094_clearcache_impl(PyObject *module)
2095/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002096{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 Py_CLEAR(cache);
2098 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00002099}
2100
Victor Stinner3f2d1012017-02-02 12:09:30 +01002101
2102/*[clinic input]
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002103calcsize -> Py_ssize_t
Victor Stinner3f2d1012017-02-02 12:09:30 +01002104
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002105 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002106 /
2107
2108Return size in bytes of the struct described by the format string.
2109[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002110
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002111static Py_ssize_t
2112calcsize_impl(PyObject *module, PyStructObject *s_object)
2113/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002114{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002115 return s_object->s_size;
Christian Heimesa34706f2008-01-04 03:06:10 +00002116}
2117
2118PyDoc_STRVAR(pack_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002119"pack(format, v1, v2, ...) -> bytes\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002120\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002121Return a bytes object containing the values v1, v2, ... packed according\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002122to the format string. See help(struct) for more on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002123
2124static PyObject *
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002125pack(PyObject *self, PyObject **args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002126{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002127 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002128 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002129
Victor Stinner3f2d1012017-02-02 12:09:30 +01002130 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002131 PyErr_SetString(PyExc_TypeError, "missing format argument");
2132 return NULL;
2133 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002134 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002135
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002136 if (!cache_struct_converter(format, &s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 return NULL;
2138 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002139 result = s_pack(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002140 Py_DECREF(s_object);
2141 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002142}
2143
2144PyDoc_STRVAR(pack_into_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002145"pack_into(format, buffer, offset, v1, v2, ...)\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002146\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002147Pack the values v1, v2, ... according to the format string and write\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002148the packed bytes into the writable buffer buf starting at offset. Note\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002149that the offset is a required argument. See help(struct) for more\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002150on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002151
2152static PyObject *
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002153pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002154{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002155 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002156 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002157
Victor Stinner3f2d1012017-02-02 12:09:30 +01002158 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002159 PyErr_SetString(PyExc_TypeError, "missing format argument");
2160 return NULL;
2161 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002162 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002163
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002164 if (!cache_struct_converter(format, &s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002165 return NULL;
2166 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002167 result = s_pack_into(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 Py_DECREF(s_object);
2169 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002170}
2171
Victor Stinner3f2d1012017-02-02 12:09:30 +01002172/*[clinic input]
2173unpack
2174
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002175 format as s_object: cache_struct
Victor Stinnerc0f59ad2017-02-02 14:24:16 +01002176 buffer: Py_buffer
Victor Stinner3f2d1012017-02-02 12:09:30 +01002177 /
2178
2179Return a tuple containing values unpacked according to the format string.
2180
2181The buffer's size in bytes must be calcsize(format).
2182
2183See help(struct) for more on format strings.
2184[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002185
2186static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002187unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2188/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002189{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002190 return Struct_unpack_impl(s_object, buffer);
Christian Heimesa34706f2008-01-04 03:06:10 +00002191}
2192
Victor Stinner3f2d1012017-02-02 12:09:30 +01002193/*[clinic input]
2194unpack_from
2195
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002196 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002197 /
2198 buffer: Py_buffer
2199 offset: Py_ssize_t = 0
2200
2201Return a tuple containing values unpacked according to the format string.
2202
2203The buffer's size, minus offset, must be at least calcsize(format).
2204
2205See help(struct) for more on format strings.
2206[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002207
2208static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002209unpack_from_impl(PyObject *module, PyStructObject *s_object,
2210 Py_buffer *buffer, Py_ssize_t offset)
2211/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002212{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002213 return Struct_unpack_from_impl(s_object, buffer, offset);
Christian Heimesa34706f2008-01-04 03:06:10 +00002214}
2215
Victor Stinner3f2d1012017-02-02 12:09:30 +01002216/*[clinic input]
2217iter_unpack
2218
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002219 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002220 buffer: object
2221 /
2222
2223Return an iterator yielding tuples unpacked from the given bytes.
2224
2225The bytes are unpacked according to the format string, like
2226a repeated invocation of unpack_from().
2227
2228Requires that the bytes length be a multiple of the format struct size.
2229[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002230
2231static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002232iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2233 PyObject *buffer)
2234/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002235{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002236 return Struct_iter_unpack(s_object, buffer);
Antoine Pitrou9f146812013-04-27 00:20:04 +02002237}
2238
Christian Heimesa34706f2008-01-04 03:06:10 +00002239static struct PyMethodDef module_functions[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002240 _CLEARCACHE_METHODDEF
2241 CALCSIZE_METHODDEF
2242 ITER_UNPACK_METHODDEF
2243 {"pack", (PyCFunction)pack, METH_FASTCALL, pack_doc},
2244 {"pack_into", (PyCFunction)pack_into, METH_FASTCALL, pack_into_doc},
2245 UNPACK_METHODDEF
2246 UNPACK_FROM_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002247 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00002248};
2249
2250
Thomas Wouters477c8d52006-05-27 19:21:47 +00002251/* Module initialization */
2252
Christian Heimesa34706f2008-01-04 03:06:10 +00002253PyDoc_STRVAR(module_doc,
2254"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002255Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002256and also as format strings (explained below) to describe the layout of data\n\
2257in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002258\n\
2259The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002260 @: native order, size & alignment (default)\n\
2261 =: native order, std. size & alignment\n\
2262 <: little-endian, std. size & alignment\n\
2263 >: big-endian, std. size & alignment\n\
2264 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002265\n\
2266The remaining chars indicate types of args and must match exactly;\n\
2267these can be preceded by a decimal repeat count:\n\
2268 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002269 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002270 h:short; H:unsigned short; i:int; I:unsigned int;\n\
Mark Dickinson7c4e4092016-09-03 17:21:29 +01002271 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002272Special cases (preceding decimal count indicates length):\n\
2273 s:string (array of char); p: pascal string (with count byte).\n\
Antoine Pitrou45d9c912011-10-06 15:27:40 +02002274Special cases (only available in native format):\n\
2275 n:ssize_t; N:size_t;\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002276 P:an integer type that is wide enough to hold a pointer.\n\
2277Special case (not in native mode unless 'long long' in platform C):\n\
2278 q:long long; Q:unsigned long long\n\
2279Whitespace between formats is ignored.\n\
2280\n\
2281The variable struct.error is an exception raised on errors.\n");
2282
Martin v. Löwis1a214512008-06-11 05:26:20 +00002283
2284static struct PyModuleDef _structmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 PyModuleDef_HEAD_INIT,
2286 "_struct",
2287 module_doc,
2288 -1,
2289 module_functions,
2290 NULL,
2291 NULL,
2292 NULL,
2293 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002294};
2295
Thomas Wouters477c8d52006-05-27 19:21:47 +00002296PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002297PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002298{
Mark Dickinson06817852010-06-12 09:25:13 +00002299 PyObject *m;
Christian Heimesa34706f2008-01-04 03:06:10 +00002300
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002301 m = PyModule_Create(&_structmodule);
2302 if (m == NULL)
2303 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002304
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 Py_TYPE(&PyStructType) = &PyType_Type;
2306 if (PyType_Ready(&PyStructType) < 0)
2307 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002308
Zachary Ware99f11b42016-10-04 01:20:21 -05002309 if (PyType_Ready(&unpackiter_type) < 0)
2310 return NULL;
2311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002312 /* Check endian and swap in faster functions */
2313 {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002314 const formatdef *native = native_table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002315 formatdef *other, *ptr;
Christian Heimes743e0cd2012-10-17 23:52:17 +02002316#if PY_LITTLE_ENDIAN
2317 other = lilendian_table;
2318#else
2319 other = bigendian_table;
2320#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002321 /* Scan through the native table, find a matching
2322 entry in the endian table and swap in the
2323 native implementations whenever possible
2324 (64-bit platforms may not have "standard" sizes) */
2325 while (native->format != '\0' && other->format != '\0') {
2326 ptr = other;
2327 while (ptr->format != '\0') {
2328 if (ptr->format == native->format) {
2329 /* Match faster when formats are
2330 listed in the same order */
2331 if (ptr == other)
2332 other++;
2333 /* Only use the trick if the
2334 size matches */
2335 if (ptr->size != native->size)
2336 break;
2337 /* Skip float and double, could be
2338 "unknown" float format */
2339 if (ptr->format == 'd' || ptr->format == 'f')
2340 break;
2341 ptr->pack = native->pack;
2342 ptr->unpack = native->unpack;
2343 break;
2344 }
2345 ptr++;
2346 }
2347 native++;
2348 }
2349 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 /* Add some symbolic constants to the module */
2352 if (StructError == NULL) {
2353 StructError = PyErr_NewException("struct.error", NULL, NULL);
2354 if (StructError == NULL)
2355 return NULL;
2356 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002358 Py_INCREF(StructError);
2359 PyModule_AddObject(m, "error", StructError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002360
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002361 Py_INCREF((PyObject*)&PyStructType);
2362 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002364 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002365}