ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dictionary.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.