Attempts to search a free hash entry, or an entry whose names and locale matches
| 637 | |
| 638 | // Attempts to search a free hash entry, or an entry whose names and locale matches |
| 639 | TMPQHash * FindFreeHashEntry(TMPQArchive * ha, DWORD dwStartIndex, DWORD dwName1, DWORD dwName2, LCID lcLocale) |
| 640 | { |
| 641 | TMPQHash * pDeletedEntry = NULL; // If a deleted entry was found in the continuous hash range |
| 642 | TMPQHash * pFreeEntry = NULL; // If a free entry was found in the continuous hash range |
| 643 | DWORD dwHashIndexMask = HASH_INDEX_MASK(ha); |
| 644 | DWORD dwIndex; |
| 645 | |
| 646 | // Set the initial index |
| 647 | dwStartIndex = dwIndex = (dwStartIndex & dwHashIndexMask); |
| 648 | |
| 649 | // Search the hash table and return the found entries in the following priority: |
| 650 | // 1) <MATCHING_ENTRY> |
| 651 | // 2) <DELETED-ENTRY> |
| 652 | // 3) <FREE-ENTRY> |
| 653 | // 4) NULL |
| 654 | for(;;) |
| 655 | { |
| 656 | TMPQHash * pHash = ha->pHashTable + dwIndex; |
| 657 | |
| 658 | // If we found a matching entry, return that one |
| 659 | if(pHash->dwName1 == dwName1 && pHash->dwName2 == dwName2 && pHash->lcLocale == lcLocale) |
| 660 | return pHash; |
| 661 | |
| 662 | // If we found a deleted entry, remember it but keep searching |
| 663 | if(pHash->dwBlockIndex == HASH_ENTRY_DELETED && pDeletedEntry == NULL) |
| 664 | pDeletedEntry = pHash; |
| 665 | |
| 666 | // If we found a free entry, we need to stop searching |
| 667 | if(pHash->dwBlockIndex == HASH_ENTRY_FREE) |
| 668 | { |
| 669 | pFreeEntry = pHash; |
| 670 | break; |
| 671 | } |
| 672 | |
| 673 | // Move to the next hash entry. |
| 674 | // If we reached the starting entry, it's failure. |
| 675 | dwIndex = (dwIndex + 1) & dwHashIndexMask; |
| 676 | if(dwIndex == dwStartIndex) |
| 677 | break; |
| 678 | } |
| 679 | |
| 680 | // If we found a deleted entry, return that one preferentially |
| 681 | return (pDeletedEntry != NULL) ? pDeletedEntry : pFreeEntry; |
| 682 | } |
| 683 | |
| 684 | // Retrieves the first hash entry for the given file. |
| 685 | // Every locale version of a file has its own hash entry |