Code

data: Let sdb_data_parse() accept a const string and copy it if necessary.
[sysdb.git] / src / utils / strbuf.c
index c310b443448a14be1eb96f8c7fdc4618707868c5..d8a95ac42f60a4003d9cdf21924cbfbf2a5ccee1 100644 (file)
@@ -25,6 +25,7 @@
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "sysdb.h"
 #include "utils/strbuf.h"
 
 #include <assert.h>
@@ -39,7 +40,8 @@
 /* free memory if most of the buffer is unused */
 #define CHECK_SHRINK(buf) \
        do { \
-               if ((buf)->pos < (buf)->size / 3) \
+               if (((buf)->pos < (buf)->size / 3) \
+                               && (2 * (buf)->pos > (buf)->min_size)) \
                        /* don't free all memory to avoid churn */ \
                        strbuf_resize((buf), 2 * (buf)->pos); \
        } while (0)
@@ -52,6 +54,9 @@ struct sdb_strbuf {
        char  *string;
        size_t size;
        size_t pos;
+
+       /* min size to shrink the buffer to */
+       size_t min_size;
 };
 
 /*
@@ -61,11 +66,18 @@ struct sdb_strbuf {
 static int
 strbuf_resize(sdb_strbuf_t *buf, size_t new_size)
 {
+       size_t tmp_size;
        char *tmp;
 
        if (new_size <= buf->pos)
                return -1;
 
+       tmp_size = SDB_MAX(buf->size, buf->min_size);
+       if (! tmp_size)
+               tmp_size = 64;
+       while (tmp_size < new_size)
+               tmp_size *= 2;
+
        tmp = realloc(buf->string, new_size);
        if (! tmp)
                return -1;
@@ -100,7 +112,10 @@ sdb_strbuf_create(size_t size)
                }
 
                buf->string[0] = '\0';
+               buf->min_size = size;
        }
+       else
+               buf->min_size = 64;
 
        buf->size = size;
        buf->pos  = 0;
@@ -224,15 +239,8 @@ sdb_strbuf_memappend(sdb_strbuf_t *buf, const void *data, size_t n)
 
        assert((buf->size == 0) || (buf->string[buf->pos] == '\0'));
 
-       if (buf->pos + n + 1 >= buf->size) {
-               size_t newsize = buf->size * 2;
-
-               if (! newsize)
-                       newsize = 64;
-               while (buf->pos + n + 1 >= newsize)
-                       newsize *= 2;
-
-               if (strbuf_resize(buf, newsize))
+       if (buf->pos + n + 1 > buf->size) {
+               if (strbuf_resize(buf, buf->pos + n + 1))
                        return -1;
        }