diff options
Diffstat (limited to 'Modules/_struct.c')
-rw-r--r-- | Modules/_struct.c | 117 |
1 files changed, 52 insertions, 65 deletions
diff --git a/Modules/_struct.c b/Modules/_struct.c index 78cd0f3..f66ee18 100644 --- a/Modules/_struct.c +++ b/Modules/_struct.c @@ -85,6 +85,19 @@ typedef struct { char c; long long x; } s_long_long; #pragma options align=reset #endif +/*[python input] +class cache_struct_converter(CConverter): + type = 'PyStructObject *' + converter = 'cache_struct_converter' + c_default = "NULL" + + def cleanup(self): + return "Py_XDECREF(%s);\n" % self.name +[python start generated code]*/ +/*[python end generated code: output=da39a3ee5e6b4b0d input=49957cca130ffb63]*/ + +static int cache_struct_converter(PyObject *, PyObject **); + #include "clinic/_struct.c.h" /* Helper for integer format codes: converts an arbitrary Python object to a @@ -2037,21 +2050,27 @@ PyTypeObject PyStructType = { #define MAXCACHE 100 static PyObject *cache = NULL; -static PyStructObject * -cache_struct(PyObject *fmt) +static int +cache_struct_converter(PyObject *fmt, PyObject **ptr) { PyObject * s_object; + if (fmt == NULL) { + Py_DECREF(*ptr); + return 1; + } + if (cache == NULL) { cache = PyDict_New(); if (cache == NULL) - return NULL; + return 0; } s_object = PyDict_GetItem(cache, fmt); if (s_object != NULL) { Py_INCREF(s_object); - return (PyStructObject *)s_object; + *ptr = s_object; + return Py_CLEANUP_SUPPORTED; } s_object = PyObject_CallFunctionObjArgs((PyObject *)(&PyStructType), fmt, NULL); @@ -2061,8 +2080,10 @@ cache_struct(PyObject *fmt) /* Attempt to cache the result */ if (PyDict_SetItem(cache, fmt, s_object) == -1) PyErr_Clear(); + *ptr = s_object; + return Py_CLEANUP_SUPPORTED; } - return (PyStructObject *)s_object; + return 0; } /*[clinic input] @@ -2081,25 +2102,19 @@ _clearcache_impl(PyObject *module) /*[clinic input] -calcsize +calcsize -> Py_ssize_t - format: object + format as s_object: cache_struct / Return size in bytes of the struct described by the format string. [clinic start generated code]*/ -static PyObject * -calcsize(PyObject *module, PyObject *format) -/*[clinic end generated code: output=90fbcf191fe9470a input=55488303a06777fa]*/ +static Py_ssize_t +calcsize_impl(PyObject *module, PyStructObject *s_object) +/*[clinic end generated code: output=db7d23d09c6932c4 input=96a6a590c7717ecd]*/ { - Py_ssize_t n; - PyStructObject *s_object = cache_struct(format); - if (s_object == NULL) - return NULL; - n = s_object->s_size; - Py_DECREF(s_object); - return PyLong_FromSsize_t(n); + return s_object->s_size; } PyDoc_STRVAR(pack_doc, @@ -2111,7 +2126,7 @@ to the format string. See help(struct) for more on format strings."); static PyObject * pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { - PyStructObject *s_object; + PyObject *s_object = NULL; PyObject *format, *result; if (nargs == 0) { @@ -2120,11 +2135,10 @@ pack(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) } format = args[0]; - s_object = cache_struct(format); - if (s_object == NULL) { + if (!cache_struct_converter(format, &s_object)) { return NULL; } - result = s_pack((PyObject *)s_object, args + 1, nargs - 1, kwnames); + result = s_pack(s_object, args + 1, nargs - 1, kwnames); Py_DECREF(s_object); return result; } @@ -2140,7 +2154,7 @@ on format strings."); static PyObject * pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { - PyStructObject *s_object; + PyObject *s_object = NULL; PyObject *format, *result; if (nargs == 0) { @@ -2149,11 +2163,10 @@ pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) } format = args[0]; - s_object = cache_struct(format); - if (s_object == NULL) { + if (!cache_struct_converter(format, &s_object)) { return NULL; } - result = s_pack_into((PyObject *)s_object, args + 1, nargs - 1, kwnames); + result = s_pack_into(s_object, args + 1, nargs - 1, kwnames); Py_DECREF(s_object); return result; } @@ -2161,7 +2174,7 @@ pack_into(PyObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) /*[clinic input] unpack - format: object + format as s_object: cache_struct buffer: Py_buffer / @@ -2173,24 +2186,16 @@ See help(struct) for more on format strings. [clinic start generated code]*/ static PyObject * -unpack_impl(PyObject *module, PyObject *format, Py_buffer *buffer) -/*[clinic end generated code: output=f75ada02aaa33b3b input=654078e6660c2df0]*/ +unpack_impl(PyObject *module, PyStructObject *s_object, Py_buffer *buffer) +/*[clinic end generated code: output=48ddd4d88eca8551 input=05fa3b91678da727]*/ { - PyStructObject *s_object; - PyObject *result; - - s_object = cache_struct(format); - if (s_object == NULL) - return NULL; - result = Struct_unpack_impl(s_object, buffer); - Py_DECREF(s_object); - return result; + return Struct_unpack_impl(s_object, buffer); } /*[clinic input] unpack_from - format: object + format as s_object: cache_struct / buffer: Py_buffer offset: Py_ssize_t = 0 @@ -2203,27 +2208,17 @@ See help(struct) for more on format strings. [clinic start generated code]*/ static PyObject * -unpack_from_impl(PyObject *module, PyObject *format, Py_buffer *buffer, - Py_ssize_t offset) -/*[clinic end generated code: output=2492f0c3a0b82577 input=9ead76c6ac7164f7]*/ +unpack_from_impl(PyObject *module, PyStructObject *s_object, + Py_buffer *buffer, Py_ssize_t offset) +/*[clinic end generated code: output=1042631674c6e0d3 input=6e80a5398e985025]*/ { - PyStructObject *s_object; - PyObject *result; - - s_object = cache_struct(format); - if (s_object == NULL) { - return NULL; - } - result = Struct_unpack_from_impl(s_object, buffer, offset); - - Py_DECREF(s_object); - return result; + return Struct_unpack_from_impl(s_object, buffer, offset); } /*[clinic input] iter_unpack - format: object + format as s_object: cache_struct buffer: object / @@ -2236,19 +2231,11 @@ Requires that the bytes length be a multiple of the format struct size. [clinic start generated code]*/ static PyObject * -iter_unpack_impl(PyObject *module, PyObject *format, PyObject *buffer) -/*[clinic end generated code: output=b1291e97a6d4cf3c input=8674dfd2f0dae416]*/ +iter_unpack_impl(PyObject *module, PyStructObject *s_object, + PyObject *buffer) +/*[clinic end generated code: output=0ae50e250d20e74d input=b214a58869a3c98d]*/ { - PyStructObject *s_object; - PyObject *result; - - s_object = cache_struct(format); - if (s_object == NULL) - return NULL; - - result = Struct_iter_unpack(s_object, buffer); - Py_DECREF(s_object); - return result; + return Struct_iter_unpack(s_object, buffer); } static struct PyMethodDef module_functions[] = { |