| OLD | NEW |
| 1 /** | 1 /** |
| 2 * \file record.h Definition of Record class. | 2 * \file record.h Definition of Record class. |
| 3 */ | 3 */ |
| 4 | 4 |
| 5 #ifndef RECORD_H | 5 #ifndef RECORD_H |
| 6 #define RECORD_H | 6 #define RECORD_H |
| 7 | 7 |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include <Windows.h> | 10 #include <Windows.h> |
| 11 #include <Msi.h> | 11 #include <Msi.h> |
| 12 | 12 |
| 13 #include "handle.h" | 13 #include "handle.h" |
| 14 | 14 |
| 15 // Forward | 15 // Forward |
| 16 class View ; | 16 class View; |
| 17 | 17 |
| 18 /** | 18 /** |
| 19 * An abstract record entity. | 19 * An abstract record entity. |
| 20 * It represents both records in the installation database and as argument vector
s for API functions. | 20 * It represents both records in the installation database and as argument vector
s for API functions. |
| 21 * | 21 * |
| 22 * The ordinary constructor creates a free-standing record. | 22 * The ordinary constructor creates a free-standing record. |
| 23 * It takes only the number of fields in the created record. | 23 * It takes only the number of fields in the created record. |
| 24 * The fields of the record are dynamically typed according to how they're assign
ed. | 24 * The fields of the record are dynamically typed according to how they're assign
ed. |
| 25 * Other constructors will be required to encapsulate records that are bound to d
atabases. | 25 * Other constructors will be required to encapsulate records that are bound to d
atabases. |
| 26 * | 26 * |
| 27 * This class has exclusive-ownership semantics for the API handle to the record. | 27 * This class has exclusive-ownership semantics for the API handle to the record. |
| 28 * Every constructor has a postcondition that the handle member points to an open
record. | 28 * Every constructor has a postcondition that the handle member points to an open
record. |
| 29 * The destructor closes the record. | 29 * The destructor closes the record. |
| 30 * The copy constructor syntax is used as a move constructor (since no C++11 yet)
. | 30 * The copy constructor syntax is used as a move constructor (since no C++11 yet)
. |
| 31 * Analogously, copy assignment has move semantics. | 31 * Analogously, copy assignment has move semantics. |
| 32 * | 32 * |
| 33 * \par Invariant | 33 * \par Invariant |
| 34 * - handle is not null implies handle points to a record open in the Windows I
nstaller subsystem | 34 * - handle is not null implies handle points to a record open in the Windows I
nstaller subsystem |
| 35 * | 35 * |
| 36 * \sa http://msdn.microsoft.com/en-us/library/windows/desktop/aa372881%28v=vs.85
%29.aspx | 36 * \sa http://msdn.microsoft.com/en-us/library/windows/desktop/aa372881%28v=vs.85
%29.aspx |
| 37 * Windows Installer on MSDN: "Working with Records" | 37 * Windows Installer on MSDN: "Working with Records" |
| 38 */ | 38 */ |
| 39 class Record { | 39 class Record |
| 40 { |
| 40 /** | 41 /** |
| 41 * | 42 * |
| 42 */ | 43 */ |
| 43 typedef Handle< MSIHANDLE, SpecialNull, GenericMsiDestruction > RecordHandleTy
pe ; | 44 typedef Handle<MSIHANDLE, SpecialNull, GenericMsiDestruction> RecordHandleType
; |
| 44 | 45 |
| 45 /** | 46 /** |
| 46 * The handle for the record as a Windows Installer resource. | 47 * The handle for the record as a Windows Installer resource. |
| 47 */ | 48 */ |
| 48 MSIHANDLE handle ; | 49 MSIHANDLE handle; |
| 49 | 50 |
| 50 /** | 51 /** |
| 51 * Construct a record from its handle as returned by some MSI call. | 52 * Construct a record from its handle as returned by some MSI call. |
| 52 */ | 53 */ |
| 53 Record( MsiHandle handle ) | 54 Record(MsiHandle handle) |
| 54 : handle( handle ) | 55 : handle(handle) |
| 55 {} | 56 {} |
| 56 | 57 |
| 57 /** | 58 /** |
| 58 * Internal validation guard for operations that require a non-null handle. | 59 * Internal validation guard for operations that require a non-null handle. |
| 59 * | 60 * |
| 60 * \post | 61 * \post |
| 61 * - if handle is zero, throw an exception | 62 * - if handle is zero, throw an exception |
| 62 * - if handle is non-zero, nothing | 63 * - if handle is non-zero, nothing |
| 63 */ | 64 */ |
| 64 void OnlyNonNull() ; | 65 void OnlyNonNull(); |
| 65 | 66 |
| 66 /** | 67 /** |
| 67 * Proxy class used to implement move semantics, prior to use of C++11. | 68 * Proxy class used to implement move semantics, prior to use of C++11. |
| 68 * | 69 * |
| 69 * /sa | 70 * /sa |
| 70 * - Wikibooks [More C++ Idioms/Move Constructor](http://en.wikibooks.org/wik
i/More_C%2B%2B_Idioms/Move_Constructor) | 71 * - Wikibooks [More C++ Idioms/Move Constructor](http://en.wikibooks.org/wik
i/More_C%2B%2B_Idioms/Move_Constructor) |
| 71 */ | 72 */ |
| 72 struct ProxyRecord | 73 struct ProxyRecord |
| 73 { | 74 { |
| 74 MSIHANDLE handle ; | 75 MSIHANDLE handle; |
| 75 | 76 |
| 76 ProxyRecord( MSIHANDLE handle ) | 77 ProxyRecord(MSIHANDLE handle) |
| 77 : handle( handle ) | 78 : handle(handle) |
| 78 {} | 79 {} |
| 79 } ; | 80 }; |
| 80 | 81 |
| 81 /** | 82 /** |
| 82 * Tag class for null record constructor | 83 * Tag class for null record constructor |
| 83 */ | 84 */ |
| 84 class NullType {} ; | 85 class NullType {}; |
| 85 | 86 |
| 86 /** | 87 /** |
| 87 * Null record constructor. | 88 * Null record constructor. |
| 88 * | 89 * |
| 89 * The null record constructor avoids the ordinary check that an external handl
e not be zero. | 90 * The null record constructor avoids the ordinary check that an external handl
e not be zero. |
| 90 * It's declared private so that only friends can instantiate them. | 91 * It's declared private so that only friends can instantiate them. |
| 91 */ | 92 */ |
| 92 Record( NullType ) | 93 Record(NullType) |
| 93 : handle( 0 ) | 94 : handle(0) |
| 94 {} | 95 {} |
| 95 | 96 |
| 96 /** | 97 /** |
| 97 * View class needs access to constructor-from-handle. | 98 * View class needs access to constructor-from-handle. |
| 98 */ | 99 */ |
| 99 friend class View ; | 100 friend class View; |
| 100 | 101 |
| 101 public: | 102 public: |
| 102 /** | 103 /** |
| 103 * Ordinary constructor creates a free-standing record. | 104 * Ordinary constructor creates a free-standing record. |
| 104 * Use this for creating argument vectors. | 105 * Use this for creating argument vectors. |
| 105 * | 106 * |
| 106 * \post handle points to a record obtained from MsiCreateRecord | 107 * \post handle points to a record obtained from MsiCreateRecord |
| 107 * | 108 * |
| 108 * \param[in] nFields | 109 * \param[in] nFields |
| 109 * Number of fields in the created record. | 110 * Number of fields in the created record. |
| 110 */ | 111 */ |
| 111 Record( unsigned int nFields ) ; | 112 Record(unsigned int nFields); |
| 112 | 113 |
| 113 /** | 114 /** |
| 114 * Destructor | 115 * Destructor |
| 115 */ | 116 */ |
| 116 ~Record() ; | 117 ~Record(); |
| 117 | 118 |
| 118 /** | 119 /** |
| 119 * Copy constructor syntax used as a move constructor. | 120 * Copy constructor syntax used as a move constructor. |
| 120 */ | 121 */ |
| 121 Record( Record & r ) | 122 Record(Record& r) |
| 122 : handle( r.handle ) | 123 : handle(r.handle) |
| 123 { | 124 { |
| 124 r.handle = 0 ; | 125 r.handle = 0; |
| 125 } | 126 } |
| 126 | 127 |
| 127 /** | 128 /** |
| 128 * Proxy move constructor. | 129 * Proxy move constructor. |
| 129 */ | 130 */ |
| 130 Record( ProxyRecord r ) | 131 Record(ProxyRecord r) |
| 131 : handle( r.handle ) | 132 : handle(r.handle) |
| 132 { | 133 { |
| 133 r.handle = 0 ; | 134 r.handle = 0; |
| 134 } | 135 } |
| 135 | 136 |
| 136 /** | 137 /** |
| 137 * Copy assignment syntax has move assignment semantics. | 138 * Copy assignment syntax has move assignment semantics. |
| 138 */ | 139 */ |
| 139 Record & operator=( Record & r ) | 140 Record& operator=(Record& r) |
| 140 { | 141 { |
| 141 this -> ~Record() ; | 142 this -> ~Record(); |
| 142 handle = r.handle ; | 143 handle = r.handle; |
| 143 r.handle = 0 ; | 144 r.handle = 0; |
| 144 return * this ; | 145 return * this; |
| 145 } | 146 } |
| 146 | 147 |
| 147 /** | 148 /** |
| 148 * Proxy move assignment. | 149 * Proxy move assignment. |
| 149 */ | 150 */ |
| 150 Record & operator=( ProxyRecord pr ) | 151 Record& operator=(ProxyRecord pr) |
| 151 { | 152 { |
| 152 this -> ~Record() ; | 153 this -> ~Record(); |
| 153 handle = pr.handle ; | 154 handle = pr.handle; |
| 154 pr.handle = 0 ; | 155 pr.handle = 0; |
| 155 return * this ; | 156 return * this; |
| 156 } | 157 } |
| 157 | 158 |
| 158 /** | 159 /** |
| 159 * Proxy conversion operator | 160 * Proxy conversion operator |
| 160 */ | 161 */ |
| 161 operator ProxyRecord() | 162 operator ProxyRecord() |
| 162 { | 163 { |
| 163 ProxyRecord pr( handle ) ; | 164 ProxyRecord pr(handle); |
| 164 handle = 0 ; | 165 handle = 0; |
| 165 return pr ; | 166 return pr; |
| 166 } | 167 } |
| 167 | 168 |
| 168 /** | 169 /** |
| 169 * Two records are equal exactly when their handles are equal. | 170 * Two records are equal exactly when their handles are equal. |
| 170 */ | 171 */ |
| 171 inline bool operator==( const Record & x ) const | 172 inline bool operator==(const Record& x) const |
| 172 { | 173 { |
| 173 return handle == x.handle ; | 174 return handle == x.handle; |
| 174 } | 175 } |
| 175 | 176 |
| 176 /** | 177 /** |
| 177 * Standard inequality operator defined by negating the equality operator. | 178 * Standard inequality operator defined by negating the equality operator. |
| 178 */ | 179 */ |
| 179 inline bool operator!=( const Record & x ) const | 180 inline bool operator!=(const Record& x) const |
| 180 { | 181 { |
| 181 return ! operator==( x ) ; | 182 return ! operator==(x); |
| 182 } | 183 } |
| 183 | 184 |
| 184 /** | 185 /** |
| 185 * Assign a string to a record, (regular) character pointer. | 186 * Assign a string to a record, (regular) character pointer. |
| 186 * | 187 * |
| 187 * \param[in] fieldIndex | 188 * \param[in] fieldIndex |
| 188 * Index into the record as a vector of fields | 189 * Index into the record as a vector of fields |
| 189 * \param[in] value | 190 * \param[in] value |
| 190 * String to write into the field | 191 * String to write into the field |
| 191 */ | 192 */ |
| 192 void AssignString( unsigned int fieldIndex, const char *value ) ; | 193 void AssignString(unsigned int fieldIndex, const char* value); |
| 193 | 194 |
| 194 /** | 195 /** |
| 195 * Assign a string to a record, regular string version. | 196 * Assign a string to a record, regular string version. |
| 196 * | 197 * |
| 197 * \param[in] fieldIndex | 198 * \param[in] fieldIndex |
| 198 * Index into the record as a vector of fields | 199 * Index into the record as a vector of fields |
| 199 * \param[in] value | 200 * \param[in] value |
| 200 * String to write into the field | 201 * String to write into the field |
| 201 */ | 202 */ |
| 202 void AssignString(unsigned int fieldIndex, const std::string value) | 203 void AssignString(unsigned int fieldIndex, const std::string value) |
| 203 { | 204 { |
| 204 AssignString(fieldIndex, value.c_str()); | 205 AssignString(fieldIndex, value.c_str()); |
| 205 } | 206 } |
| 206 | 207 |
| 207 /** | 208 /** |
| 208 * Assign a string to a record, wide character pointer version. | 209 * Assign a string to a record, wide character pointer version. |
| 209 * | 210 * |
| 210 * \param[in] fieldIndex | 211 * \param[in] fieldIndex |
| 211 * Index into the record as a vector of fields | 212 * Index into the record as a vector of fields |
| 212 * \param[in] value | 213 * \param[in] value |
| 213 * String to write into the field | 214 * String to write into the field |
| 214 */ | 215 */ |
| 215 void AssignString(unsigned int fieldIndex, const wchar_t *value) ; | 216 void AssignString(unsigned int fieldIndex, const wchar_t* value); |
| 216 | 217 |
| 217 /** | 218 /** |
| 218 * Assign a string to a record, wide string version. | 219 * Assign a string to a record, wide string version. |
| 219 * | 220 * |
| 220 * \param[in] fieldIndex | 221 * \param[in] fieldIndex |
| 221 * Index into the record as a vector of fields | 222 * Index into the record as a vector of fields |
| 222 * \param[in] value | 223 * \param[in] value |
| 223 * String to write into the field | 224 * String to write into the field |
| 224 */ | 225 */ |
| 225 void AssignString( unsigned int fieldIndex, const std::wstring value) | 226 void AssignString(unsigned int fieldIndex, const std::wstring value) |
| 226 { | 227 { |
| 227 AssignString(fieldIndex, value.c_str()); | 228 AssignString(fieldIndex, value.c_str()); |
| 228 } | 229 } |
| 229 | 230 |
| 230 /** | 231 /** |
| 231 * Retrieve a wide string value from a record | 232 * Retrieve a wide string value from a record |
| 232 */ | 233 */ |
| 233 std::wstring ValueString( unsigned int fieldIndex) ; | 234 std::wstring ValueString(unsigned int fieldIndex); |
| 234 | 235 |
| 235 /** | 236 /** |
| 236 * The number of fields in the record. | 237 * The number of fields in the record. |
| 237 */ | 238 */ |
| 238 size_t NumberOfFields() const ; | 239 size_t NumberOfFields() const; |
| 239 | 240 |
| 240 /** | 241 /** |
| 241 * Handle accessor. | 242 * Handle accessor. |
| 242 */ | 243 */ |
| 243 MSIHANDLE Handle() { return handle ; } | 244 MSIHANDLE Handle() |
| 245 { |
| 246 return handle ; |
| 247 } |
| 244 }; | 248 }; |
| 245 | 249 |
| 246 #endif | 250 #endif |
| OLD | NEW |