diff options
Diffstat (limited to 'Modules/_struct.c')
-rw-r--r-- | Modules/_struct.c | 479 |
1 files changed, 251 insertions, 228 deletions
diff --git a/Modules/_struct.c b/Modules/_struct.c index 796d1682f0..78cd0f3401 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -9,6 +9,11 @@ #include "structmember.h" #include <ctype.h> +/*[clinic input] +class Struct "PyStructObject *" "&PyStructType" +[clinic start generated code]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9b032058a83ed7c3]*/ + static PyTypeObject PyStructType; /* The translation function for each format character is table driven */ @@ -80,6 +85,8 @@ typedef struct { char c; long long x; } s_long_long; #pragma options align=reset #endif +#include "clinic/_struct.c.h" + /* Helper for integer format codes: converts an arbitrary Python object to a PyLongObject if possible, otherwise fails. Caller should decref. */ @@ -1429,41 +1436,46 @@ s_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return self; } +/*[clinic input] +Struct.__init__ + + format: object + +Create a compiled struct object. + +Return a new Struct object which writes and reads binary data according to +the format string. + +See help(struct) for more on format strings. +[clinic start generated code]*/ + static int -s_init(PyObject *self, PyObject *args, PyObject *kwds) +Struct___init___impl(PyStructObject *self, PyObject *format) +/*[clinic end generated code: output=b8e80862444e92d0 input=192a4575a3dde802]*/ { - PyStructObject *soself = (PyStructObject *)self; - PyObject *o_format = NULL; int ret = 0; - static char *kwlist[] = {"format", 0}; - - assert(PyStruct_Check(self)); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Struct", kwlist, - &o_format)) - return -1; - - if (PyUnicode_Check(o_format)) { - o_format = PyUnicode_AsASCIIString(o_format); - if (o_format == NULL) + if (PyUnicode_Check(format)) { + format = PyUnicode_AsASCIIString(format); + if (format == NULL) return -1; } /* XXX support buffer interface, too */ else { - Py_INCREF(o_format); + Py_INCREF(format); } - if (!PyBytes_Check(o_format)) { - Py_DECREF(o_format); + if (!PyBytes_Check(format)) { + Py_DECREF(format); PyErr_Format(PyExc_TypeError, "Struct() argument 1 must be a bytes object, not %.200s", - Py_TYPE(o_format)->tp_name); + Py_TYPE(format)->tp_name); return -1; } - Py_XSETREF(soself->s_format, o_format); + Py_XSETREF(self->s_format, format); - ret = prepare_s(soself); + ret = prepare_s(self); return ret; } @@ -1517,78 +1529,69 @@ fail: } -PyDoc_STRVAR(s_unpack__doc__, -"S.unpack(buffer) -> (v1, v2, ...)\n\ -\n\ -Return a tuple containing values unpacked according to the format\n\ -string S.format. The buffer's size in bytes must be S.size. See\n\ -help(struct) for more on format strings."); +/*[clinic input] +Struct.unpack + + buffer: Py_buffer + / + +Return a tuple containing unpacked values. + +Unpack according to the format string Struct.format. The buffer's size +in bytes must be Struct.size. + +See help(struct) for more on format strings. +[clinic start generated code]*/ static PyObject * -s_unpack(PyObject *self, PyObject *input) +Struct_unpack_impl(PyStructObject *self, Py_buffer *buffer) +/*[clinic end generated code: output=873a24faf02e848a input=3113f8e7038b2f6c]*/ { - Py_buffer vbuf; - PyObject *result; - PyStructObject *soself = (PyStructObject *)self; - - assert(PyStruct_Check(self)); - assert(soself->s_codes != NULL); - if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0) - return NULL; - if (vbuf.len != soself->s_size) { + assert(self->s_codes != NULL); + if (buffer->len != self->s_size) { PyErr_Format(StructError, "unpack requires a bytes object of length %zd", - soself->s_size); - PyBuffer_Release(&vbuf); + self->s_size); return NULL; } - result = s_unpack_internal(soself, vbuf.buf); - PyBuffer_Release(&vbuf); - return result; + return s_unpack_internal(self, buffer->buf); } -PyDoc_STRVAR(s_unpack_from__doc__, -"S.unpack_from(buffer, offset=0) -> (v1, v2, ...)\n\ -\n\ -Return a tuple containing values unpacked according to the format\n\ -string S.format. The buffer's size in bytes, minus offset, must be at\n\ -least S.size. See help(struct) for more on format strings."); +/*[clinic input] +Struct.unpack_from -static PyObject * -s_unpack_from(PyObject *self, PyObject *args, PyObject *kwds) -{ - static char *kwlist[] = {"buffer", "offset", 0}; + buffer: Py_buffer + offset: Py_ssize_t = 0 - PyObject *input; - Py_ssize_t offset = 0; - Py_buffer vbuf; - PyObject *result; - PyStructObject *soself = (PyStructObject *)self; +Return a tuple containing unpacked values. - assert(PyStruct_Check(self)); - assert(soself->s_codes != NULL); +Values are unpacked according to the format string Struct.format. + +The buffer's size in bytes, minus offset, must be at least Struct.size. + +See help(struct) for more on format strings. +[clinic start generated code]*/ + +static PyObject * +Struct_unpack_from_impl(PyStructObject *self, Py_buffer *buffer, + Py_ssize_t offset) +/*[clinic end generated code: output=57fac875e0977316 input=97ade52422f8962f]*/ +{ + assert(self->s_codes != NULL); - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "O|n:unpack_from", kwlist, - &input, &offset)) - return NULL; - if (PyObject_GetBuffer(input, &vbuf, PyBUF_SIMPLE) < 0) - return NULL; if (offset < 0) - offset += vbuf.len; - if (offset < 0 || vbuf.len - offset < soself->s_size) { + offset += buffer->len; + if (offset < 0 || buffer->len - offset < self->s_size) { PyErr_Format(StructError, "unpack_from requires a buffer of at least %zd bytes", - soself->s_size); - PyBuffer_Release(&vbuf); + self->s_size); return NULL; } - result = s_unpack_internal(soself, (char*)vbuf.buf + offset); - PyBuffer_Release(&vbuf); - return result; + return s_unpack_internal(self, (char*)buffer->buf + offset); } + /* Unpack iterator type */ typedef struct { @@ -1650,7 +1653,7 @@ unpackiter_iternext(unpackiterobject *self) } static PyTypeObject unpackiter_type = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) + PyVarObject_HEAD_INIT(NULL, 0) "unpack_iterator", /* tp_name */ sizeof(unpackiterobject), /* tp_basicsize */ 0, /* tp_itemsize */ @@ -1680,48 +1683,54 @@ static PyTypeObject unpackiter_type = { unpackiter_methods /* tp_methods */ }; -PyDoc_STRVAR(s_iter_unpack__doc__, -"S.iter_unpack(buffer) -> iterator(v1, v2, ...)\n\ -\n\ -Return an iterator yielding tuples unpacked from the given bytes\n\ -source, like a repeated invocation of unpack_from(). Requires\n\ -that the bytes length be a multiple of the struct size."); +/*[clinic input] +Struct.iter_unpack + + buffer: object + / + +Return an iterator yielding tuples. + +Tuples are unpacked from the given bytes source, like a repeated +invocation of unpack_from(). + +Requires that the bytes length be a multiple of the struct size. +[clinic start generated code]*/ static PyObject * -s_iter_unpack(PyObject *_so, PyObject *input) +Struct_iter_unpack(PyStructObject *self, PyObject *buffer) +/*[clinic end generated code: output=172d83d0cd15dbab input=6d65b3f3107dbc99]*/ { - PyStructObject *so = (PyStructObject *) _so; - unpackiterobject *self; + unpackiterobject *iter; - assert(PyStruct_Check(_so)); - assert(so->s_codes != NULL); + assert(self->s_codes != NULL); - if (so->s_size == 0) { + if (self->s_size == 0) { PyErr_Format(StructError, "cannot iteratively unpack with a struct of length 0"); return NULL; } - self = (unpackiterobject *) PyType_GenericAlloc(&unpackiter_type, 0); - if (self == NULL) + iter = (unpackiterobject *) PyType_GenericAlloc(&unpackiter_type, 0); + if (iter == NULL) return NULL; - if (PyObject_GetBuffer(input, &self->buf, PyBUF_SIMPLE) < 0) { - Py_DECREF(self); + if (PyObject_GetBuffer(buffer, &iter->buf, PyBUF_SIMPLE) < 0) { + Py_DECREF(iter); return NULL; } - if (self->buf.len % so->s_size != 0) { + if (iter->buf.len % self->s_size != 0) { PyErr_Format(StructError, "iterative unpacking requires a bytes length " "multiple of %zd", - so->s_size); - Py_DECREF(self); + self->s_size); + Py_DECREF(iter); return NULL; } - Py_INCREF(so); - self->so = so; - self->index = 0; - return (PyObject *) self; + Py_INCREF(self); + iter->so = self; + iter->index = 0; + return (PyObject *)iter; } @@ -1736,7 +1745,7 @@ s_iter_unpack(PyObject *_so, PyObject *input) * */ static int -s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf) +s_pack_internal(PyStructObject *soself, PyObject **args, int offset, char* buf) { formatcode *code; /* XXX(nnorwitz): why does i need to be a local? can we use @@ -1750,7 +1759,7 @@ s_pack_internal(PyStructObject *soself, PyObject *args, int offset, char* buf) char *res = buf + code->offset; Py_ssize_t j = code->repeat; while (j--) { - PyObject *v = PyTuple_GET_ITEM(args, i++); + PyObject *v = args[i++]; if (e->format == 's') { Py_ssize_t n; int isstring; @@ -1823,7 +1832,7 @@ to the format string S.format. See help(struct) for more on format\n\ strings."); static PyObject * -s_pack(PyObject *self, PyObject *args) +s_pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyStructObject *soself; PyObject *result; @@ -1832,10 +1841,13 @@ s_pack(PyObject *self, PyObject *args) soself = (PyStructObject *)self; assert(PyStruct_Check(self)); assert(soself->s_codes != NULL); - if (PyTuple_GET_SIZE(args) != soself->s_len) + if (nargs != soself->s_len) { PyErr_Format(StructError, - "pack expected %zd items for packing (got %zd)", soself->s_len, PyTuple_GET_SIZE(args)); + "pack expected %zd items for packing (got %zd)", soself->s_len, nargs); + return NULL; + } + if (!_PyArg_NoStackKeywords("pack", kwnames)) { return NULL; } @@ -1862,7 +1874,7 @@ offset. Note that the offset is a required argument. See\n\ help(struct) for more on format strings."); static PyObject * -s_pack_into(PyObject *self, PyObject *args) +s_pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { PyStructObject *soself; Py_buffer buffer; @@ -1872,31 +1884,34 @@ s_pack_into(PyObject *self, PyObject *args) soself = (PyStructObject *)self; assert(PyStruct_Check(self)); assert(soself->s_codes != NULL); - if (PyTuple_GET_SIZE(args) != (soself->s_len + 2)) + if (nargs != (soself->s_len + 2)) { - if (PyTuple_GET_SIZE(args) == 0) { + if (nargs == 0) { PyErr_Format(StructError, "pack_into expected buffer argument"); } - else if (PyTuple_GET_SIZE(args) == 1) { + else if (nargs == 1) { PyErr_Format(StructError, "pack_into expected offset argument"); } else { PyErr_Format(StructError, "pack_into expected %zd items for packing (got %zd)", - soself->s_len, (PyTuple_GET_SIZE(args) - 2)); + soself->s_len, (nargs - 2)); } return NULL; } + if (!_PyArg_NoStackKeywords("pack_into", kwnames)) { + return NULL; + } /* Extract a writable memory buffer from the first argument */ - if (!PyArg_Parse(PyTuple_GET_ITEM(args, 0), "w*", &buffer)) + if (!PyArg_Parse(args[0], "w*", &buffer)) return NULL; assert(buffer.len >= 0); /* Extract the offset from the first argument */ - offset = PyNumber_AsSsize_t(PyTuple_GET_ITEM(args, 1), PyExc_IndexError); + offset = PyNumber_AsSsize_t(args[1], PyExc_IndexError); if (offset == -1 && PyErr_Occurred()) { PyBuffer_Release(&buffer); return NULL; @@ -1956,22 +1971,15 @@ s_sizeof(PyStructObject *self, void *unused) /* List of functions */ static struct PyMethodDef s_methods[] = { - {"iter_unpack", s_iter_unpack, METH_O, s_iter_unpack__doc__}, - {"pack", s_pack, METH_VARARGS, s_pack__doc__}, - {"pack_into", s_pack_into, METH_VARARGS, s_pack_into__doc__}, - {"unpack", s_unpack, METH_O, s_unpack__doc__}, - {"unpack_from", (PyCFunction)s_unpack_from, METH_VARARGS|METH_KEYWORDS, - s_unpack_from__doc__}, + STRUCT_ITER_UNPACK_METHODDEF + {"pack", (PyCFunction)s_pack, METH_FASTCALL, s_pack__doc__}, + {"pack_into", (PyCFunction)s_pack_into, METH_FASTCALL, s_pack_into__doc__}, + STRUCT_UNPACK_METHODDEF + STRUCT_UNPACK_FROM_METHODDEF {"__sizeof__", (PyCFunction)s_sizeof, METH_NOARGS, s_sizeof__doc__}, {NULL, NULL} /* sentinel */ }; -PyDoc_STRVAR(s__doc__, -"Struct(fmt) --> compiled struct object\n" -"\n" -"Return a new Struct object which writes and reads binary data according to\n" -"the format string fmt. See help(struct) for more on format strings."); - #define OFF(x) offsetof(PyStructObject, x) static PyGetSetDef s_getsetlist[] = { @@ -1998,29 +2006,29 @@ PyTypeObject PyStructType = { 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - PyObject_GenericSetAttr, /* tp_setattro */ + PyObject_GenericGetAttr, /* tp_getattro */ + PyObject_GenericSetAttr, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ - s__doc__, /* tp_doc */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + Struct___init____doc__, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ offsetof(PyStructObject, weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - s_methods, /* tp_methods */ - NULL, /* tp_members */ - s_getsetlist, /* tp_getset */ + s_methods, /* tp_methods */ + NULL, /* tp_members */ + s_getsetlist, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ - s_init, /* tp_init */ - PyType_GenericAlloc,/* tp_alloc */ - s_new, /* tp_new */ - PyObject_Del, /* tp_free */ + Struct___init__, /* tp_init */ + PyType_GenericAlloc, /* tp_alloc */ + s_new, /* tp_new */ + PyObject_Del, /* tp_free */ }; @@ -2029,7 +2037,7 @@ PyTypeObject PyStructType = { #define MAXCACHE 100 static PyObject *cache = NULL; -static PyObject * +static PyStructObject * cache_struct(PyObject *fmt) { PyObject * s_object; @@ -2043,202 +2051,214 @@ cache_struct(PyObject *fmt) s_object = PyDict_GetItem(cache, fmt); if (s_object != NULL) { Py_INCREF(s_object); - return s_object; + return (PyStructObject *)s_object; } s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL); if (s_object != NULL) { - if (PyDict_Size(cache) >= MAXCACHE) + if (PyDict_GET_SIZE(cache) >= MAXCACHE) PyDict_Clear(cache); /* Attempt to cache the result */ if (PyDict_SetItem(cache, fmt, s_object) == -1) PyErr_Clear(); } - return s_object; + return (PyStructObject *)s_object; } -PyDoc_STRVAR(clearcache_doc, -"Clear the internal cache."); +/*[clinic input] +_clearcache + +Clear the internal cache. +[clinic start generated code]*/ static PyObject * -clearcache(PyObject *self) +_clearcache_impl(PyObject *module) +/*[clinic end generated code: output=ce4fb8a7bf7cb523 input=463eaae04bab3211]*/ { Py_CLEAR(cache); Py_RETURN_NONE; } -PyDoc_STRVAR(calcsize_doc, -"calcsize(fmt) -> integer\n\ -\n\ -Return size in bytes of the struct described by the format string fmt."); + +/*[clinic input] +calcsize + + format: object + / + +Return size in bytes of the struct described by the format string. +[clinic start generated code]*/ static PyObject * -calcsize(PyObject *self, PyObject *fmt) +calcsize(PyObject *module, PyObject *format) +/*[clinic end generated code: output=90fbcf191fe9470a input=55488303a06777fa]*/ { Py_ssize_t n; - PyObject *s_object = cache_struct(fmt); + PyStructObject *s_object = cache_struct(format); if (s_object == NULL) return NULL; - n = ((PyStructObject *)s_object)->s_size; + n = s_object->s_size; Py_DECREF(s_object); return PyLong_FromSsize_t(n); } PyDoc_STRVAR(pack_doc, -"pack(fmt, v1, v2, ...) -> bytes\n\ +"pack(format, v1, v2, ...) -> bytes\n\ \n\ Return a bytes object containing the values v1, v2, ... packed according\n\ -to the format string fmt. See help(struct) for more on format strings."); +to the format string. See help(struct) for more on format strings."); static PyObject * -pack(PyObject *self, PyObject *args) +pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *s_object, *fmt, *newargs, *result; - Py_ssize_t n = PyTuple_GET_SIZE(args); + PyStructObject *s_object; + PyObject *format, *result; - if (n == 0) { + if (nargs == 0) { PyErr_SetString(PyExc_TypeError, "missing format argument"); return NULL; } - fmt = PyTuple_GET_ITEM(args, 0); - newargs = PyTuple_GetSlice(args, 1, n); - if (newargs == NULL) - return NULL; + format = args[0]; - s_object = cache_struct(fmt); + s_object = cache_struct(format); if (s_object == NULL) { - Py_DECREF(newargs); return NULL; } - result = s_pack(s_object, newargs); - Py_DECREF(newargs); + result = s_pack((PyObject *)s_object, args + 1, nargs - 1, kwnames); Py_DECREF(s_object); return result; } PyDoc_STRVAR(pack_into_doc, -"pack_into(fmt, buffer, offset, v1, v2, ...)\n\ +"pack_into(format, buffer, offset, v1, v2, ...)\n\ \n\ -Pack the values v1, v2, ... according to the format string fmt and write\n\ +Pack the values v1, v2, ... according to the format string and write\n\ the packed bytes into the writable buffer buf starting at offset. Note\n\ that the offset is a required argument. See help(struct) for more\n\ on format strings."); static PyObject * -pack_into(PyObject *self, PyObject *args) +pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *s_object, *fmt, *newargs, *result; - Py_ssize_t n = PyTuple_GET_SIZE(args); + PyStructObject *s_object; + PyObject *format, *result; - if (n == 0) { + if (nargs == 0) { PyErr_SetString(PyExc_TypeError, "missing format argument"); return NULL; } - fmt = PyTuple_GET_ITEM(args, 0); - newargs = PyTuple_GetSlice(args, 1, n); - if (newargs == NULL) - return NULL; + format = args[0]; - s_object = cache_struct(fmt); + s_object = cache_struct(format); if (s_object == NULL) { - Py_DECREF(newargs); return NULL; } - result = s_pack_into(s_object, newargs); - Py_DECREF(newargs); + result = s_pack_into((PyObject *)s_object, args + 1, nargs - 1, kwnames); Py_DECREF(s_object); return result; } -PyDoc_STRVAR(unpack_doc, -"unpack(fmt, buffer) -> (v1, v2, ...)\n\ -\n\ -Return a tuple containing values unpacked according to the format string\n\ -fmt. The buffer's size in bytes must be calcsize(fmt). See help(struct)\n\ -for more on format strings."); +/*[clinic input] +unpack + + format: object + buffer: Py_buffer + / + +Return a tuple containing values unpacked according to the format string. + +The buffer's size in bytes must be calcsize(format). + +See help(struct) for more on format strings. +[clinic start generated code]*/ static PyObject * -unpack(PyObject *self, PyObject *args) +unpack_impl(PyObject *module, PyObject *format, Py_buffer *buffer) +/*[clinic end generated code: output=f75ada02aaa33b3b input=654078e6660c2df0]*/ { - PyObject *s_object, *fmt, *inputstr, *result; - - if (!PyArg_UnpackTuple(args, "unpack", 2, 2, &fmt, &inputstr)) - return NULL; + PyStructObject *s_object; + PyObject *result; - s_object = cache_struct(fmt); + s_object = cache_struct(format); if (s_object == NULL) return NULL; - result = s_unpack(s_object, inputstr); + result = Struct_unpack_impl(s_object, buffer); Py_DECREF(s_object); return result; } -PyDoc_STRVAR(unpack_from_doc, -"unpack_from(fmt, buffer, offset=0) -> (v1, v2, ...)\n\ -\n\ -Return a tuple containing values unpacked according to the format string\n\ -fmt. The buffer's size, minus offset, must be at least calcsize(fmt).\n\ -See help(struct) for more on format strings."); +/*[clinic input] +unpack_from + + format: object + / + buffer: Py_buffer + offset: Py_ssize_t = 0 + +Return a tuple containing values unpacked according to the format string. + +The buffer's size, minus offset, must be at least calcsize(format). + +See help(struct) for more on format strings. +[clinic start generated code]*/ static PyObject * -unpack_from(PyObject *self, PyObject *args, PyObject *kwds) +unpack_from_impl(PyObject *module, PyObject *format, Py_buffer *buffer, + Py_ssize_t offset) +/*[clinic end generated code: output=2492f0c3a0b82577 input=9ead76c6ac7164f7]*/ { - PyObject *s_object, *fmt, *newargs, *result; - Py_ssize_t n = PyTuple_GET_SIZE(args); - - if (n == 0) { - PyErr_SetString(PyExc_TypeError, "missing format argument"); - return NULL; - } - fmt = PyTuple_GET_ITEM(args, 0); - newargs = PyTuple_GetSlice(args, 1, n); - if (newargs == NULL) - return NULL; + PyStructObject *s_object; + PyObject *result; - s_object = cache_struct(fmt); + s_object = cache_struct(format); if (s_object == NULL) { - Py_DECREF(newargs); return NULL; } - result = s_unpack_from(s_object, newargs, kwds); - Py_DECREF(newargs); + result = Struct_unpack_from_impl(s_object, buffer, offset); + Py_DECREF(s_object); return result; } -PyDoc_STRVAR(iter_unpack_doc, -"iter_unpack(fmt, buffer) -> iterator(v1, v2, ...)\n\ -\n\ -Return an iterator yielding tuples unpacked from the given bytes\n\ -source according to the format string, like a repeated invocation of\n\ -unpack_from(). Requires that the bytes length be a multiple of the\n\ -format struct size."); +/*[clinic input] +iter_unpack + + format: object + buffer: object + / + +Return an iterator yielding tuples unpacked from the given bytes. + +The bytes are unpacked according to the format string, like +a repeated invocation of unpack_from(). + +Requires that the bytes length be a multiple of the format struct size. +[clinic start generated code]*/ static PyObject * -iter_unpack(PyObject *self, PyObject *args) +iter_unpack_impl(PyObject *module, PyObject *format, PyObject *buffer) +/*[clinic end generated code: output=b1291e97a6d4cf3c input=8674dfd2f0dae416]*/ { - PyObject *s_object, *fmt, *input, *result; - - if (!PyArg_ParseTuple(args, "OO:iter_unpack", &fmt, &input)) - return NULL; + PyStructObject *s_object; + PyObject *result; - s_object = cache_struct(fmt); + s_object = cache_struct(format); if (s_object == NULL) return NULL; - result = s_iter_unpack(s_object, input); + + result = Struct_iter_unpack(s_object, buffer); Py_DECREF(s_object); return result; } static struct PyMethodDef module_functions[] = { - {"_clearcache", (PyCFunction)clearcache, METH_NOARGS, clearcache_doc}, - {"calcsize", calcsize, METH_O, calcsize_doc}, - {"iter_unpack", iter_unpack, METH_VARARGS, iter_unpack_doc}, - {"pack", pack, METH_VARARGS, pack_doc}, - {"pack_into", pack_into, METH_VARARGS, pack_into_doc}, - {"unpack", unpack, METH_VARARGS, unpack_doc}, - {"unpack_from", (PyCFunction)unpack_from, - METH_VARARGS|METH_KEYWORDS, unpack_from_doc}, + _CLEARCACHE_METHODDEF + CALCSIZE_METHODDEF + ITER_UNPACK_METHODDEF + {"pack", (PyCFunction)pack, METH_FASTCALL, pack_doc}, + {"pack_into", (PyCFunction)pack_into, METH_FASTCALL, pack_into_doc}, + UNPACK_METHODDEF + UNPACK_FROM_METHODDEF {NULL, NULL} /* sentinel */ }; @@ -2301,6 +2321,9 @@ PyInit__struct(void) if (PyType_Ready(&PyStructType) < 0) return NULL; + if (PyType_Ready(&unpackiter_type) < 0) + return NULL; + /* Check endian and swap in faster functions */ { const formatdef *native = native_table; |