Mercurial > ecos
comparison host/tools/Utils/common/Properties.cpp @ 76:435cced73e2f ecos-v1_3_1-release
eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
| author | jlarmour |
|---|---|
| date | Tue, 28 Mar 2000 14:10:45 +0000 |
| parents | |
| children | 6736c52df507 |
comparison
equal
deleted
inserted
replaced
| 75:41bf073c0c32 | 76:435cced73e2f |
|---|---|
| 1 //####COPYRIGHTBEGIN#### | |
| 2 // | |
| 3 // ---------------------------------------------------------------------------- | |
| 4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. | |
| 5 // | |
| 6 // This program is part of the eCos host tools. | |
| 7 // | |
| 8 // This program is free software; you can redistribute it and/or modify it | |
| 9 // under the terms of the GNU General Public License as published by the Free | |
| 10 // Software Foundation; either version 2 of the License, or (at your option) | |
| 11 // any later version. | |
| 12 // | |
| 13 // This program is distributed in the hope that it will be useful, but WITHOUT | |
| 14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 15 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| 16 // more details. | |
| 17 // | |
| 18 // You should have received a copy of the GNU General Public License along with | |
| 19 // this program; if not, write to the Free Software Foundation, Inc., | |
| 20 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
| 21 // | |
| 22 // ---------------------------------------------------------------------------- | |
| 23 // | |
| 24 //####COPYRIGHTEND#### | |
| 25 // Properties.cpp: implementation of the CProperties class. | |
| 26 // | |
| 27 ////////////////////////////////////////////////////////////////////// | |
| 28 #include "Properties.h" | |
| 29 #if defined (_AFXDLL) || defined(_AFXEXT) | |
| 30 // MFC | |
| 31 //#ifdef _DEBUG | |
| 32 //#undef THIS_FILE | |
| 33 //static char THIS_FILE[]=__FILE__; | |
| 34 //#define new DEBUG_NEW | |
| 35 //#endif | |
| 36 #include <assert.h> | |
| 37 #include <sys/types.h> | |
| 38 #include <sys/stat.h> | |
| 39 #include <direct.h> | |
| 40 #endif | |
| 41 | |
| 42 ////////////////////////////////////////////////////////////////////// | |
| 43 // Construction/Destruction | |
| 44 ////////////////////////////////////////////////////////////////////// | |
| 45 | |
| 46 CProperties::CProperties(LPCTSTR pszKey,void *hKey): | |
| 47 m_strName(pszKey), | |
| 48 m_hKey(hKey) | |
| 49 { | |
| 50 } | |
| 51 | |
| 52 CProperties::~CProperties() | |
| 53 { | |
| 54 RemoveAll(); | |
| 55 } | |
| 56 | |
| 57 void CProperties::RemoveAll() | |
| 58 { | |
| 59 for(int i=ar.size()-1;i>=0;--i){ | |
| 60 delete (CProperties::CProperty *)ar[i]; | |
| 61 } | |
| 62 ar.clear(); | |
| 63 } | |
| 64 | |
| 65 #ifdef _WIN32 | |
| 66 bool CProperties::LoadFromRegistry(HKEY hTopKey,LPCTSTR szRegKey,LPCTSTR pszPrefix) | |
| 67 { | |
| 68 int nPrefixlen=_tcslen(pszPrefix); | |
| 69 HKEY hKey; | |
| 70 LONG l=RegOpenKeyEx (hTopKey, szRegKey, 0L, KEY_QUERY_VALUE, &hKey); | |
| 71 bool rc=(ERROR_SUCCESS==l); | |
| 72 if(rc){ | |
| 73 TCHAR szName[256]; | |
| 74 DWORD dwSizeName=sizeof szName; | |
| 75 DWORD dwMaxDatalen; | |
| 76 DWORD dwType; | |
| 77 if(ERROR_SUCCESS==RegQueryInfoKey(hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dwMaxDatalen,NULL,NULL)){ | |
| 78 char *Data=new char[dwMaxDatalen]; | |
| 79 DWORD dwDatalen=dwMaxDatalen; | |
| 80 for(DWORD dwIndex=0;ERROR_SUCCESS==RegEnumValue(hKey, dwIndex, szName, &dwSizeName, NULL, &dwType, (LPBYTE)Data, &dwDatalen);dwIndex++){ | |
| 81 if(0!=_tcsncmp(pszPrefix,szName,nPrefixlen)){ | |
| 82 continue; | |
| 83 } | |
| 84 | |
| 85 CProperties::CProperty *p=Lookup(szName+nPrefixlen); | |
| 86 if(p){ | |
| 87 switch(p->Type){ | |
| 88 case CProperty::Integer: | |
| 89 if(REG_DWORD==dwType){ | |
| 90 p->SetValue(*(int *)Data); | |
| 91 } else { | |
| 92 //TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); | |
| 93 rc=false; | |
| 94 } | |
| 95 break; | |
| 96 case CProperty::Bool: | |
| 97 if(REG_DWORD==dwType){ | |
| 98 p->SetValue((bool)0!=*(int *)Data); | |
| 99 } else { | |
| 100 //TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); | |
| 101 rc=false; | |
| 102 } | |
| 103 break; | |
| 104 case CProperty::Char: | |
| 105 if(REG_DWORD==dwType){ | |
| 106 p->SetValue(*(char *)Data); | |
| 107 } else { | |
| 108 //TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); | |
| 109 rc=false; | |
| 110 } | |
| 111 break; | |
| 112 case CProperty::Short: | |
| 113 if(REG_DWORD==dwType){ | |
| 114 p->SetValue(*(short *)Data); | |
| 115 } else { | |
| 116 //TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); | |
| 117 rc=false; | |
| 118 } | |
| 119 break; | |
| 120 case CProperty::Float: | |
| 121 case CProperty::Double: | |
| 122 case CProperty::szString: | |
| 123 case CProperty::GPString: | |
| 124 if(REG_SZ==dwType){ | |
| 125 rc&=p->SetValue((LPCTSTR)Data); | |
| 126 } else { | |
| 127 //TRACE(_T("Type mismatch - %s: expected REG_SZ, got %d\n"),(LPCTSTR)p->strName,dwType); | |
| 128 rc=false; | |
| 129 } | |
| 130 break; | |
| 131 case CProperty::Void: | |
| 132 if(REG_BINARY==dwType){ | |
| 133 memcpy(p->pData,Data,min(dwDatalen,p->nLength)); | |
| 134 } else { | |
| 135 //TRACE(_T("Type mismatch - %s: expected REG_BINARY, got %d\n"),(LPCTSTR)p->strName,dwType); | |
| 136 rc=false; | |
| 137 } | |
| 138 break; | |
| 139 } | |
| 140 } else { | |
| 141 //TRACE(_T("CProperties::LoadFromRegistry - unrecognized value %s\\%s\n"),szRegKey,szName); | |
| 142 rc=false; | |
| 143 } | |
| 144 dwSizeName=sizeof szName; | |
| 145 dwDatalen=dwMaxDatalen; | |
| 146 } | |
| 147 delete [] Data; | |
| 148 dwSizeName=sizeof szName; | |
| 149 } | |
| 150 RegCloseKey(hKey); | |
| 151 } else { | |
| 152 //TRACE(_T("Failed to open %s\n"),szRegKey); | |
| 153 } | |
| 154 | |
| 155 return rc; | |
| 156 } | |
| 157 | |
| 158 bool CProperties::SaveToRegistry(HKEY hTopKey,LPCTSTR szRegKey,LPCTSTR pszPrefix) const | |
| 159 { | |
| 160 HKEY hKey; | |
| 161 CreateKey(szRegKey); | |
| 162 bool rc=(ERROR_SUCCESS==RegOpenKeyEx (hTopKey, szRegKey, 0L, KEY_SET_VALUE, &hKey)); | |
| 163 if(rc){ | |
| 164 for(int i=ar.size()-1;i>=0;--i){ | |
| 165 // Initializations are simply to avoid compiler warnings. | |
| 166 DWORD dwDatalen=0; | |
| 167 DWORD dwType=REG_DWORD; | |
| 168 BYTE *Data=0; | |
| 169 // strValue and dw *must* be in scope for RegSetValueEx below. | |
| 170 DWORD dw; | |
| 171 String strValue; | |
| 172 CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; | |
| 173 switch(p->Type){ | |
| 174 case CProperties::CProperty::Integer: | |
| 175 case CProperties::CProperty::Bool: | |
| 176 case CProperties::CProperty::Char: | |
| 177 case CProperties::CProperty::Short: | |
| 178 dwType=REG_DWORD; | |
| 179 dwDatalen=sizeof(DWORD); | |
| 180 dw=p->GetValue(); | |
| 181 Data=(BYTE *)&dw; | |
| 182 break; | |
| 183 case CProperties::CProperty::Float: | |
| 184 case CProperties::CProperty::Double: | |
| 185 case CProperties::CProperty::szString: | |
| 186 case CProperties::CProperty::GPString: | |
| 187 strValue=p->GetStringValue(); | |
| 188 Data=(BYTE *)(LPCTSTR)strValue; | |
| 189 dwType=REG_SZ; | |
| 190 dwDatalen=(1+strValue.GetLength())*sizeof(_TCHAR); | |
| 191 break; | |
| 192 case CProperties::CProperty::Void: | |
| 193 Data=(BYTE *)p->pData; | |
| 194 dwType=REG_BINARY; | |
| 195 dwDatalen=p->nLength; | |
| 196 break; | |
| 197 default: | |
| 198 assert(false); | |
| 199 break; | |
| 200 } | |
| 201 String strName(pszPrefix); | |
| 202 strName+=p->strName; | |
| 203 rc&=(ERROR_SUCCESS==RegSetValueEx(hKey,strName,0,dwType,Data,dwDatalen)); | |
| 204 } | |
| 205 } | |
| 206 RegCloseKey(hKey); | |
| 207 return rc; | |
| 208 } | |
| 209 | |
| 210 // Create all keys down to the one specified | |
| 211 bool CProperties::CreateKey(LPCTSTR pszKey,HKEY hKey/*=HKEY_CURRENT_USER*/) | |
| 212 { | |
| 213 bool rc=true; | |
| 214 LPCTSTR pcStart=pszKey; | |
| 215 LPCTSTR pcEnd; | |
| 216 do { | |
| 217 HKEY hKey2; | |
| 218 pcEnd=_tcschr(pcStart,_TCHAR('\\')); | |
| 219 if(NULL==pcEnd){ | |
| 220 pcEnd=pcStart+_tcslen(pcStart); | |
| 221 } | |
| 222 String strKey(pcStart,pcEnd-pcStart); | |
| 223 if(ERROR_SUCCESS!=RegCreateKeyEx(hKey, // handle to an open key | |
| 224 strKey, // address of subkey name | |
| 225 0, // reserved | |
| 226 0, // address of class string | |
| 227 REG_OPTION_NON_VOLATILE, // special options flag | |
| 228 KEY_ALL_ACCESS, // desired security access | |
| 229 NULL, | |
| 230 // address of key security structure | |
| 231 &hKey2, // address of buffer for opened handle | |
| 232 NULL// address of disposition value buffer); | |
| 233 )){ | |
| 234 rc=false; | |
| 235 break; | |
| 236 } | |
| 237 RegCloseKey(hKey); | |
| 238 hKey=hKey2; | |
| 239 pcStart=pcEnd+1; | |
| 240 } while (_TCHAR('\0')!=*pcEnd); | |
| 241 RegCloseKey(hKey); | |
| 242 return rc; | |
| 243 } | |
| 244 | |
| 245 #endif | |
| 246 | |
| 247 bool CProperties::LoadFromCommandString(LPCTSTR psz,LPCTSTR pszPrefix/*=_T("-")*/) | |
| 248 { | |
| 249 bool rc=true; | |
| 250 const TCHAR *cNext; | |
| 251 int nPrefixlen=_tcslen(pszPrefix); | |
| 252 for(LPCTSTR c=_tcsstr(psz,pszPrefix);c;c=_tcsstr(cNext,pszPrefix)){ | |
| 253 c+=nPrefixlen; | |
| 254 const TCHAR *pEq=_tcschr(c,_TCHAR('=')); | |
| 255 if(NULL==pEq){ | |
| 256 //TRACE(_T("Failed to find '=' after %s\n"),c); | |
| 257 rc=false; | |
| 258 break; | |
| 259 } | |
| 260 String strName(c,pEq-c); | |
| 261 CProperties::CProperty *p=Lookup(strName); | |
| 262 c=pEq+1; | |
| 263 String str; | |
| 264 if(_TCHAR('"')==*c){ | |
| 265 // Value is a quoted string | |
| 266 for(cNext=c+1;_TCHAR('"')!=*cNext;cNext++){ | |
| 267 if(_TCHAR('\\')==*cNext){ | |
| 268 cNext++; | |
| 269 } | |
| 270 str+=*cNext; | |
| 271 } | |
| 272 } else { | |
| 273 // Value is simply terminated by whitespace | |
| 274 for(cNext=c;_TCHAR('\0')!=*cNext && !_istspace(*cNext);cNext++); | |
| 275 str=String(c,cNext-c); | |
| 276 } | |
| 277 if(p){ | |
| 278 rc&=p->SetValue(str); | |
| 279 } else { | |
| 280 //TRACE(_T("Properties: unrecognized attribute %s in command string\n"),(LPCTSTR)strName); | |
| 281 rc=false; | |
| 282 } | |
| 283 } | |
| 284 return rc; | |
| 285 } | |
| 286 | |
| 287 CProperties::CProperty * CProperties::Lookup(LPCTSTR pszName) | |
| 288 { | |
| 289 for(int i=ar.size()-1;i>=0;--i){ | |
| 290 CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; | |
| 291 if(p->strName==pszName){ | |
| 292 return p; | |
| 293 } | |
| 294 } | |
| 295 return NULL; | |
| 296 } | |
| 297 | |
| 298 String CProperties::MakeCommandString(LPCTSTR pszPrefix/*=_T("-")*/) const | |
| 299 { | |
| 300 String strResult; | |
| 301 bool bFirst=true; | |
| 302 for(int i=ar.size()-1;i>=0;--i){ | |
| 303 String str; | |
| 304 CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; | |
| 305 switch(p->Type){ | |
| 306 case CProperties::CProperty::Integer: | |
| 307 case CProperties::CProperty::Bool: | |
| 308 case CProperties::CProperty::Char: | |
| 309 case CProperties::CProperty::Short: | |
| 310 str.Format(_T("%s%s=%u"),pszPrefix,(LPCTSTR)p->strName,p->GetValue()); | |
| 311 break; | |
| 312 case CProperties::CProperty::szString: | |
| 313 case CProperties::CProperty::GPString: | |
| 314 case CProperties::CProperty::Float: | |
| 315 case CProperties::CProperty::Double: | |
| 316 case CProperties::CProperty::Void: | |
| 317 str.Format(_T("%s%s=\"%s\""),pszPrefix,(LPCTSTR)p->strName,(LPCTSTR)p->GetStringValue()); | |
| 318 break; | |
| 319 } | |
| 320 if(!bFirst){ | |
| 321 strResult+=_TCHAR(' '); | |
| 322 } | |
| 323 bFirst=false; | |
| 324 strResult+=str; | |
| 325 } | |
| 326 return strResult; | |
| 327 } | |
| 328 | |
| 329 bool CProperties::CreatePathToFile(LPCTSTR pszDir) | |
| 330 { | |
| 331 // Create intermediate directories | |
| 332 #ifdef _WIN32 | |
| 333 const TCHAR cSep='\\'; | |
| 334 #else // UNIX | |
| 335 const TCHAR cSep='/'; | |
| 336 #endif | |
| 337 for(LPCTSTR c=_tcschr(pszDir,cSep);c;c=_tcschr(c+1,cSep)){ | |
| 338 #ifdef _WIN32 | |
| 339 if(c==pszDir+2 && _istalpha(pszDir[0]) && _TCHAR(':')==pszDir[1]){ | |
| 340 continue; // don't attempt to create "C:" | |
| 341 } | |
| 342 #endif | |
| 343 String strDir(pszDir,c-pszDir); | |
| 344 struct _stat buf; | |
| 345 if(!(0==_tstat(strDir,&buf) && (S_IFDIR&buf.st_mode))){ | |
| 346 // Need to create directory | |
| 347 bool b=(0==_tmkdir(strDir)); | |
| 348 //TRACE(_T("Create directory %s rc=%d\n"),(LPCTSTR)strDir,b); | |
| 349 if(!b){ | |
| 350 return false; | |
| 351 } | |
| 352 } | |
| 353 } | |
| 354 return true; | |
| 355 } | |
| 356 | |
| 357 bool CProperties::SaveToFile(LPCTSTR pszFileName,LPCTSTR pszPrefix) const | |
| 358 { | |
| 359 CreatePathToFile(pszFileName); | |
| 360 // If we have a prefix, we assume we're tagging on to an existing file | |
| 361 FILE *f=_tfopen(pszFileName,(_TCHAR('\0')==*pszPrefix)?_T("wt"):_T("at")); | |
| 362 if(f){ | |
| 363 for(int i=ar.size()-1;i>=0;--i){ | |
| 364 CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; | |
| 365 String str(pszPrefix); | |
| 366 str+=p->strName; | |
| 367 str+=_TCHAR('='); | |
| 368 switch(p->Type){ | |
| 369 case CProperties::CProperty::Integer: | |
| 370 case CProperties::CProperty::Bool: | |
| 371 case CProperties::CProperty::Char: | |
| 372 case CProperties::CProperty::Short: | |
| 373 { | |
| 374 String strN; | |
| 375 strN.Format(_T("%u"),p->GetValue()); | |
| 376 str+=strN; | |
| 377 } | |
| 378 break; | |
| 379 case CProperties::CProperty::Float: | |
| 380 case CProperties::CProperty::Double: | |
| 381 case CProperties::CProperty::szString: | |
| 382 case CProperties::CProperty::GPString: | |
| 383 case CProperties::CProperty::Void: | |
| 384 str+=p->GetStringValue(); | |
| 385 break; | |
| 386 } | |
| 387 str+=_TCHAR('\n'); | |
| 388 _fputts(str,f); | |
| 389 } | |
| 390 fclose(f); | |
| 391 } | |
| 392 return (0!=f); | |
| 393 } | |
| 394 | |
| 395 bool CProperties::LoadFromFile(LPCTSTR pszFileName,LPCTSTR pszPrefix) | |
| 396 { | |
| 397 int nPrefixlen=_tcslen(pszPrefix); | |
| 398 FILE *f=_tfopen(pszFileName,_T("rt")); | |
| 399 bool rc=(0!=f); | |
| 400 if(rc){ | |
| 401 TCHAR c[256]; | |
| 402 while(_fgetts(c,sizeof(c)-1,f)){ | |
| 403 if(_TCHAR('\0')!=c[0]){ | |
| 404 c[_tcslen(c)-1]=_TCHAR('\0'); // remove trailing \n | |
| 405 } | |
| 406 if((signed)_tcslen(c)>nPrefixlen && 0==_tcsncmp(c,pszPrefix,nPrefixlen)){ | |
| 407 TCHAR *pEq=_tcschr(c,_TCHAR('=')); | |
| 408 if(pEq){ | |
| 409 const String strName(c+nPrefixlen,pEq-c-nPrefixlen); | |
| 410 CProperties::CProperty *p=Lookup(strName); | |
| 411 if(p){ | |
| 412 pEq++; | |
| 413 rc&=p->SetValue(pEq); | |
| 414 } else { | |
| 415 //TRACE(_T("Failed to find %s\n"),(LPCTSTR)strName); | |
| 416 rc=false; | |
| 417 } | |
| 418 } | |
| 419 } | |
| 420 } | |
| 421 fclose(f); | |
| 422 } | |
| 423 return rc; | |
| 424 | |
| 425 } | |
| 426 | |
| 427 CProperties::CProperty::CProperty(LPCTSTR pszName,Typetype type,void *_pData): | |
| 428 strName(pszName), | |
| 429 Type(type), | |
| 430 pData(_pData) | |
| 431 { | |
| 432 } | |
| 433 | |
| 434 CProperties::CProperty::~CProperty() | |
| 435 { | |
| 436 } | |
| 437 | |
| 438 void CProperties::Add(LPCTSTR pszName,int &n,int _nDefault) | |
| 439 { | |
| 440 CProperty *p=new CProperty(pszName,CProperty::Integer,&n); | |
| 441 p->nDefault=_nDefault; | |
| 442 ar.push_back(p); | |
| 443 } | |
| 444 | |
| 445 void CProperties::Add(LPCTSTR pszName,unsigned int &n,unsigned int _nDefault) | |
| 446 { | |
| 447 CProperty *p=new CProperty(pszName,CProperty::Integer,&n); | |
| 448 p->nDefault=_nDefault; | |
| 449 ar.push_back(p); | |
| 450 } | |
| 451 | |
| 452 void CProperties::Add(LPCTSTR pszName,bool &b,bool _bDefault) | |
| 453 { | |
| 454 CProperty *p=new CProperty(pszName,CProperty::Bool,&b); | |
| 455 p->nDefault=_bDefault; | |
| 456 ar.push_back(p); | |
| 457 } | |
| 458 | |
| 459 void CProperties::Add(LPCTSTR pszName,char &c,char _cDefault) | |
| 460 { | |
| 461 CProperty *p=new CProperty(pszName,CProperty::Char,&c); | |
| 462 p->nDefault=_cDefault; | |
| 463 ar.push_back(p); | |
| 464 } | |
| 465 | |
| 466 void CProperties::Add(LPCTSTR pszName,unsigned char &c,unsigned char _cDefault) | |
| 467 { | |
| 468 CProperty *p=new CProperty(pszName,CProperty::Char,&c); | |
| 469 p->nDefault=_cDefault; | |
| 470 ar.push_back(p); | |
| 471 } | |
| 472 | |
| 473 void CProperties::Add(LPCTSTR pszName,short &s,short _sDefault) | |
| 474 { | |
| 475 CProperty *p=new CProperty(pszName,CProperty::Short,&s); | |
| 476 p->nDefault=_sDefault; | |
| 477 ar.push_back(p); | |
| 478 } | |
| 479 | |
| 480 void CProperties::Add(LPCTSTR pszName,unsigned short &s,unsigned short _sDefault) | |
| 481 { | |
| 482 CProperty *p=new CProperty(pszName,CProperty::Short,&s); | |
| 483 p->nDefault=_sDefault; | |
| 484 ar.push_back(p); | |
| 485 } | |
| 486 | |
| 487 void CProperties::Add(LPCTSTR pszName,float &f,float _fDefault) | |
| 488 { | |
| 489 CProperty *p=new CProperty(pszName,CProperty::Float,&f); | |
| 490 p->dDefault=_fDefault; | |
| 491 ar.push_back(p); | |
| 492 } | |
| 493 | |
| 494 void CProperties::Add(LPCTSTR pszName,double &f,double dDefault) | |
| 495 { | |
| 496 CProperty *p=new CProperty(pszName,CProperty::Double,&f); | |
| 497 p->dDefault=dDefault; | |
| 498 ar.push_back(p); | |
| 499 } | |
| 500 | |
| 501 void CProperties::Add(LPCTSTR pszName,void *pv,unsigned int _nLength,void *pvDefault) | |
| 502 { | |
| 503 CProperty *p=new CProperty(pszName,CProperty::Void,pv); | |
| 504 p->nLength=_nLength; | |
| 505 p->pvDefault=pvDefault; | |
| 506 ar.push_back(p); | |
| 507 } | |
| 508 | |
| 509 void CProperties::Add(LPCTSTR pszName,LPTSTR s,unsigned int _nLength,LPCTSTR _pszDefault) | |
| 510 { | |
| 511 CProperty *p=new CProperty(pszName,CProperty::szString,s); | |
| 512 p->nLength=_nLength; | |
| 513 p->strDefault=_pszDefault; | |
| 514 ar.push_back(p); | |
| 515 } | |
| 516 | |
| 517 void CProperties::Add (LPCTSTR pszName,void *pObj,getFn *getFn,putFn *putFn,LPCTSTR pszDefault) | |
| 518 { | |
| 519 CProperty *p=new CProperty(pszName,CProperty::GPString,pObj); | |
| 520 p->strDefault=pszDefault; | |
| 521 p->pgetFn=getFn; | |
| 522 p->pputFn=putFn; | |
| 523 p->strDefault=pszDefault; | |
| 524 ar.push_back(p); | |
| 525 } | |
| 526 | |
| 527 unsigned long CProperties::CProperty::GetValue() const | |
| 528 { | |
| 529 unsigned long dw; | |
| 530 switch(Type){ | |
| 531 case Integer: | |
| 532 dw=*(int *)pData; | |
| 533 break; | |
| 534 case Bool: | |
| 535 dw=*(bool *)pData; | |
| 536 break; | |
| 537 case Char: | |
| 538 dw=*(char *)pData; | |
| 539 break; | |
| 540 case Short: | |
| 541 dw=*(short *)pData; | |
| 542 break; | |
| 543 default: | |
| 544 dw=0; | |
| 545 assert(false); | |
| 546 } | |
| 547 return dw; | |
| 548 } | |
| 549 | |
| 550 const String CProperties::CProperty::GetStringValue() const | |
| 551 { | |
| 552 String str; | |
| 553 switch(Type){ | |
| 554 case szString: | |
| 555 str=(LPCTSTR)(pData); | |
| 556 break; | |
| 557 case GPString: | |
| 558 str=pgetFn(pData); | |
| 559 break; | |
| 560 case CProperties::CProperty::Integer: | |
| 561 case CProperties::CProperty::Bool: | |
| 562 case CProperties::CProperty::Char: | |
| 563 case CProperties::CProperty::Short: | |
| 564 str.Format(_T("%u"),GetValue()); | |
| 565 break; | |
| 566 case CProperties::CProperty::Float: | |
| 567 str.Format(_T("%e"),*(float *)(pData)); | |
| 568 break; | |
| 569 case CProperties::CProperty::Double: | |
| 570 str.Format(_T("%e"),*(double *)(pData)); | |
| 571 break; | |
| 572 case CProperties::CProperty::Void: | |
| 573 { | |
| 574 unsigned char *c=(unsigned char *)pData; | |
| 575 for(unsigned int i=0;i<nLength;i++){ | |
| 576 TCHAR buf[3]; | |
| 577 _tprintf(buf,_T("%02x"),c[i]); | |
| 578 str+=buf; | |
| 579 } | |
| 580 } | |
| 581 break; | |
| 582 default: | |
| 583 break; | |
| 584 } | |
| 585 return str; | |
| 586 } | |
| 587 | |
| 588 bool CProperties::CProperty::SetValue(int n) | |
| 589 { | |
| 590 bool rc=true; | |
| 591 switch(Type){ | |
| 592 case Integer: | |
| 593 *(int *)(pData)=n; | |
| 594 break; | |
| 595 case Bool: | |
| 596 *(bool *)(pData)=(0!=n); | |
| 597 break; | |
| 598 case Char: | |
| 599 *(char *)(pData)=(char)n; //FIXME: range checks | |
| 600 break; | |
| 601 case Short: | |
| 602 *(short *)(pData)=(short)n;//FIXME: range checks | |
| 603 break; | |
| 604 default: | |
| 605 //TRACE(_T("Failed to set '%s' to integer value '%d'\n"),(LPCTSTR)strName,n); | |
| 606 break; | |
| 607 } | |
| 608 return rc; | |
| 609 } | |
| 610 | |
| 611 bool CProperties::CProperty::SetValue(double n) | |
| 612 { | |
| 613 bool rc=true; | |
| 614 switch(Type){ | |
| 615 case Double: | |
| 616 *(float *)(pData)=(float)n;//FIXME: range checks? | |
| 617 break; | |
| 618 case Float: | |
| 619 *(double *)(pData)=n; | |
| 620 break; | |
| 621 default: | |
| 622 //TRACE(_T("Failed to set '%s' to double value '%f'\n"),(LPCTSTR)strName,n); | |
| 623 rc=false; | |
| 624 break; | |
| 625 } | |
| 626 | |
| 627 return rc; | |
| 628 } | |
| 629 | |
| 630 bool CProperties::CProperty::SetValue(LPCTSTR psz) | |
| 631 { | |
| 632 bool rc=false; | |
| 633 TCHAR *pEnd; | |
| 634 double d; | |
| 635 long l; | |
| 636 switch(Type){ | |
| 637 case szString: | |
| 638 _tcsncpy((LPTSTR)pData,psz,nLength); | |
| 639 if(nLength<=_tcslen(psz)){ | |
| 640 ((LPTSTR)pData)[nLength]=_TCHAR('\0'); | |
| 641 } | |
| 642 rc=true; | |
| 643 break; | |
| 644 case GPString: | |
| 645 pputFn(pData,psz); | |
| 646 rc=true; | |
| 647 break; | |
| 648 case Float: | |
| 649 d=_tcstod(psz,&pEnd); | |
| 650 rc=(_TCHAR('\0')==*pEnd); | |
| 651 if(rc){ | |
| 652 SetValue((float)d); | |
| 653 } | |
| 654 break; | |
| 655 case Double: | |
| 656 d=_tcstod(psz,&pEnd); | |
| 657 rc=(_TCHAR('\0')==*pEnd); | |
| 658 if(rc){ | |
| 659 SetValue(d); | |
| 660 } | |
| 661 break; | |
| 662 case Integer: | |
| 663 case Bool: | |
| 664 case Char: | |
| 665 case Short: | |
| 666 l=_tcstol(psz,&pEnd,10); | |
| 667 rc=(_TCHAR('\0')==*pEnd); | |
| 668 if(rc){ | |
| 669 SetValue((int)l); | |
| 670 } | |
| 671 break; | |
| 672 default: | |
| 673 //TRACE(_T("Failed to set '%s' to string value '%s'\n"),(LPCTSTR)strName,psz); | |
| 674 break; | |
| 675 } | |
| 676 return rc; | |
| 677 } | |
| 678 | |
| 679 void CProperties::CProperty::SetDefault() | |
| 680 { | |
| 681 switch(Type){ | |
| 682 case Bool: | |
| 683 case Integer: | |
| 684 case Char: | |
| 685 case Short: | |
| 686 SetValue(nDefault); | |
| 687 break; | |
| 688 case Float: | |
| 689 case Double: | |
| 690 SetValue(dDefault); | |
| 691 break; | |
| 692 case szString: | |
| 693 case GPString: | |
| 694 SetValue(strDefault); | |
| 695 break; | |
| 696 case Void: | |
| 697 if(pvDefault){ | |
| 698 memcpy(pData,pvDefault,nLength); | |
| 699 } | |
| 700 break; | |
| 701 default: | |
| 702 assert(false); | |
| 703 } | |
| 704 | |
| 705 } | |
| 706 | |
| 707 void CProperties::SetDefaults() | |
| 708 { | |
| 709 for(int i=ar.size()-1;i>=0;--i){ | |
| 710 ((CProperty*)ar[i])->SetDefault(); | |
| 711 } | |
| 712 } | |
| 713 | |
| 714 bool CProperties::Load(LPCTSTR pszPrefix) | |
| 715 { | |
| 716 #ifdef _WIN32 | |
| 717 return m_hKey?LoadFromRegistry((HKEY)m_hKey,m_strName,pszPrefix):LoadFromFile(m_strName,pszPrefix); | |
| 718 #else // UNIX | |
| 719 return LoadFromFile(m_strName,pszPrefix); | |
| 720 #endif | |
| 721 } | |
| 722 | |
| 723 bool CProperties::Save(LPCTSTR pszPrefix) | |
| 724 { | |
| 725 #ifdef _WIN32 | |
| 726 return m_hKey?SaveToRegistry((HKEY)m_hKey,m_strName,pszPrefix):SaveToFile(m_strName,pszPrefix); | |
| 727 #else // UNIX | |
| 728 return SaveToFile(m_strName,pszPrefix); | |
| 729 #endif | |
| 730 } | |
| 731 /* | |
| 732 bool CProperties::Remove(LPCTSTR pszName) | |
| 733 { | |
| 734 for(int i=ar.size()-1;i>=0;--i){ | |
| 735 CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; | |
| 736 if(p->strName==pszName){ | |
| 737 delete p; | |
| 738 ar.RemoveAt(i); | |
| 739 return true; | |
| 740 } | |
| 741 } | |
| 742 return false; | |
| 743 } | |
| 744 */ |
