ENH: Modify API a little bit to allow arbitrary length values. Encode certain characters. Rename UNIX registry to FILE registry. More testing

This commit is contained in:
Andy Cedilnik 2005-09-16 13:38:25 -04:00
parent cd510bf3ac
commit 9b486bacfc
3 changed files with 165 additions and 65 deletions

View File

@ -38,7 +38,7 @@ public:
virtual ~RegistryHelper(); virtual ~RegistryHelper();
// Read a value from the registry. // Read a value from the registry.
virtual bool ReadValue(const char *key, char *value); virtual bool ReadValue(const char *key, const char **value);
// Delete a key from the registry. // Delete a key from the registry.
virtual bool DeleteKey(const char *key); virtual bool DeleteKey(const char *key);
@ -68,6 +68,10 @@ public:
void SetGlobalScope(bool b); void SetGlobalScope(bool b);
bool GetGlobalScope(); bool GetGlobalScope();
kwsys_stl::string EncodeKey(const char* str);
kwsys_stl::string EncodeValue(const char* str);
kwsys_stl::string DecodeValue(const char* str);
protected: protected:
bool m_Changed; bool m_Changed;
kwsys_stl::string m_TopLevel; kwsys_stl::string m_TopLevel;
@ -79,13 +83,14 @@ protected:
// Strip trailing and ending spaces. // Strip trailing and ending spaces.
char *Strip(char *str); char *Strip(char *str);
void SetSubKey(const char* sk); void SetSubKey(const char* sk);
char *CreateKey(const char *key); kwsys_stl::string CreateKey(const char *key);
typedef kwsys_stl::map<kwsys_stl::string, kwsys_stl::string> StringToStringMap; typedef kwsys_stl::map<kwsys_stl::string, kwsys_stl::string> StringToStringMap;
StringToStringMap EntriesMap; StringToStringMap EntriesMap;
kwsys_stl::string m_SubKey; kwsys_stl::string m_SubKey;
bool m_Empty; bool m_Empty;
bool m_SubKeySpecified; bool m_SubKeySpecified;
kwsys_stl::string m_HomeDirectory;
Registry::RegistryType m_RegistryType; Registry::RegistryType m_RegistryType;
}; };
@ -191,7 +196,7 @@ bool Registry::Close()
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool Registry::ReadValue(const char *subkey, bool Registry::ReadValue(const char *subkey,
const char *key, const char *key,
char *value) const char **value)
{ {
*value = 0; *value = 0;
bool res = true; bool res = true;
@ -388,16 +393,21 @@ bool RegistryHelper::Open(const char *toplevel, const char *subkey,
return (res != 0); return (res != 0);
} }
#endif #endif
if ( m_RegistryType == Registry::UNIX_REGISTRY ) if ( m_RegistryType == Registry::FILE_REGISTRY )
{ {
bool res = false; bool res = false;
int cc; int cc;
kwsys_ios::ostringstream str; kwsys_ios::ostringstream str;
if ( !getenv("HOME") ) const char* homeDirectory;
if ( (homeDirectory = getenv("HOME")) == 0 )
{ {
return false; if ( (homeDirectory = getenv("USERPROFILE")) == 0 )
{
return false;
}
} }
str << getenv("HOME") << "/." << toplevel << "rc"; m_HomeDirectory = homeDirectory;
str << m_HomeDirectory << "/." << toplevel << "rc";
if ( readonly == Registry::READWRITE ) if ( readonly == Registry::READWRITE )
{ {
kwsys_ios::ofstream ofs( str.str().c_str(), kwsys_ios::ios::out|kwsys_ios::ios::app ); kwsys_ios::ofstream ofs( str.str().c_str(), kwsys_ios::ios::out|kwsys_ios::ios::app );
@ -450,7 +460,7 @@ bool RegistryHelper::Open(const char *toplevel, const char *subkey,
char *value = line + cc + 1; char *value = line + cc + 1;
char *nkey = this->Strip(key); char *nkey = this->Strip(key);
char *nvalue = this->Strip(value); char *nvalue = this->Strip(value);
this->EntriesMap[nkey] = nvalue; this->EntriesMap[nkey] = this->DecodeValue(nvalue);
m_Empty = 0; m_Empty = 0;
delete [] key; delete [] key;
found = 1; found = 1;
@ -477,7 +487,7 @@ bool RegistryHelper::Close()
return (res != 0); return (res != 0);
} }
#endif #endif
if ( m_RegistryType == Registry::UNIX_REGISTRY ) if ( m_RegistryType == Registry::FILE_REGISTRY )
{ {
if ( !m_Changed ) if ( !m_Changed )
{ {
@ -490,11 +500,7 @@ bool RegistryHelper::Close()
} }
kwsys_ios::ostringstream str; kwsys_ios::ostringstream str;
if ( !getenv("HOME") ) str << m_HomeDirectory << "/." << this->GetTopLevel() << "rc";
{
return false;
}
str << getenv("HOME") << "/." << this->GetTopLevel() << "rc";
kwsys_ios::ofstream *ofs = new kwsys_ios::ofstream(str.str().c_str(), kwsys_ios::ios::out); kwsys_ios::ofstream *ofs = new kwsys_ios::ofstream(str.str().c_str(), kwsys_ios::ios::out);
if ( !ofs ) if ( !ofs )
{ {
@ -507,7 +513,7 @@ bool RegistryHelper::Close()
} }
*ofs << "# This file is automatically generated by the application" << kwsys_ios::endl *ofs << "# This file is automatically generated by the application" << kwsys_ios::endl
<< "# If you change any lines or add new lines, note that all" << kwsys_ios::endl << "# If you change any lines or add new lines, note that all" << kwsys_ios::endl
<< "# coments and empty lines will be deleted. Every line has" << kwsys_ios::endl << "# comments and empty lines will be deleted. Every line has" << kwsys_ios::endl
<< "# to be in format: " << kwsys_ios::endl << "# to be in format: " << kwsys_ios::endl
<< "# key = value" << kwsys_ios::endl << "# key = value" << kwsys_ios::endl
<< "#" << kwsys_ios::endl; << "#" << kwsys_ios::endl;
@ -535,58 +541,76 @@ bool RegistryHelper::Close()
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool RegistryHelper::ReadValue(const char *skey, char *value) bool RegistryHelper::ReadValue(const char *skey, const char **value)
{ {
#ifdef _WIN32 #ifdef _WIN32
if ( m_RegistryType == Registry::WIN32_REGISTRY) if ( m_RegistryType == Registry::WIN32_REGISTRY)
{ {
kwsys_stl::string key = this->CreateKey( skey );
if ( key.empty() )
{
return false;
}
int res = 1; int res = 1;
DWORD dwType, dwSize; DWORD dwType, dwSize;
dwType = REG_SZ; dwType = REG_SZ;
dwSize = Registry_BUFFER_SIZE; dwSize = Registry_BUFFER_SIZE;
char buffer[1024]; // Replace with RegQueryInfoKey
res = ( RegQueryValueEx(this->HKey, skey, NULL, &dwType, res = ( RegQueryValueEx(this->HKey, skey, NULL, &dwType,
(BYTE *)value, &dwSize) == ERROR_SUCCESS ); (BYTE *)buffer, &dwSize) == ERROR_SUCCESS );
return (res != 0); if ( !res )
}
#endif
if ( m_RegistryType == Registry::UNIX_REGISTRY )
{
bool res = false;
char *key = this->CreateKey( skey );
if ( !key )
{ {
return false; return false;
} }
this->EntriesMap[key] = buffer;
RegistryHelper::StringToStringMap::iterator it
= this->EntriesMap.find(key);
*value = it->second.c_str();
return true;
}
#endif
if ( m_RegistryType == Registry::FILE_REGISTRY )
{
bool res = false;
kwsys_stl::string key = this->CreateKey( skey );
if ( key.empty() )
{
return false;
}
RegistryHelper::StringToStringMap::iterator it RegistryHelper::StringToStringMap::iterator it
= this->EntriesMap.find(key); = this->EntriesMap.find(key);
if ( it != this->EntriesMap.end() ) if ( it != this->EntriesMap.end() )
{ {
strcpy(value, it->second.c_str()); *value = it->second.c_str();
res = true; res = true;
} }
delete [] key;
return res; return res;
} }
return false; return false;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool RegistryHelper::DeleteKey(const char* key) bool RegistryHelper::DeleteKey(const char* skey)
{ {
#ifdef _WIN32 #ifdef _WIN32
if ( m_RegistryType == Registry::WIN32_REGISTRY) if ( m_RegistryType == Registry::WIN32_REGISTRY)
{ {
int res = 1; int res = 1;
res = ( RegDeleteKey( this->HKey, key ) == ERROR_SUCCESS ); res = ( RegDeleteKey( this->HKey, skey ) == ERROR_SUCCESS );
return (res != 0); return (res != 0);
} }
#endif #endif
if ( m_RegistryType == Registry::UNIX_REGISTRY ) if ( m_RegistryType == Registry::FILE_REGISTRY )
{ {
(void)key; kwsys_stl::string key = this->CreateKey( skey );
bool res = false; if ( key.empty() )
return res; {
return false;
}
this->EntriesMap.erase(key);
return true;
} }
return false; return false;
} }
@ -602,15 +626,14 @@ bool RegistryHelper::DeleteValue(const char *skey)
return (res != 0); return (res != 0);
} }
#endif #endif
if ( m_RegistryType == Registry::UNIX_REGISTRY ) if ( m_RegistryType == Registry::FILE_REGISTRY )
{ {
char *key = this->CreateKey( skey ); kwsys_stl::string key = this->CreateKey( skey );
if ( !key ) if ( key.empty() )
{ {
return false; return false;
} }
this->EntriesMap.erase(key); this->EntriesMap.erase(key);
delete [] key;
return true; return true;
} }
return false; return false;
@ -630,34 +653,32 @@ bool RegistryHelper::SetValue(const char *skey, const char *value)
return (res != 0); return (res != 0);
} }
#endif #endif
if ( m_RegistryType == Registry::UNIX_REGISTRY ) if ( m_RegistryType == Registry::FILE_REGISTRY )
{ {
char *key = this->CreateKey( skey ); kwsys_stl::string key = this->CreateKey( skey );
if ( !key ) if ( key.empty() )
{ {
return 0; return 0;
} }
this->EntriesMap[key] = value; this->EntriesMap[key] = this->EncodeValue(value);
delete [] key;
return 1; return 1;
} }
return false; return false;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
char *RegistryHelper::CreateKey( const char *key ) kwsys_stl::string RegistryHelper::CreateKey( const char *key )
{ {
char *newkey;
if ( !m_SubKeySpecified || m_SubKey.empty() || !key ) if ( !m_SubKeySpecified || m_SubKey.empty() || !key )
{ {
return 0; return "";
} }
int len = strlen(this->m_SubKey.c_str()) + strlen(key) + 1; kwsys_ios::ostringstream ostr;
newkey = new char[ len+1 ] ; ostr << this->EncodeKey(this->m_SubKey.c_str()) << "\\" << this->EncodeKey(key);
::sprintf(newkey, "%s\\%s", this->m_SubKey.c_str(), key); return ostr.str();
return newkey;
} }
//----------------------------------------------------------------------------
void RegistryHelper::SetSubKey(const char* sk) void RegistryHelper::SetSubKey(const char* sk)
{ {
if ( !sk ) if ( !sk )
@ -715,4 +736,74 @@ bool RegistryHelper::GetGlobalScope()
return m_GlobalScope; return m_GlobalScope;
} }
//----------------------------------------------------------------------------
kwsys_stl::string RegistryHelper::EncodeKey(const char* str)
{
kwsys_ios::ostringstream ostr;
while ( *str )
{
switch ( *str )
{
case '%': case '=': case '\n': case '\r': case '\t': case ' ':
char buffer[4];
sprintf(buffer, "%%%02X", *str);
ostr << buffer;
break;
default:
ostr << *str;
}
str ++;
}
return ostr.str();
}
//----------------------------------------------------------------------------
kwsys_stl::string RegistryHelper::EncodeValue(const char* str)
{
kwsys_ios::ostringstream ostr;
while ( *str )
{
switch ( *str )
{
case '%': case '=': case '\n': case '\r': case '\t':
char buffer[4];
sprintf(buffer, "%%%02X", *str);
ostr << buffer;
break;
default:
ostr << *str;
}
str ++;
}
return ostr.str();
}
//----------------------------------------------------------------------------
kwsys_stl::string RegistryHelper::DecodeValue(const char* str)
{
kwsys_ios::ostringstream ostr;
while ( *str )
{
int val;
switch ( *str )
{
case '%':
if ( *(str+1) && *(str+2) && sscanf(str+1, "%x", &val) == 1 )
{
ostr << (char)val;
str += 2;
}
else
{
ostr << *str;
}
break;
default:
ostr << *str;
}
str ++;
}
return ostr.str();
}
} // namespace KWSYS_NAMESPACE } // namespace KWSYS_NAMESPACE

View File

@ -39,19 +39,19 @@ public:
#ifdef _WIN32 #ifdef _WIN32
WIN32_REGISTRY, WIN32_REGISTRY,
#endif #endif
UNIX_REGISTRY FILE_REGISTRY
}; };
#ifdef _WIN32 #ifdef _WIN32
Registry(RegistryType registryType = WIN32_REGISTRY); Registry(RegistryType registryType = WIN32_REGISTRY);
#else #else
Registry(RegistryType registryType = UNIX_REGISTRY); Registry(RegistryType registryType = FILE_REGISTRY);
#endif #endif
virtual ~Registry(); virtual ~Registry();
//! Read a value from the registry. //! Read a value from the registry.
bool ReadValue(const char *subkey, const char *key, char *value); bool ReadValue(const char *subkey, const char *key, const char **value);
//! Delete a key from the registry. //! Delete a key from the registry.
bool DeleteKey(const char *subkey, const char *key); bool DeleteKey(const char *subkey, const char *key);

View File

@ -53,14 +53,14 @@ int main(int, char**)
IFT(reg.SetValue("TestSubkey", "TestKey3", "Test Value 3"), res); IFT(reg.SetValue("TestSubkey", "TestKey3", "Test Value 3"), res);
IFT(reg.SetValue("TestSubkey2", "TestKey4", "Test Value 4"), res); IFT(reg.SetValue("TestSubkey2", "TestKey4", "Test Value 4"), res);
char buffer[1024]; const char *buffer;
IFT(reg.ReadValue("TestSubkey", "TestKey1", buffer), res); IFT(reg.ReadValue("TestSubkey", "TestKey1", &buffer), res);
CHE(buffer, "Test Value 1", res); CHE(buffer, "Test Value 1", res);
IFT(reg.ReadValue("TestSubkey1", "TestKey2", buffer), res); IFT(reg.ReadValue("TestSubkey1", "TestKey2", &buffer), res);
CHE(buffer, "Test Value 2", res); CHE(buffer, "Test Value 2", res);
IFT(reg.ReadValue("TestSubkey", "TestKey3", buffer), res); IFT(reg.ReadValue("TestSubkey", "TestKey3", &buffer), res);
CHE(buffer, "Test Value 3", res); CHE(buffer, "Test Value 3", res);
IFT(reg.ReadValue("TestSubkey2", "TestKey4", buffer), res); IFT(reg.ReadValue("TestSubkey2", "TestKey4", &buffer), res);
CHE(buffer, "Test Value 4", res); CHE(buffer, "Test Value 4", res);
IFT(reg.SetValue("TestSubkey", "TestKey1", "New Test Value 1"), res); IFT(reg.SetValue("TestSubkey", "TestKey1", "New Test Value 1"), res);
@ -68,23 +68,32 @@ int main(int, char**)
IFT(reg.SetValue("TestSubkey", "TestKey3", "New Test Value 3"), res); IFT(reg.SetValue("TestSubkey", "TestKey3", "New Test Value 3"), res);
IFT(reg.SetValue("TestSubkey2", "TestKey4", "New Test Value 4"), res); IFT(reg.SetValue("TestSubkey2", "TestKey4", "New Test Value 4"), res);
IFT(reg.ReadValue("TestSubkey", "TestKey1", buffer), res); IFT(reg.ReadValue("TestSubkey", "TestKey1", &buffer), res);
CHE(buffer, "New Test Value 1", res); CHE(buffer, "New Test Value 1", res);
IFT(reg.ReadValue("TestSubkey1", "TestKey2", buffer), res); IFT(reg.ReadValue("TestSubkey1", "TestKey2", &buffer), res);
CHE(buffer, "New Test Value 2", res); CHE(buffer, "New Test Value 2", res);
IFT(reg.ReadValue("TestSubkey", "TestKey3", buffer), res); IFT(reg.ReadValue("TestSubkey", "TestKey3", &buffer), res);
CHE(buffer, "New Test Value 3", res); CHE(buffer, "New Test Value 3", res);
IFT(reg.ReadValue("TestSubkey2", "TestKey4", buffer), res); IFT(reg.ReadValue("TestSubkey2", "TestKey4", &buffer), res);
CHE(buffer, "New Test Value 4", res); CHE(buffer, "New Test Value 4", res);
IFT( reg.DeleteValue("TestSubkey", "TestKey1"), res); IFT( reg.DeleteValue("TestSubkey", "TestKey1"), res);
IFNT(reg.ReadValue( "TestSubkey", "TestKey1", buffer), res); IFNT(reg.ReadValue( "TestSubkey", "TestKey1", &buffer), res);
IFT( reg.DeleteValue("TestSubkey1", "TestKey2"), res); IFT( reg.DeleteValue("TestSubkey1", "TestKey2"), res);
IFNT(reg.ReadValue( "TestSubkey1", "TestKey2", buffer), res); IFNT(reg.ReadValue( "TestSubkey1", "TestKey2", &buffer), res);
IFT( reg.DeleteValue("TestSubkey", "TestKey3"), res); IFT( reg.DeleteValue("TestSubkey", "TestKey3"), res);
IFNT(reg.ReadValue( "TestSubkey", "TestKey3", buffer), res); IFNT(reg.ReadValue( "TestSubkey", "TestKey3", &buffer), res);
IFT( reg.DeleteValue("TestSubkey2", "TestKey4"), res); IFT( reg.DeleteValue("TestSubkey2", "TestKey4"), res);
IFNT(reg.ReadValue( "TestSubkey2", "TestKey5", buffer), res); IFNT(reg.ReadValue( "TestSubkey2", "TestKey5", &buffer), res);
const char* longStringWithNewLines = "Value with embedded CR and LF characters CR='\015' LF='\012' CRLF='\015\012'";
IFT(reg.SetValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName", "TestKey1", longStringWithNewLines), res);
IFT(reg.ReadValue("TestSubkeyWithVeryLongInFactSoLongItsHardToImagineAnybodyWouldReallyDoItLongName", "TestKey1", &buffer), res);
CHE(buffer, longStringWithNewLines, res);
IFT(reg.SetValue("TestSubkeyWith = EqualSignChar", "TestKey = 1", "Some value"), res);
IFT(reg.ReadValue("TestSubkeyWith = EqualSignChar", "TestKey = 1", &buffer), res);
CHE(buffer, "Some value", res);
if ( res ) if ( res )
{ {