Make object allocation type agnostic
[platform/upstream/rpm.git] / python / rpmfi-py.c
1 #include "rpmsystem-py.h"
2
3 #include <rpm/rpmtypes.h>
4 #include <rpm/rpmpgp.h>
5
6 #include "header-py.h"
7 #include "rpmfi-py.h"
8
9 #include "debug.h"
10
11 struct rpmfiObject_s {
12     PyObject_HEAD
13     PyObject *md_dict;          /*!< to look like PyModuleObject */
14     int active;
15     rpmfi fi;
16 };
17
18 static PyObject *
19 rpmfi_FC(rpmfiObject * s)
20 {
21     return Py_BuildValue("i", rpmfiFC(s->fi));
22 }
23
24 static PyObject *
25 rpmfi_FX(rpmfiObject * s)
26 {
27     return Py_BuildValue("i", rpmfiFX(s->fi));
28 }
29
30 static PyObject *
31 rpmfi_DC(rpmfiObject * s)
32 {
33     return Py_BuildValue("i", rpmfiDC(s->fi));
34 }
35
36 static PyObject *
37 rpmfi_DX(rpmfiObject * s)
38 {
39     return Py_BuildValue("i", rpmfiDX(s->fi));
40 }
41
42 static PyObject *
43 rpmfi_BN(rpmfiObject * s)
44 {
45     return Py_BuildValue("s", xstrdup(rpmfiBN(s->fi)));
46 }
47
48 static PyObject *
49 rpmfi_DN(rpmfiObject * s)
50 {
51     return Py_BuildValue("s", xstrdup(rpmfiDN(s->fi)));
52 }
53
54 static PyObject *
55 rpmfi_FN(rpmfiObject * s)
56 {
57     return Py_BuildValue("s", xstrdup(rpmfiFN(s->fi)));
58 }
59
60 static PyObject *
61 rpmfi_FFlags(rpmfiObject * s)
62 {
63     return Py_BuildValue("i", rpmfiFFlags(s->fi));
64 }
65
66 static PyObject *
67 rpmfi_VFlags(rpmfiObject * s)
68 {
69     return Py_BuildValue("i", rpmfiVFlags(s->fi));
70 }
71
72 static PyObject *
73 rpmfi_FMode(rpmfiObject * s)
74 {
75     return Py_BuildValue("i", rpmfiFMode(s->fi));
76 }
77
78 static PyObject *
79 rpmfi_FState(rpmfiObject * s)
80 {
81     return Py_BuildValue("i", rpmfiFState(s->fi));
82 }
83
84 /* XXX rpmfiFDigest */
85 static PyObject *
86 rpmfi_Digest(rpmfiObject * s)
87 {
88     char *digest = rpmfiFDigestHex(s->fi, NULL);
89     if (digest) {
90         PyObject *dig = Py_BuildValue("s", digest);
91         free(digest);
92         return dig;
93     } else {
94         Py_RETURN_NONE;
95     }
96 }
97
98 static PyObject *
99 rpmfi_FLink(rpmfiObject * s)
100 {
101     return Py_BuildValue("s", xstrdup(rpmfiFLink(s->fi)));
102 }
103
104 static PyObject *
105 rpmfi_FSize(rpmfiObject * s)
106 {
107     return Py_BuildValue("L", rpmfiFSize(s->fi));
108 }
109
110 static PyObject *
111 rpmfi_FRdev(rpmfiObject * s)
112 {
113     return Py_BuildValue("i", rpmfiFRdev(s->fi));
114 }
115
116 static PyObject *
117 rpmfi_FMtime(rpmfiObject * s)
118 {
119     return Py_BuildValue("i", rpmfiFMtime(s->fi));
120 }
121
122 static PyObject *
123 rpmfi_FUser(rpmfiObject * s)
124 {
125     return Py_BuildValue("s", xstrdup(rpmfiFUser(s->fi)));
126 }
127
128 static PyObject *
129 rpmfi_FGroup(rpmfiObject * s)
130 {
131     return Py_BuildValue("s", xstrdup(rpmfiFGroup(s->fi)));
132 }
133
134 static PyObject *
135 rpmfi_FColor(rpmfiObject * s)
136 {
137     return Py_BuildValue("i", rpmfiFColor(s->fi));
138 }
139
140 static PyObject *
141 rpmfi_FClass(rpmfiObject * s)
142 {
143     const char * FClass;
144
145     if ((FClass = rpmfiFClass(s->fi)) == NULL)
146         FClass = "";
147     return Py_BuildValue("s", xstrdup(FClass));
148 }
149
150 static PyObject *
151 rpmfi_iternext(rpmfiObject * s)
152 {
153     PyObject * result = NULL;
154
155     /* Reset loop indices on 1st entry. */
156     if (!s->active) {
157         s->fi = rpmfiInit(s->fi, 0);
158         s->active = 1;
159     }
160
161     /* If more to do, return the file tuple. */
162     if (rpmfiNext(s->fi) >= 0) {
163         const char * FN = rpmfiFN(s->fi);
164         rpm_loff_t FSize = rpmfiFSize(s->fi);
165         int FMode = rpmfiFMode(s->fi);
166         int FMtime = rpmfiFMtime(s->fi);
167         int FFlags = rpmfiFFlags(s->fi);
168         int FRdev = rpmfiFRdev(s->fi);
169         int FInode = rpmfiFInode(s->fi);
170         int FNlink = rpmfiFNlink(s->fi);
171         int FState = rpmfiFState(s->fi);
172         int VFlags = rpmfiVFlags(s->fi);
173         const char * FUser = rpmfiFUser(s->fi);
174         const char * FGroup = rpmfiFGroup(s->fi);
175
176         result = PyTuple_New(13);
177         if (FN == NULL) {
178             Py_INCREF(Py_None);
179             PyTuple_SET_ITEM(result, 0, Py_None);
180         } else
181             PyTuple_SET_ITEM(result,  0, Py_BuildValue("s", FN));
182         PyTuple_SET_ITEM(result,  1, PyLong_FromLongLong(FSize));
183         PyTuple_SET_ITEM(result,  2, PyInt_FromLong(FMode));
184         PyTuple_SET_ITEM(result,  3, PyInt_FromLong(FMtime));
185         PyTuple_SET_ITEM(result,  4, PyInt_FromLong(FFlags));
186         PyTuple_SET_ITEM(result,  5, PyInt_FromLong(FRdev));
187         PyTuple_SET_ITEM(result,  6, PyInt_FromLong(FInode));
188         PyTuple_SET_ITEM(result,  7, PyInt_FromLong(FNlink));
189         PyTuple_SET_ITEM(result,  8, PyInt_FromLong(FState));
190         PyTuple_SET_ITEM(result,  9, PyInt_FromLong(VFlags));
191         if (FUser == NULL) {
192             Py_INCREF(Py_None);
193             PyTuple_SET_ITEM(result, 10, Py_None);
194         } else
195             PyTuple_SET_ITEM(result, 10, Py_BuildValue("s", FUser));
196         if (FGroup == NULL) {
197             Py_INCREF(Py_None);
198             PyTuple_SET_ITEM(result, 11, Py_None);
199         } else
200             PyTuple_SET_ITEM(result, 11, Py_BuildValue("s", FGroup));
201         PyTuple_SET_ITEM(result, 12, rpmfi_Digest(s));
202
203     } else
204         s->active = 0;
205
206     return result;
207 }
208
209 static struct PyMethodDef rpmfi_methods[] = {
210  {"FC",         (PyCFunction)rpmfi_FC,          METH_NOARGS,
211         NULL},
212  {"FX",         (PyCFunction)rpmfi_FX,          METH_NOARGS,
213         NULL},
214  {"DC",         (PyCFunction)rpmfi_DC,          METH_NOARGS,
215         NULL},
216  {"DX",         (PyCFunction)rpmfi_DX,          METH_NOARGS,
217         NULL},
218  {"BN",         (PyCFunction)rpmfi_BN,          METH_NOARGS,
219         NULL},
220  {"DN",         (PyCFunction)rpmfi_DN,          METH_NOARGS,
221         NULL},
222  {"FN",         (PyCFunction)rpmfi_FN,          METH_NOARGS,
223         NULL},
224  {"FFlags",     (PyCFunction)rpmfi_FFlags,      METH_NOARGS,
225         NULL},
226  {"VFlags",     (PyCFunction)rpmfi_VFlags,      METH_NOARGS,
227         NULL},
228  {"FMode",      (PyCFunction)rpmfi_FMode,       METH_NOARGS,
229         NULL},
230  {"FState",     (PyCFunction)rpmfi_FState,      METH_NOARGS,
231         NULL},
232  {"MD5",        (PyCFunction)rpmfi_Digest,      METH_NOARGS,
233         NULL},
234  {"Digest",     (PyCFunction)rpmfi_Digest,      METH_NOARGS,
235         NULL},
236  {"FLink",      (PyCFunction)rpmfi_FLink,       METH_NOARGS,
237         NULL},
238  {"FSize",      (PyCFunction)rpmfi_FSize,       METH_NOARGS,
239         NULL},
240  {"FRdev",      (PyCFunction)rpmfi_FRdev,       METH_NOARGS,
241         NULL},
242  {"FMtime",     (PyCFunction)rpmfi_FMtime,      METH_NOARGS,
243         NULL},
244  {"FUser",      (PyCFunction)rpmfi_FUser,       METH_NOARGS,
245         NULL},
246  {"FGroup",     (PyCFunction)rpmfi_FGroup,      METH_NOARGS,
247         NULL},
248  {"FColor",     (PyCFunction)rpmfi_FColor,      METH_NOARGS,
249         NULL},
250  {"FClass",     (PyCFunction)rpmfi_FClass,      METH_NOARGS,
251         NULL},
252  {NULL,         NULL}           /* sentinel */
253 };
254
255 /* ---------- */
256
257 static void
258 rpmfi_dealloc(rpmfiObject * s)
259 {
260     if (s) {
261         s->fi = rpmfiFree(s->fi);
262         PyObject_Del(s);
263     }
264 }
265
266 static int
267 rpmfi_length(rpmfiObject * s)
268 {
269     return rpmfiFC(s->fi);
270 }
271
272 static PyObject *
273 rpmfi_subscript(rpmfiObject * s, PyObject * key)
274 {
275     int ix;
276
277     if (!PyInt_Check(key)) {
278         PyErr_SetString(PyExc_TypeError, "integer expected");
279         return NULL;
280     }
281
282     ix = (int) PyInt_AsLong(key);
283     rpmfiSetFX(s->fi, ix);
284     return Py_BuildValue("s", xstrdup(rpmfiFN(s->fi)));
285 }
286
287 static PyMappingMethods rpmfi_as_mapping = {
288         (lenfunc) rpmfi_length,         /* mp_length */
289         (binaryfunc) rpmfi_subscript,   /* mp_subscript */
290         (objobjargproc)0,               /* mp_ass_subscript */
291 };
292
293 static int rpmfi_init(rpmfiObject * s, PyObject *args, PyObject *kwds)
294 {
295     s->active = 0;
296     return 0;
297 }
298
299 static void rpmfi_free(rpmfiObject * s)
300 {
301     s->fi = rpmfiFree(s->fi);
302
303     PyObject_Del((PyObject *)s);
304 }
305
306 static PyObject * rpmfi_new(PyTypeObject * subtype, PyObject *args, PyObject *kwds)
307 {
308     hdrObject * ho = NULL;
309     PyObject * to = NULL;
310     rpmfi fi = NULL;
311     rpmTag tagN = RPMTAG_BASENAMES;
312     int flags = 0;
313     char * kwlist[] = {"header", "tag", "flags", NULL};
314
315     if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|Oi:rpmfi_init", kwlist,
316             &hdr_Type, &ho, &to, &flags))
317         return NULL;
318
319     fi = rpmfiNew(NULL, hdrGetHeader(ho), tagN, flags);
320
321     return rpmfi_Wrap(subtype, fi);
322 }
323
324 static char rpmfi_doc[] =
325 "";
326
327 PyTypeObject rpmfi_Type = {
328         PyObject_HEAD_INIT(&PyType_Type)
329         0,                              /* ob_size */
330         "rpm.fi",                       /* tp_name */
331         sizeof(rpmfiObject),            /* tp_basicsize */
332         0,                              /* tp_itemsize */
333         /* methods */
334         (destructor) rpmfi_dealloc,     /* tp_dealloc */
335         0,                              /* tp_print */
336         (getattrfunc)0,                 /* tp_getattr */
337         (setattrfunc)0,                 /* tp_setattr */
338         (cmpfunc)0,                     /* tp_compare */
339         (reprfunc)0,                    /* tp_repr */
340         0,                              /* tp_as_number */
341         0,                              /* tp_as_sequence */
342         &rpmfi_as_mapping,              /* tp_as_mapping */
343         (hashfunc)0,                    /* tp_hash */
344         (ternaryfunc)0,                 /* tp_call */
345         (reprfunc)0,                    /* tp_str */
346         PyObject_GenericGetAttr,        /* tp_getattro */
347         PyObject_GenericSetAttr,        /* tp_setattro */
348         0,                              /* tp_as_buffer */
349         Py_TPFLAGS_DEFAULT,             /* tp_flags */
350         rpmfi_doc,                      /* tp_doc */
351         0,                              /* tp_traverse */
352         0,                              /* tp_clear */
353         0,                              /* tp_richcompare */
354         0,                              /* tp_weaklistoffset */
355         PyObject_SelfIter,              /* tp_iter */
356         (iternextfunc) rpmfi_iternext,  /* tp_iternext */
357         rpmfi_methods,                  /* tp_methods */
358         0,                              /* tp_members */
359         0,                              /* tp_getset */
360         0,                              /* tp_base */
361         0,                              /* tp_dict */
362         0,                              /* tp_descr_get */
363         0,                              /* tp_descr_set */
364         0,                              /* tp_dictoffset */
365         (initproc) rpmfi_init,          /* tp_init */
366         0,                              /* tp_alloc */
367         (newfunc) rpmfi_new,            /* tp_new */
368         (freefunc) rpmfi_free,          /* tp_free */
369         0,                              /* tp_is_gc */
370 };
371
372 /* ---------- */
373
374 rpmfi fiFromFi(rpmfiObject * s)
375 {
376     return s->fi;
377 }
378
379 PyObject * rpmfi_Wrap(PyTypeObject *subtype, rpmfi fi)
380 {
381     rpmfiObject *s = (rpmfiObject *)subtype->tp_alloc(subtype, 0);
382     if (s == NULL) return PyErr_NoMemory();
383
384     s->fi = fi;
385     s->active = 0;
386     return (PyObject *) s;
387 }
388