1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-24 07:02:30 +01:00

preliminary code for property list manipulation

This commit is contained in:
dan
2001-09-06 00:55:18 +00:00
parent 44363ce805
commit 2d5a062064
4 changed files with 258 additions and 10 deletions

View File

@@ -36,6 +36,7 @@ libWINGs_a_SOURCES = \
memory.c \
misc.c \
notification.c \
proplist.c \
selection.c \
string.c \
tree.c \
@@ -75,8 +76,7 @@ libWINGs_a_SOURCES = \
wtext.c \
wtextfield.c \
wview.c \
wwindow.c \
snprintf.c
wwindow.c
libWUtil_a_SOURCES = \
@@ -93,14 +93,15 @@ libWUtil_a_SOURCES = \
memory.c \
misc.c \
notification.c \
proplist.c \
string.c \
tree.c \
userdefaults.c \
usleep.c \
wapplication.c \
wconfig.h \
wutil.c\
snprintf.c
wutil.c
CPPFLAGS = @CPPFLAGS@ -DLOCALEDIR=\"$(NLSDIR)\"

View File

@@ -121,13 +121,13 @@ typedef struct W_Array WMArray;
typedef struct W_Bag WMBag;
typedef struct W_Data WMData;
typedef struct W_TreeNode WMTreeNode;
typedef struct W_HashTable WMDictionary;
typedef struct W_HashTable WMHashTable;
typedef struct W_UserDefaults WMUserDefaults;
typedef struct W_Notification WMNotification;
typedef struct W_NotificationQueue WMNotificationQueue;
typedef struct W_Host WMHost;
typedef struct W_Connection WMConnection;
typedef struct W_PropList WMPropList;
@@ -332,6 +332,8 @@ void WMFreeHashTable(WMHashTable *table);
void WMResetHashTable(WMHashTable *table);
unsigned WMCountHashTable(WMHashTable *table);
void* WMHashGet(WMHashTable *table, const void *key);
/* put data in table, replacing already existing data and returning
@@ -340,14 +342,20 @@ void* WMHashInsert(WMHashTable *table, const void *key, const void *data);
void WMHashRemove(WMHashTable *table, const void *key);
/* warning: do not manipulate the table while using these functions */
/* warning: do not manipulate the table while using the enumerator functions */
WMHashEnumerator WMEnumerateHashTable(WMHashTable *table);
void* WMNextHashEnumeratorItem(WMHashEnumerator *enumerator);
void* WMNextHashEnumeratorKey(WMHashEnumerator *enumerator);
unsigned WMCountHashTable(WMHashTable *table);
/* Returns True if there is a next element, in which case key and item
* will contain the next element's key and value respectively.
* If there is no next element available it will return False and in this
* case key and item will be undefined.
*/
Bool WMNextHashEnumeratorItemAndKey(WMHashEnumerator *enumerator,
void **item, void **key);

View File

@@ -185,6 +185,12 @@ WMFreeHashTable(WMHashTable *table)
}
unsigned
WMCountHashTable(WMHashTable *table)
{
return table->itemCount;
}
void*
WMHashGet(WMHashTable *table, const void *key)
@@ -388,10 +394,34 @@ WMNextHashEnumeratorKey(WMHashEnumerator *enumerator)
}
unsigned
WMCountHashTable(WMHashTable *table)
Bool
WMNextHashEnumeratorItemAndKey(WMHashEnumerator *enumerator,
void **item, void **key)
{
return table->itemCount;
const void *data = NULL;
/* this assumes the table doesn't change between
* WMEnumerateHashTable() and WMNextHashEnumeratorItemAndKey() calls */
if (enumerator->nextItem==NULL) {
HashTable *table = enumerator->table;
while (++enumerator->index < table->size) {
if (table->table[enumerator->index]!=NULL) {
enumerator->nextItem = table->table[enumerator->index];
break;
}
}
}
if (enumerator->nextItem) {
*item = (void*)((HashItem*)enumerator->nextItem)->data;
*key = (void*)((HashItem*)enumerator->nextItem)->key;
enumerator->nextItem = ((HashItem*)enumerator->nextItem)->next;
return True;
}
return False;
}

209
WINGs/proplist.c Normal file
View File

@@ -0,0 +1,209 @@
#include <string.h>
#include "WUtil.h"
#include "wconfig.h"
typedef enum {
WPLString = 0x57504c01,
WPLData = 0x57504c02,
WPLArray = 0x57504c03,
WPLDictionary = 0x57504c04
} WPLType;
typedef struct W_PropList {
WPLType type;
union {
char *string;
WMData *data;
WMArray *array;
WMHashTable *dict;
} d;
int retainCount;
} W_PropList;
static WMCompareDataProc *strCmp = (WMCompareDataProc*) strcmp;
void
WMSetPropListStringComparer(WMCompareDataProc *comparer)
{
if (!comparer)
strCmp = (WMCompareDataProc*) strcmp;
else
strCmp = comparer;
}
static unsigned
hashPropList(WMPropList *plist)
{
unsigned ret = 0;
unsigned ctr = 0;
const char *key;
int i;
switch (plist->type) {
case WPLString:
key = plist->d.string;
while (*key) {
ret ^= *key++ << ctr;
ctr = (ctr + 1) % sizeof (char *);
}
return ret;
case WPLData:
key = WMDataBytes(plist->d.data);
for (i=0; i<WMGetDataLength(plist->d.data); i++) {
ret ^= key[i] << ctr;
ctr = (ctr + 1) % sizeof (char *);
}
return ret;
default:
wwarning(_("Only string or data is supported for a proplist dictionary key"));
wassertrv(False, 0);
break;
}
}
WMPropList*
WMCreatePropListString(char *str)
{
WMPropList *plist;
wassertrv(str!=NULL, NULL);
plist = (WMPropList*)wmalloc(sizeof(WMPropList));
plist->type = WPLString;
plist->d.string = wstrdup(str);
plist->retainCount = 1;
return plist;
}
WMPropList*
WMCreatePropListDataWithBytes(unsigned char *bytes, unsigned int length)
{
WMPropList *plist;
wassertrv(length!=0 && bytes!=NULL, NULL);
plist = (WMPropList*)wmalloc(sizeof(WMPropList));
plist->type = WPLData;
plist->d.data = WMCreateDataWithBytes(bytes, length);
plist->retainCount = 1;
return plist;
}
WMPropList*
WMCreatePropListDataWithBytesNoCopy(unsigned char *bytes, unsigned int length,
WMFreeDataProc *destructor)
{
WMPropList *plist;
wassertrv(length!=0 && bytes!=NULL, NULL);
plist = (WMPropList*)wmalloc(sizeof(WMPropList));
plist->type = WPLData;
plist->d.data = WMCreateDataWithBytesNoCopy(bytes, length, destructor);
plist->retainCount = 1;
return plist;
}
WMPropList*
WMCreatePropListDataWithData(WMData *data)
{
WMPropList *plist;
wassertrv(data!=NULL, NULL);
plist = (WMPropList*)wmalloc(sizeof(WMPropList));
plist->type = WPLData;
plist->d.data = WMRetainData(data);
plist->retainCount = 1;
return plist;
}
Bool
WMIsPropListEqualWith(WMPropList *plist, WMPropList *other)
{
WMPropList *key1, *key2, *item1, *item2;
WMHashEnumerator enumerator;
int n, i;
if (plist->type != other->type)
return False;
switch(plist->type) {
case WPLString:
return ((*strCmp)(plist->d.string, other->d.string) == 0);
case WPLData:
return WMIsDataEqualToData(plist->d.data, other->d.data);
case WPLArray:
n = WMGetArrayItemCount(plist->d.array);
if (n != WMGetArrayItemCount(other->d.array))
return False;
for (i=0; i<n; i++) {
item1 = WMGetFromArray(plist->d.array, i);
item2 = WMGetFromArray(other->d.array, i);
if (!WMIsPropListEqualWith(item1, item2))
return False;
}
return True;
case WPLDictionary:
if (WMCountHashTable(plist->d.dict) != WMCountHashTable(other->d.dict))
return False;
enumerator = WMEnumerateHashTable(plist->d.dict);
while (WMNextHashEnumeratorItemAndKey(&enumerator, (void**)&item1,
(void**)&key1)) {
item2 = WMHashGet(other->d.dict, key1);
if (!item2 || !item1 || !WMIsPropListEqualWith(item1, item2))
return False;
}
return True;
default:
wwarning(_("Used proplist functions on non-WMPropLists objects"));
wassertrv(False, False);
}
return False;
}
typedef unsigned (*hashFunc)(const void*);
typedef Bool (*isEqualFunc)(const void*, const void*);
typedef void* (*retainFunc)(const void*);
typedef void (*releaseFunc)(const void*);
const WMHashTableCallbacks WMPropListHashCallbacks = {
(hashFunc)hashPropList,
(isEqualFunc)WMIsPropListEqualWith,
(retainFunc)NULL,
(releaseFunc)NULL
};