util: Introduce virBitmapNewString

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>
This commit is contained in:
Martin Kletzander 2017-08-23 09:12:10 +02:00
parent fb10602875
commit 2e5579a43b
4 changed files with 81 additions and 0 deletions

View File

@ -1365,6 +1365,7 @@ virBitmapNewCopy;
virBitmapNewData; virBitmapNewData;
virBitmapNewEmpty; virBitmapNewEmpty;
virBitmapNewQuiet; virBitmapNewQuiet;
virBitmapNewString;
virBitmapNextClearBit; virBitmapNextClearBit;
virBitmapNextSetBit; virBitmapNextSetBit;
virBitmapOverlaps; virBitmapOverlaps;

View File

@ -36,6 +36,7 @@
#include "c-ctype.h" #include "c-ctype.h"
#include "count-one-bits.h" #include "count-one-bits.h"
#include "virstring.h" #include "virstring.h"
#include "virutil.h"
#include "virerror.h" #include "virerror.h"
#define VIR_FROM_THIS VIR_FROM_NONE #define VIR_FROM_THIS VIR_FROM_NONE
@ -1071,6 +1072,43 @@ virBitmapCountBits(virBitmapPtr bitmap)
return ret; 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: * virBitmapDataFormat:
* @data: the data * @data: the data

View File

@ -80,6 +80,10 @@ bool virBitmapIsBitSet(virBitmapPtr bitmap, size_t b)
int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result) int virBitmapGetBit(virBitmapPtr bitmap, size_t b, bool *result)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_RETURN_CHECK; 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) char *virBitmapToString(virBitmapPtr bitmap, bool prefix, bool trim)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;

View File

@ -663,6 +663,42 @@ test12(const void *opaque ATTRIBUTE_UNUSED)
return ret; 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 #undef TEST_MAP
@ -711,6 +747,8 @@ mymain(void)
if (virTestRun("test12", test12, NULL) < 0) if (virTestRun("test12", test12, NULL) < 0)
ret = -1; ret = -1;
if (virTestRun("test13", test13, NULL) < 0)
ret = -1;
return ret; return ret;
} }