move all_start_offsets to CommonFileFormats
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <phosg/Encoding.hh>
|
#include <phosg/Encoding.hh>
|
||||||
|
#include <phosg/Strings.hh>
|
||||||
#include <phosg/Vector.hh>
|
#include <phosg/Vector.hh>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include "Text.hh"
|
#include "Text.hh"
|
||||||
|
|
||||||
@@ -160,3 +162,23 @@ struct RELFileFooterT {
|
|||||||
} __packed_ws_be__(RELFileFooterT, 0x20);
|
} __packed_ws_be__(RELFileFooterT, 0x20);
|
||||||
using RELFileFooter = RELFileFooterT<false>;
|
using RELFileFooter = RELFileFooterT<false>;
|
||||||
using RELFileFooterBE = RELFileFooterT<true>;
|
using RELFileFooterBE = RELFileFooterT<true>;
|
||||||
|
|
||||||
|
template <bool BE>
|
||||||
|
std::set<uint32_t> all_relocation_offsets_for_rel_file(const void* data, size_t size) {
|
||||||
|
phosg::StringReader r(data, size);
|
||||||
|
|
||||||
|
std::set<uint32_t> ret;
|
||||||
|
ret.emplace(r.size() - 0x20); // REL footer
|
||||||
|
ret.emplace(r.pget<U32T<BE>>(r.size() - 0x10)); // root
|
||||||
|
ret.emplace(r.pget<U32T<BE>>(r.size() - 0x20)); // relocations
|
||||||
|
|
||||||
|
const auto& footer = r.pget<RELFileFooterT<BE>>(r.size() - sizeof(RELFileFooterT<BE>));
|
||||||
|
auto sub_r = r.sub(footer.relocations_offset, footer.num_relocations * sizeof(U16T<BE>));
|
||||||
|
uint32_t offset = 0;
|
||||||
|
while (!sub_r.eof()) {
|
||||||
|
offset += sub_r.template get<U16T<BE>>() * 4;
|
||||||
|
ret.emplace(r.pget<U32T<BE>>(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2902,21 +2902,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
const std::set<uint32_t>& all_start_offsets() const {
|
const std::set<uint32_t>& all_start_offsets() const {
|
||||||
if (!this->start_offsets.has_value()) {
|
if (this->start_offsets.empty()) {
|
||||||
auto& ret = this->start_offsets.emplace();
|
this->start_offsets = all_relocation_offsets_for_rel_file<BE>(r.pgetv(0, r.size()), r.size());
|
||||||
ret.emplace(r.size() - 0x20); // REL footer
|
|
||||||
ret.emplace(BE ? r.pget_u32b(r.size() - 0x10) : r.pget_u32l(r.size() - 0x10)); // root
|
|
||||||
ret.emplace(BE ? r.pget_u32b(r.size() - 0x20) : r.pget_u32l(r.size() - 0x20)); // relocations
|
|
||||||
|
|
||||||
const auto& footer = r.pget<RELFileFooterT<BE>>(r.size() - sizeof(RELFileFooterT<BE>));
|
|
||||||
auto sub_r = r.sub(footer.relocations_offset, footer.num_relocations * sizeof(U16T<BE>));
|
|
||||||
uint32_t offset = 0;
|
|
||||||
while (!sub_r.eof()) {
|
|
||||||
offset += sub_r.template get<U16T<BE>>() * 4;
|
|
||||||
ret.emplace(r.pget<U32T<BE>>(offset));
|
|
||||||
}
|
}
|
||||||
}
|
return this->start_offsets;
|
||||||
return *this->start_offsets;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t get_data_range_size(size_t start_offset) const {
|
size_t get_data_range_size(size_t start_offset) const {
|
||||||
@@ -3270,7 +3259,7 @@ protected:
|
|||||||
phosg::StringReader r;
|
phosg::StringReader r;
|
||||||
const RootT* root;
|
const RootT* root;
|
||||||
|
|
||||||
mutable std::optional<std::set<uint32_t>> start_offsets;
|
mutable std::set<uint32_t> start_offsets;
|
||||||
|
|
||||||
mutable std::unordered_map<uint16_t, Weapon> weapons;
|
mutable std::unordered_map<uint16_t, Weapon> weapons;
|
||||||
mutable std::vector<ArmorOrShield> armors;
|
mutable std::vector<ArmorOrShield> armors;
|
||||||
|
|||||||
Reference in New Issue
Block a user