OLD | NEW |
1 /** | 1 /** |
2 * \file handle.h The "install session" is the context for all custom installatio
n behavior. | 2 * \file handle.h The "install session" is the context for all custom installatio
n behavior. |
3 */ | 3 */ |
4 | 4 |
5 #ifndef HANDLE_H | 5 #ifndef HANDLE_H |
6 #define HANDLE_H | 6 #define HANDLE_H |
7 | 7 |
8 #include "windows.h" | 8 #include "windows.h" |
9 #include "msi.h" | 9 #include "msi.h" |
10 | 10 |
11 //------------------------------------------------------- | 11 //------------------------------------------------------- |
12 // MsiHandle | 12 // MsiHandle |
13 //------------------------------------------------------- | 13 //------------------------------------------------------- |
14 /** | 14 /** |
15 * Disambiguation class holding an MSIHANDLE. | 15 * Disambiguation class holding an MSIHANDLE. |
16 * | 16 * |
17 * We need constructors for Record that accept both handles and record counts. | 17 * We need constructors for Record that accept both handles and record counts. |
18 * Since the underlying type of a handle is integral, without its own type these
constructors are ambiguous. | 18 * Since the underlying type of a handle is integral, without its own type these
constructors are ambiguous. |
19 */ | 19 */ |
20 class MsiHandle | 20 class MsiHandle |
21 { | 21 { |
22 MSIHANDLE handle ; | 22 MSIHANDLE handle; |
23 | 23 |
24 public: | 24 public: |
25 /** | 25 /** |
26 * Ordinary constructor is explicit to avoid inadvertent conversions. | 26 * Ordinary constructor is explicit to avoid inadvertent conversions. |
27 */ | 27 */ |
28 explicit MsiHandle( MSIHANDLE handle ) | 28 explicit MsiHandle(MSIHANDLE handle) |
29 : handle( handle ) | 29 : handle(handle) |
30 {} | 30 {} |
31 | 31 |
32 operator MSIHANDLE() | 32 operator MSIHANDLE() |
33 { | 33 { |
34 return handle ; | 34 return handle; |
35 } | 35 } |
36 } ; | 36 }; |
37 | 37 |
38 //------------------------------------------------------- | 38 //------------------------------------------------------- |
39 // Handle Policies | 39 // Handle Policies |
40 //------------------------------------------------------- | 40 //------------------------------------------------------- |
41 /** | 41 /** |
42 * Policy class that indicates that a raw handle may not be zero. | 42 * Policy class that indicates that a raw handle may not be zero. |
43 */ | 43 */ |
44 template< class T > | 44 template<class T> |
45 struct DisallowNull | 45 struct DisallowNull |
46 { | 46 { |
47 inline static bool ProhibitedAlways() { return true ; } | 47 inline static bool ProhibitedAlways() |
48 inline static bool ProhibitedFromOutside() { return true ; } | 48 { |
49 } ; | 49 return true ; |
| 50 } |
| 51 inline static bool ProhibitedFromOutside() |
| 52 { |
| 53 return true ; |
| 54 } |
| 55 }; |
50 | 56 |
51 /** | 57 /** |
52 * Policy class that indicates that a raw handle may be zero only when constructe
d internally. | 58 * Policy class that indicates that a raw handle may be zero only when constructe
d internally. |
53 */ | 59 */ |
54 template< class T > | 60 template<class T> |
55 struct SpecialNull | 61 struct SpecialNull |
56 { | 62 { |
57 inline static bool ProhibitedAlways() { return false ; } | 63 inline static bool ProhibitedAlways() |
58 inline static bool ProhibitedFromOutside() { return true ; } | 64 { |
59 } ; | 65 return false ; |
| 66 } |
| 67 inline static bool ProhibitedFromOutside() |
| 68 { |
| 69 return true ; |
| 70 } |
| 71 }; |
60 | 72 |
61 /** | 73 /** |
62 * Policy class that indicates that a raw handle is permitted to be zero. | 74 * Policy class that indicates that a raw handle is permitted to be zero. |
63 */ | 75 */ |
64 template< class T > | 76 template<class T> |
65 struct AllowNull | 77 struct AllowNull |
66 { | 78 { |
67 inline static bool ProhibitedAlways() { return false ; } | 79 inline static bool ProhibitedAlways() |
68 inline static bool ProhibitedFromOutside() { return false ; } | 80 { |
69 } ; | 81 return false ; |
| 82 } |
| 83 inline static bool ProhibitedFromOutside() |
| 84 { |
| 85 return false ; |
| 86 } |
| 87 }; |
70 | 88 |
71 /** | 89 /** |
72 * Policy class that does not close a handle at all. | 90 * Policy class that does not close a handle at all. |
73 */ | 91 */ |
74 template< class T > | 92 template<class T> |
75 class NoDestruction | 93 class NoDestruction |
76 { | 94 { |
77 public: | 95 public: |
78 inline static void Close( T handle ) {} ; | 96 inline static void Close(T handle) {}; |
79 } ; | 97 }; |
80 | 98 |
81 /** | 99 /** |
82 * Policy class that closes an MSI handle when it goes out of scope. | 100 * Policy class that closes an MSI handle when it goes out of scope. |
83 */ | 101 */ |
84 template< class T > | 102 template<class T> |
85 class GenericMsiDestruction | 103 class GenericMsiDestruction |
86 { | 104 { |
87 public: | 105 public: |
88 inline static void Close( T handle ) | 106 inline static void Close(T handle) |
89 { | 107 { |
90 MsiCloseHandle( handle ) ; | 108 MsiCloseHandle(handle); |
91 } ; | 109 }; |
92 } ; | 110 }; |
93 | 111 |
94 /** | 112 /** |
95 * Policy class that closes a Windows handle when it goes out of scope. | 113 * Policy class that closes a Windows handle when it goes out of scope. |
96 */ | 114 */ |
97 template< class T > | 115 template<class T> |
98 class GenericWindowsDestruction | 116 class GenericWindowsDestruction |
99 { | 117 { |
100 public: | 118 public: |
101 inline static void Close( T handle ) | 119 inline static void Close(T handle) |
102 { | 120 { |
103 CloseHandle( handle ) ; | 121 CloseHandle(handle); |
104 } ; | 122 }; |
105 } ; | 123 }; |
106 | 124 |
107 | 125 |
108 //------------------------------------------------------- | 126 //------------------------------------------------------- |
109 // Handle | 127 // Handle |
110 //------------------------------------------------------- | 128 //------------------------------------------------------- |
111 /** | 129 /** |
112 * Raw handle is the base class for the generic handle. | 130 * Raw handle is the base class for the generic handle. |
113 * | 131 * |
114 * Raw handles always allow null, so that generic handles may allow or disallow t
hem as they please. | 132 * Raw handles always allow null, so that generic handles may allow or disallow t
hem as they please. |
115 */ | 133 */ |
116 template< class T > | 134 template<class T> |
117 class HandleRaw | 135 class HandleRaw |
118 { | 136 { |
119 protected: | 137 protected: |
120 /** | 138 /** |
121 * The underlying handle. | 139 * The underlying handle. |
122 * | 140 * |
123 * This is the only data member of the class. | 141 * This is the only data member of the class. |
124 * Everything else is for life cycle and type conversion. | 142 * Everything else is for life cycle and type conversion. |
125 */ | 143 */ |
126 T handle ; | 144 T handle; |
127 | 145 |
128 /** | 146 /** |
129 * Basic constructor is protected to cede creation policy entirely to subclasse
s. | 147 * Basic constructor is protected to cede creation policy entirely to subclasse
s. |
130 */ | 148 */ |
131 HandleRaw( T handle ) | 149 HandleRaw(T handle) |
132 : handle( handle ) | 150 : handle(handle) |
133 {} | 151 {} |
134 | 152 |
135 public: | 153 public: |
136 /** | 154 /** |
137 * Conversion operator to underlying handle type. | 155 * Conversion operator to underlying handle type. |
138 */ | 156 */ |
139 operator T() | 157 operator T() |
140 { | 158 { |
141 return handle ; | 159 return handle; |
142 } | 160 } |
143 | 161 |
144 /** | 162 /** |
145 * Error thrown when initialize or assigning a null handle against policy. | 163 * Error thrown when initialize or assigning a null handle against policy. |
146 * | 164 * |
147 * Note that this error is a logic_error, not a runtime error. | 165 * Note that this error is a logic_error, not a runtime error. |
148 * If it's against policy for a handle to be null, it's an error for the caller
to try to make it null. | 166 * If it's against policy for a handle to be null, it's an error for the caller
to try to make it null. |
149 * Policy enforcment here is not a substitute for good error handling by the ca
ller. | 167 * Policy enforcment here is not a substitute for good error handling by the ca
ller. |
150 * In many cases, the caller ought to be throwing WindowsApiError. | 168 * In many cases, the caller ought to be throwing WindowsApiError. |
151 */ | 169 */ |
152 struct NullHandleError | 170 struct NullHandleError |
153 : public std::logic_error | 171 : public std::logic_error |
154 { | 172 { |
155 NullHandleError() | 173 NullHandleError() |
156 : std::logic_error( "May not initialize with null handle" ) | 174 : std::logic_error("May not initialize with null handle") |
157 {} | 175 {} |
158 } ; | 176 }; |
159 } ; | 177 }; |
160 | 178 |
161 /* | 179 /* |
162 * Handle class | 180 * Handle class |
163 */ | 181 */ |
164 template< | 182 template< |
165 class T, | 183 class T, |
166 template <class> class NullPolicy, | 184 template <class> class NullPolicy, |
167 template <class> class DestructionPolicy = NoDestruction | 185 template <class> class DestructionPolicy = NoDestruction |
168 > | 186 > |
169 class Handle | 187 class Handle |
170 : public HandleRaw< T > | 188 : public HandleRaw<T> |
171 { | 189 { |
172 /** | 190 /** |
173 * Copy constructor prohibited. | 191 * Copy constructor prohibited. |
174 * | 192 * |
175 * This class represents an external resource and is responsible for its lifec
ycle. | 193 * This class represents an external resource and is responsible for its lifec
ycle. |
176 * As such, the semantics here require a one-to-one match between instances an
d resource. | 194 * As such, the semantics here require a one-to-one match between instances an
d resource. |
177 * Copy construction violates these semantics. | 195 * Copy construction violates these semantics. |
178 * | 196 * |
179 * \par Implementation | 197 * \par Implementation |
180 * Currently, declared private and not defined. | 198 * Currently, declared private and not defined. |
181 * Add "= delete" for C++11. | 199 * Add "= delete" for C++11. |
182 */ | 200 */ |
183 Handle( Handle & ) ; | 201 Handle(Handle&); |
184 | 202 |
185 /** | 203 /** |
186 * Copy assignment not implemented. | 204 * Copy assignment not implemented. |
187 * | 205 * |
188 * It's not used anywhere yet. | 206 * It's not used anywhere yet. |
189 * | 207 * |
190 * \par Implementation | 208 * \par Implementation |
191 * Currently, declared private and not defined. | 209 * Currently, declared private and not defined. |
192 */ | 210 */ |
193 Handle operator=( const Handle & ) ; | 211 Handle operator=(const Handle&); |
194 | 212 |
195 /** | 213 /** |
196 * Validate initial handle values, both for construction and reinitialization
assignment. | 214 * Validate initial handle values, both for construction and reinitialization
assignment. |
197 */ | 215 */ |
198 T ValidateHandle( T handle ) | 216 T ValidateHandle(T handle) |
199 { | 217 { |
200 if ( NullPolicy< T >::ProhibitedFromOutside() && handle == 0 ) | 218 if (NullPolicy<T>::ProhibitedFromOutside() && handle == 0) |
201 { | 219 { |
202 throw NullHandleError() ; | 220 throw NullHandleError(); |
203 } | 221 } |
204 return handle ; | 222 return handle; |
205 } | 223 } |
206 | 224 |
207 protected: | 225 protected: |
208 /** | 226 /** |
209 * Tag class for null record constructor | 227 * Tag class for null record constructor |
210 */ | 228 */ |
211 class NullType {} ; | 229 class NullType {}; |
212 | 230 |
213 /** | 231 /** |
214 * Null handle constructor initializes its handle to zero. | 232 * Null handle constructor initializes its handle to zero. |
215 * | 233 * |
216 * The null record constructor avoids the ordinary check that an external hand
le not be zero. | 234 * The null record constructor avoids the ordinary check that an external hand
le not be zero. |
217 * It's declared protected so that it's not ordinarily visible. | 235 * It's declared protected so that it's not ordinarily visible. |
218 * To use this constructor, derive from it and add a friend declaration. | 236 * To use this constructor, derive from it and add a friend declaration. |
219 */ | 237 */ |
220 Handle( NullType ) | 238 Handle(NullType) |
221 : HandleRaw( 0 ) | 239 : HandleRaw(0) |
222 { | 240 { |
223 if ( NullPolicy< T >::ProhibitedAlways() ) | 241 if (NullPolicy<T>::ProhibitedAlways()) |
224 { | 242 { |
225 throw NullHandleError() ; | 243 throw NullHandleError(); |
226 } | 244 } |
227 } | 245 } |
228 | 246 |
229 public: | 247 public: |
230 /** | 248 /** |
231 * Ordinary constructor. | 249 * Ordinary constructor. |
232 * | 250 * |
233 * A check for a non-zero handle compiles in conditionally based on the NullPo
licy. | 251 * A check for a non-zero handle compiles in conditionally based on the NullPo
licy. |
234 */ | 252 */ |
235 Handle( T handle ) | 253 Handle(T handle) |
236 : HandleRaw( ValidateHandle( handle ) ) | 254 : HandleRaw(ValidateHandle(handle)) |
237 {} | 255 {} |
238 | 256 |
239 /** | 257 /** |
240 * Reinitialization Assignment. | 258 * Reinitialization Assignment. |
241 * | 259 * |
242 * If we had C++11 move constructors, we wouldn't need this, since this acts e
xactly as construct-plus-move would. | 260 * If we had C++11 move constructors, we wouldn't need this, since this acts e
xactly as construct-plus-move would. |
243 */ | 261 */ |
244 Handle & operator=( T handle ) | 262 Handle& operator=(T handle) |
245 { | 263 { |
246 ValidateHandle( handle ) ; | 264 ValidateHandle(handle); |
247 this -> ~Handle() ; | 265 this -> ~Handle(); |
248 this -> handle = handle ; | 266 this -> handle = handle; |
249 return * this ; | 267 return * this; |
250 } | 268 } |
251 | 269 |
252 /** | 270 /** |
253 * Destructor | 271 * Destructor |
254 * | 272 * |
255 * The check for a non-zero handle compiles out conditionally based on NullPol
icy. | 273 * The check for a non-zero handle compiles out conditionally based on NullPol
icy. |
256 * The specific function used to close the handle is given by the DestructionP
olicy. | 274 * The specific function used to close the handle is given by the DestructionP
olicy. |
257 */ | 275 */ |
258 ~Handle() | 276 ~Handle() |
259 { | 277 { |
260 if ( NullPolicy< T >::ProhibitedAlways() || ( handle != 0 ) ) { | 278 if (NullPolicy<T>::ProhibitedAlways() || (handle != 0)) |
261 DestructionPolicy< T >::Close( handle ) ; | 279 { |
| 280 DestructionPolicy<T>::Close(handle); |
262 } | 281 } |
263 } | 282 } |
264 | 283 |
265 /** | 284 /** |
266 * Expose the underlying handle type. | 285 * Expose the underlying handle type. |
267 */ | 286 */ |
268 typedef T HandleType ; | 287 typedef T HandleType; |
269 } ; | 288 }; |
270 | 289 |
271 //------------------------------------------------------- | 290 //------------------------------------------------------- |
272 // Common instantiations of handle | 291 // Common instantiations of handle |
273 //------------------------------------------------------- | 292 //------------------------------------------------------- |
274 typedef Handle< HANDLE, DisallowNull, GenericWindowsDestruction > WindowsHandle
; | 293 typedef Handle<HANDLE, DisallowNull, GenericWindowsDestruction> WindowsHandle; |
275 | 294 |
276 #endif | 295 #endif |
OLD | NEW |