Add rpmtd to python object converter, change header code to use that

- vastly simpler than the former goo in hdr_subscribe
This commit is contained in:
Panu Matilainen 2009-09-23 12:49:15 +03:00
parent 282efb6d4c
commit 76d8d16de0
4 changed files with 74 additions and 107 deletions

View 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

View 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)

61
python/rpmtd-py.c Normal file
View File

@ -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;
}

5
python/rpmtd-py.h Normal file
View File

@ -0,0 +1,5 @@
#ifndef H_RPMTD_PY
#define H_RPMTD_PY
PyObject * rpmtd_AsPyobj(rpmtd td);
#endif