| 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 |