blob: 81cdbb9b817d3120c13a9a0f8f8b09b7f390a2c7 [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"
Victor Stinner4a21e572020-04-15 02:35:41 +02009#include "structmember.h" // PyMemberDef
Thomas Wouters477c8d52006-05-27 19:21:47 +000010#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
Dino Viehland4f384af2019-09-10 11:18:37 +010017typedef struct {
18 PyObject *PyStructType;
19 PyObject *unpackiter_type;
20 PyObject *StructError;
21} _structmodulestate;
22
Hai Shif707d942020-03-16 21:15:01 +080023static inline _structmodulestate*
24get_struct_state(PyObject *module)
25{
26 void *state = PyModule_GetState(module);
27 assert(state != NULL);
28 return (_structmodulestate *)state;
29}
Dino Viehland4f384af2019-09-10 11:18:37 +010030
31static struct PyModuleDef _structmodule;
32
Hai Shif707d942020-03-16 21:15:01 +080033#define _structmodulestate_global get_struct_state(PyState_FindModule(&_structmodule))
Thomas Wouters477c8d52006-05-27 19:21:47 +000034
Thomas Wouters477c8d52006-05-27 19:21:47 +000035/* The translation function for each format character is table driven */
36typedef struct _formatdef {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037 char format;
38 Py_ssize_t size;
39 Py_ssize_t alignment;
40 PyObject* (*unpack)(const char *,
41 const struct _formatdef *);
42 int (*pack)(char *, PyObject *,
43 const struct _formatdef *);
Thomas Wouters477c8d52006-05-27 19:21:47 +000044} formatdef;
45
46typedef struct _formatcode {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000047 const struct _formatdef *fmtdef;
48 Py_ssize_t offset;
49 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +030050 Py_ssize_t repeat;
Thomas Wouters477c8d52006-05-27 19:21:47 +000051} formatcode;
52
53/* Struct object interface */
54
55typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000056 PyObject_HEAD
57 Py_ssize_t s_size;
58 Py_ssize_t s_len;
59 formatcode *s_codes;
60 PyObject *s_format;
61 PyObject *weakreflist; /* List of weak references */
Thomas Wouters477c8d52006-05-27 19:21:47 +000062} PyStructObject;
63
64
Dino Viehland4f384af2019-09-10 11:18:37 +010065#define PyStruct_Check(op) PyObject_TypeCheck(op, (PyTypeObject *)_structmodulestate_global->PyStructType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090066#define PyStruct_CheckExact(op) Py_IS_TYPE(op, (PyTypeObject *)_structmodulestate_global->PyStructType)
Thomas Wouters477c8d52006-05-27 19:21:47 +000067
68
69/* Define various structs to figure out the alignments of types */
70
71
72typedef struct { char c; short x; } st_short;
73typedef struct { char c; int x; } st_int;
74typedef struct { char c; long x; } st_long;
75typedef struct { char c; float x; } st_float;
76typedef struct { char c; double x; } st_double;
77typedef struct { char c; void *x; } st_void_p;
Antoine Pitrou45d9c912011-10-06 15:27:40 +020078typedef struct { char c; size_t x; } st_size_t;
Benjamin Petersona9296e72016-09-07 11:06:17 -070079typedef struct { char c; _Bool x; } st_bool;
Thomas Wouters477c8d52006-05-27 19:21:47 +000080
81#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
82#define INT_ALIGN (sizeof(st_int) - sizeof(int))
83#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
84#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
85#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
86#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
Antoine Pitrou45d9c912011-10-06 15:27:40 +020087#define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t))
Benjamin Petersona9296e72016-09-07 11:06:17 -070088#define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool))
Thomas Wouters477c8d52006-05-27 19:21:47 +000089
90/* We can't support q and Q in native mode unless the compiler does;
91 in std mode, they're 8 bytes on all platforms. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -070092typedef struct { char c; long long x; } s_long_long;
93#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long))
Thomas Wouters477c8d52006-05-27 19:21:47 +000094
Thomas Wouters477c8d52006-05-27 19:21:47 +000095#ifdef __powerc
96#pragma options align=reset
97#endif
98
Serhiy Storchakaa5a55902017-02-04 11:14:52 +020099/*[python input]
100class cache_struct_converter(CConverter):
101 type = 'PyStructObject *'
102 converter = 'cache_struct_converter'
103 c_default = "NULL"
104
105 def cleanup(self):
106 return "Py_XDECREF(%s);\n" % self.name
107[python start generated code]*/
108/*[python end generated code: output=da39a3ee5e6b4b0d input=49957cca130ffb63]*/
109
Serhiy Storchaka32d96a22018-12-25 13:23:47 +0200110static int cache_struct_converter(PyObject *, PyStructObject **);
Serhiy Storchakaa5a55902017-02-04 11:14:52 +0200111
Victor Stinner3f2d1012017-02-02 12:09:30 +0100112#include "clinic/_struct.c.h"
113
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000114/* Helper for integer format codes: converts an arbitrary Python object to a
115 PyLongObject if possible, otherwise fails. Caller should decref. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000116
117static PyObject *
118get_pylong(PyObject *v)
119{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 assert(v != NULL);
121 if (!PyLong_Check(v)) {
122 /* Not an integer; try to use __index__ to convert. */
123 if (PyIndex_Check(v)) {
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300124 v = _PyNumber_Index(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 if (v == NULL)
126 return NULL;
127 }
128 else {
Dino Viehland4f384af2019-09-10 11:18:37 +0100129 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 "required argument is not an integer");
131 return NULL;
132 }
133 }
134 else
135 Py_INCREF(v);
Mark Dickinsonea835e72009-04-19 20:40:33 +0000136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 assert(PyLong_Check(v));
138 return v;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000139}
140
Mark Dickinsonea835e72009-04-19 20:40:33 +0000141/* Helper routine to get a C long and raise the appropriate error if it isn't
142 one */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000143
144static int
145get_long(PyObject *v, long *p)
146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 v = get_pylong(v);
150 if (v == NULL)
151 return -1;
152 assert(PyLong_Check(v));
153 x = PyLong_AsLong(v);
154 Py_DECREF(v);
155 if (x == (long)-1 && PyErr_Occurred()) {
156 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100157 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 "argument out of range");
159 return -1;
160 }
161 *p = x;
162 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000163}
164
165
166/* Same, but handling unsigned long */
167
168static int
169get_ulong(PyObject *v, unsigned long *p)
170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 unsigned long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 v = get_pylong(v);
174 if (v == NULL)
175 return -1;
176 assert(PyLong_Check(v));
177 x = PyLong_AsUnsignedLong(v);
178 Py_DECREF(v);
179 if (x == (unsigned long)-1 && PyErr_Occurred()) {
180 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100181 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 "argument out of range");
183 return -1;
184 }
185 *p = x;
186 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000187}
188
Thomas Wouters477c8d52006-05-27 19:21:47 +0000189/* Same, but handling native long long. */
190
191static int
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700192get_longlong(PyObject *v, long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000193{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700194 long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 v = get_pylong(v);
197 if (v == NULL)
198 return -1;
199 assert(PyLong_Check(v));
200 x = PyLong_AsLongLong(v);
201 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700202 if (x == (long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100204 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 "argument out of range");
206 return -1;
207 }
208 *p = x;
209 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000210}
211
212/* Same, but handling native unsigned long long. */
213
214static int
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700215get_ulonglong(PyObject *v, unsigned long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000216{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700217 unsigned long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000219 v = get_pylong(v);
220 if (v == NULL)
221 return -1;
222 assert(PyLong_Check(v));
223 x = PyLong_AsUnsignedLongLong(v);
224 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700225 if (x == (unsigned long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100227 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 "argument out of range");
229 return -1;
230 }
231 *p = x;
232 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000233}
234
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200235/* Same, but handling Py_ssize_t */
236
237static int
238get_ssize_t(PyObject *v, Py_ssize_t *p)
239{
240 Py_ssize_t x;
241
242 v = get_pylong(v);
243 if (v == NULL)
244 return -1;
245 assert(PyLong_Check(v));
246 x = PyLong_AsSsize_t(v);
247 Py_DECREF(v);
248 if (x == (Py_ssize_t)-1 && PyErr_Occurred()) {
249 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100250 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200251 "argument out of range");
252 return -1;
253 }
254 *p = x;
255 return 0;
256}
257
258/* Same, but handling size_t */
259
260static int
261get_size_t(PyObject *v, size_t *p)
262{
263 size_t x;
264
265 v = get_pylong(v);
266 if (v == NULL)
267 return -1;
268 assert(PyLong_Check(v));
269 x = PyLong_AsSize_t(v);
270 Py_DECREF(v);
271 if (x == (size_t)-1 && PyErr_Occurred()) {
272 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100273 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200274 "argument out of range");
275 return -1;
276 }
277 *p = x;
278 return 0;
279}
280
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000281
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000282#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
283
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000284
Thomas Wouters477c8d52006-05-27 19:21:47 +0000285/* Floating point helpers */
286
287static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100288unpack_halffloat(const char *p, /* start of 2-byte string */
289 int le) /* true for little-endian, false for big-endian */
290{
291 double x;
292
293 x = _PyFloat_Unpack2((unsigned char *)p, le);
294 if (x == -1.0 && PyErr_Occurred()) {
295 return NULL;
296 }
297 return PyFloat_FromDouble(x);
298}
299
300static int
301pack_halffloat(char *p, /* start of 2-byte string */
302 PyObject *v, /* value to pack */
303 int le) /* true for little-endian, false for big-endian */
304{
305 double x = PyFloat_AsDouble(v);
306 if (x == -1.0 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100307 PyErr_SetString(_structmodulestate_global->StructError,
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100308 "required argument is not a float");
309 return -1;
310 }
311 return _PyFloat_Pack2(x, (unsigned char *)p, le);
312}
313
314static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000315unpack_float(const char *p, /* start of 4-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 x = _PyFloat_Unpack4((unsigned char *)p, le);
321 if (x == -1.0 && PyErr_Occurred())
322 return NULL;
323 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324}
325
326static PyObject *
327unpack_double(const char *p, /* start of 8-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 x = _PyFloat_Unpack8((unsigned char *)p, le);
333 if (x == -1.0 && PyErr_Occurred())
334 return NULL;
335 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000336}
337
338/* Helper to format the range error exceptions */
339static int
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000340_range_error(const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 /* ulargest is the largest unsigned value with f->size bytes.
343 * Note that the simpler:
344 * ((size_t)1 << (f->size * 8)) - 1
345 * doesn't work when f->size == sizeof(size_t) because C doesn't
346 * define what happens when a left shift count is >= the number of
347 * bits in the integer being shifted; e.g., on some boxes it doesn't
348 * shift at all when they're equal.
349 */
350 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
351 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
352 if (is_unsigned)
Dino Viehland4f384af2019-09-10 11:18:37 +0100353 PyErr_Format(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 "'%c' format requires 0 <= number <= %zu",
355 f->format,
356 ulargest);
357 else {
358 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
Dino Viehland4f384af2019-09-10 11:18:37 +0100359 PyErr_Format(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 "'%c' format requires %zd <= number <= %zd",
361 f->format,
362 ~ largest,
363 largest);
364 }
Mark Dickinsonae681df2009-03-21 10:26:31 +0000365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000367}
368
369
370
371/* A large number of small routines follow, with names of the form
372
373 [bln][up]_TYPE
374
Min ho Kimc4cacc82019-07-31 08:16:13 +1000375 [bln] distinguishes among big-endian, little-endian and native.
376 [pu] distinguishes between pack (to struct) and unpack (from struct).
Thomas Wouters477c8d52006-05-27 19:21:47 +0000377 TYPE is one of char, byte, ubyte, etc.
378*/
379
380/* Native mode routines. ****************************************************/
381/* NOTE:
382 In all n[up]_<type> routines handling types larger than 1 byte, there is
383 *no* guarantee that the p pointer is properly aligned for each type,
384 therefore memcpy is called. An intermediate variable is used to
385 compensate for big-endian architectures.
386 Normally both the intermediate variable and the memcpy call will be
387 skipped by C optimisation in little-endian architectures (gcc >= 2.91
388 does this). */
389
390static PyObject *
391nu_char(const char *p, const formatdef *f)
392{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 return PyBytes_FromStringAndSize(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000394}
395
396static PyObject *
397nu_byte(const char *p, const formatdef *f)
398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 return PyLong_FromLong((long) *(signed char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000400}
401
402static PyObject *
403nu_ubyte(const char *p, const formatdef *f)
404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 return PyLong_FromLong((long) *(unsigned char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000406}
407
408static PyObject *
409nu_short(const char *p, const formatdef *f)
410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 short x;
412 memcpy((char *)&x, p, sizeof x);
413 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000414}
415
416static PyObject *
417nu_ushort(const char *p, const formatdef *f)
418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 unsigned short x;
420 memcpy((char *)&x, p, sizeof x);
421 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000422}
423
424static PyObject *
425nu_int(const char *p, const formatdef *f)
426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 int x;
428 memcpy((char *)&x, p, sizeof x);
429 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000430}
431
432static PyObject *
433nu_uint(const char *p, const formatdef *f)
434{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 unsigned int x;
436 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 return PyLong_FromUnsignedLong((unsigned long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000438}
439
440static PyObject *
441nu_long(const char *p, const formatdef *f)
442{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 long x;
444 memcpy((char *)&x, p, sizeof x);
445 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000446}
447
448static PyObject *
449nu_ulong(const char *p, const formatdef *f)
450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 unsigned long x;
452 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000454}
455
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200456static PyObject *
457nu_ssize_t(const char *p, const formatdef *f)
458{
459 Py_ssize_t x;
460 memcpy((char *)&x, p, sizeof x);
461 return PyLong_FromSsize_t(x);
462}
463
464static PyObject *
465nu_size_t(const char *p, const formatdef *f)
466{
467 size_t x;
468 memcpy((char *)&x, p, sizeof x);
469 return PyLong_FromSize_t(x);
470}
471
Thomas Wouters477c8d52006-05-27 19:21:47 +0000472static PyObject *
473nu_longlong(const char *p, const formatdef *f)
474{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700475 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000478}
479
480static PyObject *
481nu_ulonglong(const char *p, const formatdef *f)
482{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700483 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000486}
487
Thomas Wouters477c8d52006-05-27 19:21:47 +0000488static PyObject *
Thomas Woutersb2137042007-02-01 18:02:27 +0000489nu_bool(const char *p, const formatdef *f)
490{
Benjamin Petersona9296e72016-09-07 11:06:17 -0700491 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 memcpy((char *)&x, p, sizeof x);
493 return PyBool_FromLong(x != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000494}
495
496
497static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100498nu_halffloat(const char *p, const formatdef *f)
499{
500#if PY_LITTLE_ENDIAN
501 return unpack_halffloat(p, 1);
502#else
503 return unpack_halffloat(p, 0);
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700504#endif
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100505}
506
507static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000508nu_float(const char *p, const formatdef *f)
509{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 float x;
511 memcpy((char *)&x, p, sizeof x);
512 return PyFloat_FromDouble((double)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000513}
514
515static PyObject *
516nu_double(const char *p, const formatdef *f)
517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 double x;
519 memcpy((char *)&x, p, sizeof x);
520 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000521}
522
523static PyObject *
524nu_void_p(const char *p, const formatdef *f)
525{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 void *x;
527 memcpy((char *)&x, p, sizeof x);
528 return PyLong_FromVoidPtr(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000529}
530
531static int
532np_byte(char *p, PyObject *v, const formatdef *f)
533{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 long x;
535 if (get_long(v, &x) < 0)
536 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800537 if (x < -128 || x > 127) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100538 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 "byte format requires -128 <= number <= 127");
540 return -1;
541 }
542 *p = (char)x;
543 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000544}
545
546static int
547np_ubyte(char *p, PyObject *v, const formatdef *f)
548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 long x;
550 if (get_long(v, &x) < 0)
551 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800552 if (x < 0 || x > 255) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100553 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 "ubyte format requires 0 <= number <= 255");
555 return -1;
556 }
Xiang Zhang981096f2017-05-15 12:04:26 +0800557 *(unsigned char *)p = (unsigned char)x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000559}
560
561static int
562np_char(char *p, PyObject *v, const formatdef *f)
563{
Dino Viehland4f384af2019-09-10 11:18:37 +0100564 if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
565 PyErr_SetString(_structmodulestate_global->StructError,
Victor Stinnerda9ec992010-12-28 13:26:42 +0000566 "char format requires a bytes object of length 1");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 return -1;
568 }
Xiang Zhang96f50282017-05-15 11:53:51 +0800569 *p = *PyBytes_AS_STRING(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000571}
572
573static int
574np_short(char *p, PyObject *v, const formatdef *f)
575{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 long x;
577 short y;
578 if (get_long(v, &x) < 0)
579 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800580 if (x < SHRT_MIN || x > SHRT_MAX) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100581 PyErr_SetString(_structmodulestate_global->StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200582 "short format requires " Py_STRINGIFY(SHRT_MIN)
583 " <= number <= " Py_STRINGIFY(SHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 return -1;
585 }
586 y = (short)x;
587 memcpy(p, (char *)&y, sizeof y);
588 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000589}
590
591static int
592np_ushort(char *p, PyObject *v, const formatdef *f)
593{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 long x;
595 unsigned short y;
596 if (get_long(v, &x) < 0)
597 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800598 if (x < 0 || x > USHRT_MAX) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100599 PyErr_SetString(_structmodulestate_global->StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200600 "ushort format requires 0 <= number <= "
601 Py_STRINGIFY(USHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 return -1;
603 }
604 y = (unsigned short)x;
605 memcpy(p, (char *)&y, sizeof y);
606 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000607}
608
609static int
610np_int(char *p, PyObject *v, const formatdef *f)
611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 long x;
613 int y;
614 if (get_long(v, &x) < 0)
615 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000616#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
618 RANGE_ERROR(x, f, 0, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000619#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 y = (int)x;
621 memcpy(p, (char *)&y, sizeof y);
622 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000623}
624
625static int
626np_uint(char *p, PyObject *v, const formatdef *f)
627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 unsigned long x;
629 unsigned int y;
630 if (get_ulong(v, &x) < 0)
631 return -1;
632 y = (unsigned int)x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000633#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 if (x > ((unsigned long)UINT_MAX))
635 RANGE_ERROR(y, f, 1, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000636#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 memcpy(p, (char *)&y, sizeof y);
638 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000639}
640
641static int
642np_long(char *p, PyObject *v, const formatdef *f)
643{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 long x;
645 if (get_long(v, &x) < 0)
646 return -1;
647 memcpy(p, (char *)&x, sizeof x);
648 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000649}
650
651static int
652np_ulong(char *p, PyObject *v, const formatdef *f)
653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 unsigned long x;
655 if (get_ulong(v, &x) < 0)
656 return -1;
657 memcpy(p, (char *)&x, sizeof x);
658 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000659}
660
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200661static int
662np_ssize_t(char *p, PyObject *v, const formatdef *f)
663{
664 Py_ssize_t x;
665 if (get_ssize_t(v, &x) < 0)
666 return -1;
667 memcpy(p, (char *)&x, sizeof x);
668 return 0;
669}
670
671static int
672np_size_t(char *p, PyObject *v, const formatdef *f)
673{
674 size_t x;
675 if (get_size_t(v, &x) < 0)
676 return -1;
677 memcpy(p, (char *)&x, sizeof x);
678 return 0;
679}
680
Thomas Wouters477c8d52006-05-27 19:21:47 +0000681static int
682np_longlong(char *p, PyObject *v, const formatdef *f)
683{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700684 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 if (get_longlong(v, &x) < 0)
686 return -1;
687 memcpy(p, (char *)&x, sizeof x);
688 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000689}
690
691static int
692np_ulonglong(char *p, PyObject *v, const formatdef *f)
693{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700694 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 if (get_ulonglong(v, &x) < 0)
696 return -1;
697 memcpy(p, (char *)&x, sizeof x);
698 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000699}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000700
Thomas Woutersb2137042007-02-01 18:02:27 +0000701
702static int
703np_bool(char *p, PyObject *v, const formatdef *f)
704{
Benjamin Petersonde73c452010-07-07 18:54:59 +0000705 int y;
Benjamin Petersona9296e72016-09-07 11:06:17 -0700706 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000708 if (y < 0)
709 return -1;
710 x = y;
711 memcpy(p, (char *)&x, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000713}
714
Thomas Wouters477c8d52006-05-27 19:21:47 +0000715static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100716np_halffloat(char *p, PyObject *v, const formatdef *f)
717{
718#if PY_LITTLE_ENDIAN
719 return pack_halffloat(p, v, 1);
720#else
721 return pack_halffloat(p, v, 0);
722#endif
723}
724
725static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000726np_float(char *p, PyObject *v, const formatdef *f)
727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 float x = (float)PyFloat_AsDouble(v);
729 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100730 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 "required argument is not a float");
732 return -1;
733 }
734 memcpy(p, (char *)&x, sizeof x);
735 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000736}
737
738static int
739np_double(char *p, PyObject *v, const formatdef *f)
740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 double x = PyFloat_AsDouble(v);
742 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100743 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000744 "required argument is not a float");
745 return -1;
746 }
747 memcpy(p, (char *)&x, sizeof(double));
748 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000749}
750
751static int
752np_void_p(char *p, PyObject *v, const formatdef *f)
753{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 void *x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000756 v = get_pylong(v);
757 if (v == NULL)
758 return -1;
759 assert(PyLong_Check(v));
760 x = PyLong_AsVoidPtr(v);
761 Py_DECREF(v);
762 if (x == NULL && PyErr_Occurred())
763 return -1;
764 memcpy(p, (char *)&x, sizeof x);
765 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000766}
767
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200768static const formatdef native_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 {'x', sizeof(char), 0, NULL},
770 {'b', sizeof(char), 0, nu_byte, np_byte},
771 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
772 {'c', sizeof(char), 0, nu_char, np_char},
773 {'s', sizeof(char), 0, NULL},
774 {'p', sizeof(char), 0, NULL},
775 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
776 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
777 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
778 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
779 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
780 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200781 {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t},
782 {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t},
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700783 {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong},
784 {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Benjamin Petersona9296e72016-09-07 11:06:17 -0700785 {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100786 {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
788 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
789 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
790 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000791};
792
793/* Big-endian routines. *****************************************************/
794
795static PyObject *
796bu_int(const char *p, const formatdef *f)
797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 long x = 0;
799 Py_ssize_t i = f->size;
800 const unsigned char *bytes = (const unsigned char *)p;
801 do {
802 x = (x<<8) | *bytes++;
803 } while (--i > 0);
804 /* Extend the sign bit. */
805 if (SIZEOF_LONG > f->size)
806 x |= -(x & (1L << ((8 * f->size) - 1)));
807 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000808}
809
810static PyObject *
811bu_uint(const char *p, const formatdef *f)
812{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000813 unsigned long x = 0;
814 Py_ssize_t i = f->size;
815 const unsigned char *bytes = (const unsigned char *)p;
816 do {
817 x = (x<<8) | *bytes++;
818 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000819 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000820}
821
822static PyObject *
823bu_longlong(const char *p, const formatdef *f)
824{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700825 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 Py_ssize_t i = f->size;
827 const unsigned char *bytes = (const unsigned char *)p;
828 do {
829 x = (x<<8) | *bytes++;
830 } while (--i > 0);
831 /* Extend the sign bit. */
832 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700833 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000835}
836
837static PyObject *
838bu_ulonglong(const char *p, const formatdef *f)
839{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700840 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 Py_ssize_t i = f->size;
842 const unsigned char *bytes = (const unsigned char *)p;
843 do {
844 x = (x<<8) | *bytes++;
845 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000847}
848
849static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100850bu_halffloat(const char *p, const formatdef *f)
851{
852 return unpack_halffloat(p, 0);
853}
854
855static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000856bu_float(const char *p, const formatdef *f)
857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 return unpack_float(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000859}
860
861static PyObject *
862bu_double(const char *p, const formatdef *f)
863{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 return unpack_double(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000865}
866
Thomas Woutersb2137042007-02-01 18:02:27 +0000867static PyObject *
868bu_bool(const char *p, const formatdef *f)
869{
Xiang Zhang96f50282017-05-15 11:53:51 +0800870 return PyBool_FromLong(*p != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000871}
872
Thomas Wouters477c8d52006-05-27 19:21:47 +0000873static int
874bp_int(char *p, PyObject *v, const formatdef *f)
875{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 long x;
877 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800878 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 if (get_long(v, &x) < 0)
880 return -1;
881 i = f->size;
882 if (i != SIZEOF_LONG) {
883 if ((i == 2) && (x < -32768 || x > 32767))
884 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000885#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
887 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000888#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 }
890 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800891 q[--i] = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 x >>= 8;
893 } while (i > 0);
894 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000895}
896
897static int
898bp_uint(char *p, PyObject *v, const formatdef *f)
899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 unsigned long x;
901 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800902 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 if (get_ulong(v, &x) < 0)
904 return -1;
905 i = f->size;
906 if (i != SIZEOF_LONG) {
907 unsigned long maxint = 1;
908 maxint <<= (unsigned long)(i * 8);
909 if (x >= maxint)
910 RANGE_ERROR(x, f, 1, maxint - 1);
911 }
912 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800913 q[--i] = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 x >>= 8;
915 } while (i > 0);
916 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000917}
918
919static int
920bp_longlong(char *p, PyObject *v, const formatdef *f)
921{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 int res;
923 v = get_pylong(v);
924 if (v == NULL)
925 return -1;
926 res = _PyLong_AsByteArray((PyLongObject *)v,
927 (unsigned char *)p,
928 8,
929 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800930 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 Py_DECREF(v);
932 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000933}
934
935static int
936bp_ulonglong(char *p, PyObject *v, const formatdef *f)
937{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 int res;
939 v = get_pylong(v);
940 if (v == NULL)
941 return -1;
942 res = _PyLong_AsByteArray((PyLongObject *)v,
943 (unsigned char *)p,
944 8,
945 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800946 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000947 Py_DECREF(v);
948 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000949}
950
951static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100952bp_halffloat(char *p, PyObject *v, const formatdef *f)
953{
954 return pack_halffloat(p, v, 0);
955}
956
957static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000958bp_float(char *p, PyObject *v, const formatdef *f)
959{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 double x = PyFloat_AsDouble(v);
961 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100962 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 "required argument is not a float");
964 return -1;
965 }
966 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000967}
968
969static int
970bp_double(char *p, PyObject *v, const formatdef *f)
971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 double x = PyFloat_AsDouble(v);
973 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100974 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 "required argument is not a float");
976 return -1;
977 }
978 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000979}
980
Thomas Woutersb2137042007-02-01 18:02:27 +0000981static int
982bp_bool(char *p, PyObject *v, const formatdef *f)
983{
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000984 int y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000986 if (y < 0)
987 return -1;
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000988 *p = (char)y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000990}
991
Thomas Wouters477c8d52006-05-27 19:21:47 +0000992static formatdef bigendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 {'x', 1, 0, NULL},
994 {'b', 1, 0, nu_byte, np_byte},
995 {'B', 1, 0, nu_ubyte, np_ubyte},
996 {'c', 1, 0, nu_char, np_char},
997 {'s', 1, 0, NULL},
998 {'p', 1, 0, NULL},
999 {'h', 2, 0, bu_int, bp_int},
1000 {'H', 2, 0, bu_uint, bp_uint},
1001 {'i', 4, 0, bu_int, bp_int},
1002 {'I', 4, 0, bu_uint, bp_uint},
1003 {'l', 4, 0, bu_int, bp_int},
1004 {'L', 4, 0, bu_uint, bp_uint},
1005 {'q', 8, 0, bu_longlong, bp_longlong},
1006 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
1007 {'?', 1, 0, bu_bool, bp_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001008 {'e', 2, 0, bu_halffloat, bp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 {'f', 4, 0, bu_float, bp_float},
1010 {'d', 8, 0, bu_double, bp_double},
1011 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001012};
1013
1014/* Little-endian routines. *****************************************************/
1015
1016static PyObject *
1017lu_int(const char *p, const formatdef *f)
1018{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001019 long x = 0;
1020 Py_ssize_t i = f->size;
1021 const unsigned char *bytes = (const unsigned char *)p;
1022 do {
1023 x = (x<<8) | bytes[--i];
1024 } while (i > 0);
1025 /* Extend the sign bit. */
1026 if (SIZEOF_LONG > f->size)
1027 x |= -(x & (1L << ((8 * f->size) - 1)));
1028 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001029}
1030
1031static PyObject *
1032lu_uint(const char *p, const formatdef *f)
1033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 unsigned long x = 0;
1035 Py_ssize_t i = f->size;
1036 const unsigned char *bytes = (const unsigned char *)p;
1037 do {
1038 x = (x<<8) | bytes[--i];
1039 } while (i > 0);
Xiang Zhang96f50282017-05-15 11:53:51 +08001040 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001041}
1042
1043static PyObject *
1044lu_longlong(const char *p, const formatdef *f)
1045{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001046 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 Py_ssize_t i = f->size;
1048 const unsigned char *bytes = (const unsigned char *)p;
1049 do {
1050 x = (x<<8) | bytes[--i];
1051 } while (i > 0);
1052 /* Extend the sign bit. */
1053 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001054 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001056}
1057
1058static PyObject *
1059lu_ulonglong(const char *p, const formatdef *f)
1060{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001061 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 Py_ssize_t i = f->size;
1063 const unsigned char *bytes = (const unsigned char *)p;
1064 do {
1065 x = (x<<8) | bytes[--i];
1066 } while (i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001068}
1069
1070static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001071lu_halffloat(const char *p, const formatdef *f)
1072{
1073 return unpack_halffloat(p, 1);
1074}
1075
1076static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001077lu_float(const char *p, const formatdef *f)
1078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 return unpack_float(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001080}
1081
1082static PyObject *
1083lu_double(const char *p, const formatdef *f)
1084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 return unpack_double(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001086}
1087
1088static int
1089lp_int(char *p, PyObject *v, const formatdef *f)
1090{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 long x;
1092 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001093 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 if (get_long(v, &x) < 0)
1095 return -1;
1096 i = f->size;
1097 if (i != SIZEOF_LONG) {
1098 if ((i == 2) && (x < -32768 || x > 32767))
1099 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001100#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
1102 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001103#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 }
1105 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001106 *q++ = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 x >>= 8;
1108 } while (--i > 0);
1109 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001110}
1111
1112static int
1113lp_uint(char *p, PyObject *v, const formatdef *f)
1114{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 unsigned long x;
1116 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001117 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 if (get_ulong(v, &x) < 0)
1119 return -1;
1120 i = f->size;
1121 if (i != SIZEOF_LONG) {
1122 unsigned long maxint = 1;
1123 maxint <<= (unsigned long)(i * 8);
1124 if (x >= maxint)
1125 RANGE_ERROR(x, f, 1, maxint - 1);
1126 }
1127 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001128 *q++ = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 x >>= 8;
1130 } while (--i > 0);
1131 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001132}
1133
1134static int
1135lp_longlong(char *p, PyObject *v, const formatdef *f)
1136{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 int res;
1138 v = get_pylong(v);
1139 if (v == NULL)
1140 return -1;
1141 res = _PyLong_AsByteArray((PyLongObject*)v,
1142 (unsigned char *)p,
1143 8,
1144 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001145 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 Py_DECREF(v);
1147 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001148}
1149
1150static int
1151lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 int res;
1154 v = get_pylong(v);
1155 if (v == NULL)
1156 return -1;
1157 res = _PyLong_AsByteArray((PyLongObject*)v,
1158 (unsigned char *)p,
1159 8,
1160 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001161 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 Py_DECREF(v);
1163 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001164}
1165
1166static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001167lp_halffloat(char *p, PyObject *v, const formatdef *f)
1168{
1169 return pack_halffloat(p, v, 1);
1170}
1171
1172static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001173lp_float(char *p, PyObject *v, const formatdef *f)
1174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 double x = PyFloat_AsDouble(v);
1176 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001177 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 "required argument is not a float");
1179 return -1;
1180 }
1181 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001182}
1183
1184static int
1185lp_double(char *p, PyObject *v, const formatdef *f)
1186{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 double x = PyFloat_AsDouble(v);
1188 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001189 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 "required argument is not a float");
1191 return -1;
1192 }
1193 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001194}
1195
1196static formatdef lilendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 {'x', 1, 0, NULL},
1198 {'b', 1, 0, nu_byte, np_byte},
1199 {'B', 1, 0, nu_ubyte, np_ubyte},
1200 {'c', 1, 0, nu_char, np_char},
1201 {'s', 1, 0, NULL},
1202 {'p', 1, 0, NULL},
1203 {'h', 2, 0, lu_int, lp_int},
1204 {'H', 2, 0, lu_uint, lp_uint},
1205 {'i', 4, 0, lu_int, lp_int},
1206 {'I', 4, 0, lu_uint, lp_uint},
1207 {'l', 4, 0, lu_int, lp_int},
1208 {'L', 4, 0, lu_uint, lp_uint},
1209 {'q', 8, 0, lu_longlong, lp_longlong},
1210 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1211 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1212 but potentially different from native rep -- reuse bx_bool funcs. */
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001213 {'e', 2, 0, lu_halffloat, lp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 {'f', 4, 0, lu_float, lp_float},
1215 {'d', 8, 0, lu_double, lp_double},
1216 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001217};
1218
1219
1220static const formatdef *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001221whichtable(const char **pfmt)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001222{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 const char *fmt = (*pfmt)++; /* May be backed out of later */
1224 switch (*fmt) {
1225 case '<':
1226 return lilendian_table;
1227 case '>':
1228 case '!': /* Network byte order is big-endian */
1229 return bigendian_table;
Ezio Melotti42da6632011-03-15 05:18:48 +02001230 case '=': { /* Host byte order -- different from native in alignment! */
Christian Heimes743e0cd2012-10-17 23:52:17 +02001231#if PY_LITTLE_ENDIAN
1232 return lilendian_table;
1233#else
1234 return bigendian_table;
1235#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 }
1237 default:
1238 --*pfmt; /* Back out of pointer increment */
1239 /* Fall through */
1240 case '@':
1241 return native_table;
1242 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001243}
1244
1245
1246/* Get the table entry for a format code */
1247
1248static const formatdef *
1249getentry(int c, const formatdef *f)
1250{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 for (; f->format != '\0'; f++) {
1252 if (f->format == c) {
1253 return f;
1254 }
1255 }
Dino Viehland4f384af2019-09-10 11:18:37 +01001256 PyErr_SetString(_structmodulestate_global->StructError, "bad char in struct format");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001258}
1259
1260
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001261/* Align a size according to a format code. Return -1 on overflow. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001262
Mark Dickinsoneac0e682010-06-11 19:05:08 +00001263static Py_ssize_t
Thomas Wouters477c8d52006-05-27 19:21:47 +00001264align(Py_ssize_t size, char c, const formatdef *e)
1265{
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001266 Py_ssize_t extra;
1267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 if (e->format == c) {
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001269 if (e->alignment && size > 0) {
1270 extra = (e->alignment - 1) - (size - 1) % (e->alignment);
1271 if (extra > PY_SSIZE_T_MAX - size)
1272 return -1;
1273 size += extra;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 }
1275 }
1276 return size;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001277}
1278
Antoine Pitrou9f146812013-04-27 00:20:04 +02001279/*
1280 * Struct object implementation.
1281 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001282
1283/* calculate the size of a format string */
1284
1285static int
1286prepare_s(PyStructObject *self)
1287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 const formatdef *f;
1289 const formatdef *e;
1290 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 const char *s;
1293 const char *fmt;
1294 char c;
Victor Stinner706768c2014-08-16 01:03:39 +02001295 Py_ssize_t size, len, num, itemsize;
1296 size_t ncodes;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 fmt = PyBytes_AS_STRING(self->s_format);
Zackery Spytz3f59b552020-05-25 01:55:09 -06001299 if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(self->s_format)) {
1300 PyErr_SetString(_structmodulestate_global->StructError,
1301 "embedded null character");
1302 return -1;
1303 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001304
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001305 f = whichtable(&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001306
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 s = fmt;
1308 size = 0;
1309 len = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001310 ncodes = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 while ((c = *s++) != '\0') {
Jordon Xu2ec70102019-09-11 00:04:08 +08001312 if (Py_ISSPACE(c))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 continue;
1314 if ('0' <= c && c <= '9') {
1315 num = c - '0';
1316 while ('0' <= (c = *s++) && c <= '9') {
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001317 /* overflow-safe version of
1318 if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1319 if (num >= PY_SSIZE_T_MAX / 10 && (
1320 num > PY_SSIZE_T_MAX / 10 ||
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001321 (c - '0') > PY_SSIZE_T_MAX % 10))
1322 goto overflow;
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001323 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 }
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001325 if (c == '\0') {
Dino Viehland4f384af2019-09-10 11:18:37 +01001326 PyErr_SetString(_structmodulestate_global->StructError,
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001327 "repeat count given without format specifier");
1328 return -1;
1329 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 }
1331 else
1332 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 e = getentry(c, f);
1335 if (e == NULL)
1336 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001337
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 switch (c) {
1339 case 's': /* fall through */
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001340 case 'p': len++; ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001341 case 'x': break;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001342 default: len += num; if (num) ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 itemsize = e->size;
1346 size = align(size, c, e);
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001347 if (size == -1)
1348 goto overflow;
1349
1350 /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1351 if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1352 goto overflow;
1353 size += num * itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 /* check for overflow */
Victor Stinner706768c2014-08-16 01:03:39 +02001357 if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 PyErr_NoMemory();
1359 return -1;
1360 }
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +00001361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 self->s_size = size;
1363 self->s_len = len;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001364 codes = PyMem_MALLOC((ncodes + 1) * sizeof(formatcode));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 if (codes == NULL) {
1366 PyErr_NoMemory();
1367 return -1;
1368 }
Mark Dickinsoncf28b952010-07-29 21:41:59 +00001369 /* Free any s_codes value left over from a previous initialization. */
1370 if (self->s_codes != NULL)
1371 PyMem_FREE(self->s_codes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 s = fmt;
1375 size = 0;
1376 while ((c = *s++) != '\0') {
Jordon Xu2ec70102019-09-11 00:04:08 +08001377 if (Py_ISSPACE(c))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 continue;
1379 if ('0' <= c && c <= '9') {
1380 num = c - '0';
1381 while ('0' <= (c = *s++) && c <= '9')
1382 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 }
1384 else
1385 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001388
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001389 size = align(size, c, e);
1390 if (c == 's' || c == 'p') {
1391 codes->offset = size;
1392 codes->size = num;
1393 codes->fmtdef = e;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001394 codes->repeat = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 codes++;
1396 size += num;
1397 } else if (c == 'x') {
1398 size += num;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001399 } else if (num) {
1400 codes->offset = size;
1401 codes->size = e->size;
1402 codes->fmtdef = e;
1403 codes->repeat = num;
1404 codes++;
1405 size += e->size * num;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001406 }
1407 }
1408 codes->fmtdef = NULL;
1409 codes->offset = size;
1410 codes->size = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001411 codes->repeat = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001412
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 return 0;
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001414
1415 overflow:
Dino Viehland4f384af2019-09-10 11:18:37 +01001416 PyErr_SetString(_structmodulestate_global->StructError,
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001417 "total struct size too long");
1418 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001419}
1420
1421static PyObject *
1422s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 PyObject *self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001425
Dino Viehland4f384af2019-09-10 11:18:37 +01001426 assert(type != NULL);
1427 allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc);
1428 assert(alloc_func != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001429
Dino Viehland4f384af2019-09-10 11:18:37 +01001430 self = alloc_func(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 if (self != NULL) {
1432 PyStructObject *s = (PyStructObject*)self;
1433 Py_INCREF(Py_None);
1434 s->s_format = Py_None;
1435 s->s_codes = NULL;
1436 s->s_size = -1;
1437 s->s_len = -1;
1438 }
1439 return self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001440}
1441
Victor Stinner3f2d1012017-02-02 12:09:30 +01001442/*[clinic input]
1443Struct.__init__
1444
1445 format: object
1446
1447Create a compiled struct object.
1448
1449Return a new Struct object which writes and reads binary data according to
1450the format string.
1451
1452See help(struct) for more on format strings.
1453[clinic start generated code]*/
1454
Thomas Wouters477c8d52006-05-27 19:21:47 +00001455static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001456Struct___init___impl(PyStructObject *self, PyObject *format)
1457/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001458{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 int ret = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001460
Victor Stinner3f2d1012017-02-02 12:09:30 +01001461 if (PyUnicode_Check(format)) {
1462 format = PyUnicode_AsASCIIString(format);
1463 if (format == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 return -1;
1465 }
1466 /* XXX support buffer interface, too */
1467 else {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001468 Py_INCREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001470
Victor Stinner3f2d1012017-02-02 12:09:30 +01001471 if (!PyBytes_Check(format)) {
1472 Py_DECREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001473 PyErr_Format(PyExc_TypeError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001474 "Struct() argument 1 must be a str or bytes object, "
1475 "not %.200s",
Dino Viehland4f384af2019-09-10 11:18:37 +01001476 _PyType_Name(Py_TYPE(format)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 return -1;
1478 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001479
Xiang Zhang96f50282017-05-15 11:53:51 +08001480 Py_SETREF(self->s_format, format);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001481
Victor Stinner3f2d1012017-02-02 12:09:30 +01001482 ret = prepare_s(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001483 return ret;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001484}
1485
1486static void
1487s_dealloc(PyStructObject *s)
1488{
Dino Viehland4f384af2019-09-10 11:18:37 +01001489 PyTypeObject *tp = Py_TYPE(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 if (s->weakreflist != NULL)
1491 PyObject_ClearWeakRefs((PyObject *)s);
1492 if (s->s_codes != NULL) {
1493 PyMem_FREE(s->s_codes);
1494 }
Dino Viehland4f384af2019-09-10 11:18:37 +01001495 Py_XDECREF(s->s_format);
1496 freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free);
1497 free_func(s);
1498 Py_DECREF(tp);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001499}
1500
1501static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001502s_unpack_internal(PyStructObject *soself, const char *startfrom) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001503 formatcode *code;
1504 Py_ssize_t i = 0;
1505 PyObject *result = PyTuple_New(soself->s_len);
1506 if (result == NULL)
1507 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001510 const formatdef *e = code->fmtdef;
1511 const char *res = startfrom + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001512 Py_ssize_t j = code->repeat;
1513 while (j--) {
1514 PyObject *v;
1515 if (e->format == 's') {
1516 v = PyBytes_FromStringAndSize(res, code->size);
1517 } else if (e->format == 'p') {
1518 Py_ssize_t n = *(unsigned char*)res;
1519 if (n >= code->size)
1520 n = code->size - 1;
1521 v = PyBytes_FromStringAndSize(res + 1, n);
1522 } else {
1523 v = e->unpack(res, e);
1524 }
1525 if (v == NULL)
1526 goto fail;
1527 PyTuple_SET_ITEM(result, i++, v);
1528 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001530 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001533fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001534 Py_DECREF(result);
1535 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001536}
1537
1538
Victor Stinner3f2d1012017-02-02 12:09:30 +01001539/*[clinic input]
1540Struct.unpack
1541
1542 buffer: Py_buffer
1543 /
1544
1545Return a tuple containing unpacked values.
1546
1547Unpack according to the format string Struct.format. The buffer's size
1548in bytes must be Struct.size.
1549
1550See help(struct) for more on format strings.
1551[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001552
1553static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001554Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1555/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001556{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001557 assert(self->s_codes != NULL);
1558 if (buffer->len != self->s_size) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001559 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001560 "unpack requires a buffer of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001561 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 return NULL;
1563 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001564 return s_unpack_internal(self, buffer->buf);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001565}
1566
Victor Stinner3f2d1012017-02-02 12:09:30 +01001567/*[clinic input]
1568Struct.unpack_from
1569
1570 buffer: Py_buffer
1571 offset: Py_ssize_t = 0
1572
1573Return a tuple containing unpacked values.
1574
1575Values are unpacked according to the format string Struct.format.
1576
Xiang Zhangc10b2882018-03-11 02:58:52 +08001577The buffer's size in bytes, starting at position offset, must be
1578at least Struct.size.
Victor Stinner3f2d1012017-02-02 12:09:30 +01001579
1580See help(struct) for more on format strings.
1581[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001582
1583static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001584Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1585 Py_ssize_t offset)
Xiang Zhangc10b2882018-03-11 02:58:52 +08001586/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001587{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001588 assert(self->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001589
Xiang Zhangc10b2882018-03-11 02:58:52 +08001590 if (offset < 0) {
1591 if (offset + self->s_size > 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001592 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001593 "not enough data to unpack %zd bytes at offset %zd",
1594 self->s_size,
1595 offset);
1596 return NULL;
1597 }
1598
1599 if (offset + buffer->len < 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001600 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001601 "offset %zd out of range for %zd-byte buffer",
1602 offset,
1603 buffer->len);
1604 return NULL;
1605 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001606 offset += buffer->len;
Xiang Zhangc10b2882018-03-11 02:58:52 +08001607 }
1608
1609 if ((buffer->len - offset) < self->s_size) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001610 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001611 "unpack_from requires a buffer of at least %zu bytes for "
1612 "unpacking %zd bytes at offset %zd "
1613 "(actual buffer size is %zd)",
1614 (size_t)self->s_size + (size_t)offset,
1615 self->s_size,
1616 offset,
1617 buffer->len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001618 return NULL;
1619 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001620 return s_unpack_internal(self, (char*)buffer->buf + offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001621}
1622
1623
Victor Stinner3f2d1012017-02-02 12:09:30 +01001624
Antoine Pitrou9f146812013-04-27 00:20:04 +02001625/* Unpack iterator type */
1626
1627typedef struct {
1628 PyObject_HEAD
1629 PyStructObject *so;
1630 Py_buffer buf;
1631 Py_ssize_t index;
1632} unpackiterobject;
1633
1634static void
1635unpackiter_dealloc(unpackiterobject *self)
1636{
INADA Naokia6296d32017-08-24 14:55:17 +09001637 /* bpo-31095: UnTrack is needed before calling any callbacks */
Dino Viehland4f384af2019-09-10 11:18:37 +01001638 PyTypeObject *tp = Py_TYPE(self);
INADA Naokia6296d32017-08-24 14:55:17 +09001639 PyObject_GC_UnTrack(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001640 Py_XDECREF(self->so);
1641 PyBuffer_Release(&self->buf);
1642 PyObject_GC_Del(self);
Dino Viehland4f384af2019-09-10 11:18:37 +01001643 Py_DECREF(tp);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001644}
1645
1646static int
1647unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1648{
Pablo Galindo1cf15af2020-05-27 10:03:38 +01001649 Py_VISIT(Py_TYPE(self));
Antoine Pitrou9f146812013-04-27 00:20:04 +02001650 Py_VISIT(self->so);
1651 Py_VISIT(self->buf.obj);
1652 return 0;
1653}
1654
1655static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301656unpackiter_len(unpackiterobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou9f146812013-04-27 00:20:04 +02001657{
1658 Py_ssize_t len;
1659 if (self->so == NULL)
1660 len = 0;
1661 else
1662 len = (self->buf.len - self->index) / self->so->s_size;
1663 return PyLong_FromSsize_t(len);
1664}
1665
1666static PyMethodDef unpackiter_methods[] = {
1667 {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1668 {NULL, NULL} /* sentinel */
1669};
1670
1671static PyObject *
1672unpackiter_iternext(unpackiterobject *self)
1673{
1674 PyObject *result;
1675 if (self->so == NULL)
1676 return NULL;
1677 if (self->index >= self->buf.len) {
1678 /* Iterator exhausted */
1679 Py_CLEAR(self->so);
1680 PyBuffer_Release(&self->buf);
1681 return NULL;
1682 }
1683 assert(self->index + self->so->s_size <= self->buf.len);
1684 result = s_unpack_internal(self->so,
1685 (char*) self->buf.buf + self->index);
1686 self->index += self->so->s_size;
1687 return result;
1688}
1689
Dino Viehland4f384af2019-09-10 11:18:37 +01001690PyObject *unpackiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1691 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s objects", _PyType_Name(type));
1692 return NULL;
1693}
1694
1695static PyType_Slot unpackiter_type_slots[] = {
1696 {Py_tp_dealloc, unpackiter_dealloc},
1697 {Py_tp_getattro, PyObject_GenericGetAttr},
1698 {Py_tp_traverse, unpackiter_traverse},
1699 {Py_tp_iter, PyObject_SelfIter},
1700 {Py_tp_iternext, unpackiter_iternext},
1701 {Py_tp_methods, unpackiter_methods},
1702 {Py_tp_new, unpackiter_new},
1703 {0, 0},
1704};
1705
1706static PyType_Spec unpackiter_type_spec = {
1707 "_struct.unpack_iterator",
1708 sizeof(unpackiterobject),
1709 0,
1710 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1711 unpackiter_type_slots
Antoine Pitrou9f146812013-04-27 00:20:04 +02001712};
1713
Victor Stinner3f2d1012017-02-02 12:09:30 +01001714/*[clinic input]
1715Struct.iter_unpack
1716
1717 buffer: object
1718 /
1719
1720Return an iterator yielding tuples.
1721
1722Tuples are unpacked from the given bytes source, like a repeated
1723invocation of unpack_from().
1724
1725Requires that the bytes length be a multiple of the struct size.
1726[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001727
1728static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001729Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1730/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001731{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001732 unpackiterobject *iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001733
Victor Stinner3f2d1012017-02-02 12:09:30 +01001734 assert(self->s_codes != NULL);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001735
Victor Stinner3f2d1012017-02-02 12:09:30 +01001736 if (self->s_size == 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001737 PyErr_Format(_structmodulestate_global->StructError,
Antoine Pitrou9f146812013-04-27 00:20:04 +02001738 "cannot iteratively unpack with a struct of length 0");
1739 return NULL;
1740 }
1741
Dino Viehland4f384af2019-09-10 11:18:37 +01001742 iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)_structmodulestate_global->unpackiter_type, 0);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001743 if (iter == NULL)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001744 return NULL;
1745
Victor Stinner3f2d1012017-02-02 12:09:30 +01001746 if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1747 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001748 return NULL;
1749 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001750 if (iter->buf.len % self->s_size != 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001751 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001752 "iterative unpacking requires a buffer of "
1753 "a multiple of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001754 self->s_size);
1755 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001756 return NULL;
1757 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001758 Py_INCREF(self);
1759 iter->so = self;
1760 iter->index = 0;
1761 return (PyObject *)iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001762}
1763
1764
Thomas Wouters477c8d52006-05-27 19:21:47 +00001765/*
1766 * Guts of the pack function.
1767 *
1768 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1769 * argument for where to start processing the arguments for packing, and a
1770 * character buffer for writing the packed string. The caller must insure
1771 * that the buffer may contain the required length for packing the arguments.
1772 * 0 is returned on success, 1 is returned if there is an error.
1773 *
1774 */
1775static int
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001776s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* buf)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001777{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001778 formatcode *code;
1779 /* XXX(nnorwitz): why does i need to be a local? can we use
1780 the offset parameter or do we need the wider width? */
1781 Py_ssize_t i;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001783 memset(buf, '\0', soself->s_size);
1784 i = offset;
1785 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001786 const formatdef *e = code->fmtdef;
1787 char *res = buf + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001788 Py_ssize_t j = code->repeat;
1789 while (j--) {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001790 PyObject *v = args[i++];
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001791 if (e->format == 's') {
1792 Py_ssize_t n;
1793 int isstring;
Serhiy Storchaka8f87eef2020-04-12 14:58:27 +03001794 const void *p;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001795 isstring = PyBytes_Check(v);
1796 if (!isstring && !PyByteArray_Check(v)) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001797 PyErr_SetString(_structmodulestate_global->StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001798 "argument for 's' must be a bytes object");
1799 return -1;
1800 }
1801 if (isstring) {
1802 n = PyBytes_GET_SIZE(v);
1803 p = PyBytes_AS_STRING(v);
1804 }
1805 else {
1806 n = PyByteArray_GET_SIZE(v);
1807 p = PyByteArray_AS_STRING(v);
1808 }
1809 if (n > code->size)
1810 n = code->size;
1811 if (n > 0)
1812 memcpy(res, p, n);
1813 } else if (e->format == 'p') {
1814 Py_ssize_t n;
1815 int isstring;
Serhiy Storchaka8f87eef2020-04-12 14:58:27 +03001816 const void *p;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001817 isstring = PyBytes_Check(v);
1818 if (!isstring && !PyByteArray_Check(v)) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001819 PyErr_SetString(_structmodulestate_global->StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001820 "argument for 'p' must be a bytes object");
1821 return -1;
1822 }
1823 if (isstring) {
1824 n = PyBytes_GET_SIZE(v);
1825 p = PyBytes_AS_STRING(v);
1826 }
1827 else {
1828 n = PyByteArray_GET_SIZE(v);
1829 p = PyByteArray_AS_STRING(v);
1830 }
1831 if (n > (code->size - 1))
1832 n = code->size - 1;
1833 if (n > 0)
1834 memcpy(res + 1, p, n);
1835 if (n > 255)
1836 n = 255;
1837 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1838 } else {
1839 if (e->pack(res, v, e) < 0) {
1840 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +01001841 PyErr_SetString(_structmodulestate_global->StructError,
Serhiy Storchaka46e1ce22013-08-27 20:17:03 +03001842 "int too large to convert");
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001843 return -1;
1844 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001845 }
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001846 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001847 }
1848 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001849
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001850 /* Success */
1851 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001852}
1853
1854
1855PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001856"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001857\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001858Return a bytes object containing values v1, v2, ... packed according\n\
1859to the format string S.format. See help(struct) for more on format\n\
1860strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001861
1862static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001863s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001864{
Dino Viehland4f384af2019-09-10 11:18:37 +01001865 char *buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 PyStructObject *soself;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 /* Validate arguments. */
1869 soself = (PyStructObject *)self;
1870 assert(PyStruct_Check(self));
1871 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001872 if (nargs != soself->s_len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 {
Dino Viehland4f384af2019-09-10 11:18:37 +01001874 PyErr_Format(_structmodulestate_global->StructError,
Victor Stinner3f2d1012017-02-02 12:09:30 +01001875 "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1876 return NULL;
1877 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001878
Dino Viehland4f384af2019-09-10 11:18:37 +01001879 /* Allocate a new string */
1880 _PyBytesWriter writer;
1881 _PyBytesWriter_Init(&writer);
1882 buf = _PyBytesWriter_Alloc(&writer, soself->s_size);
1883 if (buf == NULL) {
1884 _PyBytesWriter_Dealloc(&writer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 return NULL;
1886 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001887
Dino Viehland4f384af2019-09-10 11:18:37 +01001888 /* Call the guts */
1889 if ( s_pack_internal(soself, args, 0, buf) != 0 ) {
1890 _PyBytesWriter_Dealloc(&writer);
1891 return NULL;
1892 }
1893
1894 return _PyBytesWriter_Finish(&writer, buf + soself->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001895}
1896
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001897PyDoc_STRVAR(s_pack_into__doc__,
1898"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001899\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001900Pack the values v1, v2, ... according to the format string S.format\n\
1901and write the packed bytes into the writable buffer buf starting at\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00001902offset. Note that the offset is a required argument. See\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001903help(struct) for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001904
1905static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001906s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001907{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001908 PyStructObject *soself;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001909 Py_buffer buffer;
1910 Py_ssize_t offset;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001911
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001912 /* Validate arguments. +1 is for the first arg as buffer. */
1913 soself = (PyStructObject *)self;
1914 assert(PyStruct_Check(self));
1915 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001916 if (nargs != (soself->s_len + 2))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001917 {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001918 if (nargs == 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001919 PyErr_Format(_structmodulestate_global->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001920 "pack_into expected buffer argument");
1921 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001922 else if (nargs == 1) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001923 PyErr_Format(_structmodulestate_global->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001924 "pack_into expected offset argument");
1925 }
1926 else {
Dino Viehland4f384af2019-09-10 11:18:37 +01001927 PyErr_Format(_structmodulestate_global->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001928 "pack_into expected %zd items for packing (got %zd)",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001929 soself->s_len, (nargs - 2));
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001930 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 return NULL;
1932 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934 /* Extract a writable memory buffer from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001935 if (!PyArg_Parse(args[0], "w*", &buffer))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001937 assert(buffer.len >= 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001939 /* Extract the offset from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001940 offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001941 if (offset == -1 && PyErr_Occurred()) {
1942 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001943 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001944 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001945
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001946 /* Support negative offsets. */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001947 if (offset < 0) {
1948 /* Check that negative offset is low enough to fit data */
1949 if (offset + soself->s_size > 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001950 PyErr_Format(_structmodulestate_global->StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001951 "no space to pack %zd bytes at offset %zd",
1952 soself->s_size,
1953 offset);
1954 PyBuffer_Release(&buffer);
1955 return NULL;
1956 }
1957
1958 /* Check that negative offset is not crossing buffer boundary */
1959 if (offset + buffer.len < 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001960 PyErr_Format(_structmodulestate_global->StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001961 "offset %zd out of range for %zd-byte buffer",
1962 offset,
1963 buffer.len);
1964 PyBuffer_Release(&buffer);
1965 return NULL;
1966 }
1967
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001968 offset += buffer.len;
Andrew Nesterf78b1192017-04-04 13:46:25 +03001969 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001971 /* Check boundaries */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001972 if ((buffer.len - offset) < soself->s_size) {
Johan Liuaead53b2017-06-02 14:33:04 +08001973 assert(offset >= 0);
1974 assert(soself->s_size >= 0);
1975
Dino Viehland4f384af2019-09-10 11:18:37 +01001976 PyErr_Format(_structmodulestate_global->StructError,
Johan Liuaead53b2017-06-02 14:33:04 +08001977 "pack_into requires a buffer of at least %zu bytes for "
Andrew Nesterf78b1192017-04-04 13:46:25 +03001978 "packing %zd bytes at offset %zd "
1979 "(actual buffer size is %zd)",
Johan Liuaead53b2017-06-02 14:33:04 +08001980 (size_t)soself->s_size + (size_t)offset,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001981 soself->s_size,
1982 offset,
1983 buffer.len);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001984 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 return NULL;
1986 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001987
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001988 /* Call the guts */
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001989 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
1990 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 return NULL;
1992 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001993
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001994 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001995 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001996}
1997
1998static PyObject *
1999s_get_format(PyStructObject *self, void *unused)
2000{
Victor Stinnerf87b85f2017-06-23 15:11:12 +02002001 return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
2002 PyBytes_GET_SIZE(self->s_format));
Thomas Wouters477c8d52006-05-27 19:21:47 +00002003}
2004
2005static PyObject *
2006s_get_size(PyStructObject *self, void *unused)
2007{
Christian Heimes217cfd12007-12-02 14:31:20 +00002008 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002009}
2010
Meador Ingeb14d8c92012-07-23 10:01:29 -05002011PyDoc_STRVAR(s_sizeof__doc__,
2012"S.__sizeof__() -> size of S in memory, in bytes");
2013
2014static PyObject *
Meador Inge90bc2dbc2012-07-28 22:16:39 -05002015s_sizeof(PyStructObject *self, void *unused)
Meador Ingeb14d8c92012-07-23 10:01:29 -05002016{
2017 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002018 formatcode *code;
Meador Ingeb14d8c92012-07-23 10:01:29 -05002019
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002020 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002021 for (code = self->s_codes; code->fmtdef != NULL; code++)
2022 size += sizeof(formatcode);
Meador Ingeb14d8c92012-07-23 10:01:29 -05002023 return PyLong_FromSsize_t(size);
2024}
2025
Thomas Wouters477c8d52006-05-27 19:21:47 +00002026/* List of functions */
2027
2028static struct PyMethodDef s_methods[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002029 STRUCT_ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002030 {"pack", (PyCFunction)(void(*)(void))s_pack, METH_FASTCALL, s_pack__doc__},
2031 {"pack_into", (PyCFunction)(void(*)(void))s_pack_into, METH_FASTCALL, s_pack_into__doc__},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002032 STRUCT_UNPACK_METHODDEF
2033 STRUCT_UNPACK_FROM_METHODDEF
Meador Ingeb14d8c92012-07-23 10:01:29 -05002034 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002035 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002036};
2037
Dino Viehland4f384af2019-09-10 11:18:37 +01002038static PyMemberDef s_members[] = {
Eddie Elizondo3368f3c2019-09-19 09:29:05 -07002039 {"__weaklistoffset__", T_PYSSIZET, offsetof(PyStructObject, weakreflist), READONLY},
Dino Viehland4f384af2019-09-10 11:18:37 +01002040 {NULL} /* sentinel */
2041};
2042
Thomas Wouters477c8d52006-05-27 19:21:47 +00002043#define OFF(x) offsetof(PyStructObject, x)
2044
2045static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002046 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
2047 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
2048 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002049};
2050
Dino Viehland4f384af2019-09-10 11:18:37 +01002051PyDoc_STRVAR(s__doc__,
2052"Struct(fmt) --> compiled struct object\n"
2053"\n"
2054);
2055
2056static PyType_Slot PyStructType_slots[] = {
2057 {Py_tp_dealloc, s_dealloc},
2058 {Py_tp_getattro, PyObject_GenericGetAttr},
2059 {Py_tp_setattro, PyObject_GenericSetAttr},
2060 {Py_tp_doc, (void*)s__doc__},
2061 {Py_tp_methods, s_methods},
2062 {Py_tp_members, s_members},
2063 {Py_tp_getset, s_getsetlist},
2064 {Py_tp_init, Struct___init__},
2065 {Py_tp_alloc, PyType_GenericAlloc},
2066 {Py_tp_new, s_new},
2067 {Py_tp_free, PyObject_Del},
2068 {0, 0},
2069};
2070
2071static PyType_Spec PyStructType_spec = {
2072 "_struct.Struct",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002073 sizeof(PyStructObject),
2074 0,
Dino Viehland4f384af2019-09-10 11:18:37 +01002075 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
2076 PyStructType_slots
Thomas Wouters477c8d52006-05-27 19:21:47 +00002077};
2078
Christian Heimesa34706f2008-01-04 03:06:10 +00002079
2080/* ---- Standalone functions ---- */
2081
2082#define MAXCACHE 100
2083static PyObject *cache = NULL;
2084
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002085static int
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002086cache_struct_converter(PyObject *fmt, PyStructObject **ptr)
Christian Heimesa34706f2008-01-04 03:06:10 +00002087{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 PyObject * s_object;
Christian Heimesa34706f2008-01-04 03:06:10 +00002089
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002090 if (fmt == NULL) {
2091 Py_DECREF(*ptr);
Serhiy Storchaka40db90c2017-04-20 21:19:31 +03002092 *ptr = NULL;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002093 return 1;
2094 }
2095
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 if (cache == NULL) {
2097 cache = PyDict_New();
2098 if (cache == NULL)
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002099 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002100 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002101
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002102 s_object = PyDict_GetItemWithError(cache, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 if (s_object != NULL) {
2104 Py_INCREF(s_object);
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002105 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002106 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002107 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002108 else if (PyErr_Occurred()) {
2109 return 0;
2110 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002111
Petr Viktorinffd97532020-02-11 17:46:57 +01002112 s_object = PyObject_CallOneArg(_structmodulestate_global->PyStructType, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002113 if (s_object != NULL) {
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02002114 if (PyDict_GET_SIZE(cache) >= MAXCACHE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115 PyDict_Clear(cache);
2116 /* Attempt to cache the result */
2117 if (PyDict_SetItem(cache, fmt, s_object) == -1)
2118 PyErr_Clear();
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002119 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002120 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002122 return 0;
Christian Heimesa34706f2008-01-04 03:06:10 +00002123}
2124
Victor Stinner3f2d1012017-02-02 12:09:30 +01002125/*[clinic input]
2126_clearcache
2127
2128Clear the internal cache.
2129[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002130
2131static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002132_clearcache_impl(PyObject *module)
2133/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002134{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002135 Py_CLEAR(cache);
2136 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00002137}
2138
Victor Stinner3f2d1012017-02-02 12:09:30 +01002139
2140/*[clinic input]
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002141calcsize -> Py_ssize_t
Victor Stinner3f2d1012017-02-02 12:09:30 +01002142
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002143 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002144 /
2145
2146Return size in bytes of the struct described by the format string.
2147[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002148
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002149static Py_ssize_t
2150calcsize_impl(PyObject *module, PyStructObject *s_object)
2151/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002152{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002153 return s_object->s_size;
Christian Heimesa34706f2008-01-04 03:06:10 +00002154}
2155
2156PyDoc_STRVAR(pack_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002157"pack(format, v1, v2, ...) -> bytes\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002158\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002159Return a bytes object containing the values v1, v2, ... packed according\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002160to the format string. See help(struct) for more on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002161
2162static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02002163pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002164{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002165 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002166 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002167
Victor Stinner3f2d1012017-02-02 12:09:30 +01002168 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 PyErr_SetString(PyExc_TypeError, "missing format argument");
2170 return NULL;
2171 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002172 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002173
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002174 if (!cache_struct_converter(format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002175 return NULL;
2176 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002177 result = s_pack(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002178 Py_DECREF(s_object);
2179 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002180}
2181
2182PyDoc_STRVAR(pack_into_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002183"pack_into(format, buffer, offset, v1, v2, ...)\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002184\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002185Pack the values v1, v2, ... according to the format string and write\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002186the packed bytes into the writable buffer buf starting at offset. Note\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002187that the offset is a required argument. See help(struct) for more\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002188on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002189
2190static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02002191pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002192{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002193 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002194 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002195
Victor Stinner3f2d1012017-02-02 12:09:30 +01002196 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 PyErr_SetString(PyExc_TypeError, "missing format argument");
2198 return NULL;
2199 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002200 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002201
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002202 if (!cache_struct_converter(format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002203 return NULL;
2204 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002205 result = s_pack_into(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002206 Py_DECREF(s_object);
2207 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002208}
2209
Victor Stinner3f2d1012017-02-02 12:09:30 +01002210/*[clinic input]
2211unpack
2212
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002213 format as s_object: cache_struct
Victor Stinnerc0f59ad2017-02-02 14:24:16 +01002214 buffer: Py_buffer
Victor Stinner3f2d1012017-02-02 12:09:30 +01002215 /
2216
2217Return a tuple containing values unpacked according to the format string.
2218
2219The buffer's size in bytes must be calcsize(format).
2220
2221See help(struct) for more on format strings.
2222[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002223
2224static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002225unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2226/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002227{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002228 return Struct_unpack_impl(s_object, buffer);
Christian Heimesa34706f2008-01-04 03:06:10 +00002229}
2230
Victor Stinner3f2d1012017-02-02 12:09:30 +01002231/*[clinic input]
2232unpack_from
2233
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002234 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002235 /
2236 buffer: Py_buffer
2237 offset: Py_ssize_t = 0
2238
2239Return a tuple containing values unpacked according to the format string.
2240
2241The buffer's size, minus offset, must be at least calcsize(format).
2242
2243See help(struct) for more on format strings.
2244[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002245
2246static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002247unpack_from_impl(PyObject *module, PyStructObject *s_object,
2248 Py_buffer *buffer, Py_ssize_t offset)
2249/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002250{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002251 return Struct_unpack_from_impl(s_object, buffer, offset);
Christian Heimesa34706f2008-01-04 03:06:10 +00002252}
2253
Victor Stinner3f2d1012017-02-02 12:09:30 +01002254/*[clinic input]
2255iter_unpack
2256
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002257 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002258 buffer: object
2259 /
2260
2261Return an iterator yielding tuples unpacked from the given bytes.
2262
2263The bytes are unpacked according to the format string, like
2264a repeated invocation of unpack_from().
2265
2266Requires that the bytes length be a multiple of the format struct size.
2267[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002268
2269static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002270iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2271 PyObject *buffer)
2272/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002273{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002274 return Struct_iter_unpack(s_object, buffer);
Antoine Pitrou9f146812013-04-27 00:20:04 +02002275}
2276
Christian Heimesa34706f2008-01-04 03:06:10 +00002277static struct PyMethodDef module_functions[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002278 _CLEARCACHE_METHODDEF
2279 CALCSIZE_METHODDEF
2280 ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002281 {"pack", (PyCFunction)(void(*)(void))pack, METH_FASTCALL, pack_doc},
2282 {"pack_into", (PyCFunction)(void(*)(void))pack_into, METH_FASTCALL, pack_into_doc},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002283 UNPACK_METHODDEF
2284 UNPACK_FROM_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002285 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00002286};
2287
2288
Thomas Wouters477c8d52006-05-27 19:21:47 +00002289/* Module initialization */
2290
Christian Heimesa34706f2008-01-04 03:06:10 +00002291PyDoc_STRVAR(module_doc,
2292"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002293Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002294and also as format strings (explained below) to describe the layout of data\n\
2295in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002296\n\
2297The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002298 @: native order, size & alignment (default)\n\
2299 =: native order, std. size & alignment\n\
2300 <: little-endian, std. size & alignment\n\
2301 >: big-endian, std. size & alignment\n\
2302 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002303\n\
2304The remaining chars indicate types of args and must match exactly;\n\
2305these can be preceded by a decimal repeat count:\n\
2306 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002307 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002308 h:short; H:unsigned short; i:int; I:unsigned int;\n\
Mark Dickinson7c4e4092016-09-03 17:21:29 +01002309 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002310Special cases (preceding decimal count indicates length):\n\
2311 s:string (array of char); p: pascal string (with count byte).\n\
Antoine Pitrou45d9c912011-10-06 15:27:40 +02002312Special cases (only available in native format):\n\
2313 n:ssize_t; N:size_t;\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002314 P:an integer type that is wide enough to hold a pointer.\n\
2315Special case (not in native mode unless 'long long' in platform C):\n\
2316 q:long long; Q:unsigned long long\n\
2317Whitespace between formats is ignored.\n\
2318\n\
2319The variable struct.error is an exception raised on errors.\n");
2320
Martin v. Löwis1a214512008-06-11 05:26:20 +00002321
Dino Viehland4f384af2019-09-10 11:18:37 +01002322static int
2323_structmodule_traverse(PyObject *module, visitproc visit, void *arg)
2324{
Hai Shif707d942020-03-16 21:15:01 +08002325 _structmodulestate *state = (_structmodulestate *)PyModule_GetState(module);
2326 if (state) {
2327 Py_VISIT(state->PyStructType);
2328 Py_VISIT(state->unpackiter_type);
2329 Py_VISIT(state->StructError);
2330 }
Dino Viehland4f384af2019-09-10 11:18:37 +01002331 return 0;
2332}
2333
2334static int
2335_structmodule_clear(PyObject *module)
2336{
Hai Shif707d942020-03-16 21:15:01 +08002337 _structmodulestate *state = (_structmodulestate *)PyModule_GetState(module);
2338 if (state) {
2339 Py_CLEAR(state->PyStructType);
2340 Py_CLEAR(state->unpackiter_type);
2341 Py_CLEAR(state->StructError);
2342 }
Dino Viehland4f384af2019-09-10 11:18:37 +01002343 return 0;
2344}
2345
2346static void
2347_structmodule_free(void *module)
2348{
2349 _structmodule_clear((PyObject *)module);
2350}
2351
Martin v. Löwis1a214512008-06-11 05:26:20 +00002352static struct PyModuleDef _structmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002353 PyModuleDef_HEAD_INIT,
2354 "_struct",
2355 module_doc,
Dino Viehland4f384af2019-09-10 11:18:37 +01002356 sizeof(_structmodulestate),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002357 module_functions,
2358 NULL,
Dino Viehland4f384af2019-09-10 11:18:37 +01002359 _structmodule_traverse,
2360 _structmodule_clear,
2361 _structmodule_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +00002362};
2363
Thomas Wouters477c8d52006-05-27 19:21:47 +00002364PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002365PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002366{
Mark Dickinson06817852010-06-12 09:25:13 +00002367 PyObject *m;
Christian Heimesa34706f2008-01-04 03:06:10 +00002368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002369 m = PyModule_Create(&_structmodule);
2370 if (m == NULL)
2371 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002372
Dino Viehland4f384af2019-09-10 11:18:37 +01002373 PyObject *PyStructType = PyType_FromSpec(&PyStructType_spec);
2374 if (PyStructType == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 return NULL;
Dino Viehland4f384af2019-09-10 11:18:37 +01002376 }
2377 Py_INCREF(PyStructType);
2378 PyModule_AddObject(m, "Struct", PyStructType);
Hai Shif707d942020-03-16 21:15:01 +08002379 get_struct_state(m)->PyStructType = PyStructType;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002380
Dino Viehland4f384af2019-09-10 11:18:37 +01002381 PyObject *unpackiter_type = PyType_FromSpec(&unpackiter_type_spec);
2382 if (unpackiter_type == NULL) {
Zachary Ware99f11b42016-10-04 01:20:21 -05002383 return NULL;
Dino Viehland4f384af2019-09-10 11:18:37 +01002384 }
Hai Shif707d942020-03-16 21:15:01 +08002385 get_struct_state(m)->unpackiter_type = unpackiter_type;
Zachary Ware99f11b42016-10-04 01:20:21 -05002386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002387 /* Check endian and swap in faster functions */
2388 {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002389 const formatdef *native = native_table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002390 formatdef *other, *ptr;
Christian Heimes743e0cd2012-10-17 23:52:17 +02002391#if PY_LITTLE_ENDIAN
2392 other = lilendian_table;
2393#else
2394 other = bigendian_table;
2395#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002396 /* Scan through the native table, find a matching
2397 entry in the endian table and swap in the
2398 native implementations whenever possible
2399 (64-bit platforms may not have "standard" sizes) */
2400 while (native->format != '\0' && other->format != '\0') {
2401 ptr = other;
2402 while (ptr->format != '\0') {
2403 if (ptr->format == native->format) {
2404 /* Match faster when formats are
2405 listed in the same order */
2406 if (ptr == other)
2407 other++;
2408 /* Only use the trick if the
2409 size matches */
2410 if (ptr->size != native->size)
2411 break;
2412 /* Skip float and double, could be
2413 "unknown" float format */
2414 if (ptr->format == 'd' || ptr->format == 'f')
2415 break;
Stefan Krah472fc842020-03-24 14:01:13 +01002416 /* Skip _Bool, semantics are different for standard size */
2417 if (ptr->format == '?')
2418 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002419 ptr->pack = native->pack;
2420 ptr->unpack = native->unpack;
2421 break;
2422 }
2423 ptr++;
2424 }
2425 native++;
2426 }
2427 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002428
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002429 /* Add some symbolic constants to the module */
Dino Viehland4f384af2019-09-10 11:18:37 +01002430 PyObject *StructError = PyErr_NewException("struct.error", NULL, NULL);
2431 if (StructError == NULL)
2432 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002433 Py_INCREF(StructError);
2434 PyModule_AddObject(m, "error", StructError);
Hai Shif707d942020-03-16 21:15:01 +08002435 get_struct_state(m)->StructError = StructError;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002438}