]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/cfutilities.h
Security-164.1.tar.gz
[apple/security.git] / cdsa / cdsa_utilities / cfutilities.h
1 /*
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 //CoreFoundation related utilities
21 //
22 #ifndef _H_CFUTILITIES
23 #define _H_CFUTILITIES
24
25 #include <Security/utilities.h>
26 #include <CoreFoundation/CoreFoundation.h>
27 #include <algorithm>
28
29
30 namespace Security {
31
32
33 //
34 // Initialize-only self-releasing CF object handler (lightweight).
35 // Does not support assignment.
36 //
37 template <class CFType> class CFRef {
38 public:
39 CFRef() : mRef(NULL) { }
40 CFRef(CFType ref) : mRef(ref) { }
41 CFRef(const CFRef &ref) : mRef(ref) { if (ref) CFRetain(ref); }
42 ~CFRef() { if (mRef) CFRelease(mRef); }
43
44 CFRef &take(CFType ref)
45 { if (mRef) CFRelease(mRef); mRef = ref; return *this; }
46
47 CFRef &operator = (CFType ref)
48 { if (ref) CFRetain(ref); return take(ref); }
49
50 operator CFType () const { return mRef; }
51 operator bool () const { return mRef != NULL; }
52 bool operator ! () const { return mRef == NULL; }
53
54 private:
55 CFType mRef;
56 };
57
58
59 template <class CFType> class CFCopyRef {
60 public:
61 CFCopyRef() : mRef(NULL) { }
62 explicit CFCopyRef(CFType ref) : mRef(ref) { if (ref) CFRetain(ref); }
63 CFCopyRef(const CFCopyRef &ref) : mRef(ref) { if (ref) CFRetain(ref); }
64 ~CFCopyRef() { if (mRef) CFRelease(mRef); }
65
66 CFCopyRef &take(CFType ref)
67 { if (mRef) CFRelease(mRef); mRef = ref; return *this; }
68
69 CFCopyRef &operator = (CFType ref)
70 { if (ref) CFRetain(ref); return take(ref); }
71
72 operator CFType () const { return mRef; }
73 operator bool () const { return mRef != NULL; }
74 bool operator ! () const { return mRef == NULL; }
75
76 private:
77 CFType mRef;
78 };
79
80
81 //
82 // A simple function that turns a non-array CFTypeRef into
83 // an array of one with that element. This will retain its argument
84 // (directly or indirectly).
85 //
86 inline CFArrayRef cfArrayize(CFTypeRef arrayOrItem)
87 {
88 if (arrayOrItem == NULL)
89 return NULL; // NULL is NULL
90 else if (CFGetTypeID(arrayOrItem) == CFArrayGetTypeID()) {
91 CFRetain(arrayOrItem);
92 return CFArrayRef(arrayOrItem); // already an array
93 } else {
94 CFArrayRef array = CFArrayCreate(NULL,
95 (const void **)&arrayOrItem, 1, &kCFTypeArrayCallBacks);
96 return array;
97 }
98 }
99
100
101 //
102 // Translate CFDataRef to CssmData. The output shares the input's buffer.
103 //
104 inline CssmData cfData(CFDataRef data)
105 {
106 return CssmData(const_cast<UInt8 *>(CFDataGetBytePtr(data)),
107 CFDataGetLength(data));
108 }
109
110
111 //
112 // Translate CFStringRef to (UTF8-encoded) C++ string
113 //
114 string cfString(CFStringRef str);
115
116
117 //
118 // Translate any Data-oid source to a CFDataRef. The contents are copied.
119 //
120 template <class Data>
121 inline CFDataRef makeCFData(const Data &source)
122 {
123 return CFDataCreate(NULL, reinterpret_cast<const UInt8 *>(source.data()), source.length());
124 }
125
126
127 //
128 // Translate strings into CFStrings
129 //
130 inline CFStringRef makeCFString(const char *s)
131 {
132 return CFStringCreateWithCString(NULL, s, kCFStringEncodingUTF8);
133 }
134
135 inline CFStringRef makeCFString(const string &s)
136 {
137 return CFStringCreateWithCString(NULL, s.c_str(), kCFStringEncodingUTF8);
138 }
139
140
141 //
142 // Internally used STL adapters. Should probably be in utilities.h.
143 //
144 template <class Self>
145 Self projectPair(const Self &me)
146 { return me; }
147
148 template <class First, class Second>
149 Second projectPair(const pair<First, Second> &me)
150 { return me.second; }
151
152
153 //
154 // A CFToVector turns a CFArrayRef of items into a flat
155 // C vector of some type, using a conversion function
156 // (from CFTypeRef) specified. As a special bonus, if
157 // you provide a CFTypeRef (other than CFArrayRef), it
158 // will be transparently handled as an array-of-one.
159 // The array will be automatically released on destruction
160 // of the CFToVector object. Any internal structure shared
161 // with the CFTypeRef inputs will be left alone.
162 //
163 template <class VectorBase, class CFRefType, VectorBase convert(CFRefType)>
164 class CFToVector {
165 public:
166 CFToVector(CFArrayRef arrayRef);
167 ~CFToVector() { delete[] mVector; }
168 operator uint32 () const { return mCount; }
169 operator VectorBase *() const { return mVector; }
170 bool empty() const { return mCount == 0; }
171
172 VectorBase *begin() const { return mVector; }
173 VectorBase *end() const { return mVector + mCount; }
174
175 VectorBase &operator [] (uint32 ix) const { assert(ix < mCount); return mVector[ix]; }
176
177 private:
178 VectorBase *mVector;
179 uint32 mCount;
180 };
181
182 template <class VectorBase, class CFRefType, VectorBase convert(CFRefType)>
183 CFToVector<VectorBase, CFRefType, convert>::CFToVector(CFArrayRef arrayRef)
184 {
185 if (arrayRef == NULL) {
186 mCount = 0;
187 mVector = NULL;
188 } else {
189 mCount = CFArrayGetCount(arrayRef);
190 mVector = new VectorBase[mCount];
191 for (uint32 n = 0; n < mCount; n++)
192 mVector[n] = convert(CFRefType(CFArrayGetValueAtIndex(arrayRef, n)));
193 }
194 }
195
196
197 //
198 // Generate a CFArray of CFTypeId things generated from iterators.
199 // @@@ This should be cleaned up with partial specializations based
200 // @@@ on iterator_traits.
201 //
202 template <class Iterator, class Generator>
203 inline CFArrayRef makeCFArray(Generator &generate, Iterator first, Iterator last)
204 {
205 // how many elements?
206 size_t size = distance(first, last);
207
208 // do the CFArrayCreate tango
209 auto_array<CFTypeRef> vec(size);
210 for (uint32 n = 0; n < size; n++)
211 vec[n] = generate(projectPair(*first++));
212 assert(first == last);
213 return CFArrayCreate(NULL, (const void **)vec.get(), size, &kCFTypeArrayCallBacks);
214 }
215
216 template <class Container, class Generator>
217 inline CFArrayRef makeCFArray(Generator &generate, const Container &container)
218 {
219 return makeCFArray(generate, container.begin(), container.end());
220 }
221
222
223 } // end namespace Security
224
225 #endif //_H_CFUTILITIES