• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*[clinic input]
2 preserve
3 [clinic start generated code]*/
4 
5 #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
6 #  include "pycore_gc.h"          // PyGC_Head
7 #  include "pycore_runtime.h"     // _Py_ID()
8 #endif
9 #include "pycore_abstract.h"      // _PyNumber_Index()
10 #include "pycore_modsupport.h"    // _PyArg_UnpackKeywords()
11 
12 PyDoc_STRVAR(Struct___init____doc__,
13 "Struct(format)\n"
14 "--\n"
15 "\n"
16 "Create a compiled struct object.\n"
17 "\n"
18 "Return a new Struct object which writes and reads binary data according to\n"
19 "the format string.\n"
20 "\n"
21 "See help(struct) for more on format strings.");
22 
23 static int
24 Struct___init___impl(PyStructObject *self, PyObject *format);
25 
26 static int
Struct___init__(PyObject * self,PyObject * args,PyObject * kwargs)27 Struct___init__(PyObject *self, PyObject *args, PyObject *kwargs)
28 {
29     int return_value = -1;
30     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
31 
32     #define NUM_KEYWORDS 1
33     static struct {
34         PyGC_Head _this_is_not_used;
35         PyObject_VAR_HEAD
36         PyObject *ob_item[NUM_KEYWORDS];
37     } _kwtuple = {
38         .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
39         .ob_item = { &_Py_ID(format), },
40     };
41     #undef NUM_KEYWORDS
42     #define KWTUPLE (&_kwtuple.ob_base.ob_base)
43 
44     #else  // !Py_BUILD_CORE
45     #  define KWTUPLE NULL
46     #endif  // !Py_BUILD_CORE
47 
48     static const char * const _keywords[] = {"format", NULL};
49     static _PyArg_Parser _parser = {
50         .keywords = _keywords,
51         .fname = "Struct",
52         .kwtuple = KWTUPLE,
53     };
54     #undef KWTUPLE
55     PyObject *argsbuf[1];
56     PyObject * const *fastargs;
57     Py_ssize_t nargs = PyTuple_GET_SIZE(args);
58     PyObject *format;
59 
60     fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf);
61     if (!fastargs) {
62         goto exit;
63     }
64     format = fastargs[0];
65     return_value = Struct___init___impl((PyStructObject *)self, format);
66 
67 exit:
68     return return_value;
69 }
70 
71 PyDoc_STRVAR(Struct_unpack__doc__,
72 "unpack($self, buffer, /)\n"
73 "--\n"
74 "\n"
75 "Return a tuple containing unpacked values.\n"
76 "\n"
77 "Unpack according to the format string Struct.format. The buffer\'s size\n"
78 "in bytes must be Struct.size.\n"
79 "\n"
80 "See help(struct) for more on format strings.");
81 
82 #define STRUCT_UNPACK_METHODDEF    \
83     {"unpack", (PyCFunction)Struct_unpack, METH_O, Struct_unpack__doc__},
84 
85 static PyObject *
86 Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer);
87 
88 static PyObject *
Struct_unpack(PyStructObject * self,PyObject * arg)89 Struct_unpack(PyStructObject *self, PyObject *arg)
90 {
91     PyObject *return_value = NULL;
92     Py_buffer buffer = {NULL, NULL};
93 
94     if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) {
95         goto exit;
96     }
97     return_value = Struct_unpack_impl(self, &buffer);
98 
99 exit:
100     /* Cleanup for buffer */
101     if (buffer.obj) {
102        PyBuffer_Release(&buffer);
103     }
104 
105     return return_value;
106 }
107 
108 PyDoc_STRVAR(Struct_unpack_from__doc__,
109 "unpack_from($self, /, buffer, offset=0)\n"
110 "--\n"
111 "\n"
112 "Return a tuple containing unpacked values.\n"
113 "\n"
114 "Values are unpacked according to the format string Struct.format.\n"
115 "\n"
116 "The buffer\'s size in bytes, starting at position offset, must be\n"
117 "at least Struct.size.\n"
118 "\n"
119 "See help(struct) for more on format strings.");
120 
121 #define STRUCT_UNPACK_FROM_METHODDEF    \
122     {"unpack_from", _PyCFunction_CAST(Struct_unpack_from), METH_FASTCALL|METH_KEYWORDS, Struct_unpack_from__doc__},
123 
124 static PyObject *
125 Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer,
126                         Py_ssize_t offset);
127 
128 static PyObject *
Struct_unpack_from(PyStructObject * self,PyObject * const * args,Py_ssize_t nargs,PyObject * kwnames)129 Struct_unpack_from(PyStructObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
130 {
131     PyObject *return_value = NULL;
132     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
133 
134     #define NUM_KEYWORDS 2
135     static struct {
136         PyGC_Head _this_is_not_used;
137         PyObject_VAR_HEAD
138         PyObject *ob_item[NUM_KEYWORDS];
139     } _kwtuple = {
140         .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
141         .ob_item = { &_Py_ID(buffer), &_Py_ID(offset), },
142     };
143     #undef NUM_KEYWORDS
144     #define KWTUPLE (&_kwtuple.ob_base.ob_base)
145 
146     #else  // !Py_BUILD_CORE
147     #  define KWTUPLE NULL
148     #endif  // !Py_BUILD_CORE
149 
150     static const char * const _keywords[] = {"buffer", "offset", NULL};
151     static _PyArg_Parser _parser = {
152         .keywords = _keywords,
153         .fname = "unpack_from",
154         .kwtuple = KWTUPLE,
155     };
156     #undef KWTUPLE
157     PyObject *argsbuf[2];
158     Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
159     Py_buffer buffer = {NULL, NULL};
160     Py_ssize_t offset = 0;
161 
162     args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 2, 0, argsbuf);
163     if (!args) {
164         goto exit;
165     }
166     if (PyObject_GetBuffer(args[0], &buffer, PyBUF_SIMPLE) != 0) {
167         goto exit;
168     }
169     if (!noptargs) {
170         goto skip_optional_pos;
171     }
172     {
173         Py_ssize_t ival = -1;
174         PyObject *iobj = _PyNumber_Index(args[1]);
175         if (iobj != NULL) {
176             ival = PyLong_AsSsize_t(iobj);
177             Py_DECREF(iobj);
178         }
179         if (ival == -1 && PyErr_Occurred()) {
180             goto exit;
181         }
182         offset = ival;
183     }
184 skip_optional_pos:
185     return_value = Struct_unpack_from_impl(self, &buffer, offset);
186 
187 exit:
188     /* Cleanup for buffer */
189     if (buffer.obj) {
190        PyBuffer_Release(&buffer);
191     }
192 
193     return return_value;
194 }
195 
196 PyDoc_STRVAR(Struct_iter_unpack__doc__,
197 "iter_unpack($self, buffer, /)\n"
198 "--\n"
199 "\n"
200 "Return an iterator yielding tuples.\n"
201 "\n"
202 "Tuples are unpacked from the given bytes source, like a repeated\n"
203 "invocation of unpack_from().\n"
204 "\n"
205 "Requires that the bytes length be a multiple of the struct size.");
206 
207 #define STRUCT_ITER_UNPACK_METHODDEF    \
208     {"iter_unpack", (PyCFunction)Struct_iter_unpack, METH_O, Struct_iter_unpack__doc__},
209 
210 PyDoc_STRVAR(_clearcache__doc__,
211 "_clearcache($module, /)\n"
212 "--\n"
213 "\n"
214 "Clear the internal cache.");
215 
216 #define _CLEARCACHE_METHODDEF    \
217     {"_clearcache", (PyCFunction)_clearcache, METH_NOARGS, _clearcache__doc__},
218 
219 static PyObject *
220 _clearcache_impl(PyObject *module);
221 
222 static PyObject *
_clearcache(PyObject * module,PyObject * Py_UNUSED (ignored))223 _clearcache(PyObject *module, PyObject *Py_UNUSED(ignored))
224 {
225     return _clearcache_impl(module);
226 }
227 
228 PyDoc_STRVAR(calcsize__doc__,
229 "calcsize($module, format, /)\n"
230 "--\n"
231 "\n"
232 "Return size in bytes of the struct described by the format string.");
233 
234 #define CALCSIZE_METHODDEF    \
235     {"calcsize", (PyCFunction)calcsize, METH_O, calcsize__doc__},
236 
237 static Py_ssize_t
238 calcsize_impl(PyObject *module, PyStructObject *s_object);
239 
240 static PyObject *
calcsize(PyObject * module,PyObject * arg)241 calcsize(PyObject *module, PyObject *arg)
242 {
243     PyObject *return_value = NULL;
244     PyStructObject *s_object = NULL;
245     Py_ssize_t _return_value;
246 
247     if (!cache_struct_converter(module, arg, &s_object)) {
248         goto exit;
249     }
250     _return_value = calcsize_impl(module, s_object);
251     if ((_return_value == -1) && PyErr_Occurred()) {
252         goto exit;
253     }
254     return_value = PyLong_FromSsize_t(_return_value);
255 
256 exit:
257     /* Cleanup for s_object */
258     Py_XDECREF(s_object);
259 
260     return return_value;
261 }
262 
263 PyDoc_STRVAR(unpack__doc__,
264 "unpack($module, format, buffer, /)\n"
265 "--\n"
266 "\n"
267 "Return a tuple containing values unpacked according to the format string.\n"
268 "\n"
269 "The buffer\'s size in bytes must be calcsize(format).\n"
270 "\n"
271 "See help(struct) for more on format strings.");
272 
273 #define UNPACK_METHODDEF    \
274     {"unpack", _PyCFunction_CAST(unpack), METH_FASTCALL, unpack__doc__},
275 
276 static PyObject *
277 unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer);
278 
279 static PyObject *
unpack(PyObject * module,PyObject * const * args,Py_ssize_t nargs)280 unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
281 {
282     PyObject *return_value = NULL;
283     PyStructObject *s_object = NULL;
284     Py_buffer buffer = {NULL, NULL};
285 
286     if (!_PyArg_CheckPositional("unpack", nargs, 2, 2)) {
287         goto exit;
288     }
289     if (!cache_struct_converter(module, args[0], &s_object)) {
290         goto exit;
291     }
292     if (PyObject_GetBuffer(args[1], &buffer, PyBUF_SIMPLE) != 0) {
293         goto exit;
294     }
295     return_value = unpack_impl(module, s_object, &buffer);
296 
297 exit:
298     /* Cleanup for s_object */
299     Py_XDECREF(s_object);
300     /* Cleanup for buffer */
301     if (buffer.obj) {
302        PyBuffer_Release(&buffer);
303     }
304 
305     return return_value;
306 }
307 
308 PyDoc_STRVAR(unpack_from__doc__,
309 "unpack_from($module, format, /, buffer, offset=0)\n"
310 "--\n"
311 "\n"
312 "Return a tuple containing values unpacked according to the format string.\n"
313 "\n"
314 "The buffer\'s size, minus offset, must be at least calcsize(format).\n"
315 "\n"
316 "See help(struct) for more on format strings.");
317 
318 #define UNPACK_FROM_METHODDEF    \
319     {"unpack_from", _PyCFunction_CAST(unpack_from), METH_FASTCALL|METH_KEYWORDS, unpack_from__doc__},
320 
321 static PyObject *
322 unpack_from_impl(PyObject *module, PyStructObject *s_object,
323                  Py_buffer *buffer, Py_ssize_t offset);
324 
325 static PyObject *
unpack_from(PyObject * module,PyObject * const * args,Py_ssize_t nargs,PyObject * kwnames)326 unpack_from(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
327 {
328     PyObject *return_value = NULL;
329     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
330 
331     #define NUM_KEYWORDS 2
332     static struct {
333         PyGC_Head _this_is_not_used;
334         PyObject_VAR_HEAD
335         PyObject *ob_item[NUM_KEYWORDS];
336     } _kwtuple = {
337         .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
338         .ob_item = { &_Py_ID(buffer), &_Py_ID(offset), },
339     };
340     #undef NUM_KEYWORDS
341     #define KWTUPLE (&_kwtuple.ob_base.ob_base)
342 
343     #else  // !Py_BUILD_CORE
344     #  define KWTUPLE NULL
345     #endif  // !Py_BUILD_CORE
346 
347     static const char * const _keywords[] = {"", "buffer", "offset", NULL};
348     static _PyArg_Parser _parser = {
349         .keywords = _keywords,
350         .fname = "unpack_from",
351         .kwtuple = KWTUPLE,
352     };
353     #undef KWTUPLE
354     PyObject *argsbuf[3];
355     Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
356     PyStructObject *s_object = NULL;
357     Py_buffer buffer = {NULL, NULL};
358     Py_ssize_t offset = 0;
359 
360     args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 3, 0, argsbuf);
361     if (!args) {
362         goto exit;
363     }
364     if (!cache_struct_converter(module, args[0], &s_object)) {
365         goto exit;
366     }
367     if (PyObject_GetBuffer(args[1], &buffer, PyBUF_SIMPLE) != 0) {
368         goto exit;
369     }
370     if (!noptargs) {
371         goto skip_optional_pos;
372     }
373     {
374         Py_ssize_t ival = -1;
375         PyObject *iobj = _PyNumber_Index(args[2]);
376         if (iobj != NULL) {
377             ival = PyLong_AsSsize_t(iobj);
378             Py_DECREF(iobj);
379         }
380         if (ival == -1 && PyErr_Occurred()) {
381             goto exit;
382         }
383         offset = ival;
384     }
385 skip_optional_pos:
386     return_value = unpack_from_impl(module, s_object, &buffer, offset);
387 
388 exit:
389     /* Cleanup for s_object */
390     Py_XDECREF(s_object);
391     /* Cleanup for buffer */
392     if (buffer.obj) {
393        PyBuffer_Release(&buffer);
394     }
395 
396     return return_value;
397 }
398 
399 PyDoc_STRVAR(iter_unpack__doc__,
400 "iter_unpack($module, format, buffer, /)\n"
401 "--\n"
402 "\n"
403 "Return an iterator yielding tuples unpacked from the given bytes.\n"
404 "\n"
405 "The bytes are unpacked according to the format string, like\n"
406 "a repeated invocation of unpack_from().\n"
407 "\n"
408 "Requires that the bytes length be a multiple of the format struct size.");
409 
410 #define ITER_UNPACK_METHODDEF    \
411     {"iter_unpack", _PyCFunction_CAST(iter_unpack), METH_FASTCALL, iter_unpack__doc__},
412 
413 static PyObject *
414 iter_unpack_impl(PyObject *module, PyStructObject *s_object,
415                  PyObject *buffer);
416 
417 static PyObject *
iter_unpack(PyObject * module,PyObject * const * args,Py_ssize_t nargs)418 iter_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
419 {
420     PyObject *return_value = NULL;
421     PyStructObject *s_object = NULL;
422     PyObject *buffer;
423 
424     if (!_PyArg_CheckPositional("iter_unpack", nargs, 2, 2)) {
425         goto exit;
426     }
427     if (!cache_struct_converter(module, args[0], &s_object)) {
428         goto exit;
429     }
430     buffer = args[1];
431     return_value = iter_unpack_impl(module, s_object, buffer);
432 
433 exit:
434     /* Cleanup for s_object */
435     Py_XDECREF(s_object);
436 
437     return return_value;
438 }
439 /*[clinic end generated code: output=67bd299e5d72fee0 input=a9049054013a1b77]*/
440