OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "../../include/fxcrt/fx_basic.h" | 7 #include "../../include/fxcrt/fx_basic.h" |
8 #include "plex.h" | 8 #include "plex.h" |
9 | 9 |
10 static void ConstructElement(CFX_ByteString* pNewData) { | |
11 new (pNewData) CFX_ByteString(); | |
12 } | |
13 static void DestructElement(CFX_ByteString* pOldData) { | |
14 pOldData->~CFX_ByteString(); | |
15 } | |
16 CFX_MapPtrToPtr::CFX_MapPtrToPtr(int nBlockSize) | 10 CFX_MapPtrToPtr::CFX_MapPtrToPtr(int nBlockSize) |
17 : m_pHashTable(NULL), | 11 : m_pHashTable(NULL), |
18 m_nHashTableSize(17), | 12 m_nHashTableSize(17), |
19 m_nCount(0), | 13 m_nCount(0), |
20 m_pFreeList(NULL), | 14 m_pFreeList(NULL), |
21 m_pBlocks(NULL), | 15 m_pBlocks(NULL), |
22 m_nBlockSize(nBlockSize) { | 16 m_nBlockSize(nBlockSize) { |
23 ASSERT(m_nBlockSize > 0); | 17 ASSERT(m_nBlockSize > 0); |
24 } | 18 } |
25 void CFX_MapPtrToPtr::RemoveAll() { | 19 void CFX_MapPtrToPtr::RemoveAll() { |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 } | 156 } |
163 void CFX_MapPtrToPtr::FreeAssoc(CFX_MapPtrToPtr::CAssoc* pAssoc) { | 157 void CFX_MapPtrToPtr::FreeAssoc(CFX_MapPtrToPtr::CAssoc* pAssoc) { |
164 pAssoc->pNext = m_pFreeList; | 158 pAssoc->pNext = m_pFreeList; |
165 m_pFreeList = pAssoc; | 159 m_pFreeList = pAssoc; |
166 m_nCount--; | 160 m_nCount--; |
167 ASSERT(m_nCount >= 0); | 161 ASSERT(m_nCount >= 0); |
168 if (m_nCount == 0) { | 162 if (m_nCount == 0) { |
169 RemoveAll(); | 163 RemoveAll(); |
170 } | 164 } |
171 } | 165 } |
172 CFX_MapByteStringToPtr::CFX_MapByteStringToPtr(int nBlockSize) | |
173 : m_pHashTable(NULL), | |
174 m_nHashTableSize(17), | |
175 m_nCount(0), | |
176 m_pFreeList(NULL), | |
177 m_pBlocks(NULL), | |
178 m_nBlockSize(nBlockSize) { | |
179 ASSERT(m_nBlockSize > 0); | |
180 } | |
181 void CFX_MapByteStringToPtr::RemoveAll() { | |
182 if (m_pHashTable != NULL) { | |
183 for (FX_DWORD nHash = 0; nHash < m_nHashTableSize; nHash++) { | |
184 CAssoc* pAssoc; | |
185 for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; | |
186 pAssoc = pAssoc->pNext) { | |
187 DestructElement(&pAssoc->key); | |
188 } | |
189 } | |
190 FX_Free(m_pHashTable); | |
191 m_pHashTable = NULL; | |
192 } | |
193 m_nCount = 0; | |
194 m_pFreeList = NULL; | |
195 m_pBlocks->FreeDataChain(); | |
196 m_pBlocks = NULL; | |
197 } | |
198 CFX_MapByteStringToPtr::~CFX_MapByteStringToPtr() { | |
199 RemoveAll(); | |
200 ASSERT(m_nCount == 0); | |
201 } | |
202 void CFX_MapByteStringToPtr::GetNextAssoc(FX_POSITION& rNextPosition, | |
203 CFX_ByteString& rKey, | |
204 void*& rValue) const { | |
205 ASSERT(m_pHashTable != NULL); | |
206 CAssoc* pAssocRet = (CAssoc*)rNextPosition; | |
207 ASSERT(pAssocRet != NULL); | |
208 if (pAssocRet == (CAssoc*)-1) { | |
209 for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++) | |
210 if ((pAssocRet = m_pHashTable[nBucket]) != NULL) { | |
211 break; | |
212 } | |
213 ASSERT(pAssocRet != NULL); | |
214 } | |
215 CAssoc* pAssocNext; | |
216 if ((pAssocNext = pAssocRet->pNext) == NULL) { | |
217 for (FX_DWORD nBucket = pAssocRet->nHashValue + 1; | |
218 nBucket < m_nHashTableSize; nBucket++) | |
219 if ((pAssocNext = m_pHashTable[nBucket]) != NULL) { | |
220 break; | |
221 } | |
222 } | |
223 rNextPosition = (FX_POSITION)pAssocNext; | |
224 rKey = pAssocRet->key; | |
225 rValue = pAssocRet->value; | |
226 } | |
227 void* CFX_MapByteStringToPtr::GetNextValue(FX_POSITION& rNextPosition) const { | |
228 ASSERT(m_pHashTable != NULL); | |
229 CAssoc* pAssocRet = (CAssoc*)rNextPosition; | |
230 ASSERT(pAssocRet != NULL); | |
231 if (pAssocRet == (CAssoc*)-1) { | |
232 for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++) | |
233 if ((pAssocRet = m_pHashTable[nBucket]) != NULL) { | |
234 break; | |
235 } | |
236 ASSERT(pAssocRet != NULL); | |
237 } | |
238 CAssoc* pAssocNext; | |
239 if ((pAssocNext = pAssocRet->pNext) == NULL) { | |
240 for (FX_DWORD nBucket = pAssocRet->nHashValue + 1; | |
241 nBucket < m_nHashTableSize; nBucket++) | |
242 if ((pAssocNext = m_pHashTable[nBucket]) != NULL) { | |
243 break; | |
244 } | |
245 } | |
246 rNextPosition = (FX_POSITION)pAssocNext; | |
247 return pAssocRet->value; | |
248 } | |
249 void*& CFX_MapByteStringToPtr::operator[](const CFX_ByteStringC& key) { | |
250 FX_DWORD nHash; | |
251 CAssoc* pAssoc; | |
252 if ((pAssoc = GetAssocAt(key, nHash)) == NULL) { | |
253 if (m_pHashTable == NULL) { | |
254 InitHashTable(m_nHashTableSize); | |
255 } | |
256 pAssoc = NewAssoc(); | |
257 pAssoc->nHashValue = nHash; | |
258 pAssoc->key = key; | |
259 pAssoc->pNext = m_pHashTable[nHash]; | |
260 m_pHashTable[nHash] = pAssoc; | |
261 } | |
262 return pAssoc->value; | |
263 } | |
264 CFX_MapByteStringToPtr::CAssoc* CFX_MapByteStringToPtr::NewAssoc() { | |
265 if (m_pFreeList == NULL) { | |
266 CFX_Plex* newBlock = CFX_Plex::Create( | |
267 m_pBlocks, m_nBlockSize, sizeof(CFX_MapByteStringToPtr::CAssoc)); | |
268 CFX_MapByteStringToPtr::CAssoc* pAssoc = | |
269 (CFX_MapByteStringToPtr::CAssoc*)newBlock->data(); | |
270 pAssoc += m_nBlockSize - 1; | |
271 for (int i = m_nBlockSize - 1; i >= 0; i--, pAssoc--) { | |
272 pAssoc->pNext = m_pFreeList; | |
273 m_pFreeList = pAssoc; | |
274 } | |
275 } | |
276 ASSERT(m_pFreeList != NULL); | |
277 CFX_MapByteStringToPtr::CAssoc* pAssoc = m_pFreeList; | |
278 m_pFreeList = m_pFreeList->pNext; | |
279 m_nCount++; | |
280 ASSERT(m_nCount > 0); | |
281 ConstructElement(&pAssoc->key); | |
282 pAssoc->value = 0; | |
283 return pAssoc; | |
284 } | |
285 void CFX_MapByteStringToPtr::FreeAssoc(CFX_MapByteStringToPtr::CAssoc* pAssoc) { | |
286 DestructElement(&pAssoc->key); | |
287 pAssoc->pNext = m_pFreeList; | |
288 m_pFreeList = pAssoc; | |
289 m_nCount--; | |
290 ASSERT(m_nCount >= 0); | |
291 if (m_nCount == 0) { | |
292 RemoveAll(); | |
293 } | |
294 } | |
295 CFX_MapByteStringToPtr::CAssoc* CFX_MapByteStringToPtr::GetAssocAt( | |
296 const CFX_ByteStringC& key, | |
297 FX_DWORD& nHash) const { | |
298 nHash = HashKey(key) % m_nHashTableSize; | |
299 if (m_pHashTable == NULL) { | |
300 return NULL; | |
301 } | |
302 CAssoc* pAssoc; | |
303 for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; pAssoc = pAssoc->pNext) { | |
304 if (pAssoc->key == key) { | |
305 return pAssoc; | |
306 } | |
307 } | |
308 return NULL; | |
309 } | |
310 FX_BOOL CFX_MapByteStringToPtr::Lookup(const CFX_ByteStringC& key, | |
311 void*& rValue) const { | |
312 FX_DWORD nHash; | |
313 CAssoc* pAssoc = GetAssocAt(key, nHash); | |
314 if (pAssoc == NULL) { | |
315 return FALSE; | |
316 } | |
317 rValue = pAssoc->value; | |
318 return TRUE; | |
319 } | |
320 void CFX_MapByteStringToPtr::InitHashTable(FX_DWORD nHashSize, | |
321 FX_BOOL bAllocNow) { | |
322 ASSERT(m_nCount == 0); | |
323 ASSERT(nHashSize > 0); | |
324 if (m_pHashTable != NULL) { | |
325 FX_Free(m_pHashTable); | |
326 m_pHashTable = NULL; | |
327 } | |
328 if (bAllocNow) { | |
329 m_pHashTable = FX_Alloc(CAssoc*, nHashSize); | |
330 } | |
331 m_nHashTableSize = nHashSize; | |
332 } | |
333 inline FX_DWORD CFX_MapByteStringToPtr::HashKey( | |
334 const CFX_ByteStringC& key) const { | |
335 FX_DWORD nHash = 0; | |
336 int len = key.GetLength(); | |
337 const uint8_t* buf = key.GetPtr(); | |
338 for (int i = 0; i < len; i++) { | |
339 nHash = (nHash << 5) + nHash + buf[i]; | |
340 } | |
341 return nHash; | |
342 } | |
343 FX_BOOL CFX_MapByteStringToPtr::RemoveKey(const CFX_ByteStringC& key) { | |
344 if (m_pHashTable == NULL) { | |
345 return FALSE; | |
346 } | |
347 CAssoc** ppAssocPrev; | |
348 ppAssocPrev = &m_pHashTable[HashKey(key) % m_nHashTableSize]; | |
349 CAssoc* pAssoc; | |
350 for (pAssoc = *ppAssocPrev; pAssoc != NULL; pAssoc = pAssoc->pNext) { | |
351 if (pAssoc->key == key) { | |
352 *ppAssocPrev = pAssoc->pNext; | |
353 FreeAssoc(pAssoc); | |
354 return TRUE; | |
355 } | |
356 ppAssocPrev = &pAssoc->pNext; | |
357 } | |
358 return FALSE; | |
359 } | |
360 struct _CompactString { | 166 struct _CompactString { |
361 uint8_t m_CompactLen; | 167 uint8_t m_CompactLen; |
362 uint8_t m_LenHigh; | 168 uint8_t m_LenHigh; |
363 uint8_t m_LenLow; | 169 uint8_t m_LenLow; |
364 uint8_t m_Unused; | 170 uint8_t m_Unused; |
365 uint8_t* m_pBuffer; | 171 uint8_t* m_pBuffer; |
366 }; | 172 }; |
367 static void _CompactStringRelease(_CompactString* pCompact) { | 173 static void _CompactStringRelease(_CompactString* pCompact) { |
368 if (pCompact->m_CompactLen == 0xff) { | 174 if (pCompact->m_CompactLen == 0xff) { |
369 FX_Free(pCompact->m_pBuffer); | 175 FX_Free(pCompact->m_pBuffer); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
607 } else { | 413 } else { |
608 buf[mid].value = value; | 414 buf[mid].value = value; |
609 return; | 415 return; |
610 } | 416 } |
611 } | 417 } |
612 m_Buffer.InsertBlock(low * sizeof(_DWordPair), &pair, sizeof(_DWordPair)); | 418 m_Buffer.InsertBlock(low * sizeof(_DWordPair), &pair, sizeof(_DWordPair)); |
613 } | 419 } |
614 void CFX_CMapDWordToDWord::EstimateSize(FX_DWORD size, FX_DWORD grow_by) { | 420 void CFX_CMapDWordToDWord::EstimateSize(FX_DWORD size, FX_DWORD grow_by) { |
615 m_Buffer.EstimateSize(size, grow_by); | 421 m_Buffer.EstimateSize(size, grow_by); |
616 } | 422 } |
OLD | NEW |