Introduce virBufferCheckError

Check if the buffer is in error state and report an error if it is.

This replaces the pattern:
if (virBufferError(buf)) {
    virReportOOMError();
    goto cleanup;
}
with:

if (virBufferCheckError(buf) < 0)
    goto cleanup;

Document typical buffer usage to favor this.
Also remove the redundant FreeAndReset - if an error has
been set via virBufferSetError, the content is already freed.
This commit is contained in:
Ján Tomko 2014-06-27 09:23:13 +02:00
parent f44e2e8711
commit 058d89b9df
6 changed files with 54 additions and 10 deletions

View File

@ -776,7 +776,7 @@ Variable length string buffer
============================= =============================
If there is a need for complex string concatenations, avoid using the usual If there is a need for complex string concatenations, avoid using the usual
sequence of malloc/strcpy/strcat/snprintf functions and make use of the sequence of malloc/strcpy/strcat/snprintf functions and make use of the
virBuffer API described in buf.h virBuffer API described in virbuffer.h
Typical usage is as follows: Typical usage is as follows:
@ -794,11 +794,8 @@ Typical usage is as follows:
... ...
if (virBufferError(&buf)) { if (virBufferCheckError(&buf) < 0)
virBufferFreeAndReset(&buf);
virReportOOMError();
return NULL; return NULL;
}
return virBufferContentAndReset(&buf); return virBufferContentAndReset(&buf);
} }

View File

@ -948,7 +948,7 @@
<p> <p>
If there is a need for complex string concatenations, avoid using If there is a need for complex string concatenations, avoid using
the usual sequence of malloc/strcpy/strcat/snprintf functions and the usual sequence of malloc/strcpy/strcat/snprintf functions and
make use of the virBuffer API described in buf.h make use of the virBuffer API described in virbuffer.h
</p> </p>
<p>Typical usage is as follows:</p> <p>Typical usage is as follows:</p>
@ -968,11 +968,8 @@
... ...
if (virBufferError(&amp;buf)) { if (virBufferCheckError(&amp;buf) &lt; 0)
virBufferFreeAndReset(&amp;buf);
virReportOOMError();
return NULL; return NULL;
}
return virBufferContentAndReset(&amp;buf); return virBufferContentAndReset(&amp;buf);
} }

View File

@ -156,6 +156,7 @@ src/util/viraudit.c
src/util/virauth.c src/util/virauth.c
src/util/virauthconfig.c src/util/virauthconfig.c
src/util/virbitmap.c src/util/virbitmap.c
src/util/virbuffer.c
src/util/vircgroup.c src/util/vircgroup.c
src/util/virclosecallbacks.c src/util/virclosecallbacks.c
src/util/vircommand.c src/util/vircommand.c

View File

@ -1008,6 +1008,7 @@ virBufferAdd;
virBufferAddChar; virBufferAddChar;
virBufferAdjustIndent; virBufferAdjustIndent;
virBufferAsprintf; virBufferAsprintf;
virBufferCheckErrorInternal;
virBufferContentAndReset; virBufferContentAndReset;
virBufferCurrentContent; virBufferCurrentContent;
virBufferError; virBufferError;

View File

@ -32,6 +32,7 @@
#include "virbuffer.h" #include "virbuffer.h"
#include "viralloc.h" #include "viralloc.h"
#include "virerror.h"
/* If adding more fields, ensure to edit buf.h to match /* If adding more fields, ensure to edit buf.h to match
@ -263,6 +264,36 @@ virBufferError(const virBuffer *buf)
return buf->error; return buf->error;
} }
/**
* virBufferCheckErrorInternal:
* @buf: the buffer
*
* Report an error if the buffer is in an error state.
*
* Return -1 if an error has been reported, 0 otherwise.
*/
int
virBufferCheckErrorInternal(const virBuffer *buf,
int domcode,
const char *filename,
const char *funcname,
size_t linenr)
{
if (buf->error == 0)
return 0;
if (buf->error == ENOMEM) {
virReportOOMErrorFull(domcode, filename, funcname, linenr);
errno = ENOMEM;
} else {
virReportErrorHelper(domcode, VIR_ERR_INTERNAL_ERROR, filename,
funcname, linenr, "%s",
_("Invalid buffer API usage"));
errno = EINVAL;
}
return -1;
}
/** /**
* virBufferUse: * virBufferUse:
* @buf: the usage of the string in the buffer * @buf: the usage of the string in the buffer

View File

@ -53,6 +53,23 @@ const char *virBufferCurrentContent(virBufferPtr buf);
char *virBufferContentAndReset(virBufferPtr buf); char *virBufferContentAndReset(virBufferPtr buf);
void virBufferFreeAndReset(virBufferPtr buf); void virBufferFreeAndReset(virBufferPtr buf);
int virBufferError(const virBuffer *buf); int virBufferError(const virBuffer *buf);
int virBufferCheckErrorInternal(const virBuffer *buf,
int domcode,
const char *filename,
const char *funcname,
size_t linenr)
ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
/**
* virBufferCheckError
*
* Checks if the buffer is in error state and reports an error.
*
* Returns 0 if no error has occured, otherwise an error is reported
* and -1 is returned.
*/
# define virBufferCheckError(buf) \
virBufferCheckErrorInternal(buf, VIR_FROM_THIS, __FILE__, __FUNCTION__, \
__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 virBufferAddChar(virBufferPtr buf, char c); void virBufferAddChar(virBufferPtr buf, char c);