Right now, the only way to get at the contents of a virBuffer is
to destroy it. But there are cases in my upcoming patches where
peeking at the contents makes life easier. I suppose this does
open up the potential for bad code to dereference a stale pointer,
by disregarding the docs that the return value is invalid on the
next virBuf operation, but such is life.
* src/util/buf.h (virBufferCurrentContent): New declaration.
* src/util/buf.c (virBufferCurrentContent): Implement it.
* src/libvirt_private.syms (buf.h): Export it.
* tests/virbuftest.c (testBufAutoIndent): Test it.
---
src/libvirt_private.syms | 1 +
src/util/buf.c | 22 +++++++++++++++++++++-
src/util/buf.h | 1 +
tests/virbuftest.c | 8 ++++++++
4 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fdf2186..ef8047d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -20,6 +20,7 @@ virBufferAddChar;
virBufferAdjustIndent;
virBufferAsprintf;
virBufferContentAndReset;
+virBufferCurrentContent;
virBufferError;
virBufferEscape;
virBufferEscapeSexpr;
diff --git a/src/util/buf.c b/src/util/buf.c
index 630e4c9..6c7c501 100644
--- a/src/util/buf.c
+++ b/src/util/buf.c
@@ -175,12 +175,32 @@ virBufferAddChar(virBufferPtr buf, char c)
}
/**
+ * virBufferCurrentContent:
+ * @buf: Buffer
+ *
+ * Get the current content from the buffer. The content is only valid
+ * until the next operation on @buf, and an empty string is returned if
+ * no content is present yet.
+ *
+ * Returns the buffer content or NULL in case of error.
+ */
+const char *
+virBufferCurrentContent(virBufferPtr buf)
+{
+ if (!buf || buf->error)
+ return NULL;
+ return buf->use ? buf->content : "";
+}
+
+/**
* virBufferContentAndReset:
* @buf: Buffer
*
* Get the content from the buffer and free (only) the buffer structure.
* The caller owns the returned string & should free it when no longer
- * required. The buffer object is reset to its initial state.
+ * required. The buffer object is reset to its initial state. This
+ * interface intentionally returns NULL instead of an empty string if
+ * there is no content.
*
* Returns the buffer content or NULL in case of error.
*/
diff --git a/src/util/buf.h b/src/util/buf.h
index a8e2eb5..2750b17 100644
--- a/src/util/buf.h
+++ b/src/util/buf.h
@@ -37,6 +37,7 @@ struct _virBuffer {
};
# endif
+const char *virBufferCurrentContent(virBufferPtr buf);
char *virBufferContentAndReset(virBufferPtr buf);
void virBufferFreeAndReset(virBufferPtr buf);
int virBufferError(const virBufferPtr buf);
diff --git a/tests/virbuftest.c b/tests/virbuftest.c
index cd02db1..7af679c 100644
--- a/tests/virbuftest.c
+++ b/tests/virbuftest.c
@@ -73,6 +73,10 @@ static int testBufAutoIndent(const void *data ATTRIBUTE_UNUSED)
ret = -1;
}
virBufferAdjustIndent(buf, 3);
+ if (STRNEQ_NULLABLE(virBufferCurrentContent(buf), "")) {
+ TEST_ERROR("Wrong content");
+ ret = -1;
+ }
if (virBufferGetIndent(buf, false) != 3 ||
virBufferGetIndent(buf, true) != 3 ||
virBufferError(buf)) {
@@ -102,6 +106,10 @@ static int testBufAutoIndent(const void *data ATTRIBUTE_UNUSED)
}
virBufferAdjustIndent(buf, 2);
virBufferAddLit(buf, "1");
+ if (STRNEQ_NULLABLE(virBufferCurrentContent(buf), " 1")) {
+ TEST_ERROR("Wrong content");
+ ret = -1;
+ }
if (virBufferGetIndent(buf, false) != 2 ||
virBufferGetIndent(buf, true) != 0) {
TEST_ERROR("Wrong indentation");
--
1.7.10.2