annotate Modules/_struct.c @ 45222:cdd2ea080e23 2.5

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