]> xenbits.xensource.com Git - libvirt.git/commitdiff
added virBufferStrcat
authorKarel Zak <kzak@redhat.com>
Wed, 10 May 2006 12:15:49 +0000 (12:15 +0000)
committerKarel Zak <kzak@redhat.com>
Wed, 10 May 2006 12:15:49 +0000 (12:15 +0000)
ChangeLog
src/xml.c
src/xml.h
src/xmlrpc.c
tests/xmlrpctest.c

index 930705e277ef5feff590e2c63df6acb857895b1c..41dc9902ac5d7a27ed611015e368264970b9211d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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 
index b273154be0a80dd3c6e22f0097c76bedca635be1..f46978bb4ff8c0b7fb3c122061b8bbbe1653403b 100644 (file)
--- a/src/xml.c
+++ b/src/xml.c
@@ -107,20 +107,40 @@ 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)
 {
     if (buf) {
-       if (buf->content)
-              free(buf->content);
-       free(buf);
+        if (buf->content)
+          free(buf->content);
+               free(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
 
 /*
index 7121b55d4f3407e0e6d40fb92ac6d4484a6c2505..fbd5895ea49e67e8d8a349d754aeace9bd2d6272 100644 (file)
--- a/src/xml.h
+++ b/src/xml.h
@@ -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
index eceb2872c609efa829f6e8bb2b81391f2f6dc48c..2b6db87af72b19cce714a533f98cd71a46777e0c 100644 (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;
-
-    virBufferVSprintf(buf,
-                     "<?xml version=\"1.0\"?>\n"
-                     "<methodCall>\n"
-                     "  <methodName>%s</methodName>\n"
-                     "  <params>\n",
-                     request);
+    buf = virBufferNew(1024);
+
+    virBufferStrcat(buf,
+                   "<?xml version=\"1.0\"?>\n"
+                   "<methodCall>\n"
+                   "  <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,
-                     "  </params>\n"
-                     "</methodCall>\n");
-
+    virBufferStrcat(buf,
+                    "  </params>\n"
+                   "</methodCall>\n", NULL);
     return buf;
 }
 
index 02f0fa4978da24b649a7a4e9128aa85bfaa30042..9540bffaf9d88eaa47df146d0f204c1c7517c38f 100644 (file)
@@ -151,11 +151,10 @@ testMarshalRequestSTRING(void *data ATTRIBUTE_UNUSED)
     int check = data ? *((int *)data) : 0;
     virBufferPtr buf = marshalRequest("s", str);
 
-    if (check)
+    if (check) 
         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)
 {
@@ -194,15 +219,17 @@ 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", 
+       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;
@@ -231,8 +262,12 @@ main(int argc, char **argv)
     if (virtTestRun("XML-RPC request marshalling: STRING", 
                 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);
 }