Defragment the file table so it does not contain any gaps
| 2603 | #ifdef FULL |
| 2604 | // Defragment the file table so it does not contain any gaps |
| 2605 | int DefragmentFileTable(TMPQArchive * ha) |
| 2606 | { |
| 2607 | TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; |
| 2608 | TFileEntry * pSource = ha->pFileTable; |
| 2609 | TFileEntry * pTarget = ha->pFileTable; |
| 2610 | LPDWORD DefragmentTable; |
| 2611 | DWORD dwBlockTableSize = 0; |
| 2612 | DWORD dwSrcIndex; |
| 2613 | DWORD dwTrgIndex; |
| 2614 | |
| 2615 | // Allocate brand new file table |
| 2616 | DefragmentTable = STORM_ALLOC(DWORD, ha->dwFileTableSize); |
| 2617 | if(DefragmentTable != NULL) |
| 2618 | { |
| 2619 | // Clear the file table |
| 2620 | memset(DefragmentTable, 0xFF, sizeof(DWORD) * ha->dwFileTableSize); |
| 2621 | |
| 2622 | // Parse the entire file table and defragment it |
| 2623 | for(; pSource < pFileTableEnd; pSource++) |
| 2624 | { |
| 2625 | // If the source table entry is valid, |
| 2626 | if(pSource->dwFlags & MPQ_FILE_EXISTS) |
| 2627 | { |
| 2628 | // Remember the index conversion |
| 2629 | dwSrcIndex = (DWORD)(pSource - ha->pFileTable); |
| 2630 | dwTrgIndex = (DWORD)(pTarget - ha->pFileTable); |
| 2631 | DefragmentTable[dwSrcIndex] = dwTrgIndex; |
| 2632 | |
| 2633 | // Move the entry, if needed |
| 2634 | if(pTarget != pSource) |
| 2635 | pTarget[0] = pSource[0]; |
| 2636 | pTarget++; |
| 2637 | |
| 2638 | // Update the block table size |
| 2639 | dwBlockTableSize = (DWORD)(pTarget - ha->pFileTable); |
| 2640 | } |
| 2641 | else |
| 2642 | { |
| 2643 | // If there is file name left, free it |
| 2644 | if(pSource->szFileName != NULL) |
| 2645 | STORM_FREE(pSource->szFileName); |
| 2646 | pSource->szFileName = NULL; |
| 2647 | } |
| 2648 | } |
| 2649 | |
| 2650 | // Did we defragment something? |
| 2651 | if(pTarget < pFileTableEnd) |
| 2652 | { |
| 2653 | // Clear the remaining file entries |
| 2654 | memset(pTarget, 0, (pFileTableEnd - pTarget) * sizeof(TFileEntry)); |
| 2655 | |
| 2656 | // Go through the hash table and relocate the block indexes |
| 2657 | if(ha->pHashTable != NULL) |
| 2658 | { |
| 2659 | TMPQHash * pHashTableEnd = ha->pHashTable + ha->pHeader->dwHashTableSize; |
| 2660 | TMPQHash * pHash; |
| 2661 | DWORD dwNewBlockIndex; |
| 2662 |