101 lines
2.5 KiB
C
101 lines
2.5 KiB
C
![]() |
/* libCStreamedXML/src/libCStreamedXML/buffer.c
|
||
|
*
|
||
|
* (c)2006, Laurence Withers. Released under the GNU GPL. See file
|
||
|
* COPYING for more information / terms of license.
|
||
|
*/
|
||
|
|
||
|
static int do_realloc(struct csxml* ctx, struct csxml_buf* buf)
|
||
|
{
|
||
|
char* n = realloc(buf->data, buf->size << 1);
|
||
|
if(!n) {
|
||
|
ctx->outOfMemory(ctx, buf->size << 1);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
buf->size <<= 1;
|
||
|
buf->data = n;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int buffer_copy(struct csxml* ctx, struct csxml_buf* dest, const struct csxml_buf* src)
|
||
|
{
|
||
|
while(dest->size <= src->len) if(do_realloc(ctx, dest)) return -1;
|
||
|
strcpy(dest->data, src->data);
|
||
|
dest->len = src->len;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int buffer_strcat(struct csxml* ctx, struct csxml_buf* dest, const char* src)
|
||
|
{
|
||
|
size_t req = strlen(src) + dest->len;
|
||
|
while(req >= dest->size) if(do_realloc(ctx, dest)) return -1;
|
||
|
strcat(dest->data, src);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int buffer_init(struct csxml* ctx, struct csxml_buf* buf)
|
||
|
{
|
||
|
memset(buf, 0, sizeof(buf));
|
||
|
buf->size = 256;
|
||
|
buf->data = malloc(buf->size);
|
||
|
if(!buf->data) {
|
||
|
ctx->outOfMemory(ctx, buf->size);
|
||
|
return -1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void buffer_free(struct csxml_buf* buf)
|
||
|
{
|
||
|
free(buf->data);
|
||
|
memset(buf, 0, sizeof(struct csxml_buf));
|
||
|
}
|
||
|
|
||
|
static int do_realloc2(struct csxml* ctx, struct csxml_list* list)
|
||
|
{
|
||
|
size_t i, newlen = list->size ? (list->size << 1) : 4;
|
||
|
struct csxml_buf* n = realloc(list->data, newlen * sizeof(struct csxml_buf));
|
||
|
if(!n) {
|
||
|
ctx->outOfMemory(ctx, newlen * sizeof(struct csxml_buf));
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
memset(n + list->size * sizeof(struct csxml_buf), 0, newlen * sizeof(struct csxml_buf));
|
||
|
for(i = 0; i < newlen; ++i) {
|
||
|
if(buffer_init(ctx, n + list->size + i)) return -1;
|
||
|
}
|
||
|
|
||
|
list->size = newlen;
|
||
|
list->data = n;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int list_push(struct csxml* ctx, struct csxml_list* list, struct csxml_buf* buf)
|
||
|
{
|
||
|
if((list->size == list->len) && do_realloc2(ctx, list)) return -1;
|
||
|
if(buffer_copy(ctx, list->data + list->len, buf)) return -1;
|
||
|
++list->len;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static struct csxml_buf* list_pop(struct csxml_list* list)
|
||
|
{
|
||
|
return list->data + --list->len;
|
||
|
}
|
||
|
|
||
|
static void list_free(struct csxml_list* list)
|
||
|
{
|
||
|
size_t i;
|
||
|
|
||
|
for(i = 0; i < list->size; ++i) buffer_free(list->data + i);
|
||
|
free(list->data);
|
||
|
memset(list, 0, sizeof(struct csxml_list));
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/* options for text editors
|
||
|
kate: replace-trailing-space-save true; space-indent true; tab-width 4;
|
||
|
vim: expandtab:ts=4:sw=4
|
||
|
*/
|