diff -r ae5a98f0545c -r 88625853ae74 ucx/map.c --- a/ucx/map.c Sat Dec 01 20:34:55 2012 +0100 +++ b/ucx/map.c Mon Aug 12 14:40:19 2013 +0200 @@ -1,5 +1,29 @@ /* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * + * Copyright 2013 Olaf Wintermann. 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 HOLDER 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 @@ -8,18 +32,30 @@ #include "map.h" UcxMap *ucx_map_new(size_t size) { + return ucx_map_new_a(NULL, size); +} + +UcxMap *ucx_map_new_a(UcxAllocator *allocator, size_t size) { if(size == 0) { size = 16; } + + if(!allocator) { + allocator = ucx_default_allocator(); + } - UcxMap *map = (UcxMap*)malloc(sizeof(UcxMap)); + UcxMap *map = (UcxMap*)allocator->malloc(allocator->pool, sizeof(UcxMap)); if(map == NULL) { return NULL; } - - map->map = (UcxMapElement**)calloc(size, sizeof(UcxMapElement*)); + + map->allocator = allocator; + map->map = (UcxMapElement**)allocator->calloc( + allocator->pool, + size, + sizeof(UcxMapElement*)); if(map->map == NULL) { - free(map); + allocator->free(allocator->pool, map); return NULL; } map->size = size; @@ -28,31 +64,31 @@ return map; } -void ucx_map_free_elmlist(UcxMap *map) { +static void ucx_map_free_elmlist(UcxMap *map) { for (size_t n = 0 ; n < map->size ; n++) { UcxMapElement *elem = map->map[n]; if (elem != NULL) { do { UcxMapElement *next = elem->next; - free(elem->key.data); - free(elem); + map->allocator->free(map->allocator->pool, elem->key.data); + map->allocator->free(map->allocator->pool, elem); elem = next; } while (elem != NULL); } } - free(map->map); + map->allocator->free(map->allocator->pool, map->map); } void ucx_map_free(UcxMap *map) { ucx_map_free_elmlist(map); - free(map); + map->allocator->free(map->allocator->pool, map); } int ucx_map_copy(UcxMap *restrict from, UcxMap *restrict to, copy_func fnc, void *data) { UcxMapIterator i = ucx_map_iterator(from); void *value; - UCX_MAP_FOREACH(value, i) { + UCX_MAP_FOREACH(key, value, i) { int ret = ucx_map_put(to, i.cur->key, fnc ? fnc(value, data) : value); if(ret != 0) { return 1; @@ -78,9 +114,13 @@ oldmap.map = map->map; oldmap.size = map->size; oldmap.count = map->count; + oldmap.allocator = map->allocator; map->size = (map->count * 5) >> 1; - map->map = (UcxMapElement**)calloc(map->size, sizeof(UcxMapElement*)); + map->map = (UcxMapElement**)map->allocator->calloc( + map->allocator->pool, + map->size, + sizeof(UcxMapElement*)); if(map->map == NULL) { *map = oldmap; return 1; @@ -95,6 +135,8 @@ } int ucx_map_put(UcxMap *map, UcxKey key, void *data) { + UcxAllocator *allocator = map->allocator; + if(key.hash == 0) { key.hash = ucx_hash((char*)key.data, key.len); } @@ -109,7 +151,9 @@ } if (elm == NULL || elm->key.hash != key.hash) { - UcxMapElement *e = (UcxMapElement*)malloc(sizeof(UcxMapElement)); + UcxMapElement *e = (UcxMapElement*)allocator->malloc( + allocator->pool, + sizeof(UcxMapElement)); if(e == NULL) { return -1; } @@ -124,7 +168,7 @@ } if(elm->key.data == NULL) { - void *kd = malloc(key.len); + void *kd = allocator->malloc(allocator->pool, key.len); if (kd == NULL) { return -1; } @@ -157,7 +201,7 @@ } else { map->map[slot] = elm->next; } - free(elm); + map->allocator->free(map->allocator->pool, elm); map->count--; } @@ -238,7 +282,7 @@ return i; } -int ucx_map_iter_next(UcxMapIterator *i, void **elm) { +int ucx_map_iter_next(UcxMapIterator *i, UcxKey *key, void **elm) { UcxMapElement *e = i->cur; if(e == NULL) { @@ -252,6 +296,7 @@ if(e->data != NULL) { i->cur = e; *elm = e->data; + *key = e->key; return 0; } @@ -268,123 +313,3 @@ return 1; } -int ucx_map_load_enc(UcxMap *map, FILE *f, UcxAllocator allocator, - ucx_map_coder decoder, void* decdata) { - - int c; int r, n; - - char *key, *value; - - while ((c = fgetc(f)) > 0) { - /* Discard leading spaces and comments */ - if (c < 33) continue; - if (c == '#' || c == '!') { - while ((c = (char) fgetc(f)) > 0) { - if (c == '\n') break; - } - continue; - } - - /* read into key buffer */ - n = 16; - key = (char*) malloc(n); - r = 0; - do { - if (c == '=') break; - if (r > n - 2) { - n *= 2; - key = (char*) realloc(key, n); - } - key[r] = c; - r++; - } while ((c = fgetc(f)) > 0); - if (c <= 0) { - free(key); - return 1; - } - key[r] = 0; - while (key[--r] == ' ') key[r] = 0; - - /* skip whitespaces */ - while ((c = fgetc(f)) > 0) { - if (c > 32) break; - } - if (c <= 0) { - free(key); - return 1; - } - - /* read into value buffer */ - n = 64; - value = (char*) malloc(n); - r = 0; - do { - if (c == '\n') break; - if (r > n - 2) { - n *= 2; - value = (char*) realloc(value, n); - } - value[r] = c; - r++; - } while ((c = fgetc(f)) > 0); - value[r] = 0; - while (value[--r] < 33) value[r] = 0; - - if (decoder) { - size_t decodedSize; - void *decoded = decoder(value, decdata, &decodedSize); - free(value); - value = (char*) decoded; - r = decodedSize; - } else { - r += 2; - value = (char*) realloc(value, r); - } - - if (allocator.pool) { - void *pooledValue = allocator.malloc(allocator.pool, r); - memcpy(pooledValue, value, r); - free(value); - value = (char*) pooledValue; - } - - ucx_map_cstr_put(map, key, value); - free(key); - } - - return 0; -} - -int ucx_map_store_enc(UcxMap *map, FILE *f, - ucx_map_coder encoder, void *encdata) { - UcxMapIterator iter = ucx_map_iterator(map); - char *k, *v; - sstr_t key, value; - int written; - - UCX_MAP_FOREACH(v, iter) { - k = (char*) iter.cur->key.data; - key = sstr(k); - if (encoder) { - size_t encodedSize; - void *encoded = encoder(v, encdata, &encodedSize); - value = sstrn((char*) encoded,encodedSize - 1); - } else { - value = sstr(v); - } - - written = 0; - written += fwrite(key.ptr, 1, key.length, f); - written += fwrite(" = ", 1, 3, f); - written += fwrite(value.ptr, 1, value.length, f); - written += fwrite("\n", 1, 1, f); - - if (encoder) { - free(value.ptr); - } - - if (written != key.length + value.length + 4) return 1; - } - - return 0; -}