bitstruct 8.22.2__cp315-cp315-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bitstruct/__init__.py +700 -0
- bitstruct/bitstream.c +600 -0
- bitstruct/bitstream.h +170 -0
- bitstruct/c.c +2629 -0
- bitstruct/c.cp315-win_amd64.pyd +0 -0
- bitstruct-8.22.2.dist-info/METADATA +252 -0
- bitstruct-8.22.2.dist-info/RECORD +10 -0
- bitstruct-8.22.2.dist-info/WHEEL +5 -0
- bitstruct-8.22.2.dist-info/licenses/LICENSE +22 -0
- bitstruct-8.22.2.dist-info/top_level.txt +1 -0
bitstruct/c.c
ADDED
|
@@ -0,0 +1,2629 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CPython 3 C extension.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
#include <Python.h>
|
|
6
|
+
#include <stdbool.h>
|
|
7
|
+
#include "bitstream.h"
|
|
8
|
+
|
|
9
|
+
#include <stdio.h>
|
|
10
|
+
|
|
11
|
+
struct field_info_t;
|
|
12
|
+
|
|
13
|
+
typedef void (*pack_field_t)(struct bitstream_writer_t *self_p,
|
|
14
|
+
PyObject *value_p,
|
|
15
|
+
struct field_info_t *field_info_p);
|
|
16
|
+
|
|
17
|
+
typedef PyObject *(*unpack_field_t)(struct bitstream_reader_t *self_p,
|
|
18
|
+
struct field_info_t *field_info_p);
|
|
19
|
+
|
|
20
|
+
struct field_info_t {
|
|
21
|
+
pack_field_t pack;
|
|
22
|
+
unpack_field_t unpack;
|
|
23
|
+
int number_of_bits;
|
|
24
|
+
bool is_padding;
|
|
25
|
+
union {
|
|
26
|
+
struct {
|
|
27
|
+
int64_t lower;
|
|
28
|
+
int64_t upper;
|
|
29
|
+
} s;
|
|
30
|
+
struct {
|
|
31
|
+
uint64_t upper;
|
|
32
|
+
} u;
|
|
33
|
+
} limits;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
struct info_t {
|
|
37
|
+
int number_of_bits;
|
|
38
|
+
int number_of_fields;
|
|
39
|
+
int number_of_non_padding_fields;
|
|
40
|
+
struct field_info_t fields[1];
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
struct compiled_format_t {
|
|
44
|
+
PyObject_HEAD
|
|
45
|
+
struct info_t *info_p;
|
|
46
|
+
PyObject *format_p;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
struct compiled_format_dict_t {
|
|
50
|
+
PyObject_HEAD
|
|
51
|
+
struct info_t *info_p;
|
|
52
|
+
PyObject *format_p;
|
|
53
|
+
PyObject *names_p;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
static const char* pickle_version_key = "_pickle_version";
|
|
57
|
+
static int pickle_version = 1;
|
|
58
|
+
|
|
59
|
+
static PyObject *compiled_format_new(PyTypeObject *type_p,
|
|
60
|
+
PyObject *args_p,
|
|
61
|
+
PyObject *kwargs_p);
|
|
62
|
+
|
|
63
|
+
static int compiled_format_init(struct compiled_format_t *self_p,
|
|
64
|
+
PyObject *args_p,
|
|
65
|
+
PyObject *kwargs_p);
|
|
66
|
+
|
|
67
|
+
static int compiled_format_init_inner(struct compiled_format_t *self_p,
|
|
68
|
+
PyObject *format_p);
|
|
69
|
+
|
|
70
|
+
static void compiled_format_dealloc(struct compiled_format_t *self_p);
|
|
71
|
+
|
|
72
|
+
static PyObject *m_compiled_format_pack(struct compiled_format_t *self_p,
|
|
73
|
+
PyObject *args_p);
|
|
74
|
+
|
|
75
|
+
static PyObject *m_compiled_format_unpack(struct compiled_format_t *self_p,
|
|
76
|
+
PyObject *args_p,
|
|
77
|
+
PyObject *kwargs_p);
|
|
78
|
+
|
|
79
|
+
static PyObject *m_compiled_format_pack_into(struct compiled_format_t *self_p,
|
|
80
|
+
PyObject *args_p,
|
|
81
|
+
PyObject *kwargs_p);
|
|
82
|
+
|
|
83
|
+
static PyObject *m_compiled_format_unpack_from(struct compiled_format_t *self_p,
|
|
84
|
+
PyObject *args_p,
|
|
85
|
+
PyObject *kwargs_p);
|
|
86
|
+
|
|
87
|
+
static PyObject *m_compiled_format_calcsize(struct compiled_format_t *self_p);
|
|
88
|
+
|
|
89
|
+
static PyObject *m_compiled_format_copy(struct compiled_format_t *self_p);
|
|
90
|
+
|
|
91
|
+
static PyObject *m_compiled_format_deepcopy(struct compiled_format_t *self_p,
|
|
92
|
+
PyObject *args_p);
|
|
93
|
+
|
|
94
|
+
static PyObject *m_compiled_format_getstate(struct compiled_format_t *self_p,
|
|
95
|
+
PyObject *args_p);
|
|
96
|
+
|
|
97
|
+
static PyObject *m_compiled_format_setstate(struct compiled_format_t *self_p,
|
|
98
|
+
PyObject *args_p);
|
|
99
|
+
|
|
100
|
+
static PyObject *compiled_format_dict_new(PyTypeObject *type_p,
|
|
101
|
+
PyObject *args_p,
|
|
102
|
+
PyObject *kwargs_p);
|
|
103
|
+
|
|
104
|
+
static int compiled_format_dict_init(struct compiled_format_dict_t *self_p,
|
|
105
|
+
PyObject *args_p,
|
|
106
|
+
PyObject *kwargs_p);
|
|
107
|
+
|
|
108
|
+
static int compiled_format_dict_init_inner(struct compiled_format_dict_t *self_p,
|
|
109
|
+
PyObject *format_p,
|
|
110
|
+
PyObject *names_p);
|
|
111
|
+
|
|
112
|
+
static void compiled_format_dict_dealloc(struct compiled_format_dict_t *self_p);
|
|
113
|
+
|
|
114
|
+
static PyObject *m_compiled_format_dict_pack(struct compiled_format_dict_t *self_p,
|
|
115
|
+
PyObject *data_p);
|
|
116
|
+
|
|
117
|
+
static PyObject *m_compiled_format_dict_unpack(
|
|
118
|
+
struct compiled_format_dict_t *self_p,
|
|
119
|
+
PyObject *args_p,
|
|
120
|
+
PyObject *kwargs_p);
|
|
121
|
+
|
|
122
|
+
static PyObject *m_compiled_format_dict_pack_into(
|
|
123
|
+
struct compiled_format_dict_t *self_p,
|
|
124
|
+
PyObject *args_p,
|
|
125
|
+
PyObject *kwargs_p);
|
|
126
|
+
|
|
127
|
+
static PyObject *m_compiled_format_dict_unpack_from(
|
|
128
|
+
struct compiled_format_dict_t *self_p,
|
|
129
|
+
PyObject *args_p,
|
|
130
|
+
PyObject *kwargs_p);
|
|
131
|
+
|
|
132
|
+
static PyObject *m_compiled_format_dict_calcsize(
|
|
133
|
+
struct compiled_format_dict_t *self_p);
|
|
134
|
+
|
|
135
|
+
static PyObject *m_compiled_format_dict_copy(
|
|
136
|
+
struct compiled_format_dict_t *self_p);
|
|
137
|
+
|
|
138
|
+
static PyObject *m_compiled_format_dict_deepcopy(
|
|
139
|
+
struct compiled_format_dict_t *self_p,
|
|
140
|
+
PyObject *args_p);
|
|
141
|
+
|
|
142
|
+
static PyObject *m_compiled_format_dict_getstate(struct compiled_format_dict_t *self_p,
|
|
143
|
+
PyObject *args_p);
|
|
144
|
+
|
|
145
|
+
static PyObject *m_compiled_format_dict_setstate(struct compiled_format_dict_t *self_p,
|
|
146
|
+
PyObject *args_p);
|
|
147
|
+
|
|
148
|
+
PyDoc_STRVAR(pack___doc__,
|
|
149
|
+
"pack(fmt, *args)\n"
|
|
150
|
+
"--\n"
|
|
151
|
+
"\n");
|
|
152
|
+
PyDoc_STRVAR(compiled_format_pack___doc__,
|
|
153
|
+
"pack(*args)\n"
|
|
154
|
+
"--\n"
|
|
155
|
+
"\n");
|
|
156
|
+
|
|
157
|
+
PyDoc_STRVAR(unpack___doc__,
|
|
158
|
+
"unpack(fmt, data, allow_truncated=False)\n"
|
|
159
|
+
"--\n"
|
|
160
|
+
"\n");
|
|
161
|
+
PyDoc_STRVAR(compiled_format_unpack___doc__,
|
|
162
|
+
"unpack(data, allow_truncated=False)\n"
|
|
163
|
+
"--\n"
|
|
164
|
+
"\n");
|
|
165
|
+
|
|
166
|
+
PyDoc_STRVAR(pack_into___doc__,
|
|
167
|
+
"pack_into(fmt, buf, offset, *args, **kwargs)\n"
|
|
168
|
+
"--\n"
|
|
169
|
+
"\n");
|
|
170
|
+
PyDoc_STRVAR(compiled_format_pack_into___doc__,
|
|
171
|
+
"pack_into(buf, offset, *args, **kwargs)\n"
|
|
172
|
+
"--\n"
|
|
173
|
+
"\n");
|
|
174
|
+
|
|
175
|
+
PyDoc_STRVAR(unpack_from___doc__,
|
|
176
|
+
"unpack_from(fmt, data, offset=0, allow_truncated=False)\n"
|
|
177
|
+
"--\n"
|
|
178
|
+
"\n");
|
|
179
|
+
PyDoc_STRVAR(compiled_format_unpack_from___doc__,
|
|
180
|
+
"unpack_from(data, offset=0, allow_truncated=False)\n"
|
|
181
|
+
"--\n"
|
|
182
|
+
"\n");
|
|
183
|
+
|
|
184
|
+
PyDoc_STRVAR(calcsize___doc__,
|
|
185
|
+
"calcsize(fmt)\n"
|
|
186
|
+
"--\n"
|
|
187
|
+
"\n");
|
|
188
|
+
PyDoc_STRVAR(compiled_format_calcsize___doc__,
|
|
189
|
+
"calcsize()\n"
|
|
190
|
+
"--\n"
|
|
191
|
+
"\n");
|
|
192
|
+
|
|
193
|
+
static PyObject *py_zero_p = NULL;
|
|
194
|
+
|
|
195
|
+
static struct PyMethodDef compiled_format_methods[] = {
|
|
196
|
+
{
|
|
197
|
+
"pack",
|
|
198
|
+
(PyCFunction)m_compiled_format_pack,
|
|
199
|
+
METH_VARARGS,
|
|
200
|
+
compiled_format_pack___doc__
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"unpack",
|
|
204
|
+
(PyCFunction)m_compiled_format_unpack,
|
|
205
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
206
|
+
compiled_format_unpack___doc__
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"pack_into",
|
|
210
|
+
(PyCFunction)m_compiled_format_pack_into,
|
|
211
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
212
|
+
compiled_format_pack_into___doc__
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
"unpack_from",
|
|
216
|
+
(PyCFunction)m_compiled_format_unpack_from,
|
|
217
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
218
|
+
compiled_format_unpack_from___doc__
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"calcsize",
|
|
222
|
+
(PyCFunction)m_compiled_format_calcsize,
|
|
223
|
+
METH_NOARGS,
|
|
224
|
+
compiled_format_calcsize___doc__
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
"__copy__",
|
|
228
|
+
(PyCFunction)m_compiled_format_copy,
|
|
229
|
+
METH_NOARGS
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"__deepcopy__",
|
|
233
|
+
(PyCFunction)m_compiled_format_deepcopy,
|
|
234
|
+
METH_VARARGS
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"__getstate__",
|
|
238
|
+
(PyCFunction)m_compiled_format_getstate,
|
|
239
|
+
METH_NOARGS
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
"__setstate__",
|
|
243
|
+
(PyCFunction)m_compiled_format_setstate,
|
|
244
|
+
METH_O
|
|
245
|
+
},
|
|
246
|
+
{ NULL }
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
static PyTypeObject compiled_format_type = {
|
|
250
|
+
PyVarObject_HEAD_INIT(NULL, 0)
|
|
251
|
+
.tp_name = "bitstruct.c.CompiledFormat",
|
|
252
|
+
.tp_doc = NULL,
|
|
253
|
+
.tp_basicsize = sizeof(struct compiled_format_t),
|
|
254
|
+
.tp_itemsize = 0,
|
|
255
|
+
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
|
256
|
+
.tp_new = compiled_format_new,
|
|
257
|
+
.tp_init = (initproc)compiled_format_init,
|
|
258
|
+
.tp_dealloc = (destructor)compiled_format_dealloc,
|
|
259
|
+
.tp_methods = compiled_format_methods,
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
static struct PyMethodDef compiled_format_dict_methods[] = {
|
|
263
|
+
{
|
|
264
|
+
"pack",
|
|
265
|
+
(PyCFunction)m_compiled_format_dict_pack,
|
|
266
|
+
METH_O,
|
|
267
|
+
pack___doc__
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"unpack",
|
|
271
|
+
(PyCFunction)m_compiled_format_dict_unpack,
|
|
272
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
273
|
+
unpack___doc__
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
"pack_into",
|
|
277
|
+
(PyCFunction)m_compiled_format_dict_pack_into,
|
|
278
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
279
|
+
pack_into___doc__
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"unpack_from",
|
|
283
|
+
(PyCFunction)m_compiled_format_dict_unpack_from,
|
|
284
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
285
|
+
unpack_from___doc__
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
"calcsize",
|
|
289
|
+
(PyCFunction)m_compiled_format_dict_calcsize,
|
|
290
|
+
METH_NOARGS,
|
|
291
|
+
calcsize___doc__
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
"__copy__",
|
|
295
|
+
(PyCFunction)m_compiled_format_dict_copy,
|
|
296
|
+
METH_NOARGS
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
"__deepcopy__",
|
|
300
|
+
(PyCFunction)m_compiled_format_dict_deepcopy,
|
|
301
|
+
METH_VARARGS
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
"__getstate__",
|
|
305
|
+
(PyCFunction)m_compiled_format_dict_getstate,
|
|
306
|
+
METH_NOARGS
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"__setstate__",
|
|
310
|
+
(PyCFunction)m_compiled_format_dict_setstate,
|
|
311
|
+
METH_O
|
|
312
|
+
},
|
|
313
|
+
{ NULL }
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
static PyTypeObject compiled_format_dict_type = {
|
|
317
|
+
PyVarObject_HEAD_INIT(NULL, 0)
|
|
318
|
+
.tp_name = "bitstruct.c.CompiledFormatDict",
|
|
319
|
+
.tp_doc = NULL,
|
|
320
|
+
.tp_basicsize = sizeof(struct compiled_format_dict_t),
|
|
321
|
+
.tp_itemsize = 0,
|
|
322
|
+
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
|
|
323
|
+
.tp_new = compiled_format_dict_new,
|
|
324
|
+
.tp_init = (initproc)compiled_format_dict_init,
|
|
325
|
+
.tp_dealloc = (destructor)compiled_format_dict_dealloc,
|
|
326
|
+
.tp_methods = compiled_format_dict_methods,
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
static bool is_names_list(PyObject *names_p)
|
|
330
|
+
{
|
|
331
|
+
if (!PyList_Check(names_p)) {
|
|
332
|
+
PyErr_SetString(PyExc_TypeError, "Names is not a list.");
|
|
333
|
+
|
|
334
|
+
return (false);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return (true);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
static void pack_signed_integer(struct bitstream_writer_t *self_p,
|
|
341
|
+
PyObject *value_p,
|
|
342
|
+
struct field_info_t *field_info_p)
|
|
343
|
+
{
|
|
344
|
+
int64_t value;
|
|
345
|
+
int64_t lower;
|
|
346
|
+
int64_t upper;
|
|
347
|
+
|
|
348
|
+
value = PyLong_AsLongLong(value_p);
|
|
349
|
+
|
|
350
|
+
if ((value == -1) && PyErr_Occurred()) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (field_info_p->number_of_bits < 64) {
|
|
355
|
+
lower = field_info_p->limits.s.lower;
|
|
356
|
+
upper = field_info_p->limits.s.upper;
|
|
357
|
+
|
|
358
|
+
if ((value < lower) || (value > upper)) {
|
|
359
|
+
PyErr_Format(PyExc_OverflowError,
|
|
360
|
+
"Signed integer value %lld out of range.",
|
|
361
|
+
(long long)value);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
value &= ((1ull << field_info_p->number_of_bits) - 1);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
bitstream_writer_write_u64_bits(self_p,
|
|
368
|
+
(uint64_t)value,
|
|
369
|
+
field_info_p->number_of_bits);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
static PyObject *unpack_signed_integer(struct bitstream_reader_t *self_p,
|
|
373
|
+
struct field_info_t *field_info_p)
|
|
374
|
+
{
|
|
375
|
+
uint64_t value;
|
|
376
|
+
uint64_t sign_bit;
|
|
377
|
+
|
|
378
|
+
value = bitstream_reader_read_u64_bits(self_p, field_info_p->number_of_bits);
|
|
379
|
+
sign_bit = (1ull << (field_info_p->number_of_bits - 1));
|
|
380
|
+
|
|
381
|
+
if (value & sign_bit) {
|
|
382
|
+
value |= ~(((sign_bit) << 1) - 1);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return (PyLong_FromLongLong((long long)value));
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
static void pack_unsigned_integer(struct bitstream_writer_t *self_p,
|
|
389
|
+
PyObject *value_p,
|
|
390
|
+
struct field_info_t *field_info_p)
|
|
391
|
+
{
|
|
392
|
+
uint64_t value;
|
|
393
|
+
|
|
394
|
+
value = PyLong_AsUnsignedLongLong(value_p);
|
|
395
|
+
|
|
396
|
+
if ((value == (uint64_t)-1) && PyErr_Occurred()) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
if (value > field_info_p->limits.u.upper) {
|
|
401
|
+
PyErr_Format(PyExc_OverflowError,
|
|
402
|
+
"Unsigned integer value %llu out of range.",
|
|
403
|
+
(unsigned long long)value);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
bitstream_writer_write_u64_bits(self_p,
|
|
407
|
+
value,
|
|
408
|
+
field_info_p->number_of_bits);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
static PyObject *unpack_unsigned_integer(struct bitstream_reader_t *self_p,
|
|
412
|
+
struct field_info_t *field_info_p)
|
|
413
|
+
{
|
|
414
|
+
uint64_t value;
|
|
415
|
+
|
|
416
|
+
value = bitstream_reader_read_u64_bits(self_p,
|
|
417
|
+
field_info_p->number_of_bits);
|
|
418
|
+
|
|
419
|
+
return (PyLong_FromUnsignedLongLong(value));
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 6
|
|
423
|
+
|
|
424
|
+
static void pack_float_16(struct bitstream_writer_t *self_p,
|
|
425
|
+
PyObject *value_p,
|
|
426
|
+
struct field_info_t *field_info_p)
|
|
427
|
+
{
|
|
428
|
+
uint8_t buf[2];
|
|
429
|
+
|
|
430
|
+
#if PY_VERSION_HEX >= 0x030B00A7
|
|
431
|
+
PyFloat_Pack2(PyFloat_AsDouble(value_p),
|
|
432
|
+
(char*)&buf[0],
|
|
433
|
+
0);
|
|
434
|
+
#else
|
|
435
|
+
_PyFloat_Pack2(PyFloat_AsDouble(value_p),
|
|
436
|
+
&buf[0],
|
|
437
|
+
0);
|
|
438
|
+
#endif
|
|
439
|
+
bitstream_writer_write_bytes(self_p, &buf[0], sizeof(buf));
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
static PyObject *unpack_float_16(struct bitstream_reader_t *self_p,
|
|
443
|
+
struct field_info_t *field_info_p)
|
|
444
|
+
{
|
|
445
|
+
uint8_t buf[2];
|
|
446
|
+
double value;
|
|
447
|
+
|
|
448
|
+
bitstream_reader_read_bytes(self_p, &buf[0], sizeof(buf));
|
|
449
|
+
#if PY_VERSION_HEX >= 0x030B00A7
|
|
450
|
+
value = PyFloat_Unpack2((const char*)&buf[0], 0);
|
|
451
|
+
#else
|
|
452
|
+
value = _PyFloat_Unpack2(&buf[0], 0);
|
|
453
|
+
#endif
|
|
454
|
+
|
|
455
|
+
return (PyFloat_FromDouble(value));
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
#endif
|
|
459
|
+
|
|
460
|
+
static void pack_float_32(struct bitstream_writer_t *self_p,
|
|
461
|
+
PyObject *value_p,
|
|
462
|
+
struct field_info_t *field_info_p)
|
|
463
|
+
{
|
|
464
|
+
float value;
|
|
465
|
+
uint32_t data;
|
|
466
|
+
|
|
467
|
+
value = (float)PyFloat_AsDouble(value_p);
|
|
468
|
+
memcpy(&data, &value, sizeof(data));
|
|
469
|
+
bitstream_writer_write_u32(self_p, data);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
static PyObject *unpack_float_32(struct bitstream_reader_t *self_p,
|
|
473
|
+
struct field_info_t *field_info_p)
|
|
474
|
+
{
|
|
475
|
+
float value;
|
|
476
|
+
uint32_t data;
|
|
477
|
+
|
|
478
|
+
data = bitstream_reader_read_u32(self_p);
|
|
479
|
+
memcpy(&value, &data, sizeof(value));
|
|
480
|
+
|
|
481
|
+
return (PyFloat_FromDouble(value));
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
static void pack_float_64(struct bitstream_writer_t *self_p,
|
|
485
|
+
PyObject *value_p,
|
|
486
|
+
struct field_info_t *field_info_p)
|
|
487
|
+
{
|
|
488
|
+
double value;
|
|
489
|
+
uint64_t data;
|
|
490
|
+
|
|
491
|
+
value = PyFloat_AsDouble(value_p);
|
|
492
|
+
memcpy(&data, &value, sizeof(data));
|
|
493
|
+
bitstream_writer_write_u64_bits(self_p,
|
|
494
|
+
data,
|
|
495
|
+
field_info_p->number_of_bits);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
static PyObject *unpack_float_64(struct bitstream_reader_t *self_p,
|
|
499
|
+
struct field_info_t *field_info_p)
|
|
500
|
+
{
|
|
501
|
+
double value;
|
|
502
|
+
uint64_t data;
|
|
503
|
+
|
|
504
|
+
data = bitstream_reader_read_u64(self_p);
|
|
505
|
+
memcpy(&value, &data, sizeof(value));
|
|
506
|
+
|
|
507
|
+
return (PyFloat_FromDouble(value));
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
static void pack_bool(struct bitstream_writer_t *self_p,
|
|
511
|
+
PyObject *value_p,
|
|
512
|
+
struct field_info_t *field_info_p)
|
|
513
|
+
{
|
|
514
|
+
bitstream_writer_write_u64_bits(self_p,
|
|
515
|
+
PyObject_IsTrue(value_p),
|
|
516
|
+
field_info_p->number_of_bits);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
static PyObject *unpack_bool(struct bitstream_reader_t *self_p,
|
|
520
|
+
struct field_info_t *field_info_p)
|
|
521
|
+
{
|
|
522
|
+
return (PyBool_FromLong((long)bitstream_reader_read_u64_bits(
|
|
523
|
+
self_p,
|
|
524
|
+
field_info_p->number_of_bits)));
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
static void pack_text(struct bitstream_writer_t *self_p,
|
|
528
|
+
PyObject *value_p,
|
|
529
|
+
struct field_info_t *field_info_p)
|
|
530
|
+
{
|
|
531
|
+
Py_ssize_t size;
|
|
532
|
+
const char* buf_p;
|
|
533
|
+
|
|
534
|
+
buf_p = PyUnicode_AsUTF8AndSize(value_p, &size);
|
|
535
|
+
|
|
536
|
+
if (buf_p != NULL) {
|
|
537
|
+
if (size < (field_info_p->number_of_bits / 8)) {
|
|
538
|
+
PyErr_SetString(PyExc_NotImplementedError, "Short text.");
|
|
539
|
+
} else {
|
|
540
|
+
bitstream_writer_write_bytes(self_p,
|
|
541
|
+
(uint8_t *)buf_p,
|
|
542
|
+
field_info_p->number_of_bits / 8);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
static PyObject *unpack_text(struct bitstream_reader_t *self_p,
|
|
548
|
+
struct field_info_t *field_info_p)
|
|
549
|
+
{
|
|
550
|
+
uint8_t *buf_p;
|
|
551
|
+
PyObject *value_p;
|
|
552
|
+
int number_of_bytes;
|
|
553
|
+
|
|
554
|
+
number_of_bytes = (field_info_p->number_of_bits / 8);
|
|
555
|
+
buf_p = PyMem_RawMalloc(number_of_bytes);
|
|
556
|
+
|
|
557
|
+
if (buf_p == NULL) {
|
|
558
|
+
return (NULL);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
bitstream_reader_read_bytes(self_p, buf_p, number_of_bytes);
|
|
562
|
+
value_p = PyUnicode_FromStringAndSize((const char *)buf_p, number_of_bytes);
|
|
563
|
+
PyMem_RawFree(buf_p);
|
|
564
|
+
|
|
565
|
+
return (value_p);
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
static void pack_raw(struct bitstream_writer_t *self_p,
|
|
569
|
+
PyObject *value_p,
|
|
570
|
+
struct field_info_t *field_info_p)
|
|
571
|
+
{
|
|
572
|
+
Py_ssize_t size;
|
|
573
|
+
char* buf_p;
|
|
574
|
+
int res;
|
|
575
|
+
|
|
576
|
+
res = PyBytes_AsStringAndSize(value_p, &buf_p, &size);
|
|
577
|
+
|
|
578
|
+
if (res != -1) {
|
|
579
|
+
if (size < (field_info_p->number_of_bits / 8)) {
|
|
580
|
+
PyErr_SetString(PyExc_NotImplementedError, "Short raw data.");
|
|
581
|
+
} else {
|
|
582
|
+
bitstream_writer_write_bytes(self_p,
|
|
583
|
+
(uint8_t *)buf_p,
|
|
584
|
+
field_info_p->number_of_bits / 8);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
static PyObject *unpack_raw(struct bitstream_reader_t *self_p,
|
|
590
|
+
struct field_info_t *field_info_p)
|
|
591
|
+
{
|
|
592
|
+
uint8_t *buf_p;
|
|
593
|
+
PyObject *value_p;
|
|
594
|
+
int number_of_bytes;
|
|
595
|
+
|
|
596
|
+
number_of_bytes = (field_info_p->number_of_bits / 8);
|
|
597
|
+
value_p = PyBytes_FromStringAndSize(NULL, number_of_bytes);
|
|
598
|
+
buf_p = (uint8_t *)PyBytes_AS_STRING(value_p);
|
|
599
|
+
bitstream_reader_read_bytes(self_p, buf_p, number_of_bytes);
|
|
600
|
+
|
|
601
|
+
return (value_p);
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
static void pack_zero_padding(struct bitstream_writer_t *self_p,
|
|
605
|
+
PyObject *value_p,
|
|
606
|
+
struct field_info_t *field_info_p)
|
|
607
|
+
{
|
|
608
|
+
bitstream_writer_write_repeated_bit(self_p,
|
|
609
|
+
0,
|
|
610
|
+
field_info_p->number_of_bits);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
static void pack_one_padding(struct bitstream_writer_t *self_p,
|
|
614
|
+
PyObject *value_p,
|
|
615
|
+
struct field_info_t *field_info_p)
|
|
616
|
+
{
|
|
617
|
+
bitstream_writer_write_repeated_bit(self_p,
|
|
618
|
+
1,
|
|
619
|
+
field_info_p->number_of_bits);
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
static PyObject *unpack_padding(struct bitstream_reader_t *self_p,
|
|
623
|
+
struct field_info_t *field_info_p)
|
|
624
|
+
{
|
|
625
|
+
bitstream_reader_seek(self_p, field_info_p->number_of_bits);
|
|
626
|
+
|
|
627
|
+
return (NULL);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
static int field_info_init_signed(struct field_info_t *self_p,
|
|
631
|
+
int number_of_bits)
|
|
632
|
+
{
|
|
633
|
+
uint64_t limit;
|
|
634
|
+
|
|
635
|
+
self_p->pack = pack_signed_integer;
|
|
636
|
+
self_p->unpack = unpack_signed_integer;
|
|
637
|
+
|
|
638
|
+
if (number_of_bits > 64) {
|
|
639
|
+
PyErr_SetString(PyExc_NotImplementedError,
|
|
640
|
+
"Signed integer over 64 bits.");
|
|
641
|
+
return (-1);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
limit = (1ull << (number_of_bits - 1));
|
|
645
|
+
self_p->limits.s.lower = -limit;
|
|
646
|
+
self_p->limits.s.upper = (limit - 1);
|
|
647
|
+
|
|
648
|
+
return (0);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
static int field_info_init_unsigned(struct field_info_t *self_p,
|
|
652
|
+
int number_of_bits)
|
|
653
|
+
{
|
|
654
|
+
self_p->pack = pack_unsigned_integer;
|
|
655
|
+
self_p->unpack = unpack_unsigned_integer;
|
|
656
|
+
|
|
657
|
+
if (number_of_bits > 64) {
|
|
658
|
+
PyErr_SetString(PyExc_NotImplementedError,
|
|
659
|
+
"Unsigned integer over 64 bits.");
|
|
660
|
+
return (-1);
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
if (number_of_bits < 64) {
|
|
664
|
+
self_p->limits.u.upper = ((1ull << number_of_bits) - 1);
|
|
665
|
+
} else {
|
|
666
|
+
self_p->limits.u.upper = (uint64_t)-1;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
return (0);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
static int field_info_init_float(struct field_info_t *self_p,
|
|
673
|
+
int number_of_bits)
|
|
674
|
+
{
|
|
675
|
+
switch (number_of_bits) {
|
|
676
|
+
|
|
677
|
+
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 6
|
|
678
|
+
case 16:
|
|
679
|
+
self_p->pack = pack_float_16;
|
|
680
|
+
self_p->unpack = unpack_float_16;
|
|
681
|
+
break;
|
|
682
|
+
#endif
|
|
683
|
+
|
|
684
|
+
case 32:
|
|
685
|
+
self_p->pack = pack_float_32;
|
|
686
|
+
self_p->unpack = unpack_float_32;
|
|
687
|
+
break;
|
|
688
|
+
|
|
689
|
+
case 64:
|
|
690
|
+
self_p->pack = pack_float_64;
|
|
691
|
+
self_p->unpack = unpack_float_64;
|
|
692
|
+
break;
|
|
693
|
+
|
|
694
|
+
default:
|
|
695
|
+
#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 6
|
|
696
|
+
PyErr_SetString(PyExc_NotImplementedError,
|
|
697
|
+
"Float not 16, 32 or 64 bits.");
|
|
698
|
+
#else
|
|
699
|
+
PyErr_SetString(PyExc_NotImplementedError, "Float not 32 or 64 bits.");
|
|
700
|
+
#endif
|
|
701
|
+
return (-1);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
return (0);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
static int field_info_init_bool(struct field_info_t *self_p,
|
|
708
|
+
int number_of_bits)
|
|
709
|
+
{
|
|
710
|
+
self_p->pack = pack_bool;
|
|
711
|
+
self_p->unpack = unpack_bool;
|
|
712
|
+
|
|
713
|
+
if (number_of_bits > 64) {
|
|
714
|
+
PyErr_SetString(PyExc_NotImplementedError, "Bool over 64 bits.");
|
|
715
|
+
return (-1);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
return (0);
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
static int field_info_init_text(struct field_info_t *self_p,
|
|
722
|
+
int number_of_bits)
|
|
723
|
+
{
|
|
724
|
+
self_p->pack = pack_text;
|
|
725
|
+
self_p->unpack = unpack_text;
|
|
726
|
+
|
|
727
|
+
if ((number_of_bits % 8) != 0) {
|
|
728
|
+
PyErr_SetString(PyExc_NotImplementedError,
|
|
729
|
+
"Text not multiple of 8 bits.");
|
|
730
|
+
return (-1);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
return (0);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
static int field_info_init_raw(struct field_info_t *self_p,
|
|
737
|
+
int number_of_bits)
|
|
738
|
+
{
|
|
739
|
+
self_p->pack = pack_raw;
|
|
740
|
+
self_p->unpack = unpack_raw;
|
|
741
|
+
|
|
742
|
+
if ((number_of_bits % 8) != 0) {
|
|
743
|
+
PyErr_SetString(PyExc_NotImplementedError,
|
|
744
|
+
"Raw not multiple of 8 bits.");
|
|
745
|
+
return (-1);
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
return (0);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
static int field_info_init_zero_padding(struct field_info_t *self_p)
|
|
752
|
+
{
|
|
753
|
+
self_p->pack = pack_zero_padding;
|
|
754
|
+
self_p->unpack = unpack_padding;
|
|
755
|
+
|
|
756
|
+
return (0);
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
static int field_info_init_one_padding(struct field_info_t *self_p)
|
|
760
|
+
{
|
|
761
|
+
self_p->pack = pack_one_padding;
|
|
762
|
+
self_p->unpack = unpack_padding;
|
|
763
|
+
|
|
764
|
+
return (0);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
static int field_info_init(struct field_info_t *self_p,
|
|
768
|
+
int kind,
|
|
769
|
+
int number_of_bits)
|
|
770
|
+
{
|
|
771
|
+
int res;
|
|
772
|
+
bool is_padding;
|
|
773
|
+
|
|
774
|
+
is_padding = false;
|
|
775
|
+
|
|
776
|
+
switch (kind) {
|
|
777
|
+
|
|
778
|
+
case 's':
|
|
779
|
+
res = field_info_init_signed(self_p, number_of_bits);
|
|
780
|
+
break;
|
|
781
|
+
|
|
782
|
+
case 'u':
|
|
783
|
+
res = field_info_init_unsigned(self_p, number_of_bits);
|
|
784
|
+
break;
|
|
785
|
+
|
|
786
|
+
case 'f':
|
|
787
|
+
res = field_info_init_float(self_p, number_of_bits);
|
|
788
|
+
break;
|
|
789
|
+
|
|
790
|
+
case 'b':
|
|
791
|
+
res = field_info_init_bool(self_p, number_of_bits);
|
|
792
|
+
break;
|
|
793
|
+
|
|
794
|
+
case 't':
|
|
795
|
+
res = field_info_init_text(self_p, number_of_bits);
|
|
796
|
+
break;
|
|
797
|
+
|
|
798
|
+
case 'r':
|
|
799
|
+
res = field_info_init_raw(self_p, number_of_bits);
|
|
800
|
+
break;
|
|
801
|
+
|
|
802
|
+
case 'p':
|
|
803
|
+
is_padding = true;
|
|
804
|
+
res = field_info_init_zero_padding(self_p);
|
|
805
|
+
break;
|
|
806
|
+
|
|
807
|
+
case 'P':
|
|
808
|
+
is_padding = true;
|
|
809
|
+
res = field_info_init_one_padding(self_p);
|
|
810
|
+
break;
|
|
811
|
+
|
|
812
|
+
default:
|
|
813
|
+
PyErr_Format(PyExc_ValueError, "Bad format field type '%c'.", kind);
|
|
814
|
+
res = -1;
|
|
815
|
+
break;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
self_p->number_of_bits = number_of_bits;
|
|
819
|
+
self_p->is_padding = is_padding;
|
|
820
|
+
|
|
821
|
+
return (res);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
static int count_number_of_fields(const char *format_p,
|
|
825
|
+
int *number_of_padding_fields_p)
|
|
826
|
+
{
|
|
827
|
+
int count;
|
|
828
|
+
|
|
829
|
+
count = 0;
|
|
830
|
+
*number_of_padding_fields_p = 0;
|
|
831
|
+
|
|
832
|
+
while (*format_p != '\0') {
|
|
833
|
+
if ((*format_p >= 'A') && (*format_p <= 'z')) {
|
|
834
|
+
count++;
|
|
835
|
+
|
|
836
|
+
if ((*format_p == 'p') || (*format_p == 'P')) {
|
|
837
|
+
(*number_of_padding_fields_p)++;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
format_p++;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
return (count);
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
const char *parse_field(const char *format_p,
|
|
848
|
+
int *kind_p,
|
|
849
|
+
int *number_of_bits_p)
|
|
850
|
+
{
|
|
851
|
+
while (isspace(*format_p)) {
|
|
852
|
+
format_p++;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
*kind_p = *format_p;
|
|
856
|
+
*number_of_bits_p = 0;
|
|
857
|
+
format_p++;
|
|
858
|
+
|
|
859
|
+
while (isdigit(*format_p)) {
|
|
860
|
+
if (*number_of_bits_p > (INT_MAX / 100)) {
|
|
861
|
+
PyErr_SetString(PyExc_ValueError, "Field too long.");
|
|
862
|
+
|
|
863
|
+
return (NULL);
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
*number_of_bits_p *= 10;
|
|
867
|
+
*number_of_bits_p += (*format_p - '0');
|
|
868
|
+
format_p++;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
if (*number_of_bits_p == 0) {
|
|
872
|
+
PyErr_SetString(PyExc_ValueError, "Field of size 0.");
|
|
873
|
+
format_p = NULL;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
return (format_p);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
static struct info_t *parse_format(PyObject *format_obj_p)
|
|
880
|
+
{
|
|
881
|
+
int number_of_fields;
|
|
882
|
+
struct info_t *info_p;
|
|
883
|
+
const char *format_p;
|
|
884
|
+
int i;
|
|
885
|
+
int kind;
|
|
886
|
+
int number_of_bits;
|
|
887
|
+
int number_of_padding_fields;
|
|
888
|
+
int res;
|
|
889
|
+
|
|
890
|
+
format_p = PyUnicode_AsUTF8(format_obj_p);
|
|
891
|
+
|
|
892
|
+
if (format_p == NULL) {
|
|
893
|
+
return (NULL);
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
number_of_fields = count_number_of_fields(format_p,
|
|
897
|
+
&number_of_padding_fields);
|
|
898
|
+
|
|
899
|
+
info_p = PyMem_RawMalloc(
|
|
900
|
+
sizeof(*info_p) + number_of_fields * sizeof(info_p->fields[0]));
|
|
901
|
+
|
|
902
|
+
if (info_p == NULL) {
|
|
903
|
+
return (NULL);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
info_p->number_of_bits = 0;
|
|
907
|
+
info_p->number_of_fields = number_of_fields;
|
|
908
|
+
info_p->number_of_non_padding_fields = (
|
|
909
|
+
number_of_fields - number_of_padding_fields);
|
|
910
|
+
|
|
911
|
+
for (i = 0; i < info_p->number_of_fields; i++) {
|
|
912
|
+
format_p = parse_field(format_p, &kind, &number_of_bits);
|
|
913
|
+
|
|
914
|
+
if (format_p == NULL) {
|
|
915
|
+
PyMem_RawFree(info_p);
|
|
916
|
+
|
|
917
|
+
return (NULL);
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
res = field_info_init(&info_p->fields[i], kind, number_of_bits);
|
|
921
|
+
|
|
922
|
+
if (res != 0) {
|
|
923
|
+
PyMem_RawFree(info_p);
|
|
924
|
+
|
|
925
|
+
return (NULL);
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
if (number_of_bits > (INT_MAX - info_p->number_of_bits)) {
|
|
929
|
+
PyErr_SetString(PyExc_ValueError, "Format too long.");
|
|
930
|
+
PyMem_RawFree(info_p);
|
|
931
|
+
|
|
932
|
+
return (NULL);
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
info_p->number_of_bits += number_of_bits;
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
return (info_p);
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
static void pack_pack(struct info_t *info_p,
|
|
942
|
+
PyObject *args_p,
|
|
943
|
+
int consumed_args,
|
|
944
|
+
struct bitstream_writer_t *writer_p)
|
|
945
|
+
{
|
|
946
|
+
PyObject *value_p;
|
|
947
|
+
int i;
|
|
948
|
+
struct field_info_t *field_p;
|
|
949
|
+
|
|
950
|
+
for (i = 0; i < info_p->number_of_fields; i++) {
|
|
951
|
+
field_p = &info_p->fields[i];
|
|
952
|
+
|
|
953
|
+
if (field_p->is_padding) {
|
|
954
|
+
value_p = NULL;
|
|
955
|
+
} else {
|
|
956
|
+
value_p = PyTuple_GET_ITEM(args_p, consumed_args);
|
|
957
|
+
consumed_args++;
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
info_p->fields[i].pack(writer_p, value_p, field_p);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
static PyObject *pack_prepare(struct info_t *info_p,
|
|
965
|
+
struct bitstream_writer_t *writer_p)
|
|
966
|
+
{
|
|
967
|
+
PyObject *packed_p;
|
|
968
|
+
|
|
969
|
+
packed_p = PyBytes_FromStringAndSize(NULL, (info_p->number_of_bits + 7) / 8);
|
|
970
|
+
|
|
971
|
+
if (packed_p == NULL) {
|
|
972
|
+
return (NULL);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
bitstream_writer_init(writer_p, (uint8_t *)PyBytes_AS_STRING(packed_p));
|
|
976
|
+
|
|
977
|
+
return (packed_p);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
static PyObject *pack_finalize(PyObject *packed_p)
|
|
981
|
+
{
|
|
982
|
+
if (PyErr_Occurred() != NULL) {
|
|
983
|
+
Py_DECREF(packed_p);
|
|
984
|
+
packed_p = NULL;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
return (packed_p);
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
static PyObject *pack(struct info_t *info_p,
|
|
991
|
+
PyObject *args_p,
|
|
992
|
+
int consumed_args,
|
|
993
|
+
Py_ssize_t number_of_args)
|
|
994
|
+
{
|
|
995
|
+
struct bitstream_writer_t writer;
|
|
996
|
+
PyObject *packed_p;
|
|
997
|
+
|
|
998
|
+
if (number_of_args < info_p->number_of_non_padding_fields) {
|
|
999
|
+
PyErr_SetString(PyExc_ValueError, "Too few arguments.");
|
|
1000
|
+
|
|
1001
|
+
return (NULL);
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
packed_p = pack_prepare(info_p, &writer);
|
|
1005
|
+
|
|
1006
|
+
if (packed_p == NULL) {
|
|
1007
|
+
return (NULL);
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
pack_pack(info_p, args_p, consumed_args, &writer);
|
|
1011
|
+
|
|
1012
|
+
return (pack_finalize(packed_p));
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
static PyObject *m_pack(PyObject *module_p, PyObject *args_p)
|
|
1016
|
+
{
|
|
1017
|
+
Py_ssize_t number_of_args;
|
|
1018
|
+
PyObject *packed_p;
|
|
1019
|
+
struct info_t *info_p;
|
|
1020
|
+
|
|
1021
|
+
number_of_args = PyTuple_GET_SIZE(args_p);
|
|
1022
|
+
|
|
1023
|
+
if (number_of_args < 1) {
|
|
1024
|
+
PyErr_SetString(PyExc_ValueError, "No format string.");
|
|
1025
|
+
|
|
1026
|
+
return (NULL);
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
info_p = parse_format(PyTuple_GET_ITEM(args_p, 0));
|
|
1030
|
+
|
|
1031
|
+
if (info_p == NULL) {
|
|
1032
|
+
return (NULL);
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
packed_p = pack(info_p, args_p, 1, number_of_args - 1);
|
|
1036
|
+
PyMem_RawFree(info_p);
|
|
1037
|
+
|
|
1038
|
+
return (packed_p);
|
|
1039
|
+
}
|
|
1040
|
+
|
|
1041
|
+
static PyObject *unpack(struct info_t *info_p,
|
|
1042
|
+
PyObject *data_p,
|
|
1043
|
+
long offset,
|
|
1044
|
+
PyObject *allow_truncated_p)
|
|
1045
|
+
{
|
|
1046
|
+
struct bitstream_reader_t reader;
|
|
1047
|
+
PyObject *unpacked_p = NULL;
|
|
1048
|
+
PyObject *value_p;
|
|
1049
|
+
Py_buffer view = {NULL, NULL};
|
|
1050
|
+
int i;
|
|
1051
|
+
int tmp;
|
|
1052
|
+
int produced_args;
|
|
1053
|
+
int res;
|
|
1054
|
+
int allow_truncated;
|
|
1055
|
+
int num_result_fields;
|
|
1056
|
+
|
|
1057
|
+
res = PyObject_GetBuffer(data_p, &view, PyBUF_C_CONTIGUOUS);
|
|
1058
|
+
if (res == -1) {
|
|
1059
|
+
return (NULL);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
allow_truncated = PyObject_IsTrue(allow_truncated_p);
|
|
1063
|
+
|
|
1064
|
+
if (allow_truncated) {
|
|
1065
|
+
num_result_fields = 0;
|
|
1066
|
+
tmp = 0;
|
|
1067
|
+
for (i = 0; i < info_p->number_of_fields; i++) {
|
|
1068
|
+
if (view.len*8 < tmp + info_p->fields[i].number_of_bits) {
|
|
1069
|
+
break;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
tmp += info_p->fields[i].number_of_bits;
|
|
1073
|
+
|
|
1074
|
+
if (!info_p->fields[i].is_padding) {
|
|
1075
|
+
++num_result_fields;
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
else {
|
|
1080
|
+
num_result_fields = info_p->number_of_non_padding_fields;
|
|
1081
|
+
|
|
1082
|
+
if (view.len < ((info_p->number_of_bits + offset + 7) / 8)) {
|
|
1083
|
+
PyErr_SetString(PyExc_ValueError, "Short data.");
|
|
1084
|
+
goto exit;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
unpacked_p = PyTuple_New(num_result_fields);
|
|
1089
|
+
|
|
1090
|
+
if (unpacked_p == NULL) {
|
|
1091
|
+
goto exit;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
bitstream_reader_init(&reader, (uint8_t *)view.buf);
|
|
1095
|
+
bitstream_reader_seek(&reader, offset);
|
|
1096
|
+
produced_args = 0;
|
|
1097
|
+
|
|
1098
|
+
for (i = 0; i < info_p->number_of_fields; i++) {
|
|
1099
|
+
if (produced_args == num_result_fields) {
|
|
1100
|
+
break;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
value_p = info_p->fields[i].unpack(&reader, &info_p->fields[i]);
|
|
1104
|
+
|
|
1105
|
+
if (value_p != NULL) {
|
|
1106
|
+
PyTuple_SET_ITEM(unpacked_p, produced_args, value_p);
|
|
1107
|
+
produced_args++;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
/*
|
|
1112
|
+
out1:
|
|
1113
|
+
if (PyErr_Occurred() != NULL) {
|
|
1114
|
+
Py_DECREF(unpacked_p);
|
|
1115
|
+
unpacked_p = NULL;
|
|
1116
|
+
}
|
|
1117
|
+
*/
|
|
1118
|
+
exit:
|
|
1119
|
+
PyBuffer_Release(&view);
|
|
1120
|
+
return (unpacked_p);
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
static PyObject *m_unpack(PyObject *module_p,
|
|
1124
|
+
PyObject *args_p,
|
|
1125
|
+
PyObject *kwargs_p)
|
|
1126
|
+
{
|
|
1127
|
+
PyObject *format_p;
|
|
1128
|
+
PyObject *data_p;
|
|
1129
|
+
PyObject *unpacked_p;
|
|
1130
|
+
PyObject *allow_truncated_p;
|
|
1131
|
+
struct info_t *info_p;
|
|
1132
|
+
int res;
|
|
1133
|
+
static char *keywords[] = {
|
|
1134
|
+
"fmt",
|
|
1135
|
+
"data",
|
|
1136
|
+
"allow_truncated",
|
|
1137
|
+
NULL
|
|
1138
|
+
};
|
|
1139
|
+
|
|
1140
|
+
allow_truncated_p = py_zero_p;
|
|
1141
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
1142
|
+
kwargs_p,
|
|
1143
|
+
"OO|O",
|
|
1144
|
+
&keywords[0],
|
|
1145
|
+
&format_p,
|
|
1146
|
+
&data_p,
|
|
1147
|
+
&allow_truncated_p);
|
|
1148
|
+
|
|
1149
|
+
if (res == 0) {
|
|
1150
|
+
return (NULL);
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
info_p = parse_format(format_p);
|
|
1154
|
+
|
|
1155
|
+
if (info_p == NULL) {
|
|
1156
|
+
return (NULL);
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
unpacked_p = unpack(info_p, data_p, 0, allow_truncated_p);
|
|
1160
|
+
PyMem_RawFree(info_p);
|
|
1161
|
+
|
|
1162
|
+
return (unpacked_p);
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
static long parse_offset(PyObject *offset_p)
|
|
1166
|
+
{
|
|
1167
|
+
unsigned long offset;
|
|
1168
|
+
|
|
1169
|
+
offset = PyLong_AsUnsignedLong(offset_p);
|
|
1170
|
+
|
|
1171
|
+
if (offset == (unsigned long)-1) {
|
|
1172
|
+
return (-1);
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
if (offset > 0x7fffffff) {
|
|
1176
|
+
PyErr_Format(PyExc_ValueError,
|
|
1177
|
+
"Offset must be less or equal to %d bits.",
|
|
1178
|
+
0x7fffffff);
|
|
1179
|
+
|
|
1180
|
+
return (-1);
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
return (offset);
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
static int pack_into_prepare(struct info_t *info_p,
|
|
1187
|
+
PyObject *buf_p,
|
|
1188
|
+
PyObject *offset_p,
|
|
1189
|
+
struct bitstream_writer_t *writer_p,
|
|
1190
|
+
struct bitstream_writer_bounds_t *bounds_p)
|
|
1191
|
+
{
|
|
1192
|
+
uint8_t *packed_p;
|
|
1193
|
+
Py_ssize_t size;
|
|
1194
|
+
long offset;
|
|
1195
|
+
|
|
1196
|
+
offset = parse_offset(offset_p);
|
|
1197
|
+
|
|
1198
|
+
if (offset == -1) {
|
|
1199
|
+
return (-1);
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
if (!PyByteArray_Check(buf_p)) {
|
|
1203
|
+
PyErr_SetString(PyExc_TypeError, "Bytearray needed.");
|
|
1204
|
+
|
|
1205
|
+
return (-1);
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
packed_p = (uint8_t *)PyByteArray_AsString(buf_p);
|
|
1209
|
+
|
|
1210
|
+
if (packed_p == NULL) {
|
|
1211
|
+
return (-1);
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
size = PyByteArray_GET_SIZE(buf_p);
|
|
1215
|
+
|
|
1216
|
+
if (size < ((info_p->number_of_bits + offset + 7) / 8)) {
|
|
1217
|
+
PyErr_Format(PyExc_ValueError,
|
|
1218
|
+
"pack_into requires a buffer of at least %ld bits",
|
|
1219
|
+
info_p->number_of_bits + offset);
|
|
1220
|
+
|
|
1221
|
+
return (-1);
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
bitstream_writer_init(writer_p, packed_p);
|
|
1225
|
+
bitstream_writer_bounds_save(bounds_p,
|
|
1226
|
+
writer_p,
|
|
1227
|
+
offset,
|
|
1228
|
+
info_p->number_of_bits);
|
|
1229
|
+
bitstream_writer_seek(writer_p, offset);
|
|
1230
|
+
|
|
1231
|
+
return (0);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
static PyObject *pack_into_finalize(struct bitstream_writer_bounds_t *bounds_p)
|
|
1235
|
+
{
|
|
1236
|
+
bitstream_writer_bounds_restore(bounds_p);
|
|
1237
|
+
|
|
1238
|
+
if (PyErr_Occurred() != NULL) {
|
|
1239
|
+
return (NULL);
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
Py_RETURN_NONE;
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
static PyObject *pack_into(struct info_t *info_p,
|
|
1246
|
+
PyObject *buf_p,
|
|
1247
|
+
PyObject *offset_p,
|
|
1248
|
+
PyObject *args_p,
|
|
1249
|
+
Py_ssize_t consumed_args,
|
|
1250
|
+
Py_ssize_t number_of_args)
|
|
1251
|
+
{
|
|
1252
|
+
struct bitstream_writer_t writer;
|
|
1253
|
+
struct bitstream_writer_bounds_t bounds;
|
|
1254
|
+
int res;
|
|
1255
|
+
|
|
1256
|
+
if ((number_of_args - consumed_args) < info_p->number_of_non_padding_fields) {
|
|
1257
|
+
PyErr_SetString(PyExc_ValueError, "Too few arguments.");
|
|
1258
|
+
|
|
1259
|
+
return (NULL);
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
res = pack_into_prepare(info_p, buf_p, offset_p, &writer, &bounds);
|
|
1263
|
+
|
|
1264
|
+
if (res != 0) {
|
|
1265
|
+
return (NULL);
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
pack_pack(info_p, args_p, consumed_args, &writer);
|
|
1269
|
+
|
|
1270
|
+
return (pack_into_finalize(&bounds));
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
static PyObject *m_pack_into(PyObject *module_p,
|
|
1274
|
+
PyObject *args_p,
|
|
1275
|
+
PyObject *kwargs_p)
|
|
1276
|
+
{
|
|
1277
|
+
PyObject *format_p;
|
|
1278
|
+
PyObject *buf_p;
|
|
1279
|
+
PyObject *offset_p;
|
|
1280
|
+
PyObject *res_p;
|
|
1281
|
+
Py_ssize_t number_of_args;
|
|
1282
|
+
struct info_t *info_p;
|
|
1283
|
+
|
|
1284
|
+
number_of_args = PyTuple_GET_SIZE(args_p);
|
|
1285
|
+
|
|
1286
|
+
if (number_of_args < 3) {
|
|
1287
|
+
PyErr_SetString(PyExc_ValueError, "Too few arguments.");
|
|
1288
|
+
|
|
1289
|
+
return (NULL);
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
format_p = PyTuple_GET_ITEM(args_p, 0);
|
|
1293
|
+
buf_p = PyTuple_GET_ITEM(args_p, 1);
|
|
1294
|
+
offset_p = PyTuple_GET_ITEM(args_p, 2);
|
|
1295
|
+
info_p = parse_format(format_p);
|
|
1296
|
+
|
|
1297
|
+
if (info_p == NULL) {
|
|
1298
|
+
return (NULL);
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
res_p = pack_into(info_p,
|
|
1302
|
+
buf_p,
|
|
1303
|
+
offset_p,
|
|
1304
|
+
args_p,
|
|
1305
|
+
3,
|
|
1306
|
+
number_of_args);
|
|
1307
|
+
PyMem_RawFree(info_p);
|
|
1308
|
+
|
|
1309
|
+
return (res_p);
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
static PyObject *unpack_from(struct info_t *info_p,
|
|
1313
|
+
PyObject *data_p,
|
|
1314
|
+
PyObject *offset_p,
|
|
1315
|
+
PyObject *allow_truncated_p)
|
|
1316
|
+
{
|
|
1317
|
+
long offset;
|
|
1318
|
+
|
|
1319
|
+
offset = parse_offset(offset_p);
|
|
1320
|
+
|
|
1321
|
+
if (offset == -1) {
|
|
1322
|
+
return (NULL);
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
return (unpack(info_p, data_p, offset, allow_truncated_p));
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
static PyObject *m_unpack_from(PyObject *module_p,
|
|
1329
|
+
PyObject *args_p,
|
|
1330
|
+
PyObject *kwargs_p)
|
|
1331
|
+
{
|
|
1332
|
+
PyObject *format_p;
|
|
1333
|
+
PyObject *data_p;
|
|
1334
|
+
PyObject *offset_p;
|
|
1335
|
+
PyObject *unpacked_p;
|
|
1336
|
+
PyObject *allow_truncated_p;
|
|
1337
|
+
struct info_t *info_p;
|
|
1338
|
+
int res;
|
|
1339
|
+
static char *keywords[] = {
|
|
1340
|
+
"fmt",
|
|
1341
|
+
"data",
|
|
1342
|
+
"offset",
|
|
1343
|
+
"allow_truncated",
|
|
1344
|
+
NULL
|
|
1345
|
+
};
|
|
1346
|
+
|
|
1347
|
+
offset_p = py_zero_p;
|
|
1348
|
+
allow_truncated_p = py_zero_p;
|
|
1349
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
1350
|
+
kwargs_p,
|
|
1351
|
+
"OO|OO",
|
|
1352
|
+
&keywords[0],
|
|
1353
|
+
&format_p,
|
|
1354
|
+
&data_p,
|
|
1355
|
+
&offset_p,
|
|
1356
|
+
&allow_truncated_p);
|
|
1357
|
+
|
|
1358
|
+
if (res == 0) {
|
|
1359
|
+
return (NULL);
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
info_p = parse_format(format_p);
|
|
1363
|
+
|
|
1364
|
+
if (info_p == NULL) {
|
|
1365
|
+
return (NULL);
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
unpacked_p = unpack_from(info_p, data_p, offset_p, allow_truncated_p);
|
|
1369
|
+
PyMem_RawFree(info_p);
|
|
1370
|
+
|
|
1371
|
+
return (unpacked_p);
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
static void pack_dict_pack(struct info_t *info_p,
|
|
1375
|
+
PyObject *names_p,
|
|
1376
|
+
PyObject *data_p,
|
|
1377
|
+
struct bitstream_writer_t *writer_p)
|
|
1378
|
+
{
|
|
1379
|
+
PyObject *value_p;
|
|
1380
|
+
int i;
|
|
1381
|
+
int consumed_args;
|
|
1382
|
+
struct field_info_t *field_p;
|
|
1383
|
+
|
|
1384
|
+
consumed_args = 0;
|
|
1385
|
+
|
|
1386
|
+
for (i = 0; i < info_p->number_of_fields; i++) {
|
|
1387
|
+
field_p = &info_p->fields[i];
|
|
1388
|
+
|
|
1389
|
+
if (field_p->is_padding) {
|
|
1390
|
+
value_p = NULL;
|
|
1391
|
+
} else {
|
|
1392
|
+
value_p = PyDict_GetItem(data_p,
|
|
1393
|
+
PyList_GET_ITEM(names_p, consumed_args));
|
|
1394
|
+
consumed_args++;
|
|
1395
|
+
|
|
1396
|
+
if (value_p == NULL) {
|
|
1397
|
+
PyErr_SetString(PyExc_KeyError, "Missing value.");
|
|
1398
|
+
break;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
info_p->fields[i].pack(writer_p, value_p, field_p);
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
static PyObject *pack_dict(struct info_t *info_p,
|
|
1407
|
+
PyObject *names_p,
|
|
1408
|
+
PyObject *data_p)
|
|
1409
|
+
{
|
|
1410
|
+
struct bitstream_writer_t writer;
|
|
1411
|
+
PyObject *packed_p;
|
|
1412
|
+
|
|
1413
|
+
if (PyList_GET_SIZE(names_p) < info_p->number_of_non_padding_fields) {
|
|
1414
|
+
PyErr_SetString(PyExc_ValueError, "Too few names.");
|
|
1415
|
+
|
|
1416
|
+
return (NULL);
|
|
1417
|
+
}
|
|
1418
|
+
|
|
1419
|
+
packed_p = pack_prepare(info_p, &writer);
|
|
1420
|
+
|
|
1421
|
+
if (packed_p == NULL) {
|
|
1422
|
+
return (NULL);
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
pack_dict_pack(info_p, names_p, data_p, &writer);
|
|
1426
|
+
|
|
1427
|
+
return (pack_finalize(packed_p));
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
PyDoc_STRVAR(pack_dict___doc__,
|
|
1431
|
+
"pack_dict(fmt, names, data)\n"
|
|
1432
|
+
"--\n"
|
|
1433
|
+
"\n");
|
|
1434
|
+
|
|
1435
|
+
static PyObject *m_pack_dict(PyObject *module_p, PyObject *args_p)
|
|
1436
|
+
{
|
|
1437
|
+
PyObject *format_p;
|
|
1438
|
+
PyObject *names_p;
|
|
1439
|
+
PyObject *data_p;
|
|
1440
|
+
PyObject *packed_p;
|
|
1441
|
+
struct info_t *info_p;
|
|
1442
|
+
int res;
|
|
1443
|
+
|
|
1444
|
+
res = PyArg_ParseTuple(args_p, "OOO", &format_p, &names_p, &data_p);
|
|
1445
|
+
|
|
1446
|
+
if (res == 0) {
|
|
1447
|
+
return (NULL);
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
info_p = parse_format(format_p);
|
|
1451
|
+
|
|
1452
|
+
if (info_p == NULL) {
|
|
1453
|
+
return (NULL);
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
if (!is_names_list(names_p)) {
|
|
1457
|
+
return (NULL);
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
packed_p = pack_dict(info_p, names_p, data_p);
|
|
1461
|
+
PyMem_RawFree(info_p);
|
|
1462
|
+
|
|
1463
|
+
return (packed_p);
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
static PyObject *unpack_dict(struct info_t *info_p,
|
|
1467
|
+
PyObject *names_p,
|
|
1468
|
+
PyObject *data_p,
|
|
1469
|
+
long offset,
|
|
1470
|
+
PyObject *allow_truncated_p)
|
|
1471
|
+
{
|
|
1472
|
+
struct bitstream_reader_t reader;
|
|
1473
|
+
PyObject *unpacked_p;
|
|
1474
|
+
PyObject *value_p;
|
|
1475
|
+
Py_buffer view = {NULL, NULL};
|
|
1476
|
+
int i;
|
|
1477
|
+
int res;
|
|
1478
|
+
int produced_args;
|
|
1479
|
+
int allow_truncated;
|
|
1480
|
+
|
|
1481
|
+
if (PyList_GET_SIZE(names_p) < info_p->number_of_non_padding_fields) {
|
|
1482
|
+
PyErr_SetString(PyExc_ValueError, "Too few names.");
|
|
1483
|
+
|
|
1484
|
+
return (NULL);
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
unpacked_p = PyDict_New();
|
|
1488
|
+
|
|
1489
|
+
if (unpacked_p == NULL) {
|
|
1490
|
+
return (NULL);
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
res = PyObject_GetBuffer(data_p, &view, PyBUF_C_CONTIGUOUS);
|
|
1494
|
+
|
|
1495
|
+
if (res == -1) {
|
|
1496
|
+
goto out1;
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
allow_truncated = PyObject_IsTrue(allow_truncated_p);
|
|
1500
|
+
|
|
1501
|
+
if (!allow_truncated && view.len < ((info_p->number_of_bits + offset + 7) / 8)) {
|
|
1502
|
+
PyErr_SetString(PyExc_ValueError, "Short data.");
|
|
1503
|
+
|
|
1504
|
+
goto out1;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
bitstream_reader_init(&reader, (uint8_t *)view.buf);
|
|
1508
|
+
bitstream_reader_seek(&reader, offset);
|
|
1509
|
+
produced_args = 0;
|
|
1510
|
+
|
|
1511
|
+
for (i = 0; i < info_p->number_of_fields; i++) {
|
|
1512
|
+
if (view.len*8 < reader.bit_offset + info_p->fields[i].number_of_bits)
|
|
1513
|
+
break;
|
|
1514
|
+
|
|
1515
|
+
value_p = info_p->fields[i].unpack(&reader, &info_p->fields[i]);
|
|
1516
|
+
|
|
1517
|
+
if (value_p != NULL) {
|
|
1518
|
+
PyDict_SetItem(unpacked_p,
|
|
1519
|
+
PyList_GET_ITEM(names_p, produced_args),
|
|
1520
|
+
value_p);
|
|
1521
|
+
Py_DECREF(value_p);
|
|
1522
|
+
produced_args++;
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
out1:
|
|
1527
|
+
if (PyErr_Occurred() != NULL) {
|
|
1528
|
+
Py_DECREF(unpacked_p);
|
|
1529
|
+
unpacked_p = NULL;
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
if (view.obj != NULL) {
|
|
1533
|
+
PyBuffer_Release(&view);
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
return (unpacked_p);
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
PyDoc_STRVAR(unpack_dict___doc__,
|
|
1540
|
+
"unpack_dict(fmt, names, data, allow_truncated=False)\n"
|
|
1541
|
+
"--\n"
|
|
1542
|
+
"\n");
|
|
1543
|
+
|
|
1544
|
+
static PyObject *m_unpack_dict(PyObject *module_p,
|
|
1545
|
+
PyObject *args_p,
|
|
1546
|
+
PyObject *kwargs_p)
|
|
1547
|
+
{
|
|
1548
|
+
PyObject *format_p;
|
|
1549
|
+
PyObject *names_p;
|
|
1550
|
+
PyObject *data_p;
|
|
1551
|
+
PyObject *allow_truncated_p;
|
|
1552
|
+
PyObject *unpacked_p;
|
|
1553
|
+
struct info_t *info_p;
|
|
1554
|
+
int res;
|
|
1555
|
+
static char *keywords[] = {
|
|
1556
|
+
"fmt",
|
|
1557
|
+
"names",
|
|
1558
|
+
"data",
|
|
1559
|
+
"allow_truncated",
|
|
1560
|
+
NULL
|
|
1561
|
+
};
|
|
1562
|
+
|
|
1563
|
+
allow_truncated_p = py_zero_p;
|
|
1564
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
1565
|
+
kwargs_p,
|
|
1566
|
+
"OOO|O",
|
|
1567
|
+
&keywords[0],
|
|
1568
|
+
&format_p,
|
|
1569
|
+
&names_p,
|
|
1570
|
+
&data_p,
|
|
1571
|
+
&allow_truncated_p);
|
|
1572
|
+
|
|
1573
|
+
if (res == 0) {
|
|
1574
|
+
return (NULL);
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
info_p = parse_format(format_p);
|
|
1578
|
+
|
|
1579
|
+
if (info_p == NULL) {
|
|
1580
|
+
return (NULL);
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
if (!is_names_list(names_p)) {
|
|
1584
|
+
return (NULL);
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
unpacked_p = unpack_dict(info_p, names_p, data_p, 0, allow_truncated_p);
|
|
1588
|
+
PyMem_RawFree(info_p);
|
|
1589
|
+
|
|
1590
|
+
return (unpacked_p);
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
static PyObject *unpack_from_dict(struct info_t *info_p,
|
|
1594
|
+
PyObject *names_p,
|
|
1595
|
+
PyObject *data_p,
|
|
1596
|
+
PyObject *offset_p,
|
|
1597
|
+
PyObject *allow_truncated_p)
|
|
1598
|
+
{
|
|
1599
|
+
long offset;
|
|
1600
|
+
|
|
1601
|
+
offset = parse_offset(offset_p);
|
|
1602
|
+
|
|
1603
|
+
if (offset == -1) {
|
|
1604
|
+
return (NULL);
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
return (unpack_dict(info_p, names_p, data_p, offset, allow_truncated_p));
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
static PyObject *pack_into_dict(struct info_t *info_p,
|
|
1611
|
+
PyObject *names_p,
|
|
1612
|
+
PyObject *buf_p,
|
|
1613
|
+
PyObject *offset_p,
|
|
1614
|
+
PyObject *data_p)
|
|
1615
|
+
{
|
|
1616
|
+
struct bitstream_writer_t writer;
|
|
1617
|
+
struct bitstream_writer_bounds_t bounds;
|
|
1618
|
+
int res;
|
|
1619
|
+
|
|
1620
|
+
res = pack_into_prepare(info_p, buf_p, offset_p, &writer, &bounds);
|
|
1621
|
+
|
|
1622
|
+
if (res != 0) {
|
|
1623
|
+
return (NULL);
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
pack_dict_pack(info_p, names_p, data_p, &writer);
|
|
1627
|
+
|
|
1628
|
+
return (pack_into_finalize(&bounds));
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
PyDoc_STRVAR(pack_into_dict___doc__,
|
|
1632
|
+
"pack_into_dict(fmt, names, buf, offset, data, **kwargs)\n"
|
|
1633
|
+
"--\n"
|
|
1634
|
+
"\n");
|
|
1635
|
+
|
|
1636
|
+
static PyObject *m_pack_into_dict(PyObject *module_p,
|
|
1637
|
+
PyObject *args_p,
|
|
1638
|
+
PyObject *kwargs_p)
|
|
1639
|
+
{
|
|
1640
|
+
PyObject *format_p;
|
|
1641
|
+
PyObject *names_p;
|
|
1642
|
+
PyObject *buf_p;
|
|
1643
|
+
PyObject *offset_p;
|
|
1644
|
+
PyObject *data_p;
|
|
1645
|
+
PyObject *res_p;
|
|
1646
|
+
struct info_t *info_p;
|
|
1647
|
+
int res;
|
|
1648
|
+
static char *keywords[] = {
|
|
1649
|
+
"fmt",
|
|
1650
|
+
"names",
|
|
1651
|
+
"buf",
|
|
1652
|
+
"offset",
|
|
1653
|
+
"data",
|
|
1654
|
+
NULL
|
|
1655
|
+
};
|
|
1656
|
+
|
|
1657
|
+
offset_p = py_zero_p;
|
|
1658
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
1659
|
+
kwargs_p,
|
|
1660
|
+
"OOOOO",
|
|
1661
|
+
&keywords[0],
|
|
1662
|
+
&format_p,
|
|
1663
|
+
&names_p,
|
|
1664
|
+
&buf_p,
|
|
1665
|
+
&offset_p,
|
|
1666
|
+
&data_p);
|
|
1667
|
+
|
|
1668
|
+
if (res == 0) {
|
|
1669
|
+
return (NULL);
|
|
1670
|
+
}
|
|
1671
|
+
|
|
1672
|
+
info_p = parse_format(format_p);
|
|
1673
|
+
|
|
1674
|
+
if (info_p == NULL) {
|
|
1675
|
+
return (NULL);
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
if (!is_names_list(names_p)) {
|
|
1679
|
+
return (NULL);
|
|
1680
|
+
}
|
|
1681
|
+
|
|
1682
|
+
res_p = pack_into_dict(info_p, names_p, buf_p, offset_p, data_p);
|
|
1683
|
+
PyMem_RawFree(info_p);
|
|
1684
|
+
|
|
1685
|
+
return (res_p);
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
PyDoc_STRVAR(unpack_from_dict___doc__,
|
|
1689
|
+
"unpack_from_dict(fmt, names, data, offset=0, allow_truncated=False)\n"
|
|
1690
|
+
"--\n"
|
|
1691
|
+
"\n");
|
|
1692
|
+
|
|
1693
|
+
static PyObject *m_unpack_from_dict(PyObject *module_p,
|
|
1694
|
+
PyObject *args_p,
|
|
1695
|
+
PyObject *kwargs_p)
|
|
1696
|
+
{
|
|
1697
|
+
PyObject *format_p;
|
|
1698
|
+
PyObject *names_p;
|
|
1699
|
+
PyObject *data_p;
|
|
1700
|
+
PyObject *offset_p;
|
|
1701
|
+
PyObject *allow_truncated_p;
|
|
1702
|
+
PyObject *unpacked_p;
|
|
1703
|
+
struct info_t *info_p;
|
|
1704
|
+
int res;
|
|
1705
|
+
static char *keywords[] = {
|
|
1706
|
+
"fmt",
|
|
1707
|
+
"names",
|
|
1708
|
+
"data",
|
|
1709
|
+
"offset",
|
|
1710
|
+
"allow_truncated",
|
|
1711
|
+
NULL
|
|
1712
|
+
};
|
|
1713
|
+
|
|
1714
|
+
offset_p = py_zero_p;
|
|
1715
|
+
allow_truncated_p = py_zero_p;
|
|
1716
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
1717
|
+
kwargs_p,
|
|
1718
|
+
"OOO|OO",
|
|
1719
|
+
&keywords[0],
|
|
1720
|
+
&format_p,
|
|
1721
|
+
&names_p,
|
|
1722
|
+
&data_p,
|
|
1723
|
+
&offset_p,
|
|
1724
|
+
&allow_truncated_p);
|
|
1725
|
+
|
|
1726
|
+
if (res == 0) {
|
|
1727
|
+
return (NULL);
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
info_p = parse_format(format_p);
|
|
1731
|
+
|
|
1732
|
+
if (info_p == NULL) {
|
|
1733
|
+
return (NULL);
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
if (!is_names_list(names_p)) {
|
|
1737
|
+
return (NULL);
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
unpacked_p = unpack_from_dict(info_p, names_p, data_p, offset_p, allow_truncated_p);
|
|
1741
|
+
PyMem_RawFree(info_p);
|
|
1742
|
+
|
|
1743
|
+
return (unpacked_p);
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1746
|
+
static PyObject *calcsize(struct info_t *info_p)
|
|
1747
|
+
{
|
|
1748
|
+
return (PyLong_FromLong(info_p->number_of_bits));
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
static PyObject *m_calcsize(PyObject *module_p, PyObject *format_p)
|
|
1752
|
+
{
|
|
1753
|
+
PyObject *size_p;
|
|
1754
|
+
struct info_t *info_p;
|
|
1755
|
+
|
|
1756
|
+
info_p = parse_format(format_p);
|
|
1757
|
+
|
|
1758
|
+
if (info_p == NULL) {
|
|
1759
|
+
return (NULL);
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
size_p = calcsize(info_p);
|
|
1763
|
+
PyMem_RawFree(info_p);
|
|
1764
|
+
|
|
1765
|
+
return (size_p);
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
PyDoc_STRVAR(byteswap___doc__,
|
|
1769
|
+
"byteswap(fmt, data, offset=0)\n"
|
|
1770
|
+
"--\n"
|
|
1771
|
+
"\n");
|
|
1772
|
+
|
|
1773
|
+
static PyObject *m_byteswap(PyObject *module_p,
|
|
1774
|
+
PyObject *args_p,
|
|
1775
|
+
PyObject *kwargs_p)
|
|
1776
|
+
{
|
|
1777
|
+
PyObject *format_p;
|
|
1778
|
+
PyObject *data_p;
|
|
1779
|
+
PyObject *swapped_p;
|
|
1780
|
+
const char *c_format_p;
|
|
1781
|
+
uint8_t *src_p;
|
|
1782
|
+
uint8_t *dst_p;
|
|
1783
|
+
Py_ssize_t size;
|
|
1784
|
+
int res;
|
|
1785
|
+
int offset;
|
|
1786
|
+
|
|
1787
|
+
static char *keywords[] = {
|
|
1788
|
+
"fmt",
|
|
1789
|
+
"data",
|
|
1790
|
+
NULL
|
|
1791
|
+
};
|
|
1792
|
+
|
|
1793
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
1794
|
+
kwargs_p,
|
|
1795
|
+
"OO",
|
|
1796
|
+
&keywords[0],
|
|
1797
|
+
&format_p,
|
|
1798
|
+
&data_p);
|
|
1799
|
+
|
|
1800
|
+
if (res == 0) {
|
|
1801
|
+
return (NULL);
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
c_format_p = PyUnicode_AsUTF8(format_p);
|
|
1805
|
+
|
|
1806
|
+
if (c_format_p == NULL) {
|
|
1807
|
+
return (NULL);
|
|
1808
|
+
}
|
|
1809
|
+
|
|
1810
|
+
res = PyBytes_AsStringAndSize(data_p, (char **)&src_p, &size);
|
|
1811
|
+
|
|
1812
|
+
if (res == -1) {
|
|
1813
|
+
return (NULL);
|
|
1814
|
+
}
|
|
1815
|
+
|
|
1816
|
+
swapped_p = PyBytes_FromStringAndSize(NULL, size);
|
|
1817
|
+
|
|
1818
|
+
if (swapped_p == NULL) {
|
|
1819
|
+
return (NULL);
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
dst_p = (uint8_t *)PyBytes_AS_STRING(swapped_p);
|
|
1823
|
+
offset = 0;
|
|
1824
|
+
|
|
1825
|
+
while (*c_format_p != '\0') {
|
|
1826
|
+
switch (*c_format_p) {
|
|
1827
|
+
|
|
1828
|
+
case '1':
|
|
1829
|
+
if ((size - offset) < 1) {
|
|
1830
|
+
goto out1;
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
dst_p[offset] = src_p[offset];
|
|
1834
|
+
offset += 1;
|
|
1835
|
+
break;
|
|
1836
|
+
|
|
1837
|
+
case '2':
|
|
1838
|
+
if ((size - offset) < 2) {
|
|
1839
|
+
goto out1;
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
dst_p[offset + 0] = src_p[offset + 1];
|
|
1843
|
+
dst_p[offset + 1] = src_p[offset + 0];
|
|
1844
|
+
offset += 2;
|
|
1845
|
+
break;
|
|
1846
|
+
|
|
1847
|
+
case '4':
|
|
1848
|
+
if ((size - offset) < 4) {
|
|
1849
|
+
goto out1;
|
|
1850
|
+
}
|
|
1851
|
+
|
|
1852
|
+
dst_p[offset + 0] = src_p[offset + 3];
|
|
1853
|
+
dst_p[offset + 1] = src_p[offset + 2];
|
|
1854
|
+
dst_p[offset + 2] = src_p[offset + 1];
|
|
1855
|
+
dst_p[offset + 3] = src_p[offset + 0];
|
|
1856
|
+
offset += 4;
|
|
1857
|
+
break;
|
|
1858
|
+
|
|
1859
|
+
case '8':
|
|
1860
|
+
if ((size - offset) < 8) {
|
|
1861
|
+
goto out1;
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1864
|
+
dst_p[offset + 0] = src_p[offset + 7];
|
|
1865
|
+
dst_p[offset + 1] = src_p[offset + 6];
|
|
1866
|
+
dst_p[offset + 2] = src_p[offset + 5];
|
|
1867
|
+
dst_p[offset + 3] = src_p[offset + 4];
|
|
1868
|
+
dst_p[offset + 4] = src_p[offset + 3];
|
|
1869
|
+
dst_p[offset + 5] = src_p[offset + 2];
|
|
1870
|
+
dst_p[offset + 6] = src_p[offset + 1];
|
|
1871
|
+
dst_p[offset + 7] = src_p[offset + 0];
|
|
1872
|
+
offset += 8;
|
|
1873
|
+
break;
|
|
1874
|
+
|
|
1875
|
+
default:
|
|
1876
|
+
PyErr_Format(PyExc_ValueError,
|
|
1877
|
+
"Expected 1, 2, 4 or 8, but got %c.",
|
|
1878
|
+
(char)*c_format_p);
|
|
1879
|
+
goto out2;
|
|
1880
|
+
}
|
|
1881
|
+
|
|
1882
|
+
c_format_p++;
|
|
1883
|
+
}
|
|
1884
|
+
|
|
1885
|
+
return (swapped_p);
|
|
1886
|
+
|
|
1887
|
+
out1:
|
|
1888
|
+
PyErr_SetString(PyExc_ValueError, "Out of data to swap.");
|
|
1889
|
+
|
|
1890
|
+
out2:
|
|
1891
|
+
|
|
1892
|
+
return (NULL);
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
static PyObject *compiled_format_create(PyTypeObject *type_p,
|
|
1896
|
+
PyObject *format_p)
|
|
1897
|
+
{
|
|
1898
|
+
PyObject *self_p;
|
|
1899
|
+
|
|
1900
|
+
self_p = compiled_format_new(type_p, NULL, NULL);
|
|
1901
|
+
|
|
1902
|
+
if (self_p == NULL) {
|
|
1903
|
+
return (NULL);
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1906
|
+
if (compiled_format_init_inner((struct compiled_format_t *)self_p,
|
|
1907
|
+
format_p) != 0) {
|
|
1908
|
+
return (NULL);
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
return (self_p);
|
|
1912
|
+
}
|
|
1913
|
+
|
|
1914
|
+
static PyObject *compiled_format_new(PyTypeObject *type_p,
|
|
1915
|
+
PyObject *args_p,
|
|
1916
|
+
PyObject *kwargs_p)
|
|
1917
|
+
{
|
|
1918
|
+
return (type_p->tp_alloc(type_p, 0));
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
static int compiled_format_init(struct compiled_format_t *self_p,
|
|
1922
|
+
PyObject *args_p,
|
|
1923
|
+
PyObject *kwargs_p)
|
|
1924
|
+
{
|
|
1925
|
+
int res;
|
|
1926
|
+
PyObject *format_p;
|
|
1927
|
+
|
|
1928
|
+
static char *keywords[] = {
|
|
1929
|
+
"fmt",
|
|
1930
|
+
NULL
|
|
1931
|
+
};
|
|
1932
|
+
|
|
1933
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
1934
|
+
kwargs_p,
|
|
1935
|
+
"O",
|
|
1936
|
+
&keywords[0],
|
|
1937
|
+
&format_p);
|
|
1938
|
+
|
|
1939
|
+
if (res == 0) {
|
|
1940
|
+
return (-1);
|
|
1941
|
+
}
|
|
1942
|
+
|
|
1943
|
+
return (compiled_format_init_inner(self_p, format_p));
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
static int compiled_format_init_inner(struct compiled_format_t *self_p,
|
|
1947
|
+
PyObject *format_p)
|
|
1948
|
+
{
|
|
1949
|
+
self_p->info_p = parse_format(format_p);
|
|
1950
|
+
|
|
1951
|
+
if (self_p->info_p == NULL) {
|
|
1952
|
+
PyObject_Free(self_p);
|
|
1953
|
+
|
|
1954
|
+
return (-1);
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
Py_INCREF(format_p);
|
|
1958
|
+
self_p->format_p = format_p;
|
|
1959
|
+
|
|
1960
|
+
return (0);
|
|
1961
|
+
}
|
|
1962
|
+
|
|
1963
|
+
static void compiled_format_dealloc(struct compiled_format_t *self_p)
|
|
1964
|
+
{
|
|
1965
|
+
PyMem_RawFree(self_p->info_p);
|
|
1966
|
+
Py_DECREF(self_p->format_p);
|
|
1967
|
+
Py_TYPE(self_p)->tp_free((PyObject *)self_p);
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
static PyObject *m_compiled_format_pack(struct compiled_format_t *self_p,
|
|
1971
|
+
PyObject *args_p)
|
|
1972
|
+
{
|
|
1973
|
+
return (pack(self_p->info_p, args_p, 0, PyTuple_GET_SIZE(args_p)));
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
static PyObject *m_compiled_format_unpack(struct compiled_format_t *self_p,
|
|
1977
|
+
PyObject *args_p,
|
|
1978
|
+
PyObject *kwargs_p)
|
|
1979
|
+
{
|
|
1980
|
+
PyObject *data_p;
|
|
1981
|
+
PyObject *allow_truncated_p;
|
|
1982
|
+
int res;
|
|
1983
|
+
static char *keywords[] = {
|
|
1984
|
+
"data",
|
|
1985
|
+
"allow_truncated",
|
|
1986
|
+
NULL
|
|
1987
|
+
};
|
|
1988
|
+
|
|
1989
|
+
allow_truncated_p = py_zero_p;
|
|
1990
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
1991
|
+
kwargs_p,
|
|
1992
|
+
"O|O",
|
|
1993
|
+
&keywords[0],
|
|
1994
|
+
&data_p,
|
|
1995
|
+
&allow_truncated_p);
|
|
1996
|
+
|
|
1997
|
+
if (res == 0) {
|
|
1998
|
+
return (NULL);
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
return (unpack(self_p->info_p, data_p, 0, allow_truncated_p));
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
static PyObject *m_compiled_format_pack_into(struct compiled_format_t *self_p,
|
|
2005
|
+
PyObject *args_p,
|
|
2006
|
+
PyObject *kwargs_p)
|
|
2007
|
+
{
|
|
2008
|
+
PyObject *buf_p;
|
|
2009
|
+
PyObject *offset_p;
|
|
2010
|
+
Py_ssize_t number_of_args;
|
|
2011
|
+
|
|
2012
|
+
number_of_args = PyTuple_GET_SIZE(args_p);
|
|
2013
|
+
|
|
2014
|
+
if (number_of_args < 2) {
|
|
2015
|
+
PyErr_SetString(PyExc_ValueError, "Too few arguments.");
|
|
2016
|
+
|
|
2017
|
+
return (NULL);
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
buf_p = PyTuple_GET_ITEM(args_p, 0);
|
|
2021
|
+
offset_p = PyTuple_GET_ITEM(args_p, 1);
|
|
2022
|
+
|
|
2023
|
+
return (pack_into(self_p->info_p,
|
|
2024
|
+
buf_p,
|
|
2025
|
+
offset_p,
|
|
2026
|
+
args_p,
|
|
2027
|
+
2,
|
|
2028
|
+
number_of_args));
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
static PyObject *m_compiled_format_unpack_from(struct compiled_format_t *self_p,
|
|
2032
|
+
PyObject *args_p,
|
|
2033
|
+
PyObject *kwargs_p)
|
|
2034
|
+
{
|
|
2035
|
+
PyObject *data_p;
|
|
2036
|
+
PyObject *offset_p;
|
|
2037
|
+
PyObject *allow_truncated_p;
|
|
2038
|
+
int res;
|
|
2039
|
+
static char *keywords[] = {
|
|
2040
|
+
"data",
|
|
2041
|
+
"offset",
|
|
2042
|
+
"allow_truncated",
|
|
2043
|
+
NULL
|
|
2044
|
+
};
|
|
2045
|
+
|
|
2046
|
+
offset_p = py_zero_p;
|
|
2047
|
+
allow_truncated_p = py_zero_p;
|
|
2048
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
2049
|
+
kwargs_p,
|
|
2050
|
+
"O|OO",
|
|
2051
|
+
&keywords[0],
|
|
2052
|
+
&data_p,
|
|
2053
|
+
&offset_p,
|
|
2054
|
+
&allow_truncated_p);
|
|
2055
|
+
|
|
2056
|
+
if (res == 0) {
|
|
2057
|
+
return (NULL);
|
|
2058
|
+
}
|
|
2059
|
+
|
|
2060
|
+
return (unpack_from(self_p->info_p, data_p, offset_p, allow_truncated_p));
|
|
2061
|
+
}
|
|
2062
|
+
|
|
2063
|
+
static PyObject *m_compiled_format_calcsize(struct compiled_format_t *self_p)
|
|
2064
|
+
{
|
|
2065
|
+
return (calcsize(self_p->info_p));
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
static PyObject *m_compiled_format_copy(struct compiled_format_t *self_p)
|
|
2069
|
+
{
|
|
2070
|
+
struct compiled_format_t *new_p;
|
|
2071
|
+
size_t info_size;
|
|
2072
|
+
|
|
2073
|
+
new_p = (struct compiled_format_t *)compiled_format_new(
|
|
2074
|
+
&compiled_format_type,
|
|
2075
|
+
NULL,
|
|
2076
|
+
NULL);
|
|
2077
|
+
|
|
2078
|
+
if (new_p == NULL) {
|
|
2079
|
+
return (NULL);
|
|
2080
|
+
}
|
|
2081
|
+
|
|
2082
|
+
info_size = sizeof(*self_p->info_p);
|
|
2083
|
+
info_size += (sizeof(self_p->info_p->fields[0])
|
|
2084
|
+
* (self_p->info_p->number_of_fields - 1));
|
|
2085
|
+
|
|
2086
|
+
new_p->info_p = PyMem_RawMalloc(info_size);
|
|
2087
|
+
|
|
2088
|
+
if (new_p->info_p == NULL) {
|
|
2089
|
+
/* ToDo: Free new_p. */
|
|
2090
|
+
return (NULL);
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
memcpy(new_p->info_p, self_p->info_p, info_size);
|
|
2094
|
+
Py_INCREF(self_p->format_p);
|
|
2095
|
+
new_p->format_p = self_p->format_p;
|
|
2096
|
+
|
|
2097
|
+
return ((PyObject *)new_p);
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
static PyObject *m_compiled_format_deepcopy(struct compiled_format_t *self_p,
|
|
2101
|
+
PyObject *args_p)
|
|
2102
|
+
{
|
|
2103
|
+
return (m_compiled_format_copy(self_p));
|
|
2104
|
+
}
|
|
2105
|
+
|
|
2106
|
+
static PyObject *m_compiled_format_getstate(struct compiled_format_t *self_p,
|
|
2107
|
+
PyObject *args_p)
|
|
2108
|
+
{
|
|
2109
|
+
return (Py_BuildValue("{sOsi}",
|
|
2110
|
+
"format",
|
|
2111
|
+
self_p->format_p,
|
|
2112
|
+
pickle_version_key,
|
|
2113
|
+
pickle_version));
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
static PyObject *m_compiled_format_setstate(struct compiled_format_t *self_p,
|
|
2117
|
+
PyObject *state_p)
|
|
2118
|
+
{
|
|
2119
|
+
PyObject *version_p;
|
|
2120
|
+
int version;
|
|
2121
|
+
PyObject *format_p;
|
|
2122
|
+
|
|
2123
|
+
if (!PyDict_CheckExact(state_p)) {
|
|
2124
|
+
PyErr_SetString(PyExc_ValueError, "Pickled object is not a dict.");
|
|
2125
|
+
|
|
2126
|
+
return (NULL);
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
version_p = PyDict_GetItemString(state_p, pickle_version_key);
|
|
2130
|
+
|
|
2131
|
+
if (version_p == NULL) {
|
|
2132
|
+
PyErr_Format(PyExc_KeyError,
|
|
2133
|
+
"No \"%s\" in pickled dict.",
|
|
2134
|
+
pickle_version_key);
|
|
2135
|
+
|
|
2136
|
+
return (NULL);
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
version = (int)PyLong_AsLong(version_p);
|
|
2140
|
+
|
|
2141
|
+
if (version != pickle_version) {
|
|
2142
|
+
PyErr_Format(PyExc_ValueError,
|
|
2143
|
+
"Pickle version mismatch. Got version %d but expected version %d.",
|
|
2144
|
+
version, pickle_version);
|
|
2145
|
+
|
|
2146
|
+
return (NULL);
|
|
2147
|
+
}
|
|
2148
|
+
|
|
2149
|
+
format_p = PyDict_GetItemString(state_p, "format");
|
|
2150
|
+
|
|
2151
|
+
if (format_p == NULL) {
|
|
2152
|
+
PyErr_SetString(PyExc_KeyError, "No \"format\" in pickled dict.");
|
|
2153
|
+
|
|
2154
|
+
return (NULL);
|
|
2155
|
+
}
|
|
2156
|
+
|
|
2157
|
+
if (compiled_format_init_inner(self_p, format_p) != 0) {
|
|
2158
|
+
return (NULL);
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
Py_RETURN_NONE;
|
|
2162
|
+
}
|
|
2163
|
+
|
|
2164
|
+
static PyObject *compiled_format_dict_create(PyTypeObject *type_p,
|
|
2165
|
+
PyObject *format_p,
|
|
2166
|
+
PyObject *names_p)
|
|
2167
|
+
{
|
|
2168
|
+
PyObject *self_p;
|
|
2169
|
+
|
|
2170
|
+
self_p = compiled_format_dict_new(type_p, NULL, NULL);
|
|
2171
|
+
|
|
2172
|
+
if (self_p == NULL) {
|
|
2173
|
+
return (NULL);
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2176
|
+
if (compiled_format_dict_init_inner((struct compiled_format_dict_t *)self_p,
|
|
2177
|
+
format_p,
|
|
2178
|
+
names_p) != 0) {
|
|
2179
|
+
return (NULL);
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2182
|
+
return (self_p);
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
static PyObject *compiled_format_dict_new(PyTypeObject *type_p,
|
|
2186
|
+
PyObject *args_p,
|
|
2187
|
+
PyObject *kwargs_p)
|
|
2188
|
+
{
|
|
2189
|
+
return (type_p->tp_alloc(type_p, 0));
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
static int compiled_format_dict_init(struct compiled_format_dict_t *self_p,
|
|
2193
|
+
PyObject *args_p,
|
|
2194
|
+
PyObject *kwargs_p)
|
|
2195
|
+
{
|
|
2196
|
+
int res;
|
|
2197
|
+
PyObject *format_p;
|
|
2198
|
+
PyObject *names_p;
|
|
2199
|
+
static char *keywords[] = {
|
|
2200
|
+
"fmt",
|
|
2201
|
+
"names",
|
|
2202
|
+
NULL
|
|
2203
|
+
};
|
|
2204
|
+
|
|
2205
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
2206
|
+
kwargs_p,
|
|
2207
|
+
"OO",
|
|
2208
|
+
&keywords[0],
|
|
2209
|
+
&format_p,
|
|
2210
|
+
&names_p);
|
|
2211
|
+
|
|
2212
|
+
if (res == 0) {
|
|
2213
|
+
return (-1);
|
|
2214
|
+
}
|
|
2215
|
+
|
|
2216
|
+
return (compiled_format_dict_init_inner(self_p, format_p, names_p));
|
|
2217
|
+
}
|
|
2218
|
+
|
|
2219
|
+
static int compiled_format_dict_init_inner(struct compiled_format_dict_t *self_p,
|
|
2220
|
+
PyObject *format_p,
|
|
2221
|
+
PyObject *names_p)
|
|
2222
|
+
{
|
|
2223
|
+
if (!is_names_list(names_p)) {
|
|
2224
|
+
return (-1);
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2227
|
+
self_p->info_p = parse_format(format_p);
|
|
2228
|
+
|
|
2229
|
+
if (self_p->info_p == NULL) {
|
|
2230
|
+
PyObject_Free(self_p);
|
|
2231
|
+
|
|
2232
|
+
return (-1);
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2235
|
+
Py_INCREF(format_p);
|
|
2236
|
+
self_p->format_p = format_p;
|
|
2237
|
+
Py_INCREF(names_p);
|
|
2238
|
+
self_p->names_p = names_p;
|
|
2239
|
+
|
|
2240
|
+
return (0);
|
|
2241
|
+
}
|
|
2242
|
+
|
|
2243
|
+
static void compiled_format_dict_dealloc(struct compiled_format_dict_t *self_p)
|
|
2244
|
+
{
|
|
2245
|
+
PyMem_RawFree(self_p->info_p);
|
|
2246
|
+
Py_DECREF(self_p->names_p);
|
|
2247
|
+
Py_DECREF(self_p->format_p);
|
|
2248
|
+
Py_TYPE(self_p)->tp_free((PyObject *)self_p);
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2251
|
+
static PyObject *m_compiled_format_dict_pack(struct compiled_format_dict_t *self_p,
|
|
2252
|
+
PyObject *data_p)
|
|
2253
|
+
{
|
|
2254
|
+
return (pack_dict(self_p->info_p, self_p->names_p, data_p));
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2257
|
+
static PyObject *m_compiled_format_dict_unpack(
|
|
2258
|
+
struct compiled_format_dict_t *self_p,
|
|
2259
|
+
PyObject *args_p,
|
|
2260
|
+
PyObject *kwargs_p)
|
|
2261
|
+
{
|
|
2262
|
+
PyObject *data_p;
|
|
2263
|
+
PyObject *allow_truncated_p;
|
|
2264
|
+
int res;
|
|
2265
|
+
static char *keywords[] = {
|
|
2266
|
+
"data",
|
|
2267
|
+
"allow_truncated",
|
|
2268
|
+
NULL
|
|
2269
|
+
};
|
|
2270
|
+
|
|
2271
|
+
allow_truncated_p = py_zero_p;
|
|
2272
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
2273
|
+
kwargs_p,
|
|
2274
|
+
"O|O",
|
|
2275
|
+
&keywords[0],
|
|
2276
|
+
&data_p,
|
|
2277
|
+
&allow_truncated_p);
|
|
2278
|
+
|
|
2279
|
+
if (res == 0) {
|
|
2280
|
+
return (NULL);
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2283
|
+
return (unpack_dict(self_p->info_p, self_p->names_p, data_p, 0, allow_truncated_p));
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
static PyObject *m_compiled_format_dict_pack_into(
|
|
2287
|
+
struct compiled_format_dict_t *self_p,
|
|
2288
|
+
PyObject *args_p,
|
|
2289
|
+
PyObject *kwargs_p)
|
|
2290
|
+
{
|
|
2291
|
+
PyObject *buf_p;
|
|
2292
|
+
PyObject *data_p;
|
|
2293
|
+
PyObject *offset_p;
|
|
2294
|
+
int res;
|
|
2295
|
+
static char *keywords[] = {
|
|
2296
|
+
"buf",
|
|
2297
|
+
"data",
|
|
2298
|
+
"offset",
|
|
2299
|
+
NULL
|
|
2300
|
+
};
|
|
2301
|
+
|
|
2302
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
2303
|
+
kwargs_p,
|
|
2304
|
+
"OOO",
|
|
2305
|
+
&keywords[0],
|
|
2306
|
+
&buf_p,
|
|
2307
|
+
&data_p,
|
|
2308
|
+
&offset_p);
|
|
2309
|
+
|
|
2310
|
+
if (res == 0) {
|
|
2311
|
+
return (NULL);
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
return (pack_into_dict(self_p->info_p,
|
|
2315
|
+
self_p->names_p,
|
|
2316
|
+
buf_p,
|
|
2317
|
+
data_p,
|
|
2318
|
+
offset_p));
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
static PyObject *m_compiled_format_dict_unpack_from(
|
|
2322
|
+
struct compiled_format_dict_t *self_p,
|
|
2323
|
+
PyObject *args_p,
|
|
2324
|
+
PyObject *kwargs_p)
|
|
2325
|
+
{
|
|
2326
|
+
PyObject *data_p;
|
|
2327
|
+
PyObject *offset_p;
|
|
2328
|
+
PyObject *allow_truncated_p;
|
|
2329
|
+
int res;
|
|
2330
|
+
static char *keywords[] = {
|
|
2331
|
+
"data",
|
|
2332
|
+
"offset",
|
|
2333
|
+
NULL
|
|
2334
|
+
};
|
|
2335
|
+
|
|
2336
|
+
offset_p = py_zero_p;
|
|
2337
|
+
allow_truncated_p = py_zero_p;
|
|
2338
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
2339
|
+
kwargs_p,
|
|
2340
|
+
"O|OO",
|
|
2341
|
+
&keywords[0],
|
|
2342
|
+
&data_p,
|
|
2343
|
+
&offset_p,
|
|
2344
|
+
&allow_truncated_p);
|
|
2345
|
+
|
|
2346
|
+
if (res == 0) {
|
|
2347
|
+
return (NULL);
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
return (unpack_from_dict(self_p->info_p,
|
|
2351
|
+
self_p->names_p,
|
|
2352
|
+
data_p,
|
|
2353
|
+
offset_p,
|
|
2354
|
+
allow_truncated_p));
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
static PyObject *m_compiled_format_dict_calcsize(
|
|
2358
|
+
struct compiled_format_dict_t *self_p)
|
|
2359
|
+
{
|
|
2360
|
+
return (calcsize(self_p->info_p));
|
|
2361
|
+
}
|
|
2362
|
+
|
|
2363
|
+
static PyObject *m_compiled_format_dict_copy(struct compiled_format_dict_t *self_p)
|
|
2364
|
+
{
|
|
2365
|
+
struct compiled_format_dict_t *new_p;
|
|
2366
|
+
size_t info_size;
|
|
2367
|
+
|
|
2368
|
+
new_p = (struct compiled_format_dict_t *)compiled_format_dict_new(
|
|
2369
|
+
&compiled_format_dict_type,
|
|
2370
|
+
NULL,
|
|
2371
|
+
NULL);
|
|
2372
|
+
|
|
2373
|
+
if (new_p == NULL) {
|
|
2374
|
+
return (NULL);
|
|
2375
|
+
}
|
|
2376
|
+
|
|
2377
|
+
info_size = sizeof(*self_p->info_p);
|
|
2378
|
+
info_size += (sizeof(self_p->info_p->fields[0])
|
|
2379
|
+
* (self_p->info_p->number_of_fields - 1));
|
|
2380
|
+
|
|
2381
|
+
new_p->info_p = PyMem_RawMalloc(info_size);
|
|
2382
|
+
|
|
2383
|
+
if (new_p->info_p == NULL) {
|
|
2384
|
+
/* ToDo: Free new_p. */
|
|
2385
|
+
return (NULL);
|
|
2386
|
+
}
|
|
2387
|
+
|
|
2388
|
+
memcpy(new_p->info_p, self_p->info_p, info_size);
|
|
2389
|
+
Py_INCREF(self_p->names_p);
|
|
2390
|
+
new_p->names_p = self_p->names_p;
|
|
2391
|
+
Py_INCREF(self_p->format_p);
|
|
2392
|
+
new_p->format_p = self_p->format_p;
|
|
2393
|
+
|
|
2394
|
+
return ((PyObject *)new_p);
|
|
2395
|
+
}
|
|
2396
|
+
|
|
2397
|
+
static PyObject *m_compiled_format_dict_deepcopy(struct compiled_format_dict_t *self_p,
|
|
2398
|
+
PyObject *args_p)
|
|
2399
|
+
{
|
|
2400
|
+
return (m_compiled_format_dict_copy(self_p));
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
PyDoc_STRVAR(compile___doc__,
|
|
2404
|
+
"compile(fmt, names=None)\n"
|
|
2405
|
+
"--\n"
|
|
2406
|
+
"\n");
|
|
2407
|
+
|
|
2408
|
+
static PyObject *m_compiled_format_dict_getstate(struct compiled_format_dict_t *self_p,
|
|
2409
|
+
PyObject *args_p)
|
|
2410
|
+
{
|
|
2411
|
+
return (Py_BuildValue("{sOsOsi}",
|
|
2412
|
+
"format",
|
|
2413
|
+
self_p->format_p,
|
|
2414
|
+
"names",
|
|
2415
|
+
self_p->names_p,
|
|
2416
|
+
pickle_version_key,
|
|
2417
|
+
pickle_version));
|
|
2418
|
+
}
|
|
2419
|
+
|
|
2420
|
+
static PyObject *m_compiled_format_dict_setstate(struct compiled_format_dict_t *self_p,
|
|
2421
|
+
PyObject *state_p)
|
|
2422
|
+
{
|
|
2423
|
+
PyObject *version_p;
|
|
2424
|
+
int version;
|
|
2425
|
+
PyObject *format_p;
|
|
2426
|
+
PyObject *names_p;
|
|
2427
|
+
|
|
2428
|
+
if (!PyDict_CheckExact(state_p)) {
|
|
2429
|
+
PyErr_SetString(PyExc_ValueError, "Pickled object is not a dict.");
|
|
2430
|
+
|
|
2431
|
+
return (NULL);
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
version_p = PyDict_GetItemString(state_p, pickle_version_key);
|
|
2435
|
+
|
|
2436
|
+
if (version_p == NULL) {
|
|
2437
|
+
PyErr_Format(PyExc_KeyError,
|
|
2438
|
+
"No \"%s\" in pickled dict.",
|
|
2439
|
+
pickle_version_key);
|
|
2440
|
+
|
|
2441
|
+
return (NULL);
|
|
2442
|
+
}
|
|
2443
|
+
|
|
2444
|
+
version = (int)PyLong_AsLong(version_p);
|
|
2445
|
+
|
|
2446
|
+
if (version != pickle_version) {
|
|
2447
|
+
PyErr_Format(PyExc_ValueError,
|
|
2448
|
+
"Pickle version mismatch. Got version %d but expected version %d.",
|
|
2449
|
+
version, pickle_version);
|
|
2450
|
+
|
|
2451
|
+
return (NULL);
|
|
2452
|
+
}
|
|
2453
|
+
|
|
2454
|
+
format_p = PyDict_GetItemString(state_p, "format");
|
|
2455
|
+
|
|
2456
|
+
if (format_p == NULL) {
|
|
2457
|
+
PyErr_SetString(PyExc_KeyError, "No \"format\" in pickled dict.");
|
|
2458
|
+
|
|
2459
|
+
return (NULL);
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
names_p = PyDict_GetItemString(state_p, "names");
|
|
2463
|
+
|
|
2464
|
+
if (names_p == NULL) {
|
|
2465
|
+
PyErr_SetString(PyExc_KeyError, "No \"names\" in pickled dict.");
|
|
2466
|
+
|
|
2467
|
+
return (NULL);
|
|
2468
|
+
}
|
|
2469
|
+
|
|
2470
|
+
if (compiled_format_dict_init_inner(self_p, format_p, names_p) != 0) {
|
|
2471
|
+
return (NULL);
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
Py_RETURN_NONE;
|
|
2475
|
+
}
|
|
2476
|
+
|
|
2477
|
+
static PyObject *m_compile(PyObject *module_p,
|
|
2478
|
+
PyObject *args_p,
|
|
2479
|
+
PyObject *kwargs_p)
|
|
2480
|
+
{
|
|
2481
|
+
PyObject *format_p;
|
|
2482
|
+
PyObject *names_p;
|
|
2483
|
+
int res;
|
|
2484
|
+
static char *keywords[] = {
|
|
2485
|
+
"fmt",
|
|
2486
|
+
"names",
|
|
2487
|
+
NULL
|
|
2488
|
+
};
|
|
2489
|
+
|
|
2490
|
+
names_p = Py_None;
|
|
2491
|
+
res = PyArg_ParseTupleAndKeywords(args_p,
|
|
2492
|
+
kwargs_p,
|
|
2493
|
+
"O|O",
|
|
2494
|
+
&keywords[0],
|
|
2495
|
+
&format_p,
|
|
2496
|
+
&names_p);
|
|
2497
|
+
|
|
2498
|
+
if (res == 0) {
|
|
2499
|
+
return (NULL);
|
|
2500
|
+
}
|
|
2501
|
+
|
|
2502
|
+
if (names_p == Py_None) {
|
|
2503
|
+
return (compiled_format_create(&compiled_format_type, format_p));
|
|
2504
|
+
} else {
|
|
2505
|
+
return (compiled_format_dict_create(&compiled_format_dict_type,
|
|
2506
|
+
format_p,
|
|
2507
|
+
names_p));
|
|
2508
|
+
}
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
static struct PyMethodDef methods[] = {
|
|
2512
|
+
{
|
|
2513
|
+
"pack",
|
|
2514
|
+
m_pack,
|
|
2515
|
+
METH_VARARGS,
|
|
2516
|
+
pack___doc__
|
|
2517
|
+
},
|
|
2518
|
+
{
|
|
2519
|
+
"unpack",
|
|
2520
|
+
(PyCFunction)m_unpack,
|
|
2521
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
2522
|
+
unpack___doc__
|
|
2523
|
+
},
|
|
2524
|
+
{
|
|
2525
|
+
"pack_into",
|
|
2526
|
+
(PyCFunction)m_pack_into,
|
|
2527
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
2528
|
+
pack_into___doc__
|
|
2529
|
+
},
|
|
2530
|
+
{
|
|
2531
|
+
"unpack_from",
|
|
2532
|
+
(PyCFunction)m_unpack_from,
|
|
2533
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
2534
|
+
unpack_from___doc__
|
|
2535
|
+
},
|
|
2536
|
+
{
|
|
2537
|
+
"pack_dict",
|
|
2538
|
+
m_pack_dict,
|
|
2539
|
+
METH_VARARGS,
|
|
2540
|
+
pack_dict___doc__
|
|
2541
|
+
},
|
|
2542
|
+
{
|
|
2543
|
+
"unpack_dict",
|
|
2544
|
+
(PyCFunction)m_unpack_dict,
|
|
2545
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
2546
|
+
unpack_dict___doc__
|
|
2547
|
+
},
|
|
2548
|
+
{
|
|
2549
|
+
"pack_into_dict",
|
|
2550
|
+
(PyCFunction)m_pack_into_dict,
|
|
2551
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
2552
|
+
pack_into_dict___doc__
|
|
2553
|
+
},
|
|
2554
|
+
{
|
|
2555
|
+
"unpack_from_dict",
|
|
2556
|
+
(PyCFunction)m_unpack_from_dict,
|
|
2557
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
2558
|
+
unpack_from_dict___doc__
|
|
2559
|
+
},
|
|
2560
|
+
{
|
|
2561
|
+
"calcsize",
|
|
2562
|
+
m_calcsize,
|
|
2563
|
+
METH_O,
|
|
2564
|
+
calcsize___doc__
|
|
2565
|
+
},
|
|
2566
|
+
{
|
|
2567
|
+
"byteswap",
|
|
2568
|
+
(PyCFunction)m_byteswap,
|
|
2569
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
2570
|
+
byteswap___doc__
|
|
2571
|
+
},
|
|
2572
|
+
{
|
|
2573
|
+
"compile",
|
|
2574
|
+
(PyCFunction)m_compile,
|
|
2575
|
+
METH_VARARGS | METH_KEYWORDS,
|
|
2576
|
+
compile___doc__
|
|
2577
|
+
},
|
|
2578
|
+
{ NULL }
|
|
2579
|
+
};
|
|
2580
|
+
|
|
2581
|
+
static PyModuleDef module = {
|
|
2582
|
+
PyModuleDef_HEAD_INIT,
|
|
2583
|
+
.m_name = "bitstruct.c",
|
|
2584
|
+
.m_doc = "bitstruct C extension",
|
|
2585
|
+
.m_size = -1,
|
|
2586
|
+
.m_methods = methods
|
|
2587
|
+
};
|
|
2588
|
+
|
|
2589
|
+
PyMODINIT_FUNC PyInit_c(void)
|
|
2590
|
+
{
|
|
2591
|
+
PyObject *module_p;
|
|
2592
|
+
|
|
2593
|
+
if (PyType_Ready(&compiled_format_type) < 0) {
|
|
2594
|
+
return (NULL);
|
|
2595
|
+
}
|
|
2596
|
+
|
|
2597
|
+
if (PyType_Ready(&compiled_format_dict_type) < 0) {
|
|
2598
|
+
return (NULL);
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2601
|
+
py_zero_p = PyLong_FromLong(0);
|
|
2602
|
+
module_p = PyModule_Create(&module);
|
|
2603
|
+
|
|
2604
|
+
if (module_p == NULL) {
|
|
2605
|
+
return (NULL);
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
Py_INCREF(&compiled_format_type);
|
|
2609
|
+
|
|
2610
|
+
if (PyModule_AddObject(module_p,
|
|
2611
|
+
"CompiledFormat",
|
|
2612
|
+
(PyObject *)&compiled_format_type) < 0) {
|
|
2613
|
+
Py_DECREF(&compiled_format_type);
|
|
2614
|
+
Py_DECREF(module_p);
|
|
2615
|
+
|
|
2616
|
+
return (NULL);
|
|
2617
|
+
}
|
|
2618
|
+
|
|
2619
|
+
if (PyModule_AddObject(module_p,
|
|
2620
|
+
"CompiledFormatDict",
|
|
2621
|
+
(PyObject *)&compiled_format_dict_type) < 0) {
|
|
2622
|
+
Py_DECREF(&compiled_format_dict_type);
|
|
2623
|
+
Py_DECREF(module_p);
|
|
2624
|
+
|
|
2625
|
+
return (NULL);
|
|
2626
|
+
}
|
|
2627
|
+
|
|
2628
|
+
return (module_p);
|
|
2629
|
+
}
|