Rev 2062 Rev 2064
1 ///////////////////////////////////////////////////////////////////////////////// 1 /////////////////////////////////////////////////////////////////////////////////
2 // Cini Class Implementation 2 // Cini Class Implementation
3 ///////////////////////////////////////////////////////////////////////////////// 3 /////////////////////////////////////////////////////////////////////////////////
4 #include "stdafx.h" // include if you got "fatal error C1010: unexpected end of file..." 4 #include "stdafx.h" // include if you got "fatal error C1010: unexpected end of file..."
5 #include "Ini.h" 5 #include "Ini.h"
6 #include <string.h> 6 #include <string.h>
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <assert.h> 8 #include <assert.h>
9   9  
10 #define DEF_PROFILE_NUM_LEN 64 // numeric string length, could be quite long for binary format 10 #define DEF_PROFILE_NUM_LEN 64 // numeric string length, could be quite long for binary format
11 #define DEF_PROFILE_THRESHOLD 512 // temporary string length 11 #define DEF_PROFILE_THRESHOLD 512 // temporary string length
12 #define DEF_PROFILE_DELIMITER _T(",") // default string delimiter 12 #define DEF_PROFILE_DELIMITER _T(",") // default string delimiter
13 #define DEF_PROFILE_TESTSTRING _T("{63788286-AE30-4D6B-95DF-3B451C1C79F9}") // Uuid for internal use 13 #define DEF_PROFILE_TESTSTRING _T("{63788286-AE30-4D6B-95DF-3B451C1C79F9}") // Uuid for internal use
14   14  
15 // struct used to be passed to __KeyPairProc as a LPVOID parameter 15 // struct used to be passed to __KeyPairProc as a LPVOID parameter
16 struct STR_LIMIT 16 struct STR_LIMIT
17 { 17 {
18 LPTSTR lpTarget; 18 LPTSTR lpTarget;
19 DWORD dwRemain; 19 DWORD dwRemain;
20 DWORD dwTotalCopied; 20 DWORD dwTotalCopied;
21 }; 21 };
22   22  
23 ///////////////////////////////////////////////////////////////////////////////// 23 /////////////////////////////////////////////////////////////////////////////////
24 // Constructors & Destructor 24 // Constructors & Destructor
25 ///////////////////////////////////////////////////////////////////////////////// 25 /////////////////////////////////////////////////////////////////////////////////
26 CIni::CIni() 26 CIni::CIni()
27 { 27 {
28 m_pszPathName = NULL; 28 m_pszPathName = NULL;
29 } 29 }
30   30  
31 CIni::CIni(LPCTSTR lpPathName) 31 CIni::CIni(LPCTSTR lpPathName)
32 { 32 {
33 m_pszPathName = NULL; 33 m_pszPathName = NULL;
34 SetPathName(lpPathName); 34 SetPathName(lpPathName);
35 } 35 }
36   36  
37 CIni::~CIni() 37 CIni::~CIni()
38 { 38 {
39 if (m_pszPathName != NULL) 39 if (m_pszPathName != NULL)
40 delete [] m_pszPathName; 40 delete [] m_pszPathName;
41 } 41 }
42   42  
43 ///////////////////////////////////////////////////////////////////////////////// 43 /////////////////////////////////////////////////////////////////////////////////
44 // Ini File Path Access 44 // Ini File Path Access
45 ///////////////////////////////////////////////////////////////////////////////// 45 /////////////////////////////////////////////////////////////////////////////////
46   46  
47 // Assign ini file path name 47 // Assign ini file path name
48 void CIni::SetPathName(LPCTSTR lpPathName) 48 void CIni::SetPathName(LPCTSTR lpPathName)
49 { 49 {
50 if (lpPathName == NULL) 50 if (lpPathName == NULL)
51 { 51 {
52 if (m_pszPathName != NULL) 52 if (m_pszPathName != NULL)
53 *m_pszPathName = _T('\0'); 53 *m_pszPathName = _T('\0');
54 } 54 }
55 else 55 else
56 { 56 {
57 if (m_pszPathName != NULL) 57 if (m_pszPathName != NULL)
58 delete [] m_pszPathName; 58 delete [] m_pszPathName;
59   59  
60 m_pszPathName = _tcsdup(lpPathName); 60 m_pszPathName = _tcsdup(lpPathName);
61 } 61 }
62 } 62 }
63   63  
64 // Retrieve ini file path name 64 // Retrieve ini file path name
65 DWORD CIni::GetPathName(LPTSTR lpBuffer, DWORD dwBufSize) const 65 DWORD CIni::GetPathName(LPTSTR lpBuffer, DWORD dwBufSize) const
66 { 66 {
67 *lpBuffer = _T('\0'); 67 *lpBuffer = _T('\0');
68 DWORD dwLen = 0; 68 DWORD dwLen = 0;
69 if (lpBuffer != NULL) 69 if (lpBuffer != NULL)
70 { 70 {
71 _tcsncpy(lpBuffer, m_pszPathName, dwBufSize); 71 _tcsncpy(lpBuffer, m_pszPathName, dwBufSize);
72 dwLen = _tcslen(lpBuffer); 72 dwLen = _tcslen(lpBuffer);
73 } 73 }
74 else 74 else
75 { 75 {
76 // just calculate the required buffer size 76 // just calculate the required buffer size
77 dwLen = _tcslen(m_pszPathName); 77 dwLen = _tcslen(m_pszPathName);
78 } 78 }
79 return dwLen; 79 return dwLen;
80 } 80 }
81   81  
82 #ifdef __AFXWIN_H__ 82 #ifdef __AFXWIN_H__
83 CString CIni::GetPathName() const 83 CString CIni::GetPathName() const
84 { 84 {
85 return CString(m_pszPathName); 85 return CString(m_pszPathName);
86 } 86 }
87 #endif 87 #endif
88   88  
89 ///////////////////////////////////////////////////////////////////////////////// 89 /////////////////////////////////////////////////////////////////////////////////
90 // Raw String Access 90 // Raw String Access
91 ///////////////////////////////////////////////////////////////////////////////// 91 /////////////////////////////////////////////////////////////////////////////////
92   92  
93 // Get a profile string value, if the buffer size is not large enough, the result 93 // Get a profile string value, if the buffer size is not large enough, the result
94 // may be truncated. 94 // may be truncated.
95 DWORD CIni::GetString(LPCTSTR lpSection, LPCTSTR lpKey, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDefault) const 95 DWORD CIni::GetString(LPCTSTR lpSection, LPCTSTR lpKey, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDefault) const
96 { 96 {
97 if (lpBuffer != NULL) 97 if (lpBuffer != NULL)
98 *lpBuffer = _T('\0'); 98 *lpBuffer = _T('\0');
99   99  
100 LPTSTR psz = __GetStringDynamic(lpSection, lpKey, lpDefault); 100 LPTSTR psz = __GetStringDynamic(lpSection, lpKey, lpDefault);
101 DWORD dwLen = _tcslen(psz); 101 DWORD dwLen = _tcslen(psz);
102   102  
103 if (lpBuffer != NULL) 103 if (lpBuffer != NULL)
104 { 104 {
105 _tcsncpy(lpBuffer, psz, dwBufSize); 105 _tcsncpy(lpBuffer, psz, dwBufSize);
106 dwLen = min(dwLen, dwBufSize); 106 dwLen = min(dwLen, dwBufSize);
107 } 107 }
108   108  
109 delete [] psz; 109 delete [] psz;
110 return dwLen; 110 return dwLen;
111 } 111 }
112   112  
113 #ifdef __AFXWIN_H__ 113 #ifdef __AFXWIN_H__
114 CString CIni::GetString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpDefault) const 114 CString CIni::GetString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpDefault) const
115 { 115 {
116 LPTSTR psz = __GetStringDynamic(lpSection, lpKey, lpDefault); 116 LPTSTR psz = __GetStringDynamic(lpSection, lpKey, lpDefault);
117 CString str(psz); 117 CString str(psz);
118 delete [] psz; 118 delete [] psz;
119 return str; 119 return str;
120 } 120 }
121 #endif 121 #endif
122   122  
123 // Write a string value to the ini file 123 // Write a string value to the ini file
124 BOOL CIni::WriteString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue) const 124 BOOL CIni::WriteString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue) const
125 { 125 {
126 if (lpSection == NULL || lpKey == NULL) 126 if (lpSection == NULL || lpKey == NULL)
127 return FALSE; 127 return FALSE;
128   128  
129 return ::WritePrivateProfileString(lpSection, lpKey, lpValue == NULL ? _T("") : lpValue, m_pszPathName); 129 return ::WritePrivateProfileString(lpSection, lpKey, lpValue == NULL ? _T("") : lpValue, m_pszPathName);
130 } 130 }
131   131  
132 // Read a string value from the ini file, append another string after it and then write it 132 // Read a string value from the ini file, append another string after it and then write it
133 // back to the ini file 133 // back to the ini file
134 BOOL CIni::AppendString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpString) const 134 BOOL CIni::AppendString(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpString) const
135 { 135 {
136 if (lpString == NULL) 136 if (lpString == NULL)
137 return FALSE; 137 return FALSE;
138   138  
139 TCHAR* psz = __GetStringDynamic(lpSection, lpKey); 139 TCHAR* psz = __GetStringDynamic(lpSection, lpKey);
140 TCHAR* pNewString = new TCHAR[_tcslen(psz) + _tcslen(lpString) + 1]; 140 TCHAR* pNewString = new TCHAR[_tcslen(psz) + _tcslen(lpString) + 1];
141 _stprintf(pNewString, _T("%s%s"), psz, lpString); 141 _stprintf(pNewString, _T("%s%s"), psz, lpString);
142 const BOOL RES = WriteString(lpSection, lpKey, pNewString); 142 const BOOL RES = WriteString(lpSection, lpKey, pNewString);
143 delete [] pNewString; 143 delete [] pNewString;
144 delete [] psz; 144 delete [] psz;
145 return RES; 145 return RES;
146 } 146 }
147   147  
148 ///////////////////////////////////////////////////////////////////////////////// 148 /////////////////////////////////////////////////////////////////////////////////
149 // Ini File String Array Access 149 // Ini File String Array Access
150 ///////////////////////////////////////////////////////////////////////////////// 150 /////////////////////////////////////////////////////////////////////////////////
151   151  
152 // Get an array of string 152 // Get an array of string
153 DWORD CIni::GetArray(LPCTSTR lpSection, LPCTSTR lpKey, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDelimiter, BOOL bTrimString) const 153 DWORD CIni::GetArray(LPCTSTR lpSection, LPCTSTR lpKey, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDelimiter, BOOL bTrimString) const
154 { 154 {
155 if (lpBuffer != NULL) 155 if (lpBuffer != NULL)
156 *lpBuffer = _T('\0'); 156 *lpBuffer = _T('\0');
157   157  
158 if (lpSection == NULL || lpKey == NULL) 158 if (lpSection == NULL || lpKey == NULL)
159 return 0; 159 return 0;
160   160  
161 LPTSTR psz = __GetStringDynamic(lpSection, lpKey); 161 LPTSTR psz = __GetStringDynamic(lpSection, lpKey);
162 162
163 DWORD dwCopied = 0; 163 DWORD dwCopied = 0;
164   164  
165 if (*psz != _T('\0')) 165 if (*psz != _T('\0'))
166 { 166 {
167 if (lpBuffer == NULL) 167 if (lpBuffer == NULL)
168 { 168 {
169 // just calculate the required buffer size 169 // just calculate the required buffer size
170 const DWORD MAX_LEN = _tcslen(psz) + 2; 170 const DWORD MAX_LEN = _tcslen(psz) + 2;
171 LPTSTR p = new TCHAR[MAX_LEN + 1]; 171 LPTSTR p = new TCHAR[MAX_LEN + 1];
172 dwCopied = __StringSplit(psz, p, MAX_LEN, lpDelimiter, bTrimString); 172 dwCopied = __StringSplit(psz, p, MAX_LEN, lpDelimiter, bTrimString);
173 delete [] p; 173 delete [] p;
174 } 174 }
175 else 175 else
176 { 176 {
177 dwCopied = __StringSplit(psz, lpBuffer, dwBufSize, lpDelimiter, bTrimString); 177 dwCopied = __StringSplit(psz, lpBuffer, dwBufSize, lpDelimiter, bTrimString);
178 } 178 }
179 } 179 }
180   180  
181 delete [] psz; 181 delete [] psz;
182 return dwCopied; 182 return dwCopied;
183 } 183 }
184   184  
185 #ifdef __AFXWIN_H__ 185 #ifdef __AFXWIN_H__
186 void CIni::GetArray(LPCTSTR lpSection, LPCTSTR lpKey, CStringArray *pArray, LPCTSTR lpDelimiter, BOOL bTrimString) const 186 void CIni::GetArray(LPCTSTR lpSection, LPCTSTR lpKey, CStringArray *pArray, LPCTSTR lpDelimiter, BOOL bTrimString) const
187 { 187 {
188 if (pArray != NULL) 188 if (pArray != NULL)
189 pArray->RemoveAll(); 189 pArray->RemoveAll();
190   190  
191 const DWORD LEN = GetArray(lpSection, lpKey, NULL, 0, lpDelimiter); 191 const DWORD LEN = GetArray(lpSection, lpKey, NULL, 0, lpDelimiter);
192 if (LEN == 0) 192 if (LEN == 0)
193 return; 193 return;
194   194  
195 LPTSTR psz = new TCHAR[LEN + 3]; 195 LPTSTR psz = new TCHAR[LEN + 3];
196 GetArray(lpSection, lpKey, psz, LEN + 2, lpDelimiter); 196 GetArray(lpSection, lpKey, psz, LEN + 2, lpDelimiter);
197 ParseDNTString(psz, __SubStrAdd, (LPVOID)pArray); 197 ParseDNTString(psz, __SubStrAdd, (LPVOID)pArray);
198 delete [] psz; 198 delete [] psz;
199 } 199 }
200 #endif 200 #endif
201   201  
202 #ifdef __AFXWIN_H__ 202 #ifdef __AFXWIN_H__
203 BOOL CIni::WriteArray(LPCTSTR lpSection, LPCTSTR lpKey, const CStringArray *pArray, int nWriteCount, LPCTSTR lpDelimiter) const 203 BOOL CIni::WriteArray(LPCTSTR lpSection, LPCTSTR lpKey, const CStringArray *pArray, int nWriteCount, LPCTSTR lpDelimiter) const
204 { 204 {
205 if (pArray == NULL) 205 if (pArray == NULL)
206 return FALSE; 206 return FALSE;
207   207  
208 if (nWriteCount < 0) 208 if (nWriteCount < 0)
209 nWriteCount = pArray->GetSize(); 209 nWriteCount = pArray->GetSize();
210 else 210 else
211 nWriteCount = min(nWriteCount, pArray->GetSize()); 211 nWriteCount = min(nWriteCount, pArray->GetSize());
212   212  
213 const CString DELIMITER = (lpDelimiter == NULL || *lpDelimiter == _T('\0')) ? _T(",") : lpDelimiter; 213 const CString DELIMITER = (lpDelimiter == NULL || *lpDelimiter == _T('\0')) ? _T(",") : lpDelimiter;
214 CString sLine; 214 CString sLine;
215 for (int i = 0; i < nWriteCount; i++) 215 for (int i = 0; i < nWriteCount; i++)
216 { 216 {
217 sLine += pArray->GetAt(i); 217 sLine += pArray->GetAt(i);
218 if (i != nWriteCount - 1) 218 if (i != nWriteCount - 1)
219 sLine += DELIMITER; 219 sLine += DELIMITER;
220 } 220 }
221 return WriteString(lpSection, lpKey, sLine); 221 return WriteString(lpSection, lpKey, sLine);
222 } 222 }
223 #endif 223 #endif
224   224  
225 ///////////////////////////////////////////////////////////////////////////////// 225 /////////////////////////////////////////////////////////////////////////////////
226 // Primitive Data Type Access 226 // Primitive Data Type Access
227 ///////////////////////////////////////////////////////////////////////////////// 227 /////////////////////////////////////////////////////////////////////////////////
228   228  
229 // Get a signed integral value 229 // Get a signed integral value
230 int CIni::GetInt(LPCTSTR lpSection, LPCTSTR lpKey, int nDefault, int nBase) const 230 int CIni::GetInt(LPCTSTR lpSection, LPCTSTR lpKey, int nDefault, int nBase) const
231 { 231 {
232 TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T(""); 232 TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T("");
233 GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN); 233 GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN);
234 return *sz == _T('\0') ? nDefault : int(_tcstoul(sz, NULL, __ValidateBase(nBase))); 234 return *sz == _T('\0') ? nDefault : int(_tcstoul(sz, NULL, __ValidateBase(nBase)));
235 } 235 }
236   236  
237 // Get an unsigned integral value 237 // Get an unsigned integral value
238 UINT CIni::GetUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nDefault, int nBase) const 238 UINT CIni::GetUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nDefault, int nBase) const
239 { 239 {
240 TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T(""); 240 TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T("");
241 GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN); 241 GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN);
242 return *sz == _T('\0') ? nDefault : UINT(_tcstoul(sz, NULL, __ValidateBase(nBase))); 242 return *sz == _T('\0') ? nDefault : UINT(_tcstoul(sz, NULL, __ValidateBase(nBase)));
243 } 243 }
244   244  
245 // Get a boolean value 245 // Get a boolean value
246 BOOL CIni::GetBool(LPCTSTR lpSection, LPCTSTR lpKey, BOOL bDefault) const 246 BOOL CIni::GetBool(LPCTSTR lpSection, LPCTSTR lpKey, BOOL bDefault) const
247 { 247 {
248 TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T(""); 248 TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T("");
249 GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN); 249 GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN);
250 return StringToBool(sz, bDefault); 250 return StringToBool(sz, bDefault);
251 } 251 }
252   252  
253 // Get a double floating value 253 // Get a double floating value
254 double CIni::GetDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fDefault) const 254 double CIni::GetDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fDefault) const
255 { 255 {
256 TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T(""); 256 TCHAR sz[DEF_PROFILE_NUM_LEN + 1] = _T("");
257 GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN); 257 GetString(lpSection, lpKey, sz, DEF_PROFILE_NUM_LEN);
258 return *sz == _T('\0') ? fDefault : _tcstod(sz, NULL); 258 return *sz == _T('\0') ? fDefault : _tcstod(sz, NULL);
259 } 259 }
260   260  
261 // Write a signed integral value to the ini file 261 // Write a signed integral value to the ini file
262 BOOL CIni::WriteInt(LPCTSTR lpSection, LPCTSTR lpKey, int nValue, int nBase) const 262 BOOL CIni::WriteInt(LPCTSTR lpSection, LPCTSTR lpKey, int nValue, int nBase) const
263 { 263 {
264 TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T(""); 264 TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T("");
265 __IntToString(nValue, szValue, nBase); 265 __IntToString(nValue, szValue, nBase);
266 return WriteString(lpSection, lpKey, szValue); 266 return WriteString(lpSection, lpKey, szValue);
267 } 267 }
268   268  
269 // Write an unsigned value to the ini file 269 // Write an unsigned value to the ini file
270 BOOL CIni::WriteUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nValue, int nBase) const 270 BOOL CIni::WriteUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nValue, int nBase) const
271 { 271 {
272 TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T(""); 272 TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T("");
273 __UIntToString(nValue, szValue, nBase); 273 __UIntToString(nValue, szValue, nBase);
274 return WriteString(lpSection, lpKey, szValue); 274 return WriteString(lpSection, lpKey, szValue);
275 } 275 }
276   276  
277 // Write a double floating value to the ini file 277 // Write a double floating value to the ini file
278 BOOL CIni::WriteDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fValue, int nPrecision) const 278 BOOL CIni::WriteDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fValue, int nPrecision) const
279 { 279 {
280 TCHAR szFmt[16] = _T("%f"); 280 TCHAR szFmt[16] = _T("%f");
281   281  
282 if (nPrecision > 0) 282 if (nPrecision > 0)
283 _stprintf(szFmt, _T("%%.%df"), nPrecision); 283 _stprintf(szFmt, _T("%%.%df"), nPrecision);
284   284  
285 TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T(""); 285 TCHAR szValue[DEF_PROFILE_NUM_LEN + 1] = _T("");
286 _stprintf(szValue, szFmt, fValue); 286 _stprintf(szValue, szFmt, fValue);
287 return WriteString(lpSection, lpKey, szValue); 287 return WriteString(lpSection, lpKey, szValue);
288 } 288 }
289   289  
290 // Read a double value from the ini file, increase it then write it back 290 // Read a double value from the ini file, increase it then write it back
291 BOOL CIni::IncreaseDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fIncrease, int nPrecision) const 291 BOOL CIni::IncreaseDouble(LPCTSTR lpSection, LPCTSTR lpKey, double fIncrease, int nPrecision) const
292 { 292 {
293 double f = GetDouble(lpSection, lpKey, 0.0); 293 double f = GetDouble(lpSection, lpKey, 0.0);
294 f += fIncrease; 294 f += fIncrease;
295 return WriteDouble(lpSection, lpKey, f, nPrecision); 295 return WriteDouble(lpSection, lpKey, f, nPrecision);
296 } 296 }
297   297  
298 // Write a boolean value to the ini file 298 // Write a boolean value to the ini file
299 BOOL CIni::WriteBool(LPCTSTR lpSection, LPCTSTR lpKey, BOOL bValue) const 299 BOOL CIni::WriteBool(LPCTSTR lpSection, LPCTSTR lpKey, BOOL bValue) const
300 { 300 {
301 return WriteInt(lpSection, lpKey, bValue ? 1 : 0, BASE_DECIMAL); 301 return WriteInt(lpSection, lpKey, bValue ? 1 : 0, BASE_DECIMAL);
302 } 302 }
303   303  
304 // Read a boolean value from the ini file, invert it(true becomes false, false becomes true), 304 // Read a boolean value from the ini file, invert it(true becomes false, false becomes true),
305 // then write it back 305 // then write it back
306 BOOL CIni::InvertBool(LPCTSTR lpSection, LPCTSTR lpKey) const 306 BOOL CIni::InvertBool(LPCTSTR lpSection, LPCTSTR lpKey) const
307 { 307 {
308 return WriteBool(lpSection, lpKey, !GetBool(lpSection, lpKey, FALSE)); 308 return WriteBool(lpSection, lpKey, !GetBool(lpSection, lpKey, FALSE));
309 } 309 }
310   310  
311 // Read a int from the ini file, increase it and then write it back to the ini file 311 // Read a int from the ini file, increase it and then write it back to the ini file
312 BOOL CIni::IncreaseInt(LPCTSTR lpSection, LPCTSTR lpKey, int nIncrease, int nBase) const 312 BOOL CIni::IncreaseInt(LPCTSTR lpSection, LPCTSTR lpKey, int nIncrease, int nBase) const
313 { 313 {
314 int nVal = GetInt(lpSection, lpKey, 0, nBase); 314 int nVal = GetInt(lpSection, lpKey, 0, nBase);
315 nVal += nIncrease; 315 nVal += nIncrease;
316 return WriteInt(lpSection, lpKey, nVal, nBase); 316 return WriteInt(lpSection, lpKey, nVal, nBase);
317 } 317 }
318   318  
319 // Read an UINT from the ini file, increase it and then write it back to the ini file 319 // Read an UINT from the ini file, increase it and then write it back to the ini file
320 BOOL CIni::IncreaseUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nIncrease, int nBase) const 320 BOOL CIni::IncreaseUInt(LPCTSTR lpSection, LPCTSTR lpKey, UINT nIncrease, int nBase) const
321 { 321 {
322 UINT nVal = GetUInt(lpSection, lpKey, 0, nBase); 322 UINT nVal = GetUInt(lpSection, lpKey, 0, nBase);
323 nVal += nIncrease; 323 nVal += nIncrease;
324 return WriteUInt(lpSection, lpKey, nVal, nBase); 324 return WriteUInt(lpSection, lpKey, nVal, nBase);
325 } 325 }
326   326  
327 TCHAR CIni::GetChar(LPCTSTR lpSection, LPCTSTR lpKey, TCHAR cDefault) const 327 TCHAR CIni::GetChar(LPCTSTR lpSection, LPCTSTR lpKey, TCHAR cDefault) const
328 { 328 {
329 TCHAR sz[2] = _T(""); 329 TCHAR sz[2] = _T("");
330 GetString(lpSection, lpKey, sz, 1); 330 GetString(lpSection, lpKey, sz, 1);
331 return *sz == _T('\0') ? cDefault : sz[0]; 331 return *sz == _T('\0') ? cDefault : sz[0];
332 } 332 }
333   333  
334 BOOL CIni::WriteChar(LPCTSTR lpSection, LPCTSTR lpKey, TCHAR c) const 334 BOOL CIni::WriteChar(LPCTSTR lpSection, LPCTSTR lpKey, TCHAR c) const
335 { 335 {
336 TCHAR sz[2] = { c, _T('\0') }; 336 TCHAR sz[2] = { c, _T('\0') };
337 return WriteString(lpSection, lpKey, sz); 337 return WriteString(lpSection, lpKey, sz);
338 } 338 }
339   339  
340 ///////////////////////////////////////////////////////////////////////////////// 340 /////////////////////////////////////////////////////////////////////////////////
341 // User-Defined Data Type Access 341 // User-Defined Data Type Access
342 ///////////////////////////////////////////////////////////////////////////////// 342 /////////////////////////////////////////////////////////////////////////////////
343   343  
344 // Get a block of raw data from the ini file 344 // Get a block of raw data from the ini file
345 DWORD CIni::GetDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPVOID lpBuffer, DWORD dwBufSize, DWORD dwOffset) const 345 DWORD CIni::GetDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPVOID lpBuffer, DWORD dwBufSize, DWORD dwOffset) const
346 { 346 {
347 LPTSTR psz = __GetStringDynamic(lpSection, lpKey); 347 LPTSTR psz = __GetStringDynamic(lpSection, lpKey);
348 DWORD dwLen = _tcslen(psz) / 2; 348 DWORD dwLen = _tcslen(psz) / 2;
349 if (dwLen <= dwOffset) 349 if (dwLen <= dwOffset)
350 { 350 {
351 delete [] psz; 351 delete [] psz;
352 return 0; 352 return 0;
353 } 353 }
354   354  
355 // verify psz, must be all in hex format 355 // verify psz, must be all in hex format
356 for (int i = 0; psz[i] != _T('\0'); i++) 356 for (int i = 0; psz[i] != _T('\0'); i++)
357 { 357 {
358 TCHAR c = psz[i]; 358 TCHAR c = psz[i];
359 if ((c >= _T('0') && c <= _T('9')) 359 if ((c >= _T('0') && c <= _T('9'))
360 || (c >= _T('a') && c <= _T('f')) 360 || (c >= _T('a') && c <= _T('f'))
361 || (c >= _T('A') && c <= _T('F'))) 361 || (c >= _T('A') && c <= _T('F')))
362 { 362 {
363 // valid 363 // valid
364 } 364 }
365 else 365 else
366 { 366 {
367 delete [] psz; 367 delete [] psz;
368 return 0; 368 return 0;
369 } 369 }
370 } 370 }
371   371  
372 DWORD dwProcLen = 0; 372 DWORD dwProcLen = 0;
373 LPBYTE lpb = (LPBYTE)lpBuffer; 373 LPBYTE lpb = (LPBYTE)lpBuffer;
374   374  
375 if (lpb != NULL) 375 if (lpb != NULL)
376 { 376 {
377 dwProcLen = min(dwLen - dwOffset, dwBufSize); 377 dwProcLen = min(dwLen - dwOffset, dwBufSize);
378 LPCTSTR p = &psz[dwOffset * 2]; 378 LPCTSTR p = &psz[dwOffset * 2];
379 for (DWORD i = 0; i < dwProcLen; i++) 379 for (DWORD i = 0; i < dwProcLen; i++)
380 { 380 {
381 TCHAR sz[3] = _T(""); 381 TCHAR sz[3] = _T("");
382 _tcsncpy(sz, p, 2); 382 _tcsncpy(sz, p, 2);
383 lpb[i] = BYTE(_tcstoul(sz, NULL, 16)); 383 lpb[i] = BYTE(_tcstoul(sz, NULL, 16));
384 p = &p[2]; 384 p = &p[2];
385 } 385 }
386 } 386 }
387 else 387 else
388 { 388 {
389 dwProcLen = dwLen - dwOffset; 389 dwProcLen = dwLen - dwOffset;
390 } 390 }
391 delete [] psz; 391 delete [] psz;
392 return dwProcLen; 392 return dwProcLen;
393 } 393 }
394   394  
395 // Write a block of raw data to the ini file 395 // Write a block of raw data to the ini file
396 BOOL CIni::WriteDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPCVOID lpData, DWORD dwDataSize) const 396 BOOL CIni::WriteDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPCVOID lpData, DWORD dwDataSize) const
397 { 397 {
398 const BYTE* lpb = (const BYTE*)lpData; 398 const BYTE* lpb = (const BYTE*)lpData;
399 if (lpb == NULL) 399 if (lpb == NULL)
400 return FALSE; 400 return FALSE;
401   401  
402 LPTSTR psz = new TCHAR[dwDataSize * 2 + 1]; 402 LPTSTR psz = new TCHAR[dwDataSize * 2 + 1];
403 for (DWORD i = 0, j = 0; i < dwDataSize; i++, j += 2) 403 for (DWORD i = 0, j = 0; i < dwDataSize; i++, j += 2)
404 _stprintf(&psz[j], _T("%02X"), lpb[i]); 404 _stprintf(&psz[j], _T("%02X"), lpb[i]);
405 const BOOL RES = WriteString(lpSection, lpKey, psz); 405 const BOOL RES = WriteString(lpSection, lpKey, psz);
406 delete [] psz; 406 delete [] psz;
407 return RES; 407 return RES;
408 } 408 }
409   409  
410 // Append a block of raw data to a specified key in the ini file 410 // Append a block of raw data to a specified key in the ini file
411 BOOL CIni::AppendDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPCVOID lpData, DWORD dwDataSize) const 411 BOOL CIni::AppendDataBlock(LPCTSTR lpSection, LPCTSTR lpKey, LPCVOID lpData, DWORD dwDataSize) const
412 { 412 {
413 const BYTE* lpb = (const BYTE*)lpData; 413 const BYTE* lpb = (const BYTE*)lpData;
414 if (lpb == NULL) 414 if (lpb == NULL)
415 return FALSE; 415 return FALSE;
416   416  
417 LPTSTR psz = new TCHAR[dwDataSize * 2 + 1]; 417 LPTSTR psz = new TCHAR[dwDataSize * 2 + 1];
418 for (DWORD i = 0, j = 0; i < dwDataSize; i++, j += 2) 418 for (DWORD i = 0, j = 0; i < dwDataSize; i++, j += 2)
419 _stprintf(&psz[j], _T("%02X"), lpb[i]); 419 _stprintf(&psz[j], _T("%02X"), lpb[i]);
420 const BOOL RES = AppendString(lpSection, lpKey, psz); 420 const BOOL RES = AppendString(lpSection, lpKey, psz);
421 delete [] psz; 421 delete [] psz;
422 return RES; 422 return RES;
423 } 423 }
424   424  
425 // Get a POINT value 425 // Get a POINT value
426 POINT CIni::GetPoint(LPCTSTR lpSection, LPCTSTR lpKey, POINT ptDefault) const 426 POINT CIni::GetPoint(LPCTSTR lpSection, LPCTSTR lpKey, POINT ptDefault) const
427 { 427 {
428 POINT pt; 428 POINT pt;
429 if (GetDataBlock(lpSection, lpKey, &pt, sizeof(POINT)) != sizeof(POINT)) 429 if (GetDataBlock(lpSection, lpKey, &pt, sizeof(POINT)) != sizeof(POINT))
430 pt = ptDefault; 430 pt = ptDefault;
431 return pt; 431 return pt;
432 } 432 }
433   433  
434 // Get a RECT value 434 // Get a RECT value
435 RECT CIni::GetRect(LPCTSTR lpSection, LPCTSTR lpKey, RECT rcDefault) const 435 RECT CIni::GetRect(LPCTSTR lpSection, LPCTSTR lpKey, RECT rcDefault) const
436 { 436 {
437 RECT rc; 437 RECT rc;
438 if (GetDataBlock(lpSection, lpKey, &rc, sizeof(RECT)) != sizeof(RECT)) 438 if (GetDataBlock(lpSection, lpKey, &rc, sizeof(RECT)) != sizeof(RECT))
439 rc = rcDefault; 439 rc = rcDefault;
440 return rc; 440 return rc;
441 } 441 }
442   442  
443 // Write a POINT to the ini file 443 // Write a POINT to the ini file
444 BOOL CIni::WritePoint(LPCTSTR lpSection, LPCTSTR lpKey, POINT pt) const 444 BOOL CIni::WritePoint(LPCTSTR lpSection, LPCTSTR lpKey, POINT pt) const
445 { 445 {
446 return WriteDataBlock(lpSection, lpKey, &pt, sizeof(POINT)); 446 return WriteDataBlock(lpSection, lpKey, &pt, sizeof(POINT));
447 } 447 }
448   448  
449 // Write a RECT to the ini file 449 // Write a RECT to the ini file
450 BOOL CIni::WriteRect(LPCTSTR lpSection, LPCTSTR lpKey, RECT rc) const 450 BOOL CIni::WriteRect(LPCTSTR lpSection, LPCTSTR lpKey, RECT rc) const
451 { 451 {
452 return WriteDataBlock(lpSection, lpKey, &rc, sizeof(RECT)); 452 return WriteDataBlock(lpSection, lpKey, &rc, sizeof(RECT));
453 } 453 }
454   454  
455 ///////////////////////////////////////////////////////////////////////////////// 455 /////////////////////////////////////////////////////////////////////////////////
456 // Sections & Keys Access 456 // Sections & Keys Access
457 ///////////////////////////////////////////////////////////////////////////////// 457 /////////////////////////////////////////////////////////////////////////////////
458   458  
459 // Retrieve a list of key-lines(key-pairs) of the specified section 459 // Retrieve a list of key-lines(key-pairs) of the specified section
460 DWORD CIni::GetKeyLines(LPCTSTR lpSection, LPTSTR lpBuffer, DWORD dwBufSize) const 460 DWORD CIni::GetKeyLines(LPCTSTR lpSection, LPTSTR lpBuffer, DWORD dwBufSize) const
461 { 461 {
462 if (lpBuffer != NULL) 462 if (lpBuffer != NULL)
463 *lpBuffer = _T('\0'); 463 *lpBuffer = _T('\0');
464   464  
465 if (lpSection == NULL) 465 if (lpSection == NULL)
466 return 0; 466 return 0;
467   467  
468 if (lpBuffer == NULL) 468 if (lpBuffer == NULL)
469 { 469 {
470 // just calculate the required buffer size 470 // just calculate the required buffer size
471 DWORD dwLen = DEF_PROFILE_THRESHOLD; 471 DWORD dwLen = DEF_PROFILE_THRESHOLD;
472 LPTSTR psz = new TCHAR[dwLen + 1]; 472 LPTSTR psz = new TCHAR[dwLen + 1];
473 DWORD dwCopied = ::GetPrivateProfileSection(lpSection, psz, dwLen, m_pszPathName); 473 DWORD dwCopied = ::GetPrivateProfileSection(lpSection, psz, dwLen, m_pszPathName);
474   474  
475 while (dwCopied + 2 >= dwLen) 475 while (dwCopied + 2 >= dwLen)
476 { 476 {
477 dwLen += DEF_PROFILE_THRESHOLD; 477 dwLen += DEF_PROFILE_THRESHOLD;
478 delete [] psz; 478 delete [] psz;
479 psz = new TCHAR[dwLen + 1]; 479 psz = new TCHAR[dwLen + 1];
480 dwCopied = ::GetPrivateProfileSection(lpSection, psz, dwLen, m_pszPathName); 480 dwCopied = ::GetPrivateProfileSection(lpSection, psz, dwLen, m_pszPathName);
481 } 481 }
482   482  
483 delete [] psz; 483 delete [] psz;
484 return dwCopied + 2; 484 return dwCopied + 2;
485 } 485 }
486 else 486 else
487 { 487 {
488 return ::GetPrivateProfileSection(lpSection, lpBuffer, dwBufSize, m_pszPathName); 488 return ::GetPrivateProfileSection(lpSection, lpBuffer, dwBufSize, m_pszPathName);
489 } 489 }
490 } 490 }
491   491  
492 // Retrieve a list of key names of the specified section 492 // Retrieve a list of key names of the specified section
493 DWORD CIni::GetKeyNames(LPCTSTR lpSection, LPTSTR lpBuffer, DWORD dwBufSize) const 493 DWORD CIni::GetKeyNames(LPCTSTR lpSection, LPTSTR lpBuffer, DWORD dwBufSize) const
494 { 494 {
495 if (lpBuffer != NULL) 495 if (lpBuffer != NULL)
496 *lpBuffer = _T('\0'); 496 *lpBuffer = _T('\0');
497   497  
498 if (lpSection == NULL) 498 if (lpSection == NULL)
499 return 0; 499 return 0;
500   500  
501 STR_LIMIT sl; 501 STR_LIMIT sl;
502 sl.lpTarget = lpBuffer; 502 sl.lpTarget = lpBuffer;
503 sl.dwRemain = dwBufSize; 503 sl.dwRemain = dwBufSize;
504 sl.dwTotalCopied = 0; 504 sl.dwTotalCopied = 0;
505   505  
506 const DWORD LEN = GetKeyLines(lpSection, NULL, 0); 506 const DWORD LEN = GetKeyLines(lpSection, NULL, 0);
507 if (LEN == 0) 507 if (LEN == 0)
508 return 0; 508 return 0;
509   509  
510 LPTSTR psz = new TCHAR[LEN + 1]; 510 LPTSTR psz = new TCHAR[LEN + 1];
511 GetKeyLines(lpSection, psz, LEN); 511 GetKeyLines(lpSection, psz, LEN);
512 ParseDNTString(psz, __KeyPairProc, (LPVOID)(&sl)); 512 ParseDNTString(psz, __KeyPairProc, (LPVOID)(&sl));
513 delete [] psz; 513 delete [] psz;
514 if (lpBuffer != NULL) 514 if (lpBuffer != NULL)
515 lpBuffer[sl.dwTotalCopied] = _T('\0'); 515 lpBuffer[sl.dwTotalCopied] = _T('\0');
516 return sl.dwTotalCopied; 516 return sl.dwTotalCopied;
517 } 517 }
518   518  
519 // Get all section names from an ini file 519 // Get all section names from an ini file
520 DWORD CIni::GetSectionNames(LPTSTR lpBuffer, DWORD dwBufSize) const 520 DWORD CIni::GetSectionNames(LPTSTR lpBuffer, DWORD dwBufSize) const
521 { 521 {
522 if (lpBuffer == NULL) 522 if (lpBuffer == NULL)
523 { 523 {
524 // just calculate the required buffer size 524 // just calculate the required buffer size
525 DWORD dwLen = DEF_PROFILE_THRESHOLD; 525 DWORD dwLen = DEF_PROFILE_THRESHOLD;
526 LPTSTR psz = new TCHAR[dwLen + 1]; 526 LPTSTR psz = new TCHAR[dwLen + 1];
527 DWORD dwCopied = ::GetPrivateProfileSectionNames(psz, dwLen, m_pszPathName); 527 DWORD dwCopied = ::GetPrivateProfileSectionNames(psz, dwLen, m_pszPathName);
528 while (dwCopied + 2 >= dwLen) 528 while (dwCopied + 2 >= dwLen)
529 { 529 {
530 dwLen += DEF_PROFILE_THRESHOLD; 530 dwLen += DEF_PROFILE_THRESHOLD;
531 delete [] psz; 531 delete [] psz;
532 psz = new TCHAR[dwLen + 1]; 532 psz = new TCHAR[dwLen + 1];
533 dwCopied = ::GetPrivateProfileSectionNames(psz, dwLen, m_pszPathName); 533 dwCopied = ::GetPrivateProfileSectionNames(psz, dwLen, m_pszPathName);
534 } 534 }
535 535
536 delete [] psz; 536 delete [] psz;
537 return dwCopied + 2; 537 return dwCopied + 2;
538 } 538 }
539 else 539 else
540 { 540 {
541 return ::GetPrivateProfileSectionNames(lpBuffer, dwBufSize, m_pszPathName); 541 return ::GetPrivateProfileSectionNames(lpBuffer, dwBufSize, m_pszPathName);
542 } 542 }
543 } 543 }
544   544  
545 #ifdef __AFXWIN_H__ 545 #ifdef __AFXWIN_H__
546 void CIni::GetSectionNames(CStringArray *pArray) const 546 void CIni::GetSectionNames(CStringArray *pArray) const
547 { 547 {
548 if (pArray != NULL) 548 if (pArray != NULL)
549 pArray->RemoveAll(); 549 pArray->RemoveAll();
550   550  
551 const DWORD LEN = GetSectionNames(NULL, 0); 551 const DWORD LEN = GetSectionNames(NULL, 0);
552 if (LEN == 0) 552 if (LEN == 0)
553 return; 553 return;
554   554  
555 LPTSTR psz = new TCHAR[LEN + 1]; 555 LPTSTR psz = new TCHAR[LEN + 1];
556 GetSectionNames(psz, LEN); 556 GetSectionNames(psz, LEN);
557 ParseDNTString(psz, __SubStrAdd, pArray); 557 ParseDNTString(psz, __SubStrAdd, pArray);
558 delete [] psz; 558 delete [] psz;
559 } 559 }
560 #endif 560 #endif
561   561  
562 #ifdef __AFXWIN_H__ 562 #ifdef __AFXWIN_H__
563 // Retrieve a list of key-lines(key-pairs) of the specified section 563 // Retrieve a list of key-lines(key-pairs) of the specified section
564 void CIni::GetKeyLines(LPCTSTR lpSection, CStringArray *pArray) const 564 void CIni::GetKeyLines(LPCTSTR lpSection, CStringArray *pArray) const
565 { 565 {
566 if (pArray != NULL) 566 if (pArray != NULL)
567 pArray->RemoveAll(); 567 pArray->RemoveAll();
568   568  
569 const DWORD LEN = GetKeyLines(lpSection, NULL, 0); 569 const DWORD LEN = GetKeyLines(lpSection, NULL, 0);
570 if (LEN == 0) 570 if (LEN == 0)
571 return; 571 return;
572   572  
573 LPTSTR psz = new TCHAR[LEN + 1]; 573 LPTSTR psz = new TCHAR[LEN + 1];
574 GetKeyLines(lpSection, psz, LEN); 574 GetKeyLines(lpSection, psz, LEN);
575 ParseDNTString(psz, __SubStrAdd, pArray); 575 ParseDNTString(psz, __SubStrAdd, pArray);
576 delete [] psz; 576 delete [] psz;
577 } 577 }
578 #endif 578 #endif
579   579  
580 #ifdef __AFXWIN_H__ 580 #ifdef __AFXWIN_H__
581 // Retrieve a list of key names of the specified section 581 // Retrieve a list of key names of the specified section
582 void CIni::GetKeyNames(LPCTSTR lpSection, CStringArray *pArray) const 582 void CIni::GetKeyNames(LPCTSTR lpSection, CStringArray *pArray) const
583 { 583 {
584 if (pArray == NULL) 584 if (pArray == NULL)
585 return; 585 return;
586   586  
587 pArray->RemoveAll(); 587 pArray->RemoveAll();
588 #ifndef _VS_USED 588 #ifndef _VS_USED
589 const int LEN = GetKeyNames(lpSection, NULL, 0); 589 const int LEN = GetKeyNames(lpSection, NULL, 0);
590 #else 590 #else
591 const LEN = GetKeyNames(lpSection, NULL, 0); 591 const LEN = GetKeyNames(lpSection, NULL, 0);
592 #endif 592 #endif
593 LPTSTR psz = new TCHAR[LEN + 1]; 593 LPTSTR psz = new TCHAR[LEN + 1];
594 GetKeyNames(lpSection, psz, LEN); 594 GetKeyNames(lpSection, psz, LEN);
595 ParseDNTString(psz, __SubStrAdd, (LPVOID)pArray); 595 ParseDNTString(psz, __SubStrAdd, (LPVOID)pArray);
596 delete [] psz; 596 delete [] psz;
597 } 597 }
598 #endif 598 #endif
599   599  
600 // Remove whole section from the ini file 600 // Remove whole section from the ini file
601 BOOL CIni::DeleteSection(LPCTSTR lpSection) const 601 BOOL CIni::DeleteSection(LPCTSTR lpSection) const
602 { 602 {
603 return ::WritePrivateProfileString(lpSection, NULL, _T(""), m_pszPathName); 603 return ::WritePrivateProfileString(lpSection, NULL, _T(""), m_pszPathName);
604 } 604 }
605   605  
606 // Remove a key from a section 606 // Remove a key from a section
607 BOOL CIni::DeleteKey(LPCTSTR lpSection, LPCTSTR lpKey) const 607 BOOL CIni::DeleteKey(LPCTSTR lpSection, LPCTSTR lpKey) const
608 { 608 {
609 return ::WritePrivateProfileString(lpSection, lpKey, NULL, m_pszPathName); 609 return ::WritePrivateProfileString(lpSection, lpKey, NULL, m_pszPathName);
610 } 610 }
611   611  
612 BOOL CIni::IsSectionExist(LPCTSTR lpSection) const 612 BOOL CIni::IsSectionExist(LPCTSTR lpSection) const
613 { 613 {
614 if (lpSection == NULL) 614 if (lpSection == NULL)
615 return FALSE; 615 return FALSE;
616   616  
617 // first get the section name list, then check if lpSection exists 617 // first get the section name list, then check if lpSection exists
618 // in the list. 618 // in the list.
619 const DWORD LEN = GetSectionNames(NULL, 0); 619 const DWORD LEN = GetSectionNames(NULL, 0);
620 if (LEN == 0) 620 if (LEN == 0)
621 return FALSE; 621 return FALSE;
622   622  
623 LPTSTR psz = new TCHAR[LEN + 1]; 623 LPTSTR psz = new TCHAR[LEN + 1];
624 GetSectionNames(psz, LEN); 624 GetSectionNames(psz, LEN);
625 BOOL RES = !ParseDNTString(psz, __SubStrCompare, (LPVOID)lpSection); 625 BOOL RES = !ParseDNTString(psz, __SubStrCompare, (LPVOID)lpSection);
626 delete [] psz; 626 delete [] psz;
627 return RES; 627 return RES;
628 } 628 }
629   629  
630 BOOL CIni::IsKeyExist(LPCTSTR lpSection, LPCTSTR lpKey) const 630 BOOL CIni::IsKeyExist(LPCTSTR lpSection, LPCTSTR lpKey) const
631 { 631 {
632 if (lpSection == NULL || lpKey == NULL) 632 if (lpSection == NULL || lpKey == NULL)
633 return FALSE; 633 return FALSE;
634   634  
635 // Test it with the default unique string 635 // Test it with the default unique string
636 LPTSTR psz = __GetStringDynamic(lpSection, lpKey, DEF_PROFILE_TESTSTRING); 636 LPTSTR psz = __GetStringDynamic(lpSection, lpKey, DEF_PROFILE_TESTSTRING);
637 const BOOL RES = (_tcscmp(psz, DEF_PROFILE_TESTSTRING) != 0); 637 const BOOL RES = (_tcscmp(psz, DEF_PROFILE_TESTSTRING) != 0);
638 delete [] psz; 638 delete [] psz;
639 return RES; 639 return RES;
640 } 640 }
641   641  
642 BOOL CIni::CopySection(LPCTSTR lpSrcSection, LPCTSTR lpDestSection, BOOL bFailIfExist) const 642 BOOL CIni::CopySection(LPCTSTR lpSrcSection, LPCTSTR lpDestSection, BOOL bFailIfExist) const
643 { 643 {
644 if (lpSrcSection == NULL || lpDestSection == NULL) 644 if (lpSrcSection == NULL || lpDestSection == NULL)
645 return FALSE; 645 return FALSE;
646   646  
647 if (_tcsicmp(lpSrcSection, lpDestSection) == 0) 647 if (_tcsicmp(lpSrcSection, lpDestSection) == 0)
648 return FALSE; 648 return FALSE;
649   649  
650 if (!IsSectionExist(lpSrcSection)) 650 if (!IsSectionExist(lpSrcSection))
651 return FALSE; 651 return FALSE;
652   652  
653 if (bFailIfExist && IsSectionExist(lpDestSection)) 653 if (bFailIfExist && IsSectionExist(lpDestSection))
654 return FALSE; 654 return FALSE;
655   655  
656 DeleteSection(lpDestSection); 656 DeleteSection(lpDestSection);
657   657  
658 const DWORD SRC_LEN = GetKeyLines(lpSrcSection, NULL, 0); 658 const DWORD SRC_LEN = GetKeyLines(lpSrcSection, NULL, 0);
659 LPTSTR psz = new TCHAR[SRC_LEN + 2]; 659 LPTSTR psz = new TCHAR[SRC_LEN + 2];
660 //memset(psz, 0, sizeof(TCHAR) * (SRC_LEN + 2)); 660 //memset(psz, 0, sizeof(TCHAR) * (SRC_LEN + 2));
661 GetKeyLines(lpSrcSection, psz, SRC_LEN); 661 GetKeyLines(lpSrcSection, psz, SRC_LEN);
662 const BOOL RES = ::WritePrivateProfileSection(lpDestSection, psz, m_pszPathName); 662 const BOOL RES = ::WritePrivateProfileSection(lpDestSection, psz, m_pszPathName);
663 delete [] psz; 663 delete [] psz;
664   664  
665 return RES; 665 return RES;
666 } 666 }
667   667  
668 BOOL CIni::CopyKey(LPCTSTR lpSrcSection, LPCTSTR lpSrcKey, LPCTSTR lpDestSection, LPCTSTR lpDestKey, BOOL bFailIfExist) const 668 BOOL CIni::CopyKey(LPCTSTR lpSrcSection, LPCTSTR lpSrcKey, LPCTSTR lpDestSection, LPCTSTR lpDestKey, BOOL bFailIfExist) const
669 { 669 {
670 if (lpSrcSection == NULL || lpSrcKey == NULL || lpDestKey == NULL) 670 if (lpSrcSection == NULL || lpSrcKey == NULL || lpDestKey == NULL)
671 return FALSE; 671 return FALSE;
672   672  
673 if (_tcsicmp(lpSrcSection, lpDestSection) == 0 673 if (_tcsicmp(lpSrcSection, lpDestSection) == 0
674 && _tcsicmp(lpSrcKey, lpDestKey) == 0) 674 && _tcsicmp(lpSrcKey, lpDestKey) == 0)
675 return FALSE; 675 return FALSE;
676   676  
677 if (!IsKeyExist(lpSrcSection, lpSrcKey)) 677 if (!IsKeyExist(lpSrcSection, lpSrcKey))
678 return FALSE; 678 return FALSE;
679   679  
680 if (bFailIfExist && IsKeyExist(lpDestSection, lpDestKey)) 680 if (bFailIfExist && IsKeyExist(lpDestSection, lpDestKey))
681 return FALSE; 681 return FALSE;
682 682
683 LPTSTR psz = __GetStringDynamic(lpSrcSection, lpSrcKey); 683 LPTSTR psz = __GetStringDynamic(lpSrcSection, lpSrcKey);
684 const BOOL RES = WriteString(lpDestSection, lpDestKey, psz); 684 const BOOL RES = WriteString(lpDestSection, lpDestKey, psz);
685 delete [] psz; 685 delete [] psz;
686 return RES; 686 return RES;
687 } 687 }
688   688  
689 BOOL CIni::MoveSection(LPCTSTR lpSrcSection, LPCTSTR lpDestSection, BOOL bFailIfExist) const 689 BOOL CIni::MoveSection(LPCTSTR lpSrcSection, LPCTSTR lpDestSection, BOOL bFailIfExist) const
690 { 690 {
691 return CopySection(lpSrcSection, lpDestSection, bFailIfExist) 691 return CopySection(lpSrcSection, lpDestSection, bFailIfExist)
692 && DeleteSection(lpSrcSection); 692 && DeleteSection(lpSrcSection);
693 } 693 }
694   694  
695 BOOL CIni::MoveKey(LPCTSTR lpSrcSection, LPCTSTR lpSrcKey, LPCTSTR lpDestSection, LPCTSTR lpDestKey, BOOL bFailIfExist) const 695 BOOL CIni::MoveKey(LPCTSTR lpSrcSection, LPCTSTR lpSrcKey, LPCTSTR lpDestSection, LPCTSTR lpDestKey, BOOL bFailIfExist) const
696 { 696 {
697 return CopyKey(lpSrcSection, lpSrcKey, lpDestSection, lpDestKey, bFailIfExist) 697 return CopyKey(lpSrcSection, lpSrcKey, lpDestSection, lpDestKey, bFailIfExist)
698 && DeleteKey(lpSrcSection, lpSrcKey); 698 && DeleteKey(lpSrcSection, lpSrcKey);
699 } 699 }
700   700  
701 ///////////////////////////////////////////////////////////////////////////////// 701 /////////////////////////////////////////////////////////////////////////////////
702 // Helper Functions 702 // Helper Functions
703 ///////////////////////////////////////////////////////////////////////////////// 703 /////////////////////////////////////////////////////////////////////////////////
704   704  
705 // Get a profile string value, return a heap pointer so we do not have to worry 705 // Get a profile string value, return a heap pointer so we do not have to worry
706 // about the buffer size, however, this function requires the caller to manually 706 // about the buffer size, however, this function requires the caller to manually
707 // free the memory. 707 // free the memory.
708 // This function is the back-bone of all "Getxxx" functions of this class. 708 // This function is the back-bone of all "Getxxx" functions of this class.
709 LPTSTR CIni::__GetStringDynamic(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpDefault) const 709 LPTSTR CIni::__GetStringDynamic(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpDefault) const
710 { 710 {
711 TCHAR* psz = NULL; 711 TCHAR* psz = NULL;
712 if (lpSection == NULL || lpKey == NULL) 712 if (lpSection == NULL || lpKey == NULL)
713 { 713 {
714 // Invalid section or key name, just return the default string 714 // Invalid section or key name, just return the default string
715 if (lpDefault == NULL) 715 if (lpDefault == NULL)
716 { 716 {
717 // Empty string 717 // Empty string
718 psz = new TCHAR[1]; 718 psz = new TCHAR[1];
719 *psz = _T('\0'); 719 *psz = _T('\0');
720 } 720 }
721 else 721 else
722 { 722 {
723 psz = new TCHAR[_tcslen(lpDefault) + 1]; 723 psz = new TCHAR[_tcslen(lpDefault) + 1];
724 _tcscpy(psz, lpDefault); 724 _tcscpy(psz, lpDefault);
725 } 725 }
726 726
727 return psz; 727 return psz;
728 } 728 }
729 729
730 // Keep enlarging the buffer size until being certain on that the string we 730 // Keep enlarging the buffer size until being certain on that the string we
731 // retrieved was original(not truncated). 731 // retrieved was original(not truncated).
732 DWORD dwLen = DEF_PROFILE_THRESHOLD; 732 DWORD dwLen = DEF_PROFILE_THRESHOLD;
733 psz = new TCHAR[dwLen + 1]; 733 psz = new TCHAR[dwLen + 1];
734 DWORD dwCopied = ::GetPrivateProfileString(lpSection, lpKey, lpDefault == NULL ? _T("") : lpDefault, psz, dwLen, m_pszPathName); 734 DWORD dwCopied = ::GetPrivateProfileString(lpSection, lpKey, lpDefault == NULL ? _T("") : lpDefault, psz, dwLen, m_pszPathName);
735 while (dwCopied + 1 >= dwLen) 735 while (dwCopied + 1 >= dwLen)
736 { 736 {
737 dwLen += DEF_PROFILE_THRESHOLD; 737 dwLen += DEF_PROFILE_THRESHOLD;
738 delete [] psz; 738 delete [] psz;
739 psz = new TCHAR[dwLen + 1]; 739 psz = new TCHAR[dwLen + 1];
740 dwCopied = ::GetPrivateProfileString(lpSection, lpKey, lpDefault == NULL ? _T("") : lpDefault, psz, dwLen, m_pszPathName); 740 dwCopied = ::GetPrivateProfileString(lpSection, lpKey, lpDefault == NULL ? _T("") : lpDefault, psz, dwLen, m_pszPathName);
741 } 741 }
742 742
743 return psz; // !!! Requires the caller to free this memory !!! 743 return psz; // !!! Requires the caller to free this memory !!!
744 } 744 }
745   745  
746 // Split a string usinf a particular delimiter, split result are copied into lpBuffer 746 // Split a string usinf a particular delimiter, split result are copied into lpBuffer
747 // in the "double null terminated string" format as the following figure shows: 747 // in the "double null terminated string" format as the following figure shows:
748 // xxx\0xxxx\0xx\0xxx\0\0 748 // xxx\0xxxx\0xx\0xxx\0\0
749 // 749 //
750 // For example, if the delimiter is ",", then string "ab,cd,e" will be 750 // For example, if the delimiter is ",", then string "ab,cd,e" will be
751 // splitted into "ab\0cd\0e\0\0", this string format can be parsed into an array 751 // splitted into "ab\0cd\0e\0\0", this string format can be parsed into an array
752 // of sub strings easily using user defined functions or CIni::ParseStringArray. 752 // of sub strings easily using user defined functions or CIni::ParseStringArray.
753 DWORD CIni::__StringSplit(LPCTSTR lpString, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDelimiter, BOOL bTrimString) 753 DWORD CIni::__StringSplit(LPCTSTR lpString, LPTSTR lpBuffer, DWORD dwBufSize, LPCTSTR lpDelimiter, BOOL bTrimString)
754 { 754 {
755 if (lpString == NULL || lpBuffer == NULL || dwBufSize == 0) 755 if (lpString == NULL || lpBuffer == NULL || dwBufSize == 0)
756 return 0; 756 return 0;
757   757  
758 DWORD dwCopied = 0; 758 DWORD dwCopied = 0;
759 *lpBuffer = _T('\0'); 759 *lpBuffer = _T('\0');
760 if (*lpString == _T('\0')) 760 if (*lpString == _T('\0'))
761 return 0; 761 return 0;
762   762  
763 // If lpDelimiter is NULL, use the default delimiter ",", if delimiter length 763 // If lpDelimiter is NULL, use the default delimiter ",", if delimiter length
764 // is 0, then return whole string 764 // is 0, then return whole string
765 if (lpDelimiter != NULL && *lpDelimiter == _T('\0')) 765 if (lpDelimiter != NULL && *lpDelimiter == _T('\0'))
766 { 766 {
767 _tcsncpy(lpBuffer, lpString, dwBufSize - 1); 767 _tcsncpy(lpBuffer, lpString, dwBufSize - 1);
768 return _tcslen(lpBuffer); 768 return _tcslen(lpBuffer);
769 } 769 }
770   770  
771 LPTSTR pszDel = (lpDelimiter == NULL) ? _tcsdup(DEF_PROFILE_DELIMITER) : _tcsdup(lpDelimiter); 771 LPTSTR pszDel = (lpDelimiter == NULL) ? _tcsdup(DEF_PROFILE_DELIMITER) : _tcsdup(lpDelimiter);
772 const DWORD DEL_LEN = _tcslen(pszDel); 772 const DWORD DEL_LEN = _tcslen(pszDel);
773 LPTSTR lpTarget = lpBuffer; 773 LPTSTR lpTarget = lpBuffer;
774   774  
775 // Search through lpString for delimiter matches, and extract sub strings out 775 // Search through lpString for delimiter matches, and extract sub strings out
776 LPCTSTR lpPos = lpString; 776 LPCTSTR lpPos = lpString;
777 LPCTSTR lpEnd = _tcsstr(lpPos, pszDel); 777 LPCTSTR lpEnd = _tcsstr(lpPos, pszDel);
778   778  
779 while (lpEnd != NULL) 779 while (lpEnd != NULL)
780 { 780 {
781 LPTSTR pszSeg = __StrDupEx(lpPos, lpEnd); 781 LPTSTR pszSeg = __StrDupEx(lpPos, lpEnd);
782 if (bTrimString) 782 if (bTrimString)
783 __TrimString(pszSeg); 783 __TrimString(pszSeg);
784   784  
785 const DWORD SEG_LEN = _tcslen(pszSeg); 785 const DWORD SEG_LEN = _tcslen(pszSeg);
786 const DWORD COPY_LEN = min(SEG_LEN, dwBufSize - dwCopied); 786 const DWORD COPY_LEN = min(SEG_LEN, dwBufSize - dwCopied);
787   787  
788 // Need to avoid buffer overflow 788 // Need to avoid buffer overflow
789 if (COPY_LEN > 0) 789 if (COPY_LEN > 0)
790 { 790 {
791 dwCopied += COPY_LEN + 1; 791 dwCopied += COPY_LEN + 1;
792 _tcsncpy(lpTarget, pszSeg, COPY_LEN); 792 _tcsncpy(lpTarget, pszSeg, COPY_LEN);
793 lpTarget[COPY_LEN] = _T('\0'); 793 lpTarget[COPY_LEN] = _T('\0');
794 lpTarget = &lpTarget[SEG_LEN + 1]; 794 lpTarget = &lpTarget[SEG_LEN + 1];
795 } 795 }
796 delete [] pszSeg; 796 delete [] pszSeg;
797 lpPos = &lpEnd[DEL_LEN]; // Advance the pointer for next search 797 lpPos = &lpEnd[DEL_LEN]; // Advance the pointer for next search
798 lpEnd = _tcsstr(lpPos, pszDel); 798 lpEnd = _tcsstr(lpPos, pszDel);
799 } 799 }
800   800  
801 // The last part of string, there may not be the trailing delimiter, so we 801 // The last part of string, there may not be the trailing delimiter, so we
802 // need to take care of this part, too 802 // need to take care of this part, too
803 LPTSTR pszSeg = _tcsdup(lpPos); 803 LPTSTR pszSeg = _tcsdup(lpPos);
804 if (bTrimString) 804 if (bTrimString)
805 __TrimString(pszSeg); 805 __TrimString(pszSeg);
806   806  
807 const DWORD SEG_LEN = _tcslen(pszSeg); 807 const DWORD SEG_LEN = _tcslen(pszSeg);
808 const DWORD COPY_LEN = min(SEG_LEN, dwBufSize - dwCopied); 808 const DWORD COPY_LEN = min(SEG_LEN, dwBufSize - dwCopied);
809   809  
810 if (COPY_LEN > 0) 810 if (COPY_LEN > 0)
811 { 811 {
812 dwCopied += COPY_LEN + 1; 812 dwCopied += COPY_LEN + 1;
813 _tcsncpy(lpTarget, pszSeg, COPY_LEN); 813 _tcsncpy(lpTarget, pszSeg, COPY_LEN);
814 lpTarget[COPY_LEN] = _T('\0'); 814 lpTarget[COPY_LEN] = _T('\0');
815 } 815 }
816   816  
817 delete [] pszSeg; 817 delete [] pszSeg;
818 lpBuffer[dwCopied] = _T('\0'); 818 lpBuffer[dwCopied] = _T('\0');
819 delete [] pszDel; 819 delete [] pszDel;
820 return dwCopied; 820 return dwCopied;
821 } 821 }
822   822  
823 // Parse a "double null terminated string", pass each sub string to a user-defined 823 // Parse a "double null terminated string", pass each sub string to a user-defined
824 // callback function 824 // callback function
825 BOOL CIni::ParseDNTString(LPCTSTR lpString, SUBSTRPROC lpFnStrProc, LPVOID lpParam) 825 BOOL CIni::ParseDNTString(LPCTSTR lpString, SUBSTRPROC lpFnStrProc, LPVOID lpParam)
826 { 826 {
827 if (lpString == NULL || lpFnStrProc == NULL) 827 if (lpString == NULL || lpFnStrProc == NULL)
828 return FALSE; 828 return FALSE;
829   829  
830 LPCTSTR p = lpString; 830 LPCTSTR p = lpString;
831 DWORD dwLen = _tcslen(p); 831 DWORD dwLen = _tcslen(p);
832   832  
833 while (dwLen > 0) 833 while (dwLen > 0)
834 { 834 {
835 if (!lpFnStrProc(p, lpParam)) 835 if (!lpFnStrProc(p, lpParam))
836 return FALSE; 836 return FALSE;
837   837  
838 p = &p[dwLen + 1]; 838 p = &p[dwLen + 1];
839 dwLen = _tcslen(p); 839 dwLen = _tcslen(p);
840 } 840 }
841 return TRUE; 841 return TRUE;
842 } 842 }
843   843  
844 // Callback function used to compare elements inside of a 844 // Callback function used to compare elements inside of a
845 // "double null terminated string" with a given string. Useful for 845 // "double null terminated string" with a given string. Useful for
846 // searching in the section names list. 846 // searching in the section names list.
847 BOOL CALLBACK CIni::__SubStrCompare(LPCTSTR lpString1, LPVOID lpParam) 847 BOOL CALLBACK CIni::__SubStrCompare(LPCTSTR lpString1, LPVOID lpParam)
848 { 848 {
849 assert(lpString1 != NULL); 849 assert(lpString1 != NULL);
850 LPCTSTR lpString2 = (LPCTSTR)lpParam; 850 LPCTSTR lpString2 = (LPCTSTR)lpParam;
851 assert(lpString2 != NULL); 851 assert(lpString2 != NULL);
852 // if two string matches, return zero to stop the parsing 852 // if two string matches, return zero to stop the parsing
853 return _tcsicmp(lpString1, lpString2) != 0; 853 return _tcsicmp(lpString1, lpString2) != 0;
854 } 854 }
855   855  
856 // Callback function used to process a key-pair, it extracts the 856 // Callback function used to process a key-pair, it extracts the
857 // key name from the key-pair string 857 // key name from the key-pair string
858 BOOL CALLBACK CIni:: __KeyPairProc(LPCTSTR lpString, LPVOID lpParam) 858 BOOL CALLBACK CIni:: __KeyPairProc(LPCTSTR lpString, LPVOID lpParam)
859 { 859 {
860 STR_LIMIT* psl = (STR_LIMIT*)lpParam; 860 STR_LIMIT* psl = (STR_LIMIT*)lpParam;
861 if (lpString == NULL || psl== NULL) 861 if (lpString == NULL || psl== NULL)
862 return FALSE; 862 return FALSE;
863 863
864 LPCTSTR p = _tcschr(lpString, _T('=')); 864 LPCTSTR p = _tcschr(lpString, _T('='));
865 if (p == NULL || p == lpString) 865 if (p == NULL || p == lpString)
866 return TRUE; 866 return TRUE;
867 867
868 // extract the sub-string on left side of the '=' 868 // extract the sub-string on left side of the '='
869 LPTSTR psz = new TCHAR[_tcslen(lpString) + 1]; 869 LPTSTR psz = new TCHAR[_tcslen(lpString) + 1];
870   870  
871 //#ifndef _VS6_USED 871 #ifndef _VS6_USED
872 int i; 872 int i;
873 //#endif 873 #endif
874   874  
875 for (int i = 0; &lpString[i] < p; i++) 875 for (int i = 0; &lpString[i] < p; i++)
876 psz[i] = lpString[i]; 876 psz[i] = lpString[i];
877 psz[i] = _T('\0'); 877 psz[i] = _T('\0');
878   878  
879 // trim 879 // trim
880 __TrimString(psz); 880 __TrimString(psz);
881 DWORD dwNameLen = _tcslen(psz); 881 DWORD dwNameLen = _tcslen(psz);
882 DWORD dwCopyLen = 0; 882 DWORD dwCopyLen = 0;
883 883
884 //copy to the buffer 884 //copy to the buffer
885 if (psl->lpTarget != NULL) 885 if (psl->lpTarget != NULL)
886 { 886 {
887 dwCopyLen = (psl->dwRemain > 1) ? min(dwNameLen, psl->dwRemain - 1) : 0; 887 dwCopyLen = (psl->dwRemain > 1) ? min(dwNameLen, psl->dwRemain - 1) : 0;
888 _tcsncpy(psl->lpTarget, psz, dwCopyLen); 888 _tcsncpy(psl->lpTarget, psz, dwCopyLen);
889 psl->lpTarget[dwCopyLen] = _T('\0'); 889 psl->lpTarget[dwCopyLen] = _T('\0');
890 psl->lpTarget = &(psl->lpTarget[dwCopyLen + 1]); 890 psl->lpTarget = &(psl->lpTarget[dwCopyLen + 1]);
891 psl->dwRemain -= dwCopyLen + 1; 891 psl->dwRemain -= dwCopyLen + 1;
892 } 892 }
893 else 893 else
894 { 894 {
895 dwCopyLen = dwNameLen; 895 dwCopyLen = dwNameLen;
896 } 896 }
897   897  
898 delete [] psz; 898 delete [] psz;
899 psl->dwTotalCopied += dwCopyLen + 1; 899 psl->dwTotalCopied += dwCopyLen + 1;
900 return TRUE; 900 return TRUE;
901 } 901 }
902   902  
903 #ifdef __AFXWIN_H__ 903 #ifdef __AFXWIN_H__
904 // Callback function used to add elements that are extracted from a 904 // Callback function used to add elements that are extracted from a
905 // "double null terminated string" to an MFC CStringArray. 905 // "double null terminated string" to an MFC CStringArray.
906 BOOL CALLBACK CIni::__SubStrAdd(LPCTSTR lpString, LPVOID lpParam) 906 BOOL CALLBACK CIni::__SubStrAdd(LPCTSTR lpString, LPVOID lpParam)
907 { 907 {
908 CStringArray* pArray = (CStringArray*)lpParam; 908 CStringArray* pArray = (CStringArray*)lpParam;
909 if (pArray == NULL || lpString == NULL) 909 if (pArray == NULL || lpString == NULL)
910 return FALSE; 910 return FALSE;
911   911  
912 pArray->Add(lpString); 912 pArray->Add(lpString);
913 return TRUE; 913 return TRUE;
914 } 914 }
915 #endif 915 #endif
916   916  
917 // Convert an integer into binary string format 917 // Convert an integer into binary string format
918 void CIni::__ToBinaryString(UINT nNumber, LPTSTR lpBuffer, DWORD dwBufSize) 918 void CIni::__ToBinaryString(UINT nNumber, LPTSTR lpBuffer, DWORD dwBufSize)
919 { 919 {
920 if (dwBufSize == 0) 920 if (dwBufSize == 0)
921 return; 921 return;
922 922
923 DWORD dwIndex = 0; 923 DWORD dwIndex = 0;
924 do 924 do
925 { 925 {
926 lpBuffer[dwIndex++] = (nNumber % 2) ? _T('1') : _T('0'); 926 lpBuffer[dwIndex++] = (nNumber % 2) ? _T('1') : _T('0');
927 nNumber /= 2; 927 nNumber /= 2;
928 } while (nNumber > 0 && dwIndex < dwBufSize); 928 } while (nNumber > 0 && dwIndex < dwBufSize);
929   929  
930 lpBuffer[dwIndex] = _T('\0'); 930 lpBuffer[dwIndex] = _T('\0');
931 _tcsrev(lpBuffer); 931 _tcsrev(lpBuffer);
932 } 932 }
933   933  
934 // Make sure the base will be expected value 934 // Make sure the base will be expected value
935 int CIni::__ValidateBase(int nBase) 935 int CIni::__ValidateBase(int nBase)
936 { 936 {
937 switch (nBase) 937 switch (nBase)
938 { 938 {
939 case BASE_BINARY: 939 case BASE_BINARY:
940 case BASE_OCTAL: 940 case BASE_OCTAL:
941 case BASE_HEXADECIMAL: 941 case BASE_HEXADECIMAL:
942 break; 942 break;
943   943  
944 default: 944 default:
945 nBase = BASE_DECIMAL; 945 nBase = BASE_DECIMAL;
946 } 946 }
947   947  
948 return nBase; 948 return nBase;
949 } 949 }
950   950  
951 // Convert a signed integer into string representation, based on its base 951 // Convert a signed integer into string representation, based on its base
952 void CIni::__IntToString(int nNumber, LPTSTR lpBuffer, int nBase) 952 void CIni::__IntToString(int nNumber, LPTSTR lpBuffer, int nBase)
953 { 953 {
954 switch (nBase) 954 switch (nBase)
955 { 955 {
956 case BASE_BINARY: 956 case BASE_BINARY:
957 case BASE_OCTAL: 957 case BASE_OCTAL:
958 case BASE_HEXADECIMAL: 958 case BASE_HEXADECIMAL:
959 __UIntToString((UINT)nNumber, lpBuffer, nBase); 959 __UIntToString((UINT)nNumber, lpBuffer, nBase);
960 break; 960 break;
961   961  
962 default: 962 default:
963 _stprintf(lpBuffer, _T("%d"), nNumber); 963 _stprintf(lpBuffer, _T("%d"), nNumber);
964 break; 964 break;
965 } 965 }
966 } 966 }
967   967  
968 // Convert an unsigned integer into string representation, based on its base 968 // Convert an unsigned integer into string representation, based on its base
969 void CIni::__UIntToString(UINT nNumber, LPTSTR lpBuffer, int nBase) 969 void CIni::__UIntToString(UINT nNumber, LPTSTR lpBuffer, int nBase)
970 { 970 {
971 switch (nBase) 971 switch (nBase)
972 { 972 {
973 case BASE_BINARY: 973 case BASE_BINARY:
974 __ToBinaryString(nNumber, lpBuffer, DEF_PROFILE_NUM_LEN); 974 __ToBinaryString(nNumber, lpBuffer, DEF_PROFILE_NUM_LEN);
975 break; 975 break;
976   976  
977 case BASE_OCTAL: 977 case BASE_OCTAL:
978 _stprintf(lpBuffer, _T("%o"), nNumber); 978 _stprintf(lpBuffer, _T("%o"), nNumber);
979 break; 979 break;
980   980  
981 case BASE_HEXADECIMAL: 981 case BASE_HEXADECIMAL:
982 _stprintf(lpBuffer, _T("%X"), nNumber); 982 _stprintf(lpBuffer, _T("%X"), nNumber);
983 break; 983 break;
984   984  
985 default: 985 default:
986 _stprintf(lpBuffer, _T("%u"), nNumber); 986 _stprintf(lpBuffer, _T("%u"), nNumber);
987 break; 987 break;
988 } 988 }
989 } 989 }
990   990  
991 BOOL CIni::StringToBool(LPCTSTR lpString, BOOL bDefault) 991 BOOL CIni::StringToBool(LPCTSTR lpString, BOOL bDefault)
992 { 992 {
993 // Default: empty string 993 // Default: empty string
994 // TRUE: "true", "yes", non-zero decimal numner 994 // TRUE: "true", "yes", non-zero decimal numner
995 // FALSE: all other cases 995 // FALSE: all other cases
996 if (lpString == NULL || *lpString == _T('\0')) 996 if (lpString == NULL || *lpString == _T('\0'))
997 return bDefault; 997 return bDefault;
998   998  
999 return (_tcsicmp(lpString, _T("true")) == 0 999 return (_tcsicmp(lpString, _T("true")) == 0
1000 || _tcsicmp(lpString, _T("yes")) == 0 1000 || _tcsicmp(lpString, _T("yes")) == 0
1001 || _tcstol(lpString, NULL, BASE_DECIMAL) != 0); 1001 || _tcstol(lpString, NULL, BASE_DECIMAL) != 0);
1002 } 1002 }
1003   1003  
1004 BOOL CIni::__TrimString(LPTSTR lpString) 1004 BOOL CIni::__TrimString(LPTSTR lpString)
1005 { 1005 {
1006 if (lpString == NULL) 1006 if (lpString == NULL)
1007 return FALSE; 1007 return FALSE;
1008   1008  
1009 BOOL bTrimmed = FALSE; 1009 BOOL bTrimmed = FALSE;
1010 int nLen = _tcslen(lpString); 1010 int nLen = _tcslen(lpString);
1011   1011  
1012 // '\n' and '\r' are actually not possible in this case, but anyway... 1012 // '\n' and '\r' are actually not possible in this case, but anyway...
1013 1013
1014 // Trim right side 1014 // Trim right side
1015 while (nLen >= 0 1015 while (nLen >= 0
1016 && (lpString[nLen - 1] == _T(' ') 1016 && (lpString[nLen - 1] == _T(' ')
1017 || lpString[nLen - 1] == _T('\t') 1017 || lpString[nLen - 1] == _T('\t')
1018 || lpString[nLen - 1] == _T('\r') 1018 || lpString[nLen - 1] == _T('\r')
1019 || lpString[nLen - 1] == _T('\n'))) 1019 || lpString[nLen - 1] == _T('\n')))
1020 { 1020 {
1021 lpString[--nLen] = _T('\0'); 1021 lpString[--nLen] = _T('\0');
1022 bTrimmed = TRUE; 1022 bTrimmed = TRUE;
1023 } 1023 }
1024   1024  
1025 // Trim left side 1025 // Trim left side
1026 LPCTSTR p = lpString; 1026 LPCTSTR p = lpString;
1027 while (*p == _T(' ') 1027 while (*p == _T(' ')
1028 || *p == _T('\t') 1028 || *p == _T('\t')
1029 || *p == _T('\r') 1029 || *p == _T('\r')
1030 || *p == _T('\n')) 1030 || *p == _T('\n'))
1031 { 1031 {
1032 p = &p[1]; 1032 p = &p[1];
1033 bTrimmed = TRUE; 1033 bTrimmed = TRUE;
1034 } 1034 }
1035   1035  
1036 if (p != lpString) 1036 if (p != lpString)
1037 { 1037 {
1038 LPTSTR psz = _tcsdup(p); 1038 LPTSTR psz = _tcsdup(p);
1039 _tcscpy(lpString, psz); 1039 _tcscpy(lpString, psz);
1040 delete [] psz; 1040 delete [] psz;
1041 } 1041 }
1042   1042  
1043 return bTrimmed; 1043 return bTrimmed;
1044 } 1044 }
1045   1045  
1046 LPTSTR CIni::__StrDupEx(LPCTSTR lpStart, LPCTSTR lpEnd) 1046 LPTSTR CIni::__StrDupEx(LPCTSTR lpStart, LPCTSTR lpEnd)
1047 { 1047 {
1048 const DWORD LEN = ((DWORD)lpEnd - (DWORD)lpStart) / sizeof(TCHAR); 1048 const DWORD LEN = ((DWORD)lpEnd - (DWORD)lpStart) / sizeof(TCHAR);
1049 LPTSTR psz = new TCHAR[LEN + 1]; 1049 LPTSTR psz = new TCHAR[LEN + 1];
1050 _tcsncpy(psz, lpStart, LEN); 1050 _tcsncpy(psz, lpStart, LEN);
1051 psz[LEN] = _T('\0'); 1051 psz[LEN] = _T('\0');
1052 return psz; // !!! Requires the caller to free this memory !!! 1052 return psz; // !!! Requires the caller to free this memory !!!
1053 } 1053 }
1054   1054  
1055 ///////////////////////////////////////////////////////////////////////////////// 1055 /////////////////////////////////////////////////////////////////////////////////
1056 // End of Cini Class Implementation 1056 // End of Cini Class Implementation
1057 ///////////////////////////////////////////////////////////////////////////////// 1057 /////////////////////////////////////////////////////////////////////////////////
1058   1058  
1059 // If you are getting this error: 1059 // If you are getting this error:
1060 // ---------------------------------------------------------------------------- 1060 // ----------------------------------------------------------------------------
1061 // "fatal error C1010: unexpected end of file while looking for precompiled 1061 // "fatal error C1010: unexpected end of file while looking for precompiled
1062 // header directive" 1062 // header directive"
1063 //----------------------------------------------------------------------------- 1063 //-----------------------------------------------------------------------------
1064 // Please scroll all the way up and uncomment '#include "stdafx.h"' 1064 // Please scroll all the way up and uncomment '#include "stdafx.h"'