Merged silc_1_0_branch to trunk.
[silc.git] / lib / silccore / silcidcache.c
index fb284c22237fc333807f9a90b56e4deb264e6d67..a2a279cc4567b48abfc8f98439e655b49b47cb04 100644 (file)
@@ -4,12 +4,11 @@
 
   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
 
-  Copyright (C) 2000 - 2001 Pekka Riikonen
+  Copyright (C) 2000 - 2005 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
-  (at your option) any later version.
+  the Free Software Foundation; version 2 of the License.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -67,7 +66,10 @@ struct SilcIDCacheStruct {
   SilcHashTable name_table;
   SilcHashTable context_table;
   SilcIDCacheDestructor destructor;
+  void *context;
   SilcIdType type;
+  unsigned int delete_id : 1;
+  unsigned int delete_name : 1;
 };
 
 /*
@@ -99,7 +101,9 @@ struct SilcIDCacheListStruct {
    cache. */
 
 SilcIDCache silc_idcache_alloc(SilcUInt32 count, SilcIdType id_type,
-                              SilcIDCacheDestructor destructor)
+                              SilcIDCacheDestructor destructor,
+                              void *destructor_context,
+                              bool delete_id, bool delete_name)
 {
   SilcIDCache cache;
 
@@ -109,17 +113,21 @@ SilcIDCache silc_idcache_alloc(SilcUInt32 count, SilcIdType id_type,
   if (!cache)
     return NULL;
   cache->id_table = silc_hash_table_alloc(count, silc_hash_id,
-                                         (void *)(SilcUInt32)id_type,
+                                         SILC_32_TO_PTR(id_type),
                                          silc_hash_id_compare,
-                                         (void *)(SilcUInt32)id_type,
-                                         silc_idcache_destructor, NULL, TRUE);
-  cache->name_table = silc_hash_table_alloc(count, silc_hash_string, NULL,
-                                           silc_hash_string_compare, NULL,
+                                         SILC_32_TO_PTR(id_type),
+                                         silc_idcache_destructor,
+                                         cache, TRUE);
+  cache->name_table = silc_hash_table_alloc(count, silc_hash_utf8_string, NULL,
+                                           silc_hash_utf8_compare, NULL,
                                            NULL, NULL, TRUE);
   cache->context_table = silc_hash_table_alloc(count, silc_hash_ptr, NULL,
                                               NULL, NULL, NULL, NULL, TRUE);
   cache->destructor = destructor;
+  cache->context = destructor_context;
   cache->type = id_type;
+  cache->delete_id = delete_id;
+  cache->delete_name = delete_name;
 
   if (!cache->id_table || !cache->name_table || !cache->context_table) {
     if (cache->id_table)
@@ -191,6 +199,13 @@ static void silc_idcache_destructor(void *key, void *context,
 {
   SilcIDCacheEntry c = context;
   if (c) {
+    SilcIDCache cache = user_context;
+    if (cache) {
+      if (cache->delete_id)
+       silc_free(c->id);
+      if (cache->delete_name)
+       silc_free(c->name);
+    }
     memset(c, 'F', sizeof(*c));
     silc_free(c);
   }
@@ -257,7 +272,6 @@ bool silc_idcache_del_by_id_ext(SilcIDCache cache, void *id,
     ret = silc_hash_table_del_ext(cache->id_table, c->id, hash,
                                  hash_context, compare, compare_context,
                                  NULL, NULL);
-
   return ret;
 }
 
@@ -332,7 +346,7 @@ static void silc_idcache_purge_foreach(void *key, void *context,
     if (ret == TRUE) {
       /* Call the destructor */
       if (cache->destructor)
-       cache->destructor(cache, c);
+       cache->destructor(cache, c, cache->context);
 
       /* Free the entry, it has been deleted from the hash tables */
       silc_idcache_destructor(NULL, c, NULL);
@@ -373,7 +387,7 @@ bool silc_idcache_purge_by_context(SilcIDCache cache, void *context)
   if (ret == TRUE) {
     /* Call the destructor */
     if (cache->destructor)
-      cache->destructor(cache, c);
+      cache->destructor(cache, c, cache->context);
 
     /* Free the entry, it has been deleted from the hash tables */
     silc_idcache_destructor(NULL, c, NULL);