blob: 13d8072f61218753909995948dc6aa92970cc00c [file] [log] [blame]
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001/* struct module -- pack values into and (out of) bytes objects */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002
3/* New version supporting byte order, alignment and size options,
4 character strings, and unsigned numbers */
5
6#define PY_SSIZE_T_CLEAN
7
8#include "Python.h"
Victor Stinner4a21e572020-04-15 02:35:41 +02009#include "structmember.h" // PyMemberDef
Thomas Wouters477c8d52006-05-27 19:21:47 +000010#include <ctype.h>
11
Victor Stinner3f2d1012017-02-02 12:09:30 +010012/*[clinic input]
13class Struct "PyStructObject *" "&PyStructType"
14[clinic start generated code]*/
15/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/
16
Dino Viehland4f384af2019-09-10 11:18:37 +010017typedef struct {
18 PyObject *PyStructType;
19 PyObject *unpackiter_type;
20 PyObject *StructError;
21} _structmodulestate;
22
Hai Shif707d942020-03-16 21:15:01 +080023static inline _structmodulestate*
24get_struct_state(PyObject *module)
25{
26 void *state = PyModule_GetState(module);
27 assert(state != NULL);
28 return (_structmodulestate *)state;
29}
Dino Viehland4f384af2019-09-10 11:18:37 +010030
31static struct PyModuleDef _structmodule;
32
Hai Shif707d942020-03-16 21:15:01 +080033#define _structmodulestate_global get_struct_state(PyState_FindModule(&_structmodule))
Thomas Wouters477c8d52006-05-27 19:21:47 +000034
Thomas Wouters477c8d52006-05-27 19:21:47 +000035/* The translation function for each format character is table driven */
36typedef struct _formatdef {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037 char format;
38 Py_ssize_t size;
39 Py_ssize_t alignment;
40 PyObject* (*unpack)(const char *,
41 const struct _formatdef *);
42 int (*pack)(char *, PyObject *,
43 const struct _formatdef *);
Thomas Wouters477c8d52006-05-27 19:21:47 +000044} formatdef;
45
46typedef struct _formatcode {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000047 const struct _formatdef *fmtdef;
48 Py_ssize_t offset;
49 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +030050 Py_ssize_t repeat;
Thomas Wouters477c8d52006-05-27 19:21:47 +000051} formatcode;
52
53/* Struct object interface */
54
55typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000056 PyObject_HEAD
57 Py_ssize_t s_size;
58 Py_ssize_t s_len;
59 formatcode *s_codes;
60 PyObject *s_format;
61 PyObject *weakreflist; /* List of weak references */
Thomas Wouters477c8d52006-05-27 19:21:47 +000062} PyStructObject;
63
64
Dino Viehland4f384af2019-09-10 11:18:37 +010065#define PyStruct_Check(op) PyObject_TypeCheck(op, (PyTypeObject *)_structmodulestate_global->PyStructType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090066#define PyStruct_CheckExact(op) Py_IS_TYPE(op, (PyTypeObject *)_structmodulestate_global->PyStructType)
Thomas Wouters477c8d52006-05-27 19:21:47 +000067
68
69/* Define various structs to figure out the alignments of types */
70
71
72typedef struct { char c; short x; } st_short;
73typedef struct { char c; int x; } st_int;
74typedef struct { char c; long x; } st_long;
75typedef struct { char c; float x; } st_float;
76typedef struct { char c; double x; } st_double;
77typedef struct { char c; void *x; } st_void_p;
Antoine Pitrou45d9c912011-10-06 15:27:40 +020078typedef struct { char c; size_t x; } st_size_t;
Benjamin Petersona9296e72016-09-07 11:06:17 -070079typedef struct { char c; _Bool x; } st_bool;
Thomas Wouters477c8d52006-05-27 19:21:47 +000080
81#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
82#define INT_ALIGN (sizeof(st_int) - sizeof(int))
83#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
84#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
85#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
86#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
Antoine Pitrou45d9c912011-10-06 15:27:40 +020087#define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t))
Benjamin Petersona9296e72016-09-07 11:06:17 -070088#define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool))
Thomas Wouters477c8d52006-05-27 19:21:47 +000089
90/* We can't support q and Q in native mode unless the compiler does;
91 in std mode, they're 8 bytes on all platforms. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -070092typedef struct { char c; long long x; } s_long_long;
93#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long))
Thomas Wouters477c8d52006-05-27 19:21:47 +000094
Thomas Wouters477c8d52006-05-27 19:21:47 +000095#ifdef __powerc
96#pragma options align=reset
97#endif
98
Serhiy Storchakaa5a55902017-02-04 11:14:52 +020099/*[python input]
100class cache_struct_converter(CConverter):
101 type = 'PyStructObject *'
102 converter = 'cache_struct_converter'
103 c_default = "NULL"
104
105 def cleanup(self):
106 return "Py_XDECREF(%s);\n" % self.name
107[python start generated code]*/
108/*[python end generated code: output=da39a3ee5e6b4b0d input=49957cca130ffb63]*/
109
Serhiy Storchaka32d96a22018-12-25 13:23:47 +0200110static int cache_struct_converter(PyObject *, PyStructObject **);
Serhiy Storchakaa5a55902017-02-04 11:14:52 +0200111
Victor Stinner3f2d1012017-02-02 12:09:30 +0100112#include "clinic/_struct.c.h"
113
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000114/* Helper for integer format codes: converts an arbitrary Python object to a
115 PyLongObject if possible, otherwise fails. Caller should decref. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000116
117static PyObject *
118get_pylong(PyObject *v)
119{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 assert(v != NULL);
121 if (!PyLong_Check(v)) {
122 /* Not an integer; try to use __index__ to convert. */
123 if (PyIndex_Check(v)) {
124 v = PyNumber_Index(v);
125 if (v == NULL)
126 return NULL;
127 }
128 else {
Dino Viehland4f384af2019-09-10 11:18:37 +0100129 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 "required argument is not an integer");
131 return NULL;
132 }
133 }
134 else
135 Py_INCREF(v);
Mark Dickinsonea835e72009-04-19 20:40:33 +0000136
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 assert(PyLong_Check(v));
138 return v;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000139}
140
Mark Dickinsonea835e72009-04-19 20:40:33 +0000141/* Helper routine to get a C long and raise the appropriate error if it isn't
142 one */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000143
144static int
145get_long(PyObject *v, long *p)
146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000147 long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 v = get_pylong(v);
150 if (v == NULL)
151 return -1;
152 assert(PyLong_Check(v));
153 x = PyLong_AsLong(v);
154 Py_DECREF(v);
155 if (x == (long)-1 && PyErr_Occurred()) {
156 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100157 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000158 "argument out of range");
159 return -1;
160 }
161 *p = x;
162 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000163}
164
165
166/* Same, but handling unsigned long */
167
168static int
169get_ulong(PyObject *v, unsigned long *p)
170{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 unsigned long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000173 v = get_pylong(v);
174 if (v == NULL)
175 return -1;
176 assert(PyLong_Check(v));
177 x = PyLong_AsUnsignedLong(v);
178 Py_DECREF(v);
179 if (x == (unsigned long)-1 && PyErr_Occurred()) {
180 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100181 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 "argument out of range");
183 return -1;
184 }
185 *p = x;
186 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000187}
188
Thomas Wouters477c8d52006-05-27 19:21:47 +0000189/* Same, but handling native long long. */
190
191static int
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700192get_longlong(PyObject *v, long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000193{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700194 long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000195
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000196 v = get_pylong(v);
197 if (v == NULL)
198 return -1;
199 assert(PyLong_Check(v));
200 x = PyLong_AsLongLong(v);
201 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700202 if (x == (long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000203 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100204 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 "argument out of range");
206 return -1;
207 }
208 *p = x;
209 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000210}
211
212/* Same, but handling native unsigned long long. */
213
214static int
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700215get_ulonglong(PyObject *v, unsigned long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000216{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700217 unsigned long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000219 v = get_pylong(v);
220 if (v == NULL)
221 return -1;
222 assert(PyLong_Check(v));
223 x = PyLong_AsUnsignedLongLong(v);
224 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700225 if (x == (unsigned long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100227 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 "argument out of range");
229 return -1;
230 }
231 *p = x;
232 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000233}
234
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200235/* Same, but handling Py_ssize_t */
236
237static int
238get_ssize_t(PyObject *v, Py_ssize_t *p)
239{
240 Py_ssize_t x;
241
242 v = get_pylong(v);
243 if (v == NULL)
244 return -1;
245 assert(PyLong_Check(v));
246 x = PyLong_AsSsize_t(v);
247 Py_DECREF(v);
248 if (x == (Py_ssize_t)-1 && PyErr_Occurred()) {
249 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100250 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200251 "argument out of range");
252 return -1;
253 }
254 *p = x;
255 return 0;
256}
257
258/* Same, but handling size_t */
259
260static int
261get_size_t(PyObject *v, size_t *p)
262{
263 size_t x;
264
265 v = get_pylong(v);
266 if (v == NULL)
267 return -1;
268 assert(PyLong_Check(v));
269 x = PyLong_AsSize_t(v);
270 Py_DECREF(v);
271 if (x == (size_t)-1 && PyErr_Occurred()) {
272 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100273 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200274 "argument out of range");
275 return -1;
276 }
277 *p = x;
278 return 0;
279}
280
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000281
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000282#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
283
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000284
Thomas Wouters477c8d52006-05-27 19:21:47 +0000285/* Floating point helpers */
286
287static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100288unpack_halffloat(const char *p, /* start of 2-byte string */
289 int le) /* true for little-endian, false for big-endian */
290{
291 double x;
292
293 x = _PyFloat_Unpack2((unsigned char *)p, le);
294 if (x == -1.0 && PyErr_Occurred()) {
295 return NULL;
296 }
297 return PyFloat_FromDouble(x);
298}
299
300static int
301pack_halffloat(char *p, /* start of 2-byte string */
302 PyObject *v, /* value to pack */
303 int le) /* true for little-endian, false for big-endian */
304{
305 double x = PyFloat_AsDouble(v);
306 if (x == -1.0 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100307 PyErr_SetString(_structmodulestate_global->StructError,
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100308 "required argument is not a float");
309 return -1;
310 }
311 return _PyFloat_Pack2(x, (unsigned char *)p, le);
312}
313
314static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000315unpack_float(const char *p, /* start of 4-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000317{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 x = _PyFloat_Unpack4((unsigned char *)p, le);
321 if (x == -1.0 && PyErr_Occurred())
322 return NULL;
323 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000324}
325
326static PyObject *
327unpack_double(const char *p, /* start of 8-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000330 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 x = _PyFloat_Unpack8((unsigned char *)p, le);
333 if (x == -1.0 && PyErr_Occurred())
334 return NULL;
335 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000336}
337
338/* Helper to format the range error exceptions */
339static int
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000340_range_error(const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000341{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 /* ulargest is the largest unsigned value with f->size bytes.
343 * Note that the simpler:
344 * ((size_t)1 << (f->size * 8)) - 1
345 * doesn't work when f->size == sizeof(size_t) because C doesn't
346 * define what happens when a left shift count is >= the number of
347 * bits in the integer being shifted; e.g., on some boxes it doesn't
348 * shift at all when they're equal.
349 */
350 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
351 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
352 if (is_unsigned)
Dino Viehland4f384af2019-09-10 11:18:37 +0100353 PyErr_Format(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 "'%c' format requires 0 <= number <= %zu",
355 f->format,
356 ulargest);
357 else {
358 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
Dino Viehland4f384af2019-09-10 11:18:37 +0100359 PyErr_Format(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 "'%c' format requires %zd <= number <= %zd",
361 f->format,
362 ~ largest,
363 largest);
364 }
Mark Dickinsonae681df2009-03-21 10:26:31 +0000365
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000366 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000367}
368
369
370
371/* A large number of small routines follow, with names of the form
372
373 [bln][up]_TYPE
374
Min ho Kimc4cacc82019-07-31 08:16:13 +1000375 [bln] distinguishes among big-endian, little-endian and native.
376 [pu] distinguishes between pack (to struct) and unpack (from struct).
Thomas Wouters477c8d52006-05-27 19:21:47 +0000377 TYPE is one of char, byte, ubyte, etc.
378*/
379
380/* Native mode routines. ****************************************************/
381/* NOTE:
382 In all n[up]_<type> routines handling types larger than 1 byte, there is
383 *no* guarantee that the p pointer is properly aligned for each type,
384 therefore memcpy is called. An intermediate variable is used to
385 compensate for big-endian architectures.
386 Normally both the intermediate variable and the memcpy call will be
387 skipped by C optimisation in little-endian architectures (gcc >= 2.91
388 does this). */
389
390static PyObject *
391nu_char(const char *p, const formatdef *f)
392{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 return PyBytes_FromStringAndSize(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000394}
395
396static PyObject *
397nu_byte(const char *p, const formatdef *f)
398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 return PyLong_FromLong((long) *(signed char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000400}
401
402static PyObject *
403nu_ubyte(const char *p, const formatdef *f)
404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 return PyLong_FromLong((long) *(unsigned char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000406}
407
408static PyObject *
409nu_short(const char *p, const formatdef *f)
410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 short x;
412 memcpy((char *)&x, p, sizeof x);
413 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000414}
415
416static PyObject *
417nu_ushort(const char *p, const formatdef *f)
418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 unsigned short x;
420 memcpy((char *)&x, p, sizeof x);
421 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000422}
423
424static PyObject *
425nu_int(const char *p, const formatdef *f)
426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 int x;
428 memcpy((char *)&x, p, sizeof x);
429 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000430}
431
432static PyObject *
433nu_uint(const char *p, const formatdef *f)
434{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 unsigned int x;
436 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 return PyLong_FromUnsignedLong((unsigned long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000438}
439
440static PyObject *
441nu_long(const char *p, const formatdef *f)
442{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000443 long x;
444 memcpy((char *)&x, p, sizeof x);
445 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000446}
447
448static PyObject *
449nu_ulong(const char *p, const formatdef *f)
450{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 unsigned long x;
452 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000453 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000454}
455
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200456static PyObject *
457nu_ssize_t(const char *p, const formatdef *f)
458{
459 Py_ssize_t x;
460 memcpy((char *)&x, p, sizeof x);
461 return PyLong_FromSsize_t(x);
462}
463
464static PyObject *
465nu_size_t(const char *p, const formatdef *f)
466{
467 size_t x;
468 memcpy((char *)&x, p, sizeof x);
469 return PyLong_FromSize_t(x);
470}
471
Thomas Wouters477c8d52006-05-27 19:21:47 +0000472static PyObject *
473nu_longlong(const char *p, const formatdef *f)
474{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700475 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000476 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000478}
479
480static PyObject *
481nu_ulonglong(const char *p, const formatdef *f)
482{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700483 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000486}
487
Thomas Wouters477c8d52006-05-27 19:21:47 +0000488static PyObject *
Thomas Woutersb2137042007-02-01 18:02:27 +0000489nu_bool(const char *p, const formatdef *f)
490{
Benjamin Petersona9296e72016-09-07 11:06:17 -0700491 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000492 memcpy((char *)&x, p, sizeof x);
493 return PyBool_FromLong(x != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000494}
495
496
497static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100498nu_halffloat(const char *p, const formatdef *f)
499{
500#if PY_LITTLE_ENDIAN
501 return unpack_halffloat(p, 1);
502#else
503 return unpack_halffloat(p, 0);
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700504#endif
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100505}
506
507static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000508nu_float(const char *p, const formatdef *f)
509{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 float x;
511 memcpy((char *)&x, p, sizeof x);
512 return PyFloat_FromDouble((double)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000513}
514
515static PyObject *
516nu_double(const char *p, const formatdef *f)
517{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000518 double x;
519 memcpy((char *)&x, p, sizeof x);
520 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000521}
522
523static PyObject *
524nu_void_p(const char *p, const formatdef *f)
525{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 void *x;
527 memcpy((char *)&x, p, sizeof x);
528 return PyLong_FromVoidPtr(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000529}
530
531static int
532np_byte(char *p, PyObject *v, const formatdef *f)
533{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000534 long x;
535 if (get_long(v, &x) < 0)
536 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800537 if (x < -128 || x > 127) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100538 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 "byte format requires -128 <= number <= 127");
540 return -1;
541 }
542 *p = (char)x;
543 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000544}
545
546static int
547np_ubyte(char *p, PyObject *v, const formatdef *f)
548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 long x;
550 if (get_long(v, &x) < 0)
551 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800552 if (x < 0 || x > 255) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100553 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 "ubyte format requires 0 <= number <= 255");
555 return -1;
556 }
Xiang Zhang981096f2017-05-15 12:04:26 +0800557 *(unsigned char *)p = (unsigned char)x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000559}
560
561static int
562np_char(char *p, PyObject *v, const formatdef *f)
563{
Dino Viehland4f384af2019-09-10 11:18:37 +0100564 if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
565 PyErr_SetString(_structmodulestate_global->StructError,
Victor Stinnerda9ec992010-12-28 13:26:42 +0000566 "char format requires a bytes object of length 1");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000567 return -1;
568 }
Xiang Zhang96f50282017-05-15 11:53:51 +0800569 *p = *PyBytes_AS_STRING(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000571}
572
573static int
574np_short(char *p, PyObject *v, const formatdef *f)
575{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000576 long x;
577 short y;
578 if (get_long(v, &x) < 0)
579 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800580 if (x < SHRT_MIN || x > SHRT_MAX) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100581 PyErr_SetString(_structmodulestate_global->StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200582 "short format requires " Py_STRINGIFY(SHRT_MIN)
583 " <= number <= " Py_STRINGIFY(SHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000584 return -1;
585 }
586 y = (short)x;
587 memcpy(p, (char *)&y, sizeof y);
588 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000589}
590
591static int
592np_ushort(char *p, PyObject *v, const formatdef *f)
593{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000594 long x;
595 unsigned short y;
596 if (get_long(v, &x) < 0)
597 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800598 if (x < 0 || x > USHRT_MAX) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100599 PyErr_SetString(_structmodulestate_global->StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200600 "ushort format requires 0 <= number <= "
601 Py_STRINGIFY(USHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 return -1;
603 }
604 y = (unsigned short)x;
605 memcpy(p, (char *)&y, sizeof y);
606 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000607}
608
609static int
610np_int(char *p, PyObject *v, const formatdef *f)
611{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000612 long x;
613 int y;
614 if (get_long(v, &x) < 0)
615 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000616#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
618 RANGE_ERROR(x, f, 0, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000619#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 y = (int)x;
621 memcpy(p, (char *)&y, sizeof y);
622 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000623}
624
625static int
626np_uint(char *p, PyObject *v, const formatdef *f)
627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 unsigned long x;
629 unsigned int y;
630 if (get_ulong(v, &x) < 0)
631 return -1;
632 y = (unsigned int)x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000633#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 if (x > ((unsigned long)UINT_MAX))
635 RANGE_ERROR(y, f, 1, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000636#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 memcpy(p, (char *)&y, sizeof y);
638 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000639}
640
641static int
642np_long(char *p, PyObject *v, const formatdef *f)
643{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000644 long x;
645 if (get_long(v, &x) < 0)
646 return -1;
647 memcpy(p, (char *)&x, sizeof x);
648 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000649}
650
651static int
652np_ulong(char *p, PyObject *v, const formatdef *f)
653{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000654 unsigned long x;
655 if (get_ulong(v, &x) < 0)
656 return -1;
657 memcpy(p, (char *)&x, sizeof x);
658 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000659}
660
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200661static int
662np_ssize_t(char *p, PyObject *v, const formatdef *f)
663{
664 Py_ssize_t x;
665 if (get_ssize_t(v, &x) < 0)
666 return -1;
667 memcpy(p, (char *)&x, sizeof x);
668 return 0;
669}
670
671static int
672np_size_t(char *p, PyObject *v, const formatdef *f)
673{
674 size_t x;
675 if (get_size_t(v, &x) < 0)
676 return -1;
677 memcpy(p, (char *)&x, sizeof x);
678 return 0;
679}
680
Thomas Wouters477c8d52006-05-27 19:21:47 +0000681static int
682np_longlong(char *p, PyObject *v, const formatdef *f)
683{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700684 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 if (get_longlong(v, &x) < 0)
686 return -1;
687 memcpy(p, (char *)&x, sizeof x);
688 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000689}
690
691static int
692np_ulonglong(char *p, PyObject *v, const formatdef *f)
693{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700694 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 if (get_ulonglong(v, &x) < 0)
696 return -1;
697 memcpy(p, (char *)&x, sizeof x);
698 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000699}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000700
Thomas Woutersb2137042007-02-01 18:02:27 +0000701
702static int
703np_bool(char *p, PyObject *v, const formatdef *f)
704{
Benjamin Petersonde73c452010-07-07 18:54:59 +0000705 int y;
Benjamin Petersona9296e72016-09-07 11:06:17 -0700706 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000708 if (y < 0)
709 return -1;
710 x = y;
711 memcpy(p, (char *)&x, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000713}
714
Thomas Wouters477c8d52006-05-27 19:21:47 +0000715static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100716np_halffloat(char *p, PyObject *v, const formatdef *f)
717{
718#if PY_LITTLE_ENDIAN
719 return pack_halffloat(p, v, 1);
720#else
721 return pack_halffloat(p, v, 0);
722#endif
723}
724
725static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000726np_float(char *p, PyObject *v, const formatdef *f)
727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 float x = (float)PyFloat_AsDouble(v);
729 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100730 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000731 "required argument is not a float");
732 return -1;
733 }
734 memcpy(p, (char *)&x, sizeof x);
735 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000736}
737
738static int
739np_double(char *p, PyObject *v, const formatdef *f)
740{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 double x = PyFloat_AsDouble(v);
742 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100743 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000744 "required argument is not a float");
745 return -1;
746 }
747 memcpy(p, (char *)&x, sizeof(double));
748 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000749}
750
751static int
752np_void_p(char *p, PyObject *v, const formatdef *f)
753{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 void *x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000755
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000756 v = get_pylong(v);
757 if (v == NULL)
758 return -1;
759 assert(PyLong_Check(v));
760 x = PyLong_AsVoidPtr(v);
761 Py_DECREF(v);
762 if (x == NULL && PyErr_Occurred())
763 return -1;
764 memcpy(p, (char *)&x, sizeof x);
765 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000766}
767
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200768static const formatdef native_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 {'x', sizeof(char), 0, NULL},
770 {'b', sizeof(char), 0, nu_byte, np_byte},
771 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
772 {'c', sizeof(char), 0, nu_char, np_char},
773 {'s', sizeof(char), 0, NULL},
774 {'p', sizeof(char), 0, NULL},
775 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
776 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
777 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
778 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
779 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
780 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200781 {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t},
782 {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t},
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700783 {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong},
784 {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Benjamin Petersona9296e72016-09-07 11:06:17 -0700785 {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100786 {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
788 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
789 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
790 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000791};
792
793/* Big-endian routines. *****************************************************/
794
795static PyObject *
796bu_int(const char *p, const formatdef *f)
797{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000798 long x = 0;
799 Py_ssize_t i = f->size;
800 const unsigned char *bytes = (const unsigned char *)p;
801 do {
802 x = (x<<8) | *bytes++;
803 } while (--i > 0);
804 /* Extend the sign bit. */
805 if (SIZEOF_LONG > f->size)
806 x |= -(x & (1L << ((8 * f->size) - 1)));
807 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000808}
809
810static PyObject *
811bu_uint(const char *p, const formatdef *f)
812{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000813 unsigned long x = 0;
814 Py_ssize_t i = f->size;
815 const unsigned char *bytes = (const unsigned char *)p;
816 do {
817 x = (x<<8) | *bytes++;
818 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000819 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000820}
821
822static PyObject *
823bu_longlong(const char *p, const formatdef *f)
824{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700825 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 Py_ssize_t i = f->size;
827 const unsigned char *bytes = (const unsigned char *)p;
828 do {
829 x = (x<<8) | *bytes++;
830 } while (--i > 0);
831 /* Extend the sign bit. */
832 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700833 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000834 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000835}
836
837static PyObject *
838bu_ulonglong(const char *p, const formatdef *f)
839{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700840 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 Py_ssize_t i = f->size;
842 const unsigned char *bytes = (const unsigned char *)p;
843 do {
844 x = (x<<8) | *bytes++;
845 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000847}
848
849static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100850bu_halffloat(const char *p, const formatdef *f)
851{
852 return unpack_halffloat(p, 0);
853}
854
855static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000856bu_float(const char *p, const formatdef *f)
857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 return unpack_float(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000859}
860
861static PyObject *
862bu_double(const char *p, const formatdef *f)
863{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000864 return unpack_double(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000865}
866
Thomas Woutersb2137042007-02-01 18:02:27 +0000867static PyObject *
868bu_bool(const char *p, const formatdef *f)
869{
Xiang Zhang96f50282017-05-15 11:53:51 +0800870 return PyBool_FromLong(*p != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000871}
872
Thomas Wouters477c8d52006-05-27 19:21:47 +0000873static int
874bp_int(char *p, PyObject *v, const formatdef *f)
875{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 long x;
877 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800878 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000879 if (get_long(v, &x) < 0)
880 return -1;
881 i = f->size;
882 if (i != SIZEOF_LONG) {
883 if ((i == 2) && (x < -32768 || x > 32767))
884 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000885#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
887 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000888#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 }
890 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800891 q[--i] = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 x >>= 8;
893 } while (i > 0);
894 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000895}
896
897static int
898bp_uint(char *p, PyObject *v, const formatdef *f)
899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 unsigned long x;
901 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800902 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 if (get_ulong(v, &x) < 0)
904 return -1;
905 i = f->size;
906 if (i != SIZEOF_LONG) {
907 unsigned long maxint = 1;
908 maxint <<= (unsigned long)(i * 8);
909 if (x >= maxint)
910 RANGE_ERROR(x, f, 1, maxint - 1);
911 }
912 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800913 q[--i] = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000914 x >>= 8;
915 } while (i > 0);
916 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000917}
918
919static int
920bp_longlong(char *p, PyObject *v, const formatdef *f)
921{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 int res;
923 v = get_pylong(v);
924 if (v == NULL)
925 return -1;
926 res = _PyLong_AsByteArray((PyLongObject *)v,
927 (unsigned char *)p,
928 8,
929 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800930 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 Py_DECREF(v);
932 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000933}
934
935static int
936bp_ulonglong(char *p, PyObject *v, const formatdef *f)
937{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 int res;
939 v = get_pylong(v);
940 if (v == NULL)
941 return -1;
942 res = _PyLong_AsByteArray((PyLongObject *)v,
943 (unsigned char *)p,
944 8,
945 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800946 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000947 Py_DECREF(v);
948 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000949}
950
951static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100952bp_halffloat(char *p, PyObject *v, const formatdef *f)
953{
954 return pack_halffloat(p, v, 0);
955}
956
957static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000958bp_float(char *p, PyObject *v, const formatdef *f)
959{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 double x = PyFloat_AsDouble(v);
961 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100962 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 "required argument is not a float");
964 return -1;
965 }
966 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000967}
968
969static int
970bp_double(char *p, PyObject *v, const formatdef *f)
971{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 double x = PyFloat_AsDouble(v);
973 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100974 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000975 "required argument is not a float");
976 return -1;
977 }
978 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000979}
980
Thomas Woutersb2137042007-02-01 18:02:27 +0000981static int
982bp_bool(char *p, PyObject *v, const formatdef *f)
983{
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000984 int y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000986 if (y < 0)
987 return -1;
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000988 *p = (char)y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000990}
991
Thomas Wouters477c8d52006-05-27 19:21:47 +0000992static formatdef bigendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 {'x', 1, 0, NULL},
994 {'b', 1, 0, nu_byte, np_byte},
995 {'B', 1, 0, nu_ubyte, np_ubyte},
996 {'c', 1, 0, nu_char, np_char},
997 {'s', 1, 0, NULL},
998 {'p', 1, 0, NULL},
999 {'h', 2, 0, bu_int, bp_int},
1000 {'H', 2, 0, bu_uint, bp_uint},
1001 {'i', 4, 0, bu_int, bp_int},
1002 {'I', 4, 0, bu_uint, bp_uint},
1003 {'l', 4, 0, bu_int, bp_int},
1004 {'L', 4, 0, bu_uint, bp_uint},
1005 {'q', 8, 0, bu_longlong, bp_longlong},
1006 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
1007 {'?', 1, 0, bu_bool, bp_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001008 {'e', 2, 0, bu_halffloat, bp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 {'f', 4, 0, bu_float, bp_float},
1010 {'d', 8, 0, bu_double, bp_double},
1011 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001012};
1013
1014/* Little-endian routines. *****************************************************/
1015
1016static PyObject *
1017lu_int(const char *p, const formatdef *f)
1018{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001019 long x = 0;
1020 Py_ssize_t i = f->size;
1021 const unsigned char *bytes = (const unsigned char *)p;
1022 do {
1023 x = (x<<8) | bytes[--i];
1024 } while (i > 0);
1025 /* Extend the sign bit. */
1026 if (SIZEOF_LONG > f->size)
1027 x |= -(x & (1L << ((8 * f->size) - 1)));
1028 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001029}
1030
1031static PyObject *
1032lu_uint(const char *p, const formatdef *f)
1033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 unsigned long x = 0;
1035 Py_ssize_t i = f->size;
1036 const unsigned char *bytes = (const unsigned char *)p;
1037 do {
1038 x = (x<<8) | bytes[--i];
1039 } while (i > 0);
Xiang Zhang96f50282017-05-15 11:53:51 +08001040 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001041}
1042
1043static PyObject *
1044lu_longlong(const char *p, const formatdef *f)
1045{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001046 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001047 Py_ssize_t i = f->size;
1048 const unsigned char *bytes = (const unsigned char *)p;
1049 do {
1050 x = (x<<8) | bytes[--i];
1051 } while (i > 0);
1052 /* Extend the sign bit. */
1053 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001054 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001056}
1057
1058static PyObject *
1059lu_ulonglong(const char *p, const formatdef *f)
1060{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001061 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 Py_ssize_t i = f->size;
1063 const unsigned char *bytes = (const unsigned char *)p;
1064 do {
1065 x = (x<<8) | bytes[--i];
1066 } while (i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001068}
1069
1070static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001071lu_halffloat(const char *p, const formatdef *f)
1072{
1073 return unpack_halffloat(p, 1);
1074}
1075
1076static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001077lu_float(const char *p, const formatdef *f)
1078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 return unpack_float(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001080}
1081
1082static PyObject *
1083lu_double(const char *p, const formatdef *f)
1084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 return unpack_double(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001086}
1087
1088static int
1089lp_int(char *p, PyObject *v, const formatdef *f)
1090{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001091 long x;
1092 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001093 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 if (get_long(v, &x) < 0)
1095 return -1;
1096 i = f->size;
1097 if (i != SIZEOF_LONG) {
1098 if ((i == 2) && (x < -32768 || x > 32767))
1099 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001100#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
1102 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001103#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 }
1105 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001106 *q++ = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 x >>= 8;
1108 } while (--i > 0);
1109 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001110}
1111
1112static int
1113lp_uint(char *p, PyObject *v, const formatdef *f)
1114{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 unsigned long x;
1116 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001117 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 if (get_ulong(v, &x) < 0)
1119 return -1;
1120 i = f->size;
1121 if (i != SIZEOF_LONG) {
1122 unsigned long maxint = 1;
1123 maxint <<= (unsigned long)(i * 8);
1124 if (x >= maxint)
1125 RANGE_ERROR(x, f, 1, maxint - 1);
1126 }
1127 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001128 *q++ = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001129 x >>= 8;
1130 } while (--i > 0);
1131 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001132}
1133
1134static int
1135lp_longlong(char *p, PyObject *v, const formatdef *f)
1136{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001137 int res;
1138 v = get_pylong(v);
1139 if (v == NULL)
1140 return -1;
1141 res = _PyLong_AsByteArray((PyLongObject*)v,
1142 (unsigned char *)p,
1143 8,
1144 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001145 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 Py_DECREF(v);
1147 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001148}
1149
1150static int
1151lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1152{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001153 int res;
1154 v = get_pylong(v);
1155 if (v == NULL)
1156 return -1;
1157 res = _PyLong_AsByteArray((PyLongObject*)v,
1158 (unsigned char *)p,
1159 8,
1160 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001161 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 Py_DECREF(v);
1163 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001164}
1165
1166static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001167lp_halffloat(char *p, PyObject *v, const formatdef *f)
1168{
1169 return pack_halffloat(p, v, 1);
1170}
1171
1172static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001173lp_float(char *p, PyObject *v, const formatdef *f)
1174{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001175 double x = PyFloat_AsDouble(v);
1176 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001177 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 "required argument is not a float");
1179 return -1;
1180 }
1181 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001182}
1183
1184static int
1185lp_double(char *p, PyObject *v, const formatdef *f)
1186{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 double x = PyFloat_AsDouble(v);
1188 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001189 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 "required argument is not a float");
1191 return -1;
1192 }
1193 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001194}
1195
1196static formatdef lilendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 {'x', 1, 0, NULL},
1198 {'b', 1, 0, nu_byte, np_byte},
1199 {'B', 1, 0, nu_ubyte, np_ubyte},
1200 {'c', 1, 0, nu_char, np_char},
1201 {'s', 1, 0, NULL},
1202 {'p', 1, 0, NULL},
1203 {'h', 2, 0, lu_int, lp_int},
1204 {'H', 2, 0, lu_uint, lp_uint},
1205 {'i', 4, 0, lu_int, lp_int},
1206 {'I', 4, 0, lu_uint, lp_uint},
1207 {'l', 4, 0, lu_int, lp_int},
1208 {'L', 4, 0, lu_uint, lp_uint},
1209 {'q', 8, 0, lu_longlong, lp_longlong},
1210 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1211 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1212 but potentially different from native rep -- reuse bx_bool funcs. */
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001213 {'e', 2, 0, lu_halffloat, lp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 {'f', 4, 0, lu_float, lp_float},
1215 {'d', 8, 0, lu_double, lp_double},
1216 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001217};
1218
1219
1220static const formatdef *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001221whichtable(const char **pfmt)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001222{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 const char *fmt = (*pfmt)++; /* May be backed out of later */
1224 switch (*fmt) {
1225 case '<':
1226 return lilendian_table;
1227 case '>':
1228 case '!': /* Network byte order is big-endian */
1229 return bigendian_table;
Ezio Melotti42da6632011-03-15 05:18:48 +02001230 case '=': { /* Host byte order -- different from native in alignment! */
Christian Heimes743e0cd2012-10-17 23:52:17 +02001231#if PY_LITTLE_ENDIAN
1232 return lilendian_table;
1233#else
1234 return bigendian_table;
1235#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 }
1237 default:
1238 --*pfmt; /* Back out of pointer increment */
1239 /* Fall through */
1240 case '@':
1241 return native_table;
1242 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001243}
1244
1245
1246/* Get the table entry for a format code */
1247
1248static const formatdef *
1249getentry(int c, const formatdef *f)
1250{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 for (; f->format != '\0'; f++) {
1252 if (f->format == c) {
1253 return f;
1254 }
1255 }
Dino Viehland4f384af2019-09-10 11:18:37 +01001256 PyErr_SetString(_structmodulestate_global->StructError, "bad char in struct format");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001258}
1259
1260
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001261/* Align a size according to a format code. Return -1 on overflow. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001262
Mark Dickinsoneac0e682010-06-11 19:05:08 +00001263static Py_ssize_t
Thomas Wouters477c8d52006-05-27 19:21:47 +00001264align(Py_ssize_t size, char c, const formatdef *e)
1265{
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001266 Py_ssize_t extra;
1267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 if (e->format == c) {
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001269 if (e->alignment && size > 0) {
1270 extra = (e->alignment - 1) - (size - 1) % (e->alignment);
1271 if (extra > PY_SSIZE_T_MAX - size)
1272 return -1;
1273 size += extra;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 }
1275 }
1276 return size;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001277}
1278
Antoine Pitrou9f146812013-04-27 00:20:04 +02001279/*
1280 * Struct object implementation.
1281 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001282
1283/* calculate the size of a format string */
1284
1285static int
1286prepare_s(PyStructObject *self)
1287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 const formatdef *f;
1289 const formatdef *e;
1290 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 const char *s;
1293 const char *fmt;
1294 char c;
Victor Stinner706768c2014-08-16 01:03:39 +02001295 Py_ssize_t size, len, num, itemsize;
1296 size_t ncodes;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001297
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 fmt = PyBytes_AS_STRING(self->s_format);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001299
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001300 f = whichtable(&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 s = fmt;
1303 size = 0;
1304 len = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001305 ncodes = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 while ((c = *s++) != '\0') {
Jordon Xu2ec70102019-09-11 00:04:08 +08001307 if (Py_ISSPACE(c))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 continue;
1309 if ('0' <= c && c <= '9') {
1310 num = c - '0';
1311 while ('0' <= (c = *s++) && c <= '9') {
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001312 /* overflow-safe version of
1313 if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1314 if (num >= PY_SSIZE_T_MAX / 10 && (
1315 num > PY_SSIZE_T_MAX / 10 ||
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001316 (c - '0') > PY_SSIZE_T_MAX % 10))
1317 goto overflow;
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001318 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 }
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001320 if (c == '\0') {
Dino Viehland4f384af2019-09-10 11:18:37 +01001321 PyErr_SetString(_structmodulestate_global->StructError,
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001322 "repeat count given without format specifier");
1323 return -1;
1324 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 }
1326 else
1327 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 e = getentry(c, f);
1330 if (e == NULL)
1331 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 switch (c) {
1334 case 's': /* fall through */
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001335 case 'p': len++; ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 case 'x': break;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001337 default: len += num; if (num) ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 itemsize = e->size;
1341 size = align(size, c, e);
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001342 if (size == -1)
1343 goto overflow;
1344
1345 /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1346 if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1347 goto overflow;
1348 size += num * itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 /* check for overflow */
Victor Stinner706768c2014-08-16 01:03:39 +02001352 if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001353 PyErr_NoMemory();
1354 return -1;
1355 }
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +00001356
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001357 self->s_size = size;
1358 self->s_len = len;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001359 codes = PyMem_MALLOC((ncodes + 1) * sizeof(formatcode));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 if (codes == NULL) {
1361 PyErr_NoMemory();
1362 return -1;
1363 }
Mark Dickinsoncf28b952010-07-29 21:41:59 +00001364 /* Free any s_codes value left over from a previous initialization. */
1365 if (self->s_codes != NULL)
1366 PyMem_FREE(self->s_codes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 s = fmt;
1370 size = 0;
1371 while ((c = *s++) != '\0') {
Jordon Xu2ec70102019-09-11 00:04:08 +08001372 if (Py_ISSPACE(c))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 continue;
1374 if ('0' <= c && c <= '9') {
1375 num = c - '0';
1376 while ('0' <= (c = *s++) && c <= '9')
1377 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 }
1379 else
1380 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 size = align(size, c, e);
1385 if (c == 's' || c == 'p') {
1386 codes->offset = size;
1387 codes->size = num;
1388 codes->fmtdef = e;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001389 codes->repeat = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 codes++;
1391 size += num;
1392 } else if (c == 'x') {
1393 size += num;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001394 } else if (num) {
1395 codes->offset = size;
1396 codes->size = e->size;
1397 codes->fmtdef = e;
1398 codes->repeat = num;
1399 codes++;
1400 size += e->size * num;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001401 }
1402 }
1403 codes->fmtdef = NULL;
1404 codes->offset = size;
1405 codes->size = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001406 codes->repeat = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 return 0;
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001409
1410 overflow:
Dino Viehland4f384af2019-09-10 11:18:37 +01001411 PyErr_SetString(_structmodulestate_global->StructError,
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001412 "total struct size too long");
1413 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001414}
1415
1416static PyObject *
1417s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1418{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001419 PyObject *self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001420
Dino Viehland4f384af2019-09-10 11:18:37 +01001421 assert(type != NULL);
1422 allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc);
1423 assert(alloc_func != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001424
Dino Viehland4f384af2019-09-10 11:18:37 +01001425 self = alloc_func(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 if (self != NULL) {
1427 PyStructObject *s = (PyStructObject*)self;
1428 Py_INCREF(Py_None);
1429 s->s_format = Py_None;
1430 s->s_codes = NULL;
1431 s->s_size = -1;
1432 s->s_len = -1;
1433 }
1434 return self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001435}
1436
Victor Stinner3f2d1012017-02-02 12:09:30 +01001437/*[clinic input]
1438Struct.__init__
1439
1440 format: object
1441
1442Create a compiled struct object.
1443
1444Return a new Struct object which writes and reads binary data according to
1445the format string.
1446
1447See help(struct) for more on format strings.
1448[clinic start generated code]*/
1449
Thomas Wouters477c8d52006-05-27 19:21:47 +00001450static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001451Struct___init___impl(PyStructObject *self, PyObject *format)
1452/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001453{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 int ret = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001455
Victor Stinner3f2d1012017-02-02 12:09:30 +01001456 if (PyUnicode_Check(format)) {
1457 format = PyUnicode_AsASCIIString(format);
1458 if (format == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 return -1;
1460 }
1461 /* XXX support buffer interface, too */
1462 else {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001463 Py_INCREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001465
Victor Stinner3f2d1012017-02-02 12:09:30 +01001466 if (!PyBytes_Check(format)) {
1467 Py_DECREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 PyErr_Format(PyExc_TypeError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001469 "Struct() argument 1 must be a str or bytes object, "
1470 "not %.200s",
Dino Viehland4f384af2019-09-10 11:18:37 +01001471 _PyType_Name(Py_TYPE(format)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 return -1;
1473 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001474
Xiang Zhang96f50282017-05-15 11:53:51 +08001475 Py_SETREF(self->s_format, format);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001476
Victor Stinner3f2d1012017-02-02 12:09:30 +01001477 ret = prepare_s(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 return ret;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001479}
1480
1481static void
1482s_dealloc(PyStructObject *s)
1483{
Dino Viehland4f384af2019-09-10 11:18:37 +01001484 PyTypeObject *tp = Py_TYPE(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 if (s->weakreflist != NULL)
1486 PyObject_ClearWeakRefs((PyObject *)s);
1487 if (s->s_codes != NULL) {
1488 PyMem_FREE(s->s_codes);
1489 }
Dino Viehland4f384af2019-09-10 11:18:37 +01001490 Py_XDECREF(s->s_format);
1491 freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free);
1492 free_func(s);
1493 Py_DECREF(tp);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001494}
1495
1496static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001497s_unpack_internal(PyStructObject *soself, const char *startfrom) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 formatcode *code;
1499 Py_ssize_t i = 0;
1500 PyObject *result = PyTuple_New(soself->s_len);
1501 if (result == NULL)
1502 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001503
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001505 const formatdef *e = code->fmtdef;
1506 const char *res = startfrom + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001507 Py_ssize_t j = code->repeat;
1508 while (j--) {
1509 PyObject *v;
1510 if (e->format == 's') {
1511 v = PyBytes_FromStringAndSize(res, code->size);
1512 } else if (e->format == 'p') {
1513 Py_ssize_t n = *(unsigned char*)res;
1514 if (n >= code->size)
1515 n = code->size - 1;
1516 v = PyBytes_FromStringAndSize(res + 1, n);
1517 } else {
1518 v = e->unpack(res, e);
1519 }
1520 if (v == NULL)
1521 goto fail;
1522 PyTuple_SET_ITEM(result, i++, v);
1523 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001524 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001525 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001526
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001527 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001528fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 Py_DECREF(result);
1530 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001531}
1532
1533
Victor Stinner3f2d1012017-02-02 12:09:30 +01001534/*[clinic input]
1535Struct.unpack
1536
1537 buffer: Py_buffer
1538 /
1539
1540Return a tuple containing unpacked values.
1541
1542Unpack according to the format string Struct.format. The buffer's size
1543in bytes must be Struct.size.
1544
1545See help(struct) for more on format strings.
1546[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001547
1548static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001549Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1550/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001551{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001552 assert(self->s_codes != NULL);
1553 if (buffer->len != self->s_size) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001554 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001555 "unpack requires a buffer of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001556 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 return NULL;
1558 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001559 return s_unpack_internal(self, buffer->buf);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001560}
1561
Victor Stinner3f2d1012017-02-02 12:09:30 +01001562/*[clinic input]
1563Struct.unpack_from
1564
1565 buffer: Py_buffer
1566 offset: Py_ssize_t = 0
1567
1568Return a tuple containing unpacked values.
1569
1570Values are unpacked according to the format string Struct.format.
1571
Xiang Zhangc10b2882018-03-11 02:58:52 +08001572The buffer's size in bytes, starting at position offset, must be
1573at least Struct.size.
Victor Stinner3f2d1012017-02-02 12:09:30 +01001574
1575See help(struct) for more on format strings.
1576[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001577
1578static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001579Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1580 Py_ssize_t offset)
Xiang Zhangc10b2882018-03-11 02:58:52 +08001581/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001582{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001583 assert(self->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001584
Xiang Zhangc10b2882018-03-11 02:58:52 +08001585 if (offset < 0) {
1586 if (offset + self->s_size > 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001587 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001588 "not enough data to unpack %zd bytes at offset %zd",
1589 self->s_size,
1590 offset);
1591 return NULL;
1592 }
1593
1594 if (offset + buffer->len < 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001595 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001596 "offset %zd out of range for %zd-byte buffer",
1597 offset,
1598 buffer->len);
1599 return NULL;
1600 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001601 offset += buffer->len;
Xiang Zhangc10b2882018-03-11 02:58:52 +08001602 }
1603
1604 if ((buffer->len - offset) < self->s_size) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001605 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001606 "unpack_from requires a buffer of at least %zu bytes for "
1607 "unpacking %zd bytes at offset %zd "
1608 "(actual buffer size is %zd)",
1609 (size_t)self->s_size + (size_t)offset,
1610 self->s_size,
1611 offset,
1612 buffer->len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001613 return NULL;
1614 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001615 return s_unpack_internal(self, (char*)buffer->buf + offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001616}
1617
1618
Victor Stinner3f2d1012017-02-02 12:09:30 +01001619
Antoine Pitrou9f146812013-04-27 00:20:04 +02001620/* Unpack iterator type */
1621
1622typedef struct {
1623 PyObject_HEAD
1624 PyStructObject *so;
1625 Py_buffer buf;
1626 Py_ssize_t index;
1627} unpackiterobject;
1628
1629static void
1630unpackiter_dealloc(unpackiterobject *self)
1631{
INADA Naokia6296d32017-08-24 14:55:17 +09001632 /* bpo-31095: UnTrack is needed before calling any callbacks */
Dino Viehland4f384af2019-09-10 11:18:37 +01001633 PyTypeObject *tp = Py_TYPE(self);
INADA Naokia6296d32017-08-24 14:55:17 +09001634 PyObject_GC_UnTrack(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001635 Py_XDECREF(self->so);
1636 PyBuffer_Release(&self->buf);
1637 PyObject_GC_Del(self);
Dino Viehland4f384af2019-09-10 11:18:37 +01001638 Py_DECREF(tp);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001639}
1640
1641static int
1642unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1643{
1644 Py_VISIT(self->so);
1645 Py_VISIT(self->buf.obj);
1646 return 0;
1647}
1648
1649static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301650unpackiter_len(unpackiterobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou9f146812013-04-27 00:20:04 +02001651{
1652 Py_ssize_t len;
1653 if (self->so == NULL)
1654 len = 0;
1655 else
1656 len = (self->buf.len - self->index) / self->so->s_size;
1657 return PyLong_FromSsize_t(len);
1658}
1659
1660static PyMethodDef unpackiter_methods[] = {
1661 {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1662 {NULL, NULL} /* sentinel */
1663};
1664
1665static PyObject *
1666unpackiter_iternext(unpackiterobject *self)
1667{
1668 PyObject *result;
1669 if (self->so == NULL)
1670 return NULL;
1671 if (self->index >= self->buf.len) {
1672 /* Iterator exhausted */
1673 Py_CLEAR(self->so);
1674 PyBuffer_Release(&self->buf);
1675 return NULL;
1676 }
1677 assert(self->index + self->so->s_size <= self->buf.len);
1678 result = s_unpack_internal(self->so,
1679 (char*) self->buf.buf + self->index);
1680 self->index += self->so->s_size;
1681 return result;
1682}
1683
Dino Viehland4f384af2019-09-10 11:18:37 +01001684PyObject *unpackiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1685 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s objects", _PyType_Name(type));
1686 return NULL;
1687}
1688
1689static PyType_Slot unpackiter_type_slots[] = {
1690 {Py_tp_dealloc, unpackiter_dealloc},
1691 {Py_tp_getattro, PyObject_GenericGetAttr},
1692 {Py_tp_traverse, unpackiter_traverse},
1693 {Py_tp_iter, PyObject_SelfIter},
1694 {Py_tp_iternext, unpackiter_iternext},
1695 {Py_tp_methods, unpackiter_methods},
1696 {Py_tp_new, unpackiter_new},
1697 {0, 0},
1698};
1699
1700static PyType_Spec unpackiter_type_spec = {
1701 "_struct.unpack_iterator",
1702 sizeof(unpackiterobject),
1703 0,
1704 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1705 unpackiter_type_slots
Antoine Pitrou9f146812013-04-27 00:20:04 +02001706};
1707
Victor Stinner3f2d1012017-02-02 12:09:30 +01001708/*[clinic input]
1709Struct.iter_unpack
1710
1711 buffer: object
1712 /
1713
1714Return an iterator yielding tuples.
1715
1716Tuples are unpacked from the given bytes source, like a repeated
1717invocation of unpack_from().
1718
1719Requires that the bytes length be a multiple of the struct size.
1720[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001721
1722static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001723Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1724/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001725{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001726 unpackiterobject *iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001727
Victor Stinner3f2d1012017-02-02 12:09:30 +01001728 assert(self->s_codes != NULL);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001729
Victor Stinner3f2d1012017-02-02 12:09:30 +01001730 if (self->s_size == 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001731 PyErr_Format(_structmodulestate_global->StructError,
Antoine Pitrou9f146812013-04-27 00:20:04 +02001732 "cannot iteratively unpack with a struct of length 0");
1733 return NULL;
1734 }
1735
Dino Viehland4f384af2019-09-10 11:18:37 +01001736 iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)_structmodulestate_global->unpackiter_type, 0);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001737 if (iter == NULL)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001738 return NULL;
1739
Victor Stinner3f2d1012017-02-02 12:09:30 +01001740 if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1741 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001742 return NULL;
1743 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001744 if (iter->buf.len % self->s_size != 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001745 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001746 "iterative unpacking requires a buffer of "
1747 "a multiple of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001748 self->s_size);
1749 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001750 return NULL;
1751 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001752 Py_INCREF(self);
1753 iter->so = self;
1754 iter->index = 0;
1755 return (PyObject *)iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001756}
1757
1758
Thomas Wouters477c8d52006-05-27 19:21:47 +00001759/*
1760 * Guts of the pack function.
1761 *
1762 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1763 * argument for where to start processing the arguments for packing, and a
1764 * character buffer for writing the packed string. The caller must insure
1765 * that the buffer may contain the required length for packing the arguments.
1766 * 0 is returned on success, 1 is returned if there is an error.
1767 *
1768 */
1769static int
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001770s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* buf)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001771{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001772 formatcode *code;
1773 /* XXX(nnorwitz): why does i need to be a local? can we use
1774 the offset parameter or do we need the wider width? */
1775 Py_ssize_t i;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001776
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001777 memset(buf, '\0', soself->s_size);
1778 i = offset;
1779 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 const formatdef *e = code->fmtdef;
1781 char *res = buf + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001782 Py_ssize_t j = code->repeat;
1783 while (j--) {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001784 PyObject *v = args[i++];
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001785 if (e->format == 's') {
1786 Py_ssize_t n;
1787 int isstring;
Serhiy Storchaka8f87eef2020-04-12 14:58:27 +03001788 const void *p;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001789 isstring = PyBytes_Check(v);
1790 if (!isstring && !PyByteArray_Check(v)) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001791 PyErr_SetString(_structmodulestate_global->StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001792 "argument for 's' must be a bytes object");
1793 return -1;
1794 }
1795 if (isstring) {
1796 n = PyBytes_GET_SIZE(v);
1797 p = PyBytes_AS_STRING(v);
1798 }
1799 else {
1800 n = PyByteArray_GET_SIZE(v);
1801 p = PyByteArray_AS_STRING(v);
1802 }
1803 if (n > code->size)
1804 n = code->size;
1805 if (n > 0)
1806 memcpy(res, p, n);
1807 } else if (e->format == 'p') {
1808 Py_ssize_t n;
1809 int isstring;
Serhiy Storchaka8f87eef2020-04-12 14:58:27 +03001810 const void *p;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001811 isstring = PyBytes_Check(v);
1812 if (!isstring && !PyByteArray_Check(v)) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001813 PyErr_SetString(_structmodulestate_global->StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001814 "argument for 'p' must be a bytes object");
1815 return -1;
1816 }
1817 if (isstring) {
1818 n = PyBytes_GET_SIZE(v);
1819 p = PyBytes_AS_STRING(v);
1820 }
1821 else {
1822 n = PyByteArray_GET_SIZE(v);
1823 p = PyByteArray_AS_STRING(v);
1824 }
1825 if (n > (code->size - 1))
1826 n = code->size - 1;
1827 if (n > 0)
1828 memcpy(res + 1, p, n);
1829 if (n > 255)
1830 n = 255;
1831 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1832 } else {
1833 if (e->pack(res, v, e) < 0) {
1834 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +01001835 PyErr_SetString(_structmodulestate_global->StructError,
Serhiy Storchaka46e1ce22013-08-27 20:17:03 +03001836 "int too large to convert");
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001837 return -1;
1838 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001839 }
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001840 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001841 }
1842 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001843
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001844 /* Success */
1845 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001846}
1847
1848
1849PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001850"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001851\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001852Return a bytes object containing values v1, v2, ... packed according\n\
1853to the format string S.format. See help(struct) for more on format\n\
1854strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001855
1856static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001857s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001858{
Dino Viehland4f384af2019-09-10 11:18:37 +01001859 char *buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001860 PyStructObject *soself;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001861
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001862 /* Validate arguments. */
1863 soself = (PyStructObject *)self;
1864 assert(PyStruct_Check(self));
1865 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001866 if (nargs != soself->s_len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 {
Dino Viehland4f384af2019-09-10 11:18:37 +01001868 PyErr_Format(_structmodulestate_global->StructError,
Victor Stinner3f2d1012017-02-02 12:09:30 +01001869 "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1870 return NULL;
1871 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001872
Dino Viehland4f384af2019-09-10 11:18:37 +01001873 /* Allocate a new string */
1874 _PyBytesWriter writer;
1875 _PyBytesWriter_Init(&writer);
1876 buf = _PyBytesWriter_Alloc(&writer, soself->s_size);
1877 if (buf == NULL) {
1878 _PyBytesWriter_Dealloc(&writer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001879 return NULL;
1880 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001881
Dino Viehland4f384af2019-09-10 11:18:37 +01001882 /* Call the guts */
1883 if ( s_pack_internal(soself, args, 0, buf) != 0 ) {
1884 _PyBytesWriter_Dealloc(&writer);
1885 return NULL;
1886 }
1887
1888 return _PyBytesWriter_Finish(&writer, buf + soself->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001889}
1890
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001891PyDoc_STRVAR(s_pack_into__doc__,
1892"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001893\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001894Pack the values v1, v2, ... according to the format string S.format\n\
1895and write the packed bytes into the writable buffer buf starting at\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00001896offset. Note that the offset is a required argument. See\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001897help(struct) for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001898
1899static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001900s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001901{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001902 PyStructObject *soself;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001903 Py_buffer buffer;
1904 Py_ssize_t offset;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001905
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001906 /* Validate arguments. +1 is for the first arg as buffer. */
1907 soself = (PyStructObject *)self;
1908 assert(PyStruct_Check(self));
1909 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001910 if (nargs != (soself->s_len + 2))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001911 {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001912 if (nargs == 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001913 PyErr_Format(_structmodulestate_global->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001914 "pack_into expected buffer argument");
1915 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001916 else if (nargs == 1) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001917 PyErr_Format(_structmodulestate_global->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001918 "pack_into expected offset argument");
1919 }
1920 else {
Dino Viehland4f384af2019-09-10 11:18:37 +01001921 PyErr_Format(_structmodulestate_global->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001922 "pack_into expected %zd items for packing (got %zd)",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001923 soself->s_len, (nargs - 2));
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001924 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 return NULL;
1926 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001927
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001928 /* Extract a writable memory buffer from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001929 if (!PyArg_Parse(args[0], "w*", &buffer))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001930 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001931 assert(buffer.len >= 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001932
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001933 /* Extract the offset from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001934 offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001935 if (offset == -1 && PyErr_Occurred()) {
1936 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001937 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001938 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001940 /* Support negative offsets. */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001941 if (offset < 0) {
1942 /* Check that negative offset is low enough to fit data */
1943 if (offset + soself->s_size > 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001944 PyErr_Format(_structmodulestate_global->StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001945 "no space to pack %zd bytes at offset %zd",
1946 soself->s_size,
1947 offset);
1948 PyBuffer_Release(&buffer);
1949 return NULL;
1950 }
1951
1952 /* Check that negative offset is not crossing buffer boundary */
1953 if (offset + buffer.len < 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001954 PyErr_Format(_structmodulestate_global->StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001955 "offset %zd out of range for %zd-byte buffer",
1956 offset,
1957 buffer.len);
1958 PyBuffer_Release(&buffer);
1959 return NULL;
1960 }
1961
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001962 offset += buffer.len;
Andrew Nesterf78b1192017-04-04 13:46:25 +03001963 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001965 /* Check boundaries */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001966 if ((buffer.len - offset) < soself->s_size) {
Johan Liuaead53b2017-06-02 14:33:04 +08001967 assert(offset >= 0);
1968 assert(soself->s_size >= 0);
1969
Dino Viehland4f384af2019-09-10 11:18:37 +01001970 PyErr_Format(_structmodulestate_global->StructError,
Johan Liuaead53b2017-06-02 14:33:04 +08001971 "pack_into requires a buffer of at least %zu bytes for "
Andrew Nesterf78b1192017-04-04 13:46:25 +03001972 "packing %zd bytes at offset %zd "
1973 "(actual buffer size is %zd)",
Johan Liuaead53b2017-06-02 14:33:04 +08001974 (size_t)soself->s_size + (size_t)offset,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001975 soself->s_size,
1976 offset,
1977 buffer.len);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001978 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 return NULL;
1980 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001981
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001982 /* Call the guts */
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001983 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
1984 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001985 return NULL;
1986 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001987
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001988 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001989 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001990}
1991
1992static PyObject *
1993s_get_format(PyStructObject *self, void *unused)
1994{
Victor Stinnerf87b85f2017-06-23 15:11:12 +02001995 return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
1996 PyBytes_GET_SIZE(self->s_format));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001997}
1998
1999static PyObject *
2000s_get_size(PyStructObject *self, void *unused)
2001{
Christian Heimes217cfd12007-12-02 14:31:20 +00002002 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002003}
2004
Meador Ingeb14d8c92012-07-23 10:01:29 -05002005PyDoc_STRVAR(s_sizeof__doc__,
2006"S.__sizeof__() -> size of S in memory, in bytes");
2007
2008static PyObject *
Meador Inge90bc2dbc2012-07-28 22:16:39 -05002009s_sizeof(PyStructObject *self, void *unused)
Meador Ingeb14d8c92012-07-23 10:01:29 -05002010{
2011 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002012 formatcode *code;
Meador Ingeb14d8c92012-07-23 10:01:29 -05002013
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002014 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002015 for (code = self->s_codes; code->fmtdef != NULL; code++)
2016 size += sizeof(formatcode);
Meador Ingeb14d8c92012-07-23 10:01:29 -05002017 return PyLong_FromSsize_t(size);
2018}
2019
Thomas Wouters477c8d52006-05-27 19:21:47 +00002020/* List of functions */
2021
2022static struct PyMethodDef s_methods[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002023 STRUCT_ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002024 {"pack", (PyCFunction)(void(*)(void))s_pack, METH_FASTCALL, s_pack__doc__},
2025 {"pack_into", (PyCFunction)(void(*)(void))s_pack_into, METH_FASTCALL, s_pack_into__doc__},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002026 STRUCT_UNPACK_METHODDEF
2027 STRUCT_UNPACK_FROM_METHODDEF
Meador Ingeb14d8c92012-07-23 10:01:29 -05002028 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002029 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002030};
2031
Dino Viehland4f384af2019-09-10 11:18:37 +01002032static PyMemberDef s_members[] = {
Eddie Elizondo3368f3c2019-09-19 09:29:05 -07002033 {"__weaklistoffset__", T_PYSSIZET, offsetof(PyStructObject, weakreflist), READONLY},
Dino Viehland4f384af2019-09-10 11:18:37 +01002034 {NULL} /* sentinel */
2035};
2036
Thomas Wouters477c8d52006-05-27 19:21:47 +00002037#define OFF(x) offsetof(PyStructObject, x)
2038
2039static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002040 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
2041 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
2042 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002043};
2044
Dino Viehland4f384af2019-09-10 11:18:37 +01002045PyDoc_STRVAR(s__doc__,
2046"Struct(fmt) --> compiled struct object\n"
2047"\n"
2048);
2049
2050static PyType_Slot PyStructType_slots[] = {
2051 {Py_tp_dealloc, s_dealloc},
2052 {Py_tp_getattro, PyObject_GenericGetAttr},
2053 {Py_tp_setattro, PyObject_GenericSetAttr},
2054 {Py_tp_doc, (void*)s__doc__},
2055 {Py_tp_methods, s_methods},
2056 {Py_tp_members, s_members},
2057 {Py_tp_getset, s_getsetlist},
2058 {Py_tp_init, Struct___init__},
2059 {Py_tp_alloc, PyType_GenericAlloc},
2060 {Py_tp_new, s_new},
2061 {Py_tp_free, PyObject_Del},
2062 {0, 0},
2063};
2064
2065static PyType_Spec PyStructType_spec = {
2066 "_struct.Struct",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002067 sizeof(PyStructObject),
2068 0,
Dino Viehland4f384af2019-09-10 11:18:37 +01002069 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
2070 PyStructType_slots
Thomas Wouters477c8d52006-05-27 19:21:47 +00002071};
2072
Christian Heimesa34706f2008-01-04 03:06:10 +00002073
2074/* ---- Standalone functions ---- */
2075
2076#define MAXCACHE 100
2077static PyObject *cache = NULL;
2078
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002079static int
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002080cache_struct_converter(PyObject *fmt, PyStructObject **ptr)
Christian Heimesa34706f2008-01-04 03:06:10 +00002081{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002082 PyObject * s_object;
Christian Heimesa34706f2008-01-04 03:06:10 +00002083
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002084 if (fmt == NULL) {
2085 Py_DECREF(*ptr);
Serhiy Storchaka40db90c2017-04-20 21:19:31 +03002086 *ptr = NULL;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002087 return 1;
2088 }
2089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002090 if (cache == NULL) {
2091 cache = PyDict_New();
2092 if (cache == NULL)
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002093 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002094 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002095
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002096 s_object = PyDict_GetItemWithError(cache, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002097 if (s_object != NULL) {
2098 Py_INCREF(s_object);
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002099 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002100 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002102 else if (PyErr_Occurred()) {
2103 return 0;
2104 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002105
Petr Viktorinffd97532020-02-11 17:46:57 +01002106 s_object = PyObject_CallOneArg(_structmodulestate_global->PyStructType, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002107 if (s_object != NULL) {
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02002108 if (PyDict_GET_SIZE(cache) >= MAXCACHE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 PyDict_Clear(cache);
2110 /* Attempt to cache the result */
2111 if (PyDict_SetItem(cache, fmt, s_object) == -1)
2112 PyErr_Clear();
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002113 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002114 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002115 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002116 return 0;
Christian Heimesa34706f2008-01-04 03:06:10 +00002117}
2118
Victor Stinner3f2d1012017-02-02 12:09:30 +01002119/*[clinic input]
2120_clearcache
2121
2122Clear the internal cache.
2123[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002124
2125static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002126_clearcache_impl(PyObject *module)
2127/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002128{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002129 Py_CLEAR(cache);
2130 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00002131}
2132
Victor Stinner3f2d1012017-02-02 12:09:30 +01002133
2134/*[clinic input]
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002135calcsize -> Py_ssize_t
Victor Stinner3f2d1012017-02-02 12:09:30 +01002136
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002137 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002138 /
2139
2140Return size in bytes of the struct described by the format string.
2141[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002142
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002143static Py_ssize_t
2144calcsize_impl(PyObject *module, PyStructObject *s_object)
2145/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002146{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002147 return s_object->s_size;
Christian Heimesa34706f2008-01-04 03:06:10 +00002148}
2149
2150PyDoc_STRVAR(pack_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002151"pack(format, v1, v2, ...) -> bytes\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002152\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002153Return a bytes object containing the values v1, v2, ... packed according\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002154to the format string. See help(struct) for more on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002155
2156static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02002157pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002158{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002159 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002160 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002161
Victor Stinner3f2d1012017-02-02 12:09:30 +01002162 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 PyErr_SetString(PyExc_TypeError, "missing format argument");
2164 return NULL;
2165 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002166 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002167
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002168 if (!cache_struct_converter(format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002169 return NULL;
2170 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002171 result = s_pack(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002172 Py_DECREF(s_object);
2173 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002174}
2175
2176PyDoc_STRVAR(pack_into_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002177"pack_into(format, buffer, offset, v1, v2, ...)\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002178\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002179Pack the values v1, v2, ... according to the format string and write\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002180the packed bytes into the writable buffer buf starting at offset. Note\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002181that the offset is a required argument. See help(struct) for more\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002182on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002183
2184static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02002185pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002186{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002187 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002188 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002189
Victor Stinner3f2d1012017-02-02 12:09:30 +01002190 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 PyErr_SetString(PyExc_TypeError, "missing format argument");
2192 return NULL;
2193 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002194 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002195
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002196 if (!cache_struct_converter(format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002197 return NULL;
2198 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002199 result = s_pack_into(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002200 Py_DECREF(s_object);
2201 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002202}
2203
Victor Stinner3f2d1012017-02-02 12:09:30 +01002204/*[clinic input]
2205unpack
2206
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002207 format as s_object: cache_struct
Victor Stinnerc0f59ad2017-02-02 14:24:16 +01002208 buffer: Py_buffer
Victor Stinner3f2d1012017-02-02 12:09:30 +01002209 /
2210
2211Return a tuple containing values unpacked according to the format string.
2212
2213The buffer's size in bytes must be calcsize(format).
2214
2215See help(struct) for more on format strings.
2216[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002217
2218static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002219unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2220/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002221{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002222 return Struct_unpack_impl(s_object, buffer);
Christian Heimesa34706f2008-01-04 03:06:10 +00002223}
2224
Victor Stinner3f2d1012017-02-02 12:09:30 +01002225/*[clinic input]
2226unpack_from
2227
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002228 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002229 /
2230 buffer: Py_buffer
2231 offset: Py_ssize_t = 0
2232
2233Return a tuple containing values unpacked according to the format string.
2234
2235The buffer's size, minus offset, must be at least calcsize(format).
2236
2237See help(struct) for more on format strings.
2238[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002239
2240static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002241unpack_from_impl(PyObject *module, PyStructObject *s_object,
2242 Py_buffer *buffer, Py_ssize_t offset)
2243/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002244{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002245 return Struct_unpack_from_impl(s_object, buffer, offset);
Christian Heimesa34706f2008-01-04 03:06:10 +00002246}
2247
Victor Stinner3f2d1012017-02-02 12:09:30 +01002248/*[clinic input]
2249iter_unpack
2250
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002251 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002252 buffer: object
2253 /
2254
2255Return an iterator yielding tuples unpacked from the given bytes.
2256
2257The bytes are unpacked according to the format string, like
2258a repeated invocation of unpack_from().
2259
2260Requires that the bytes length be a multiple of the format struct size.
2261[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002262
2263static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002264iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2265 PyObject *buffer)
2266/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002267{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002268 return Struct_iter_unpack(s_object, buffer);
Antoine Pitrou9f146812013-04-27 00:20:04 +02002269}
2270
Christian Heimesa34706f2008-01-04 03:06:10 +00002271static struct PyMethodDef module_functions[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002272 _CLEARCACHE_METHODDEF
2273 CALCSIZE_METHODDEF
2274 ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002275 {"pack", (PyCFunction)(void(*)(void))pack, METH_FASTCALL, pack_doc},
2276 {"pack_into", (PyCFunction)(void(*)(void))pack_into, METH_FASTCALL, pack_into_doc},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002277 UNPACK_METHODDEF
2278 UNPACK_FROM_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002279 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00002280};
2281
2282
Thomas Wouters477c8d52006-05-27 19:21:47 +00002283/* Module initialization */
2284
Christian Heimesa34706f2008-01-04 03:06:10 +00002285PyDoc_STRVAR(module_doc,
2286"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002287Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002288and also as format strings (explained below) to describe the layout of data\n\
2289in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002290\n\
2291The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002292 @: native order, size & alignment (default)\n\
2293 =: native order, std. size & alignment\n\
2294 <: little-endian, std. size & alignment\n\
2295 >: big-endian, std. size & alignment\n\
2296 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002297\n\
2298The remaining chars indicate types of args and must match exactly;\n\
2299these can be preceded by a decimal repeat count:\n\
2300 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002301 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002302 h:short; H:unsigned short; i:int; I:unsigned int;\n\
Mark Dickinson7c4e4092016-09-03 17:21:29 +01002303 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002304Special cases (preceding decimal count indicates length):\n\
2305 s:string (array of char); p: pascal string (with count byte).\n\
Antoine Pitrou45d9c912011-10-06 15:27:40 +02002306Special cases (only available in native format):\n\
2307 n:ssize_t; N:size_t;\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002308 P:an integer type that is wide enough to hold a pointer.\n\
2309Special case (not in native mode unless 'long long' in platform C):\n\
2310 q:long long; Q:unsigned long long\n\
2311Whitespace between formats is ignored.\n\
2312\n\
2313The variable struct.error is an exception raised on errors.\n");
2314
Martin v. Löwis1a214512008-06-11 05:26:20 +00002315
Dino Viehland4f384af2019-09-10 11:18:37 +01002316static int
2317_structmodule_traverse(PyObject *module, visitproc visit, void *arg)
2318{
Hai Shif707d942020-03-16 21:15:01 +08002319 _structmodulestate *state = (_structmodulestate *)PyModule_GetState(module);
2320 if (state) {
2321 Py_VISIT(state->PyStructType);
2322 Py_VISIT(state->unpackiter_type);
2323 Py_VISIT(state->StructError);
2324 }
Dino Viehland4f384af2019-09-10 11:18:37 +01002325 return 0;
2326}
2327
2328static int
2329_structmodule_clear(PyObject *module)
2330{
Hai Shif707d942020-03-16 21:15:01 +08002331 _structmodulestate *state = (_structmodulestate *)PyModule_GetState(module);
2332 if (state) {
2333 Py_CLEAR(state->PyStructType);
2334 Py_CLEAR(state->unpackiter_type);
2335 Py_CLEAR(state->StructError);
2336 }
Dino Viehland4f384af2019-09-10 11:18:37 +01002337 return 0;
2338}
2339
2340static void
2341_structmodule_free(void *module)
2342{
2343 _structmodule_clear((PyObject *)module);
2344}
2345
Martin v. Löwis1a214512008-06-11 05:26:20 +00002346static struct PyModuleDef _structmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002347 PyModuleDef_HEAD_INIT,
2348 "_struct",
2349 module_doc,
Dino Viehland4f384af2019-09-10 11:18:37 +01002350 sizeof(_structmodulestate),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 module_functions,
2352 NULL,
Dino Viehland4f384af2019-09-10 11:18:37 +01002353 _structmodule_traverse,
2354 _structmodule_clear,
2355 _structmodule_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +00002356};
2357
Thomas Wouters477c8d52006-05-27 19:21:47 +00002358PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002359PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002360{
Mark Dickinson06817852010-06-12 09:25:13 +00002361 PyObject *m;
Christian Heimesa34706f2008-01-04 03:06:10 +00002362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002363 m = PyModule_Create(&_structmodule);
2364 if (m == NULL)
2365 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002366
Dino Viehland4f384af2019-09-10 11:18:37 +01002367 PyObject *PyStructType = PyType_FromSpec(&PyStructType_spec);
2368 if (PyStructType == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002369 return NULL;
Dino Viehland4f384af2019-09-10 11:18:37 +01002370 }
2371 Py_INCREF(PyStructType);
2372 PyModule_AddObject(m, "Struct", PyStructType);
Hai Shif707d942020-03-16 21:15:01 +08002373 get_struct_state(m)->PyStructType = PyStructType;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002374
Dino Viehland4f384af2019-09-10 11:18:37 +01002375 PyObject *unpackiter_type = PyType_FromSpec(&unpackiter_type_spec);
2376 if (unpackiter_type == NULL) {
Zachary Ware99f11b42016-10-04 01:20:21 -05002377 return NULL;
Dino Viehland4f384af2019-09-10 11:18:37 +01002378 }
Hai Shif707d942020-03-16 21:15:01 +08002379 get_struct_state(m)->unpackiter_type = unpackiter_type;
Zachary Ware99f11b42016-10-04 01:20:21 -05002380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002381 /* Check endian and swap in faster functions */
2382 {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002383 const formatdef *native = native_table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002384 formatdef *other, *ptr;
Christian Heimes743e0cd2012-10-17 23:52:17 +02002385#if PY_LITTLE_ENDIAN
2386 other = lilendian_table;
2387#else
2388 other = bigendian_table;
2389#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002390 /* Scan through the native table, find a matching
2391 entry in the endian table and swap in the
2392 native implementations whenever possible
2393 (64-bit platforms may not have "standard" sizes) */
2394 while (native->format != '\0' && other->format != '\0') {
2395 ptr = other;
2396 while (ptr->format != '\0') {
2397 if (ptr->format == native->format) {
2398 /* Match faster when formats are
2399 listed in the same order */
2400 if (ptr == other)
2401 other++;
2402 /* Only use the trick if the
2403 size matches */
2404 if (ptr->size != native->size)
2405 break;
2406 /* Skip float and double, could be
2407 "unknown" float format */
2408 if (ptr->format == 'd' || ptr->format == 'f')
2409 break;
Stefan Krah472fc842020-03-24 14:01:13 +01002410 /* Skip _Bool, semantics are different for standard size */
2411 if (ptr->format == '?')
2412 break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002413 ptr->pack = native->pack;
2414 ptr->unpack = native->unpack;
2415 break;
2416 }
2417 ptr++;
2418 }
2419 native++;
2420 }
2421 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002422
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002423 /* Add some symbolic constants to the module */
Dino Viehland4f384af2019-09-10 11:18:37 +01002424 PyObject *StructError = PyErr_NewException("struct.error", NULL, NULL);
2425 if (StructError == NULL)
2426 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002427 Py_INCREF(StructError);
2428 PyModule_AddObject(m, "error", StructError);
Hai Shif707d942020-03-16 21:15:01 +08002429 get_struct_state(m)->StructError = StructError;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002431 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002432}