Implement strbuffer

String buffer (strbuffer) is an object that resizes automatically when
data is added to it. It was implemented by generalizing the technique
used in json_dumps().
This commit is contained in:
Petri Lehtinen 2009-06-11 08:56:11 +03:00
parent 9b825f7b18
commit 197d3aa160
4 changed files with 93 additions and 28 deletions

View File

@ -6,6 +6,8 @@ libjansson_la_SOURCES = \
hashtable.c \
hashtable.h \
load.c \
strbuffer.c \
strbuffer.h \
util.h \
value.c
libjansson_la_LDFLAGS = -version-info 0:0:0

View File

@ -5,6 +5,7 @@
#include <unistd.h>
#include <jansson.h>
#include "strbuffer.h"
typedef int (*dump_func)(const char *buffer, int size, void *data);
@ -15,28 +16,9 @@ struct string
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)
@ -229,19 +211,19 @@ int json_dump(const json_t *json, const char *path, uint32_t flags)
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;
}

62
src/strbuffer.c Normal file
View File

@ -0,0 +1,62 @@
#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;
}

19
src/strbuffer.h Normal file
View File

@ -0,0 +1,19 @@
#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