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 <mpriv...@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

Attachment: pgpnfXkUXcq77.pgp
Description: PGP signature

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to