fx_basic_maps.cpp revision ee451cb395940862dad63c85adfe8f2fd55e864c
1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file.
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/fxcrt/fx_ext.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "plex.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void ConstructElement(CFX_ByteString* pNewData)
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    new (pNewData) CFX_ByteString();
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void DestructElement(CFX_ByteString* pOldData)
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pOldData->~CFX_ByteString();
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_MapPtrToPtr::CFX_MapPtrToPtr(int nBlockSize, IFX_Allocator* pAllocator)
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    : m_pAllocator(pAllocator)
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pHashTable(NULL)
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_nHashTableSize(17)
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_nCount(0)
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pFreeList(NULL)
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pBlocks(NULL)
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_nBlockSize(nBlockSize)
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_nBlockSize > 0);
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_MapPtrToPtr::RemoveAll()
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pHashTable) {
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Allocator_Free(m_pAllocator, m_pHashTable);
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pHashTable = NULL;
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nCount = 0;
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFreeList = NULL;
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBlocks->FreeDataChain(m_pAllocator);
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBlocks = NULL;
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_MapPtrToPtr::~CFX_MapPtrToPtr()
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    RemoveAll();
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_nCount == 0);
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_DWORD CFX_MapPtrToPtr::HashKey(void* key) const
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ((FX_DWORD)(FX_UINTPTR)key) >> 4;
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_MapPtrToPtr::GetNextAssoc(FX_POSITION& rNextPosition, void*& rKey, void*& rValue) const
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_pHashTable != NULL);
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssocRet = (CAssoc*)rNextPosition;
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(pAssocRet != NULL);
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pAssocRet == (CAssoc*) - 1) {
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++)
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((pAssocRet = m_pHashTable[nBucket]) != NULL) {
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ASSERT(pAssocRet != NULL);
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssocNext;
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((pAssocNext = pAssocRet->pNext) == NULL) {
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (FX_DWORD nBucket = (HashKey(pAssocRet->key) % m_nHashTableSize) + 1; nBucket < m_nHashTableSize; nBucket ++) {
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((pAssocNext = m_pHashTable[nBucket]) != NULL) {
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rNextPosition = (FX_POSITION) pAssocNext;
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rKey = pAssocRet->key;
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rValue = pAssocRet->value;
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_MapPtrToPtr::Lookup(void* key, void*& rValue) const
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD nHash;
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssoc = GetAssocAt(key, nHash);
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pAssoc == NULL) {
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rValue = pAssoc->value;
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid* CFX_MapPtrToPtr::GetValueAt(void* key) const
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD nHash;
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssoc = GetAssocAt(key, nHash);
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pAssoc == NULL) {
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pAssoc->value;
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid*& CFX_MapPtrToPtr::operator[](void* key)
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD nHash;
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssoc;
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((pAssoc = GetAssocAt(key, nHash)) == NULL) {
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pHashTable == NULL) {
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            InitHashTable(m_nHashTableSize);
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pAssoc = NewAssoc();
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pAssoc->key = key;
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pAssoc->pNext = m_pHashTable[nHash];
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pHashTable[nHash] = pAssoc;
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pAssoc->value;
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_MapPtrToPtr::CAssoc*
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_MapPtrToPtr::GetAssocAt(void* key, FX_DWORD& nHash) const
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    nHash = HashKey(key) % m_nHashTableSize;
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pHashTable == NULL) {
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssoc;
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; pAssoc = pAssoc->pNext) {
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pAssoc->key == key) {
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return pAssoc;
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return NULL;
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_MapPtrToPtr::CAssoc*
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_MapPtrToPtr::NewAssoc()
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFreeList == NULL) {
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_Plex* newBlock = CFX_Plex::Create(m_pAllocator, m_pBlocks, m_nBlockSize, sizeof(CFX_MapPtrToPtr::CAssoc));
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_MapPtrToPtr::CAssoc* pAssoc = (CFX_MapPtrToPtr::CAssoc*)newBlock->data();
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pAssoc += m_nBlockSize - 1;
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = m_nBlockSize - 1; i >= 0; i--, pAssoc--) {
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pAssoc->pNext = m_pFreeList;
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pFreeList = pAssoc;
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_pFreeList != NULL);
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_MapPtrToPtr::CAssoc* pAssoc = m_pFreeList;
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFreeList = m_pFreeList->pNext;
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nCount++;
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_nCount > 0);
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pAssoc->key = 0;
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pAssoc->value = 0;
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pAssoc;
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_MapPtrToPtr::InitHashTable(
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD nHashSize, FX_BOOL bAllocNow)
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_nCount == 0);
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(nHashSize > 0);
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pHashTable != NULL) {
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Allocator_Free(m_pAllocator, m_pHashTable);
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pHashTable = NULL;
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bAllocNow) {
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pHashTable = FX_Allocator_Alloc(m_pAllocator, CAssoc*, nHashSize);
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pHashTable) {
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXSYS_memset32(m_pHashTable, 0, sizeof(CAssoc*) * nHashSize);
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nHashTableSize = nHashSize;
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_MapPtrToPtr::RemoveKey(void* key)
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pHashTable == NULL) {
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc** ppAssocPrev;
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ppAssocPrev = &m_pHashTable[HashKey(key) % m_nHashTableSize];
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssoc;
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (pAssoc = *ppAssocPrev; pAssoc != NULL; pAssoc = pAssoc->pNext) {
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pAssoc->key == key) {
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *ppAssocPrev = pAssoc->pNext;
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FreeAssoc(pAssoc);
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ppAssocPrev = &pAssoc->pNext;
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_MapPtrToPtr::FreeAssoc(CFX_MapPtrToPtr::CAssoc* pAssoc)
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pAssoc->pNext = m_pFreeList;
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFreeList = pAssoc;
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nCount--;
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_nCount >= 0);
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_nCount == 0) {
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        RemoveAll();
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_MapByteStringToPtr::CFX_MapByteStringToPtr(int nBlockSize, IFX_Allocator* pAllocator)
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    : m_pAllocator(pAllocator)
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pHashTable(NULL)
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_nHashTableSize(17)
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_nCount(0)
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pFreeList(NULL)
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pBlocks(NULL)
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_nBlockSize(nBlockSize)
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_nBlockSize > 0);
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_MapByteStringToPtr::RemoveAll()
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pHashTable != NULL) {
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (FX_DWORD nHash = 0; nHash < m_nHashTableSize; nHash++) {
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CAssoc* pAssoc;
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL;
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pAssoc = pAssoc->pNext) {
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                DestructElement(&pAssoc->key);
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Allocator_Free(m_pAllocator, m_pHashTable);
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pHashTable = NULL;
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nCount = 0;
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFreeList = NULL;
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBlocks->FreeDataChain(m_pAllocator);
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBlocks = NULL;
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_MapByteStringToPtr::~CFX_MapByteStringToPtr()
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    RemoveAll();
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_nCount == 0);
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_MapByteStringToPtr::GetNextAssoc(FX_POSITION& rNextPosition,
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_ByteString& rKey, void*& rValue) const
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_pHashTable != NULL);
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssocRet = (CAssoc*)rNextPosition;
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(pAssocRet != NULL);
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pAssocRet == (CAssoc*) - 1) {
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++)
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((pAssocRet = m_pHashTable[nBucket]) != NULL) {
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ASSERT(pAssocRet != NULL);
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssocNext;
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((pAssocNext = pAssocRet->pNext) == NULL) {
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (FX_DWORD nBucket = pAssocRet->nHashValue + 1;
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                nBucket < m_nHashTableSize; nBucket++)
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((pAssocNext = m_pHashTable[nBucket]) != NULL) {
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rNextPosition = (FX_POSITION) pAssocNext;
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rKey = pAssocRet->key;
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rValue = pAssocRet->value;
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_LPVOID CFX_MapByteStringToPtr::GetNextValue(FX_POSITION& rNextPosition) const
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_pHashTable != NULL);
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssocRet = (CAssoc*)rNextPosition;
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(pAssocRet != NULL);
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pAssocRet == (CAssoc*) - 1) {
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++)
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((pAssocRet = m_pHashTable[nBucket]) != NULL) {
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ASSERT(pAssocRet != NULL);
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssocNext;
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((pAssocNext = pAssocRet->pNext) == NULL) {
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (FX_DWORD nBucket = pAssocRet->nHashValue + 1;
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                nBucket < m_nHashTableSize; nBucket++)
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((pAssocNext = m_pHashTable[nBucket]) != NULL) {
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rNextPosition = (FX_POSITION) pAssocNext;
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pAssocRet->value;
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid*& CFX_MapByteStringToPtr::operator[](FX_BSTR key)
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD nHash;
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssoc;
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((pAssoc = GetAssocAt(key, nHash)) == NULL) {
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pHashTable == NULL) {
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            InitHashTable(m_nHashTableSize);
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pAssoc = NewAssoc();
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pAssoc->nHashValue = nHash;
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pAssoc->key = key;
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pAssoc->pNext = m_pHashTable[nHash];
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pHashTable[nHash] = pAssoc;
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pAssoc->value;
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_MapByteStringToPtr::CAssoc*
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_MapByteStringToPtr::NewAssoc()
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFreeList == NULL) {
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_Plex* newBlock = CFX_Plex::Create(m_pAllocator, m_pBlocks, m_nBlockSize, sizeof(CFX_MapByteStringToPtr::CAssoc));
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_MapByteStringToPtr::CAssoc* pAssoc = (CFX_MapByteStringToPtr::CAssoc*)newBlock->data();
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pAssoc += m_nBlockSize - 1;
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int i = m_nBlockSize - 1; i >= 0; i--, pAssoc--) {
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pAssoc->pNext = m_pFreeList;
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pFreeList = pAssoc;
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_pFreeList != NULL);
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_MapByteStringToPtr::CAssoc* pAssoc = m_pFreeList;
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFreeList = m_pFreeList->pNext;
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nCount++;
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_nCount > 0);
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ConstructElement(&pAssoc->key);
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pAssoc->value = 0;
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pAssoc;
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_MapByteStringToPtr::FreeAssoc(CFX_MapByteStringToPtr::CAssoc* pAssoc)
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    DestructElement(&pAssoc->key);
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pAssoc->pNext = m_pFreeList;
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFreeList = pAssoc;
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nCount--;
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_nCount >= 0);
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_nCount == 0) {
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        RemoveAll();
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_MapByteStringToPtr::CAssoc*
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_MapByteStringToPtr::GetAssocAt(FX_BSTR key, FX_DWORD& nHash) const
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    nHash = HashKey(key) % m_nHashTableSize;
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pHashTable == NULL) {
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssoc;
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; pAssoc = pAssoc->pNext) {
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pAssoc->key == key) {
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return pAssoc;
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return NULL;
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_MapByteStringToPtr::Lookup(FX_BSTR key, void*& rValue) const
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD nHash;
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssoc = GetAssocAt(key, nHash);
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pAssoc == NULL) {
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rValue = pAssoc->value;
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_MapByteStringToPtr::InitHashTable(
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD nHashSize, FX_BOOL bAllocNow)
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(m_nCount == 0);
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(nHashSize > 0);
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pHashTable != NULL) {
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Allocator_Free(m_pAllocator, m_pHashTable);
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pHashTable = NULL;
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bAllocNow) {
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pHashTable = FX_Allocator_Alloc(m_pAllocator, CAssoc*, nHashSize);
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pHashTable) {
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FXSYS_memset32(m_pHashTable, 0, sizeof(CAssoc*) * nHashSize);
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nHashTableSize = nHashSize;
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovinline FX_DWORD CFX_MapByteStringToPtr::HashKey(FX_BSTR key) const
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD nHash = 0;
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int len = key.GetLength();
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPCBYTE buf = key;
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < len; i ++) {
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        nHash = (nHash << 5) + nHash + buf[i];
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return nHash;
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_MapByteStringToPtr::RemoveKey(FX_BSTR key)
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pHashTable == NULL) {
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc** ppAssocPrev;
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ppAssocPrev = &m_pHashTable[HashKey(key) % m_nHashTableSize];
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CAssoc* pAssoc;
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (pAssoc = *ppAssocPrev; pAssoc != NULL; pAssoc = pAssoc->pNext) {
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pAssoc->key == key) {
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *ppAssocPrev = pAssoc->pNext;
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FreeAssoc(pAssoc);
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ppAssocPrev = &pAssoc->pNext;
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstruct _CompactString {
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE		m_CompactLen;
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE		m_LenHigh;
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE		m_LenLow;
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BYTE		m_Unused;
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPBYTE	m_pBuffer;
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void _CompactStringRelease(IFX_Allocator* pAllocator, _CompactString* pCompact)
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pCompact->m_CompactLen == 0xff) {
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_Allocator_Free(pAllocator, pCompact->m_pBuffer);
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic FX_BOOL _CompactStringSame(_CompactString* pCompact, FX_LPCBYTE pStr, int len)
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (len < sizeof(_CompactString)) {
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pCompact->m_CompactLen != len) {
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FXSYS_memcmp32(&pCompact->m_LenHigh, pStr, len) == 0;
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pCompact->m_CompactLen != 0xff || pCompact->m_LenHigh * 256 + pCompact->m_LenLow != len) {
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FXSYS_memcmp32(pCompact->m_pBuffer, pStr, len) == 0;
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic void _CompactStringStore(IFX_Allocator* pAllocator, _CompactString* pCompact, FX_LPCBYTE pStr, int len)
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (len < (int)sizeof(_CompactString)) {
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCompact->m_CompactLen = (FX_BYTE)len;
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memcpy32(&pCompact->m_LenHigh, pStr, len);
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pCompact->m_CompactLen = 0xff;
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pCompact->m_LenHigh = len / 256;
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pCompact->m_LenLow = len % 256;
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pCompact->m_pBuffer = FX_Allocator_Alloc(pAllocator, FX_BYTE, len);
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pCompact->m_pBuffer) {
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memcpy32(pCompact->m_pBuffer, pStr, len);
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic CFX_ByteStringC _CompactStringGet(_CompactString* pCompact)
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pCompact->m_CompactLen == 0xff) {
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return CFX_ByteStringC(pCompact->m_pBuffer, pCompact->m_LenHigh * 256 + pCompact->m_LenLow);
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pCompact->m_CompactLen == 0xfe) {
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return CFX_ByteStringC();
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return CFX_ByteStringC(&pCompact->m_LenHigh, pCompact->m_CompactLen);
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CMAP_ALLOC_STEP		8
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CMAP_INDEX_SIZE		8
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_CMapByteStringToPtr::CFX_CMapByteStringToPtr(IFX_Allocator* pAllocator)
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    : m_Buffer(sizeof(_CompactString) + sizeof(void*), CMAP_ALLOC_STEP, CMAP_INDEX_SIZE, pAllocator)
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_CMapByteStringToPtr::~CFX_CMapByteStringToPtr()
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    RemoveAll();
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_CMapByteStringToPtr::RemoveAll()
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    IFX_Allocator* pAllocator = m_Buffer.m_pAllocator;
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = m_Buffer.GetSize();
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < size; i ++) {
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompactStringRelease(pAllocator, (_CompactString*)m_Buffer.GetAt(i));
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Buffer.RemoveAll();
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_POSITION CFX_CMapByteStringToPtr::GetStartPosition() const
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = m_Buffer.GetSize();
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < size; i ++) {
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(i);
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pKey->m_CompactLen != 0xfe) {
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return (FX_POSITION)(FX_UINTPTR)(i + 1);
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return NULL;
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_CMapByteStringToPtr::GetNextAssoc(FX_POSITION& rNextPosition, CFX_ByteString& rKey, void*& rValue) const
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (rNextPosition == NULL) {
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int index = (int)(FX_UINTPTR)rNextPosition - 1;
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index);
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rKey = _CompactStringGet(pKey);
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rValue = *(void**)(pKey + 1);
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    index ++;
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = m_Buffer.GetSize();
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (index < size) {
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pKey = (_CompactString*)m_Buffer.GetAt(index);
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pKey->m_CompactLen != 0xfe) {
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            rNextPosition = (FX_POSITION)(FX_UINTPTR)(index + 1);
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        index ++;
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rNextPosition = NULL;
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_LPVOID CFX_CMapByteStringToPtr::GetNextValue(FX_POSITION& rNextPosition) const
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (rNextPosition == NULL) {
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int index = (int)(FX_UINTPTR)rNextPosition - 1;
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index);
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPVOID rValue = *(void**)(pKey + 1);
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    index ++;
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = m_Buffer.GetSize();
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (index < size) {
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pKey = (_CompactString*)m_Buffer.GetAt(index);
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pKey->m_CompactLen != 0xfe) {
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            rNextPosition = (FX_POSITION)(FX_UINTPTR)(index + 1);
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return rValue;
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        index ++;
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rNextPosition = NULL;
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return rValue;
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL _CMapLookupCallback(void* param, void* pData)
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return !_CompactStringSame((_CompactString*)pData, ((CFX_ByteStringC*)param)->GetPtr(), ((CFX_ByteStringC*)param)->GetLength());
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_CMapByteStringToPtr::Lookup(FX_BSTR key, void*& rValue) const
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void* p = m_Buffer.Iterate(_CMapLookupCallback, (void*)&key);
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!p) {
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rValue = *(void**)((_CompactString*)p + 1);
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_CMapByteStringToPtr::SetAt(FX_BSTR key, void* value)
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(value != NULL);
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int index, key_len = key.GetLength();
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = m_Buffer.GetSize();
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (index = 0; index < size; index ++) {
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index);
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!_CompactStringSame(pKey, (FX_LPCBYTE)key, key_len)) {
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *(void**)(pKey + 1) = value;
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    IFX_Allocator* pAllocator = m_Buffer.m_pAllocator;
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (index = 0; index < size; index ++) {
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index);
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pKey->m_CompactLen) {
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompactStringStore(pAllocator, pKey, (FX_LPCBYTE)key, key_len);
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *(void**)(pKey + 1) = value;
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompactString* pKey = (_CompactString*)m_Buffer.Add();
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompactStringStore(pAllocator, pKey, (FX_LPCBYTE)key, key_len);
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *(void**)(pKey + 1) = value;
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_CMapByteStringToPtr::AddValue(FX_BSTR key, void* value)
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(value != NULL);
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompactString* pKey = (_CompactString*)m_Buffer.Add();
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _CompactStringStore(m_Buffer.m_pAllocator, pKey, (FX_LPCBYTE)key, key.GetLength());
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *(void**)(pKey + 1) = value;
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_CMapByteStringToPtr::RemoveKey(FX_BSTR key)
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int key_len = key.GetLength();
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    IFX_Allocator* pAllocator = m_Buffer.m_pAllocator;
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = m_Buffer.GetSize();
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int index = 0; index < size; index ++) {
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(index);
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!_CompactStringSame(pKey, (FX_LPCBYTE)key, key_len)) {
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompactStringRelease(pAllocator, pKey);
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pKey->m_CompactLen = 0xfe;
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CFX_CMapByteStringToPtr::GetCount() const
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int count = 0;
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int size = m_Buffer.GetSize();
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < size; i ++) {
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _CompactString* pKey = (_CompactString*)m_Buffer.GetAt(i);
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pKey->m_CompactLen != 0xfe) {
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            count ++;
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return count;
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern "C" {
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static int _CompareDWord(const void* p1, const void* p2)
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return (*(FX_DWORD*)p1) - (*(FX_DWORD*)p2);
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstruct _DWordPair {
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD key;
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD value;
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CFX_CMapDWordToDWord::Lookup(FX_DWORD key, FX_DWORD& value) const
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPVOID pResult = FXSYS_bsearch(&key, m_Buffer.GetBuffer(), m_Buffer.GetSize() / sizeof(_DWordPair),
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      sizeof(_DWordPair), _CompareDWord);
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pResult == NULL) {
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    value = ((FX_DWORD*)pResult)[1];
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_POSITION CFX_CMapDWordToDWord::GetStartPosition() const
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD count = m_Buffer.GetSize() / sizeof(_DWordPair);
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (count == 0) {
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return (FX_POSITION)1;
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_CMapDWordToDWord::GetNextAssoc(FX_POSITION& pos, FX_DWORD& key, FX_DWORD& value) const
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pos == 0) {
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD index = ((FX_DWORD)(FX_UINTPTR)pos) - 1;
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD count = m_Buffer.GetSize() / sizeof(_DWordPair);
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _DWordPair* buf = (_DWordPair*)m_Buffer.GetBuffer();
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    key = buf[index].key;
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    value = buf[index].value;
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (index == count - 1) {
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pos = 0;
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pos = (FX_POSITION)((FX_UINTPTR)pos + 1);
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_CMapDWordToDWord::SetAt(FX_DWORD key, FX_DWORD value)
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD count = m_Buffer.GetSize() / sizeof(_DWordPair);
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _DWordPair* buf = (_DWordPair*)m_Buffer.GetBuffer();
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _DWordPair pair = {key, value};
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (count == 0 || key > buf[count - 1].key) {
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Buffer.AppendBlock(&pair, sizeof(_DWordPair));
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int low = 0, high = count - 1;
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (low <= high) {
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int mid = (low + high) / 2;
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (buf[mid].key < key) {
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            low = mid + 1;
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (buf[mid].key > key) {
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            high = mid - 1;
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            buf[mid].value = value;
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Buffer.InsertBlock(low * sizeof(_DWordPair), &pair, sizeof(_DWordPair));
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CFX_CMapDWordToDWord::EstimateSize(FX_DWORD size, FX_DWORD grow_by)
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Buffer.EstimateSize(size, grow_by);
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
655