|
|
c1c534 |
From 75d7a0195b91b16116e5ad37d2cdd2374c80ef1b Mon Sep 17 00:00:00 2001
|
|
|
c1c534 |
Message-Id: <75d7a0195b91b16116e5ad37d2cdd2374c80ef1b@dist-git>
|
|
|
c1c534 |
From: Martin Kletzander <mkletzan@redhat.com>
|
|
|
c1c534 |
Date: Wed, 31 Jan 2018 16:32:14 +0100
|
|
|
c1c534 |
Subject: [PATCH] util: Introduce virBitmapNewString
|
|
|
c1c534 |
|
|
|
c1c534 |
https://bugzilla.redhat.com/show_bug.cgi?id=1289368
|
|
|
c1c534 |
|
|
|
c1c534 |
Our bitmaps can be represented as data (raw bytes for which we have
|
|
|
c1c534 |
virBitmapNewData() and virBitmapToData()), human representation (list
|
|
|
c1c534 |
of numbers in a string for which we have virBitmapParse() and
|
|
|
c1c534 |
virBitmapFormat()) and hexadecimal string (for which we have only
|
|
|
c1c534 |
virBitmapToString()). So let's add the missing complement for the
|
|
|
c1c534 |
last one so that we can parse hexadecimal strings.
|
|
|
c1c534 |
|
|
|
c1c534 |
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
|
|
c1c534 |
Reviewed-by: John Ferlan <jferlan@redhat.com>
|
|
|
c1c534 |
(cherry picked from commit 2e5579a43b45e55d744cac9f62aaa901e2587fee)
|
|
|
c1c534 |
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
|
|
|
c1c534 |
---
|
|
|
c1c534 |
src/libvirt_private.syms | 1 +
|
|
|
c1c534 |
src/util/virbitmap.c | 38 ++++++++++++++++++++++++++++++++++++++
|
|
|
c1c534 |
src/util/virbitmap.h | 4 ++++
|
|
|
c1c534 |
tests/virbitmaptest.c | 38 ++++++++++++++++++++++++++++++++++++++
|
|
|
c1c534 |
4 files changed, 81 insertions(+)
|
|
|
c1c534 |
|
|
|
c1c534 |
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
|
|
|
c1c534 |
index f1c6786ecf..1d895a3bf6 100644
|
|
|
c1c534 |
--- a/src/libvirt_private.syms
|
|
|
c1c534 |
+++ b/src/libvirt_private.syms
|
|
|
c1c534 |
@@ -1372,6 +1372,7 @@ virBitmapNewCopy;
|
|
|
c1c534 |
virBitmapNewData;
|
|
|
c1c534 |
virBitmapNewEmpty;
|
|
|
c1c534 |
virBitmapNewQuiet;
|
|
|
c1c534 |
+virBitmapNewString;
|
|
|
c1c534 |
virBitmapNextClearBit;
|
|
|
c1c534 |
virBitmapNextSetBit;
|
|
|
c1c534 |
virBitmapOverlaps;
|
|
|
c1c534 |
diff --git a/src/util/virbitmap.c b/src/util/virbitmap.c
|
|
|
c1c534 |
index b1c1236fd3..47d16ee222 100644
|
|
|
c1c534 |
--- a/src/util/virbitmap.c
|
|
|
c1c534 |
+++ b/src/util/virbitmap.c
|
|
|
c1c534 |
@@ -36,6 +36,7 @@
|
|
|
c1c534 |
#include "c-ctype.h"
|
|
|
c1c534 |
#include "count-one-bits.h"
|
|
|
c1c534 |
#include "virstring.h"
|
|
|
c1c534 |
+#include "virutil.h"
|
|
|
c1c534 |
#include "virerror.h"
|
|
|
c1c534 |
|
|
|
c1c534 |
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
c1c534 |
@@ -1071,6 +1072,43 @@ virBitmapCountBits(virBitmapPtr bitmap)
|
|
|
c1c534 |
return ret;
|
|
|
c1c534 |
}
|
|
|
c1c534 |
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+/**
|
|
|
c1c534 |
+ * virBitmapNewString:
|
|
|
c1c534 |
+ * @string: the string to be converted to a bitmap
|
|
|
c1c534 |
+ *
|
|
|
c1c534 |
+ * Allocate a bitmap from a string of hexadecimal data.
|
|
|
c1c534 |
+ *
|
|
|
c1c534 |
+ * Returns a pointer to the allocated bitmap or NULL if
|
|
|
c1c534 |
+ * memory cannot be allocated.
|
|
|
c1c534 |
+ */
|
|
|
c1c534 |
+virBitmapPtr
|
|
|
c1c534 |
+virBitmapNewString(const char *string)
|
|
|
c1c534 |
+{
|
|
|
c1c534 |
+ virBitmapPtr bitmap;
|
|
|
c1c534 |
+ size_t i = 0;
|
|
|
c1c534 |
+ size_t len = strlen(string);
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ if (strspn(string, "0123456789abcdefABCDEF") != len) {
|
|
|
c1c534 |
+ virReportError(VIR_ERR_INVALID_ARG,
|
|
|
c1c534 |
+ _("Invalid hexadecimal string '%s'"), string);
|
|
|
c1c534 |
+ return NULL;
|
|
|
c1c534 |
+ }
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ bitmap = virBitmapNew(len * 4);
|
|
|
c1c534 |
+ if (!bitmap)
|
|
|
c1c534 |
+ return NULL;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ for (i = 0; i < len; i++) {
|
|
|
c1c534 |
+ unsigned long nibble = virHexToBin(string[len - i - 1]);
|
|
|
c1c534 |
+ nibble <<= VIR_BITMAP_BIT_OFFSET(i * 4);
|
|
|
c1c534 |
+ bitmap->map[VIR_BITMAP_UNIT_OFFSET(i * 4)] |= nibble;
|
|
|
c1c534 |
+ }
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ return bitmap;
|
|
|
c1c534 |
+}
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+
|
|
|
c1c534 |
/**
|
|
|
c1c534 |
* virBitmapDataFormat:
|
|
|
c1c534 |
* @data: the data
|
|
|
c1c534 |
diff --git a/src/util/virbitmap.h b/src/util/virbitmap.h
|
|
|
c1c534 |
index 02acb7519d..e964a3edc9 100644
|
|
|
c1c534 |
--- a/src/util/virbitmap.h
|
|
|
c1c534 |
+++ b/src/util/virbitmap.h
|
|
|
c1c534 |
@@ -80,6 +80,10 @@ bool virBitmapIsBitSet(virBitmapPtr bitmap, size_t b)
|
|
|
c1c534 |
int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result)
|
|
|
c1c534 |
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_RETURN_CHECK;
|
|
|
c1c534 |
|
|
|
c1c534 |
+virBitmapPtr
|
|
|
c1c534 |
+virBitmapNewString(const char *string)
|
|
|
c1c534 |
+ ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
char *virBitmapToString(virBitmapPtr bitmap, bool prefix, bool trim)
|
|
|
c1c534 |
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
|
|
|
c1c534 |
|
|
|
c1c534 |
diff --git a/tests/virbitmaptest.c b/tests/virbitmaptest.c
|
|
|
c1c534 |
index 75cdddf9a7..9daa8316f3 100644
|
|
|
c1c534 |
--- a/tests/virbitmaptest.c
|
|
|
c1c534 |
+++ b/tests/virbitmaptest.c
|
|
|
c1c534 |
@@ -663,6 +663,42 @@ test12(const void *opaque ATTRIBUTE_UNUSED)
|
|
|
c1c534 |
return ret;
|
|
|
c1c534 |
}
|
|
|
c1c534 |
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+/* virBitmap(New/To)String */
|
|
|
c1c534 |
+static int
|
|
|
c1c534 |
+test13(const void *opaque ATTRIBUTE_UNUSED)
|
|
|
c1c534 |
+{
|
|
|
c1c534 |
+ virBitmapPtr map = NULL;
|
|
|
c1c534 |
+ const char *strings[] = { "1234feebee", "000c0fefe" };
|
|
|
c1c534 |
+ char *str = NULL;
|
|
|
c1c534 |
+ size_t i = 0;
|
|
|
c1c534 |
+ int ret = -1;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ for (i = 0; i < ARRAY_CARDINALITY(strings); i++) {
|
|
|
c1c534 |
+ map = virBitmapNewString(strings[i]);
|
|
|
c1c534 |
+ str = virBitmapToString(map, false, true);
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ if (!map || !str)
|
|
|
c1c534 |
+ goto cleanup;
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ if (STRNEQ(strings[i], str)) {
|
|
|
c1c534 |
+ fprintf(stderr, "\n expected bitmap string '%s' actual string "
|
|
|
c1c534 |
+ "'%s'\n", strings[i], str);
|
|
|
c1c534 |
+ goto cleanup;
|
|
|
c1c534 |
+ }
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ VIR_FREE(str);
|
|
|
c1c534 |
+ virBitmapFree(map);
|
|
|
c1c534 |
+ map = NULL;
|
|
|
c1c534 |
+ }
|
|
|
c1c534 |
+
|
|
|
c1c534 |
+ ret = 0;
|
|
|
c1c534 |
+ cleanup:
|
|
|
c1c534 |
+ VIR_FREE(str);
|
|
|
c1c534 |
+ virBitmapFree(map);
|
|
|
c1c534 |
+ return ret;
|
|
|
c1c534 |
+}
|
|
|
c1c534 |
+
|
|
|
c1c534 |
#undef TEST_MAP
|
|
|
c1c534 |
|
|
|
c1c534 |
|
|
|
c1c534 |
@@ -711,6 +747,8 @@ mymain(void)
|
|
|
c1c534 |
|
|
|
c1c534 |
if (virTestRun("test12", test12, NULL) < 0)
|
|
|
c1c534 |
ret = -1;
|
|
|
c1c534 |
+ if (virTestRun("test13", test13, NULL) < 0)
|
|
|
c1c534 |
+ ret = -1;
|
|
|
c1c534 |
|
|
|
c1c534 |
return ret;
|
|
|
c1c534 |
}
|
|
|
c1c534 |
--
|
|
|
c1c534 |
2.16.1
|
|
|
c1c534 |
|