#include <unistd.h>
#include <jansson.h>
+#include "strbuffer.h"
typedef int (*dump_func)(const char *buffer, int size, void *data);
int size;
};
-static int dump_to_string(const char *buffer, int size, void *data)
+static int dump_to_strbuffer(const char *buffer, int size, void *data)
{
- struct string *string = (struct string *)data;
- if(string->length + size > string->size)
- {
- if(string->length == 0)
- string->size = 16;
- else
- string->size *= 2;
-
- string->buffer = realloc(string->buffer, string->size);
- if(!string->buffer)
- return -1;
-
- memset(string->buffer + string->length, 0,
- string->size - string->length);
- }
-
- memcpy(string->buffer + string->length, buffer, size);
- string->length += size;
-
- return 0;
+ return strbuffer_append_bytes((strbuffer_t *)data, buffer, size);
}
static int dump_to_file(const char *buffer, int size, void *data)
char *json_dumps(const json_t *json, uint32_t flags)
{
- struct string string;
+ strbuffer_t strbuff;
char *result;
- memset(&string, 0, sizeof(struct string));
- if(do_dump(json, flags, 0, dump_to_string, (void *)&string))
+ strbuffer_init(&strbuff);
+
+ if(do_dump(json, flags, 0, dump_to_strbuffer, (void *)&strbuff))
return NULL;
- if(dump_to_string("\n", 1, (void *)&string))
+ if(dump_to_strbuffer("\n", 1, (void *)&strbuff))
return NULL;
- /* consume just the right amount of memory */
- result = strdup(string.buffer);
- free(string.buffer);
+ result = strbuffer_value(&strbuff);
+ strbuffer_close(&strbuff);
return result;
}
--- /dev/null
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <string.h>
+#include "strbuffer.h"
+#include "util.h"
+
+#define STRBUFFER_MIN_SIZE 16
+#define STRBUFFER_FACTOR 2
+
+void strbuffer_init(strbuffer_t *strbuff)
+{
+ strbuff->value = NULL;
+ strbuff->length = 0;
+ strbuff->size = 0;
+}
+
+void strbuffer_close(strbuffer_t *strbuff)
+{
+ free(strbuff->value);
+ strbuffer_init(strbuff);
+}
+
+char *strbuffer_value(strbuffer_t *strbuff)
+{
+ return strdup(strbuff->value);
+}
+
+char *strbuffer_steal_value(strbuffer_t *strbuff)
+{
+ char *result = strbuff->value;
+ strbuffer_init(strbuff);
+ return result;
+}
+
+int strbuffer_append(strbuffer_t *strbuff, const char *string)
+{
+ return strbuffer_append_bytes(strbuff, string, strlen(string));
+}
+
+int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, int size)
+{
+ if(strbuff->length + size > strbuff->size)
+ {
+ if(strbuff->length == 0)
+ strbuff->size = STRBUFFER_MIN_SIZE;
+ else
+ strbuff->size = max(strbuff->size * STRBUFFER_FACTOR,
+ strbuff->length + size + 1);
+
+ strbuff->value = realloc(strbuff->value, strbuff->size);
+ if(!strbuff->value)
+ return -1;
+
+ memset(strbuff->value + strbuff->length + size, 0,
+ strbuff->size - strbuff->length - size);
+ }
+
+ memcpy(strbuff->value + strbuff->length, data, size);
+ strbuff->length += size;
+
+ return 0;
+}
--- /dev/null
+#ifndef STRBUFFER_H
+#define STRBUFFER_H
+
+typedef struct {
+ char *value;
+ int length;
+ int size;
+} strbuffer_t;
+
+void strbuffer_init(strbuffer_t *strbuff);
+void strbuffer_close(strbuffer_t *strbuff);
+
+char *strbuffer_value(strbuffer_t *strbuff);
+char *strbuffer_steal_value(strbuffer_t *strbuff);
+
+int strbuffer_append(strbuffer_t *strbuff, const char *string);
+int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, int size);
+
+#endif