From 76d8d16de0c96f2b3e66eafe9f03127e96ad5804 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Wed, 23 Sep 2009 12:49:15 +0300 Subject: [PATCH] Add rpmtd to python object converter, change header code to use that - vastly simpler than the former goo in hdr_subscribe --- python/Makefile.am | 1 + python/header-py.c | 114 ++++------------------------------------------------- python/rpmtd-py.c | 61 ++++++++++++++++++++++++++++ python/rpmtd-py.h | 5 +++ 4 files changed, 74 insertions(+), 107 deletions(-) create mode 100644 python/rpmtd-py.c create mode 100644 python/rpmtd-py.h diff --git a/python/Makefile.am b/python/Makefile.am index 8d763ed..c326a6a 100644 --- a/python/Makefile.am +++ b/python/Makefile.am @@ -26,6 +26,7 @@ _rpmmodule_la_SOURCES = rpmmodule.c rpmsystem-py.h \ rpmmi-py.c rpmmi-py.h \ rpmps-py.c rpmps-py.h \ rpmmacro-py.c rpmmacro-py.h \ + rpmtd-py.c rpmtd-py.h \ rpmte-py.c rpmte-py.h \ rpmts-py.c rpmts-py.h \ spec-py.c spec-py.h diff --git a/python/header-py.c b/python/header-py.c index c84056d..50c1819 100644 --- a/python/header-py.c +++ b/python/header-py.c @@ -9,6 +9,7 @@ #include "rpmds-py.h" #include "rpmfd-py.h" #include "rpmfi-py.h" +#include "rpmtd-py.h" #include "debug.h" @@ -433,119 +434,18 @@ int tagNumFromPyObject (PyObject *item, rpmTag *tagp) static PyObject * hdr_subscript(hdrObject * s, PyObject * item) { - rpmTagType tagtype, type; rpmTag tag = RPMTAG_NOT_FOUND; - rpm_count_t count, i; - rpm_data_t data; - PyObject * o, * metao; - char ** stringArray; - int forceArray = 0; struct rpmtd_s td; + PyObject *res = NULL; if (!tagNumFromPyObject(item, &tag)) return NULL; - - tagtype = rpmTagGetType(tag); - forceArray = (tagtype & RPM_MASK_RETURN_TYPE) == RPM_ARRAY_RETURN_TYPE; - - /* Retrieve data from extension or header. */ - if (!headerGet(s->h, tag, &td, HEADERGET_EXT)) { - if (forceArray) { - o = PyList_New(0); - } else { - o = Py_None; - Py_INCREF(o); - } - return o; - } - - count = td.count; - data = td.data; - type = td.type; - - switch (type) { - case RPM_BIN_TYPE: - o = PyString_FromStringAndSize(data, count); - break; - - case RPM_INT32_TYPE: - if (count != 1 || forceArray) { - metao = PyList_New(0); - for (i = 0; i < count; i++) { - o = PyInt_FromLong(((int *) data)[i]); - PyList_Append(metao, o); - Py_DECREF(o); - } - o = metao; - } else { - o = PyInt_FromLong(*((int *) data)); - } - break; - - case RPM_CHAR_TYPE: - case RPM_INT8_TYPE: - if (count != 1 || forceArray) { - metao = PyList_New(0); - for (i = 0; i < count; i++) { - o = PyInt_FromLong(((char *) data)[i]); - PyList_Append(metao, o); - Py_DECREF(o); - } - o = metao; - } else { - o = PyInt_FromLong(*((char *) data)); - } - break; - - case RPM_INT16_TYPE: - if (count != 1 || forceArray) { - metao = PyList_New(0); - for (i = 0; i < count; i++) { - o = PyInt_FromLong(((short *) data)[i]); - PyList_Append(metao, o); - Py_DECREF(o); - } - o = metao; - } else { - o = PyInt_FromLong(*((short *) data)); - } - break; - - case RPM_STRING_ARRAY_TYPE: - stringArray = data; - - metao = PyList_New(0); - for (i = 0; i < count; i++) { - o = PyString_FromString(stringArray[i]); - PyList_Append(metao, o); - Py_DECREF(o); - } - o = metao; - break; - - case RPM_STRING_TYPE: - case RPM_I18NSTRING_TYPE: - if (count != 1 || forceArray) { - stringArray = data; - - metao = PyList_New(0); - for (i=0; i < count; i++) { - o = PyString_FromString(stringArray[i]); - PyList_Append(metao, o); - Py_DECREF(o); - } - o = metao; - } else { - o = PyString_FromString(data); - } - break; - - default: - PyErr_SetString(PyExc_TypeError, "unsupported type in header"); - return NULL; - } + + /* rpmtd_AsPyObj() knows how to handle empty containers and all */ + (void) headerGet(s->h, tag, &td, HEADERGET_EXT); + res = rpmtd_AsPyobj(&td); rpmtdFreeData(&td); - return o; + return res; } static PyObject * hdr_getattro(PyObject * o, PyObject * n) diff --git a/python/rpmtd-py.c b/python/rpmtd-py.c new file mode 100644 index 0000000..77df8cd --- /dev/null +++ b/python/rpmtd-py.c @@ -0,0 +1,61 @@ +/** \ingroup py_c + * \file python/rpmtd-py.c + */ + +#include "rpmsystem-py.h" +#include +#include "rpmtd-py.h" + +/* + * Convert single tag data item to python object of suitable type + */ +static PyObject * rpmtd_ItemAsPyobj(rpmtd td, rpmTagClass class) +{ + PyObject *res = NULL; + char *str = NULL; + const char *errmsg = NULL; + + switch (class) { + case RPM_STRING_CLASS: + res = PyString_FromString(rpmtdGetString(td)); + break; + case RPM_NUMERIC_CLASS: + res = PyLong_FromLongLong(rpmtdGetNumber(td)); + break; + case RPM_BINARY_CLASS: + str = rpmtdFormat(td, RPMTD_FORMAT_STRING, &errmsg); + if (errmsg) { + PyErr_SetString(PyExc_ValueError, errmsg); + } else { + res = PyString_FromString(str); + } + free(str); + break; + default: + PyErr_SetString(PyExc_KeyError, "unknown data type"); + break; + } + return res; +} + +PyObject *rpmtd_AsPyobj(rpmtd td) +{ + PyObject *res = NULL; + rpmTagType type = rpmTagGetType(td->tag); + int array = ((type & RPM_MASK_RETURN_TYPE) == RPM_ARRAY_RETURN_TYPE); + rpmTagClass class = rpmtdClass(td); + + if (!array && rpmtdCount(td) < 1) { + Py_RETURN_NONE; + } + + if (array) { + res = PyList_New(0); + while (rpmtdNext(td) >= 0) { + PyList_Append(res, rpmtd_ItemAsPyobj(td, class)); + } + } else { + res = rpmtd_ItemAsPyobj(td, class); + } + return res; +} diff --git a/python/rpmtd-py.h b/python/rpmtd-py.h new file mode 100644 index 0000000..39469f2 --- /dev/null +++ b/python/rpmtd-py.h @@ -0,0 +1,5 @@ +#ifndef H_RPMTD_PY +#define H_RPMTD_PY + +PyObject * rpmtd_AsPyobj(rpmtd td); +#endif -- 2.7.4