]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
util: Introduce virBufferAddBuffer
authorMichal Privoznik <mprivozn@redhat.com>
Thu, 19 Feb 2015 09:56:58 +0000 (10:56 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Wed, 25 Feb 2015 08:23:42 +0000 (09:23 +0100)
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>
src/libvirt_private.syms
src/util/virbuffer.c
src/util/virbuffer.h
tests/virbuftest.c

index c156b40c5309d4f83eee37f8ae53d82ae036b139..ba05cc6882c365b2fe698ad6666344652278a718 100644 (file)
@@ -1081,6 +1081,7 @@ virBitmapToData;
 
 # util/virbuffer.h
 virBufferAdd;
+virBufferAddBuffer;
 virBufferAddChar;
 virBufferAdjustIndent;
 virBufferAsprintf;
index e94b35d1dcb9df92e92ae9c82c6162016bc196db..96a0f16d57ccc8a158b94631514a2056b608b096 100644 (file)
@@ -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);
@@ -172,6 +171,43 @@ virBufferAdd(virBufferPtr buf, const char *str, int len)
     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:
  * @buf: the buffer to append to
index 90e248d1c650d721b9cdf58756e0d5b30866d03d..24e81c766cdaf13a06a3c309a98053c939ae4d85 100644 (file)
@@ -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);
index 554a8c070ae339eac873eef966a62c611144182b..f964febd27e874b0b63fc93f8299c6b96ed4d73e 100644 (file)
@@ -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"    \
+"    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
 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;
 }