| 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 |