📄 properties.cpp
字号:
//####COPYRIGHTBEGIN####// // ----------------------------------------------------------------------------// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.//// This program is part of the eCos host tools.//// This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version.// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details.// // You should have received a copy of the GNU General Public License along with// this program; if not, write to the Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.//// ----------------------------------------------------------------------------// //####COPYRIGHTEND####// Properties.cpp: implementation of the CProperties class.////////////////////////////////////////////////////////////////////////#include "Properties.h"#if defined (_AFXDLL) || defined(_AFXEXT) // MFC //#ifdef _DEBUG //#undef THIS_FILE //static char THIS_FILE[]=__FILE__; //#define new DEBUG_NEW //#endif #include <assert.h> #include <sys/types.h> #include <sys/stat.h> #include <direct.h>#endif//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////CProperties::CProperties(LPCTSTR pszKey,void *hKey): m_strName(pszKey), m_hKey(hKey){}CProperties::~CProperties(){ RemoveAll();}void CProperties::RemoveAll(){ for(int i=ar.size()-1;i>=0;--i){ delete (CProperties::CProperty *)ar[i]; } ar.clear();}#ifdef _WIN32bool CProperties::LoadFromRegistry(HKEY hTopKey,LPCTSTR szRegKey,LPCTSTR pszPrefix){ int nPrefixlen=_tcslen(pszPrefix); HKEY hKey; LONG l=RegOpenKeyEx (hTopKey, szRegKey, 0L, KEY_QUERY_VALUE, &hKey); bool rc=(ERROR_SUCCESS==l); if(rc){ TCHAR szName[256]; DWORD dwSizeName=sizeof szName; DWORD dwMaxDatalen; DWORD dwType; if(ERROR_SUCCESS==RegQueryInfoKey(hKey,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dwMaxDatalen,NULL,NULL)){ char *Data=new char[dwMaxDatalen]; DWORD dwDatalen=dwMaxDatalen; for(DWORD dwIndex=0;ERROR_SUCCESS==RegEnumValue(hKey, dwIndex, szName, &dwSizeName, NULL, &dwType, (LPBYTE)Data, &dwDatalen);dwIndex++){ if(0!=_tcsncmp(pszPrefix,szName,nPrefixlen)){ continue; } CProperties::CProperty *p=Lookup(szName+nPrefixlen); if(p){ switch(p->Type){ case CProperty::Integer: if(REG_DWORD==dwType){ p->SetValue(*(int *)Data); } else { //TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); rc=false; } break; case CProperty::Bool: if(REG_DWORD==dwType){ p->SetValue((bool)0!=*(int *)Data); } else { //TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); rc=false; } break; case CProperty::Char: if(REG_DWORD==dwType){ p->SetValue(*(char *)Data); } else { //TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); rc=false; } break; case CProperty::Short: if(REG_DWORD==dwType){ p->SetValue(*(short *)Data); } else { //TRACE(_T("Type mismatch - %s: expected REG_DWORD, got %d\n"),(LPCTSTR)p->strName,dwType); rc=false; } break; case CProperty::Float: case CProperty::Double: case CProperty::szString: case CProperty::GPString: if(REG_SZ==dwType){ rc&=p->SetValue((LPCTSTR)Data); } else { //TRACE(_T("Type mismatch - %s: expected REG_SZ, got %d\n"),(LPCTSTR)p->strName,dwType); rc=false; } break; case CProperty::Void: if(REG_BINARY==dwType){ memcpy(p->pData,Data,min(dwDatalen,p->nLength)); } else { //TRACE(_T("Type mismatch - %s: expected REG_BINARY, got %d\n"),(LPCTSTR)p->strName,dwType); rc=false; } break; } } else { //TRACE(_T("CProperties::LoadFromRegistry - unrecognized value %s\\%s\n"),szRegKey,szName); rc=false; } dwSizeName=sizeof szName; dwDatalen=dwMaxDatalen; } delete [] Data; dwSizeName=sizeof szName; } RegCloseKey(hKey); } else { //TRACE(_T("Failed to open %s\n"),szRegKey); } return rc;}bool CProperties::SaveToRegistry(HKEY hTopKey,LPCTSTR szRegKey,LPCTSTR pszPrefix) const{ HKEY hKey; CreateKey(szRegKey); bool rc=(ERROR_SUCCESS==RegOpenKeyEx (hTopKey, szRegKey, 0L, KEY_SET_VALUE, &hKey)); if(rc){ for(int i=ar.size()-1;i>=0;--i){ // Initializations are simply to avoid compiler warnings. DWORD dwDatalen=0; DWORD dwType=REG_DWORD; BYTE *Data=0; // strValue and dw *must* be in scope for RegSetValueEx below. DWORD dw; String strValue; CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; switch(p->Type){ case CProperties::CProperty::Integer: case CProperties::CProperty::Bool: case CProperties::CProperty::Char: case CProperties::CProperty::Short: dwType=REG_DWORD; dwDatalen=sizeof(DWORD); dw=p->GetValue(); Data=(BYTE *)&dw; break; case CProperties::CProperty::Float: case CProperties::CProperty::Double: case CProperties::CProperty::szString: case CProperties::CProperty::GPString: strValue=p->GetStringValue(); Data=(BYTE *)(LPCTSTR)strValue; dwType=REG_SZ; dwDatalen=(1+strValue.GetLength())*sizeof(_TCHAR); break; case CProperties::CProperty::Void: Data=(BYTE *)p->pData; dwType=REG_BINARY; dwDatalen=p->nLength; break; default: assert(false); break; } String strName(pszPrefix); strName+=p->strName; rc&=(ERROR_SUCCESS==RegSetValueEx(hKey,strName,0,dwType,Data,dwDatalen)); } } RegCloseKey(hKey); return rc; }// Create all keys down to the one specifiedbool CProperties::CreateKey(LPCTSTR pszKey,HKEY hKey/*=HKEY_CURRENT_USER*/){ bool rc=true; LPCTSTR pcStart=pszKey; LPCTSTR pcEnd; do { HKEY hKey2; pcEnd=_tcschr(pcStart,_TCHAR('\\')); if(NULL==pcEnd){ pcEnd=pcStart+_tcslen(pcStart); } String strKey(pcStart,pcEnd-pcStart); if(ERROR_SUCCESS!=RegCreateKeyEx(hKey, // handle to an open key strKey, // address of subkey name 0, // reserved 0, // address of class string REG_OPTION_NON_VOLATILE, // special options flag KEY_ALL_ACCESS, // desired security access NULL, // address of key security structure &hKey2, // address of buffer for opened handle NULL// address of disposition value buffer); )){ rc=false; break; } RegCloseKey(hKey); hKey=hKey2; pcStart=pcEnd+1; } while (_TCHAR('\0')!=*pcEnd); RegCloseKey(hKey); return rc;}#endifbool CProperties::LoadFromCommandString(LPCTSTR psz,LPCTSTR pszPrefix/*=_T("-")*/){ bool rc=true; const TCHAR *cNext; int nPrefixlen=_tcslen(pszPrefix); for(LPCTSTR c=_tcsstr(psz,pszPrefix);c;c=_tcsstr(cNext,pszPrefix)){ c+=nPrefixlen; const TCHAR *pEq=_tcschr(c,_TCHAR('=')); if(NULL==pEq){ //TRACE(_T("Failed to find '=' after %s\n"),c); rc=false; break; } String strName(c,pEq-c); CProperties::CProperty *p=Lookup(strName); c=pEq+1; String str; if(_TCHAR('"')==*c){ // Value is a quoted string for(cNext=c+1;_TCHAR('"')!=*cNext;cNext++){ if(_TCHAR('\\')==*cNext){ cNext++; } str+=*cNext; } } else { // Value is simply terminated by whitespace for(cNext=c;_TCHAR('\0')!=*cNext && !_istspace(*cNext);cNext++); str=String(c,cNext-c); } if(p){ rc&=p->SetValue(str); } else { //TRACE(_T("Properties: unrecognized attribute %s in command string\n"),(LPCTSTR)strName); rc=false; } } return rc;}CProperties::CProperty * CProperties::Lookup(LPCTSTR pszName){ for(int i=ar.size()-1;i>=0;--i){ CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; if(p->strName==pszName){ return p; } } return NULL;}String CProperties::MakeCommandString(LPCTSTR pszPrefix/*=_T("-")*/) const{ String strResult; bool bFirst=true; for(int i=ar.size()-1;i>=0;--i){ String str; CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; switch(p->Type){ case CProperties::CProperty::Integer: case CProperties::CProperty::Bool: case CProperties::CProperty::Char: case CProperties::CProperty::Short: str.Format(_T("%s%s=%u"),pszPrefix,(LPCTSTR)p->strName,p->GetValue()); break; case CProperties::CProperty::szString: case CProperties::CProperty::GPString: case CProperties::CProperty::Float: case CProperties::CProperty::Double: case CProperties::CProperty::Void: str.Format(_T("%s%s=\"%s\""),pszPrefix,(LPCTSTR)p->strName,(LPCTSTR)p->GetStringValue()); break; } if(!bFirst){ strResult+=_TCHAR(' '); } bFirst=false; strResult+=str; } return strResult;} bool CProperties::CreatePathToFile(LPCTSTR pszDir) { // Create intermediate directories #ifdef _WIN32 const TCHAR cSep='\\'; #else // UNIX const TCHAR cSep='/'; #endif for(LPCTSTR c=_tcschr(pszDir,cSep);c;c=_tcschr(c+1,cSep)){ #ifdef _WIN32 if(c==pszDir+2 && _istalpha(pszDir[0]) && _TCHAR(':')==pszDir[1]){ continue; // don't attempt to create "C:" } #endif String strDir(pszDir,c-pszDir); struct _stat buf; if(!(0==_tstat(strDir,&buf) && (S_IFDIR&buf.st_mode))){ // Need to create directory bool b=(0==_tmkdir(strDir)); //TRACE(_T("Create directory %s rc=%d\n"),(LPCTSTR)strDir,b); if(!b){ return false; } } } return true;}bool CProperties::SaveToFile(LPCTSTR pszFileName,LPCTSTR pszPrefix) const{ CreatePathToFile(pszFileName); // If we have a prefix, we assume we're tagging on to an existing file FILE *f=_tfopen(pszFileName,(_TCHAR('\0')==*pszPrefix)?_T("wt"):_T("at")); if(f){ for(int i=ar.size()-1;i>=0;--i){ CProperties::CProperty *p=(CProperties::CProperty *)ar[i]; String str(pszPrefix); str+=p->strName; str+=_TCHAR('='); switch(p->Type){ case CProperties::CProperty::Integer: case CProperties::CProperty::Bool: case CProperties::CProperty::Char: case CProperties::CProperty::Short: {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -