]>
git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_utilities/cfutilities.h
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
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
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.
20 //CoreFoundation related utilities
22 #ifndef _H_CFUTILITIES
23 #define _H_CFUTILITIES
25 #include <Security/utilities.h>
26 #include <CoreFoundation/CoreFoundation.h>
34 // Initialize-only self-releasing CF object handler (lightweight).
35 // Does not support assignment.
37 template <class CFType
> class CFRef
{
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
); }
44 CFRef
&operator = (CFType ref
)
45 { if (ref
) CFRetain(ref
); if (mRef
) CFRelease(mRef
); mRef
= ref
; return *this; }
47 operator CFType () const { return mRef
; }
48 operator bool () const { return mRef
!= NULL
; }
49 bool operator ! () const { return mRef
== NULL
; }
56 template <class CFType
> class CFCopyRef
{
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
); }
63 CFCopyRef
&operator = (CFType ref
)
64 { if (ref
) CFRetain(ref
); if (mRef
) CFRelease(mRef
); mRef
= ref
; return *this; }
66 operator CFType () const { return mRef
; }
67 operator bool () const { return mRef
!= NULL
; }
68 bool operator ! () const { return mRef
== NULL
; }
76 // A simple function that turns a non-array CFTypeRef into
77 // an array of one with that element.
79 inline CFArrayRef
cfArrayize(CFTypeRef arrayOrItem
)
81 if (arrayOrItem
== NULL
)
82 return NULL
; // NULL is NULL
83 else if (CFGetTypeID(arrayOrItem
) == CFArrayGetTypeID())
84 return CFArrayRef(arrayOrItem
); // already an array
86 CFArrayRef array
= CFArrayCreate(NULL
,
87 (const void **)&arrayOrItem
, 1, &kCFTypeArrayCallBacks
);
88 CFRelease(arrayOrItem
); // was retained by ArrayCreate
95 // Translate CFDataRef to CssmData. The output shares the input's buffer.
97 inline CssmData
cfData(CFDataRef data
)
99 return CssmData(const_cast<UInt8
*>(CFDataGetBytePtr(data
)),
100 CFDataGetLength(data
));
105 // Translate CFStringRef to (UTF8-encoded) C++ string
107 string
cfString(CFStringRef str
);
111 // Translate any Data-oid source to a CFDataRef. The contents are copied.
113 template <class Data
>
114 inline CFDataRef
makeCFData(const Data
&source
)
116 return CFDataCreate(NULL
, reinterpret_cast<const UInt8
*>(source
.data()), source
.length());
121 // Translate strings into CFStrings
123 inline CFStringRef
makeCFString(const char *s
)
125 return CFStringCreateWithCString(NULL
, s
, kCFStringEncodingUTF8
);
128 inline CFStringRef
makeCFString(const string
&s
)
130 return CFStringCreateWithCString(NULL
, s
.c_str(), kCFStringEncodingUTF8
);
135 // Internally used STL adapters. Should probably be in utilities.h.
137 template <class Self
>
138 Self
projectPair(const Self
&me
)
141 template <class First
, class Second
>
142 Second
projectPair(const pair
<First
, Second
> &me
)
143 { return me
.second
; }
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.
156 template <class VectorBase
, class CFRefType
, VectorBase
convert(CFRefType
)>
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; }
165 VectorBase
*begin() const { return mVector
; }
166 VectorBase
*end() const { return mVector
+ mCount
; }
168 VectorBase
&operator [] (uint32 ix
) const { assert(ix
< mCount
); return mVector
[ix
]; }
175 template <class VectorBase
, class CFRefType
, VectorBase
convert(CFTypeRef
)>
176 CFToVector
<VectorBase
, CFRefType
, convert
>::CFToVector(CFArrayRef arrayRef
)
178 if (arrayRef
== NULL
) {
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
)));
191 // Generate a CFArray of CFTypeId things generated from iterators.
192 // @@@ This should be cleaned up with partial specializations based
193 // @@@ on iterator_traits.
195 template <class Iterator
, class Generator
>
196 inline CFArrayRef
makeCFArray(Generator
&generate
, Iterator first
, Iterator last
)
198 // how many elements?
199 size_t size
= distance(first
, last
);
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
);
209 template <class Container
, class Generator
>
210 inline CFArrayRef
makeCFArray(Generator
&generate
, const Container
&container
)
212 return makeCFArray(generate
, container
.begin(), container
.end());
216 } // end namespace Security
218 #endif //_H_CFUTILITIES