Skip to content

Commit 875005e

Browse files
committed
feat: Offset2ID
1 parent 5796b8a commit 875005e

3 files changed

Lines changed: 97 additions & 6 deletions

File tree

include/REL/IDDB.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ namespace REL
2929
V5 = 5
3030
};
3131

32+
struct MAPPING
33+
{
34+
std::uint64_t id;
35+
std::uint64_t offset;
36+
};
37+
3238
IDDB();
3339

3440
std::uint64_t offset(std::uint64_t a_id) const;
@@ -38,17 +44,18 @@ namespace REL
3844
class HEADER_V2;
3945
class HEADER_V5;
4046

41-
struct MAPPING
42-
{
43-
std::uint64_t id;
44-
std::uint64_t offset;
45-
};
46-
4747
void load_v0();
4848
void load_v2(STREAM& a_stream);
4949
void load_v5(STREAM& a_stream);
5050
void unpack_file(STREAM& a_stream, const HEADER_V2& a_header);
5151

52+
protected:
53+
// clang-format off
54+
template <class T> std::span<T> get_id2offset() const noexcept;
55+
template <> std::span<MAPPING> get_id2offset() const noexcept { return m_v0; }
56+
template <> std::span<std::uint32_t> get_id2offset() const noexcept { return m_v5; }
57+
// clang-format on
58+
5259
private:
5360
std::filesystem::path m_path;
5461
Loader m_loader{ Loader::None };

include/REL/Offset2ID.h

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#pragma once
2+
3+
#include "REX/BASE.h"
4+
5+
#include "REL/IDDB.h"
6+
7+
namespace REL
8+
{
9+
template <class T>
10+
class Offset2ID
11+
{
12+
public:
13+
using value_type = T;
14+
using container_type = std::vector<value_type>;
15+
using size_type = typename container_type::size_type;
16+
using const_iterator = typename container_type::const_iterator;
17+
using const_reverse_iterator = typename container_type::const_reverse_iterator;
18+
19+
template <class ExecutionPolicy>
20+
explicit Offset2ID(ExecutionPolicy&& a_policy) // NOLINT(bugprone-forwarding-reference-overload)
21+
requires(std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>)
22+
{
23+
const auto iddb = IDDB::GetSingleton();
24+
const auto id2offset = iddb->get_id2offset<T>();
25+
_offset2id.reserve(id2offset.size());
26+
_offset2id.insert(_offset2id.begin(), id2offset.begin(), id2offset.end());
27+
std::sort(a_policy, _offset2id.begin(), _offset2id.end(), [](auto&& a_lhs, auto&& a_rhs) {
28+
return a_lhs.offset < a_rhs.offset;
29+
});
30+
}
31+
32+
Offset2ID() :
33+
Offset2ID(std::execution::sequenced_policy{})
34+
{}
35+
36+
[[nodiscard]] std::uint64_t operator()(std::size_t a_offset) const
37+
{
38+
if (_offset2id.empty()) {
39+
REX::FAIL("No Address Library has been loaded!");
40+
}
41+
42+
const value_type elem{ 0, a_offset };
43+
const auto it = std::lower_bound(
44+
_offset2id.begin(),
45+
_offset2id.end(),
46+
elem,
47+
[](auto&& a_lhs, auto&& a_rhs) {
48+
return a_lhs.offset < a_rhs.offset;
49+
});
50+
if (it == _offset2id.end()) {
51+
const auto mod = Module::GetSingleton();
52+
const auto version = mod->version();
53+
REX::FAIL(
54+
"Failed to find Address Library ID for offset!\n"
55+
"Invalid offset: 0x{:08X}\n"
56+
"Game Version: {}",
57+
a_offset, version.string());
58+
}
59+
60+
return it->id;
61+
}
62+
63+
[[nodiscard]] const_iterator begin() const noexcept { return _offset2id.begin(); }
64+
[[nodiscard]] const_iterator cbegin() const noexcept { return _offset2id.cbegin(); }
65+
66+
[[nodiscard]] const_iterator end() const noexcept { return _offset2id.end(); }
67+
[[nodiscard]] const_iterator cend() const noexcept { return _offset2id.cend(); }
68+
69+
[[nodiscard]] const_reverse_iterator rbegin() const noexcept { return _offset2id.rbegin(); }
70+
[[nodiscard]] const_reverse_iterator crbegin() const noexcept { return _offset2id.crbegin(); }
71+
72+
[[nodiscard]] const_reverse_iterator rend() const noexcept { return _offset2id.rend(); }
73+
[[nodiscard]] const_reverse_iterator crend() const noexcept { return _offset2id.crend(); }
74+
75+
[[nodiscard]] size_type size() const noexcept { return _offset2id.size(); }
76+
77+
protected:
78+
friend class IDDB;
79+
80+
private:
81+
container_type _offset2id;
82+
};
83+
}

include/REL/REL.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "REL/IDDB.h"
1010
#include "REL/Module.h"
1111
#include "REL/Offset.h"
12+
#include "REL/Offset2ID.h"
1213
#include "REL/Pattern.h"
1314
#include "REL/Relocation.h"
1415
#include "REL/Segment.h"

0 commit comments

Comments
 (0)