summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Lioncash2020-09-15 09:06:43 -0400
committerGravatar Lioncash2020-09-15 09:06:46 -0400
commit99b372a6c5c6d42e1c2e36e710e191901973f449 (patch)
treea45928d4706a8447077e568490c0ee022f006707
parentMerge pull request #4655 from lioncash/internal2 (diff)
downloadyuzu-99b372a6c5c6d42e1c2e36e710e191901973f449.tar.gz
yuzu-99b372a6c5c6d42e1c2e36e710e191901973f449.tar.xz
yuzu-99b372a6c5c6d42e1c2e36e710e191901973f449.zip
nca_patch: Make SearchBucketEntry() internally linked
This is only used internally and doesn't depend on any class state, so we can make it fully internal.
-rw-r--r--src/core/file_sys/nca_patch.cpp83
-rw-r--r--src/core/file_sys/nca_patch.h4
2 files changed, 43 insertions, 44 deletions
diff --git a/src/core/file_sys/nca_patch.cpp b/src/core/file_sys/nca_patch.cpp
index fe7375e84..fd7b69e11 100644
--- a/src/core/file_sys/nca_patch.cpp
+++ b/src/core/file_sys/nca_patch.cpp
@@ -12,6 +12,49 @@
12#include "core/file_sys/nca_patch.h" 12#include "core/file_sys/nca_patch.h"
13 13
14namespace FileSys { 14namespace FileSys {
15namespace {
16template <bool Subsection, typename BlockType, typename BucketType>
17std::pair<std::size_t, std::size_t> SearchBucketEntry(u64 offset, BlockType block,
18 BucketType buckets) {
19 if constexpr (Subsection) {
20 const auto last_bucket = buckets[block.number_buckets - 1];
21 if (offset >= last_bucket.entries[last_bucket.number_entries].address_patch) {
22 return {block.number_buckets - 1, last_bucket.number_entries};
23 }
24 } else {
25 ASSERT_MSG(offset <= block.size, "Offset is out of bounds in BKTR relocation block.");
26 }
27
28 std::size_t bucket_id = std::count_if(
29 block.base_offsets.begin() + 1, block.base_offsets.begin() + block.number_buckets,
30 [&offset](u64 base_offset) { return base_offset <= offset; });
31
32 const auto bucket = buckets[bucket_id];
33
34 if (bucket.number_entries == 1) {
35 return {bucket_id, 0};
36 }
37
38 std::size_t low = 0;
39 std::size_t mid = 0;
40 std::size_t high = bucket.number_entries - 1;
41 while (low <= high) {
42 mid = (low + high) / 2;
43 if (bucket.entries[mid].address_patch > offset) {
44 high = mid - 1;
45 } else {
46 if (mid == bucket.number_entries - 1 ||
47 bucket.entries[mid + 1].address_patch > offset) {
48 return {bucket_id, mid};
49 }
50
51 low = mid + 1;
52 }
53 }
54
55 UNREACHABLE_MSG("Offset could not be found in BKTR block.");
56}
57} // Anonymous namespace
15 58
16BKTR::BKTR(VirtualFile base_romfs_, VirtualFile bktr_romfs_, RelocationBlock relocation_, 59BKTR::BKTR(VirtualFile base_romfs_, VirtualFile bktr_romfs_, RelocationBlock relocation_,
17 std::vector<RelocationBucket> relocation_buckets_, SubsectionBlock subsection_, 60 std::vector<RelocationBucket> relocation_buckets_, SubsectionBlock subsection_,
@@ -110,46 +153,6 @@ std::size_t BKTR::Read(u8* data, std::size_t length, std::size_t offset) const {
110 return raw_read; 153 return raw_read;
111} 154}
112 155
113template <bool Subsection, typename BlockType, typename BucketType>
114std::pair<std::size_t, std::size_t> BKTR::SearchBucketEntry(u64 offset, BlockType block,
115 BucketType buckets) const {
116 if constexpr (Subsection) {
117 const auto last_bucket = buckets[block.number_buckets - 1];
118 if (offset >= last_bucket.entries[last_bucket.number_entries].address_patch)
119 return {block.number_buckets - 1, last_bucket.number_entries};
120 } else {
121 ASSERT_MSG(offset <= block.size, "Offset is out of bounds in BKTR relocation block.");
122 }
123
124 std::size_t bucket_id = std::count_if(
125 block.base_offsets.begin() + 1, block.base_offsets.begin() + block.number_buckets,
126 [&offset](u64 base_offset) { return base_offset <= offset; });
127
128 const auto bucket = buckets[bucket_id];
129
130 if (bucket.number_entries == 1)
131 return {bucket_id, 0};
132
133 std::size_t low = 0;
134 std::size_t mid = 0;
135 std::size_t high = bucket.number_entries - 1;
136 while (low <= high) {
137 mid = (low + high) / 2;
138 if (bucket.entries[mid].address_patch > offset) {
139 high = mid - 1;
140 } else {
141 if (mid == bucket.number_entries - 1 ||
142 bucket.entries[mid + 1].address_patch > offset) {
143 return {bucket_id, mid};
144 }
145
146 low = mid + 1;
147 }
148 }
149
150 UNREACHABLE_MSG("Offset could not be found in BKTR block.");
151}
152
153RelocationEntry BKTR::GetRelocationEntry(u64 offset) const { 156RelocationEntry BKTR::GetRelocationEntry(u64 offset) const {
154 const auto res = SearchBucketEntry<false>(offset, relocation, relocation_buckets); 157 const auto res = SearchBucketEntry<false>(offset, relocation, relocation_buckets);
155 return relocation_buckets[res.first].entries[res.second]; 158 return relocation_buckets[res.first].entries[res.second];
diff --git a/src/core/file_sys/nca_patch.h b/src/core/file_sys/nca_patch.h
index 8e64e8378..60c544f8e 100644
--- a/src/core/file_sys/nca_patch.h
+++ b/src/core/file_sys/nca_patch.h
@@ -117,10 +117,6 @@ public:
117 bool Rename(std::string_view name) override; 117 bool Rename(std::string_view name) override;
118 118
119private: 119private:
120 template <bool Subsection, typename BlockType, typename BucketType>
121 std::pair<std::size_t, std::size_t> SearchBucketEntry(u64 offset, BlockType block,
122 BucketType buckets) const;
123
124 RelocationEntry GetRelocationEntry(u64 offset) const; 120 RelocationEntry GetRelocationEntry(u64 offset) const;
125 RelocationEntry GetNextRelocationEntry(u64 offset) const; 121 RelocationEntry GetNextRelocationEntry(u64 offset) const;
126 122