Add some new rpmtd creation methods
authorPanu Matilainen <pmatilai@redhat.com>
Tue, 17 Jun 2008 09:07:19 +0000 (12:07 +0300)
committerPanu Matilainen <pmatilai@redhat.com>
Tue, 17 Jun 2008 09:07:19 +0000 (12:07 +0300)
- rpmtdFromString(), rpmtdFromStringArray() and rpmtdFromUint32() permit
  populating tag containers of compatible datatypes that can be used for
  headerPut() with some extra type-safety and sanity checks on the types

lib/rpmtd.c
lib/rpmtd.h

index 2c377a4..e86c1b5 100644 (file)
@@ -260,6 +260,59 @@ exit:
     return rc;
 }
 
+static inline int rpmtdSet(rpmtd td, rpmTag tag, rpmTagType type, 
+                           rpm_constdata_t data, rpm_count_t count)
+{
+    rpmtdReset(td);
+    td->tag = tag;
+    td->type = type;
+    td->count = count;
+    /* 
+     * Discards const, but we won't touch the data (even rpmtdFreeData()
+     * wont free it as allocation flags aren't set) so it's "ok". 
+     * XXX: Should there be a separate RPMTD_FOO flag for "user data"?
+     */
+    td->data = (void *) data;
+    return 1;
+}
+
+int rpmtdFromUint32(rpmtd td, rpmTag tag, uint32_t *data, rpm_count_t count)
+{
+    rpmTagType type = rpmTagGetType(tag) & RPM_MASK_TYPE;
+    rpmTagReturnType retype = rpmTagGetType(tag) & RPM_MASK_RETURN_TYPE;
+    if (type != RPM_INT32_TYPE || count < 1) 
+       return 0;
+    if (retype != RPM_ARRAY_RETURN_TYPE && count > 1) 
+       return 0;
+    
+    return rpmtdSet(td, tag, type, data, count);
+}
+
+int rpmtdFromString(rpmtd td, rpmTag tag, const char *data)
+{
+    rpmTagType type = rpmTagGetType(tag) & RPM_MASK_TYPE;
+    int rc = 0;
+
+    if (type == RPM_STRING_TYPE) {
+       rc = rpmtdSet(td, tag, type, data, 1);
+    } else if (type == RPM_STRING_ARRAY_TYPE) {
+       rc = rpmtdSet(td, tag, type, &data, 1);
+    }
+
+    return rc;
+}
+
+int rpmtdFromStringArray(rpmtd td, rpmTag tag, char **data, rpm_count_t count)
+{
+    rpmTagType type = rpmTagGetType(tag) & RPM_MASK_TYPE;
+    if (type != RPM_STRING_ARRAY_TYPE || count < 1)
+       return 0;
+    if (type == RPM_STRING_TYPE && count != 1)
+       return 0;
+
+    return rpmtdSet(td, tag, type, data, count);
+}
+
 int rpmtdFromArgv(rpmtd td, rpmTag tag, ARGV_t argv)
 {
     int count = argvCount(argv);
@@ -268,13 +321,7 @@ int rpmtdFromArgv(rpmtd td, rpmTag tag, ARGV_t argv)
     if (type != RPM_STRING_ARRAY_TYPE || count < 1)
        return 0;
 
-    assert(td != NULL);
-    rpmtdReset(td);
-    td->type = type;
-    td->tag = tag;
-    td->count = count;
-    td->data = argv;
-    return 1;
+    return rpmtdSet(td, tag, type, argv, count);
 }
 
 int rpmtdFromArgi(rpmtd td, rpmTag tag, ARGI_t argi)
@@ -286,13 +333,7 @@ int rpmtdFromArgi(rpmtd td, rpmTag tag, ARGI_t argi)
     if (type != RPM_INT32_TYPE || retype != RPM_ARRAY_RETURN_TYPE || count < 1)
        return 0;
 
-    assert(td != NULL);
-    rpmtdReset(td);
-    td->type = type;
-    td->tag = tag;
-    td->count = count;
-    td->data = argiData(argi);
-    return 1;
+    return rpmtdSet(td, tag, type, argiData(argi), count);
 }
 
 rpmtd rpmtdDup(rpmtd td)
index ac72ddd..7ebea39 100644 (file)
@@ -216,6 +216,40 @@ char *rpmtdFormat(rpmtd td, rpmtdFormats fmt, const char *errmsg);
 int rpmtdSetTag(rpmtd td, rpmTag tag);
 
 /** \ingroup rpmtd
+ * Construct tag container from uint32_t pointer.
+ * Tag type is checked to be of INT32 type. For non-array types count
+ * must be exactly 1.
+ * @param td           Tag data container
+ * @param tag          Rpm tag to construct
+ * @param data         Pointer to uint32_t (value or array)
+ * @param count                Number of entries
+ * @return             1 on success, 0 on error (eg wrong type)
+ */
+int rpmtdFromUint32(rpmtd td, rpmTag tag, uint32_t *data, rpm_count_t count);
+
+/** \ingroup rpmtd
+ * Construct tag container from a string.
+ * Tag type is checked to be of string type. 
+ * @param td           Tag data container
+ * @param tag          Rpm tag to construct
+ * @param data         String to use
+ * @return             1 on success, 0 on error (eg wrong type)
+ */
+int rpmtdFromString(rpmtd td, rpmTag tag, const char *data);
+
+/** \ingroup rpmtd
+ * Construct tag container from a string array.
+ * Tag type is checked to be of string or string array type. For non-array
+ * types count must be exactly 1.
+ * @param td           Tag data container
+ * @param tag          Rpm tag to construct
+ * @param data         Pointer to string array
+ * @param count                Number of entries
+ * @return             1 on success, 0 on error (eg wrong type)
+ */
+int rpmtdFromStringArray(rpmtd td, rpmTag tag, char **data, rpm_count_t count);
+
+/** \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.