]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: Introduce virBitmapNewString
authorMartin Kletzander <mkletzan@redhat.com>
Wed, 23 Aug 2017 07:12:10 +0000 (09:12 +0200)
committerMartin Kletzander <mkletzan@redhat.com>
Sat, 18 Nov 2017 09:45:10 +0000 (10:45 +0100)
Our bitmaps can be represented as data (raw bytes for which we have
virBitmapNewData() and virBitmapToData()), human representation (list
of numbers in a string for which we have virBitmapParse() and
virBitmapFormat()) and hexadecimal string (for which we have only
virBitmapToString()).  So let's add the missing complement for the
last one so that we can parse hexadecimal strings.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: John Ferlan <jferlan@redhat.com>
src/libvirt_private.syms
src/util/virbitmap.c
src/util/virbitmap.h
tests/virbitmaptest.c

index 79ce11b29c81817dcbf66cae18ff69f940807c10..9d845c7f63f3ce8c1c46c70cf37ff039d9acc6a6 100644 (file)
@@ -1365,6 +1365,7 @@ virBitmapNewCopy;
 virBitmapNewData;
 virBitmapNewEmpty;
 virBitmapNewQuiet;
+virBitmapNewString;
 virBitmapNextClearBit;
 virBitmapNextSetBit;
 virBitmapOverlaps;
index b1c1236fd3ac98126cc1bad32911f34b3629cf0e..47d16ee2228f6b74194dd37853994d6a6834b638 100644 (file)
@@ -36,6 +36,7 @@
 #include "c-ctype.h"
 #include "count-one-bits.h"
 #include "virstring.h"
+#include "virutil.h"
 #include "virerror.h"
 
 #define VIR_FROM_THIS VIR_FROM_NONE
@@ -1071,6 +1072,43 @@ virBitmapCountBits(virBitmapPtr bitmap)
     return ret;
 }
 
+
+/**
+ * virBitmapNewString:
+ * @string: the string to be converted to a bitmap
+ *
+ * Allocate a bitmap from a string of hexadecimal data.
+ *
+ * Returns a pointer to the allocated bitmap or NULL if
+ * memory cannot be allocated.
+ */
+virBitmapPtr
+virBitmapNewString(const char *string)
+{
+    virBitmapPtr bitmap;
+    size_t i = 0;
+    size_t len = strlen(string);
+
+    if (strspn(string, "0123456789abcdefABCDEF") != len) {
+        virReportError(VIR_ERR_INVALID_ARG,
+                       _("Invalid hexadecimal string '%s'"), string);
+        return NULL;
+    }
+
+    bitmap = virBitmapNew(len * 4);
+    if (!bitmap)
+        return NULL;
+
+    for (i = 0; i < len; i++) {
+        unsigned long nibble = virHexToBin(string[len - i - 1]);
+        nibble <<= VIR_BITMAP_BIT_OFFSET(i * 4);
+        bitmap->map[VIR_BITMAP_UNIT_OFFSET(i * 4)] |= nibble;
+    }
+
+    return bitmap;
+}
+
+
 /**
  * virBitmapDataFormat:
  * @data: the data
index 02acb7519d370235ebbf819da37b50365486f825..e964a3edc9cbb4896921660ed9fc385c07f0f705 100644 (file)
@@ -80,6 +80,10 @@ bool virBitmapIsBitSet(virBitmapPtr bitmap, size_t b)
 int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_RETURN_CHECK;
 
+virBitmapPtr
+virBitmapNewString(const char *string)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
+
 char *virBitmapToString(virBitmapPtr bitmap, bool prefix, bool trim)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
 
index b666065346ee3ddd0c4650d5ec3bde16d24f6bea..656ce456295f90b964d34ff4f526518de70606fd 100644 (file)
@@ -663,6 +663,42 @@ test12(const void *opaque ATTRIBUTE_UNUSED)
     return ret;
 }
 
+
+/* virBitmap(New/To)String */
+static int
+test13(const void *opaque ATTRIBUTE_UNUSED)
+{
+    virBitmapPtr map = NULL;
+    const char *strings[] = { "1234feebee", "000c0fefe" };
+    char *str = NULL;
+    size_t i = 0;
+    int ret = -1;
+
+    for (i = 0; i < ARRAY_CARDINALITY(strings); i++) {
+        map = virBitmapNewString(strings[i]);
+        str = virBitmapToString(map, false, true);
+
+        if (!map || !str)
+            goto cleanup;
+
+        if (STRNEQ(strings[i], str)) {
+            fprintf(stderr, "\n expected bitmap string '%s' actual string "
+                    "'%s'\n", strings[i], str);
+            goto cleanup;
+        }
+
+        VIR_FREE(str);
+        virBitmapFree(map);
+        map = NULL;
+    }
+
+    ret = 0;
+ cleanup:
+    VIR_FREE(str);
+    virBitmapFree(map);
+    return ret;
+}
+
 #undef TEST_MAP
 
 
@@ -711,6 +747,8 @@ mymain(void)
 
     if (virTestRun("test12", test12, NULL) < 0)
         ret = -1;
+    if (virTestRun("test13", test13, NULL) < 0)
+        ret = -1;
 
     return ret;
 }