]>
Commit | Line | Data |
---|---|---|
dd9b4b7f RN |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: wx/mac/corefoundation/cfwrappers.h | |
3 | // Purpose: Wrappers around some complex core foundation types | |
4 | // Author: Ryan Norton | |
5 | // Modified by: | |
6 | // Created: 17/04/2005 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) 2005 Ryan Norton | |
9 | // Licence: wxWindows licence | |
10 | /////////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | #ifndef __WX_CFWRAPPERS_H__ | |
13 | #define __WX_CFWRAPPERS_H__ | |
14 | ||
15 | #include "wx/mac/corefoundation/cfstring.h" | |
16 | #include "wx/intl.h" //wxLocale for wxCFString | |
17 | ||
18 | #define wxCF_RELEASE true | |
19 | #define wxCF_RETAIN false | |
20 | ||
21 | // ---------------------------------------------------------------------------- | |
22 | // wxCFDictionary | |
23 | // ---------------------------------------------------------------------------- | |
24 | ||
25 | class wxCFDictionary | |
26 | { | |
27 | public: | |
28 | wxCFDictionary(CFTypeRef ref, bool bRetain = wxCF_RELEASE) | |
29 | { | |
30 | m_cfmdRef = (CFMutableDictionaryRef) ref; | |
31 | if(bRetain == wxCF_RETAIN && ref) | |
32 | CFRetain(ref); | |
33 | } | |
34 | ||
35 | wxCFDictionary(CFIndex cfiSize = 0) | |
36 | { | |
37 | CFDictionaryKeyCallBacks kcbs; | |
38 | CFDictionaryValueCallBacks vcbs; | |
39 | BuildKeyCallbacks(&kcbs); | |
40 | BuildValueCallbacks(&vcbs); | |
41 | ||
42 | m_cfmdRef = CFDictionaryCreateMutable( | |
43 | kCFAllocatorDefault, cfiSize, &kcbs, &vcbs); | |
44 | ||
45 | } | |
46 | ||
47 | ~wxCFDictionary() | |
48 | { Clear(); } | |
49 | ||
50 | void Clear() | |
51 | {if(m_cfmdRef) CFRelease(m_cfmdRef);} | |
52 | ||
53 | static const void* RetainProc(CFAllocatorRef, const void* v) | |
54 | { return (const void*) CFRetain(v); } | |
55 | ||
56 | static void ReleaseProc(CFAllocatorRef, const void* v) | |
57 | { CFRelease(v); } | |
58 | ||
59 | void MakeMutable(CFIndex cfiSize = 0) | |
60 | { | |
61 | CFDictionaryRef oldref = (CFDictionaryRef) m_cfmdRef; | |
62 | ||
63 | m_cfmdRef = CFDictionaryCreateMutableCopy( | |
64 | kCFAllocatorDefault, | |
65 | cfiSize, | |
66 | oldref); | |
67 | ||
68 | CFRelease(oldref); | |
69 | } | |
70 | ||
71 | void BuildKeyCallbacks(CFDictionaryKeyCallBacks* pCbs) | |
72 | { | |
73 | pCbs->version = 0; | |
74 | pCbs->retain = RetainProc; | |
75 | pCbs->release = ReleaseProc; | |
76 | pCbs->copyDescription = NULL; | |
77 | pCbs->equal = NULL; | |
78 | pCbs->hash = NULL; | |
79 | } | |
80 | ||
81 | void BuildValueCallbacks(CFDictionaryValueCallBacks* pCbs) | |
82 | { | |
83 | pCbs->version = 0; | |
84 | pCbs->retain = RetainProc; | |
85 | pCbs->release = ReleaseProc; | |
86 | pCbs->copyDescription = NULL; | |
87 | pCbs->equal = NULL; | |
88 | } | |
89 | ||
90 | operator CFTypeRef () const | |
91 | { return (CFTypeRef)m_cfmdRef; } | |
92 | ||
93 | CFDictionaryRef GetCFDictionary() const | |
94 | { return (CFDictionaryRef)m_cfmdRef; } | |
95 | ||
96 | CFMutableDictionaryRef GetCFMutableDictionary() | |
97 | { return (CFMutableDictionaryRef) m_cfmdRef; } | |
98 | ||
99 | CFTypeRef operator [] (CFTypeRef cftEntry) const | |
100 | { | |
101 | wxASSERT(IsValid()); | |
102 | return (CFTypeRef) CFDictionaryGetValue((CFDictionaryRef)m_cfmdRef, cftEntry); | |
103 | } | |
104 | ||
105 | CFIndex GetCount() const | |
106 | { | |
107 | wxASSERT(IsValid()); | |
108 | return CFDictionaryGetCount((CFDictionaryRef)m_cfmdRef); | |
109 | } | |
110 | ||
111 | void Add(CFTypeRef cftKey, CFTypeRef cftValue) | |
112 | { | |
113 | wxASSERT(IsValid()); | |
114 | wxASSERT(Exists(cftKey) == false); | |
115 | CFDictionaryAddValue(m_cfmdRef, cftKey, cftValue); | |
116 | } | |
117 | ||
118 | void Remove(CFTypeRef cftKey) | |
119 | { | |
120 | wxASSERT(IsValid()); | |
121 | wxASSERT(Exists(cftKey)); | |
122 | CFDictionaryRemoveValue(m_cfmdRef, cftKey); | |
123 | } | |
124 | ||
125 | void Set(CFTypeRef cftKey, CFTypeRef cftValue) | |
126 | { | |
127 | wxASSERT(IsValid()); | |
128 | wxASSERT(Exists(cftKey)); | |
129 | CFDictionarySetValue(m_cfmdRef, cftKey, cftValue); | |
130 | } | |
131 | ||
132 | bool Exists(CFTypeRef cftKey) const | |
133 | { | |
134 | wxASSERT(IsValid()); | |
135 | return CFDictionaryContainsKey((CFDictionaryRef)m_cfmdRef, cftKey) == true; | |
136 | } | |
137 | ||
138 | bool IsOk() const {return m_cfmdRef != NULL; } | |
139 | ||
140 | bool IsValid() const | |
141 | { | |
142 | return IsOk() && CFGetTypeID((CFTypeRef)m_cfmdRef) == CFDictionaryGetTypeID(); | |
143 | } | |
144 | ||
145 | void PrintOut(wxString& sMessage) | |
146 | { | |
147 | PrintOutDictionary(sMessage, m_cfmdRef); | |
148 | } | |
149 | ||
150 | static void PrintOutDictionary(wxString& sMessage, CFDictionaryRef cfdRef) | |
151 | { | |
152 | CFIndex cfiCount = CFDictionaryGetCount(cfdRef); | |
153 | CFTypeRef* pKeys = new CFTypeRef[cfiCount]; | |
154 | CFTypeRef* pValues = new CFTypeRef[cfiCount]; | |
155 | ||
156 | CFDictionaryGetKeysAndValues(cfdRef, pKeys, pValues); | |
157 | ||
158 | for(CFIndex i = 0; i < cfiCount; ++i) | |
159 | { | |
160 | wxString sKey = wxMacCFStringHolder(CFCopyTypeIDDescription(CFGetTypeID(pKeys[i]))).AsString(); | |
161 | wxString sValue = wxMacCFStringHolder(CFCopyTypeIDDescription(CFGetTypeID(pValues[i]))).AsString(); | |
162 | ||
163 | sMessage << | |
164 | wxString::Format(wxT("[{#%d} Key : %s]"), (int) i, | |
165 | sKey.c_str()); | |
166 | ||
167 | PrintOutType(sMessage, sKey, pKeys[i]); | |
168 | ||
169 | sMessage << | |
170 | wxString::Format(wxT("\n\t[Value : %s]"), | |
171 | sValue.c_str()); | |
172 | ||
173 | PrintOutType(sMessage, sValue, pValues[i]); | |
174 | ||
175 | sMessage << wxT("\n"); | |
176 | } | |
177 | ||
178 | delete[] pKeys; | |
179 | delete[] pValues; | |
180 | } | |
181 | ||
182 | static void PrintOutArray(wxString& sMessage, CFArrayRef cfaRef) | |
183 | { | |
184 | ||
185 | for(CFIndex i = 0; i < CFArrayGetCount(cfaRef); ++i) | |
186 | { | |
187 | wxString sValue = wxMacCFStringHolder(CFCopyTypeIDDescription(CFGetTypeID( | |
188 | CFArrayGetValueAtIndex(cfaRef, i) | |
189 | ))).AsString(); | |
190 | ||
191 | sMessage << | |
192 | wxString::Format(wxT("\t\t[{#%d} ArrayValue : %s]\n"), (int) i, | |
193 | sValue.c_str()); | |
194 | ||
195 | PrintOutType(sMessage, sValue, CFArrayGetValueAtIndex(cfaRef, i)); | |
196 | } | |
197 | } | |
198 | ||
199 | static void PrintOutType(wxString& sMessage, wxString sValue, CFTypeRef cfRef) | |
200 | { | |
201 | sMessage << wxT(" {"); | |
202 | ||
203 | if(sValue == wxT("CFString")) | |
204 | { | |
205 | sMessage << wxMacCFStringHolder((CFStringRef)cfRef, false).AsString(); | |
206 | } | |
207 | else if(sValue == wxT("CFNumber")) | |
208 | { | |
209 | int nOut; | |
210 | CFNumberGetValue((CFNumberRef)cfRef, kCFNumberIntType, &nOut); | |
211 | sMessage << nOut; | |
212 | } | |
213 | else if(sValue == wxT("CFDictionary")) | |
214 | { | |
215 | PrintOutDictionary(sMessage, (CFDictionaryRef)cfRef); | |
216 | } | |
217 | else if(sValue == wxT("CFArray")) | |
218 | { | |
219 | PrintOutArray(sMessage, (CFArrayRef)cfRef); | |
220 | } | |
221 | else if(sValue == wxT("CFBoolean")) | |
222 | { | |
223 | sMessage << (cfRef == kCFBooleanTrue ? wxT("true") : wxT("false")); | |
224 | } | |
225 | else if(sValue == wxT("CFURL")) | |
226 | { | |
227 | sMessage << wxMacCFStringHolder(CFURLCopyPath((CFURLRef) cfRef)).AsString(); | |
228 | } | |
229 | else | |
230 | { | |
231 | sMessage << wxT("*****UNKNOWN TYPE******"); | |
232 | } | |
233 | ||
234 | sMessage << wxT("} "); | |
235 | } | |
236 | ||
237 | #if wxUSE_MIMETYPE | |
238 | void MakeValidXML(); | |
239 | #endif | |
240 | ||
241 | CFTypeRef WriteAsXML() | |
242 | { | |
243 | return CFPropertyListCreateXMLData(kCFAllocatorDefault, m_cfmdRef); | |
244 | } | |
245 | ||
246 | bool ReadAsXML(CFTypeRef cfData, wxString* pErrorMsg = NULL) | |
247 | { | |
248 | Clear(); | |
249 | CFStringRef cfsError=NULL; | |
250 | m_cfmdRef = (CFMutableDictionaryRef) CFPropertyListCreateFromXMLData( | |
251 | kCFAllocatorDefault, | |
252 | (CFDataRef)cfData, | |
253 | kCFPropertyListMutableContainersAndLeaves, | |
254 | &cfsError ); | |
255 | if(cfsError) | |
256 | { | |
257 | if(pErrorMsg) | |
258 | *pErrorMsg = wxMacCFStringHolder(cfsError).AsString(); | |
259 | else | |
260 | CFRelease(cfsError); | |
261 | } | |
262 | ||
263 | return m_cfmdRef != NULL; | |
264 | } | |
265 | private: | |
266 | CFMutableDictionaryRef m_cfmdRef; | |
267 | }; | |
268 | ||
269 | // ---------------------------------------------------------------------------- | |
270 | // wxCFArray | |
271 | // ---------------------------------------------------------------------------- | |
272 | ||
273 | class wxCFArray | |
274 | { | |
275 | public: | |
276 | wxCFArray(CFTypeRef ref, bool bRetain = wxCF_RELEASE) | |
277 | { | |
278 | m_cfmaRef = (CFMutableArrayRef)ref; | |
279 | if(bRetain == wxCF_RETAIN && ref) | |
280 | CFRetain(ref); | |
281 | } | |
282 | ||
283 | wxCFArray(CFIndex cfiSize = 0) : m_cfmaRef(NULL) | |
284 | { Create(cfiSize); } | |
285 | ||
286 | ~wxCFArray() | |
287 | { Clear(); } | |
288 | ||
289 | void MakeMutable(CFIndex cfiSize = 0) | |
290 | { | |
291 | wxASSERT(IsValid()); | |
292 | ||
293 | CFMutableArrayRef oldref = m_cfmaRef; | |
294 | m_cfmaRef = CFArrayCreateMutableCopy( | |
295 | kCFAllocatorDefault, | |
296 | cfiSize, | |
297 | (CFArrayRef)oldref); | |
298 | CFRelease(oldref); | |
299 | } | |
300 | ||
301 | void BuildCallbacks(CFArrayCallBacks* pCbs) | |
302 | { | |
303 | pCbs->version = 0; | |
304 | pCbs->retain = RetainProc; | |
305 | pCbs->release = ReleaseProc; | |
306 | pCbs->copyDescription = NULL; | |
307 | pCbs->equal = NULL; | |
308 | } | |
309 | ||
310 | void Create(CFIndex cfiSize = 0) | |
311 | { | |
312 | Clear(); | |
313 | CFArrayCallBacks cb; | |
314 | BuildCallbacks(&cb); | |
315 | ||
316 | m_cfmaRef = CFArrayCreateMutable(kCFAllocatorDefault, cfiSize, &cb); | |
317 | } | |
318 | ||
319 | void Clear() | |
320 | {if(m_cfmaRef) CFRelease(m_cfmaRef);} | |
321 | ||
322 | static const void* RetainProc(CFAllocatorRef, const void* v) | |
323 | { return (const void*) CFRetain(v); } | |
324 | ||
325 | static void ReleaseProc(CFAllocatorRef, const void* v) | |
326 | { CFRelease(v); } | |
327 | ||
328 | operator CFTypeRef () const | |
329 | { return (CFTypeRef)m_cfmaRef; } | |
330 | ||
331 | CFArrayRef GetCFArray() const | |
332 | { return (CFArrayRef)m_cfmaRef; } | |
333 | ||
334 | CFMutableArrayRef GetCFMutableArray() | |
335 | { return (CFMutableArrayRef) m_cfmaRef; } | |
336 | ||
337 | CFTypeRef operator [] (CFIndex cfiIndex) const | |
338 | { | |
339 | wxASSERT(IsValid()); | |
340 | return (CFTypeRef) CFArrayGetValueAtIndex((CFArrayRef)m_cfmaRef, cfiIndex); | |
341 | } | |
342 | ||
343 | CFIndex GetCount() | |
344 | { | |
345 | wxASSERT(IsValid()); | |
346 | return CFArrayGetCount((CFArrayRef)m_cfmaRef); | |
347 | } | |
348 | ||
349 | void Add(CFTypeRef cftValue) | |
350 | { | |
351 | wxASSERT(IsValid()); | |
352 | CFArrayAppendValue(m_cfmaRef, cftValue); | |
353 | } | |
354 | ||
355 | void Remove(CFIndex cfiIndex) | |
356 | { | |
357 | wxASSERT(IsValid()); | |
358 | wxASSERT(cfiIndex < GetCount()); | |
359 | CFArrayRemoveValueAtIndex(m_cfmaRef, cfiIndex); | |
360 | } | |
361 | ||
362 | void Set(CFIndex cfiIndex, CFTypeRef cftValue) | |
363 | { | |
364 | wxASSERT(IsValid()); | |
365 | wxASSERT(cfiIndex < GetCount()); | |
366 | CFArraySetValueAtIndex(m_cfmaRef, cfiIndex, cftValue); | |
367 | } | |
368 | ||
369 | bool IsOk() const {return m_cfmaRef != NULL; } | |
370 | ||
371 | bool IsValid() const | |
372 | { | |
373 | return IsOk() && CFGetTypeID((CFTypeRef)m_cfmaRef) == CFArrayGetTypeID(); | |
374 | } | |
375 | ||
376 | #if wxUSE_MIMETYPE | |
377 | void MakeValidXML(); | |
378 | #endif | |
379 | ||
380 | private: | |
381 | CFMutableArrayRef m_cfmaRef; | |
382 | }; | |
383 | ||
384 | // ---------------------------------------------------------------------------- | |
385 | // wxCFString | |
386 | // ---------------------------------------------------------------------------- | |
387 | ||
388 | class wxCFString | |
389 | { | |
390 | public: | |
391 | wxCFString(CFTypeRef ref, bool bRetain = wxCF_RELEASE) : m_Holder((CFStringRef)ref, bRetain == wxCF_RELEASE) | |
392 | { } | |
393 | ||
394 | wxCFString(const wxChar* szString) : m_Holder(wxString(szString), wxLocale::GetSystemEncoding()) | |
395 | { } | |
396 | ||
397 | wxCFString(const wxString& sString) : m_Holder(sString, wxLocale::GetSystemEncoding()) | |
398 | { } | |
399 | ||
400 | operator CFTypeRef() const | |
401 | {return (CFTypeRef) ((CFStringRef) m_Holder); } | |
402 | ||
403 | bool IsOk() { return ((CFTypeRef)(*this)) != NULL; } | |
404 | ||
405 | wxString BuildWXString() {return m_Holder.AsString(); } | |
406 | ||
407 | private: | |
408 | wxMacCFStringHolder m_Holder; | |
409 | }; | |
410 | ||
411 | // ---------------------------------------------------------------------------- | |
412 | // wxCFNumber | |
413 | // ---------------------------------------------------------------------------- | |
414 | ||
415 | class wxCFNumber | |
416 | { | |
417 | public: | |
418 | wxCFNumber(int nValue) | |
419 | { | |
420 | m_cfnRef = CFNumberCreate(kCFAllocatorDefault, | |
421 | kCFNumberIntType, &nValue); | |
422 | } | |
423 | ||
424 | wxCFNumber(CFTypeRef ref, bool bRetain = wxCF_RELEASE) : m_cfnRef((CFNumberRef)ref) | |
425 | { | |
426 | if(bRetain == wxCF_RETAIN && ref) | |
427 | CFRetain(ref); | |
428 | } | |
429 | ||
430 | ~wxCFNumber() | |
431 | { if(m_cfnRef) CFRelease(m_cfnRef); } | |
432 | ||
433 | ||
434 | operator CFTypeRef() const | |
435 | { return (CFTypeRef) m_cfnRef; } | |
436 | ||
437 | int GetValue() | |
438 | { | |
439 | int nOut; | |
440 | CFNumberGetValue( | |
441 | m_cfnRef, | |
442 | kCFNumberIntType, | |
443 | &nOut | |
444 | ); | |
445 | ||
446 | return nOut; | |
447 | } | |
448 | ||
449 | bool IsOk() { return m_cfnRef != NULL; } | |
450 | ||
451 | private: | |
452 | CFNumberRef m_cfnRef; | |
453 | }; | |
454 | ||
455 | // ---------------------------------------------------------------------------- | |
456 | // wxCFURL | |
457 | // ---------------------------------------------------------------------------- | |
458 | ||
459 | class wxCFURL | |
460 | { | |
461 | public: | |
462 | wxCFURL(CFTypeRef ref, bool bRetain = wxCF_RELEASE) : m_cfurlRef((CFURLRef)ref) | |
463 | { | |
464 | if(bRetain == wxCF_RETAIN && ref) | |
465 | CFRetain(ref); | |
466 | } | |
467 | wxCFURL(const wxCFString& URLString, CFTypeRef BaseURL = NULL) | |
468 | { | |
469 | m_cfurlRef = CFURLCreateWithString( | |
470 | kCFAllocatorDefault, | |
471 | (CFStringRef)(CFTypeRef)URLString, | |
472 | (CFURLRef) BaseURL); | |
473 | } | |
474 | ~wxCFURL() {if(m_cfurlRef) CFRelease(m_cfurlRef);} | |
475 | ||
476 | wxString BuildWXString() | |
477 | { | |
478 | return wxCFString(CFURLCopyPath(m_cfurlRef)).BuildWXString(); | |
479 | } | |
480 | ||
481 | operator CFTypeRef() const | |
482 | { return (CFTypeRef)m_cfurlRef; } | |
483 | ||
484 | bool IsOk() { return m_cfurlRef != NULL; } | |
485 | private: | |
486 | CFURLRef m_cfurlRef; | |
487 | }; | |
488 | ||
489 | // ---------------------------------------------------------------------------- | |
490 | // wxCFData | |
491 | // ---------------------------------------------------------------------------- | |
492 | ||
493 | #define wxCFDATA_RELEASEBUFFER 1 | |
494 | #define wxCFDATA_RETAINBUFFER 0 | |
495 | ||
496 | class wxCFData | |
497 | { | |
498 | public: | |
499 | wxCFData(CFTypeRef ref, bool bRetain = wxCF_RELEASE) : m_cfdaRef((CFDataRef)ref) | |
500 | { | |
501 | if(bRetain == wxCF_RETAIN && ref) | |
502 | CFRetain(ref); | |
503 | } | |
504 | wxCFData(const UInt8* pBytes, CFIndex len, bool bKeep = wxCFDATA_RELEASEBUFFER) | |
505 | { | |
506 | if(bKeep == wxCFDATA_RELEASEBUFFER) | |
507 | { | |
508 | m_cfdaRef = CFDataCreateWithBytesNoCopy | |
509 | (kCFAllocatorDefault, pBytes, len, kCFAllocatorDefault); | |
510 | } | |
511 | else | |
512 | { | |
513 | m_cfdaRef = CFDataCreate(kCFAllocatorDefault, pBytes, len); | |
514 | } | |
515 | } | |
516 | ~wxCFData() {if(m_cfdaRef) CFRelease(m_cfdaRef);} | |
517 | ||
518 | const UInt8* GetValue() | |
519 | { | |
520 | return CFDataGetBytePtr(m_cfdaRef); | |
521 | } | |
522 | ||
523 | CFIndex GetCount() | |
524 | { | |
525 | return CFDataGetLength(m_cfdaRef); | |
526 | } | |
527 | ||
528 | operator CFTypeRef() const | |
529 | { return (CFTypeRef)m_cfdaRef; } | |
530 | ||
531 | bool IsOk() { return m_cfdaRef != NULL; } | |
532 | private: | |
533 | CFDataRef m_cfdaRef; | |
534 | }; | |
535 | ||
536 | #endif //__WX_CFWRAPPERS_H__ |