blob: 30ad9f2b79d8f3fdc378ade6c8a66bb9c2bec882 [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 Stinnercdad2722021-04-22 00:52:52 +02009#include "pycore_moduleobject.h" // _PyModule_GetState()
Victor Stinner4a21e572020-04-15 02:35:41 +020010#include "structmember.h" // PyMemberDef
Thomas Wouters477c8d52006-05-27 19:21:47 +000011#include <ctype.h>
12
Victor Stinner3f2d1012017-02-02 12:09:30 +010013/*[clinic input]
14class Struct "PyStructObject *" "&PyStructType"
15[clinic start generated code]*/
16/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/
17
Dino Viehland4f384af2019-09-10 11:18:37 +010018typedef struct {
Christian Heimescfeb5432020-11-19 14:36:23 +010019 PyObject *cache;
Dino Viehland4f384af2019-09-10 11:18:37 +010020 PyObject *PyStructType;
21 PyObject *unpackiter_type;
22 PyObject *StructError;
23} _structmodulestate;
24
Hai Shif707d942020-03-16 21:15:01 +080025static inline _structmodulestate*
26get_struct_state(PyObject *module)
27{
Victor Stinnercdad2722021-04-22 00:52:52 +020028 void *state = _PyModule_GetState(module);
Hai Shif707d942020-03-16 21:15:01 +080029 assert(state != NULL);
30 return (_structmodulestate *)state;
31}
Dino Viehland4f384af2019-09-10 11:18:37 +010032
33static struct PyModuleDef _structmodule;
34
Christian Heimescfeb5432020-11-19 14:36:23 +010035#define get_struct_state_structinst(self) \
36 (get_struct_state(_PyType_GetModuleByDef(Py_TYPE(self), &_structmodule)))
37#define get_struct_state_iterinst(self) \
38 (get_struct_state(PyType_GetModule(Py_TYPE(self))))
Thomas Wouters477c8d52006-05-27 19:21:47 +000039
Thomas Wouters477c8d52006-05-27 19:21:47 +000040/* The translation function for each format character is table driven */
41typedef struct _formatdef {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000042 char format;
43 Py_ssize_t size;
44 Py_ssize_t alignment;
Christian Heimescfeb5432020-11-19 14:36:23 +010045 PyObject* (*unpack)(_structmodulestate *, const char *,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000046 const struct _formatdef *);
Christian Heimescfeb5432020-11-19 14:36:23 +010047 int (*pack)(_structmodulestate *, char *, PyObject *,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000048 const struct _formatdef *);
Thomas Wouters477c8d52006-05-27 19:21:47 +000049} formatdef;
50
51typedef struct _formatcode {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000052 const struct _formatdef *fmtdef;
53 Py_ssize_t offset;
54 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +030055 Py_ssize_t repeat;
Thomas Wouters477c8d52006-05-27 19:21:47 +000056} formatcode;
57
58/* Struct object interface */
59
60typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000061 PyObject_HEAD
62 Py_ssize_t s_size;
63 Py_ssize_t s_len;
64 formatcode *s_codes;
65 PyObject *s_format;
66 PyObject *weakreflist; /* List of weak references */
Thomas Wouters477c8d52006-05-27 19:21:47 +000067} PyStructObject;
68
Christian Heimescfeb5432020-11-19 14:36:23 +010069#define PyStruct_Check(op, state) PyObject_TypeCheck(op, (PyTypeObject *)(state)->PyStructType)
Thomas Wouters477c8d52006-05-27 19:21:47 +000070
71/* Define various structs to figure out the alignments of types */
72
73
74typedef struct { char c; short x; } st_short;
75typedef struct { char c; int x; } st_int;
76typedef struct { char c; long x; } st_long;
77typedef struct { char c; float x; } st_float;
78typedef struct { char c; double x; } st_double;
79typedef struct { char c; void *x; } st_void_p;
Antoine Pitrou45d9c912011-10-06 15:27:40 +020080typedef struct { char c; size_t x; } st_size_t;
Benjamin Petersona9296e72016-09-07 11:06:17 -070081typedef struct { char c; _Bool x; } st_bool;
Thomas Wouters477c8d52006-05-27 19:21:47 +000082
83#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
84#define INT_ALIGN (sizeof(st_int) - sizeof(int))
85#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
86#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
87#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
88#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
Antoine Pitrou45d9c912011-10-06 15:27:40 +020089#define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t))
Benjamin Petersona9296e72016-09-07 11:06:17 -070090#define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool))
Thomas Wouters477c8d52006-05-27 19:21:47 +000091
92/* We can't support q and Q in native mode unless the compiler does;
93 in std mode, they're 8 bytes on all platforms. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -070094typedef struct { char c; long long x; } s_long_long;
95#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long))
Thomas Wouters477c8d52006-05-27 19:21:47 +000096
Thomas Wouters477c8d52006-05-27 19:21:47 +000097#ifdef __powerc
98#pragma options align=reset
99#endif
100
Serhiy Storchakaa5a55902017-02-04 11:14:52 +0200101/*[python input]
102class cache_struct_converter(CConverter):
103 type = 'PyStructObject *'
104 converter = 'cache_struct_converter'
105 c_default = "NULL"
106
Christian Heimescfeb5432020-11-19 14:36:23 +0100107 def parse_arg(self, argname, displayname):
108 return """
109 if (!{converter}(module, {argname}, &{paramname})) {{{{
110 goto exit;
111 }}}}
112 """.format(argname=argname, paramname=self.name,
113 converter=self.converter)
114
Serhiy Storchakaa5a55902017-02-04 11:14:52 +0200115 def cleanup(self):
116 return "Py_XDECREF(%s);\n" % self.name
117[python start generated code]*/
Christian Heimescfeb5432020-11-19 14:36:23 +0100118/*[python end generated code: output=da39a3ee5e6b4b0d input=d6746621c2fb1a7d]*/
Serhiy Storchakaa5a55902017-02-04 11:14:52 +0200119
Christian Heimescfeb5432020-11-19 14:36:23 +0100120static int cache_struct_converter(PyObject *, PyObject *, PyStructObject **);
Serhiy Storchakaa5a55902017-02-04 11:14:52 +0200121
Victor Stinner3f2d1012017-02-02 12:09:30 +0100122#include "clinic/_struct.c.h"
123
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000124/* Helper for integer format codes: converts an arbitrary Python object to a
125 PyLongObject if possible, otherwise fails. Caller should decref. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000126
127static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100128get_pylong(_structmodulestate *state, PyObject *v)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000129{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 assert(v != NULL);
131 if (!PyLong_Check(v)) {
132 /* Not an integer; try to use __index__ to convert. */
133 if (PyIndex_Check(v)) {
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300134 v = _PyNumber_Index(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 if (v == NULL)
136 return NULL;
137 }
138 else {
Christian Heimescfeb5432020-11-19 14:36:23 +0100139 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000140 "required argument is not an integer");
141 return NULL;
142 }
143 }
144 else
145 Py_INCREF(v);
Mark Dickinsonea835e72009-04-19 20:40:33 +0000146
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 assert(PyLong_Check(v));
148 return v;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000149}
150
Mark Dickinsonea835e72009-04-19 20:40:33 +0000151/* Helper routine to get a C long and raise the appropriate error if it isn't
152 one */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000153
154static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100155get_long(_structmodulestate *state, PyObject *v, long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000156{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000158
Christian Heimescfeb5432020-11-19 14:36:23 +0100159 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 if (v == NULL)
161 return -1;
162 assert(PyLong_Check(v));
163 x = PyLong_AsLong(v);
164 Py_DECREF(v);
165 if (x == (long)-1 && PyErr_Occurred()) {
166 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +0100167 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 "argument out of range");
169 return -1;
170 }
171 *p = x;
172 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000173}
174
175
176/* Same, but handling unsigned long */
177
178static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100179get_ulong(_structmodulestate *state, PyObject *v, unsigned long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 unsigned long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000182
Christian Heimescfeb5432020-11-19 14:36:23 +0100183 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 if (v == NULL)
185 return -1;
186 assert(PyLong_Check(v));
187 x = PyLong_AsUnsignedLong(v);
188 Py_DECREF(v);
189 if (x == (unsigned long)-1 && PyErr_Occurred()) {
190 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +0100191 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 "argument out of range");
193 return -1;
194 }
195 *p = x;
196 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000197}
198
Thomas Wouters477c8d52006-05-27 19:21:47 +0000199/* Same, but handling native long long. */
200
201static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100202get_longlong(_structmodulestate *state, PyObject *v, long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000203{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700204 long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000205
Christian Heimescfeb5432020-11-19 14:36:23 +0100206 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000207 if (v == NULL)
208 return -1;
209 assert(PyLong_Check(v));
210 x = PyLong_AsLongLong(v);
211 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700212 if (x == (long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +0100214 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 "argument out of range");
216 return -1;
217 }
218 *p = x;
219 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000220}
221
222/* Same, but handling native unsigned long long. */
223
224static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100225get_ulonglong(_structmodulestate *state, PyObject *v, unsigned long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000226{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700227 unsigned long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000228
Christian Heimescfeb5432020-11-19 14:36:23 +0100229 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000230 if (v == NULL)
231 return -1;
232 assert(PyLong_Check(v));
233 x = PyLong_AsUnsignedLongLong(v);
234 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700235 if (x == (unsigned long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000236 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +0100237 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000238 "argument out of range");
239 return -1;
240 }
241 *p = x;
242 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000243}
244
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200245/* Same, but handling Py_ssize_t */
246
247static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100248get_ssize_t(_structmodulestate *state, PyObject *v, Py_ssize_t *p)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200249{
250 Py_ssize_t x;
251
Christian Heimescfeb5432020-11-19 14:36:23 +0100252 v = get_pylong(state, v);
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200253 if (v == NULL)
254 return -1;
255 assert(PyLong_Check(v));
256 x = PyLong_AsSsize_t(v);
257 Py_DECREF(v);
258 if (x == (Py_ssize_t)-1 && PyErr_Occurred()) {
259 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +0100260 PyErr_SetString(state->StructError,
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200261 "argument out of range");
262 return -1;
263 }
264 *p = x;
265 return 0;
266}
267
268/* Same, but handling size_t */
269
270static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100271get_size_t(_structmodulestate *state, PyObject *v, size_t *p)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200272{
273 size_t x;
274
Christian Heimescfeb5432020-11-19 14:36:23 +0100275 v = get_pylong(state, v);
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200276 if (v == NULL)
277 return -1;
278 assert(PyLong_Check(v));
279 x = PyLong_AsSize_t(v);
280 Py_DECREF(v);
281 if (x == (size_t)-1 && PyErr_Occurred()) {
282 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +0100283 PyErr_SetString(state->StructError,
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200284 "argument out of range");
285 return -1;
286 }
287 *p = x;
288 return 0;
289}
290
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000291
Christian Heimescfeb5432020-11-19 14:36:23 +0100292#define RANGE_ERROR(state, x, f, flag, mask) return _range_error(state, f, flag)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000293
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000294
Thomas Wouters477c8d52006-05-27 19:21:47 +0000295/* Floating point helpers */
296
297static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100298unpack_halffloat(const char *p, /* start of 2-byte string */
299 int le) /* true for little-endian, false for big-endian */
300{
301 double x;
302
303 x = _PyFloat_Unpack2((unsigned char *)p, le);
304 if (x == -1.0 && PyErr_Occurred()) {
305 return NULL;
306 }
307 return PyFloat_FromDouble(x);
308}
309
310static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100311pack_halffloat(_structmodulestate *state,
312 char *p, /* start of 2-byte string */
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100313 PyObject *v, /* value to pack */
314 int le) /* true for little-endian, false for big-endian */
315{
316 double x = PyFloat_AsDouble(v);
317 if (x == -1.0 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100318 PyErr_SetString(state->StructError,
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100319 "required argument is not a float");
320 return -1;
321 }
322 return _PyFloat_Pack2(x, (unsigned char *)p, le);
323}
324
325static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000326unpack_float(const char *p, /* start of 4-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 x = _PyFloat_Unpack4((unsigned char *)p, le);
332 if (x == -1.0 && PyErr_Occurred())
333 return NULL;
334 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000335}
336
337static PyObject *
338unpack_double(const char *p, /* start of 8-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000340{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000342
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000343 x = _PyFloat_Unpack8((unsigned char *)p, le);
344 if (x == -1.0 && PyErr_Occurred())
345 return NULL;
346 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000347}
348
349/* Helper to format the range error exceptions */
350static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100351_range_error(_structmodulestate *state, const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000352{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 /* ulargest is the largest unsigned value with f->size bytes.
354 * Note that the simpler:
355 * ((size_t)1 << (f->size * 8)) - 1
356 * doesn't work when f->size == sizeof(size_t) because C doesn't
357 * define what happens when a left shift count is >= the number of
358 * bits in the integer being shifted; e.g., on some boxes it doesn't
359 * shift at all when they're equal.
360 */
361 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
362 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
363 if (is_unsigned)
Christian Heimescfeb5432020-11-19 14:36:23 +0100364 PyErr_Format(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 "'%c' format requires 0 <= number <= %zu",
366 f->format,
367 ulargest);
368 else {
369 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
Christian Heimescfeb5432020-11-19 14:36:23 +0100370 PyErr_Format(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 "'%c' format requires %zd <= number <= %zd",
372 f->format,
373 ~ largest,
374 largest);
375 }
Mark Dickinsonae681df2009-03-21 10:26:31 +0000376
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000378}
379
380
381
382/* A large number of small routines follow, with names of the form
383
384 [bln][up]_TYPE
385
Min ho Kimc4cacc82019-07-31 08:16:13 +1000386 [bln] distinguishes among big-endian, little-endian and native.
387 [pu] distinguishes between pack (to struct) and unpack (from struct).
Thomas Wouters477c8d52006-05-27 19:21:47 +0000388 TYPE is one of char, byte, ubyte, etc.
389*/
390
391/* Native mode routines. ****************************************************/
392/* NOTE:
393 In all n[up]_<type> routines handling types larger than 1 byte, there is
394 *no* guarantee that the p pointer is properly aligned for each type,
395 therefore memcpy is called. An intermediate variable is used to
396 compensate for big-endian architectures.
397 Normally both the intermediate variable and the memcpy call will be
398 skipped by C optimisation in little-endian architectures (gcc >= 2.91
399 does this). */
400
401static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100402nu_char(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000403{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 return PyBytes_FromStringAndSize(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000405}
406
407static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100408nu_byte(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000409{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000410 return PyLong_FromLong((long) *(signed char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000411}
412
413static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100414nu_ubyte(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 return PyLong_FromLong((long) *(unsigned char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000417}
418
419static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100420nu_short(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000421{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 short x;
423 memcpy((char *)&x, p, sizeof x);
424 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000425}
426
427static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100428nu_ushort(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000429{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000430 unsigned short x;
431 memcpy((char *)&x, p, sizeof x);
432 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000433}
434
435static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100436nu_int(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000437{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 int x;
439 memcpy((char *)&x, p, sizeof x);
440 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000441}
442
443static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100444nu_uint(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000445{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 unsigned int x;
447 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 return PyLong_FromUnsignedLong((unsigned long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000449}
450
451static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100452nu_long(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 long x;
455 memcpy((char *)&x, p, sizeof x);
456 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000457}
458
459static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100460nu_ulong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000461{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000462 unsigned long x;
463 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000465}
466
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200467static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100468nu_ssize_t(_structmodulestate *state, const char *p, const formatdef *f)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200469{
470 Py_ssize_t x;
471 memcpy((char *)&x, p, sizeof x);
472 return PyLong_FromSsize_t(x);
473}
474
475static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100476nu_size_t(_structmodulestate *state, const char *p, const formatdef *f)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200477{
478 size_t x;
479 memcpy((char *)&x, p, sizeof x);
480 return PyLong_FromSize_t(x);
481}
482
Thomas Wouters477c8d52006-05-27 19:21:47 +0000483static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100484nu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000485{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700486 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000489}
490
491static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100492nu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000493{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700494 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000497}
498
Thomas Wouters477c8d52006-05-27 19:21:47 +0000499static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100500nu_bool(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Woutersb2137042007-02-01 18:02:27 +0000501{
Benjamin Petersona9296e72016-09-07 11:06:17 -0700502 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 memcpy((char *)&x, p, sizeof x);
504 return PyBool_FromLong(x != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000505}
506
507
508static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100509nu_halffloat(_structmodulestate *state, const char *p, const formatdef *f)
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100510{
511#if PY_LITTLE_ENDIAN
512 return unpack_halffloat(p, 1);
513#else
514 return unpack_halffloat(p, 0);
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700515#endif
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100516}
517
518static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100519nu_float(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000520{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 float x;
522 memcpy((char *)&x, p, sizeof x);
523 return PyFloat_FromDouble((double)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000524}
525
526static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100527nu_double(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000528{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 double x;
530 memcpy((char *)&x, p, sizeof x);
531 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000532}
533
534static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100535nu_void_p(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000536{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 void *x;
538 memcpy((char *)&x, p, sizeof x);
539 return PyLong_FromVoidPtr(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000540}
541
542static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100543np_byte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000544{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 long x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100546 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800548 if (x < -128 || x > 127) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100549 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000550 "byte format requires -128 <= number <= 127");
551 return -1;
552 }
553 *p = (char)x;
554 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000555}
556
557static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100558np_ubyte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000559{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 long x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100561 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800563 if (x < 0 || x > 255) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100564 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 "ubyte format requires 0 <= number <= 255");
566 return -1;
567 }
Xiang Zhang981096f2017-05-15 12:04:26 +0800568 *(unsigned char *)p = (unsigned char)x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000569 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000570}
571
572static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100573np_char(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000574{
Dino Viehland4f384af2019-09-10 11:18:37 +0100575 if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100576 PyErr_SetString(state->StructError,
Victor Stinnerda9ec992010-12-28 13:26:42 +0000577 "char format requires a bytes object of length 1");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 return -1;
579 }
Xiang Zhang96f50282017-05-15 11:53:51 +0800580 *p = *PyBytes_AS_STRING(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000581 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000582}
583
584static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100585np_short(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000586{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 long x;
588 short y;
Christian Heimescfeb5432020-11-19 14:36:23 +0100589 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000590 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800591 if (x < SHRT_MIN || x > SHRT_MAX) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100592 PyErr_SetString(state->StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200593 "short format requires " Py_STRINGIFY(SHRT_MIN)
594 " <= number <= " Py_STRINGIFY(SHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000595 return -1;
596 }
597 y = (short)x;
598 memcpy(p, (char *)&y, sizeof y);
599 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000600}
601
602static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100603np_ushort(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000604{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 long x;
606 unsigned short y;
Christian Heimescfeb5432020-11-19 14:36:23 +0100607 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000608 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800609 if (x < 0 || x > USHRT_MAX) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100610 PyErr_SetString(state->StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200611 "ushort format requires 0 <= number <= "
612 Py_STRINGIFY(USHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 return -1;
614 }
615 y = (unsigned short)x;
616 memcpy(p, (char *)&y, sizeof y);
617 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000618}
619
620static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100621np_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000622{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 long x;
624 int y;
Christian Heimescfeb5432020-11-19 14:36:23 +0100625 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000627#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Christian Heimescfeb5432020-11-19 14:36:23 +0100629 RANGE_ERROR(state, x, f, 0, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000630#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 y = (int)x;
632 memcpy(p, (char *)&y, sizeof y);
633 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000634}
635
636static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100637np_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000638{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 unsigned long x;
640 unsigned int y;
Christian Heimescfeb5432020-11-19 14:36:23 +0100641 if (get_ulong(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 return -1;
643 y = (unsigned int)x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000644#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000645 if (x > ((unsigned long)UINT_MAX))
Christian Heimescfeb5432020-11-19 14:36:23 +0100646 RANGE_ERROR(state, y, f, 1, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000647#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 memcpy(p, (char *)&y, sizeof y);
649 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000650}
651
652static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100653np_long(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000654{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000655 long x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100656 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000657 return -1;
658 memcpy(p, (char *)&x, sizeof x);
659 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000660}
661
662static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100663np_ulong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000664{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 unsigned long x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100666 if (get_ulong(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 return -1;
668 memcpy(p, (char *)&x, sizeof x);
669 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000670}
671
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200672static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100673np_ssize_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200674{
675 Py_ssize_t x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100676 if (get_ssize_t(state, v, &x) < 0)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200677 return -1;
678 memcpy(p, (char *)&x, sizeof x);
679 return 0;
680}
681
682static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100683np_size_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200684{
685 size_t x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100686 if (get_size_t(state, v, &x) < 0)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200687 return -1;
688 memcpy(p, (char *)&x, sizeof x);
689 return 0;
690}
691
Thomas Wouters477c8d52006-05-27 19:21:47 +0000692static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100693np_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000694{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700695 long long x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100696 if (get_longlong(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 return -1;
698 memcpy(p, (char *)&x, sizeof x);
699 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000700}
701
702static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100703np_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000704{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700705 unsigned long long x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100706 if (get_ulonglong(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 return -1;
708 memcpy(p, (char *)&x, sizeof x);
709 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000710}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000711
Thomas Woutersb2137042007-02-01 18:02:27 +0000712
713static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100714np_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Woutersb2137042007-02-01 18:02:27 +0000715{
Benjamin Petersonde73c452010-07-07 18:54:59 +0000716 int y;
Benjamin Petersona9296e72016-09-07 11:06:17 -0700717 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000718 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000719 if (y < 0)
720 return -1;
721 x = y;
722 memcpy(p, (char *)&x, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000724}
725
Thomas Wouters477c8d52006-05-27 19:21:47 +0000726static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100727np_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100728{
729#if PY_LITTLE_ENDIAN
Christian Heimescfeb5432020-11-19 14:36:23 +0100730 return pack_halffloat(state, p, v, 1);
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100731#else
Dong-hee Na588c7c92020-11-19 23:14:34 +0900732 return pack_halffloat(state, p, v, 0);
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100733#endif
734}
735
736static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100737np_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000738{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 float x = (float)PyFloat_AsDouble(v);
740 if (x == -1 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100741 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 "required argument is not a float");
743 return -1;
744 }
745 memcpy(p, (char *)&x, sizeof x);
746 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000747}
748
749static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100750np_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000751{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 double x = PyFloat_AsDouble(v);
753 if (x == -1 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100754 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 "required argument is not a float");
756 return -1;
757 }
758 memcpy(p, (char *)&x, sizeof(double));
759 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000760}
761
762static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100763np_void_p(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000764{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000765 void *x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000766
Christian Heimescfeb5432020-11-19 14:36:23 +0100767 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000768 if (v == NULL)
769 return -1;
770 assert(PyLong_Check(v));
771 x = PyLong_AsVoidPtr(v);
772 Py_DECREF(v);
773 if (x == NULL && PyErr_Occurred())
774 return -1;
775 memcpy(p, (char *)&x, sizeof x);
776 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000777}
778
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200779static const formatdef native_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 {'x', sizeof(char), 0, NULL},
781 {'b', sizeof(char), 0, nu_byte, np_byte},
782 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
783 {'c', sizeof(char), 0, nu_char, np_char},
784 {'s', sizeof(char), 0, NULL},
785 {'p', sizeof(char), 0, NULL},
786 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
787 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
788 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
789 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
790 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
791 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200792 {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t},
793 {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t},
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700794 {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong},
795 {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Benjamin Petersona9296e72016-09-07 11:06:17 -0700796 {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100797 {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
799 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
800 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
801 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000802};
803
804/* Big-endian routines. *****************************************************/
805
806static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100807bu_int(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000808{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 long x = 0;
810 Py_ssize_t i = f->size;
811 const unsigned char *bytes = (const unsigned char *)p;
812 do {
813 x = (x<<8) | *bytes++;
814 } while (--i > 0);
815 /* Extend the sign bit. */
816 if (SIZEOF_LONG > f->size)
817 x |= -(x & (1L << ((8 * f->size) - 1)));
818 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000819}
820
821static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100822bu_uint(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000823{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000824 unsigned long x = 0;
825 Py_ssize_t i = f->size;
826 const unsigned char *bytes = (const unsigned char *)p;
827 do {
828 x = (x<<8) | *bytes++;
829 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000830 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000831}
832
833static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100834bu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000835{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700836 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 Py_ssize_t i = f->size;
838 const unsigned char *bytes = (const unsigned char *)p;
839 do {
840 x = (x<<8) | *bytes++;
841 } while (--i > 0);
842 /* Extend the sign bit. */
843 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700844 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000846}
847
848static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100849bu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000850{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700851 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 Py_ssize_t i = f->size;
853 const unsigned char *bytes = (const unsigned char *)p;
854 do {
855 x = (x<<8) | *bytes++;
856 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000857 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000858}
859
860static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100861bu_halffloat(_structmodulestate *state, const char *p, const formatdef *f)
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100862{
863 return unpack_halffloat(p, 0);
864}
865
866static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100867bu_float(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000868{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000869 return unpack_float(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000870}
871
872static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100873bu_double(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000874{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000875 return unpack_double(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000876}
877
Thomas Woutersb2137042007-02-01 18:02:27 +0000878static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100879bu_bool(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Woutersb2137042007-02-01 18:02:27 +0000880{
Xiang Zhang96f50282017-05-15 11:53:51 +0800881 return PyBool_FromLong(*p != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000882}
883
Thomas Wouters477c8d52006-05-27 19:21:47 +0000884static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100885bp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000886{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000887 long x;
888 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800889 unsigned char *q = (unsigned char *)p;
Christian Heimescfeb5432020-11-19 14:36:23 +0100890 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 return -1;
892 i = f->size;
893 if (i != SIZEOF_LONG) {
894 if ((i == 2) && (x < -32768 || x > 32767))
Christian Heimescfeb5432020-11-19 14:36:23 +0100895 RANGE_ERROR(state, x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000896#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000897 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Christian Heimescfeb5432020-11-19 14:36:23 +0100898 RANGE_ERROR(state, x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000899#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 }
901 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800902 q[--i] = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 x >>= 8;
904 } while (i > 0);
905 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000906}
907
908static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100909bp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000910{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 unsigned long x;
912 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800913 unsigned char *q = (unsigned char *)p;
Christian Heimescfeb5432020-11-19 14:36:23 +0100914 if (get_ulong(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000915 return -1;
916 i = f->size;
917 if (i != SIZEOF_LONG) {
918 unsigned long maxint = 1;
919 maxint <<= (unsigned long)(i * 8);
920 if (x >= maxint)
Christian Heimescfeb5432020-11-19 14:36:23 +0100921 RANGE_ERROR(state, x, f, 1, maxint - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 }
923 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800924 q[--i] = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 x >>= 8;
926 } while (i > 0);
927 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000928}
929
930static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100931bp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000932{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 int res;
Christian Heimescfeb5432020-11-19 14:36:23 +0100934 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000935 if (v == NULL)
936 return -1;
937 res = _PyLong_AsByteArray((PyLongObject *)v,
938 (unsigned char *)p,
939 8,
940 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800941 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000942 Py_DECREF(v);
943 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000944}
945
946static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100947bp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 int res;
Christian Heimescfeb5432020-11-19 14:36:23 +0100950 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 if (v == NULL)
952 return -1;
953 res = _PyLong_AsByteArray((PyLongObject *)v,
954 (unsigned char *)p,
955 8,
956 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800957 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 Py_DECREF(v);
959 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000960}
961
962static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100963bp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100964{
Christian Heimescfeb5432020-11-19 14:36:23 +0100965 return pack_halffloat(state, p, v, 0);
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100966}
967
968static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100969bp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000970{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 double x = PyFloat_AsDouble(v);
972 if (x == -1 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100973 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 "required argument is not a float");
975 return -1;
976 }
977 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000978}
979
980static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100981bp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000982{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 double x = PyFloat_AsDouble(v);
984 if (x == -1 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100985 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 "required argument is not a float");
987 return -1;
988 }
989 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000990}
991
Thomas Woutersb2137042007-02-01 18:02:27 +0000992static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100993bp_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Woutersb2137042007-02-01 18:02:27 +0000994{
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000995 int y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000996 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000997 if (y < 0)
998 return -1;
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000999 *p = (char)y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +00001001}
1002
Thomas Wouters477c8d52006-05-27 19:21:47 +00001003static formatdef bigendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 {'x', 1, 0, NULL},
1005 {'b', 1, 0, nu_byte, np_byte},
1006 {'B', 1, 0, nu_ubyte, np_ubyte},
1007 {'c', 1, 0, nu_char, np_char},
1008 {'s', 1, 0, NULL},
1009 {'p', 1, 0, NULL},
1010 {'h', 2, 0, bu_int, bp_int},
1011 {'H', 2, 0, bu_uint, bp_uint},
1012 {'i', 4, 0, bu_int, bp_int},
1013 {'I', 4, 0, bu_uint, bp_uint},
1014 {'l', 4, 0, bu_int, bp_int},
1015 {'L', 4, 0, bu_uint, bp_uint},
1016 {'q', 8, 0, bu_longlong, bp_longlong},
1017 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
1018 {'?', 1, 0, bu_bool, bp_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001019 {'e', 2, 0, bu_halffloat, bp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 {'f', 4, 0, bu_float, bp_float},
1021 {'d', 8, 0, bu_double, bp_double},
1022 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001023};
1024
1025/* Little-endian routines. *****************************************************/
1026
1027static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001028lu_int(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001029{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001030 long x = 0;
1031 Py_ssize_t i = f->size;
1032 const unsigned char *bytes = (const unsigned char *)p;
1033 do {
1034 x = (x<<8) | bytes[--i];
1035 } while (i > 0);
1036 /* Extend the sign bit. */
1037 if (SIZEOF_LONG > f->size)
1038 x |= -(x & (1L << ((8 * f->size) - 1)));
1039 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001040}
1041
1042static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001043lu_uint(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001044{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 unsigned long x = 0;
1046 Py_ssize_t i = f->size;
1047 const unsigned char *bytes = (const unsigned char *)p;
1048 do {
1049 x = (x<<8) | bytes[--i];
1050 } while (i > 0);
Xiang Zhang96f50282017-05-15 11:53:51 +08001051 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001052}
1053
1054static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001055lu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001056{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001057 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 Py_ssize_t i = f->size;
1059 const unsigned char *bytes = (const unsigned char *)p;
1060 do {
1061 x = (x<<8) | bytes[--i];
1062 } while (i > 0);
1063 /* Extend the sign bit. */
1064 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001065 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001067}
1068
1069static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001070lu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001071{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001072 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 Py_ssize_t i = f->size;
1074 const unsigned char *bytes = (const unsigned char *)p;
1075 do {
1076 x = (x<<8) | bytes[--i];
1077 } while (i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001079}
1080
1081static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001082lu_halffloat(_structmodulestate *state, const char *p, const formatdef *f)
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001083{
1084 return unpack_halffloat(p, 1);
1085}
1086
1087static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001088lu_float(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 return unpack_float(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001091}
1092
1093static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001094lu_double(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001095{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 return unpack_double(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001097}
1098
1099static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001100lp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001101{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 long x;
1103 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001104 unsigned char *q = (unsigned char *)p;
Christian Heimescfeb5432020-11-19 14:36:23 +01001105 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001106 return -1;
1107 i = f->size;
1108 if (i != SIZEOF_LONG) {
1109 if ((i == 2) && (x < -32768 || x > 32767))
Christian Heimescfeb5432020-11-19 14:36:23 +01001110 RANGE_ERROR(state, x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001111#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001112 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Christian Heimescfeb5432020-11-19 14:36:23 +01001113 RANGE_ERROR(state, x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001114#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 }
1116 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001117 *q++ = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 x >>= 8;
1119 } while (--i > 0);
1120 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001121}
1122
1123static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001124lp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001125{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 unsigned long x;
1127 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001128 unsigned char *q = (unsigned char *)p;
Christian Heimescfeb5432020-11-19 14:36:23 +01001129 if (get_ulong(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001130 return -1;
1131 i = f->size;
1132 if (i != SIZEOF_LONG) {
1133 unsigned long maxint = 1;
1134 maxint <<= (unsigned long)(i * 8);
1135 if (x >= maxint)
Christian Heimescfeb5432020-11-19 14:36:23 +01001136 RANGE_ERROR(state, x, f, 1, maxint - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 }
1138 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001139 *q++ = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 x >>= 8;
1141 } while (--i > 0);
1142 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001143}
1144
1145static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001146lp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001147{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001148 int res;
Christian Heimescfeb5432020-11-19 14:36:23 +01001149 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 if (v == NULL)
1151 return -1;
1152 res = _PyLong_AsByteArray((PyLongObject*)v,
1153 (unsigned char *)p,
1154 8,
1155 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001156 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001157 Py_DECREF(v);
1158 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001159}
1160
1161static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001162lp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 int res;
Christian Heimescfeb5432020-11-19 14:36:23 +01001165 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 if (v == NULL)
1167 return -1;
1168 res = _PyLong_AsByteArray((PyLongObject*)v,
1169 (unsigned char *)p,
1170 8,
1171 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001172 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 Py_DECREF(v);
1174 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001175}
1176
1177static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001178lp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001179{
Christian Heimescfeb5432020-11-19 14:36:23 +01001180 return pack_halffloat(state, p, v, 1);
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001181}
1182
1183static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001184lp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001185{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 double x = PyFloat_AsDouble(v);
1187 if (x == -1 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001188 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 "required argument is not a float");
1190 return -1;
1191 }
1192 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001193}
1194
1195static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001196lp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001197{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 double x = PyFloat_AsDouble(v);
1199 if (x == -1 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001200 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 "required argument is not a float");
1202 return -1;
1203 }
1204 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001205}
1206
1207static formatdef lilendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 {'x', 1, 0, NULL},
1209 {'b', 1, 0, nu_byte, np_byte},
1210 {'B', 1, 0, nu_ubyte, np_ubyte},
1211 {'c', 1, 0, nu_char, np_char},
1212 {'s', 1, 0, NULL},
1213 {'p', 1, 0, NULL},
1214 {'h', 2, 0, lu_int, lp_int},
1215 {'H', 2, 0, lu_uint, lp_uint},
1216 {'i', 4, 0, lu_int, lp_int},
1217 {'I', 4, 0, lu_uint, lp_uint},
1218 {'l', 4, 0, lu_int, lp_int},
1219 {'L', 4, 0, lu_uint, lp_uint},
1220 {'q', 8, 0, lu_longlong, lp_longlong},
1221 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1222 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1223 but potentially different from native rep -- reuse bx_bool funcs. */
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001224 {'e', 2, 0, lu_halffloat, lp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 {'f', 4, 0, lu_float, lp_float},
1226 {'d', 8, 0, lu_double, lp_double},
1227 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001228};
1229
1230
1231static const formatdef *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001232whichtable(const char **pfmt)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001233{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001234 const char *fmt = (*pfmt)++; /* May be backed out of later */
1235 switch (*fmt) {
1236 case '<':
1237 return lilendian_table;
1238 case '>':
1239 case '!': /* Network byte order is big-endian */
1240 return bigendian_table;
Ezio Melotti42da6632011-03-15 05:18:48 +02001241 case '=': { /* Host byte order -- different from native in alignment! */
Christian Heimes743e0cd2012-10-17 23:52:17 +02001242#if PY_LITTLE_ENDIAN
1243 return lilendian_table;
1244#else
1245 return bigendian_table;
1246#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 }
1248 default:
1249 --*pfmt; /* Back out of pointer increment */
1250 /* Fall through */
1251 case '@':
1252 return native_table;
1253 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001254}
1255
1256
1257/* Get the table entry for a format code */
1258
1259static const formatdef *
Christian Heimescfeb5432020-11-19 14:36:23 +01001260getentry(_structmodulestate *state, int c, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001261{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 for (; f->format != '\0'; f++) {
1263 if (f->format == c) {
1264 return f;
1265 }
1266 }
Christian Heimescfeb5432020-11-19 14:36:23 +01001267 PyErr_SetString(state->StructError, "bad char in struct format");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001269}
1270
1271
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001272/* Align a size according to a format code. Return -1 on overflow. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001273
Mark Dickinsoneac0e682010-06-11 19:05:08 +00001274static Py_ssize_t
Thomas Wouters477c8d52006-05-27 19:21:47 +00001275align(Py_ssize_t size, char c, const formatdef *e)
1276{
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001277 Py_ssize_t extra;
1278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 if (e->format == c) {
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001280 if (e->alignment && size > 0) {
1281 extra = (e->alignment - 1) - (size - 1) % (e->alignment);
1282 if (extra > PY_SSIZE_T_MAX - size)
1283 return -1;
1284 size += extra;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001285 }
1286 }
1287 return size;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001288}
1289
Antoine Pitrou9f146812013-04-27 00:20:04 +02001290/*
1291 * Struct object implementation.
1292 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001293
1294/* calculate the size of a format string */
1295
1296static int
1297prepare_s(PyStructObject *self)
1298{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 const formatdef *f;
1300 const formatdef *e;
1301 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001302
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 const char *s;
1304 const char *fmt;
1305 char c;
Victor Stinner706768c2014-08-16 01:03:39 +02001306 Py_ssize_t size, len, num, itemsize;
1307 size_t ncodes;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001308
Christian Heimescfeb5432020-11-19 14:36:23 +01001309 _structmodulestate *state = get_struct_state_structinst(self);
1310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 fmt = PyBytes_AS_STRING(self->s_format);
Zackery Spytz3f59b552020-05-25 01:55:09 -06001312 if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(self->s_format)) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001313 PyErr_SetString(state->StructError,
Zackery Spytz3f59b552020-05-25 01:55:09 -06001314 "embedded null character");
1315 return -1;
1316 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001317
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001318 f = whichtable(&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 s = fmt;
1321 size = 0;
1322 len = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001323 ncodes = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 while ((c = *s++) != '\0') {
Jordon Xu2ec70102019-09-11 00:04:08 +08001325 if (Py_ISSPACE(c))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 continue;
1327 if ('0' <= c && c <= '9') {
1328 num = c - '0';
1329 while ('0' <= (c = *s++) && c <= '9') {
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001330 /* overflow-safe version of
1331 if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1332 if (num >= PY_SSIZE_T_MAX / 10 && (
1333 num > PY_SSIZE_T_MAX / 10 ||
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001334 (c - '0') > PY_SSIZE_T_MAX % 10))
1335 goto overflow;
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001336 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 }
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001338 if (c == '\0') {
Christian Heimescfeb5432020-11-19 14:36:23 +01001339 PyErr_SetString(state->StructError,
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001340 "repeat count given without format specifier");
1341 return -1;
1342 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 }
1344 else
1345 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001346
Christian Heimescfeb5432020-11-19 14:36:23 +01001347 e = getentry(state, c, f);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001348 if (e == NULL)
1349 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 switch (c) {
1352 case 's': /* fall through */
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001353 case 'p': len++; ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 case 'x': break;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001355 default: len += num; if (num) ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 itemsize = e->size;
1359 size = align(size, c, e);
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001360 if (size == -1)
1361 goto overflow;
1362
1363 /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1364 if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1365 goto overflow;
1366 size += num * itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 /* check for overflow */
Victor Stinner706768c2014-08-16 01:03:39 +02001370 if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 PyErr_NoMemory();
1372 return -1;
1373 }
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +00001374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001375 self->s_size = size;
1376 self->s_len = len;
Victor Stinner00d7abd2020-12-01 09:56:42 +01001377 codes = PyMem_Malloc((ncodes + 1) * sizeof(formatcode));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 if (codes == NULL) {
1379 PyErr_NoMemory();
1380 return -1;
1381 }
Mark Dickinsoncf28b952010-07-29 21:41:59 +00001382 /* Free any s_codes value left over from a previous initialization. */
1383 if (self->s_codes != NULL)
Victor Stinner00d7abd2020-12-01 09:56:42 +01001384 PyMem_Free(self->s_codes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001385 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001386
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001387 s = fmt;
1388 size = 0;
1389 while ((c = *s++) != '\0') {
Jordon Xu2ec70102019-09-11 00:04:08 +08001390 if (Py_ISSPACE(c))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 continue;
1392 if ('0' <= c && c <= '9') {
1393 num = c - '0';
1394 while ('0' <= (c = *s++) && c <= '9')
1395 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001396 }
1397 else
1398 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001399
Christian Heimescfeb5432020-11-19 14:36:23 +01001400 e = getentry(state, c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 size = align(size, c, e);
1403 if (c == 's' || c == 'p') {
1404 codes->offset = size;
1405 codes->size = num;
1406 codes->fmtdef = e;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001407 codes->repeat = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 codes++;
1409 size += num;
1410 } else if (c == 'x') {
1411 size += num;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001412 } else if (num) {
1413 codes->offset = size;
1414 codes->size = e->size;
1415 codes->fmtdef = e;
1416 codes->repeat = num;
1417 codes++;
1418 size += e->size * num;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 }
1420 }
1421 codes->fmtdef = NULL;
1422 codes->offset = size;
1423 codes->size = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001424 codes->repeat = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 return 0;
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001427
1428 overflow:
Christian Heimescfeb5432020-11-19 14:36:23 +01001429 PyErr_SetString(state->StructError,
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001430 "total struct size too long");
1431 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001432}
1433
1434static PyObject *
1435s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1436{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001437 PyObject *self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001438
Dino Viehland4f384af2019-09-10 11:18:37 +01001439 assert(type != NULL);
1440 allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc);
1441 assert(alloc_func != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001442
Dino Viehland4f384af2019-09-10 11:18:37 +01001443 self = alloc_func(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 if (self != NULL) {
1445 PyStructObject *s = (PyStructObject*)self;
Pablo Galindo290f5ae2020-12-28 23:59:16 +00001446 s->s_format = Py_NewRef(Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 s->s_codes = NULL;
1448 s->s_size = -1;
1449 s->s_len = -1;
1450 }
1451 return self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001452}
1453
Victor Stinner3f2d1012017-02-02 12:09:30 +01001454/*[clinic input]
1455Struct.__init__
1456
1457 format: object
1458
1459Create a compiled struct object.
1460
1461Return a new Struct object which writes and reads binary data according to
1462the format string.
1463
1464See help(struct) for more on format strings.
1465[clinic start generated code]*/
1466
Thomas Wouters477c8d52006-05-27 19:21:47 +00001467static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001468Struct___init___impl(PyStructObject *self, PyObject *format)
1469/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 int ret = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001472
Victor Stinner3f2d1012017-02-02 12:09:30 +01001473 if (PyUnicode_Check(format)) {
1474 format = PyUnicode_AsASCIIString(format);
1475 if (format == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 return -1;
1477 }
1478 /* XXX support buffer interface, too */
1479 else {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001480 Py_INCREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001482
Victor Stinner3f2d1012017-02-02 12:09:30 +01001483 if (!PyBytes_Check(format)) {
1484 Py_DECREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 PyErr_Format(PyExc_TypeError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001486 "Struct() argument 1 must be a str or bytes object, "
1487 "not %.200s",
Dino Viehland4f384af2019-09-10 11:18:37 +01001488 _PyType_Name(Py_TYPE(format)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 return -1;
1490 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001491
Xiang Zhang96f50282017-05-15 11:53:51 +08001492 Py_SETREF(self->s_format, format);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001493
Victor Stinner3f2d1012017-02-02 12:09:30 +01001494 ret = prepare_s(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 return ret;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001496}
1497
1498static void
1499s_dealloc(PyStructObject *s)
1500{
Dino Viehland4f384af2019-09-10 11:18:37 +01001501 PyTypeObject *tp = Py_TYPE(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 if (s->weakreflist != NULL)
1503 PyObject_ClearWeakRefs((PyObject *)s);
1504 if (s->s_codes != NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01001505 PyMem_Free(s->s_codes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 }
Dino Viehland4f384af2019-09-10 11:18:37 +01001507 Py_XDECREF(s->s_format);
1508 freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free);
1509 free_func(s);
1510 Py_DECREF(tp);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001511}
1512
1513static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001514s_unpack_internal(PyStructObject *soself, const char *startfrom,
1515 _structmodulestate *state) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 formatcode *code;
1517 Py_ssize_t i = 0;
1518 PyObject *result = PyTuple_New(soself->s_len);
1519 if (result == NULL)
1520 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 const formatdef *e = code->fmtdef;
1524 const char *res = startfrom + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001525 Py_ssize_t j = code->repeat;
1526 while (j--) {
1527 PyObject *v;
1528 if (e->format == 's') {
1529 v = PyBytes_FromStringAndSize(res, code->size);
1530 } else if (e->format == 'p') {
1531 Py_ssize_t n = *(unsigned char*)res;
1532 if (n >= code->size)
1533 n = code->size - 1;
1534 v = PyBytes_FromStringAndSize(res + 1, n);
1535 } else {
Christian Heimescfeb5432020-11-19 14:36:23 +01001536 v = e->unpack(state, res, e);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001537 }
1538 if (v == NULL)
1539 goto fail;
1540 PyTuple_SET_ITEM(result, i++, v);
1541 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001546fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 Py_DECREF(result);
1548 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001549}
1550
1551
Victor Stinner3f2d1012017-02-02 12:09:30 +01001552/*[clinic input]
1553Struct.unpack
1554
1555 buffer: Py_buffer
1556 /
1557
1558Return a tuple containing unpacked values.
1559
1560Unpack according to the format string Struct.format. The buffer's size
1561in bytes must be Struct.size.
1562
1563See help(struct) for more on format strings.
1564[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001565
1566static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001567Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1568/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001569{
Christian Heimescfeb5432020-11-19 14:36:23 +01001570 _structmodulestate *state = get_struct_state_structinst(self);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001571 assert(self->s_codes != NULL);
1572 if (buffer->len != self->s_size) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001573 PyErr_Format(state->StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001574 "unpack requires a buffer of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001575 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 return NULL;
1577 }
Christian Heimescfeb5432020-11-19 14:36:23 +01001578 return s_unpack_internal(self, buffer->buf, state);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001579}
1580
Victor Stinner3f2d1012017-02-02 12:09:30 +01001581/*[clinic input]
1582Struct.unpack_from
1583
1584 buffer: Py_buffer
1585 offset: Py_ssize_t = 0
1586
1587Return a tuple containing unpacked values.
1588
1589Values are unpacked according to the format string Struct.format.
1590
Xiang Zhangc10b2882018-03-11 02:58:52 +08001591The buffer's size in bytes, starting at position offset, must be
1592at least Struct.size.
Victor Stinner3f2d1012017-02-02 12:09:30 +01001593
1594See help(struct) for more on format strings.
1595[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001596
1597static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001598Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1599 Py_ssize_t offset)
Xiang Zhangc10b2882018-03-11 02:58:52 +08001600/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001601{
Christian Heimescfeb5432020-11-19 14:36:23 +01001602 _structmodulestate *state = get_struct_state_structinst(self);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001603 assert(self->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001604
Xiang Zhangc10b2882018-03-11 02:58:52 +08001605 if (offset < 0) {
1606 if (offset + self->s_size > 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001607 PyErr_Format(state->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001608 "not enough data to unpack %zd bytes at offset %zd",
1609 self->s_size,
1610 offset);
1611 return NULL;
1612 }
1613
1614 if (offset + buffer->len < 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001615 PyErr_Format(state->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001616 "offset %zd out of range for %zd-byte buffer",
1617 offset,
1618 buffer->len);
1619 return NULL;
1620 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001621 offset += buffer->len;
Xiang Zhangc10b2882018-03-11 02:58:52 +08001622 }
1623
1624 if ((buffer->len - offset) < self->s_size) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001625 PyErr_Format(state->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001626 "unpack_from requires a buffer of at least %zu bytes for "
1627 "unpacking %zd bytes at offset %zd "
1628 "(actual buffer size is %zd)",
1629 (size_t)self->s_size + (size_t)offset,
1630 self->s_size,
1631 offset,
1632 buffer->len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 return NULL;
1634 }
Christian Heimescfeb5432020-11-19 14:36:23 +01001635 return s_unpack_internal(self, (char*)buffer->buf + offset, state);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001636}
1637
1638
Victor Stinner3f2d1012017-02-02 12:09:30 +01001639
Antoine Pitrou9f146812013-04-27 00:20:04 +02001640/* Unpack iterator type */
1641
1642typedef struct {
1643 PyObject_HEAD
1644 PyStructObject *so;
1645 Py_buffer buf;
1646 Py_ssize_t index;
1647} unpackiterobject;
1648
1649static void
1650unpackiter_dealloc(unpackiterobject *self)
1651{
INADA Naokia6296d32017-08-24 14:55:17 +09001652 /* bpo-31095: UnTrack is needed before calling any callbacks */
Dino Viehland4f384af2019-09-10 11:18:37 +01001653 PyTypeObject *tp = Py_TYPE(self);
INADA Naokia6296d32017-08-24 14:55:17 +09001654 PyObject_GC_UnTrack(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001655 Py_XDECREF(self->so);
1656 PyBuffer_Release(&self->buf);
1657 PyObject_GC_Del(self);
Dino Viehland4f384af2019-09-10 11:18:37 +01001658 Py_DECREF(tp);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001659}
1660
1661static int
1662unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1663{
Pablo Galindo1cf15af2020-05-27 10:03:38 +01001664 Py_VISIT(Py_TYPE(self));
Antoine Pitrou9f146812013-04-27 00:20:04 +02001665 Py_VISIT(self->so);
1666 Py_VISIT(self->buf.obj);
1667 return 0;
1668}
1669
1670static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301671unpackiter_len(unpackiterobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou9f146812013-04-27 00:20:04 +02001672{
1673 Py_ssize_t len;
1674 if (self->so == NULL)
1675 len = 0;
1676 else
1677 len = (self->buf.len - self->index) / self->so->s_size;
1678 return PyLong_FromSsize_t(len);
1679}
1680
1681static PyMethodDef unpackiter_methods[] = {
1682 {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1683 {NULL, NULL} /* sentinel */
1684};
1685
1686static PyObject *
1687unpackiter_iternext(unpackiterobject *self)
1688{
Christian Heimescfeb5432020-11-19 14:36:23 +01001689 _structmodulestate *state = get_struct_state_iterinst(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001690 PyObject *result;
1691 if (self->so == NULL)
1692 return NULL;
1693 if (self->index >= self->buf.len) {
1694 /* Iterator exhausted */
1695 Py_CLEAR(self->so);
1696 PyBuffer_Release(&self->buf);
1697 return NULL;
1698 }
1699 assert(self->index + self->so->s_size <= self->buf.len);
1700 result = s_unpack_internal(self->so,
Christian Heimescfeb5432020-11-19 14:36:23 +01001701 (char*) self->buf.buf + self->index,
1702 state);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001703 self->index += self->so->s_size;
1704 return result;
1705}
1706
Dino Viehland4f384af2019-09-10 11:18:37 +01001707PyObject *unpackiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1708 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s objects", _PyType_Name(type));
1709 return NULL;
1710}
1711
1712static PyType_Slot unpackiter_type_slots[] = {
1713 {Py_tp_dealloc, unpackiter_dealloc},
1714 {Py_tp_getattro, PyObject_GenericGetAttr},
1715 {Py_tp_traverse, unpackiter_traverse},
1716 {Py_tp_iter, PyObject_SelfIter},
1717 {Py_tp_iternext, unpackiter_iternext},
1718 {Py_tp_methods, unpackiter_methods},
1719 {Py_tp_new, unpackiter_new},
1720 {0, 0},
1721};
1722
1723static PyType_Spec unpackiter_type_spec = {
1724 "_struct.unpack_iterator",
1725 sizeof(unpackiterobject),
1726 0,
1727 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1728 unpackiter_type_slots
Antoine Pitrou9f146812013-04-27 00:20:04 +02001729};
1730
Victor Stinner3f2d1012017-02-02 12:09:30 +01001731/*[clinic input]
1732Struct.iter_unpack
1733
1734 buffer: object
1735 /
1736
1737Return an iterator yielding tuples.
1738
1739Tuples are unpacked from the given bytes source, like a repeated
1740invocation of unpack_from().
1741
1742Requires that the bytes length be a multiple of the struct size.
1743[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001744
1745static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001746Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1747/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001748{
Christian Heimescfeb5432020-11-19 14:36:23 +01001749 _structmodulestate *state = get_struct_state_structinst(self);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001750 unpackiterobject *iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001751
Victor Stinner3f2d1012017-02-02 12:09:30 +01001752 assert(self->s_codes != NULL);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001753
Victor Stinner3f2d1012017-02-02 12:09:30 +01001754 if (self->s_size == 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001755 PyErr_Format(state->StructError,
Antoine Pitrou9f146812013-04-27 00:20:04 +02001756 "cannot iteratively unpack with a struct of length 0");
1757 return NULL;
1758 }
1759
Christian Heimescfeb5432020-11-19 14:36:23 +01001760 iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)state->unpackiter_type, 0);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001761 if (iter == NULL)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001762 return NULL;
1763
Victor Stinner3f2d1012017-02-02 12:09:30 +01001764 if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1765 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001766 return NULL;
1767 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001768 if (iter->buf.len % self->s_size != 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001769 PyErr_Format(state->StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001770 "iterative unpacking requires a buffer of "
1771 "a multiple of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001772 self->s_size);
1773 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001774 return NULL;
1775 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001776 Py_INCREF(self);
1777 iter->so = self;
1778 iter->index = 0;
1779 return (PyObject *)iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001780}
1781
1782
Thomas Wouters477c8d52006-05-27 19:21:47 +00001783/*
1784 * Guts of the pack function.
1785 *
1786 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1787 * argument for where to start processing the arguments for packing, and a
1788 * character buffer for writing the packed string. The caller must insure
1789 * that the buffer may contain the required length for packing the arguments.
1790 * 0 is returned on success, 1 is returned if there is an error.
1791 *
1792 */
1793static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001794s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset,
1795 char* buf, _structmodulestate *state)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001796{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 formatcode *code;
1798 /* XXX(nnorwitz): why does i need to be a local? can we use
1799 the offset parameter or do we need the wider width? */
1800 Py_ssize_t i;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 memset(buf, '\0', soself->s_size);
1803 i = offset;
1804 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 const formatdef *e = code->fmtdef;
1806 char *res = buf + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001807 Py_ssize_t j = code->repeat;
1808 while (j--) {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001809 PyObject *v = args[i++];
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001810 if (e->format == 's') {
1811 Py_ssize_t n;
1812 int isstring;
Serhiy Storchaka8f87eef2020-04-12 14:58:27 +03001813 const void *p;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001814 isstring = PyBytes_Check(v);
1815 if (!isstring && !PyByteArray_Check(v)) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001816 PyErr_SetString(state->StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001817 "argument for 's' must be a bytes object");
1818 return -1;
1819 }
1820 if (isstring) {
1821 n = PyBytes_GET_SIZE(v);
1822 p = PyBytes_AS_STRING(v);
1823 }
1824 else {
1825 n = PyByteArray_GET_SIZE(v);
1826 p = PyByteArray_AS_STRING(v);
1827 }
1828 if (n > code->size)
1829 n = code->size;
1830 if (n > 0)
1831 memcpy(res, p, n);
1832 } else if (e->format == 'p') {
1833 Py_ssize_t n;
1834 int isstring;
Serhiy Storchaka8f87eef2020-04-12 14:58:27 +03001835 const void *p;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001836 isstring = PyBytes_Check(v);
1837 if (!isstring && !PyByteArray_Check(v)) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001838 PyErr_SetString(state->StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001839 "argument for 'p' must be a bytes object");
1840 return -1;
1841 }
1842 if (isstring) {
1843 n = PyBytes_GET_SIZE(v);
1844 p = PyBytes_AS_STRING(v);
1845 }
1846 else {
1847 n = PyByteArray_GET_SIZE(v);
1848 p = PyByteArray_AS_STRING(v);
1849 }
1850 if (n > (code->size - 1))
1851 n = code->size - 1;
1852 if (n > 0)
1853 memcpy(res + 1, p, n);
1854 if (n > 255)
1855 n = 255;
1856 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1857 } else {
Christian Heimescfeb5432020-11-19 14:36:23 +01001858 if (e->pack(state, res, v, e) < 0) {
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001859 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +01001860 PyErr_SetString(state->StructError,
Serhiy Storchaka46e1ce22013-08-27 20:17:03 +03001861 "int too large to convert");
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001862 return -1;
1863 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 }
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001865 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 }
1867 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 /* Success */
1870 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001871}
1872
1873
1874PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001875"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001876\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001877Return a bytes object containing values v1, v2, ... packed according\n\
1878to the format string S.format. See help(struct) for more on format\n\
1879strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001880
1881static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001882s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001883{
Dino Viehland4f384af2019-09-10 11:18:37 +01001884 char *buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 PyStructObject *soself;
Christian Heimescfeb5432020-11-19 14:36:23 +01001886 _structmodulestate *state = get_struct_state_structinst(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 /* Validate arguments. */
1889 soself = (PyStructObject *)self;
Christian Heimescfeb5432020-11-19 14:36:23 +01001890 assert(PyStruct_Check(self, state));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001892 if (nargs != soself->s_len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 {
Christian Heimescfeb5432020-11-19 14:36:23 +01001894 PyErr_Format(state->StructError,
Victor Stinner3f2d1012017-02-02 12:09:30 +01001895 "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1896 return NULL;
1897 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001898
Dino Viehland4f384af2019-09-10 11:18:37 +01001899 /* Allocate a new string */
1900 _PyBytesWriter writer;
1901 _PyBytesWriter_Init(&writer);
1902 buf = _PyBytesWriter_Alloc(&writer, soself->s_size);
1903 if (buf == NULL) {
1904 _PyBytesWriter_Dealloc(&writer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 return NULL;
1906 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001907
Dino Viehland4f384af2019-09-10 11:18:37 +01001908 /* Call the guts */
Christian Heimescfeb5432020-11-19 14:36:23 +01001909 if ( s_pack_internal(soself, args, 0, buf, state) != 0 ) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001910 _PyBytesWriter_Dealloc(&writer);
1911 return NULL;
1912 }
1913
1914 return _PyBytesWriter_Finish(&writer, buf + soself->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001915}
1916
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001917PyDoc_STRVAR(s_pack_into__doc__,
1918"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001919\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001920Pack the values v1, v2, ... according to the format string S.format\n\
1921and write the packed bytes into the writable buffer buf starting at\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00001922offset. Note that the offset is a required argument. See\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001923help(struct) for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001924
1925static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001926s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001927{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 PyStructObject *soself;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001929 Py_buffer buffer;
1930 Py_ssize_t offset;
Christian Heimescfeb5432020-11-19 14:36:23 +01001931 _structmodulestate *state = get_struct_state_structinst(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 /* Validate arguments. +1 is for the first arg as buffer. */
1934 soself = (PyStructObject *)self;
Christian Heimescfeb5432020-11-19 14:36:23 +01001935 assert(PyStruct_Check(self, state));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001937 if (nargs != (soself->s_len + 2))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001939 if (nargs == 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001940 PyErr_Format(state->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001941 "pack_into expected buffer argument");
1942 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001943 else if (nargs == 1) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001944 PyErr_Format(state->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001945 "pack_into expected offset argument");
1946 }
1947 else {
Christian Heimescfeb5432020-11-19 14:36:23 +01001948 PyErr_Format(state->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001949 "pack_into expected %zd items for packing (got %zd)",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001950 soself->s_len, (nargs - 2));
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001951 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 return NULL;
1953 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 /* Extract a writable memory buffer from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001956 if (!PyArg_Parse(args[0], "w*", &buffer))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001958 assert(buffer.len >= 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960 /* Extract the offset from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001961 offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001962 if (offset == -1 && PyErr_Occurred()) {
1963 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001965 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 /* Support negative offsets. */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001968 if (offset < 0) {
1969 /* Check that negative offset is low enough to fit data */
1970 if (offset + soself->s_size > 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001971 PyErr_Format(state->StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001972 "no space to pack %zd bytes at offset %zd",
1973 soself->s_size,
1974 offset);
1975 PyBuffer_Release(&buffer);
1976 return NULL;
1977 }
1978
1979 /* Check that negative offset is not crossing buffer boundary */
1980 if (offset + buffer.len < 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001981 PyErr_Format(state->StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001982 "offset %zd out of range for %zd-byte buffer",
1983 offset,
1984 buffer.len);
1985 PyBuffer_Release(&buffer);
1986 return NULL;
1987 }
1988
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001989 offset += buffer.len;
Andrew Nesterf78b1192017-04-04 13:46:25 +03001990 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 /* Check boundaries */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001993 if ((buffer.len - offset) < soself->s_size) {
Johan Liuaead53b2017-06-02 14:33:04 +08001994 assert(offset >= 0);
1995 assert(soself->s_size >= 0);
1996
Christian Heimescfeb5432020-11-19 14:36:23 +01001997 PyErr_Format(state->StructError,
Johan Liuaead53b2017-06-02 14:33:04 +08001998 "pack_into requires a buffer of at least %zu bytes for "
Andrew Nesterf78b1192017-04-04 13:46:25 +03001999 "packing %zd bytes at offset %zd "
2000 "(actual buffer size is %zd)",
Johan Liuaead53b2017-06-02 14:33:04 +08002001 (size_t)soself->s_size + (size_t)offset,
Andrew Nesterf78b1192017-04-04 13:46:25 +03002002 soself->s_size,
2003 offset,
2004 buffer.len);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002005 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 return NULL;
2007 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 /* Call the guts */
Christian Heimescfeb5432020-11-19 14:36:23 +01002010 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset, state) != 0) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002011 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002012 return NULL;
2013 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002014
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002015 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002017}
2018
2019static PyObject *
2020s_get_format(PyStructObject *self, void *unused)
2021{
Victor Stinnerf87b85f2017-06-23 15:11:12 +02002022 return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
2023 PyBytes_GET_SIZE(self->s_format));
Thomas Wouters477c8d52006-05-27 19:21:47 +00002024}
2025
2026static PyObject *
2027s_get_size(PyStructObject *self, void *unused)
2028{
Christian Heimes217cfd12007-12-02 14:31:20 +00002029 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002030}
2031
Meador Ingeb14d8c92012-07-23 10:01:29 -05002032PyDoc_STRVAR(s_sizeof__doc__,
2033"S.__sizeof__() -> size of S in memory, in bytes");
2034
2035static PyObject *
Meador Inge90bc2dbc2012-07-28 22:16:39 -05002036s_sizeof(PyStructObject *self, void *unused)
Meador Ingeb14d8c92012-07-23 10:01:29 -05002037{
2038 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002039 formatcode *code;
Meador Ingeb14d8c92012-07-23 10:01:29 -05002040
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002041 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002042 for (code = self->s_codes; code->fmtdef != NULL; code++)
2043 size += sizeof(formatcode);
Meador Ingeb14d8c92012-07-23 10:01:29 -05002044 return PyLong_FromSsize_t(size);
2045}
2046
Thomas Wouters477c8d52006-05-27 19:21:47 +00002047/* List of functions */
2048
2049static struct PyMethodDef s_methods[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002050 STRUCT_ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002051 {"pack", (PyCFunction)(void(*)(void))s_pack, METH_FASTCALL, s_pack__doc__},
2052 {"pack_into", (PyCFunction)(void(*)(void))s_pack_into, METH_FASTCALL, s_pack_into__doc__},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002053 STRUCT_UNPACK_METHODDEF
2054 STRUCT_UNPACK_FROM_METHODDEF
Meador Ingeb14d8c92012-07-23 10:01:29 -05002055 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002057};
2058
Dino Viehland4f384af2019-09-10 11:18:37 +01002059static PyMemberDef s_members[] = {
Eddie Elizondo3368f3c2019-09-19 09:29:05 -07002060 {"__weaklistoffset__", T_PYSSIZET, offsetof(PyStructObject, weakreflist), READONLY},
Dino Viehland4f384af2019-09-10 11:18:37 +01002061 {NULL} /* sentinel */
2062};
2063
Thomas Wouters477c8d52006-05-27 19:21:47 +00002064#define OFF(x) offsetof(PyStructObject, x)
2065
2066static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
2068 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
2069 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002070};
2071
Dino Viehland4f384af2019-09-10 11:18:37 +01002072PyDoc_STRVAR(s__doc__,
2073"Struct(fmt) --> compiled struct object\n"
2074"\n"
2075);
2076
2077static PyType_Slot PyStructType_slots[] = {
2078 {Py_tp_dealloc, s_dealloc},
2079 {Py_tp_getattro, PyObject_GenericGetAttr},
2080 {Py_tp_setattro, PyObject_GenericSetAttr},
2081 {Py_tp_doc, (void*)s__doc__},
2082 {Py_tp_methods, s_methods},
2083 {Py_tp_members, s_members},
2084 {Py_tp_getset, s_getsetlist},
2085 {Py_tp_init, Struct___init__},
2086 {Py_tp_alloc, PyType_GenericAlloc},
2087 {Py_tp_new, s_new},
2088 {Py_tp_free, PyObject_Del},
2089 {0, 0},
2090};
2091
2092static PyType_Spec PyStructType_spec = {
2093 "_struct.Struct",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 sizeof(PyStructObject),
2095 0,
Dino Viehland4f384af2019-09-10 11:18:37 +01002096 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
2097 PyStructType_slots
Thomas Wouters477c8d52006-05-27 19:21:47 +00002098};
2099
Christian Heimesa34706f2008-01-04 03:06:10 +00002100
2101/* ---- Standalone functions ---- */
2102
2103#define MAXCACHE 100
Christian Heimesa34706f2008-01-04 03:06:10 +00002104
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002105static int
Christian Heimescfeb5432020-11-19 14:36:23 +01002106cache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr)
Christian Heimesa34706f2008-01-04 03:06:10 +00002107{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 PyObject * s_object;
Christian Heimescfeb5432020-11-19 14:36:23 +01002109 _structmodulestate *state = get_struct_state(module);
Christian Heimesa34706f2008-01-04 03:06:10 +00002110
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002111 if (fmt == NULL) {
2112 Py_DECREF(*ptr);
Serhiy Storchaka40db90c2017-04-20 21:19:31 +03002113 *ptr = NULL;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002114 return 1;
2115 }
2116
Christian Heimescfeb5432020-11-19 14:36:23 +01002117 if (state->cache == NULL) {
2118 state->cache = PyDict_New();
2119 if (state->cache == NULL)
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002120 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002122
Christian Heimescfeb5432020-11-19 14:36:23 +01002123 s_object = PyDict_GetItemWithError(state->cache, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 if (s_object != NULL) {
2125 Py_INCREF(s_object);
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002126 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002127 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002129 else if (PyErr_Occurred()) {
2130 return 0;
2131 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002132
Christian Heimescfeb5432020-11-19 14:36:23 +01002133 s_object = PyObject_CallOneArg(state->PyStructType, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002134 if (s_object != NULL) {
Christian Heimescfeb5432020-11-19 14:36:23 +01002135 if (PyDict_GET_SIZE(state->cache) >= MAXCACHE)
2136 PyDict_Clear(state->cache);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 /* Attempt to cache the result */
Christian Heimescfeb5432020-11-19 14:36:23 +01002138 if (PyDict_SetItem(state->cache, fmt, s_object) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 PyErr_Clear();
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002140 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002141 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002142 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002143 return 0;
Christian Heimesa34706f2008-01-04 03:06:10 +00002144}
2145
Victor Stinner3f2d1012017-02-02 12:09:30 +01002146/*[clinic input]
2147_clearcache
2148
2149Clear the internal cache.
2150[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002151
2152static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002153_clearcache_impl(PyObject *module)
2154/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002155{
Christian Heimescfeb5432020-11-19 14:36:23 +01002156 Py_CLEAR(get_struct_state(module)->cache);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00002158}
2159
Victor Stinner3f2d1012017-02-02 12:09:30 +01002160
2161/*[clinic input]
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002162calcsize -> Py_ssize_t
Victor Stinner3f2d1012017-02-02 12:09:30 +01002163
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002164 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002165 /
2166
2167Return size in bytes of the struct described by the format string.
2168[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002169
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002170static Py_ssize_t
2171calcsize_impl(PyObject *module, PyStructObject *s_object)
2172/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002173{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002174 return s_object->s_size;
Christian Heimesa34706f2008-01-04 03:06:10 +00002175}
2176
2177PyDoc_STRVAR(pack_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002178"pack(format, v1, v2, ...) -> bytes\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002179\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002180Return a bytes object containing the values v1, v2, ... packed according\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002181to the format string. See help(struct) for more on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002182
2183static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01002184pack(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002185{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002186 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002187 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002188
Victor Stinner3f2d1012017-02-02 12:09:30 +01002189 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190 PyErr_SetString(PyExc_TypeError, "missing format argument");
2191 return NULL;
2192 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002193 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002194
Christian Heimescfeb5432020-11-19 14:36:23 +01002195 if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 return NULL;
2197 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002198 result = s_pack(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 Py_DECREF(s_object);
2200 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002201}
2202
2203PyDoc_STRVAR(pack_into_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002204"pack_into(format, buffer, offset, v1, v2, ...)\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002205\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002206Pack the values v1, v2, ... according to the format string and write\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002207the packed bytes into the writable buffer buf starting at offset. Note\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002208that the offset is a required argument. See help(struct) for more\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002209on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002210
2211static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01002212pack_into(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002213{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002214 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002215 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002216
Victor Stinner3f2d1012017-02-02 12:09:30 +01002217 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002218 PyErr_SetString(PyExc_TypeError, "missing format argument");
2219 return NULL;
2220 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002221 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002222
Christian Heimescfeb5432020-11-19 14:36:23 +01002223 if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002224 return NULL;
2225 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002226 result = s_pack_into(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002227 Py_DECREF(s_object);
2228 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002229}
2230
Victor Stinner3f2d1012017-02-02 12:09:30 +01002231/*[clinic input]
2232unpack
2233
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002234 format as s_object: cache_struct
Victor Stinnerc0f59ad2017-02-02 14:24:16 +01002235 buffer: Py_buffer
Victor Stinner3f2d1012017-02-02 12:09:30 +01002236 /
2237
2238Return a tuple containing values unpacked according to the format string.
2239
2240The buffer's size in bytes must be calcsize(format).
2241
2242See help(struct) for more on format strings.
2243[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002244
2245static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002246unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2247/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002248{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002249 return Struct_unpack_impl(s_object, buffer);
Christian Heimesa34706f2008-01-04 03:06:10 +00002250}
2251
Victor Stinner3f2d1012017-02-02 12:09:30 +01002252/*[clinic input]
2253unpack_from
2254
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002255 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002256 /
2257 buffer: Py_buffer
2258 offset: Py_ssize_t = 0
2259
2260Return a tuple containing values unpacked according to the format string.
2261
2262The buffer's size, minus offset, must be at least calcsize(format).
2263
2264See help(struct) for more on format strings.
2265[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002266
2267static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002268unpack_from_impl(PyObject *module, PyStructObject *s_object,
2269 Py_buffer *buffer, Py_ssize_t offset)
2270/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002271{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002272 return Struct_unpack_from_impl(s_object, buffer, offset);
Christian Heimesa34706f2008-01-04 03:06:10 +00002273}
2274
Victor Stinner3f2d1012017-02-02 12:09:30 +01002275/*[clinic input]
2276iter_unpack
2277
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002278 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002279 buffer: object
2280 /
2281
2282Return an iterator yielding tuples unpacked from the given bytes.
2283
2284The bytes are unpacked according to the format string, like
2285a repeated invocation of unpack_from().
2286
2287Requires that the bytes length be a multiple of the format struct size.
2288[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002289
2290static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002291iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2292 PyObject *buffer)
2293/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002294{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002295 return Struct_iter_unpack(s_object, buffer);
Antoine Pitrou9f146812013-04-27 00:20:04 +02002296}
2297
Christian Heimesa34706f2008-01-04 03:06:10 +00002298static struct PyMethodDef module_functions[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002299 _CLEARCACHE_METHODDEF
2300 CALCSIZE_METHODDEF
2301 ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002302 {"pack", (PyCFunction)(void(*)(void))pack, METH_FASTCALL, pack_doc},
2303 {"pack_into", (PyCFunction)(void(*)(void))pack_into, METH_FASTCALL, pack_into_doc},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002304 UNPACK_METHODDEF
2305 UNPACK_FROM_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002306 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00002307};
2308
2309
Thomas Wouters477c8d52006-05-27 19:21:47 +00002310/* Module initialization */
2311
Christian Heimesa34706f2008-01-04 03:06:10 +00002312PyDoc_STRVAR(module_doc,
2313"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002314Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002315and also as format strings (explained below) to describe the layout of data\n\
2316in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002317\n\
2318The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002319 @: native order, size & alignment (default)\n\
2320 =: native order, std. size & alignment\n\
2321 <: little-endian, std. size & alignment\n\
2322 >: big-endian, std. size & alignment\n\
2323 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002324\n\
2325The remaining chars indicate types of args and must match exactly;\n\
2326these can be preceded by a decimal repeat count:\n\
2327 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002328 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002329 h:short; H:unsigned short; i:int; I:unsigned int;\n\
Mark Dickinson7c4e4092016-09-03 17:21:29 +01002330 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002331Special cases (preceding decimal count indicates length):\n\
2332 s:string (array of char); p: pascal string (with count byte).\n\
Antoine Pitrou45d9c912011-10-06 15:27:40 +02002333Special cases (only available in native format):\n\
2334 n:ssize_t; N:size_t;\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002335 P:an integer type that is wide enough to hold a pointer.\n\
2336Special case (not in native mode unless 'long long' in platform C):\n\
2337 q:long long; Q:unsigned long long\n\
2338Whitespace between formats is ignored.\n\
2339\n\
2340The variable struct.error is an exception raised on errors.\n");
2341
Martin v. Löwis1a214512008-06-11 05:26:20 +00002342
Dino Viehland4f384af2019-09-10 11:18:37 +01002343static int
2344_structmodule_traverse(PyObject *module, visitproc visit, void *arg)
2345{
Christian Heimescfeb5432020-11-19 14:36:23 +01002346 _structmodulestate *state = get_struct_state(module);
Hai Shif707d942020-03-16 21:15:01 +08002347 if (state) {
Christian Heimescfeb5432020-11-19 14:36:23 +01002348 Py_VISIT(state->cache);
Hai Shif707d942020-03-16 21:15:01 +08002349 Py_VISIT(state->PyStructType);
2350 Py_VISIT(state->unpackiter_type);
2351 Py_VISIT(state->StructError);
2352 }
Dino Viehland4f384af2019-09-10 11:18:37 +01002353 return 0;
2354}
2355
2356static int
2357_structmodule_clear(PyObject *module)
2358{
Christian Heimescfeb5432020-11-19 14:36:23 +01002359 _structmodulestate *state = get_struct_state(module);
Hai Shif707d942020-03-16 21:15:01 +08002360 if (state) {
Christian Heimescfeb5432020-11-19 14:36:23 +01002361 Py_CLEAR(state->cache);
Hai Shif707d942020-03-16 21:15:01 +08002362 Py_CLEAR(state->PyStructType);
2363 Py_CLEAR(state->unpackiter_type);
2364 Py_CLEAR(state->StructError);
2365 }
Dino Viehland4f384af2019-09-10 11:18:37 +01002366 return 0;
2367}
2368
2369static void
2370_structmodule_free(void *module)
2371{
2372 _structmodule_clear((PyObject *)module);
2373}
2374
Christian Heimescfeb5432020-11-19 14:36:23 +01002375static int
2376_structmodule_exec(PyObject *m)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002377{
Christian Heimescfeb5432020-11-19 14:36:23 +01002378 _structmodulestate *state = get_struct_state(m);
Christian Heimesa34706f2008-01-04 03:06:10 +00002379
Christian Heimescfeb5432020-11-19 14:36:23 +01002380 state->PyStructType = PyType_FromModuleAndSpec(
2381 m, &PyStructType_spec, NULL);
2382 if (state->PyStructType == NULL) {
2383 return -1;
Dino Viehland4f384af2019-09-10 11:18:37 +01002384 }
Christian Heimescfeb5432020-11-19 14:36:23 +01002385 if (PyModule_AddType(m, (PyTypeObject *)state->PyStructType) < 0) {
2386 return -1;
Dino Viehland4f384af2019-09-10 11:18:37 +01002387 }
Christian Heimescfeb5432020-11-19 14:36:23 +01002388
2389 state->unpackiter_type = PyType_FromModuleAndSpec(
2390 m, &unpackiter_type_spec, NULL);
2391 if (state->unpackiter_type == NULL) {
2392 return -1;
2393 }
Zachary Ware99f11b42016-10-04 01:20:21 -05002394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 /* Check endian and swap in faster functions */
2396 {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002397 const formatdef *native = native_table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 formatdef *other, *ptr;
Christian Heimes743e0cd2012-10-17 23:52:17 +02002399#if PY_LITTLE_ENDIAN
2400 other = lilendian_table;
2401#else
2402 other = bigendian_table;
2403#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 /* Scan through the native table, find a matching
2405 entry in the endian table and swap in the
2406 native implementations whenever possible
2407 (64-bit platforms may not have "standard" sizes) */
2408 while (native->format != '\0' && other->format != '\0') {
2409 ptr = other;
2410 while (ptr->format != '\0') {
2411 if (ptr->format == native->format) {
2412 /* Match faster when formats are
2413 listed in the same order */
2414 if (ptr == other)
2415 other++;
2416 /* Only use the trick if the
2417 size matches */
2418 if (ptr->size != native->size)
2419 break;
2420 /* Skip float and double, could be
2421 "unknown" float format */
2422 if (ptr->format == 'd' || ptr->format == 'f')
2423 break;
Stefan Krah472fc842020-03-24 14:01:13 +01002424 /* Skip _Bool, semantics are different for standard size */
2425 if (ptr->format == '?')
2426 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 ptr->pack = native->pack;
2428 ptr->unpack = native->unpack;
2429 break;
2430 }
2431 ptr++;
2432 }
2433 native++;
2434 }
2435 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 /* Add some symbolic constants to the module */
Christian Heimescfeb5432020-11-19 14:36:23 +01002438 state->StructError = PyErr_NewException("struct.error", NULL, NULL);
2439 if (state->StructError == NULL) {
2440 return -1;
2441 }
2442 if (PyModule_AddObjectRef(m, "error", state->StructError) < 0) {
2443 return -1;
2444 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002445
Christian Heimescfeb5432020-11-19 14:36:23 +01002446 return 0;
2447}
2448
2449static PyModuleDef_Slot _structmodule_slots[] = {
2450 {Py_mod_exec, _structmodule_exec},
2451 {0, NULL}
2452};
2453
2454static struct PyModuleDef _structmodule = {
2455 PyModuleDef_HEAD_INIT,
2456 .m_name = "_struct",
2457 .m_doc = module_doc,
2458 .m_size = sizeof(_structmodulestate),
2459 .m_methods = module_functions,
2460 .m_slots = _structmodule_slots,
2461 .m_traverse = _structmodule_traverse,
2462 .m_clear = _structmodule_clear,
2463 .m_free = _structmodule_free,
2464};
2465
2466PyMODINIT_FUNC
2467PyInit__struct(void)
2468{
2469 return PyModuleDef_Init(&_structmodule);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002470}