blob: eeccc17965468c8bd5a8e907880e407457ac0e68 [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;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001376 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)
1383 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;
1445 Py_INCREF(Py_None);
1446 s->s_format = Py_None;
1447 s->s_codes = NULL;
1448 s->s_size = -1;
1449 s->s_len = -1;
1450 }
1451 return self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001452}
1453
Victor Stinner3f2d1012017-02-02 12:09:30 +01001454/*[clinic input]
1455Struct.__init__
1456
1457 format: object
1458
1459Create a compiled struct object.
1460
1461Return a new Struct object which writes and reads binary data according to
1462the format string.
1463
1464See help(struct) for more on format strings.
1465[clinic start generated code]*/
1466
Thomas Wouters477c8d52006-05-27 19:21:47 +00001467static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001468Struct___init___impl(PyStructObject *self, PyObject *format)
1469/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 int ret = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001472
Victor Stinner3f2d1012017-02-02 12:09:30 +01001473 if (PyUnicode_Check(format)) {
1474 format = PyUnicode_AsASCIIString(format);
1475 if (format == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 return -1;
1477 }
1478 /* XXX support buffer interface, too */
1479 else {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001480 Py_INCREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001482
Victor Stinner3f2d1012017-02-02 12:09:30 +01001483 if (!PyBytes_Check(format)) {
1484 Py_DECREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 PyErr_Format(PyExc_TypeError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001486 "Struct() argument 1 must be a str or bytes object, "
1487 "not %.200s",
Dino Viehland4f384af2019-09-10 11:18:37 +01001488 _PyType_Name(Py_TYPE(format)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 return -1;
1490 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001491
Xiang Zhang96f50282017-05-15 11:53:51 +08001492 Py_SETREF(self->s_format, format);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001493
Victor Stinner3f2d1012017-02-02 12:09:30 +01001494 ret = prepare_s(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001495 return ret;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001496}
1497
1498static void
1499s_dealloc(PyStructObject *s)
1500{
Dino Viehland4f384af2019-09-10 11:18:37 +01001501 PyTypeObject *tp = Py_TYPE(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001502 if (s->weakreflist != NULL)
1503 PyObject_ClearWeakRefs((PyObject *)s);
1504 if (s->s_codes != NULL) {
1505 PyMem_FREE(s->s_codes);
1506 }
Dino Viehland4f384af2019-09-10 11:18:37 +01001507 Py_XDECREF(s->s_format);
1508 freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free);
1509 free_func(s);
1510 Py_DECREF(tp);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001511}
1512
1513static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01001514s_unpack_internal(PyStructObject *soself, const char *startfrom,
1515 _structmodulestate *state) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001516 formatcode *code;
1517 Py_ssize_t i = 0;
1518 PyObject *result = PyTuple_New(soself->s_len);
1519 if (result == NULL)
1520 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001521
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001522 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 const formatdef *e = code->fmtdef;
1524 const char *res = startfrom + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001525 Py_ssize_t j = code->repeat;
1526 while (j--) {
1527 PyObject *v;
1528 if (e->format == 's') {
1529 v = PyBytes_FromStringAndSize(res, code->size);
1530 } else if (e->format == 'p') {
1531 Py_ssize_t n = *(unsigned char*)res;
1532 if (n >= code->size)
1533 n = code->size - 1;
1534 v = PyBytes_FromStringAndSize(res + 1, n);
1535 } else {
Christian Heimescfeb5432020-11-19 14:36:23 +01001536 v = e->unpack(state, res, e);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001537 }
1538 if (v == NULL)
1539 goto fail;
1540 PyTuple_SET_ITEM(result, i++, v);
1541 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001542 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001543 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001546fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001547 Py_DECREF(result);
1548 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001549}
1550
1551
Victor Stinner3f2d1012017-02-02 12:09:30 +01001552/*[clinic input]
1553Struct.unpack
1554
1555 buffer: Py_buffer
1556 /
1557
1558Return a tuple containing unpacked values.
1559
1560Unpack according to the format string Struct.format. The buffer's size
1561in bytes must be Struct.size.
1562
1563See help(struct) for more on format strings.
1564[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001565
1566static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001567Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1568/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001569{
Christian Heimescfeb5432020-11-19 14:36:23 +01001570 _structmodulestate *state = get_struct_state_structinst(self);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001571 assert(self->s_codes != NULL);
1572 if (buffer->len != self->s_size) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001573 PyErr_Format(state->StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001574 "unpack requires a buffer of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001575 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001576 return NULL;
1577 }
Christian Heimescfeb5432020-11-19 14:36:23 +01001578 return s_unpack_internal(self, buffer->buf, state);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001579}
1580
Victor Stinner3f2d1012017-02-02 12:09:30 +01001581/*[clinic input]
1582Struct.unpack_from
1583
1584 buffer: Py_buffer
1585 offset: Py_ssize_t = 0
1586
1587Return a tuple containing unpacked values.
1588
1589Values are unpacked according to the format string Struct.format.
1590
Xiang Zhangc10b2882018-03-11 02:58:52 +08001591The buffer's size in bytes, starting at position offset, must be
1592at least Struct.size.
Victor Stinner3f2d1012017-02-02 12:09:30 +01001593
1594See help(struct) for more on format strings.
1595[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001596
1597static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001598Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1599 Py_ssize_t offset)
Xiang Zhangc10b2882018-03-11 02:58:52 +08001600/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001601{
Christian Heimescfeb5432020-11-19 14:36:23 +01001602 _structmodulestate *state = get_struct_state_structinst(self);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001603 assert(self->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001604
Xiang Zhangc10b2882018-03-11 02:58:52 +08001605 if (offset < 0) {
1606 if (offset + self->s_size > 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001607 PyErr_Format(state->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001608 "not enough data to unpack %zd bytes at offset %zd",
1609 self->s_size,
1610 offset);
1611 return NULL;
1612 }
1613
1614 if (offset + buffer->len < 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001615 PyErr_Format(state->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001616 "offset %zd out of range for %zd-byte buffer",
1617 offset,
1618 buffer->len);
1619 return NULL;
1620 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001621 offset += buffer->len;
Xiang Zhangc10b2882018-03-11 02:58:52 +08001622 }
1623
1624 if ((buffer->len - offset) < self->s_size) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001625 PyErr_Format(state->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001626 "unpack_from requires a buffer of at least %zu bytes for "
1627 "unpacking %zd bytes at offset %zd "
1628 "(actual buffer size is %zd)",
1629 (size_t)self->s_size + (size_t)offset,
1630 self->s_size,
1631 offset,
1632 buffer->len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 return NULL;
1634 }
Christian Heimescfeb5432020-11-19 14:36:23 +01001635 return s_unpack_internal(self, (char*)buffer->buf + offset, state);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001636}
1637
1638
Victor Stinner3f2d1012017-02-02 12:09:30 +01001639
Antoine Pitrou9f146812013-04-27 00:20:04 +02001640/* Unpack iterator type */
1641
1642typedef struct {
1643 PyObject_HEAD
1644 PyStructObject *so;
1645 Py_buffer buf;
1646 Py_ssize_t index;
1647} unpackiterobject;
1648
1649static void
1650unpackiter_dealloc(unpackiterobject *self)
1651{
INADA Naokia6296d32017-08-24 14:55:17 +09001652 /* bpo-31095: UnTrack is needed before calling any callbacks */
Dino Viehland4f384af2019-09-10 11:18:37 +01001653 PyTypeObject *tp = Py_TYPE(self);
INADA Naokia6296d32017-08-24 14:55:17 +09001654 PyObject_GC_UnTrack(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001655 Py_XDECREF(self->so);
1656 PyBuffer_Release(&self->buf);
1657 PyObject_GC_Del(self);
Dino Viehland4f384af2019-09-10 11:18:37 +01001658 Py_DECREF(tp);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001659}
1660
1661static int
1662unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1663{
Pablo Galindo1cf15af2020-05-27 10:03:38 +01001664 Py_VISIT(Py_TYPE(self));
Antoine Pitrou9f146812013-04-27 00:20:04 +02001665 Py_VISIT(self->so);
1666 Py_VISIT(self->buf.obj);
1667 return 0;
1668}
1669
1670static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301671unpackiter_len(unpackiterobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou9f146812013-04-27 00:20:04 +02001672{
1673 Py_ssize_t len;
1674 if (self->so == NULL)
1675 len = 0;
1676 else
1677 len = (self->buf.len - self->index) / self->so->s_size;
1678 return PyLong_FromSsize_t(len);
1679}
1680
1681static PyMethodDef unpackiter_methods[] = {
1682 {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1683 {NULL, NULL} /* sentinel */
1684};
1685
1686static PyObject *
1687unpackiter_iternext(unpackiterobject *self)
1688{
Christian Heimescfeb5432020-11-19 14:36:23 +01001689 _structmodulestate *state = get_struct_state_iterinst(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001690 PyObject *result;
1691 if (self->so == NULL)
1692 return NULL;
1693 if (self->index >= self->buf.len) {
1694 /* Iterator exhausted */
1695 Py_CLEAR(self->so);
1696 PyBuffer_Release(&self->buf);
1697 return NULL;
1698 }
1699 assert(self->index + self->so->s_size <= self->buf.len);
1700 result = s_unpack_internal(self->so,
Christian Heimescfeb5432020-11-19 14:36:23 +01001701 (char*) self->buf.buf + self->index,
1702 state);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001703 self->index += self->so->s_size;
1704 return result;
1705}
1706
Dino Viehland4f384af2019-09-10 11:18:37 +01001707PyObject *unpackiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1708 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s objects", _PyType_Name(type));
1709 return NULL;
1710}
1711
1712static PyType_Slot unpackiter_type_slots[] = {
1713 {Py_tp_dealloc, unpackiter_dealloc},
1714 {Py_tp_getattro, PyObject_GenericGetAttr},
1715 {Py_tp_traverse, unpackiter_traverse},
1716 {Py_tp_iter, PyObject_SelfIter},
1717 {Py_tp_iternext, unpackiter_iternext},
1718 {Py_tp_methods, unpackiter_methods},
1719 {Py_tp_new, unpackiter_new},
1720 {0, 0},
1721};
1722
1723static PyType_Spec unpackiter_type_spec = {
1724 "_struct.unpack_iterator",
1725 sizeof(unpackiterobject),
1726 0,
1727 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1728 unpackiter_type_slots
Antoine Pitrou9f146812013-04-27 00:20:04 +02001729};
1730
Victor Stinner3f2d1012017-02-02 12:09:30 +01001731/*[clinic input]
1732Struct.iter_unpack
1733
1734 buffer: object
1735 /
1736
1737Return an iterator yielding tuples.
1738
1739Tuples are unpacked from the given bytes source, like a repeated
1740invocation of unpack_from().
1741
1742Requires that the bytes length be a multiple of the struct size.
1743[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001744
1745static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001746Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1747/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001748{
Christian Heimescfeb5432020-11-19 14:36:23 +01001749 _structmodulestate *state = get_struct_state_structinst(self);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001750 unpackiterobject *iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001751
Victor Stinner3f2d1012017-02-02 12:09:30 +01001752 assert(self->s_codes != NULL);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001753
Victor Stinner3f2d1012017-02-02 12:09:30 +01001754 if (self->s_size == 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001755 PyErr_Format(state->StructError,
Antoine Pitrou9f146812013-04-27 00:20:04 +02001756 "cannot iteratively unpack with a struct of length 0");
1757 return NULL;
1758 }
1759
Christian Heimescfeb5432020-11-19 14:36:23 +01001760 iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)state->unpackiter_type, 0);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001761 if (iter == NULL)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001762 return NULL;
1763
Victor Stinner3f2d1012017-02-02 12:09:30 +01001764 if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1765 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001766 return NULL;
1767 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001768 if (iter->buf.len % self->s_size != 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001769 PyErr_Format(state->StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001770 "iterative unpacking requires a buffer of "
1771 "a multiple of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001772 self->s_size);
1773 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001774 return NULL;
1775 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001776 Py_INCREF(self);
1777 iter->so = self;
1778 iter->index = 0;
1779 return (PyObject *)iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001780}
1781
1782
Thomas Wouters477c8d52006-05-27 19:21:47 +00001783/*
1784 * Guts of the pack function.
1785 *
1786 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1787 * argument for where to start processing the arguments for packing, and a
1788 * character buffer for writing the packed string. The caller must insure
1789 * that the buffer may contain the required length for packing the arguments.
1790 * 0 is returned on success, 1 is returned if there is an error.
1791 *
1792 */
1793static int
Christian Heimescfeb5432020-11-19 14:36:23 +01001794s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset,
1795 char* buf, _structmodulestate *state)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001796{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001797 formatcode *code;
1798 /* XXX(nnorwitz): why does i need to be a local? can we use
1799 the offset parameter or do we need the wider width? */
1800 Py_ssize_t i;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001801
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001802 memset(buf, '\0', soself->s_size);
1803 i = offset;
1804 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001805 const formatdef *e = code->fmtdef;
1806 char *res = buf + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001807 Py_ssize_t j = code->repeat;
1808 while (j--) {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001809 PyObject *v = args[i++];
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001810 if (e->format == 's') {
1811 Py_ssize_t n;
1812 int isstring;
Serhiy Storchaka8f87eef2020-04-12 14:58:27 +03001813 const void *p;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001814 isstring = PyBytes_Check(v);
1815 if (!isstring && !PyByteArray_Check(v)) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001816 PyErr_SetString(state->StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001817 "argument for 's' must be a bytes object");
1818 return -1;
1819 }
1820 if (isstring) {
1821 n = PyBytes_GET_SIZE(v);
1822 p = PyBytes_AS_STRING(v);
1823 }
1824 else {
1825 n = PyByteArray_GET_SIZE(v);
1826 p = PyByteArray_AS_STRING(v);
1827 }
1828 if (n > code->size)
1829 n = code->size;
1830 if (n > 0)
1831 memcpy(res, p, n);
1832 } else if (e->format == 'p') {
1833 Py_ssize_t n;
1834 int isstring;
Serhiy Storchaka8f87eef2020-04-12 14:58:27 +03001835 const void *p;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001836 isstring = PyBytes_Check(v);
1837 if (!isstring && !PyByteArray_Check(v)) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001838 PyErr_SetString(state->StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001839 "argument for 'p' must be a bytes object");
1840 return -1;
1841 }
1842 if (isstring) {
1843 n = PyBytes_GET_SIZE(v);
1844 p = PyBytes_AS_STRING(v);
1845 }
1846 else {
1847 n = PyByteArray_GET_SIZE(v);
1848 p = PyByteArray_AS_STRING(v);
1849 }
1850 if (n > (code->size - 1))
1851 n = code->size - 1;
1852 if (n > 0)
1853 memcpy(res + 1, p, n);
1854 if (n > 255)
1855 n = 255;
1856 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1857 } else {
Christian Heimescfeb5432020-11-19 14:36:23 +01001858 if (e->pack(state, res, v, e) < 0) {
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001859 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
Christian Heimescfeb5432020-11-19 14:36:23 +01001860 PyErr_SetString(state->StructError,
Serhiy Storchaka46e1ce22013-08-27 20:17:03 +03001861 "int too large to convert");
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001862 return -1;
1863 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001864 }
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001865 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001866 }
1867 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001868
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001869 /* Success */
1870 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001871}
1872
1873
1874PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001875"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001876\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001877Return a bytes object containing values v1, v2, ... packed according\n\
1878to the format string S.format. See help(struct) for more on format\n\
1879strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001880
1881static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001882s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001883{
Dino Viehland4f384af2019-09-10 11:18:37 +01001884 char *buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001885 PyStructObject *soself;
Christian Heimescfeb5432020-11-19 14:36:23 +01001886 _structmodulestate *state = get_struct_state_structinst(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001887
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001888 /* Validate arguments. */
1889 soself = (PyStructObject *)self;
Christian Heimescfeb5432020-11-19 14:36:23 +01001890 assert(PyStruct_Check(self, state));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001892 if (nargs != soself->s_len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001893 {
Christian Heimescfeb5432020-11-19 14:36:23 +01001894 PyErr_Format(state->StructError,
Victor Stinner3f2d1012017-02-02 12:09:30 +01001895 "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1896 return NULL;
1897 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001898
Dino Viehland4f384af2019-09-10 11:18:37 +01001899 /* Allocate a new string */
1900 _PyBytesWriter writer;
1901 _PyBytesWriter_Init(&writer);
1902 buf = _PyBytesWriter_Alloc(&writer, soself->s_size);
1903 if (buf == NULL) {
1904 _PyBytesWriter_Dealloc(&writer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 return NULL;
1906 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001907
Dino Viehland4f384af2019-09-10 11:18:37 +01001908 /* Call the guts */
Christian Heimescfeb5432020-11-19 14:36:23 +01001909 if ( s_pack_internal(soself, args, 0, buf, state) != 0 ) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001910 _PyBytesWriter_Dealloc(&writer);
1911 return NULL;
1912 }
1913
1914 return _PyBytesWriter_Finish(&writer, buf + soself->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001915}
1916
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001917PyDoc_STRVAR(s_pack_into__doc__,
1918"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001919\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001920Pack the values v1, v2, ... according to the format string S.format\n\
1921and write the packed bytes into the writable buffer buf starting at\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00001922offset. Note that the offset is a required argument. See\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001923help(struct) for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001924
1925static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001926s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001927{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 PyStructObject *soself;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001929 Py_buffer buffer;
1930 Py_ssize_t offset;
Christian Heimescfeb5432020-11-19 14:36:23 +01001931 _structmodulestate *state = get_struct_state_structinst(self);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 /* Validate arguments. +1 is for the first arg as buffer. */
1934 soself = (PyStructObject *)self;
Christian Heimescfeb5432020-11-19 14:36:23 +01001935 assert(PyStruct_Check(self, state));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001936 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001937 if (nargs != (soself->s_len + 2))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001938 {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001939 if (nargs == 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001940 PyErr_Format(state->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001941 "pack_into expected buffer argument");
1942 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001943 else if (nargs == 1) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001944 PyErr_Format(state->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001945 "pack_into expected offset argument");
1946 }
1947 else {
Christian Heimescfeb5432020-11-19 14:36:23 +01001948 PyErr_Format(state->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001949 "pack_into expected %zd items for packing (got %zd)",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001950 soself->s_len, (nargs - 2));
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001951 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001952 return NULL;
1953 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 /* Extract a writable memory buffer from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001956 if (!PyArg_Parse(args[0], "w*", &buffer))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001957 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001958 assert(buffer.len >= 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001960 /* Extract the offset from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001961 offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001962 if (offset == -1 && PyErr_Occurred()) {
1963 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001965 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 /* Support negative offsets. */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001968 if (offset < 0) {
1969 /* Check that negative offset is low enough to fit data */
1970 if (offset + soself->s_size > 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001971 PyErr_Format(state->StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001972 "no space to pack %zd bytes at offset %zd",
1973 soself->s_size,
1974 offset);
1975 PyBuffer_Release(&buffer);
1976 return NULL;
1977 }
1978
1979 /* Check that negative offset is not crossing buffer boundary */
1980 if (offset + buffer.len < 0) {
Christian Heimescfeb5432020-11-19 14:36:23 +01001981 PyErr_Format(state->StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001982 "offset %zd out of range for %zd-byte buffer",
1983 offset,
1984 buffer.len);
1985 PyBuffer_Release(&buffer);
1986 return NULL;
1987 }
1988
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001989 offset += buffer.len;
Andrew Nesterf78b1192017-04-04 13:46:25 +03001990 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001991
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001992 /* Check boundaries */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001993 if ((buffer.len - offset) < soself->s_size) {
Johan Liuaead53b2017-06-02 14:33:04 +08001994 assert(offset >= 0);
1995 assert(soself->s_size >= 0);
1996
Christian Heimescfeb5432020-11-19 14:36:23 +01001997 PyErr_Format(state->StructError,
Johan Liuaead53b2017-06-02 14:33:04 +08001998 "pack_into requires a buffer of at least %zu bytes for "
Andrew Nesterf78b1192017-04-04 13:46:25 +03001999 "packing %zd bytes at offset %zd "
2000 "(actual buffer size is %zd)",
Johan Liuaead53b2017-06-02 14:33:04 +08002001 (size_t)soself->s_size + (size_t)offset,
Andrew Nesterf78b1192017-04-04 13:46:25 +03002002 soself->s_size,
2003 offset,
2004 buffer.len);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002005 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002006 return NULL;
2007 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002008
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002009 /* Call the guts */
Christian Heimescfeb5432020-11-19 14:36:23 +01002010 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset, state) != 0) {
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002011 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002012 return NULL;
2013 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002014
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02002015 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002016 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002017}
2018
2019static PyObject *
2020s_get_format(PyStructObject *self, void *unused)
2021{
Victor Stinnerf87b85f2017-06-23 15:11:12 +02002022 return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
2023 PyBytes_GET_SIZE(self->s_format));
Thomas Wouters477c8d52006-05-27 19:21:47 +00002024}
2025
2026static PyObject *
2027s_get_size(PyStructObject *self, void *unused)
2028{
Christian Heimes217cfd12007-12-02 14:31:20 +00002029 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002030}
2031
Meador Ingeb14d8c92012-07-23 10:01:29 -05002032PyDoc_STRVAR(s_sizeof__doc__,
2033"S.__sizeof__() -> size of S in memory, in bytes");
2034
2035static PyObject *
Meador Inge90bc2dbc2012-07-28 22:16:39 -05002036s_sizeof(PyStructObject *self, void *unused)
Meador Ingeb14d8c92012-07-23 10:01:29 -05002037{
2038 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002039 formatcode *code;
Meador Ingeb14d8c92012-07-23 10:01:29 -05002040
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002041 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002042 for (code = self->s_codes; code->fmtdef != NULL; code++)
2043 size += sizeof(formatcode);
Meador Ingeb14d8c92012-07-23 10:01:29 -05002044 return PyLong_FromSsize_t(size);
2045}
2046
Thomas Wouters477c8d52006-05-27 19:21:47 +00002047/* List of functions */
2048
2049static struct PyMethodDef s_methods[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002050 STRUCT_ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002051 {"pack", (PyCFunction)(void(*)(void))s_pack, METH_FASTCALL, s_pack__doc__},
2052 {"pack_into", (PyCFunction)(void(*)(void))s_pack_into, METH_FASTCALL, s_pack_into__doc__},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002053 STRUCT_UNPACK_METHODDEF
2054 STRUCT_UNPACK_FROM_METHODDEF
Meador Ingeb14d8c92012-07-23 10:01:29 -05002055 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002056 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002057};
2058
Dino Viehland4f384af2019-09-10 11:18:37 +01002059static PyMemberDef s_members[] = {
Eddie Elizondo3368f3c2019-09-19 09:29:05 -07002060 {"__weaklistoffset__", T_PYSSIZET, offsetof(PyStructObject, weakreflist), READONLY},
Dino Viehland4f384af2019-09-10 11:18:37 +01002061 {NULL} /* sentinel */
2062};
2063
Thomas Wouters477c8d52006-05-27 19:21:47 +00002064#define OFF(x) offsetof(PyStructObject, x)
2065
2066static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
2068 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
2069 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002070};
2071
Dino Viehland4f384af2019-09-10 11:18:37 +01002072PyDoc_STRVAR(s__doc__,
2073"Struct(fmt) --> compiled struct object\n"
2074"\n"
2075);
2076
2077static PyType_Slot PyStructType_slots[] = {
2078 {Py_tp_dealloc, s_dealloc},
2079 {Py_tp_getattro, PyObject_GenericGetAttr},
2080 {Py_tp_setattro, PyObject_GenericSetAttr},
2081 {Py_tp_doc, (void*)s__doc__},
2082 {Py_tp_methods, s_methods},
2083 {Py_tp_members, s_members},
2084 {Py_tp_getset, s_getsetlist},
2085 {Py_tp_init, Struct___init__},
2086 {Py_tp_alloc, PyType_GenericAlloc},
2087 {Py_tp_new, s_new},
2088 {Py_tp_free, PyObject_Del},
2089 {0, 0},
2090};
2091
2092static PyType_Spec PyStructType_spec = {
2093 "_struct.Struct",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 sizeof(PyStructObject),
2095 0,
Dino Viehland4f384af2019-09-10 11:18:37 +01002096 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
2097 PyStructType_slots
Thomas Wouters477c8d52006-05-27 19:21:47 +00002098};
2099
Christian Heimesa34706f2008-01-04 03:06:10 +00002100
2101/* ---- Standalone functions ---- */
2102
2103#define MAXCACHE 100
Christian Heimesa34706f2008-01-04 03:06:10 +00002104
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002105static int
Christian Heimescfeb5432020-11-19 14:36:23 +01002106cache_struct_converter(PyObject *module, PyObject *fmt, PyStructObject **ptr)
Christian Heimesa34706f2008-01-04 03:06:10 +00002107{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002108 PyObject * s_object;
Christian Heimescfeb5432020-11-19 14:36:23 +01002109 _structmodulestate *state = get_struct_state(module);
Christian Heimesa34706f2008-01-04 03:06:10 +00002110
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002111 if (fmt == NULL) {
2112 Py_DECREF(*ptr);
Serhiy Storchaka40db90c2017-04-20 21:19:31 +03002113 *ptr = NULL;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002114 return 1;
2115 }
2116
Christian Heimescfeb5432020-11-19 14:36:23 +01002117 if (state->cache == NULL) {
2118 state->cache = PyDict_New();
2119 if (state->cache == NULL)
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002120 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002122
Christian Heimescfeb5432020-11-19 14:36:23 +01002123 s_object = PyDict_GetItemWithError(state->cache, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002124 if (s_object != NULL) {
2125 Py_INCREF(s_object);
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002126 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002127 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002128 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002129 else if (PyErr_Occurred()) {
2130 return 0;
2131 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002132
Christian Heimescfeb5432020-11-19 14:36:23 +01002133 s_object = PyObject_CallOneArg(state->PyStructType, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002134 if (s_object != NULL) {
Christian Heimescfeb5432020-11-19 14:36:23 +01002135 if (PyDict_GET_SIZE(state->cache) >= MAXCACHE)
2136 PyDict_Clear(state->cache);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002137 /* Attempt to cache the result */
Christian Heimescfeb5432020-11-19 14:36:23 +01002138 if (PyDict_SetItem(state->cache, fmt, s_object) == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002139 PyErr_Clear();
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002140 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002141 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002142 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002143 return 0;
Christian Heimesa34706f2008-01-04 03:06:10 +00002144}
2145
Victor Stinner3f2d1012017-02-02 12:09:30 +01002146/*[clinic input]
2147_clearcache
2148
2149Clear the internal cache.
2150[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002151
2152static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002153_clearcache_impl(PyObject *module)
2154/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002155{
Christian Heimescfeb5432020-11-19 14:36:23 +01002156 Py_CLEAR(get_struct_state(module)->cache);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00002158}
2159
Victor Stinner3f2d1012017-02-02 12:09:30 +01002160
2161/*[clinic input]
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002162calcsize -> Py_ssize_t
Victor Stinner3f2d1012017-02-02 12:09:30 +01002163
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002164 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002165 /
2166
2167Return size in bytes of the struct described by the format string.
2168[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002169
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002170static Py_ssize_t
2171calcsize_impl(PyObject *module, PyStructObject *s_object)
2172/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002173{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002174 return s_object->s_size;
Christian Heimesa34706f2008-01-04 03:06:10 +00002175}
2176
2177PyDoc_STRVAR(pack_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002178"pack(format, v1, v2, ...) -> bytes\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002179\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002180Return a bytes object containing the values v1, v2, ... packed according\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002181to the format string. See help(struct) for more on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002182
2183static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01002184pack(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002185{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002186 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002187 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002188
Victor Stinner3f2d1012017-02-02 12:09:30 +01002189 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002190 PyErr_SetString(PyExc_TypeError, "missing format argument");
2191 return NULL;
2192 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002193 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002194
Christian Heimescfeb5432020-11-19 14:36:23 +01002195 if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002196 return NULL;
2197 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002198 result = s_pack(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002199 Py_DECREF(s_object);
2200 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002201}
2202
2203PyDoc_STRVAR(pack_into_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002204"pack_into(format, buffer, offset, v1, v2, ...)\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002205\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002206Pack the values v1, v2, ... according to the format string and write\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002207the packed bytes into the writable buffer buf starting at offset. Note\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002208that the offset is a required argument. See help(struct) for more\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002209on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002210
2211static PyObject *
Christian Heimescfeb5432020-11-19 14:36:23 +01002212pack_into(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002213{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002214 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002215 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002216
Victor Stinner3f2d1012017-02-02 12:09:30 +01002217 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002218 PyErr_SetString(PyExc_TypeError, "missing format argument");
2219 return NULL;
2220 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002221 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002222
Christian Heimescfeb5432020-11-19 14:36:23 +01002223 if (!cache_struct_converter(module, format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002224 return NULL;
2225 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002226 result = s_pack_into(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002227 Py_DECREF(s_object);
2228 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002229}
2230
Victor Stinner3f2d1012017-02-02 12:09:30 +01002231/*[clinic input]
2232unpack
2233
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002234 format as s_object: cache_struct
Victor Stinnerc0f59ad2017-02-02 14:24:16 +01002235 buffer: Py_buffer
Victor Stinner3f2d1012017-02-02 12:09:30 +01002236 /
2237
2238Return a tuple containing values unpacked according to the format string.
2239
2240The buffer's size in bytes must be calcsize(format).
2241
2242See help(struct) for more on format strings.
2243[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002244
2245static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002246unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2247/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002248{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002249 return Struct_unpack_impl(s_object, buffer);
Christian Heimesa34706f2008-01-04 03:06:10 +00002250}
2251
Victor Stinner3f2d1012017-02-02 12:09:30 +01002252/*[clinic input]
2253unpack_from
2254
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002255 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002256 /
2257 buffer: Py_buffer
2258 offset: Py_ssize_t = 0
2259
2260Return a tuple containing values unpacked according to the format string.
2261
2262The buffer's size, minus offset, must be at least calcsize(format).
2263
2264See help(struct) for more on format strings.
2265[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002266
2267static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002268unpack_from_impl(PyObject *module, PyStructObject *s_object,
2269 Py_buffer *buffer, Py_ssize_t offset)
2270/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002271{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002272 return Struct_unpack_from_impl(s_object, buffer, offset);
Christian Heimesa34706f2008-01-04 03:06:10 +00002273}
2274
Victor Stinner3f2d1012017-02-02 12:09:30 +01002275/*[clinic input]
2276iter_unpack
2277
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002278 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002279 buffer: object
2280 /
2281
2282Return an iterator yielding tuples unpacked from the given bytes.
2283
2284The bytes are unpacked according to the format string, like
2285a repeated invocation of unpack_from().
2286
2287Requires that the bytes length be a multiple of the format struct size.
2288[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002289
2290static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002291iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2292 PyObject *buffer)
2293/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002294{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002295 return Struct_iter_unpack(s_object, buffer);
Antoine Pitrou9f146812013-04-27 00:20:04 +02002296}
2297
Christian Heimesa34706f2008-01-04 03:06:10 +00002298static struct PyMethodDef module_functions[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002299 _CLEARCACHE_METHODDEF
2300 CALCSIZE_METHODDEF
2301 ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002302 {"pack", (PyCFunction)(void(*)(void))pack, METH_FASTCALL, pack_doc},
2303 {"pack_into", (PyCFunction)(void(*)(void))pack_into, METH_FASTCALL, pack_into_doc},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002304 UNPACK_METHODDEF
2305 UNPACK_FROM_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002306 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00002307};
2308
2309
Thomas Wouters477c8d52006-05-27 19:21:47 +00002310/* Module initialization */
2311
Christian Heimesa34706f2008-01-04 03:06:10 +00002312PyDoc_STRVAR(module_doc,
2313"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002314Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002315and also as format strings (explained below) to describe the layout of data\n\
2316in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002317\n\
2318The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002319 @: native order, size & alignment (default)\n\
2320 =: native order, std. size & alignment\n\
2321 <: little-endian, std. size & alignment\n\
2322 >: big-endian, std. size & alignment\n\
2323 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002324\n\
2325The remaining chars indicate types of args and must match exactly;\n\
2326these can be preceded by a decimal repeat count:\n\
2327 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002328 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002329 h:short; H:unsigned short; i:int; I:unsigned int;\n\
Mark Dickinson7c4e4092016-09-03 17:21:29 +01002330 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002331Special cases (preceding decimal count indicates length):\n\
2332 s:string (array of char); p: pascal string (with count byte).\n\
Antoine Pitrou45d9c912011-10-06 15:27:40 +02002333Special cases (only available in native format):\n\
2334 n:ssize_t; N:size_t;\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002335 P:an integer type that is wide enough to hold a pointer.\n\
2336Special case (not in native mode unless 'long long' in platform C):\n\
2337 q:long long; Q:unsigned long long\n\
2338Whitespace between formats is ignored.\n\
2339\n\
2340The variable struct.error is an exception raised on errors.\n");
2341
Martin v. Löwis1a214512008-06-11 05:26:20 +00002342
Dino Viehland4f384af2019-09-10 11:18:37 +01002343static int
2344_structmodule_traverse(PyObject *module, visitproc visit, void *arg)
2345{
Christian Heimescfeb5432020-11-19 14:36:23 +01002346 _structmodulestate *state = get_struct_state(module);
Hai Shif707d942020-03-16 21:15:01 +08002347 if (state) {
Christian Heimescfeb5432020-11-19 14:36:23 +01002348 Py_VISIT(state->cache);
Hai Shif707d942020-03-16 21:15:01 +08002349 Py_VISIT(state->PyStructType);
2350 Py_VISIT(state->unpackiter_type);
2351 Py_VISIT(state->StructError);
2352 }
Dino Viehland4f384af2019-09-10 11:18:37 +01002353 return 0;
2354}
2355
2356static int
2357_structmodule_clear(PyObject *module)
2358{
Christian Heimescfeb5432020-11-19 14:36:23 +01002359 _structmodulestate *state = get_struct_state(module);
Hai Shif707d942020-03-16 21:15:01 +08002360 if (state) {
Christian Heimescfeb5432020-11-19 14:36:23 +01002361 Py_CLEAR(state->cache);
Hai Shif707d942020-03-16 21:15:01 +08002362 Py_CLEAR(state->PyStructType);
2363 Py_CLEAR(state->unpackiter_type);
2364 Py_CLEAR(state->StructError);
2365 }
Dino Viehland4f384af2019-09-10 11:18:37 +01002366 return 0;
2367}
2368
2369static void
2370_structmodule_free(void *module)
2371{
2372 _structmodule_clear((PyObject *)module);
2373}
2374
Christian Heimescfeb5432020-11-19 14:36:23 +01002375static int
2376_structmodule_exec(PyObject *m)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002377{
Christian Heimescfeb5432020-11-19 14:36:23 +01002378 _structmodulestate *state = get_struct_state(m);
Christian Heimesa34706f2008-01-04 03:06:10 +00002379
Christian Heimescfeb5432020-11-19 14:36:23 +01002380 state->PyStructType = PyType_FromModuleAndSpec(
2381 m, &PyStructType_spec, NULL);
2382 if (state->PyStructType == NULL) {
2383 return -1;
Dino Viehland4f384af2019-09-10 11:18:37 +01002384 }
Christian Heimescfeb5432020-11-19 14:36:23 +01002385 if (PyModule_AddType(m, (PyTypeObject *)state->PyStructType) < 0) {
2386 return -1;
Dino Viehland4f384af2019-09-10 11:18:37 +01002387 }
Christian Heimescfeb5432020-11-19 14:36:23 +01002388
2389 state->unpackiter_type = PyType_FromModuleAndSpec(
2390 m, &unpackiter_type_spec, NULL);
2391 if (state->unpackiter_type == NULL) {
2392 return -1;
2393 }
Zachary Ware99f11b42016-10-04 01:20:21 -05002394
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002395 /* Check endian and swap in faster functions */
2396 {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002397 const formatdef *native = native_table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002398 formatdef *other, *ptr;
Christian Heimes743e0cd2012-10-17 23:52:17 +02002399#if PY_LITTLE_ENDIAN
2400 other = lilendian_table;
2401#else
2402 other = bigendian_table;
2403#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002404 /* Scan through the native table, find a matching
2405 entry in the endian table and swap in the
2406 native implementations whenever possible
2407 (64-bit platforms may not have "standard" sizes) */
2408 while (native->format != '\0' && other->format != '\0') {
2409 ptr = other;
2410 while (ptr->format != '\0') {
2411 if (ptr->format == native->format) {
2412 /* Match faster when formats are
2413 listed in the same order */
2414 if (ptr == other)
2415 other++;
2416 /* Only use the trick if the
2417 size matches */
2418 if (ptr->size != native->size)
2419 break;
2420 /* Skip float and double, could be
2421 "unknown" float format */
2422 if (ptr->format == 'd' || ptr->format == 'f')
2423 break;
Stefan Krah472fc842020-03-24 14:01:13 +01002424 /* Skip _Bool, semantics are different for standard size */
2425 if (ptr->format == '?')
2426 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 ptr->pack = native->pack;
2428 ptr->unpack = native->unpack;
2429 break;
2430 }
2431 ptr++;
2432 }
2433 native++;
2434 }
2435 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002436
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002437 /* Add some symbolic constants to the module */
Christian Heimescfeb5432020-11-19 14:36:23 +01002438 state->StructError = PyErr_NewException("struct.error", NULL, NULL);
2439 if (state->StructError == NULL) {
2440 return -1;
2441 }
2442 if (PyModule_AddObjectRef(m, "error", state->StructError) < 0) {
2443 return -1;
2444 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002445
Christian Heimescfeb5432020-11-19 14:36:23 +01002446 return 0;
2447}
2448
2449static PyModuleDef_Slot _structmodule_slots[] = {
2450 {Py_mod_exec, _structmodule_exec},
2451 {0, NULL}
2452};
2453
2454static struct PyModuleDef _structmodule = {
2455 PyModuleDef_HEAD_INIT,
2456 .m_name = "_struct",
2457 .m_doc = module_doc,
2458 .m_size = sizeof(_structmodulestate),
2459 .m_methods = module_functions,
2460 .m_slots = _structmodule_slots,
2461 .m_traverse = _structmodule_traverse,
2462 .m_clear = _structmodule_clear,
2463 .m_free = _structmodule_free,
2464};
2465
2466PyMODINIT_FUNC
2467PyInit__struct(void)
2468{
2469 return PyModuleDef_Init(&_structmodule);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002470}