From 7578f068b6dd10641ced7d08d5eebb4654c4911c Mon Sep 17 00:00:00 2001 From: Vadim Dashevskiy Date: Fri, 14 Feb 2014 15:34:14 +0000 Subject: Dbx_tree moved to deprecated git-svn-id: http://svn.miranda-ng.org/main/trunk@8122 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- plugins/!Deprecated/Dbx_tree/src/Settings.cpp | 1473 +++++++++++++++++++++++++ 1 file changed, 1473 insertions(+) create mode 100644 plugins/!Deprecated/Dbx_tree/src/Settings.cpp (limited to 'plugins/!Deprecated/Dbx_tree/src/Settings.cpp') diff --git a/plugins/!Deprecated/Dbx_tree/src/Settings.cpp b/plugins/!Deprecated/Dbx_tree/src/Settings.cpp new file mode 100644 index 0000000000..17d8fe635f --- /dev/null +++ b/plugins/!Deprecated/Dbx_tree/src/Settings.cpp @@ -0,0 +1,1473 @@ +/* + +dbx_tree: tree database driver for Miranda IM + +Copyright 2007-2010 Michael "Protogenes" Kunz, + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +*/ + +#include "Interface.h" +#include "Settings.h" +#include // floor function +#include "Hash.h" + +TDBTSettingHandle CSettingsTree::_FindSetting(const uint32_t Hash, const char * Name, const uint32_t Length) +{ + TSettingKey key = {0,0}; + key.Hash = Hash; + iterator i = LowerBound(key); + uint16_t l; + + TDBTSettingHandle res = 0; + + char * str = NULL; + + while ((res == 0) && (i) && (i->Hash == Hash)) + { + l = Length; + if (m_Owner._ReadSettingName(m_BlockManager, i->Setting, l, str) && + (strncmp(str, Name, Length) == 0)) + { + res = i->Setting; + } else { + ++i; + } + } + + free(str); + + return res; +} + +bool CSettingsTree::_DeleteSetting(const uint32_t Hash, const TDBTSettingHandle hSetting) +{ + TSettingKey key = {0,0}; + key.Hash = Hash; + iterator i = LowerBound(key); + + while ((i) && (i->Hash == Hash) && (i->Setting != hSetting)) + ++i; + + if ((i) && (i->Hash == Hash)) + { + Delete(*i); + return true; + } + + return false; +} + +bool CSettingsTree::_AddSetting(const uint32_t Hash, const TDBTSettingHandle hSetting) +{ + TSettingKey key; + key.Hash = Hash; + key.Setting = hSetting; + Insert(key); + return true; +} + +CSettings::CSettings( + CBlockManager & BlockManagerSet, + CBlockManager & BlockManagerPri, + CSettingsTree::TNodeRef SettingsRoot, + CEntities & Entities +) +: m_BlockManagerSet(BlockManagerSet), + m_BlockManagerPri(BlockManagerPri), + m_Entities(Entities), + m_SettingsMap(), + m_sigRootChanged(), + m_Modules() +{ + CSettingsTree * settree = new CSettingsTree(*this, m_BlockManagerSet, SettingsRoot, 0); + + settree->sigRootChanged().connect(this, &CSettings::onRootChanged); + m_SettingsMap.insert(std::make_pair(0, settree)); + + m_Entities._sigDeleteSettings().connect(this, &CSettings::onDeleteSettings); + m_Entities._sigMergeSettings().connect (this, &CSettings::onMergeSettings); + + _LoadModules(); + _EnsureModuleExists("$Modules"); +} + +CSettings::~CSettings() +{ + TSettingsTreeMap::iterator it = m_SettingsMap.begin(); + + while (it != m_SettingsMap.end()) + { + delete it->second; + ++it; + } + + TModulesMap::iterator it2 = m_Modules.begin(); + while (it2 != m_Modules.end()) + { + delete [] it2->second; + ++it2; + } +} + + +CSettingsTree * CSettings::getSettingsTree(TDBTEntityHandle hEntity) +{ + TSettingsTreeMap::iterator i = m_SettingsMap.find(hEntity); + if (i != m_SettingsMap.end()) + return i->second; + + uint32_t root = m_Entities._getSettingsRoot(hEntity); + if (root == DBT_INVALIDPARAM) + return NULL; + + CSettingsTree * tree = new CSettingsTree(*this, m_BlockManagerPri, root, hEntity); + tree->sigRootChanged().connect(this, &CSettings::onRootChanged); + m_SettingsMap.insert(std::make_pair(hEntity, tree)); + + return tree; +} + +// TODO check if we need to copy the name or if we can just use the cache +inline bool CSettings::_ReadSettingName(CBlockManager & BlockManager, TDBTSettingHandle Setting, uint16_t & NameLength, char *& NameBuf) +{ + uint32_t sig = cSettingSignature; + uint32_t size = 0; + + TSetting * setting = BlockManager.ReadBlock(Setting, size, sig); + if (!setting) + return false; + + if ((NameLength != 0) && (NameLength != setting->NameLength)) + return false; + + NameLength = setting->NameLength; + NameBuf = (char*) realloc(NameBuf, NameLength + 1); + + memcpy(NameBuf, setting + 1, NameLength + 1); + NameBuf[NameLength] = 0; + + return true; +} + +void CSettings::_EnsureModuleExists(char * Module) +{ + if ((Module == NULL) || (*Module == 0)) + return; + + char * e = strchr(Module, '/'); + if (e) + *e = 0; + + TModulesMap::iterator i = m_Modules.find(*((uint16_t*)Module)); + while ((i != m_Modules.end()) && (i->first == *((uint16_t*)Module)) && (strcmp(i->second, Module) != 0)) + { + ++i; + } + + if ((i == m_Modules.end()) || (i->first != *reinterpret_cast(Module))) + { + size_t l = strlen(Module); + char * tmp = new char [l + 1]; + memcpy(tmp, Module, l + 1); + m_Modules.insert(std::make_pair(*reinterpret_cast(tmp), tmp)); + + char namebuf[512]; + strcpy_s(namebuf, "$Modules/"); + strcat_s(namebuf, Module); + + TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; + desc.cbSize = sizeof(desc); + desc.pszSettingName = namebuf; + + TDBTSetting set = {0,0,0,0}; + set.cbSize = sizeof(set); + set.Descriptor = &desc; + set.Type = DBT_ST_DWORD; + + WriteSetting(set, cSettingsFileFlag); + } + + if (e) + *e = '/'; +} + +void CSettings::_LoadModules() +{ + TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; + desc.cbSize = sizeof(desc); + + TDBTSettingIterFilter f = {0,0,0,0,0,0,0,0}; + f.cbSize = sizeof(f); + f.Descriptor = &desc; + f.NameStart = "$Modules/"; + + TDBTSettingIterationHandle hiter = IterationInit(f); + + if ((hiter != 0) && (hiter != DBT_INVALIDPARAM)) + { + TDBTSettingHandle res = IterationNext(hiter); + while ((res != 0) && (res != DBT_INVALIDPARAM)) + { + size_t l = strlen(desc.pszSettingName); + char * tmp = new char [l - 9 + 1]; + memcpy(tmp, desc.pszSettingName + 9, l - 9 + 1); + m_Modules.insert(std::make_pair(*reinterpret_cast(tmp), tmp)); + res = IterationNext(hiter); + } + + IterationClose(hiter); + } +} + +void CSettings::onRootChanged(void* SettingsTree, CSettingsTree::TNodeRef NewRoot) +{ + if (((CSettingsTree*)SettingsTree)->Entity() == 0) + m_sigRootChanged.emit(this, NewRoot); + else + m_Entities._setSettingsRoot(((CSettingsTree*)SettingsTree)->Entity(), NewRoot); +} + +void CSettings::onDeleteSettingCallback(void * Tree, const TSettingKey & Key, uint32_t Param) +{ + if (Param == 0) + { + m_BlockManagerSet.DeleteBlock(Key.Setting); + } else { + m_BlockManagerPri.DeleteBlock(Key.Setting); + } +} +void CSettings::onDeleteSettings(CEntities * Entities, TDBTEntityHandle hEntity) +{ + CSettingsTree * tree = getSettingsTree(hEntity); + + m_Entities._setSettingsRoot(hEntity, 0); + + if (tree) + { + CSettingsTree::TDeleteCallback callback; + callback.connect(this, &CSettings::onDeleteSettingCallback); + + tree->DeleteTree(&callback, hEntity); + + TSettingsTreeMap::iterator i = m_SettingsMap.find(hEntity); + delete i->second; // tree + m_SettingsMap.erase(i); + } +} + + +typedef struct TSettingMergeHelper +{ + TDBTEntityHandle Source; + TDBTEntityHandle Dest; + CSettingsTree * SourceTree; + +} TSettingMergeHelper, *PSettingMergeHelper; + + +void CSettings::onMergeSettingCallback(void * Tree, const TSettingKey & Key,uint32_t Param) +{ + PSettingMergeHelper hlp = (PSettingMergeHelper)Param; + + uint16_t dnl = 0; + char * dnb = NULL; + + _ReadSettingName(m_BlockManagerPri, Key.Setting, dnl, dnb); + + TSettingKey k = {0,0}; + k.Hash = Key.Hash; + + CSettingsTree::iterator i = hlp->SourceTree->LowerBound(k); + TDBTSettingHandle res = 0; + while ((res == 0) && i && (i->Hash == Key.Hash)) + { + uint16_t snl = dnl; + char * snb = NULL; + + if (_ReadSettingName(m_BlockManagerPri, i->Setting, snl, snb) + && (strcmp(dnb, snb) == 0)) // found it + { + res = i->Setting; + } + } + + if (res == 0) + { + hlp->SourceTree->Insert(Key); + } else { + hlp->SourceTree->Delete(*i); + hlp->SourceTree->Insert(Key); + m_BlockManagerPri.DeleteBlock(res); + } +} + +void CSettings::onMergeSettings(CEntities * Entities, TDBTEntityHandle Source, TDBTEntityHandle Dest) +{ + + if ((Source != 0) && (Dest != 0)) + { + LOG(logERROR, _T("Cannot Merge with global settings!\nSource %d Dest %d"), Source, Dest); + return; + } + + CSettingsTree * stree = getSettingsTree(Source); + CSettingsTree * dtree = getSettingsTree(Dest); + + if (stree && dtree) + { + m_Entities._setSettingsRoot(Source, 0); + + stree->Entity(Dest); + m_Entities._setSettingsRoot(Dest, stree->getRoot()); + + TSettingKey key = {0,0}; + CSettingsTree::iterator it = stree->LowerBound(key); + + while (it) // transfer all source settings to new Entity + { + uint32_t sig = cSettingSignature; + uint32_t size = 0; + TSetting * tmp = m_BlockManagerPri.ReadBlock(it->Setting, size, sig); + if (tmp) + { + tmp->Entity = Dest; + m_BlockManagerPri.UpdateBlock(it->Setting); + } + ++it; + } + + // merge the dest tree into the source tree. override existing items + // do it this way, because source tree should be much larger + TSettingMergeHelper hlp; + hlp.Source = Source; + hlp.Dest = Dest; + hlp.SourceTree = stree; + + CSettingsTree::TDeleteCallback callback; + callback.connect(this, &CSettings::onMergeSettingCallback); + dtree->DeleteTree(&callback, (uint32_t)&hlp); + + TSettingsTreeMap::iterator i = m_SettingsMap.find(Dest); + delete i->second; // dtree + i->second = stree; + m_SettingsMap.erase(Source); + + } +} + + + + +TDBTSettingHandle CSettings::FindSetting(TDBTSettingDescriptor & Descriptor) +{ + if (Descriptor.Flags & DBT_SDF_FoundValid) + return Descriptor.FoundHandle; + + uint32_t namelength = static_cast( strlen(Descriptor.pszSettingName)); + uint32_t namehash; + + if (Descriptor.Flags & DBT_SDF_HashValid) + { + namehash = Descriptor.Hash; + } else { + namehash = Hash(Descriptor.pszSettingName, namelength); + Descriptor.Hash = namehash; + Descriptor.Flags = Descriptor.Flags | DBT_SDF_HashValid; + } + + Descriptor.Flags = Descriptor.Flags & ~DBT_SDF_FoundValid; + + CSettingsTree * tree; + TDBTSettingHandle res = 0; + CBlockManager * file = &m_BlockManagerPri; + if (Descriptor.Entity == 0) + file = &m_BlockManagerSet; + + CBlockManager::ReadTransaction trans(*file); + + if ((Descriptor.Entity == 0) || (Descriptor.Options == 0)) + { + tree = getSettingsTree(Descriptor.Entity); + if (tree == NULL) + return DBT_INVALIDPARAM; + + res = tree->_FindSetting(namehash, Descriptor.pszSettingName, namelength); + + if (res) + { + Descriptor.FoundInEntity = Descriptor.Entity; + Descriptor.FoundHandle = res; + Descriptor.Flags = Descriptor.Flags | DBT_SDF_FoundValid; + } + + if (Descriptor.Entity == 0) + res = res | cSettingsFileFlag; + + return res; + } + + uint32_t cf = m_Entities.getFlags(Descriptor.Entity); + if (cf == DBT_INVALIDPARAM) + return DBT_INVALIDPARAM; + + // search the setting + res = 0; + + TDBTEntityIterFilter f; + f.cbSize = sizeof(f); + if (cf & DBT_NF_IsGroup) + { + f.fDontHasFlags = 0; + f.fHasFlags = DBT_NF_IsGroup; + } else { + f.fDontHasFlags = DBT_NF_IsGroup; + f.fHasFlags = 0; + } + f.Options = Descriptor.Options; + + TDBTEntityIterationHandle i = m_Entities.IterationInit(f, Descriptor.Entity); + if ((i == DBT_INVALIDPARAM) || (i == 0)) + return DBT_INVALIDPARAM; + + TDBTEntityHandle e = m_Entities.IterationNext(i); + TDBTEntityHandle found = 0; + while ((res == 0) && (e != 0)) + { + tree = getSettingsTree(e); + if (tree) + { + res = tree->_FindSetting(namehash, Descriptor.pszSettingName, namelength); + found = e; + } + + e = m_Entities.IterationNext(i); + } + + m_Entities.IterationClose(i); + + if (res) + { + Descriptor.FoundInEntity = found; + Descriptor.FoundHandle = res; + Descriptor.Flags = Descriptor.Flags | DBT_SDF_FoundValid; + } + + return res; +} + +unsigned int CSettings::DeleteSetting(TDBTSettingDescriptor & Descriptor) +{ + TDBTSettingHandle hset = FindSetting(Descriptor); + if ((hset == 0) || (hset == DBT_INVALIDPARAM)) + { + return DBT_INVALIDPARAM; + } + + unsigned int res = 0; + if ((Descriptor.Flags & DBT_SDF_FoundValid) && (Descriptor.Flags & DBT_SDF_HashValid)) + { + CBlockManager * file = &m_BlockManagerPri; + + if (Descriptor.FoundInEntity == 0) + { + file = &m_BlockManagerSet; + hset = hset & ~cSettingsFileFlag; + } + + CBlockManager::WriteTransaction trans(*file); + + uint32_t sig = cSettingSignature; + uint32_t size = 0; + TSetting * setting = file->ReadBlock(hset, size, sig); + if (setting && (setting->Entity == Descriptor.FoundInEntity)) + { + CSettingsTree * tree = getSettingsTree(setting->Entity); + if (tree) + { + tree->_DeleteSetting(Descriptor.Hash, hset); + file->DeleteBlock(hset); + } + } + + } else { + res = DeleteSetting(hset); + } + + return res; +} +unsigned int CSettings::DeleteSetting(TDBTSettingHandle hSetting) +{ + CBlockManager * file = &m_BlockManagerPri; + + if (hSetting & cSettingsFileFlag) + { + file = &m_BlockManagerSet; + hSetting = hSetting & ~cSettingsFileFlag; + } + + CBlockManager::WriteTransaction trans(*file); + + uint32_t sig = cSettingSignature; + uint32_t size = 0; + TSetting * setting = file->ReadBlock(hSetting, size, sig); + + if (!setting) + return DBT_INVALIDPARAM; + + CSettingsTree * tree = getSettingsTree(setting->Entity); + if (tree == NULL) + return DBT_INVALIDPARAM; + + char * str = reinterpret_cast(setting + 1); + tree->_DeleteSetting(Hash(str, setting->NameLength), hSetting); + + file->DeleteBlock(hSetting); + + return 0; +} +TDBTSettingHandle CSettings::WriteSetting(TDBTSetting & Setting) +{ + CBlockManager * file = &m_BlockManagerPri; + if (Setting.Descriptor->Entity == 0) + file = &m_BlockManagerSet; + + CBlockManager::WriteTransaction trans(*file); + + TDBTSettingHandle hset = FindSetting(*Setting.Descriptor); + if (hset == DBT_INVALIDPARAM) + return hset; + + hset = WriteSetting(Setting, hset); + + return hset; +} + +TDBTSettingHandle CSettings::WriteSetting(TDBTSetting & Setting, TDBTSettingHandle hSetting) +{ + uint32_t sig = cSettingSignature; + uint32_t size = 0; + TSetting * setting = NULL; + + if (!hSetting && !(Setting.Descriptor && Setting.Descriptor->Entity)) + return DBT_INVALIDPARAM; + + CBlockManager * file = &m_BlockManagerPri; + bool fileflag = false; + + if (hSetting & cSettingsFileFlag) + { + file = &m_BlockManagerSet; + hSetting = hSetting & ~cSettingsFileFlag; + fileflag = true; + } + + CSettingsTree * tree = NULL; + + if (hSetting == 0) + { + if (Setting.Descriptor->Entity == 0) + { + file = &m_BlockManagerSet; + fileflag = true; + } + + CBlockManager::WriteTransaction trans(*file); + + if ((Setting.Descriptor) && (Setting.Descriptor->pszSettingName)) // setting needs a name + { + tree = getSettingsTree(Setting.Descriptor->Entity); + _EnsureModuleExists(Setting.Descriptor->pszSettingName); + } + + } else { + CBlockManager::WriteTransaction trans(*file); + + setting = file->ReadBlock(hSetting, size, sig); + + if (setting) // check if hSetting is valid + tree = getSettingsTree(setting->Entity); + } + + if (tree == NULL) + return DBT_INVALIDPARAM; + + uint32_t blobsize = 0; + + if (Setting.Type & DBT_STF_VariableLength) + { + switch (Setting.Type) + { + case DBT_ST_ANSI: case DBT_ST_UTF8: + { + if (Setting.Value.Length == 0) + blobsize = static_cast(strlen(Setting.Value.pAnsi) + 1); + else + blobsize = Setting.Value.Length; + } break; + case DBT_ST_WCHAR: + { + if (Setting.Value.Length == 0) + blobsize = sizeof(wchar_t) * static_cast(wcslen(Setting.Value.pWide) + 1); + else + blobsize = sizeof(wchar_t) * (Setting.Value.Length); + } break; + default: + blobsize = Setting.Value.Length; + break; + } + } + + size = sizeof(TSetting) + static_cast(strlen(Setting.Descriptor->pszSettingName)) + 1 + blobsize; + + if (hSetting == 0) // create new setting + { + setting = file->CreateBlock(hSetting, cSettingSignature, size); + + setting->Entity = Setting.Descriptor->Entity; + setting->Flags = 0; + setting->AllocSize = blobsize; + + if (Setting.Descriptor && (Setting.Descriptor->Flags & DBT_SDF_HashValid)) + { + tree->_AddSetting(Setting.Descriptor->Hash, hSetting); + } else { + tree->_AddSetting(Hash(Setting.Descriptor->pszSettingName, static_cast(strlen(Setting.Descriptor->pszSettingName))), hSetting); + } + + } else { + uint32_t tmp = 0; + setting = file->ReadBlock(hSetting, tmp, sig); + + if (((Setting.Type & DBT_STF_VariableLength) == 0) && (setting->Type & DBT_STF_VariableLength)) + { // shrink setting (variable size->fixed size) + file->ResizeBlock(hSetting, setting, size); + } + + if ((Setting.Type & DBT_STF_VariableLength) && ((setting->Type & DBT_STF_VariableLength) == 0)) + { // trick it + setting->AllocSize = 0; + } + } + + setting->Type = Setting.Type; + setting->NameLength = static_cast(strlen(Setting.Descriptor->pszSettingName)); + memcpy(setting + 1, Setting.Descriptor->pszSettingName, setting->NameLength + 1); + + if (Setting.Type & DBT_STF_VariableLength) + { + setting->AllocSize = file->ResizeBlock(hSetting, setting, size) - + (sizeof(TSetting) + setting->NameLength + 1); + + setting->BlobLength = blobsize; + + memcpy(reinterpret_cast(setting + 1) + setting->NameLength + 1, Setting.Value.pBlob, blobsize); + } else { + memset(&(setting->Value), 0, sizeof(setting->Value)); + switch (Setting.Type) + { + case DBT_ST_BOOL: + setting->Value.Bool = Setting.Value.Bool; break; + case DBT_ST_BYTE: case DBT_ST_CHAR: + setting->Value.Byte = Setting.Value.Byte; break; + case DBT_ST_SHORT: case DBT_ST_WORD: + setting->Value.Short = Setting.Value.Short; break; + case DBT_ST_INT: case DBT_ST_DWORD: + setting->Value.Int = Setting.Value.Int; break; + default: + setting->Value.QWord = Setting.Value.QWord; break; + } + } + + file->UpdateBlock(hSetting); + + if (fileflag) + hSetting = hSetting | cSettingsFileFlag; + + return hSetting; +} + +unsigned int CSettings::ReadSetting(TDBTSetting & Setting) +{ + CBlockManager * file = &m_BlockManagerPri; + if (Setting.Descriptor->Entity == 0) + file = &m_BlockManagerSet; + + CBlockManager::ReadTransaction trans(*file); + + TDBTSettingHandle hset = FindSetting(*Setting.Descriptor); + if ((hset == 0) || (hset == DBT_INVALIDPARAM)) + return DBT_INVALIDPARAM; + + PDBTSettingDescriptor back = Setting.Descriptor; + Setting.Descriptor = NULL; + + if (ReadSetting(Setting, hset) == DBT_INVALIDPARAM) + hset = DBT_INVALIDPARAM; + + Setting.Descriptor = back; + + return hset; +} + +unsigned int CSettings::ReadSetting(TDBTSetting & Setting, TDBTSettingHandle hSetting) +{ + CBlockManager * file = &m_BlockManagerPri; + + if (hSetting & cSettingsFileFlag) + { + file = &m_BlockManagerSet; + hSetting = hSetting & ~cSettingsFileFlag; + } + + uint32_t sig = cSettingSignature; + uint32_t size = 0; + + if (hSetting == 0) + return DBT_INVALIDPARAM; + + CBlockManager::ReadTransaction trans(*file); + + TSetting * setting = file->ReadBlock(hSetting, size, sig); + + if (!setting) + return DBT_INVALIDPARAM; + + uint8_t* str = reinterpret_cast(setting + 1) + setting->NameLength + 1; + + if (Setting.Type == 0) + { + Setting.Type = setting->Type; + if (setting->Type & DBT_STF_VariableLength) + { + Setting.Value.Length = setting->BlobLength; + switch (setting->Type) + { + case DBT_ST_WCHAR: + { + Setting.Value.Length = setting->BlobLength / sizeof(wchar_t); + Setting.Value.pWide = (wchar_t*) mir_realloc(Setting.Value.pWide, sizeof(wchar_t) * Setting.Value.Length); + memcpy(Setting.Value.pWide, str, setting->BlobLength); + Setting.Value.pWide[Setting.Value.Length - 1] = 0; + + } break; + case DBT_ST_ANSI: case DBT_ST_UTF8: + { + Setting.Value.Length = setting->BlobLength; + Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, setting->BlobLength); + memcpy(Setting.Value.pAnsi, str, setting->BlobLength); + Setting.Value.pAnsi[Setting.Value.Length - 1] = 0; + + } break; + default: + { + Setting.Value.Length = setting->BlobLength; + Setting.Value.pBlob = (uint8_t *) mir_realloc(Setting.Value.pBlob, setting->BlobLength); + memcpy(Setting.Value.pBlob, str, setting->BlobLength); + } break; + } + } else { + Setting.Value.QWord = setting->Value.QWord; + } + } else { + switch (setting->Type) + { + case DBT_ST_BYTE: case DBT_ST_WORD: case DBT_ST_DWORD: case DBT_ST_QWORD: + { + switch (Setting.Type) + { + case DBT_ST_BYTE: Setting.Value.Byte = (uint8_t) setting->Value.QWord; break; + case DBT_ST_WORD: Setting.Value.Word = (uint16_t) setting->Value.QWord; break; + case DBT_ST_DWORD: Setting.Value.DWord = (uint32_t) setting->Value.QWord; break; + case DBT_ST_QWORD: Setting.Value.QWord = (uint64_t) setting->Value.QWord; break; + case DBT_ST_CHAR: Setting.Value.Char = ( int8_t) setting->Value.QWord; break; + case DBT_ST_SHORT: Setting.Value.Short = ( int16_t) setting->Value.QWord; break; + case DBT_ST_INT: Setting.Value.Int = ( int32_t) setting->Value.QWord; break; + case DBT_ST_INT64: Setting.Value.Int64 = ( int64_t) setting->Value.QWord; break; + case DBT_ST_BOOL: Setting.Value.Bool = setting->Value.QWord != 0; break; + + case DBT_ST_ANSI: case DBT_ST_UTF8: + { + char buffer[24]; + buffer[0] = 0; + Setting.Value.Length = 1 + mir_snprintf(buffer, SIZEOF(buffer), "%llu", setting->Value.QWord); + Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, Setting.Value.Length); + memcpy(Setting.Value.pAnsi, buffer, Setting.Value.Length); + + } break; + case DBT_ST_WCHAR: + { + wchar_t buffer[24]; + buffer[0] = 0; + Setting.Value.Length = 1 + mir_snwprintf(buffer, SIZEOF(buffer), L"%llu", setting->Value.QWord); + Setting.Value.pWide = (wchar_t *) mir_realloc(Setting.Value.pWide, Setting.Value.Length * sizeof(wchar_t)); + memcpy(Setting.Value.pWide, buffer, Setting.Value.Length * sizeof(wchar_t)); + + } break; + case DBT_ST_BLOB: + { + Setting.Value.Length = 0; + switch (setting->Type) + { + case DBT_ST_BYTE: Setting.Value.Length = 1; break; + case DBT_ST_WORD: Setting.Value.Length = 2; break; + case DBT_ST_DWORD: Setting.Value.Length = 4; break; + case DBT_ST_QWORD: Setting.Value.Length = 8; break; + } + + Setting.Value.pBlob = (uint8_t *) mir_realloc(Setting.Value.pBlob, Setting.Value.Length); + memcpy(Setting.Value.pBlob, &setting->Value, Setting.Value.Length); + + + } break; + } + + } break; + case DBT_ST_CHAR: case DBT_ST_SHORT: case DBT_ST_INT: case DBT_ST_INT64: + { + int64_t val = 0; + switch (setting->Type) + { + case DBT_ST_CHAR: val = setting->Value.Char; break; + case DBT_ST_SHORT: val = setting->Value.Short; break; + case DBT_ST_INT: val = setting->Value.Int; break; + case DBT_ST_INT64: val = setting->Value.Int64; break; + } + switch (Setting.Type) + { + case DBT_ST_BYTE: Setting.Value.Byte = (uint8_t) val; break; + case DBT_ST_WORD: Setting.Value.Word = (uint16_t) val; break; + case DBT_ST_DWORD: Setting.Value.DWord = (uint32_t) val; break; + case DBT_ST_QWORD: Setting.Value.QWord = (uint64_t) val; break; + case DBT_ST_CHAR: Setting.Value.Char = ( int8_t) val; break; + case DBT_ST_SHORT: Setting.Value.Short = ( int16_t) val; break; + case DBT_ST_INT: Setting.Value.Int = ( int32_t) val; break; + case DBT_ST_INT64: Setting.Value.Int64 = ( int64_t) val; break; + case DBT_ST_BOOL: Setting.Value.Bool = val != 0; break; + + case DBT_ST_ANSI: case DBT_ST_UTF8: + { + char buffer[24]; + buffer[0] = 0; + Setting.Value.Length = 1 + mir_snprintf(buffer, SIZEOF(buffer), "%lli", val); + Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, Setting.Value.Length); + memcpy(Setting.Value.pAnsi, buffer, Setting.Value.Length); + + } break; + case DBT_ST_WCHAR: + { + wchar_t buffer[24]; + buffer[0] = 0; + Setting.Value.Length = 1 + mir_snwprintf(buffer, SIZEOF(buffer), L"%lli", val); + Setting.Value.pWide = (wchar_t *) mir_realloc(Setting.Value.pWide, Setting.Value.Length * sizeof(wchar_t)); + memcpy(Setting.Value.pWide, buffer, Setting.Value.Length * sizeof(wchar_t)); + + } break; + case DBT_ST_BLOB: + { + Setting.Value.Length = 0; + switch (setting->Type) + { + case DBT_ST_CHAR: Setting.Value.Length = 1; break; + case DBT_ST_SHORT: Setting.Value.Length = 2; break; + case DBT_ST_INT: Setting.Value.Length = 4; break; + case DBT_ST_INT64: Setting.Value.Length = 8; break; + } + + Setting.Value.pBlob = (unsigned char *) mir_realloc(Setting.Value.pBlob, Setting.Value.Length); + memcpy(Setting.Value.pBlob, &setting->Value, Setting.Value.Length); + + } break; + } + + } break; + case DBT_ST_FLOAT: case DBT_ST_DOUBLE: + { + double val = 0; + if (setting->Type == DBT_ST_DOUBLE) + val = setting->Value.Double; + else + val = setting->Value.Float; + + switch (Setting.Type) + { + case DBT_ST_BYTE: Setting.Value.Byte = (uint8_t) floor(val); break; + case DBT_ST_WORD: Setting.Value.Word = (uint16_t) floor(val); break; + case DBT_ST_DWORD: Setting.Value.DWord = (uint32_t) floor(val); break; + case DBT_ST_QWORD: Setting.Value.QWord = (uint64_t) floor(val); break; + case DBT_ST_CHAR: Setting.Value.Char = ( int8_t) floor(val); break; + case DBT_ST_SHORT: Setting.Value.Short = ( int16_t) floor(val); break; + case DBT_ST_INT: Setting.Value.Int = ( int32_t) floor(val); break; + case DBT_ST_INT64: Setting.Value.Int64 = ( int64_t) floor(val); break; + case DBT_ST_BOOL: Setting.Value.Bool = val != 0; break; + + case DBT_ST_ANSI: case DBT_ST_UTF8: + { + char buffer[128]; + buffer[0] = 0; + Setting.Value.Length = 1 + mir_snprintf(buffer, SIZEOF(buffer), "%lf", setting->Value.QWord); + Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, Setting.Value.Length); + memcpy(Setting.Value.pAnsi, buffer, Setting.Value.Length); + } break; + case DBT_ST_WCHAR: + { + wchar_t buffer[128]; + buffer[0] = 0; + Setting.Value.Length = 1 + mir_snwprintf(buffer, SIZEOF(buffer), L"%lf", setting->Value.QWord); + Setting.Value.pWide = (wchar_t *) mir_realloc(Setting.Value.pWide, Setting.Value.Length * sizeof(wchar_t)); + memcpy(Setting.Value.pWide, buffer, Setting.Value.Length * sizeof(wchar_t)); + } break; + case DBT_ST_BLOB: + { + Setting.Value.Length = 4; + if (setting->Type == DBT_ST_DOUBLE) + Setting.Value.Length = 8; + + Setting.Value.pBlob = (uint8_t*) mir_realloc(Setting.Value.pBlob, Setting.Value.Length); + memcpy(Setting.Value.pBlob, &setting->Value, Setting.Value.Length); + + } break; + } + + } break; + case DBT_ST_BOOL: + { + switch (Setting.Type) + { + case DBT_ST_BYTE: case DBT_ST_WORD: case DBT_ST_DWORD: case DBT_ST_QWORD: + case DBT_ST_CHAR: case DBT_ST_SHORT: case DBT_ST_INT: case DBT_ST_INT64: + { + if (setting->Value.Bool) + Setting.Value.QWord = 1; + else + Setting.Value.QWord = 0; + } break; + case DBT_ST_FLOAT: + { + if (setting->Value.Bool) + Setting.Value.Float = 1; + else + Setting.Value.Float = 0; + } break; + case DBT_ST_DOUBLE: + { + if (setting->Value.Bool) + Setting.Value.Double = 1; + else + Setting.Value.Double = 0; + } break; + case DBT_ST_ANSI: case DBT_ST_UTF8: + { + char * buffer = "false"; + Setting.Value.Length = 5; + if (setting->Value.Bool) + { + buffer = "true"; + Setting.Value.Length = 4; + } + + Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, Setting.Value.Length); + memcpy(Setting.Value.pAnsi, buffer, Setting.Value.Length); + } break; + case DBT_ST_WCHAR: + { + wchar_t * buffer = L"false"; + Setting.Value.Length = 5; + if (setting->Value.Bool) + { + buffer = L"true"; + Setting.Value.Length = 4; + } + + Setting.Value.pWide = (wchar_t *) mir_realloc(Setting.Value.pWide, Setting.Value.Length * sizeof(wchar_t)); + memcpy(Setting.Value.pWide, buffer, Setting.Value.Length * sizeof(wchar_t)); + } break; + case DBT_ST_BLOB: + { + Setting.Value.pBlob = (uint8_t*) mir_realloc(Setting.Value.pBlob, sizeof(bool)); + (*((bool*)Setting.Value.pBlob)) = setting->Value.Bool; + Setting.Value.Length = sizeof(bool); + } break; + } + } break; + case DBT_ST_ANSI: + { + str[setting->BlobLength - 1] = 0; + + switch (Setting.Type) + { + case DBT_ST_BYTE: case DBT_ST_WORD: case DBT_ST_DWORD: case DBT_ST_QWORD: case DBT_ST_BOOL: + case DBT_ST_CHAR: case DBT_ST_SHORT: case DBT_ST_INT: case DBT_ST_INT64: + { + Setting.Value.QWord = 0; + } break; + case DBT_ST_ANSI: + { + Setting.Value.Length = setting->BlobLength; + Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, setting->BlobLength); + memcpy(Setting.Value.pAnsi, str, setting->BlobLength); + } break; + case DBT_ST_UTF8: + { + Setting.Value.pUTF8 = mir_utf8encode((char*)str); + Setting.Value.Length = static_cast(strlen(Setting.Value.pUTF8) + 1); + } break; + case DBT_ST_WCHAR: + { + Setting.Value.pWide = mir_a2u((char*)str); + Setting.Value.Length = static_cast(wcslen(Setting.Value.pWide) + 1); + } break; + case DBT_ST_BLOB: + { + Setting.Value.Length = setting->BlobLength; + Setting.Value.pBlob = (uint8_t *) mir_realloc(Setting.Value.pBlob, setting->BlobLength); + memcpy(Setting.Value.pBlob, str, setting->BlobLength); + } break; + } + } break; + case DBT_ST_UTF8: + { + str[setting->BlobLength - 1] = 0; + + switch (Setting.Type) + { + case DBT_ST_BYTE: case DBT_ST_WORD: case DBT_ST_DWORD: case DBT_ST_QWORD: case DBT_ST_BOOL: + case DBT_ST_CHAR: case DBT_ST_SHORT: case DBT_ST_INT: case DBT_ST_INT64: + { + Setting.Value.QWord = 0; + } break; + case DBT_ST_ANSI: + { + mir_utf8decode((char*)str, NULL); + Setting.Value.Length = static_cast(strlen((char*)str) + 1); + Setting.Value.pAnsi = (char *) mir_realloc(Setting.Value.pAnsi, Setting.Value.Length); + memcpy(Setting.Value.pAnsi, str, Setting.Value.Length); + } break; + case DBT_ST_UTF8: + { + Setting.Value.Length = setting->BlobLength; + Setting.Value.pUTF8 = (char *) mir_realloc(Setting.Value.pUTF8, setting->BlobLength); + memcpy(Setting.Value.pUTF8, str, setting->BlobLength); + } break; + case DBT_ST_WCHAR: + { + Setting.Value.pWide = mir_utf8decodeW((char*)str); + if (Setting.Value.pWide) + { + Setting.Value.Length = static_cast(wcslen(Setting.Value.pWide) + 1); + } else { + Setting.Value.Length = 0; + Setting.Type = 0; + } + } break; + case DBT_ST_BLOB: + { + Setting.Value.pBlob = (uint8_t *) mir_realloc(Setting.Value.pBlob, setting->BlobLength); + memcpy(Setting.Value.pBlob, str, setting->BlobLength); + Setting.Value.Length = setting->BlobLength; + } break; + } + } break; + case DBT_ST_WCHAR: + { + ((wchar_t*)str)[setting->BlobLength / sizeof(wchar_t) - 1] = 0; + + switch (Setting.Type) + { + case DBT_ST_BYTE: case DBT_ST_WORD: case DBT_ST_DWORD: case DBT_ST_QWORD: case DBT_ST_BOOL: + case DBT_ST_CHAR: case DBT_ST_SHORT: case DBT_ST_INT: case DBT_ST_INT64: + { + Setting.Value.QWord = 0; + } break; + case DBT_ST_ANSI: + { + Setting.Value.pAnsi = mir_u2a((wchar_t*)str); + Setting.Value.Length = static_cast(strlen(Setting.Value.pAnsi) + 1); + } break; + case DBT_ST_UTF8: + { + Setting.Value.pUTF8 = mir_utf8encodeW((wchar_t*)str); + Setting.Value.Length = static_cast(strlen(Setting.Value.pUTF8) + 1); + } break; + case DBT_ST_WCHAR: + { + Setting.Value.Length = setting->BlobLength / sizeof(wchar_t); + Setting.Value.pWide = (wchar_t*) mir_realloc(Setting.Value.pWide, Setting.Value.Length * sizeof(wchar_t)); + memcpy(Setting.Value.pWide, str, Setting.Value.Length * sizeof(wchar_t)); + } break; + case DBT_ST_BLOB: + { + Setting.Value.pBlob = (uint8_t *) mir_realloc(Setting.Value.pBlob, setting->BlobLength); + memcpy(Setting.Value.pBlob, str, setting->BlobLength); + Setting.Value.Length = setting->BlobLength; + } break; + } + } break; + case DBT_ST_BLOB: + { + switch (Setting.Type) + { + case DBT_ST_BYTE: case DBT_ST_WORD: case DBT_ST_DWORD: case DBT_ST_QWORD: case DBT_ST_BOOL: + case DBT_ST_CHAR: case DBT_ST_SHORT: case DBT_ST_INT: case DBT_ST_INT64: + { + Setting.Value.QWord = 0; + } break; + case DBT_ST_ANSI: case DBT_ST_WCHAR: case DBT_ST_UTF8: + { + Setting.Value.Length = 0; + if (Setting.Value.pBlob) + mir_free(Setting.Value.pBlob); + + Setting.Value.pBlob = NULL; + } break; + case DBT_ST_BLOB: + { + Setting.Value.pBlob = (uint8_t *) mir_realloc(Setting.Value.pBlob, setting->BlobLength); + memcpy(Setting.Value.pBlob, str, setting->BlobLength); + Setting.Value.Length = setting->BlobLength; + } break; + } + } break; + + } + } + + + if (Setting.Descriptor) + { + Setting.Descriptor->Entity = setting->Entity; + Setting.Descriptor->FoundInEntity = setting->Entity; + + Setting.Descriptor->pszSettingName = (char *) mir_realloc(Setting.Descriptor->pszSettingName, setting->NameLength + 1); + memcpy(Setting.Descriptor->pszSettingName, setting + 1, setting->NameLength + 1); + Setting.Descriptor->pszSettingName[setting->NameLength] = 0; + } + + return setting->Type; +} + + + + +TDBTSettingIterationHandle CSettings::IterationInit(TDBTSettingIterFilter & Filter) +{ + CBlockManager::ReadTransaction transset(m_BlockManagerSet); + CBlockManager::ReadTransaction transpri(m_BlockManagerPri); + + std::queue Entities; + Entities.push(Filter.hEntity); + + CSettingsTree * tree = getSettingsTree(Filter.hEntity); + + if (tree == NULL) + return DBT_INVALIDPARAM; + + if (Filter.hEntity != 0) + { + uint32_t cf = m_Entities.getFlags(Filter.hEntity); + + if (cf == DBT_INVALIDPARAM) + return DBT_INVALIDPARAM; + + TDBTEntityIterFilter f = {0,0,0,0}; + f.cbSize = sizeof(f); + if (cf & DBT_NF_IsGroup) + { + f.fHasFlags = DBT_NF_IsGroup; + } else { + f.fDontHasFlags = DBT_NF_IsGroup; + } + f.Options = Filter.Options; + + TDBTEntityIterationHandle citer = m_Entities.IterationInit(f, Filter.hEntity); + if (citer != DBT_INVALIDPARAM) + { + m_Entities.IterationNext(citer); // the initial Entity was already added + TDBTEntityHandle e = m_Entities.IterationNext(citer); + while (e != 0) + { + Entities.push(e); + e = m_Entities.IterationNext(citer); + } + + m_Entities.IterationClose(citer); + } + } + + for (unsigned int j = 0; j < Filter.ExtraCount; ++j) + Entities.push(Filter.ExtraEntities[j]); + + + PSettingIteration iter = new TSettingIteration; + iter->Filter = Filter; + iter->FilterNameStartLength = 0; + iter->LockSetting = (Filter.hEntity == 0); + iter->LockPrivate = (Filter.hEntity != 0); + if (Filter.NameStart) + { + uint16_t l = static_cast(strlen(Filter.NameStart)); + iter->Filter.NameStart = new char[l + 1]; + memcpy(iter->Filter.NameStart, Filter.NameStart, l + 1); + iter->FilterNameStartLength = l; + } + + TSettingKey key = {0, 0}; + + // pop first Entity. we have always one and always its tree + Entities.pop(); + + CSettingsTree::iterator * tmp = new CSettingsTree::iterator(tree->LowerBound(key)); + tmp->setManaged(); + iter->Heap = new TSettingsHeap(*tmp, TSettingsHeap::ITForward, true); + + while (!Entities.empty()) + { + TDBTEntityHandle e = Entities.front(); + Entities.pop(); + + tree = getSettingsTree(e); + if (tree != NULL) + { + tmp = new CSettingsTree::iterator(tree->LowerBound(key)); + tmp->setManaged(); + iter->Heap->Insert(*tmp); + + iter->LockSetting = iter->LockSetting || (e == 0); + iter->LockPrivate = iter->LockPrivate || (e != 0); + } + } + + iter->Frame = new std::queue; + + return reinterpret_cast(iter); +} + + +typedef struct TSettingIterationHelper { + TDBTSettingHandle Handle; + CSettingsTree * Tree; + uint16_t NameLen; + char * Name; + } TSettingIterationHelper; + +TDBTSettingHandle CSettings::IterationNext(TDBTSettingIterationHandle Iteration) +{ + PSettingIteration iter = reinterpret_cast(Iteration); + CBlockManager::ReadTransaction transset; + CBlockManager::ReadTransaction transpri; + + if (iter->LockSetting) + transset = CBlockManager::ReadTransaction(m_BlockManagerSet); + if (iter->LockPrivate) + transpri = CBlockManager::ReadTransaction(m_BlockManagerPri); + + while (iter->Frame->empty() && iter->Heap->Top()) + { + while (iter->Heap->Top() && iter->Heap->Top().wasDeleted()) + iter->Heap->Pop(); + + if (iter->Heap->Top()) + { + uint32_t h = iter->Heap->Top()->Hash; + std::queue q; + TSettingIterationHelper help; + help.NameLen = 0; + help.Name = NULL; + + help.Handle = iter->Heap->Top()->Setting; + help.Tree = (CSettingsTree *) iter->Heap->Top().Tree(); + if (help.Tree) + q.push(help); + + iter->Heap->Pop(); + + // add all candidates + while (iter->Heap->Top() && (iter->Heap->Top()->Hash == h)) + { + if (!iter->Heap->Top().wasDeleted()) + { + help.Handle = iter->Heap->Top()->Setting; + help.Tree = (CSettingsTree *) iter->Heap->Top().Tree(); + q.push(help); + } + iter->Heap->Pop(); + } + + while (!q.empty()) + { + help = q.front(); + q.pop(); + + if (help.Name == NULL) + { + if (help.Tree->Entity() == 0) + _ReadSettingName(m_BlockManagerSet, help.Handle, help.NameLen, help.Name); + else + _ReadSettingName(m_BlockManagerPri, help.Handle, help.NameLen, help.Name); + } + + + q.push(help); + while (q.front().Handle != help.Handle) // remove all queued settings with same name + { + bool namereadres = false; + + TSettingIterationHelper tmp; + tmp = q.front(); + q.pop(); + + if (tmp.Name == NULL) + { + if (tmp.Tree->Entity() == 0) + namereadres = _ReadSettingName(m_BlockManagerSet, tmp.Handle, tmp.NameLen, tmp.Name); + else + namereadres = _ReadSettingName(m_BlockManagerPri, tmp.Handle, tmp.NameLen, tmp.Name); + } + + if (!namereadres) + { + q.push(tmp); + } else { + if (strcmp(tmp.Name, help.Name) != 0) + { + q.push(tmp); + } else { + free(tmp.Name); + } + } + } + + // namefilter + if ((iter->Filter.NameStart == NULL) || ((iter->FilterNameStartLength <= help.NameLen) && (memcmp(iter->Filter.NameStart, help.Name, iter->FilterNameStartLength) == 0))) + { + TSettingIterationResult tmp; + if (help.Tree->Entity() == 0) + help.Handle |= cSettingsFileFlag; + + tmp.Handle = help.Handle; + tmp.Entity = help.Tree->Entity(); + tmp.Name = help.Name; + tmp.NameLen = help.NameLen; + iter->Frame->push(tmp); + } else { + free(help.Name); + } + + q.pop(); + } + } + } + + + TSettingIterationResult res = {0,0,0,0}; + if (!iter->Frame->empty()) + { + res = iter->Frame->front(); + iter->Frame->pop(); + + if ((iter->Filter.Descriptor) && ((iter->Filter.Setting == NULL) || (iter->Filter.Setting->Descriptor != iter->Filter.Descriptor))) + { + iter->Filter.Descriptor->Entity = res.Entity; + iter->Filter.Descriptor->pszSettingName = (char *) mir_realloc(iter->Filter.Descriptor->pszSettingName, res.NameLen + 1); + memcpy(iter->Filter.Descriptor->pszSettingName, res.Name, res.NameLen + 1); + iter->Filter.Descriptor->FoundInEntity = res.Entity; + } + if (iter->Filter.Setting) + { + if ((iter->Filter.Setting->Type & DBT_STF_VariableLength) && (iter->Filter.Setting->Value.pBlob)) + { + mir_free(iter->Filter.Setting->Value.pBlob); + iter->Filter.Setting->Value.pBlob = NULL; + } + iter->Filter.Setting->Type = 0; + + ReadSetting(*iter->Filter.Setting, res.Handle); + } + + free(res.Name); + } + + return res.Handle; +} +unsigned int CSettings::IterationClose(TDBTSettingIterationHandle Iteration) +{ + PSettingIteration iter = reinterpret_cast(Iteration); + { + CBlockManager::ReadTransaction transset; + CBlockManager::ReadTransaction transpri; + + if (iter->LockSetting) + transset = CBlockManager::ReadTransaction(m_BlockManagerSet); + if (iter->LockPrivate) + transpri = CBlockManager::ReadTransaction(m_BlockManagerPri); + + delete iter->Heap; // only this needs synchronization + } + + delete [] iter->Filter.NameStart; + + if (iter->Filter.Descriptor && iter->Filter.Descriptor->pszSettingName) + { + mir_free(iter->Filter.Descriptor->pszSettingName); + iter->Filter.Descriptor->pszSettingName = NULL; + } + if (iter->Filter.Setting) + { + if (iter->Filter.Setting->Descriptor) + { + mir_free(iter->Filter.Setting->Descriptor->pszSettingName); + iter->Filter.Setting->Descriptor->pszSettingName = NULL; + } + + if (iter->Filter.Setting->Type & DBT_STF_VariableLength) + { + mir_free(iter->Filter.Setting->Value.pBlob); + iter->Filter.Setting->Value.pBlob = NULL; + } + } + + while (!iter->Frame->empty()) + { + free(iter->Frame->front().Name); + + iter->Frame->pop(); + } + delete iter->Frame; + delete iter; + + return 0; +} + + +int CSettings::CompEnumModules(DBMODULEENUMPROC CallBack, LPARAM lParam) +{ + CBlockManager::ReadTransaction trans(m_BlockManagerSet); + + TModulesMap::iterator i = m_Modules.begin(); + int res = 0; + while ((i != m_Modules.end()) && (res == 0)) + { + char * tmp = i->second; + trans.Close(); + + res = CallBack(tmp, 0, lParam); + + trans = CBlockManager::ReadTransaction(m_BlockManagerSet); + ++i; + } + + return res; +} -- cgit v1.2.3