Begin implementing IPropertyStorage.
This commit is contained in:
parent
f75609087a
commit
be84f8d9e6
|
@ -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 \
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
/* 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);
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/* 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__ */
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue