From 7aff1e4cb053394db57c2814d5fe1e6493e0cc75 Mon Sep 17 00:00:00 2001 From: watcherhd Date: Sat, 26 Nov 2011 14:19:43 +0000 Subject: Project folders rename part 2 git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@214 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- dbx_tree/BTree.h | 1358 -------------- dbx_tree/BlockManager.cpp | 965 ---------- dbx_tree/BlockManager.h | 401 ---- dbx_tree/Compatibility.cpp | 866 --------- dbx_tree/Compatibility.h | 65 - dbx_tree/DataBase.cpp | 374 ---- dbx_tree/DataBase.h | 157 -- dbx_tree/DatabaseLink.cpp | 178 -- dbx_tree/DatabaseLink.h | 29 - dbx_tree/DirectAccess.cpp | 118 -- dbx_tree/DirectAccess.h | 43 - dbx_tree/EncryptionManager.cpp | 241 --- dbx_tree/EncryptionManager.h | 107 -- dbx_tree/Entities.cpp | 1032 ----------- dbx_tree/Entities.h | 299 --- dbx_tree/Events.cpp | 986 ---------- dbx_tree/Events.h | 263 --- dbx_tree/FileAccess.cpp | 299 --- dbx_tree/FileAccess.h | 191 -- dbx_tree/FileBTree.h | 102 -- dbx_tree/Filestructure.txt | Bin 25894 -> 0 bytes dbx_tree/Hash.cpp | 183 -- dbx_tree/Hash.h | 29 - dbx_tree/Interface.h | 58 - dbx_tree/IterationHeap.h | 196 -- dbx_tree/Logger.cpp | 124 -- dbx_tree/Logger.h | 76 - dbx_tree/MREWSync.cpp | 330 ---- dbx_tree/MREWSync.h | 55 - dbx_tree/MappedMemory.cpp | 167 -- dbx_tree/MappedMemory.h | 47 - dbx_tree/SHA256.cpp | 301 --- dbx_tree/SHA256.h | 49 - dbx_tree/Services.cpp | 402 ---- dbx_tree/Services.h | 69 - dbx_tree/Settings.cpp | 1479 --------------- dbx_tree/Settings.h | 235 --- dbx_tree/TLS.h | 161 -- dbx_tree/Thread.cpp | 114 -- dbx_tree/Thread.h | 77 - dbx_tree/dbConfig.rc | 113 -- dbx_tree/dbConfig_rc.h | 20 - dbx_tree/dbVersion.rc | 105 -- dbx_tree/dbVersion_rc.h | 14 - dbx_tree/dbx_tree.vcproj | 1169 ------------ dbx_tree/dbx_tree_10.sln | 37 - dbx_tree/dbx_tree_10.vcxproj | 701 ------- dbx_tree/dbx_tree_10.vcxproj.filters | 204 --- dbx_tree/encryption/ARC4.cpp | 129 -- dbx_tree/encryption/ARC4.h | 65 - dbx_tree/encryption/ARC4.vcproj | 376 ---- dbx_tree/encryption/ARC4.vcxproj | 476 ----- dbx_tree/encryption/ARC4.vcxproj.filters | 30 - dbx_tree/encryption/CAST128.cpp | 260 --- dbx_tree/encryption/CAST128.h | 61 - dbx_tree/encryption/CAST128.inc | 302 --- dbx_tree/encryption/Cast128.vcproj | 380 ---- dbx_tree/encryption/Cast128.vcxproj | 479 ----- dbx_tree/encryption/Cast128.vcxproj.filters | 35 - dbx_tree/encryption/Cipher.h | 180 -- dbx_tree/encryption/HC256.cpp | 243 --- dbx_tree/encryption/HC256.h | 66 - dbx_tree/encryption/HC256.vcproj | 376 ---- dbx_tree/encryption/HC256.vcxproj | 476 ----- dbx_tree/encryption/HC256.vcxproj.filters | 30 - dbx_tree/init.cpp | 83 - dbx_tree/intrinsics.h | 407 ----- dbx_tree/inttypes.h | 305 ---- dbx_tree/lockfree_hashmap.h | 749 -------- dbx_tree/lockfree_hashmultimap.h | 750 -------- dbx_tree/m_dbx_tree.h | 688 ------- dbx_tree/savestrings_gcc.h | 127 -- dbx_tree/sigslot.h | 2639 --------------------------- dbx_tree/stdint.h | 247 --- 74 files changed, 24548 deletions(-) delete mode 100644 dbx_tree/BTree.h delete mode 100644 dbx_tree/BlockManager.cpp delete mode 100644 dbx_tree/BlockManager.h delete mode 100644 dbx_tree/Compatibility.cpp delete mode 100644 dbx_tree/Compatibility.h delete mode 100644 dbx_tree/DataBase.cpp delete mode 100644 dbx_tree/DataBase.h delete mode 100644 dbx_tree/DatabaseLink.cpp delete mode 100644 dbx_tree/DatabaseLink.h delete mode 100644 dbx_tree/DirectAccess.cpp delete mode 100644 dbx_tree/DirectAccess.h delete mode 100644 dbx_tree/EncryptionManager.cpp delete mode 100644 dbx_tree/EncryptionManager.h delete mode 100644 dbx_tree/Entities.cpp delete mode 100644 dbx_tree/Entities.h delete mode 100644 dbx_tree/Events.cpp delete mode 100644 dbx_tree/Events.h delete mode 100644 dbx_tree/FileAccess.cpp delete mode 100644 dbx_tree/FileAccess.h delete mode 100644 dbx_tree/FileBTree.h delete mode 100644 dbx_tree/Filestructure.txt delete mode 100644 dbx_tree/Hash.cpp delete mode 100644 dbx_tree/Hash.h delete mode 100644 dbx_tree/Interface.h delete mode 100644 dbx_tree/IterationHeap.h delete mode 100644 dbx_tree/Logger.cpp delete mode 100644 dbx_tree/Logger.h delete mode 100644 dbx_tree/MREWSync.cpp delete mode 100644 dbx_tree/MREWSync.h delete mode 100644 dbx_tree/MappedMemory.cpp delete mode 100644 dbx_tree/MappedMemory.h delete mode 100644 dbx_tree/SHA256.cpp delete mode 100644 dbx_tree/SHA256.h delete mode 100644 dbx_tree/Services.cpp delete mode 100644 dbx_tree/Services.h delete mode 100644 dbx_tree/Settings.cpp delete mode 100644 dbx_tree/Settings.h delete mode 100644 dbx_tree/TLS.h delete mode 100644 dbx_tree/Thread.cpp delete mode 100644 dbx_tree/Thread.h delete mode 100644 dbx_tree/dbConfig.rc delete mode 100644 dbx_tree/dbConfig_rc.h delete mode 100644 dbx_tree/dbVersion.rc delete mode 100644 dbx_tree/dbVersion_rc.h delete mode 100644 dbx_tree/dbx_tree.vcproj delete mode 100644 dbx_tree/dbx_tree_10.sln delete mode 100644 dbx_tree/dbx_tree_10.vcxproj delete mode 100644 dbx_tree/dbx_tree_10.vcxproj.filters delete mode 100644 dbx_tree/encryption/ARC4.cpp delete mode 100644 dbx_tree/encryption/ARC4.h delete mode 100644 dbx_tree/encryption/ARC4.vcproj delete mode 100644 dbx_tree/encryption/ARC4.vcxproj delete mode 100644 dbx_tree/encryption/ARC4.vcxproj.filters delete mode 100644 dbx_tree/encryption/CAST128.cpp delete mode 100644 dbx_tree/encryption/CAST128.h delete mode 100644 dbx_tree/encryption/CAST128.inc delete mode 100644 dbx_tree/encryption/Cast128.vcproj delete mode 100644 dbx_tree/encryption/Cast128.vcxproj delete mode 100644 dbx_tree/encryption/Cast128.vcxproj.filters delete mode 100644 dbx_tree/encryption/Cipher.h delete mode 100644 dbx_tree/encryption/HC256.cpp delete mode 100644 dbx_tree/encryption/HC256.h delete mode 100644 dbx_tree/encryption/HC256.vcproj delete mode 100644 dbx_tree/encryption/HC256.vcxproj delete mode 100644 dbx_tree/encryption/HC256.vcxproj.filters delete mode 100644 dbx_tree/init.cpp delete mode 100644 dbx_tree/intrinsics.h delete mode 100644 dbx_tree/inttypes.h delete mode 100644 dbx_tree/lockfree_hashmap.h delete mode 100644 dbx_tree/lockfree_hashmultimap.h delete mode 100644 dbx_tree/m_dbx_tree.h delete mode 100644 dbx_tree/savestrings_gcc.h delete mode 100644 dbx_tree/sigslot.h delete mode 100644 dbx_tree/stdint.h (limited to 'dbx_tree') diff --git a/dbx_tree/BTree.h b/dbx_tree/BTree.h deleted file mode 100644 index 20c2abf..0000000 --- a/dbx_tree/BTree.h +++ /dev/null @@ -1,1358 +0,0 @@ -/* - -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. - -*/ - -#pragma once - -#include -#include "lockfree_hashmultimap.h" -#include "sigslot.h" -#ifdef _MSC_VER -#include "stdint.h" -#else -#include -#endif - -#include "Logger.h" - -#ifndef _MSC_VER -#ifdef offsetof -#undef offsetof -#endif -#define offsetof(TYPE, MEMBER) \ - ( (reinterpret_cast \ - (&reinterpret_cast \ - (static_cast (0)->MEMBER)))) -#endif - -template -class CBTree -{ -public: - typedef uint32_t TNodeRef; /// 32bit indices (not storing pointers) - typedef sigslot::signal2< void *, TNodeRef > TOnRootChanged; - - #pragma pack(push, 1) // push current alignment to stack, set alignment to 1 byte boundary - - typedef struct TNode { - uint16_t Info; /// Node information (IsLeaf and stored KeyCount) - uint16_t Signature; /// signature - TNodeRef Parent; /// Handle to the parent node - TKey Key[SizeParam * 2 - 1]; /// array with Keys - TNodeRef Child[SizeParam * 2]; /// array with child node handles - } TNode; - - #pragma pack(pop) - - class iterator - { - public: - iterator(); - iterator(CBTree* Tree, TNodeRef Node, uint16_t Index); - iterator(const iterator& Other); - ~iterator(); - - CBTree * Tree(); - - /** - \brief Keeps track of changes in the tree and refresh the iterator - **/ - void setManaged(); - bool wasDeleted(); - - operator bool() const; - bool operator !() const; - - const TKey & operator *(); - const TKey * operator->(); - - - bool operator == (iterator & Other); - bool operator < (iterator & Other); - bool operator > (iterator & Other); - - iterator& operator =(const iterator& Other); - - iterator& operator ++(); //pre ++i - iterator& operator --(); //pre --i - iterator operator ++(int); //post i++ - iterator operator --(int); //post i-- - - - protected: - friend class CBTree; - - TNodeRef m_Node; - uint16_t m_Index; - CBTree* m_Tree; - - bool m_Managed; - bool m_LoadedKey; - TKey m_ManagedKey; - bool m_ManagedDeleted; - - void Backup(); - void Dec(); - void Inc(); - void RemoveManaged(TNodeRef FromNode); - void InsertManaged(); - }; - - - CBTree(TNodeRef RootNode = 0); - virtual ~CBTree(); - - iterator Insert(const TKey & Key); - iterator Find(const TKey & Key); - iterator LowerBound(const TKey & Key); - iterator UpperBound(const TKey & Key); - bool Delete(const TKey & Key); - - typedef sigslot::signal3 TDeleteCallback; - void DeleteTree(TDeleteCallback * CallBack, uint32_t Param); - - TNodeRef getRoot(); - void setRoot(TNodeRef NewRoot); - - TOnRootChanged & sigRootChanged() {return m_sigRootChanged;}; - - -protected: - static const uint16_t cIsLeafMask = 0x8000; - static const uint16_t cKeyCountMask = 0x7FFF; - static const uint16_t cFullNode = SizeParam * 2 - 1; - static const uint16_t cEmptyNode = SizeParam - 1; - - typedef lockfree::hash_multimap TManagedMap; - - TNodeRef m_Root; - TOnRootChanged m_sigRootChanged; - TManagedMap m_ManagedIterators; - - bool m_DestroyTree; - - uint32_t m_AllocCount; - uint32_t m_Count; - uint32_t m_FreeIndex; - TNode * m_Alloc; - - virtual void PrepareInsertOperation(); - virtual TNode * CreateNewNode(TNodeRef & NodeRef); - virtual void DeleteNode(TNodeRef Node); - virtual TNode * Read(TNodeRef Node); - virtual void Write(TNodeRef Node); - - void DestroyTree(); - - -private: - friend class iterator; - - bool InNodeFind(const TNode * Node, const TKey & Key, uint16_t & GreaterEqual); - void SplitNode(TNodeRef Node, TNode * NodeData, TNodeRef & Left, TNodeRef & Right, TKey & UpKey, TNodeRef ParentNode, uint16_t ParentIndex); - TNodeRef MergeNodes(TNodeRef Left, TNode * LeftData, TNodeRef Right, TNode * RightData, const TKey & DownKey, TNodeRef ParentNode, uint16_t ParentIndex); - void KeyInsert(TNodeRef Node, TNode * NodeData, uint16_t Where); - void KeyDelete(TNodeRef Node, TNode * NodeData, uint16_t Where); - void KeyMove(TNodeRef Source, uint16_t SourceIndex, const TNode * SourceData, TNodeRef Dest, uint16_t DestIndex, TNode * DestData); -}; - - - - - - -template -CBTree::CBTree(TNodeRef RootNode = NULL) -: m_sigRootChanged(), - m_ManagedIterators() -{ - m_Root = RootNode; - m_DestroyTree = true; - - m_AllocCount = 0; - m_Count = 0; - m_FreeIndex = 0; - m_Alloc = NULL; -} - -template -CBTree::~CBTree() -{ - typename TManagedMap::iterator i = m_ManagedIterators.begin(); - while (i != m_ManagedIterators.end()) - { - i->second->m_Tree = NULL; - i++; - } - - if (m_DestroyTree) - DestroyTree(); -} - -template -inline bool CBTree::InNodeFind(const TNode * Node, const TKey & Key, uint16_t & GreaterEqual) -{ - uint16_t l = 0; - uint16_t r = (Node->Info & cKeyCountMask); - bool res = false; - GreaterEqual = 0; - while ((l < r) && !res) - { - GreaterEqual = (l + r) >> 1; - if (Node->Key[GreaterEqual] < Key) - { - GreaterEqual++; - l = GreaterEqual; - } else if (Node->Key[GreaterEqual] == Key) - { - //r = -1; - res = true; - } else { - r = GreaterEqual; - } - } - - return res; -} - - -template -inline void CBTree::SplitNode(TNodeRef Node, TNode * NodeData, TNodeRef & Left, TNodeRef & Right, TKey & UpKey, TNodeRef ParentNode, uint16_t ParentIndex) -{ - const uint16_t upindex = SizeParam - 1; - TNode *ldata, *rdata; - Left = Node; - ldata = NodeData; - rdata = CreateNewNode(Right); - - typename TManagedMap::iterator it = m_ManagedIterators.find(Node); - while ((it != m_ManagedIterators.end()) && (it->first == Node)) - { - if (it->second->m_Index == upindex) - { - it->second->m_Index = ParentIndex; - it->second->m_Node = ParentNode; - m_ManagedIterators.insert(std::make_pair(ParentNode, it->second)); - it = m_ManagedIterators.erase(it); - } else if (it->second->m_Index > upindex) - { - it->second->m_Index = it->second->m_Index - upindex - 1; - it->second->m_Node = Right; - m_ManagedIterators.insert(std::make_pair(Right, it->second)); - it = m_ManagedIterators.erase(it); - } else { - ++it; - } - } - - UpKey = NodeData->Key[upindex]; - - memcpy(&(rdata->Key[0]), &(NodeData->Key[upindex+1]), sizeof(TKey) * (cFullNode - upindex)); - if ((NodeData->Info & cIsLeafMask) == 0) - { - memcpy(&(rdata->Child[0]), &(NodeData->Child[upindex+1]), sizeof(TNodeRef) * (cFullNode - upindex + 1)); - - for (int i = 0; i <= upindex; i++) - { - TNode * tmp = Read(rdata->Child[i]); - tmp->Parent = Right; - Write(rdata->Child[i]); - } - } - - rdata->Info = (NodeData->Info & cIsLeafMask) | upindex; - NodeData->Info = rdata->Info; - rdata->Parent = NodeData->Parent; - - Write(Left); - Write(Right); -} - -template -inline typename CBTree::TNodeRef CBTree::MergeNodes(TNodeRef Left, TNode * LeftData, TNodeRef Right, TNode * RightData, const TKey & DownKey, TNodeRef ParentNode, uint16_t ParentIndex) -{ - uint16_t downindex = LeftData->Info & cKeyCountMask; - LeftData->Key[downindex] = DownKey; - - typename TManagedMap::iterator it = m_ManagedIterators.find(Right); - while ((it != m_ManagedIterators.end()) && (it->first == Right)) - { - it->second->m_Index = it->second->m_Index + downindex + 1; - it->second->m_Node = Left; - m_ManagedIterators.insert(std::make_pair(Left, it->second)); - it = m_ManagedIterators.erase(it); - } - - it = m_ManagedIterators.find(ParentNode); - while ((it != m_ManagedIterators.end()) && (it->first == ParentNode)) - { - if (it->second->m_Index == ParentIndex) - { - it->second->m_Index = downindex; - it->second->m_Node = Left; - m_ManagedIterators.insert(std::make_pair(Left, it->second)); - it = m_ManagedIterators.erase(it); - } else { - ++it; - } - } - - memcpy(&(LeftData->Key[downindex+1]), &(RightData->Key[0]), sizeof(TKey) * (RightData->Info & cKeyCountMask)); - if ((LeftData->Info & cIsLeafMask) == 0) - { - memcpy(&(LeftData->Child[downindex+1]), &(RightData->Child[0]), sizeof(TNodeRef) * ((RightData->Info & cKeyCountMask) + 1)); - - for (int i = 0; i <= (RightData->Info & cKeyCountMask); i++) - { - TNode * tmp = Read(RightData->Child[i]); - tmp->Parent = Left; - Write(RightData->Child[i]); - } - } - - LeftData->Info = ((LeftData->Info & cIsLeafMask) | (downindex + 1 + (RightData->Info & cKeyCountMask))); - - Write(Left); - DeleteNode(Right); - - return Left; -} - - -template -inline void CBTree::KeyInsert(TNodeRef Node, TNode * NodeData, uint16_t Where) -{ - memcpy(&(NodeData->Key[Where+1]), &(NodeData->Key[Where]), sizeof(TKey) * ((NodeData->Info & cKeyCountMask) - Where)); - - if ((NodeData->Info & cIsLeafMask) == 0) - memcpy(&(NodeData->Child[Where+1]), &(NodeData->Child[Where]), sizeof(TNodeRef) * ((NodeData->Info & cKeyCountMask) - Where + 1)); - - NodeData->Info++; - - typename TManagedMap::iterator it = m_ManagedIterators.find(Node); - while ((it != m_ManagedIterators.end()) && (it->first == Node)) - { - if (it->second->m_Index >= Where) - it->second->m_Index++; - - ++it; - } -} - -template -inline void CBTree::KeyDelete(TNodeRef Node, TNode * NodeData, uint16_t Where) -{ - NodeData->Info--; - - typename TManagedMap::iterator it = m_ManagedIterators.find(Node); - while ((it != m_ManagedIterators.end()) && (it->first == Node)) - { - if (it->second->m_Index == Where) - { - it->second->Backup(); - } else if (it->second->m_Index > Where) - { - it->second->m_Index--; - } - - ++it; - } - - memcpy(&(NodeData->Key[Where]), &(NodeData->Key[Where+1]), sizeof(TKey) * ((NodeData->Info & cKeyCountMask) - Where)); - - if ((NodeData->Info & cIsLeafMask) == 0) - memcpy(&(NodeData->Child[Where]), &(NodeData->Child[Where+1]), sizeof(TNodeRef) * ((NodeData->Info & cKeyCountMask) - Where + 1)); -} - - -template -inline void CBTree::KeyMove(TNodeRef Source, uint16_t SourceIndex, const TNode * SourceData, TNodeRef Dest, uint16_t DestIndex, TNode * DestData) -{ - DestData->Key[DestIndex] = SourceData->Key[SourceIndex]; - - typename TManagedMap::iterator it = m_ManagedIterators.find(Source); - while ((it != m_ManagedIterators.end()) && (it->first == Source)) - { - if (it->second->m_Index == SourceIndex) - { - it->second->m_Index = DestIndex; - it->second->m_Node = Dest; - m_ManagedIterators.insert(std::make_pair(Dest, it->second)); - it = m_ManagedIterators.erase(it); - } else { - ++it; - } - } -} - -template -typename CBTree::iterator -CBTree::Insert(const TKey & Key) -{ - TNode *node, *node2; - TNodeRef actnode; - TNodeRef nextnode; - bool exists; - uint16_t ge; - - PrepareInsertOperation(); - - if (!m_Root) - { - node = CreateNewNode(m_Root); - node->Info = cIsLeafMask; - Write(m_Root); - m_sigRootChanged.emit(this, m_Root); - } - - actnode = m_Root; - node = Read(actnode); - if ((node->Info & cKeyCountMask) == cFullNode) // root split - { - // be a little tricky and let the main code handle the actual splitting. - // just assign a new root with keycount to zero and one child = old root - // the InNode test will fail with GreaterEqual = 0 - node2 = CreateNewNode(nextnode); - node2->Info = 0; - node2->Child[0] = actnode; - Write(nextnode); - - node->Parent = nextnode; - Write(actnode); - - node = node2; - actnode = nextnode; - - m_Root = nextnode; - m_sigRootChanged.emit(this, m_Root); - } - - while (actnode) - { - exists = InNodeFind(node, Key, ge); - if (exists) // already exists - { - return iterator(this, actnode, ge); - } else { - if (node->Info & cIsLeafMask) // direct insert to leaf node - { - KeyInsert(actnode, node, ge); - - node->Key[ge] = Key; - - Write(actnode); - - return iterator(this, actnode, ge); - - } else { // middle node - nextnode = node->Child[ge]; - node2 = Read(nextnode); - - if ((node2->Info & cKeyCountMask) == cFullNode) // split the childnode - { - KeyInsert(actnode, node, ge); - SplitNode(nextnode, node2, node->Child[ge], node->Child[ge+1], node->Key[ge], actnode, ge); - - Write(actnode); - if (node->Key[ge] == Key) - { - return iterator(this, actnode, ge); - } else { - if (node->Key[ge] < Key) - { - nextnode = node->Child[ge+1]; - } else { - nextnode = node->Child[ge]; - } - } - - } - actnode = nextnode; - node = Read(actnode); - - } // if (node.Info & cIsLeafMask) - } // if (exists) - } // while (actnode) - - // something went wrong - return iterator(this, 0, 0xFFFF); -} - - -template -typename CBTree::iterator -CBTree::Find(const TKey & Key) -{ - TNode * node; - TNodeRef actnode = m_Root; - uint16_t ge; - - if (!m_Root) return iterator(this, 0, 0xFFFF); - - node = Read(actnode); - - while (actnode) - { - if (InNodeFind(node, Key, ge)) - { - return iterator(this, actnode, ge); - } - - if (!(node->Info & cIsLeafMask)) - { - actnode = node->Child[ge]; - node = Read(actnode); - } else { - actnode = 0; - } - } - - return iterator(this, 0, 0xFFFF); -} - -template -typename CBTree::iterator -CBTree::LowerBound(const TKey & Key) -{ - TNode * node; - TNodeRef actnode = m_Root; - uint16_t ge; - - if (!m_Root) return iterator(this, 0, 0xFFFF); - - node = Read(actnode); - - while (actnode) - { - if (InNodeFind(node, Key, ge)) - { - return iterator(this, actnode, ge); - } - - if (node->Info & cIsLeafMask) - { - if (ge >= (node->Info & cKeyCountMask)) - { - iterator i(this, actnode, ge - 1); - ++i; - return i; - } else { - return iterator(this, actnode, ge); - } - } else { - actnode = node->Child[ge]; - node = Read(actnode); - } - } - - return iterator(this, 0, 0xFFFF); -} - -template -typename CBTree::iterator -CBTree::UpperBound(const TKey & Key) -{ - TNode * node; - TNodeRef actnode = m_Root; - uint16_t ge; - if (!m_Root) return iterator(this, 0, 0xFFFF); - - node = Read(actnode); - - while (actnode) - { - if (InNodeFind(node, Key, ge)) - { - return iterator(this, actnode, ge); - } - - if (node->Info & cIsLeafMask) - { - if (ge == 0) - { - iterator i(this, actnode, 0); - --i; - return i; - } else { - return iterator(this, actnode, ge - 1); - } - } else { - actnode = node->Child[ge]; - node = Read(actnode); - } - } - - return iterator(this, 0, 0xFFFF); -} - -template -bool CBTree::Delete(const TKey& Key) -{ - if (!m_Root) return false; - - TNode *node, *node2, *lnode, *rnode; - - TNodeRef actnode = m_Root; - TNodeRef nextnode, l, r; - bool exists, skipread; - uint16_t ge; - - bool foundininnernode = false; - bool wantleftmost = false; - TNodeRef innernode = 0; - TNode * innernodedata = NULL; - uint16_t innerindex = 0xFFFF; - - node = Read(actnode); - - while (actnode) - { - skipread = false; - - if (foundininnernode) - { - exists = false; - if (wantleftmost) - ge = 0; - else - ge = node->Info & cKeyCountMask; - - } else { - exists = InNodeFind(node, Key, ge); - } - - if (exists) - { - if (node->Info & cIsLeafMask) // delete in leaf - { - KeyDelete(actnode, node, ge); - Write(actnode); - - return true; - - } else { // delete in inner node - l = node->Child[ge]; - r = node->Child[ge+1]; - lnode = Read(l); - rnode = Read(r); - - - if (((rnode->Info & cKeyCountMask) == cEmptyNode) && ((lnode->Info & cKeyCountMask) == cEmptyNode)) - { // merge childnodes and keep going - nextnode = MergeNodes(l, lnode, r, rnode, node->Key[ge], actnode, ge); - - KeyDelete(actnode, node, ge); - node->Child[ge] = nextnode; - - if ((actnode == m_Root) && ((node->Info & cKeyCountMask) == 0)) - { // root node is empty. delete it - DeleteNode(actnode); - m_Root = nextnode; - m_sigRootChanged.emit(this, m_Root); - } else { - Write(actnode); - } - - } else { // need a key-data-pair from a leaf to replace deleted pair -> save position - foundininnernode = true; - innernode = actnode; - innerindex = ge; - innernodedata = node; - - if ((lnode->Info & cKeyCountMask) == cEmptyNode) - { - wantleftmost = true; - nextnode = r; - } else { - wantleftmost = false; - nextnode = l; - } - } - } - - } else if (node->Info & cIsLeafMask) { // we are at the bottom. finish it - if (foundininnernode) - { - if (wantleftmost) - { - KeyMove(actnode, 0, node, innernode, innerindex, innernodedata); - Write(innernode); - - KeyDelete(actnode, node, 0); - Write(actnode); - - } else { - KeyMove(actnode, (node->Info & cKeyCountMask) - 1, node, innernode, innerindex, innernodedata); - Write(innernode); - - //KeyDelete(actnode, node, node.Info & cKeyCountMask); - node->Info--; - Write(actnode); - } - } - return foundininnernode; - - } else { // inner node. go on and check if moving or merging is neccessary - nextnode = node->Child[ge]; - node2 = Read(nextnode); - - if ((node2->Info & cKeyCountMask) == cEmptyNode) // move or merge - { - // set l and r for easier access - if (ge > 0) - { - l = node->Child[ge - 1]; - lnode = Read(l); - } else - l = 0; - - if (ge < (node->Info & cKeyCountMask)) - { - r = node->Child[ge + 1]; - rnode = Read(r); - } else - r = 0; - - if ((r != 0) && ((rnode->Info & cKeyCountMask) > cEmptyNode)) // move a Key-Data-pair from the right - { - // move key-data-pair down from current to the next node - KeyMove(actnode, ge, node, nextnode, node2->Info & cKeyCountMask, node2); - - // move the child from right to next node - node2->Child[(node2->Info & cKeyCountMask) + 1] = rnode->Child[0]; - - // move key-data-pair up from right to current node - KeyMove(r, 0, rnode, actnode, ge, node); - Write(actnode); - - // decrement right node key count and remove the first key-data-pair - KeyDelete(r, rnode, 0); - - // increment KeyCount of the next node - node2->Info++; - - if ((node2->Info & cIsLeafMask) == 0) // update the parent property of moved child - { - TNode * tmp = Read(node2->Child[node2->Info & cKeyCountMask]); - tmp->Parent = nextnode; - Write(node2->Child[node2->Info & cKeyCountMask]); - } - - - Write(r); - Write(nextnode); - node = node2; - skipread = true; - - } else if ((l != 0) && ((lnode->Info & cKeyCountMask) > cEmptyNode)) // move a Key-Data-pair from the left - { - // increment next node key count and make new first key-data-pair - KeyInsert(nextnode, node2, 0); - - // move key-data-pair down from current to the next node - KeyMove(actnode, ge - 1, node, nextnode, 0, node2); - - // move the child from left to next node - node2->Child[0] = lnode->Child[lnode->Info & cKeyCountMask]; - - // move key-data-pair up from left to current node - KeyMove(l, (lnode->Info & cKeyCountMask) - 1, lnode, actnode, ge - 1, node); - Write(actnode); - - // decrement left node key count - lnode->Info--; - Write(l); - - if ((node2->Info & cIsLeafMask) == 0) // update the parent property of moved child - { - TNode * tmp = Read(node2->Child[0]); - tmp->Parent = nextnode; - Write(node2->Child[0]); - } - - Write(nextnode); - node = node2; - skipread = true; - - } else { - if (l != 0) // merge with the left node - { - nextnode = MergeNodes(l, lnode, nextnode, node2, node->Key[ge - 1], actnode, ge - 1); - KeyDelete(actnode, node, ge - 1); - node->Child[ge - 1] = nextnode; - - } else { // merge with the right node - nextnode = MergeNodes(nextnode, node2, r, rnode, node->Key[ge], actnode, ge); - KeyDelete(actnode, node, ge); - node->Child[ge] = nextnode; - } - - if ((actnode == m_Root) && ((node->Info & cKeyCountMask) == 0)) - { - DeleteNode(actnode); - m_Root = nextnode; - m_sigRootChanged(this, nextnode); - } else { - Write(actnode); - } - } - } - } // if (exists) else if (node.Info & cIsLeafMask) - - actnode = nextnode; - if (!skipread) - node = Read(actnode); - - } // while(actnode) - - return false; -} - -template -typename CBTree::TNodeRef CBTree::getRoot() -{ - return m_Root; -} - -template -void CBTree::setRoot(TNodeRef NewRoot) -{ - m_Root = NewRoot; - return; -} - -template -void CBTree::PrepareInsertOperation() -{ - if (m_Count + 64 > m_AllocCount) - { - m_AllocCount += 64; - m_Alloc = (TNode *)realloc(m_Alloc, sizeof(TNode) * m_AllocCount); - - for (TNodeRef i = m_AllocCount - 64; i < m_AllocCount; ++i) - m_Alloc[i].Parent = i + 1; - - m_Alloc[m_AllocCount - 1].Parent = 0; - - if (m_FreeIndex) - { - TNodeRef i = m_FreeIndex; - while (m_Alloc[i].Parent) - i = m_Alloc[i].Parent; - - m_Alloc[i].Parent = m_AllocCount - 64; - - } else { - m_FreeIndex = m_AllocCount - 63; - } - - } -} - -template -typename CBTree::TNode * CBTree::CreateNewNode(TNodeRef & NodeRef) -{ - NodeRef = m_FreeIndex; - m_FreeIndex = m_Alloc[m_FreeIndex].Parent; - m_Count++; - memset(m_Alloc + NodeRef, 0, sizeof(TNode)); - return m_Alloc + NodeRef; -} - -template -void CBTree::DeleteNode(TNodeRef Node) -{ - CHECK((Node > 0) && (Node < m_AllocCount), logERROR, _T("Invalid Node")); - m_Alloc[Node].Parent = m_FreeIndex; - m_FreeIndex = Node; - m_Count--; -} - -template -typename CBTree::TNode * CBTree::Read(TNodeRef Node) -{ - CHECK((Node > 0) && (Node < m_AllocCount), logERROR, _T("Invalid Node")); - return m_Alloc + Node; -} - -template -void CBTree::Write(TNodeRef Node) -{ - return; -} - -template -void CBTree::DestroyTree() -{ - std::stack s; - TNodeRef node; - TNode* nodedata; - uint16_t i; - - if (m_Root) - s.push(m_Root); - while (!s.empty()) - { - node = s.top(); - nodedata = Read(node); - s.pop(); - - if ((nodedata->Info & cIsLeafMask) == 0) - { - for (i = 0; i <= (nodedata->Info & cKeyCountMask); i++) - s.push(nodedata->Child[i]); - } - - DeleteNode(node); - } - - if (m_Alloc) - free(m_Alloc); - m_Alloc = NULL; - m_AllocCount = 0; - m_Count = 0; - m_FreeIndex = 0; -} - - -template -void CBTree::DeleteTree(TDeleteCallback * CallBack, uint32_t Param) -{ - std::stack s; - TNodeRef actnode; - TNode * node; - uint16_t i; - - typename TManagedMap::iterator it = m_ManagedIterators.begin(); - while (it != m_ManagedIterators.end()) - { - it->second->m_Node = 0; - it->second->m_Index = 0xffff; - ++it; - } - - if (m_Root) - s.push(m_Root); - - m_Root = 0; - m_sigRootChanged.emit(this, m_Root); - - while (!s.empty()) - { - actnode = s.top(); - s.pop(); - - node = Read(actnode); - - if ((node->Info & cIsLeafMask) == 0) - { - for (i = 0; i <= (node->Info & cKeyCountMask); i++) - s.push(node->Child[i]); - - } - if (CallBack) - { - for (i = 0; i < (node->Info & cKeyCountMask); i++) - CallBack->emit(this, node->Key[i], Param); - } - - DeleteNode(actnode); - } -} - - - - - - - -template -CBTree::iterator::iterator() -{ - m_Tree = NULL; - m_Node = 0; - m_Index = 0xFFFF; - m_Managed = false; - m_ManagedDeleted = false; - m_LoadedKey = false; -} -template -CBTree::iterator::iterator(CBTree* Tree, TNodeRef Node, uint16_t Index) -{ - m_Tree = Tree; - m_Node = Node; - m_Index = Index; - m_Managed = false; - m_ManagedDeleted = false; - m_LoadedKey = false; -} -template -CBTree::iterator::iterator(const iterator& Other) -{ - m_Tree = Other.m_Tree; - m_Node = Other.m_Node; - m_Index = Other.m_Index; - m_ManagedDeleted = Other.m_ManagedDeleted; - m_Managed = Other.m_Managed; - m_LoadedKey = Other.m_LoadedKey; - m_ManagedKey = Other.m_ManagedKey; - - if (m_Managed) - InsertManaged(); -} - -template -CBTree::iterator::~iterator() -{ - RemoveManaged(m_Node); -} - - -template -void CBTree::iterator::setManaged() -{ - if (!m_Managed) - InsertManaged(); - - m_Managed = true; -} - -template -inline void CBTree::iterator::RemoveManaged(TNodeRef FromNode) -{ - if (m_Managed && m_Tree) - { - typename TManagedMap::iterator i = m_Tree->m_ManagedIterators.find(FromNode); - - while ((i != m_Tree->m_ManagedIterators.end()) && (i->second != this) && (i->first == FromNode)) - ++i; - - if ((i != m_Tree->m_ManagedIterators.end()) && (i->second == this)) - m_Tree->m_ManagedIterators.erase(i); - } -} -template -inline void CBTree::iterator::InsertManaged() -{ - if (m_Tree) - m_Tree->m_ManagedIterators.insert(std::make_pair(m_Node, this)); -} - -template -bool CBTree::iterator::wasDeleted() -{ - return m_ManagedDeleted; -} - -template -void CBTree::iterator::Backup() -{ - if ((!m_ManagedDeleted) && (*this)) - { - TNode * tmp; - if (!m_LoadedKey) - { - tmp = m_Tree->Read(m_Node); - m_ManagedKey = tmp->Key[m_Index]; - } - m_LoadedKey = true; - } - - m_ManagedDeleted = true; -} - -template -CBTree * CBTree::iterator::Tree() -{ - return m_Tree; -} - -template -const TKey& CBTree::iterator::operator *() -{ - if (!m_LoadedKey) - { - TNode * node; - node = m_Tree->Read(m_Node); - m_ManagedKey = node->Key[m_Index]; - m_LoadedKey = true; - } - return m_ManagedKey; -} - -template -const TKey* CBTree::iterator::operator ->() -{ - if (!m_LoadedKey) - { - TNode * node; - node = m_Tree->Read(m_Node); - m_ManagedKey = node->Key[m_Index]; - m_LoadedKey = true; - } - return &m_ManagedKey; -} - -template -inline CBTree::iterator::operator bool() const -{ - if (m_Tree && m_Node) - { - TNode * node; - node = m_Tree->Read(m_Node); - return (m_Index < (node->Info & cKeyCountMask)); - } else - return false; -} - -template -inline bool CBTree::iterator::operator !() const -{ - if (m_Tree && m_Node) - { - TNode * node; - node = m_Tree->Read(m_Node); - return (m_Index > (node->Info & cKeyCountMask)); - } else - return true; -} - -template -inline bool CBTree::iterator::operator ==(iterator & Other) -{ - //return (m_Tree == Other.m_Tree) && (m_Node == Other.m_Node) && (m_Index == Other.m_Index) && (!m_ManagedDeleted) && (!Other.m_ManagedDeleted); - return Key() == Other.Key(); -} - -template -inline bool CBTree::iterator::operator < (iterator & Other) -{ - return Key() < Other.Key(); -} -template -inline bool CBTree::iterator::operator > (iterator & Other) -{ - return Key() > Other.Key(); -} - - -template -typename CBTree::iterator& -CBTree::iterator::operator =(const iterator& Other) -{ - RemoveManaged(m_Node); - - m_Tree = Other.m_Tree; - m_Node = Other.m_Node; - m_Index = Other.m_Index; - m_ManagedDeleted = Other.m_ManagedDeleted; - m_Managed = Other.m_Managed; - m_LoadedKey = Other.m_LoadedKey; - m_ManagedKey = Other.m_ManagedKey; - - if (m_Managed) - InsertManaged(); - - return *this; -} - -template -typename CBTree::iterator& -CBTree::iterator::operator ++() //pre ++i -{ - TNodeRef oldnode = m_Node; - if (m_Managed && m_ManagedDeleted) - { - TKey oldkey = m_ManagedKey; - m_LoadedKey = false; - m_ManagedDeleted = false; - iterator other = m_Tree->LowerBound(m_ManagedKey); - m_Node = other.m_Node; - m_Index = other.m_Index; - while (((**this) == oldkey) && (*this)) - Inc(); - - } else - Inc(); - - if (m_Managed && (oldnode != m_Node)) - { - RemoveManaged(oldnode); - InsertManaged(); - } - return *this; -} - -template -typename CBTree::iterator& -CBTree::iterator::operator --() //pre --i -{ - TNodeRef oldnode = m_Node; - if (m_Managed && m_ManagedDeleted) - { - TKey oldkey = m_ManagedKey; - m_LoadedKey = false; - - m_ManagedDeleted = false; - iterator other = m_Tree->UpperBound(m_ManagedKey); - m_Node = other.m_Node; - m_Index = other.m_Index; - while (((**this) == oldkey) && (*this)) - Dec(); - } else - Dec(); - - if (m_Managed && (oldnode != m_Node)) - { - RemoveManaged(oldnode); - InsertManaged(); - } - return *this; -} - -template -typename CBTree::iterator -CBTree::iterator::operator ++(int) //post i++ -{ - iterator tmp(*this); - ++(*this); - return tmp; -} -template -typename CBTree::iterator -CBTree::iterator::operator --(int) //post i-- -{ - iterator tmp(*this); - --(*this); - return tmp; -} - -template -void CBTree::iterator::Inc() -{ - TNode * node; - TNodeRef nextnode; - node = m_Tree->Read(m_Node); - - m_LoadedKey = false; - - if ((node->Info & cIsLeafMask) && ((node->Info & cKeyCountMask) > m_Index + 1)) // leaf - { - m_Index++; - return; - } - - if ((node->Info & cIsLeafMask) == 0) // inner node. go down - { - m_Node = node->Child[m_Index + 1]; - node = m_Tree->Read(m_Node); - - m_Index = 0; - - while ((node->Info & cIsLeafMask) == 0) // go down to a leaf - { - m_Node = node->Child[0]; - node = m_Tree->Read(m_Node); - } - - return; - } - - while (m_Index >= (node->Info & cKeyCountMask) - 1) // go up - { - if (m_Node == m_Tree->m_Root) // the root is the top, we cannot go further - { - m_Index = 0xFFFF; - m_Node = 0; - return; - } - - nextnode = node->Parent; - node = m_Tree->Read(nextnode); - m_Index = 0; - - while ((m_Index <= (node->Info & cKeyCountMask)) && (node->Child[m_Index] != m_Node)) - m_Index++; - - m_Node = nextnode; - - if (m_Index < (node->Info & cKeyCountMask)) - return; - } - -} - -template -void CBTree::iterator::Dec() -{ - TNode * node; - TNodeRef nextnode; - node = m_Tree->Read(m_Node); - - m_LoadedKey = false; - - if ((node->Info & cIsLeafMask) && (m_Index > 0)) // leaf - { - m_Index--; - return; - } - - if ((node->Info & cIsLeafMask) == 0) // inner node. go down - { - m_Node = node->Child[m_Index]; - node = m_Tree->Read(m_Node); - m_Index = (node->Info & cKeyCountMask) - 1; - - while ((node->Info & cIsLeafMask) == 0) // go down to a leaf - { - m_Node = node->Child[node->Info & cKeyCountMask]; - node = m_Tree->Read(m_Node); - m_Index = (node->Info & cKeyCountMask) - 1; - } - - return; - } - - while (m_Index == 0) // go up - { - if (m_Node == m_Tree->m_Root) // the root is the top, we cannot go further - { - m_Index = 0xFFFF; - m_Node = 0; - return; - } - - nextnode = node->Parent; - node = m_Tree->Read(nextnode); - m_Index = 0; - - while ((m_Index <= (node->Info & cKeyCountMask)) && (node->Child[m_Index] != m_Node)) - m_Index++; - - m_Node = nextnode; - - if (m_Index > 0) - { - m_Index--; - return; - } - } -} diff --git a/dbx_tree/BlockManager.cpp b/dbx_tree/BlockManager.cpp deleted file mode 100644 index 3be5d80..0000000 --- a/dbx_tree/BlockManager.cpp +++ /dev/null @@ -1,965 +0,0 @@ -/* - -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 "BlockManager.h" -#include "Logger.h" - -CBlockManager::CBlockManager( - CFileAccess & FileAccess, - CEncryptionManager & EncryptionManager - ) -: m_BlockSync(), - m_FileAccess(FileAccess), - m_EncryptionManager(EncryptionManager), - m_BlockTable(1024), - m_FreeBlocks() -{ - m_Optimize.Thread = NULL; - m_Optimize.Source = 0; - m_Optimize.Dest = 0; - - m_CacheInfo.Growth = 0; - m_CacheInfo.Size = 0; - m_CacheInfo.LastPurge = time(NULL); - - m_PendingHead = NULL; - m_PendingTail = NULL; - m_PendingLast = NULL; - m_LastFlush = time(NULL); - m_BytesPending = 20; - m_FirstFreeIndex = 0; - - m_SaveMode = true; - m_ReadOnly = m_FileAccess.ReadOnly(); - - memset(m_Cache, 0, sizeof(m_Cache)); -} - -CBlockManager::~CBlockManager() -{ - m_BlockSync.BeginWrite(); - if (m_Optimize.Thread) - { - m_Optimize.Thread->FreeOnTerminate(false); - m_Optimize.Thread->Terminate(); - - m_BlockSync.EndWrite(); - m_Optimize.Thread->WaitFor(); - - delete m_Optimize.Thread; - } else { - m_BlockSync.EndWrite(); - } - - _PendingFlush(true); - - for (uint32_t buddy = 0; buddy < cCacheBuddyCount; buddy++) - { - TCacheEntry * i = m_Cache[buddy]; - while (i) - { - free(i->Cache); - - TCacheEntry * tmp = i; - i = i->Next; - free(tmp); - } - } -} - -// Optimize File Size -void CBlockManager::ExecuteOptimize() -{ /* - TBlockHeadFree h = {0,0}; - uint8_t * buf = (uint8_t*)malloc(1 << 18); // 256kb - uint32_t bufuse = 0; - uint32_t bufsize = 1 << 18; - uint32_t lastflush = 0; - - { - int i = 0; - while (!m_Optimize.Thread->Terminated() && (i < 600)) - { - ++i; - Sleep(100); // wait for Miranda to start - } - } - - TransactionBeginWrite(); - - while (!m_Optimize.Thread->Terminated() && (m_Optimize.Source < m_FileAccess.Size()) && !m_ReadOnly) - { - m_FileAccess.Read(&h, m_Optimize.Source, sizeof(h)); - if (h.ID == cFreeBlockID) - { - _RemoveFreeBlock(m_Optimize.Source, h.Size); - - m_Optimize.Source += h.Size; - } else { - - if (bufsize < bufuse + h.Size) - { - buf = (uint8_t*)realloc(buf, bufuse + h.Size); - bufsize = bufuse + h.Size; - } - m_FileAccess.Read(buf + bufuse, m_Optimize.Source, h.Size); - - m_BlockTable[h.ID >> 2].Addr = (m_Optimize.Dest + bufuse) >> 2; - - m_Optimize.Source += h.Size; - bufuse += h.Size; - } - - if ((m_BlockSync.Waiting() > 0) - || (bufuse + 1024 >= bufsize) - || (m_Optimize.Source >= m_FileAccess.Size())) // buffer is nearly full or EOF - { - if (m_Optimize.Dest != m_Optimize.Source) // move blocks - { - TBlockHeadFree h = {cFreeBlockID, m_Optimize.Source - m_Optimize.Dest}; - TBlockTailFree t = {m_Optimize.Source - m_Optimize.Dest, cFreeBlockID}; - - m_FileAccess.Write(buf, m_Optimize.Dest, bufuse); - - m_FileAccess.Write(&h, m_Optimize.Dest + bufuse, sizeof(h)); - m_FileAccess.Invalidate(m_Optimize.Dest + bufuse + sizeof(h), m_Optimize.Source - m_Optimize.Dest - bufuse - sizeof(h) - sizeof(t)); - m_FileAccess.Write(&t, m_Optimize.Dest + bufuse - sizeof(t), sizeof(t)); - - if (m_SaveMode) - { - m_FileAccess.CloseTransaction(); - m_FileAccess.Flush(); - m_FileAccess.UseJournal(false); - - m_FileAccess.Write(buf, m_Optimize.Dest, bufuse); - - m_FileAccess.Write(&h, m_Optimize.Dest + bufuse, sizeof(h)); - m_FileAccess.Invalidate(m_Optimize.Dest + bufuse + sizeof(h), m_Optimize.Source - m_Optimize.Dest - bufuse - sizeof(h) - sizeof(t)); - m_FileAccess.Write(&t, m_Optimize.Dest + bufuse - sizeof(t), sizeof(t)); - - m_FileAccess.Flush(); - m_FileAccess.CleanJournal(); - m_FileAccess.UseJournal(true); - } - - m_Optimize.Dest += bufuse; - bufuse = 0; - } - - if (m_BlockSync.Waiting() > 0) - { - unsigned int w = m_BlockSync.Waiting(); - m_BlockSync.EndWrite(); - Sleep(w * 64 + 1); - m_BlockSync.BeginWrite(); - m_FileAccess.UseJournal(m_SaveMode); - } - } - } - - if (m_Optimize.Source >= m_FileAccess.Size()) - m_FileAccess.Size(m_Optimize.Dest); - - m_Optimize.Thread = NULL; - m_Optimize.Source = 0; - m_Optimize.Dest = 0; - if (m_SaveMode) - TransactionEndWrite(); - else - m_BlockSync.EndWrite(); - - free(buf); */ - - m_Optimize.Thread = NULL; -} - -inline void CBlockManager::_PendingAdd(uint32_t BlockID, uint32_t Addr, uint32_t Size, TCacheEntry * Cache) -{ - TPendingOperation * p = NULL; - if (BlockID == cFreeBlockID) - { - p = (TPendingOperation*)malloc(sizeof(TPendingOperation)); - - p->BlockID = cFreeBlockID; - p->Addr = Addr; - p->Size = Size; - p->CacheEntry = NULL; - p->EncryptionBuffer = NULL; - - m_BytesPending += 24 + sizeof(TBlockHeadFree) + sizeof(TBlockTailFree); - if (Addr & cPendingInvalidate) - m_BytesPending += 12; - - } else { - if (Cache->Pending) - { - p = Cache->Pending; - _PendingRemove(Cache->Pending, false); - } else { - p = (TPendingOperation*)malloc(sizeof(TPendingOperation)); - } - - p->BlockID = BlockID; - p->Addr = Addr; - p->Size = Size; - p->CacheEntry = Cache; - p->EncryptionBuffer = NULL; - - m_BytesPending += 12 + Size; - - Cache->Pending = p; - } - - p->Next = NULL; - p->Prev = m_PendingTail; - if (m_PendingTail) - m_PendingTail->Next = p; - - m_PendingTail = p; - if (!m_PendingHead) - m_PendingHead = p; -} - -inline void CBlockManager::_PendingRemove(TPendingOperation * Pending, bool Free) -{ - if (Pending->Prev) - Pending->Prev->Next = Pending->Next; - else - m_PendingHead = Pending->Next; - - if (Pending->Next) - Pending->Next->Prev = Pending->Prev; - else - m_PendingTail = Pending->Prev; - - if (Pending->EncryptionBuffer) - free(Pending->EncryptionBuffer); - - if (m_PendingLast == Pending) - m_PendingLast = Pending->Prev; - - Pending->CacheEntry->Pending = NULL; - if (Free) - free(Pending); -} - -inline void CBlockManager::_PendingFlush(bool FullFlush) -{ - TPendingOperation * i = NULL; - - if (m_ReadOnly) - return; - - if (FullFlush) - { - if (m_SaveMode) - { - _PendingFlush(false); // write to journal - m_FileAccess.Flush(); - m_FileAccess.UseJournal(false); - m_FileAccess.Size(m_FileAccess.Size()); // resize real file - } else { - m_FileAccess.UseJournal(false); - } - - i = m_PendingHead; - } else if (m_PendingLast) - { - i = m_PendingLast->Next; - m_FileAccess.UseJournal(m_SaveMode); - } else { - i = m_PendingHead; - m_FileAccess.UseJournal(m_SaveMode); - } - - while (i) - { - if (i->BlockID == cFreeBlockID) - { - uint32_t addr = i->Addr & ~cPendingInvalidate; - if (addr + i->Size <= m_FileAccess.Size()) - { - TBlockHeadFree h = {cFreeBlockID, i->Size}; - TBlockTailFree t = {i->Size, cFreeBlockID}; - - m_FileAccess.Write(&h, addr, sizeof(h)); - if (i->Addr & cPendingInvalidate) - m_FileAccess.Invalidate(addr + sizeof(h), i->Size - sizeof(h) - sizeof(t)); - m_FileAccess.Write(&t, addr + i->Size - sizeof(t), sizeof(t)); - } - - } else { - - if (i->BlockID && !i->EncryptionBuffer && m_EncryptionManager.IsEncrypted(i->BlockID)) - { - i->EncryptionBuffer = (TBlockHeadOcc*) malloc(i->Size); - memcpy(i->EncryptionBuffer, i->CacheEntry->Cache, i->Size); - m_EncryptionManager.Encrypt(i->EncryptionBuffer + 1, i->Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc), i->BlockID, 0); - } - - if (i->EncryptionBuffer) - { - m_FileAccess.Write(i->EncryptionBuffer, i->Addr, i->Size); - } else { - m_FileAccess.Write(i->CacheEntry->Cache, i->Addr, i->Size); - } - } - - i = i->Next; - } // while - - if (FullFlush) - { - m_FileAccess.Flush(); - if (m_SaveMode) - m_FileAccess.CleanJournal(); - - m_BytesPending = 20; - m_LastFlush = time(NULL); - - i = m_PendingHead; - while (i) - { - if (i->EncryptionBuffer) - free(i->EncryptionBuffer); - - if (i->CacheEntry) - i->CacheEntry->Pending = NULL; - - TPendingOperation * tmp = i; - i = i->Next; - free(tmp); - } - m_PendingHead = NULL; - m_PendingTail = NULL; - m_PendingLast = NULL; - } else { - m_PendingLast = m_PendingTail; - m_FileAccess.CloseTransaction(); - } -} - -inline CBlockManager::TCacheEntry * CBlockManager::_CacheInsert(uint32_t Idx, TBlockHeadOcc * Cache, bool Virtual) -{ - TCacheEntry * res; - uint32_t myidx = ROR_32(Idx, cCacheBuddyBits); - - res = (TCacheEntry *)malloc(sizeof(TCacheEntry)); - res->Cache = Cache; - res->Pending = NULL; - res->Idx = myidx; - res->Forced = Virtual; - - TCacheEntry * volatile * last = &m_Cache[Idx % cCacheBuddyCount]; - TCacheEntry * i; - do { - i = *last; - - while (i && (i->Idx < myidx)) - { - last = &i->Next; - i = i->Next; - } - - if (i && (i->Idx == myidx)) - { - free(res); - free(Cache); - - i->LastUse = time(NULL) >> 2; - return i; - } - - res->Next = i; - - } while (i != CMPXCHG_Ptr(*last, res, i) ); - - res->LastUse = time(NULL) >> 2; - - m_BlockTable[Idx].InCache = true; - if (!Virtual) - XADD_32(m_CacheInfo.Growth, res->Cache->Size); - - return res; -} - -inline CBlockManager::TCacheEntry * CBlockManager::_CacheFind(uint32_t Idx) -{ - TCacheEntry * i = m_Cache[Idx % cCacheBuddyCount]; - uint32_t myidx = ROR_32(Idx, cCacheBuddyBits); - while (i && (i->Idx < myidx)) - i = i->Next; - - if (i && (i->Idx == myidx)) - return i; - else - return NULL; -} - -inline void CBlockManager::_CacheErase(uint32_t Idx) -{ - TCacheEntry * i = m_Cache[Idx % cCacheBuddyCount]; - TCacheEntry * volatile * l = &m_Cache[Idx % cCacheBuddyCount]; - - uint32_t myidx = ROR_32(Idx, cCacheBuddyBits); - - while (i->Idx < myidx) - { - l = &i->Next; - i = i->Next; - } - *l = i->Next; - - if (i->Cache) - free(i->Cache); - free(i); -} - -inline void CBlockManager::_CachePurge() -{ - _PendingFlush(true); - - uint32_t ts = time(NULL); - if (m_CacheInfo.Size + m_CacheInfo.Growth > cCachePurgeSize) { - ts = ts - (ts - m_CacheInfo.LastPurge) * cCachePurgeSize / (m_CacheInfo.Size + 2 * m_CacheInfo.Growth); - } else if (m_CacheInfo.Growth > m_CacheInfo.Size) - { - ts = ts - (ts - m_CacheInfo.LastPurge) * m_CacheInfo.Size / m_CacheInfo.Growth; - } else if (m_CacheInfo.Size > m_CacheInfo.Growth) - { - ts = ts - (ts - m_CacheInfo.LastPurge) * m_CacheInfo.Growth / m_CacheInfo.Size; - } else { - ts = m_CacheInfo.LastPurge; - } - - m_CacheInfo.Size += m_CacheInfo.Growth; - m_CacheInfo.Growth = 0; - m_CacheInfo.LastPurge = time(NULL); - - for (uint32_t buddy = 0; buddy < cCacheBuddyCount; buddy++) - { - TCacheEntry * i = m_Cache[buddy]; - TCacheEntry * volatile * l = &m_Cache[buddy]; - - while (i) - { - if (!i->Forced && !i->KeepInCache && i->Idx && ((i->LastUse << 2) < ts)) - { - uint32_t idx = ROL_32(i->Idx, cCacheBuddyBits); - m_CacheInfo.Size -= i->Cache->Size; - m_BlockTable[idx].InCache = false; - free(i->Cache); - - *l = i->Next; - TCacheEntry * tmp = i; - i = i->Next; - free(tmp); - - } else { - l = &i->Next; - i = i->Next; - } - } - } -} - -inline uint32_t CBlockManager::_GetAvailableIndex() -{ - uint32_t id; - if (m_FirstFreeIndex) - { - id = m_FirstFreeIndex; - m_FirstFreeIndex = m_BlockTable[id].Addr; - TBlockTableEntry b = {false, false, 0}; - m_BlockTable[id] = b; - } else { - id = static_cast(m_BlockTable.size()); - if (id > (1 << 12)) - m_BlockTable.resize(id + (1 << 12)); - else - m_BlockTable.resize(id * 2); - - for (uint32_t i = static_cast(m_BlockTable.size() - 1); i > id; --i) - { - TBlockTableEntry b = {true, true, m_FirstFreeIndex}; - m_BlockTable[i] = b; - m_FirstFreeIndex = i; - } - } - return id; -} - -inline void CBlockManager::_InsertFreeBlock(uint32_t Addr, uint32_t Size, bool InvalidateData, bool Reuse) -{ - if (Addr + Size == m_FileAccess.Size()) - { - if (Reuse) // in FindFreePosition we would want to use that block - m_FileAccess.Size(Addr); - } else { - - if (Reuse) - m_FreeBlocks.insert(std::make_pair(Size, Addr)); - - if (!m_ReadOnly) - _PendingAdd(cFreeBlockID, InvalidateData ? Addr | cPendingInvalidate : Addr, Size, NULL); - - } -} - -inline void CBlockManager::_RemoveFreeBlock(uint32_t Addr, uint32_t Size) -{ - TFreeBlockMap::iterator i = m_FreeBlocks.find(Size); - while ((i != m_FreeBlocks.end()) && (i->first == Size)) - { - if (i->second == Addr) - { - m_FreeBlocks.erase(i); - i = m_FreeBlocks.end(); - } else { - ++i; - } - } -} - -inline uint32_t CBlockManager::_FindFreePosition(uint32_t Size) -{ - // try to find free block - TFreeBlockMap::iterator f; - TFreeBlockMap::iterator e = m_FreeBlocks.end(); - - if (m_FreeBlocks.size()) - { - f = m_FreeBlocks.find(Size); - if (f == e) - { - if (m_FreeBlocks.rbegin()->first > Size * 2) - { - f = m_FreeBlocks.end(); - --f; - } - } - } else { - f = e; - } - - uint32_t addr = 0; - - if (f == e) // no block found - expand file - { - addr = m_FileAccess.Size(); - m_FileAccess.Size(addr + Size); - - } else { - addr = f->second; - - if (f->first != Size) - { - _InsertFreeBlock(addr + Size, f->first - Size, false, true); - } - _InsertFreeBlock(addr, Size, false, false); - - m_FreeBlocks.erase(f); - } - - return addr; -} - -inline bool CBlockManager::_InitOperation(uint32_t BlockID, uint32_t & Addr, TCacheEntry * & Cache) -{ - if (!BlockID || (BlockID & 3) || ((BlockID >> 2) >= m_BlockTable.size())) - return false; - - uint32_t idx = BlockID >> 2; - TBlockTableEntry dat = m_BlockTable[idx]; - - if (dat.Deleted) // deleted or FreeIDList item - return false; - - Addr = dat.Addr << 2; - if (dat.InCache) - { - Cache = _CacheFind(idx); - } else if (Addr) - { - TBlockHeadOcc h; - - m_FileAccess.Read(&h, Addr, sizeof(h)); - - TBlockHeadOcc * block = (TBlockHeadOcc *) malloc(h.Size); - m_FileAccess.Read(block, Addr, h.Size); - - m_EncryptionManager.Decrypt(block + 1, h.Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc), BlockID, 0); - - Cache = _CacheInsert(idx, block, false); - } else { - return false; - } - - return Cache != NULL; -} - -inline void CBlockManager::_UpdateBlock(uint32_t BlockID, TCacheEntry * CacheEntry, uint32_t Addr) -{ - CacheEntry->KeepInCache = m_ReadOnly; - - if (!CacheEntry->Forced) - { - if (!m_ReadOnly) - _PendingAdd(BlockID, Addr, CacheEntry->Cache->Size, CacheEntry); - } -} - - -uint32_t CBlockManager::ScanFile(uint32_t FirstBlockStart, uint32_t HeaderSignature, uint32_t FileSize) -{ - TBlockHeadOcc h, lasth = {0, 0, 0}; - uint32_t p; - uint32_t res = 0; - bool invalidateblock = false; - - p = FirstBlockStart; - m_FirstBlockStart = FirstBlockStart; - m_Optimize.Source = 0; - m_Optimize.Dest = 0; - - { // insert header cache element - void * header = malloc(FirstBlockStart); - m_FileAccess.Read(header, 0, FirstBlockStart); - _CacheInsert(0, (TBlockHeadOcc*)header, false); - } - - TransactionBeginWrite(); - - while (p < FileSize) - { - m_FileAccess.Read(&h, p, sizeof(h)); - if (CLogger::Instance().Level() >= CLogger::logERROR || !h.Size) - { - LOG(logCRITICAL, _T("Block-structure of file is corrupt!")); - return 0; - } - - if (h.ID == cFreeBlockID) - { - if (m_Optimize.Dest == 0) - m_Optimize.Dest = p; - - if (lasth.ID == cFreeBlockID) - { - lasth.Size += h.Size; - invalidateblock = true; - } else { - lasth = h; - } - - } else { - - if (lasth.ID == cFreeBlockID) - { - if (m_Optimize.Source == 0) - m_Optimize.Source = p; - - _InsertFreeBlock(p - lasth.Size, lasth.Size, invalidateblock, true); - } - lasth = h; - invalidateblock = false; - - while ((h.ID >> 2) >= m_BlockTable.size()) - m_BlockTable.resize(m_BlockTable.size() << 1); - - m_BlockTable[h.ID >> 2].Addr = p >> 2; - - if (h.Signature == HeaderSignature) - res = h.ID; - } - - p = p + h.Size; - } - - m_FirstFreeIndex = 0; - for (uint32_t i = static_cast(m_BlockTable.size() - 1); i > 0; --i) - { - if (m_BlockTable[i].Addr == 0) - { - TBlockTableEntry b = {true, true, m_FirstFreeIndex}; - m_BlockTable[i] = b; - m_FirstFreeIndex = i; - } - } - - TransactionEndWrite(); - - if (m_Optimize.Source && !m_FileAccess.ReadOnly()) - { - m_Optimize.Thread = new COptimizeThread(*this); - m_Optimize.Thread->Priority(CThread::tpLowest); - m_Optimize.Thread->FreeOnTerminate(true); - m_Optimize.Thread->Resume(); - } - - return res; -} - -void * CBlockManager::_CreateBlock(uint32_t & BlockID, const uint32_t Signature, uint32_t Size) -{ - uint32_t idx = _GetAvailableIndex(); - BlockID = idx << 2; - - Size = m_EncryptionManager.AlignSize(BlockID, (Size + 3) & 0xfffffffc); // align on cipher after we aligned on 4 bytes - - TBlockHeadOcc h = {BlockID, Size + sizeof(TBlockHeadOcc) + sizeof(TBlockTailOcc), Signature}; - TBlockTailOcc t = {BlockID}; - - TBlockHeadOcc * block = (TBlockHeadOcc*) malloc(Size + sizeof(h) + sizeof(t)); - *block = h; - memset(block + 1, 0, Size); - *(TBlockTailOcc*)(((uint8_t*)(block + 1)) + Size) = t; - - TCacheEntry * ce = _CacheInsert(idx, block, false); - - if (m_ReadOnly) - { - TBlockTableEntry b = {false, true, 0}; - m_BlockTable[idx] = b; - } else { - uint32_t addr = _FindFreePosition(Size + sizeof(h) + sizeof(t)); - TBlockTableEntry b = {false, true, addr >> 2 }; - m_BlockTable[idx] = b; - - _UpdateBlock(BlockID, ce, addr); - } - - return ce->Cache + 1; -} - -void * CBlockManager::_CreateBlockVirtual(uint32_t & BlockID, const uint32_t Signature, uint32_t Size) -{ - uint32_t idx = _GetAvailableIndex(); - BlockID = idx << 2; - - Size = m_EncryptionManager.AlignSize(BlockID, (Size + 3) & 0xfffffffc); // align on cipher after we aligned on 4 bytes - - TBlockHeadOcc h = {BlockID, Size + sizeof(TBlockHeadOcc) + sizeof(TBlockTailOcc), Signature}; - TBlockTailOcc t = {BlockID}; - - TBlockHeadOcc * block = (TBlockHeadOcc*) malloc(Size + sizeof(h) + sizeof(t)); - *block = h; - memset(block + 1, 0, Size); - *(TBlockTailOcc*)(((uint8_t*)(block + 1)) + Size) = t; - - return _CacheInsert(idx, block, true)->Cache + 1; -} - -bool CBlockManager::DeleteBlock(uint32_t BlockID) -{ - uint32_t idx = BlockID >> 2; - uint32_t addr; - uint32_t size; - TCacheEntry * ce; - if (!_InitOperation(BlockID, addr, ce)) - return false; - - if (!ce->Forced) - XADD_32(m_CacheInfo.Size, 0 - ce->Cache->Size); - - if (ce->Pending) - _PendingRemove(ce->Pending, true); - - size = ce->Cache->Size; - _CacheErase(idx); - - if (addr == 0) // Block in memory only - { - TBlockTableEntry b = {false, false, 0}; - m_BlockTable[idx] = b; - - } else if (m_ReadOnly) - { - m_BlockTable[idx].Deleted = true; - m_BlockTable[idx].InCache = false; - } else { - _InsertFreeBlock(addr, size, true, true); - - TBlockTableEntry b = {false, false, 0}; - m_BlockTable[idx] = b; - } - - return true; -} - -uint32_t CBlockManager::_ResizeBlock(uint32_t BlockID, void * & Buffer, uint32_t Size) -{ - uint32_t idx = BlockID >> 2; - uint32_t addr; - TCacheEntry * ce; - - if (Size == 0) - return 0; - - if (!_InitOperation(BlockID, addr, ce)) - return 0; - - Size = m_EncryptionManager.AlignSize(BlockID, (Size + 3) & 0xfffffffc); // align on cipher after we aligned on 4 bytes - - uint32_t os = ce->Cache->Size; - uint32_t ns = Size + sizeof(TBlockHeadOcc) + sizeof(TBlockTailOcc); - if (ns == ce->Cache->Size) - { - Buffer = ce->Cache + 1; - return Size; - } - - ce->Cache = (TBlockHeadOcc*) realloc(ce->Cache, ns); - ce->Cache->Size = ns; - TBlockTailOcc t = {BlockID}; - *(TBlockTailOcc*)(((uint8_t*)(ce->Cache + 1)) + Size) = t; - XADD_32(m_CacheInfo.Size, ns - os); - - Buffer = ce->Cache + 1; - ce->KeepInCache = m_ReadOnly; - - if (!m_ReadOnly && addr) - { - _InsertFreeBlock(addr, os, true, true); - addr = _FindFreePosition(ns); - m_BlockTable[idx].Addr = addr >> 2; - - _UpdateBlock(BlockID, ce, addr); // write down - } - - return Size; -} - -bool CBlockManager::IsForcedVirtual(uint32_t BlockID) -{ - TCacheEntry * ce = _CacheFind(BlockID >> 2); - return ce && ce->Forced; -} - -bool CBlockManager::WriteBlockToDisk(uint32_t BlockID) -{ - uint32_t addr; - TCacheEntry * ce; - - if (!_InitOperation(BlockID, addr, ce)) - return false; - - if (!ce->Forced) - return true; - - ce->Forced = false; - XADD_32(m_CacheInfo.Size, ce->Cache->Size); - - if (!m_ReadOnly) - { - addr = _FindFreePosition(ce->Cache->Size); - m_BlockTable[BlockID >> 2].Addr = addr >> 2; - _UpdateBlock(BlockID, ce, addr); - } - return true; -} - -bool CBlockManager::MakeBlockVirtual(uint32_t BlockID) -{ - uint32_t addr; - TCacheEntry * ce; - - if (!_InitOperation(BlockID, addr, ce)) - return false; - - if (ce->Forced) - return true; - - if (ce->Pending) // don't write down, we kill it anyway - _PendingRemove(ce->Pending, true); - - ce->Forced = true; - XADD_32(m_CacheInfo.Size, 0 - ce->Cache->Size); - - if (!m_ReadOnly) - { - _InsertFreeBlock(addr, ce->Cache->Size, true, true); - m_BlockTable[BlockID >> 2].Addr = 0; - } - return true; -} - -void * CBlockManager::_ReadBlock(uint32_t BlockID, uint32_t & Size, uint32_t & Signature) -{ - uint32_t addr; - TCacheEntry * ce; - - if ((BlockID == 0) && (Signature == -1)) - { - Size = m_FirstBlockStart; - return m_Cache[0]->Cache; - } - - if (!_InitOperation(BlockID, addr, ce)) - return NULL; - - if ((Signature != 0) && (Signature != ce->Cache->Signature)) - { - Signature = ce->Cache->Signature; - return NULL; - } - Signature = ce->Cache->Signature; - - if ((Size != 0) && (Size != ce->Cache->Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc))) - { - Size = ce->Cache->Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc); - return NULL; - } - Size = ce->Cache->Size - sizeof(TBlockHeadOcc) - sizeof(TBlockTailOcc); - - return ce->Cache + 1; -} - -bool CBlockManager::UpdateBlock(uint32_t BlockID, uint32_t Signature) -{ - uint32_t addr; - TCacheEntry * ce; - - if ((BlockID == 0) && (Signature == -1)) - { - if (!m_ReadOnly) - _PendingAdd(0, 0, m_FirstBlockStart, m_Cache[0]); - - return true; - } - - if (!_InitOperation(BlockID, addr, ce)) - return false; - - if (Signature) - ce->Cache->Signature = Signature; - - _UpdateBlock(BlockID, ce, addr); - - return true; -} - -// make file writeable: -// write all cached blocks to file and check for the old addresses -// remove virtual only from file -// update m_FreeBlocks along the way - diff --git a/dbx_tree/BlockManager.h b/dbx_tree/BlockManager.h deleted file mode 100644 index dcccd4f..0000000 --- a/dbx_tree/BlockManager.h +++ /dev/null @@ -1,401 +0,0 @@ -/* - -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. - -*/ - -#pragma once - -#include -#include -#include - -#include "stdint.h" -#include "FileAccess.h" -#include "EncryptionManager.h" -#include "MREWSync.h" -#include "Thread.h" -#include "intrinsics.h" - -class CBlockManager -{ -protected: - static const uint32_t cFreeBlockID = 0xFFFFFFFF; - - static const uint32_t cJournalFlushBytes = (1 << 20) - 2048; // flush before reserved journal-space is exhausted - static const uint32_t cJournalFlushTimeout = 300; // journal flush every 5 minutes - - static const uint32_t cCacheBuddyBits = 10; - static const uint32_t cCacheBuddyCount = 1 << cCacheBuddyBits; // count of static allocated buddy nodes - static const uint32_t cCacheBuddyCheck = 0xffffffff << cCacheBuddyBits; - - static const uint32_t cCacheMinimumTimeout = 2; // purge less than every n seconds (high priority) - static const uint32_t cCacheMaximumTimeout = 600; // purge every 10 minutes (high priority) - static const uint32_t cCachePurgeSize = 1 << 21; // cache up to 2MB - static const uint32_t cCacheMinimumGrowthForPurge = 1 << 19; // cache only when 512kb were added - - #pragma pack(push, 1) // push current alignment to stack, set alignment to 1 byte boundary - - typedef struct TBlockHeadFree { - uint32_t ID; - uint32_t Size; - } TBlockHeadFree; - typedef struct TBlockHeadOcc { - uint32_t ID; - uint32_t Size; - uint32_t Signature; /// if occupied block - } TBlockHeadOcc; - - typedef struct TBlockTailOcc { - uint32_t ID; - } TBlockTailOcc; - - typedef struct TBlockTailFree { - uint32_t Size; /// if free block - uint32_t ID; - } TBlockTailFree; - - #pragma pack(pop) - - //////////////////////////////////////////////////////////////////////////////////////////////////// - /// Block table entry. - /// - /// Addr Deleted InCache Meaning - /// 0 0 0 successfully deleted block - /// 0 0 1 virtual only block (either forced virtual or created on a read-only file) - /// 0 1 0 invalid - /// 0 1 1 FreeID list (last entry) - /// set 0 0 Normal in-file block - /// set 0 1 in file and cache (normal cache which could differ on a read-only file or forced virtual out of a read-only file - check TCacheEntry) - /// set 1 0 deleted block or a read-only file - /// set 1 1 FreeID list entry - /// - /// Michael "Protogenes" Kunz, 07.09.2010. - //////////////////////////////////////////////////////////////////////////////////////////////////// - typedef struct TBlockTableEntry { - uint32_t Deleted : 1; ///< Flag is set if the block was deleted but can't be removed, because the file is read-only - uint32_t InCache : 1; ///< Flag is set if block is in the cache (either forced virtual or from the file) - uint32_t Addr : 30; ///< The Offset in the file div 4, so we can address files up to 4GB - } TBlockTableEntry; - std::vector m_BlockTable; - - struct TPendingOperation; - typedef struct TCacheEntry { - TCacheEntry * volatile Next; - TBlockHeadOcc * volatile Cache; - TPendingOperation * Pending; - - uint32_t Idx; - uint32_t Forced : 1; - uint32_t KeepInCache : 1; - uint32_t LastUse : 30; - } TCacheEntry; - - TCacheEntry * m_Cache[cCacheBuddyCount]; - - struct { - uint32_t volatile Size; - uint32_t volatile Growth; - uint32_t volatile LastPurge; - } m_CacheInfo; - - CFileAccess & m_FileAccess; - CEncryptionManager & m_EncryptionManager; - CMultiReadExclusiveWriteSynchronizer m_BlockSync; - - uint32_t m_FirstBlockStart; - bool m_SaveMode; - bool m_ReadOnly; - - typedef std::multimap TFreeBlockMap; - TFreeBlockMap m_FreeBlocks; - uint32_t m_FirstFreeIndex; - - static const uint32_t cPendingInvalidate = 0x00000001; - typedef struct TPendingOperation { - TPendingOperation * Next; ///< The next - TPendingOperation * Prev; ///< The previous - uint32_t BlockID; ///< Identifier for the block - uint32_t Addr; ///< The address in the file - uint32_t Size; ///< The size of the block - TCacheEntry * CacheEntry; ///< The cache entry - TBlockHeadOcc * EncryptionBuffer; ///< Buffer for encrypted block - } TPendingOperation; - - TPendingOperation * m_PendingHead; ///< The double linked list head - TPendingOperation * m_PendingTail; ///< The double linked list tail - TPendingOperation * m_PendingLast; ///< The last processed item - - uint32_t m_LastFlush; ///< The last flush timestamp - uint32_t m_BytesPending; ///< The bytes pending for write - - class COptimizeThread : public CThread - { - protected: - CBlockManager & m_Owner; - void Execute() { m_Owner.ExecuteOptimize(); }; - public: - COptimizeThread(CBlockManager & Owner) : CThread(true), m_Owner(Owner) {}; - ~COptimizeThread() {}; - }; - - struct { - uint32_t Source; - uint32_t Dest; - COptimizeThread * Thread; - } m_Optimize; - void ExecuteOptimize(); - - uint32_t _GetAvailableIndex(); - void _InsertFreeBlock(uint32_t Addr, uint32_t Size, bool InvalidateData, bool Reuse); - void _RemoveFreeBlock(uint32_t Addr, uint32_t Size); - uint32_t _FindFreePosition(uint32_t Size); - - bool _InitOperation(uint32_t BlockID, uint32_t & Addr, TCacheEntry * & Cache); - void _UpdateBlock(uint32_t BlockID, TCacheEntry * CacheEntry, uint32_t Addr); - - void * _ReadBlock(uint32_t BlockID, uint32_t & Size, uint32_t & Signature); - void * _CreateBlock(uint32_t & BlockID, const uint32_t Signature, uint32_t Size); - void * _CreateBlockVirtual(uint32_t & BlockID, const uint32_t Signature, uint32_t Size); - uint32_t _ResizeBlock(uint32_t BlockID, void * & Buffer, uint32_t Size); - - TCacheEntry * _CacheInsert(uint32_t Idx, TBlockHeadOcc * Cache, bool Virtual); - TCacheEntry * _CacheFind(uint32_t Idx); - void _CacheErase(uint32_t Idx); - - void _CachePurge(); - void _PendingAdd(uint32_t BlockID, uint32_t Addr, uint32_t Size, TCacheEntry * Cache); - void _PendingRemove(TPendingOperation * Pending, bool Free); - void _PendingFlush(bool FullFlush); - - - - void TransactionBeginRead() - { - m_BlockSync.BeginRead(); - }; - - void TransactionEndRead() - { - m_BlockSync.EndRead(); - }; - - void TransactionBeginWrite() - { - m_BlockSync.BeginWrite(); - m_FileAccess.UseJournal(m_SaveMode); - }; - - void TransactionEndWrite() - { - if (m_BlockSync.WriteRecursionCount() == 1) - { - m_FileAccess.CompleteTransaction(); - m_BytesPending += 12; - - if ((m_CacheInfo.LastPurge + cCacheMaximumTimeout < time(NULL)) - || ((m_CacheInfo.Size + m_CacheInfo.Growth > cCachePurgeSize) - && (m_CacheInfo.Growth > cCacheMinimumGrowthForPurge) - && (m_CacheInfo.LastPurge + cCacheMinimumTimeout < time(NULL)))) - { - _CachePurge(); - } else if ((m_BytesPending >= cJournalFlushBytes) || (time(NULL) > m_LastFlush + cJournalFlushTimeout)) - { - _PendingFlush(true); - } else { - _PendingFlush(false); - } - } - - m_BlockSync.EndWrite(); - }; -public: - CBlockManager(CFileAccess & FileAccess, CEncryptionManager & EncryptionManager); - ~CBlockManager(); - - - class ReadTransaction - { - private: - CBlockManager * m_Owner; - uint32_t volatile * m_RefCount; - bool m_Closed; - public: - ReadTransaction() - : m_Owner(NULL), - m_RefCount(NULL), - m_Closed(true) - { - - }; - ReadTransaction(CBlockManager & BlockManager) - : m_Owner(&BlockManager), - m_RefCount(new uint32_t(1)), - m_Closed(false) - { - m_Owner->TransactionBeginRead(); - }; - ReadTransaction(const ReadTransaction & Other) - : m_Owner(Other.m_Owner), - m_RefCount(Other.m_RefCount), - m_Closed(Other.m_Closed) - { - if (!m_Closed) - INC_32(*m_RefCount); - }; - ~ReadTransaction() - { - if (!m_Closed && (DEC_32(*m_RefCount) == 0)) - { - delete m_RefCount; - m_Owner->TransactionEndRead(); - } - }; - - ReadTransaction & operator =(const ReadTransaction & Other) - { - if (!m_Closed && (DEC_32(*m_RefCount) == 0)) - { - delete m_RefCount; - m_Owner->TransactionEndRead(); - } - - m_Owner = Other.m_Owner; - m_RefCount = Other.m_RefCount; - m_Closed = Other.m_Closed; - if (!m_Closed) - INC_32(*m_RefCount); - - return *this; - } - - void Close() - { - if (!m_Closed && (DEC_32(*m_RefCount) == 0)) - { - delete m_RefCount; - m_Owner->TransactionEndRead(); - } - m_Closed = true; - } - - }; - class WriteTransaction - { - private: - CBlockManager * m_Owner; - uint32_t volatile * m_RefCount; - bool m_Closed; - public: - WriteTransaction() - : m_Owner(NULL), - m_RefCount(NULL), - m_Closed(true) - { - - }; - WriteTransaction(CBlockManager & BlockManager) - : m_Owner(&BlockManager), - m_RefCount(new uint32_t(1)), - m_Closed(false) - { - m_Owner->TransactionBeginWrite(); - }; - WriteTransaction(const WriteTransaction & Other) - : m_Owner(Other.m_Owner), - m_RefCount(Other.m_RefCount), - m_Closed(Other.m_Closed) - { - if (!m_Closed) - INC_32(*m_RefCount); - }; - ~WriteTransaction() - { - if (!m_Closed && (DEC_32(*m_RefCount) == 0)) - { - delete m_RefCount; - m_Owner->TransactionEndWrite(); - } - }; - - WriteTransaction & operator =(const WriteTransaction & Other) - { - if (!m_Closed && (DEC_32(*m_RefCount) == 0)) - { - delete m_RefCount; - m_Owner->TransactionEndWrite(); - } - - m_Owner = Other.m_Owner; - m_RefCount = Other.m_RefCount; - m_Closed = Other.m_Closed; - if (!m_Closed) - INC_32(*m_RefCount); - - return *this; - } - - void Close() - { - if (!m_Closed && (DEC_32(*m_RefCount) == 0)) - { - delete m_RefCount; - m_Owner->TransactionEndWrite(); - } - m_Closed = true; - } - - }; - - uint32_t ScanFile(uint32_t FirstBlockStart, uint32_t HeaderSignature, uint32_t FileSize); - - template - BlockType * ReadBlock(uint32_t BlockID, uint32_t & Size, uint32_t & Signature) - { - return reinterpret_cast(_ReadBlock(BlockID, Size, Signature)); - }; - - template - BlockType * CreateBlock(uint32_t & BlockID, const uint32_t Signature, uint32_t Size = sizeof(BlockType)) - { - return reinterpret_cast(_CreateBlock(BlockID, Signature, Size)); - }; - - template - BlockType * CreateBlockVirtual(uint32_t & BlockID, const uint32_t Signature, uint32_t Size = sizeof(BlockType)) - { - return reinterpret_cast(_CreateBlockVirtual(BlockID, Signature, Size)); - }; - - template - uint32_t ResizeBlock(uint32_t BlockID, BlockType * & Buffer, uint32_t Size) - { - void * tmp = Buffer; - uint32_t res = _ResizeBlock(BlockID, tmp, Size); - Buffer = reinterpret_cast(tmp); - return res; - }; - - bool UpdateBlock(uint32_t BlockID, uint32_t Signature = 0); - bool DeleteBlock(uint32_t BlockID); - - bool IsForcedVirtual(uint32_t BlockID); - bool WriteBlockToDisk(uint32_t BlockID); - bool MakeBlockVirtual(uint32_t BlockID); -}; diff --git a/dbx_tree/Compatibility.cpp b/dbx_tree/Compatibility.cpp deleted file mode 100644 index 38b8f92..0000000 --- a/dbx_tree/Compatibility.cpp +++ /dev/null @@ -1,866 +0,0 @@ -/* - -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 "Compatibility.h" -#include "Logger.h" -#define DB_NOHELPERFUNCTIONS - #include "m_database.h" -#undef DB_NOHELPERFUNCTIONS -#ifndef _MSC_VER -#include "savestrings_gcc.h" -#endif - -HANDLE gCompServices[31] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -HANDLE gEvents[6] = {0,0,0,0,0,0}; - -HANDLE hEventDeletedEvent, - hEventAddedEvent, - hEventFilterAddedEvent, - hSettingChangeEvent, - hContactDeletedEvent, - hContactAddedEvent; - -INT_PTR CompAddContact(WPARAM wParam, LPARAM lParam) -{ - TDBTEntity entity = {0,0,0,0}; - entity.hParentEntity = DBEntityGetRoot(0, 0); - entity.hAccountEntity = entity.hParentEntity; - - TDBTEntityHandle res = gDataBase->getEntities().CreateEntity(entity); - if (res == DBT_INVALIDPARAM) - return 1; - - NotifyEventHooks(hContactAddedEvent, res, 0); - return res; -} -INT_PTR CompDeleteContact(WPARAM hContact, LPARAM lParam) -{ - NotifyEventHooks(hContactDeletedEvent, hContact, 0); - - int res = DBEntityDelete(hContact, 0); - if (res == DBT_INVALIDPARAM) - return 1; - - return res; -} -INT_PTR CompIsDbContact(WPARAM hContact, LPARAM lParam) -{ - int flags = DBEntityGetFlags(hContact, 0); - return (flags != DBT_INVALIDPARAM) && - ((flags & DBT_NFM_SpecialEntity) == 0); -} -INT_PTR CompGetContactCount(WPARAM wParam, LPARAM lParam) -{ - TDBTEntityIterFilter f = {0,0,0,0}; - f.cbSize = sizeof(f); - f.fDontHasFlags = DBT_NF_IsGroup | DBT_NF_IsVirtual | DBT_NF_IsAccount | DBT_NF_IsRoot; - f.Options = DBT_NIFO_OSC_AC | DBT_NIFO_OC_AC; - - TDBTEntityIterationHandle hiter = DBEntityIterInit((WPARAM)&f, gDataBase->getEntities().getRootEntity()); - int c = 0; - if ((hiter != 0) && (hiter != DBT_INVALIDPARAM)) - { - TDBTEntityHandle con = DBEntityIterNext(hiter, 0); - - while ((con != DBT_INVALIDPARAM) && (con != 0)) - { - if ((con != 0) && (con != DBT_INVALIDPARAM)) - c++; - - con = DBEntityIterNext(hiter, 0); - } - DBEntityIterClose(hiter, 0); - } - return c; -} -INT_PTR CompFindFirstContact(WPARAM wParam, LPARAM lParam) -{ - return gDataBase->getEntities().compFirstContact(); -} -INT_PTR CompFindNextContact(WPARAM hContact, LPARAM lParam) -{ - return gDataBase->getEntities().compNextContact(hContact); -} - -INT_PTR CompGetContactSetting(WPARAM hContact, LPARAM pSetting) -{ - DBCONTACTGETSETTING * dbcgs = reinterpret_cast(pSetting); - dbcgs->pValue->type = 0; - - char namebuf[512]; - namebuf[0] = 0; - - if (!(dbcgs->szModule || dbcgs->szSetting)) - return -1; - - if (dbcgs->szModule) - strcpy_s(namebuf, dbcgs->szModule); - strcat_s(namebuf, "/"); - if (dbcgs->szSetting) - strcat_s(namebuf, dbcgs->szSetting); - - TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; - TDBTSetting set = {0,0,0,0}; - desc.cbSize = sizeof(desc); - desc.Entity = hContact; - desc.pszSettingName = namebuf; - - set.cbSize = sizeof(set); - set.Descriptor = &desc; - - if (DBSettingRead(reinterpret_cast(&set), 0) == DBT_INVALIDPARAM) - return -1; - - switch (set.Type) - { - case DBT_ST_ANSI: - { - dbcgs->pValue->type = DBVT_ASCIIZ; - dbcgs->pValue->pszVal = set.Value.pAnsi; - dbcgs->pValue->cchVal = set.Value.Length - 1; - } break; - case DBT_ST_UTF8: - { - dbcgs->pValue->type = DBVT_WCHAR; - dbcgs->pValue->pwszVal = mir_utf8decodeW(set.Value.pUTF8); - if (dbcgs->pValue->pwszVal) - dbcgs->pValue->cchVal = static_cast(wcslen(dbcgs->pValue->pwszVal)); - else - dbcgs->pValue->cchVal = 0; - mir_free(set.Value.pUTF8); - } break; - case DBT_ST_WCHAR: - { - dbcgs->pValue->type = DBVT_WCHAR; - dbcgs->pValue->pwszVal = set.Value.pWide; - dbcgs->pValue->cchVal = set.Value.Length - 1; - } break; - case DBT_ST_BLOB: - { - dbcgs->pValue->type = DBVT_BLOB; - dbcgs->pValue->pbVal = set.Value.pBlob; - dbcgs->pValue->cpbVal = set.Value.Length; - } break; - case DBT_ST_BOOL: - { - dbcgs->pValue->type = DBVT_BYTE; - dbcgs->pValue->bVal = (uint8_t)set.Value.Bool; - } break; - case DBT_ST_BYTE: case DBT_ST_CHAR: - { - dbcgs->pValue->type = DBVT_BYTE; - dbcgs->pValue->bVal = set.Value.Byte; - } break; - case DBT_ST_SHORT: case DBT_ST_WORD: - { - dbcgs->pValue->type = DBVT_WORD; - dbcgs->pValue->wVal = set.Value.Word; - } break; - case DBT_ST_INT: case DBT_ST_DWORD: - { - dbcgs->pValue->type = DBVT_DWORD; - dbcgs->pValue->dVal = set.Value.DWord; - } break; - case DBT_ST_INT64: case DBT_ST_QWORD: - case DBT_ST_DOUBLE: case DBT_ST_FLOAT: - { - dbcgs->pValue->type = DBVT_BLOB; - dbcgs->pValue->cpbVal = sizeof(set.Value); - dbcgs->pValue->pbVal = reinterpret_cast(mir_alloc(sizeof(set.Value))); - memcpy(dbcgs->pValue->pbVal, &set.Value, sizeof(set.Value)); - } break; - default: - { - return -1; - } - } - - return 0; -} -INT_PTR CompGetContactSettingStr(WPARAM hContact, LPARAM pSetting) -{ - DBCONTACTGETSETTING * dbcgs = reinterpret_cast(pSetting); - - if ((dbcgs->pValue->type & DBVTF_VARIABLELENGTH) == 0) - { - CompFreeVariant(0, reinterpret_cast(dbcgs->pValue)); - dbcgs->pValue->type = 0; - } - - char namebuf[512]; - namebuf[0] = 0; - if (dbcgs->szModule) - strcpy_s(namebuf, dbcgs->szModule); - strcat_s(namebuf, "/"); - if (dbcgs->szSetting) - strcat_s(namebuf, dbcgs->szSetting); - - TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; - TDBTSetting set = {0,0,0,0}; - desc.cbSize = sizeof(desc); - desc.Entity = hContact; - desc.pszSettingName = namebuf; - - set.cbSize = sizeof(set); - set.Descriptor = &desc; - - - switch (dbcgs->pValue->type) - { - case DBVT_ASCIIZ: set.Type = DBT_ST_ANSI; break; - case DBVT_BLOB: set.Type = DBT_ST_BLOB; break; - case DBVT_UTF8: set.Type = DBT_ST_UTF8; break; - case DBVT_WCHAR: set.Type = DBT_ST_WCHAR; break; - } - - if (DBSettingRead(reinterpret_cast(&set), 0) == DBT_INVALIDPARAM) - return -1; - - switch (set.Type) - { - case DBT_ST_ANSI: - { - dbcgs->pValue->type = DBVT_ASCIIZ; - dbcgs->pValue->pszVal = set.Value.pAnsi; - dbcgs->pValue->cchVal = set.Value.Length - 1; - } break; - case DBT_ST_UTF8: - { - dbcgs->pValue->type = DBVT_UTF8; - dbcgs->pValue->pszVal = set.Value.pUTF8; - dbcgs->pValue->cchVal = set.Value.Length - 1; - } break; - case DBT_ST_WCHAR: - { - if (dbcgs->pValue->type == DBVT_WCHAR) - { - dbcgs->pValue->pwszVal = set.Value.pWide; - dbcgs->pValue->cchVal = set.Value.Length - 1; - } else { - dbcgs->pValue->type = DBVT_UTF8; - dbcgs->pValue->pszVal = mir_utf8encodeW(set.Value.pWide); - dbcgs->pValue->cchVal = static_cast(strlen(dbcgs->pValue->pszVal)); - mir_free(set.Value.pWide); - } - } break; - case DBT_ST_BLOB: - { - dbcgs->pValue->type = DBVT_BLOB; - dbcgs->pValue->pbVal = set.Value.pBlob; - dbcgs->pValue->cpbVal = set.Value.Length; - } break; - case DBT_ST_BOOL: - { - dbcgs->pValue->type = DBVT_BYTE; - dbcgs->pValue->bVal = (uint8_t)set.Value.Bool; - } break; - case DBT_ST_BYTE: case DBT_ST_CHAR: - { - dbcgs->pValue->type = DBVT_BYTE; - dbcgs->pValue->bVal = set.Value.Byte; - } break; - case DBT_ST_SHORT: case DBT_ST_WORD: - { - dbcgs->pValue->type = DBVT_WORD; - dbcgs->pValue->wVal = set.Value.Word; - } break; - case DBT_ST_INT: case DBT_ST_DWORD: - { - dbcgs->pValue->type = DBVT_DWORD; - dbcgs->pValue->dVal = set.Value.DWord; - } break; - case DBT_ST_INT64: case DBT_ST_QWORD: - case DBT_ST_DOUBLE: case DBT_ST_FLOAT: - { - dbcgs->pValue->type = DBVT_BLOB; - dbcgs->pValue->cpbVal = sizeof(set.Value); - dbcgs->pValue->pbVal = reinterpret_cast(mir_alloc(sizeof(set.Value))); - memcpy(dbcgs->pValue->pbVal, &set.Value, sizeof(set.Value)); - } break; - default: - { - return -1; - } - } - - return 0; -} -INT_PTR CompGetContactSettingStatic(WPARAM hContact, LPARAM pSetting) -{ - DBCONTACTGETSETTING * dbcgs = reinterpret_cast(pSetting); - - char namebuf[512]; - namebuf[0] = 0; - if (dbcgs->szModule) - strcpy_s(namebuf, dbcgs->szModule); - strcat_s(namebuf, "/"); - if (dbcgs->szSetting) - strcat_s(namebuf, dbcgs->szSetting); - - TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; - TDBTSetting set = {0,0,0,0}; - desc.cbSize = sizeof(desc); - desc.Entity = hContact; - desc.pszSettingName = namebuf; - - set.cbSize = sizeof(set); - set.Descriptor = &desc; - - if (DBSettingRead(reinterpret_cast(&set), 0) == DBT_INVALIDPARAM) - return -1; - - if ((set.Type & DBT_STF_VariableLength) ^ (dbcgs->pValue->type & DBVTF_VARIABLELENGTH)) - { - if (set.Type & DBT_STF_VariableLength) - mir_free(set.Value.pBlob); - return -1; - } - - switch (set.Type) - { - case DBT_ST_ANSI: - { - if (dbcgs->pValue->cchVal < set.Value.Length) - { - memcpy(dbcgs->pValue->pszVal, set.Value.pAnsi, dbcgs->pValue->cchVal); - dbcgs->pValue->pszVal[dbcgs->pValue->cchVal - 1] = 0; - } else { - memcpy(dbcgs->pValue->pszVal, set.Value.pAnsi, set.Value.Length); - } - dbcgs->pValue->type = DBVT_ASCIIZ; - dbcgs->pValue->cchVal = set.Value.Length - 1; - - mir_free(set.Value.pAnsi); - } break; - case DBT_ST_UTF8: - { - set.Value.pUTF8 = mir_utf8decode(set.Value.pUTF8, NULL); - set.Value.Length = static_cast(strlen(set.Value.pUTF8)); - - if (dbcgs->pValue->cchVal < set.Value.Length) - { - memcpy(dbcgs->pValue->pszVal, set.Value.pUTF8, dbcgs->pValue->cchVal); - dbcgs->pValue->pszVal[dbcgs->pValue->cchVal - 1] = 0; - } else { - memcpy(dbcgs->pValue->pszVal, set.Value.pUTF8, set.Value.Length); - } - dbcgs->pValue->type = DBVT_ASCIIZ; - dbcgs->pValue->cchVal = set.Value.Length - 1; - - mir_free(set.Value.pUTF8); - } break; - case DBT_ST_WCHAR: - { - char * tmp = mir_u2a(set.Value.pWide); - WORD l = static_cast(strlen(tmp)); - mir_free(set.Value.pWide); - - if (dbcgs->pValue->cchVal < l + 1) - { - memcpy(dbcgs->pValue->pszVal, tmp, dbcgs->pValue->cchVal); - dbcgs->pValue->pszVal[l] = 0; - } else { - memcpy(dbcgs->pValue->pszVal, tmp, l + 1); - } - dbcgs->pValue->type = DBVT_ASCIIZ; - dbcgs->pValue->cchVal = l; - - mir_free(tmp); - } break; - case DBT_ST_BLOB: - { - if (dbcgs->pValue->cchVal < set.Value.Length) - { - memcpy(dbcgs->pValue->pbVal, set.Value.pBlob, dbcgs->pValue->cchVal); - } else { - memcpy(dbcgs->pValue->pbVal, set.Value.pBlob, set.Value.Length); - } - dbcgs->pValue->type = DBVT_BLOB; - dbcgs->pValue->cchVal = set.Value.Length; - - mir_free(set.Value.pBlob); - } break; - case DBT_ST_BOOL: - { - dbcgs->pValue->type = DBVT_BYTE; - dbcgs->pValue->bVal = set.Value.Bool ? TRUE : FALSE; - } break; - case DBT_ST_BYTE: case DBT_ST_CHAR: - { - dbcgs->pValue->type = DBVT_BYTE; - dbcgs->pValue->bVal = set.Value.Byte; - } break; - case DBT_ST_SHORT: case DBT_ST_WORD: - { - dbcgs->pValue->type = DBVT_WORD; - dbcgs->pValue->wVal = set.Value.Word; - } break; - case DBT_ST_INT: case DBT_ST_DWORD: - { - dbcgs->pValue->type = DBVT_DWORD; - dbcgs->pValue->dVal = set.Value.DWord; - } break; - default: - { - return -1; - } - } - - return 0; -} -INT_PTR CompFreeVariant(WPARAM wParam, LPARAM pSetting) -{ - DBVARIANT * dbv = reinterpret_cast(pSetting); - - if ((dbv->type == DBVT_BLOB) && (dbv->pbVal)) - { - mir_free(dbv->pbVal); - dbv->pbVal = 0; - } else if ((dbv->type & DBVTF_VARIABLELENGTH) && (dbv->pszVal)) - { - mir_free(dbv->pszVal); - dbv->pszVal = NULL; - } - dbv->type = 0; - return 0; -} -INT_PTR CompWriteContactSetting(WPARAM hContact, LPARAM pSetting) -{ - DBCONTACTWRITESETTING * dbcws = reinterpret_cast(pSetting); - - char namebuf[512]; - namebuf[0] = 0; - if (dbcws->szModule) - strcpy_s(namebuf, dbcws->szModule); - strcat_s(namebuf, "/"); - if (dbcws->szSetting) - strcat_s(namebuf, dbcws->szSetting); - - TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; - TDBTSetting set = {0,0,0,0}; - desc.cbSize = sizeof(desc); - desc.Entity = hContact; - desc.pszSettingName = namebuf; - - set.cbSize = sizeof(set); - set.Descriptor = &desc; - - switch (dbcws->value.type) - { - case DBVT_ASCIIZ: - { - set.Type = DBT_ST_ANSI; - set.Value.pAnsi = dbcws->value.pszVal; - } break; - case DBVT_UTF8: - { - wchar_t * tmp = mir_utf8decodeW(dbcws->value.pszVal); - if (tmp == 0) - { - if (IsDebuggerPresent()) - { - DebugBreak(); -#ifdef _DEBUG - } else { - LOG(logWARNING, _T("Trying to write malformed UTF8 setting \"%hs\" in module \"%hs\""), dbcws->szSetting, dbcws->szModule); - CLogger::Instance().ShowMessage(); -#endif - } - return -1; - } else { - mir_free(tmp); - } - - set.Type = DBT_ST_UTF8; - set.Value.pUTF8 = dbcws->value.pszVal; - } break; - case DBVT_WCHAR: - { - set.Type = DBT_ST_WCHAR; - set.Value.pWide = dbcws->value.pwszVal; - } break; - case DBVT_BLOB: - { - set.Type = DBT_ST_BLOB; - set.Value.pBlob = dbcws->value.pbVal; - set.Value.Length = dbcws->value.cpbVal; - } break; - case DBVT_BYTE: - { - set.Type = DBT_ST_BYTE; - set.Value.Byte = dbcws->value.bVal; - } break; - case DBVT_WORD: - { - set.Type = DBT_ST_WORD; - set.Value.Word = dbcws->value.wVal; - } break; - case DBVT_DWORD: - { - set.Type = DBT_ST_DWORD; - set.Value.DWord = dbcws->value.dVal; - } break; - default: - { - return -1; - } - } - - if (DBSettingWrite(reinterpret_cast(&set), 0) == DBT_INVALIDPARAM) - return -1; - - if (dbcws->value.type == DBVT_WCHAR) - { - dbcws->value.type = DBVT_UTF8; - wchar_t * tmp = dbcws->value.pwszVal; - dbcws->value.pszVal = mir_utf8encodeW(dbcws->value.pwszVal); - NotifyEventHooks(hSettingChangeEvent, hContact, pSetting); - mir_free(dbcws->value.pszVal); - dbcws->value.type = DBVT_WCHAR; - dbcws->value.pwszVal = tmp; - } else { - NotifyEventHooks(hSettingChangeEvent, hContact, pSetting); - } - - return 0; -} - -INT_PTR CompDeleteContactSetting(WPARAM hContact, LPARAM pSetting) -{ - DBCONTACTGETSETTING * dbcgs = reinterpret_cast(pSetting); - - char namebuf[512]; - namebuf[0] = 0; - if (dbcgs->szModule) - strcpy_s(namebuf, dbcgs->szModule); - strcat_s(namebuf, "/"); - if (dbcgs->szSetting) - strcat_s(namebuf, dbcgs->szSetting); - - TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; - desc.cbSize = sizeof(desc); - desc.Entity = hContact; - desc.pszSettingName = namebuf; - - if (DBSettingDelete(reinterpret_cast(&desc), 0) == DBT_INVALIDPARAM) - return -1; - - { - DBCONTACTWRITESETTING tmp = {0,0,0,0}; - tmp.szModule = dbcgs->szModule; - tmp.szSetting = dbcgs->szSetting; - tmp.value.type = 0; - NotifyEventHooks(hSettingChangeEvent, hContact, reinterpret_cast(&tmp)); - } - - return 0; -} -INT_PTR CompEnumContactSettings(WPARAM hContact, LPARAM pEnum) -{ - DBCONTACTENUMSETTINGS * pces = reinterpret_cast(pEnum); - - TDBTSettingDescriptor desc = {0,0,0,0,0,0,0,0}; - desc.cbSize = sizeof(desc); - desc.Entity = hContact; - - char namebuf[512]; - namebuf[0] = 0; - if (pces->szModule) - strcpy_s(namebuf, pces->szModule); - strcat_s(namebuf, "/"); - - TDBTSettingIterFilter filter = {0,0,0,0,0,0,0,0}; - filter.cbSize = sizeof(filter); - filter.Descriptor = &desc; - filter.hEntity = hContact; - filter.NameStart = namebuf; - - TDBTSettingIterationHandle hiter = DBSettingIterInit(reinterpret_cast(&filter), 0); - if ((hiter == 0) || (hiter == DBT_INVALIDPARAM)) - return -1; - - int res = 0; - TDBTSettingHandle hset = DBSettingIterNext(hiter, 0); - while (hset != 0) - { - char * p = strchr(desc.pszSettingName, '/'); - if (p) { - ++p; - } else { - p = desc.pszSettingName; - } - - res = pces->pfnEnumProc(p, pces->lParam); - if (res == 0) - { - hset = DBSettingIterNext(hiter, 0); - } else { - hset = 0; - } - } - - DBSettingIterClose(hiter, 0); - - if (desc.pszSettingName) - mir_free(desc.pszSettingName); - - return res; -} - - -INT_PTR CompGetEventCount(WPARAM hContact, LPARAM lParam) -{ - if (hContact == 0) - hContact = gDataBase->getEntities().getRootEntity(); - - return DBEventGetCount(hContact, 0); -} -INT_PTR CompAddEvent(WPARAM hContact, LPARAM pEventInfo) -{ - DBEVENTINFO * dbei = reinterpret_cast(pEventInfo); - if (dbei->cbSize < sizeof(DBEVENTINFO)) - return -1; - - int tmp = NotifyEventHooks(hEventFilterAddedEvent, hContact, pEventInfo); - if (tmp != 0) - return tmp; - - if (hContact == 0) - hContact = gDataBase->getEntities().getRootEntity(); - - - TDBTEvent ev = {0,0,0,0,0,0,0}; - ev.cbSize = sizeof(ev); - ev.ModuleName = dbei->szModule; - ev.Timestamp = dbei->timestamp; - ev.Flags = dbei->flags; - if (ev.Flags & DBEF_SENT) - ev.Flags = ev.Flags | DBEF_READ; - ev.EventType = dbei->eventType; - ev.cbBlob = dbei->cbBlob; - ev.pBlob = dbei->pBlob; - - int res = DBEventAdd(hContact, reinterpret_cast(&ev)); - if (res != DBT_INVALIDPARAM) - { - NotifyEventHooks(hEventAddedEvent, hContact, res); - return res; - } - return 0; -} -INT_PTR CompDeleteEvent(WPARAM hContact, LPARAM hEvent) -{ - int res = NotifyEventHooks(hEventDeletedEvent, hContact, hEvent); - - if (hContact == 0) - hContact = gDataBase->getEntities().getRootEntity(); - - if (res == 0) - return DBEventDelete(hEvent, 0); - - return res; -} -INT_PTR CompGetBlobSize(WPARAM hEvent, LPARAM lParam) -{ - int res = DBEventGetBlobSize(hEvent, 0); - if (res == DBT_INVALIDPARAM) - return -1; - - return res; -} -INT_PTR CompGetEvent(WPARAM hEvent, LPARAM pEventInfo) -{ - DBEVENTINFO * dbei = reinterpret_cast(pEventInfo); - if (dbei->cbSize < sizeof(DBEVENTINFO)) - return -1; - - TDBTEvent ev = {0,0,0,0,0,0,0}; - ev.cbSize = sizeof(ev); - ev.cbBlob = 0; - ev.pBlob = NULL; - - int res = DBEventGet(hEvent, reinterpret_cast(&ev)); - - dbei->szModule = ev.ModuleName; - dbei->timestamp = ev.Timestamp; - dbei->flags = ev.Flags; - if (dbei->flags & DBEF_SENT) - dbei->flags = dbei->flags & ~DBEF_READ; - dbei->eventType = ev.EventType; - - if (dbei->cbBlob && dbei->pBlob) - { - if (dbei->cbBlob >= ev.cbBlob) - memcpy(dbei->pBlob, ev.pBlob, ev.cbBlob); - else - memcpy(dbei->pBlob, ev.pBlob, dbei->cbBlob); - } - mir_free(ev.pBlob); - dbei->cbBlob = ev.cbBlob; - - if (res == DBT_INVALIDPARAM) - return 1; - - return res; -} -INT_PTR CompMarkEventRead(WPARAM hContact, LPARAM hEvent) -{ - int res = DBEventMarkRead(hEvent, 0); - if ((res != DBT_INVALIDPARAM) && (res & DBEF_SENT)) - res = res & ~DBEF_READ; - return res; -} -INT_PTR CompGetEventContact(WPARAM hEvent, LPARAM lParam) -{ - TDBTEntityHandle res = DBEventGetEntity(hEvent, 0); - if (res == gDataBase->getEntities().getRootEntity()) - res = 0; - - return res; -} -INT_PTR CompFindFirstEvent(WPARAM hContact, LPARAM lParam) -{ - if (hContact == 0) - hContact = gDataBase->getEntities().getRootEntity(); - - return gDataBase->getEvents().compFirstEvent(hContact); -} -INT_PTR CompFindFirstUnreadEvent(WPARAM hContact, LPARAM lParam) -{ - if (hContact == 0) - hContact = gDataBase->getEntities().getRootEntity(); - return gDataBase->getEvents().compFirstUnreadEvent(hContact); -} -INT_PTR CompFindLastEvent(WPARAM hContact, LPARAM lParam) -{ - if (hContact == 0) - hContact = gDataBase->getEntities().getRootEntity(); - return gDataBase->getEvents().compLastEvent(hContact); -} -INT_PTR CompFindNextEvent(WPARAM hEvent, LPARAM lParam) -{ - return gDataBase->getEvents().compNextEvent(hEvent); -} -INT_PTR CompFindPrevEvent(WPARAM hEvent, LPARAM lParam) -{ - return gDataBase->getEvents().compPrevEvent(hEvent); -} - -INT_PTR CompEnumModules(WPARAM wParam, LPARAM pCallback) -{ - if (!pCallback) - return -1; - - return gDataBase->getSettings().CompEnumModules(reinterpret_cast(pCallback), wParam); -} - -void Encrypt(char* msg, BOOL up) -{ - int i; - const int jump = up ? 5 : -5; - - for (i=0; msg[i]; i++) - { - msg[i] = msg[i] + jump; - } - -} - -INT_PTR CompEncodeString(WPARAM wParam, LPARAM lParam) -{ - Encrypt(reinterpret_cast(lParam),TRUE); - return 0; -} - -INT_PTR CompDecodeString(WPARAM wParam, LPARAM lParam) -{ - Encrypt(reinterpret_cast(lParam),FALSE); - return 0; -} - -INT_PTR CompGetProfileName(WPARAM cbBytes, LPARAM pszName) -{ - return gDataBase->getProfileName(cbBytes, reinterpret_cast(pszName)); -} - -INT_PTR CompGetProfilePath(WPARAM cbBytes, LPARAM pszName) -{ - return gDataBase->getProfilePath(cbBytes, reinterpret_cast(pszName)); -} - -bool CompatibilityRegister() -{ - gCompServices[ 0] = CreateServiceFunction(MS_DB_CONTACT_GETCOUNT, CompGetContactCount); - gCompServices[ 1] = CreateServiceFunction(MS_DB_CONTACT_FINDFIRST, CompFindFirstContact); - gCompServices[ 2] = CreateServiceFunction(MS_DB_CONTACT_FINDNEXT, CompFindNextContact); - gCompServices[ 3] = CreateServiceFunction(MS_DB_CONTACT_DELETE, CompDeleteContact); - gCompServices[ 4] = CreateServiceFunction(MS_DB_CONTACT_ADD, CompAddContact); - gCompServices[ 5] = CreateServiceFunction(MS_DB_CONTACT_IS, CompIsDbContact); - - gCompServices[ 6] = CreateServiceFunction(MS_DB_CONTACT_GETSETTING, CompGetContactSetting); - gCompServices[ 7] = CreateServiceFunction(MS_DB_CONTACT_GETSETTING_STR, CompGetContactSettingStr); - gCompServices[ 8] = CreateServiceFunction(MS_DB_CONTACT_GETSETTINGSTATIC, CompGetContactSettingStatic); - gCompServices[ 9] = CreateServiceFunction(MS_DB_CONTACT_FREEVARIANT, CompFreeVariant); - gCompServices[10] = CreateServiceFunction(MS_DB_CONTACT_WRITESETTING, CompWriteContactSetting); - gCompServices[11] = CreateServiceFunction(MS_DB_CONTACT_DELETESETTING, CompDeleteContactSetting); - gCompServices[12] = CreateServiceFunction(MS_DB_CONTACT_ENUMSETTINGS, CompEnumContactSettings); - //gCompServices[13] = CreateServiceFunction(MS_DB_SETSETTINGRESIDENT, CompSetSettingResident); - - gCompServices[14] = CreateServiceFunction(MS_DB_EVENT_GETCOUNT, CompGetEventCount); - gCompServices[15] = CreateServiceFunction(MS_DB_EVENT_ADD, CompAddEvent); - gCompServices[16] = CreateServiceFunction(MS_DB_EVENT_DELETE, CompDeleteEvent); - gCompServices[17] = CreateServiceFunction(MS_DB_EVENT_GETBLOBSIZE, CompGetBlobSize); - gCompServices[18] = CreateServiceFunction(MS_DB_EVENT_GET, CompGetEvent); - gCompServices[19] = CreateServiceFunction(MS_DB_EVENT_MARKREAD, CompMarkEventRead); - gCompServices[20] = CreateServiceFunction(MS_DB_EVENT_GETCONTACT, CompGetEventContact); - gCompServices[21] = CreateServiceFunction(MS_DB_EVENT_FINDFIRST, CompFindFirstEvent); - gCompServices[22] = CreateServiceFunction(MS_DB_EVENT_FINDFIRSTUNREAD, CompFindFirstUnreadEvent); - gCompServices[23] = CreateServiceFunction(MS_DB_EVENT_FINDLAST, CompFindLastEvent); - gCompServices[24] = CreateServiceFunction(MS_DB_EVENT_FINDNEXT, CompFindNextEvent); - gCompServices[25] = CreateServiceFunction(MS_DB_EVENT_FINDPREV, CompFindPrevEvent); - - gCompServices[26] = CreateServiceFunction(MS_DB_MODULES_ENUM, CompEnumModules); - - gCompServices[27] = CreateServiceFunction(MS_DB_CRYPT_ENCODESTRING, CompEncodeString); - gCompServices[28] = CreateServiceFunction(MS_DB_CRYPT_DECODESTRING, CompDecodeString); - - gCompServices[29] = CreateServiceFunction(MS_DB_GETPROFILENAME, CompGetProfileName); - gCompServices[30] = CreateServiceFunction(MS_DB_GETPROFILEPATH, CompGetProfilePath); - - - hEventDeletedEvent = CreateHookableEvent(ME_DB_EVENT_DELETED); - hEventAddedEvent = CreateHookableEvent(ME_DB_EVENT_ADDED); - hEventFilterAddedEvent = CreateHookableEvent(ME_DB_EVENT_FILTER_ADD); - hSettingChangeEvent = CreateHookableEvent(ME_DB_CONTACT_SETTINGCHANGED); - hContactDeletedEvent = CreateHookableEvent(ME_DB_CONTACT_DELETED); - hContactAddedEvent = CreateHookableEvent(ME_DB_CONTACT_ADDED); - return true; -} -bool CompatibilityUnRegister() -{ - int i; - for (i = 0; i < sizeof(gCompServices) / sizeof(gCompServices[0]); ++i) - { - DestroyServiceFunction(gCompServices[i]); - } - return true; -} diff --git a/dbx_tree/Compatibility.h b/dbx_tree/Compatibility.h deleted file mode 100644 index b6b6c16..0000000 --- a/dbx_tree/Compatibility.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - -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. - -*/ - -#pragma once - -#include "Interface.h" -#include "DataBase.h" -#include "Services.h" - -bool CompatibilityRegister(); -bool CompatibilityUnRegister(); - -INT_PTR CompGetContactCount(WPARAM wParam,LPARAM lParam); -INT_PTR CompFindFirstContact(WPARAM wParam,LPARAM lParam); -INT_PTR CompFindNextContact(WPARAM hContact,LPARAM lParam); -INT_PTR CompDeleteContact(WPARAM hContact,LPARAM lParam); -INT_PTR CompAddContact(WPARAM wParam,LPARAM lParam); -INT_PTR CompIsDbContact(WPARAM hContact,LPARAM lParam); - -INT_PTR CompGetContactSetting(WPARAM hContact, LPARAM pSetting); -INT_PTR CompGetContactSettingStr(WPARAM hContact, LPARAM pSetting); -INT_PTR CompGetContactSettingStatic(WPARAM hContact, LPARAM pSetting); -INT_PTR CompFreeVariant(WPARAM wParam, LPARAM pSetting); -INT_PTR CompWriteContactSetting(WPARAM hContact, LPARAM pSetting); -INT_PTR CompDeleteContactSetting(WPARAM hContact, LPARAM pSetting); -INT_PTR CompEnumContactSettings(WPARAM hContact, LPARAM pEnum); - -INT_PTR CompGetEventCount(WPARAM wParam, LPARAM lParam); -INT_PTR CompAddEvent(WPARAM hContact, LPARAM pEventInfo); -INT_PTR CompDeleteEvent(WPARAM hContact, LPARAM hEvent); -INT_PTR CompGetBlobSize(WPARAM hEvent, LPARAM lParam); -INT_PTR CompGetEvent(WPARAM hEvent, LPARAM pEventInfo); -INT_PTR CompMarkEventRead(WPARAM hContact, LPARAM hEvent); -INT_PTR CompGetEventContact(WPARAM hEvent, LPARAM lParam); -INT_PTR CompFindFirstEvent(WPARAM hContact, LPARAM lParam); -INT_PTR CompFindFirstUnreadEvent(WPARAM hContact, LPARAM lParam); -INT_PTR CompFindLastEvent(WPARAM hContact, LPARAM lParam); -INT_PTR CompFindNextEvent(WPARAM hEvent, LPARAM lParam); -INT_PTR CompFindPrevEvent(WPARAM hEvent, LPARAM lParam); - - -INT_PTR CompEncodeString(WPARAM wParam, LPARAM lParam); -INT_PTR CompDecodeString(WPARAM wParam, LPARAM lParam); - -INT_PTR CompGetProfileName(WPARAM cbBytes, LPARAM pszName); -INT_PTR CompGetProfilePath(WPARAM cbBytes, LPARAM pszName); diff --git a/dbx_tree/DataBase.cpp b/dbx_tree/DataBase.cpp deleted file mode 100644 index 85a9d67..0000000 --- a/dbx_tree/DataBase.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/* - -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 "DataBase.h" -#include "newpluginapi.h" -#ifndef _MSC_VER -#include "savestrings_gcc.h" -#endif -#include "Logger.h" - -CDataBase *gDataBase = NULL; - -CDataBase::CDataBase(const char* FileName) -{ - int len; -#ifdef UNICODE - len = MultiByteToWideChar(CP_ACP, 0, FileName, -1, NULL, 0); - m_FileName[0] = new TCHAR[len + 1]; - MultiByteToWideChar(CP_ACP, 0, FileName, -1, m_FileName[0], len + 1); - m_FileName[0][len] = 0; -#else - len = strlen(FileName); - m_FileName[0] = new TCHAR[len + 1]; - strcpy_s(m_FileName[0], len + 1, FileName); -#endif - - TCHAR * tmp = _tcsrchr(m_FileName[0], '.'); - if (tmp) - { - m_FileName[1] = new TCHAR[len + 1]; - _tcsncpy_s(m_FileName[1], len + 1, m_FileName[0], tmp - m_FileName[0]); - _tcscat_s(m_FileName[1], len + 1, _T(".pri")); - } else { - m_FileName[1] = new TCHAR[len + 5]; - _tcscpy_s(m_FileName[1], len + 5, m_FileName[0]); - _tcscat_s(m_FileName[1], len + 5, _T(".pri")); - } - - m_Opened = false; - - for (int i = 0; i < DBFileMax; ++i) - { - m_BlockManager[i] = NULL; - m_FileAccess[i] = NULL; - m_EncryptionManager[i] = NULL; - m_HeaderBlock[i] = 0; - } - - m_Entities = NULL; - m_Settings = NULL; - m_Events = NULL; -} -CDataBase::~CDataBase() -{ - if (m_Events) delete m_Events; - if (m_Settings) delete m_Settings; - if (m_Entities) delete m_Entities; - - m_Entities = NULL; - m_Settings = NULL; - m_Events = NULL; - - for (int i = DBFileMax - 1; i >= 0; --i) - { - if (m_BlockManager[i]) delete m_BlockManager[i]; - if (m_FileAccess[i]) delete m_FileAccess[i]; - if (m_EncryptionManager[i]) delete m_EncryptionManager[i]; - - m_BlockManager[i] = NULL; - m_FileAccess[i] = NULL; - m_EncryptionManager[i] = NULL; - - delete [] (m_FileName[i]); - } - -} -int CDataBase::CreateDB() -{ - /// TODO: create and show wizard - if (!CreateNewFile(DBFileSetting) || - !CreateNewFile(DBFilePrivate)) - return EMKPRF_CREATEFAILED; - - return 0; -} - - -int CDataBase::CheckFile(TDBFileType Index) -{ - TGenericFileHeader h; - memset(&h, 0, sizeof(h)); - DWORD r = 0; - HANDLE htmp = CreateFile(m_FileName[Index], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL); - if (htmp != INVALID_HANDLE_VALUE) - { - SetFilePointer(htmp, 0, NULL, FILE_BEGIN); - if (ReadFile(htmp, &h, sizeof(h), &r, NULL)) - { - if (0 != memcmp(h.Gen.Signature, cFileSignature[Index], sizeof(cFileSignature[Index]))) - { - CloseHandle(htmp); - return EGROKPRF_UNKHEADER; - } - - if (cDBVersion < h.Gen.Version) - { - CloseHandle(htmp); - return EGROKPRF_VERNEWER; - } - - CloseHandle(htmp); - return EGROKPRF_NOERROR; - } - CloseHandle(htmp); - } - - return EGROKPRF_CANTREAD; -} - -int CDataBase::CheckDB() -{ - int res = CheckFile(DBFileSetting); - - if (res != EGROKPRF_NOERROR) - return res; - - if (PrivateFileExists()) - res = CheckFile(DBFilePrivate); - - return res; -} - -int CDataBase::LoadFile(TDBFileType Index) -{ - TGenericFileHeader h; - m_EncryptionManager[Index] = new CEncryptionManager; - - if (CMappedMemory::InitMMAP()) - m_FileAccess[Index] = new CMappedMemory(m_FileName[Index]); - else - m_FileAccess[Index] = new CDirectAccess(m_FileName[Index]); - - m_FileAccess[Index]->Read(&h, 0, sizeof(h)); - m_EncryptionManager[Index]->InitEncryption(h.Gen.FileEncryption); - - m_FileAccess[Index]->Size(h.Gen.FileSize); - m_FileAccess[Index]->sigFileSizeChanged().connect(this, &CDataBase::onFileSizeChanged); - - m_BlockManager[Index] = new CBlockManager(*m_FileAccess[Index], *m_EncryptionManager[Index]); - - CBlockManager::WriteTransaction trans(*m_BlockManager[Index]); // don't fire size event until header is loaded - - m_HeaderBlock[Index] = m_BlockManager[Index]->ScanFile(sizeof(h), cHeaderBlockSignature, h.Gen.FileSize); - - if (m_HeaderBlock[Index] == 0) - { - LOG(logCRITICAL, _T("Header Block not found! File damaged: \"%s\""), m_FileName[Index]); - return -1; - } - - uint32_t size = sizeof(h); - uint32_t sig = -1; - m_Header[Index] = m_BlockManager[Index]->ReadBlock(0, size, sig); - - sig = cHeaderBlockSignature; - TGenericFileHeader * buf = m_BlockManager[Index]->ReadBlock(m_HeaderBlock[Index], size, sig); - if (!buf) - { - LOG(logCRITICAL, _T("Header Block cannot be read! File damaged: \"%s\""), m_FileName[Index]); - return -1; - } - - buf->Gen.Obscure = 0; - - if (memcmp(m_Header[Index], buf, size)) - { - LOG(logCRITICAL, _T("Header Block in \"%s\" damaged!"), m_FileName[Index]); - return -1; - } - - return 0; -} - -int CDataBase::OpenDB() -{ - if (!PrivateFileExists()) - { - // TODO WIZARD - if (!CreateNewFile(DBFilePrivate)) - return -1; - } - - int res = LoadFile(DBFileSetting); - if ((res != 0) && (CLogger::logERROR <= CLogger::Instance().ShowMessage())) - { - return res; - } - - res = LoadFile(DBFilePrivate); - - if ((res != 0) && (CLogger::logERROR <= CLogger::Instance().ShowMessage())) - { - return res; - } - if (CLogger::logERROR <= CLogger::Instance().ShowMessage()) - return -1; - - m_Entities = new CEntities(*m_BlockManager[DBFilePrivate], - m_Header[DBFilePrivate]->Pri.RootEntity, - m_Header[DBFilePrivate]->Pri.Entities, - m_Header[DBFilePrivate]->Pri.Virtuals); - - m_Entities->sigRootChanged().connect(this, &CDataBase::onEntitiesRootChanged); - m_Entities->sigVirtualRootChanged().connect(this, &CDataBase::onVirtualsRootChanged); - - if (m_Entities->getRootEntity() != m_Header[DBFilePrivate]->Pri.RootEntity) - { - m_Header[DBFilePrivate]->Pri.RootEntity = m_Entities->getRootEntity(); - ReWriteHeader(DBFilePrivate); - } - - m_Settings = new CSettings(*m_BlockManager[DBFileSetting], - *m_BlockManager[DBFilePrivate], - m_Header[DBFileSetting]->Set.Settings, - *m_Entities); - - m_Settings->sigRootChanged().connect(this, &CDataBase::onSettingsRootChanged); - - m_Events = new CEvents(*m_BlockManager[DBFilePrivate], - *m_EncryptionManager[DBFilePrivate], - *m_Entities, - *m_Settings); - - return 0; -} - -bool CDataBase::PrivateFileExists() -{ - HANDLE htmp = CreateFile(m_FileName[DBFilePrivate], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL); - if (htmp != INVALID_HANDLE_VALUE) - { - CloseHandle(htmp); - return true; - } - - return false; -} - - -bool CDataBase::CreateNewFile(TDBFileType File) -{ - CEncryptionManager enc; - CDirectAccess fa(m_FileName[File]); - fa.Size(sizeof(TGenericFileHeader)); - CBlockManager bm(fa, enc); - bm.ScanFile(sizeof(TGenericFileHeader), 0, sizeof(TGenericFileHeader)); - - CBlockManager::WriteTransaction trans(bm); - - uint32_t block; - TGenericFileHeader * buf = bm.CreateBlock(block, cHeaderBlockSignature); - uint32_t size = 0; - uint32_t sig = -1; - TGenericFileHeader * h = bm.ReadBlock(0, size, sig); - - memset(h, 0, sizeof(TGenericFileHeader)); - memcpy(&h->Gen.Signature, &cFileSignature[File], sizeof(h->Gen.Signature)); - h->Gen.Version = cDBVersion; - h->Gen.FileSize = fa.Size(); - - memcpy(buf, h, sizeof(TGenericFileHeader)); - bm.UpdateBlock(block, 0); - bm.UpdateBlock(0, -1); - - return true; -} - -inline void CDataBase::ReWriteHeader(TDBFileType Index) -{ - m_BlockManager[Index]->UpdateBlock(0, -1); - uint32_t size = 0, sig = 0; - TGenericFileHeader * h = m_BlockManager[Index]->ReadBlock(m_HeaderBlock[Index], size, sig); - - *h = *m_Header[Index]; - h->Gen.Obscure = GetTickCount(); - m_BlockManager[Index]->UpdateBlock(m_HeaderBlock[Index], 0); -} - - -void CDataBase::onSettingsRootChanged(CSettings* Settings, CSettingsTree::TNodeRef NewRoot) -{ - m_Header[DBFileSetting]->Set.Settings = NewRoot; - ReWriteHeader(DBFileSetting); -} -void CDataBase::onVirtualsRootChanged(void* Virtuals, CVirtuals::TNodeRef NewRoot) -{ - m_Header[DBFilePrivate]->Pri.Virtuals = NewRoot; - ReWriteHeader(DBFilePrivate); -} -void CDataBase::onEntitiesRootChanged(void* Entities, CEntities::TNodeRef NewRoot) -{ - m_Header[DBFilePrivate]->Pri.Entities = NewRoot; - ReWriteHeader(DBFilePrivate); -} -void CDataBase::onFileSizeChanged(CFileAccess * File, uint32_t Size) -{ - if (File == m_FileAccess[DBFileSetting]) - { - m_Header[DBFileSetting]->Gen.FileSize = Size; - ReWriteHeader(DBFileSetting); - } else { - m_Header[DBFilePrivate]->Gen.FileSize = Size; - ReWriteHeader(DBFilePrivate); - } -} - -int CDataBase::getProfileName(int BufferSize, char * Buffer) -{ - TCHAR * slash = _tcsrchr(m_FileName[DBFileSetting], '\\'); - if (slash) - slash++; - else - slash = m_FileName[DBFileSetting]; - - int l = static_cast(_tcslen(slash)); - if (BufferSize < l + 1) - return -1; - - char * tmp = mir_t2a(slash); - strcpy_s(Buffer, BufferSize, tmp); - mir_free(tmp); - - return 0; -} -int CDataBase::getProfilePath(int BufferSize, char * Buffer) -{ - TCHAR * slash = _tcsrchr(m_FileName[DBFileSetting], '\\'); - if (!slash) - return -1; - - int l = slash - m_FileName[DBFileSetting]; - - if (BufferSize < l + 1) - { - return -1; - } - - *slash = 0; - char * tmp = mir_t2a(m_FileName[DBFileSetting]); - strcpy_s(Buffer, BufferSize, tmp); - mir_free(tmp); - *slash = '\\'; - - return 0; -} diff --git a/dbx_tree/DataBase.h b/dbx_tree/DataBase.h deleted file mode 100644 index 2577249..0000000 --- a/dbx_tree/DataBase.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - -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. - -*/ - -#pragma once - -#ifndef _MSC_VER -#include -#else -#include "stdint.h" -#endif -#include "MREWSync.h" - -#include "Events.h" -#include "Settings.h" -#include "Entities.h" - -#include "FileAccess.h" -#include "MappedMemory.h" -#include "DirectAccess.h" -#include "Blockmanager.h" - -#include "sigslot.h" - -#include "EncryptionManager.h" - -typedef enum TDBFileType { - DBFileSetting = 0, - DBFilePrivate = 1, - DBFileMax = 2 -} TDBFileType; - -static const uint8_t cFileSignature[DBFileMax][20] = {"Miranda IM Settings", "Miranda IM DataTree"}; -static const uint32_t cDBVersion = 0x00000001; - -static const uint32_t cHeaderBlockSignature = 0x7265491E; - -#pragma pack(push, 1) // push current alignment to stack, set alignment to 1 byte boundary - -typedef struct TSettingsHeader { - uint8_t Signature[20]; /// signature must be cSettingsHeader - uint32_t Version; /// internal DB version cDataBaseVersion - uint32_t Obscure; - TFileEncryption FileEncryption; /// Encryption Method - uint32_t FileStructureBlock; /// Offset of CBlockManager master block - uint32_t FileSize; /// Offset to the last used byte + 1 - uint32_t Settings; /// Offset to the SettingsBTree RootNode - uint8_t Reserved[256 - sizeof(TFileEncryption) - 20 - 5*sizeof(uint32_t)]; /// reserved storage -} TSettingsHeader; - -typedef struct TPrivateHeader { - uint8_t Signature[20]; /// signature must be CDataHeader - uint32_t Version; /// internal DB version cDataBaseVersion - uint32_t Obscure; - TFileEncryption FileEncryption; /// Encryption Method - uint32_t FileStructureBlock; /// Offset of CBlockManager master block - uint32_t FileSize; /// Offset to the last used byte + 1 - uint32_t RootEntity; /// Offset to the Root CList Entity - uint32_t Entities; /// Offset to the EntityBTree RootNode - uint32_t Virtuals; /// Offset to the VirtualsBTree RootNode - uint8_t Reserved[256 - sizeof(TFileEncryption) - 20 - 7*sizeof(uint32_t)]; /// reserved storage -} TPrivateHeader; - - -typedef union TGenericFileHeader { - struct { - uint8_t Signature[20]; /// signature must be cSettingsHeader - uint32_t Version; /// internal DB version cDataBaseVersion - uint32_t Obscure; - TFileEncryption FileEncryption; /// Encryption Method - uint32_t FileStructureBlock; /// Offset of CBlockManager master block - uint32_t FileSize; /// Offset to the last used byte + 1 - uint8_t Reserved[256 - sizeof(TFileEncryption) - 20 - 4*sizeof(uint32_t)]; /// reserved storage - } Gen; - TSettingsHeader Set; - TPrivateHeader Pri; -} TGenericFileHeader; - -#pragma pack(pop) - - -class CDataBase : public sigslot::has_slots<> -{ -private: - TCHAR* m_FileName[DBFileMax]; - bool m_Opened; - - CBlockManager *m_BlockManager[DBFileMax]; - CFileAccess *m_FileAccess[DBFileMax]; - TGenericFileHeader * m_Header[DBFileMax]; - CEncryptionManager *m_EncryptionManager[DBFileMax]; - - uint32_t m_HeaderBlock[DBFileMax]; - - void onSettingsRootChanged(CSettings* Settings, CSettingsTree::TNodeRef NewRoot); - void onVirtualsRootChanged(void* Virtuals, CVirtuals::TNodeRef NewRoot); - void onEntitiesRootChanged(void* Entities, CEntities::TNodeRef NewRoot); - void onFileSizeChanged(CFileAccess * File, uint32_t Size); - - bool PrivateFileExists(); - bool CreateNewFile(TDBFileType File); - - int CheckFile(TDBFileType Index); - int LoadFile(TDBFileType Index); -protected: - CEntities *m_Entities; - CSettings *m_Settings; - CEvents *m_Events; - - void ReWriteHeader(TDBFileType Index); - -public: - CDataBase(const char* FileName); - virtual ~CDataBase(); - - int CreateDB(); - int CheckDB(); - int OpenDB(); - - CEntities & getEntities() - { - return *m_Entities; - } - CSettings & getSettings() - { - return *m_Settings; - } - CEvents & getEvents() - { - return *m_Events; - } - - int getProfileName(int BufferSize, char * Buffer); - int getProfilePath(int BufferSize, char * Buffer); - -}; - - -extern CDataBase *gDataBase; diff --git a/dbx_tree/DatabaseLink.cpp b/dbx_tree/DatabaseLink.cpp deleted file mode 100644 index b6cd91e..0000000 --- a/dbx_tree/DatabaseLink.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - -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 "DatabaseLink.h" -#ifndef _MSC_VER -#include "savestrings_gcc.h" -#endif - -static int getCapability(int); -static int getFriendlyName(char*, size_t, int); -static int makeDatabase(char*, int*); -static int grokHeader(char*, int*); -static int Load(char*, void*); -static int Unload(int); - -DATABASELINK gDBLink = { - sizeof(DATABASELINK), - getCapability, - getFriendlyName, - makeDatabase, - grokHeader, - Load, - Unload, -}; - -PLUGINLINK *pluginLink = NULL; -MM_INTERFACE mmi = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -UTF8_INTERFACE utfi = {0,0,0,0,0,0,0}; -HANDLE hSystemModulesLoaded = 0; - - -static int SystemModulesLoaded(WPARAM wParam, LPARAM lParam) -{ - Update upd = {0,0,0,0,0,0,0,0,0,0,0,0,0}; - - upd.cbSize = sizeof(upd); - upd.szComponentName = gInternalName; - upd.szBetaVersionURL = "http://www-user.tu-chemnitz.de/~kunmi/?dbx_tree"; -#ifdef _M_X64 - upd.pbBetaVersionPrefix = (BYTE *)"