Begin implementing IPropertyStorage.
This commit is contained in:
parent
f75609087a
commit
be84f8d9e6
@ -5,7 +5,7 @@ SRCDIR = @srcdir@
|
|||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
MODULE = ole32.dll
|
MODULE = ole32.dll
|
||||||
IMPORTS = advapi32 user32 gdi32 rpcrt4 kernel32 ntdll
|
IMPORTS = advapi32 user32 gdi32 rpcrt4 kernel32 ntdll
|
||||||
EXTRALIBS = -luuid
|
EXTRALIBS = -luuid $(LIBUNICODE)
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
antimoniker.c \
|
antimoniker.c \
|
||||||
@ -15,6 +15,7 @@ C_SRCS = \
|
|||||||
compositemoniker.c \
|
compositemoniker.c \
|
||||||
datacache.c \
|
datacache.c \
|
||||||
defaulthandler.c \
|
defaulthandler.c \
|
||||||
|
dictionary.c \
|
||||||
errorinfo.c \
|
errorinfo.c \
|
||||||
filemoniker.c \
|
filemoniker.c \
|
||||||
ftmarshal.c \
|
ftmarshal.c \
|
||||||
|
170
dlls/ole32/dictionary.c
Normal file
170
dlls/ole32/dictionary.c
Normal file
@ -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);
|
||||||
|
}
|
87
dlls/ole32/dictionary.h
Normal file
87
dlls/ole32/dictionary.h
Normal file
@ -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…
x
Reference in New Issue
Block a user