]> git.proxmox.com Git - mirror_edk2.git/blame - AppPkg/Applications/Python/Python-2.7.10/Modules/_struct.c
EmbeddedPkg: Extend NvVarStoreFormattedLib LIBRARY_CLASS
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.10 / Modules / _struct.c
CommitLineData
7eb75bcc
DM
1/* struct module -- pack values into and (out of) strings */\r
2\r
3/* New version supporting byte order, alignment and size options,\r
4 character strings, and unsigned numbers */\r
5\r
6#define PY_SSIZE_T_CLEAN\r
7\r
8#include "Python.h"\r
9#include "structseq.h"\r
10#include "structmember.h"\r
11#include <ctype.h>\r
12\r
13static PyTypeObject PyStructType;\r
14\r
15/* compatibility macros */\r
16#if (PY_VERSION_HEX < 0x02050000)\r
17typedef int Py_ssize_t;\r
18#endif\r
19\r
20/* warning messages */\r
21#define FLOAT_COERCE_WARN "integer argument expected, got float"\r
22#define NON_INTEGER_WARN "integer argument expected, got non-integer " \\r
23 "(implicit conversion using __int__ is deprecated)"\r
24\r
25\r
26/* The translation function for each format character is table driven */\r
27typedef struct _formatdef {\r
28 char format;\r
29 Py_ssize_t size;\r
30 Py_ssize_t alignment;\r
31 PyObject* (*unpack)(const char *,\r
32 const struct _formatdef *);\r
33 int (*pack)(char *, PyObject *,\r
34 const struct _formatdef *);\r
35} formatdef;\r
36\r
37typedef struct _formatcode {\r
38 const struct _formatdef *fmtdef;\r
39 Py_ssize_t offset;\r
40 Py_ssize_t size;\r
41} formatcode;\r
42\r
43/* Struct object interface */\r
44\r
45typedef struct {\r
46 PyObject_HEAD\r
47 Py_ssize_t s_size;\r
48 Py_ssize_t s_len;\r
49 formatcode *s_codes;\r
50 PyObject *s_format;\r
51 PyObject *weakreflist; /* List of weak references */\r
52} PyStructObject;\r
53\r
54\r
55#define PyStruct_Check(op) PyObject_TypeCheck(op, &PyStructType)\r
56#define PyStruct_CheckExact(op) (Py_TYPE(op) == &PyStructType)\r
57\r
58\r
59/* Exception */\r
60\r
61static PyObject *StructError;\r
62\r
63\r
64/* Define various structs to figure out the alignments of types */\r
65\r
66\r
67typedef struct { char c; short x; } st_short;\r
68typedef struct { char c; int x; } st_int;\r
69typedef struct { char c; long x; } st_long;\r
70typedef struct { char c; float x; } st_float;\r
71typedef struct { char c; double x; } st_double;\r
72typedef struct { char c; void *x; } st_void_p;\r
73\r
74#define SHORT_ALIGN (sizeof(st_short) - sizeof(short))\r
75#define INT_ALIGN (sizeof(st_int) - sizeof(int))\r
76#define LONG_ALIGN (sizeof(st_long) - sizeof(long))\r
77#define FLOAT_ALIGN (sizeof(st_float) - sizeof(float))\r
78#define DOUBLE_ALIGN (sizeof(st_double) - sizeof(double))\r
79#define VOID_P_ALIGN (sizeof(st_void_p) - sizeof(void *))\r
80\r
81/* We can't support q and Q in native mode unless the compiler does;\r
82 in std mode, they're 8 bytes on all platforms. */\r
83#ifdef HAVE_LONG_LONG\r
84typedef struct { char c; PY_LONG_LONG x; } s_long_long;\r
85#define LONG_LONG_ALIGN (sizeof(s_long_long) - sizeof(PY_LONG_LONG))\r
86#endif\r
87\r
88#ifdef HAVE_C99_BOOL\r
89#define BOOL_TYPE _Bool\r
90typedef struct { char c; _Bool x; } s_bool;\r
91#define BOOL_ALIGN (sizeof(s_bool) - sizeof(BOOL_TYPE))\r
92#else\r
93#define BOOL_TYPE char\r
94#define BOOL_ALIGN 0\r
95#endif\r
96\r
97#define STRINGIFY(x) #x\r
98\r
99#ifdef __powerc\r
100#pragma options align=reset\r
101#endif\r
102\r
103static char *integer_codes = "bBhHiIlLqQ";\r
104\r
105/* Helper to get a PyLongObject by hook or by crook. Caller should decref. */\r
106\r
107static PyObject *\r
108get_pylong(PyObject *v)\r
109{\r
110 PyObject *r, *w;\r
111 int converted = 0;\r
112 assert(v != NULL);\r
113 if (!PyInt_Check(v) && !PyLong_Check(v)) {\r
114 PyNumberMethods *m;\r
115 /* Not an integer; first try to use __index__ to\r
116 convert to an integer. If the __index__ method\r
117 doesn't exist, or raises a TypeError, try __int__.\r
118 Use of the latter is deprecated, and will fail in\r
119 Python 3.x. */\r
120\r
121 m = Py_TYPE(v)->tp_as_number;\r
122 if (PyIndex_Check(v)) {\r
123 w = PyNumber_Index(v);\r
124 if (w != NULL) {\r
125 v = w;\r
126 /* successfully converted to an integer */\r
127 converted = 1;\r
128 }\r
129 else if (PyErr_ExceptionMatches(PyExc_TypeError)) {\r
130 PyErr_Clear();\r
131 }\r
132 else\r
133 return NULL;\r
134 }\r
135 if (!converted && m != NULL && m->nb_int != NULL) {\r
136 /* Special case warning message for floats, for\r
137 backwards compatibility. */\r
138 if (PyFloat_Check(v)) {\r
139 if (PyErr_WarnEx(\r
140 PyExc_DeprecationWarning,\r
141 FLOAT_COERCE_WARN, 1))\r
142 return NULL;\r
143 }\r
144 else {\r
145 if (PyErr_WarnEx(\r
146 PyExc_DeprecationWarning,\r
147 NON_INTEGER_WARN, 1))\r
148 return NULL;\r
149 }\r
150 v = m->nb_int(v);\r
151 if (v == NULL)\r
152 return NULL;\r
153 if (!PyInt_Check(v) && !PyLong_Check(v)) {\r
154 PyErr_SetString(PyExc_TypeError,\r
155 "__int__ method returned "\r
156 "non-integer");\r
157 return NULL;\r
158 }\r
159 converted = 1;\r
160 }\r
161 if (!converted) {\r
162 PyErr_SetString(StructError,\r
163 "cannot convert argument "\r
164 "to integer");\r
165 return NULL;\r
166 }\r
167 }\r
168 else\r
169 /* Ensure we own a reference to v. */\r
170 Py_INCREF(v);\r
171\r
172 assert(PyInt_Check(v) || PyLong_Check(v));\r
173 if (PyInt_Check(v)) {\r
174 r = PyLong_FromLong(PyInt_AS_LONG(v));\r
175 Py_DECREF(v);\r
176 }\r
177 else if (PyLong_Check(v)) {\r
178 assert(PyLong_Check(v));\r
179 r = v;\r
180 }\r
181 else {\r
182 r = NULL; /* silence compiler warning about\r
183 possibly uninitialized variable */\r
184 assert(0); /* shouldn't ever get here */\r
185 }\r
186\r
187 return r;\r
188}\r
189\r
190/* Helper to convert a Python object to a C long. Sets an exception\r
191 (struct.error for an inconvertible type, OverflowError for\r
192 out-of-range values) and returns -1 on error. */\r
193\r
194static int\r
195get_long(PyObject *v, long *p)\r
196{\r
197 long x;\r
198\r
199 v = get_pylong(v);\r
200 if (v == NULL)\r
201 return -1;\r
202 assert(PyLong_Check(v));\r
203 x = PyLong_AsLong(v);\r
204 Py_DECREF(v);\r
205 if (x == (long)-1 && PyErr_Occurred())\r
206 return -1;\r
207 *p = x;\r
208 return 0;\r
209}\r
210\r
211/* Same, but handling unsigned long */\r
212\r
213static int\r
214get_ulong(PyObject *v, unsigned long *p)\r
215{\r
216 unsigned long x;\r
217\r
218 v = get_pylong(v);\r
219 if (v == NULL)\r
220 return -1;\r
221 assert(PyLong_Check(v));\r
222 x = PyLong_AsUnsignedLong(v);\r
223 Py_DECREF(v);\r
224 if (x == (unsigned long)-1 && PyErr_Occurred())\r
225 return -1;\r
226 *p = x;\r
227 return 0;\r
228}\r
229\r
230#ifdef HAVE_LONG_LONG\r
231\r
232/* Same, but handling native long long. */\r
233\r
234static int\r
235get_longlong(PyObject *v, PY_LONG_LONG *p)\r
236{\r
237 PY_LONG_LONG x;\r
238\r
239 v = get_pylong(v);\r
240 if (v == NULL)\r
241 return -1;\r
242 assert(PyLong_Check(v));\r
243 x = PyLong_AsLongLong(v);\r
244 Py_DECREF(v);\r
245 if (x == (PY_LONG_LONG)-1 && PyErr_Occurred())\r
246 return -1;\r
247 *p = x;\r
248 return 0;\r
249}\r
250\r
251/* Same, but handling native unsigned long long. */\r
252\r
253static int\r
254get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)\r
255{\r
256 unsigned PY_LONG_LONG x;\r
257\r
258 v = get_pylong(v);\r
259 if (v == NULL)\r
260 return -1;\r
261 assert(PyLong_Check(v));\r
262 x = PyLong_AsUnsignedLongLong(v);\r
263 Py_DECREF(v);\r
264 if (x == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())\r
265 return -1;\r
266 *p = x;\r
267 return 0;\r
268}\r
269\r
270#endif\r
271\r
272/* Floating point helpers */\r
273\r
274static PyObject *\r
275unpack_float(const char *p, /* start of 4-byte string */\r
276 int le) /* true for little-endian, false for big-endian */\r
277{\r
278 double x;\r
279\r
280 x = _PyFloat_Unpack4((unsigned char *)p, le);\r
281 if (x == -1.0 && PyErr_Occurred())\r
282 return NULL;\r
283 return PyFloat_FromDouble(x);\r
284}\r
285\r
286static PyObject *\r
287unpack_double(const char *p, /* start of 8-byte string */\r
288 int le) /* true for little-endian, false for big-endian */\r
289{\r
290 double x;\r
291\r
292 x = _PyFloat_Unpack8((unsigned char *)p, le);\r
293 if (x == -1.0 && PyErr_Occurred())\r
294 return NULL;\r
295 return PyFloat_FromDouble(x);\r
296}\r
297\r
298/* Helper to format the range error exceptions */\r
299static int\r
300_range_error(const formatdef *f, int is_unsigned)\r
301{\r
302 /* ulargest is the largest unsigned value with f->size bytes.\r
303 * Note that the simpler:\r
304 * ((size_t)1 << (f->size * 8)) - 1\r
305 * doesn't work when f->size == sizeof(size_t) because C doesn't\r
306 * define what happens when a left shift count is >= the number of\r
307 * bits in the integer being shifted; e.g., on some boxes it doesn't\r
308 * shift at all when they're equal.\r
309 */\r
310 const size_t ulargest = (size_t)-1 >> ((SIZEOF_SIZE_T - f->size)*8);\r
311 assert(f->size >= 1 && f->size <= SIZEOF_SIZE_T);\r
312 if (is_unsigned)\r
313 PyErr_Format(StructError,\r
314 "'%c' format requires 0 <= number <= %zu",\r
315 f->format,\r
316 ulargest);\r
317 else {\r
318 const Py_ssize_t largest = (Py_ssize_t)(ulargest >> 1);\r
319 PyErr_Format(StructError,\r
320 "'%c' format requires %zd <= number <= %zd",\r
321 f->format,\r
322 ~ largest,\r
323 largest);\r
324 }\r
325 return -1;\r
326}\r
327\r
328\r
329\r
330/* A large number of small routines follow, with names of the form\r
331\r
332 [bln][up]_TYPE\r
333\r
334 [bln] distiguishes among big-endian, little-endian and native.\r
335 [pu] distiguishes between pack (to struct) and unpack (from struct).\r
336 TYPE is one of char, byte, ubyte, etc.\r
337*/\r
338\r
339/* Native mode routines. ****************************************************/\r
340/* NOTE:\r
341 In all n[up]_<type> routines handling types larger than 1 byte, there is\r
342 *no* guarantee that the p pointer is properly aligned for each type,\r
343 therefore memcpy is called. An intermediate variable is used to\r
344 compensate for big-endian architectures.\r
345 Normally both the intermediate variable and the memcpy call will be\r
346 skipped by C optimisation in little-endian architectures (gcc >= 2.91\r
347 does this). */\r
348\r
349static PyObject *\r
350nu_char(const char *p, const formatdef *f)\r
351{\r
352 return PyString_FromStringAndSize(p, 1);\r
353}\r
354\r
355static PyObject *\r
356nu_byte(const char *p, const formatdef *f)\r
357{\r
358 return PyInt_FromLong((long) *(signed char *)p);\r
359}\r
360\r
361static PyObject *\r
362nu_ubyte(const char *p, const formatdef *f)\r
363{\r
364 return PyInt_FromLong((long) *(unsigned char *)p);\r
365}\r
366\r
367static PyObject *\r
368nu_short(const char *p, const formatdef *f)\r
369{\r
370 short x;\r
371 memcpy((char *)&x, p, sizeof x);\r
372 return PyInt_FromLong((long)x);\r
373}\r
374\r
375static PyObject *\r
376nu_ushort(const char *p, const formatdef *f)\r
377{\r
378 unsigned short x;\r
379 memcpy((char *)&x, p, sizeof x);\r
380 return PyInt_FromLong((long)x);\r
381}\r
382\r
383static PyObject *\r
384nu_int(const char *p, const formatdef *f)\r
385{\r
386 int x;\r
387 memcpy((char *)&x, p, sizeof x);\r
388 return PyInt_FromLong((long)x);\r
389}\r
390\r
391static PyObject *\r
392nu_uint(const char *p, const formatdef *f)\r
393{\r
394 unsigned int x;\r
395 memcpy((char *)&x, p, sizeof x);\r
396#if (SIZEOF_LONG > SIZEOF_INT)\r
397 return PyInt_FromLong((long)x);\r
398#else\r
399 if (x <= ((unsigned int)LONG_MAX))\r
400 return PyInt_FromLong((long)x);\r
401 return PyLong_FromUnsignedLong((unsigned long)x);\r
402#endif\r
403}\r
404\r
405static PyObject *\r
406nu_long(const char *p, const formatdef *f)\r
407{\r
408 long x;\r
409 memcpy((char *)&x, p, sizeof x);\r
410 return PyInt_FromLong(x);\r
411}\r
412\r
413static PyObject *\r
414nu_ulong(const char *p, const formatdef *f)\r
415{\r
416 unsigned long x;\r
417 memcpy((char *)&x, p, sizeof x);\r
418 if (x <= LONG_MAX)\r
419 return PyInt_FromLong((long)x);\r
420 return PyLong_FromUnsignedLong(x);\r
421}\r
422\r
423/* Native mode doesn't support q or Q unless the platform C supports\r
424 long long (or, on Windows, __int64). */\r
425\r
426#ifdef HAVE_LONG_LONG\r
427\r
428static PyObject *\r
429nu_longlong(const char *p, const formatdef *f)\r
430{\r
431 PY_LONG_LONG x;\r
432 memcpy((char *)&x, p, sizeof x);\r
433 if (x >= LONG_MIN && x <= LONG_MAX)\r
434 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));\r
435 return PyLong_FromLongLong(x);\r
436}\r
437\r
438static PyObject *\r
439nu_ulonglong(const char *p, const formatdef *f)\r
440{\r
441 unsigned PY_LONG_LONG x;\r
442 memcpy((char *)&x, p, sizeof x);\r
443 if (x <= LONG_MAX)\r
444 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));\r
445 return PyLong_FromUnsignedLongLong(x);\r
446}\r
447\r
448#endif\r
449\r
450static PyObject *\r
451nu_bool(const char *p, const formatdef *f)\r
452{\r
453 BOOL_TYPE x;\r
454 memcpy((char *)&x, p, sizeof x);\r
455 return PyBool_FromLong(x != 0);\r
456}\r
457\r
458\r
459static PyObject *\r
460nu_float(const char *p, const formatdef *f)\r
461{\r
462 float x;\r
463 memcpy((char *)&x, p, sizeof x);\r
464 return PyFloat_FromDouble((double)x);\r
465}\r
466\r
467static PyObject *\r
468nu_double(const char *p, const formatdef *f)\r
469{\r
470 double x;\r
471 memcpy((char *)&x, p, sizeof x);\r
472 return PyFloat_FromDouble(x);\r
473}\r
474\r
475static PyObject *\r
476nu_void_p(const char *p, const formatdef *f)\r
477{\r
478 void *x;\r
479 memcpy((char *)&x, p, sizeof x);\r
480 return PyLong_FromVoidPtr(x);\r
481}\r
482\r
483static int\r
484np_byte(char *p, PyObject *v, const formatdef *f)\r
485{\r
486 long x;\r
487 if (get_long(v, &x) < 0)\r
488 return -1;\r
489 if (x < -128 || x > 127){\r
490 PyErr_SetString(StructError,\r
491 "byte format requires -128 <= number <= 127");\r
492 return -1;\r
493 }\r
494 *p = (char)x;\r
495 return 0;\r
496}\r
497\r
498static int\r
499np_ubyte(char *p, PyObject *v, const formatdef *f)\r
500{\r
501 long x;\r
502 if (get_long(v, &x) < 0)\r
503 return -1;\r
504 if (x < 0 || x > 255){\r
505 PyErr_SetString(StructError,\r
506 "ubyte format requires 0 <= number <= 255");\r
507 return -1;\r
508 }\r
509 *p = (char)x;\r
510 return 0;\r
511}\r
512\r
513static int\r
514np_char(char *p, PyObject *v, const formatdef *f)\r
515{\r
516 if (!PyString_Check(v) || PyString_Size(v) != 1) {\r
517 PyErr_SetString(StructError,\r
518 "char format require string of length 1");\r
519 return -1;\r
520 }\r
521 *p = *PyString_AsString(v);\r
522 return 0;\r
523}\r
524\r
525static int\r
526np_short(char *p, PyObject *v, const formatdef *f)\r
527{\r
528 long x;\r
529 short y;\r
530 if (get_long(v, &x) < 0)\r
531 return -1;\r
532 if (x < SHRT_MIN || x > SHRT_MAX){\r
533 PyErr_SetString(StructError,\r
534 "short format requires " STRINGIFY(SHRT_MIN)\r
535 " <= number <= " STRINGIFY(SHRT_MAX));\r
536 return -1;\r
537 }\r
538 y = (short)x;\r
539 memcpy(p, (char *)&y, sizeof y);\r
540 return 0;\r
541}\r
542\r
543static int\r
544np_ushort(char *p, PyObject *v, const formatdef *f)\r
545{\r
546 long x;\r
547 unsigned short y;\r
548 if (get_long(v, &x) < 0)\r
549 return -1;\r
550 if (x < 0 || x > USHRT_MAX){\r
551 PyErr_SetString(StructError,\r
552 "ushort format requires 0 <= number <= " STRINGIFY(USHRT_MAX));\r
553 return -1;\r
554 }\r
555 y = (unsigned short)x;\r
556 memcpy(p, (char *)&y, sizeof y);\r
557 return 0;\r
558}\r
559\r
560static int\r
561np_int(char *p, PyObject *v, const formatdef *f)\r
562{\r
563 long x;\r
564 int y;\r
565 if (get_long(v, &x) < 0)\r
566 return -1;\r
567#if (SIZEOF_LONG > SIZEOF_INT)\r
568 if ((x < ((long)INT_MIN)) || (x > ((long)INT_MAX)))\r
569 return _range_error(f, 0);\r
570#endif\r
571 y = (int)x;\r
572 memcpy(p, (char *)&y, sizeof y);\r
573 return 0;\r
574}\r
575\r
576static int\r
577np_uint(char *p, PyObject *v, const formatdef *f)\r
578{\r
579 unsigned long x;\r
580 unsigned int y;\r
581 if (get_ulong(v, &x) < 0)\r
582 return -1;\r
583 y = (unsigned int)x;\r
584#if (SIZEOF_LONG > SIZEOF_INT)\r
585 if (x > ((unsigned long)UINT_MAX))\r
586 return _range_error(f, 1);\r
587#endif\r
588 memcpy(p, (char *)&y, sizeof y);\r
589 return 0;\r
590}\r
591\r
592static int\r
593np_long(char *p, PyObject *v, const formatdef *f)\r
594{\r
595 long x;\r
596 if (get_long(v, &x) < 0)\r
597 return -1;\r
598 memcpy(p, (char *)&x, sizeof x);\r
599 return 0;\r
600}\r
601\r
602static int\r
603np_ulong(char *p, PyObject *v, const formatdef *f)\r
604{\r
605 unsigned long x;\r
606 if (get_ulong(v, &x) < 0)\r
607 return -1;\r
608 memcpy(p, (char *)&x, sizeof x);\r
609 return 0;\r
610}\r
611\r
612#ifdef HAVE_LONG_LONG\r
613\r
614static int\r
615np_longlong(char *p, PyObject *v, const formatdef *f)\r
616{\r
617 PY_LONG_LONG x;\r
618 if (get_longlong(v, &x) < 0)\r
619 return -1;\r
620 memcpy(p, (char *)&x, sizeof x);\r
621 return 0;\r
622}\r
623\r
624static int\r
625np_ulonglong(char *p, PyObject *v, const formatdef *f)\r
626{\r
627 unsigned PY_LONG_LONG x;\r
628 if (get_ulonglong(v, &x) < 0)\r
629 return -1;\r
630 memcpy(p, (char *)&x, sizeof x);\r
631 return 0;\r
632}\r
633#endif\r
634\r
635\r
636static int\r
637np_bool(char *p, PyObject *v, const formatdef *f)\r
638{\r
639 int y;\r
640 BOOL_TYPE x;\r
641 y = PyObject_IsTrue(v);\r
642 if (y < 0)\r
643 return -1;\r
644 x = y;\r
645 memcpy(p, (char *)&x, sizeof x);\r
646 return 0;\r
647}\r
648\r
649static int\r
650np_float(char *p, PyObject *v, const formatdef *f)\r
651{\r
652 float x = (float)PyFloat_AsDouble(v);\r
653 if (x == -1 && PyErr_Occurred()) {\r
654 PyErr_SetString(StructError,\r
655 "required argument is not a float");\r
656 return -1;\r
657 }\r
658 memcpy(p, (char *)&x, sizeof x);\r
659 return 0;\r
660}\r
661\r
662static int\r
663np_double(char *p, PyObject *v, const formatdef *f)\r
664{\r
665 double x = PyFloat_AsDouble(v);\r
666 if (x == -1 && PyErr_Occurred()) {\r
667 PyErr_SetString(StructError,\r
668 "required argument is not a float");\r
669 return -1;\r
670 }\r
671 memcpy(p, (char *)&x, sizeof(double));\r
672 return 0;\r
673}\r
674\r
675static int\r
676np_void_p(char *p, PyObject *v, const formatdef *f)\r
677{\r
678 void *x;\r
679\r
680 v = get_pylong(v);\r
681 if (v == NULL)\r
682 return -1;\r
683 assert(PyLong_Check(v));\r
684 x = PyLong_AsVoidPtr(v);\r
685 Py_DECREF(v);\r
686 if (x == NULL && PyErr_Occurred())\r
687 return -1;\r
688 memcpy(p, (char *)&x, sizeof x);\r
689 return 0;\r
690}\r
691\r
692static formatdef native_table[] = {\r
693 {'x', sizeof(char), 0, NULL},\r
694 {'b', sizeof(char), 0, nu_byte, np_byte},\r
695 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},\r
696 {'c', sizeof(char), 0, nu_char, np_char},\r
697 {'s', sizeof(char), 0, NULL},\r
698 {'p', sizeof(char), 0, NULL},\r
699 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},\r
700 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},\r
701 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},\r
702 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},\r
703 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},\r
704 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},\r
705#ifdef HAVE_LONG_LONG\r
706 {'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_longlong, np_longlong},\r
707 {'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, nu_ulonglong,np_ulonglong},\r
708#endif\r
709 {'?', sizeof(BOOL_TYPE), BOOL_ALIGN, nu_bool, np_bool},\r
710 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},\r
711 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},\r
712 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},\r
713 {0}\r
714};\r
715\r
716/* Big-endian routines. *****************************************************/\r
717\r
718static PyObject *\r
719bu_int(const char *p, const formatdef *f)\r
720{\r
721 long x = 0;\r
722 Py_ssize_t i = f->size;\r
723 const unsigned char *bytes = (const unsigned char *)p;\r
724 do {\r
725 x = (x<<8) | *bytes++;\r
726 } while (--i > 0);\r
727 /* Extend the sign bit. */\r
728 if (SIZEOF_LONG > f->size)\r
729 x |= -(x & (1L << ((8 * f->size) - 1)));\r
730 return PyInt_FromLong(x);\r
731}\r
732\r
733static PyObject *\r
734bu_uint(const char *p, const formatdef *f)\r
735{\r
736 unsigned long x = 0;\r
737 Py_ssize_t i = f->size;\r
738 const unsigned char *bytes = (const unsigned char *)p;\r
739 do {\r
740 x = (x<<8) | *bytes++;\r
741 } while (--i > 0);\r
742 if (x <= LONG_MAX)\r
743 return PyInt_FromLong((long)x);\r
744 return PyLong_FromUnsignedLong(x);\r
745}\r
746\r
747static PyObject *\r
748bu_longlong(const char *p, const formatdef *f)\r
749{\r
750#ifdef HAVE_LONG_LONG\r
751 PY_LONG_LONG x = 0;\r
752 Py_ssize_t i = f->size;\r
753 const unsigned char *bytes = (const unsigned char *)p;\r
754 do {\r
755 x = (x<<8) | *bytes++;\r
756 } while (--i > 0);\r
757 /* Extend the sign bit. */\r
758 if (SIZEOF_LONG_LONG > f->size)\r
759 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));\r
760 if (x >= LONG_MIN && x <= LONG_MAX)\r
761 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));\r
762 return PyLong_FromLongLong(x);\r
763#else\r
764 return _PyLong_FromByteArray((const unsigned char *)p,\r
765 8,\r
766 0, /* little-endian */\r
767 1 /* signed */);\r
768#endif\r
769}\r
770\r
771static PyObject *\r
772bu_ulonglong(const char *p, const formatdef *f)\r
773{\r
774#ifdef HAVE_LONG_LONG\r
775 unsigned PY_LONG_LONG x = 0;\r
776 Py_ssize_t i = f->size;\r
777 const unsigned char *bytes = (const unsigned char *)p;\r
778 do {\r
779 x = (x<<8) | *bytes++;\r
780 } while (--i > 0);\r
781 if (x <= LONG_MAX)\r
782 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));\r
783 return PyLong_FromUnsignedLongLong(x);\r
784#else\r
785 return _PyLong_FromByteArray((const unsigned char *)p,\r
786 8,\r
787 0, /* little-endian */\r
788 0 /* signed */);\r
789#endif\r
790}\r
791\r
792static PyObject *\r
793bu_float(const char *p, const formatdef *f)\r
794{\r
795 return unpack_float(p, 0);\r
796}\r
797\r
798static PyObject *\r
799bu_double(const char *p, const formatdef *f)\r
800{\r
801 return unpack_double(p, 0);\r
802}\r
803\r
804static PyObject *\r
805bu_bool(const char *p, const formatdef *f)\r
806{\r
807 char x;\r
808 memcpy((char *)&x, p, sizeof x);\r
809 return PyBool_FromLong(x != 0);\r
810}\r
811\r
812static int\r
813bp_int(char *p, PyObject *v, const formatdef *f)\r
814{\r
815 long x;\r
816 Py_ssize_t i;\r
817 if (get_long(v, &x) < 0)\r
818 return -1;\r
819 i = f->size;\r
820 if (i != SIZEOF_LONG) {\r
821 if ((i == 2) && (x < -32768 || x > 32767))\r
822 return _range_error(f, 0);\r
823#if (SIZEOF_LONG != 4)\r
824 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))\r
825 return _range_error(f, 0);\r
826#endif\r
827 }\r
828 do {\r
829 p[--i] = (char)x;\r
830 x >>= 8;\r
831 } while (i > 0);\r
832 return 0;\r
833}\r
834\r
835static int\r
836bp_uint(char *p, PyObject *v, const formatdef *f)\r
837{\r
838 unsigned long x;\r
839 Py_ssize_t i;\r
840 if (get_ulong(v, &x) < 0)\r
841 return -1;\r
842 i = f->size;\r
843 if (i != SIZEOF_LONG) {\r
844 unsigned long maxint = 1;\r
845 maxint <<= (unsigned long)(i * 8);\r
846 if (x >= maxint)\r
847 return _range_error(f, 1);\r
848 }\r
849 do {\r
850 p[--i] = (char)x;\r
851 x >>= 8;\r
852 } while (i > 0);\r
853 return 0;\r
854}\r
855\r
856static int\r
857bp_longlong(char *p, PyObject *v, const formatdef *f)\r
858{\r
859 int res;\r
860 v = get_pylong(v);\r
861 if (v == NULL)\r
862 return -1;\r
863 res = _PyLong_AsByteArray((PyLongObject *)v,\r
864 (unsigned char *)p,\r
865 8,\r
866 0, /* little_endian */\r
867 1 /* signed */);\r
868 Py_DECREF(v);\r
869 return res;\r
870}\r
871\r
872static int\r
873bp_ulonglong(char *p, PyObject *v, const formatdef *f)\r
874{\r
875 int res;\r
876 v = get_pylong(v);\r
877 if (v == NULL)\r
878 return -1;\r
879 res = _PyLong_AsByteArray((PyLongObject *)v,\r
880 (unsigned char *)p,\r
881 8,\r
882 0, /* little_endian */\r
883 0 /* signed */);\r
884 Py_DECREF(v);\r
885 return res;\r
886}\r
887\r
888static int\r
889bp_float(char *p, PyObject *v, const formatdef *f)\r
890{\r
891 double x = PyFloat_AsDouble(v);\r
892 if (x == -1 && PyErr_Occurred()) {\r
893 PyErr_SetString(StructError,\r
894 "required argument is not a float");\r
895 return -1;\r
896 }\r
897 return _PyFloat_Pack4(x, (unsigned char *)p, 0);\r
898}\r
899\r
900static int\r
901bp_double(char *p, PyObject *v, const formatdef *f)\r
902{\r
903 double x = PyFloat_AsDouble(v);\r
904 if (x == -1 && PyErr_Occurred()) {\r
905 PyErr_SetString(StructError,\r
906 "required argument is not a float");\r
907 return -1;\r
908 }\r
909 return _PyFloat_Pack8(x, (unsigned char *)p, 0);\r
910}\r
911\r
912static int\r
913bp_bool(char *p, PyObject *v, const formatdef *f)\r
914{\r
915 int y;\r
916 y = PyObject_IsTrue(v);\r
917 if (y < 0)\r
918 return -1;\r
919 *p = (char)y;\r
920 return 0;\r
921}\r
922\r
923static formatdef bigendian_table[] = {\r
924 {'x', 1, 0, NULL},\r
925 {'b', 1, 0, nu_byte, np_byte},\r
926 {'B', 1, 0, nu_ubyte, np_ubyte},\r
927 {'c', 1, 0, nu_char, np_char},\r
928 {'s', 1, 0, NULL},\r
929 {'p', 1, 0, NULL},\r
930 {'h', 2, 0, bu_int, bp_int},\r
931 {'H', 2, 0, bu_uint, bp_uint},\r
932 {'i', 4, 0, bu_int, bp_int},\r
933 {'I', 4, 0, bu_uint, bp_uint},\r
934 {'l', 4, 0, bu_int, bp_int},\r
935 {'L', 4, 0, bu_uint, bp_uint},\r
936 {'q', 8, 0, bu_longlong, bp_longlong},\r
937 {'Q', 8, 0, bu_ulonglong, bp_ulonglong},\r
938 {'?', 1, 0, bu_bool, bp_bool},\r
939 {'f', 4, 0, bu_float, bp_float},\r
940 {'d', 8, 0, bu_double, bp_double},\r
941 {0}\r
942};\r
943\r
944/* Little-endian routines. *****************************************************/\r
945\r
946static PyObject *\r
947lu_int(const char *p, const formatdef *f)\r
948{\r
949 long x = 0;\r
950 Py_ssize_t i = f->size;\r
951 const unsigned char *bytes = (const unsigned char *)p;\r
952 do {\r
953 x = (x<<8) | bytes[--i];\r
954 } while (i > 0);\r
955 /* Extend the sign bit. */\r
956 if (SIZEOF_LONG > f->size)\r
957 x |= -(x & (1L << ((8 * f->size) - 1)));\r
958 return PyInt_FromLong(x);\r
959}\r
960\r
961static PyObject *\r
962lu_uint(const char *p, const formatdef *f)\r
963{\r
964 unsigned long x = 0;\r
965 Py_ssize_t i = f->size;\r
966 const unsigned char *bytes = (const unsigned char *)p;\r
967 do {\r
968 x = (x<<8) | bytes[--i];\r
969 } while (i > 0);\r
970 if (x <= LONG_MAX)\r
971 return PyInt_FromLong((long)x);\r
972 return PyLong_FromUnsignedLong((long)x);\r
973}\r
974\r
975static PyObject *\r
976lu_longlong(const char *p, const formatdef *f)\r
977{\r
978#ifdef HAVE_LONG_LONG\r
979 PY_LONG_LONG x = 0;\r
980 Py_ssize_t i = f->size;\r
981 const unsigned char *bytes = (const unsigned char *)p;\r
982 do {\r
983 x = (x<<8) | bytes[--i];\r
984 } while (i > 0);\r
985 /* Extend the sign bit. */\r
986 if (SIZEOF_LONG_LONG > f->size)\r
987 x |= -(x & ((PY_LONG_LONG)1 << ((8 * f->size) - 1)));\r
988 if (x >= LONG_MIN && x <= LONG_MAX)\r
989 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, PY_LONG_LONG, long));\r
990 return PyLong_FromLongLong(x);\r
991#else\r
992 return _PyLong_FromByteArray((const unsigned char *)p,\r
993 8,\r
994 1, /* little-endian */\r
995 1 /* signed */);\r
996#endif\r
997}\r
998\r
999static PyObject *\r
1000lu_ulonglong(const char *p, const formatdef *f)\r
1001{\r
1002#ifdef HAVE_LONG_LONG\r
1003 unsigned PY_LONG_LONG x = 0;\r
1004 Py_ssize_t i = f->size;\r
1005 const unsigned char *bytes = (const unsigned char *)p;\r
1006 do {\r
1007 x = (x<<8) | bytes[--i];\r
1008 } while (i > 0);\r
1009 if (x <= LONG_MAX)\r
1010 return PyInt_FromLong(Py_SAFE_DOWNCAST(x, unsigned PY_LONG_LONG, long));\r
1011 return PyLong_FromUnsignedLongLong(x);\r
1012#else\r
1013 return _PyLong_FromByteArray((const unsigned char *)p,\r
1014 8,\r
1015 1, /* little-endian */\r
1016 0 /* signed */);\r
1017#endif\r
1018}\r
1019\r
1020static PyObject *\r
1021lu_float(const char *p, const formatdef *f)\r
1022{\r
1023 return unpack_float(p, 1);\r
1024}\r
1025\r
1026static PyObject *\r
1027lu_double(const char *p, const formatdef *f)\r
1028{\r
1029 return unpack_double(p, 1);\r
1030}\r
1031\r
1032static int\r
1033lp_int(char *p, PyObject *v, const formatdef *f)\r
1034{\r
1035 long x;\r
1036 Py_ssize_t i;\r
1037 if (get_long(v, &x) < 0)\r
1038 return -1;\r
1039 i = f->size;\r
1040 if (i != SIZEOF_LONG) {\r
1041 if ((i == 2) && (x < -32768 || x > 32767))\r
1042 return _range_error(f, 0);\r
1043#if (SIZEOF_LONG != 4)\r
1044 else if ((i == 4) && (x < -2147483648L || x > 2147483647L))\r
1045 return _range_error(f, 0);\r
1046#endif\r
1047 }\r
1048 do {\r
1049 *p++ = (char)x;\r
1050 x >>= 8;\r
1051 } while (--i > 0);\r
1052 return 0;\r
1053}\r
1054\r
1055static int\r
1056lp_uint(char *p, PyObject *v, const formatdef *f)\r
1057{\r
1058 unsigned long x;\r
1059 Py_ssize_t i;\r
1060 if (get_ulong(v, &x) < 0)\r
1061 return -1;\r
1062 i = f->size;\r
1063 if (i != SIZEOF_LONG) {\r
1064 unsigned long maxint = 1;\r
1065 maxint <<= (unsigned long)(i * 8);\r
1066 if (x >= maxint)\r
1067 return _range_error(f, 1);\r
1068 }\r
1069 do {\r
1070 *p++ = (char)x;\r
1071 x >>= 8;\r
1072 } while (--i > 0);\r
1073 return 0;\r
1074}\r
1075\r
1076static int\r
1077lp_longlong(char *p, PyObject *v, const formatdef *f)\r
1078{\r
1079 int res;\r
1080 v = get_pylong(v);\r
1081 if (v == NULL)\r
1082 return -1;\r
1083 res = _PyLong_AsByteArray((PyLongObject*)v,\r
1084 (unsigned char *)p,\r
1085 8,\r
1086 1, /* little_endian */\r
1087 1 /* signed */);\r
1088 Py_DECREF(v);\r
1089 return res;\r
1090}\r
1091\r
1092static int\r
1093lp_ulonglong(char *p, PyObject *v, const formatdef *f)\r
1094{\r
1095 int res;\r
1096 v = get_pylong(v);\r
1097 if (v == NULL)\r
1098 return -1;\r
1099 res = _PyLong_AsByteArray((PyLongObject*)v,\r
1100 (unsigned char *)p,\r
1101 8,\r
1102 1, /* little_endian */\r
1103 0 /* signed */);\r
1104 Py_DECREF(v);\r
1105 return res;\r
1106}\r
1107\r
1108static int\r
1109lp_float(char *p, PyObject *v, const formatdef *f)\r
1110{\r
1111 double x = PyFloat_AsDouble(v);\r
1112 if (x == -1 && PyErr_Occurred()) {\r
1113 PyErr_SetString(StructError,\r
1114 "required argument is not a float");\r
1115 return -1;\r
1116 }\r
1117 return _PyFloat_Pack4(x, (unsigned char *)p, 1);\r
1118}\r
1119\r
1120static int\r
1121lp_double(char *p, PyObject *v, const formatdef *f)\r
1122{\r
1123 double x = PyFloat_AsDouble(v);\r
1124 if (x == -1 && PyErr_Occurred()) {\r
1125 PyErr_SetString(StructError,\r
1126 "required argument is not a float");\r
1127 return -1;\r
1128 }\r
1129 return _PyFloat_Pack8(x, (unsigned char *)p, 1);\r
1130}\r
1131\r
1132static formatdef lilendian_table[] = {\r
1133 {'x', 1, 0, NULL},\r
1134 {'b', 1, 0, nu_byte, np_byte},\r
1135 {'B', 1, 0, nu_ubyte, np_ubyte},\r
1136 {'c', 1, 0, nu_char, np_char},\r
1137 {'s', 1, 0, NULL},\r
1138 {'p', 1, 0, NULL},\r
1139 {'h', 2, 0, lu_int, lp_int},\r
1140 {'H', 2, 0, lu_uint, lp_uint},\r
1141 {'i', 4, 0, lu_int, lp_int},\r
1142 {'I', 4, 0, lu_uint, lp_uint},\r
1143 {'l', 4, 0, lu_int, lp_int},\r
1144 {'L', 4, 0, lu_uint, lp_uint},\r
1145 {'q', 8, 0, lu_longlong, lp_longlong},\r
1146 {'Q', 8, 0, lu_ulonglong, lp_ulonglong},\r
1147 {'?', 1, 0, bu_bool, bp_bool}, /* Std rep not endian dep,\r
1148 but potentially different from native rep -- reuse bx_bool funcs. */\r
1149 {'f', 4, 0, lu_float, lp_float},\r
1150 {'d', 8, 0, lu_double, lp_double},\r
1151 {0}\r
1152};\r
1153\r
1154\r
1155static const formatdef *\r
1156whichtable(char **pfmt)\r
1157{\r
1158 const char *fmt = (*pfmt)++; /* May be backed out of later */\r
1159 switch (*fmt) {\r
1160 case '<':\r
1161 return lilendian_table;\r
1162 case '>':\r
1163 case '!': /* Network byte order is big-endian */\r
1164 return bigendian_table;\r
1165 case '=': { /* Host byte order -- different from native in alignment! */\r
1166 int n = 1;\r
1167 char *p = (char *) &n;\r
1168 if (*p == 1)\r
1169 return lilendian_table;\r
1170 else\r
1171 return bigendian_table;\r
1172 }\r
1173 default:\r
1174 --*pfmt; /* Back out of pointer increment */\r
1175 /* Fall through */\r
1176 case '@':\r
1177 return native_table;\r
1178 }\r
1179}\r
1180\r
1181\r
1182/* Get the table entry for a format code */\r
1183\r
1184static const formatdef *\r
1185getentry(int c, const formatdef *f)\r
1186{\r
1187 for (; f->format != '\0'; f++) {\r
1188 if (f->format == c) {\r
1189 return f;\r
1190 }\r
1191 }\r
1192 PyErr_SetString(StructError, "bad char in struct format");\r
1193 return NULL;\r
1194}\r
1195\r
1196\r
1197/* Align a size according to a format code. Return -1 on overflow. */\r
1198\r
1199static Py_ssize_t\r
1200align(Py_ssize_t size, char c, const formatdef *e)\r
1201{\r
1202 Py_ssize_t extra;\r
1203\r
1204 if (e->format == c) {\r
1205 if (e->alignment && size > 0) {\r
1206 extra = (e->alignment - 1) - (size - 1) % (e->alignment);\r
1207 if (extra > PY_SSIZE_T_MAX - size)\r
1208 return -1;\r
1209 size += extra;\r
1210 }\r
1211 }\r
1212 return size;\r
1213}\r
1214\r
1215\r
1216/* calculate the size of a format string */\r
1217\r
1218static int\r
1219prepare_s(PyStructObject *self)\r
1220{\r
1221 const formatdef *f;\r
1222 const formatdef *e;\r
1223 formatcode *codes;\r
1224\r
1225 const char *s;\r
1226 const char *fmt;\r
1227 char c;\r
1228 Py_ssize_t size, len, num, itemsize;\r
1229\r
1230 fmt = PyString_AS_STRING(self->s_format);\r
1231\r
1232 f = whichtable((char **)&fmt);\r
1233\r
1234 s = fmt;\r
1235 size = 0;\r
1236 len = 0;\r
1237 while ((c = *s++) != '\0') {\r
1238 if (isspace(Py_CHARMASK(c)))\r
1239 continue;\r
1240 if ('0' <= c && c <= '9') {\r
1241 num = c - '0';\r
1242 while ('0' <= (c = *s++) && c <= '9') {\r
1243 /* overflow-safe version of\r
1244 if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */\r
1245 if (num >= PY_SSIZE_T_MAX / 10 && (\r
1246 num > PY_SSIZE_T_MAX / 10 ||\r
1247 (c - '0') > PY_SSIZE_T_MAX % 10))\r
1248 goto overflow;\r
1249 num = num*10 + (c - '0');\r
1250 }\r
1251 if (c == '\0')\r
1252 break;\r
1253 }\r
1254 else\r
1255 num = 1;\r
1256\r
1257 e = getentry(c, f);\r
1258 if (e == NULL)\r
1259 return -1;\r
1260\r
1261 switch (c) {\r
1262 case 's': /* fall through */\r
1263 case 'p': len++; break;\r
1264 case 'x': break;\r
1265 default: len += num; break;\r
1266 }\r
1267\r
1268 itemsize = e->size;\r
1269 size = align(size, c, e);\r
1270 if (size == -1)\r
1271 goto overflow;\r
1272\r
1273 /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */\r
1274 if (num > (PY_SSIZE_T_MAX - size) / itemsize)\r
1275 goto overflow;\r
1276 size += num * itemsize;\r
1277 }\r
1278\r
1279 /* check for overflow */\r
1280 if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) {\r
1281 PyErr_NoMemory();\r
1282 return -1;\r
1283 }\r
1284\r
1285 self->s_size = size;\r
1286 self->s_len = len;\r
1287 codes = PyMem_MALLOC((len + 1) * sizeof(formatcode));\r
1288 if (codes == NULL) {\r
1289 PyErr_NoMemory();\r
1290 return -1;\r
1291 }\r
1292 /* Free any s_codes value left over from a previous initialization. */\r
1293 if (self->s_codes != NULL)\r
1294 PyMem_FREE(self->s_codes);\r
1295 self->s_codes = codes;\r
1296\r
1297 s = fmt;\r
1298 size = 0;\r
1299 while ((c = *s++) != '\0') {\r
1300 if (isspace(Py_CHARMASK(c)))\r
1301 continue;\r
1302 if ('0' <= c && c <= '9') {\r
1303 num = c - '0';\r
1304 while ('0' <= (c = *s++) && c <= '9')\r
1305 num = num*10 + (c - '0');\r
1306 if (c == '\0')\r
1307 break;\r
1308 }\r
1309 else\r
1310 num = 1;\r
1311\r
1312 e = getentry(c, f);\r
1313\r
1314 size = align(size, c, e);\r
1315 if (c == 's' || c == 'p') {\r
1316 codes->offset = size;\r
1317 codes->size = num;\r
1318 codes->fmtdef = e;\r
1319 codes++;\r
1320 size += num;\r
1321 } else if (c == 'x') {\r
1322 size += num;\r
1323 } else {\r
1324 while (--num >= 0) {\r
1325 codes->offset = size;\r
1326 codes->size = e->size;\r
1327 codes->fmtdef = e;\r
1328 codes++;\r
1329 size += e->size;\r
1330 }\r
1331 }\r
1332 }\r
1333 codes->fmtdef = NULL;\r
1334 codes->offset = size;\r
1335 codes->size = 0;\r
1336\r
1337 return 0;\r
1338\r
1339 overflow:\r
1340 PyErr_SetString(StructError,\r
1341 "total struct size too long");\r
1342 return -1;\r
1343}\r
1344\r
1345static PyObject *\r
1346s_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
1347{\r
1348 PyObject *self;\r
1349\r
1350 assert(type != NULL && type->tp_alloc != NULL);\r
1351\r
1352 self = type->tp_alloc(type, 0);\r
1353 if (self != NULL) {\r
1354 PyStructObject *s = (PyStructObject*)self;\r
1355 Py_INCREF(Py_None);\r
1356 s->s_format = Py_None;\r
1357 s->s_codes = NULL;\r
1358 s->s_size = -1;\r
1359 s->s_len = -1;\r
1360 }\r
1361 return self;\r
1362}\r
1363\r
1364static int\r
1365s_init(PyObject *self, PyObject *args, PyObject *kwds)\r
1366{\r
1367 PyStructObject *soself = (PyStructObject *)self;\r
1368 PyObject *o_format = NULL;\r
1369 int ret = 0;\r
1370 static char *kwlist[] = {"format", 0};\r
1371\r
1372 assert(PyStruct_Check(self));\r
1373\r
1374 if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Struct", kwlist,\r
1375 &o_format))\r
1376 return -1;\r
1377\r
1378 if (PyString_Check(o_format)) {\r
1379 Py_INCREF(o_format);\r
1380 Py_CLEAR(soself->s_format);\r
1381 soself->s_format = o_format;\r
1382 }\r
1383 else if (PyUnicode_Check(o_format)) {\r
1384 PyObject *str = PyUnicode_AsEncodedString(o_format, "ascii", NULL);\r
1385 if (str == NULL)\r
1386 return -1;\r
1387 Py_CLEAR(soself->s_format);\r
1388 soself->s_format = str;\r
1389 }\r
1390 else {\r
1391 PyErr_Format(PyExc_TypeError,\r
1392 "Struct() argument 1 must be string, not %s",\r
1393 Py_TYPE(o_format)->tp_name);\r
1394 return -1;\r
1395 }\r
1396\r
1397 ret = prepare_s(soself);\r
1398 return ret;\r
1399}\r
1400\r
1401static void\r
1402s_dealloc(PyStructObject *s)\r
1403{\r
1404 if (s->weakreflist != NULL)\r
1405 PyObject_ClearWeakRefs((PyObject *)s);\r
1406 if (s->s_codes != NULL) {\r
1407 PyMem_FREE(s->s_codes);\r
1408 }\r
1409 Py_XDECREF(s->s_format);\r
1410 Py_TYPE(s)->tp_free((PyObject *)s);\r
1411}\r
1412\r
1413static PyObject *\r
1414s_unpack_internal(PyStructObject *soself, char *startfrom) {\r
1415 formatcode *code;\r
1416 Py_ssize_t i = 0;\r
1417 PyObject *result = PyTuple_New(soself->s_len);\r
1418 if (result == NULL)\r
1419 return NULL;\r
1420\r
1421 for (code = soself->s_codes; code->fmtdef != NULL; code++) {\r
1422 PyObject *v;\r
1423 const formatdef *e = code->fmtdef;\r
1424 const char *res = startfrom + code->offset;\r
1425 if (e->format == 's') {\r
1426 v = PyString_FromStringAndSize(res, code->size);\r
1427 } else if (e->format == 'p') {\r
1428 Py_ssize_t n = *(unsigned char*)res;\r
1429 if (n >= code->size)\r
1430 n = code->size - 1;\r
1431 v = PyString_FromStringAndSize(res + 1, n);\r
1432 } else {\r
1433 v = e->unpack(res, e);\r
1434 }\r
1435 if (v == NULL)\r
1436 goto fail;\r
1437 PyTuple_SET_ITEM(result, i++, v);\r
1438 }\r
1439\r
1440 return result;\r
1441fail:\r
1442 Py_DECREF(result);\r
1443 return NULL;\r
1444}\r
1445\r
1446\r
1447PyDoc_STRVAR(s_unpack__doc__,\r
1448"S.unpack(str) -> (v1, v2, ...)\n\\r
1449\n\\r
1450Return tuple containing values unpacked according to this Struct's format.\n\\r
1451Requires len(str) == self.size. See struct.__doc__ for more on format\n\\r
1452strings.");\r
1453\r
1454static PyObject *\r
1455s_unpack(PyObject *self, PyObject *inputstr)\r
1456{\r
1457 Py_buffer buf;\r
1458 char *start;\r
1459 Py_ssize_t len;\r
1460 PyObject *args=NULL, *result;\r
1461 PyStructObject *soself = (PyStructObject *)self;\r
1462 assert(PyStruct_Check(self));\r
1463 assert(soself->s_codes != NULL);\r
1464 if (inputstr == NULL)\r
1465 goto fail;\r
1466 if (PyString_Check(inputstr) &&\r
1467 PyString_GET_SIZE(inputstr) == soself->s_size) {\r
1468 return s_unpack_internal(soself, PyString_AS_STRING(inputstr));\r
1469 }\r
1470 args = PyTuple_Pack(1, inputstr);\r
1471 if (args == NULL)\r
1472 return NULL;\r
1473 if (!PyArg_ParseTuple(args, "s*:unpack", &buf))\r
1474 goto fail;\r
1475 start = buf.buf;\r
1476 len = buf.len;\r
1477 if (soself->s_size != len) {\r
1478 PyBuffer_Release(&buf);\r
1479 goto fail;\r
1480 }\r
1481 result = s_unpack_internal(soself, start);\r
1482 Py_DECREF(args);\r
1483 PyBuffer_Release(&buf);\r
1484 return result;\r
1485\r
1486fail:\r
1487 Py_XDECREF(args);\r
1488 PyErr_Format(StructError,\r
1489 "unpack requires a string argument of length %zd",\r
1490 soself->s_size);\r
1491 return NULL;\r
1492}\r
1493\r
1494PyDoc_STRVAR(s_unpack_from__doc__,\r
1495"S.unpack_from(buffer[, offset]) -> (v1, v2, ...)\n\\r
1496\n\\r
1497Return tuple containing values unpacked according to this Struct's format.\n\\r
1498Unlike unpack, unpack_from can unpack values from any object supporting\n\\r
1499the buffer API, not just str. Requires len(buffer[offset:]) >= self.size.\n\\r
1500See struct.__doc__ for more on format strings.");\r
1501\r
1502static PyObject *\r
1503s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds)\r
1504{\r
1505 static char *kwlist[] = {"buffer", "offset", 0};\r
1506 static char *fmt = "z*|n:unpack_from";\r
1507 Py_buffer buf;\r
1508 Py_ssize_t buffer_len = 0, offset = 0;\r
1509 char *buffer = NULL;\r
1510 PyStructObject *soself = (PyStructObject *)self;\r
1511 PyObject *result;\r
1512 assert(PyStruct_Check(self));\r
1513 assert(soself->s_codes != NULL);\r
1514\r
1515 if (!PyArg_ParseTupleAndKeywords(args, kwds, fmt, kwlist,\r
1516 &buf, &offset))\r
1517 return NULL;\r
1518 buffer = buf.buf;\r
1519 buffer_len = buf.len;\r
1520 if (buffer == NULL) {\r
1521 PyErr_Format(StructError,\r
1522 "unpack_from requires a buffer argument");\r
1523 PyBuffer_Release(&buf);\r
1524 return NULL;\r
1525 }\r
1526\r
1527 if (offset < 0)\r
1528 offset += buffer_len;\r
1529\r
1530 if (offset < 0 || (buffer_len - offset) < soself->s_size) {\r
1531 PyErr_Format(StructError,\r
1532 "unpack_from requires a buffer of at least %zd bytes",\r
1533 soself->s_size);\r
1534 PyBuffer_Release(&buf);\r
1535 return NULL;\r
1536 }\r
1537 result = s_unpack_internal(soself, buffer + offset);\r
1538 PyBuffer_Release(&buf);\r
1539 return result;\r
1540}\r
1541\r
1542\r
1543/*\r
1544 * Guts of the pack function.\r
1545 *\r
1546 * Takes a struct object, a tuple of arguments, and offset in that tuple of\r
1547 * argument for where to start processing the arguments for packing, and a\r
1548 * character buffer for writing the packed string. The caller must insure\r
1549 * that the buffer may contain the required length for packing the arguments.\r
1550 * 0 is returned on success, 1 is returned if there is an error.\r
1551 *\r
1552 */\r
1553static int\r
1554s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf)\r
1555{\r
1556 formatcode *code;\r
1557 /* XXX(nnorwitz): why does i need to be a local? can we use\r
1558 the offset parameter or do we need the wider width? */\r
1559 Py_ssize_t i;\r
1560\r
1561 memset(buf, '\0', soself->s_size);\r
1562 i = offset;\r
1563 for (code = soself->s_codes; code->fmtdef != NULL; code++) {\r
1564 Py_ssize_t n;\r
1565 PyObject *v = PyTuple_GET_ITEM(args, i++);\r
1566 const formatdef *e = code->fmtdef;\r
1567 char *res = buf + code->offset;\r
1568 if (e->format == 's') {\r
1569 if (!PyString_Check(v)) {\r
1570 PyErr_SetString(StructError,\r
1571 "argument for 's' must "\r
1572 "be a string");\r
1573 return -1;\r
1574 }\r
1575 n = PyString_GET_SIZE(v);\r
1576 if (n > code->size)\r
1577 n = code->size;\r
1578 if (n > 0)\r
1579 memcpy(res, PyString_AS_STRING(v), n);\r
1580 } else if (e->format == 'p') {\r
1581 if (!PyString_Check(v)) {\r
1582 PyErr_SetString(StructError,\r
1583 "argument for 'p' must "\r
1584 "be a string");\r
1585 return -1;\r
1586 }\r
1587 n = PyString_GET_SIZE(v);\r
1588 if (n > (code->size - 1))\r
1589 n = code->size - 1;\r
1590 if (n > 0)\r
1591 memcpy(res + 1, PyString_AS_STRING(v), n);\r
1592 if (n > 255)\r
1593 n = 255;\r
1594 *res = Py_SAFE_DOWNCAST(n, Py_ssize_t, unsigned char);\r
1595 } else if (e->pack(res, v, e) < 0) {\r
1596 if (strchr(integer_codes, e->format) != NULL &&\r
1597 PyErr_ExceptionMatches(PyExc_OverflowError))\r
1598 PyErr_Format(StructError,\r
1599 "integer out of range for "\r
1600 "'%c' format code",\r
1601 e->format);\r
1602 return -1;\r
1603 }\r
1604 }\r
1605\r
1606 /* Success */\r
1607 return 0;\r
1608}\r
1609\r
1610\r
1611PyDoc_STRVAR(s_pack__doc__,\r
1612"S.pack(v1, v2, ...) -> string\n\\r
1613\n\\r
1614Return a string containing values v1, v2, ... packed according to this\n\\r
1615Struct's format. See struct.__doc__ for more on format strings.");\r
1616\r
1617static PyObject *\r
1618s_pack(PyObject *self, PyObject *args)\r
1619{\r
1620 PyStructObject *soself;\r
1621 PyObject *result;\r
1622\r
1623 /* Validate arguments. */\r
1624 soself = (PyStructObject *)self;\r
1625 assert(PyStruct_Check(self));\r
1626 assert(soself->s_codes != NULL);\r
1627 if (PyTuple_GET_SIZE(args) != soself->s_len)\r
1628 {\r
1629 PyErr_Format(StructError,\r
1630 "pack expected %zd items for packing (got %zd)", soself->s_len, PyTuple_GET_SIZE(args));\r
1631 return NULL;\r
1632 }\r
1633\r
1634 /* Allocate a new string */\r
1635 result = PyString_FromStringAndSize((char *)NULL, soself->s_size);\r
1636 if (result == NULL)\r
1637 return NULL;\r
1638\r
1639 /* Call the guts */\r
1640 if ( s_pack_internal(soself, args, 0, PyString_AS_STRING(result)) != 0 ) {\r
1641 Py_DECREF(result);\r
1642 return NULL;\r
1643 }\r
1644\r
1645 return result;\r
1646}\r
1647\r
1648PyDoc_STRVAR(s_pack_into__doc__,\r
1649"S.pack_into(buffer, offset, v1, v2, ...)\n\\r
1650\n\\r
1651Pack the values v1, v2, ... according to this Struct's format, write \n\\r
1652the packed bytes into the writable buffer buf starting at offset. Note\n\\r
1653that the offset is not an optional argument. See struct.__doc__ for \n\\r
1654more on format strings.");\r
1655\r
1656static PyObject *\r
1657s_pack_into(PyObject *self, PyObject *args)\r
1658{\r
1659 PyStructObject *soself;\r
1660 Py_buffer buf;\r
1661 Py_ssize_t offset;\r
1662\r
1663 /* Validate arguments. +1 is for the first arg as buffer. */\r
1664 soself = (PyStructObject *)self;\r
1665 assert(PyStruct_Check(self));\r
1666 assert(soself->s_codes != NULL);\r
1667 if (PyTuple_GET_SIZE(args) != (soself->s_len + 2))\r
1668 {\r
1669 if (PyTuple_GET_SIZE(args) == 0) {\r
1670 PyErr_Format(StructError,\r
1671 "pack_into expected buffer argument");\r
1672 }\r
1673 else if (PyTuple_GET_SIZE(args) == 1) {\r
1674 PyErr_Format(StructError,\r
1675 "pack_into expected offset argument");\r
1676 }\r
1677 else {\r
1678 PyErr_Format(StructError,\r
1679 "pack_into expected %zd items for packing (got %zd)",\r
1680 soself->s_len, (PyTuple_GET_SIZE(args) - 2));\r
1681 }\r
1682 return NULL;\r
1683 }\r
1684\r
1685 /* Extract a writable memory buffer from the first argument */\r
1686 if (!PyArg_Parse(PyTuple_GET_ITEM(args, 0), "w*", &buf))\r
1687 return NULL;\r
1688\r
1689 /* Extract the offset from the first argument */\r
1690 offset = PyInt_AsSsize_t(PyTuple_GET_ITEM(args, 1));\r
1691 if (offset == -1 && PyErr_Occurred()) {\r
1692 PyBuffer_Release(&buf);\r
1693 return NULL;\r
1694 }\r
1695\r
1696 /* Support negative offsets. */\r
1697 if (offset < 0)\r
1698 offset += buf.len;\r
1699\r
1700 /* Check boundaries */\r
1701 if (offset < 0 || (buf.len - offset) < soself->s_size) {\r
1702 PyErr_Format(StructError,\r
1703 "pack_into requires a buffer of at least %zd bytes",\r
1704 soself->s_size);\r
1705 PyBuffer_Release(&buf);\r
1706 return NULL;\r
1707 }\r
1708\r
1709 /* Call the guts */\r
1710 if (s_pack_internal(soself, args, 2, (char *)buf.buf + offset) != 0) {\r
1711 PyBuffer_Release(&buf);\r
1712 return NULL;\r
1713 }\r
1714 PyBuffer_Release(&buf);\r
1715\r
1716 Py_RETURN_NONE;\r
1717}\r
1718\r
1719static PyObject *\r
1720s_get_format(PyStructObject *self, void *unused)\r
1721{\r
1722 Py_INCREF(self->s_format);\r
1723 return self->s_format;\r
1724}\r
1725\r
1726static PyObject *\r
1727s_get_size(PyStructObject *self, void *unused)\r
1728{\r
1729 return PyInt_FromSsize_t(self->s_size);\r
1730}\r
1731\r
1732PyDoc_STRVAR(s_sizeof__doc__,\r
1733"S.__sizeof__() -> size of S in memory, in bytes");\r
1734\r
1735static PyObject *\r
1736s_sizeof(PyStructObject *self, void *unused)\r
1737{\r
1738 Py_ssize_t size;\r
1739\r
1740 size = sizeof(PyStructObject) + sizeof(formatcode) * (self->s_len + 1);\r
1741 return PyLong_FromSsize_t(size);\r
1742}\r
1743\r
1744/* List of functions */\r
1745\r
1746static struct PyMethodDef s_methods[] = {\r
1747 {"pack", s_pack, METH_VARARGS, s_pack__doc__},\r
1748 {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__},\r
1749 {"unpack", s_unpack, METH_O, s_unpack__doc__},\r
1750 {"unpack_from", (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS,\r
1751 s_unpack_from__doc__},\r
1752 {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__},\r
1753 {NULL, NULL} /* sentinel */\r
1754};\r
1755\r
1756PyDoc_STRVAR(s__doc__, "Compiled struct object");\r
1757\r
1758#define OFF(x) offsetof(PyStructObject, x)\r
1759\r
1760static PyGetSetDef s_getsetlist[] = {\r
1761 {"format", (getter)s_get_format, (setter)NULL, "struct format string", NULL},\r
1762 {"size", (getter)s_get_size, (setter)NULL, "struct size in bytes", NULL},\r
1763 {NULL} /* sentinel */\r
1764};\r
1765\r
1766static\r
1767PyTypeObject PyStructType = {\r
1768 PyVarObject_HEAD_INIT(NULL, 0)\r
1769 "Struct",\r
1770 sizeof(PyStructObject),\r
1771 0,\r
1772 (destructor)s_dealloc, /* tp_dealloc */\r
1773 0, /* tp_print */\r
1774 0, /* tp_getattr */\r
1775 0, /* tp_setattr */\r
1776 0, /* tp_compare */\r
1777 0, /* tp_repr */\r
1778 0, /* tp_as_number */\r
1779 0, /* tp_as_sequence */\r
1780 0, /* tp_as_mapping */\r
1781 0, /* tp_hash */\r
1782 0, /* tp_call */\r
1783 0, /* tp_str */\r
1784 PyObject_GenericGetAttr, /* tp_getattro */\r
1785 PyObject_GenericSetAttr, /* tp_setattro */\r
1786 0, /* tp_as_buffer */\r
1787 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_WEAKREFS,/* tp_flags */\r
1788 s__doc__, /* tp_doc */\r
1789 0, /* tp_traverse */\r
1790 0, /* tp_clear */\r
1791 0, /* tp_richcompare */\r
1792 offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */\r
1793 0, /* tp_iter */\r
1794 0, /* tp_iternext */\r
1795 s_methods, /* tp_methods */\r
1796 NULL, /* tp_members */\r
1797 s_getsetlist, /* tp_getset */\r
1798 0, /* tp_base */\r
1799 0, /* tp_dict */\r
1800 0, /* tp_descr_get */\r
1801 0, /* tp_descr_set */\r
1802 0, /* tp_dictoffset */\r
1803 s_init, /* tp_init */\r
1804 PyType_GenericAlloc,/* tp_alloc */\r
1805 s_new, /* tp_new */\r
1806 PyObject_Del, /* tp_free */\r
1807};\r
1808\r
1809\r
1810/* ---- Standalone functions ---- */\r
1811\r
1812#define MAXCACHE 100\r
1813static PyObject *cache = NULL;\r
1814\r
1815static PyObject *\r
1816cache_struct(PyObject *fmt)\r
1817{\r
1818 PyObject * s_object;\r
1819\r
1820 if (cache == NULL) {\r
1821 cache = PyDict_New();\r
1822 if (cache == NULL)\r
1823 return NULL;\r
1824 }\r
1825\r
1826 s_object = PyDict_GetItem(cache, fmt);\r
1827 if (s_object != NULL) {\r
1828 Py_INCREF(s_object);\r
1829 return s_object;\r
1830 }\r
1831\r
1832 s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL);\r
1833 if (s_object != NULL) {\r
1834 if (PyDict_Size(cache) >= MAXCACHE)\r
1835 PyDict_Clear(cache);\r
1836 /* Attempt to cache the result */\r
1837 if (PyDict_SetItem(cache, fmt, s_object) == -1)\r
1838 PyErr_Clear();\r
1839 }\r
1840 return s_object;\r
1841}\r
1842\r
1843PyDoc_STRVAR(clearcache_doc,\r
1844"Clear the internal cache.");\r
1845\r
1846static PyObject *\r
1847clearcache(PyObject *self)\r
1848{\r
1849 Py_CLEAR(cache);\r
1850 Py_RETURN_NONE;\r
1851}\r
1852\r
1853PyDoc_STRVAR(calcsize_doc,\r
1854"Return size of C struct described by format string fmt.");\r
1855\r
1856static PyObject *\r
1857calcsize(PyObject *self, PyObject *fmt)\r
1858{\r
1859 Py_ssize_t n;\r
1860 PyObject *s_object = cache_struct(fmt);\r
1861 if (s_object == NULL)\r
1862 return NULL;\r
1863 n = ((PyStructObject *)s_object)->s_size;\r
1864 Py_DECREF(s_object);\r
1865 return PyInt_FromSsize_t(n);\r
1866}\r
1867\r
1868PyDoc_STRVAR(pack_doc,\r
1869"Return string containing values v1, v2, ... packed according to fmt.");\r
1870\r
1871static PyObject *\r
1872pack(PyObject *self, PyObject *args)\r
1873{\r
1874 PyObject *s_object, *fmt, *newargs, *result;\r
1875 Py_ssize_t n = PyTuple_GET_SIZE(args);\r
1876\r
1877 if (n == 0) {\r
1878 PyErr_SetString(PyExc_TypeError, "missing format argument");\r
1879 return NULL;\r
1880 }\r
1881 fmt = PyTuple_GET_ITEM(args, 0);\r
1882 newargs = PyTuple_GetSlice(args, 1, n);\r
1883 if (newargs == NULL)\r
1884 return NULL;\r
1885\r
1886 s_object = cache_struct(fmt);\r
1887 if (s_object == NULL) {\r
1888 Py_DECREF(newargs);\r
1889 return NULL;\r
1890 }\r
1891 result = s_pack(s_object, newargs);\r
1892 Py_DECREF(newargs);\r
1893 Py_DECREF(s_object);\r
1894 return result;\r
1895}\r
1896\r
1897PyDoc_STRVAR(pack_into_doc,\r
1898"Pack the values v1, v2, ... according to fmt.\n\\r
1899Write the packed bytes into the writable buffer buf starting at offset.");\r
1900\r
1901static PyObject *\r
1902pack_into(PyObject *self, PyObject *args)\r
1903{\r
1904 PyObject *s_object, *fmt, *newargs, *result;\r
1905 Py_ssize_t n = PyTuple_GET_SIZE(args);\r
1906\r
1907 if (n == 0) {\r
1908 PyErr_SetString(PyExc_TypeError, "missing format argument");\r
1909 return NULL;\r
1910 }\r
1911 fmt = PyTuple_GET_ITEM(args, 0);\r
1912 newargs = PyTuple_GetSlice(args, 1, n);\r
1913 if (newargs == NULL)\r
1914 return NULL;\r
1915\r
1916 s_object = cache_struct(fmt);\r
1917 if (s_object == NULL) {\r
1918 Py_DECREF(newargs);\r
1919 return NULL;\r
1920 }\r
1921 result = s_pack_into(s_object, newargs);\r
1922 Py_DECREF(newargs);\r
1923 Py_DECREF(s_object);\r
1924 return result;\r
1925}\r
1926\r
1927PyDoc_STRVAR(unpack_doc,\r
1928"Unpack the string containing packed C structure data, according to fmt.\n\\r
1929Requires len(string) == calcsize(fmt).");\r
1930\r
1931static PyObject *\r
1932unpack(PyObject *self, PyObject *args)\r
1933{\r
1934 PyObject *s_object, *fmt, *inputstr, *result;\r
1935\r
1936 if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr))\r
1937 return NULL;\r
1938\r
1939 s_object = cache_struct(fmt);\r
1940 if (s_object == NULL)\r
1941 return NULL;\r
1942 result = s_unpack(s_object, inputstr);\r
1943 Py_DECREF(s_object);\r
1944 return result;\r
1945}\r
1946\r
1947PyDoc_STRVAR(unpack_from_doc,\r
1948"Unpack the buffer, containing packed C structure data, according to\n\\r
1949fmt, starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).");\r
1950\r
1951static PyObject *\r
1952unpack_from(PyObject *self, PyObject *args, PyObject *kwds)\r
1953{\r
1954 PyObject *s_object, *fmt, *newargs, *result;\r
1955 Py_ssize_t n = PyTuple_GET_SIZE(args);\r
1956\r
1957 if (n == 0) {\r
1958 PyErr_SetString(PyExc_TypeError, "missing format argument");\r
1959 return NULL;\r
1960 }\r
1961 fmt = PyTuple_GET_ITEM(args, 0);\r
1962 newargs = PyTuple_GetSlice(args, 1, n);\r
1963 if (newargs == NULL)\r
1964 return NULL;\r
1965\r
1966 s_object = cache_struct(fmt);\r
1967 if (s_object == NULL) {\r
1968 Py_DECREF(newargs);\r
1969 return NULL;\r
1970 }\r
1971 result = s_unpack_from(s_object, newargs, kwds);\r
1972 Py_DECREF(newargs);\r
1973 Py_DECREF(s_object);\r
1974 return result;\r
1975}\r
1976\r
1977static struct PyMethodDef module_functions[] = {\r
1978 {"_clearcache", (PyCFunction)clearcache, METH_NOARGS, clearcache_doc},\r
1979 {"calcsize", calcsize, METH_O, calcsize_doc},\r
1980 {"pack", pack, METH_VARARGS, pack_doc},\r
1981 {"pack_into", pack_into, METH_VARARGS, pack_into_doc},\r
1982 {"unpack", unpack, METH_VARARGS, unpack_doc},\r
1983 {"unpack_from", (PyCFunction)unpack_from,\r
1984 METH_VARARGS|METH_KEYWORDS, unpack_from_doc},\r
1985 {NULL, NULL} /* sentinel */\r
1986};\r
1987\r
1988\r
1989/* Module initialization */\r
1990\r
1991PyDoc_STRVAR(module_doc,\r
1992"Functions to convert between Python values and C structs represented\n\\r
1993as Python strings. It uses format strings (explained below) as compact\n\\r
1994descriptions of the lay-out of the C structs and the intended conversion\n\\r
1995to/from Python values.\n\\r
1996\n\\r
1997The optional first format char indicates byte order, size and alignment:\n\\r
1998 @: native order, size & alignment (default)\n\\r
1999 =: native order, std. size & alignment\n\\r
2000 <: little-endian, std. size & alignment\n\\r
2001 >: big-endian, std. size & alignment\n\\r
2002 !: same as >\n\\r
2003\n\\r
2004The remaining chars indicate types of args and must match exactly;\n\\r
2005these can be preceded by a decimal repeat count:\n\\r
2006 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\\r
2007 ?: _Bool (requires C99; if not available, char is used instead)\n\\r
2008 h:short; H:unsigned short; i:int; I:unsigned int;\n\\r
2009 l:long; L:unsigned long; f:float; d:double.\n\\r
2010Special cases (preceding decimal count indicates length):\n\\r
2011 s:string (array of char); p: pascal string (with count byte).\n\\r
2012Special case (only available in native format):\n\\r
2013 P:an integer type that is wide enough to hold a pointer.\n\\r
2014Special case (not in native mode unless 'long long' in platform C):\n\\r
2015 q:long long; Q:unsigned long long\n\\r
2016Whitespace between formats is ignored.\n\\r
2017\n\\r
2018The variable struct.error is an exception raised on errors.\n");\r
2019\r
2020PyMODINIT_FUNC\r
2021init_struct(void)\r
2022{\r
2023 PyObject *ver, *m;\r
2024\r
2025 ver = PyString_FromString("0.2");\r
2026 if (ver == NULL)\r
2027 return;\r
2028\r
2029 m = Py_InitModule3("_struct", module_functions, module_doc);\r
2030 if (m == NULL)\r
2031 return;\r
2032\r
2033 Py_TYPE(&PyStructType) = &PyType_Type;\r
2034 if (PyType_Ready(&PyStructType) < 0)\r
2035 return;\r
2036\r
2037 /* This speed trick can't be used until overflow masking goes\r
2038 away, because native endian always raises exceptions\r
2039 instead of overflow masking. */\r
2040\r
2041 /* Check endian and swap in faster functions */\r
2042 {\r
2043 int one = 1;\r
2044 formatdef *native = native_table;\r
2045 formatdef *other, *ptr;\r
2046 if ((int)*(unsigned char*)&one)\r
2047 other = lilendian_table;\r
2048 else\r
2049 other = bigendian_table;\r
2050 /* Scan through the native table, find a matching\r
2051 entry in the endian table and swap in the\r
2052 native implementations whenever possible\r
2053 (64-bit platforms may not have "standard" sizes) */\r
2054 while (native->format != '\0' && other->format != '\0') {\r
2055 ptr = other;\r
2056 while (ptr->format != '\0') {\r
2057 if (ptr->format == native->format) {\r
2058 /* Match faster when formats are\r
2059 listed in the same order */\r
2060 if (ptr == other)\r
2061 other++;\r
2062 /* Only use the trick if the\r
2063 size matches */\r
2064 if (ptr->size != native->size)\r
2065 break;\r
2066 /* Skip float and double, could be\r
2067 "unknown" float format */\r
2068 if (ptr->format == 'd' || ptr->format == 'f')\r
2069 break;\r
2070 ptr->pack = native->pack;\r
2071 ptr->unpack = native->unpack;\r
2072 break;\r
2073 }\r
2074 ptr++;\r
2075 }\r
2076 native++;\r
2077 }\r
2078 }\r
2079\r
2080 /* Add some symbolic constants to the module */\r
2081 if (StructError == NULL) {\r
2082 StructError = PyErr_NewException("struct.error", NULL, NULL);\r
2083 if (StructError == NULL)\r
2084 return;\r
2085 }\r
2086\r
2087 Py_INCREF(StructError);\r
2088 PyModule_AddObject(m, "error", StructError);\r
2089\r
2090 Py_INCREF((PyObject*)&PyStructType);\r
2091 PyModule_AddObject(m, "Struct", (PyObject*)&PyStructType);\r
2092\r
2093 PyModule_AddObject(m, "__version__", ver);\r
2094\r
2095 PyModule_AddIntConstant(m, "_PY_STRUCT_RANGE_CHECKING", 1);\r
2096 PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);\r
2097}\r