2022-06-22 23:37:46 -04:00
|
|
|
#include "DgoReader.h"
|
|
|
|
|
2021-01-27 20:46:58 -05:00
|
|
|
#include <cstring>
|
|
|
|
#include <unordered_set>
|
2022-06-22 23:37:46 -04:00
|
|
|
#include <utility>
|
|
|
|
|
2021-01-27 20:46:58 -05:00
|
|
|
#include "BinaryReader.h"
|
2021-12-26 11:43:16 -05:00
|
|
|
#include "BitUtils.h"
|
2021-01-27 20:46:58 -05:00
|
|
|
#include "dgo_util.h"
|
|
|
|
|
2022-06-22 23:37:46 -04:00
|
|
|
#include "common/link_types.h"
|
2024-02-01 13:01:41 -05:00
|
|
|
#include "common/log/log.h"
|
2022-06-22 23:37:46 -04:00
|
|
|
|
|
|
|
#include "third-party/json.hpp"
|
|
|
|
|
2021-01-27 20:46:58 -05:00
|
|
|
DgoReader::DgoReader(std::string file_name, const std::vector<u8>& data)
|
|
|
|
: m_file_name(std::move(file_name)) {
|
|
|
|
BinaryReader reader(data);
|
|
|
|
auto header = reader.read<DgoHeader>();
|
|
|
|
m_internal_name = header.name;
|
|
|
|
std::unordered_set<std::string> all_unique_names;
|
|
|
|
|
|
|
|
// get all obj files...
|
|
|
|
for (uint32_t i = 0; i < header.object_count; i++) {
|
2021-07-24 11:17:27 -04:00
|
|
|
ObjectHeader obj_header = reader.read<ObjectHeader>();
|
|
|
|
|
|
|
|
if (reader.bytes_left() < obj_header.size && i == header.object_count - 1 &&
|
|
|
|
obj_header.size - reader.bytes_left() <= 48) {
|
2024-02-01 13:01:41 -05:00
|
|
|
lg::print(
|
|
|
|
"Warning: final file {} in DGO {} has a size missing {} bytes. It will be adjusted from "
|
|
|
|
"{} to {} bytes.\n",
|
2021-07-24 11:17:27 -04:00
|
|
|
obj_header.name, header.name, obj_header.size - reader.bytes_left(), obj_header.size,
|
|
|
|
(int)reader.bytes_left());
|
|
|
|
obj_header.size = reader.bytes_left();
|
|
|
|
}
|
2022-02-08 19:02:47 -05:00
|
|
|
ASSERT(reader.bytes_left() >= obj_header.size);
|
2021-01-27 20:46:58 -05:00
|
|
|
assert_string_empty_after(obj_header.name, 60);
|
|
|
|
|
|
|
|
DgoDataEntry entry;
|
|
|
|
entry.internal_name = obj_header.name;
|
2021-03-06 16:06:08 -05:00
|
|
|
|
2021-01-27 20:46:58 -05:00
|
|
|
entry.unique_name = get_object_file_name(entry.internal_name, reader.here(), obj_header.size);
|
2021-03-06 16:06:08 -05:00
|
|
|
if (all_unique_names.find(entry.unique_name) != all_unique_names.end()) {
|
2024-02-01 13:01:41 -05:00
|
|
|
lg::print("Warning: there are multiple files named {}\n", entry.unique_name.c_str());
|
2021-03-06 16:06:08 -05:00
|
|
|
entry.unique_name += '-';
|
|
|
|
entry.unique_name += std::to_string(obj_header.size);
|
|
|
|
}
|
|
|
|
|
2021-01-27 20:46:58 -05:00
|
|
|
all_unique_names.insert(entry.unique_name);
|
|
|
|
entry.data.resize(obj_header.size);
|
|
|
|
|
2022-02-08 19:02:47 -05:00
|
|
|
ASSERT((reader.get_seek() % 16) == 0);
|
2021-01-27 20:46:58 -05:00
|
|
|
memcpy(entry.data.data(), reader.here(), obj_header.size);
|
|
|
|
m_entries.push_back(entry);
|
|
|
|
|
2021-12-26 11:43:16 -05:00
|
|
|
reader.ffwd(align16(obj_header.size));
|
2021-01-27 20:46:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// check we're at the end
|
2022-02-08 19:02:47 -05:00
|
|
|
ASSERT(0 == reader.bytes_left());
|
|
|
|
ASSERT(all_unique_names.size() == m_entries.size());
|
2021-01-27 20:46:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string DgoReader::description_as_json() const {
|
|
|
|
using namespace nlohmann;
|
|
|
|
json j;
|
|
|
|
j["file_name"] = m_file_name;
|
|
|
|
j["internal_name"] = m_internal_name;
|
|
|
|
for (auto& entry : m_entries) {
|
|
|
|
json entry_desc;
|
|
|
|
entry_desc["unique_name"] = entry.unique_name;
|
|
|
|
entry_desc["internal_name"] = entry.internal_name;
|
|
|
|
j["objects"].push_back(entry_desc);
|
|
|
|
}
|
|
|
|
|
|
|
|
return j.dump(4);
|
2021-07-23 18:30:49 -04:00
|
|
|
}
|