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>
42 // Elementary debugging support.
43 // #include <debugging.h> for more debugging facilities.
45 #define IFDEBUG(it) IFELSEDEBUG(it,)
46 #define IFNDEBUG(it) IFELSEDEBUG(,it)
50 # define safe_cast static_cast
51 # define safer_cast static_cast
53 # define IFELSEDEBUG(d,nd) nd
57 template <class Derived
, class Base
>
58 inline Derived
safer_cast(Base
&base
)
60 return dynamic_cast<Derived
>(base
);
63 template <class Derived
, class Base
>
64 inline Derived
safe_cast(Base
*base
)
67 return NULL
; // okay to cast NULL to NULL
68 Derived p
= dynamic_cast<Derived
>(base
);
73 # define IFELSEDEBUG(d,nd) d
79 // Place this into your class definition if you don't want it to be copyable
80 // or asignable. This will not prohibit allocation on the stack or in static
81 // memory, but it will make anything derived from it, and anything containing
82 // it, fixed-once-created. A proper object, I suppose.
84 #define NOCOPY(Type) \
85 private: Type(const Type &) DEPRECATED_IN_MAC_OS_X_VERSION_10_0_AND_LATER; \
86 void operator = (const Type &) DEPRECATED_IN_MAC_OS_X_VERSION_10_0_AND_LATER;
90 // Helpers for memory pointer validation
92 #define MY_CSSM_ERRCODE_INVALID_POINTER 0x0004
94 inline T
&Required(T
*ptr
, OSStatus err
= MY_CSSM_ERRCODE_INVALID_POINTER
)
97 MacOSError::throwMe(err
);
101 // specialization for void * (just check for non-null; don't return a void & :-)
102 inline void Required(void *ptr
, OSStatus err
= MY_CSSM_ERRCODE_INVALID_POINTER
)
105 MacOSError::throwMe(err
);
110 // Tools to build POD wrapper classes
112 template <class Wrapper
, class POD
>
113 class PodWrapper
: public POD
{
116 static Wrapper
* &overlayVar(POD
* &data
)
117 { return reinterpret_cast<Wrapper
* &>(data
); }
118 static const Wrapper
* &overlayVar(const POD
* &data
)
119 { return reinterpret_cast<const Wrapper
* &>(data
); }
121 static Wrapper
*overlay(POD
*data
)
122 { return static_cast<Wrapper
*>(data
); }
123 static const Wrapper
*overlay(const POD
*data
)
124 { return static_cast<const Wrapper
*>(data
); }
125 static Wrapper
&overlay(POD
&data
)
126 { return static_cast<Wrapper
&>(data
); }
127 static const Wrapper
&overlay(const POD
&data
)
128 { return static_cast<const Wrapper
&>(data
); }
130 // optional/required forms
131 static Wrapper
&required(POD
*data
)
132 { return overlay(Required(data
)); }
133 static const Wrapper
&required(const POD
*data
)
134 { return overlay(Required(data
)); }
135 static Wrapper
*optional(POD
*data
)
136 { return overlay(data
); }
137 static const Wrapper
*optional(const POD
*data
)
138 { return overlay(data
); }
140 // general helpers for all PodWrappers
142 { memset(static_cast<POD
*>(this), 0, sizeof(POD
)); }
144 void assignPod(const POD
&source
)
145 { static_cast<POD
&>(*this) = source
; }
150 // Template builder support
158 struct Nonconst
<const U
> {
163 struct Nonconst
<const U
*> {
167 // cast away pointed-to constness
169 typename Nonconst
<T
>::Type
unconst_cast(T obj
)
171 return const_cast<typename Nonconst
<T
>::Type
>(obj
);
175 typename Nonconst
<T
>::Type
&unconst_ref_cast(T
&obj
)
177 return const_cast<typename Nonconst
<T
>::Type
&>(obj
);
181 // Help with container of something->pointer cleanup
183 static inline void for_each_delete(In first
, In last
)
185 while (first
!= last
)
189 // Help with map of something->pointer cleanup
191 static inline void for_each_map_delete(In first
, In last
)
193 while (first
!= last
)
194 delete (first
++)->second
;
197 // versions of copy that project to pair elements
198 template <class InIterator
, class OutIterator
>
199 inline OutIterator
copy_first(InIterator first
, InIterator last
, OutIterator out
)
201 while (first
!= last
)
202 *out
++ = (first
++)->first
;
206 template <class InIterator
, class OutIterator
>
207 inline OutIterator
copy_second(InIterator first
, InIterator last
, OutIterator out
)
209 while (first
!= last
)
210 *out
++ = (first
++)->second
;
215 // simple safe re-entry blocker
216 class RecursionBlock
{
218 RecursionBlock() : mActive(false) { }
219 ~RecursionBlock() { assert(!mActive
); }
224 Once(RecursionBlock
&rb
) : block(rb
), mActive(false) { }
225 ~Once() { block
.mActive
&= !mActive
; }
227 { if (block
.mActive
) return true; mActive
= block
.mActive
= true; return false; }
229 RecursionBlock
&block
;
240 // Quick and dirty template for a (temporary) array of something
241 // Usage example auto_array<UInt32> anArray(20);
246 auto_array() : mArray(NULL
) {}
247 auto_array(size_t inSize
) : mArray(new T
[inSize
]) {}
248 ~auto_array() { if (mArray
) delete[] mArray
; }
249 T
&operator[](size_t inIndex
) { return mArray
[inIndex
]; }
250 void allocate(size_t inSize
) { if (mArray
) delete[] mArray
; mArray
= new T
[inSize
]; }
251 T
*get() { return mArray
; }
252 T
*release() { T
*anArray
= mArray
; mArray
= NULL
; return anArray
; }
257 // Template for a vector-like class that takes a c-array as it's
258 // underlying storage without making a copy.
262 NOCOPY(constVector
<_Tp
>)
264 typedef _Tp value_type
;
265 typedef const value_type
* const_pointer
;
266 typedef const value_type
* const_iterator
;
267 typedef const value_type
& const_reference
;
268 typedef size_t size_type
;
269 typedef ptrdiff_t difference_type
;
271 typedef std::reverse_iterator
<const_iterator
> const_reverse_iterator
;
273 const_iterator
begin() const { return _M_start
; }
274 const_iterator
end() const { return _M_finish
; }
276 const_reverse_iterator
rbegin() const
277 { return const_reverse_iterator(end()); }
278 const_reverse_iterator
rend() const
279 { return const_reverse_iterator(begin()); }
281 size_type
size() const
282 { return size_type(end() - begin()); }
284 { return begin() == end(); }
286 const_reference
operator[](size_type __n
) const { return *(begin() + __n
); }
288 // "at" will eventually have range checking, once we have the
289 // infrastructure to be able to throw stl range errors.
290 const_reference
at(size_type n
) const { return (*this)[n
]; }
292 constVector(size_type __n
, const _Tp
* __value
)
293 : _M_start(__value
), _M_finish(__value
+ __n
)
296 constVector() : _M_start(NULL
), _M_finish(NULL
) {}
298 void overlay(size_type __n
, const _Tp
* __value
) {
300 _M_finish
= __value
+ __n
;
303 const_reference
front() const { return *begin(); }
304 const_reference
back() const { return *(end() - 1); }
307 const _Tp
*_M_finish
;
310 char *cached_realpath(const char * file_name
, char * resolved_name
);
312 } // end namespace Security
315 #endif //_H_UTILITIES