Rebuilds the file table, removing all deleted file entries. Used when compacting the archive
| 2728 | // Rebuilds the file table, removing all deleted file entries. |
| 2729 | // Used when compacting the archive |
| 2730 | int RebuildFileTable(TMPQArchive * ha, DWORD dwNewHashTableSize) |
| 2731 | { |
| 2732 | TFileEntry * pFileEntry; |
| 2733 | TMPQHash * pHashTableEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; |
| 2734 | TMPQHash * pOldHashTable = ha->pHashTable; |
| 2735 | TMPQHash * pHashTable = NULL; |
| 2736 | TMPQHash * pHash; |
| 2737 | int nError = ERROR_SUCCESS; |
| 2738 | |
| 2739 | // The new hash table size must be greater or equal to the current hash table size |
| 2740 | assert(dwNewHashTableSize >= ha->pHeader->dwHashTableSize); |
| 2741 | assert(dwNewHashTableSize >= ha->dwMaxFileCount); |
| 2742 | assert((dwNewHashTableSize & (dwNewHashTableSize - 1)) == 0); |
| 2743 | assert(ha->pHashTable != NULL); |
| 2744 | |
| 2745 | // Reallocate the new file table, if needed |
| 2746 | if(dwNewHashTableSize > ha->dwFileTableSize) |
| 2747 | { |
| 2748 | ha->pFileTable = STORM_REALLOC(TFileEntry, ha->pFileTable, dwNewHashTableSize); |
| 2749 | if(ha->pFileTable == NULL) |
| 2750 | return ERROR_NOT_ENOUGH_MEMORY; |
| 2751 | |
| 2752 | memset(ha->pFileTable + ha->dwFileTableSize, 0, (dwNewHashTableSize - ha->dwFileTableSize) * sizeof(TFileEntry)); |
| 2753 | } |
| 2754 | |
| 2755 | // Allocate new hash table |
| 2756 | if(nError == ERROR_SUCCESS) |
| 2757 | { |
| 2758 | pHashTable = STORM_ALLOC(TMPQHash, dwNewHashTableSize); |
| 2759 | if(pHashTable == NULL) |
| 2760 | nError = ERROR_NOT_ENOUGH_MEMORY; |
| 2761 | } |
| 2762 | |
| 2763 | // If both succeeded, we need to rebuild the file table |
| 2764 | if(nError == ERROR_SUCCESS) |
| 2765 | { |
| 2766 | // Make sure that the hash table is properly filled |
| 2767 | memset(pHashTable, 0xFF, sizeof(TMPQHash) * dwNewHashTableSize); |
| 2768 | ha->pHashTable = pHashTable; |
| 2769 | |
| 2770 | // Set the new limits to the MPQ archive |
| 2771 | ha->pHeader->dwHashTableSize = dwNewHashTableSize; |
| 2772 | |
| 2773 | // Parse the old hash table and copy all entries to the new table |
| 2774 | for(pHash = pOldHashTable; pHash < pHashTableEnd; pHash++) |
| 2775 | { |
| 2776 | if(IsValidHashEntry(ha, pHash)) |
| 2777 | { |
| 2778 | pFileEntry = ha->pFileTable + MPQ_BLOCK_INDEX(pHash); |
| 2779 | AllocateHashEntry(ha, pFileEntry, pHash->lcLocale); |
| 2780 | } |
| 2781 | } |
| 2782 | |
| 2783 | // Increment the max file count for the file |
| 2784 | ha->dwFileTableSize = dwNewHashTableSize; |
| 2785 | ha->dwMaxFileCount = dwNewHashTableSize; |
| 2786 | ha->dwFlags |= MPQ_FLAG_CHANGED; |
| 2787 | } |
nothing calls this directly
no test coverage detected