]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
d8f41ccd | 2 | * Copyright (c) 2000-2004,2011,2014 Apple Inc. All Rights Reserved. |
b1ab9ed8 A |
3 | * |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
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 | |
11 | * file. | |
12 | * | |
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. | |
20 | * | |
21 | * @APPLE_LICENSE_HEADER_END@ | |
22 | */ | |
23 | ||
24 | ||
25 | /* | |
26 | * cssm utilities | |
27 | */ | |
28 | #ifndef _H_UTILITIES | |
29 | #define _H_UTILITIES | |
30 | ||
31 | #include <security_utilities/utility_config.h> | |
32 | #include <security_utilities/errors.h> | |
33 | #include <exception> | |
34 | #include <new> | |
35 | #include <string> | |
36 | #include <string.h> | |
37 | ||
d64be36e A |
38 | #include <security_utilities/simulatecrash_assert.h> |
39 | ||
b1ab9ed8 A |
40 | namespace Security |
41 | { | |
42 | ||
43 | // | |
44 | // Elementary debugging support. | |
45 | // #include <debugging.h> for more debugging facilities. | |
46 | // | |
47 | #define IFDEBUG(it) IFELSEDEBUG(it,) | |
48 | #define IFNDEBUG(it) IFELSEDEBUG(,it) | |
49 | ||
50 | #if defined(NDEBUG) | |
51 | ||
52 | # define safe_cast static_cast | |
53 | # define safer_cast static_cast | |
54 | ||
55 | # define IFELSEDEBUG(d,nd) nd | |
56 | ||
57 | #else | |
58 | ||
59 | template <class Derived, class Base> | |
60 | inline Derived safer_cast(Base &base) | |
61 | { | |
62 | return dynamic_cast<Derived>(base); | |
63 | } | |
64 | ||
65 | template <class Derived, class Base> | |
66 | inline Derived safe_cast(Base *base) | |
67 | { | |
68 | if (base == NULL) | |
69 | return NULL; // okay to cast NULL to NULL | |
70 | Derived p = dynamic_cast<Derived>(base); | |
71 | assert(p); | |
72 | return p; | |
73 | } | |
74 | ||
75 | # define IFELSEDEBUG(d,nd) d | |
76 | ||
77 | #endif //NDEBUG | |
78 | ||
79 | ||
80 | // | |
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. | |
85 | // | |
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; | |
89 | ||
90 | ||
91 | // | |
92 | // Helpers for memory pointer validation | |
93 | // | |
94 | #define MY_CSSM_ERRCODE_INVALID_POINTER 0x0004 | |
95 | template <class T> | |
96 | inline T &Required(T *ptr, OSStatus err = MY_CSSM_ERRCODE_INVALID_POINTER) | |
97 | { | |
98 | if (ptr == NULL) | |
99 | MacOSError::throwMe(err); | |
100 | return *ptr; | |
101 | } | |
102 | ||
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) | |
105 | { | |
106 | if (ptr == NULL) | |
107 | MacOSError::throwMe(err); | |
108 | } | |
109 | ||
110 | ||
111 | // | |
112 | // Tools to build POD wrapper classes | |
113 | // | |
114 | template <class Wrapper, class POD> | |
115 | class PodWrapper : public POD { | |
116 | public: | |
117 | // pure typecasts | |
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); } | |
122 | ||
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); } | |
131 | ||
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); } | |
141 | ||
142 | // general helpers for all PodWrappers | |
143 | void clearPod() | |
144 | { memset(static_cast<POD *>(this), 0, sizeof(POD)); } | |
145 | ||
146 | void assignPod(const POD &source) | |
147 | { static_cast<POD &>(*this) = source; } | |
148 | }; | |
149 | ||
150 | ||
151 | // | |
152 | // Template builder support | |
153 | // | |
154 | template <class T> | |
155 | struct Nonconst { | |
156 | typedef T Type; | |
157 | }; | |
158 | ||
159 | template <class U> | |
160 | struct Nonconst<const U> { | |
161 | typedef U Type; | |
162 | }; | |
163 | ||
164 | template <class U> | |
165 | struct Nonconst<const U *> { | |
166 | typedef U *Type; | |
167 | }; | |
168 | ||
169 | // cast away pointed-to constness | |
170 | template <class T> | |
171 | typename Nonconst<T>::Type unconst_cast(T obj) | |
172 | { | |
173 | return const_cast<typename Nonconst<T>::Type>(obj); | |
174 | } | |
175 | ||
176 | template <class T> | |
177 | typename Nonconst<T>::Type &unconst_ref_cast(T &obj) | |
178 | { | |
179 | return const_cast<typename Nonconst<T>::Type &>(obj); | |
180 | } | |
181 | ||
182 | ||
183 | // Help with container of something->pointer cleanup | |
184 | template <class In> | |
185 | static inline void for_each_delete(In first, In last) | |
186 | { | |
187 | while (first != last) | |
188 | delete *(first++); | |
189 | } | |
190 | ||
191 | // Help with map of something->pointer cleanup | |
192 | template <class In> | |
193 | static inline void for_each_map_delete(In first, In last) | |
194 | { | |
195 | while (first != last) | |
196 | delete (first++)->second; | |
197 | } | |
198 | ||
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) | |
202 | { | |
203 | while (first != last) | |
204 | *out++ = (first++)->first; | |
205 | return out; | |
206 | } | |
207 | ||
208 | template <class InIterator, class OutIterator> | |
209 | inline OutIterator copy_second(InIterator first, InIterator last, OutIterator out) | |
210 | { | |
211 | while (first != last) | |
212 | *out++ = (first++)->second; | |
213 | return out; | |
214 | } | |
215 | ||
216 | ||
217 | // simple safe re-entry blocker | |
218 | class RecursionBlock { | |
219 | public: | |
220 | RecursionBlock() : mActive(false) { } | |
221 | ~RecursionBlock() { assert(!mActive); } | |
222 | ||
223 | public: | |
224 | class Once { | |
225 | public: | |
226 | Once(RecursionBlock &rb) : block(rb), mActive(false) { } | |
227 | ~Once() { block.mActive &= !mActive; } | |
228 | bool operator () () | |
229 | { if (block.mActive) return true; mActive = block.mActive = true; return false; } | |
230 | ||
231 | RecursionBlock █ | |
232 | ||
233 | private: | |
234 | bool mActive; | |
235 | }; | |
236 | friend class Once; | |
237 | ||
238 | private: | |
239 | bool mActive; | |
240 | }; | |
241 | ||
242 | // Quick and dirty template for a (temporary) array of something | |
243 | // Usage example auto_array<UInt32> anArray(20); | |
244 | template <class T> | |
245 | class auto_array | |
246 | { | |
247 | public: | |
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; } | |
255 | private: | |
256 | T *mArray; | |
257 | }; | |
258 | ||
259 | // Template for a vector-like class that takes a c-array as it's | |
260 | // underlying storage without making a copy. | |
261 | template <class _Tp> | |
262 | class constVector | |
263 | { | |
264 | NOCOPY(constVector<_Tp>) | |
265 | public: | |
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; | |
272 | ||
273 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | |
274 | public: | |
275 | const_iterator begin() const { return _M_start; } | |
276 | const_iterator end() const { return _M_finish; } | |
277 | ||
278 | const_reverse_iterator rbegin() const | |
279 | { return const_reverse_iterator(end()); } | |
280 | const_reverse_iterator rend() const | |
281 | { return const_reverse_iterator(begin()); } | |
282 | ||
283 | size_type size() const | |
284 | { return size_type(end() - begin()); } | |
285 | bool empty() const | |
286 | { return begin() == end(); } | |
287 | ||
288 | const_reference operator[](size_type __n) const { return *(begin() + __n); } | |
289 | ||
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]; } | |
293 | ||
294 | constVector(size_type __n, const _Tp* __value) | |
295 | : _M_start(__value), _M_finish(__value + __n) | |
296 | {} | |
297 | ||
298 | constVector() : _M_start(NULL), _M_finish(NULL) {} | |
299 | ||
300 | void overlay(size_type __n, const _Tp* __value) { | |
301 | _M_start = __value; | |
302 | _M_finish = __value + __n; | |
303 | } | |
304 | ||
305 | const_reference front() const { return *begin(); } | |
306 | const_reference back() const { return *(end() - 1); } | |
307 | private: | |
308 | const _Tp *_M_start; | |
309 | const _Tp *_M_finish; | |
310 | }; | |
311 | ||
312 | char *cached_realpath(const char * file_name, char * resolved_name); | |
313 | ||
314 | } // end namespace Security | |
315 | ||
316 | ||
317 | #endif //_H_UTILITIES |