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