2 * Copyright (c) 2000-2004,2011,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
31 #include <security_utilities/utility_config.h>
32 #include <security_utilities/errors.h>
38 #include <security_utilities/simulatecrash_assert.h>
44 // Elementary debugging support.
45 // #include <debugging.h> for more debugging facilities.
47 #define IFDEBUG(it) IFELSEDEBUG(it,)
48 #define IFNDEBUG(it) IFELSEDEBUG(,it)
52 # define safe_cast static_cast
53 # define safer_cast static_cast
55 # define IFELSEDEBUG(d,nd) nd
59 template <class Derived
, class Base
>
60 inline Derived
safer_cast(Base
&base
)
62 return dynamic_cast<Derived
>(base
);
65 template <class Derived
, class Base
>
66 inline Derived
safe_cast(Base
*base
)
69 return NULL
; // okay to cast NULL to NULL
70 Derived p
= dynamic_cast<Derived
>(base
);
75 # define IFELSEDEBUG(d,nd) d
81 // Place this into your class definition if you don't want it to be copyable
82 // or asignable. This will not prohibit allocation on the stack or in static
83 // memory, but it will make anything derived from it, and anything containing
84 // it, fixed-once-created. A proper object, I suppose.
86 #define NOCOPY(Type) \
87 private: Type(const Type &) DEPRECATED_IN_MAC_OS_X_VERSION_10_0_AND_LATER; \
88 void operator = (const Type &) DEPRECATED_IN_MAC_OS_X_VERSION_10_0_AND_LATER;
92 // Helpers for memory pointer validation
94 #define MY_CSSM_ERRCODE_INVALID_POINTER 0x0004
96 inline T
&Required(T
*ptr
, OSStatus err
= MY_CSSM_ERRCODE_INVALID_POINTER
)
99 MacOSError::throwMe(err
);
103 // specialization for void * (just check for non-null; don't return a void & :-)
104 inline void Required(void *ptr
, OSStatus err
= MY_CSSM_ERRCODE_INVALID_POINTER
)
107 MacOSError::throwMe(err
);
112 // Tools to build POD wrapper classes
114 template <class Wrapper
, class POD
>
115 class PodWrapper
: public POD
{
118 static Wrapper
* &overlayVar(POD
* &data
)
119 { return reinterpret_cast<Wrapper
* &>(data
); }
120 static const Wrapper
* &overlayVar(const POD
* &data
)
121 { return reinterpret_cast<const Wrapper
* &>(data
); }
123 static Wrapper
*overlay(POD
*data
)
124 { return static_cast<Wrapper
*>(data
); }
125 static const Wrapper
*overlay(const POD
*data
)
126 { return static_cast<const Wrapper
*>(data
); }
127 static Wrapper
&overlay(POD
&data
)
128 { return static_cast<Wrapper
&>(data
); }
129 static const Wrapper
&overlay(const POD
&data
)
130 { return static_cast<const Wrapper
&>(data
); }
132 // optional/required forms
133 static Wrapper
&required(POD
*data
)
134 { return overlay(Required(data
)); }
135 static const Wrapper
&required(const POD
*data
)
136 { return overlay(Required(data
)); }
137 static Wrapper
*optional(POD
*data
)
138 { return overlay(data
); }
139 static const Wrapper
*optional(const POD
*data
)
140 { return overlay(data
); }
142 // general helpers for all PodWrappers
144 { memset(static_cast<POD
*>(this), 0, sizeof(POD
)); }
146 void assignPod(const POD
&source
)
147 { static_cast<POD
&>(*this) = source
; }
152 // Template builder support
160 struct Nonconst
<const U
> {
165 struct Nonconst
<const U
*> {
169 // cast away pointed-to constness
171 typename Nonconst
<T
>::Type
unconst_cast(T obj
)
173 return const_cast<typename Nonconst
<T
>::Type
>(obj
);
177 typename Nonconst
<T
>::Type
&unconst_ref_cast(T
&obj
)
179 return const_cast<typename Nonconst
<T
>::Type
&>(obj
);
183 // Help with container of something->pointer cleanup
185 static inline void for_each_delete(In first
, In last
)
187 while (first
!= last
)
191 // Help with map of something->pointer cleanup
193 static inline void for_each_map_delete(In first
, In last
)
195 while (first
!= last
)
196 delete (first
++)->second
;
199 // versions of copy that project to pair elements
200 template <class InIterator
, class OutIterator
>
201 inline OutIterator
copy_first(InIterator first
, InIterator last
, OutIterator out
)
203 while (first
!= last
)
204 *out
++ = (first
++)->first
;
208 template <class InIterator
, class OutIterator
>
209 inline OutIterator
copy_second(InIterator first
, InIterator last
, OutIterator out
)
211 while (first
!= last
)
212 *out
++ = (first
++)->second
;
217 // simple safe re-entry blocker
218 class RecursionBlock
{
220 RecursionBlock() : mActive(false) { }
221 ~RecursionBlock() { assert(!mActive
); }
226 Once(RecursionBlock
&rb
) : block(rb
), mActive(false) { }
227 ~Once() { block
.mActive
&= !mActive
; }
229 { if (block
.mActive
) return true; mActive
= block
.mActive
= true; return false; }
231 RecursionBlock
&block
;
242 // Quick and dirty template for a (temporary) array of something
243 // Usage example auto_array<UInt32> anArray(20);
248 auto_array() : mArray(NULL
) {}
249 auto_array(size_t inSize
) : mArray(new T
[inSize
]) {}
250 ~auto_array() { if (mArray
) delete[] mArray
; }
251 T
&operator[](size_t inIndex
) { return mArray
[inIndex
]; }
252 void allocate(size_t inSize
) { if (mArray
) delete[] mArray
; mArray
= new T
[inSize
]; }
253 T
*get() { return mArray
; }
254 T
*release() { T
*anArray
= mArray
; mArray
= NULL
; return anArray
; }
259 // Template for a vector-like class that takes a c-array as it's
260 // underlying storage without making a copy.
264 NOCOPY(constVector
<_Tp
>)
266 typedef _Tp value_type
;
267 typedef const value_type
* const_pointer
;
268 typedef const value_type
* const_iterator
;
269 typedef const value_type
& const_reference
;
270 typedef size_t size_type
;
271 typedef ptrdiff_t difference_type
;
273 typedef std::reverse_iterator
<const_iterator
> const_reverse_iterator
;
275 const_iterator
begin() const { return _M_start
; }
276 const_iterator
end() const { return _M_finish
; }
278 const_reverse_iterator
rbegin() const
279 { return const_reverse_iterator(end()); }
280 const_reverse_iterator
rend() const
281 { return const_reverse_iterator(begin()); }
283 size_type
size() const
284 { return size_type(end() - begin()); }
286 { return begin() == end(); }
288 const_reference
operator[](size_type __n
) const { return *(begin() + __n
); }
290 // "at" will eventually have range checking, once we have the
291 // infrastructure to be able to throw stl range errors.
292 const_reference
at(size_type n
) const { return (*this)[n
]; }
294 constVector(size_type __n
, const _Tp
* __value
)
295 : _M_start(__value
), _M_finish(__value
+ __n
)
298 constVector() : _M_start(NULL
), _M_finish(NULL
) {}
300 void overlay(size_type __n
, const _Tp
* __value
) {
302 _M_finish
= __value
+ __n
;
305 const_reference
front() const { return *begin(); }
306 const_reference
back() const { return *(end() - 1); }
309 const _Tp
*_M_finish
;
312 char *cached_realpath(const char * file_name
, char * resolved_name
);
314 } // end namespace Security
317 #endif //_H_UTILITIES