summaryrefslogtreecommitdiff
path: root/lib/rpmtd.h
blob: 6da2482b5787c7aa443bdfb48d01021f8587c1e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#ifndef _RPMTD_H
#define _RPMTD_H

#include <rpm/rpmtypes.h>
#include <rpm/argv.h>

typedef enum rpmtdFlags_e {
    RPMTD_NONE		= 0,
    RPMTD_ALLOCED	= (1 << 0),	/* was memory allocated? */
    RPMTD_PTR_ALLOCED	= (1 << 1),	/* were array pointers allocated? */
    RPMTD_IMMUTABLE	= (1 << 2),	/* header data or modifiable? */
} rpmtdFlags;

/** \ingroup rpmtd
 * Container for rpm tag data (from headers or extensions).
 * @todo		Make this opaque (at least outside rpm itself)
 */
struct rpmtd_s {
    rpmTag tag;		/* rpm tag of this data entry*/
    rpmTagType type;	/* data type */
    rpm_count_t count;	/* number of entries */
    rpm_data_t data;	/* pointer to actual data */
    rpmtdFlags flags;	/* flags on memory allocation etc */
    int ix;		/* iteration index */
};

/** \ingroup rpmtd
 * Create new tag data container
 * @return		New, initialized tag data container.
 */
rpmtd rpmtdNew(void);

/** \ingroup rpmtd
 * Destroy tag data container.
 * @param td		Tag data container
 * @return		NULL always
 */
rpmtd rpmtdFree(rpmtd td);
 
/** \ingroup rpmtd
 * (Re-)initialize tag data container. Contents will be zeroed out
 * and iteration index reset.
 * @param td		Tag data container
 */
void rpmtdReset(rpmtd td);

/** \ingroup rpmtd
 * Free contained data. This is always safe to call as the container knows 
 * if data was malloc'ed or not. Container is reinitialized.
 * @param td		Tag data container
 */
void rpmtdFreeData(rpmtd td);

/** \ingroup rpmtd
 * Retrieve array size of the container. For non-array types this is always 1.
 * @param td		Tag data container
 * @return		Number of entries in contained data.
 */
rpm_count_t rpmtdCount(rpmtd td);

/** \ingroup rpmtd
 * Retrieve tag of the container.
 * @param td		Tag data container
 * @return		Rpm tag.
 */
rpmTag rpmtdTag(rpmtd td);

/** \ingroup rpmtd
 * Retrieve type of the container.
 * @param td		Tag data container
 * @return		Rpm tag type.
 */
rpmTagType rpmtdType(rpmtd td);

/** \ingroup rpmtd
 * Retrieve current iteration index of the container.
 * @param td		Tag data container
 * @return		Iteration index (or -1 if not iterating)
 */
int rpmtdGetIndex(rpmtd td);

/** \ingroup rpmtd
 * Set iteration index of the container.
 * If new index is out of bounds for the container, -1 is returned and
 * iteration index is left untouched. 
 * @param td		Tag data container
 * @param index		New index
 * @return		New index, or -1 if index out of bounds
 */
int rpmtdSetIndex(rpmtd td, int index);

/** \ingroup rpmtd
 * Initialize tag container for iteration
 * @param td		Tag data container
 * @return		0 on success
 */
int rpmtdInit(rpmtd td);

/** \ingroup rpmtd
 * Iterate over tag data container.
 * @param td		Tag data container
 * @return		Tag data container iterator index, -1 on termination
 */
int rpmtdNext(rpmtd td);

/** \ingroup rpmtd
 * Iterate over uint32_t type tag data container.
 * @param td		Tag data container
 * @return		Pointer to next value, NULL on termination or error
 */
uint32_t *rpmtdNextUint32(rpmtd td);

/** \ingroup rpmtd
 * Iterate over string / string array type tag data container.
 * @param td		Tag data container
 * @return		Pointer to next value, NULL on termination or error
 */
const char *rpmtdNextString(rpmtd td);

/** \ingroup rpmtd
 * Return char data from tag container.
 * For scalar return type, just return pointer to the integer. On array
 * types, return pointer to current iteration index. If the tag container
 * is not for char type, NULL is returned.
 * @param td		Tag data container
 * @return		Pointer to uint16_t, NULL on error
 */
char *rpmtdGetChar(rpmtd td);

/** \ingroup rpmtd
 * Return uint16_t data from tag container.
 * For scalar return type, just return pointer to the integer. On array
 * types, return pointer to current iteration index. If the tag container
 * is not for int16 type, NULL is returned.
 * @param td		Tag data container
 * @return		Pointer to uint16_t, NULL on error
 */
uint16_t * rpmtdGetUint16(rpmtd td);

/** \ingroup rpmtd
 * Return uint32_t data from tag container.
 * For scalar return type, just return pointer to the integer. On array
 * types, return pointer to current iteration index. If the tag container
 * is not for int32 type, NULL is returned.
 * @param td		Tag data container
 * @return		Pointer to uint32_t, NULL on error
 */
uint32_t * rpmtdGetUint32(rpmtd td);

/** \ingroup rpmtd
 * Return string data from tag container.
 * For string types, just return the string. On string array types,
 * return the string from current iteration index. If the tag container
 * is not for a string type, NULL is returned.
 * @param td		Tag data container
 * @return		String constant from container, NULL on error
 */
const char * rpmtdGetString(rpmtd td);

typedef enum rpmtdFormats_e {
    RPMTD_FORMAT_STRING		= 0,	/* plain string (any type) */
    RPMTD_FORMAT_ARMOR		= 1,	/* ascii armor format (bin types) */
    RPMTD_FORMAT_BASE64		= 2,	/* base64 encoding (bin types) */
    RPMTD_FORMAT_PGPSIG		= 3,	/* pgp/gpg signature (bin types) */
    RPMTD_FORMAT_DEPFLAGS	= 4,	/* dependency flags (int32 types) */
    RPMTD_FORMAT_FFLAGS		= 5,	/* file flags (int32 types) */
    RPMTD_FORMAT_PERMS		= 6,	/* permission string (int32 types) */
    RPMTD_FORMAT_TRIGGERTYPE	= 7,	/* trigger types */
    RPMTD_FORMAT_XML		= 8,	/* xml format (any type) */
    RPMTD_FORMAT_OCTAL		= 9,	/* octal format (int32 types) */
    RPMTD_FORMAT_HEX		= 10,	/* hex format (int32 types) */
    RPMTD_FORMAT_DATE		= 11,	/* date format (int32 types) */
    RPMTD_FORMAT_DAY		= 12,	/* day format (int32 types) */
    RPMTD_FORMAT_SHESCAPE	= 13,	/* shell escaped (any type) */
    RPMTD_FORMAT_ARRAYSIZE	= 14,	/* size of contained array (any type) */
} rpmtdFormats;

/** \ingroup rpmtd
 * Format data from tag container to string presentation of given format.
 * Return malloced string presentation of current data in container,
 * converting from integers etc as necessary. On array types, data from
 * current iteration index is used for formatting.
 * @param td		Tag data container
 * @param fmt		Format to apply
 * @param errmsg	Error message from conversion (or NULL)
 * @return		String representation of current data (malloc'ed), 
 * 			NULL on error
 */
char *rpmtdFormat(rpmtd td, rpmtdFormats fmt, const char *errmsg);

/** \ingroup rpmtd
 * Set container tag and type.
 * For empty container, any valid tag can be set. If the container has
 * data, changing is only permitted to tag of same type. 
 * @param td		Tag data container
 * @param tag		New tag
 * @return		1 on success, 0 on error
 */
int rpmtdSetTag(rpmtd td, rpmTag tag);

/** \ingroup rpmtd
 * Construct tag container from ARGV_t array.
 * Tag type is checked to be of string array type and array is checked
 * to be non-empty.
 * @param td		Tag data container
 * @param tag		Rpm tag to construct
 * @param argv		ARGV array
 * @return		1 on success, 0 on error (eg wrong type)
 */
int rpmtdFromArgv(rpmtd td, rpmTag tag, ARGV_t argv);

/** \ingroup rpmtd
 * Construct tag container from ARGI_t array.
 * Tag type is checked to be of integer array type and array is checked
 * to be non-empty.
 * @param td		Tag data container
 * @param tag		Rpm tag to construct
 * @param argi		ARGI array
 * @return		1 on success, 0 on error (eg wrong type)
 */
int rpmtdFromArgi(rpmtd td, rpmTag tag, ARGI_t argi);

/* \ingroup rpmtd
 * Perform deep copy of container.
 * Create a modifiable copy of tag data container (on string arrays each
 * string is separately allocated)
 * @todo		Only string arrays types are supported currently
 * @param td		Container to copy
 * @return		New container or NULL on error
 */
rpmtd rpmtdDup(rpmtd td);

#endif /* _RPMTD_H */