From 2d5a062064f976dac100db76198e13221e93dabc Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 6 Sep 2001 00:55:18 +0000 Subject: [PATCH] preliminary code for property list manipulation --- WINGs/Makefile.am | 9 ++- WINGs/WINGs/WUtil.h | 14 +++- WINGs/hashtable.c | 36 ++++++++- WINGs/proplist.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 258 insertions(+), 10 deletions(-) create mode 100644 WINGs/proplist.c diff --git a/WINGs/Makefile.am b/WINGs/Makefile.am index a962871c..83cfa480 100644 --- a/WINGs/Makefile.am +++ b/WINGs/Makefile.am @@ -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)\" diff --git a/WINGs/WINGs/WUtil.h b/WINGs/WINGs/WUtil.h index 79ee8946..756c8920 100644 --- a/WINGs/WINGs/WUtil.h +++ b/WINGs/WINGs/WUtil.h @@ -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); diff --git a/WINGs/hashtable.c b/WINGs/hashtable.c index fc5f0f8a..2c67ebdb 100644 --- a/WINGs/hashtable.c +++ b/WINGs/hashtable.c @@ -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; } diff --git a/WINGs/proplist.c b/WINGs/proplist.c new file mode 100644 index 00000000..3c435c2d --- /dev/null +++ b/WINGs/proplist.c @@ -0,0 +1,209 @@ + + +#include +#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; id.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; id.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 +}; + + + -- 2.11.4.GIT