blob: 053970671f17c4cce018732e30bb0555f92c572f [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
Thomas Wouters477c8d52006-05-27 19:21:47 +000017static PyTypeObject PyStructType;
18
Thomas Wouters477c8d52006-05-27 19:21:47 +000019/* The translation function for each format character is table driven */
20typedef struct _formatdef {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000021 char format;
22 Py_ssize_t size;
23 Py_ssize_t alignment;
24 PyObject* (*unpack)(const char *,
25 const struct _formatdef *);
26 int (*pack)(char *, PyObject *,
27 const struct _formatdef *);
Thomas Wouters477c8d52006-05-27 19:21:47 +000028} formatdef;
29
30typedef struct _formatcode {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000031 const struct _formatdef *fmtdef;
32 Py_ssize_t offset;
33 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +030034 Py_ssize_t repeat;
Thomas Wouters477c8d52006-05-27 19:21:47 +000035} formatcode;
36
37/* Struct object interface */
38
39typedef struct {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040 PyObject_HEAD
41 Py_ssize_t s_size;
42 Py_ssize_t s_len;
43 formatcode *s_codes;
44 PyObject *s_format;
45 PyObject *weakreflist; /* List of weak references */
Thomas Wouters477c8d52006-05-27 19:21:47 +000046} PyStructObject;
47
48
49#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)
Christian Heimes90aa7642007-12-19 02:45:37 +000050#define PyStruct_CheckExact(op) (Py_TYPE(op) == &PyStructType)
Thomas Wouters477c8d52006-05-27 19:21:47 +000051
52
53/* Exception */
54
55static PyObject *StructError;
56
57
58/* Define various structs to figure out the alignments of types */
59
60
61typedef struct { char c; short x; } st_short;
62typedef struct { char c; int x; } st_int;
63typedef struct { char c; long x; } st_long;
64typedef struct { char c; float x; } st_float;
65typedef struct { char c; double x; } st_double;
66typedef struct { char c; void *x; } st_void_p;
Antoine Pitrou45d9c912011-10-06 15:27:40 +020067typedef struct { char c; size_t x; } st_size_t;
Benjamin Petersona9296e72016-09-07 11:06:17 -070068typedef struct { char c; _Bool x; } st_bool;
Thomas Wouters477c8d52006-05-27 19:21:47 +000069
70#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))
71#define INT_ALIGN (sizeof(st_int) - sizeof(int))
72#define LONG_ALIGN (sizeof(st_long) - sizeof(long))
73#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))
74#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))
75#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))
Antoine Pitrou45d9c912011-10-06 15:27:40 +020076#define SIZE_T_ALIGN (sizeof(st_size_t) - sizeof(size_t))
Benjamin Petersona9296e72016-09-07 11:06:17 -070077#define BOOL_ALIGN (sizeof(st_bool) - sizeof(_Bool))
Thomas Wouters477c8d52006-05-27 19:21:47 +000078
79/* We can't support q and Q in native mode unless the compiler does;
80 in std mode, they're 8 bytes on all platforms. */
Benjamin Petersonaf580df2016-09-06 10:46:49 -070081typedef struct { char c; long long x; } s_long_long;
82#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(long long))
Thomas Wouters477c8d52006-05-27 19:21:47 +000083
Thomas Wouters477c8d52006-05-27 19:21:47 +000084#ifdef __powerc
85#pragma options align=reset
86#endif
87
Serhiy Storchakaa5a55902017-02-04 11:14:52 +020088/*[python input]
89class cache_struct_converter(CConverter):
90 type = 'PyStructObject *'
91 converter = 'cache_struct_converter'
92 c_default = "NULL"
93
94 def cleanup(self):
95 return "Py_XDECREF(%s);\n" % self.name
96[python start generated code]*/
97/*[python end generated code: output=da39a3ee5e6b4b0d input=49957cca130ffb63]*/
98
99static int cache_struct_converter(PyObject *, PyObject **);
100
Victor Stinner3f2d1012017-02-02 12:09:30 +0100101#include "clinic/_struct.c.h"
102
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000103/* Helper for integer format codes: converts an arbitrary Python object to a
104 PyLongObject if possible, otherwise fails. Caller should decref. */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000105
106static PyObject *
107get_pylong(PyObject *v)
108{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 assert(v != NULL);
110 if (!PyLong_Check(v)) {
111 /* Not an integer; try to use __index__ to convert. */
112 if (PyIndex_Check(v)) {
113 v = PyNumber_Index(v);
114 if (v == NULL)
115 return NULL;
116 }
117 else {
118 PyErr_SetString(StructError,
119 "required argument is not an integer");
120 return NULL;
121 }
122 }
123 else
124 Py_INCREF(v);
Mark Dickinsonea835e72009-04-19 20:40:33 +0000125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000126 assert(PyLong_Check(v));
127 return v;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000128}
129
Mark Dickinsonea835e72009-04-19 20:40:33 +0000130/* Helper routine to get a C long and raise the appropriate error if it isn't
131 one */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000132
133static int
134get_long(PyObject *v, long *p)
135{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000136 long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000137
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 v = get_pylong(v);
139 if (v == NULL)
140 return -1;
141 assert(PyLong_Check(v));
142 x = PyLong_AsLong(v);
143 Py_DECREF(v);
144 if (x == (long)-1 && PyErr_Occurred()) {
145 if (PyErr_ExceptionMatches(PyExc_OverflowError))
146 PyErr_SetString(StructError,
147 "argument out of range");
148 return -1;
149 }
150 *p = x;
151 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000152}
153
154
155/* Same, but handling unsigned long */
156
157static int
158get_ulong(PyObject *v, unsigned long *p)
159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 unsigned long x;
Mark Dickinsonea835e72009-04-19 20:40:33 +0000161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 v = get_pylong(v);
163 if (v == NULL)
164 return -1;
165 assert(PyLong_Check(v));
166 x = PyLong_AsUnsignedLong(v);
167 Py_DECREF(v);
168 if (x == (unsigned long)-1 && PyErr_Occurred()) {
169 if (PyErr_ExceptionMatches(PyExc_OverflowError))
170 PyErr_SetString(StructError,
171 "argument out of range");
172 return -1;
173 }
174 *p = x;
175 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000176}
177
Thomas Wouters477c8d52006-05-27 19:21:47 +0000178/* Same, but handling native long long. */
179
180static int
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700181get_longlong(PyObject *v, long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000182{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700183 long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000184
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 v = get_pylong(v);
186 if (v == NULL)
187 return -1;
188 assert(PyLong_Check(v));
189 x = PyLong_AsLongLong(v);
190 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700191 if (x == (long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 if (PyErr_ExceptionMatches(PyExc_OverflowError))
193 PyErr_SetString(StructError,
194 "argument out of range");
195 return -1;
196 }
197 *p = x;
198 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000199}
200
201/* Same, but handling native unsigned long long. */
202
203static int
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700204get_ulonglong(PyObject *v, unsigned long long *p)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000205{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700206 unsigned long long x;
Mark Dickinson055a3fb2010-04-03 15:26:31 +0000207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 v = get_pylong(v);
209 if (v == NULL)
210 return -1;
211 assert(PyLong_Check(v));
212 x = PyLong_AsUnsignedLongLong(v);
213 Py_DECREF(v);
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700214 if (x == (unsigned long long)-1 && PyErr_Occurred()) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000215 if (PyErr_ExceptionMatches(PyExc_OverflowError))
216 PyErr_SetString(StructError,
217 "argument out of range");
218 return -1;
219 }
220 *p = x;
221 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000222}
223
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200224/* Same, but handling Py_ssize_t */
225
226static int
227get_ssize_t(PyObject *v, Py_ssize_t *p)
228{
229 Py_ssize_t x;
230
231 v = get_pylong(v);
232 if (v == NULL)
233 return -1;
234 assert(PyLong_Check(v));
235 x = PyLong_AsSsize_t(v);
236 Py_DECREF(v);
237 if (x == (Py_ssize_t)-1 && PyErr_Occurred()) {
238 if (PyErr_ExceptionMatches(PyExc_OverflowError))
239 PyErr_SetString(StructError,
240 "argument out of range");
241 return -1;
242 }
243 *p = x;
244 return 0;
245}
246
247/* Same, but handling size_t */
248
249static int
250get_size_t(PyObject *v, size_t *p)
251{
252 size_t x;
253
254 v = get_pylong(v);
255 if (v == NULL)
256 return -1;
257 assert(PyLong_Check(v));
258 x = PyLong_AsSize_t(v);
259 Py_DECREF(v);
260 if (x == (size_t)-1 && PyErr_Occurred()) {
261 if (PyErr_ExceptionMatches(PyExc_OverflowError))
262 PyErr_SetString(StructError,
263 "argument out of range");
264 return -1;
265 }
266 *p = x;
267 return 0;
268}
269
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000270
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000271#define RANGE_ERROR(x, f, flag, mask) return _range_error(f, flag)
272
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000273
Thomas Wouters477c8d52006-05-27 19:21:47 +0000274/* Floating point helpers */
275
276static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100277unpack_halffloat(const char *p, /* start of 2-byte string */
278 int le) /* true for little-endian, false for big-endian */
279{
280 double x;
281
282 x = _PyFloat_Unpack2((unsigned char *)p, le);
283 if (x == -1.0 && PyErr_Occurred()) {
284 return NULL;
285 }
286 return PyFloat_FromDouble(x);
287}
288
289static int
290pack_halffloat(char *p, /* start of 2-byte string */
291 PyObject *v, /* value to pack */
292 int le) /* true for little-endian, false for big-endian */
293{
294 double x = PyFloat_AsDouble(v);
295 if (x == -1.0 && PyErr_Occurred()) {
296 PyErr_SetString(StructError,
297 "required argument is not a float");
298 return -1;
299 }
300 return _PyFloat_Pack2(x, (unsigned char *)p, le);
301}
302
303static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000304unpack_float(const char *p, /* start of 4-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000306{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 x = _PyFloat_Unpack4((unsigned char *)p, le);
310 if (x == -1.0 && PyErr_Occurred())
311 return NULL;
312 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000313}
314
315static PyObject *
316unpack_double(const char *p, /* start of 8-byte string */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 int le) /* true for little-endian, false for big-endian */
Thomas Wouters477c8d52006-05-27 19:21:47 +0000318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 double x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000321 x = _PyFloat_Unpack8((unsigned char *)p, le);
322 if (x == -1.0 && PyErr_Occurred())
323 return NULL;
324 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000325}
326
327/* Helper to format the range error exceptions */
328static int
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000329_range_error(const formatdef *f, int is_unsigned)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 /* ulargest is the largest unsigned value with f->size bytes.
332 * Note that the simpler:
333 * ((size_t)1 << (f->size * 8)) - 1
334 * doesn't work when f->size == sizeof(size_t) because C doesn't
335 * define what happens when a left shift count is >= the number of
336 * bits in the integer being shifted; e.g., on some boxes it doesn't
337 * shift at all when they're equal.
338 */
339 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);
340 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);
341 if (is_unsigned)
342 PyErr_Format(StructError,
343 "'%c' format requires 0 <= number <= %zu",
344 f->format,
345 ulargest);
346 else {
347 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);
348 PyErr_Format(StructError,
349 "'%c' format requires %zd <= number <= %zd",
350 f->format,
351 ~ largest,
352 largest);
353 }
Mark Dickinsonae681df2009-03-21 10:26:31 +0000354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000355 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000356}
357
358
359
360/* A large number of small routines follow, with names of the form
361
362 [bln][up]_TYPE
363
364 [bln] distiguishes among big-endian, little-endian and native.
365 [pu] distiguishes between pack (to struct) and unpack (from struct).
366 TYPE is one of char, byte, ubyte, etc.
367*/
368
369/* Native mode routines. ****************************************************/
370/* NOTE:
371 In all n[up]_<type> routines handling types larger than 1 byte, there is
372 *no* guarantee that the p pointer is properly aligned for each type,
373 therefore memcpy is called. An intermediate variable is used to
374 compensate for big-endian architectures.
375 Normally both the intermediate variable and the memcpy call will be
376 skipped by C optimisation in little-endian architectures (gcc >= 2.91
377 does this). */
378
379static PyObject *
380nu_char(const char *p, const formatdef *f)
381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000382 return PyBytes_FromStringAndSize(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000383}
384
385static PyObject *
386nu_byte(const char *p, const formatdef *f)
387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 return PyLong_FromLong((long) *(signed char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000389}
390
391static PyObject *
392nu_ubyte(const char *p, const formatdef *f)
393{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000394 return PyLong_FromLong((long) *(unsigned char *)p);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000395}
396
397static PyObject *
398nu_short(const char *p, const formatdef *f)
399{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 short x;
401 memcpy((char *)&x, p, sizeof x);
402 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000403}
404
405static PyObject *
406nu_ushort(const char *p, const formatdef *f)
407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 unsigned short x;
409 memcpy((char *)&x, p, sizeof x);
410 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000411}
412
413static PyObject *
414nu_int(const char *p, const formatdef *f)
415{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000416 int x;
417 memcpy((char *)&x, p, sizeof x);
418 return PyLong_FromLong((long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000419}
420
421static PyObject *
422nu_uint(const char *p, const formatdef *f)
423{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 unsigned int x;
425 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 return PyLong_FromUnsignedLong((unsigned long)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000427}
428
429static PyObject *
430nu_long(const char *p, const formatdef *f)
431{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 long x;
433 memcpy((char *)&x, p, sizeof x);
434 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000435}
436
437static PyObject *
438nu_ulong(const char *p, const formatdef *f)
439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 unsigned long x;
441 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000443}
444
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200445static PyObject *
446nu_ssize_t(const char *p, const formatdef *f)
447{
448 Py_ssize_t x;
449 memcpy((char *)&x, p, sizeof x);
450 return PyLong_FromSsize_t(x);
451}
452
453static PyObject *
454nu_size_t(const char *p, const formatdef *f)
455{
456 size_t x;
457 memcpy((char *)&x, p, sizeof x);
458 return PyLong_FromSize_t(x);
459}
460
Thomas Wouters477c8d52006-05-27 19:21:47 +0000461static PyObject *
462nu_longlong(const char *p, const formatdef *f)
463{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700464 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000465 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000467}
468
469static PyObject *
470nu_ulonglong(const char *p, const formatdef *f)
471{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700472 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 memcpy((char *)&x, p, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000475}
476
Thomas Wouters477c8d52006-05-27 19:21:47 +0000477static PyObject *
Thomas Woutersb2137042007-02-01 18:02:27 +0000478nu_bool(const char *p, const formatdef *f)
479{
Benjamin Petersona9296e72016-09-07 11:06:17 -0700480 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 memcpy((char *)&x, p, sizeof x);
482 return PyBool_FromLong(x != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000483}
484
485
486static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100487nu_halffloat(const char *p, const formatdef *f)
488{
489#if PY_LITTLE_ENDIAN
490 return unpack_halffloat(p, 1);
491#else
492 return unpack_halffloat(p, 0);
Benjamin Petersone2e792d2016-09-19 22:17:16 -0700493#endif
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100494}
495
496static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000497nu_float(const char *p, const formatdef *f)
498{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 float x;
500 memcpy((char *)&x, p, sizeof x);
501 return PyFloat_FromDouble((double)x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000502}
503
504static PyObject *
505nu_double(const char *p, const formatdef *f)
506{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 double x;
508 memcpy((char *)&x, p, sizeof x);
509 return PyFloat_FromDouble(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000510}
511
512static PyObject *
513nu_void_p(const char *p, const formatdef *f)
514{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 void *x;
516 memcpy((char *)&x, p, sizeof x);
517 return PyLong_FromVoidPtr(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000518}
519
520static int
521np_byte(char *p, PyObject *v, const formatdef *f)
522{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 long x;
524 if (get_long(v, &x) < 0)
525 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800526 if (x < -128 || x > 127) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 PyErr_SetString(StructError,
528 "byte format requires -128 <= number <= 127");
529 return -1;
530 }
531 *p = (char)x;
532 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000533}
534
535static int
536np_ubyte(char *p, PyObject *v, const formatdef *f)
537{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 long x;
539 if (get_long(v, &x) < 0)
540 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800541 if (x < 0 || x > 255) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000542 PyErr_SetString(StructError,
543 "ubyte format requires 0 <= number <= 255");
544 return -1;
545 }
Xiang Zhang981096f2017-05-15 12:04:26 +0800546 *(unsigned char *)p = (unsigned char)x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000548}
549
550static int
551np_char(char *p, PyObject *v, const formatdef *f)
552{
Xiang Zhang96f50282017-05-15 11:53:51 +0800553 if (!PyBytes_Check(v) || PyBytes_GET_SIZE(v) != 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 PyErr_SetString(StructError,
Victor Stinnerda9ec992010-12-28 13:26:42 +0000555 "char format requires a bytes object of length 1");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 return -1;
557 }
Xiang Zhang96f50282017-05-15 11:53:51 +0800558 *p = *PyBytes_AS_STRING(v);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000560}
561
562static int
563np_short(char *p, PyObject *v, const formatdef *f)
564{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000565 long x;
566 short y;
567 if (get_long(v, &x) < 0)
568 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800569 if (x < SHRT_MIN || x > SHRT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 PyErr_SetString(StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200571 "short format requires " Py_STRINGIFY(SHRT_MIN)
572 " <= number <= " Py_STRINGIFY(SHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000573 return -1;
574 }
575 y = (short)x;
576 memcpy(p, (char *)&y, sizeof y);
577 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000578}
579
580static int
581np_ushort(char *p, PyObject *v, const formatdef *f)
582{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 long x;
584 unsigned short y;
585 if (get_long(v, &x) < 0)
586 return -1;
Xiang Zhang96f50282017-05-15 11:53:51 +0800587 if (x < 0 || x > USHRT_MAX) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 PyErr_SetString(StructError,
Victor Stinner45e8e2f2014-05-14 17:24:35 +0200589 "ushort format requires 0 <= number <= "
590 Py_STRINGIFY(USHRT_MAX));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000591 return -1;
592 }
593 y = (unsigned short)x;
594 memcpy(p, (char *)&y, sizeof y);
595 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000596}
597
598static int
599np_int(char *p, PyObject *v, const formatdef *f)
600{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 long x;
602 int y;
603 if (get_long(v, &x) < 0)
604 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000605#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000606 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))
607 RANGE_ERROR(x, f, 0, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000608#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 y = (int)x;
610 memcpy(p, (char *)&y, sizeof y);
611 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000612}
613
614static int
615np_uint(char *p, PyObject *v, const formatdef *f)
616{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000617 unsigned long x;
618 unsigned int y;
619 if (get_ulong(v, &x) < 0)
620 return -1;
621 y = (unsigned int)x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000622#if (SIZEOF_LONG > SIZEOF_INT)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000623 if (x > ((unsigned long)UINT_MAX))
624 RANGE_ERROR(y, f, 1, -1);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000625#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 memcpy(p, (char *)&y, sizeof y);
627 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000628}
629
630static int
631np_long(char *p, PyObject *v, const formatdef *f)
632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 long x;
634 if (get_long(v, &x) < 0)
635 return -1;
636 memcpy(p, (char *)&x, sizeof x);
637 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000638}
639
640static int
641np_ulong(char *p, PyObject *v, const formatdef *f)
642{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 unsigned long x;
644 if (get_ulong(v, &x) < 0)
645 return -1;
646 memcpy(p, (char *)&x, sizeof x);
647 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000648}
649
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200650static int
651np_ssize_t(char *p, PyObject *v, const formatdef *f)
652{
653 Py_ssize_t x;
654 if (get_ssize_t(v, &x) < 0)
655 return -1;
656 memcpy(p, (char *)&x, sizeof x);
657 return 0;
658}
659
660static int
661np_size_t(char *p, PyObject *v, const formatdef *f)
662{
663 size_t x;
664 if (get_size_t(v, &x) < 0)
665 return -1;
666 memcpy(p, (char *)&x, sizeof x);
667 return 0;
668}
669
Thomas Wouters477c8d52006-05-27 19:21:47 +0000670static int
671np_longlong(char *p, PyObject *v, const formatdef *f)
672{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700673 long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000674 if (get_longlong(v, &x) < 0)
675 return -1;
676 memcpy(p, (char *)&x, sizeof x);
677 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000678}
679
680static int
681np_ulonglong(char *p, PyObject *v, const formatdef *f)
682{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700683 unsigned long long x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000684 if (get_ulonglong(v, &x) < 0)
685 return -1;
686 memcpy(p, (char *)&x, sizeof x);
687 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000688}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000689
Thomas Woutersb2137042007-02-01 18:02:27 +0000690
691static int
692np_bool(char *p, PyObject *v, const formatdef *f)
693{
Benjamin Petersonde73c452010-07-07 18:54:59 +0000694 int y;
Benjamin Petersona9296e72016-09-07 11:06:17 -0700695 _Bool x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000697 if (y < 0)
698 return -1;
699 x = y;
700 memcpy(p, (char *)&x, sizeof x);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000702}
703
Thomas Wouters477c8d52006-05-27 19:21:47 +0000704static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100705np_halffloat(char *p, PyObject *v, const formatdef *f)
706{
707#if PY_LITTLE_ENDIAN
708 return pack_halffloat(p, v, 1);
709#else
710 return pack_halffloat(p, v, 0);
711#endif
712}
713
714static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000715np_float(char *p, PyObject *v, const formatdef *f)
716{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000717 float x = (float)PyFloat_AsDouble(v);
718 if (x == -1 && PyErr_Occurred()) {
719 PyErr_SetString(StructError,
720 "required argument is not a float");
721 return -1;
722 }
723 memcpy(p, (char *)&x, sizeof x);
724 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000725}
726
727static int
728np_double(char *p, PyObject *v, const formatdef *f)
729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 double x = PyFloat_AsDouble(v);
731 if (x == -1 && PyErr_Occurred()) {
732 PyErr_SetString(StructError,
733 "required argument is not a float");
734 return -1;
735 }
736 memcpy(p, (char *)&x, sizeof(double));
737 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000738}
739
740static int
741np_void_p(char *p, PyObject *v, const formatdef *f)
742{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000743 void *x;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 v = get_pylong(v);
746 if (v == NULL)
747 return -1;
748 assert(PyLong_Check(v));
749 x = PyLong_AsVoidPtr(v);
750 Py_DECREF(v);
751 if (x == NULL && PyErr_Occurred())
752 return -1;
753 memcpy(p, (char *)&x, sizeof x);
754 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000755}
756
Serhiy Storchaka2d06e842015-12-25 19:53:18 +0200757static const formatdef native_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 {'x', sizeof(char), 0, NULL},
759 {'b', sizeof(char), 0, nu_byte, np_byte},
760 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
761 {'c', sizeof(char), 0, nu_char, np_char},
762 {'s', sizeof(char), 0, NULL},
763 {'p', sizeof(char), 0, NULL},
764 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
765 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
766 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
767 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
768 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
769 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Antoine Pitrou45d9c912011-10-06 15:27:40 +0200770 {'n', sizeof(size_t), SIZE_T_ALIGN, nu_ssize_t, np_ssize_t},
771 {'N', sizeof(size_t), SIZE_T_ALIGN, nu_size_t, np_size_t},
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700772 {'q', sizeof(long long), LONG_LONG_ALIGN, nu_longlong, np_longlong},
773 {'Q', sizeof(long long), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},
Benjamin Petersona9296e72016-09-07 11:06:17 -0700774 {'?', sizeof(_Bool), BOOL_ALIGN, nu_bool, np_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100775 {'e', sizeof(short), SHORT_ALIGN, nu_halffloat, np_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000776 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
777 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
778 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
779 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +0000780};
781
782/* Big-endian routines. *****************************************************/
783
784static PyObject *
785bu_int(const char *p, const formatdef *f)
786{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 long x = 0;
788 Py_ssize_t i = f->size;
789 const unsigned char *bytes = (const unsigned char *)p;
790 do {
791 x = (x<<8) | *bytes++;
792 } while (--i > 0);
793 /* Extend the sign bit. */
794 if (SIZEOF_LONG > f->size)
795 x |= -(x & (1L << ((8 * f->size) - 1)));
796 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000797}
798
799static PyObject *
800bu_uint(const char *p, const formatdef *f)
801{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 unsigned long x = 0;
803 Py_ssize_t i = f->size;
804 const unsigned char *bytes = (const unsigned char *)p;
805 do {
806 x = (x<<8) | *bytes++;
807 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000809}
810
811static PyObject *
812bu_longlong(const char *p, const formatdef *f)
813{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700814 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000815 Py_ssize_t i = f->size;
816 const unsigned char *bytes = (const unsigned char *)p;
817 do {
818 x = (x<<8) | *bytes++;
819 } while (--i > 0);
820 /* Extend the sign bit. */
821 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700822 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000823 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000824}
825
826static PyObject *
827bu_ulonglong(const char *p, const formatdef *f)
828{
Benjamin Petersonaf580df2016-09-06 10:46:49 -0700829 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000830 Py_ssize_t i = f->size;
831 const unsigned char *bytes = (const unsigned char *)p;
832 do {
833 x = (x<<8) | *bytes++;
834 } while (--i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000836}
837
838static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100839bu_halffloat(const char *p, const formatdef *f)
840{
841 return unpack_halffloat(p, 0);
842}
843
844static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +0000845bu_float(const char *p, const formatdef *f)
846{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000847 return unpack_float(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000848}
849
850static PyObject *
851bu_double(const char *p, const formatdef *f)
852{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 return unpack_double(p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000854}
855
Thomas Woutersb2137042007-02-01 18:02:27 +0000856static PyObject *
857bu_bool(const char *p, const formatdef *f)
858{
Xiang Zhang96f50282017-05-15 11:53:51 +0800859 return PyBool_FromLong(*p != 0);
Thomas Woutersb2137042007-02-01 18:02:27 +0000860}
861
Thomas Wouters477c8d52006-05-27 19:21:47 +0000862static int
863bp_int(char *p, PyObject *v, const formatdef *f)
864{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 long x;
866 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800867 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 if (get_long(v, &x) < 0)
869 return -1;
870 i = f->size;
871 if (i != SIZEOF_LONG) {
872 if ((i == 2) && (x < -32768 || x > 32767))
873 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000874#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000875 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
876 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +0000877#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000878 }
879 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800880 q[--i] = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000881 x >>= 8;
882 } while (i > 0);
883 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000884}
885
886static int
887bp_uint(char *p, PyObject *v, const formatdef *f)
888{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000889 unsigned long x;
890 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +0800891 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 if (get_ulong(v, &x) < 0)
893 return -1;
894 i = f->size;
895 if (i != SIZEOF_LONG) {
896 unsigned long maxint = 1;
897 maxint <<= (unsigned long)(i * 8);
898 if (x >= maxint)
899 RANGE_ERROR(x, f, 1, maxint - 1);
900 }
901 do {
Xiang Zhang981096f2017-05-15 12:04:26 +0800902 q[--i] = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000903 x >>= 8;
904 } while (i > 0);
905 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000906}
907
908static int
909bp_longlong(char *p, PyObject *v, const formatdef *f)
910{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 int res;
912 v = get_pylong(v);
913 if (v == NULL)
914 return -1;
915 res = _PyLong_AsByteArray((PyLongObject *)v,
916 (unsigned char *)p,
917 8,
918 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800919 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 Py_DECREF(v);
921 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000922}
923
924static int
925bp_ulonglong(char *p, PyObject *v, const formatdef *f)
926{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 int res;
928 v = get_pylong(v);
929 if (v == NULL)
930 return -1;
931 res = _PyLong_AsByteArray((PyLongObject *)v,
932 (unsigned char *)p,
933 8,
934 0, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +0800935 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000936 Py_DECREF(v);
937 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +0000938}
939
940static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100941bp_halffloat(char *p, PyObject *v, const formatdef *f)
942{
943 return pack_halffloat(p, v, 0);
944}
945
946static int
Thomas Wouters477c8d52006-05-27 19:21:47 +0000947bp_float(char *p, PyObject *v, const formatdef *f)
948{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 double x = PyFloat_AsDouble(v);
950 if (x == -1 && PyErr_Occurred()) {
951 PyErr_SetString(StructError,
952 "required argument is not a float");
953 return -1;
954 }
955 return _PyFloat_Pack4(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000956}
957
958static int
959bp_double(char *p, PyObject *v, const formatdef *f)
960{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 double x = PyFloat_AsDouble(v);
962 if (x == -1 && PyErr_Occurred()) {
963 PyErr_SetString(StructError,
964 "required argument is not a float");
965 return -1;
966 }
967 return _PyFloat_Pack8(x, (unsigned char *)p, 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +0000968}
969
Thomas Woutersb2137042007-02-01 18:02:27 +0000970static int
971bp_bool(char *p, PyObject *v, const formatdef *f)
972{
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000973 int y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 y = PyObject_IsTrue(v);
Benjamin Petersonde73c452010-07-07 18:54:59 +0000975 if (y < 0)
976 return -1;
Mark Dickinsoneff5d852010-07-18 07:29:02 +0000977 *p = (char)y;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 return 0;
Thomas Woutersb2137042007-02-01 18:02:27 +0000979}
980
Thomas Wouters477c8d52006-05-27 19:21:47 +0000981static formatdef bigendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 {'x', 1, 0, NULL},
983 {'b', 1, 0, nu_byte, np_byte},
984 {'B', 1, 0, nu_ubyte, np_ubyte},
985 {'c', 1, 0, nu_char, np_char},
986 {'s', 1, 0, NULL},
987 {'p', 1, 0, NULL},
988 {'h', 2, 0, bu_int, bp_int},
989 {'H', 2, 0, bu_uint, bp_uint},
990 {'i', 4, 0, bu_int, bp_int},
991 {'I', 4, 0, bu_uint, bp_uint},
992 {'l', 4, 0, bu_int, bp_int},
993 {'L', 4, 0, bu_uint, bp_uint},
994 {'q', 8, 0, bu_longlong, bp_longlong},
995 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},
996 {'?', 1, 0, bu_bool, bp_bool},
Mark Dickinson7c4e4092016-09-03 17:21:29 +0100997 {'e', 2, 0, bu_halffloat, bp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000998 {'f', 4, 0, bu_float, bp_float},
999 {'d', 8, 0, bu_double, bp_double},
1000 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001001};
1002
1003/* Little-endian routines. *****************************************************/
1004
1005static PyObject *
1006lu_int(const char *p, const formatdef *f)
1007{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 long x = 0;
1009 Py_ssize_t i = f->size;
1010 const unsigned char *bytes = (const unsigned char *)p;
1011 do {
1012 x = (x<<8) | bytes[--i];
1013 } while (i > 0);
1014 /* Extend the sign bit. */
1015 if (SIZEOF_LONG > f->size)
1016 x |= -(x & (1L << ((8 * f->size) - 1)));
1017 return PyLong_FromLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001018}
1019
1020static PyObject *
1021lu_uint(const char *p, const formatdef *f)
1022{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 unsigned long x = 0;
1024 Py_ssize_t i = f->size;
1025 const unsigned char *bytes = (const unsigned char *)p;
1026 do {
1027 x = (x<<8) | bytes[--i];
1028 } while (i > 0);
Xiang Zhang96f50282017-05-15 11:53:51 +08001029 return PyLong_FromUnsignedLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001030}
1031
1032static PyObject *
1033lu_longlong(const char *p, const formatdef *f)
1034{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001035 long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 Py_ssize_t i = f->size;
1037 const unsigned char *bytes = (const unsigned char *)p;
1038 do {
1039 x = (x<<8) | bytes[--i];
1040 } while (i > 0);
1041 /* Extend the sign bit. */
1042 if (SIZEOF_LONG_LONG > f->size)
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001043 x |= -(x & ((long long)1 << ((8 * f->size) - 1)));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001044 return PyLong_FromLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001045}
1046
1047static PyObject *
1048lu_ulonglong(const char *p, const formatdef *f)
1049{
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001050 unsigned long long x = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001051 Py_ssize_t i = f->size;
1052 const unsigned char *bytes = (const unsigned char *)p;
1053 do {
1054 x = (x<<8) | bytes[--i];
1055 } while (i > 0);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 return PyLong_FromUnsignedLongLong(x);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001057}
1058
1059static PyObject *
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001060lu_halffloat(const char *p, const formatdef *f)
1061{
1062 return unpack_halffloat(p, 1);
1063}
1064
1065static PyObject *
Thomas Wouters477c8d52006-05-27 19:21:47 +00001066lu_float(const char *p, const formatdef *f)
1067{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 return unpack_float(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001069}
1070
1071static PyObject *
1072lu_double(const char *p, const formatdef *f)
1073{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001074 return unpack_double(p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001075}
1076
1077static int
1078lp_int(char *p, PyObject *v, const formatdef *f)
1079{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 long x;
1081 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001082 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 if (get_long(v, &x) < 0)
1084 return -1;
1085 i = f->size;
1086 if (i != SIZEOF_LONG) {
1087 if ((i == 2) && (x < -32768 || x > 32767))
1088 RANGE_ERROR(x, f, 0, 0xffffL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001089#if (SIZEOF_LONG != 4)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))
1091 RANGE_ERROR(x, f, 0, 0xffffffffL);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001092#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001093 }
1094 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001095 *q++ = (unsigned char)(x & 0xffL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 x >>= 8;
1097 } while (--i > 0);
1098 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001099}
1100
1101static int
1102lp_uint(char *p, PyObject *v, const formatdef *f)
1103{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 unsigned long x;
1105 Py_ssize_t i;
Xiang Zhang981096f2017-05-15 12:04:26 +08001106 unsigned char *q = (unsigned char *)p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001107 if (get_ulong(v, &x) < 0)
1108 return -1;
1109 i = f->size;
1110 if (i != SIZEOF_LONG) {
1111 unsigned long maxint = 1;
1112 maxint <<= (unsigned long)(i * 8);
1113 if (x >= maxint)
1114 RANGE_ERROR(x, f, 1, maxint - 1);
1115 }
1116 do {
Xiang Zhang981096f2017-05-15 12:04:26 +08001117 *q++ = (unsigned char)(x & 0xffUL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 x >>= 8;
1119 } while (--i > 0);
1120 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001121}
1122
1123static int
1124lp_longlong(char *p, PyObject *v, const formatdef *f)
1125{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 int res;
1127 v = get_pylong(v);
1128 if (v == NULL)
1129 return -1;
1130 res = _PyLong_AsByteArray((PyLongObject*)v,
1131 (unsigned char *)p,
1132 8,
1133 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001134 1 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001135 Py_DECREF(v);
1136 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001137}
1138
1139static int
1140lp_ulonglong(char *p, PyObject *v, const formatdef *f)
1141{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 int res;
1143 v = get_pylong(v);
1144 if (v == NULL)
1145 return -1;
1146 res = _PyLong_AsByteArray((PyLongObject*)v,
1147 (unsigned char *)p,
1148 8,
1149 1, /* little_endian */
Xiang Zhang96f50282017-05-15 11:53:51 +08001150 0 /* signed */);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 Py_DECREF(v);
1152 return res;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001153}
1154
1155static int
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001156lp_halffloat(char *p, PyObject *v, const formatdef *f)
1157{
1158 return pack_halffloat(p, v, 1);
1159}
1160
1161static int
Thomas Wouters477c8d52006-05-27 19:21:47 +00001162lp_float(char *p, PyObject *v, const formatdef *f)
1163{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 double x = PyFloat_AsDouble(v);
1165 if (x == -1 && PyErr_Occurred()) {
1166 PyErr_SetString(StructError,
1167 "required argument is not a float");
1168 return -1;
1169 }
1170 return _PyFloat_Pack4(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001171}
1172
1173static int
1174lp_double(char *p, PyObject *v, const formatdef *f)
1175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 double x = PyFloat_AsDouble(v);
1177 if (x == -1 && PyErr_Occurred()) {
1178 PyErr_SetString(StructError,
1179 "required argument is not a float");
1180 return -1;
1181 }
1182 return _PyFloat_Pack8(x, (unsigned char *)p, 1);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001183}
1184
1185static formatdef lilendian_table[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 {'x', 1, 0, NULL},
1187 {'b', 1, 0, nu_byte, np_byte},
1188 {'B', 1, 0, nu_ubyte, np_ubyte},
1189 {'c', 1, 0, nu_char, np_char},
1190 {'s', 1, 0, NULL},
1191 {'p', 1, 0, NULL},
1192 {'h', 2, 0, lu_int, lp_int},
1193 {'H', 2, 0, lu_uint, lp_uint},
1194 {'i', 4, 0, lu_int, lp_int},
1195 {'I', 4, 0, lu_uint, lp_uint},
1196 {'l', 4, 0, lu_int, lp_int},
1197 {'L', 4, 0, lu_uint, lp_uint},
1198 {'q', 8, 0, lu_longlong, lp_longlong},
1199 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},
1200 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,
1201 but potentially different from native rep -- reuse bx_bool funcs. */
Mark Dickinson7c4e4092016-09-03 17:21:29 +01001202 {'e', 2, 0, lu_halffloat, lp_halffloat},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 {'f', 4, 0, lu_float, lp_float},
1204 {'d', 8, 0, lu_double, lp_double},
1205 {0}
Thomas Wouters477c8d52006-05-27 19:21:47 +00001206};
1207
1208
1209static const formatdef *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001210whichtable(const char **pfmt)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001211{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 const char *fmt = (*pfmt)++; /* May be backed out of later */
1213 switch (*fmt) {
1214 case '<':
1215 return lilendian_table;
1216 case '>':
1217 case '!': /* Network byte order is big-endian */
1218 return bigendian_table;
Ezio Melotti42da6632011-03-15 05:18:48 +02001219 case '=': { /* Host byte order -- different from native in alignment! */
Christian Heimes743e0cd2012-10-17 23:52:17 +02001220#if PY_LITTLE_ENDIAN
1221 return lilendian_table;
1222#else
1223 return bigendian_table;
1224#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 }
1226 default:
1227 --*pfmt; /* Back out of pointer increment */
1228 /* Fall through */
1229 case '@':
1230 return native_table;
1231 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001232}
1233
1234
1235/* Get the table entry for a format code */
1236
1237static const formatdef *
1238getentry(int c, const formatdef *f)
1239{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 for (; f->format != '\0'; f++) {
1241 if (f->format == c) {
1242 return f;
1243 }
1244 }
1245 PyErr_SetString(StructError, "bad char in struct format");
1246 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001247}
1248
1249
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001250/* Align a size according to a format code. Return -1 on overflow. */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001251
Mark Dickinsoneac0e682010-06-11 19:05:08 +00001252static Py_ssize_t
Thomas Wouters477c8d52006-05-27 19:21:47 +00001253align(Py_ssize_t size, char c, const formatdef *e)
1254{
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001255 Py_ssize_t extra;
1256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 if (e->format == c) {
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001258 if (e->alignment && size > 0) {
1259 extra = (e->alignment - 1) - (size - 1) % (e->alignment);
1260 if (extra > PY_SSIZE_T_MAX - size)
1261 return -1;
1262 size += extra;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001263 }
1264 }
1265 return size;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001266}
1267
Antoine Pitrou9f146812013-04-27 00:20:04 +02001268/*
1269 * Struct object implementation.
1270 */
Thomas Wouters477c8d52006-05-27 19:21:47 +00001271
1272/* calculate the size of a format string */
1273
1274static int
1275prepare_s(PyStructObject *self)
1276{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 const formatdef *f;
1278 const formatdef *e;
1279 formatcode *codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001280
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 const char *s;
1282 const char *fmt;
1283 char c;
Victor Stinner706768c2014-08-16 01:03:39 +02001284 Py_ssize_t size, len, num, itemsize;
1285 size_t ncodes;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001286
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 fmt = PyBytes_AS_STRING(self->s_format);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001288
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001289 f = whichtable(&fmt);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001290
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 s = fmt;
1292 size = 0;
1293 len = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001294 ncodes = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 while ((c = *s++) != '\0') {
Antoine Pitrou4de74572013-02-09 23:11:27 +01001296 if (Py_ISSPACE(Py_CHARMASK(c)))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 continue;
1298 if ('0' <= c && c <= '9') {
1299 num = c - '0';
1300 while ('0' <= (c = *s++) && c <= '9') {
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001301 /* overflow-safe version of
1302 if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */
1303 if (num >= PY_SSIZE_T_MAX / 10 && (
1304 num > PY_SSIZE_T_MAX / 10 ||
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001305 (c - '0') > PY_SSIZE_T_MAX % 10))
1306 goto overflow;
Mark Dickinsonab4096f2010-06-11 16:56:34 +00001307 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 }
Alexander Belopolsky177e8532010-06-11 16:04:59 +00001309 if (c == '\0') {
1310 PyErr_SetString(StructError,
1311 "repeat count given without format specifier");
1312 return -1;
1313 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 }
1315 else
1316 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 e = getentry(c, f);
1319 if (e == NULL)
1320 return -1;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001322 switch (c) {
1323 case 's': /* fall through */
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001324 case 'p': len++; ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 case 'x': break;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001326 default: len += num; if (num) ncodes++; break;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001327 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 itemsize = e->size;
1330 size = align(size, c, e);
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001331 if (size == -1)
1332 goto overflow;
1333
1334 /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */
1335 if (num > (PY_SSIZE_T_MAX - size) / itemsize)
1336 goto overflow;
1337 size += num * itemsize;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001338 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 /* check for overflow */
Victor Stinner706768c2014-08-16 01:03:39 +02001341 if ((ncodes + 1) > ((size_t)PY_SSIZE_T_MAX / sizeof(formatcode))) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 PyErr_NoMemory();
1343 return -1;
1344 }
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +00001345
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001346 self->s_size = size;
1347 self->s_len = len;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001348 codes = PyMem_MALLOC((ncodes + 1) * sizeof(formatcode));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001349 if (codes == NULL) {
1350 PyErr_NoMemory();
1351 return -1;
1352 }
Mark Dickinsoncf28b952010-07-29 21:41:59 +00001353 /* Free any s_codes value left over from a previous initialization. */
1354 if (self->s_codes != NULL)
1355 PyMem_FREE(self->s_codes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001356 self->s_codes = codes;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001357
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001358 s = fmt;
1359 size = 0;
1360 while ((c = *s++) != '\0') {
Antoine Pitrou4de74572013-02-09 23:11:27 +01001361 if (Py_ISSPACE(Py_CHARMASK(c)))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 continue;
1363 if ('0' <= c && c <= '9') {
1364 num = c - '0';
1365 while ('0' <= (c = *s++) && c <= '9')
1366 num = num*10 + (c - '0');
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 }
1368 else
1369 num = 1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001370
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001371 e = getentry(c, f);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 size = align(size, c, e);
1374 if (c == 's' || c == 'p') {
1375 codes->offset = size;
1376 codes->size = num;
1377 codes->fmtdef = e;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001378 codes->repeat = 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 codes++;
1380 size += num;
1381 } else if (c == 'x') {
1382 size += num;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001383 } else if (num) {
1384 codes->offset = size;
1385 codes->size = e->size;
1386 codes->fmtdef = e;
1387 codes->repeat = num;
1388 codes++;
1389 size += e->size * num;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 }
1391 }
1392 codes->fmtdef = NULL;
1393 codes->offset = size;
1394 codes->size = 0;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001395 codes->repeat = 0;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001397 return 0;
Mark Dickinsonb72e6862010-06-11 19:50:30 +00001398
1399 overflow:
1400 PyErr_SetString(StructError,
1401 "total struct size too long");
1402 return -1;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001403}
1404
1405static PyObject *
1406s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1407{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001408 PyObject *self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001409
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001410 assert(type != NULL && type->tp_alloc != NULL);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001411
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 self = type->tp_alloc(type, 0);
1413 if (self != NULL) {
1414 PyStructObject *s = (PyStructObject*)self;
1415 Py_INCREF(Py_None);
1416 s->s_format = Py_None;
1417 s->s_codes = NULL;
1418 s->s_size = -1;
1419 s->s_len = -1;
1420 }
1421 return self;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001422}
1423
Victor Stinner3f2d1012017-02-02 12:09:30 +01001424/*[clinic input]
1425Struct.__init__
1426
1427 format: object
1428
1429Create a compiled struct object.
1430
1431Return a new Struct object which writes and reads binary data according to
1432the format string.
1433
1434See help(struct) for more on format strings.
1435[clinic start generated code]*/
1436
Thomas Wouters477c8d52006-05-27 19:21:47 +00001437static int
Victor Stinner3f2d1012017-02-02 12:09:30 +01001438Struct___init___impl(PyStructObject *self, PyObject *format)
1439/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001440{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001441 int ret = 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001442
Victor Stinner3f2d1012017-02-02 12:09:30 +01001443 if (PyUnicode_Check(format)) {
1444 format = PyUnicode_AsASCIIString(format);
1445 if (format == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 return -1;
1447 }
1448 /* XXX support buffer interface, too */
1449 else {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001450 Py_INCREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001451 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001452
Victor Stinner3f2d1012017-02-02 12:09:30 +01001453 if (!PyBytes_Check(format)) {
1454 Py_DECREF(format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 PyErr_Format(PyExc_TypeError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001456 "Struct() argument 1 must be a str or bytes object, "
1457 "not %.200s",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001458 Py_TYPE(format)->tp_name);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 return -1;
1460 }
Christian Heimesa34706f2008-01-04 03:06:10 +00001461
Xiang Zhang96f50282017-05-15 11:53:51 +08001462 Py_SETREF(self->s_format, format);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001463
Victor Stinner3f2d1012017-02-02 12:09:30 +01001464 ret = prepare_s(self);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 return ret;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001466}
1467
1468static void
1469s_dealloc(PyStructObject *s)
1470{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001471 if (s->weakreflist != NULL)
1472 PyObject_ClearWeakRefs((PyObject *)s);
1473 if (s->s_codes != NULL) {
1474 PyMem_FREE(s->s_codes);
1475 }
Xiang Zhang96f50282017-05-15 11:53:51 +08001476 Py_DECREF(s->s_format);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 Py_TYPE(s)->tp_free((PyObject *)s);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001478}
1479
1480static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001481s_unpack_internal(PyStructObject *soself, const char *startfrom) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001482 formatcode *code;
1483 Py_ssize_t i = 0;
1484 PyObject *result = PyTuple_New(soself->s_len);
1485 if (result == NULL)
1486 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001487
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001488 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 const formatdef *e = code->fmtdef;
1490 const char *res = startfrom + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001491 Py_ssize_t j = code->repeat;
1492 while (j--) {
1493 PyObject *v;
1494 if (e->format == 's') {
1495 v = PyBytes_FromStringAndSize(res, code->size);
1496 } else if (e->format == 'p') {
1497 Py_ssize_t n = *(unsigned char*)res;
1498 if (n >= code->size)
1499 n = code->size - 1;
1500 v = PyBytes_FromStringAndSize(res + 1, n);
1501 } else {
1502 v = e->unpack(res, e);
1503 }
1504 if (v == NULL)
1505 goto fail;
1506 PyTuple_SET_ITEM(result, i++, v);
1507 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001508 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001511 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001512fail:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 Py_DECREF(result);
1514 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001515}
1516
1517
Victor Stinner3f2d1012017-02-02 12:09:30 +01001518/*[clinic input]
1519Struct.unpack
1520
1521 buffer: Py_buffer
1522 /
1523
1524Return a tuple containing unpacked values.
1525
1526Unpack according to the format string Struct.format. The buffer's size
1527in bytes must be Struct.size.
1528
1529See help(struct) for more on format strings.
1530[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001531
1532static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001533Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer)
1534/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001535{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001536 assert(self->s_codes != NULL);
1537 if (buffer->len != self->s_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 PyErr_Format(StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001539 "unpack requires a buffer of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001540 self->s_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001541 return NULL;
1542 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001543 return s_unpack_internal(self, buffer->buf);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001544}
1545
Victor Stinner3f2d1012017-02-02 12:09:30 +01001546/*[clinic input]
1547Struct.unpack_from
1548
1549 buffer: Py_buffer
1550 offset: Py_ssize_t = 0
1551
1552Return a tuple containing unpacked values.
1553
1554Values are unpacked according to the format string Struct.format.
1555
Xiang Zhangc10b2882018-03-11 02:58:52 +08001556The buffer's size in bytes, starting at position offset, must be
1557at least Struct.size.
Victor Stinner3f2d1012017-02-02 12:09:30 +01001558
1559See help(struct) for more on format strings.
1560[clinic start generated code]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001561
1562static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001563Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
1564 Py_ssize_t offset)
Xiang Zhangc10b2882018-03-11 02:58:52 +08001565/*[clinic end generated code: output=57fac875e0977316 input=cafd4851d473c894]*/
Thomas Wouters477c8d52006-05-27 19:21:47 +00001566{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001567 assert(self->s_codes != NULL);
Guido van Rossum98297ee2007-11-06 21:34:58 +00001568
Xiang Zhangc10b2882018-03-11 02:58:52 +08001569 if (offset < 0) {
1570 if (offset + self->s_size > 0) {
1571 PyErr_Format(StructError,
1572 "not enough data to unpack %zd bytes at offset %zd",
1573 self->s_size,
1574 offset);
1575 return NULL;
1576 }
1577
1578 if (offset + buffer->len < 0) {
1579 PyErr_Format(StructError,
1580 "offset %zd out of range for %zd-byte buffer",
1581 offset,
1582 buffer->len);
1583 return NULL;
1584 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001585 offset += buffer->len;
Xiang Zhangc10b2882018-03-11 02:58:52 +08001586 }
1587
1588 if ((buffer->len - offset) < self->s_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001589 PyErr_Format(StructError,
Xiang Zhangc10b2882018-03-11 02:58:52 +08001590 "unpack_from requires a buffer of at least %zu bytes for "
1591 "unpacking %zd bytes at offset %zd "
1592 "(actual buffer size is %zd)",
1593 (size_t)self->s_size + (size_t)offset,
1594 self->s_size,
1595 offset,
1596 buffer->len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 return NULL;
1598 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001599 return s_unpack_internal(self, (char*)buffer->buf + offset);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001600}
1601
1602
Victor Stinner3f2d1012017-02-02 12:09:30 +01001603
Antoine Pitrou9f146812013-04-27 00:20:04 +02001604/* Unpack iterator type */
1605
1606typedef struct {
1607 PyObject_HEAD
1608 PyStructObject *so;
1609 Py_buffer buf;
1610 Py_ssize_t index;
1611} unpackiterobject;
1612
1613static void
1614unpackiter_dealloc(unpackiterobject *self)
1615{
INADA Naokia6296d32017-08-24 14:55:17 +09001616 /* bpo-31095: UnTrack is needed before calling any callbacks */
1617 PyObject_GC_UnTrack(self);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001618 Py_XDECREF(self->so);
1619 PyBuffer_Release(&self->buf);
1620 PyObject_GC_Del(self);
1621}
1622
1623static int
1624unpackiter_traverse(unpackiterobject *self, visitproc visit, void *arg)
1625{
1626 Py_VISIT(self->so);
1627 Py_VISIT(self->buf.obj);
1628 return 0;
1629}
1630
1631static PyObject *
1632unpackiter_len(unpackiterobject *self)
1633{
1634 Py_ssize_t len;
1635 if (self->so == NULL)
1636 len = 0;
1637 else
1638 len = (self->buf.len - self->index) / self->so->s_size;
1639 return PyLong_FromSsize_t(len);
1640}
1641
1642static PyMethodDef unpackiter_methods[] = {
1643 {"__length_hint__", (PyCFunction) unpackiter_len, METH_NOARGS, NULL},
1644 {NULL, NULL} /* sentinel */
1645};
1646
1647static PyObject *
1648unpackiter_iternext(unpackiterobject *self)
1649{
1650 PyObject *result;
1651 if (self->so == NULL)
1652 return NULL;
1653 if (self->index >= self->buf.len) {
1654 /* Iterator exhausted */
1655 Py_CLEAR(self->so);
1656 PyBuffer_Release(&self->buf);
1657 return NULL;
1658 }
1659 assert(self->index + self->so->s_size <= self->buf.len);
1660 result = s_unpack_internal(self->so,
1661 (char*) self->buf.buf + self->index);
1662 self->index += self->so->s_size;
1663 return result;
1664}
1665
doko@ubuntu.com46c5deb2013-11-23 16:07:55 +01001666static PyTypeObject unpackiter_type = {
Zachary Ware854adb12016-10-02 00:33:39 -05001667 PyVarObject_HEAD_INIT(NULL, 0)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001668 "unpack_iterator", /* tp_name */
1669 sizeof(unpackiterobject), /* tp_basicsize */
1670 0, /* tp_itemsize */
1671 (destructor)unpackiter_dealloc, /* tp_dealloc */
1672 0, /* tp_print */
1673 0, /* tp_getattr */
1674 0, /* tp_setattr */
1675 0, /* tp_reserved */
1676 0, /* tp_repr */
1677 0, /* tp_as_number */
1678 0, /* tp_as_sequence */
1679 0, /* tp_as_mapping */
1680 0, /* tp_hash */
1681 0, /* tp_call */
1682 0, /* tp_str */
1683 PyObject_GenericGetAttr, /* tp_getattro */
1684 0, /* tp_setattro */
1685 0, /* tp_as_buffer */
1686 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
1687 0, /* tp_doc */
1688 (traverseproc)unpackiter_traverse, /* tp_traverse */
1689 0, /* tp_clear */
1690 0, /* tp_richcompare */
1691 0, /* tp_weaklistoffset */
1692 PyObject_SelfIter, /* tp_iter */
1693 (iternextfunc)unpackiter_iternext, /* tp_iternext */
1694 unpackiter_methods /* tp_methods */
1695};
1696
Victor Stinner3f2d1012017-02-02 12:09:30 +01001697/*[clinic input]
1698Struct.iter_unpack
1699
1700 buffer: object
1701 /
1702
1703Return an iterator yielding tuples.
1704
1705Tuples are unpacked from the given bytes source, like a repeated
1706invocation of unpack_from().
1707
1708Requires that the bytes length be a multiple of the struct size.
1709[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001710
1711static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01001712Struct_iter_unpack(PyStructObject *self, PyObject *buffer)
1713/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02001714{
Victor Stinner3f2d1012017-02-02 12:09:30 +01001715 unpackiterobject *iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001716
Victor Stinner3f2d1012017-02-02 12:09:30 +01001717 assert(self->s_codes != NULL);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001718
Victor Stinner3f2d1012017-02-02 12:09:30 +01001719 if (self->s_size == 0) {
Antoine Pitrou9f146812013-04-27 00:20:04 +02001720 PyErr_Format(StructError,
1721 "cannot iteratively unpack with a struct of length 0");
1722 return NULL;
1723 }
1724
Victor Stinner3f2d1012017-02-02 12:09:30 +01001725 iter = (unpackiterobject *) PyType_GenericAlloc(&unpackiter_type, 0);
1726 if (iter == NULL)
Antoine Pitrou9f146812013-04-27 00:20:04 +02001727 return NULL;
1728
Victor Stinner3f2d1012017-02-02 12:09:30 +01001729 if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) {
1730 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001731 return NULL;
1732 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001733 if (iter->buf.len % self->s_size != 0) {
Antoine Pitrou9f146812013-04-27 00:20:04 +02001734 PyErr_Format(StructError,
Xiang Zhangc3e97d92017-09-14 10:33:26 +08001735 "iterative unpacking requires a buffer of "
1736 "a multiple of %zd bytes",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001737 self->s_size);
1738 Py_DECREF(iter);
Antoine Pitrou9f146812013-04-27 00:20:04 +02001739 return NULL;
1740 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001741 Py_INCREF(self);
1742 iter->so = self;
1743 iter->index = 0;
1744 return (PyObject *)iter;
Antoine Pitrou9f146812013-04-27 00:20:04 +02001745}
1746
1747
Thomas Wouters477c8d52006-05-27 19:21:47 +00001748/*
1749 * Guts of the pack function.
1750 *
1751 * Takes a struct object, a tuple of arguments, and offset in that tuple of
1752 * argument for where to start processing the arguments for packing, and a
1753 * character buffer for writing the packed string. The caller must insure
1754 * that the buffer may contain the required length for packing the arguments.
1755 * 0 is returned on success, 1 is returned if there is an error.
1756 *
1757 */
1758static int
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001759s_pack_internal(PyStructObject *soself, PyObject *const *args, int offset, char* buf)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001760{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001761 formatcode *code;
1762 /* XXX(nnorwitz): why does i need to be a local? can we use
1763 the offset parameter or do we need the wider width? */
1764 Py_ssize_t i;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001765
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001766 memset(buf, '\0', soself->s_size);
1767 i = offset;
1768 for (code = soself->s_codes; code->fmtdef != NULL; code++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001769 const formatdef *e = code->fmtdef;
1770 char *res = buf + code->offset;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001771 Py_ssize_t j = code->repeat;
1772 while (j--) {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001773 PyObject *v = args[i++];
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001774 if (e->format == 's') {
1775 Py_ssize_t n;
1776 int isstring;
1777 void *p;
1778 isstring = PyBytes_Check(v);
1779 if (!isstring && !PyByteArray_Check(v)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001780 PyErr_SetString(StructError,
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001781 "argument for 's' must be a bytes object");
1782 return -1;
1783 }
1784 if (isstring) {
1785 n = PyBytes_GET_SIZE(v);
1786 p = PyBytes_AS_STRING(v);
1787 }
1788 else {
1789 n = PyByteArray_GET_SIZE(v);
1790 p = PyByteArray_AS_STRING(v);
1791 }
1792 if (n > code->size)
1793 n = code->size;
1794 if (n > 0)
1795 memcpy(res, p, n);
1796 } else if (e->format == 'p') {
1797 Py_ssize_t n;
1798 int isstring;
1799 void *p;
1800 isstring = PyBytes_Check(v);
1801 if (!isstring && !PyByteArray_Check(v)) {
1802 PyErr_SetString(StructError,
1803 "argument for 'p' must be a bytes object");
1804 return -1;
1805 }
1806 if (isstring) {
1807 n = PyBytes_GET_SIZE(v);
1808 p = PyBytes_AS_STRING(v);
1809 }
1810 else {
1811 n = PyByteArray_GET_SIZE(v);
1812 p = PyByteArray_AS_STRING(v);
1813 }
1814 if (n > (code->size - 1))
1815 n = code->size - 1;
1816 if (n > 0)
1817 memcpy(res + 1, p, n);
1818 if (n > 255)
1819 n = 255;
1820 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);
1821 } else {
1822 if (e->pack(res, v, e) < 0) {
1823 if (PyLong_Check(v) && PyErr_ExceptionMatches(PyExc_OverflowError))
1824 PyErr_SetString(StructError,
Serhiy Storchaka46e1ce22013-08-27 20:17:03 +03001825 "int too large to convert");
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001826 return -1;
1827 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001828 }
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001829 res += code->size;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001830 }
1831 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001832
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001833 /* Success */
1834 return 0;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001835}
1836
1837
1838PyDoc_STRVAR(s_pack__doc__,
Benjamin Peterson4ae19462008-07-31 15:03:40 +00001839"S.pack(v1, v2, ...) -> bytes\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001840\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001841Return a bytes object containing values v1, v2, ... packed according\n\
1842to the format string S.format. See help(struct) for more on format\n\
1843strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001844
1845static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001846s_pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001847{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001848 PyStructObject *soself;
1849 PyObject *result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001850
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001851 /* Validate arguments. */
1852 soself = (PyStructObject *)self;
1853 assert(PyStruct_Check(self));
1854 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001855 if (nargs != soself->s_len)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001856 {
1857 PyErr_Format(StructError,
Victor Stinner3f2d1012017-02-02 12:09:30 +01001858 "pack expected %zd items for packing (got %zd)", soself->s_len, nargs);
1859 return NULL;
1860 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001861
Xiang Zhang96f50282017-05-15 11:53:51 +08001862 /* Allocate a new buffer */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001863 result = PyBytes_FromStringAndSize((char *)NULL, soself->s_size);
1864 if (result == NULL)
1865 return NULL;
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001866
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001867 /* Call the guts */
1868 if ( s_pack_internal(soself, args, 0, PyBytes_AS_STRING(result)) != 0 ) {
1869 Py_DECREF(result);
1870 return NULL;
1871 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001872
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001873 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001874}
1875
Thomas Wouters73e5a5b2006-06-08 15:35:45 +00001876PyDoc_STRVAR(s_pack_into__doc__,
1877"S.pack_into(buffer, offset, v1, v2, ...)\n\
Thomas Wouters477c8d52006-05-27 19:21:47 +00001878\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001879Pack the values v1, v2, ... according to the format string S.format\n\
1880and write the packed bytes into the writable buffer buf starting at\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00001881offset. Note that the offset is a required argument. See\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00001882help(struct) for more on format strings.");
Thomas Wouters477c8d52006-05-27 19:21:47 +00001883
1884static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02001885s_pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Thomas Wouters477c8d52006-05-27 19:21:47 +00001886{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001887 PyStructObject *soself;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001888 Py_buffer buffer;
1889 Py_ssize_t offset;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001890
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001891 /* Validate arguments. +1 is for the first arg as buffer. */
1892 soself = (PyStructObject *)self;
1893 assert(PyStruct_Check(self));
1894 assert(soself->s_codes != NULL);
Victor Stinner3f2d1012017-02-02 12:09:30 +01001895 if (nargs != (soself->s_len + 2))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001896 {
Victor Stinner3f2d1012017-02-02 12:09:30 +01001897 if (nargs == 0) {
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001898 PyErr_Format(StructError,
1899 "pack_into expected buffer argument");
1900 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01001901 else if (nargs == 1) {
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001902 PyErr_Format(StructError,
1903 "pack_into expected offset argument");
1904 }
1905 else {
1906 PyErr_Format(StructError,
1907 "pack_into expected %zd items for packing (got %zd)",
Victor Stinner3f2d1012017-02-02 12:09:30 +01001908 soself->s_len, (nargs - 2));
Petri Lehtinen92c28ca2012-10-29 21:16:57 +02001909 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001910 return NULL;
1911 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001912
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001913 /* Extract a writable memory buffer from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001914 if (!PyArg_Parse(args[0], "w*", &buffer))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001915 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001916 assert(buffer.len >= 0);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001917
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001918 /* Extract the offset from the first argument */
Victor Stinner3f2d1012017-02-02 12:09:30 +01001919 offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001920 if (offset == -1 && PyErr_Occurred()) {
1921 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001922 return NULL;
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001923 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001925 /* Support negative offsets. */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001926 if (offset < 0) {
1927 /* Check that negative offset is low enough to fit data */
1928 if (offset + soself->s_size > 0) {
1929 PyErr_Format(StructError,
1930 "no space to pack %zd bytes at offset %zd",
1931 soself->s_size,
1932 offset);
1933 PyBuffer_Release(&buffer);
1934 return NULL;
1935 }
1936
1937 /* Check that negative offset is not crossing buffer boundary */
1938 if (offset + buffer.len < 0) {
1939 PyErr_Format(StructError,
1940 "offset %zd out of range for %zd-byte buffer",
1941 offset,
1942 buffer.len);
1943 PyBuffer_Release(&buffer);
1944 return NULL;
1945 }
1946
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001947 offset += buffer.len;
Andrew Nesterf78b1192017-04-04 13:46:25 +03001948 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001950 /* Check boundaries */
Andrew Nesterf78b1192017-04-04 13:46:25 +03001951 if ((buffer.len - offset) < soself->s_size) {
Johan Liuaead53b2017-06-02 14:33:04 +08001952 assert(offset >= 0);
1953 assert(soself->s_size >= 0);
1954
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001955 PyErr_Format(StructError,
Johan Liuaead53b2017-06-02 14:33:04 +08001956 "pack_into requires a buffer of at least %zu bytes for "
Andrew Nesterf78b1192017-04-04 13:46:25 +03001957 "packing %zd bytes at offset %zd "
1958 "(actual buffer size is %zd)",
Johan Liuaead53b2017-06-02 14:33:04 +08001959 (size_t)soself->s_size + (size_t)offset,
Andrew Nesterf78b1192017-04-04 13:46:25 +03001960 soself->s_size,
1961 offset,
1962 buffer.len);
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001963 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001964 return NULL;
1965 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00001966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001967 /* Call the guts */
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001968 if (s_pack_internal(soself, args, 2, (char*)buffer.buf + offset) != 0) {
1969 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001970 return NULL;
1971 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00001972
Serhiy Storchaka4fdb6842015-02-03 01:21:08 +02001973 PyBuffer_Release(&buffer);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001974 Py_RETURN_NONE;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001975}
1976
1977static PyObject *
1978s_get_format(PyStructObject *self, void *unused)
1979{
Victor Stinnerf87b85f2017-06-23 15:11:12 +02001980 return PyUnicode_FromStringAndSize(PyBytes_AS_STRING(self->s_format),
1981 PyBytes_GET_SIZE(self->s_format));
Thomas Wouters477c8d52006-05-27 19:21:47 +00001982}
1983
1984static PyObject *
1985s_get_size(PyStructObject *self, void *unused)
1986{
Christian Heimes217cfd12007-12-02 14:31:20 +00001987 return PyLong_FromSsize_t(self->s_size);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001988}
1989
Meador Ingeb14d8c92012-07-23 10:01:29 -05001990PyDoc_STRVAR(s_sizeof__doc__,
1991"S.__sizeof__() -> size of S in memory, in bytes");
1992
1993static PyObject *
Meador Inge90bc2dbc2012-07-28 22:16:39 -05001994s_sizeof(PyStructObject *self, void *unused)
Meador Ingeb14d8c92012-07-23 10:01:29 -05001995{
1996 Py_ssize_t size;
Serhiy Storchakafff61f22013-05-17 10:49:44 +03001997 formatcode *code;
Meador Ingeb14d8c92012-07-23 10:01:29 -05001998
Serhiy Storchaka5c4064e2015-12-19 20:05:25 +02001999 size = _PyObject_SIZE(Py_TYPE(self)) + sizeof(formatcode);
Serhiy Storchakafff61f22013-05-17 10:49:44 +03002000 for (code = self->s_codes; code->fmtdef != NULL; code++)
2001 size += sizeof(formatcode);
Meador Ingeb14d8c92012-07-23 10:01:29 -05002002 return PyLong_FromSsize_t(size);
2003}
2004
Thomas Wouters477c8d52006-05-27 19:21:47 +00002005/* List of functions */
2006
2007static struct PyMethodDef s_methods[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002008 STRUCT_ITER_UNPACK_METHODDEF
2009 {"pack", (PyCFunction)s_pack, METH_FASTCALL, s_pack__doc__},
2010 {"pack_into", (PyCFunction)s_pack_into, METH_FASTCALL, s_pack_into__doc__},
2011 STRUCT_UNPACK_METHODDEF
2012 STRUCT_UNPACK_FROM_METHODDEF
Meador Ingeb14d8c92012-07-23 10:01:29 -05002013 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002014 {NULL, NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002015};
2016
Thomas Wouters477c8d52006-05-27 19:21:47 +00002017#define OFF(x) offsetof(PyStructObject, x)
2018
2019static PyGetSetDef s_getsetlist[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002020 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},
2021 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},
2022 {NULL} /* sentinel */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002023};
2024
2025static
2026PyTypeObject PyStructType = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002027 PyVarObject_HEAD_INIT(NULL, 0)
2028 "Struct",
2029 sizeof(PyStructObject),
2030 0,
2031 (destructor)s_dealloc, /* tp_dealloc */
2032 0, /* tp_print */
2033 0, /* tp_getattr */
2034 0, /* tp_setattr */
2035 0, /* tp_reserved */
2036 0, /* tp_repr */
2037 0, /* tp_as_number */
2038 0, /* tp_as_sequence */
2039 0, /* tp_as_mapping */
2040 0, /* tp_hash */
2041 0, /* tp_call */
2042 0, /* tp_str */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002043 PyObject_GenericGetAttr, /* tp_getattro */
2044 PyObject_GenericSetAttr, /* tp_setattro */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002045 0, /* tp_as_buffer */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002046 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
2047 Struct___init____doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002048 0, /* tp_traverse */
2049 0, /* tp_clear */
2050 0, /* tp_richcompare */
2051 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */
2052 0, /* tp_iter */
2053 0, /* tp_iternext */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002054 s_methods, /* tp_methods */
2055 NULL, /* tp_members */
2056 s_getsetlist, /* tp_getset */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002057 0, /* tp_base */
2058 0, /* tp_dict */
2059 0, /* tp_descr_get */
2060 0, /* tp_descr_set */
2061 0, /* tp_dictoffset */
Victor Stinner3f2d1012017-02-02 12:09:30 +01002062 Struct___init__, /* tp_init */
2063 PyType_GenericAlloc, /* tp_alloc */
2064 s_new, /* tp_new */
2065 PyObject_Del, /* tp_free */
Thomas Wouters477c8d52006-05-27 19:21:47 +00002066};
2067
Christian Heimesa34706f2008-01-04 03:06:10 +00002068
2069/* ---- Standalone functions ---- */
2070
2071#define MAXCACHE 100
2072static PyObject *cache = NULL;
2073
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002074static int
2075cache_struct_converter(PyObject *fmt, PyObject **ptr)
Christian Heimesa34706f2008-01-04 03:06:10 +00002076{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002077 PyObject * s_object;
Christian Heimesa34706f2008-01-04 03:06:10 +00002078
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002079 if (fmt == NULL) {
2080 Py_DECREF(*ptr);
Serhiy Storchaka40db90c2017-04-20 21:19:31 +03002081 *ptr = NULL;
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002082 return 1;
2083 }
2084
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002085 if (cache == NULL) {
2086 cache = PyDict_New();
2087 if (cache == NULL)
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002088 return 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002089 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002090
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002091 s_object = PyDict_GetItem(cache, fmt);
2092 if (s_object != NULL) {
2093 Py_INCREF(s_object);
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002094 *ptr = s_object;
2095 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002096 }
Christian Heimesa34706f2008-01-04 03:06:10 +00002097
Victor Stinnerde4ae3d2016-12-04 22:59:09 +01002098 s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002099 if (s_object != NULL) {
Serhiy Storchaka5ab81d72016-12-16 16:18:57 +02002100 if (PyDict_GET_SIZE(cache) >= MAXCACHE)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002101 PyDict_Clear(cache);
2102 /* Attempt to cache the result */
2103 if (PyDict_SetItem(cache, fmt, s_object) == -1)
2104 PyErr_Clear();
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002105 *ptr = s_object;
2106 return Py_CLEANUP_SUPPORTED;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002107 }
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002108 return 0;
Christian Heimesa34706f2008-01-04 03:06:10 +00002109}
2110
Victor Stinner3f2d1012017-02-02 12:09:30 +01002111/*[clinic input]
2112_clearcache
2113
2114Clear the internal cache.
2115[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002116
2117static PyObject *
Victor Stinner3f2d1012017-02-02 12:09:30 +01002118_clearcache_impl(PyObject *module)
2119/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002121 Py_CLEAR(cache);
2122 Py_RETURN_NONE;
Christian Heimesa34706f2008-01-04 03:06:10 +00002123}
2124
Victor Stinner3f2d1012017-02-02 12:09:30 +01002125
2126/*[clinic input]
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002127calcsize -> Py_ssize_t
Victor Stinner3f2d1012017-02-02 12:09:30 +01002128
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002129 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002130 /
2131
2132Return size in bytes of the struct described by the format string.
2133[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002134
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002135static Py_ssize_t
2136calcsize_impl(PyObject *module, PyStructObject *s_object)
2137/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002138{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002139 return s_object->s_size;
Christian Heimesa34706f2008-01-04 03:06:10 +00002140}
2141
2142PyDoc_STRVAR(pack_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002143"pack(format, v1, v2, ...) -> bytes\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002144\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002145Return a bytes object containing the values v1, v2, ... packed according\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002146to the format string. See help(struct) for more on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002147
2148static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02002149pack(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002150{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002151 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002152 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002153
Victor Stinner3f2d1012017-02-02 12:09:30 +01002154 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002155 PyErr_SetString(PyExc_TypeError, "missing format argument");
2156 return NULL;
2157 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002158 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002159
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002160 if (!cache_struct_converter(format, &s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002161 return NULL;
2162 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002163 result = s_pack(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002164 Py_DECREF(s_object);
2165 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002166}
2167
2168PyDoc_STRVAR(pack_into_doc,
Victor Stinner3f2d1012017-02-02 12:09:30 +01002169"pack_into(format, buffer, offset, v1, v2, ...)\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002170\n\
Victor Stinner3f2d1012017-02-02 12:09:30 +01002171Pack the values v1, v2, ... according to the format string and write\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002172the packed bytes into the writable buffer buf starting at offset. Note\n\
Mark Dickinsonfdb99f12010-06-12 16:30:53 +00002173that the offset is a required argument. See help(struct) for more\n\
Mark Dickinsonaacfa952010-06-12 15:43:45 +00002174on format strings.");
Christian Heimesa34706f2008-01-04 03:06:10 +00002175
2176static PyObject *
Serhiy Storchakaa5552f02017-12-15 13:11:11 +02002177pack_into(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
Christian Heimesa34706f2008-01-04 03:06:10 +00002178{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002179 PyObject *s_object = NULL;
Victor Stinner3f2d1012017-02-02 12:09:30 +01002180 PyObject *format, *result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002181
Victor Stinner3f2d1012017-02-02 12:09:30 +01002182 if (nargs == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002183 PyErr_SetString(PyExc_TypeError, "missing format argument");
2184 return NULL;
2185 }
Victor Stinner3f2d1012017-02-02 12:09:30 +01002186 format = args[0];
Christian Heimesa34706f2008-01-04 03:06:10 +00002187
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002188 if (!cache_struct_converter(format, &s_object)) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002189 return NULL;
2190 }
Serhiy Storchaka6969eaf2017-07-03 21:20:15 +03002191 result = s_pack_into(s_object, args + 1, nargs - 1);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002192 Py_DECREF(s_object);
2193 return result;
Christian Heimesa34706f2008-01-04 03:06:10 +00002194}
2195
Victor Stinner3f2d1012017-02-02 12:09:30 +01002196/*[clinic input]
2197unpack
2198
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002199 format as s_object: cache_struct
Victor Stinnerc0f59ad2017-02-02 14:24:16 +01002200 buffer: Py_buffer
Victor Stinner3f2d1012017-02-02 12:09:30 +01002201 /
2202
2203Return a tuple containing values unpacked according to the format string.
2204
2205The buffer's size in bytes must be calcsize(format).
2206
2207See help(struct) for more on format strings.
2208[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002209
2210static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002211unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer)
2212/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002213{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002214 return Struct_unpack_impl(s_object, buffer);
Christian Heimesa34706f2008-01-04 03:06:10 +00002215}
2216
Victor Stinner3f2d1012017-02-02 12:09:30 +01002217/*[clinic input]
2218unpack_from
2219
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002220 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002221 /
2222 buffer: Py_buffer
2223 offset: Py_ssize_t = 0
2224
2225Return a tuple containing values unpacked according to the format string.
2226
2227The buffer's size, minus offset, must be at least calcsize(format).
2228
2229See help(struct) for more on format strings.
2230[clinic start generated code]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002231
2232static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002233unpack_from_impl(PyObject *module, PyStructObject *s_object,
2234 Py_buffer *buffer, Py_ssize_t offset)
2235/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/
Christian Heimesa34706f2008-01-04 03:06:10 +00002236{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002237 return Struct_unpack_from_impl(s_object, buffer, offset);
Christian Heimesa34706f2008-01-04 03:06:10 +00002238}
2239
Victor Stinner3f2d1012017-02-02 12:09:30 +01002240/*[clinic input]
2241iter_unpack
2242
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002243 format as s_object: cache_struct
Victor Stinner3f2d1012017-02-02 12:09:30 +01002244 buffer: object
2245 /
2246
2247Return an iterator yielding tuples unpacked from the given bytes.
2248
2249The bytes are unpacked according to the format string, like
2250a repeated invocation of unpack_from().
2251
2252Requires that the bytes length be a multiple of the format struct size.
2253[clinic start generated code]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002254
2255static PyObject *
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002256iter_unpack_impl(PyObject *module, PyStructObject *s_object,
2257 PyObject *buffer)
2258/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/
Antoine Pitrou9f146812013-04-27 00:20:04 +02002259{
Serhiy Storchakaa5a55902017-02-04 11:14:52 +02002260 return Struct_iter_unpack(s_object, buffer);
Antoine Pitrou9f146812013-04-27 00:20:04 +02002261}
2262
Christian Heimesa34706f2008-01-04 03:06:10 +00002263static struct PyMethodDef module_functions[] = {
Victor Stinner3f2d1012017-02-02 12:09:30 +01002264 _CLEARCACHE_METHODDEF
2265 CALCSIZE_METHODDEF
2266 ITER_UNPACK_METHODDEF
2267 {"pack", (PyCFunction)pack, METH_FASTCALL, pack_doc},
2268 {"pack_into", (PyCFunction)pack_into, METH_FASTCALL, pack_into_doc},
2269 UNPACK_METHODDEF
2270 UNPACK_FROM_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002271 {NULL, NULL} /* sentinel */
Christian Heimesa34706f2008-01-04 03:06:10 +00002272};
2273
2274
Thomas Wouters477c8d52006-05-27 19:21:47 +00002275/* Module initialization */
2276
Christian Heimesa34706f2008-01-04 03:06:10 +00002277PyDoc_STRVAR(module_doc,
2278"Functions to convert between Python values and C structs.\n\
Benjamin Peterson4ae19462008-07-31 15:03:40 +00002279Python bytes objects are used to hold the data representing the C struct\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002280and also as format strings (explained below) to describe the layout of data\n\
2281in the C struct.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002282\n\
2283The optional first format char indicates byte order, size and alignment:\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002284 @: native order, size & alignment (default)\n\
2285 =: native order, std. size & alignment\n\
2286 <: little-endian, std. size & alignment\n\
2287 >: big-endian, std. size & alignment\n\
2288 !: same as >\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002289\n\
2290The remaining chars indicate types of args and must match exactly;\n\
2291these can be preceded by a decimal repeat count:\n\
2292 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
Mark Dickinson40714af2009-10-08 15:59:20 +00002293 ?: _Bool (requires C99; if not available, char is used instead)\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002294 h:short; H:unsigned short; i:int; I:unsigned int;\n\
Mark Dickinson7c4e4092016-09-03 17:21:29 +01002295 l:long; L:unsigned long; f:float; d:double; e:half-float.\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002296Special cases (preceding decimal count indicates length):\n\
2297 s:string (array of char); p: pascal string (with count byte).\n\
Antoine Pitrou45d9c912011-10-06 15:27:40 +02002298Special cases (only available in native format):\n\
2299 n:ssize_t; N:size_t;\n\
Christian Heimesa34706f2008-01-04 03:06:10 +00002300 P:an integer type that is wide enough to hold a pointer.\n\
2301Special case (not in native mode unless 'long long' in platform C):\n\
2302 q:long long; Q:unsigned long long\n\
2303Whitespace between formats is ignored.\n\
2304\n\
2305The variable struct.error is an exception raised on errors.\n");
2306
Martin v. Löwis1a214512008-06-11 05:26:20 +00002307
2308static struct PyModuleDef _structmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002309 PyModuleDef_HEAD_INIT,
2310 "_struct",
2311 module_doc,
2312 -1,
2313 module_functions,
2314 NULL,
2315 NULL,
2316 NULL,
2317 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00002318};
2319
Thomas Wouters477c8d52006-05-27 19:21:47 +00002320PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00002321PyInit__struct(void)
Thomas Wouters477c8d52006-05-27 19:21:47 +00002322{
Mark Dickinson06817852010-06-12 09:25:13 +00002323 PyObject *m;
Christian Heimesa34706f2008-01-04 03:06:10 +00002324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002325 m = PyModule_Create(&_structmodule);
2326 if (m == NULL)
2327 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002329 Py_TYPE(&PyStructType) = &PyType_Type;
2330 if (PyType_Ready(&PyStructType) < 0)
2331 return NULL;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002332
Zachary Ware99f11b42016-10-04 01:20:21 -05002333 if (PyType_Ready(&unpackiter_type) < 0)
2334 return NULL;
2335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002336 /* Check endian and swap in faster functions */
2337 {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02002338 const formatdef *native = native_table;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002339 formatdef *other, *ptr;
Christian Heimes743e0cd2012-10-17 23:52:17 +02002340#if PY_LITTLE_ENDIAN
2341 other = lilendian_table;
2342#else
2343 other = bigendian_table;
2344#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002345 /* Scan through the native table, find a matching
2346 entry in the endian table and swap in the
2347 native implementations whenever possible
2348 (64-bit platforms may not have "standard" sizes) */
2349 while (native->format != '\0' && other->format != '\0') {
2350 ptr = other;
2351 while (ptr->format != '\0') {
2352 if (ptr->format == native->format) {
2353 /* Match faster when formats are
2354 listed in the same order */
2355 if (ptr == other)
2356 other++;
2357 /* Only use the trick if the
2358 size matches */
2359 if (ptr->size != native->size)
2360 break;
2361 /* Skip float and double, could be
2362 "unknown" float format */
2363 if (ptr->format == 'd' || ptr->format == 'f')
2364 break;
2365 ptr->pack = native->pack;
2366 ptr->unpack = native->unpack;
2367 break;
2368 }
2369 ptr++;
2370 }
2371 native++;
2372 }
2373 }
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002374
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002375 /* Add some symbolic constants to the module */
2376 if (StructError == NULL) {
2377 StructError = PyErr_NewException("struct.error", NULL, NULL);
2378 if (StructError == NULL)
2379 return NULL;
2380 }
Thomas Wouters477c8d52006-05-27 19:21:47 +00002381
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002382 Py_INCREF(StructError);
2383 PyModule_AddObject(m, "error", StructError);
Thomas Wouters477c8d52006-05-27 19:21:47 +00002384
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002385 Py_INCREF((PyObject*)&PyStructType);
2386 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);
Thomas Wouters4d70c3d2006-06-08 14:42:34 +00002387
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00002388 return m;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002389}