| 89 | } |
| 90 | |
| 91 | static void CreateEntryMap(ZipProviderContext* archive) |
| 92 | { |
| 93 | dmZip::HZip zip = archive->m_Zip; |
| 94 | uint32_t archive_entry_count = dmZip::GetNumEntries(zip); |
| 95 | |
| 96 | dmHashTable64<EntryInfo> temp_archive_map; |
| 97 | temp_archive_map.SetCapacity(dmMath::Max(1U, (archive_entry_count * 2) / 3), archive_entry_count); |
| 98 | |
| 99 | // Iterate over archive once and collect all the info about files |
| 100 | for (uint32_t i = 0; i < archive_entry_count; ++i) |
| 101 | { |
| 102 | dmZip::Result zr = dmZip::OpenEntry(zip, i); |
| 103 | if (dmZip::RESULT_OK != zr) |
| 104 | { |
| 105 | dmLogError("Failed to list entry in zip file %s%s", archive->m_BaseUri.m_Location, archive->m_BaseUri.m_Path); |
| 106 | continue; |
| 107 | } |
| 108 | |
| 109 | const char* name = dmZip::GetEntryName(zip); |
| 110 | |
| 111 | char archive_path[dmResource::RESOURCE_PATH_MAX]; |
| 112 | dmSnPrintf(archive_path, sizeof(archive_path), "%s%s", name[0] != '/' ? "/" : "", name); |
| 113 | dmhash_t archive_path_hash = dmHashBufferNoReverse64(archive_path, strlen(archive_path)); |
| 114 | |
| 115 | EntryInfo info; |
| 116 | info.m_ManifestEntry = 0; |
| 117 | dmZip::GetEntrySize(zip, &info.m_Size); |
| 118 | dmZip::GetEntryIndex(zip, &info.m_EntryIndex); |
| 119 | |
| 120 | dmZip::CloseEntry(zip); |
| 121 | |
| 122 | temp_archive_map.Put(archive_path_hash, info); |
| 123 | } |
| 124 | |
| 125 | dmLiveUpdateDDF::HashAlgorithm algorithm = archive->m_Manifest->m_DDFData->m_Header.m_ResourceHashAlgorithm; |
| 126 | uint32_t hash_len = dmResource::HashLength(algorithm); |
| 127 | |
| 128 | uint32_t manifest_entry_count = archive->m_Manifest->m_DDFData->m_Resources.m_Count; |
| 129 | |
| 130 | dmHashTable64<EntryInfo>* entry_map = &archive->m_EntryMap; |
| 131 | uint32_t map_size = archive_entry_count + manifest_entry_count; |
| 132 | entry_map->SetCapacity(dmMath::Max(1U, (map_size*2)/3), map_size); |
| 133 | |
| 134 | // Iterate over manifest entries. Different entries may refer to the same file in archive. |
| 135 | for (uint32_t i = 0; i < manifest_entry_count; ++i) |
| 136 | { |
| 137 | dmLiveUpdateDDF::ResourceEntry* entry = &archive->m_Manifest->m_DDFData->m_Resources.m_Data[i]; |
| 138 | char name_buffer[dmResourceArchive::MAX_HASH*2+1]; |
| 139 | dmResource::BytesToHexString(entry->m_Hash.m_Data.m_Data, hash_len, name_buffer, sizeof(name_buffer)); |
| 140 | char archive_path_buffer[dmResourceArchive::MAX_HASH*2+1]; |
| 141 | dmSnPrintf(archive_path_buffer, dmResourceArchive::MAX_HASH*2, "%s%s", name_buffer[0] != '/' ? "/" : "", name_buffer); |
| 142 | archive_path_buffer[dmResourceArchive::MAX_HASH*2] = 0; |
| 143 | dmhash_t archive_path_hash = dmHashBufferNoReverse64(archive_path_buffer, strlen(archive_path_buffer)); |
| 144 | EntryInfo* info = temp_archive_map.Get(archive_path_hash); |
| 145 | if (!info) |
| 146 | { |
| 147 | // There is no such file in this archive |
| 148 | continue; |
no test coverage detected