Commit be84f8d9 authored by Juan Lang's avatar Juan Lang Committed by Alexandre Julliard

Begin implementing IPropertyStorage.

parent f7560908
......@@ -5,7 +5,7 @@ SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = ole32.dll
IMPORTS = advapi32 user32 gdi32 rpcrt4 kernel32 ntdll
EXTRALIBS = -luuid
EXTRALIBS = -luuid $(LIBUNICODE)
C_SRCS = \
antimoniker.c \
......@@ -15,6 +15,7 @@ C_SRCS = \
compositemoniker.c \
datacache.c \
defaulthandler.c \
dictionary.c \
errorinfo.c \
filemoniker.c \
ftmarshal.c \
......
/* Simple dictionary implementation using a linked list.
* FIXME: a skip list would be faster.
*
* Copyright 2005 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <assert.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "dictionary.h"
struct dictionary_entry
{
void *key;
void *value;
struct dictionary_entry *next;
};
struct dictionary
{
comparefunc comp;
destroyfunc destroy;
void *extra;
struct dictionary_entry *head;
};
struct dictionary *dictionary_create(comparefunc c, destroyfunc d, void *extra)
{
struct dictionary *ret;
if (!c)
return NULL;
ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dictionary));
if (ret)
{
ret->comp = c;
ret->destroy = d;
ret->extra = extra;
ret->head = NULL;
}
return ret;
}
void dictionary_destroy(struct dictionary *d)
{
if (d)
{
struct dictionary_entry *p;
for (p = d->head; p; )
{
struct dictionary_entry *next = p->next;
if (d->destroy)
d->destroy(p->key, p->value, d->extra);
HeapFree(GetProcessHeap(), 0, p);
p = next;
}
HeapFree(GetProcessHeap(), 0, d);
}
}
/* Returns the address of the pointer to the node containing k. (It returns
* the address of either h->head or the address of the next member of the
* prior node. It's useful when you want to delete.)
* Assumes h and prev are not NULL.
*/
static struct dictionary_entry **dictionary_find_internal(struct dictionary *d,
const void *k)
{
struct dictionary_entry **ret = NULL;
struct dictionary_entry *p;
assert(d);
/* special case for head containing the desired element */
if (d->head && d->comp(k, d->head->key, d->extra) == 0)
ret = &d->head;
for (p = d->head; !ret && p && p->next; p = p->next)
{
if (d->comp(k, p->next->key, d->extra) == 0)
ret = &p->next;
}
return ret;
}
void dictionary_insert(struct dictionary *d, const void *k, const void *v)
{
struct dictionary_entry **prior;
if (!d)
return;
if ((prior = dictionary_find_internal(d, k)))
{
if (d->destroy)
d->destroy((*prior)->key, (*prior)->value, d->extra);
(*prior)->key = (void *)k;
(*prior)->value = (void *)v;
}
else
{
struct dictionary_entry *elem = (struct dictionary_entry *)
HeapAlloc(GetProcessHeap(), 0, sizeof(struct dictionary_entry));
if (!elem)
return;
elem->key = (void *)k;
elem->value = (void *)v;
elem->next = d->head;
d->head = elem;
}
}
BOOL dictionary_find(struct dictionary *d, const void *k, void **value)
{
struct dictionary_entry **prior;
BOOL ret = FALSE;
if (!d)
return FALSE;
if (!value)
return FALSE;
if ((prior = dictionary_find_internal(d, k)))
{
*value = (*prior)->value;
ret = TRUE;
}
return ret;
}
void dictionary_remove(struct dictionary *d, const void *k)
{
struct dictionary_entry **prior, *temp;
if (!d)
return;
if ((prior = dictionary_find_internal(d, k)))
{
temp = *prior;
if (d->destroy)
d->destroy((*prior)->key, (*prior)->value, d->extra);
*prior = (*prior)->next;
HeapFree(GetProcessHeap(), 0, temp);
}
}
void dictionary_enumerate(struct dictionary *d, enumeratefunc e)
{
struct dictionary_entry *p;
if (!d)
return;
if (!e)
return;
for (p = d->head; p; p = p->next)
e(p->key, p->value, d->extra);
}
/* Simple dictionary
*
* Copyright 2005 Juan Lang
*
* This is a pretty basic dictionary, or map if you prefer. It's not
* thread-safe.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __DICTIONARY_H__
#define __DICTIONARY_H__
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
struct dictionary;
/* Returns whether key a is less than, equal to, or greater than key b, in
* the same way (a - b) would for integers or strcmp(a, b) would for ANSI
* strings.
*/
typedef int (*comparefunc)(const void *a, const void *b, void *extra);
/* Called for every element removed from the dictionary. See
* dictionary_destroy, dictionary_insert, and dictionary_remove.
*/
typedef void (*destroyfunc)(void *k, void *v, void *extra);
/* Called for each element in the dictionary. Return FALSE if you don't want
* to enumerate any more.
*/
typedef BOOL (*enumeratefunc)(const void *k, const void *d, void *extra);
/* Constructs a dictionary, using c as a comparison function for keys.
* If d is not NULL, it will be called whenever an item is about to be removed
* from the table, for example when dictionary_remove is called for a key, or
* when dictionary_destroy is called.
* extra is passed to c (and d, if it's provided).
* Assumes c is not NULL.
*/
struct dictionary *dictionary_create(comparefunc c, destroyfunc d, void *extra);
/* Assumes d is not NULL. */
void dictionary_destroy(struct dictionary *d);
/* Sets an element with key k and value v to the dictionary. If a value
* already exists with key k, its value is replaced, and the destroyfunc (if
* set) is called for the previous item.
* Assumes k and v can be bitwise-copied.
* Both k and v are allowed to be NULL, in case you want to use integer
* values for either the key or the value.
* Assumes d is not NULL.
*/
void dictionary_insert(struct dictionary *d, const void *k, const void *v);
/* If a value with key k has been inserted into the dictionary, *v is set
* to its associated value. Returns FALSE if the key is not found, and TRUE
* if it is. *v is undefined if it returns FALSE. (It is not set to NULL,
* because this dictionary doesn't prevent you from using NULL as a value
* value; see dictionary_insert.)
* Assumes d and v are not NULL.
*/
BOOL dictionary_find(struct dictionary *d, const void *k, void **v);
/* Removes the element with key k from the dictionary. Calls the destroyfunc
* for the dictionary with the element if found (so you may destroy it if it's
* dynamically allocated.)
* Assumes d is not NULL.
*/
void dictionary_remove(struct dictionary *d, const void *k);
void dictionary_enumerate(struct dictionary *d, enumeratefunc e);
#endif /* ndef __DICTIONARY_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment