Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -1,14 +1,15 @@ SHARED_LIB = ${LIB_PREFIX}corefw${LIB_SUFFIX} LIB_MAJOR = 0 LIB_MINOR = 0 -SRCS = array.c \ - class.c \ - map.c \ - object.c \ - range.c \ +SRCS = array.c \ + class.c \ + map.c \ + object.c \ + range.c \ + refpool.c \ string.c INCLUDES = ${SRCS:.c=.h} \ corefw.h \ hash.h Index: src/object.c ================================================================== --- src/object.c +++ src/object.c @@ -23,12 +23,14 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include +#include #include "object.h" +#include "refpool.h" void* cfw_new(CFWClass *class, ...) { CFWObject *obj; @@ -48,10 +50,43 @@ return NULL; } va_end(args); } + + return obj; +} + +void* +cfw_new_p(CFWClass *class, ...) +{ + CFWObject *obj; + + assert(class != cfw_refpool); + + if ((obj = malloc(class->size)) == NULL) + return NULL; + + obj->cls = class; + obj->ref_cnt = 1; + + if (class->ctor != NULL) { + va_list args; + va_start(args, class); + + if (!class->ctor(obj, args)) { + cfw_unref(obj); + return NULL; + } + + va_end(args); + } + + if (!cfw_refpool_add(obj)) { + cfw_unref(obj); + return NULL; + } return obj; } void* Index: src/object.h ================================================================== --- src/object.h +++ src/object.h @@ -34,10 +34,11 @@ int ref_cnt; } CFWObject; extern CFWClass *cfw_object; extern void* cfw_new(CFWClass*, ...); +extern void* cfw_new_p(CFWClass*, ...); extern void* cfw_ref(void*); extern void cfw_unref(void*); extern void cfw_free(void*); extern bool cfw_equal(void*, void*); extern uint32_t cfw_hash(void*); ADDED src/refpool.c Index: src/refpool.c ================================================================== --- /dev/null +++ src/refpool.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2012, Jonathan Schleifer + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include "object.h" +#include "refpool.h" +#include "array.h" + +struct CFWRefPool { + CFWObject obj; + void **data; + size_t size; + CFWRefPool *prev, *next; +}; + +static CFWRefPool *top; + +static bool +ctor(void *ptr, va_list args) +{ + CFWRefPool *pool = ptr; + + pool->data = NULL; + pool->size = 0; + + if (top != NULL) { + pool->prev = top; + top->next = pool; + } else + pool->prev = NULL; + pool->next = NULL; + + top = pool; + + return true; +} + +static void +dtor(void *ptr) +{ + CFWRefPool *pool = ptr; + size_t i; + + if (pool->next != NULL) + cfw_unref(pool->next); + + for (i = 0; i < pool->size; i++) + cfw_unref(pool->data[i]); + + if (pool->data != NULL) + free(pool->data); + + top = pool->prev; +} + +bool +cfw_refpool_add(void *ptr) +{ + void **ndata; + + assert(top != NULL); + + if (top->data != NULL) + ndata = realloc(top->data, (top->size + 1) * sizeof(void*)); + else + ndata = malloc((top->size + 1) * sizeof(void*)); + + if (ndata == NULL) + return false; + + ndata[top->size++] = ptr; + + top->data = ndata; + + return true; +} + +static CFWClass class = { + .name = "CFWRefPool", + .size = sizeof(CFWRefPool), + .ctor = ctor, + .dtor = dtor +}; +CFWClass *cfw_refpool = &class; ADDED src/refpool.h Index: src/refpool.h ================================================================== --- /dev/null +++ src/refpool.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012, Jonathan Schleifer + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __COREFW_REFPOOL_H__ +#define __COREFW_REFPOOL_H__ + +#include "class.h" + +typedef struct CFWRefPool CFWRefPool; +extern CFWClass *cfw_refpool; +extern bool cfw_refpool_add(void*); + +#endif Index: tests/tests.c ================================================================== --- tests/tests.c +++ tests/tests.c @@ -25,15 +25,16 @@ */ #include #include "object.h" +#include "refpool.h" #include "string.h" #include "array.h" #include "map.h" -void +static void print_map(CFWMap *map) { cfw_map_iter_t iter; cfw_map_iter(map, &iter); @@ -55,57 +56,57 @@ } int main() { - CFWString *s[3]; + CFWRefPool *p; CFWArray *a; + CFWString *s, *s2; CFWMap *m; size_t i; - s[0] = cfw_new(cfw_string, "Hallo"); - s[1] = cfw_new(cfw_string, " Welt"); - s[2] = cfw_new(cfw_string, "!"); - - a = cfw_new(cfw_array, s[0], s[1], s[2], NULL); - - cfw_unref(s[0]); - cfw_unref(s[1]); - cfw_unref(s[2]); - - s[0] = cfw_new(cfw_string, NULL); + p = cfw_new(cfw_refpool); + + a = cfw_new_p(cfw_array, + cfw_new_p(cfw_string, "Hallo"), + cfw_new_p(cfw_string, " Welt"), + cfw_new_p(cfw_string, "!"), NULL); + + s = cfw_new(cfw_string, NULL); for (i = 0; i < cfw_array_size(a); i++) - cfw_string_append(s[0], cfw_array_get(a, i)); - - cfw_unref(a); - - puts(cfw_string_c(s[0])); - - s[1] = cfw_new(cfw_string, "ll"); - printf("%zd\n", cfw_string_find(s[0], s[1], cfw_range_all)); - cfw_unref(s[1]); - - cfw_unref(s[0]); - - s[0] = cfw_new(cfw_string, "Hallo"); - s[1] = cfw_new(cfw_string, "Welt!"); - - m = cfw_new(cfw_map, s[0], s[1], NULL); - cfw_unref(s[1]); - - print_map(m); - - s[1] = cfw_new(cfw_string, "Test"); - cfw_map_set(m, s[0], s[1]); - cfw_unref(s[1]); - - print_map(m); - - cfw_map_set(m, s[0], NULL); - print_map(m); - - cfw_unref(s[0]); - cfw_unref(m); + cfw_string_append(s, cfw_array_get(a, i)); + + cfw_unref(p); + + puts(cfw_string_c(s)); + + p = cfw_new(cfw_refpool); + s2 = cfw_new_p(cfw_string, "ll"); + printf("%zd\n", cfw_string_find(s, s2, cfw_range_all)); + + cfw_unref(p); + cfw_unref(s); + + p = cfw_new(cfw_refpool); + + m = cfw_new_p(cfw_map, + cfw_new_p(cfw_string, "Hallo"), + cfw_new_p(cfw_string, "Welt!"), + cfw_new_p(cfw_string, "Test"), + cfw_new_p(cfw_string, "success!"), NULL); + + print_map(m); + + cfw_map_set(m, + cfw_new_p(cfw_string, "Hallo"), + cfw_new_p(cfw_string, "Test")); + + print_map(m); + + cfw_map_set(m, cfw_new_p(cfw_string, "Hallo"), NULL); + print_map(m); + + cfw_unref(p); return 0; }