Index: src/ch/CfgProperties.h =================================================================== diff -u -N -r3fc1109991e7311d6b1e34ef0b730f9b4e1fd42a -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/CfgProperties.h (.../CfgProperties.h) (revision 3fc1109991e7311d6b1e34ef0b730f9b4e1fd42a) +++ src/ch/CfgProperties.h (.../CfgProperties.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -23,7 +23,7 @@ #include "TTaskConfiguration.h" -class TConfig; +namespace chcore { class TConfig; } // properties definitions enum ECHProperties @@ -250,24 +250,24 @@ // Properties retrieval template -typename PropData::value_type GetPropValue(const TConfig& rConfig) +typename PropData::value_type GetPropValue(const chcore::TConfig& rConfig) { typename PropData::value_type tValue; - if(!rConfig.GetValue(CString(PropData::GetPropertyNamePrefix()) + PropData::GetPropertyName(), tValue)) + if(!GetConfigValue(rConfig, CString(PropData::GetPropertyNamePrefix()) + PropData::GetPropertyName(), tValue)) tValue = PropData::GetDefaultValue(); return tValue; } template -bool GetPropValue(const TConfig& rConfig, typename PropData::value_type& rValue) +bool GetPropValue(const chcore::TConfig& rConfig, typename PropData::value_type& rValue) { - return rConfig.GetValue(CString(PropData::GetPropertyNamePrefix()) + PropData::GetPropertyName(), rValue); + return GetConfigValue(rConfig, CString(PropData::GetPropertyNamePrefix()) + PropData::GetPropertyName(), rValue); } template -void SetPropValue(TConfig& rConfig, const typename PropData::value_type& rValue) +void SetPropValue(chcore::TConfig& rConfig, const typename PropData::value_type& rValue) { - rConfig.SetValue(CString(PropData::GetPropertyNamePrefix()) + PropData::GetPropertyName(), rValue); + SetConfigValue(rConfig, CString(PropData::GetPropertyNamePrefix()) + PropData::GetPropertyName(), rValue); } #endif Index: src/ch/ClipboardMonitor.cpp =================================================================== diff -u -N -r69b48f0b4d7fad78f95854e95fca166014311474 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/ClipboardMonitor.cpp (.../ClipboardMonitor.cpp) (revision 69b48f0b4d7fad78f95854e95fca166014311474) +++ src/ch/ClipboardMonitor.cpp (.../ClipboardMonitor.cpp) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -73,7 +73,7 @@ UINT nFormat=RegisterClipboardFormat(_T("Preferred DropEffect")); UINT uiCounter=0, uiShutCounter=0; - TConfig& rConfig = GetConfig(); + chcore::TConfig& rConfig = GetConfig(); for(;;) { if (uiCounter == 0 && GetPropValue(rConfig) && IsClipboardFormatAvailable(CF_HDROP)) Index: src/ch/FileFilter.cpp =================================================================== diff -u -N -rc54aa186fda8c0af84325325276245e9d8fcfa26 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/FileFilter.cpp (.../FileFilter.cpp) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) +++ src/ch/FileFilter.cpp (.../FileFilter.cpp) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -19,7 +19,7 @@ #include "stdafx.h" #include "FileInfo.h" #include "FileFilter.h" -#include "TConfig.h" +#include "../libchcore/TConfig.h" //////////////////////////////////////////////////////////////////////////// bool _tcicmp(TCHAR c1, TCHAR c2) @@ -185,121 +185,121 @@ delete [] pszData; } -void CFileFilter::StoreInConfig(TConfig& rConfig) const +void CFileFilter::StoreInConfig(chcore::TConfig& rConfig) const { - rConfig.SetValue(_T("IncludeMask.Use"), m_bUseMask); - rConfig.SetValue(_T("IncludeMask.MaskList.Mask"), m_astrMask); + SetConfigValue(rConfig, _T("IncludeMask.Use"), m_bUseMask); + SetConfigValue(rConfig, _T("IncludeMask.MaskList.Mask"), m_astrMask); - rConfig.SetValue(_T("ExcludeMask.Use"), m_bUseExcludeMask); - rConfig.SetValue(_T("ExcludeMask.MaskList.Mask"), m_astrExcludeMask); + SetConfigValue(rConfig, _T("ExcludeMask.Use"), m_bUseExcludeMask); + SetConfigValue(rConfig, _T("ExcludeMask.MaskList.Mask"), m_astrExcludeMask); - rConfig.SetValue(_T("SizeA.Use"), m_bUseSize); - rConfig.SetValue(_T("SizeA.FilteringType"), m_iSizeType1); - rConfig.SetValue(_T("SizeA.Value"), m_ullSize1); - rConfig.SetValue(_T("SizeB.Use"), m_bUseSize2); - rConfig.SetValue(_T("SizeB.FilteringType"), m_iSizeType2); - rConfig.SetValue(_T("SizeB.Value"), m_ullSize2); + SetConfigValue(rConfig, _T("SizeA.Use"), m_bUseSize); + SetConfigValue(rConfig, _T("SizeA.FilteringType"), m_iSizeType1); + SetConfigValue(rConfig, _T("SizeA.Value"), m_ullSize1); + SetConfigValue(rConfig, _T("SizeB.Use"), m_bUseSize2); + SetConfigValue(rConfig, _T("SizeB.FilteringType"), m_iSizeType2); + SetConfigValue(rConfig, _T("SizeB.Value"), m_ullSize2); - rConfig.SetValue(_T("DateA.Use"), m_bUseDate); - rConfig.SetValue(_T("DateA.Type"), m_iDateType); // created/last modified/last accessed - rConfig.SetValue(_T("DateA.FilteringType"), m_iDateType1); // before/after - rConfig.SetValue(_T("DateA.EnableDatePart"), m_bDate1); - rConfig.SetValue(_T("DateA.DateValue"), m_tDate1.GetTime()); - rConfig.SetValue(_T("DateA.EnableTimePart"), m_bTime1); - rConfig.SetValue(_T("DateA.TimeValue"), m_tTime1.GetTime()); + SetConfigValue(rConfig, _T("DateA.Use"), m_bUseDate); + SetConfigValue(rConfig, _T("DateA.Type"), m_iDateType); // created/last modified/last accessed + SetConfigValue(rConfig, _T("DateA.FilteringType"), m_iDateType1); // before/after + SetConfigValue(rConfig, _T("DateA.EnableDatePart"), m_bDate1); + SetConfigValue(rConfig, _T("DateA.DateValue"), m_tDate1.GetTime()); + SetConfigValue(rConfig, _T("DateA.EnableTimePart"), m_bTime1); + SetConfigValue(rConfig, _T("DateA.TimeValue"), m_tTime1.GetTime()); - rConfig.SetValue(_T("DateB.Type"), m_bUseDate2); - rConfig.SetValue(_T("DateB.FilteringType"), m_iDateType2); - rConfig.SetValue(_T("DateB.EnableDatePart"), m_bDate2); - rConfig.SetValue(_T("DateB.DateValue"), m_tDate2.GetTime()); - rConfig.SetValue(_T("DateB.EnableTimePart"), m_bTime2); - rConfig.SetValue(_T("DateB.TimeValue"), m_tTime2.GetTime()); + SetConfigValue(rConfig, _T("DateB.Type"), m_bUseDate2); + SetConfigValue(rConfig, _T("DateB.FilteringType"), m_iDateType2); + SetConfigValue(rConfig, _T("DateB.EnableDatePart"), m_bDate2); + SetConfigValue(rConfig, _T("DateB.DateValue"), m_tDate2.GetTime()); + SetConfigValue(rConfig, _T("DateB.EnableTimePart"), m_bTime2); + SetConfigValue(rConfig, _T("DateB.TimeValue"), m_tTime2.GetTime()); - rConfig.SetValue(_T("Attributes.Use"), m_bUseAttributes); - rConfig.SetValue(_T("Attributes.Archive"), m_iArchive); - rConfig.SetValue(_T("Attributes.ReadOnly"), m_iReadOnly); - rConfig.SetValue(_T("Attributes.Hidden"), m_iHidden); - rConfig.SetValue(_T("Attributes.System"), m_iSystem); - rConfig.SetValue(_T("Attributes.Directory"), m_iDirectory); + SetConfigValue(rConfig, _T("Attributes.Use"), m_bUseAttributes); + SetConfigValue(rConfig, _T("Attributes.Archive"), m_iArchive); + SetConfigValue(rConfig, _T("Attributes.ReadOnly"), m_iReadOnly); + SetConfigValue(rConfig, _T("Attributes.Hidden"), m_iHidden); + SetConfigValue(rConfig, _T("Attributes.System"), m_iSystem); + SetConfigValue(rConfig, _T("Attributes.Directory"), m_iDirectory); } -void CFileFilter::ReadFromConfig(const TConfig& rConfig) +void CFileFilter::ReadFromConfig(const chcore::TConfig& rConfig) { __time64_t tTime = 0; - if(!rConfig.GetValue(_T("IncludeMask.Use"), m_bUseMask)) + if(!GetConfigValue(rConfig, _T("IncludeMask.Use"), m_bUseMask)) m_bUseMask = false; m_astrMask.clear(); - rConfig.GetValue(_T("IncludeMask.MaskList.Mask"), m_astrMask); + GetConfigValue(rConfig, _T("IncludeMask.MaskList"), m_astrMask); - if(!rConfig.GetValue(_T("ExcludeMask.Use"), m_bUseExcludeMask)) + if(!GetConfigValue(rConfig, _T("ExcludeMask.Use"), m_bUseExcludeMask)) m_bUseExcludeMask = false; m_astrExcludeMask.clear(); - rConfig.GetValue(_T("ExcludeMask.MaskList.Mask"), m_astrExcludeMask); + GetConfigValue(rConfig, _T("ExcludeMask.MaskList.Mask"), m_astrExcludeMask); - if(!rConfig.GetValue(_T("SizeA.Use"), m_bUseSize)) + if(!GetConfigValue(rConfig, _T("SizeA.Use"), m_bUseSize)) m_bUseSize = false; - if(!rConfig.GetValue(_T("SizeA.FilteringType"), m_iSizeType1)) + if(!GetConfigValue(rConfig, _T("SizeA.FilteringType"), m_iSizeType1)) m_iSizeType1 = EQ; - if(!rConfig.GetValue(_T("SizeA.Value"), m_ullSize1)) + if(!GetConfigValue(rConfig, _T("SizeA.Value"), m_ullSize1)) m_ullSize1 = 0; - if(!rConfig.GetValue(_T("SizeB.Use"), m_bUseSize2)) + if(!GetConfigValue(rConfig, _T("SizeB.Use"), m_bUseSize2)) m_bUseSize2 = false; - if(!rConfig.GetValue(_T("SizeB.FilteringType"), m_iSizeType2)) + if(!GetConfigValue(rConfig, _T("SizeB.FilteringType"), m_iSizeType2)) m_iSizeType2 = EQ; - if(!rConfig.GetValue(_T("SizeB.Value"), m_ullSize2)) + if(!GetConfigValue(rConfig, _T("SizeB.Value"), m_ullSize2)) m_ullSize2 = 0; - if(!rConfig.GetValue(_T("DateA.Use"), m_bUseDate)) + if(!GetConfigValue(rConfig, _T("DateA.Use"), m_bUseDate)) m_bUseDate = false; - if(!rConfig.GetValue(_T("DateA.Type"), m_iDateType)) // created/last modified/last accessed + if(!GetConfigValue(rConfig, _T("DateA.Type"), m_iDateType)) // created/last modified/last accessed m_iDateType = DATE_CREATED; - if(!rConfig.GetValue(_T("DateA.FilteringType"), m_iDateType1)) // before/after + if(!GetConfigValue(rConfig, _T("DateA.FilteringType"), m_iDateType1)) // before/after m_iDateType1 = EQ; - if(!rConfig.GetValue(_T("DateA.EnableDatePart"), m_bDate1)) + if(!GetConfigValue(rConfig, _T("DateA.EnableDatePart"), m_bDate1)) m_bDate1 = false; - if(!rConfig.GetValue(_T("DateA.DateValue"), tTime)) + if(!GetConfigValue(rConfig, _T("DateA.DateValue"), tTime)) tTime = 0; m_tDate1 = tTime; - if(!rConfig.GetValue(_T("DateA.EnableTimePart"), m_bTime1)) + if(!GetConfigValue(rConfig, _T("DateA.EnableTimePart"), m_bTime1)) m_bTime1 = false; - if(!rConfig.GetValue(_T("DateA.TimeValue"), tTime)) + if(!GetConfigValue(rConfig, _T("DateA.TimeValue"), tTime)) tTime = 0; m_tTime1 = tTime; - if(!rConfig.GetValue(_T("DateB.Type"), m_bUseDate2)) + if(!GetConfigValue(rConfig, _T("DateB.Type"), m_bUseDate2)) m_bUseDate2 = false; - if(!rConfig.GetValue(_T("DateB.FilteringType"), m_iDateType2)) + if(!GetConfigValue(rConfig, _T("DateB.FilteringType"), m_iDateType2)) m_iDateType2 = EQ; - if(!rConfig.GetValue(_T("DateB.EnableDatePart"), m_bDate2)) + if(!GetConfigValue(rConfig, _T("DateB.EnableDatePart"), m_bDate2)) m_bDate2 = false; - if(!rConfig.GetValue(_T("DateB.DateValue"), tTime)) + if(!GetConfigValue(rConfig, _T("DateB.DateValue"), tTime)) tTime = 0; m_tDate2 = tTime; - if(!rConfig.GetValue(_T("DateB.EnableTimePart"), m_bTime2)) + if(!GetConfigValue(rConfig, _T("DateB.EnableTimePart"), m_bTime2)) m_bTime2 = false; - if(!rConfig.GetValue(_T("DateB.TimeValue"), tTime)) + if(!GetConfigValue(rConfig, _T("DateB.TimeValue"), tTime)) tTime = 0; m_tTime2 = tTime; - if(!rConfig.GetValue(_T("Attributes.Use"), m_bUseAttributes)) + if(!GetConfigValue(rConfig, _T("Attributes.Use"), m_bUseAttributes)) m_bUseAttributes = false; - if(!rConfig.GetValue(_T("Attributes.Archive"), m_iArchive)) + if(!GetConfigValue(rConfig, _T("Attributes.Archive"), m_iArchive)) m_iArchive = 0; - if(!rConfig.GetValue(_T("Attributes.ReadOnly"), m_iReadOnly)) + if(!GetConfigValue(rConfig, _T("Attributes.ReadOnly"), m_iReadOnly)) m_iReadOnly = false; - if(!rConfig.GetValue(_T("Attributes.Hidden"), m_iHidden)) + if(!GetConfigValue(rConfig, _T("Attributes.Hidden"), m_iHidden)) m_iHidden = 0; - if(!rConfig.GetValue(_T("Attributes.System"), m_iSystem)) + if(!GetConfigValue(rConfig, _T("Attributes.System"), m_iSystem)) m_iSystem = 0; - if(!rConfig.GetValue(_T("Attributes.Directory"), m_iDirectory)) + if(!GetConfigValue(rConfig, _T("Attributes.Directory"), m_iDirectory)) m_iDirectory = 0; } @@ -586,30 +586,32 @@ return false; } -void CFiltersArray::StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const +void CFiltersArray::StoreInConfig(chcore::TConfig& rConfig, PCTSTR pszNodeName) const { rConfig.DeleteNode(pszNodeName); BOOST_FOREACH(const CFileFilter& rFilter, m_vFilters) { - TConfig cfgNode; + chcore::TConfig cfgNode; rFilter.StoreInConfig(cfgNode); rConfig.AddSubConfig(CString(pszNodeName) + _T(".FilterDefinition"), cfgNode); } } -void CFiltersArray::ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName) +bool CFiltersArray::ReadFromConfig(const chcore::TConfig& rConfig, PCTSTR pszNodeName) { m_vFilters.clear(); - std::vector vConfigs; - rConfig.ExtractMultiSubConfigs(pszNodeName, vConfigs); - BOOST_FOREACH(const TConfig& rCfg, vConfigs) + std::vector vConfigs; + if(!rConfig.ExtractMultiSubConfigs(pszNodeName, vConfigs)) + return false; + BOOST_FOREACH(const chcore::TConfig& rCfg, vConfigs) { CFileFilter tFilter; tFilter.ReadFromConfig(rCfg); m_vFilters.push_back(tFilter); } + return true; } bool CFiltersArray::IsEmpty() const Index: src/ch/FileFilter.h =================================================================== diff -u -N -rc54aa186fda8c0af84325325276245e9d8fcfa26 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/FileFilter.h (.../FileFilter.h) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) +++ src/ch/FileFilter.h (.../FileFilter.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -19,6 +19,8 @@ #ifndef __FILEFILTER_H__ #define __FILEFILTER_H__ +#include "FileInfo.h" + // definitions for comparing sizes and dates #define LT 0 #define LE 1 @@ -31,7 +33,7 @@ #define DATE_MODIFIED 1 #define DATE_LASTACCESSED 2 -class TConfig; +namespace chcore { class TConfig; } class CFileFilter { @@ -48,8 +50,8 @@ CString& GetCombinedExcludeMask(CString& pMask) const; void SetCombinedExcludeMask(const CString& pMask); - void StoreInConfig(TConfig& rConfig) const; - void ReadFromConfig(const TConfig& rConfig); + void StoreInConfig(chcore::TConfig& rConfig) const; + void ReadFromConfig(const chcore::TConfig& rConfig); template void serialize(Archive& ar, unsigned int /*uiVersion*/) @@ -145,8 +147,8 @@ CFiltersArray& operator=(const CFiltersArray& rSrc); bool Match(const CFileInfoPtr& spInfo) const; - void StoreInConfig(TConfig& rConfig, PCTSTR pszNodeName) const; - void ReadFromConfig(const TConfig& rConfig, PCTSTR pszNodeName); + void StoreInConfig(chcore::TConfig& rConfig, PCTSTR pszNodeName) const; + bool ReadFromConfig(const chcore::TConfig& rConfig, PCTSTR pszNodeName); template void serialize(Archive& ar, unsigned int /*uiVersion*/) @@ -166,4 +168,7 @@ std::vector m_vFilters; }; -#endif \ No newline at end of file +CONFIG_MEMBER_SERIALIZATION(CFiltersArray) + +#endif + Index: src/ch/MainWnd.cpp =================================================================== diff -u -N -rc54aa186fda8c0af84325325276245e9d8fcfa26 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) +++ src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -224,7 +224,7 @@ pDlg->m_bAutoDelete = true; pDlg->Create(); - TConfig& rConfig = GetConfig(); + chcore::TConfig& rConfig = GetConfig(); try { SetPropValue(rConfig, _time64(NULL)); @@ -440,7 +440,7 @@ } while (iOffset < ulLen); - TConfig& rConfig = GetConfig(); + chcore::TConfig& rConfig = GetConfig(); // special operation - modify stuff CFiltersArray ffFilters; @@ -530,7 +530,7 @@ SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_FIRSTCOPY_STRING)); SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_NEXTCOPY_STRING)); - ffFilters.StoreInConfig(tTaskDefinition.GetConfiguration(), TASK_PROP_NAME_FILTERING); + SetTaskPropValue(tTaskDefinition.GetConfiguration(), ffFilters); // create task with the above definition CTaskPtr spTask = m_tasks.CreateTask(); @@ -558,7 +558,7 @@ void CMainWnd::OnPopupCustomCopy() { - TConfig& rConfig = GetConfig(); + chcore::TConfig& rConfig = GetConfig(); CCustomCopyDlg dlg; dlg.m_ccData.m_iOperation=0; @@ -619,7 +619,7 @@ SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_FIRSTCOPY_STRING)); SetTaskPropValue(tTaskDefinition.GetConfiguration(), GetResManager().LoadString(IDS_NEXTCOPY_STRING)); - dlg.m_ccData.m_afFilters.StoreInConfig(tTaskDefinition.GetConfiguration(), TASK_PROP_NAME_FILTERING); + SetTaskPropValue(tTaskDefinition.GetConfiguration(), dlg.m_ccData.m_afFilters); // new task CTaskPtr spTask = m_tasks.CreateTask(); @@ -665,7 +665,7 @@ case WM_GETCONFIG: { - TConfig& rConfig = GetConfig(); + chcore::TConfig& rConfig = GetConfig(); // std config values g_pscsShared->bShowFreeSpace=GetPropValue(rConfig); Index: src/ch/OptionsDlg.cpp =================================================================== diff -u -N -r9ea1e103b5fa4ddfebf8028f121ce16e917eec04 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/OptionsDlg.cpp (.../OptionsDlg.cpp) (revision 9ea1e103b5fa4ddfebf8028f121ce16e917eec04) +++ src/ch/OptionsDlg.cpp (.../OptionsDlg.cpp) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -102,7 +102,7 @@ m_ctlProperties.Init(); // copy shortcut and recent paths - TConfig& rConfig = GetConfig(); + chcore::TConfig& rConfig = GetConfig(); m_cvRecent.clear(); GetPropValue(rConfig, m_cvRecent); @@ -324,7 +324,7 @@ // counter int iPosition=0; - TConfig& rConfig = GetConfig(); + chcore::TConfig& rConfig = GetConfig(); rConfig.DelayNotifications(); SKIP_SEPARATOR(iPosition); Index: src/ch/SerializationHelpers.h =================================================================== diff -u -N -r5057e08b0cc064972abeb94a488e5f12d9db14a0 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/SerializationHelpers.h (.../SerializationHelpers.h) (revision 5057e08b0cc064972abeb94a488e5f12d9db14a0) +++ src/ch/SerializationHelpers.h (.../SerializationHelpers.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -22,6 +22,7 @@ #include #include +// Standard serialization using boost serialization library BOOST_SERIALIZATION_SPLIT_FREE(CString); BOOST_SERIALIZATION_SPLIT_FREE(CTime); @@ -61,5 +62,4 @@ } // namespace serialization } // namespace boost - #endif Index: src/ch/Stdafx.h =================================================================== diff -u -N -r73b2826b21fdda4cbae36e8a1a7b7d5454ee519c -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/Stdafx.h (.../Stdafx.h) (revision 73b2826b21fdda4cbae36e8a1a7b7d5454ee519c) +++ src/ch/Stdafx.h (.../Stdafx.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -48,6 +48,7 @@ #include "../libictranslate/LanguageDialog.h" #include "../common/ErrorConstants.h" #include "../libchcore/TLogger.h" +#include "../libchcore/TConfigSerializers.h" #include "SerializationHelpers.h" #ifdef _UNICODE Index: src/ch/TTaskConfigTracker.cpp =================================================================== diff -u -N -rc54aa186fda8c0af84325325276245e9d8fcfa26 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/TTaskConfigTracker.cpp (.../TTaskConfigTracker.cpp) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) +++ src/ch/TTaskConfigTracker.cpp (.../TTaskConfigTracker.cpp) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -104,7 +104,7 @@ return bModified; } -void TTaskConfigTracker::AddModified(const CString& strModified) +void TTaskConfigTracker::AddModified(const std::wstring& strModified) { ETaskOptions eOption = TTaskConfigTracker::GetOptionFromString(strModified); @@ -125,9 +125,9 @@ m_setModified.insert(setOptions.Get().begin(), setOptions.Get().end()); } -void TTaskConfigTracker::AddModified(const std::set& setModified) +void TTaskConfigTracker::AddModified(const std::set& setModified) { - BOOST_FOREACH(const CString& strVal, setModified) + BOOST_FOREACH(const std::wstring& strVal, setModified) { AddModified(strVal); } @@ -167,7 +167,7 @@ } } -void TTaskConfigTracker::RemoveModification(const CString& strModified) +void TTaskConfigTracker::RemoveModification(const std::wstring& strModified) { ETaskOptions eOption = TTaskConfigTracker::GetOptionFromString(strModified); RemoveModification(eOption); @@ -179,7 +179,7 @@ m_setModified.clear(); } -void TTaskConfigTracker::NotificationProc(const std::set& setModifications, void* pParam) +void TTaskConfigTracker::NotificationProc(const std::set& setModifications, void* pParam) { if(!pParam) THROW(_T("Invalid pointer"), 0, 0, 0); @@ -188,7 +188,7 @@ pTracker->AddModified(setModifications); } -ETaskOptions TTaskConfigTracker::GetOptionFromString(const CString& strOption) +ETaskOptions TTaskConfigTracker::GetOptionFromString(const std::wstring& strOption) { if(strOption == TaskPropData::GetPropertyName()) return eTO_UseOnlyDefaultBuffer; @@ -232,7 +232,7 @@ return eTO_AlternateFilenameFormatString_AfterFirst; else if(strOption == TaskPropData::GetPropertyName()) return eTO_AlternateFilenameFormatString_First; - else if(strOption == TASK_PROP_NAME_FILTERING) + else if(strOption == TaskPropData::GetPropertyName()) return eTO_Filters; else { Index: src/ch/TTaskConfigTracker.h =================================================================== diff -u -N -r8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/TTaskConfigTracker.h (.../TTaskConfigTracker.h) (revision 8213d63ae7b0a09fc4c5e15aa6ca7ddf655ae31f) +++ src/ch/TTaskConfigTracker.h (.../TTaskConfigTracker.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -48,21 +48,21 @@ bool IsModified(ETaskOptions eOption, bool bResetModificationState); bool IsModified(TOptionsSet setOptions, bool bResetModificationState); - void AddModified(const CString& strModified); + void AddModified(const std::wstring& strModified); void AddModified(ETaskOptions eModified); void AddModified(TOptionsSet setOptions); - void AddModified(const std::set& setModified); + void AddModified(const std::set& setModified); void AddModified(const std::set& setModified); void RemoveModification(ETaskOptions eModified); void RemoveModificationSet(TOptionsSet setOptions); - void RemoveModification(const CString& strModified); + void RemoveModification(const std::wstring& strModified); void Clear(); - static void NotificationProc(const std::set& setModifications, void* pParam); + static void NotificationProc(const std::set& setModifications, void* pParam); protected: - static ETaskOptions GetOptionFromString(const CString& strOption); + static ETaskOptions GetOptionFromString(const std::wstring& strOption); protected: std::set m_setModified; Index: src/ch/TTaskConfiguration.h =================================================================== diff -u -N -rc54aa186fda8c0af84325325276245e9d8fcfa26 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/TTaskConfiguration.h (.../TTaskConfiguration.h) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) +++ src/ch/TTaskConfiguration.h (.../TTaskConfiguration.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -23,7 +23,8 @@ #ifndef __TTASKCONFIGURATION_H__ #define __TTASKCONFIGURATION_H__ -#include "TConfig.h" +#include "../libchcore/TConfig.h" +#include "FileFilter.h" enum ETaskOptions { @@ -63,15 +64,20 @@ template struct TaskPropData; #define TASK_PROPERTY(enum_id, val_type, val_name, def_value)\ - template<> struct TaskPropData : public PropDataBase\ + template<> struct TaskPropData\ {\ + typedef val_type value_type;\ +\ static value_type GetDefaultValue() { return def_value; }\ static const wchar_t* GetPropertyName() { return val_name; }\ + static void ValidateRange(value_type&) {}\ } #define TASK_PROPERTY_MINMAX(enum_id, val_type, val_name, def_value, min_val, max_val)\ - template<> struct TaskPropData : public PropDataMinMaxBase\ + template<> struct TaskPropData\ {\ + typedef val_type value_type;\ +\ static value_type GetDefaultValue() { return def_value; }\ static const wchar_t* GetPropertyName() { return val_name; }\ static void ValidateRange(value_type& rValue)\ @@ -83,6 +89,7 @@ }\ } +// Buffer settings TASK_PROPERTY(eTO_UseOnlyDefaultBuffer, bool, _T("Buffer.UseOnlyDefaultBuffer"), false); TASK_PROPERTY_MINMAX(eTO_DefaultBufferSize, unsigned int, _T("Buffer.DefaultBufferSize"), 2097152, 1, 0xffffffff); TASK_PROPERTY_MINMAX(eTO_OneDiskBufferSize, unsigned int, _T("Buffer.OnePhysicalDiskSize"), 4194304, 1, 0xffffffff); @@ -98,40 +105,54 @@ TASK_PROPERTY(eTO_ProtectReadOnlyFiles, bool, _T("Operation.ProtectReadOnlyFiles"), true); TASK_PROPERTY(eTO_ScanDirectoriesBeforeBlocking, bool, _T("Operation.ScanForFilesBeforeBlocking"), true); +// Thread settings TASK_PROPERTY(eTO_ThreadPriority, int, _T("Operation.Thread.Priority"), THREAD_PRIORITY_NORMAL); TASK_PROPERTY(eTO_DisablePriorityBoost, bool, _T("Operation.Thread.DisablePriorityBoost"), false); +// Operation settings TASK_PROPERTY(eTO_DeleteInSeparateSubTask, bool, _T("Operation.DeleteFilesInSeparateOperation"), true); TASK_PROPERTY(eTO_CreateEmptyFiles, bool, _T("Operation.CreateEmptyFiles"), false); TASK_PROPERTY(eTO_CreateDirectoriesRelativeToRoot, bool, _T("Operation.CreateDirectoriesRelativeToRoot"), false); TASK_PROPERTY(eTO_IgnoreDirectories, bool, _T("Operation.IgnoreDirectories"), false); +TASK_PROPERTY(eTO_Filters, CFiltersArray, _T("Operation.Filtering"), CFiltersArray()); + +// Naming settings TASK_PROPERTY(eTO_AlternateFilenameFormatString_First, CString, _T("Naming.AlternateFilenameFormatFirst"), _T("Copy of %name")); TASK_PROPERTY(eTO_AlternateFilenameFormatString_AfterFirst, CString, _T("Naming.AlternateFilenameFormatAfterFirst"), _T("Copy (%count) of %name")); ///////////////////////////////////////////////////////////////////////////////////////////// // other properties names -#define TASK_PROP_NAME_FILTERING _T("Filtering") +//#define TASK_PROP_NAME_FILTERING _T("Filtering") ///////////////////////////////////////////////////////////////////////////////////////////// // Properties retrieval template -typename TaskPropData::value_type GetTaskPropValue(const TConfig& rConfig) +typename TaskPropData::value_type GetTaskPropValue(const chcore::TConfig& rConfig) { - return rConfig.GetPropValue >(); + typename TaskPropData::value_type tValue; + bool bResult = GetConfigValue(rConfig, TaskPropData::GetPropertyName(), tValue); + if(!bResult) + tValue = TaskPropData::GetDefaultValue(); + + TaskPropData::ValidateRange(tValue); + return tValue; } template -bool GetTaskPropValue(const TConfig& rConfig, typename TaskPropData::value_type& rValue) +bool GetTaskPropValue(const chcore::TConfig& rConfig, typename TaskPropData::value_type& rValue) { - return rConfig.GetPropValue >(rValue); + bool bResult = GetConfigValue(rConfig, TaskPropData::GetPropertyName(), rValue); + if(bResult) + TaskPropData::ValidateRange(rValue); + return bResult; } template -void SetTaskPropValue(TConfig& rConfig, const typename TaskPropData::value_type& rValue) +void SetTaskPropValue(chcore::TConfig& rConfig, const typename TaskPropData::value_type& rValue) { - rConfig.SetPropValue >(rValue); + SetConfigValue(rConfig, TaskPropData::GetPropertyName(), rValue); } Index: src/ch/TTaskDefinition.cpp =================================================================== diff -u -N -r591f291e22d2ece89acb266c8aa0b05c257a407c -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/TTaskDefinition.cpp (.../TTaskDefinition.cpp) (revision 591f291e22d2ece89acb266c8aa0b05c257a407c) +++ src/ch/TTaskDefinition.cpp (.../TTaskDefinition.cpp) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -131,18 +131,18 @@ } // Task configuration -void TTaskDefinition::SetConfig(const TConfig& rConfig) +void TTaskDefinition::SetConfig(const chcore::TConfig& rConfig) { m_tConfiguration = rConfig; m_bModified = true; } -TConfig& TTaskDefinition::GetConfiguration() +chcore::TConfig& TTaskDefinition::GetConfiguration() { return m_tConfiguration; } -const TConfig& TTaskDefinition::GetConfiguration() const +const chcore::TConfig& TTaskDefinition::GetConfiguration() const { return m_tConfiguration; } @@ -151,7 +151,7 @@ void TTaskDefinition::Load(const CString& strPath) { // read everything - TConfig tTaskInfo; + chcore::TConfig tTaskInfo; tTaskInfo.Read(strPath); // clear everything @@ -165,7 +165,7 @@ // get information from config file // task unique id - use if provided, generate otherwise - if(!tTaskInfo.GetValue(_T("TaskDefinition.UniqueID"), m_strTaskUniqueID) || m_strTaskUniqueID.IsEmpty()) + if(!GetConfigValue(tTaskInfo, _T("TaskDefinition.UniqueID"), m_strTaskUniqueID) || m_strTaskUniqueID.IsEmpty()) { boost::uuids::random_generator gen; boost::uuids::uuid u = gen(); @@ -175,10 +175,10 @@ } // basic information - if(!tTaskInfo.GetValue(_T("TaskDefinition.SourcePaths"), m_vSourcePaths) || m_vSourcePaths.IsEmpty()) + if(!GetConfigValue(tTaskInfo, _T("TaskDefinition.SourcePaths"), m_vSourcePaths) || m_vSourcePaths.IsEmpty()) THROW(_T("Missing source paths"), 0, 0, 0); - if(!tTaskInfo.GetValue(_T("TaskDefinition.DestinationPath"), m_pathDestinationPath) || m_pathDestinationPath.IsEmpty()) + if(!GetConfigValue(tTaskInfo, _T("TaskDefinition.DestinationPath"), m_pathDestinationPath) || m_pathDestinationPath.IsEmpty()) THROW(_T("Missing destination path"), 0, 0, 0); m_pathDestinationPath.AppendSeparatorIfDoesNotExist(); @@ -197,19 +197,19 @@ if(!bOnlyIfModified || m_bModified || m_tConfiguration.IsModified()) { // read everything - TConfig tTaskInfo; + chcore::TConfig tTaskInfo; tTaskInfo.SetFilePath(strPath); // get information from config file // task unique id - use if provided, generate otherwise - tTaskInfo.SetValue(_T("TaskDefinition.UniqueID"), m_strTaskUniqueID); + SetConfigValue(tTaskInfo, _T("TaskDefinition.UniqueID"), m_strTaskUniqueID); // basic information - tTaskInfo.SetValue(_T("TaskDefinition.SourcePaths.Path"), m_vSourcePaths); - tTaskInfo.SetValue(_T("TaskDefinition.DestinationPath"), m_pathDestinationPath); + SetConfigValue(tTaskInfo, _T("TaskDefinition.SourcePaths.Path"), m_vSourcePaths); + SetConfigValue(tTaskInfo, _T("TaskDefinition.DestinationPath"), m_pathDestinationPath); int iOperation = m_tOperationPlan.GetOperationType(); - tTaskInfo.SetValue(_T("TaskDefinition.OperationType"), iOperation); + SetConfigValue(tTaskInfo, _T("TaskDefinition.OperationType"), iOperation); tTaskInfo.PutSubConfig(_T("TaskDefinition.TaskSettings"), m_tConfiguration); Index: src/ch/TTaskDefinition.h =================================================================== diff -u -N -r69b48f0b4d7fad78f95854e95fca166014311474 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/TTaskDefinition.h (.../TTaskDefinition.h) (revision 69b48f0b4d7fad78f95854e95fca166014311474) +++ src/ch/TTaskDefinition.h (.../TTaskDefinition.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -24,7 +24,7 @@ #define __TTASKDEFINITION_H__ #include "TTaskOperationPlan.h" -#include "TConfig.h" +#include "../libchcore/TConfig.h" #include "FileInfo.h" /////////////////////////////////////////////////////////////////////////// @@ -60,9 +60,9 @@ const TOperationPlan& GetOperationPlan() const; // Task configuration - void SetConfig(const TConfig& rConfig); - TConfig& GetConfiguration(); - const TConfig& GetConfiguration() const; + void SetConfig(const chcore::TConfig& rConfig); + chcore::TConfig& GetConfiguration(); + const chcore::TConfig& GetConfiguration() const; // Serialization void Load(const CString& strPath); @@ -78,7 +78,7 @@ TOperationPlan m_tOperationPlan; ///< Describes the operation along with sub-operations to be performed on the task input data // Global task settings - TConfig m_tConfiguration; + chcore::TConfig m_tConfiguration; // Other info (volatile, not to be saved to xml) mutable bool m_bModified; ///< Some parameters has been modified and this object needs to be serialized again Index: src/ch/ch.cpp =================================================================== diff -u -N -rd16e1e189903c740e101b1ef0492639ccaaa9d52 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/ch.cpp (.../ch.cpp) (revision d16e1e189903c740e101b1ef0492639ccaaa9d52) +++ src/ch/ch.cpp (.../ch.cpp) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -77,7 +77,7 @@ theApp.OnResManNotify(uiMsg); } -void ConfigPropertyChangedCallback(const std::set& setPropNames, void* /*pParam*/) +void ConfigPropertyChangedCallback(const std::set& setPropNames, void* /*pParam*/) { theApp.OnConfigNotify(setPropNames); } @@ -123,9 +123,9 @@ return ictranslate::CResourceManager::Acquire(); } -TConfig& GetConfig() +chcore::TConfig& GetConfig() { - static TConfig tCfg; + static chcore::TConfig tCfg; return tCfg; } @@ -228,7 +228,7 @@ strCfgPath = strPath + _T("\\ch.xml"); // initialize configuration file - TConfig& rCfg = GetConfig(); + chcore::TConfig& rCfg = GetConfig(); rCfg.ConnectToNotifier(ConfigPropertyChangedCallback, NULL); // read the configuration @@ -403,7 +403,7 @@ return false; } -void CCopyHandlerApp::OnConfigNotify(const std::set& setPropNames) +void CCopyHandlerApp::OnConfigNotify(const std::set& setPropNames) { // is this language if(setPropNames.find(PropData::GetPropertyName()) != setPropNames.end()) Index: src/ch/ch.h =================================================================== diff -u -N -r9ea1e103b5fa4ddfebf8028f121ce16e917eec04 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/ch.h (.../ch.h) (revision 9ea1e103b5fa4ddfebf8028f121ce16e917eec04) +++ src/ch/ch.h (.../ch.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -29,7 +29,7 @@ #include "../chext/chext.h" #include "../libicpf/log.h" #include "../libictranslate/ResourceManager.h" -#include "TConfig.h" +#include "../libchcore/TConfig.h" using namespace std; @@ -56,11 +56,11 @@ friend LRESULT MainRouter(ULONGLONG ullDst, UINT uiMsg, WPARAM wParam, LPARAM lParam); friend CCopyHandlerApp& GetApp(); friend ictranslate::CResourceManager& GetResManager(); - friend TConfig& GetConfig(); + friend chcore::TConfig& GetConfig(); bool IsShellExtEnabled() const; - void OnConfigNotify(const std::set& setPropNames); + void OnConfigNotify(const std::set& setPropNames); void OnResManNotify(UINT uiType); protected: Index: src/ch/ch.vc90.vcproj =================================================================== diff -u -N -r16a61d123d45e60dea731a6620f6f47acccd8c43 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/ch.vc90.vcproj (.../ch.vc90.vcproj) (revision 16a61d123d45e60dea731a6620f6f47acccd8c43) +++ src/ch/ch.vc90.vcproj (.../ch.vc90.vcproj) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -615,14 +615,6 @@ > - - - - Index: src/ch/task.cpp =================================================================== diff -u -N -rc54aa186fda8c0af84325325276245e9d8fcfa26 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/task.cpp (.../task.cpp) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) +++ src/ch/task.cpp (.../task.cpp) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -593,7 +593,7 @@ // update members according to the task definition // make sure to resize paths info array size to match source paths count m_arrSourcePathsInfo.SetCount(m_tTaskDefinition.GetSourcePathCount()); - m_afFilters.ReadFromConfig(m_tTaskDefinition.GetConfiguration(), TASK_PROP_NAME_FILTERING); + GetTaskPropValue(m_tTaskDefinition.GetConfiguration(), m_afFilters); //////////////////////////////// // now rarely changing task progress data @@ -1034,7 +1034,7 @@ m_files.Clear(); // read filtering options - m_afFilters.ReadFromConfig(m_tTaskDefinition.GetConfiguration(), TASK_PROP_NAME_FILTERING); + GetTaskPropValue(m_tTaskDefinition.GetConfiguration(), m_afFilters); // enter some data to m_files int iDestDrvNumber = 0; @@ -2560,7 +2560,7 @@ } } -void CTask::OnCfgOptionChanged(const std::set& rsetChanges, void* pParam) +void CTask::OnCfgOptionChanged(const std::set& rsetChanges, void* pParam) { CTask* pTask = (CTask*)pParam; if(!pTask) Index: src/ch/task.h =================================================================== diff -u -N -rc54aa186fda8c0af84325325276245e9d8fcfa26 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/ch/task.h (.../task.h) (revision c54aa186fda8c0af84325325276245e9d8fcfa26) +++ src/ch/task.h (.../task.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -390,7 +390,7 @@ CString GetRelatedPathNL(EPathType ePathType); - static void OnCfgOptionChanged(const std::set& rsetChanges, void* pParam); + static void OnCfgOptionChanged(const std::set& rsetChanges, void* pParam); chcore::TSmartPath FindFreeSubstituteName(chcore::TSmartPath pathSrcPath, chcore::TSmartPath pathDstPath) const; chcore::TSmartPath GetDestinationPath(const CFileInfoPtr& spFileInfo, chcore::TSmartPath strPath, int iFlags) const; Index: src/libchcore/TConfig.cpp =================================================================== diff -u -N --- src/libchcore/TConfig.cpp (revision 0) +++ src/libchcore/TConfig.cpp (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -0,0 +1,553 @@ +// ============================================================================ +// Copyright (C) 2001-2010 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// 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 Library 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. +// ============================================================================ +/// @file TConfig.cpp +/// @date 2010/09/27 +/// @brief Contains implementations of classes related to configuration handling. +// ============================================================================ +#include "stdafx.h" +#include "TConfig.h" +#include +#include +#include +#include "../libicpf/exception.h" + +#pragma warning(push) +#pragma warning(disable: 4702) + #include +#pragma warning(pop) + +BEGIN_CHCORE_NAMESPACE + +/////////////////////////////////////////////////////////////////////////////////////////////// +// class TConfigNotifier + +TConfigNotifier::TConfigNotifier(void (*pfnCallback)(const std::set&, void*), void* pParam) : + m_pfnCallback(pfnCallback), + m_pParam(pParam) +{ +} + +TConfigNotifier::~TConfigNotifier() +{ +} + +void TConfigNotifier::operator()(const std::set& rsetPropNames) +{ + if(!m_pfnCallback) + THROW(_T("Invalid pointer"), 0, 0, 0); + + (*m_pfnCallback)(rsetPropNames, m_pParam); +} + +TConfigNotifier& TConfigNotifier::operator=(const TConfigNotifier& rNotifier) +{ + if(this != &rNotifier) + { + m_pfnCallback = rNotifier.m_pfnCallback; + m_pParam = rNotifier.m_pParam; + } + return *this; +} + +bool TConfigNotifier::operator==(const TConfigNotifier& rNotifier) const +{ + return m_pfnCallback == rNotifier.m_pfnCallback/* && m_pParam == rNotifier.m_pParam*/; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +// common set/get templates +template +bool InternalGetValue(const boost::property_tree::wiptree& rTree, PCTSTR pszPropName, T& tOutValue, boost::shared_mutex& rLock) +{ + boost::shared_lock lock(rLock); + + boost::optional tValue = rTree.get_optional(pszPropName); + if(tValue.is_initialized()) + { + tOutValue = tValue.get(); + return true; + } + else + return false; +} + +template +bool InternalSetValue(boost::property_tree::wiptree& rTree, bool& bModified, boost::shared_mutex& rLock, PCTSTR pszPropName, const T& tNewValue) +{ + // separate scope for mutex (to avoid calling notifier inside critical section) + boost::upgrade_lock lock(rLock); + + boost::optional tValue = rTree.get_optional(pszPropName); + if(!tValue.is_initialized() || tValue.get() != tNewValue) + { + boost::upgrade_to_unique_lock upgraded_lock(lock); + rTree.put(pszPropName, tNewValue); + bModified = true; + return true; + } + + return false; +} + +///////////////////////////////////////////////////////////////////////////////////////////// +// class TConfig + +TConfig::TConfig() : + m_bDelayedEnabled(false), + m_bModified(false) +{ +} + +TConfig::TConfig(const TConfig& rSrc) : + m_bDelayedEnabled(false), + m_bModified(rSrc.m_bModified) +{ + boost::shared_lock lock(rSrc.m_lock); + + m_propTree = rSrc.m_propTree; + m_strFilePath = rSrc.m_strFilePath; +} + +TConfig& TConfig::operator=(const TConfig& rSrc) +{ + if(this != &rSrc) + { + boost::shared_lock src_lock(rSrc.m_lock); + boost::unique_lock lock(m_lock); + + m_propTree = rSrc.m_propTree; + m_bModified = rSrc.m_bModified; + m_strFilePath = rSrc.m_strFilePath; + m_bDelayedEnabled = false; + m_setDelayedNotifications.clear(); + } + + return *this; +} + +TConfig::~TConfig() +{ +} + +// read/write +void TConfig::Read(PCTSTR pszFile) +{ + if(!pszFile) + THROW(_T("Invalid argument"), 0, 0, 0); + + boost::unique_lock lock(m_lock); + + // Note: we need to store filename for later use BEFORE trying to open a file + // since it might be nonexistent, but we still would like to store config to this file later + ClearNL(); // also clears m_bModified + m_strFilePath = pszFile; + + std::wifstream ifs(m_strFilePath.c_str(), std::ios_base::in); + try + { + boost::property_tree::xml_parser::read_xml(ifs, m_propTree); + } + catch(...) + { + m_propTree.clear(); + throw; + } +} + +void TConfig::Write(bool bOnlyIfModified) +{ + boost::shared_lock lock(m_lock); + if(!bOnlyIfModified || m_bModified) + { + std::wofstream ofs(m_strFilePath.c_str(), std::ios_base::out); + + boost::property_tree::xml_parser::write_xml(ofs, m_propTree); + m_bModified = false; + } +} + +void TConfig::SetFilePath(PCTSTR pszPath) +{ + boost::unique_lock lock(m_lock); + if(m_strFilePath != pszPath) + { + m_strFilePath = pszPath; + m_bModified = true; // since the path is modified, we can only assume that stuff needs to be written into it regardless of the current modification state + } +} + +bool TConfig::IsModified() const +{ + boost::shared_lock lock(m_lock); + return m_bModified; +} + +void TConfig::MarkAsModified() +{ + boost::unique_lock lock(m_lock); + m_bModified = true; +} + +void TConfig::MarkAsNotModified() +{ + boost::unique_lock lock(m_lock); + m_bModified = false; +} + +void TConfig::Clear() +{ + boost::unique_lock lock(m_lock); + + ClearNL(); +} + +void TConfig::ClearNL() +{ + m_propTree.clear(); + m_bModified = false; + m_setDelayedNotifications.clear(); + m_bDelayedEnabled = false; + m_strFilePath.clear(); +} + +// value setting/retrieval +bool TConfig::GetBool(PCTSTR pszPropName, bool bDefault) const +{ + bool bResult = bDefault; + if(!InternalGetValue(m_propTree, pszPropName, bResult, m_lock)) + bResult = bDefault; + return bResult; +} + +bool TConfig::GetValue(PCTSTR pszPropName, bool& bValue) const +{ + return InternalGetValue(m_propTree, pszPropName, bValue, m_lock); +} + +TConfig& TConfig::SetValue(PCTSTR pszPropName, bool bValue) +{ + if(InternalSetValue(m_propTree, m_bModified, m_lock, pszPropName, bValue)) + SendNotification(pszPropName); + + return *this; +} + +int TConfig::GetInt(PCTSTR pszPropName, int iDefault) const +{ + int iResult = 0; + if(!InternalGetValue(m_propTree, pszPropName, iResult, m_lock)) + iResult = iDefault; + return iResult; +} + +bool TConfig::GetValue(PCTSTR pszPropName, int& iValue) const +{ + return InternalGetValue(m_propTree, pszPropName, iValue, m_lock); +} + +TConfig& TConfig::SetValue(PCTSTR pszPropName, int iValue) +{ + if(InternalSetValue(m_propTree, m_bModified, m_lock, pszPropName, iValue)) + SendNotification(pszPropName); + + return *this; +} + +unsigned int TConfig::GetUInt(PCTSTR pszPropName, unsigned int uiDefault) const +{ + boost::shared_lock lock(m_lock); + return m_propTree.get(pszPropName, uiDefault); +} + +bool TConfig::GetValue(PCTSTR pszPropName, unsigned int& uiValue) const +{ + return InternalGetValue(m_propTree, pszPropName, uiValue, m_lock); +} + +TConfig& TConfig::SetValue(PCTSTR pszPropName, unsigned int uiValue) +{ + if(InternalSetValue(m_propTree, m_bModified, m_lock, pszPropName, uiValue)) + SendNotification(pszPropName); + + return *this; +} + +long long TConfig::GetLongLong(PCTSTR pszPropName, long long llDefault) const +{ + boost::shared_lock lock(m_lock); + return m_propTree.get(pszPropName, llDefault); +} + +bool TConfig::GetValue(PCTSTR pszPropName, long long& llValue) const +{ + return InternalGetValue(m_propTree, pszPropName, llValue, m_lock); +} + +TConfig& TConfig::SetValue(PCTSTR pszPropName, long long llValue) +{ + if(InternalSetValue(m_propTree, m_bModified, m_lock, pszPropName, llValue)) + SendNotification(pszPropName); + + return *this; +} + +unsigned long long TConfig::GetULongLong(PCTSTR pszPropName, unsigned long long ullDefault) const +{ + boost::shared_lock lock(m_lock); + return m_propTree.get(pszPropName, ullDefault); +} + +bool TConfig::GetValue(PCTSTR pszPropName, unsigned long long& ullValue) const +{ + return InternalGetValue(m_propTree, pszPropName, ullValue, m_lock); +} + +TConfig& TConfig::SetValue(PCTSTR pszPropName, unsigned long long ullValue) +{ + if(InternalSetValue(m_propTree, m_bModified, m_lock, pszPropName, ullValue)) + SendNotification(pszPropName); + + return *this; +} + +double TConfig::GetDouble(PCTSTR pszPropName, double dDefault) const +{ + boost::shared_lock lock(m_lock); + return m_propTree.get(pszPropName, dDefault); +} + +bool TConfig::GetValue(PCTSTR pszPropName, double& dValue) const +{ + return InternalGetValue(m_propTree, pszPropName, dValue, m_lock); +} + +TConfig& TConfig::SetValue(PCTSTR pszPropName, double dValue) +{ + if(InternalSetValue(m_propTree, m_bModified, m_lock, pszPropName, dValue)) + SendNotification(pszPropName); + + return *this; +} + +std::wstring TConfig::GetString(PCTSTR pszPropName, const std::wstring& strDefault) const +{ + boost::shared_lock lock(m_lock); + std::wstring wstrData = m_propTree.get(pszPropName, std::wstring(strDefault)); + return wstrData.c_str(); +} + +bool TConfig::GetValue(PCTSTR pszPropName, std::wstring& rstrValue) const +{ + std::wstring wstrData; + bool bResult = InternalGetValue(m_propTree, pszPropName, wstrData, m_lock); + rstrValue = wstrData.c_str(); + + return bResult; +} + +TConfig& TConfig::SetValue(PCTSTR pszPropName, const std::wstring& strValue) +{ + std::wstring wstrData = strValue; + if(InternalSetValue(m_propTree, m_bModified, m_lock, pszPropName, wstrData)) + SendNotification(pszPropName); + + return *this; +} + +bool TConfig::GetValue(PCTSTR pszPropName, std::vector& rvValues) const +{ + boost::shared_lock lock(m_lock); + rvValues.clear(); + + boost::optional children = m_propTree.get_child_optional(pszPropName); + if(children.is_initialized()) + { + BOOST_FOREACH(const boost::property_tree::wiptree::value_type& rEntry, children.get()) + { + rvValues.push_back(rEntry.second.data().c_str()); + } + + return true; + } + else + return false; +} + +void TConfig::SetValue(PCTSTR pszPropName, const std::vector& rvValues) +{ + // separate scope for mutex (to avoid calling notifier inside critical section) + { + boost::unique_lock lock(m_lock); + m_propTree.erase(pszPropName); + BOOST_FOREACH(const std::wstring& strValue, rvValues) + { + m_propTree.add(pszPropName, strValue); + } + + m_bModified = true; + } + + SendNotification(pszPropName); +} + +// extraction of subtrees +bool TConfig::ExtractSubConfig(PCTSTR pszSubTreeName, TConfig& rSubConfig) const +{ + boost::unique_lock dst_lock(rSubConfig.m_lock); + rSubConfig.ClearNL(); + + boost::shared_lock lock(m_lock); + + boost::optional optChildren = m_propTree.get_child_optional(pszSubTreeName); + if(optChildren.is_initialized()) + { + rSubConfig.m_propTree = optChildren.get(); + return true; + } + else + return false; +} + +bool TConfig::ExtractMultiSubConfigs(PCTSTR pszSubTreeName, std::vector& rSubConfigs) const +{ + TConfig cfg; + + boost::shared_lock lock(m_lock); + + boost::optional optChildren = m_propTree.get_child_optional(pszSubTreeName); + if(optChildren.is_initialized()) + { + BOOST_FOREACH(const boost::property_tree::wiptree::value_type& rEntry, optChildren.get()) + { + cfg.m_propTree = rEntry.second; + rSubConfigs.push_back(cfg); + } + + return true; + } + else + return false; +} + +void TConfig::PutSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig) +{ + boost::unique_lock lock(m_lock); + boost::shared_lock src_lock(rSubConfig.m_lock); + + m_propTree.put_child(pszSubTreeName, rSubConfig.m_propTree); + + m_bModified = true; +} + +void TConfig::AddSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig) +{ + boost::unique_lock lock(m_lock); + boost::shared_lock src_lock(rSubConfig.m_lock); + + m_propTree.add_child(pszSubTreeName, rSubConfig.m_propTree); + + m_bModified = true; +} + +void TConfig::DeleteNode(PCTSTR pszNodeName) +{ + boost::unique_lock lock(m_lock); + m_propTree.erase(pszNodeName); +} + +void TConfig::ConnectToNotifier(void (*pfnCallback)(const std::set&, void*), void* pParam) +{ + m_notifier.connect(TConfigNotifier(pfnCallback, pParam)); +} + +void TConfig::DisconnectFromNotifier(void (*pfnCallback)(const std::set&, void*)) +{ + m_notifier.disconnect(TConfigNotifier(pfnCallback, NULL)); +} + +void TConfig::DelayNotifications() +{ + boost::unique_lock lock(m_lock); + m_bDelayedEnabled = true; +} + +void TConfig::ResumeNotifications() +{ + std::set setNotifications; + + // separate scope for shared mutex (to avoid calling notifier inside critical section) + { + boost::upgrade_lock lock(m_lock); + if(m_bDelayedEnabled) + { + m_bDelayedEnabled = false; + if(!m_setDelayedNotifications.empty()) + { + setNotifications = m_setDelayedNotifications; + + boost::upgrade_to_unique_lock upgraded_lock(lock); + m_setDelayedNotifications.clear(); + } + } + } + + // NOTE: no locking here! + if(!setNotifications.empty()) + SendNotification(setNotifications); +} + +void TConfig::SendNotification(const std::set& rsetInfo) +{ + // separate scope for shared mutex (to avoid calling notifier inside critical section) + { + boost::upgrade_lock lock(m_lock); + if(m_bDelayedEnabled) + { + boost::upgrade_to_unique_lock upgraded_lock(lock); + + m_setDelayedNotifications.insert(rsetInfo.begin(), rsetInfo.end()); + return; + } + } + + // NOTE: we don't lock here + m_notifier(rsetInfo); +} + +void TConfig::SendNotification(PCTSTR pszInfo) +{ + // separate scope for shared mutex (to avoid calling notifier inside critical section) + { + boost::upgrade_lock lock(m_lock); + if(m_bDelayedEnabled) + { + boost::upgrade_to_unique_lock upgraded_lock(lock); + + m_setDelayedNotifications.insert(pszInfo); + return; + } + } + + // NOTE: we don't lock here + std::set setData; + setData.insert(pszInfo); + m_notifier(setData); +} + +END_CHCORE_NAMESPACE Index: src/ch/TConfig.cpp =================================================================== diff -u -N --- src/ch/TConfig.cpp (revision c54aa186fda8c0af84325325276245e9d8fcfa26) +++ src/ch/TConfig.cpp (revision 0) @@ -1,593 +0,0 @@ -// ============================================================================ -// Copyright (C) 2001-2010 by Jozef Starosczyk -// ixen@copyhandler.com -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU Library General Public License -// (version 2) as published by the Free Software Foundation; -// -// 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 Library 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. -// ============================================================================ -/// @file TConfig.cpp -/// @date 2010/09/27 -/// @brief Contains implementations of classes related to configuration handling. -// ============================================================================ -#include "stdafx.h" -#include "TConfig.h" -#pragma warning(push) -#pragma warning(disable: 4702) -#include -#pragma warning(pop) - -/////////////////////////////////////////////////////////////////////////////////////////////// -// class TConfigNotifier - -TConfigNotifier::TConfigNotifier(void (*pfnCallback)(const std::set&, void*), void* pParam) : - m_pfnCallback(pfnCallback), - m_pParam(pParam) -{ -} - -TConfigNotifier::~TConfigNotifier() -{ -} - -void TConfigNotifier::operator()(const std::set& rsetPropNames) -{ - if(!m_pfnCallback) - THROW(_T("Invalid pointer"), 0, 0, 0); - - (*m_pfnCallback)(rsetPropNames, m_pParam); -} - -TConfigNotifier& TConfigNotifier::operator=(const TConfigNotifier& rNotifier) -{ - if(this != &rNotifier) - { - m_pfnCallback = rNotifier.m_pfnCallback; - m_pParam = rNotifier.m_pParam; - } - return *this; -} - -bool TConfigNotifier::operator==(const TConfigNotifier& rNotifier) const -{ - return m_pfnCallback == rNotifier.m_pfnCallback/* && m_pParam == rNotifier.m_pParam*/; -} - -///////////////////////////////////////////////////////////////////////////////////////////// -// common set/get templates -template -bool GetValue(const boost::property_tree::wiptree& rTree, PCTSTR pszPropName, T& tOutValue, boost::shared_mutex& rLock) -{ - boost::shared_lock lock(rLock); - - boost::optional tValue = rTree.get_optional(pszPropName); - if(tValue.is_initialized()) - { - tOutValue = tValue.get(); - return true; - } - else - return false; -} - -template -bool SetValue(boost::property_tree::wiptree& rTree, bool& bModified, boost::shared_mutex& rLock, PCTSTR pszPropName, const T& tNewValue) -{ - // separate scope for mutex (to avoid calling notifier inside critical section) - boost::upgrade_lock lock(rLock); - - boost::optional tValue = rTree.get_optional(pszPropName); - if(!tValue.is_initialized() || tValue.get() != tNewValue) - { - boost::upgrade_to_unique_lock upgraded_lock(lock); - rTree.put(pszPropName, tNewValue); - bModified = true; - return true; - } - - return false; -} - -///////////////////////////////////////////////////////////////////////////////////////////// -// class TConfig - -TConfig::TConfig() : - m_bDelayedEnabled(false), - m_bModified(false) -{ -} - -TConfig::TConfig(const TConfig& rSrc) : - m_bDelayedEnabled(false), - m_bModified(rSrc.m_bModified) -{ - boost::shared_lock lock(rSrc.m_lock); - - m_propTree = rSrc.m_propTree; - m_strFilePath = rSrc.m_strFilePath; -} - -TConfig& TConfig::operator=(const TConfig& rSrc) -{ - if(this != &rSrc) - { - boost::shared_lock src_lock(rSrc.m_lock); - boost::unique_lock lock(m_lock); - - m_propTree = rSrc.m_propTree; - m_bModified = rSrc.m_bModified; - m_strFilePath = rSrc.m_strFilePath; - m_bDelayedEnabled = false; - m_setDelayedNotifications.clear(); - } - - return *this; -} - -TConfig::~TConfig() -{ -} - -// read/write -void TConfig::Read(const CString& strFile) -{ - boost::unique_lock lock(m_lock); - - // Note: we need to store filename for later use BEFORE trying to open a file - // since it might be nonexistent, but we still would like to store config to this file later - ClearNL(); // also clears m_bModified - m_strFilePath = strFile; - - std::wifstream ifs(m_strFilePath, ios_base::in); - try - { - boost::property_tree::xml_parser::read_xml(ifs, m_propTree); - } - catch(...) - { - m_propTree.clear(); - throw; - } -} - -void TConfig::Write(bool bOnlyIfModified) -{ - boost::shared_lock lock(m_lock); - if(!bOnlyIfModified || m_bModified) - { - std::wofstream ofs(m_strFilePath, ios_base::out); - - boost::property_tree::xml_parser::write_xml(ofs, m_propTree); - m_bModified = false; - } -} - -void TConfig::SetFilePath(const CString& strPath) -{ - boost::unique_lock lock(m_lock); - if(m_strFilePath != strPath) - { - m_strFilePath = strPath; - m_bModified = true; // since the path is modified, we can only assume that stuff needs to be written into it regardless of the current modification state - } -} - -bool TConfig::IsModified() const -{ - boost::shared_lock lock(m_lock); - return m_bModified; -} - -void TConfig::MarkAsModified() -{ - boost::unique_lock lock(m_lock); - m_bModified = true; -} - -void TConfig::MarkAsNotModified() -{ - boost::unique_lock lock(m_lock); - m_bModified = false; -} - -void TConfig::Clear() -{ - boost::unique_lock lock(m_lock); - - ClearNL(); -} - -void TConfig::ClearNL() -{ - m_propTree.clear(); - m_bModified = false; - m_setDelayedNotifications.clear(); - m_bDelayedEnabled = false; - m_strFilePath.Empty(); -} - -// value setting/retrieval -bool TConfig::GetBool(PCTSTR pszPropName, bool bDefault) const -{ - bool bResult = bDefault; - if(!::GetValue(m_propTree, pszPropName, bResult, m_lock)) - bResult = bDefault; - return bResult; -} - -bool TConfig::GetValue(PCTSTR pszPropName, bool& bValue) const -{ - return ::GetValue(m_propTree, pszPropName, bValue, m_lock); -} - -TConfig& TConfig::SetValue(PCTSTR pszPropName, bool bValue) -{ - if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, bValue)) - SendNotification(pszPropName); - - return *this; -} - -int TConfig::GetInt(PCTSTR pszPropName, int iDefault) const -{ - int iResult = 0; - if(!::GetValue(m_propTree, pszPropName, iResult, m_lock)) - iResult = iDefault; - return iResult; -} - -bool TConfig::GetValue(PCTSTR pszPropName, int& iValue) const -{ - return ::GetValue(m_propTree, pszPropName, iValue, m_lock); -} - -TConfig& TConfig::SetValue(PCTSTR pszPropName, int iValue) -{ - if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, iValue)) - SendNotification(pszPropName); - - return *this; -} - -unsigned int TConfig::GetUInt(PCTSTR pszPropName, unsigned int uiDefault) const -{ - boost::shared_lock lock(m_lock); - return m_propTree.get(pszPropName, uiDefault); -} - -bool TConfig::GetValue(PCTSTR pszPropName, unsigned int& uiValue) const -{ - return ::GetValue(m_propTree, pszPropName, uiValue, m_lock); -} - -TConfig& TConfig::SetValue(PCTSTR pszPropName, unsigned int uiValue) -{ - if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, uiValue)) - SendNotification(pszPropName); - - return *this; -} - -long long TConfig::GetLongLong(PCTSTR pszPropName, long long llDefault) const -{ - boost::shared_lock lock(m_lock); - return m_propTree.get(pszPropName, llDefault); -} - -bool TConfig::GetValue(PCTSTR pszPropName, long long& llValue) const -{ - return ::GetValue(m_propTree, pszPropName, llValue, m_lock); -} - -TConfig& TConfig::SetValue(PCTSTR pszPropName, long long llValue) -{ - if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, llValue)) - SendNotification(pszPropName); - - return *this; -} - -unsigned long long TConfig::GetULongLong(PCTSTR pszPropName, unsigned long long ullDefault) const -{ - boost::shared_lock lock(m_lock); - return m_propTree.get(pszPropName, ullDefault); -} - -bool TConfig::GetValue(PCTSTR pszPropName, unsigned long long& ullValue) const -{ - return ::GetValue(m_propTree, pszPropName, ullValue, m_lock); -} - -TConfig& TConfig::SetValue(PCTSTR pszPropName, unsigned long long ullValue) -{ - if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, ullValue)) - SendNotification(pszPropName); - - return *this; -} - -double TConfig::GetDouble(PCTSTR pszPropName, double dDefault) const -{ - boost::shared_lock lock(m_lock); - return m_propTree.get(pszPropName, dDefault); -} - -bool TConfig::GetValue(PCTSTR pszPropName, double& dValue) const -{ - return ::GetValue(m_propTree, pszPropName, dValue, m_lock); -} - -TConfig& TConfig::SetValue(PCTSTR pszPropName, double dValue) -{ - if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, dValue)) - SendNotification(pszPropName); - - return *this; -} - -CString TConfig::GetString(PCTSTR pszPropName, const CString& strDefault) const -{ - boost::shared_lock lock(m_lock); - std::wstring wstrData = m_propTree.get(pszPropName, std::wstring(strDefault)); - return wstrData.c_str(); -} - -bool TConfig::GetValue(PCTSTR pszPropName, CString& rstrValue) const -{ - std::wstring wstrData; - bool bResult = ::GetValue(m_propTree, pszPropName, wstrData, m_lock); - rstrValue = wstrData.c_str(); - - return bResult; -} - -TConfig& TConfig::SetValue(PCTSTR pszPropName, const CString& strValue) -{ - std::wstring wstrData = strValue; - if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, wstrData)) - SendNotification(pszPropName); - - return *this; -} - -chcore::TSmartPath TConfig::GetPath(PCTSTR pszPropName, const chcore::TSmartPath& pathDefault) const -{ - boost::shared_lock lock(m_lock); - std::wstring wstrData = m_propTree.get(pszPropName, pathDefault.ToWString()); - return chcore::PathFromString(wstrData); -} - -bool TConfig::GetValue(PCTSTR pszPropName, chcore::TSmartPath& rpathValue) const -{ - std::wstring wstrData; - bool bResult = ::GetValue(m_propTree, pszPropName, wstrData, m_lock); - rpathValue.FromString(wstrData); - - return bResult; -} - -TConfig& TConfig::SetValue(PCTSTR pszPropName, const chcore::TSmartPath& pathValue) -{ - std::wstring wstrData(pathValue.ToWString()); - if(::SetValue(m_propTree, m_bModified, m_lock, pszPropName, wstrData)) - SendNotification(pszPropName); - - return *this; -} - -bool TConfig::GetValue(PCTSTR pszPropName, std::vector& rvValues) const -{ - boost::shared_lock lock(m_lock); - rvValues.clear(); - - boost::optional children = m_propTree.get_child_optional(pszPropName); - if(children.is_initialized()) - { - BOOST_FOREACH(const boost::property_tree::wiptree::value_type& rEntry, children.get()) - { - rvValues.push_back(rEntry.second.data().c_str()); - } - - return true; - } - else - return false; -} - -void TConfig::SetValue(PCTSTR pszPropName, const std::vector& rvValues) -{ - // separate scope for mutex (to avoid calling notifier inside critical section) - { - boost::unique_lock lock(m_lock); - m_propTree.erase(pszPropName); - BOOST_FOREACH(const CString& strValue, rvValues) - { - m_propTree.add(pszPropName, (PCTSTR)strValue); - } - - m_bModified = true; - } - - SendNotification(pszPropName); -} - -bool TConfig::GetValue(PCTSTR pszPropName, chcore::TPathContainer& rvValues) const -{ - rvValues.Clear(); - boost::shared_lock lock(m_lock); - - boost::optional children = m_propTree.get_child_optional(pszPropName); - if(children.is_initialized()) - { - BOOST_FOREACH(const boost::property_tree::wiptree::value_type& rEntry, children.get()) - { - rvValues.Add(chcore::PathFromString(rEntry.second.data())); - } - - return true; - } - else - return false; -} - -void TConfig::SetValue(PCTSTR pszPropName, const chcore::TPathContainer& rvValues) -{ - // separate scope for mutex (to avoid calling notifier inside critical section) - { - boost::unique_lock lock(m_lock); - m_propTree.erase(pszPropName); - for(size_t stIndex = 0; stIndex < rvValues.GetCount(); ++stIndex) - { - m_propTree.add(pszPropName, rvValues.GetAt(stIndex).ToWString()); - } - - m_bModified = true; - } - - SendNotification(pszPropName); -} - -// extraction of subtrees -void TConfig::ExtractSubConfig(PCTSTR pszSubTreeName, TConfig& rSubConfig) const -{ - boost::unique_lock dst_lock(rSubConfig.m_lock); - rSubConfig.ClearNL(); - - boost::shared_lock lock(m_lock); - - boost::optional optChildren = m_propTree.get_child_optional(pszSubTreeName); - if(optChildren.is_initialized()) - rSubConfig.m_propTree = optChildren.get(); -} - -void TConfig::ExtractMultiSubConfigs(PCTSTR pszSubTreeName, std::vector& rSubConfigs) const -{ - TConfig cfg; - - boost::shared_lock lock(m_lock); - - boost::optional optChildren = m_propTree.get_child_optional(pszSubTreeName); - if(optChildren.is_initialized()) - { - BOOST_FOREACH(const boost::property_tree::wiptree::value_type& rEntry, optChildren.get()) - { - cfg.m_propTree = rEntry.second; - rSubConfigs.push_back(cfg); - } - } -} - -void TConfig::PutSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig) -{ - boost::unique_lock lock(m_lock); - boost::shared_lock src_lock(rSubConfig.m_lock); - - m_propTree.put_child(pszSubTreeName, rSubConfig.m_propTree); - - m_bModified = true; -} - -void TConfig::AddSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig) -{ - boost::unique_lock lock(m_lock); - boost::shared_lock src_lock(rSubConfig.m_lock); - - m_propTree.add_child(pszSubTreeName, rSubConfig.m_propTree); - - m_bModified = true; -} - -void TConfig::DeleteNode(PCTSTR pszNodeName) -{ - boost::unique_lock lock(m_lock); - m_propTree.erase(pszNodeName); -} - -void TConfig::ConnectToNotifier(void (*pfnCallback)(const std::set&, void*), void* pParam) -{ - m_notifier.connect(TConfigNotifier(pfnCallback, pParam)); -} - -void TConfig::DisconnectFromNotifier(void (*pfnCallback)(const std::set&, void*)) -{ - m_notifier.disconnect(TConfigNotifier(pfnCallback, NULL)); -} - -void TConfig::DelayNotifications() -{ - boost::unique_lock lock(m_lock); - m_bDelayedEnabled = true; -} - -void TConfig::ResumeNotifications() -{ - std::set setNotifications; - - // separate scope for shared mutex (to avoid calling notifier inside critical section) - { - boost::upgrade_lock lock(m_lock); - if(m_bDelayedEnabled) - { - m_bDelayedEnabled = false; - if(!m_setDelayedNotifications.empty()) - { - setNotifications = m_setDelayedNotifications; - - boost::upgrade_to_unique_lock upgraded_lock(lock); - m_setDelayedNotifications.clear(); - } - } - } - - // NOTE: no locking here! - if(!setNotifications.empty()) - SendNotification(setNotifications); -} - -void TConfig::SendNotification(const std::set& rsetInfo) -{ - // separate scope for shared mutex (to avoid calling notifier inside critical section) - { - boost::upgrade_lock lock(m_lock); - if(m_bDelayedEnabled) - { - boost::upgrade_to_unique_lock upgraded_lock(lock); - - m_setDelayedNotifications.insert(rsetInfo.begin(), rsetInfo.end()); - return; - } - } - - // NOTE: we don't lock here - m_notifier(rsetInfo); -} - -void TConfig::SendNotification(PCTSTR pszInfo) -{ - // separate scope for shared mutex (to avoid calling notifier inside critical section) - { - boost::upgrade_lock lock(m_lock); - if(m_bDelayedEnabled) - { - boost::upgrade_to_unique_lock upgraded_lock(lock); - - m_setDelayedNotifications.insert(pszInfo); - return; - } - } - - // NOTE: we don't lock here - std::set setData; - setData.insert(pszInfo); - m_notifier(setData); -} Index: src/libchcore/TConfig.h =================================================================== diff -u -N --- src/libchcore/TConfig.h (revision 0) +++ src/libchcore/TConfig.h (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -0,0 +1,215 @@ +// ============================================================================ +// Copyright (C) 2001-2010 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// 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 Library 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. +// ============================================================================ +/// @file TConfig.h +/// @date 2010/09/27 +/// @brief Contains declaration of classes related to configuration handling. +// ============================================================================ +#ifndef __TCONFIG_H__ +#define __TCONFIG_H__ + +#pragma warning(push) +#pragma warning(disable: 4100 4702) + #include + #include +#pragma warning(pop) + +BEGIN_CHCORE_NAMESPACE + +// class defines configuration change notification record; not to be used outside +class TConfigNotifier +{ +public: + TConfigNotifier(void (*pfnCallback)(const std::set&, void*), void* pParam); + ~TConfigNotifier(); + + void operator()(const std::set& rsetPropNames); + + TConfigNotifier& operator=(const TConfigNotifier& rNotifier); + + bool operator==(const TConfigNotifier& rNotifier) const; + +private: + void (*m_pfnCallback)(const std::set&, void*); + void* m_pParam; +}; + +// class for handling configuration settings +class LIBCHCORE_API TConfig +{ +public: + TConfig(); + TConfig(const TConfig& rSrc); + ~TConfig(); + + TConfig& operator=(const TConfig& rSrc); + + void Clear(); + + // read/write + void Read(PCTSTR pszFile); + void Write(bool bOnlyIfModified = false); + + void SetFilePath(PCTSTR pszPath); + + // Modifications management + bool IsModified() const; + void MarkAsModified(); + void MarkAsNotModified(); + + // value setting/retrieval + bool GetBool(PCTSTR pszPropName, bool bDefault = false) const; + bool GetValue(PCTSTR pszPropName, bool& bValue) const; + TConfig& SetValue(PCTSTR pszPropName, bool bValue); + + int GetInt(PCTSTR pszPropName, int iDefault = 0) const; + bool GetValue(PCTSTR pszPropName, int& iValue) const; + TConfig& SetValue(PCTSTR pszPropName, int iValue); + + unsigned int GetUInt(PCTSTR pszPropName, unsigned int uiDefault) 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; + 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; + bool GetValue(PCTSTR pszPropName, unsigned long long& ullValue) const; + TConfig& SetValue(PCTSTR pszPropName, unsigned long long ullValue); + + double GetDouble(PCTSTR pszPropName, double dDefault) const; + bool GetValue(PCTSTR pszPropName, double& dValue) const; + TConfig& SetValue(PCTSTR pszPropName, double dValue); + + std::wstring GetString(PCTSTR pszPropName, const std::wstring& strDefault) const; + bool GetValue(PCTSTR pszPropName, std::wstring& rstrValue) const; + TConfig& SetValue(PCTSTR pszPropName, const std::wstring& strValue); + + bool GetValue(PCTSTR pszPropName, std::vector& rvValues) const; + void SetValue(PCTSTR pszPropName, const std::vector& rvValues); + + void DeleteNode(PCTSTR pszNodeName); + + // extraction of subtrees + bool ExtractSubConfig(PCTSTR pszSubTreeName, TConfig& rSubConfig) const; + bool ExtractMultiSubConfigs(PCTSTR pszSubTreeName, std::vector& rSubConfigs) const; + void PutSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig); + void AddSubConfig(PCTSTR pszSubTreeName, const TConfig& rSubConfig); + + // property change notification + void ConnectToNotifier(void (*pfnCallback)(const std::set&, void*), void* pParam); + void DisconnectFromNotifier(void (*pfnCallback)(const std::set&, void*)); + + void DelayNotifications(); + void ResumeNotifications(); + +protected: + void SendNotification(const std::set& rsetInfo); + void SendNotification(PCTSTR pszInfo); + + void ClearNL(); + +private: +#pragma warning(push) +#pragma warning(disable: 4251) + boost::property_tree::wiptree m_propTree; + std::wstring m_strFilePath; + + boost::signals2::signal&)> m_notifier; + std::set m_setDelayedNotifications; + bool m_bDelayedEnabled; + + bool m_bModified; ///< Modification state - cleared when saving + + mutable boost::shared_mutex m_lock; +#pragma warning(pop) +}; + +template +inline void SetConfigValue(TConfig& rConfig, PCTSTR pszPropName, const Type& rValue) +{ + rConfig.SetValue(pszPropName, rValue); +} + +template +inline Type GetConfigValueDef(const TConfig& rConfig, PCTSTR pszPropName, const Type& rDefault) +{ + Type tValue; + if(!rConfig.GetValue(pszPropName, tValue)) + tValue = rDefault; + return tValue; +} + +template +inline bool GetConfigValue(const TConfig& rConfig, PCTSTR pszPropName, Type& rValue) +{ + return rConfig.GetValue(pszPropName, rValue); +} + +#define CONFIG_MEMBER_SERIALIZATION(cls)\ + namespace chcore {\ + template<>\ + static void SetConfigValue(TConfig& rConfig, PCTSTR pszPropName, const cls& rValue)\ + {\ + rValue.StoreInConfig(rConfig, pszPropName);\ + }\ +\ + template<>\ + static cls GetConfigValueDef(const TConfig& rConfig, PCTSTR pszPropName, const cls& rDefault)\ + {\ + cls tValue;\ + if(!tValue.ReadFromConfig(rConfig, pszPropName))\ + tValue = rDefault;\ + return tValue;\ + }\ +\ + template<>\ + static bool GetConfigValue(const TConfig& rConfig, PCTSTR pszPropName, cls& rValue)\ + {\ + return rValue.ReadFromConfig(rConfig, pszPropName);\ + }\ + } + +#define CONFIG_STANDALONE_SERIALIZATION(cls)\ + namespace chcore {\ + template<>\ + static void SetConfigValue(TConfig& rConfig, PCTSTR pszPropName, const cls& rValue)\ + {\ + StoreInConfig(rValue, rConfig, pszPropName);\ + }\ +\ + template<>\ + static cls GetConfigValueDef(const TConfig& rConfig, PCTSTR pszPropName, const cls& rDefault)\ + {\ + cls tValue;\ + if(!ReadFromConfig(tValue, rConfig, pszPropName))\ + tValue = rDefault;\ + return tValue;\ + }\ +\ + template<>\ + static bool GetConfigValue(const TConfig& rConfig, PCTSTR pszPropName, cls& rValue)\ + {\ + return ReadFromConfig(rValue, rConfig, pszPropName);\ + }\ + } + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TCoreConfig.cpp =================================================================== diff -u -N --- src/libchcore/TCoreConfig.cpp (revision beeac49d2e0888993bd231a4e5863c7f0741e154) +++ src/libchcore/TCoreConfig.cpp (revision 0) @@ -1,61 +0,0 @@ -/*************************************************************************** -* Copyright (C) 2001-2008 by J�zef Starosczyk * -* ixen@copyhandler.com * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU Library General Public License * -* (version 2) as published by the Free Software Foundation; * -* * -* 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 Library 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. * -***************************************************************************/ -#include "stdafx.h" -#include "../libicpf/cfg.h" -#include "TCoreConfig.h" -#include "../libicpf/exception.h" - -BEGIN_CHCORE_NAMESPACE - -TCoreConfig TCoreConfig::S_Config; - -// ============================================================================ -/// chcore::TCoreConfig::TCoreConfig -/// @date 2009/11/30 -/// -/// @brief Constructs the core configuration object. -// ============================================================================ -TCoreConfig::TCoreConfig() : - m_config(icpf::config::eIni) -{ -} - -// ============================================================================ -/// chcore::TCoreConfig::~TCoreConfig -/// @date 2009/11/30 -/// -/// @brief Destructs the core configuration object. -// ============================================================================ -TCoreConfig::~TCoreConfig() -{ -} - -// ============================================================================ -/// chcore::TCoreConfig::Acquire -/// @date 2009/11/30 -/// -/// @brief Acquires reference to core config. -/// @return Reference to core config. -// ============================================================================ -TCoreConfig& TCoreConfig::Acquire() -{ - return S_Config; -} - -END_CHCORE_NAMESPACE Index: src/libchcore/TCoreConfig.h =================================================================== diff -u -N --- src/libchcore/TCoreConfig.h (revision beeac49d2e0888993bd231a4e5863c7f0741e154) +++ src/libchcore/TCoreConfig.h (revision 0) @@ -1,47 +0,0 @@ -/*************************************************************************** -* Copyright (C) 2001-2008 by J�zef Starosczyk * -* ixen@copyhandler.com * -* * -* This program is free software; you can redistribute it and/or modify * -* it under the terms of the GNU Library General Public License * -* (version 2) as published by the Free Software Foundation; * -* * -* 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 Library 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. * -***************************************************************************/ -#ifndef __ENGINE_CFG_H__ -#define __ENGINE_CFG_H__ - -#include "libchcore.h" -#include "../libicpf/cfg.h" - -BEGIN_CHCORE_NAMESPACE - -// contains everything that could be configured inside the engine. -// supports both the informations contained in the ini file and -// ones related to current instance of CH core -class LIBCHCORE_API TCoreConfig -{ -protected: - TCoreConfig(); - virtual ~TCoreConfig(); - -public: - static TCoreConfig& Acquire(); - -private: - icpf::config m_config; - - static TCoreConfig S_Config; -}; - -END_CHCORE_NAMESPACE - -#endif Index: src/libchcore/TPath.cpp =================================================================== diff -u -N -r3fc1109991e7311d6b1e34ef0b730f9b4e1fd42a -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/libchcore/TPath.cpp (.../TPath.cpp) (revision 3fc1109991e7311d6b1e34ef0b730f9b4e1fd42a) +++ src/libchcore/TPath.cpp (.../TPath.cpp) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -1078,6 +1078,24 @@ return !m_pPath || m_pPath->m_strPath.empty(); } +void TSmartPath::StoreInConfig(chcore::TConfig& rConfig, PCTSTR pszPropName) const +{ + rConfig.SetValue(pszPropName, m_pPath ? m_pPath->m_strPath : std::wstring()); +} + +bool TSmartPath::ReadFromConfig(const chcore::TConfig& rConfig, PCTSTR pszPropName) +{ + std::wstring wstrPath; + if(rConfig.GetValue(pszPropName, wstrPath)) + { + PrepareToWrite(); + m_pPath->m_strPath = wstrPath; + return true; + } + else + return false; +} + // ============================================================================ /// TSmartPath::AppendIfNotExists /// @date 2009/11/29 @@ -1303,4 +1321,34 @@ return m_vPaths.empty(); } +void TPathContainer::StoreInConfig(chcore::TConfig& rConfig, PCTSTR pszPropName) const +{ + std::vector vPaths; + + // store as vector of strings (ineffective; should be done better) + BOOST_FOREACH(const TSmartPath& spPath, m_vPaths) + { + vPaths.push_back(spPath.ToWString()); + } + + rConfig.SetValue(pszPropName, vPaths); +} + +bool TPathContainer::ReadFromConfig(const chcore::TConfig& rConfig, PCTSTR pszPropName) +{ + m_vPaths.clear(); + + std::vector vPaths; + if(rConfig.GetValue(pszPropName, vPaths)) + { + BOOST_FOREACH(const std::wstring& wstrPath, vPaths) + { + m_vPaths.push_back(PathFromString(wstrPath)); + } + return true; + } + else + return false; +} + END_CHCORE_NAMESPACE Index: src/libchcore/TPath.h =================================================================== diff -u -N -r44307d01df646fd0320eff428856b0676761d34d -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/libchcore/TPath.h (.../TPath.h) (revision 44307d01df646fd0320eff428856b0676761d34d) +++ src/libchcore/TPath.h (.../TPath.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -21,6 +21,7 @@ #include #include "libchcore.h" +#include "TConfig.h" BEGIN_CHCORE_NAMESPACE @@ -41,7 +42,7 @@ static void Delete(TPath* pPath); protected: - tstring_t m_strPath; + std::wstring m_strPath; long m_lRefCount; friend class TSmartPath; @@ -145,6 +146,9 @@ } } + void StoreInConfig(chcore::TConfig& rConfig, PCTSTR pszPropName) const; + bool ReadFromConfig(const chcore::TConfig& rConfig, PCTSTR pszPropName); + BOOST_SERIALIZATION_SPLIT_MEMBER(); protected: @@ -181,6 +185,9 @@ size_t GetCount() const; bool IsEmpty() const; + void StoreInConfig(chcore::TConfig& rConfig, PCTSTR pszPropName) const; + bool ReadFromConfig(const chcore::TConfig& rConfig, PCTSTR pszPropName); + private: #pragma warning(push) #pragma warning(disable: 4251) @@ -190,4 +197,7 @@ END_CHCORE_NAMESPACE +CONFIG_MEMBER_SERIALIZATION(TSmartPath) +CONFIG_MEMBER_SERIALIZATION(TPathContainer) + #endif Index: src/libchcore/libchcore.vc90.vcproj =================================================================== diff -u -N -rb8222db9e695712dc5e3ac9cb28983bfb8793ac4 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision b8222db9e695712dc5e3ac9cb28983bfb8793ac4) +++ src/libchcore/libchcore.vc90.vcproj (.../libchcore.vc90.vcproj) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -438,14 +438,18 @@ > + + Index: src/libchcore/stdafx.h =================================================================== diff -u -N -r39db7f4bffdd185122d8dab0772bd6fc49a0b675 -rb684bec49aaaea4b89ab2e599497f4085d8698a3 --- src/libchcore/stdafx.h (.../stdafx.h) (revision 39db7f4bffdd185122d8dab0772bd6fc49a0b675) +++ src/libchcore/stdafx.h (.../stdafx.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) @@ -12,7 +12,11 @@ #include #include +#include +#include +#include #include +#include #include "../libicpf/gen_types.h"