From c65f975a4d21f7ab35e18ff62385fa0ac8e3602c Mon Sep 17 00:00:00 2001 From: moonshadow565 Date: Thu, 20 Oct 2022 23:26:44 +0200 Subject: [PATCH] .load files --- CMakeLists.txt | 1 + lib/rlib/ar.cpp | 1 + lib/rlib/ar.hpp | 3 +++ lib/rlib/ar_load.cpp | 64 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 lib/rlib/ar_load.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d7daef..0d7e083 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ add_library(rlib STATIC lib/rlib/ar.cpp lib/rlib/ar_fsb.cpp lib/rlib/ar_fsb5.cpp + lib/rlib/ar_load.cpp lib/rlib/ar_mac.cpp lib/rlib/ar_pe.cpp lib/rlib/ar_wad.cpp diff --git a/lib/rlib/ar.cpp b/lib/rlib/ar.cpp index c360820..63ead48 100644 --- a/lib/rlib/ar.cpp +++ b/lib/rlib/ar.cpp @@ -6,6 +6,7 @@ auto Ar::PROCESSORS() noexcept -> std::span { static constexpr Processor const instance[] = { {"fsb", &Ar::process_try_fsb}, {"fsb5", &Ar::process_try_fsb5}, + {"load", &Ar::process_try_load}, {"mac_exe", &Ar::process_try_mac_exe}, {"mac_fat", &Ar::process_try_mac_fat}, {"pe", &Ar::process_try_pe}, diff --git a/lib/rlib/ar.hpp b/lib/rlib/ar.hpp index e6518e7..9d6f5bd 100644 --- a/lib/rlib/ar.hpp +++ b/lib/rlib/ar.hpp @@ -42,6 +42,7 @@ namespace rlib { struct FSB; struct FSB5; struct MAC; + struct Load; struct PE; struct WAD; struct WPK; @@ -53,6 +54,8 @@ namespace rlib { auto process_try_fsb5(IO const& io, offset_cb cb, Entry const& top_entry) const -> bool; + auto process_try_load(IO const& io, offset_cb cb, Entry const& top_entry) const -> bool; + auto process_try_mac_exe(IO const& io, offset_cb cb, Entry const& top_entry) const -> bool; auto process_try_mac_fat(IO const& io, offset_cb cb, Entry const& top_entry) const -> bool; diff --git a/lib/rlib/ar_load.cpp b/lib/rlib/ar_load.cpp new file mode 100644 index 0000000..15ae373 --- /dev/null +++ b/lib/rlib/ar_load.cpp @@ -0,0 +1,64 @@ +#include "ar.hpp" +using namespace rlib; + +struct Ar::Load { + struct Header; + struct Desc; + + static inline auto constexpr MAGIC = std::array{'r', '3', 'd', '2', 'l', 'o', 'a', 'd'}; +}; + +struct Ar::Load::Header { + std::array magic; + std::uint32_t version; + std::uint32_t size; + std::uint32_t off_abs_data; + std::uint32_t off_abs_toc; + std::uint32_t file_count; + std::uint32_t off_rel_toc; +}; + +struct Ar::Load::Desc { + char type[4]; + std::uint32_t hash; + std::uint32_t maybe_size; + std::uint32_t maybe_size2; + std::uint32_t maybe_zero; + std::uint32_t off_abs_data; + std::uint32_t off_abs_name; + std::uint32_t size_name; + std::uint32_t off_rel_data; + std::uint32_t off_rel_name; +}; + +auto Ar::process_try_load(IO const &io, offset_cb cb, Entry const &top_entry) const -> bool { + auto reader = IO::Reader(io, top_entry.offset, top_entry.size); + + auto header = Load::Header{}; + if (!reader.read(header) || header.magic != Load::MAGIC) { + return false; + } + rlib_assert(reader.seek(header.off_abs_toc)); + + auto toc = std::vector(); + rlib_assert(reader.read_n(toc, header.file_count)); + + auto entries = std::vector(header.file_count); + for (auto i = std::size_t{}; i != header.file_count; ++i) { + auto const &desc = toc[i]; + rlib_ar_assert(desc.maybe_zero == 0); + rlib_ar_assert(desc.off_abs_data); + rlib_ar_assert(desc.maybe_size == desc.maybe_size2); + rlib_ar_assert(reader.contains(desc.off_abs_data, desc.maybe_size)); + rlib_ar_assert(reader.contains(desc.off_abs_name, desc.size_name)); + entries[i] = { + .offset = top_entry.offset + desc.off_abs_data, + .size = desc.maybe_size, + .nest = true, + }; + } + + rlib_ar_assert(this->process_iter(io, cb, top_entry, std::move(entries))); + + return true; +} \ No newline at end of file