gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnurl] 178/411: dynbuf: make *addf() not require extra mallocs


From: gnunet
Subject: [gnurl] 178/411: dynbuf: make *addf() not require extra mallocs
Date: Wed, 13 Jan 2021 01:19:53 +0100

This is an automated email from the git hooks/post-receive script.

nikita pushed a commit to branch master
in repository gnurl.

commit 7e8561e030fcfaba5cd620d7e9c9ab8356163132
Author: Daniel Stenberg <daniel@haxx.se>
AuthorDate: Tue Sep 22 17:28:34 2020 +0200

    dynbuf: make *addf() not require extra mallocs
    
    ... by introducing a printf() function that appends directly into a
    dynbuf: Curl_dyn_vprintf(). This avoids the mandatory extra malloc so if
    the buffer is already big enough it can just printf directly into it.
    
    Since this less-malloc version requires tthe use of a library internal
    printf function, we only provide this version when building libcurl and
    not for the dynbuf code that is used when building the curl tool.
    
    Closes #5998
---
 lib/curl_printf.h |  2 +-
 lib/dynbuf.c      | 14 +++++++++++++-
 lib/dynbuf.h      |  4 ++++
 lib/mprintf.c     | 43 +++++++++++++++++++++++++++----------------
 4 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/lib/curl_printf.h b/lib/curl_printf.h
index 0d37b8e57..9d2de7ba8 100644
--- a/lib/curl_printf.h
+++ b/lib/curl_printf.h
@@ -7,7 +7,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
diff --git a/lib/dynbuf.c b/lib/dynbuf.c
index 5e15040bb..2dace3428 100644
--- a/lib/dynbuf.c
+++ b/lib/dynbuf.c
@@ -181,8 +181,17 @@ CURLcode Curl_dyn_add(struct dynbuf *s, const char *str)
  */
 CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, ...)
 {
-  char *str;
   va_list ap;
+#ifdef BUILDING_LIBCURL
+  int rc;
+  va_start(ap, fmt);
+  rc = Curl_dyn_vprintf(s, fmt, ap);
+  va_end(ap);
+
+  if(!rc)
+    return CURLE_OK;
+#else
+  char *str;
   va_start(ap, fmt);
   str = vaprintf(fmt, ap); /* this allocs a new string to append */
   va_end(ap);
@@ -194,9 +203,12 @@ CURLcode Curl_dyn_addf(struct dynbuf *s, const char *fmt, 
...)
   }
   /* If we failed, we cleanup the whole buffer and return error */
   Curl_dyn_free(s);
+#endif
   return CURLE_OUT_OF_MEMORY;
 }
 
+
+
 /*
  * Returns a pointer to the buffer.
  */
diff --git a/lib/dynbuf.h b/lib/dynbuf.h
index 1360dd432..94b5dbf68 100644
--- a/lib/dynbuf.h
+++ b/lib/dynbuf.h
@@ -62,6 +62,10 @@ char *Curl_dyn_ptr(const struct dynbuf *s);
 unsigned char *Curl_dyn_uptr(const struct dynbuf *s);
 size_t Curl_dyn_len(const struct dynbuf *s);
 
+/* returns 0 on success, -1 on error */
+/* The implementation of this function exists in mprintf.c */
+int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save);
+
 /* Dynamic buffer max sizes */
 #define DYN_DOH_RESPONSE    3000
 #define DYN_DOH_CNAME       256
diff --git a/lib/mprintf.c b/lib/mprintf.c
index 6b62fdfbc..8f0011e91 100644
--- a/lib/mprintf.c
+++ b/lib/mprintf.c
@@ -169,7 +169,7 @@ struct nsprintf {
 };
 
 struct asprintf {
-  struct dynbuf b;
+  struct dynbuf *b;
   bool fail; /* if an alloc has failed and thus the output is not the complete
                 data */
 };
@@ -1042,50 +1042,61 @@ static int alloc_addbyter(int output, FILE *data)
   struct asprintf *infop = (struct asprintf *)data;
   unsigned char outc = (unsigned char)output;
 
-  if(Curl_dyn_addn(&infop->b, &outc, 1)) {
+  if(Curl_dyn_addn(infop->b, &outc, 1)) {
     infop->fail = 1;
     return -1; /* fail */
   }
   return outc; /* fputc() returns like this on success */
 }
 
-char *curl_maprintf(const char *format, ...)
+extern int Curl_dyn_vprintf(struct dynbuf *dyn,
+                            const char *format, va_list ap_save);
+
+/* appends the formatted string, returns 0 on success, 1 on error */
+int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save)
 {
-  va_list ap_save; /* argument pointer */
   int retcode;
   struct asprintf info;
-  Curl_dyn_init(&info.b, DYN_APRINTF);
+  info.b = dyn;
   info.fail = 0;
 
-  va_start(ap_save, format);
   retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
-  va_end(ap_save);
   if((-1 == retcode) || info.fail) {
-    Curl_dyn_free(&info.b);
-    return NULL;
+    Curl_dyn_free(info.b);
+    return 1;
   }
-  if(Curl_dyn_len(&info.b))
-    return Curl_dyn_ptr(&info.b);
-  return strdup("");
+  return 0;
 }
 
 char *curl_mvaprintf(const char *format, va_list ap_save)
 {
   int retcode;
   struct asprintf info;
-  Curl_dyn_init(&info.b, DYN_APRINTF);
+  struct dynbuf dyn;
+  info.b = &dyn;
+  Curl_dyn_init(info.b, DYN_APRINTF);
   info.fail = 0;
 
   retcode = dprintf_formatf(&info, alloc_addbyter, format, ap_save);
   if((-1 == retcode) || info.fail) {
-    Curl_dyn_free(&info.b);
+    Curl_dyn_free(info.b);
     return NULL;
   }
-  if(Curl_dyn_len(&info.b))
-    return Curl_dyn_ptr(&info.b);
+  if(Curl_dyn_len(info.b))
+    return Curl_dyn_ptr(info.b);
   return strdup("");
 }
 
+char *curl_maprintf(const char *format, ...)
+{
+  va_list ap_save;
+  char *s;
+  va_start(ap_save, format);
+  s = curl_mvaprintf(format, ap_save);
+  va_end(ap_save);
+  return s;
+}
+
 static int storebuffer(int output, FILE *data)
 {
   char **buffer = (char **)data;

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]