preliminary code for property list manipulation
[wmaker-crm.git] / WINGs / proplist.c
blob3c435c2d460688f0bfae59660fe3a71edda12f0f
3 #include <string.h>
4 #include "WUtil.h"
5 #include "wconfig.h"
9 typedef enum {
10 WPLString = 0x57504c01,
11 WPLData = 0x57504c02,
12 WPLArray = 0x57504c03,
13 WPLDictionary = 0x57504c04
14 } WPLType;
17 typedef struct W_PropList {
18 WPLType type;
20 union {
21 char *string;
22 WMData *data;
23 WMArray *array;
24 WMHashTable *dict;
25 } d;
27 int retainCount;
28 } W_PropList;
32 static WMCompareDataProc *strCmp = (WMCompareDataProc*) strcmp;
36 void
37 WMSetPropListStringComparer(WMCompareDataProc *comparer)
39 if (!comparer)
40 strCmp = (WMCompareDataProc*) strcmp;
41 else
42 strCmp = comparer;
46 static unsigned
47 hashPropList(WMPropList *plist)
49 unsigned ret = 0;
50 unsigned ctr = 0;
51 const char *key;
52 int i;
54 switch (plist->type) {
55 case WPLString:
56 key = plist->d.string;
57 while (*key) {
58 ret ^= *key++ << ctr;
59 ctr = (ctr + 1) % sizeof (char *);
61 return ret;
63 case WPLData:
64 key = WMDataBytes(plist->d.data);
65 for (i=0; i<WMGetDataLength(plist->d.data); i++) {
66 ret ^= key[i] << ctr;
67 ctr = (ctr + 1) % sizeof (char *);
69 return ret;
71 default:
72 wwarning(_("Only string or data is supported for a proplist dictionary key"));
73 wassertrv(False, 0);
74 break;
79 WMPropList*
80 WMCreatePropListString(char *str)
82 WMPropList *plist;
84 wassertrv(str!=NULL, NULL);
86 plist = (WMPropList*)wmalloc(sizeof(WMPropList));
88 plist->type = WPLString;
89 plist->d.string = wstrdup(str);
90 plist->retainCount = 1;
92 return plist;
96 WMPropList*
97 WMCreatePropListDataWithBytes(unsigned char *bytes, unsigned int length)
99 WMPropList *plist;
101 wassertrv(length!=0 && bytes!=NULL, NULL);
103 plist = (WMPropList*)wmalloc(sizeof(WMPropList));
105 plist->type = WPLData;
106 plist->d.data = WMCreateDataWithBytes(bytes, length);
107 plist->retainCount = 1;
109 return plist;
113 WMPropList*
114 WMCreatePropListDataWithBytesNoCopy(unsigned char *bytes, unsigned int length,
115 WMFreeDataProc *destructor)
117 WMPropList *plist;
119 wassertrv(length!=0 && bytes!=NULL, NULL);
121 plist = (WMPropList*)wmalloc(sizeof(WMPropList));
123 plist->type = WPLData;
124 plist->d.data = WMCreateDataWithBytesNoCopy(bytes, length, destructor);
125 plist->retainCount = 1;
127 return plist;
131 WMPropList*
132 WMCreatePropListDataWithData(WMData *data)
134 WMPropList *plist;
136 wassertrv(data!=NULL, NULL);
138 plist = (WMPropList*)wmalloc(sizeof(WMPropList));
140 plist->type = WPLData;
141 plist->d.data = WMRetainData(data);
142 plist->retainCount = 1;
144 return plist;
148 Bool
149 WMIsPropListEqualWith(WMPropList *plist, WMPropList *other)
151 WMPropList *key1, *key2, *item1, *item2;
152 WMHashEnumerator enumerator;
153 int n, i;
155 if (plist->type != other->type)
156 return False;
158 switch(plist->type) {
159 case WPLString:
160 return ((*strCmp)(plist->d.string, other->d.string) == 0);
161 case WPLData:
162 return WMIsDataEqualToData(plist->d.data, other->d.data);
163 case WPLArray:
164 n = WMGetArrayItemCount(plist->d.array);
165 if (n != WMGetArrayItemCount(other->d.array))
166 return False;
167 for (i=0; i<n; i++) {
168 item1 = WMGetFromArray(plist->d.array, i);
169 item2 = WMGetFromArray(other->d.array, i);
170 if (!WMIsPropListEqualWith(item1, item2))
171 return False;
173 return True;
174 case WPLDictionary:
175 if (WMCountHashTable(plist->d.dict) != WMCountHashTable(other->d.dict))
176 return False;
177 enumerator = WMEnumerateHashTable(plist->d.dict);
178 while (WMNextHashEnumeratorItemAndKey(&enumerator, (void**)&item1,
179 (void**)&key1)) {
180 item2 = WMHashGet(other->d.dict, key1);
181 if (!item2 || !item1 || !WMIsPropListEqualWith(item1, item2))
182 return False;
184 return True;
185 default:
186 wwarning(_("Used proplist functions on non-WMPropLists objects"));
187 wassertrv(False, False);
190 return False;
195 typedef unsigned (*hashFunc)(const void*);
196 typedef Bool (*isEqualFunc)(const void*, const void*);
197 typedef void* (*retainFunc)(const void*);
198 typedef void (*releaseFunc)(const void*);
201 const WMHashTableCallbacks WMPropListHashCallbacks = {
202 (hashFunc)hashPropList,
203 (isEqualFunc)WMIsPropListEqualWith,
204 (retainFunc)NULL,
205 (releaseFunc)NULL