added virBufferStrcat

This commit is contained in:
Karel Zak 2006-05-10 12:15:49 +00:00
parent 0f579f785c
commit 0d8e15fa75
5 changed files with 128 additions and 35 deletions

View File

@ -1,3 +1,10 @@
Wed May 10 13:17:00 CEST 2006 Karel Zak <kzak@redhat.com>
* src/xml.c src/xml.h: added virBufferNew() and virBufferStrcat()
* tests/xmlrpctest.c: added performace tests for virBufferStrcat() and
virBufferVSprintf()
* src/xmlrpc.c: used virBufferStrcat()
Tue May 9 16:37:22 CEST 2006 Karel Zak <kzak@redhat.com>
* tests/Makefile.am tests/xmlrpctest.c tests/testutils.h: added test

View File

@ -107,13 +107,33 @@ virBufferAdd(virBufferPtr buf, const char *str, int len)
return (-1);
}
}
/* XXX: memmove() is 2x slower than memcpy(), do we really need it? */
memmove(&buf->content[buf->use], str, len);
buf->use += len;
buf->content[buf->use] = 0;
return (0);
}
virBufferPtr
virBufferNew(unsigned int size)
{
virBufferPtr buf;
if (!(buf = malloc(sizeof(*buf)))) {
virXMLError(VIR_ERR_NO_MEMORY, "allocate new buffer", sizeof(*buf));
return NULL;
}
if (size && (buf->content = malloc(size))==NULL) {
virXMLError(VIR_ERR_NO_MEMORY, "allocate buffer content", size);
free(buf);
return NULL;
}
buf->size = size;
buf->use = 0;
return buf;
}
void
virBufferFree(virBufferPtr buf)
{
@ -162,6 +182,39 @@ virBufferVSprintf(virBufferPtr buf, const char *format, ...)
return (0);
}
/**
* virBufferStrcat:
* @buf: the buffer to dump
* @argptr: the variable list of strings, the last argument must be NULL
*
* Concatenate strings to an XML buffer.
*
* Returns 0 successful, -1 in case of internal or API error.
*/
int
virBufferStrcat(virBufferPtr buf, ...)
{
va_list ap;
char *str;
va_start(ap, buf);
while ((str = va_arg(ap, char *)) != NULL) {
unsigned int len = strlen(str);
unsigned int needSize = buf->use + len + 2;
if (needSize > buf->size) {
if (!virBufferGrow(buf, needSize))
return -1;
}
memcpy(&buf->content[buf->use], str, len);
buf->use += len;
buf->content[buf->use] = 0;
}
va_end(ap);
return 0;
}
#if 0
/*

View File

@ -24,9 +24,11 @@ struct _virBuffer {
unsigned int size; /* The buffer size */
};
virBufferPtr virBufferNew(unsigned int size);
void virBufferFree(virBufferPtr buf);
int virBufferAdd(virBufferPtr buf, const char *str, int len);
int virBufferVSprintf(virBufferPtr buf, const char *format, ...);
int virBufferStrcat(virBufferPtr buf, ...);
char *virDomainParseXMLDesc(const char *xmldesc, char **name);
#ifdef __cplusplus

View File

@ -266,13 +266,13 @@ void xmlRpcValueMarshal(xmlRpcValuePtr value, virBufferPtr buf, int indent)
virBufferVSprintf(buf, "%*s<value>", indent, "");
switch (value->kind) {
case XML_RPC_ARRAY:
virBufferVSprintf(buf, "<array><data>\n", indent, "");
virBufferStrcat(buf, "<array><data>\n", NULL);
for (i = 0; i < value->value.array.n_elements; i++)
xmlRpcValueMarshal(value->value.array.elements[i], buf, indent+2);
virBufferVSprintf(buf, "%*s</data></array>", indent, "");
break;
case XML_RPC_STRUCT:
virBufferVSprintf(buf, "<struct>\n", indent, "");
virBufferStrcat(buf, "<struct>\n", NULL);
indent += 2;
for (elem = value->value.dict.root; elem; elem = elem->next) {
virBufferVSprintf(buf, "%*s<member>\n", indent, "");
@ -306,13 +306,14 @@ void xmlRpcValueMarshal(xmlRpcValuePtr value, virBufferPtr buf, int indent)
TODO;
break;
case XML_RPC_STRING:
virBufferVSprintf(buf, "<string>%s</string>", value->value.string);
virBufferStrcat(buf,
"<string>", value->value.string, "</string>", NULL);
break;
case XML_RPC_NIL:
virBufferVSprintf(buf, "<nil> </nil>");
virBufferStrcat(buf, "<nil> </nil>", NULL);
break;
}
virBufferVSprintf(buf, "</value>\n");
virBufferStrcat(buf, "</value>\n", NULL);
}
virBufferPtr xmlRpcMarshalRequest(const char *request,
@ -321,28 +322,23 @@ virBufferPtr xmlRpcMarshalRequest(const char *request,
virBufferPtr buf;
int i;
buf = malloc(sizeof(*buf));
buf->size = 1024;
buf->content = malloc(buf->size);
buf->use = 0;
buf = virBufferNew(1024);
virBufferVSprintf(buf,
virBufferStrcat(buf,
"<?xml version=\"1.0\"?>\n"
"<methodCall>\n"
" <methodName>%s</methodName>\n"
" <params>\n",
request);
" <methodName>", request, "</methodName>\n"
" <params>\n", NULL);
for (i = 0; i < argc; i++) {
virBufferVSprintf(buf,
" <param>\n");
virBufferStrcat(buf,
" <param>\n", NULL);
xmlRpcValueMarshal(argv[i], buf, 6);
virBufferVSprintf(buf,
" </param>\n");
virBufferStrcat(buf,
" </param>\n", NULL);
}
virBufferVSprintf(buf,
virBufferStrcat(buf,
" </params>\n"
"</methodCall>\n");
"</methodCall>\n", NULL);
return buf;
}

View File

@ -155,7 +155,6 @@ testMarshalRequestSTRING(void *data ATTRIBUTE_UNUSED)
ret = checkRequestValue(buf->content,
"string(/methodCall/params/param[1]/value/string)",
XML_RPC_STRING, (void *) str);
virBufferFree(buf);
return ret;
}
@ -177,6 +176,32 @@ testMarshalRequestDOUBLE(void *data)
return ret;
}
static int
testBufferStrcat(void *data ATTRIBUTE_UNUSED)
{
virBufferPtr buf = virBufferNew(1000*32); /* don't waste time with realloc */
int i;
for (i=0; i < 1000; i++)
virBufferStrcat(buf, "My name is ", "libvirt", ".\n", NULL);
virBufferFree(buf);
return 0;
}
static int
testBufferVSprintf(void *data ATTRIBUTE_UNUSED)
{
virBufferPtr buf = virBufferNew(1000*32); /* don't waste time with realloc */
int i;
for (i=0; i < 1000; i++)
virBufferVSprintf(buf, "My name is %s.\n", "libvirt");
virBufferFree(buf);
return 0;
}
int
main(int argc, char **argv)
{
@ -195,13 +220,15 @@ main(int argc, char **argv)
if (argc == 2)
url = argv[1];
/*
* client-server tests
*/
if (!(cxt = xmlRpcContextNew(url)))
{
fprintf(stderr, "%s: failed create new RPC context\n", progname);
exit(EXIT_FAILURE);
}
/* client-server tests */
if (virtTestRun("XML-RPC methodCall INT+INT",
NLOOPS, testMethodPlusINT, (void *) cxt) != 0)
ret = -1;
@ -210,7 +237,11 @@ main(int argc, char **argv)
NLOOPS, testMethodPlusDOUBLE, (void *) cxt) != 0)
ret = -1;
/* regression / performance tests */
xmlRpcContextFree(cxt);
/*
* regression / performance tests
*/
if (virtTestRun("XML-RPC request marshalling: INT (check)",
1, testMarshalRequestINT, (void *) &check) != 0)
ret = -1;
@ -232,7 +263,11 @@ main(int argc, char **argv)
NLOOPS, testMarshalRequestSTRING, NULL) != 0)
ret = -1;
xmlRpcContextFree(cxt);
if (virtTestRun("Buffer: strcat", NLOOPS, testBufferStrcat, NULL) != 0)
ret = -1;
if (virtTestRun("Buffer: sprintf", NLOOPS, testBufferVSprintf, NULL) != 0)
ret = -1;
exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
}