blob: 1a5e0ae28e876b746aacc7bc0b42ff2009ef9d3c [file] [log] [blame]
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001/* struct module -- pack values into and (out of) bytes objects */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002
3/* New version supporting byte order, alignment and size options,
4 character strings, and unsigned numbers */
5
6#define PY_SSIZE_T_CLEAN
7
8#include "Python.h"
Victor Stinner4a21e572020-04-15 02:35:41 +02009#include "structmember.h" // PyMemberDef
Thomas Wouters477c8d52006-05-27 19:21:47 +000010#include <ctype.h>
11
Victor Stinner3f2d1012017-02-02 12:09:30 +010012/*[clinic input]
13class Struct "PyStructObject *" "&PyStructType"
14[clinic start generated code]*/
15/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/
16
Dino Viehland4f384af2019-09-10 11:18:37 +010017typedef struct {
Christian Heimescfeb5432020-11-19 14:36:23 +010018 PyObject *cache;
Dino Viehland4f384af2019-09-10 11:18:37 +010019 PyObject *PyStructType;
20 PyObject *unpackiter_type;
21 PyObject *StructError;
22} _structmodulestate;
23
Hai Shif707d942020-03-16 21:15:01 +080024static inline _structmodulestate*
25get_struct_state(PyObject *module)
26{
27 void *state = PyModule_GetState(module);
28 assert(state != NULL);
29 return (_structmodulestate *)state;
30}
Dino Viehland4f384af2019-09-10 11:18:37 +010031
32static struct PyModuleDef _structmodule;
33
Christian Heimescfeb5432020-11-19 14:36:23 +010034#define get_struct_state_structinst(self) \
35 (get_struct_state(_PyType_GetModuleByDef(Py_TYPE(self), &_structmodule)))
36#define get_struct_state_iterinst(self) \
37 (get_struct_state(PyType_GetModule(Py_TYPE(self))))
Thomas Wouters477c8d52006-05-27 19:21:47 +000038
Thomas Wouters477c8d52006-05-27 19:21:47 +000039/* The translation function for each format character is table driven */
40typedef struct _formatdef {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000041 char format;
42 Py_ssize_t size;
43 Py_ssize_t alignment;
Christian Heimescfeb5432020-11-19 14:36:23 +010044 PyObject* (*unpack)(_structmodulestate *, const char *,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000045 const struct _formatdef *);
Christian Heimescfeb5432020-11-19 14:36:23 +010046 int (*pack)(_structmodulestate *, char *, PyObject *,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000047 const struct _formatdef *);
Thomas Wouters477c8d52006-05-27 19:21:47 +000048} formatdef;
49
50typedef struct _formatcode {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051 const struct _formatdef *fmtdef;
52 Py_ssize_t offset;
53 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +030054 Py_ssize_t repeat;
Thomas Wouters477c8d52006-05-27 19:21:47 +000055} formatcode;
56
57/* Struct object interface */
58
59typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000060 PyObject_HEAD
61 Py_ssize_t s_size;
62 Py_ssize_t s_len;
63 formatcode *s_codes;
64 PyObject *s_format;
65 PyObject *weakreflist; /* List of weak references */
Thomas Wouters477c8d52006-05-27 19:21:47 +000066} PyStructObject;
67
Christian Heimescfeb5432020-11-19 14:36:23 +010068#define PyStruct_Check(op, state) PyObject_TypeCheck(op, (PyTypeObject *)(state)->PyStructType)
Thomas Wouters477c8d52006-05-27 19:21:47 +000069
70/* Define various structs to figure out the alignments of types */
71
72
73typedef struct { char c; short x; } st_short;
74typedef struct { char c; int x; } st_int;
75typedef struct { char c; long x; } st_long;
76typedef struct { char c; float x; } st_float;
77typedef struct { char c; double x; } st_double;
78typedef struct { char c; void *x; } st_void_p;
Antoine Pitrou45d9c912011-10-06 15:27:40 +020079typedef struct { char c; size_t x; } st_size_t;
Benjamin Petersona9296e72016-09-07 11:06:17 -070080typedef struct { char c; _Bool x; } st_bool;
Thomas Wouters477c8d52006-05-27 19:21:47 +000081
82#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
83#define INT_ALIGN (sizeof(st_int) - sizeof(int))
84#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
85#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
86#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
87#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
Antoine Pitrou45d9c912011-10-06 15:27:40 +020088#define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t))
Benjamin Petersona9296e72016-09-07 11:06:17 -070089#define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool))
Thomas Wouters477c8d52006-05-27 19:21:47 +000090
91/* We can't support q and Q in native mode unless the compiler does;
92 in std mode, they're 8 bytes on all platforms. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -070093typedef struct { char c; long long x; } s_long_long;
94#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long))
Thomas Wouters477c8d52006-05-27 19:21:47 +000095
Thomas Wouters477c8d52006-05-27 19:21:47 +000096#ifdef __powerc
97#pragma options align=reset
98#endif
99
Serhiy Storchakaa5a55902017-02-04 11:14:52 +0200100/*[python input]
101class cache_struct_converter(CConverter):
102 type = 'PyStructObject *'
103 converter = 'cache_struct_converter'
104 c_default = "NULL"
105
Christian Heimescfeb5432020-11-19 14:36:23 +0100106 def parse_arg(self, argname, displayname):
107 return """
108 if (!{converter}(module, {argname}, &{paramname})) {{{{
109 goto exit;
110 }}}}
111 """.format(argname=argname, paramname=self.name,
112 converter=self.converter)
113
Serhiy Storchakaa5a55902017-02-04 11:14:52 +0200114 def cleanup(self):
115 return "Py_XDECREF(%s);\n" % self.name
116[python start generated code]*/
Christian Heimescfeb5432020-11-19 14:36:23 +0100117/*[python end generated code: output=da39a3ee5e6b4b0d input=d6746621c2fb1a7d]*/
Serhiy Storchakaa5a55902017-02-04 11:14:52 +0200118
Christian Heimescfeb5432020-11-19 14:36:23 +0100119static int cache_struct_converter(PyObject *, PyObject *, PyStructObject **);
Serhiy Storchakaa5a55902017-02-04 11:14:52 +0200120
Victor Stinner3f2d1012017-02-02 12:09:30 +0100121#include "clinic/_struct.c.h"
122
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000123/* Helper for integer format codes: converts an arbitrary Python object to a
124 PyLongObject if possible, otherwise fails. Caller should decref. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000125
126static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100127get_pylong(_structmodulestate *state, PyObject *v)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000128{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000129 assert(v != NULL);
130 if (!PyLong_Check(v)) {
131 /* Not an integer; try to use __index__ to convert. */
132 if (PyIndex_Check(v)) {
Serhiy Storchaka5f4b229d2020-05-28 10:33:45 +0300133 v = _PyNumber_Index(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 if (v == NULL)
135 return NULL;
136 }
137 else {
Christian Heimescfeb5432020-11-19 14:36:23 +0100138 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 "required argument is not an integer");
140 return NULL;
141 }
142 }
143 else
144 Py_INCREF(v);
Mark Dickinsonea835e72009-04-19 20:40:33 +0000145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000146 assert(PyLong_Check(v));
147 return v;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000148}
149
Mark Dickinsonea835e72009-04-19 20:40:33 +0000150/* Helper routine to get a C long and raise the appropriate error if it isn't
151 one */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000152
153static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100154get_long(_structmodulestate *state, PyObject *v, long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000155{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000156 long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000157
Christian Heimescfeb5432020-11-19 14:36:23 +0100158 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 if (v == NULL)
160 return -1;
161 assert(PyLong_Check(v));
162 x = PyLong_AsLong(v);
163 Py_DECREF(v);
164 if (x == (long)-1 && PyErr_Occurred()) {
165 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +0100166 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 "argument out of range");
168 return -1;
169 }
170 *p = x;
171 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000172}
173
174
175/* Same, but handling unsigned long */
176
177static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100178get_ulong(_structmodulestate *state, PyObject *v, unsigned long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000179{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000180 unsigned long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000181
Christian Heimescfeb5432020-11-19 14:36:23 +0100182 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000183 if (v == NULL)
184 return -1;
185 assert(PyLong_Check(v));
186 x = PyLong_AsUnsignedLong(v);
187 Py_DECREF(v);
188 if (x == (unsigned long)-1 && PyErr_Occurred()) {
189 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +0100190 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000191 "argument out of range");
192 return -1;
193 }
194 *p = x;
195 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000196}
197
Thomas Wouters477c8d52006-05-27 19:21:47 +0000198/* Same, but handling native long long. */
199
200static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100201get_longlong(_structmodulestate *state, PyObject *v, long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000202{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700203 long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000204
Christian Heimescfeb5432020-11-19 14:36:23 +0100205 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 if (v == NULL)
207 return -1;
208 assert(PyLong_Check(v));
209 x = PyLong_AsLongLong(v);
210 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700211 if (x == (long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +0100213 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000214 "argument out of range");
215 return -1;
216 }
217 *p = x;
218 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000219}
220
221/* Same, but handling native unsigned long long. */
222
223static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100224get_ulonglong(_structmodulestate *state, PyObject *v, unsigned long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000225{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700226 unsigned long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000227
Christian Heimescfeb5432020-11-19 14:36:23 +0100228 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000229 if (v == NULL)
230 return -1;
231 assert(PyLong_Check(v));
232 x = PyLong_AsUnsignedLongLong(v);
233 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700234 if (x == (unsigned long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +0100236 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000237 "argument out of range");
238 return -1;
239 }
240 *p = x;
241 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000242}
243
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200244/* Same, but handling Py_ssize_t */
245
246static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100247get_ssize_t(_structmodulestate *state, PyObject *v, Py_ssize_t *p)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200248{
249 Py_ssize_t x;
250
Christian Heimescfeb5432020-11-19 14:36:23 +0100251 v = get_pylong(state, v);
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200252 if (v == NULL)
253 return -1;
254 assert(PyLong_Check(v));
255 x = PyLong_AsSsize_t(v);
256 Py_DECREF(v);
257 if (x == (Py_ssize_t)-1 && PyErr_Occurred()) {
258 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +0100259 PyErr_SetString(state->StructError,
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200260 "argument out of range");
261 return -1;
262 }
263 *p = x;
264 return 0;
265}
266
267/* Same, but handling size_t */
268
269static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100270get_size_t(_structmodulestate *state, PyObject *v, size_t *p)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200271{
272 size_t x;
273
Christian Heimescfeb5432020-11-19 14:36:23 +0100274 v = get_pylong(state, v);
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200275 if (v == NULL)
276 return -1;
277 assert(PyLong_Check(v));
278 x = PyLong_AsSize_t(v);
279 Py_DECREF(v);
280 if (x == (size_t)-1 && PyErr_Occurred()) {
281 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +0100282 PyErr_SetString(state->StructError,
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200283 "argument out of range");
284 return -1;
285 }
286 *p = x;
287 return 0;
288}
289
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000290
Christian Heimescfeb5432020-11-19 14:36:23 +0100291#define RANGE_ERROR(state, x, f, flag, mask) return _range_error(state, f, flag)
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000292
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000293
Thomas Wouters477c8d52006-05-27 19:21:47 +0000294/* Floating point helpers */
295
296static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100297unpack_halffloat(const char *p, /* start of 2-byte string */
298 int le) /* true for little-endian, false for big-endian */
299{
300 double x;
301
302 x = _PyFloat_Unpack2((unsigned char *)p, le);
303 if (x == -1.0 && PyErr_Occurred()) {
304 return NULL;
305 }
306 return PyFloat_FromDouble(x);
307}
308
309static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100310pack_halffloat(_structmodulestate *state,
311 char *p, /* start of 2-byte string */
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100312 PyObject *v, /* value to pack */
313 int le) /* true for little-endian, false for big-endian */
314{
315 double x = PyFloat_AsDouble(v);
316 if (x == -1.0 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100317 PyErr_SetString(state->StructError,
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100318 "required argument is not a float");
319 return -1;
320 }
321 return _PyFloat_Pack2(x, (unsigned char *)p, le);
322}
323
324static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325unpack_float(const char *p, /* start of 4-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 x = _PyFloat_Unpack4((unsigned char *)p, le);
331 if (x == -1.0 && PyErr_Occurred())
332 return NULL;
333 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000334}
335
336static PyObject *
337unpack_double(const char *p, /* start of 8-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000339{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 x = _PyFloat_Unpack8((unsigned char *)p, le);
343 if (x == -1.0 && PyErr_Occurred())
344 return NULL;
345 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000346}
347
348/* Helper to format the range error exceptions */
349static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100350_range_error(_structmodulestate *state, const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000351{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000352 /* ulargest is the largest unsigned value with f->size bytes.
353 * Note that the simpler:
354 * ((size_t)1 << (f->size * 8)) - 1
355 * doesn't work when f->size == sizeof(size_t) because C doesn't
356 * define what happens when a left shift count is >= the number of
357 * bits in the integer being shifted; e.g., on some boxes it doesn't
358 * shift at all when they're equal.
359 */
360 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
361 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
362 if (is_unsigned)
Christian Heimescfeb5432020-11-19 14:36:23 +0100363 PyErr_Format(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 "'%c' format requires 0 <= number <= %zu",
365 f->format,
366 ulargest);
367 else {
368 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
Christian Heimescfeb5432020-11-19 14:36:23 +0100369 PyErr_Format(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000370 "'%c' format requires %zd <= number <= %zd",
371 f->format,
372 ~ largest,
373 largest);
374 }
Mark Dickinsonae681df2009-03-21 10:26:31 +0000375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000376 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000377}
378
379
380
381/* A large number of small routines follow, with names of the form
382
383 [bln][up]_TYPE
384
Min ho Kimc4cacc82019-07-31 08:16:13 +1000385 [bln] distinguishes among big-endian, little-endian and native.
386 [pu] distinguishes between pack (to struct) and unpack (from struct).
Thomas Wouters477c8d52006-05-27 19:21:47 +0000387 TYPE is one of char, byte, ubyte, etc.
388*/
389
390/* Native mode routines. ****************************************************/
391/* NOTE:
392 In all n[up]_<type> routines handling types larger than 1 byte, there is
393 *no* guarantee that the p pointer is properly aligned for each type,
394 therefore memcpy is called. An intermediate variable is used to
395 compensate for big-endian architectures.
396 Normally both the intermediate variable and the memcpy call will be
397 skipped by C optimisation in little-endian architectures (gcc >= 2.91
398 does this). */
399
400static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100401nu_char(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000402{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000403 return PyBytes_FromStringAndSize(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000404}
405
406static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100407nu_byte(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000408{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000409 return PyLong_FromLong((long) *(signed char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000410}
411
412static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100413nu_ubyte(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000414{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000415 return PyLong_FromLong((long) *(unsigned char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000416}
417
418static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100419nu_short(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000420{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 short x;
422 memcpy((char *)&x, p, sizeof x);
423 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000424}
425
426static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100427nu_ushort(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 unsigned short x;
430 memcpy((char *)&x, p, sizeof x);
431 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000432}
433
434static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100435nu_int(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000436{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 int x;
438 memcpy((char *)&x, p, sizeof x);
439 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000440}
441
442static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100443nu_uint(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000444{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 unsigned int x;
446 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 return PyLong_FromUnsignedLong((unsigned long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000448}
449
450static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100451nu_long(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000452{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 long x;
454 memcpy((char *)&x, p, sizeof x);
455 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000456}
457
458static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100459nu_ulong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000460{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 unsigned long x;
462 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000464}
465
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200466static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100467nu_ssize_t(_structmodulestate *state, const char *p, const formatdef *f)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200468{
469 Py_ssize_t x;
470 memcpy((char *)&x, p, sizeof x);
471 return PyLong_FromSsize_t(x);
472}
473
474static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100475nu_size_t(_structmodulestate *state, const char *p, const formatdef *f)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200476{
477 size_t x;
478 memcpy((char *)&x, p, sizeof x);
479 return PyLong_FromSize_t(x);
480}
481
Thomas Wouters477c8d52006-05-27 19:21:47 +0000482static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100483nu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000484{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700485 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000487 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000488}
489
490static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100491nu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000492{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700493 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000496}
497
Thomas Wouters477c8d52006-05-27 19:21:47 +0000498static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100499nu_bool(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Woutersb2137042007-02-01 18:02:27 +0000500{
Benjamin Petersona9296e72016-09-07 11:06:17 -0700501 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 memcpy((char *)&x, p, sizeof x);
503 return PyBool_FromLong(x != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000504}
505
506
507static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100508nu_halffloat(_structmodulestate *state, const char *p, const formatdef *f)
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100509{
510#if PY_LITTLE_ENDIAN
511 return unpack_halffloat(p, 1);
512#else
513 return unpack_halffloat(p, 0);
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700514#endif
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100515}
516
517static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100518nu_float(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000519{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 float x;
521 memcpy((char *)&x, p, sizeof x);
522 return PyFloat_FromDouble((double)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000523}
524
525static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100526nu_double(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 double x;
529 memcpy((char *)&x, p, sizeof x);
530 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000531}
532
533static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100534nu_void_p(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000535{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 void *x;
537 memcpy((char *)&x, p, sizeof x);
538 return PyLong_FromVoidPtr(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000539}
540
541static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100542np_byte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000543{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 long x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100545 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800547 if (x < -128 || x > 127) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100548 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 "byte format requires -128 <= number <= 127");
550 return -1;
551 }
552 *p = (char)x;
553 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000554}
555
556static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100557np_ubyte(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000558{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 long x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100560 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800562 if (x < 0 || x > 255) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100563 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 "ubyte format requires 0 <= number <= 255");
565 return -1;
566 }
Xiang Zhang981096f2017-05-15 12:04:26 +0800567 *(unsigned char *)p = (unsigned char)x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000569}
570
571static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100572np_char(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000573{
Dino Viehland4f384af2019-09-10 11:18:37 +0100574 if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100575 PyErr_SetString(state->StructError,
Victor Stinnerda9ec992010-12-28 13:26:42 +0000576 "char format requires a bytes object of length 1");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000577 return -1;
578 }
Xiang Zhang96f50282017-05-15 11:53:51 +0800579 *p = *PyBytes_AS_STRING(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000581}
582
583static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100584np_short(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000585{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000586 long x;
587 short y;
Christian Heimescfeb5432020-11-19 14:36:23 +0100588 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000589 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800590 if (x < SHRT_MIN || x > SHRT_MAX) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100591 PyErr_SetString(state->StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200592 "short format requires " Py_STRINGIFY(SHRT_MIN)
593 " <= number <= " Py_STRINGIFY(SHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 return -1;
595 }
596 y = (short)x;
597 memcpy(p, (char *)&y, sizeof y);
598 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000599}
600
601static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100602np_ushort(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000603{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000604 long x;
605 unsigned short y;
Christian Heimescfeb5432020-11-19 14:36:23 +0100606 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000607 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800608 if (x < 0 || x > USHRT_MAX) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100609 PyErr_SetString(state->StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200610 "ushort format requires 0 <= number <= "
611 Py_STRINGIFY(USHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 return -1;
613 }
614 y = (unsigned short)x;
615 memcpy(p, (char *)&y, sizeof y);
616 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000617}
618
619static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100620np_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 long x;
623 int y;
Christian Heimescfeb5432020-11-19 14:36:23 +0100624 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000626#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
Christian Heimescfeb5432020-11-19 14:36:23 +0100628 RANGE_ERROR(state, x, f, 0, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000629#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 y = (int)x;
631 memcpy(p, (char *)&y, sizeof y);
632 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000633}
634
635static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100636np_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000637{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 unsigned long x;
639 unsigned int y;
Christian Heimescfeb5432020-11-19 14:36:23 +0100640 if (get_ulong(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 return -1;
642 y = (unsigned int)x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000643#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 if (x > ((unsigned long)UINT_MAX))
Christian Heimescfeb5432020-11-19 14:36:23 +0100645 RANGE_ERROR(state, y, f, 1, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000646#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000647 memcpy(p, (char *)&y, sizeof y);
648 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000649}
650
651static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100652np_long(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 long x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100655 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 return -1;
657 memcpy(p, (char *)&x, sizeof x);
658 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000659}
660
661static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100662np_ulong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000663{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 unsigned long x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100665 if (get_ulong(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000666 return -1;
667 memcpy(p, (char *)&x, sizeof x);
668 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000669}
670
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200671static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100672np_ssize_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200673{
674 Py_ssize_t x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100675 if (get_ssize_t(state, v, &x) < 0)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200676 return -1;
677 memcpy(p, (char *)&x, sizeof x);
678 return 0;
679}
680
681static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100682np_size_t(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200683{
684 size_t x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100685 if (get_size_t(state, v, &x) < 0)
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200686 return -1;
687 memcpy(p, (char *)&x, sizeof x);
688 return 0;
689}
690
Thomas Wouters477c8d52006-05-27 19:21:47 +0000691static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100692np_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000693{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700694 long long x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100695 if (get_longlong(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 return -1;
697 memcpy(p, (char *)&x, sizeof x);
698 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000699}
700
701static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100702np_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000703{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700704 unsigned long long x;
Christian Heimescfeb5432020-11-19 14:36:23 +0100705 if (get_ulonglong(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 return -1;
707 memcpy(p, (char *)&x, sizeof x);
708 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000709}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000710
Thomas Woutersb2137042007-02-01 18:02:27 +0000711
712static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100713np_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Woutersb2137042007-02-01 18:02:27 +0000714{
Benjamin Petersonde73c452010-07-07 18:54:59 +0000715 int y;
Benjamin Petersona9296e72016-09-07 11:06:17 -0700716 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000718 if (y < 0)
719 return -1;
720 x = y;
721 memcpy(p, (char *)&x, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000723}
724
Thomas Wouters477c8d52006-05-27 19:21:47 +0000725static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100726np_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100727{
728#if PY_LITTLE_ENDIAN
Christian Heimescfeb5432020-11-19 14:36:23 +0100729 return pack_halffloat(state, p, v, 1);
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100730#else
Dong-hee Na588c7c92020-11-19 23:14:34 +0900731 return pack_halffloat(state, p, v, 0);
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100732#endif
733}
734
735static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100736np_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000737{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 float x = (float)PyFloat_AsDouble(v);
739 if (x == -1 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100740 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 "required argument is not a float");
742 return -1;
743 }
744 memcpy(p, (char *)&x, sizeof x);
745 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000746}
747
748static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100749np_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000750{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000751 double x = PyFloat_AsDouble(v);
752 if (x == -1 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100753 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 "required argument is not a float");
755 return -1;
756 }
757 memcpy(p, (char *)&x, sizeof(double));
758 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000759}
760
761static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100762np_void_p(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000763{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 void *x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000765
Christian Heimescfeb5432020-11-19 14:36:23 +0100766 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000767 if (v == NULL)
768 return -1;
769 assert(PyLong_Check(v));
770 x = PyLong_AsVoidPtr(v);
771 Py_DECREF(v);
772 if (x == NULL && PyErr_Occurred())
773 return -1;
774 memcpy(p, (char *)&x, sizeof x);
775 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000776}
777
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200778static const formatdef native_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 {'x', sizeof(char), 0, NULL},
780 {'b', sizeof(char), 0, nu_byte, np_byte},
781 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
782 {'c', sizeof(char), 0, nu_char, np_char},
783 {'s', sizeof(char), 0, NULL},
784 {'p', sizeof(char), 0, NULL},
785 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
786 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
787 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
788 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
789 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
790 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200791 {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t},
792 {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t},
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700793 {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong},
794 {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Benjamin Petersona9296e72016-09-07 11:06:17 -0700795 {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100796 {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000797 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
798 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
799 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
800 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000801};
802
803/* Big-endian routines. *****************************************************/
804
805static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100806bu_int(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000807{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 long x = 0;
809 Py_ssize_t i = f->size;
810 const unsigned char *bytes = (const unsigned char *)p;
811 do {
812 x = (x<<8) | *bytes++;
813 } while (--i > 0);
814 /* Extend the sign bit. */
815 if (SIZEOF_LONG > f->size)
816 x |= -(x & (1L << ((8 * f->size) - 1)));
817 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000818}
819
820static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100821bu_uint(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000822{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000823 unsigned long x = 0;
824 Py_ssize_t i = f->size;
825 const unsigned char *bytes = (const unsigned char *)p;
826 do {
827 x = (x<<8) | *bytes++;
828 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000829 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000830}
831
832static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100833bu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000834{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700835 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 Py_ssize_t i = f->size;
837 const unsigned char *bytes = (const unsigned char *)p;
838 do {
839 x = (x<<8) | *bytes++;
840 } while (--i > 0);
841 /* Extend the sign bit. */
842 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700843 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000844 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000845}
846
847static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100848bu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000849{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700850 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000851 Py_ssize_t i = f->size;
852 const unsigned char *bytes = (const unsigned char *)p;
853 do {
854 x = (x<<8) | *bytes++;
855 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000857}
858
859static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100860bu_halffloat(_structmodulestate *state, const char *p, const formatdef *f)
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100861{
862 return unpack_halffloat(p, 0);
863}
864
865static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100866bu_float(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000867{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 return unpack_float(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000869}
870
871static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100872bu_double(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000873{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000874 return unpack_double(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000875}
876
Thomas Woutersb2137042007-02-01 18:02:27 +0000877static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +0100878bu_bool(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Woutersb2137042007-02-01 18:02:27 +0000879{
Xiang Zhang96f50282017-05-15 11:53:51 +0800880 return PyBool_FromLong(*p != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000881}
882
Thomas Wouters477c8d52006-05-27 19:21:47 +0000883static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100884bp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000885{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 long x;
887 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800888 unsigned char *q = (unsigned char *)p;
Christian Heimescfeb5432020-11-19 14:36:23 +0100889 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000890 return -1;
891 i = f->size;
892 if (i != SIZEOF_LONG) {
893 if ((i == 2) && (x < -32768 || x > 32767))
Christian Heimescfeb5432020-11-19 14:36:23 +0100894 RANGE_ERROR(state, x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000895#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Christian Heimescfeb5432020-11-19 14:36:23 +0100897 RANGE_ERROR(state, x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000898#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 }
900 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800901 q[--i] = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 x >>= 8;
903 } while (i > 0);
904 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000905}
906
907static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100908bp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000909{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000910 unsigned long x;
911 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800912 unsigned char *q = (unsigned char *)p;
Christian Heimescfeb5432020-11-19 14:36:23 +0100913 if (get_ulong(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 return -1;
915 i = f->size;
916 if (i != SIZEOF_LONG) {
917 unsigned long maxint = 1;
918 maxint <<= (unsigned long)(i * 8);
919 if (x >= maxint)
Christian Heimescfeb5432020-11-19 14:36:23 +0100920 RANGE_ERROR(state, x, f, 1, maxint - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 }
922 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800923 q[--i] = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 x >>= 8;
925 } while (i > 0);
926 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000927}
928
929static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100930bp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000931{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 int res;
Christian Heimescfeb5432020-11-19 14:36:23 +0100933 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000934 if (v == NULL)
935 return -1;
936 res = _PyLong_AsByteArray((PyLongObject *)v,
937 (unsigned char *)p,
938 8,
939 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800940 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 Py_DECREF(v);
942 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000943}
944
945static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100946bp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000947{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000948 int res;
Christian Heimescfeb5432020-11-19 14:36:23 +0100949 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 if (v == NULL)
951 return -1;
952 res = _PyLong_AsByteArray((PyLongObject *)v,
953 (unsigned char *)p,
954 8,
955 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800956 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 Py_DECREF(v);
958 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000959}
960
961static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100962bp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100963{
Christian Heimescfeb5432020-11-19 14:36:23 +0100964 return pack_halffloat(state, p, v, 0);
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100965}
966
967static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100968bp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000969{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 double x = PyFloat_AsDouble(v);
971 if (x == -1 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100972 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 "required argument is not a float");
974 return -1;
975 }
976 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000977}
978
979static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100980bp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000981{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 double x = PyFloat_AsDouble(v);
983 if (x == -1 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +0100984 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 "required argument is not a float");
986 return -1;
987 }
988 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000989}
990
Thomas Woutersb2137042007-02-01 18:02:27 +0000991static int
Christian Heimescfeb5432020-11-19 14:36:23 +0100992bp_bool(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Woutersb2137042007-02-01 18:02:27 +0000993{
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000994 int y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000996 if (y < 0)
997 return -1;
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000998 *p = (char)y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000999 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +00001000}
1001
Thomas Wouters477c8d52006-05-27 19:21:47 +00001002static formatdef bigendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 {'x', 1, 0, NULL},
1004 {'b', 1, 0, nu_byte, np_byte},
1005 {'B', 1, 0, nu_ubyte, np_ubyte},
1006 {'c', 1, 0, nu_char, np_char},
1007 {'s', 1, 0, NULL},
1008 {'p', 1, 0, NULL},
1009 {'h', 2, 0, bu_int, bp_int},
1010 {'H', 2, 0, bu_uint, bp_uint},
1011 {'i', 4, 0, bu_int, bp_int},
1012 {'I', 4, 0, bu_uint, bp_uint},
1013 {'l', 4, 0, bu_int, bp_int},
1014 {'L', 4, 0, bu_uint, bp_uint},
1015 {'q', 8, 0, bu_longlong, bp_longlong},
1016 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
1017 {'?', 1, 0, bu_bool, bp_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001018 {'e', 2, 0, bu_halffloat, bp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001019 {'f', 4, 0, bu_float, bp_float},
1020 {'d', 8, 0, bu_double, bp_double},
1021 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001022};
1023
1024/* Little-endian routines. *****************************************************/
1025
1026static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001027lu_int(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001028{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001029 long x = 0;
1030 Py_ssize_t i = f->size;
1031 const unsigned char *bytes = (const unsigned char *)p;
1032 do {
1033 x = (x<<8) | bytes[--i];
1034 } while (i > 0);
1035 /* Extend the sign bit. */
1036 if (SIZEOF_LONG > f->size)
1037 x |= -(x & (1L << ((8 * f->size) - 1)));
1038 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001039}
1040
1041static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001042lu_uint(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001043{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 unsigned long x = 0;
1045 Py_ssize_t i = f->size;
1046 const unsigned char *bytes = (const unsigned char *)p;
1047 do {
1048 x = (x<<8) | bytes[--i];
1049 } while (i > 0);
Xiang Zhang96f50282017-05-15 11:53:51 +08001050 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001051}
1052
1053static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001054lu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001055{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001056 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 Py_ssize_t i = f->size;
1058 const unsigned char *bytes = (const unsigned char *)p;
1059 do {
1060 x = (x<<8) | bytes[--i];
1061 } while (i > 0);
1062 /* Extend the sign bit. */
1063 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001064 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001066}
1067
1068static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001069lu_ulonglong(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001070{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001071 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 Py_ssize_t i = f->size;
1073 const unsigned char *bytes = (const unsigned char *)p;
1074 do {
1075 x = (x<<8) | bytes[--i];
1076 } while (i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001078}
1079
1080static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001081lu_halffloat(_structmodulestate *state, const char *p, const formatdef *f)
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001082{
1083 return unpack_halffloat(p, 1);
1084}
1085
1086static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001087lu_float(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001088{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001089 return unpack_float(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001090}
1091
1092static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001093lu_double(_structmodulestate *state, const char *p, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001094{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 return unpack_double(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001096}
1097
1098static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001099lp_int(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001100{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 long x;
1102 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001103 unsigned char *q = (unsigned char *)p;
Christian Heimescfeb5432020-11-19 14:36:23 +01001104 if (get_long(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 return -1;
1106 i = f->size;
1107 if (i != SIZEOF_LONG) {
1108 if ((i == 2) && (x < -32768 || x > 32767))
Christian Heimescfeb5432020-11-19 14:36:23 +01001109 RANGE_ERROR(state, x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001110#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
Christian Heimescfeb5432020-11-19 14:36:23 +01001112 RANGE_ERROR(state, x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001113#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 }
1115 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001116 *q++ = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 x >>= 8;
1118 } while (--i > 0);
1119 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001120}
1121
1122static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001123lp_uint(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001124{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 unsigned long x;
1126 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001127 unsigned char *q = (unsigned char *)p;
Christian Heimescfeb5432020-11-19 14:36:23 +01001128 if (get_ulong(state, v, &x) < 0)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 return -1;
1130 i = f->size;
1131 if (i != SIZEOF_LONG) {
1132 unsigned long maxint = 1;
1133 maxint <<= (unsigned long)(i * 8);
1134 if (x >= maxint)
Christian Heimescfeb5432020-11-19 14:36:23 +01001135 RANGE_ERROR(state, x, f, 1, maxint - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 }
1137 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001138 *q++ = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 x >>= 8;
1140 } while (--i > 0);
1141 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001142}
1143
1144static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001145lp_longlong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 int res;
Christian Heimescfeb5432020-11-19 14:36:23 +01001148 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 if (v == NULL)
1150 return -1;
1151 res = _PyLong_AsByteArray((PyLongObject*)v,
1152 (unsigned char *)p,
1153 8,
1154 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001155 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 Py_DECREF(v);
1157 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001158}
1159
1160static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001161lp_ulonglong(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001162{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 int res;
Christian Heimescfeb5432020-11-19 14:36:23 +01001164 v = get_pylong(state, v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 if (v == NULL)
1166 return -1;
1167 res = _PyLong_AsByteArray((PyLongObject*)v,
1168 (unsigned char *)p,
1169 8,
1170 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001171 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 Py_DECREF(v);
1173 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001174}
1175
1176static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001177lp_halffloat(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001178{
Christian Heimescfeb5432020-11-19 14:36:23 +01001179 return pack_halffloat(state, p, v, 1);
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001180}
1181
1182static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001183lp_float(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001184{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 double x = PyFloat_AsDouble(v);
1186 if (x == -1 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001187 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 "required argument is not a float");
1189 return -1;
1190 }
1191 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001192}
1193
1194static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001195lp_double(_structmodulestate *state, char *p, PyObject *v, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001196{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 double x = PyFloat_AsDouble(v);
1198 if (x == -1 && PyErr_Occurred()) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001199 PyErr_SetString(state->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 "required argument is not a float");
1201 return -1;
1202 }
1203 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001204}
1205
1206static formatdef lilendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 {'x', 1, 0, NULL},
1208 {'b', 1, 0, nu_byte, np_byte},
1209 {'B', 1, 0, nu_ubyte, np_ubyte},
1210 {'c', 1, 0, nu_char, np_char},
1211 {'s', 1, 0, NULL},
1212 {'p', 1, 0, NULL},
1213 {'h', 2, 0, lu_int, lp_int},
1214 {'H', 2, 0, lu_uint, lp_uint},
1215 {'i', 4, 0, lu_int, lp_int},
1216 {'I', 4, 0, lu_uint, lp_uint},
1217 {'l', 4, 0, lu_int, lp_int},
1218 {'L', 4, 0, lu_uint, lp_uint},
1219 {'q', 8, 0, lu_longlong, lp_longlong},
1220 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1221 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1222 but potentially different from native rep -- reuse bx_bool funcs. */
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001223 {'e', 2, 0, lu_halffloat, lp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 {'f', 4, 0, lu_float, lp_float},
1225 {'d', 8, 0, lu_double, lp_double},
1226 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001227};
1228
1229
1230static const formatdef *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001231whichtable(const char **pfmt)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001232{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001233 const char *fmt = (*pfmt)++; /* May be backed out of later */
1234 switch (*fmt) {
1235 case '<':
1236 return lilendian_table;
1237 case '>':
1238 case '!': /* Network byte order is big-endian */
1239 return bigendian_table;
Ezio Melotti42da6632011-03-15 05:18:48 +02001240 case '=': { /* Host byte order -- different from native in alignment! */
Christian Heimes743e0cd2012-10-17 23:52:17 +02001241#if PY_LITTLE_ENDIAN
1242 return lilendian_table;
1243#else
1244 return bigendian_table;
1245#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 }
1247 default:
1248 --*pfmt; /* Back out of pointer increment */
1249 /* Fall through */
1250 case '@':
1251 return native_table;
1252 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001253}
1254
1255
1256/* Get the table entry for a format code */
1257
1258static const formatdef *
Christian Heimescfeb5432020-11-19 14:36:23 +01001259getentry(_structmodulestate *state, int c, const formatdef *f)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001261 for (; f->format != '\0'; f++) {
1262 if (f->format == c) {
1263 return f;
1264 }
1265 }
Christian Heimescfeb5432020-11-19 14:36:23 +01001266 PyErr_SetString(state->StructError, "bad char in struct format");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001267 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001268}
1269
1270
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001271/* Align a size according to a format code. Return -1 on overflow. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001272
Mark Dickinsoneac0e682010-06-11 19:05:08 +00001273static Py_ssize_t
Thomas Wouters477c8d52006-05-27 19:21:47 +00001274align(Py_ssize_t size, char c, const formatdef *e)
1275{
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001276 Py_ssize_t extra;
1277
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 if (e->format == c) {
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001279 if (e->alignment && size > 0) {
1280 extra = (e->alignment - 1) - (size - 1) % (e->alignment);
1281 if (extra > PY_SSIZE_T_MAX - size)
1282 return -1;
1283 size += extra;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001284 }
1285 }
1286 return size;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001287}
1288
Antoine Pitrou9f146812013-04-27 00:20:04 +02001289/*
1290 * Struct object implementation.
1291 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001292
1293/* calculate the size of a format string */
1294
1295static int
1296prepare_s(PyStructObject *self)
1297{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 const formatdef *f;
1299 const formatdef *e;
1300 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 const char *s;
1303 const char *fmt;
1304 char c;
Victor Stinner706768c2014-08-16 01:03:39 +02001305 Py_ssize_t size, len, num, itemsize;
1306 size_t ncodes;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001307
Christian Heimescfeb5432020-11-19 14:36:23 +01001308 _structmodulestate *state = get_struct_state_structinst(self);
1309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 fmt = PyBytes_AS_STRING(self->s_format);
Zackery Spytz3f59b552020-05-25 01:55:09 -06001311 if (strlen(fmt) != (size_t)PyBytes_GET_SIZE(self->s_format)) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001312 PyErr_SetString(state->StructError,
Zackery Spytz3f59b552020-05-25 01:55:09 -06001313 "embedded null character");
1314 return -1;
1315 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001316
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001317 f = whichtable(&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 s = fmt;
1320 size = 0;
1321 len = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001322 ncodes = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 while ((c = *s++) != '\0') {
Jordon Xu2ec70102019-09-11 00:04:08 +08001324 if (Py_ISSPACE(c))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 continue;
1326 if ('0' <= c && c <= '9') {
1327 num = c - '0';
1328 while ('0' <= (c = *s++) && c <= '9') {
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001329 /* overflow-safe version of
1330 if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1331 if (num >= PY_SSIZE_T_MAX / 10 && (
1332 num > PY_SSIZE_T_MAX / 10 ||
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001333 (c - '0') > PY_SSIZE_T_MAX % 10))
1334 goto overflow;
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001335 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 }
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001337 if (c == '\0') {
Christian Heimescfeb5432020-11-19 14:36:23 +01001338 PyErr_SetString(state->StructError,
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001339 "repeat count given without format specifier");
1340 return -1;
1341 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 }
1343 else
1344 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001345
Christian Heimescfeb5432020-11-19 14:36:23 +01001346 e = getentry(state, c, f);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 if (e == NULL)
1348 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 switch (c) {
1351 case 's': /* fall through */
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001352 case 'p': len++; ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 case 'x': break;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001354 default: len += num; if (num) ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 itemsize = e->size;
1358 size = align(size, c, e);
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001359 if (size == -1)
1360 goto overflow;
1361
1362 /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1363 if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1364 goto overflow;
1365 size += num * itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001366 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001367
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 /* check for overflow */
Victor Stinner706768c2014-08-16 01:03:39 +02001369 if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 PyErr_NoMemory();
1371 return -1;
1372 }
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +00001373
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 self->s_size = size;
1375 self->s_len = len;
Victor Stinner00d7abd2020-12-01 09:56:42 +01001376 codes = PyMem_Malloc((ncodes + 1) * sizeof(formatcode));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001377 if (codes == NULL) {
1378 PyErr_NoMemory();
1379 return -1;
1380 }
Mark Dickinsoncf28b952010-07-29 21:41:59 +00001381 /* Free any s_codes value left over from a previous initialization. */
1382 if (self->s_codes != NULL)
Victor Stinner00d7abd2020-12-01 09:56:42 +01001383 PyMem_Free(self->s_codes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 s = fmt;
1387 size = 0;
1388 while ((c = *s++) != '\0') {
Jordon Xu2ec70102019-09-11 00:04:08 +08001389 if (Py_ISSPACE(c))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 continue;
1391 if ('0' <= c && c <= '9') {
1392 num = c - '0';
1393 while ('0' <= (c = *s++) && c <= '9')
1394 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 }
1396 else
1397 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001398
Christian Heimescfeb5432020-11-19 14:36:23 +01001399 e = getentry(state, c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001400
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 size = align(size, c, e);
1402 if (c == 's' || c == 'p') {
1403 codes->offset = size;
1404 codes->size = num;
1405 codes->fmtdef = e;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001406 codes->repeat = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001407 codes++;
1408 size += num;
1409 } else if (c == 'x') {
1410 size += num;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001411 } else if (num) {
1412 codes->offset = size;
1413 codes->size = e->size;
1414 codes->fmtdef = e;
1415 codes->repeat = num;
1416 codes++;
1417 size += e->size * num;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001418 }
1419 }
1420 codes->fmtdef = NULL;
1421 codes->offset = size;
1422 codes->size = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001423 codes->repeat = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 return 0;
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001426
1427 overflow:
Christian Heimescfeb5432020-11-19 14:36:23 +01001428 PyErr_SetString(state->StructError,
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001429 "total struct size too long");
1430 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001431}
1432
1433static PyObject *
1434s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1435{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 PyObject *self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001437
Dino Viehland4f384af2019-09-10 11:18:37 +01001438 assert(type != NULL);
1439 allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc);
1440 assert(alloc_func != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001441
Dino Viehland4f384af2019-09-10 11:18:37 +01001442 self = alloc_func(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 if (self != NULL) {
1444 PyStructObject *s = (PyStructObject*)self;
Pablo Galindo290f5ae2020-12-28 23:59:16 +00001445 s->s_format = Py_NewRef(Py_None);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 s->s_codes = NULL;
1447 s->s_size = -1;
1448 s->s_len = -1;
1449 }
1450 return self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001451}
1452
Victor Stinner3f2d1012017-02-02 12:09:30 +01001453/*[clinic input]
1454Struct.__init__
1455
1456 format: object
1457
1458Create a compiled struct object.
1459
1460Return a new Struct object which writes and reads binary data according to
1461the format string.
1462
1463See help(struct) for more on format strings.
1464[clinic start generated code]*/
1465
Thomas Wouters477c8d52006-05-27 19:21:47 +00001466static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001467Struct___init___impl(PyStructObject *self, PyObject *format)
1468/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001469{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 int ret = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001471
Victor Stinner3f2d1012017-02-02 12:09:30 +01001472 if (PyUnicode_Check(format)) {
1473 format = PyUnicode_AsASCIIString(format);
1474 if (format == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001475 return -1;
1476 }
1477 /* XXX support buffer interface, too */
1478 else {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001479 Py_INCREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001480 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001481
Victor Stinner3f2d1012017-02-02 12:09:30 +01001482 if (!PyBytes_Check(format)) {
1483 Py_DECREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001484 PyErr_Format(PyExc_TypeError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001485 "Struct() argument 1 must be a str or bytes object, "
1486 "not %.200s",
Dino Viehland4f384af2019-09-10 11:18:37 +01001487 _PyType_Name(Py_TYPE(format)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 return -1;
1489 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001490
Xiang Zhang96f50282017-05-15 11:53:51 +08001491 Py_SETREF(self->s_format, format);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001492
Victor Stinner3f2d1012017-02-02 12:09:30 +01001493 ret = prepare_s(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001494 return ret;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001495}
1496
1497static void
1498s_dealloc(PyStructObject *s)
1499{
Dino Viehland4f384af2019-09-10 11:18:37 +01001500 PyTypeObject *tp = Py_TYPE(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 if (s->weakreflist != NULL)
1502 PyObject_ClearWeakRefs((PyObject *)s);
1503 if (s->s_codes != NULL) {
Victor Stinner00d7abd2020-12-01 09:56:42 +01001504 PyMem_Free(s->s_codes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 }
Dino Viehland4f384af2019-09-10 11:18:37 +01001506 Py_XDECREF(s->s_format);
1507 freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free);
1508 free_func(s);
1509 Py_DECREF(tp);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510}
1511
1512static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001513s_unpack_internal(PyStructObject *soself, const char *startfrom,
1514 _structmodulestate *state) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001515 formatcode *code;
1516 Py_ssize_t i = 0;
1517 PyObject *result = PyTuple_New(soself->s_len);
1518 if (result == NULL)
1519 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 const formatdef *e = code->fmtdef;
1523 const char *res = startfrom + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001524 Py_ssize_t j = code->repeat;
1525 while (j--) {
1526 PyObject *v;
1527 if (e->format == 's') {
1528 v = PyBytes_FromStringAndSize(res, code->size);
1529 } else if (e->format == 'p') {
1530 Py_ssize_t n = *(unsigned char*)res;
1531 if (n >= code->size)
1532 n = code->size - 1;
1533 v = PyBytes_FromStringAndSize(res + 1, n);
1534 } else {
Christian Heimescfeb5432020-11-19 14:36:23 +01001535 v = e->unpack(state, res, e);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001536 }
1537 if (v == NULL)
1538 goto fail;
1539 PyTuple_SET_ITEM(result, i++, v);
1540 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001545fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 Py_DECREF(result);
1547 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001548}
1549
1550
Victor Stinner3f2d1012017-02-02 12:09:30 +01001551/*[clinic input]
1552Struct.unpack
1553
1554 buffer: Py_buffer
1555 /
1556
1557Return a tuple containing unpacked values.
1558
1559Unpack according to the format string Struct.format. The buffer's size
1560in bytes must be Struct.size.
1561
1562See help(struct) for more on format strings.
1563[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001564
1565static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001566Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1567/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001568{
Christian Heimescfeb5432020-11-19 14:36:23 +01001569 _structmodulestate *state = get_struct_state_structinst(self);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001570 assert(self->s_codes != NULL);
1571 if (buffer->len != self->s_size) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001572 PyErr_Format(state->StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001573 "unpack requires a buffer of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001574 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 return NULL;
1576 }
Christian Heimescfeb5432020-11-19 14:36:23 +01001577 return s_unpack_internal(self, buffer->buf, state);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001578}
1579
Victor Stinner3f2d1012017-02-02 12:09:30 +01001580/*[clinic input]
1581Struct.unpack_from
1582
1583 buffer: Py_buffer
1584 offset: Py_ssize_t = 0
1585
1586Return a tuple containing unpacked values.
1587
1588Values are unpacked according to the format string Struct.format.
1589
Xiang Zhangc10b2882018-03-11 02:58:52 +08001590The buffer's size in bytes, starting at position offset, must be
1591at least Struct.size.
Victor Stinner3f2d1012017-02-02 12:09:30 +01001592
1593See help(struct) for more on format strings.
1594[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001595
1596static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001597Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1598 Py_ssize_t offset)
Xiang Zhangc10b2882018-03-11 02:58:52 +08001599/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001600{
Christian Heimescfeb5432020-11-19 14:36:23 +01001601 _structmodulestate *state = get_struct_state_structinst(self);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001602 assert(self->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001603
Xiang Zhangc10b2882018-03-11 02:58:52 +08001604 if (offset < 0) {
1605 if (offset + self->s_size > 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001606 PyErr_Format(state->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001607 "not enough data to unpack %zd bytes at offset %zd",
1608 self->s_size,
1609 offset);
1610 return NULL;
1611 }
1612
1613 if (offset + buffer->len < 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001614 PyErr_Format(state->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001615 "offset %zd out of range for %zd-byte buffer",
1616 offset,
1617 buffer->len);
1618 return NULL;
1619 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001620 offset += buffer->len;
Xiang Zhangc10b2882018-03-11 02:58:52 +08001621 }
1622
1623 if ((buffer->len - offset) < self->s_size) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001624 PyErr_Format(state->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001625 "unpack_from requires a buffer of at least %zu bytes for "
1626 "unpacking %zd bytes at offset %zd "
1627 "(actual buffer size is %zd)",
1628 (size_t)self->s_size + (size_t)offset,
1629 self->s_size,
1630 offset,
1631 buffer->len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001632 return NULL;
1633 }
Christian Heimescfeb5432020-11-19 14:36:23 +01001634 return s_unpack_internal(self, (char*)buffer->buf + offset, state);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001635}
1636
1637
Victor Stinner3f2d1012017-02-02 12:09:30 +01001638
Antoine Pitrou9f146812013-04-27 00:20:04 +02001639/* Unpack iterator type */
1640
1641typedef struct {
1642 PyObject_HEAD
1643 PyStructObject *so;
1644 Py_buffer buf;
1645 Py_ssize_t index;
1646} unpackiterobject;
1647
1648static void
1649unpackiter_dealloc(unpackiterobject *self)
1650{
INADA Naokia6296d32017-08-24 14:55:17 +09001651 /* bpo-31095: UnTrack is needed before calling any callbacks */
Dino Viehland4f384af2019-09-10 11:18:37 +01001652 PyTypeObject *tp = Py_TYPE(self);
INADA Naokia6296d32017-08-24 14:55:17 +09001653 PyObject_GC_UnTrack(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001654 Py_XDECREF(self->so);
1655 PyBuffer_Release(&self->buf);
1656 PyObject_GC_Del(self);
Dino Viehland4f384af2019-09-10 11:18:37 +01001657 Py_DECREF(tp);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001658}
1659
1660static int
1661unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1662{
Pablo Galindo1cf15af2020-05-27 10:03:38 +01001663 Py_VISIT(Py_TYPE(self));
Antoine Pitrou9f146812013-04-27 00:20:04 +02001664 Py_VISIT(self->so);
1665 Py_VISIT(self->buf.obj);
1666 return 0;
1667}
1668
1669static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301670unpackiter_len(unpackiterobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou9f146812013-04-27 00:20:04 +02001671{
1672 Py_ssize_t len;
1673 if (self->so == NULL)
1674 len = 0;
1675 else
1676 len = (self->buf.len - self->index) / self->so->s_size;
1677 return PyLong_FromSsize_t(len);
1678}
1679
1680static PyMethodDef unpackiter_methods[] = {
1681 {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1682 {NULL, NULL} /* sentinel */
1683};
1684
1685static PyObject *
1686unpackiter_iternext(unpackiterobject *self)
1687{
Christian Heimescfeb5432020-11-19 14:36:23 +01001688 _structmodulestate *state = get_struct_state_iterinst(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001689 PyObject *result;
1690 if (self->so == NULL)
1691 return NULL;
1692 if (self->index >= self->buf.len) {
1693 /* Iterator exhausted */
1694 Py_CLEAR(self->so);
1695 PyBuffer_Release(&self->buf);
1696 return NULL;
1697 }
1698 assert(self->index + self->so->s_size <= self->buf.len);
1699 result = s_unpack_internal(self->so,
Christian Heimescfeb5432020-11-19 14:36:23 +01001700 (char*) self->buf.buf + self->index,
1701 state);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001702 self->index += self->so->s_size;
1703 return result;
1704}
1705
Dino Viehland4f384af2019-09-10 11:18:37 +01001706PyObject *unpackiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1707 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s objects", _PyType_Name(type));
1708 return NULL;
1709}
1710
1711static PyType_Slot unpackiter_type_slots[] = {
1712 {Py_tp_dealloc, unpackiter_dealloc},
1713 {Py_tp_getattro, PyObject_GenericGetAttr},
1714 {Py_tp_traverse, unpackiter_traverse},
1715 {Py_tp_iter, PyObject_SelfIter},
1716 {Py_tp_iternext, unpackiter_iternext},
1717 {Py_tp_methods, unpackiter_methods},
1718 {Py_tp_new, unpackiter_new},
1719 {0, 0},
1720};
1721
1722static PyType_Spec unpackiter_type_spec = {
1723 "_struct.unpack_iterator",
1724 sizeof(unpackiterobject),
1725 0,
1726 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1727 unpackiter_type_slots
Antoine Pitrou9f146812013-04-27 00:20:04 +02001728};
1729
Victor Stinner3f2d1012017-02-02 12:09:30 +01001730/*[clinic input]
1731Struct.iter_unpack
1732
1733 buffer: object
1734 /
1735
1736Return an iterator yielding tuples.
1737
1738Tuples are unpacked from the given bytes source, like a repeated
1739invocation of unpack_from().
1740
1741Requires that the bytes length be a multiple of the struct size.
1742[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001743
1744static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001745Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1746/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001747{
Christian Heimescfeb5432020-11-19 14:36:23 +01001748 _structmodulestate *state = get_struct_state_structinst(self);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001749 unpackiterobject *iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001750
Victor Stinner3f2d1012017-02-02 12:09:30 +01001751 assert(self->s_codes != NULL);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001752
Victor Stinner3f2d1012017-02-02 12:09:30 +01001753 if (self->s_size == 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001754 PyErr_Format(state->StructError,
Antoine Pitrou9f146812013-04-27 00:20:04 +02001755 "cannot iteratively unpack with a struct of length 0");
1756 return NULL;
1757 }
1758
Christian Heimescfeb5432020-11-19 14:36:23 +01001759 iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)state->unpackiter_type, 0);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001760 if (iter == NULL)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001761 return NULL;
1762
Victor Stinner3f2d1012017-02-02 12:09:30 +01001763 if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1764 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001765 return NULL;
1766 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001767 if (iter->buf.len % self->s_size != 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001768 PyErr_Format(state->StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001769 "iterative unpacking requires a buffer of "
1770 "a multiple of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001771 self->s_size);
1772 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001773 return NULL;
1774 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001775 Py_INCREF(self);
1776 iter->so = self;
1777 iter->index = 0;
1778 return (PyObject *)iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001779}
1780
1781
Thomas Wouters477c8d52006-05-27 19:21:47 +00001782/*
1783 * Guts of the pack function.
1784 *
1785 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1786 * argument for where to start processing the arguments for packing, and a
1787 * character buffer for writing the packed string. The caller must insure
1788 * that the buffer may contain the required length for packing the arguments.
1789 * 0 is returned on success, 1 is returned if there is an error.
1790 *
1791 */
1792static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001793s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset,
1794 char* buf, _structmodulestate *state)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001795{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001796 formatcode *code;
1797 /* XXX(nnorwitz): why does i need to be a local? can we use
1798 the offset parameter or do we need the wider width? */
1799 Py_ssize_t i;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001801 memset(buf, '\0', soself->s_size);
1802 i = offset;
1803 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001804 const formatdef *e = code->fmtdef;
1805 char *res = buf + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001806 Py_ssize_t j = code->repeat;
1807 while (j--) {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001808 PyObject *v = args[i++];
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001809 if (e->format == 's') {
1810 Py_ssize_t n;
1811 int isstring;
Serhiy Storchaka8f87eef2020-04-12 14:58:27 +03001812 const void *p;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001813 isstring = PyBytes_Check(v);
1814 if (!isstring && !PyByteArray_Check(v)) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001815 PyErr_SetString(state->StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001816 "argument for 's' must be a bytes object");
1817 return -1;
1818 }
1819 if (isstring) {
1820 n = PyBytes_GET_SIZE(v);
1821 p = PyBytes_AS_STRING(v);
1822 }
1823 else {
1824 n = PyByteArray_GET_SIZE(v);
1825 p = PyByteArray_AS_STRING(v);
1826 }
1827 if (n > code->size)
1828 n = code->size;
1829 if (n > 0)
1830 memcpy(res, p, n);
1831 } else if (e->format == 'p') {
1832 Py_ssize_t n;
1833 int isstring;
Serhiy Storchaka8f87eef2020-04-12 14:58:27 +03001834 const void *p;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001835 isstring = PyBytes_Check(v);
1836 if (!isstring && !PyByteArray_Check(v)) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001837 PyErr_SetString(state->StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001838 "argument for 'p' must be a bytes object");
1839 return -1;
1840 }
1841 if (isstring) {
1842 n = PyBytes_GET_SIZE(v);
1843 p = PyBytes_AS_STRING(v);
1844 }
1845 else {
1846 n = PyByteArray_GET_SIZE(v);
1847 p = PyByteArray_AS_STRING(v);
1848 }
1849 if (n > (code->size - 1))
1850 n = code->size - 1;
1851 if (n > 0)
1852 memcpy(res + 1, p, n);
1853 if (n > 255)
1854 n = 255;
1855 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1856 } else {
Christian Heimescfeb5432020-11-19 14:36:23 +01001857 if (e->pack(state, res, v, e) < 0) {
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001858 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +01001859 PyErr_SetString(state->StructError,
Serhiy Storchaka46e1ce22013-08-27 20:17:03 +03001860 "int too large to convert");
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001861 return -1;
1862 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 }
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001864 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001865 }
1866 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001867
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001868 /* Success */
1869 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001870}
1871
1872
1873PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001874"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001875\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001876Return a bytes object containing values v1, v2, ... packed according\n\
1877to the format string S.format. See help(struct) for more on format\n\
1878strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001879
1880static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001881s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001882{
Dino Viehland4f384af2019-09-10 11:18:37 +01001883 char *buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001884 PyStructObject *soself;
Christian Heimescfeb5432020-11-19 14:36:23 +01001885 _structmodulestate *state = get_struct_state_structinst(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001886
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 /* Validate arguments. */
1888 soself = (PyStructObject *)self;
Christian Heimescfeb5432020-11-19 14:36:23 +01001889 assert(PyStruct_Check(self, state));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001890 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001891 if (nargs != soself->s_len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001892 {
Christian Heimescfeb5432020-11-19 14:36:23 +01001893 PyErr_Format(state->StructError,
Victor Stinner3f2d1012017-02-02 12:09:30 +01001894 "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1895 return NULL;
1896 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001897
Dino Viehland4f384af2019-09-10 11:18:37 +01001898 /* Allocate a new string */
1899 _PyBytesWriter writer;
1900 _PyBytesWriter_Init(&writer);
1901 buf = _PyBytesWriter_Alloc(&writer, soself->s_size);
1902 if (buf == NULL) {
1903 _PyBytesWriter_Dealloc(&writer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001904 return NULL;
1905 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001906
Dino Viehland4f384af2019-09-10 11:18:37 +01001907 /* Call the guts */
Christian Heimescfeb5432020-11-19 14:36:23 +01001908 if ( s_pack_internal(soself, args, 0, buf, state) != 0 ) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001909 _PyBytesWriter_Dealloc(&writer);
1910 return NULL;
1911 }
1912
1913 return _PyBytesWriter_Finish(&writer, buf + soself->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001914}
1915
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001916PyDoc_STRVAR(s_pack_into__doc__,
1917"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001918\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001919Pack the values v1, v2, ... according to the format string S.format\n\
1920and write the packed bytes into the writable buffer buf starting at\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00001921offset. Note that the offset is a required argument. See\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001922help(struct) for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001923
1924static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001925s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001926{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 PyStructObject *soself;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001928 Py_buffer buffer;
1929 Py_ssize_t offset;
Christian Heimescfeb5432020-11-19 14:36:23 +01001930 _structmodulestate *state = get_struct_state_structinst(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001932 /* Validate arguments. +1 is for the first arg as buffer. */
1933 soself = (PyStructObject *)self;
Christian Heimescfeb5432020-11-19 14:36:23 +01001934 assert(PyStruct_Check(self, state));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001935 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001936 if (nargs != (soself->s_len + 2))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001938 if (nargs == 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001939 PyErr_Format(state->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001940 "pack_into expected buffer argument");
1941 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001942 else if (nargs == 1) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001943 PyErr_Format(state->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001944 "pack_into expected offset argument");
1945 }
1946 else {
Christian Heimescfeb5432020-11-19 14:36:23 +01001947 PyErr_Format(state->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001948 "pack_into expected %zd items for packing (got %zd)",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001949 soself->s_len, (nargs - 2));
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001950 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001951 return NULL;
1952 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001953
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001954 /* Extract a writable memory buffer from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001955 if (!PyArg_Parse(args[0], "w*", &buffer))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001956 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001957 assert(buffer.len >= 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 /* Extract the offset from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001960 offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001961 if (offset == -1 && PyErr_Occurred()) {
1962 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001963 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001964 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001966 /* Support negative offsets. */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001967 if (offset < 0) {
1968 /* Check that negative offset is low enough to fit data */
1969 if (offset + soself->s_size > 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001970 PyErr_Format(state->StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001971 "no space to pack %zd bytes at offset %zd",
1972 soself->s_size,
1973 offset);
1974 PyBuffer_Release(&buffer);
1975 return NULL;
1976 }
1977
1978 /* Check that negative offset is not crossing buffer boundary */
1979 if (offset + buffer.len < 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001980 PyErr_Format(state->StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001981 "offset %zd out of range for %zd-byte buffer",
1982 offset,
1983 buffer.len);
1984 PyBuffer_Release(&buffer);
1985 return NULL;
1986 }
1987
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001988 offset += buffer.len;
Andrew Nesterf78b1192017-04-04 13:46:25 +03001989 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001990
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001991 /* Check boundaries */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001992 if ((buffer.len - offset) < soself->s_size) {
Johan Liuaead53b2017-06-02 14:33:04 +08001993 assert(offset >= 0);
1994 assert(soself->s_size >= 0);
1995
Christian Heimescfeb5432020-11-19 14:36:23 +01001996 PyErr_Format(state->StructError,
Johan Liuaead53b2017-06-02 14:33:04 +08001997 "pack_into requires a buffer of at least %zu bytes for "
Andrew Nesterf78b1192017-04-04 13:46:25 +03001998 "packing %zd bytes at offset %zd "
1999 "(actual buffer size is %zd)",
Johan Liuaead53b2017-06-02 14:33:04 +08002000 (size_t)soself->s_size + (size_t)offset,
Andrew Nesterf78b1192017-04-04 13:46:25 +03002001 soself->s_size,
2002 offset,
2003 buffer.len);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002004 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002005 return NULL;
2006 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002007
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002008 /* Call the guts */
Christian Heimescfeb5432020-11-19 14:36:23 +01002009 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset, state) != 0) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002010 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002011 return NULL;
2012 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002013
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002014 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002015 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002016}
2017
2018static PyObject *
2019s_get_format(PyStructObject *self, void *unused)
2020{
Victor Stinnerf87b85f2017-06-23 15:11:12 +02002021 return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
2022 PyBytes_GET_SIZE(self->s_format));
Thomas Wouters477c8d52006-05-27 19:21:47 +00002023}
2024
2025static PyObject *
2026s_get_size(PyStructObject *self, void *unused)
2027{
Christian Heimes217cfd12007-12-02 14:31:20 +00002028 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002029}
2030
Meador Ingeb14d8c92012-07-23 10:01:29 -05002031PyDoc_STRVAR(s_sizeof__doc__,
2032"S.__sizeof__() -> size of S in memory, in bytes");
2033
2034static PyObject *
Meador Inge90bc2dbc2012-07-28 22:16:39 -05002035s_sizeof(PyStructObject *self, void *unused)
Meador Ingeb14d8c92012-07-23 10:01:29 -05002036{
2037 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002038 formatcode *code;
Meador Ingeb14d8c92012-07-23 10:01:29 -05002039
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002040 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002041 for (code = self->s_codes; code->fmtdef != NULL; code++)
2042 size += sizeof(formatcode);
Meador Ingeb14d8c92012-07-23 10:01:29 -05002043 return PyLong_FromSsize_t(size);
2044}
2045
Thomas Wouters477c8d52006-05-27 19:21:47 +00002046/* List of functions */
2047
2048static struct PyMethodDef s_methods[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002049 STRUCT_ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002050 {"pack", (PyCFunction)(void(*)(void))s_pack, METH_FASTCALL, s_pack__doc__},
2051 {"pack_into", (PyCFunction)(void(*)(void))s_pack_into, METH_FASTCALL, s_pack_into__doc__},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002052 STRUCT_UNPACK_METHODDEF
2053 STRUCT_UNPACK_FROM_METHODDEF
Meador Ingeb14d8c92012-07-23 10:01:29 -05002054 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002055 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002056};
2057
Dino Viehland4f384af2019-09-10 11:18:37 +01002058static PyMemberDef s_members[] = {
Eddie Elizondo3368f3c2019-09-19 09:29:05 -07002059 {"__weaklistoffset__", T_PYSSIZET, offsetof(PyStructObject, weakreflist), READONLY},
Dino Viehland4f384af2019-09-10 11:18:37 +01002060 {NULL} /* sentinel */
2061};
2062
Thomas Wouters477c8d52006-05-27 19:21:47 +00002063#define OFF(x) offsetof(PyStructObject, x)
2064
2065static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002066 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
2067 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
2068 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002069};
2070
Dino Viehland4f384af2019-09-10 11:18:37 +01002071PyDoc_STRVAR(s__doc__,
2072"Struct(fmt) --> compiled struct object\n"
2073"\n"
2074);
2075
2076static PyType_Slot PyStructType_slots[] = {
2077 {Py_tp_dealloc, s_dealloc},
2078 {Py_tp_getattro, PyObject_GenericGetAttr},
2079 {Py_tp_setattro, PyObject_GenericSetAttr},
2080 {Py_tp_doc, (void*)s__doc__},
2081 {Py_tp_methods, s_methods},
2082 {Py_tp_members, s_members},
2083 {Py_tp_getset, s_getsetlist},
2084 {Py_tp_init, Struct___init__},
2085 {Py_tp_alloc, PyType_GenericAlloc},
2086 {Py_tp_new, s_new},
2087 {Py_tp_free, PyObject_Del},
2088 {0, 0},
2089};
2090
2091static PyType_Spec PyStructType_spec = {
2092 "_struct.Struct",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002093 sizeof(PyStructObject),
2094 0,
Dino Viehland4f384af2019-09-10 11:18:37 +01002095 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
2096 PyStructType_slots
Thomas Wouters477c8d52006-05-27 19:21:47 +00002097};
2098
Christian Heimesa34706f2008-01-04 03:06:10 +00002099
2100/* ---- Standalone functions ---- */
2101
2102#define MAXCACHE 100
Christian Heimesa34706f2008-01-04 03:06:10 +00002103
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002104static int
Christian Heimescfeb5432020-11-19 14:36:23 +01002105cache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr)
Christian Heimesa34706f2008-01-04 03:06:10 +00002106{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002107 PyObject * s_object;
Christian Heimescfeb5432020-11-19 14:36:23 +01002108 _structmodulestate *state = get_struct_state(module);
Christian Heimesa34706f2008-01-04 03:06:10 +00002109
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002110 if (fmt == NULL) {
2111 Py_DECREF(*ptr);
Serhiy Storchaka40db90c2017-04-20 21:19:31 +03002112 *ptr = NULL;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002113 return 1;
2114 }
2115
Christian Heimescfeb5432020-11-19 14:36:23 +01002116 if (state->cache == NULL) {
2117 state->cache = PyDict_New();
2118 if (state->cache == NULL)
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002119 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002120 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002121
Christian Heimescfeb5432020-11-19 14:36:23 +01002122 s_object = PyDict_GetItemWithError(state->cache, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 if (s_object != NULL) {
2124 Py_INCREF(s_object);
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002125 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002126 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002127 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002128 else if (PyErr_Occurred()) {
2129 return 0;
2130 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002131
Christian Heimescfeb5432020-11-19 14:36:23 +01002132 s_object = PyObject_CallOneArg(state->PyStructType, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002133 if (s_object != NULL) {
Christian Heimescfeb5432020-11-19 14:36:23 +01002134 if (PyDict_GET_SIZE(state->cache) >= MAXCACHE)
2135 PyDict_Clear(state->cache);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002136 /* Attempt to cache the result */
Christian Heimescfeb5432020-11-19 14:36:23 +01002137 if (PyDict_SetItem(state->cache, fmt, s_object) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002138 PyErr_Clear();
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002139 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002140 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002141 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002142 return 0;
Christian Heimesa34706f2008-01-04 03:06:10 +00002143}
2144
Victor Stinner3f2d1012017-02-02 12:09:30 +01002145/*[clinic input]
2146_clearcache
2147
2148Clear the internal cache.
2149[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002150
2151static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002152_clearcache_impl(PyObject *module)
2153/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002154{
Christian Heimescfeb5432020-11-19 14:36:23 +01002155 Py_CLEAR(get_struct_state(module)->cache);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002156 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00002157}
2158
Victor Stinner3f2d1012017-02-02 12:09:30 +01002159
2160/*[clinic input]
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002161calcsize -> Py_ssize_t
Victor Stinner3f2d1012017-02-02 12:09:30 +01002162
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002163 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002164 /
2165
2166Return size in bytes of the struct described by the format string.
2167[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002168
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002169static Py_ssize_t
2170calcsize_impl(PyObject *module, PyStructObject *s_object)
2171/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002172{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002173 return s_object->s_size;
Christian Heimesa34706f2008-01-04 03:06:10 +00002174}
2175
2176PyDoc_STRVAR(pack_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002177"pack(format, v1, v2, ...) -> bytes\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002178\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002179Return a bytes object containing the values v1, v2, ... packed according\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002180to the format string. See help(struct) for more on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002181
2182static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01002183pack(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002184{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002185 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002186 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002187
Victor Stinner3f2d1012017-02-02 12:09:30 +01002188 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 PyErr_SetString(PyExc_TypeError, "missing format argument");
2190 return NULL;
2191 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002192 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002193
Christian Heimescfeb5432020-11-19 14:36:23 +01002194 if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002195 return NULL;
2196 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002197 result = s_pack(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002198 Py_DECREF(s_object);
2199 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002200}
2201
2202PyDoc_STRVAR(pack_into_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002203"pack_into(format, buffer, offset, v1, v2, ...)\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002204\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002205Pack the values v1, v2, ... according to the format string and write\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002206the packed bytes into the writable buffer buf starting at offset. Note\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002207that the offset is a required argument. See help(struct) for more\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002208on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002209
2210static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01002211pack_into(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002212{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002213 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002214 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002215
Victor Stinner3f2d1012017-02-02 12:09:30 +01002216 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002217 PyErr_SetString(PyExc_TypeError, "missing format argument");
2218 return NULL;
2219 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002220 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002221
Christian Heimescfeb5432020-11-19 14:36:23 +01002222 if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002223 return NULL;
2224 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002225 result = s_pack_into(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002226 Py_DECREF(s_object);
2227 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002228}
2229
Victor Stinner3f2d1012017-02-02 12:09:30 +01002230/*[clinic input]
2231unpack
2232
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002233 format as s_object: cache_struct
Victor Stinnerc0f59ad2017-02-02 14:24:16 +01002234 buffer: Py_buffer
Victor Stinner3f2d1012017-02-02 12:09:30 +01002235 /
2236
2237Return a tuple containing values unpacked according to the format string.
2238
2239The buffer's size in bytes must be calcsize(format).
2240
2241See help(struct) for more on format strings.
2242[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002243
2244static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002245unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2246/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002247{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002248 return Struct_unpack_impl(s_object, buffer);
Christian Heimesa34706f2008-01-04 03:06:10 +00002249}
2250
Victor Stinner3f2d1012017-02-02 12:09:30 +01002251/*[clinic input]
2252unpack_from
2253
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002254 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002255 /
2256 buffer: Py_buffer
2257 offset: Py_ssize_t = 0
2258
2259Return a tuple containing values unpacked according to the format string.
2260
2261The buffer's size, minus offset, must be at least calcsize(format).
2262
2263See help(struct) for more on format strings.
2264[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002265
2266static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002267unpack_from_impl(PyObject *module, PyStructObject *s_object,
2268 Py_buffer *buffer, Py_ssize_t offset)
2269/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002270{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002271 return Struct_unpack_from_impl(s_object, buffer, offset);
Christian Heimesa34706f2008-01-04 03:06:10 +00002272}
2273
Victor Stinner3f2d1012017-02-02 12:09:30 +01002274/*[clinic input]
2275iter_unpack
2276
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002277 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002278 buffer: object
2279 /
2280
2281Return an iterator yielding tuples unpacked from the given bytes.
2282
2283The bytes are unpacked according to the format string, like
2284a repeated invocation of unpack_from().
2285
2286Requires that the bytes length be a multiple of the format struct size.
2287[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002288
2289static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002290iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2291 PyObject *buffer)
2292/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002293{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002294 return Struct_iter_unpack(s_object, buffer);
Antoine Pitrou9f146812013-04-27 00:20:04 +02002295}
2296
Christian Heimesa34706f2008-01-04 03:06:10 +00002297static struct PyMethodDef module_functions[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002298 _CLEARCACHE_METHODDEF
2299 CALCSIZE_METHODDEF
2300 ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002301 {"pack", (PyCFunction)(void(*)(void))pack, METH_FASTCALL, pack_doc},
2302 {"pack_into", (PyCFunction)(void(*)(void))pack_into, METH_FASTCALL, pack_into_doc},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002303 UNPACK_METHODDEF
2304 UNPACK_FROM_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002305 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00002306};
2307
2308
Thomas Wouters477c8d52006-05-27 19:21:47 +00002309/* Module initialization */
2310
Christian Heimesa34706f2008-01-04 03:06:10 +00002311PyDoc_STRVAR(module_doc,
2312"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002313Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002314and also as format strings (explained below) to describe the layout of data\n\
2315in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002316\n\
2317The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002318 @: native order, size & alignment (default)\n\
2319 =: native order, std. size & alignment\n\
2320 <: little-endian, std. size & alignment\n\
2321 >: big-endian, std. size & alignment\n\
2322 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002323\n\
2324The remaining chars indicate types of args and must match exactly;\n\
2325these can be preceded by a decimal repeat count:\n\
2326 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002327 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002328 h:short; H:unsigned short; i:int; I:unsigned int;\n\
Mark Dickinson7c4e4092016-09-03 17:21:29 +01002329 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002330Special cases (preceding decimal count indicates length):\n\
2331 s:string (array of char); p: pascal string (with count byte).\n\
Antoine Pitrou45d9c912011-10-06 15:27:40 +02002332Special cases (only available in native format):\n\
2333 n:ssize_t; N:size_t;\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002334 P:an integer type that is wide enough to hold a pointer.\n\
2335Special case (not in native mode unless 'long long' in platform C):\n\
2336 q:long long; Q:unsigned long long\n\
2337Whitespace between formats is ignored.\n\
2338\n\
2339The variable struct.error is an exception raised on errors.\n");
2340
Martin v. Löwis1a214512008-06-11 05:26:20 +00002341
Dino Viehland4f384af2019-09-10 11:18:37 +01002342static int
2343_structmodule_traverse(PyObject *module, visitproc visit, void *arg)
2344{
Christian Heimescfeb5432020-11-19 14:36:23 +01002345 _structmodulestate *state = get_struct_state(module);
Hai Shif707d942020-03-16 21:15:01 +08002346 if (state) {
Christian Heimescfeb5432020-11-19 14:36:23 +01002347 Py_VISIT(state->cache);
Hai Shif707d942020-03-16 21:15:01 +08002348 Py_VISIT(state->PyStructType);
2349 Py_VISIT(state->unpackiter_type);
2350 Py_VISIT(state->StructError);
2351 }
Dino Viehland4f384af2019-09-10 11:18:37 +01002352 return 0;
2353}
2354
2355static int
2356_structmodule_clear(PyObject *module)
2357{
Christian Heimescfeb5432020-11-19 14:36:23 +01002358 _structmodulestate *state = get_struct_state(module);
Hai Shif707d942020-03-16 21:15:01 +08002359 if (state) {
Christian Heimescfeb5432020-11-19 14:36:23 +01002360 Py_CLEAR(state->cache);
Hai Shif707d942020-03-16 21:15:01 +08002361 Py_CLEAR(state->PyStructType);
2362 Py_CLEAR(state->unpackiter_type);
2363 Py_CLEAR(state->StructError);
2364 }
Dino Viehland4f384af2019-09-10 11:18:37 +01002365 return 0;
2366}
2367
2368static void
2369_structmodule_free(void *module)
2370{
2371 _structmodule_clear((PyObject *)module);
2372}
2373
Christian Heimescfeb5432020-11-19 14:36:23 +01002374static int
2375_structmodule_exec(PyObject *m)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002376{
Christian Heimescfeb5432020-11-19 14:36:23 +01002377 _structmodulestate *state = get_struct_state(m);
Christian Heimesa34706f2008-01-04 03:06:10 +00002378
Christian Heimescfeb5432020-11-19 14:36:23 +01002379 state->PyStructType = PyType_FromModuleAndSpec(
2380 m, &PyStructType_spec, NULL);
2381 if (state->PyStructType == NULL) {
2382 return -1;
Dino Viehland4f384af2019-09-10 11:18:37 +01002383 }
Christian Heimescfeb5432020-11-19 14:36:23 +01002384 if (PyModule_AddType(m, (PyTypeObject *)state->PyStructType) < 0) {
2385 return -1;
Dino Viehland4f384af2019-09-10 11:18:37 +01002386 }
Christian Heimescfeb5432020-11-19 14:36:23 +01002387
2388 state->unpackiter_type = PyType_FromModuleAndSpec(
2389 m, &unpackiter_type_spec, NULL);
2390 if (state->unpackiter_type == NULL) {
2391 return -1;
2392 }
Zachary Ware99f11b42016-10-04 01:20:21 -05002393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002394 /* Check endian and swap in faster functions */
2395 {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002396 const formatdef *native = native_table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002397 formatdef *other, *ptr;
Christian Heimes743e0cd2012-10-17 23:52:17 +02002398#if PY_LITTLE_ENDIAN
2399 other = lilendian_table;
2400#else
2401 other = bigendian_table;
2402#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002403 /* Scan through the native table, find a matching
2404 entry in the endian table and swap in the
2405 native implementations whenever possible
2406 (64-bit platforms may not have "standard" sizes) */
2407 while (native->format != '\0' && other->format != '\0') {
2408 ptr = other;
2409 while (ptr->format != '\0') {
2410 if (ptr->format == native->format) {
2411 /* Match faster when formats are
2412 listed in the same order */
2413 if (ptr == other)
2414 other++;
2415 /* Only use the trick if the
2416 size matches */
2417 if (ptr->size != native->size)
2418 break;
2419 /* Skip float and double, could be
2420 "unknown" float format */
2421 if (ptr->format == 'd' || ptr->format == 'f')
2422 break;
Stefan Krah472fc842020-03-24 14:01:13 +01002423 /* Skip _Bool, semantics are different for standard size */
2424 if (ptr->format == '?')
2425 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002426 ptr->pack = native->pack;
2427 ptr->unpack = native->unpack;
2428 break;
2429 }
2430 ptr++;
2431 }
2432 native++;
2433 }
2434 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002435
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002436 /* Add some symbolic constants to the module */
Christian Heimescfeb5432020-11-19 14:36:23 +01002437 state->StructError = PyErr_NewException("struct.error", NULL, NULL);
2438 if (state->StructError == NULL) {
2439 return -1;
2440 }
2441 if (PyModule_AddObjectRef(m, "error", state->StructError) < 0) {
2442 return -1;
2443 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002444
Christian Heimescfeb5432020-11-19 14:36:23 +01002445 return 0;
2446}
2447
2448static PyModuleDef_Slot _structmodule_slots[] = {
2449 {Py_mod_exec, _structmodule_exec},
2450 {0, NULL}
2451};
2452
2453static struct PyModuleDef _structmodule = {
2454 PyModuleDef_HEAD_INIT,
2455 .m_name = "_struct",
2456 .m_doc = module_doc,
2457 .m_size = sizeof(_structmodulestate),
2458 .m_methods = module_functions,
2459 .m_slots = _structmodule_slots,
2460 .m_traverse = _structmodule_traverse,
2461 .m_clear = _structmodule_clear,
2462 .m_free = _structmodule_free,
2463};
2464
2465PyMODINIT_FUNC
2466PyInit__struct(void)
2467{
2468 return PyModuleDef_Init(&_structmodule);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002469}