Add rpmtd to python object converter, change header code to use that
authorPanu Matilainen <pmatilai@redhat.com>
Wed, 23 Sep 2009 09:49:15 +0000 (12:49 +0300)
committerPanu Matilainen <pmatilai@redhat.com>
Wed, 23 Sep 2009 09:49:15 +0000 (12:49 +0300)
- vastly simpler than the former goo in hdr_subscribe

python/Makefile.am
python/header-py.c
python/rpmtd-py.c [new file with mode: 0644]
python/rpmtd-py.h [new file with mode: 0644]

index 8d763ed..c326a6a 100644 (file)
@@ -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
index c84056d..50c1819 100644 (file)
@@ -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 (file)
index 0000000..77df8cd
--- /dev/null
@@ -0,0 +1,61 @@
+/** \ingroup py_c
+ * \file python/rpmtd-py.c
+ */
+
+#include "rpmsystem-py.h"
+#include <rpm/rpmtd.h>
+#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 (file)
index 0000000..39469f2
--- /dev/null
@@ -0,0 +1,5 @@
+#ifndef H_RPMTD_PY
+#define H_RPMTD_PY
+
+PyObject * rpmtd_AsPyobj(rpmtd td);
+#endif