mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-01 06:27:16 +00:00
util: Introduce virBufferAddBuffer
This API joins the following two lines: char *s = virBufferContentAndReset(buf1); virBufferAdd(buf2, s, -1); into one: virBufferAddBuffer(buf2, buf1); With one exception: there's no re-indentation applied to @buf1. The idea is, that in general both can have different indentation (like the test I'm adding proves) Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
efd30e2e1c
commit
83c5467ee9
@ -1081,6 +1081,7 @@ virBitmapToData;
|
|||||||
|
|
||||||
# util/virbuffer.h
|
# util/virbuffer.h
|
||||||
virBufferAdd;
|
virBufferAdd;
|
||||||
|
virBufferAddBuffer;
|
||||||
virBufferAddChar;
|
virBufferAddChar;
|
||||||
virBufferAdjustIndent;
|
virBufferAdjustIndent;
|
||||||
virBufferAsprintf;
|
virBufferAsprintf;
|
||||||
|
@ -162,8 +162,7 @@ virBufferAdd(virBufferPtr buf, const char *str, int len)
|
|||||||
len = strlen(str);
|
len = strlen(str);
|
||||||
|
|
||||||
needSize = buf->use + indent + len + 2;
|
needSize = buf->use + indent + len + 2;
|
||||||
if (needSize > buf->size &&
|
if (virBufferGrow(buf, needSize - buf->use) < 0)
|
||||||
virBufferGrow(buf, needSize - buf->use) < 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
memset(&buf->content[buf->use], ' ', indent);
|
memset(&buf->content[buf->use], ' ', indent);
|
||||||
@ -172,6 +171,43 @@ virBufferAdd(virBufferPtr buf, const char *str, int len)
|
|||||||
buf->content[buf->use] = '\0';
|
buf->content[buf->use] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virBufferAddBuffer:
|
||||||
|
* @buf: the buffer to append to
|
||||||
|
* @toadd: the buffer to append
|
||||||
|
*
|
||||||
|
* Add a buffer into another buffer without need to go through:
|
||||||
|
* virBufferContentAndReset(), virBufferAdd(). Auto indentation
|
||||||
|
* is (intentionally) NOT applied!
|
||||||
|
*
|
||||||
|
* Moreover, be aware that @toadd is eaten with hair. IOW, the
|
||||||
|
* @toadd buffer is reset after this.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
virBufferAddBuffer(virBufferPtr buf, virBufferPtr toadd)
|
||||||
|
{
|
||||||
|
unsigned int needSize;
|
||||||
|
|
||||||
|
if (!buf || !toadd)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (buf->error || toadd->error) {
|
||||||
|
if (!buf->error)
|
||||||
|
buf->error = toadd->error;
|
||||||
|
virBufferFreeAndReset(toadd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
needSize = buf->use + toadd->use;
|
||||||
|
if (virBufferGrow(buf, needSize - buf->use) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
memcpy(&buf->content[buf->use], toadd->content, toadd->use);
|
||||||
|
buf->use += toadd->use;
|
||||||
|
buf->content[buf->use] = '\0';
|
||||||
|
virBufferFreeAndReset(toadd);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virBufferAddChar:
|
* virBufferAddChar:
|
||||||
* @buf: the buffer to append to
|
* @buf: the buffer to append to
|
||||||
|
@ -72,6 +72,7 @@ int virBufferCheckErrorInternal(const virBuffer *buf,
|
|||||||
__LINE__)
|
__LINE__)
|
||||||
unsigned int virBufferUse(const virBuffer *buf);
|
unsigned int virBufferUse(const virBuffer *buf);
|
||||||
void virBufferAdd(virBufferPtr buf, const char *str, int len);
|
void virBufferAdd(virBufferPtr buf, const char *str, int len);
|
||||||
|
void virBufferAddBuffer(virBufferPtr buf, virBufferPtr toadd);
|
||||||
void virBufferAddChar(virBufferPtr buf, char c);
|
void virBufferAddChar(virBufferPtr buf, char c);
|
||||||
void virBufferAsprintf(virBufferPtr buf, const char *format, ...)
|
void virBufferAsprintf(virBufferPtr buf, const char *format, ...)
|
||||||
ATTRIBUTE_FMT_PRINTF(2, 3);
|
ATTRIBUTE_FMT_PRINTF(2, 3);
|
||||||
|
@ -199,6 +199,117 @@ static int testBufTrim(const void *data ATTRIBUTE_UNUSED)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int testBufAddBuffer(const void *data ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
virBuffer buf1 = VIR_BUFFER_INITIALIZER;
|
||||||
|
virBuffer buf2 = VIR_BUFFER_INITIALIZER;
|
||||||
|
virBuffer buf3 = VIR_BUFFER_INITIALIZER;
|
||||||
|
int ret = -1;
|
||||||
|
char *result = NULL;
|
||||||
|
const char *expected = \
|
||||||
|
" A long time ago, in a galaxy far,\n" \
|
||||||
|
" far away...\n" \
|
||||||
|
" It is a period of civil war.\n" \
|
||||||
|
" Rebel spaceships, striking\n" \
|
||||||
|
" from a hidden base, have won\n" \
|
||||||
|
" their first victory against\n" \
|
||||||
|
" the evil Galactic Empire.\n" \
|
||||||
|
" During the battle, rebel\n" \
|
||||||
|
" spies managed to steal secret\n" \
|
||||||
|
" plans to the Empire's\n" \
|
||||||
|
" ultimate weapon, the DEATH\n" \
|
||||||
|
" STAR, an armored space\n" \
|
||||||
|
" station with enough power to\n" \
|
||||||
|
" destroy an entire planet.\n";
|
||||||
|
|
||||||
|
if (virBufferUse(&buf1)) {
|
||||||
|
TEST_ERROR("buf1 already in use");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virBufferUse(&buf2)) {
|
||||||
|
TEST_ERROR("buf2 already in use");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virBufferUse(&buf3)) {
|
||||||
|
TEST_ERROR("buf3 already in use");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAdjustIndent(&buf1, 2);
|
||||||
|
virBufferAddLit(&buf1, "A long time ago, in a galaxy far,\n");
|
||||||
|
virBufferAddLit(&buf1, "far away...\n");
|
||||||
|
|
||||||
|
virBufferAdjustIndent(&buf2, 4);
|
||||||
|
virBufferAddLit(&buf2, "It is a period of civil war.\n");
|
||||||
|
virBufferAddLit(&buf2, "Rebel spaceships, striking\n");
|
||||||
|
virBufferAddLit(&buf2, "from a hidden base, have won\n");
|
||||||
|
virBufferAddLit(&buf2, "their first victory against\n");
|
||||||
|
virBufferAddLit(&buf2, "the evil Galactic Empire.\n");
|
||||||
|
|
||||||
|
virBufferAdjustIndent(&buf3, 2);
|
||||||
|
virBufferAddLit(&buf3, "During the battle, rebel\n");
|
||||||
|
virBufferAddLit(&buf3, "spies managed to steal secret\n");
|
||||||
|
virBufferAddLit(&buf3, "plans to the Empire's\n");
|
||||||
|
virBufferAddLit(&buf3, "ultimate weapon, the DEATH\n");
|
||||||
|
virBufferAddLit(&buf3, "STAR, an armored space\n");
|
||||||
|
virBufferAddLit(&buf3, "station with enough power to\n");
|
||||||
|
virBufferAddLit(&buf3, "destroy an entire planet.\n");
|
||||||
|
|
||||||
|
if (!virBufferUse(&buf1)) {
|
||||||
|
TEST_ERROR("Error adding to buf1");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!virBufferUse(&buf2)) {
|
||||||
|
TEST_ERROR("Error adding to buf2");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!virBufferUse(&buf3)) {
|
||||||
|
TEST_ERROR("Error adding to buf3");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAddBuffer(&buf2, &buf3);
|
||||||
|
|
||||||
|
if (!virBufferUse(&buf2)) {
|
||||||
|
TEST_ERROR("buf2 cleared mistakenly");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virBufferUse(&buf3)) {
|
||||||
|
TEST_ERROR("buf3 is not clear even though it should be");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
virBufferAddBuffer(&buf1, &buf2);
|
||||||
|
|
||||||
|
if (!virBufferUse(&buf1)) {
|
||||||
|
TEST_ERROR("buf1 cleared mistakenly");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virBufferUse(&buf2)) {
|
||||||
|
TEST_ERROR("buf2 is not clear even though it should be");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = virBufferContentAndReset(&buf1);
|
||||||
|
if (STRNEQ_NULLABLE(result, expected)) {
|
||||||
|
virtTestDifference(stderr, expected, result);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
virBufferFreeAndReset(&buf1);
|
||||||
|
virBufferFreeAndReset(&buf2);
|
||||||
|
VIR_FREE(result);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
mymain(void)
|
mymain(void)
|
||||||
@ -217,6 +328,7 @@ mymain(void)
|
|||||||
DO_TEST("VSprintf infinite loop", testBufInfiniteLoop, 0);
|
DO_TEST("VSprintf infinite loop", testBufInfiniteLoop, 0);
|
||||||
DO_TEST("Auto-indentation", testBufAutoIndent, 0);
|
DO_TEST("Auto-indentation", testBufAutoIndent, 0);
|
||||||
DO_TEST("Trim", testBufTrim, 0);
|
DO_TEST("Trim", testBufTrim, 0);
|
||||||
|
DO_TEST("AddBuffer", testBufAddBuffer, 0);
|
||||||
|
|
||||||
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user