mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-05-17 07:21:43 +00:00
chore: enable reading of big endian ipaks
This commit is contained in:
@@ -2,8 +2,10 @@
|
||||
|
||||
#include "IPakStreamManager.h"
|
||||
#include "ObjContainer/IPak/IPakTypes.h"
|
||||
#include "Utils/Endianness.h"
|
||||
#include "Utils/Logging/Log.h"
|
||||
|
||||
#include <concepts>
|
||||
#include <filesystem>
|
||||
#include <format>
|
||||
#include <iostream>
|
||||
@@ -37,9 +39,10 @@ namespace
|
||||
: m_path(std::move(path)),
|
||||
m_stream(std::move(stream)),
|
||||
m_initialized(false),
|
||||
m_little_endian(true),
|
||||
m_index_section(nullptr),
|
||||
m_data_section(nullptr),
|
||||
m_stream_manager(*m_stream)
|
||||
m_stream_manager(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -65,7 +68,7 @@ namespace
|
||||
{
|
||||
if (entry.key.combinedKey == wantedKey.combinedKey)
|
||||
{
|
||||
return m_stream_manager.OpenStream(static_cast<int64_t>(m_data_section->offset) + entry.offset, entry.size);
|
||||
return m_stream_manager->OpenStream(static_cast<int64_t>(m_data_section->offset) + entry.offset, entry.size);
|
||||
}
|
||||
else if (entry.key.combinedKey > wantedKey.combinedKey)
|
||||
{
|
||||
@@ -102,7 +105,11 @@ namespace
|
||||
return false;
|
||||
}
|
||||
|
||||
m_index_entries.push_back(indexEntry);
|
||||
SwapBytesIfNecessary(indexEntry.key.combinedKey);
|
||||
SwapBytesIfNecessary(indexEntry.offset);
|
||||
SwapBytesIfNecessary(indexEntry.size);
|
||||
|
||||
m_index_entries.emplace_back(indexEntry);
|
||||
}
|
||||
|
||||
std::ranges::sort(m_index_entries,
|
||||
@@ -125,6 +132,11 @@ namespace
|
||||
return false;
|
||||
}
|
||||
|
||||
SwapBytesIfNecessary(section.type);
|
||||
SwapBytesIfNecessary(section.offset);
|
||||
SwapBytesIfNecessary(section.size);
|
||||
SwapBytesIfNecessary(section.itemCount);
|
||||
|
||||
switch (section.type)
|
||||
{
|
||||
case ipak_consts::IPAK_INDEX_SECTION:
|
||||
@@ -153,18 +165,31 @@ namespace
|
||||
return false;
|
||||
}
|
||||
|
||||
if (header.magic != ipak_consts::IPAK_MAGIC)
|
||||
if (header.magic == ipak_consts::IPAK_MAGIC_LITTLE_ENDIAN)
|
||||
{
|
||||
m_little_endian = true;
|
||||
m_stream_manager = IPakStreamManager::Create(*m_stream, true);
|
||||
}
|
||||
else if (header.magic == ipak_consts::IPAK_MAGIC_BIG_ENDIAN)
|
||||
{
|
||||
m_little_endian = false;
|
||||
m_stream_manager = IPakStreamManager::Create(*m_stream, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
con::error("Invalid ipak magic '{:#x}'.", header.magic);
|
||||
return false;
|
||||
}
|
||||
|
||||
SwapBytesIfNecessary(header.version);
|
||||
if (header.version != ipak_consts::IPAK_VERSION)
|
||||
{
|
||||
con::error("Unsupported ipak version '{}'.", header.version);
|
||||
return false;
|
||||
}
|
||||
|
||||
SwapBytesIfNecessary(header.size);
|
||||
SwapBytesIfNecessary(header.sectionCount);
|
||||
for (unsigned section = 0; section < header.sectionCount; section++)
|
||||
{
|
||||
if (!ReadSection())
|
||||
@@ -189,17 +214,26 @@ namespace
|
||||
return true;
|
||||
}
|
||||
|
||||
template<std::integral T> void SwapBytesIfNecessary(T& value)
|
||||
{
|
||||
if (m_little_endian)
|
||||
value = endianness::FromLittleEndian(value);
|
||||
else
|
||||
value = endianness::FromBigEndian(value);
|
||||
}
|
||||
|
||||
std::string m_path;
|
||||
std::unique_ptr<std::istream> m_stream;
|
||||
|
||||
bool m_initialized;
|
||||
bool m_little_endian;
|
||||
|
||||
std::unique_ptr<IPakSection> m_index_section;
|
||||
std::unique_ptr<IPakSection> m_data_section;
|
||||
|
||||
std::vector<IPakIndexEntry> m_index_entries;
|
||||
|
||||
IPakStreamManager m_stream_manager;
|
||||
std::unique_ptr<IPakStreamManager> m_stream_manager;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
||||
Reference in New Issue
Block a user