1 #ifndef _RPMTD_H
2 #define _RPMTD_H
3 
4 /** \ingroup rpmtd
5  *  \file lib/rpmtd.h
6  *
7  *  RPM Tag Data Container API
8  */
9 
10 #include <rpm/rpmtypes.h>
11 #include <rpm/argv.h>
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 enum rpmtdFlags_e {
18     RPMTD_NONE		= 0,
19     RPMTD_ALLOCED	= (1 << 0),	/* was memory allocated? */
20     RPMTD_PTR_ALLOCED	= (1 << 1),	/* were array pointers allocated? */
21     RPMTD_IMMUTABLE	= (1 << 2),	/* header data or modifiable? */
22     RPMTD_ARGV		= (1 << 3),	/* string array is NULL-terminated? */
23     RPMTD_INVALID	= (1 << 4),	/* invalid data (in header) */
24 };
25 
26 typedef rpmFlags rpmtdFlags;
27 
28 /** \ingroup rpmtd
29  * Container for rpm tag data (from headers or extensions).
30  * @todo		Make this opaque (at least outside rpm itself)
31  */
32 struct rpmtd_s {
33     rpm_tag_t tag;	/* rpm tag of this data entry*/
34     rpm_tagtype_t type;	/* data type */
35     rpm_count_t count;	/* number of entries */
36     rpm_data_t data;	/* pointer to actual data */
37     rpmtdFlags flags;	/* flags on memory allocation etc */
38     int ix;		/* iteration index */
39     rpm_count_t size;	/* size of data (only works for RPMTD_IMMUTABLE atm) */
40 };
41 
42 /** \ingroup rpmtd
43  * Create new tag data container
44  * @return		New, initialized tag data container.
45  */
46 rpmtd rpmtdNew(void);
47 
48 /** \ingroup rpmtd
49  * Destroy tag data container.
50  * @param td		Tag data container
51  * @return		NULL always
52  */
53 rpmtd rpmtdFree(rpmtd td);
54 
55 /** \ingroup rpmtd
56  * (Re-)initialize tag data container. Contents will be zeroed out
57  * and iteration index reset.
58  * @param td		Tag data container
59  */
60 void rpmtdReset(rpmtd td);
61 
62 /** \ingroup rpmtd
63  * Free contained data. This is always safe to call as the container knows
64  * if data was malloc'ed or not. Container is reinitialized.
65  * @param td		Tag data container
66  */
67 void rpmtdFreeData(rpmtd td);
68 
69 /** \ingroup rpmtd
70  * Retrieve array size of the container. For non-array types this is always 1.
71  * @param td		Tag data container
72  * @return		Number of entries in contained data.
73  */
74 rpm_count_t rpmtdCount(rpmtd td);
75 
76 /** \ingroup rpmtd
77  * Retrieve container data size (eg required for allocation).
78  * Note this currently only works for RPMTD_IMMUTABLE data.
79  * @param td		Tag data container
80  * @return		Data size in bytes.
81  */
82 rpm_count_t rpmtdSize(rpmtd td);
83 
84 /** \ingroup rpmtd
85  * Retrieve tag of the container.
86  * @param td		Tag data container
87  * @return		Rpm tag.
88  */
89 rpmTagVal rpmtdTag(rpmtd td);
90 
91 /** \ingroup rpmtd
92  * Retrieve type of the container.
93  * @param td		Tag data container
94  * @return		Rpm tag type.
95  */
96 rpmTagType rpmtdType(rpmtd td);
97 
98 /** \ingroup rpmtd
99  * Retrieve class of the container.
100  * @param td		Tag data container
101  * @return		Rpm tag class
102  */
103 rpmTagClass rpmtdClass(rpmtd td);
104 
105 /** \ingroup rpmtd
106  * Retrieve flags of the container (allocation details etc)
107  * @param td		Tag data container
108  * @return		Container flags
109  */
110 rpmtdFlags rpmtdGetFlags(rpmtd td);
111 
112 /** \ingroup rpmtd
113  * Retrieve current iteration index of the container.
114  * @param td		Tag data container
115  * @return		Iteration index (or -1 if not iterating)
116  */
117 int rpmtdGetIndex(rpmtd td);
118 
119 /** \ingroup rpmtd
120  * Set iteration index of the container.
121  * If new index is out of bounds for the container, -1 is returned and
122  * iteration index is left untouched.
123  * @param td		Tag data container
124  * @param index		New index
125  * @return		New index, or -1 if index out of bounds
126  */
127 int rpmtdSetIndex(rpmtd td, int index);
128 
129 /** \ingroup rpmtd
130  * Initialize tag container for iteration
131  * @param td		Tag data container
132  * @return		0 on success
133  */
134 int rpmtdInit(rpmtd td);
135 
136 /** \ingroup rpmtd
137  * Iterate over tag data container.
138  * @param td		Tag data container
139  * @return		Tag data container iterator index, -1 on termination
140  */
141 int rpmtdNext(rpmtd td);
142 
143 /** \ingroup rpmtd
144  * Iterate over uint32_t type tag data container.
145  * @param td		Tag data container
146  * @return		Pointer to next value, NULL on termination or error
147  */
148 uint32_t *rpmtdNextUint32(rpmtd td);
149 
150 /** \ingroup rpmtd
151  * Iterate over uint64_t type tag data container.
152  * @param td		Tag data container
153  * @return		Pointer to next value, NULL on termination or error
154  */
155 uint64_t *rpmtdNextUint64(rpmtd td);
156 
157 /** \ingroup rpmtd
158  * Iterate over string / string array type tag data container.
159  * @param td		Tag data container
160  * @return		Pointer to next value, NULL on termination or error
161  */
162 const char *rpmtdNextString(rpmtd td);
163 
164 /** \ingroup rpmtd
165  * Return char data from tag container.
166  * For scalar return type, just return pointer to the integer. On array
167  * types, return pointer to current iteration index. If the tag container
168  * is not for char type, NULL is returned.
169  * @param td		Tag data container
170  * @return		Pointer to uint16_t, NULL on error
171  */
172 char *rpmtdGetChar(rpmtd td);
173 
174 /** \ingroup rpmtd
175  * Return uint16_t data from tag container.
176  * For scalar return type, just return pointer to the integer. On array
177  * types, return pointer to current iteration index. If the tag container
178  * is not for int16 type, NULL is returned.
179  * @param td		Tag data container
180  * @return		Pointer to uint16_t, NULL on error
181  */
182 uint16_t * rpmtdGetUint16(rpmtd td);
183 
184 /** \ingroup rpmtd
185  * Return uint32_t data from tag container.
186  * For scalar return type, just return pointer to the integer. On array
187  * types, return pointer to current iteration index. If the tag container
188  * is not for int32 type, NULL is returned.
189  * @param td		Tag data container
190  * @return		Pointer to uint32_t, NULL on error
191  */
192 uint32_t * rpmtdGetUint32(rpmtd td);
193 
194 /** \ingroup rpmtd
195  * Return uint64_t data from tag container.
196  * For scalar return type, just return pointer to the integer. On array
197  * types, return pointer to current iteration index. If the tag container
198  * is not for int64 type, NULL is returned.
199  * @param td		Tag data container
200  * @return		Pointer to uint64_t, NULL on error
201  */
202 uint64_t * rpmtdGetUint64(rpmtd td);
203 
204 /** \ingroup rpmtd
205  * Return string data from tag container.
206  * For string types, just return the string. On string array types,
207  * return the string from current iteration index. If the tag container
208  * is not for a string type, NULL is returned.
209  * @param td		Tag data container
210  * @return		String constant from container, NULL on error
211  */
212 const char * rpmtdGetString(rpmtd td);
213 
214 /** \ingroup rpmtd
215  * Return numeric value from tag container.
216  * Returns the value of numeric container (RPM_NUMERIC_CLASS) from
217  * current iteration index as uint64_t regardless of its internal
218  * presentation (8/16/32/64-bit integer).
219  * @param td		Tag data container
220  * @return		Value of current iteration item as uint64_t,
221  * 			0 for non-numeric types (error)
222  */
223 uint64_t rpmtdGetNumber(rpmtd td);
224 
225 typedef enum rpmtdFormats_e {
226     RPMTD_FORMAT_STRING		= 0,	/* plain string (any type) */
227     RPMTD_FORMAT_ARMOR		= 1,	/* ascii armor format (bin types) */
228     RPMTD_FORMAT_BASE64		= 2,	/* base64 encoding (bin types) */
229     RPMTD_FORMAT_PGPSIG		= 3,	/* pgp/gpg signature (bin types) */
230     RPMTD_FORMAT_DEPFLAGS	= 4,	/* dependency flags (int types) */
231     RPMTD_FORMAT_FFLAGS		= 5,	/* file flags (int types) */
232     RPMTD_FORMAT_PERMS		= 6,	/* permission string (int types) */
233     RPMTD_FORMAT_TRIGGERTYPE	= 7,	/* trigger types (int types) */
234     RPMTD_FORMAT_XML		= 8,	/* xml format (any type) */
235     RPMTD_FORMAT_OCTAL		= 9,	/* octal format (int types) */
236     RPMTD_FORMAT_HEX		= 10,	/* hex format (int types) */
237     RPMTD_FORMAT_DATE		= 11,	/* date format (int types) */
238     RPMTD_FORMAT_DAY		= 12,	/* day format (int types) */
239     RPMTD_FORMAT_SHESCAPE	= 13,	/* shell escaped (any type) */
240     RPMTD_FORMAT_ARRAYSIZE	= 14,	/* size of contained array (any type) */
241     RPMTD_FORMAT_DEPTYPE	= 15,	/* dependency types (int types) */
242     RPMTD_FORMAT_FSTATE		= 16,	/* file states (int types) */
243     RPMTD_FORMAT_VFLAGS		= 17,	/* file verify flags (int types) */
244     RPMTD_FORMAT_EXPAND		= 18,	/* macro expansion (string types) */
245     RPMTD_FORMAT_FSTATUS	= 19,	/* file verify status (int types) */
246     RPMTD_FORMAT_HUMANSI	= 20,	/* human readable value, K = 1000 (int types) */
247     RPMTD_FORMAT_HUMANIEC	= 21,	/* human readable value, K = 1024 (int types) */
248 } rpmtdFormats;
249 
250 /** \ingroup rpmtd
251  * Format data from tag container to string presentation of given format.
252  * Return malloced string presentation of current data in container,
253  * converting from integers etc as necessary. On array types, data from
254  * current iteration index is used for formatting.
255  * @param td		Tag data container
256  * @param fmt		Format to apply
257  * @param errmsg	Error message from conversion (or NULL)
258  * @return		String representation of current data (malloc'ed),
259  * 			NULL on error
260  */
261 char *rpmtdFormat(rpmtd td, rpmtdFormats fmt, const char *errmsg);
262 
263 /** \ingroup rpmtd
264  * Set container tag and type.
265  * For empty container, any valid tag can be set. If the container has
266  * data, changing is only permitted to tag of same type.
267  * @param td		Tag data container
268  * @param tag		New tag
269  * @return		1 on success, 0 on error
270  */
271 int rpmtdSetTag(rpmtd td, rpmTagVal tag);
272 
273 /** \ingroup rpmtd
274  * Construct tag container from uint8_t pointer.
275  * Tag type is checked to be of compatible type (CHAR, INT8 or BIN).
276  * For non-array types (BIN is a special case of INT8 array)
277  * count must be exactly 1.
278  * @param td		Tag data container
279  * @param tag		Rpm tag to construct
280  * @param data		Pointer to uint8_t (value or array)
281  * @param count		Number of entries
282  * @return		1 on success, 0 on error (eg wrong type)
283  */
284 int rpmtdFromUint8(rpmtd td, rpmTagVal tag, uint8_t *data, rpm_count_t count);
285 
286 /** \ingroup rpmtd
287  * Construct tag container from uint16_t pointer.
288  * Tag type is checked to be of INT16 type. For non-array types count
289  * must be exactly 1.
290  * @param td		Tag data container
291  * @param tag		Rpm tag to construct
292  * @param data		Pointer to uint16_t (value or array)
293  * @param count		Number of entries
294  * @return		1 on success, 0 on error (eg wrong type)
295  */
296 int rpmtdFromUint16(rpmtd td, rpmTagVal tag, uint16_t *data, rpm_count_t count);
297 
298 /** \ingroup rpmtd
299  * Construct tag container from uint32_t pointer.
300  * Tag type is checked to be of INT32 type. For non-array types count
301  * must be exactly 1.
302  * @param td		Tag data container
303  * @param tag		Rpm tag to construct
304  * @param data		Pointer to uint32_t (value or array)
305  * @param count		Number of entries
306  * @return		1 on success, 0 on error (eg wrong type)
307  */
308 int rpmtdFromUint32(rpmtd td, rpmTagVal tag, uint32_t *data, rpm_count_t count);
309 
310 /** \ingroup rpmtd
311  * Construct tag container from uint64_t pointer.
312  * Tag type is checked to be of INT64 type. For non-array types count
313  * must be exactly 1.
314  * @param td		Tag data container
315  * @param tag		Rpm tag to construct
316  * @param data		Pointer to uint64_t (value or array)
317  * @param count		Number of entries
318  * @return		1 on success, 0 on error (eg wrong type)
319  */
320 int rpmtdFromUint64(rpmtd td, rpmTagVal tag, uint64_t *data, rpm_count_t count);
321 
322 /** \ingroup rpmtd
323  * Construct tag container from a string.
324  * Tag type is checked to be of string type.
325  * @param td		Tag data container
326  * @param tag		Rpm tag to construct
327  * @param data		String to use
328  * @return		1 on success, 0 on error (eg wrong type)
329  */
330 int rpmtdFromString(rpmtd td, rpmTagVal tag, const char *data);
331 
332 /** \ingroup rpmtd
333  * Construct tag container from a string array.
334  * Tag type is checked to be of string or string array type. For non-array
335  * types count must be exactly 1.
336  * @param td		Tag data container
337  * @param tag		Rpm tag to construct
338  * @param data		Pointer to string array
339  * @param count		Number of entries
340  * @return		1 on success, 0 on error (eg wrong type)
341  */
342 int rpmtdFromStringArray(rpmtd td, rpmTagVal tag, const char **data, rpm_count_t count);
343 
344 /** \ingroup rpmtd
345  * Construct tag container from ARGV_t array.
346  * Tag type is checked to be of string array type and array is checked
347  * to be non-empty.
348  * @param td		Tag data container
349  * @param tag		Rpm tag to construct
350  * @param argv		ARGV array
351  * @return		1 on success, 0 on error (eg wrong type)
352  */
353 int rpmtdFromArgv(rpmtd td, rpmTagVal tag, ARGV_t argv);
354 
355 /** \ingroup rpmtd
356  * Construct tag container from ARGI_t array.
357  * Tag type is checked to be of integer array type and array is checked
358  * to be non-empty.
359  * @param td		Tag data container
360  * @param tag		Rpm tag to construct
361  * @param argi		ARGI array
362  * @return		1 on success, 0 on error (eg wrong type)
363  */
364 int rpmtdFromArgi(rpmtd td, rpmTagVal tag, ARGI_t argi);
365 
366 /** \ingroup rpmtd
367  * Perform deep copy of container.
368  * Create a modifiable copy of tag data container (on string arrays each
369  * string is separately allocated)
370  * @todo		Only string arrays types are supported currently
371  * @param td		Container to copy
372  * @return		New container or NULL on error
373  */
374 rpmtd rpmtdDup(rpmtd td);
375 
376 /** \ingroup rpmtd
377  * Push string array container contents to a string pool, return string ids.
378  * @param td		Tag data container
379  * @param pool		String pool
380  * @return		Array of string id's (malloced)
381  */
382 rpmsid * rpmtdToPool(rpmtd td, rpmstrPool pool);
383 
384 #ifdef __cplusplus
385 }
386 #endif
387 
388 #endif /* _RPMTD_H */
389