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