12 WPLString
= 0x57504c01,
14 WPLArray
= 0x57504c03,
15 WPLDictionary
= 0x57504c04
19 typedef struct W_PropList
{
35 static unsigned hashPropList(WMPropList
*plist
);
40 typedef unsigned (*hashFunc
)(const void*);
41 typedef Bool (*isEqualFunc
)(const void*, const void*);
42 typedef void* (*retainFunc
)(const void*);
43 typedef void (*releaseFunc
)(const void*);
45 static const WMHashTableCallbacks WMPropListHashCallbacks
= {
46 (hashFunc
)hashPropList
,
47 (isEqualFunc
)WMArePropListsEqual
,
52 static WMCompareDataProc
*strCmp
= (WMCompareDataProc
*) strcmp
;
57 hashPropList(WMPropList
*plist
)
64 switch (plist
->type
) {
66 key
= plist
->d
.string
;
69 ctr
= (ctr
+ 1) % sizeof (char *);
74 key
= WMDataBytes(plist
->d
.data
);
75 for (i
=0; i
<WMGetDataLength(plist
->d
.data
); i
++) {
77 ctr
= (ctr
+ 1) % sizeof (char *);
82 wwarning(_("Only string or data is supported for a proplist dictionary key"));
90 WMSetPropListStringComparer(WMCompareDataProc
*comparer
)
93 strCmp
= (WMCompareDataProc
*) strcmp
;
100 WMCreatePropListString(char *str
)
104 wassertrv(str
!=NULL
, NULL
);
106 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
108 plist
->type
= WPLString
;
109 plist
->d
.string
= wstrdup(str
);
110 plist
->retainCount
= 1;
117 WMCreatePropListDataWithBytes(unsigned char *bytes
, unsigned int length
)
121 wassertrv(bytes
!=NULL
, NULL
);
123 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
125 plist
->type
= WPLData
;
126 plist
->d
.data
= WMCreateDataWithBytes(bytes
, length
);
127 plist
->retainCount
= 1;
134 WMCreatePropListDataWithBytesNoCopy(unsigned char *bytes
, unsigned int length
,
135 WMFreeDataProc
*destructor
)
139 wassertrv(length
!=0 && bytes
!=NULL
, NULL
);
141 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
143 plist
->type
= WPLData
;
144 plist
->d
.data
= WMCreateDataWithBytesNoCopy(bytes
, length
, destructor
);
145 plist
->retainCount
= 1;
152 WMCreatePropListDataWithData(WMData
*data
)
156 wassertrv(data
!=NULL
, NULL
);
158 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
160 plist
->type
= WPLData
;
161 plist
->d
.data
= WMRetainData(data
);
162 plist
->retainCount
= 1;
169 WMCreatePropListArrayFromElements(WMPropList
*elem
, ...)
171 WMPropList
*plist
, *nelem
;
174 plist
= (WMPropList
*)wmalloc(sizeof(W_PropList
));
175 plist
->type
= WPLArray
;
176 plist
->d
.array
= WMCreateArray(4);
177 plist
->retainCount
= 1;
182 WMAddToArray(plist
->d
.array
, WMRetainPropList(elem
));
187 nelem
= va_arg(ap
, WMPropList
*);
192 WMAddToArray(plist
->d
.array
, WMRetainPropList(nelem
));
198 WMCreatePropListDictionaryFromEntries(WMPropList
*key
, WMPropList
*value
, ...)
204 WMRetainPropList(WMPropList
*plist
)
206 WMPropList
*key
, *value
;
210 plist
->retainCount
++;
212 switch(plist
->type
) {
217 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
218 WMRetainPropList(WMGetFromArray(plist
->d
.array
, i
));
222 e
= WMEnumerateHashTable(plist
->d
.dict
);
223 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&value
, (void**)&key
)) {
224 WMRetainPropList(key
);
225 WMRetainPropList(value
);
229 wwarning(_("Used proplist functions on non-WMPropLists objects"));
230 wassertrv(False
, NULL
);
239 WMReleasePropList(WMPropList
*plist
)
241 WMPropList
*key
, *value
;
245 plist
->retainCount
--;
247 switch(plist
->type
) {
249 if (plist
->retainCount
< 1) {
250 wfree(plist
->d
.string
);
255 if (plist
->retainCount
< 1) {
256 WMReleaseData(plist
->d
.data
);
261 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
262 WMReleasePropList(WMGetFromArray(plist
->d
.array
, i
));
264 if (plist
->retainCount
< 1) {
265 WMFreeArray(plist
->d
.array
);
270 e
= WMEnumerateHashTable(plist
->d
.dict
);
271 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&value
, (void**)&key
)) {
272 WMReleasePropList(key
);
273 WMReleasePropList(value
);
275 if (plist
->retainCount
< 1) {
276 WMFreeHashTable(plist
->d
.dict
);
281 wwarning(_("Used proplist functions on non-WMPropLists objects"));
288 WMReleasePropList(WMPropList
*plist
)
290 WMPropList
*key
, *value
;
294 plist
->retainCount
--;
296 switch(plist
->type
) {
301 for (i
=0; i
<WMGetArrayItemCount(plist
->d
.array
); i
++) {
302 WMReleasePropList(WMGetFromArray(plist
->d
.array
, i
));
306 e
= WMEnumerateHashTable(plist
->d
.dict
);
307 while (WMNextHashEnumeratorItemAndKey(&e
, (void**)&value
, (void**)&key
)) {
308 WMReleasePropList(key
);
309 WMReleasePropList(value
);
313 wwarning(_("Used proplist functions on non-WMPropLists objects"));
317 if (plist
->retainCount
> 0)
320 switch(plist
->type
) {
322 wfree(plist
->d
.string
);
325 WMReleaseData(plist
->d
.data
);
328 WMFreeArray(plist
->d
.array
);
331 WMFreeHashTable(plist
->d
.dict
);
334 wwarning(_("Used proplist functions on non-WMPropLists objects"));
343 WMPropListIsString(WMPropList
*plist
)
345 return (plist
->type
== WPLString
);
350 WMPropListIsData(WMPropList
*plist
)
352 return (plist
->type
== WPLData
);
357 WMPropListIsArray(WMPropList
*plist
)
359 return (plist
->type
== WPLArray
);
364 WMPropListIsDictionary(WMPropList
*plist
)
366 return (plist
->type
== WPLDictionary
);
371 WMPropListIsSimple(WMPropList
*plist
)
373 return (plist
->type
==WPLString
|| plist
->type
==WPLData
);
378 WMPropListIsCompound(WMPropList
*plist
)
380 return (plist
->type
==WPLArray
|| plist
->type
==WPLDictionary
);
385 WMArePropListsEqual(WMPropList
*plist
, WMPropList
*other
)
387 WMPropList
*key1
, *key2
, *item1
, *item2
;
388 WMHashEnumerator enumerator
;
391 if (plist
->type
!= other
->type
)
394 switch(plist
->type
) {
396 return ((*strCmp
)(plist
->d
.string
, other
->d
.string
) == 0);
398 return WMIsDataEqualToData(plist
->d
.data
, other
->d
.data
);
400 n
= WMGetArrayItemCount(plist
->d
.array
);
401 if (n
!= WMGetArrayItemCount(other
->d
.array
))
403 for (i
=0; i
<n
; i
++) {
404 item1
= WMGetFromArray(plist
->d
.array
, i
);
405 item2
= WMGetFromArray(other
->d
.array
, i
);
406 if (!WMArePropListsEqual(item1
, item2
))
411 if (WMCountHashTable(plist
->d
.dict
) != WMCountHashTable(other
->d
.dict
))
413 enumerator
= WMEnumerateHashTable(plist
->d
.dict
);
414 while (WMNextHashEnumeratorItemAndKey(&enumerator
, (void**)&item1
,
416 item2
= WMHashGet(other
->d
.dict
, key1
);
417 if (!item2
|| !item1
|| !WMArePropListsEqual(item1
, item2
))
422 wwarning(_("Used proplist functions on non-WMPropLists objects"));
423 wassertrv(False
, False
);