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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 } | 152 } |
159 void CFX_MapPtrToPtr::FreeAssoc(CFX_MapPtrToPtr::CAssoc* pAssoc) { | 153 void CFX_MapPtrToPtr::FreeAssoc(CFX_MapPtrToPtr::CAssoc* pAssoc) { |
160 pAssoc->pNext = m_pFreeList; | 154 pAssoc->pNext = m_pFreeList; |
161 m_pFreeList = pAssoc; | 155 m_pFreeList = pAssoc; |
162 m_nCount--; | 156 m_nCount--; |
163 ASSERT(m_nCount >= 0); | 157 ASSERT(m_nCount >= 0); |
164 if (m_nCount == 0) { | 158 if (m_nCount == 0) { |
165 RemoveAll(); | 159 RemoveAll(); |
166 } | 160 } |
167 } | 161 } |
168 CFX_MapByteStringToPtr::CFX_MapByteStringToPtr(int nBlockSize) | |
169 : m_pHashTable(NULL), | |
170 m_nHashTableSize(17), | |
171 m_nCount(0), | |
172 m_pFreeList(NULL), | |
173 m_pBlocks(NULL), | |
174 m_nBlockSize(nBlockSize) { | |
175 ASSERT(m_nBlockSize > 0); | |
176 } | |
177 void CFX_MapByteStringToPtr::RemoveAll() { | |
178 if (m_pHashTable != NULL) { | |
179 for (FX_DWORD nHash = 0; nHash < m_nHashTableSize; nHash++) { | |
180 CAssoc* pAssoc; | |
181 for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; | |
182 pAssoc = pAssoc->pNext) { | |
183 DestructElement(&pAssoc->key); | |
184 } | |
185 } | |
186 FX_Free(m_pHashTable); | |
187 m_pHashTable = NULL; | |
188 } | |
189 m_nCount = 0; | |
190 m_pFreeList = NULL; | |
191 m_pBlocks->FreeDataChain(); | |
192 m_pBlocks = NULL; | |
193 } | |
194 CFX_MapByteStringToPtr::~CFX_MapByteStringToPtr() { | |
195 RemoveAll(); | |
196 ASSERT(m_nCount == 0); | |
197 } | |
198 void CFX_MapByteStringToPtr::GetNextAssoc(FX_POSITION& rNextPosition, | |
199 CFX_ByteString& rKey, | |
200 void*& rValue) const { | |
201 ASSERT(m_pHashTable != NULL); | |
202 CAssoc* pAssocRet = (CAssoc*)rNextPosition; | |
203 ASSERT(pAssocRet != NULL); | |
204 if (pAssocRet == (CAssoc*)-1) { | |
205 for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++) | |
206 if ((pAssocRet = m_pHashTable[nBucket]) != NULL) { | |
207 break; | |
208 } | |
209 ASSERT(pAssocRet != NULL); | |
210 } | |
211 CAssoc* pAssocNext; | |
212 if ((pAssocNext = pAssocRet->pNext) == NULL) { | |
213 for (FX_DWORD nBucket = pAssocRet->nHashValue + 1; | |
214 nBucket < m_nHashTableSize; nBucket++) | |
215 if ((pAssocNext = m_pHashTable[nBucket]) != NULL) { | |
216 break; | |
217 } | |
218 } | |
219 rNextPosition = (FX_POSITION)pAssocNext; | |
220 rKey = pAssocRet->key; | |
221 rValue = pAssocRet->value; | |
222 } | |
223 void* CFX_MapByteStringToPtr::GetNextValue(FX_POSITION& rNextPosition) const { | |
224 ASSERT(m_pHashTable != NULL); | |
225 CAssoc* pAssocRet = (CAssoc*)rNextPosition; | |
226 ASSERT(pAssocRet != NULL); | |
227 if (pAssocRet == (CAssoc*)-1) { | |
228 for (FX_DWORD nBucket = 0; nBucket < m_nHashTableSize; nBucket++) | |
229 if ((pAssocRet = m_pHashTable[nBucket]) != NULL) { | |
230 break; | |
231 } | |
232 ASSERT(pAssocRet != NULL); | |
233 } | |
234 CAssoc* pAssocNext; | |
235 if ((pAssocNext = pAssocRet->pNext) == NULL) { | |
236 for (FX_DWORD nBucket = pAssocRet->nHashValue + 1; | |
237 nBucket < m_nHashTableSize; nBucket++) | |
238 if ((pAssocNext = m_pHashTable[nBucket]) != NULL) { | |
239 break; | |
240 } | |
241 } | |
242 rNextPosition = (FX_POSITION)pAssocNext; | |
243 return pAssocRet->value; | |
244 } | |
245 void*& CFX_MapByteStringToPtr::operator[](const CFX_ByteStringC& key) { | |
246 FX_DWORD nHash; | |
247 CAssoc* pAssoc; | |
248 if ((pAssoc = GetAssocAt(key, nHash)) == NULL) { | |
249 if (m_pHashTable == NULL) { | |
250 InitHashTable(m_nHashTableSize); | |
251 } | |
252 pAssoc = NewAssoc(); | |
253 pAssoc->nHashValue = nHash; | |
254 pAssoc->key = key; | |
255 pAssoc->pNext = m_pHashTable[nHash]; | |
256 m_pHashTable[nHash] = pAssoc; | |
257 } | |
258 return pAssoc->value; | |
259 } | |
260 CFX_MapByteStringToPtr::CAssoc* CFX_MapByteStringToPtr::NewAssoc() { | |
261 if (m_pFreeList == NULL) { | |
262 CFX_Plex* newBlock = CFX_Plex::Create( | |
263 m_pBlocks, m_nBlockSize, sizeof(CFX_MapByteStringToPtr::CAssoc)); | |
264 CFX_MapByteStringToPtr::CAssoc* pAssoc = | |
265 (CFX_MapByteStringToPtr::CAssoc*)newBlock->data(); | |
266 pAssoc += m_nBlockSize - 1; | |
267 for (int i = m_nBlockSize - 1; i >= 0; i--, pAssoc--) { | |
268 pAssoc->pNext = m_pFreeList; | |
269 m_pFreeList = pAssoc; | |
270 } | |
271 } | |
272 ASSERT(m_pFreeList != NULL); | |
273 CFX_MapByteStringToPtr::CAssoc* pAssoc = m_pFreeList; | |
274 m_pFreeList = m_pFreeList->pNext; | |
275 m_nCount++; | |
276 ASSERT(m_nCount > 0); | |
277 ConstructElement(&pAssoc->key); | |
278 pAssoc->value = 0; | |
279 return pAssoc; | |
280 } | |
281 void CFX_MapByteStringToPtr::FreeAssoc(CFX_MapByteStringToPtr::CAssoc* pAssoc) { | |
282 DestructElement(&pAssoc->key); | |
283 pAssoc->pNext = m_pFreeList; | |
284 m_pFreeList = pAssoc; | |
285 m_nCount--; | |
286 ASSERT(m_nCount >= 0); | |
287 if (m_nCount == 0) { | |
288 RemoveAll(); | |
289 } | |
290 } | |
291 CFX_MapByteStringToPtr::CAssoc* CFX_MapByteStringToPtr::GetAssocAt( | |
292 const CFX_ByteStringC& key, | |
293 FX_DWORD& nHash) const { | |
294 nHash = HashKey(key) % m_nHashTableSize; | |
295 if (m_pHashTable == NULL) { | |
296 return NULL; | |
297 } | |
298 CAssoc* pAssoc; | |
299 for (pAssoc = m_pHashTable[nHash]; pAssoc != NULL; pAssoc = pAssoc->pNext) { | |
300 if (pAssoc->key == key) { | |
301 return pAssoc; | |
302 } | |
303 } | |
304 return NULL; | |
305 } | |
306 FX_BOOL CFX_MapByteStringToPtr::Lookup(const CFX_ByteStringC& key, | |
307 void*& rValue) const { | |
308 FX_DWORD nHash; | |
309 CAssoc* pAssoc = GetAssocAt(key, nHash); | |
310 if (pAssoc == NULL) { | |
311 return FALSE; | |
312 } | |
313 rValue = pAssoc->value; | |
314 return TRUE; | |
315 } | |
316 void CFX_MapByteStringToPtr::InitHashTable(FX_DWORD nHashSize, | |
317 FX_BOOL bAllocNow) { | |
318 ASSERT(m_nCount == 0); | |
319 ASSERT(nHashSize > 0); | |
320 FX_Free(m_pHashTable); | |
321 m_pHashTable = NULL; | |
322 if (bAllocNow) { | |
323 m_pHashTable = FX_Alloc(CAssoc*, nHashSize); | |
324 } | |
325 m_nHashTableSize = nHashSize; | |
326 } | |
327 inline FX_DWORD CFX_MapByteStringToPtr::HashKey( | |
328 const CFX_ByteStringC& key) const { | |
329 FX_DWORD nHash = 0; | |
330 int len = key.GetLength(); | |
331 const uint8_t* buf = key.GetPtr(); | |
332 for (int i = 0; i < len; i++) { | |
333 nHash = (nHash << 5) + nHash + buf[i]; | |
334 } | |
335 return nHash; | |
336 } | |
337 FX_BOOL CFX_MapByteStringToPtr::RemoveKey(const CFX_ByteStringC& key) { | |
338 if (m_pHashTable == NULL) { | |
339 return FALSE; | |
340 } | |
341 CAssoc** ppAssocPrev; | |
342 ppAssocPrev = &m_pHashTable[HashKey(key) % m_nHashTableSize]; | |
343 CAssoc* pAssoc; | |
344 for (pAssoc = *ppAssocPrev; pAssoc != NULL; pAssoc = pAssoc->pNext) { | |
345 if (pAssoc->key == key) { | |
346 *ppAssocPrev = pAssoc->pNext; | |
347 FreeAssoc(pAssoc); | |
348 return TRUE; | |
349 } | |
350 ppAssocPrev = &pAssoc->pNext; | |
351 } | |
352 return FALSE; | |
353 } | |
354 struct _CompactString { | 162 struct _CompactString { |
355 uint8_t m_CompactLen; | 163 uint8_t m_CompactLen; |
356 uint8_t m_LenHigh; | 164 uint8_t m_LenHigh; |
357 uint8_t m_LenLow; | 165 uint8_t m_LenLow; |
358 uint8_t m_Unused; | 166 uint8_t m_Unused; |
359 uint8_t* m_pBuffer; | 167 uint8_t* m_pBuffer; |
360 }; | 168 }; |
361 static void _CompactStringRelease(_CompactString* pCompact) { | 169 static void _CompactStringRelease(_CompactString* pCompact) { |
362 if (pCompact->m_CompactLen == 0xff) { | 170 if (pCompact->m_CompactLen == 0xff) { |
363 FX_Free(pCompact->m_pBuffer); | 171 FX_Free(pCompact->m_pBuffer); |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 } else { | 409 } else { |
602 buf[mid].value = value; | 410 buf[mid].value = value; |
603 return; | 411 return; |
604 } | 412 } |
605 } | 413 } |
606 m_Buffer.InsertBlock(low * sizeof(_DWordPair), &pair, sizeof(_DWordPair)); | 414 m_Buffer.InsertBlock(low * sizeof(_DWordPair), &pair, sizeof(_DWordPair)); |
607 } | 415 } |
608 void CFX_CMapDWordToDWord::EstimateSize(FX_DWORD size, FX_DWORD grow_by) { | 416 void CFX_CMapDWordToDWord::EstimateSize(FX_DWORD size, FX_DWORD grow_by) { |
609 m_Buffer.EstimateSize(size, grow_by); | 417 m_Buffer.EstimateSize(size, grow_by); |
610 } | 418 } |
OLD | NEW |