blob: 64a9827e83aaeed473493518ce0231de4ae0a176 [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
Serhiy Storchaka32d96a22018-12-25 13:23:47 +020099static int cache_struct_converter(PyObject *, PyStructObject **);
Serhiy Storchakaa5a55902017-02-04 11:14:52 +0200100
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);
Zackery Spytz5ff5edf2020-05-26 02:57:09 -06001288 if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(self->s_format)) {
1289 PyErr_SetString(StructError, "embedded null character");
1290 return -1;
1291 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001292
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001293 f = whichtable(&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 s = fmt;
1296 size = 0;
1297 len = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001298 ncodes = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 while ((c = *s++) != '\0') {
Antoine Pitrou4de74572013-02-09 23:11:27 +01001300 if (Py_ISSPACE(Py_CHARMASK(c)))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 continue;
1302 if ('0' <= c && c <= '9') {
1303 num = c - '0';
1304 while ('0' <= (c = *s++) && c <= '9') {
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001305 /* overflow-safe version of
1306 if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1307 if (num >= PY_SSIZE_T_MAX / 10 && (
1308 num > PY_SSIZE_T_MAX / 10 ||
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001309 (c - '0') > PY_SSIZE_T_MAX % 10))
1310 goto overflow;
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001311 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 }
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001313 if (c == '\0') {
1314 PyErr_SetString(StructError,
1315 "repeat count given without format specifier");
1316 return -1;
1317 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 }
1319 else
1320 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 e = getentry(c, f);
1323 if (e == NULL)
1324 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 switch (c) {
1327 case 's': /* fall through */
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001328 case 'p': len++; ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 case 'x': break;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001330 default: len += num; if (num) ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 itemsize = e->size;
1334 size = align(size, c, e);
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001335 if (size == -1)
1336 goto overflow;
1337
1338 /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1339 if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1340 goto overflow;
1341 size += num * itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 /* check for overflow */
Victor Stinner706768c2014-08-16 01:03:39 +02001345 if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 PyErr_NoMemory();
1347 return -1;
1348 }
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +00001349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 self->s_size = size;
1351 self->s_len = len;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001352 codes = PyMem_MALLOC((ncodes + 1) * sizeof(formatcode));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 if (codes == NULL) {
1354 PyErr_NoMemory();
1355 return -1;
1356 }
Mark Dickinsoncf28b952010-07-29 21:41:59 +00001357 /* Free any s_codes value left over from a previous initialization. */
1358 if (self->s_codes != NULL)
1359 PyMem_FREE(self->s_codes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 s = fmt;
1363 size = 0;
1364 while ((c = *s++) != '\0') {
Antoine Pitrou4de74572013-02-09 23:11:27 +01001365 if (Py_ISSPACE(Py_CHARMASK(c)))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 continue;
1367 if ('0' <= c && c <= '9') {
1368 num = c - '0';
1369 while ('0' <= (c = *s++) && c <= '9')
1370 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 }
1372 else
1373 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 size = align(size, c, e);
1378 if (c == 's' || c == 'p') {
1379 codes->offset = size;
1380 codes->size = num;
1381 codes->fmtdef = e;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001382 codes->repeat = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 codes++;
1384 size += num;
1385 } else if (c == 'x') {
1386 size += num;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001387 } else if (num) {
1388 codes->offset = size;
1389 codes->size = e->size;
1390 codes->fmtdef = e;
1391 codes->repeat = num;
1392 codes++;
1393 size += e->size * num;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 }
1395 }
1396 codes->fmtdef = NULL;
1397 codes->offset = size;
1398 codes->size = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001399 codes->repeat = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 return 0;
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001402
1403 overflow:
1404 PyErr_SetString(StructError,
1405 "total struct size too long");
1406 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001407}
1408
1409static PyObject *
1410s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 PyObject *self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 assert(type != NULL && type->tp_alloc != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 self = type->tp_alloc(type, 0);
1417 if (self != NULL) {
1418 PyStructObject *s = (PyStructObject*)self;
1419 Py_INCREF(Py_None);
1420 s->s_format = Py_None;
1421 s->s_codes = NULL;
1422 s->s_size = -1;
1423 s->s_len = -1;
1424 }
1425 return self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001426}
1427
Victor Stinner3f2d1012017-02-02 12:09:30 +01001428/*[clinic input]
1429Struct.__init__
1430
1431 format: object
1432
1433Create a compiled struct object.
1434
1435Return a new Struct object which writes and reads binary data according to
1436the format string.
1437
1438See help(struct) for more on format strings.
1439[clinic start generated code]*/
1440
Thomas Wouters477c8d52006-05-27 19:21:47 +00001441static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001442Struct___init___impl(PyStructObject *self, PyObject *format)
1443/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001444{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001445 int ret = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001446
Victor Stinner3f2d1012017-02-02 12:09:30 +01001447 if (PyUnicode_Check(format)) {
1448 format = PyUnicode_AsASCIIString(format);
1449 if (format == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 return -1;
1451 }
1452 /* XXX support buffer interface, too */
1453 else {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001454 Py_INCREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001456
Victor Stinner3f2d1012017-02-02 12:09:30 +01001457 if (!PyBytes_Check(format)) {
1458 Py_DECREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 PyErr_Format(PyExc_TypeError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001460 "Struct() argument 1 must be a str or bytes object, "
1461 "not %.200s",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001462 Py_TYPE(format)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001463 return -1;
1464 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001465
Xiang Zhang96f50282017-05-15 11:53:51 +08001466 Py_SETREF(self->s_format, format);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001467
Victor Stinner3f2d1012017-02-02 12:09:30 +01001468 ret = prepare_s(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 return ret;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001470}
1471
1472static void
1473s_dealloc(PyStructObject *s)
1474{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 if (s->weakreflist != NULL)
1476 PyObject_ClearWeakRefs((PyObject *)s);
1477 if (s->s_codes != NULL) {
1478 PyMem_FREE(s->s_codes);
1479 }
Xiang Zhang96f50282017-05-15 11:53:51 +08001480 Py_DECREF(s->s_format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 Py_TYPE(s)->tp_free((PyObject *)s);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001482}
1483
1484static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001485s_unpack_internal(PyStructObject *soself, const char *startfrom) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001486 formatcode *code;
1487 Py_ssize_t i = 0;
1488 PyObject *result = PyTuple_New(soself->s_len);
1489 if (result == NULL)
1490 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001491
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 const formatdef *e = code->fmtdef;
1494 const char *res = startfrom + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001495 Py_ssize_t j = code->repeat;
1496 while (j--) {
1497 PyObject *v;
1498 if (e->format == 's') {
1499 v = PyBytes_FromStringAndSize(res, code->size);
1500 } else if (e->format == 'p') {
1501 Py_ssize_t n = *(unsigned char*)res;
1502 if (n >= code->size)
1503 n = code->size - 1;
1504 v = PyBytes_FromStringAndSize(res + 1, n);
1505 } else {
1506 v = e->unpack(res, e);
1507 }
1508 if (v == NULL)
1509 goto fail;
1510 PyTuple_SET_ITEM(result, i++, v);
1511 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001516fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 Py_DECREF(result);
1518 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001519}
1520
1521
Victor Stinner3f2d1012017-02-02 12:09:30 +01001522/*[clinic input]
1523Struct.unpack
1524
1525 buffer: Py_buffer
1526 /
1527
1528Return a tuple containing unpacked values.
1529
1530Unpack according to the format string Struct.format. The buffer's size
1531in bytes must be Struct.size.
1532
1533See help(struct) for more on format strings.
1534[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535
1536static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001537Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1538/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001539{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001540 assert(self->s_codes != NULL);
1541 if (buffer->len != self->s_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 PyErr_Format(StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001543 "unpack requires a buffer of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001544 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 return NULL;
1546 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001547 return s_unpack_internal(self, buffer->buf);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001548}
1549
Victor Stinner3f2d1012017-02-02 12:09:30 +01001550/*[clinic input]
1551Struct.unpack_from
1552
1553 buffer: Py_buffer
1554 offset: Py_ssize_t = 0
1555
1556Return a tuple containing unpacked values.
1557
1558Values are unpacked according to the format string Struct.format.
1559
Xiang Zhangc10b2882018-03-11 02:58:52 +08001560The buffer's size in bytes, starting at position offset, must be
1561at least Struct.size.
Victor Stinner3f2d1012017-02-02 12:09:30 +01001562
1563See help(struct) for more on format strings.
1564[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001565
1566static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001567Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1568 Py_ssize_t offset)
Xiang Zhangc10b2882018-03-11 02:58:52 +08001569/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001570{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001571 assert(self->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001572
Xiang Zhangc10b2882018-03-11 02:58:52 +08001573 if (offset < 0) {
1574 if (offset + self->s_size > 0) {
1575 PyErr_Format(StructError,
1576 "not enough data to unpack %zd bytes at offset %zd",
1577 self->s_size,
1578 offset);
1579 return NULL;
1580 }
1581
1582 if (offset + buffer->len < 0) {
1583 PyErr_Format(StructError,
1584 "offset %zd out of range for %zd-byte buffer",
1585 offset,
1586 buffer->len);
1587 return NULL;
1588 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001589 offset += buffer->len;
Xiang Zhangc10b2882018-03-11 02:58:52 +08001590 }
1591
1592 if ((buffer->len - offset) < self->s_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 PyErr_Format(StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001594 "unpack_from requires a buffer of at least %zu bytes for "
1595 "unpacking %zd bytes at offset %zd "
1596 "(actual buffer size is %zd)",
1597 (size_t)self->s_size + (size_t)offset,
1598 self->s_size,
1599 offset,
1600 buffer->len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 return NULL;
1602 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001603 return s_unpack_internal(self, (char*)buffer->buf + offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001604}
1605
1606
Victor Stinner3f2d1012017-02-02 12:09:30 +01001607
Antoine Pitrou9f146812013-04-27 00:20:04 +02001608/* Unpack iterator type */
1609
1610typedef struct {
1611 PyObject_HEAD
1612 PyStructObject *so;
1613 Py_buffer buf;
1614 Py_ssize_t index;
1615} unpackiterobject;
1616
1617static void
1618unpackiter_dealloc(unpackiterobject *self)
1619{
INADA Naokia6296d32017-08-24 14:55:17 +09001620 /* bpo-31095: UnTrack is needed before calling any callbacks */
1621 PyObject_GC_UnTrack(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001622 Py_XDECREF(self->so);
1623 PyBuffer_Release(&self->buf);
1624 PyObject_GC_Del(self);
1625}
1626
1627static int
1628unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1629{
1630 Py_VISIT(self->so);
1631 Py_VISIT(self->buf.obj);
1632 return 0;
1633}
1634
1635static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301636unpackiter_len(unpackiterobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou9f146812013-04-27 00:20:04 +02001637{
1638 Py_ssize_t len;
1639 if (self->so == NULL)
1640 len = 0;
1641 else
1642 len = (self->buf.len - self->index) / self->so->s_size;
1643 return PyLong_FromSsize_t(len);
1644}
1645
1646static PyMethodDef unpackiter_methods[] = {
1647 {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1648 {NULL, NULL} /* sentinel */
1649};
1650
1651static PyObject *
1652unpackiter_iternext(unpackiterobject *self)
1653{
1654 PyObject *result;
1655 if (self->so == NULL)
1656 return NULL;
1657 if (self->index >= self->buf.len) {
1658 /* Iterator exhausted */
1659 Py_CLEAR(self->so);
1660 PyBuffer_Release(&self->buf);
1661 return NULL;
1662 }
1663 assert(self->index + self->so->s_size <= self->buf.len);
1664 result = s_unpack_internal(self->so,
1665 (char*) self->buf.buf + self->index);
1666 self->index += self->so->s_size;
1667 return result;
1668}
1669
doko@ubuntu.com46c5deb2013-11-23 16:07:55 +01001670static PyTypeObject unpackiter_type = {
Zachary Ware854adb12016-10-02 00:33:39 -05001671 PyVarObject_HEAD_INIT(NULL, 0)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001672 "unpack_iterator", /* tp_name */
1673 sizeof(unpackiterobject), /* tp_basicsize */
1674 0, /* tp_itemsize */
1675 (destructor)unpackiter_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001676 0, /* tp_vectorcall_offset */
Antoine Pitrou9f146812013-04-27 00:20:04 +02001677 0, /* tp_getattr */
1678 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02001679 0, /* tp_as_async */
Antoine Pitrou9f146812013-04-27 00:20:04 +02001680 0, /* tp_repr */
1681 0, /* tp_as_number */
1682 0, /* tp_as_sequence */
1683 0, /* tp_as_mapping */
1684 0, /* tp_hash */
1685 0, /* tp_call */
1686 0, /* tp_str */
1687 PyObject_GenericGetAttr, /* tp_getattro */
1688 0, /* tp_setattro */
1689 0, /* tp_as_buffer */
1690 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1691 0, /* tp_doc */
1692 (traverseproc)unpackiter_traverse, /* tp_traverse */
1693 0, /* tp_clear */
1694 0, /* tp_richcompare */
1695 0, /* tp_weaklistoffset */
1696 PyObject_SelfIter, /* tp_iter */
1697 (iternextfunc)unpackiter_iternext, /* tp_iternext */
1698 unpackiter_methods /* tp_methods */
1699};
1700
Victor Stinner3f2d1012017-02-02 12:09:30 +01001701/*[clinic input]
1702Struct.iter_unpack
1703
1704 buffer: object
1705 /
1706
1707Return an iterator yielding tuples.
1708
1709Tuples are unpacked from the given bytes source, like a repeated
1710invocation of unpack_from().
1711
1712Requires that the bytes length be a multiple of the struct size.
1713[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001714
1715static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001716Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1717/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001718{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001719 unpackiterobject *iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001720
Victor Stinner3f2d1012017-02-02 12:09:30 +01001721 assert(self->s_codes != NULL);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001722
Victor Stinner3f2d1012017-02-02 12:09:30 +01001723 if (self->s_size == 0) {
Antoine Pitrou9f146812013-04-27 00:20:04 +02001724 PyErr_Format(StructError,
1725 "cannot iteratively unpack with a struct of length 0");
1726 return NULL;
1727 }
1728
Victor Stinner3f2d1012017-02-02 12:09:30 +01001729 iter = (unpackiterobject *) PyType_GenericAlloc(&unpackiter_type, 0);
1730 if (iter == NULL)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001731 return NULL;
1732
Victor Stinner3f2d1012017-02-02 12:09:30 +01001733 if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1734 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001735 return NULL;
1736 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001737 if (iter->buf.len % self->s_size != 0) {
Antoine Pitrou9f146812013-04-27 00:20:04 +02001738 PyErr_Format(StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001739 "iterative unpacking requires a buffer of "
1740 "a multiple of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001741 self->s_size);
1742 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001743 return NULL;
1744 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001745 Py_INCREF(self);
1746 iter->so = self;
1747 iter->index = 0;
1748 return (PyObject *)iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001749}
1750
1751
Thomas Wouters477c8d52006-05-27 19:21:47 +00001752/*
1753 * Guts of the pack function.
1754 *
1755 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1756 * argument for where to start processing the arguments for packing, and a
1757 * character buffer for writing the packed string. The caller must insure
1758 * that the buffer may contain the required length for packing the arguments.
1759 * 0 is returned on success, 1 is returned if there is an error.
1760 *
1761 */
1762static int
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001763s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* buf)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001764{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001765 formatcode *code;
1766 /* XXX(nnorwitz): why does i need to be a local? can we use
1767 the offset parameter or do we need the wider width? */
1768 Py_ssize_t i;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001769
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001770 memset(buf, '\0', soself->s_size);
1771 i = offset;
1772 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001773 const formatdef *e = code->fmtdef;
1774 char *res = buf + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001775 Py_ssize_t j = code->repeat;
1776 while (j--) {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001777 PyObject *v = args[i++];
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001778 if (e->format == 's') {
1779 Py_ssize_t n;
1780 int isstring;
1781 void *p;
1782 isstring = PyBytes_Check(v);
1783 if (!isstring && !PyByteArray_Check(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001784 PyErr_SetString(StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001785 "argument for 's' must be a bytes object");
1786 return -1;
1787 }
1788 if (isstring) {
1789 n = PyBytes_GET_SIZE(v);
1790 p = PyBytes_AS_STRING(v);
1791 }
1792 else {
1793 n = PyByteArray_GET_SIZE(v);
1794 p = PyByteArray_AS_STRING(v);
1795 }
1796 if (n > code->size)
1797 n = code->size;
1798 if (n > 0)
1799 memcpy(res, p, n);
1800 } else if (e->format == 'p') {
1801 Py_ssize_t n;
1802 int isstring;
1803 void *p;
1804 isstring = PyBytes_Check(v);
1805 if (!isstring && !PyByteArray_Check(v)) {
1806 PyErr_SetString(StructError,
1807 "argument for 'p' must be a bytes object");
1808 return -1;
1809 }
1810 if (isstring) {
1811 n = PyBytes_GET_SIZE(v);
1812 p = PyBytes_AS_STRING(v);
1813 }
1814 else {
1815 n = PyByteArray_GET_SIZE(v);
1816 p = PyByteArray_AS_STRING(v);
1817 }
1818 if (n > (code->size - 1))
1819 n = code->size - 1;
1820 if (n > 0)
1821 memcpy(res + 1, p, n);
1822 if (n > 255)
1823 n = 255;
1824 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1825 } else {
1826 if (e->pack(res, v, e) < 0) {
1827 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1828 PyErr_SetString(StructError,
Serhiy Storchaka46e1ce22013-08-27 20:17:03 +03001829 "int too large to convert");
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001830 return -1;
1831 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001832 }
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001833 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001834 }
1835 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001836
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001837 /* Success */
1838 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001839}
1840
1841
1842PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001843"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001844\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001845Return a bytes object containing values v1, v2, ... packed according\n\
1846to the format string S.format. See help(struct) for more on format\n\
1847strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001848
1849static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001850s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001851{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001852 PyStructObject *soself;
1853 PyObject *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001854
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001855 /* Validate arguments. */
1856 soself = (PyStructObject *)self;
1857 assert(PyStruct_Check(self));
1858 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001859 if (nargs != soself->s_len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 {
1861 PyErr_Format(StructError,
Victor Stinner3f2d1012017-02-02 12:09:30 +01001862 "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1863 return NULL;
1864 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001865
Xiang Zhang96f50282017-05-15 11:53:51 +08001866 /* Allocate a new buffer */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size);
1868 if (result == NULL)
1869 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001870
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001871 /* Call the guts */
1872 if ( s_pack_internal(soself, args, 0, PyBytes_AS_STRING(result)) != 0 ) {
1873 Py_DECREF(result);
1874 return NULL;
1875 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001876
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001877 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001878}
1879
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001880PyDoc_STRVAR(s_pack_into__doc__,
1881"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001882\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001883Pack the values v1, v2, ... according to the format string S.format\n\
1884and write the packed bytes into the writable buffer buf starting at\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00001885offset. Note that the offset is a required argument. See\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001886help(struct) for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001887
1888static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001889s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001890{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 PyStructObject *soself;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001892 Py_buffer buffer;
1893 Py_ssize_t offset;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001894
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001895 /* Validate arguments. +1 is for the first arg as buffer. */
1896 soself = (PyStructObject *)self;
1897 assert(PyStruct_Check(self));
1898 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001899 if (nargs != (soself->s_len + 2))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001901 if (nargs == 0) {
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001902 PyErr_Format(StructError,
1903 "pack_into expected buffer argument");
1904 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001905 else if (nargs == 1) {
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001906 PyErr_Format(StructError,
1907 "pack_into expected offset argument");
1908 }
1909 else {
1910 PyErr_Format(StructError,
1911 "pack_into expected %zd items for packing (got %zd)",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001912 soself->s_len, (nargs - 2));
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001913 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001914 return NULL;
1915 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001916
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 /* Extract a writable memory buffer from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001918 if (!PyArg_Parse(args[0], "w*", &buffer))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001920 assert(buffer.len >= 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 /* Extract the offset from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001923 offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001924 if (offset == -1 && PyErr_Occurred()) {
1925 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001926 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001927 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001928
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001929 /* Support negative offsets. */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001930 if (offset < 0) {
1931 /* Check that negative offset is low enough to fit data */
1932 if (offset + soself->s_size > 0) {
1933 PyErr_Format(StructError,
1934 "no space to pack %zd bytes at offset %zd",
1935 soself->s_size,
1936 offset);
1937 PyBuffer_Release(&buffer);
1938 return NULL;
1939 }
1940
1941 /* Check that negative offset is not crossing buffer boundary */
1942 if (offset + buffer.len < 0) {
1943 PyErr_Format(StructError,
1944 "offset %zd out of range for %zd-byte buffer",
1945 offset,
1946 buffer.len);
1947 PyBuffer_Release(&buffer);
1948 return NULL;
1949 }
1950
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001951 offset += buffer.len;
Andrew Nesterf78b1192017-04-04 13:46:25 +03001952 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 /* Check boundaries */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001955 if ((buffer.len - offset) < soself->s_size) {
Johan Liuaead53b2017-06-02 14:33:04 +08001956 assert(offset >= 0);
1957 assert(soself->s_size >= 0);
1958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 PyErr_Format(StructError,
Johan Liuaead53b2017-06-02 14:33:04 +08001960 "pack_into requires a buffer of at least %zu bytes for "
Andrew Nesterf78b1192017-04-04 13:46:25 +03001961 "packing %zd bytes at offset %zd "
1962 "(actual buffer size is %zd)",
Johan Liuaead53b2017-06-02 14:33:04 +08001963 (size_t)soself->s_size + (size_t)offset,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001964 soself->s_size,
1965 offset,
1966 buffer.len);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001967 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001968 return NULL;
1969 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 /* Call the guts */
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001972 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
1973 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 return NULL;
1975 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001976
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001977 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001978 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001979}
1980
1981static PyObject *
1982s_get_format(PyStructObject *self, void *unused)
1983{
Victor Stinnerf87b85f2017-06-23 15:11:12 +02001984 return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
1985 PyBytes_GET_SIZE(self->s_format));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001986}
1987
1988static PyObject *
1989s_get_size(PyStructObject *self, void *unused)
1990{
Christian Heimes217cfd12007-12-02 14:31:20 +00001991 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001992}
1993
Meador Ingeb14d8c92012-07-23 10:01:29 -05001994PyDoc_STRVAR(s_sizeof__doc__,
1995"S.__sizeof__() -> size of S in memory, in bytes");
1996
1997static PyObject *
Meador Inge90bc2dbc2012-07-28 22:16:39 -05001998s_sizeof(PyStructObject *self, void *unused)
Meador Ingeb14d8c92012-07-23 10:01:29 -05001999{
2000 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002001 formatcode *code;
Meador Ingeb14d8c92012-07-23 10:01:29 -05002002
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002003 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002004 for (code = self->s_codes; code->fmtdef != NULL; code++)
2005 size += sizeof(formatcode);
Meador Ingeb14d8c92012-07-23 10:01:29 -05002006 return PyLong_FromSsize_t(size);
2007}
2008
Thomas Wouters477c8d52006-05-27 19:21:47 +00002009/* List of functions */
2010
2011static struct PyMethodDef s_methods[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002012 STRUCT_ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002013 {"pack", (PyCFunction)(void(*)(void))s_pack, METH_FASTCALL, s_pack__doc__},
2014 {"pack_into", (PyCFunction)(void(*)(void))s_pack_into, METH_FASTCALL, s_pack_into__doc__},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002015 STRUCT_UNPACK_METHODDEF
2016 STRUCT_UNPACK_FROM_METHODDEF
Meador Ingeb14d8c92012-07-23 10:01:29 -05002017 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002018 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002019};
2020
Thomas Wouters477c8d52006-05-27 19:21:47 +00002021#define OFF(x) offsetof(PyStructObject, x)
2022
2023static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002024 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
2025 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
2026 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002027};
2028
2029static
2030PyTypeObject PyStructType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002031 PyVarObject_HEAD_INIT(NULL, 0)
2032 "Struct",
2033 sizeof(PyStructObject),
2034 0,
2035 (destructor)s_dealloc, /* tp_dealloc */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002036 0, /* tp_vectorcall_offset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002037 0, /* tp_getattr */
2038 0, /* tp_setattr */
Jeroen Demeyer530f5062019-05-31 04:13:39 +02002039 0, /* tp_as_async */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 0, /* tp_repr */
2041 0, /* tp_as_number */
2042 0, /* tp_as_sequence */
2043 0, /* tp_as_mapping */
2044 0, /* tp_hash */
2045 0, /* tp_call */
2046 0, /* tp_str */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002047 PyObject_GenericGetAttr, /* tp_getattro */
2048 PyObject_GenericSetAttr, /* tp_setattro */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002049 0, /* tp_as_buffer */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002050 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2051 Struct___init____doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002052 0, /* tp_traverse */
2053 0, /* tp_clear */
2054 0, /* tp_richcompare */
2055 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
2056 0, /* tp_iter */
2057 0, /* tp_iternext */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002058 s_methods, /* tp_methods */
2059 NULL, /* tp_members */
2060 s_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 0, /* tp_base */
2062 0, /* tp_dict */
2063 0, /* tp_descr_get */
2064 0, /* tp_descr_set */
2065 0, /* tp_dictoffset */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002066 Struct___init__, /* tp_init */
2067 PyType_GenericAlloc, /* tp_alloc */
2068 s_new, /* tp_new */
2069 PyObject_Del, /* tp_free */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002070};
2071
Christian Heimesa34706f2008-01-04 03:06:10 +00002072
2073/* ---- Standalone functions ---- */
2074
2075#define MAXCACHE 100
2076static PyObject *cache = NULL;
2077
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002078static int
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002079cache_struct_converter(PyObject *fmt, PyStructObject **ptr)
Christian Heimesa34706f2008-01-04 03:06:10 +00002080{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002081 PyObject * s_object;
Christian Heimesa34706f2008-01-04 03:06:10 +00002082
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002083 if (fmt == NULL) {
2084 Py_DECREF(*ptr);
Serhiy Storchaka40db90c2017-04-20 21:19:31 +03002085 *ptr = NULL;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002086 return 1;
2087 }
2088
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002089 if (cache == NULL) {
2090 cache = PyDict_New();
2091 if (cache == NULL)
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002092 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002094
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002095 s_object = PyDict_GetItemWithError(cache, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 if (s_object != NULL) {
2097 Py_INCREF(s_object);
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002098 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002099 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002101 else if (PyErr_Occurred()) {
2102 return 0;
2103 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002104
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01002105 s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002106 if (s_object != NULL) {
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02002107 if (PyDict_GET_SIZE(cache) >= MAXCACHE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 PyDict_Clear(cache);
2109 /* Attempt to cache the result */
2110 if (PyDict_SetItem(cache, fmt, s_object) == -1)
2111 PyErr_Clear();
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002112 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002113 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002114 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002115 return 0;
Christian Heimesa34706f2008-01-04 03:06:10 +00002116}
2117
Victor Stinner3f2d1012017-02-02 12:09:30 +01002118/*[clinic input]
2119_clearcache
2120
2121Clear the internal cache.
2122[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002123
2124static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002125_clearcache_impl(PyObject *module)
2126/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002127{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 Py_CLEAR(cache);
2129 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00002130}
2131
Victor Stinner3f2d1012017-02-02 12:09:30 +01002132
2133/*[clinic input]
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002134calcsize -> Py_ssize_t
Victor Stinner3f2d1012017-02-02 12:09:30 +01002135
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002136 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002137 /
2138
2139Return size in bytes of the struct described by the format string.
2140[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002141
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002142static Py_ssize_t
2143calcsize_impl(PyObject *module, PyStructObject *s_object)
2144/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002145{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002146 return s_object->s_size;
Christian Heimesa34706f2008-01-04 03:06:10 +00002147}
2148
2149PyDoc_STRVAR(pack_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002150"pack(format, v1, v2, ...) -> bytes\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002151\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002152Return a bytes object containing the values v1, v2, ... packed according\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002153to the format string. See help(struct) for more on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002154
2155static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02002156pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002157{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002158 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002159 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002160
Victor Stinner3f2d1012017-02-02 12:09:30 +01002161 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002162 PyErr_SetString(PyExc_TypeError, "missing format argument");
2163 return NULL;
2164 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002165 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002166
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002167 if (!cache_struct_converter(format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002168 return NULL;
2169 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002170 result = s_pack(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002171 Py_DECREF(s_object);
2172 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002173}
2174
2175PyDoc_STRVAR(pack_into_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002176"pack_into(format, buffer, offset, v1, v2, ...)\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002177\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002178Pack the values v1, v2, ... according to the format string and write\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002179the packed bytes into the writable buffer buf starting at offset. Note\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002180that the offset is a required argument. See help(struct) for more\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002181on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002182
2183static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02002184pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002185{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002186 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002187 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002188
Victor Stinner3f2d1012017-02-02 12:09:30 +01002189 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190 PyErr_SetString(PyExc_TypeError, "missing format argument");
2191 return NULL;
2192 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002193 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002194
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002195 if (!cache_struct_converter(format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 return NULL;
2197 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002198 result = s_pack_into(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 Py_DECREF(s_object);
2200 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002201}
2202
Victor Stinner3f2d1012017-02-02 12:09:30 +01002203/*[clinic input]
2204unpack
2205
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002206 format as s_object: cache_struct
Victor Stinnerc0f59ad2017-02-02 14:24:16 +01002207 buffer: Py_buffer
Victor Stinner3f2d1012017-02-02 12:09:30 +01002208 /
2209
2210Return a tuple containing values unpacked according to the format string.
2211
2212The buffer's size in bytes must be calcsize(format).
2213
2214See help(struct) for more on format strings.
2215[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002216
2217static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002218unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2219/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002220{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002221 return Struct_unpack_impl(s_object, buffer);
Christian Heimesa34706f2008-01-04 03:06:10 +00002222}
2223
Victor Stinner3f2d1012017-02-02 12:09:30 +01002224/*[clinic input]
2225unpack_from
2226
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002227 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002228 /
2229 buffer: Py_buffer
2230 offset: Py_ssize_t = 0
2231
2232Return a tuple containing values unpacked according to the format string.
2233
2234The buffer's size, minus offset, must be at least calcsize(format).
2235
2236See help(struct) for more on format strings.
2237[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002238
2239static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002240unpack_from_impl(PyObject *module, PyStructObject *s_object,
2241 Py_buffer *buffer, Py_ssize_t offset)
2242/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002243{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002244 return Struct_unpack_from_impl(s_object, buffer, offset);
Christian Heimesa34706f2008-01-04 03:06:10 +00002245}
2246
Victor Stinner3f2d1012017-02-02 12:09:30 +01002247/*[clinic input]
2248iter_unpack
2249
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002250 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002251 buffer: object
2252 /
2253
2254Return an iterator yielding tuples unpacked from the given bytes.
2255
2256The bytes are unpacked according to the format string, like
2257a repeated invocation of unpack_from().
2258
2259Requires that the bytes length be a multiple of the format struct size.
2260[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002261
2262static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002263iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2264 PyObject *buffer)
2265/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002266{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002267 return Struct_iter_unpack(s_object, buffer);
Antoine Pitrou9f146812013-04-27 00:20:04 +02002268}
2269
Christian Heimesa34706f2008-01-04 03:06:10 +00002270static struct PyMethodDef module_functions[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002271 _CLEARCACHE_METHODDEF
2272 CALCSIZE_METHODDEF
2273 ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002274 {"pack", (PyCFunction)(void(*)(void))pack, METH_FASTCALL, pack_doc},
2275 {"pack_into", (PyCFunction)(void(*)(void))pack_into, METH_FASTCALL, pack_into_doc},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002276 UNPACK_METHODDEF
2277 UNPACK_FROM_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002278 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00002279};
2280
2281
Thomas Wouters477c8d52006-05-27 19:21:47 +00002282/* Module initialization */
2283
Christian Heimesa34706f2008-01-04 03:06:10 +00002284PyDoc_STRVAR(module_doc,
2285"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002286Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002287and also as format strings (explained below) to describe the layout of data\n\
2288in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002289\n\
2290The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002291 @: native order, size & alignment (default)\n\
2292 =: native order, std. size & alignment\n\
2293 <: little-endian, std. size & alignment\n\
2294 >: big-endian, std. size & alignment\n\
2295 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002296\n\
2297The remaining chars indicate types of args and must match exactly;\n\
2298these can be preceded by a decimal repeat count:\n\
2299 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002300 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002301 h:short; H:unsigned short; i:int; I:unsigned int;\n\
Mark Dickinson7c4e4092016-09-03 17:21:29 +01002302 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002303Special cases (preceding decimal count indicates length):\n\
2304 s:string (array of char); p: pascal string (with count byte).\n\
Antoine Pitrou45d9c912011-10-06 15:27:40 +02002305Special cases (only available in native format):\n\
2306 n:ssize_t; N:size_t;\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002307 P:an integer type that is wide enough to hold a pointer.\n\
2308Special case (not in native mode unless 'long long' in platform C):\n\
2309 q:long long; Q:unsigned long long\n\
2310Whitespace between formats is ignored.\n\
2311\n\
2312The variable struct.error is an exception raised on errors.\n");
2313
Martin v. Löwis1a214512008-06-11 05:26:20 +00002314
2315static struct PyModuleDef _structmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002316 PyModuleDef_HEAD_INIT,
2317 "_struct",
2318 module_doc,
2319 -1,
2320 module_functions,
2321 NULL,
2322 NULL,
2323 NULL,
2324 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002325};
2326
Thomas Wouters477c8d52006-05-27 19:21:47 +00002327PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002328PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002329{
Mark Dickinson06817852010-06-12 09:25:13 +00002330 PyObject *m;
Christian Heimesa34706f2008-01-04 03:06:10 +00002331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002332 m = PyModule_Create(&_structmodule);
2333 if (m == NULL)
2334 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002336 Py_TYPE(&PyStructType) = &PyType_Type;
2337 if (PyType_Ready(&PyStructType) < 0)
2338 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002339
Zachary Ware99f11b42016-10-04 01:20:21 -05002340 if (PyType_Ready(&unpackiter_type) < 0)
2341 return NULL;
2342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002343 /* Check endian and swap in faster functions */
2344 {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002345 const formatdef *native = native_table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002346 formatdef *other, *ptr;
Christian Heimes743e0cd2012-10-17 23:52:17 +02002347#if PY_LITTLE_ENDIAN
2348 other = lilendian_table;
2349#else
2350 other = bigendian_table;
2351#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002352 /* Scan through the native table, find a matching
2353 entry in the endian table and swap in the
2354 native implementations whenever possible
2355 (64-bit platforms may not have "standard" sizes) */
2356 while (native->format != '\0' && other->format != '\0') {
2357 ptr = other;
2358 while (ptr->format != '\0') {
2359 if (ptr->format == native->format) {
2360 /* Match faster when formats are
2361 listed in the same order */
2362 if (ptr == other)
2363 other++;
2364 /* Only use the trick if the
2365 size matches */
2366 if (ptr->size != native->size)
2367 break;
2368 /* Skip float and double, could be
2369 "unknown" float format */
2370 if (ptr->format == 'd' || ptr->format == 'f')
2371 break;
Miss Islington (bot)572ef742020-03-31 05:26:05 -07002372 /* Skip _Bool, semantics are different for standard size */
2373 if (ptr->format == '?')
2374 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 ptr->pack = native->pack;
2376 ptr->unpack = native->unpack;
2377 break;
2378 }
2379 ptr++;
2380 }
2381 native++;
2382 }
2383 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002385 /* Add some symbolic constants to the module */
2386 if (StructError == NULL) {
2387 StructError = PyErr_NewException("struct.error", NULL, NULL);
2388 if (StructError == NULL)
2389 return NULL;
2390 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002392 Py_INCREF(StructError);
2393 PyModule_AddObject(m, "error", StructError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 Py_INCREF((PyObject*)&PyStructType);
2396 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002397
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002399}