]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/cfutilities.h
Security-54.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 &operator = (CFType ref)
45 { if (ref) CFRetain(ref); if (mRef) CFRelease(mRef); mRef = ref; return *this; }
46
47 operator CFType () const { return mRef; }
48 operator bool () const { return mRef != NULL; }
49 bool operator ! () const { return mRef == NULL; }
50
51 private:
52 CFType mRef;
53 };
54
55
56 template <class CFType> class CFCopyRef {
57 public:
58 CFCopyRef() : mRef(NULL) { }
59 explicit CFCopyRef(CFType ref) : mRef(ref) { if (ref) CFRetain(ref); }
60 CFCopyRef(const CFCopyRef &ref) : mRef(ref) { if (ref) CFRetain(ref); }
61 ~CFCopyRef() { if (mRef) CFRelease(mRef); }
62
63 CFCopyRef &operator = (CFType ref)
64 { if (ref) CFRetain(ref); if (mRef) CFRelease(mRef); mRef = ref; return *this; }
65
66 operator CFType () const { return mRef; }
67 operator bool () const { return mRef != NULL; }
68 bool operator ! () const { return mRef == NULL; }
69
70 private:
71 CFType mRef;
72 };
73
74
75 //
76 // A simple function that turns a non-array CFTypeRef into
77 // an array of one with that element.
78 //
79 inline CFArrayRef cfArrayize(CFTypeRef arrayOrItem)
80 {
81 if (arrayOrItem == NULL)
82 return NULL; // NULL is NULL
83 else if (CFGetTypeID(arrayOrItem) == CFArrayGetTypeID())
84 return CFArrayRef(arrayOrItem); // already an array
85 else {
86 CFArrayRef array = CFArrayCreate(NULL,
87 (const void **)&arrayOrItem, 1, &kCFTypeArrayCallBacks);
88 CFRelease(arrayOrItem); // was retained by ArrayCreate
89 return array;
90 }
91 }
92
93
94 //
95 // Translate CFDataRef to CssmData. The output shares the input's buffer.
96 //
97 inline CssmData cfData(CFDataRef data)
98 {
99 return CssmData(const_cast<UInt8 *>(CFDataGetBytePtr(data)),
100 CFDataGetLength(data));
101 }
102
103
104 //
105 // Translate CFStringRef to (UTF8-encoded) C++ string
106 //
107 string cfString(CFStringRef str);
108
109
110 //
111 // Translate any Data-oid source to a CFDataRef. The contents are copied.
112 //
113 template <class Data>
114 inline CFDataRef makeCFData(const Data &source)
115 {
116 return CFDataCreate(NULL, reinterpret_cast<const UInt8 *>(source.data()), source.length());
117 }
118
119
120 //
121 // Translate strings into CFStrings
122 //
123 inline CFStringRef makeCFString(const char *s)
124 {
125 return CFStringCreateWithCString(NULL, s, kCFStringEncodingUTF8);
126 }
127
128 inline CFStringRef makeCFString(const string &s)
129 {
130 return CFStringCreateWithCString(NULL, s.c_str(), kCFStringEncodingUTF8);
131 }
132
133
134 //
135 // Internally used STL adapters. Should probably be in utilities.h.
136 //
137 template <class Self>
138 Self projectPair(const Self &me)
139 { return me; }
140
141 template <class First, class Second>
142 Second projectPair(const pair<First, Second> &me)
143 { return me.second; }
144
145
146 //
147 // A CFToVector turns a CFArrayRef of items into a flat
148 // C vector of some type, using a conversion function
149 // (from CFTypeRef) specified. As a special bonus, if
150 // you provide a CFTypeRef (other than CFArrayRef), it
151 // will be transparently handled as an array-of-one.
152 // The array will be automatically released on destruction
153 // of the CFToVector object. Any internal structure shared
154 // with the CFTypeRef inputs will be left alone.
155 //
156 template <class VectorBase, class CFRefType, VectorBase convert(CFRefType)>
157 class CFToVector {
158 public:
159 CFToVector(CFArrayRef arrayRef);
160 ~CFToVector() { delete[] mVector; }
161 operator uint32 () const { return mCount; }
162 operator VectorBase *() const { return mVector; }
163 bool empty() const { return mCount == 0; }
164
165 VectorBase *begin() const { return mVector; }
166 VectorBase *end() const { return mVector + mCount; }
167
168 VectorBase &operator [] (uint32 ix) const { assert(ix < mCount); return mVector[ix]; }
169
170 private:
171 VectorBase *mVector;
172 uint32 mCount;
173 };
174
175 template <class VectorBase, class CFRefType, VectorBase convert(CFTypeRef)>
176 CFToVector<VectorBase, CFRefType, convert>::CFToVector(CFArrayRef arrayRef)
177 {
178 if (arrayRef == NULL) {
179 mCount = 0;
180 mVector = NULL;
181 } else {
182 mCount = CFArrayGetCount(arrayRef);
183 mVector = new VectorBase[mCount];
184 for (uint32 n = 0; n < mCount; n++)
185 mVector[n] = convert(CFRefType(CFArrayGetValueAtIndex(arrayRef, n)));
186 }
187 }
188
189
190 //
191 // Generate a CFArray of CFTypeId things generated from iterators.
192 // @@@ This should be cleaned up with partial specializations based
193 // @@@ on iterator_traits.
194 //
195 template <class Iterator, class Generator>
196 inline CFArrayRef makeCFArray(Generator &generate, Iterator first, Iterator last)
197 {
198 // how many elements?
199 size_t size = distance(first, last);
200
201 // do the CFArrayCreate tango
202 auto_array<CFTypeRef> vec(size);
203 for (uint32 n = 0; n < size; n++)
204 vec[n] = generate(projectPair(*first++));
205 assert(first == last);
206 return CFArrayCreate(NULL, (const void **)vec.get(), size, &kCFTypeArrayCallBacks);
207 }
208
209 template <class Container, class Generator>
210 inline CFArrayRef makeCFArray(Generator &generate, const Container &container)
211 {
212 return makeCFArray(generate, container.begin(), container.end());
213 }
214
215
216 } // end namespace Security
217
218 #endif //_H_CFUTILITIES