Index: src/libchcore/ConfigNodeContainer.cpp =================================================================== diff -u -r2fe97a93f21771d75901d4b6559057d1ea055104 -r5324d0ca7af614cb066df1f121a7a338c4f7d7ed --- src/libchcore/ConfigNodeContainer.cpp (.../ConfigNodeContainer.cpp) (revision 2fe97a93f21771d75901d4b6559057d1ea055104) +++ src/libchcore/ConfigNodeContainer.cpp (.../ConfigNodeContainer.cpp) (revision 5324d0ca7af614cb066df1f121a7a338c4f7d7ed) @@ -512,7 +512,7 @@ } // same ID - add new element to existing property tree node - treeSubnodes.put(strSubnodeName.c_str(), iter->m_strValue); + treeSubnodes.put(strSubnodeName.c_str(), iter->m_strValue.Get()); } else { @@ -524,7 +524,7 @@ } // no bracket in the node name - this is just a standard entry - rTree.add(strNodeName.c_str(), iter->m_strValue); + rTree.add(strNodeName.c_str(), iter->m_strValue.Get()); } } Index: src/libchcore/ConfigNodeContainer.h =================================================================== diff -u -r2fe97a93f21771d75901d4b6559057d1ea055104 -r5324d0ca7af614cb066df1f121a7a338c4f7d7ed --- src/libchcore/ConfigNodeContainer.h (.../ConfigNodeContainer.h) (revision 2fe97a93f21771d75901d4b6559057d1ea055104) +++ src/libchcore/ConfigNodeContainer.h (.../ConfigNodeContainer.h) (revision 5324d0ca7af614cb066df1f121a7a338c4f7d7ed) @@ -207,7 +207,7 @@ } else { - m_mic.insert(ConfigNode(++m_stLastObjectID, pszPropName, 0, boost::lexical_cast(bValue).c_str())); + m_mic.insert(ConfigNode(++m_stLastObjectID, pszPropName, 0, bValue ? _T("true") : _T("false"))); return true; } } Index: src/libchcore/TConfig.cpp =================================================================== diff -u -r2fe97a93f21771d75901d4b6559057d1ea055104 -r5324d0ca7af614cb066df1f121a7a338c4f7d7ed --- src/libchcore/TConfig.cpp (.../TConfig.cpp) (revision 2fe97a93f21771d75901d4b6559057d1ea055104) +++ src/libchcore/TConfig.cpp (.../TConfig.cpp) (revision 5324d0ca7af614cb066df1f121a7a338c4f7d7ed) @@ -350,6 +350,11 @@ return *this; } +TConfig& TConfig::SetValue(PCTSTR pszPropName, PCTSTR pszValue) +{ + return SetValue(pszPropName, TString(pszValue)); +} + bool TConfig::GetValue(PCTSTR pszPropName, TStringArray& rvValues) const { return GetImpl()->GetArrayValueNoDefault(pszPropName, rvValues); Index: src/libchcore/TConfig.h =================================================================== diff -u -rfc67a825635691930b3ac00dc95b16e59f3d2fae -r5324d0ca7af614cb066df1f121a7a338c4f7d7ed --- src/libchcore/TConfig.h (.../TConfig.h) (revision fc67a825635691930b3ac00dc95b16e59f3d2fae) +++ src/libchcore/TConfig.h (.../TConfig.h) (revision 5324d0ca7af614cb066df1f121a7a338c4f7d7ed) @@ -51,17 +51,15 @@ // read/write void Read(PCTSTR pszFile); void Write(); + void SetFilePath(PCTSTR pszPath); + void ReadFromString(const TString& strInput); + void WriteToString(TString& strOutput); + void Store(const ISerializerContainerPtr& spContainer) const; void Load(const ISerializerContainerPtr& spContainer) const; - void InitColumns(const ISerializerContainerPtr& spContainer) const; - void ReadFromString(const TString& strInput); - void WriteToString(TString& strOutput); - - void SetFilePath(PCTSTR pszPath); - // value setting/retrieval bool GetBool(PCTSTR pszPropName, bool bDefault = false) const; bool GetValue(PCTSTR pszPropName, bool& bValue) const; @@ -71,27 +69,28 @@ bool GetValue(PCTSTR pszPropName, int& iValue) const; TConfig& SetValue(PCTSTR pszPropName, int iValue); - unsigned int GetUInt(PCTSTR pszPropName, unsigned int uiDefault) const; + unsigned int GetUInt(PCTSTR pszPropName, unsigned int uiDefault = 0) const; bool GetValue(PCTSTR pszPropName, unsigned int& uiValue) const; TConfig& SetValue(PCTSTR pszPropName, unsigned int uiValue); - long long GetLongLong(PCTSTR pszPropName, long long llDefault) const; + long long GetLongLong(PCTSTR pszPropName, long long llDefault = 0) const; bool GetValue(PCTSTR pszPropName, long long& llValue) const; TConfig& SetValue(PCTSTR pszPropName, long long llValue); - unsigned long long GetULongLong(PCTSTR pszPropName, unsigned long long ullDefault) const; + unsigned long long GetULongLong(PCTSTR pszPropName, unsigned long long ullDefault = 0) const; bool GetValue(PCTSTR pszPropName, unsigned long long& ullValue) const; TConfig& SetValue(PCTSTR pszPropName, unsigned long long ullValue); - double GetDouble(PCTSTR pszPropName, double dDefault) const; + double GetDouble(PCTSTR pszPropName, double dDefault = 0.0) const; bool GetValue(PCTSTR pszPropName, double& dValue) const; TConfig& SetValue(PCTSTR pszPropName, double dValue); - TString GetString(PCTSTR pszPropName, const TString& strDefault) const; + TString GetString(PCTSTR pszPropName, const TString& strDefault = TString()) const; bool GetValue(PCTSTR pszPropName, TString& rstrValue) const; TConfig& SetValue(PCTSTR pszPropName, const TString& strValue); + TConfig& SetValue(PCTSTR pszPropName, PCTSTR pszValue); - TSmartPath GetPath(PCTSTR pszPropName, const TSmartPath& pathDefault) const; + TSmartPath GetPath(PCTSTR pszPropName, const TSmartPath& pathDefault = TSmartPath()) const; bool GetValue(PCTSTR pszPropName, TSmartPath& rpathValue) const; TConfig& SetValue(PCTSTR pszPropName, const TSmartPath& pathValue); Index: src/libchcore/Tests/TestsTConfig.cpp =================================================================== diff -u --- src/libchcore/Tests/TestsTConfig.cpp (revision 0) +++ src/libchcore/Tests/TestsTConfig.cpp (revision 5324d0ca7af614cb066df1f121a7a338c4f7d7ed) @@ -0,0 +1,299 @@ +#include "stdafx.h" +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include +#include +#include "../TConfig.h" + +using namespace chcore; + +namespace +{ + std::wstring GetTmpPath() + { + TCHAR szPath[_MAX_PATH]; + GetTempPath(_MAX_PATH, szPath); + + TCHAR szFilename[_MAX_PATH]; + GetTempFileName(szPath, _T("TempCfg"), 0, szFilename); + + return szFilename; + } +} + +// fixtures +class FileWithConfigurationFixture : public ::testing::Test +{ +protected: + virtual void SetUp() + { + m_strTempFilePath = GetTmpPath(); + + std::wofstream outFile(m_strTempFilePath.c_str(), std::wofstream::out | std::wofstream::binary); + + std::locale utf8locale(std::locale(), new std::codecvt_byname ("en_US.UTF-8")); + outFile.imbue(utf8locale); + + std::wstring wstrData = + L"\ +\ + \ + 30000\ + \ + \ + true\ + <WINDOWS>\\media\\chord.wav\ + <WINDOWS>\\media\\ding.wav\ + \ + \ + c:\\Windows\\System32\ + d:\\Movies\ + x:\\Music\ + s:\\projects\\ch-rw\ + \ + \ + \ + \ + <WINDOWS>\\FirstPath\ + FirstName\ + \ + \ + <WINDOWS>\\SecondPath\ + SecondName\ + \ + \ + \ +"; + + outFile << wstrData; + outFile.flush(); + } + + virtual void TearDown() + { + DeleteFile(m_strTempFilePath.c_str()); + } + + std::wstring m_strTempFilePath; +}; + +/////////////////////////////////////////////////////////////////////////// +// read from/write to file + +TEST_F(FileWithConfigurationFixture, ReadFromFile) +{ + TConfig cfg; + cfg.Read(m_strTempFilePath.c_str()); + + EXPECT_EQ(true, cfg.GetBool(_T("CHConfig.Core.Notifications.Sounds.Enable"), false)); + EXPECT_EQ(30000, cfg.GetInt(_T("CHConfig.Core.AutosaveInterval"), 0)); + EXPECT_EQ(TString(_T("\\media\\ding.wav")), cfg.GetString(_T("CHConfig.Core.Notifications.Sounds.FinishedSoundPath"), _T(""))); +} + +TEST(TConfigTests, WriteToFile) +{ + TConfig cfg; + cfg.SetValue(_T("CHConfig.Core.Notifications.Sounds.Enable"), true); + cfg.SetValue(_T("CHConfig.Core.AutosaveInterval"), 10000); + cfg.SetValue(_T("CHConfig.Core.Notifications.Sounds.FinishedSoundPath"), _T("c:\\Users\\NewUser")); + + std::wstring strPath(GetTmpPath()); + cfg.SetFilePath(strPath.c_str()); + + cfg.Write(); + + std::wstring wstrData; + std::wifstream inFile(strPath.c_str(), std::wofstream::in | std::wofstream::binary); + + std::locale utf8locale(std::locale(), new std::codecvt_byname ("en_US.UTF-8")); + inFile.imbue(utf8locale); + + std::wstringstream wstrStream; + wstrStream << inFile.rdbuf(); + + wstrData = wstrStream.str(); + + DeleteFile(strPath.c_str()); + + EXPECT_EQ(_T("\n\ +10000truec:\\Users\\NewUser"), wstrData); +} + +/////////////////////////////////////////////////////////////////////////// +// store in/load from string +TEST(TConfigTests, ReadFromString) +{ + std::wstring wstrData = + L"\ +\ + \ + 30000\ + \ + \ + true\ + <WINDOWS>\\media\\chord.wav\ + <WINDOWS>\\media\\ding.wav\ + \ + \ + c:\\Windows\\System32\ + d:\\Movies\ + x:\\Music\ + s:\\projects\\ch-rw\ + \ + \ + \ + \ + <WINDOWS>\\FirstPath\ + FirstName\ + \ + \ + <WINDOWS>\\SecondPath\ + SecondName\ + \ + \ + \ +"; + + TConfig cfg; + cfg.ReadFromString(TString(wstrData.c_str())); + + EXPECT_EQ(true, cfg.GetBool(_T("CHConfig.Core.Notifications.Sounds.Enable"), false)); + EXPECT_EQ(30000, cfg.GetInt(_T("CHConfig.Core.AutosaveInterval"), 0)); + EXPECT_EQ(TString(_T("\\media\\ding.wav")), cfg.GetString(_T("CHConfig.Core.Notifications.Sounds.FinishedSoundPath"), _T(""))); +} + +TEST(TConfigTests, WriteToString) +{ + TConfig cfg; + cfg.SetValue(_T("CHConfig.Core.Notifications.Sounds.Enable"), true); + cfg.SetValue(_T("CHConfig.Core.AutosaveInterval"), 10000); + cfg.SetValue(_T("CHConfig.Core.Notifications.Sounds.FinishedSoundPath"), _T("c:\\Users\\NewUser")); + + TString strData; + cfg.WriteToString(strData); + + EXPECT_EQ(TString(_T("\n\ +10000truec:\\Users\\NewUser")), strData); +} + +/////////////////////////////////////////////////////////////////////////// +// value get/set + +// bool + +TEST(TConfigTests, GetSetBool) +{ + TConfig cfg; + + // store data in config + cfg.SetValue(_T("Root.Node.Value1"), true); + cfg.SetValue(_T("Root.Node.Value2"), false); + + // check if stored successfully (typed get) + EXPECT_EQ(true, cfg.GetBool(_T("Root.Node.Value1"))); + EXPECT_EQ(false, cfg.GetBool(_T("Root.Node.Value2"))); + + // check if stored successfully (GetValue) + bool bValue = false; + cfg.GetValue(_T("Root.Node.Value1"), bValue); + EXPECT_EQ(true, bValue); + cfg.GetValue(_T("Root.Node.Value2"), bValue); + EXPECT_EQ(false, bValue); +} + +TEST(TConfigTests, GetSetBoolExport) +{ + TConfig cfg; + + TString strXmlData(_T("\n\ +truefalse")); + + // store in string + cfg.ReadFromString(strXmlData); + + EXPECT_EQ(true, cfg.GetBool(_T("Root.Node.Value1"))); + EXPECT_EQ(false, cfg.GetBool(_T("Root.Node.Value2"))); + + TString strWriteXmlData; + cfg.WriteToString(strWriteXmlData); + + EXPECT_EQ(strXmlData, strWriteXmlData); +} + +TEST(TConfigTests, GetSetInt) +{ + TConfig cfg; + + // store data in config + cfg.SetValue(_T("Root.Node.Value1"), 1489); + cfg.SetValue(_T("Root.Node.Value2"), -12987); + + // check if stored successfully (typed get) + EXPECT_EQ(1489, cfg.GetInt(_T("Root.Node.Value1"))); + EXPECT_EQ(-12987, cfg.GetInt(_T("Root.Node.Value2"))); + + // check if stored successfully (GetValue) + int iValue = 0; + cfg.GetValue(_T("Root.Node.Value1"), iValue); + EXPECT_EQ(1489, iValue); + cfg.GetValue(_T("Root.Node.Value2"), iValue); + EXPECT_EQ(-12987, iValue); +} + +TEST(TConfigTests, GetSetIntExport) +{ + TConfig cfg; + + TString strXmlData(_T("\n\ +1489-12987")); + + // store in string + cfg.ReadFromString(strXmlData); + + EXPECT_EQ(1489, cfg.GetInt(_T("Root.Node.Value1"))); + EXPECT_EQ(-12987, cfg.GetInt(_T("Root.Node.Value2"))); + + TString strWriteXmlData; + cfg.WriteToString(strWriteXmlData); + + EXPECT_EQ(strXmlData, strWriteXmlData); +} + +TEST(TConfigTests, GetSetUInt) +{ + TConfig cfg; + + // store data in config + cfg.SetValue(_T("Root.Node.Value1"), (unsigned int)1489); + cfg.SetValue(_T("Root.Node.Value2"), (unsigned int)12987); + + // check if stored successfully (typed get) + EXPECT_EQ(1489, cfg.GetUInt(_T("Root.Node.Value1"))); + EXPECT_EQ(12987, cfg.GetUInt(_T("Root.Node.Value2"))); + + // check if stored successfully (GetValue) + int value = 0; + cfg.GetValue(_T("Root.Node.Value1"), value); + EXPECT_EQ(1489, value); + cfg.GetValue(_T("Root.Node.Value2"), value); + EXPECT_EQ(12987, value); +} + +TEST(TConfigTests, GetSetUIntExport) +{ + TConfig cfg; + + TString strXmlData(_T("\n\ +148912987")); + + // store in string + cfg.ReadFromString(strXmlData); + + EXPECT_EQ(1489, cfg.GetInt(_T("Root.Node.Value1"))); + EXPECT_EQ(12987, cfg.GetInt(_T("Root.Node.Value2"))); + + TString strWriteXmlData; + cfg.WriteToString(strWriteXmlData); + + EXPECT_EQ(strXmlData, strWriteXmlData); +} Index: src/libchcore/libchcore.vc90.vcproj =================================================================== diff -u -r7b830c34855c8aaa81aac2c6e0ca0fa6bae95e66 -r5324d0ca7af614cb066df1f121a7a338c4f7d7ed --- src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision 7b830c34855c8aaa81aac2c6e0ca0fa6bae95e66) +++ src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision 5324d0ca7af614cb066df1f121a7a338c4f7d7ed) @@ -1623,6 +1623,42 @@ + + + + + + + + + + + + + +