mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-28 17:32:29 +01:00
preliminary code for property list manipulation
This commit is contained in:
@@ -36,6 +36,7 @@ libWINGs_a_SOURCES = \
|
|||||||
memory.c \
|
memory.c \
|
||||||
misc.c \
|
misc.c \
|
||||||
notification.c \
|
notification.c \
|
||||||
|
proplist.c \
|
||||||
selection.c \
|
selection.c \
|
||||||
string.c \
|
string.c \
|
||||||
tree.c \
|
tree.c \
|
||||||
@@ -75,8 +76,7 @@ libWINGs_a_SOURCES = \
|
|||||||
wtext.c \
|
wtext.c \
|
||||||
wtextfield.c \
|
wtextfield.c \
|
||||||
wview.c \
|
wview.c \
|
||||||
wwindow.c \
|
wwindow.c
|
||||||
snprintf.c
|
|
||||||
|
|
||||||
|
|
||||||
libWUtil_a_SOURCES = \
|
libWUtil_a_SOURCES = \
|
||||||
@@ -93,14 +93,15 @@ libWUtil_a_SOURCES = \
|
|||||||
memory.c \
|
memory.c \
|
||||||
misc.c \
|
misc.c \
|
||||||
notification.c \
|
notification.c \
|
||||||
|
proplist.c \
|
||||||
string.c \
|
string.c \
|
||||||
tree.c \
|
tree.c \
|
||||||
userdefaults.c \
|
userdefaults.c \
|
||||||
usleep.c \
|
usleep.c \
|
||||||
wapplication.c \
|
wapplication.c \
|
||||||
wconfig.h \
|
wconfig.h \
|
||||||
wutil.c\
|
wutil.c
|
||||||
snprintf.c
|
|
||||||
|
|
||||||
CPPFLAGS = @CPPFLAGS@ -DLOCALEDIR=\"$(NLSDIR)\"
|
CPPFLAGS = @CPPFLAGS@ -DLOCALEDIR=\"$(NLSDIR)\"
|
||||||
|
|
||||||
|
|||||||
@@ -121,13 +121,13 @@ typedef struct W_Array WMArray;
|
|||||||
typedef struct W_Bag WMBag;
|
typedef struct W_Bag WMBag;
|
||||||
typedef struct W_Data WMData;
|
typedef struct W_Data WMData;
|
||||||
typedef struct W_TreeNode WMTreeNode;
|
typedef struct W_TreeNode WMTreeNode;
|
||||||
typedef struct W_HashTable WMDictionary;
|
|
||||||
typedef struct W_HashTable WMHashTable;
|
typedef struct W_HashTable WMHashTable;
|
||||||
typedef struct W_UserDefaults WMUserDefaults;
|
typedef struct W_UserDefaults WMUserDefaults;
|
||||||
typedef struct W_Notification WMNotification;
|
typedef struct W_Notification WMNotification;
|
||||||
typedef struct W_NotificationQueue WMNotificationQueue;
|
typedef struct W_NotificationQueue WMNotificationQueue;
|
||||||
typedef struct W_Host WMHost;
|
typedef struct W_Host WMHost;
|
||||||
typedef struct W_Connection WMConnection;
|
typedef struct W_Connection WMConnection;
|
||||||
|
typedef struct W_PropList WMPropList;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -332,6 +332,8 @@ void WMFreeHashTable(WMHashTable *table);
|
|||||||
|
|
||||||
void WMResetHashTable(WMHashTable *table);
|
void WMResetHashTable(WMHashTable *table);
|
||||||
|
|
||||||
|
unsigned WMCountHashTable(WMHashTable *table);
|
||||||
|
|
||||||
void* WMHashGet(WMHashTable *table, const void *key);
|
void* WMHashGet(WMHashTable *table, const void *key);
|
||||||
|
|
||||||
/* put data in table, replacing already existing data and returning
|
/* 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);
|
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);
|
WMHashEnumerator WMEnumerateHashTable(WMHashTable *table);
|
||||||
|
|
||||||
void* WMNextHashEnumeratorItem(WMHashEnumerator *enumerator);
|
void* WMNextHashEnumeratorItem(WMHashEnumerator *enumerator);
|
||||||
|
|
||||||
void* WMNextHashEnumeratorKey(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);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -185,6 +185,12 @@ WMFreeHashTable(WMHashTable *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned
|
||||||
|
WMCountHashTable(WMHashTable *table)
|
||||||
|
{
|
||||||
|
return table->itemCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void*
|
void*
|
||||||
WMHashGet(WMHashTable *table, const void *key)
|
WMHashGet(WMHashTable *table, const void *key)
|
||||||
@@ -388,10 +394,34 @@ WMNextHashEnumeratorKey(WMHashEnumerator *enumerator)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned
|
Bool
|
||||||
WMCountHashTable(WMHashTable *table)
|
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
209
WINGs/proplist.c
Normal 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
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user