[libvirt] [PATCH v2 1/4] util: Introduce virBufferAddBuffer

Martin Kletzander mkletzan at redhat.com
Wed Feb 25 04:45:09 UTC 2015


On Tue, Feb 24, 2015 at 04:14:37PM +0100, Michal Privoznik wrote:
>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 at redhat.com>
>---
>
>diff to v1:
>-Martin's suggestions worked in (hopefully)
>
> src/libvirt_private.syms |   1 +
> src/util/virbuffer.c     |  40 ++++++++++++++++-
> src/util/virbuffer.h     |   1 +
> tests/virbuftest.c       | 112 +++++++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 152 insertions(+), 2 deletions(-)
>
>diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
>index c156b40..ba05cc6 100644
>--- a/src/libvirt_private.syms
>+++ b/src/libvirt_private.syms
>@@ -1081,6 +1081,7 @@ virBitmapToData;
>
> # util/virbuffer.h
> virBufferAdd;
>+virBufferAddBuffer;
> virBufferAddChar;
> virBufferAdjustIndent;
> virBufferAsprintf;
>diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
>index e94b35d..96a0f16 100644
>--- a/src/util/virbuffer.c
>+++ b/src/util/virbuffer.c
>@@ -162,8 +162,7 @@ virBufferAdd(virBufferPtr buf, const char *str, int len)
>         len = strlen(str);
>
>     needSize = buf->use + indent + len + 2;
>-    if (needSize > buf->size &&
>-        virBufferGrow(buf, needSize - buf->use) < 0)
>+    if (virBufferGrow(buf, needSize - buf->use) < 0)
>         return;
>
>     memset(&buf->content[buf->use], ' ', indent);
>@@ -173,6 +172,43 @@ virBufferAdd(virBufferPtr buf, const char *str, int len)
> }
>
> /**
>+ * 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:
>  * @buf: the buffer to append to
>  * @c: the character to add
>diff --git a/src/util/virbuffer.h b/src/util/virbuffer.h
>index 90e248d..24e81c7 100644
>--- a/src/util/virbuffer.h
>+++ b/src/util/virbuffer.h
>@@ -72,6 +72,7 @@ int virBufferCheckErrorInternal(const virBuffer *buf,
>     __LINE__)
> unsigned int virBufferUse(const virBuffer *buf);
> void virBufferAdd(virBufferPtr buf, const char *str, int len);
>+void virBufferAddBuffer(virBufferPtr buf, virBufferPtr toadd);
> void virBufferAddChar(virBufferPtr buf, char c);
> void virBufferAsprintf(virBufferPtr buf, const char *format, ...)
>   ATTRIBUTE_FMT_PRINTF(2, 3);
>diff --git a/tests/virbuftest.c b/tests/virbuftest.c
>index 554a8c0..884468c 100644
>--- a/tests/virbuftest.c
>+++ b/tests/virbuftest.c
>@@ -199,6 +199,117 @@ static int testBufTrim(const void *data ATTRIBUTE_UNUSED)
>     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"    \

s/war,/war./

>+"    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");

Same here ;)

>+    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 (!result || STRNEQ(result, expected)) {

Just use STRNEQ_NULLABLE.

ACK

>+        virtTestDifference(stderr, expected, result);
>+        goto cleanup;
>+    }
>+
>+    ret = 0;
>+ cleanup:
>+    virBufferFreeAndReset(&buf1);
>+    virBufferFreeAndReset(&buf2);
>+    VIR_FREE(result);
>+    return ret;
>+}
>+
>
> static int
> mymain(void)
>@@ -217,6 +328,7 @@ mymain(void)
>     DO_TEST("VSprintf infinite loop", testBufInfiniteLoop, 0);
>     DO_TEST("Auto-indentation", testBufAutoIndent, 0);
>     DO_TEST("Trim", testBufTrim, 0);
>+    DO_TEST("AddBuffer", testBufAddBuffer, 0);
>
>     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
> }
>--
>2.0.5
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20150225/2ee5027e/attachment-0001.sig>


More information about the libvir-list mailing list