ucx/map.c

changeset 5
88625853ae74
parent 1
1bcaac272cdf
child 17
11dffb40cd91
--- 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 <stdlib.h>
@@ -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;
-}

mercurial