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