History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Modules/_struct.c (1 of 3706 files). Show all

Unified · Split

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

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t