blob: eed3659ed884fb43811d16e77903af8e80ec6c3b [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"
Thomas Wouters477c8d52006-05-27 19:21:47 +00009#include "structmember.h"
10#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
23#define _structmodulestate(o) ((_structmodulestate *)PyModule_GetState(o))
24
25static struct PyModuleDef _structmodule;
26
27#define _structmodulestate_global _structmodulestate(PyState_FindModule(&_structmodule))
Thomas Wouters477c8d52006-05-27 19:21:47 +000028
Thomas Wouters477c8d52006-05-27 19:21:47 +000029/* The translation function for each format character is table driven */
30typedef struct _formatdef {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000031 char format;
32 Py_ssize_t size;
33 Py_ssize_t alignment;
34 PyObject* (*unpack)(const char *,
35 const struct _formatdef *);
36 int (*pack)(char *, PyObject *,
37 const struct _formatdef *);
Thomas Wouters477c8d52006-05-27 19:21:47 +000038} formatdef;
39
40typedef struct _formatcode {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000041 const struct _formatdef *fmtdef;
42 Py_ssize_t offset;
43 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +030044 Py_ssize_t repeat;
Thomas Wouters477c8d52006-05-27 19:21:47 +000045} formatcode;
46
47/* Struct object interface */
48
49typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000050 PyObject_HEAD
51 Py_ssize_t s_size;
52 Py_ssize_t s_len;
53 formatcode *s_codes;
54 PyObject *s_format;
55 PyObject *weakreflist; /* List of weak references */
Thomas Wouters477c8d52006-05-27 19:21:47 +000056} PyStructObject;
57
58
Dino Viehland4f384af2019-09-10 11:18:37 +010059#define PyStruct_Check(op) PyObject_TypeCheck(op, (PyTypeObject *)_structmodulestate_global->PyStructType)
Dong-hee Na1b55b652020-02-17 19:09:15 +090060#define PyStruct_CheckExact(op) Py_IS_TYPE(op, (PyTypeObject *)_structmodulestate_global->PyStructType)
Thomas Wouters477c8d52006-05-27 19:21:47 +000061
62
63/* Define various structs to figure out the alignments of types */
64
65
66typedef struct { char c; short x; } st_short;
67typedef struct { char c; int x; } st_int;
68typedef struct { char c; long x; } st_long;
69typedef struct { char c; float x; } st_float;
70typedef struct { char c; double x; } st_double;
71typedef struct { char c; void *x; } st_void_p;
Antoine Pitrou45d9c912011-10-06 15:27:40 +020072typedef struct { char c; size_t x; } st_size_t;
Benjamin Petersona9296e72016-09-07 11:06:17 -070073typedef struct { char c; _Bool x; } st_bool;
Thomas Wouters477c8d52006-05-27 19:21:47 +000074
75#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
76#define INT_ALIGN (sizeof(st_int) - sizeof(int))
77#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
78#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
79#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
80#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
Antoine Pitrou45d9c912011-10-06 15:27:40 +020081#define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t))
Benjamin Petersona9296e72016-09-07 11:06:17 -070082#define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool))
Thomas Wouters477c8d52006-05-27 19:21:47 +000083
84/* We can't support q and Q in native mode unless the compiler does;
85 in std mode, they're 8 bytes on all platforms. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -070086typedef struct { char c; long long x; } s_long_long;
87#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long))
Thomas Wouters477c8d52006-05-27 19:21:47 +000088
Thomas Wouters477c8d52006-05-27 19:21:47 +000089#ifdef __powerc
90#pragma options align=reset
91#endif
92
Serhiy Storchakaa5a55902017-02-04 11:14:52 +020093/*[python input]
94class cache_struct_converter(CConverter):
95 type = 'PyStructObject *'
96 converter = 'cache_struct_converter'
97 c_default = "NULL"
98
99 def cleanup(self):
100 return "Py_XDECREF(%s);\n" % self.name
101[python start generated code]*/
102/*[python end generated code: output=da39a3ee5e6b4b0d input=49957cca130ffb63]*/
103
Serhiy Storchaka32d96a22018-12-25 13:23:47 +0200104static int cache_struct_converter(PyObject *, PyStructObject **);
Serhiy Storchakaa5a55902017-02-04 11:14:52 +0200105
Victor Stinner3f2d1012017-02-02 12:09:30 +0100106#include "clinic/_struct.c.h"
107
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000108/* Helper for integer format codes: converts an arbitrary Python object to a
109 PyLongObject if possible, otherwise fails. Caller should decref. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000110
111static PyObject *
112get_pylong(PyObject *v)
113{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 assert(v != NULL);
115 if (!PyLong_Check(v)) {
116 /* Not an integer; try to use __index__ to convert. */
117 if (PyIndex_Check(v)) {
118 v = PyNumber_Index(v);
119 if (v == NULL)
120 return NULL;
121 }
122 else {
Dino Viehland4f384af2019-09-10 11:18:37 +0100123 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 "required argument is not an integer");
125 return NULL;
126 }
127 }
128 else
129 Py_INCREF(v);
Mark Dickinsonea835e72009-04-19 20:40:33 +0000130
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000131 assert(PyLong_Check(v));
132 return v;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000133}
134
Mark Dickinsonea835e72009-04-19 20:40:33 +0000135/* Helper routine to get a C long and raise the appropriate error if it isn't
136 one */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000137
138static int
139get_long(PyObject *v, long *p)
140{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000141 long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000142
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000143 v = get_pylong(v);
144 if (v == NULL)
145 return -1;
146 assert(PyLong_Check(v));
147 x = PyLong_AsLong(v);
148 Py_DECREF(v);
149 if (x == (long)-1 && PyErr_Occurred()) {
150 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100151 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 "argument out of range");
153 return -1;
154 }
155 *p = x;
156 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000157}
158
159
160/* Same, but handling unsigned long */
161
162static int
163get_ulong(PyObject *v, unsigned long *p)
164{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 unsigned long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000166
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000167 v = get_pylong(v);
168 if (v == NULL)
169 return -1;
170 assert(PyLong_Check(v));
171 x = PyLong_AsUnsignedLong(v);
172 Py_DECREF(v);
173 if (x == (unsigned long)-1 && PyErr_Occurred()) {
174 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100175 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 "argument out of range");
177 return -1;
178 }
179 *p = x;
180 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000181}
182
Thomas Wouters477c8d52006-05-27 19:21:47 +0000183/* Same, but handling native long long. */
184
185static int
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700186get_longlong(PyObject *v, long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000187{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700188 long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000189
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000190 v = get_pylong(v);
191 if (v == NULL)
192 return -1;
193 assert(PyLong_Check(v));
194 x = PyLong_AsLongLong(v);
195 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700196 if (x == (long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100198 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 "argument out of range");
200 return -1;
201 }
202 *p = x;
203 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000204}
205
206/* Same, but handling native unsigned long long. */
207
208static int
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700209get_ulonglong(PyObject *v, unsigned long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000210{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700211 unsigned long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 v = get_pylong(v);
214 if (v == NULL)
215 return -1;
216 assert(PyLong_Check(v));
217 x = PyLong_AsUnsignedLongLong(v);
218 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700219 if (x == (unsigned long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100221 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 "argument out of range");
223 return -1;
224 }
225 *p = x;
226 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000227}
228
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200229/* Same, but handling Py_ssize_t */
230
231static int
232get_ssize_t(PyObject *v, Py_ssize_t *p)
233{
234 Py_ssize_t x;
235
236 v = get_pylong(v);
237 if (v == NULL)
238 return -1;
239 assert(PyLong_Check(v));
240 x = PyLong_AsSsize_t(v);
241 Py_DECREF(v);
242 if (x == (Py_ssize_t)-1 && PyErr_Occurred()) {
243 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100244 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200245 "argument out of range");
246 return -1;
247 }
248 *p = x;
249 return 0;
250}
251
252/* Same, but handling size_t */
253
254static int
255get_size_t(PyObject *v, size_t *p)
256{
257 size_t x;
258
259 v = get_pylong(v);
260 if (v == NULL)
261 return -1;
262 assert(PyLong_Check(v));
263 x = PyLong_AsSize_t(v);
264 Py_DECREF(v);
265 if (x == (size_t)-1 && PyErr_Occurred()) {
266 if (PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +0100267 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200268 "argument out of range");
269 return -1;
270 }
271 *p = x;
272 return 0;
273}
274
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000275
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000276#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
277
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000278
Thomas Wouters477c8d52006-05-27 19:21:47 +0000279/* Floating point helpers */
280
281static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100282unpack_halffloat(const char *p, /* start of 2-byte string */
283 int le) /* true for little-endian, false for big-endian */
284{
285 double x;
286
287 x = _PyFloat_Unpack2((unsigned char *)p, le);
288 if (x == -1.0 && PyErr_Occurred()) {
289 return NULL;
290 }
291 return PyFloat_FromDouble(x);
292}
293
294static int
295pack_halffloat(char *p, /* start of 2-byte string */
296 PyObject *v, /* value to pack */
297 int le) /* true for little-endian, false for big-endian */
298{
299 double x = PyFloat_AsDouble(v);
300 if (x == -1.0 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100301 PyErr_SetString(_structmodulestate_global->StructError,
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100302 "required argument is not a float");
303 return -1;
304 }
305 return _PyFloat_Pack2(x, (unsigned char *)p, le);
306}
307
308static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000309unpack_float(const char *p, /* start of 4-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000310 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 x = _PyFloat_Unpack4((unsigned char *)p, le);
315 if (x == -1.0 && PyErr_Occurred())
316 return NULL;
317 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000318}
319
320static PyObject *
321unpack_double(const char *p, /* start of 8-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000323{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 x = _PyFloat_Unpack8((unsigned char *)p, le);
327 if (x == -1.0 && PyErr_Occurred())
328 return NULL;
329 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000330}
331
332/* Helper to format the range error exceptions */
333static int
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000334_range_error(const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000335{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 /* ulargest is the largest unsigned value with f->size bytes.
337 * Note that the simpler:
338 * ((size_t)1 << (f->size * 8)) - 1
339 * doesn't work when f->size == sizeof(size_t) because C doesn't
340 * define what happens when a left shift count is >= the number of
341 * bits in the integer being shifted; e.g., on some boxes it doesn't
342 * shift at all when they're equal.
343 */
344 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
345 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
346 if (is_unsigned)
Dino Viehland4f384af2019-09-10 11:18:37 +0100347 PyErr_Format(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 "'%c' format requires 0 <= number <= %zu",
349 f->format,
350 ulargest);
351 else {
352 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
Dino Viehland4f384af2019-09-10 11:18:37 +0100353 PyErr_Format(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 "'%c' format requires %zd <= number <= %zd",
355 f->format,
356 ~ largest,
357 largest);
358 }
Mark Dickinsonae681df2009-03-21 10:26:31 +0000359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000360 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000361}
362
363
364
365/* A large number of small routines follow, with names of the form
366
367 [bln][up]_TYPE
368
Min ho Kimc4cacc82019-07-31 08:16:13 +1000369 [bln] distinguishes among big-endian, little-endian and native.
370 [pu] distinguishes between pack (to struct) and unpack (from struct).
Thomas Wouters477c8d52006-05-27 19:21:47 +0000371 TYPE is one of char, byte, ubyte, etc.
372*/
373
374/* Native mode routines. ****************************************************/
375/* NOTE:
376 In all n[up]_<type> routines handling types larger than 1 byte, there is
377 *no* guarantee that the p pointer is properly aligned for each type,
378 therefore memcpy is called. An intermediate variable is used to
379 compensate for big-endian architectures.
380 Normally both the intermediate variable and the memcpy call will be
381 skipped by C optimisation in little-endian architectures (gcc >= 2.91
382 does this). */
383
384static PyObject *
385nu_char(const char *p, const formatdef *f)
386{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000387 return PyBytes_FromStringAndSize(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000388}
389
390static PyObject *
391nu_byte(const char *p, const formatdef *f)
392{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 return PyLong_FromLong((long) *(signed char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000394}
395
396static PyObject *
397nu_ubyte(const char *p, const formatdef *f)
398{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000399 return PyLong_FromLong((long) *(unsigned char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000400}
401
402static PyObject *
403nu_short(const char *p, const formatdef *f)
404{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000405 short x;
406 memcpy((char *)&x, p, sizeof x);
407 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000408}
409
410static PyObject *
411nu_ushort(const char *p, const formatdef *f)
412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 unsigned short x;
414 memcpy((char *)&x, p, sizeof x);
415 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000416}
417
418static PyObject *
419nu_int(const char *p, const formatdef *f)
420{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000421 int x;
422 memcpy((char *)&x, p, sizeof x);
423 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000424}
425
426static PyObject *
427nu_uint(const char *p, const formatdef *f)
428{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 unsigned int x;
430 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 return PyLong_FromUnsignedLong((unsigned long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000432}
433
434static PyObject *
435nu_long(const char *p, const formatdef *f)
436{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000437 long x;
438 memcpy((char *)&x, p, sizeof x);
439 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000440}
441
442static PyObject *
443nu_ulong(const char *p, const formatdef *f)
444{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 unsigned long x;
446 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000448}
449
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200450static PyObject *
451nu_ssize_t(const char *p, const formatdef *f)
452{
453 Py_ssize_t x;
454 memcpy((char *)&x, p, sizeof x);
455 return PyLong_FromSsize_t(x);
456}
457
458static PyObject *
459nu_size_t(const char *p, const formatdef *f)
460{
461 size_t x;
462 memcpy((char *)&x, p, sizeof x);
463 return PyLong_FromSize_t(x);
464}
465
Thomas Wouters477c8d52006-05-27 19:21:47 +0000466static PyObject *
467nu_longlong(const char *p, const formatdef *f)
468{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700469 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000471 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000472}
473
474static PyObject *
475nu_ulonglong(const char *p, const formatdef *f)
476{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700477 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000480}
481
Thomas Wouters477c8d52006-05-27 19:21:47 +0000482static PyObject *
Thomas Woutersb2137042007-02-01 18:02:27 +0000483nu_bool(const char *p, const formatdef *f)
484{
Benjamin Petersona9296e72016-09-07 11:06:17 -0700485 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000486 memcpy((char *)&x, p, sizeof x);
487 return PyBool_FromLong(x != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000488}
489
490
491static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100492nu_halffloat(const char *p, const formatdef *f)
493{
494#if PY_LITTLE_ENDIAN
495 return unpack_halffloat(p, 1);
496#else
497 return unpack_halffloat(p, 0);
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700498#endif
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100499}
500
501static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000502nu_float(const char *p, const formatdef *f)
503{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 float x;
505 memcpy((char *)&x, p, sizeof x);
506 return PyFloat_FromDouble((double)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000507}
508
509static PyObject *
510nu_double(const char *p, const formatdef *f)
511{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 double x;
513 memcpy((char *)&x, p, sizeof x);
514 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000515}
516
517static PyObject *
518nu_void_p(const char *p, const formatdef *f)
519{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 void *x;
521 memcpy((char *)&x, p, sizeof x);
522 return PyLong_FromVoidPtr(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000523}
524
525static int
526np_byte(char *p, PyObject *v, const formatdef *f)
527{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 long x;
529 if (get_long(v, &x) < 0)
530 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800531 if (x < -128 || x > 127) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100532 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 "byte format requires -128 <= number <= 127");
534 return -1;
535 }
536 *p = (char)x;
537 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000538}
539
540static int
541np_ubyte(char *p, PyObject *v, const formatdef *f)
542{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 long x;
544 if (get_long(v, &x) < 0)
545 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800546 if (x < 0 || x > 255) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100547 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 "ubyte format requires 0 <= number <= 255");
549 return -1;
550 }
Xiang Zhang981096f2017-05-15 12:04:26 +0800551 *(unsigned char *)p = (unsigned char)x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000553}
554
555static int
556np_char(char *p, PyObject *v, const formatdef *f)
557{
Dino Viehland4f384af2019-09-10 11:18:37 +0100558 if (!PyBytes_Check(v) || PyBytes_Size(v) != 1) {
559 PyErr_SetString(_structmodulestate_global->StructError,
Victor Stinnerda9ec992010-12-28 13:26:42 +0000560 "char format requires a bytes object of length 1");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000561 return -1;
562 }
Xiang Zhang96f50282017-05-15 11:53:51 +0800563 *p = *PyBytes_AS_STRING(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000565}
566
567static int
568np_short(char *p, PyObject *v, const formatdef *f)
569{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 long x;
571 short y;
572 if (get_long(v, &x) < 0)
573 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800574 if (x < SHRT_MIN || x > SHRT_MAX) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100575 PyErr_SetString(_structmodulestate_global->StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200576 "short format requires " Py_STRINGIFY(SHRT_MIN)
577 " <= number <= " Py_STRINGIFY(SHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 return -1;
579 }
580 y = (short)x;
581 memcpy(p, (char *)&y, sizeof y);
582 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000583}
584
585static int
586np_ushort(char *p, PyObject *v, const formatdef *f)
587{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 long x;
589 unsigned short y;
590 if (get_long(v, &x) < 0)
591 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800592 if (x < 0 || x > USHRT_MAX) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100593 PyErr_SetString(_structmodulestate_global->StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200594 "ushort format requires 0 <= number <= "
595 Py_STRINGIFY(USHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000596 return -1;
597 }
598 y = (unsigned short)x;
599 memcpy(p, (char *)&y, sizeof y);
600 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000601}
602
603static int
604np_int(char *p, PyObject *v, const formatdef *f)
605{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 long x;
607 int y;
608 if (get_long(v, &x) < 0)
609 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000610#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
612 RANGE_ERROR(x, f, 0, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000613#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000614 y = (int)x;
615 memcpy(p, (char *)&y, sizeof y);
616 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000617}
618
619static int
620np_uint(char *p, PyObject *v, const formatdef *f)
621{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000622 unsigned long x;
623 unsigned int y;
624 if (get_ulong(v, &x) < 0)
625 return -1;
626 y = (unsigned int)x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000627#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000628 if (x > ((unsigned long)UINT_MAX))
629 RANGE_ERROR(y, f, 1, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000630#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 memcpy(p, (char *)&y, sizeof y);
632 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000633}
634
635static int
636np_long(char *p, PyObject *v, const formatdef *f)
637{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000638 long x;
639 if (get_long(v, &x) < 0)
640 return -1;
641 memcpy(p, (char *)&x, sizeof x);
642 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000643}
644
645static int
646np_ulong(char *p, PyObject *v, const formatdef *f)
647{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000648 unsigned long x;
649 if (get_ulong(v, &x) < 0)
650 return -1;
651 memcpy(p, (char *)&x, sizeof x);
652 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000653}
654
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200655static int
656np_ssize_t(char *p, PyObject *v, const formatdef *f)
657{
658 Py_ssize_t x;
659 if (get_ssize_t(v, &x) < 0)
660 return -1;
661 memcpy(p, (char *)&x, sizeof x);
662 return 0;
663}
664
665static int
666np_size_t(char *p, PyObject *v, const formatdef *f)
667{
668 size_t x;
669 if (get_size_t(v, &x) < 0)
670 return -1;
671 memcpy(p, (char *)&x, sizeof x);
672 return 0;
673}
674
Thomas Wouters477c8d52006-05-27 19:21:47 +0000675static int
676np_longlong(char *p, PyObject *v, const formatdef *f)
677{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700678 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 if (get_longlong(v, &x) < 0)
680 return -1;
681 memcpy(p, (char *)&x, sizeof x);
682 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000683}
684
685static int
686np_ulonglong(char *p, PyObject *v, const formatdef *f)
687{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700688 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000689 if (get_ulonglong(v, &x) < 0)
690 return -1;
691 memcpy(p, (char *)&x, sizeof x);
692 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000693}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000694
Thomas Woutersb2137042007-02-01 18:02:27 +0000695
696static int
697np_bool(char *p, PyObject *v, const formatdef *f)
698{
Benjamin Petersonde73c452010-07-07 18:54:59 +0000699 int y;
Benjamin Petersona9296e72016-09-07 11:06:17 -0700700 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000702 if (y < 0)
703 return -1;
704 x = y;
705 memcpy(p, (char *)&x, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000706 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000707}
708
Thomas Wouters477c8d52006-05-27 19:21:47 +0000709static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100710np_halffloat(char *p, PyObject *v, const formatdef *f)
711{
712#if PY_LITTLE_ENDIAN
713 return pack_halffloat(p, v, 1);
714#else
715 return pack_halffloat(p, v, 0);
716#endif
717}
718
719static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000720np_float(char *p, PyObject *v, const formatdef *f)
721{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 float x = (float)PyFloat_AsDouble(v);
723 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100724 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 "required argument is not a float");
726 return -1;
727 }
728 memcpy(p, (char *)&x, sizeof x);
729 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000730}
731
732static int
733np_double(char *p, PyObject *v, const formatdef *f)
734{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000735 double x = PyFloat_AsDouble(v);
736 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100737 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 "required argument is not a float");
739 return -1;
740 }
741 memcpy(p, (char *)&x, sizeof(double));
742 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000743}
744
745static int
746np_void_p(char *p, PyObject *v, const formatdef *f)
747{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 void *x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000749
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 v = get_pylong(v);
751 if (v == NULL)
752 return -1;
753 assert(PyLong_Check(v));
754 x = PyLong_AsVoidPtr(v);
755 Py_DECREF(v);
756 if (x == NULL && PyErr_Occurred())
757 return -1;
758 memcpy(p, (char *)&x, sizeof x);
759 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000760}
761
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200762static const formatdef native_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000763 {'x', sizeof(char), 0, NULL},
764 {'b', sizeof(char), 0, nu_byte, np_byte},
765 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
766 {'c', sizeof(char), 0, nu_char, np_char},
767 {'s', sizeof(char), 0, NULL},
768 {'p', sizeof(char), 0, NULL},
769 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
770 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
771 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
772 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
773 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
774 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200775 {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t},
776 {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t},
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700777 {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong},
778 {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Benjamin Petersona9296e72016-09-07 11:06:17 -0700779 {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100780 {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000781 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
782 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
783 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
784 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000785};
786
787/* Big-endian routines. *****************************************************/
788
789static PyObject *
790bu_int(const char *p, const formatdef *f)
791{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000792 long x = 0;
793 Py_ssize_t i = f->size;
794 const unsigned char *bytes = (const unsigned char *)p;
795 do {
796 x = (x<<8) | *bytes++;
797 } while (--i > 0);
798 /* Extend the sign bit. */
799 if (SIZEOF_LONG > f->size)
800 x |= -(x & (1L << ((8 * f->size) - 1)));
801 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000802}
803
804static PyObject *
805bu_uint(const char *p, const formatdef *f)
806{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000807 unsigned long x = 0;
808 Py_ssize_t i = f->size;
809 const unsigned char *bytes = (const unsigned char *)p;
810 do {
811 x = (x<<8) | *bytes++;
812 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000813 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000814}
815
816static PyObject *
817bu_longlong(const char *p, const formatdef *f)
818{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700819 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 Py_ssize_t i = f->size;
821 const unsigned char *bytes = (const unsigned char *)p;
822 do {
823 x = (x<<8) | *bytes++;
824 } while (--i > 0);
825 /* Extend the sign bit. */
826 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700827 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000828 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000829}
830
831static PyObject *
832bu_ulonglong(const char *p, const formatdef *f)
833{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700834 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 Py_ssize_t i = f->size;
836 const unsigned char *bytes = (const unsigned char *)p;
837 do {
838 x = (x<<8) | *bytes++;
839 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000841}
842
843static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100844bu_halffloat(const char *p, const formatdef *f)
845{
846 return unpack_halffloat(p, 0);
847}
848
849static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000850bu_float(const char *p, const formatdef *f)
851{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000852 return unpack_float(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000853}
854
855static PyObject *
856bu_double(const char *p, const formatdef *f)
857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 return unpack_double(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000859}
860
Thomas Woutersb2137042007-02-01 18:02:27 +0000861static PyObject *
862bu_bool(const char *p, const formatdef *f)
863{
Xiang Zhang96f50282017-05-15 11:53:51 +0800864 return PyBool_FromLong(*p != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000865}
866
Thomas Wouters477c8d52006-05-27 19:21:47 +0000867static int
868bp_int(char *p, PyObject *v, const formatdef *f)
869{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 long x;
871 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800872 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000873 if (get_long(v, &x) < 0)
874 return -1;
875 i = f->size;
876 if (i != SIZEOF_LONG) {
877 if ((i == 2) && (x < -32768 || x > 32767))
878 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000879#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
881 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000882#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000883 }
884 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800885 q[--i] = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000886 x >>= 8;
887 } while (i > 0);
888 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000889}
890
891static int
892bp_uint(char *p, PyObject *v, const formatdef *f)
893{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 unsigned long x;
895 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800896 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000897 if (get_ulong(v, &x) < 0)
898 return -1;
899 i = f->size;
900 if (i != SIZEOF_LONG) {
901 unsigned long maxint = 1;
902 maxint <<= (unsigned long)(i * 8);
903 if (x >= maxint)
904 RANGE_ERROR(x, f, 1, maxint - 1);
905 }
906 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800907 q[--i] = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000908 x >>= 8;
909 } while (i > 0);
910 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000911}
912
913static int
914bp_longlong(char *p, PyObject *v, const formatdef *f)
915{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 int res;
917 v = get_pylong(v);
918 if (v == NULL)
919 return -1;
920 res = _PyLong_AsByteArray((PyLongObject *)v,
921 (unsigned char *)p,
922 8,
923 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800924 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 Py_DECREF(v);
926 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000927}
928
929static int
930bp_ulonglong(char *p, PyObject *v, const formatdef *f)
931{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 int res;
933 v = get_pylong(v);
934 if (v == NULL)
935 return -1;
936 res = _PyLong_AsByteArray((PyLongObject *)v,
937 (unsigned char *)p,
938 8,
939 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800940 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 Py_DECREF(v);
942 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000943}
944
945static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100946bp_halffloat(char *p, PyObject *v, const formatdef *f)
947{
948 return pack_halffloat(p, v, 0);
949}
950
951static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000952bp_float(char *p, PyObject *v, const formatdef *f)
953{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 double x = PyFloat_AsDouble(v);
955 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100956 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 "required argument is not a float");
958 return -1;
959 }
960 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000961}
962
963static int
964bp_double(char *p, PyObject *v, const formatdef *f)
965{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 double x = PyFloat_AsDouble(v);
967 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +0100968 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 "required argument is not a float");
970 return -1;
971 }
972 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000973}
974
Thomas Woutersb2137042007-02-01 18:02:27 +0000975static int
976bp_bool(char *p, PyObject *v, const formatdef *f)
977{
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000978 int y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000980 if (y < 0)
981 return -1;
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000982 *p = (char)y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000984}
985
Thomas Wouters477c8d52006-05-27 19:21:47 +0000986static formatdef bigendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 {'x', 1, 0, NULL},
988 {'b', 1, 0, nu_byte, np_byte},
989 {'B', 1, 0, nu_ubyte, np_ubyte},
990 {'c', 1, 0, nu_char, np_char},
991 {'s', 1, 0, NULL},
992 {'p', 1, 0, NULL},
993 {'h', 2, 0, bu_int, bp_int},
994 {'H', 2, 0, bu_uint, bp_uint},
995 {'i', 4, 0, bu_int, bp_int},
996 {'I', 4, 0, bu_uint, bp_uint},
997 {'l', 4, 0, bu_int, bp_int},
998 {'L', 4, 0, bu_uint, bp_uint},
999 {'q', 8, 0, bu_longlong, bp_longlong},
1000 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
1001 {'?', 1, 0, bu_bool, bp_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001002 {'e', 2, 0, bu_halffloat, bp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001003 {'f', 4, 0, bu_float, bp_float},
1004 {'d', 8, 0, bu_double, bp_double},
1005 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001006};
1007
1008/* Little-endian routines. *****************************************************/
1009
1010static PyObject *
1011lu_int(const char *p, const formatdef *f)
1012{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 long x = 0;
1014 Py_ssize_t i = f->size;
1015 const unsigned char *bytes = (const unsigned char *)p;
1016 do {
1017 x = (x<<8) | bytes[--i];
1018 } while (i > 0);
1019 /* Extend the sign bit. */
1020 if (SIZEOF_LONG > f->size)
1021 x |= -(x & (1L << ((8 * f->size) - 1)));
1022 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001023}
1024
1025static PyObject *
1026lu_uint(const char *p, const formatdef *f)
1027{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 unsigned long x = 0;
1029 Py_ssize_t i = f->size;
1030 const unsigned char *bytes = (const unsigned char *)p;
1031 do {
1032 x = (x<<8) | bytes[--i];
1033 } while (i > 0);
Xiang Zhang96f50282017-05-15 11:53:51 +08001034 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001035}
1036
1037static PyObject *
1038lu_longlong(const char *p, const formatdef *f)
1039{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001040 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001041 Py_ssize_t i = f->size;
1042 const unsigned char *bytes = (const unsigned char *)p;
1043 do {
1044 x = (x<<8) | bytes[--i];
1045 } while (i > 0);
1046 /* Extend the sign bit. */
1047 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001048 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001050}
1051
1052static PyObject *
1053lu_ulonglong(const char *p, const formatdef *f)
1054{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001055 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 Py_ssize_t i = f->size;
1057 const unsigned char *bytes = (const unsigned char *)p;
1058 do {
1059 x = (x<<8) | bytes[--i];
1060 } while (i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001062}
1063
1064static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001065lu_halffloat(const char *p, const formatdef *f)
1066{
1067 return unpack_halffloat(p, 1);
1068}
1069
1070static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001071lu_float(const char *p, const formatdef *f)
1072{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 return unpack_float(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001074}
1075
1076static PyObject *
1077lu_double(const char *p, const formatdef *f)
1078{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001079 return unpack_double(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001080}
1081
1082static int
1083lp_int(char *p, PyObject *v, const formatdef *f)
1084{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001085 long x;
1086 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001087 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 if (get_long(v, &x) < 0)
1089 return -1;
1090 i = f->size;
1091 if (i != SIZEOF_LONG) {
1092 if ((i == 2) && (x < -32768 || x > 32767))
1093 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001094#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
1096 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001097#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001098 }
1099 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001100 *q++ = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 x >>= 8;
1102 } while (--i > 0);
1103 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001104}
1105
1106static int
1107lp_uint(char *p, PyObject *v, const formatdef *f)
1108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 unsigned long x;
1110 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001111 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001112 if (get_ulong(v, &x) < 0)
1113 return -1;
1114 i = f->size;
1115 if (i != SIZEOF_LONG) {
1116 unsigned long maxint = 1;
1117 maxint <<= (unsigned long)(i * 8);
1118 if (x >= maxint)
1119 RANGE_ERROR(x, f, 1, maxint - 1);
1120 }
1121 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001122 *q++ = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 x >>= 8;
1124 } while (--i > 0);
1125 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001126}
1127
1128static int
1129lp_longlong(char *p, PyObject *v, const formatdef *f)
1130{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 int res;
1132 v = get_pylong(v);
1133 if (v == NULL)
1134 return -1;
1135 res = _PyLong_AsByteArray((PyLongObject*)v,
1136 (unsigned char *)p,
1137 8,
1138 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001139 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 Py_DECREF(v);
1141 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001142}
1143
1144static int
1145lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1146{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 int res;
1148 v = get_pylong(v);
1149 if (v == NULL)
1150 return -1;
1151 res = _PyLong_AsByteArray((PyLongObject*)v,
1152 (unsigned char *)p,
1153 8,
1154 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001155 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 Py_DECREF(v);
1157 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001158}
1159
1160static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001161lp_halffloat(char *p, PyObject *v, const formatdef *f)
1162{
1163 return pack_halffloat(p, v, 1);
1164}
1165
1166static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001167lp_float(char *p, PyObject *v, const formatdef *f)
1168{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 double x = PyFloat_AsDouble(v);
1170 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001171 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 "required argument is not a float");
1173 return -1;
1174 }
1175 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001176}
1177
1178static int
1179lp_double(char *p, PyObject *v, const formatdef *f)
1180{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 double x = PyFloat_AsDouble(v);
1182 if (x == -1 && PyErr_Occurred()) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001183 PyErr_SetString(_structmodulestate_global->StructError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 "required argument is not a float");
1185 return -1;
1186 }
1187 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001188}
1189
1190static formatdef lilendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001191 {'x', 1, 0, NULL},
1192 {'b', 1, 0, nu_byte, np_byte},
1193 {'B', 1, 0, nu_ubyte, np_ubyte},
1194 {'c', 1, 0, nu_char, np_char},
1195 {'s', 1, 0, NULL},
1196 {'p', 1, 0, NULL},
1197 {'h', 2, 0, lu_int, lp_int},
1198 {'H', 2, 0, lu_uint, lp_uint},
1199 {'i', 4, 0, lu_int, lp_int},
1200 {'I', 4, 0, lu_uint, lp_uint},
1201 {'l', 4, 0, lu_int, lp_int},
1202 {'L', 4, 0, lu_uint, lp_uint},
1203 {'q', 8, 0, lu_longlong, lp_longlong},
1204 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1205 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1206 but potentially different from native rep -- reuse bx_bool funcs. */
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001207 {'e', 2, 0, lu_halffloat, lp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 {'f', 4, 0, lu_float, lp_float},
1209 {'d', 8, 0, lu_double, lp_double},
1210 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001211};
1212
1213
1214static const formatdef *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001215whichtable(const char **pfmt)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001216{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 const char *fmt = (*pfmt)++; /* May be backed out of later */
1218 switch (*fmt) {
1219 case '<':
1220 return lilendian_table;
1221 case '>':
1222 case '!': /* Network byte order is big-endian */
1223 return bigendian_table;
Ezio Melotti42da6632011-03-15 05:18:48 +02001224 case '=': { /* Host byte order -- different from native in alignment! */
Christian Heimes743e0cd2012-10-17 23:52:17 +02001225#if PY_LITTLE_ENDIAN
1226 return lilendian_table;
1227#else
1228 return bigendian_table;
1229#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 }
1231 default:
1232 --*pfmt; /* Back out of pointer increment */
1233 /* Fall through */
1234 case '@':
1235 return native_table;
1236 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001237}
1238
1239
1240/* Get the table entry for a format code */
1241
1242static const formatdef *
1243getentry(int c, const formatdef *f)
1244{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 for (; f->format != '\0'; f++) {
1246 if (f->format == c) {
1247 return f;
1248 }
1249 }
Dino Viehland4f384af2019-09-10 11:18:37 +01001250 PyErr_SetString(_structmodulestate_global->StructError, "bad char in struct format");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001252}
1253
1254
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001255/* Align a size according to a format code. Return -1 on overflow. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001256
Mark Dickinsoneac0e682010-06-11 19:05:08 +00001257static Py_ssize_t
Thomas Wouters477c8d52006-05-27 19:21:47 +00001258align(Py_ssize_t size, char c, const formatdef *e)
1259{
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001260 Py_ssize_t extra;
1261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 if (e->format == c) {
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001263 if (e->alignment && size > 0) {
1264 extra = (e->alignment - 1) - (size - 1) % (e->alignment);
1265 if (extra > PY_SSIZE_T_MAX - size)
1266 return -1;
1267 size += extra;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 }
1269 }
1270 return size;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001271}
1272
Antoine Pitrou9f146812013-04-27 00:20:04 +02001273/*
1274 * Struct object implementation.
1275 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001276
1277/* calculate the size of a format string */
1278
1279static int
1280prepare_s(PyStructObject *self)
1281{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 const formatdef *f;
1283 const formatdef *e;
1284 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001285
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001286 const char *s;
1287 const char *fmt;
1288 char c;
Victor Stinner706768c2014-08-16 01:03:39 +02001289 Py_ssize_t size, len, num, itemsize;
1290 size_t ncodes;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 fmt = PyBytes_AS_STRING(self->s_format);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001293
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001294 f = whichtable(&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 s = fmt;
1297 size = 0;
1298 len = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001299 ncodes = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001300 while ((c = *s++) != '\0') {
Jordon Xu2ec70102019-09-11 00:04:08 +08001301 if (Py_ISSPACE(c))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001302 continue;
1303 if ('0' <= c && c <= '9') {
1304 num = c - '0';
1305 while ('0' <= (c = *s++) && c <= '9') {
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001306 /* overflow-safe version of
1307 if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1308 if (num >= PY_SSIZE_T_MAX / 10 && (
1309 num > PY_SSIZE_T_MAX / 10 ||
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001310 (c - '0') > PY_SSIZE_T_MAX % 10))
1311 goto overflow;
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001312 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 }
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001314 if (c == '\0') {
Dino Viehland4f384af2019-09-10 11:18:37 +01001315 PyErr_SetString(_structmodulestate_global->StructError,
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001316 "repeat count given without format specifier");
1317 return -1;
1318 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 }
1320 else
1321 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 e = getentry(c, f);
1324 if (e == NULL)
1325 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001326
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 switch (c) {
1328 case 's': /* fall through */
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001329 case 'p': len++; ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 case 'x': break;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001331 default: len += num; if (num) ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 itemsize = e->size;
1335 size = align(size, c, e);
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001336 if (size == -1)
1337 goto overflow;
1338
1339 /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1340 if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1341 goto overflow;
1342 size += num * itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001343 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001344
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001345 /* check for overflow */
Victor Stinner706768c2014-08-16 01:03:39 +02001346 if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001347 PyErr_NoMemory();
1348 return -1;
1349 }
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +00001350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 self->s_size = size;
1352 self->s_len = len;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001353 codes = PyMem_MALLOC((ncodes + 1) * sizeof(formatcode));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 if (codes == NULL) {
1355 PyErr_NoMemory();
1356 return -1;
1357 }
Mark Dickinsoncf28b952010-07-29 21:41:59 +00001358 /* Free any s_codes value left over from a previous initialization. */
1359 if (self->s_codes != NULL)
1360 PyMem_FREE(self->s_codes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001361 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001362
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001363 s = fmt;
1364 size = 0;
1365 while ((c = *s++) != '\0') {
Jordon Xu2ec70102019-09-11 00:04:08 +08001366 if (Py_ISSPACE(c))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 continue;
1368 if ('0' <= c && c <= '9') {
1369 num = c - '0';
1370 while ('0' <= (c = *s++) && c <= '9')
1371 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001372 }
1373 else
1374 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001375
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001377
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001378 size = align(size, c, e);
1379 if (c == 's' || c == 'p') {
1380 codes->offset = size;
1381 codes->size = num;
1382 codes->fmtdef = e;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001383 codes->repeat = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 codes++;
1385 size += num;
1386 } else if (c == 'x') {
1387 size += num;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001388 } else if (num) {
1389 codes->offset = size;
1390 codes->size = e->size;
1391 codes->fmtdef = e;
1392 codes->repeat = num;
1393 codes++;
1394 size += e->size * num;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001395 }
1396 }
1397 codes->fmtdef = NULL;
1398 codes->offset = size;
1399 codes->size = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001400 codes->repeat = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 return 0;
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001403
1404 overflow:
Dino Viehland4f384af2019-09-10 11:18:37 +01001405 PyErr_SetString(_structmodulestate_global->StructError,
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001406 "total struct size too long");
1407 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001408}
1409
1410static PyObject *
1411s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1412{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001413 PyObject *self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001414
Dino Viehland4f384af2019-09-10 11:18:37 +01001415 assert(type != NULL);
1416 allocfunc alloc_func = PyType_GetSlot(type, Py_tp_alloc);
1417 assert(alloc_func != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001418
Dino Viehland4f384af2019-09-10 11:18:37 +01001419 self = alloc_func(type, 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001420 if (self != NULL) {
1421 PyStructObject *s = (PyStructObject*)self;
1422 Py_INCREF(Py_None);
1423 s->s_format = Py_None;
1424 s->s_codes = NULL;
1425 s->s_size = -1;
1426 s->s_len = -1;
1427 }
1428 return self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001429}
1430
Victor Stinner3f2d1012017-02-02 12:09:30 +01001431/*[clinic input]
1432Struct.__init__
1433
1434 format: object
1435
1436Create a compiled struct object.
1437
1438Return a new Struct object which writes and reads binary data according to
1439the format string.
1440
1441See help(struct) for more on format strings.
1442[clinic start generated code]*/
1443
Thomas Wouters477c8d52006-05-27 19:21:47 +00001444static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001445Struct___init___impl(PyStructObject *self, PyObject *format)
1446/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001447{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001448 int ret = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001449
Victor Stinner3f2d1012017-02-02 12:09:30 +01001450 if (PyUnicode_Check(format)) {
1451 format = PyUnicode_AsASCIIString(format);
1452 if (format == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001453 return -1;
1454 }
1455 /* XXX support buffer interface, too */
1456 else {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001457 Py_INCREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001459
Victor Stinner3f2d1012017-02-02 12:09:30 +01001460 if (!PyBytes_Check(format)) {
1461 Py_DECREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001462 PyErr_Format(PyExc_TypeError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001463 "Struct() argument 1 must be a str or bytes object, "
1464 "not %.200s",
Dino Viehland4f384af2019-09-10 11:18:37 +01001465 _PyType_Name(Py_TYPE(format)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001466 return -1;
1467 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001468
Xiang Zhang96f50282017-05-15 11:53:51 +08001469 Py_SETREF(self->s_format, format);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001470
Victor Stinner3f2d1012017-02-02 12:09:30 +01001471 ret = prepare_s(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001472 return ret;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001473}
1474
1475static void
1476s_dealloc(PyStructObject *s)
1477{
Dino Viehland4f384af2019-09-10 11:18:37 +01001478 PyTypeObject *tp = Py_TYPE(s);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001479 if (s->weakreflist != NULL)
1480 PyObject_ClearWeakRefs((PyObject *)s);
1481 if (s->s_codes != NULL) {
1482 PyMem_FREE(s->s_codes);
1483 }
Dino Viehland4f384af2019-09-10 11:18:37 +01001484 Py_XDECREF(s->s_format);
1485 freefunc free_func = PyType_GetSlot(Py_TYPE(s), Py_tp_free);
1486 free_func(s);
1487 Py_DECREF(tp);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001488}
1489
1490static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001491s_unpack_internal(PyStructObject *soself, const char *startfrom) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001492 formatcode *code;
1493 Py_ssize_t i = 0;
1494 PyObject *result = PyTuple_New(soself->s_len);
1495 if (result == NULL)
1496 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001498 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001499 const formatdef *e = code->fmtdef;
1500 const char *res = startfrom + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001501 Py_ssize_t j = code->repeat;
1502 while (j--) {
1503 PyObject *v;
1504 if (e->format == 's') {
1505 v = PyBytes_FromStringAndSize(res, code->size);
1506 } else if (e->format == 'p') {
1507 Py_ssize_t n = *(unsigned char*)res;
1508 if (n >= code->size)
1509 n = code->size - 1;
1510 v = PyBytes_FromStringAndSize(res + 1, n);
1511 } else {
1512 v = e->unpack(res, e);
1513 }
1514 if (v == NULL)
1515 goto fail;
1516 PyTuple_SET_ITEM(result, i++, v);
1517 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001518 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001519 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001520
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001521 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001522fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001523 Py_DECREF(result);
1524 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001525}
1526
1527
Victor Stinner3f2d1012017-02-02 12:09:30 +01001528/*[clinic input]
1529Struct.unpack
1530
1531 buffer: Py_buffer
1532 /
1533
1534Return a tuple containing unpacked values.
1535
1536Unpack according to the format string Struct.format. The buffer's size
1537in bytes must be Struct.size.
1538
1539See help(struct) for more on format strings.
1540[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001541
1542static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001543Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1544/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001545{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001546 assert(self->s_codes != NULL);
1547 if (buffer->len != self->s_size) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001548 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001549 "unpack requires a buffer of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001550 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 return NULL;
1552 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001553 return s_unpack_internal(self, buffer->buf);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001554}
1555
Victor Stinner3f2d1012017-02-02 12:09:30 +01001556/*[clinic input]
1557Struct.unpack_from
1558
1559 buffer: Py_buffer
1560 offset: Py_ssize_t = 0
1561
1562Return a tuple containing unpacked values.
1563
1564Values are unpacked according to the format string Struct.format.
1565
Xiang Zhangc10b2882018-03-11 02:58:52 +08001566The buffer's size in bytes, starting at position offset, must be
1567at least Struct.size.
Victor Stinner3f2d1012017-02-02 12:09:30 +01001568
1569See help(struct) for more on format strings.
1570[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001571
1572static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001573Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1574 Py_ssize_t offset)
Xiang Zhangc10b2882018-03-11 02:58:52 +08001575/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001576{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001577 assert(self->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001578
Xiang Zhangc10b2882018-03-11 02:58:52 +08001579 if (offset < 0) {
1580 if (offset + self->s_size > 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001581 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001582 "not enough data to unpack %zd bytes at offset %zd",
1583 self->s_size,
1584 offset);
1585 return NULL;
1586 }
1587
1588 if (offset + buffer->len < 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001589 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001590 "offset %zd out of range for %zd-byte buffer",
1591 offset,
1592 buffer->len);
1593 return NULL;
1594 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001595 offset += buffer->len;
Xiang Zhangc10b2882018-03-11 02:58:52 +08001596 }
1597
1598 if ((buffer->len - offset) < self->s_size) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001599 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001600 "unpack_from requires a buffer of at least %zu bytes for "
1601 "unpacking %zd bytes at offset %zd "
1602 "(actual buffer size is %zd)",
1603 (size_t)self->s_size + (size_t)offset,
1604 self->s_size,
1605 offset,
1606 buffer->len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001607 return NULL;
1608 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001609 return s_unpack_internal(self, (char*)buffer->buf + offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001610}
1611
1612
Victor Stinner3f2d1012017-02-02 12:09:30 +01001613
Antoine Pitrou9f146812013-04-27 00:20:04 +02001614/* Unpack iterator type */
1615
1616typedef struct {
1617 PyObject_HEAD
1618 PyStructObject *so;
1619 Py_buffer buf;
1620 Py_ssize_t index;
1621} unpackiterobject;
1622
1623static void
1624unpackiter_dealloc(unpackiterobject *self)
1625{
INADA Naokia6296d32017-08-24 14:55:17 +09001626 /* bpo-31095: UnTrack is needed before calling any callbacks */
Dino Viehland4f384af2019-09-10 11:18:37 +01001627 PyTypeObject *tp = Py_TYPE(self);
INADA Naokia6296d32017-08-24 14:55:17 +09001628 PyObject_GC_UnTrack(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001629 Py_XDECREF(self->so);
1630 PyBuffer_Release(&self->buf);
1631 PyObject_GC_Del(self);
Dino Viehland4f384af2019-09-10 11:18:37 +01001632 Py_DECREF(tp);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001633}
1634
1635static int
1636unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1637{
1638 Py_VISIT(self->so);
1639 Py_VISIT(self->buf.obj);
1640 return 0;
1641}
1642
1643static PyObject *
Siddhesh Poyarekar55edd0c2018-04-30 00:29:33 +05301644unpackiter_len(unpackiterobject *self, PyObject *Py_UNUSED(ignored))
Antoine Pitrou9f146812013-04-27 00:20:04 +02001645{
1646 Py_ssize_t len;
1647 if (self->so == NULL)
1648 len = 0;
1649 else
1650 len = (self->buf.len - self->index) / self->so->s_size;
1651 return PyLong_FromSsize_t(len);
1652}
1653
1654static PyMethodDef unpackiter_methods[] = {
1655 {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1656 {NULL, NULL} /* sentinel */
1657};
1658
1659static PyObject *
1660unpackiter_iternext(unpackiterobject *self)
1661{
1662 PyObject *result;
1663 if (self->so == NULL)
1664 return NULL;
1665 if (self->index >= self->buf.len) {
1666 /* Iterator exhausted */
1667 Py_CLEAR(self->so);
1668 PyBuffer_Release(&self->buf);
1669 return NULL;
1670 }
1671 assert(self->index + self->so->s_size <= self->buf.len);
1672 result = s_unpack_internal(self->so,
1673 (char*) self->buf.buf + self->index);
1674 self->index += self->so->s_size;
1675 return result;
1676}
1677
Dino Viehland4f384af2019-09-10 11:18:37 +01001678PyObject *unpackiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
1679 PyErr_Format(PyExc_TypeError, "Cannot create '%.200s objects", _PyType_Name(type));
1680 return NULL;
1681}
1682
1683static PyType_Slot unpackiter_type_slots[] = {
1684 {Py_tp_dealloc, unpackiter_dealloc},
1685 {Py_tp_getattro, PyObject_GenericGetAttr},
1686 {Py_tp_traverse, unpackiter_traverse},
1687 {Py_tp_iter, PyObject_SelfIter},
1688 {Py_tp_iternext, unpackiter_iternext},
1689 {Py_tp_methods, unpackiter_methods},
1690 {Py_tp_new, unpackiter_new},
1691 {0, 0},
1692};
1693
1694static PyType_Spec unpackiter_type_spec = {
1695 "_struct.unpack_iterator",
1696 sizeof(unpackiterobject),
1697 0,
1698 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1699 unpackiter_type_slots
Antoine Pitrou9f146812013-04-27 00:20:04 +02001700};
1701
Victor Stinner3f2d1012017-02-02 12:09:30 +01001702/*[clinic input]
1703Struct.iter_unpack
1704
1705 buffer: object
1706 /
1707
1708Return an iterator yielding tuples.
1709
1710Tuples are unpacked from the given bytes source, like a repeated
1711invocation of unpack_from().
1712
1713Requires that the bytes length be a multiple of the struct size.
1714[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001715
1716static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001717Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1718/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001719{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001720 unpackiterobject *iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001721
Victor Stinner3f2d1012017-02-02 12:09:30 +01001722 assert(self->s_codes != NULL);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001723
Victor Stinner3f2d1012017-02-02 12:09:30 +01001724 if (self->s_size == 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001725 PyErr_Format(_structmodulestate_global->StructError,
Antoine Pitrou9f146812013-04-27 00:20:04 +02001726 "cannot iteratively unpack with a struct of length 0");
1727 return NULL;
1728 }
1729
Dino Viehland4f384af2019-09-10 11:18:37 +01001730 iter = (unpackiterobject *) PyType_GenericAlloc((PyTypeObject *)_structmodulestate_global->unpackiter_type, 0);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001731 if (iter == NULL)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001732 return NULL;
1733
Victor Stinner3f2d1012017-02-02 12:09:30 +01001734 if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1735 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001736 return NULL;
1737 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001738 if (iter->buf.len % self->s_size != 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001739 PyErr_Format(_structmodulestate_global->StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001740 "iterative unpacking requires a buffer of "
1741 "a multiple of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001742 self->s_size);
1743 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001744 return NULL;
1745 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001746 Py_INCREF(self);
1747 iter->so = self;
1748 iter->index = 0;
1749 return (PyObject *)iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001750}
1751
1752
Thomas Wouters477c8d52006-05-27 19:21:47 +00001753/*
1754 * Guts of the pack function.
1755 *
1756 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1757 * argument for where to start processing the arguments for packing, and a
1758 * character buffer for writing the packed string. The caller must insure
1759 * that the buffer may contain the required length for packing the arguments.
1760 * 0 is returned on success, 1 is returned if there is an error.
1761 *
1762 */
1763static int
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001764s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* buf)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001765{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 formatcode *code;
1767 /* XXX(nnorwitz): why does i need to be a local? can we use
1768 the offset parameter or do we need the wider width? */
1769 Py_ssize_t i;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001770
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001771 memset(buf, '\0', soself->s_size);
1772 i = offset;
1773 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001774 const formatdef *e = code->fmtdef;
1775 char *res = buf + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001776 Py_ssize_t j = code->repeat;
1777 while (j--) {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001778 PyObject *v = args[i++];
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001779 if (e->format == 's') {
1780 Py_ssize_t n;
1781 int isstring;
1782 void *p;
1783 isstring = PyBytes_Check(v);
1784 if (!isstring && !PyByteArray_Check(v)) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001785 PyErr_SetString(_structmodulestate_global->StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001786 "argument for 's' must be a bytes object");
1787 return -1;
1788 }
1789 if (isstring) {
1790 n = PyBytes_GET_SIZE(v);
1791 p = PyBytes_AS_STRING(v);
1792 }
1793 else {
1794 n = PyByteArray_GET_SIZE(v);
1795 p = PyByteArray_AS_STRING(v);
1796 }
1797 if (n > code->size)
1798 n = code->size;
1799 if (n > 0)
1800 memcpy(res, p, n);
1801 } else if (e->format == 'p') {
1802 Py_ssize_t n;
1803 int isstring;
1804 void *p;
1805 isstring = PyBytes_Check(v);
1806 if (!isstring && !PyByteArray_Check(v)) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001807 PyErr_SetString(_structmodulestate_global->StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001808 "argument for 'p' must be a bytes object");
1809 return -1;
1810 }
1811 if (isstring) {
1812 n = PyBytes_GET_SIZE(v);
1813 p = PyBytes_AS_STRING(v);
1814 }
1815 else {
1816 n = PyByteArray_GET_SIZE(v);
1817 p = PyByteArray_AS_STRING(v);
1818 }
1819 if (n > (code->size - 1))
1820 n = code->size - 1;
1821 if (n > 0)
1822 memcpy(res + 1, p, n);
1823 if (n > 255)
1824 n = 255;
1825 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1826 } else {
1827 if (e->pack(res, v, e) < 0) {
1828 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
Dino Viehland4f384af2019-09-10 11:18:37 +01001829 PyErr_SetString(_structmodulestate_global->StructError,
Serhiy Storchaka46e1ce22013-08-27 20:17:03 +03001830 "int too large to convert");
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001831 return -1;
1832 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 }
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001834 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001835 }
1836 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001837
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001838 /* Success */
1839 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001840}
1841
1842
1843PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001844"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001845\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001846Return a bytes object containing values v1, v2, ... packed according\n\
1847to the format string S.format. See help(struct) for more on format\n\
1848strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001849
1850static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001851s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001852{
Dino Viehland4f384af2019-09-10 11:18:37 +01001853 char *buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001854 PyStructObject *soself;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001855
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 /* Validate arguments. */
1857 soself = (PyStructObject *)self;
1858 assert(PyStruct_Check(self));
1859 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001860 if (nargs != soself->s_len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001861 {
Dino Viehland4f384af2019-09-10 11:18:37 +01001862 PyErr_Format(_structmodulestate_global->StructError,
Victor Stinner3f2d1012017-02-02 12:09:30 +01001863 "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1864 return NULL;
1865 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001866
Dino Viehland4f384af2019-09-10 11:18:37 +01001867 /* Allocate a new string */
1868 _PyBytesWriter writer;
1869 _PyBytesWriter_Init(&writer);
1870 buf = _PyBytesWriter_Alloc(&writer, soself->s_size);
1871 if (buf == NULL) {
1872 _PyBytesWriter_Dealloc(&writer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 return NULL;
1874 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001875
Dino Viehland4f384af2019-09-10 11:18:37 +01001876 /* Call the guts */
1877 if ( s_pack_internal(soself, args, 0, buf) != 0 ) {
1878 _PyBytesWriter_Dealloc(&writer);
1879 return NULL;
1880 }
1881
1882 return _PyBytesWriter_Finish(&writer, buf + soself->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001883}
1884
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001885PyDoc_STRVAR(s_pack_into__doc__,
1886"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001887\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001888Pack the values v1, v2, ... according to the format string S.format\n\
1889and write the packed bytes into the writable buffer buf starting at\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00001890offset. Note that the offset is a required argument. See\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001891help(struct) for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001892
1893static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001894s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001895{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 PyStructObject *soself;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001897 Py_buffer buffer;
1898 Py_ssize_t offset;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001899
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001900 /* Validate arguments. +1 is for the first arg as buffer. */
1901 soself = (PyStructObject *)self;
1902 assert(PyStruct_Check(self));
1903 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001904 if (nargs != (soself->s_len + 2))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001905 {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001906 if (nargs == 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001907 PyErr_Format(_structmodulestate_global->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001908 "pack_into expected buffer argument");
1909 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001910 else if (nargs == 1) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001911 PyErr_Format(_structmodulestate_global->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001912 "pack_into expected offset argument");
1913 }
1914 else {
Dino Viehland4f384af2019-09-10 11:18:37 +01001915 PyErr_Format(_structmodulestate_global->StructError,
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001916 "pack_into expected %zd items for packing (got %zd)",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001917 soself->s_len, (nargs - 2));
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001918 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001919 return NULL;
1920 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 /* Extract a writable memory buffer from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001923 if (!PyArg_Parse(args[0], "w*", &buffer))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001924 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001925 assert(buffer.len >= 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001926
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001927 /* Extract the offset from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001928 offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001929 if (offset == -1 && PyErr_Occurred()) {
1930 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001931 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001932 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001934 /* Support negative offsets. */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001935 if (offset < 0) {
1936 /* Check that negative offset is low enough to fit data */
1937 if (offset + soself->s_size > 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001938 PyErr_Format(_structmodulestate_global->StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001939 "no space to pack %zd bytes at offset %zd",
1940 soself->s_size,
1941 offset);
1942 PyBuffer_Release(&buffer);
1943 return NULL;
1944 }
1945
1946 /* Check that negative offset is not crossing buffer boundary */
1947 if (offset + buffer.len < 0) {
Dino Viehland4f384af2019-09-10 11:18:37 +01001948 PyErr_Format(_structmodulestate_global->StructError,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001949 "offset %zd out of range for %zd-byte buffer",
1950 offset,
1951 buffer.len);
1952 PyBuffer_Release(&buffer);
1953 return NULL;
1954 }
1955
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001956 offset += buffer.len;
Andrew Nesterf78b1192017-04-04 13:46:25 +03001957 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001958
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001959 /* Check boundaries */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001960 if ((buffer.len - offset) < soself->s_size) {
Johan Liuaead53b2017-06-02 14:33:04 +08001961 assert(offset >= 0);
1962 assert(soself->s_size >= 0);
1963
Dino Viehland4f384af2019-09-10 11:18:37 +01001964 PyErr_Format(_structmodulestate_global->StructError,
Johan Liuaead53b2017-06-02 14:33:04 +08001965 "pack_into requires a buffer of at least %zu bytes for "
Andrew Nesterf78b1192017-04-04 13:46:25 +03001966 "packing %zd bytes at offset %zd "
1967 "(actual buffer size is %zd)",
Johan Liuaead53b2017-06-02 14:33:04 +08001968 (size_t)soself->s_size + (size_t)offset,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001969 soself->s_size,
1970 offset,
1971 buffer.len);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001972 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001973 return NULL;
1974 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001976 /* Call the guts */
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001977 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
1978 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001979 return NULL;
1980 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001981
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001982 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001983 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001984}
1985
1986static PyObject *
1987s_get_format(PyStructObject *self, void *unused)
1988{
Victor Stinnerf87b85f2017-06-23 15:11:12 +02001989 return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
1990 PyBytes_GET_SIZE(self->s_format));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001991}
1992
1993static PyObject *
1994s_get_size(PyStructObject *self, void *unused)
1995{
Christian Heimes217cfd12007-12-02 14:31:20 +00001996 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001997}
1998
Meador Ingeb14d8c92012-07-23 10:01:29 -05001999PyDoc_STRVAR(s_sizeof__doc__,
2000"S.__sizeof__() -> size of S in memory, in bytes");
2001
2002static PyObject *
Meador Inge90bc2dbc2012-07-28 22:16:39 -05002003s_sizeof(PyStructObject *self, void *unused)
Meador Ingeb14d8c92012-07-23 10:01:29 -05002004{
2005 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002006 formatcode *code;
Meador Ingeb14d8c92012-07-23 10:01:29 -05002007
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02002008 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002009 for (code = self->s_codes; code->fmtdef != NULL; code++)
2010 size += sizeof(formatcode);
Meador Ingeb14d8c92012-07-23 10:01:29 -05002011 return PyLong_FromSsize_t(size);
2012}
2013
Thomas Wouters477c8d52006-05-27 19:21:47 +00002014/* List of functions */
2015
2016static struct PyMethodDef s_methods[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002017 STRUCT_ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002018 {"pack", (PyCFunction)(void(*)(void))s_pack, METH_FASTCALL, s_pack__doc__},
2019 {"pack_into", (PyCFunction)(void(*)(void))s_pack_into, METH_FASTCALL, s_pack_into__doc__},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002020 STRUCT_UNPACK_METHODDEF
2021 STRUCT_UNPACK_FROM_METHODDEF
Meador Ingeb14d8c92012-07-23 10:01:29 -05002022 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002023 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002024};
2025
Dino Viehland4f384af2019-09-10 11:18:37 +01002026static PyMemberDef s_members[] = {
Eddie Elizondo3368f3c2019-09-19 09:29:05 -07002027 {"__weaklistoffset__", T_PYSSIZET, offsetof(PyStructObject, weakreflist), READONLY},
Dino Viehland4f384af2019-09-10 11:18:37 +01002028 {NULL} /* sentinel */
2029};
2030
Thomas Wouters477c8d52006-05-27 19:21:47 +00002031#define OFF(x) offsetof(PyStructObject, x)
2032
2033static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002034 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
2035 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
2036 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002037};
2038
Dino Viehland4f384af2019-09-10 11:18:37 +01002039PyDoc_STRVAR(s__doc__,
2040"Struct(fmt) --> compiled struct object\n"
2041"\n"
2042);
2043
2044static PyType_Slot PyStructType_slots[] = {
2045 {Py_tp_dealloc, s_dealloc},
2046 {Py_tp_getattro, PyObject_GenericGetAttr},
2047 {Py_tp_setattro, PyObject_GenericSetAttr},
2048 {Py_tp_doc, (void*)s__doc__},
2049 {Py_tp_methods, s_methods},
2050 {Py_tp_members, s_members},
2051 {Py_tp_getset, s_getsetlist},
2052 {Py_tp_init, Struct___init__},
2053 {Py_tp_alloc, PyType_GenericAlloc},
2054 {Py_tp_new, s_new},
2055 {Py_tp_free, PyObject_Del},
2056 {0, 0},
2057};
2058
2059static PyType_Spec PyStructType_spec = {
2060 "_struct.Struct",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002061 sizeof(PyStructObject),
2062 0,
Dino Viehland4f384af2019-09-10 11:18:37 +01002063 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
2064 PyStructType_slots
Thomas Wouters477c8d52006-05-27 19:21:47 +00002065};
2066
Christian Heimesa34706f2008-01-04 03:06:10 +00002067
2068/* ---- Standalone functions ---- */
2069
2070#define MAXCACHE 100
2071static PyObject *cache = NULL;
2072
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002073static int
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002074cache_struct_converter(PyObject *fmt, PyStructObject **ptr)
Christian Heimesa34706f2008-01-04 03:06:10 +00002075{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002076 PyObject * s_object;
Christian Heimesa34706f2008-01-04 03:06:10 +00002077
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002078 if (fmt == NULL) {
2079 Py_DECREF(*ptr);
Serhiy Storchaka40db90c2017-04-20 21:19:31 +03002080 *ptr = NULL;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002081 return 1;
2082 }
2083
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002084 if (cache == NULL) {
2085 cache = PyDict_New();
2086 if (cache == NULL)
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002087 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002088 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002089
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002090 s_object = PyDict_GetItemWithError(cache, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002091 if (s_object != NULL) {
2092 Py_INCREF(s_object);
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002093 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002094 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002095 }
Serhiy Storchakaa24107b2019-02-25 17:59:46 +02002096 else if (PyErr_Occurred()) {
2097 return 0;
2098 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002099
Petr Viktorinffd97532020-02-11 17:46:57 +01002100 s_object = PyObject_CallOneArg(_structmodulestate_global->PyStructType, fmt);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 if (s_object != NULL) {
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02002102 if (PyDict_GET_SIZE(cache) >= MAXCACHE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002103 PyDict_Clear(cache);
2104 /* Attempt to cache the result */
2105 if (PyDict_SetItem(cache, fmt, s_object) == -1)
2106 PyErr_Clear();
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002107 *ptr = (PyStructObject *)s_object;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002108 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002109 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002110 return 0;
Christian Heimesa34706f2008-01-04 03:06:10 +00002111}
2112
Victor Stinner3f2d1012017-02-02 12:09:30 +01002113/*[clinic input]
2114_clearcache
2115
2116Clear the internal cache.
2117[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002118
2119static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002120_clearcache_impl(PyObject *module)
2121/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002122{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002123 Py_CLEAR(cache);
2124 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00002125}
2126
Victor Stinner3f2d1012017-02-02 12:09:30 +01002127
2128/*[clinic input]
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002129calcsize -> Py_ssize_t
Victor Stinner3f2d1012017-02-02 12:09:30 +01002130
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002131 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002132 /
2133
2134Return size in bytes of the struct described by the format string.
2135[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002136
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002137static Py_ssize_t
2138calcsize_impl(PyObject *module, PyStructObject *s_object)
2139/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002140{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002141 return s_object->s_size;
Christian Heimesa34706f2008-01-04 03:06:10 +00002142}
2143
2144PyDoc_STRVAR(pack_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002145"pack(format, v1, v2, ...) -> bytes\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002146\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002147Return a bytes object containing the values v1, v2, ... packed according\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002148to the format string. See help(struct) for more on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002149
2150static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02002151pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002152{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002153 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002154 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002155
Victor Stinner3f2d1012017-02-02 12:09:30 +01002156 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002157 PyErr_SetString(PyExc_TypeError, "missing format argument");
2158 return NULL;
2159 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002160 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002161
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002162 if (!cache_struct_converter(format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002163 return NULL;
2164 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002165 result = s_pack(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002166 Py_DECREF(s_object);
2167 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002168}
2169
2170PyDoc_STRVAR(pack_into_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002171"pack_into(format, buffer, offset, v1, v2, ...)\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002172\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002173Pack the values v1, v2, ... according to the format string and write\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002174the packed bytes into the writable buffer buf starting at offset. Note\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002175that the offset is a required argument. See help(struct) for more\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002176on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002177
2178static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02002179pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002180{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002181 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002182 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002183
Victor Stinner3f2d1012017-02-02 12:09:30 +01002184 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002185 PyErr_SetString(PyExc_TypeError, "missing format argument");
2186 return NULL;
2187 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002188 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002189
Serhiy Storchaka32d96a22018-12-25 13:23:47 +02002190 if (!cache_struct_converter(format, (PyStructObject **)&s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002191 return NULL;
2192 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002193 result = s_pack_into(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002194 Py_DECREF(s_object);
2195 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002196}
2197
Victor Stinner3f2d1012017-02-02 12:09:30 +01002198/*[clinic input]
2199unpack
2200
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002201 format as s_object: cache_struct
Victor Stinnerc0f59ad2017-02-02 14:24:16 +01002202 buffer: Py_buffer
Victor Stinner3f2d1012017-02-02 12:09:30 +01002203 /
2204
2205Return a tuple containing values unpacked according to the format string.
2206
2207The buffer's size in bytes must be calcsize(format).
2208
2209See help(struct) for more on format strings.
2210[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002211
2212static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002213unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2214/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002215{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002216 return Struct_unpack_impl(s_object, buffer);
Christian Heimesa34706f2008-01-04 03:06:10 +00002217}
2218
Victor Stinner3f2d1012017-02-02 12:09:30 +01002219/*[clinic input]
2220unpack_from
2221
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002222 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002223 /
2224 buffer: Py_buffer
2225 offset: Py_ssize_t = 0
2226
2227Return a tuple containing values unpacked according to the format string.
2228
2229The buffer's size, minus offset, must be at least calcsize(format).
2230
2231See help(struct) for more on format strings.
2232[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002233
2234static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002235unpack_from_impl(PyObject *module, PyStructObject *s_object,
2236 Py_buffer *buffer, Py_ssize_t offset)
2237/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002238{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002239 return Struct_unpack_from_impl(s_object, buffer, offset);
Christian Heimesa34706f2008-01-04 03:06:10 +00002240}
2241
Victor Stinner3f2d1012017-02-02 12:09:30 +01002242/*[clinic input]
2243iter_unpack
2244
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002245 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002246 buffer: object
2247 /
2248
2249Return an iterator yielding tuples unpacked from the given bytes.
2250
2251The bytes are unpacked according to the format string, like
2252a repeated invocation of unpack_from().
2253
2254Requires that the bytes length be a multiple of the format struct size.
2255[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002256
2257static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002258iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2259 PyObject *buffer)
2260/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002261{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002262 return Struct_iter_unpack(s_object, buffer);
Antoine Pitrou9f146812013-04-27 00:20:04 +02002263}
2264
Christian Heimesa34706f2008-01-04 03:06:10 +00002265static struct PyMethodDef module_functions[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002266 _CLEARCACHE_METHODDEF
2267 CALCSIZE_METHODDEF
2268 ITER_UNPACK_METHODDEF
Serhiy Storchaka62be7422018-11-27 13:27:31 +02002269 {"pack", (PyCFunction)(void(*)(void))pack, METH_FASTCALL, pack_doc},
2270 {"pack_into", (PyCFunction)(void(*)(void))pack_into, METH_FASTCALL, pack_into_doc},
Victor Stinner3f2d1012017-02-02 12:09:30 +01002271 UNPACK_METHODDEF
2272 UNPACK_FROM_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002273 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00002274};
2275
2276
Thomas Wouters477c8d52006-05-27 19:21:47 +00002277/* Module initialization */
2278
Christian Heimesa34706f2008-01-04 03:06:10 +00002279PyDoc_STRVAR(module_doc,
2280"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002281Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002282and also as format strings (explained below) to describe the layout of data\n\
2283in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002284\n\
2285The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002286 @: native order, size & alignment (default)\n\
2287 =: native order, std. size & alignment\n\
2288 <: little-endian, std. size & alignment\n\
2289 >: big-endian, std. size & alignment\n\
2290 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002291\n\
2292The remaining chars indicate types of args and must match exactly;\n\
2293these can be preceded by a decimal repeat count:\n\
2294 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002295 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002296 h:short; H:unsigned short; i:int; I:unsigned int;\n\
Mark Dickinson7c4e4092016-09-03 17:21:29 +01002297 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002298Special cases (preceding decimal count indicates length):\n\
2299 s:string (array of char); p: pascal string (with count byte).\n\
Antoine Pitrou45d9c912011-10-06 15:27:40 +02002300Special cases (only available in native format):\n\
2301 n:ssize_t; N:size_t;\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002302 P:an integer type that is wide enough to hold a pointer.\n\
2303Special case (not in native mode unless 'long long' in platform C):\n\
2304 q:long long; Q:unsigned long long\n\
2305Whitespace between formats is ignored.\n\
2306\n\
2307The variable struct.error is an exception raised on errors.\n");
2308
Martin v. Löwis1a214512008-06-11 05:26:20 +00002309
Dino Viehland4f384af2019-09-10 11:18:37 +01002310static int
2311_structmodule_traverse(PyObject *module, visitproc visit, void *arg)
2312{
2313 Py_VISIT(_structmodulestate(module)->PyStructType);
2314 Py_VISIT(_structmodulestate(module)->unpackiter_type);
2315 Py_VISIT(_structmodulestate(module)->StructError);
2316 return 0;
2317}
2318
2319static int
2320_structmodule_clear(PyObject *module)
2321{
2322 Py_CLEAR(_structmodulestate(module)->PyStructType);
2323 Py_CLEAR(_structmodulestate(module)->unpackiter_type);
2324 Py_CLEAR(_structmodulestate(module)->StructError);
2325 return 0;
2326}
2327
2328static void
2329_structmodule_free(void *module)
2330{
2331 _structmodule_clear((PyObject *)module);
2332}
2333
Martin v. Löwis1a214512008-06-11 05:26:20 +00002334static struct PyModuleDef _structmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002335 PyModuleDef_HEAD_INIT,
2336 "_struct",
2337 module_doc,
Dino Viehland4f384af2019-09-10 11:18:37 +01002338 sizeof(_structmodulestate),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002339 module_functions,
2340 NULL,
Dino Viehland4f384af2019-09-10 11:18:37 +01002341 _structmodule_traverse,
2342 _structmodule_clear,
2343 _structmodule_free,
Martin v. Löwis1a214512008-06-11 05:26:20 +00002344};
2345
Thomas Wouters477c8d52006-05-27 19:21:47 +00002346PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002347PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002348{
Mark Dickinson06817852010-06-12 09:25:13 +00002349 PyObject *m;
Christian Heimesa34706f2008-01-04 03:06:10 +00002350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002351 m = PyModule_Create(&_structmodule);
2352 if (m == NULL)
2353 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002354
Dino Viehland4f384af2019-09-10 11:18:37 +01002355 PyObject *PyStructType = PyType_FromSpec(&PyStructType_spec);
2356 if (PyStructType == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002357 return NULL;
Dino Viehland4f384af2019-09-10 11:18:37 +01002358 }
2359 Py_INCREF(PyStructType);
2360 PyModule_AddObject(m, "Struct", PyStructType);
2361 _structmodulestate(m)->PyStructType = PyStructType;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002362
Dino Viehland4f384af2019-09-10 11:18:37 +01002363 PyObject *unpackiter_type = PyType_FromSpec(&unpackiter_type_spec);
2364 if (unpackiter_type == NULL) {
Zachary Ware99f11b42016-10-04 01:20:21 -05002365 return NULL;
Dino Viehland4f384af2019-09-10 11:18:37 +01002366 }
2367 _structmodulestate(m)->unpackiter_type = unpackiter_type;
Zachary Ware99f11b42016-10-04 01:20:21 -05002368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002369 /* Check endian and swap in faster functions */
2370 {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002371 const formatdef *native = native_table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002372 formatdef *other, *ptr;
Christian Heimes743e0cd2012-10-17 23:52:17 +02002373#if PY_LITTLE_ENDIAN
2374 other = lilendian_table;
2375#else
2376 other = bigendian_table;
2377#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002378 /* Scan through the native table, find a matching
2379 entry in the endian table and swap in the
2380 native implementations whenever possible
2381 (64-bit platforms may not have "standard" sizes) */
2382 while (native->format != '\0' && other->format != '\0') {
2383 ptr = other;
2384 while (ptr->format != '\0') {
2385 if (ptr->format == native->format) {
2386 /* Match faster when formats are
2387 listed in the same order */
2388 if (ptr == other)
2389 other++;
2390 /* Only use the trick if the
2391 size matches */
2392 if (ptr->size != native->size)
2393 break;
2394 /* Skip float and double, could be
2395 "unknown" float format */
2396 if (ptr->format == 'd' || ptr->format == 'f')
2397 break;
2398 ptr->pack = native->pack;
2399 ptr->unpack = native->unpack;
2400 break;
2401 }
2402 ptr++;
2403 }
2404 native++;
2405 }
2406 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002407
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002408 /* Add some symbolic constants to the module */
Dino Viehland4f384af2019-09-10 11:18:37 +01002409 PyObject *StructError = PyErr_NewException("struct.error", NULL, NULL);
2410 if (StructError == NULL)
2411 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002412 Py_INCREF(StructError);
2413 PyModule_AddObject(m, "error", StructError);
Dino Viehland4f384af2019-09-10 11:18:37 +01002414 _structmodulestate(m)->StructError = StructError;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002416 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002417}