4 #include <rpm/rpmstring.h>
5 #include <rpm/rpmpgp.h>
9 typedef char * (*headerTagFormatFunction) (rpmtd td, char *formatPrefix);
11 extern void *rpmHeaderFormatFuncByValue(rpmtdFormats fmt);
15 rpmtd td = xmalloc(sizeof(*td));
20 rpmtd rpmtdFree(rpmtd td)
22 /* permit free on NULL td */
24 /* XXX should we free data too - a flag maybe? */
30 void rpmtdReset(rpmtd td)
34 memset(td, 0, sizeof(*td));
38 void rpmtdFreeData(rpmtd td)
42 if (td->flags & RPMTD_ALLOCED) {
43 if (td->flags & RPMTD_PTR_ALLOCED) {
44 assert(td->data != NULL);
45 char **data = td->data;
46 for (int i = 0; i < td->count; i++) {
55 rpm_count_t rpmtdCount(rpmtd td)
58 /* fix up for binary type abusing count as data length */
59 return (td->type == RPM_BIN_TYPE) ? 1 : td->count;
62 rpmTag rpmtdTag(rpmtd td)
68 rpmTagType rpmtdType(rpmtd td)
74 int rpmtdGetIndex(rpmtd td)
80 int rpmtdSetIndex(rpmtd td, int index)
84 if (index < 0 || index >= rpmtdCount(td)) {
91 int rpmtdInit(rpmtd td)
95 /* XXX check that this is an array type? */
100 int rpmtdNext(rpmtd td)
107 if (td->ix < rpmtdCount(td)) {
116 uint32_t *rpmtdNextUint32(rpmtd td)
119 uint32_t *res = NULL;
120 if (rpmtdNext(td) >= 0) {
121 res = rpmtdGetUint32(td);
126 uint64_t *rpmtdNextUint64(rpmtd td)
129 uint64_t *res = NULL;
130 if (rpmtdNext(td) >= 0) {
131 res = rpmtdGetUint64(td);
136 const char *rpmtdNextString(rpmtd td)
139 const char *res = NULL;
140 if (rpmtdNext(td) >= 0) {
141 res = rpmtdGetString(td);
146 char * rpmtdGetChar(rpmtd td)
152 if (td->type == RPM_CHAR_TYPE) {
153 int ix = (td->ix >= 0 ? td->ix : 0);
154 res = (char *) td->data + ix;
158 uint16_t * rpmtdGetUint16(rpmtd td)
160 uint16_t *res = NULL;
164 if (td->type == RPM_INT16_TYPE) {
165 int ix = (td->ix >= 0 ? td->ix : 0);
166 res = (uint16_t *) td->data + ix;
171 uint32_t * rpmtdGetUint32(rpmtd td)
173 uint32_t *res = NULL;
177 if (td->type == RPM_INT32_TYPE) {
178 int ix = (td->ix >= 0 ? td->ix : 0);
179 res = (uint32_t *) td->data + ix;
184 uint64_t * rpmtdGetUint64(rpmtd td)
186 uint64_t *res = NULL;
190 if (td->type == RPM_INT64_TYPE) {
191 int ix = (td->ix >= 0 ? td->ix : 0);
192 res = (uint64_t *) td->data + ix;
197 const char * rpmtdGetString(rpmtd td)
199 const char *str = NULL;
203 if (td->type == RPM_STRING_TYPE) {
204 str = (const char *) td->data;
205 } else if (td->type == RPM_STRING_ARRAY_TYPE ||
206 td->type == RPM_I18NSTRING_TYPE) {
207 /* XXX TODO: check for array bounds */
208 int ix = (td->ix >= 0 ? td->ix : 0);
209 str = *((const char**) td->data + ix);
214 char *rpmtdFormat(rpmtd td, rpmtdFormats fmt, const char *errmsg)
216 headerTagFormatFunction func = rpmHeaderFormatFuncByValue(fmt);
217 const char *err = NULL;
221 char fmtbuf[50]; /* yuck, get rid of this */
223 str = func(td, fmtbuf);
225 err = _("Unknown format");
235 int rpmtdSetTag(rpmtd td, rpmTag tag)
238 rpmTagType newtype = rpmTagGetType(tag);
243 * - is the new tag valid at all
244 * - if changing tag of non-empty container, require matching type
246 if (newtype == RPM_NULL_TYPE)
249 if (td->data || td->count > 0) {
250 if (rpmTagGetType(td->tag) != rpmTagGetType(tag)) {
256 td->type = newtype & RPM_MASK_TYPE;
263 int rpmtdFromArgv(rpmtd td, rpmTag tag, ARGV_t argv)
265 int count = argvCount(argv);
266 rpmTagType type = rpmTagGetType(tag) & RPM_MASK_TYPE;
268 if (type != RPM_STRING_ARRAY_TYPE || count < 1)
280 int rpmtdFromArgi(rpmtd td, rpmTag tag, ARGI_t argi)
282 int count = argiCount(argi);
283 rpmTagType type = rpmTagGetType(tag) & RPM_MASK_TYPE;
284 rpmTagReturnType retype = rpmTagGetType(tag) & RPM_MASK_RETURN_TYPE;
286 if (type != RPM_INT32_TYPE || retype != RPM_ARRAY_RETURN_TYPE || count < 1)
294 td->data = argiData(argi);
298 rpmtd rpmtdDup(rpmtd td)
305 /* TODO: permit other types too */
306 if (td->type != RPM_STRING_ARRAY_TYPE && td->type != RPM_I18NSTRING_TYPE) {
310 /* deep-copy container and data, drop immutable flag */
312 memcpy(newtd, td, sizeof(*td));
313 newtd->flags &= ~(RPMTD_IMMUTABLE);
315 newtd->flags |= (RPMTD_ALLOCED | RPMTD_PTR_ALLOCED);
316 newtd->data = data = xmalloc(td->count * sizeof(*data));
317 while ((i = rpmtdNext(td)) >= 0) {
318 data[i] = xstrdup(rpmtdGetString(td));