Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendictionary.c
Go to the documentation of this file.
00001 /* Simple dictionary implementation using a linked list. 00002 * FIXME: a skip list would be faster. 00003 * 00004 * Copyright 2005 Juan Lang 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 #include <assert.h> 00021 #include <stdarg.h> 00022 #include "windef.h" 00023 #include "winbase.h" 00024 #include "dictionary.h" 00025 #include "wine/debug.h" 00026 00027 WINE_DEFAULT_DEBUG_CHANNEL(storage); 00028 00029 struct dictionary_entry 00030 { 00031 void *key; 00032 void *value; 00033 struct dictionary_entry *next; 00034 }; 00035 00036 struct dictionary 00037 { 00038 comparefunc comp; 00039 destroyfunc destroy; 00040 void *extra; 00041 struct dictionary_entry *head; 00042 UINT num_entries; 00043 }; 00044 00045 struct dictionary *dictionary_create(comparefunc c, destroyfunc d, void *extra) 00046 { 00047 struct dictionary *ret; 00048 00049 TRACE("(%p, %p, %p)\n", c, d, extra); 00050 if (!c) 00051 return NULL; 00052 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dictionary)); 00053 if (ret) 00054 { 00055 ret->comp = c; 00056 ret->destroy = d; 00057 ret->extra = extra; 00058 ret->head = NULL; 00059 ret->num_entries = 0; 00060 } 00061 TRACE("returning %p\n", ret); 00062 return ret; 00063 } 00064 00065 void dictionary_destroy(struct dictionary *d) 00066 { 00067 TRACE("(%p)\n", d); 00068 if (d) 00069 { 00070 struct dictionary_entry *p; 00071 00072 for (p = d->head; p; ) 00073 { 00074 struct dictionary_entry *next = p->next; 00075 00076 if (d->destroy) 00077 d->destroy(p->key, p->value, d->extra); 00078 HeapFree(GetProcessHeap(), 0, p); 00079 p = next; 00080 } 00081 HeapFree(GetProcessHeap(), 0, d); 00082 } 00083 } 00084 00085 UINT dictionary_num_entries(struct dictionary *d) 00086 { 00087 return d ? d->num_entries : 0; 00088 } 00089 00090 /* Returns the address of the pointer to the node containing k. (It returns 00091 * the address of either h->head or the address of the next member of the 00092 * prior node. It's useful when you want to delete.) 00093 * Assumes h and prev are not NULL. 00094 */ 00095 static struct dictionary_entry **dictionary_find_internal(struct dictionary *d, 00096 const void *k) 00097 { 00098 struct dictionary_entry **ret = NULL; 00099 struct dictionary_entry *p; 00100 00101 assert(d); 00102 /* special case for head containing the desired element */ 00103 if (d->head && d->comp(k, d->head->key, d->extra) == 0) 00104 ret = &d->head; 00105 for (p = d->head; !ret && p && p->next; p = p->next) 00106 { 00107 if (d->comp(k, p->next->key, d->extra) == 0) 00108 ret = &p->next; 00109 } 00110 return ret; 00111 } 00112 00113 void dictionary_insert(struct dictionary *d, const void *k, const void *v) 00114 { 00115 struct dictionary_entry **prior; 00116 00117 TRACE("(%p, %p, %p)\n", d, k, v); 00118 if (!d) 00119 return; 00120 if ((prior = dictionary_find_internal(d, k))) 00121 { 00122 if (d->destroy) 00123 d->destroy((*prior)->key, (*prior)->value, d->extra); 00124 (*prior)->key = (void *)k; 00125 (*prior)->value = (void *)v; 00126 } 00127 else 00128 { 00129 struct dictionary_entry *elem = HeapAlloc(GetProcessHeap(), 0, 00130 sizeof(struct dictionary_entry)); 00131 00132 if (!elem) 00133 return; 00134 elem->key = (void *)k; 00135 elem->value = (void *)v; 00136 elem->next = d->head; 00137 d->head = elem; 00138 d->num_entries++; 00139 } 00140 } 00141 00142 BOOL dictionary_find(struct dictionary *d, const void *k, void **value) 00143 { 00144 struct dictionary_entry **prior; 00145 BOOL ret = FALSE; 00146 00147 TRACE("(%p, %p, %p)\n", d, k, value); 00148 if (!d) 00149 return FALSE; 00150 if (!value) 00151 return FALSE; 00152 if ((prior = dictionary_find_internal(d, k))) 00153 { 00154 *value = (*prior)->value; 00155 ret = TRUE; 00156 } 00157 TRACE("returning %d (%p)\n", ret, *value); 00158 return ret; 00159 } 00160 00161 void dictionary_remove(struct dictionary *d, const void *k) 00162 { 00163 struct dictionary_entry **prior, *temp; 00164 00165 TRACE("(%p, %p)\n", d, k); 00166 if (!d) 00167 return; 00168 if ((prior = dictionary_find_internal(d, k))) 00169 { 00170 temp = *prior; 00171 if (d->destroy) 00172 d->destroy((*prior)->key, (*prior)->value, d->extra); 00173 *prior = (*prior)->next; 00174 HeapFree(GetProcessHeap(), 0, temp); 00175 d->num_entries--; 00176 } 00177 } 00178 00179 void dictionary_enumerate(struct dictionary *d, enumeratefunc e, void *closure) 00180 { 00181 struct dictionary_entry *p; 00182 00183 TRACE("(%p, %p, %p)\n", d, e, closure); 00184 if (!d) 00185 return; 00186 if (!e) 00187 return; 00188 for (p = d->head; p; p = p->next) 00189 if (!e(p->key, p->value, d->extra, closure)) 00190 break; 00191 } Generated on Sat May 26 2012 04:24:08 for ReactOS by
1.7.6.1
|