mirror of
https://github.com/zeldaret/botw
synced 2026-08-08 18:43:11 -04:00
Switch to subrepos
git subrepo clone https://github.com/open-ead/sead lib/sead subrepo: subdir: "lib/sead" merged: "1b66e825d" upstream: origin: "https://github.com/open-ead/sead" branch: "master" commit: "1b66e825d" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo" commit: "2f68596" git subrepo clone (merge) https://github.com/open-ead/nnheaders lib/NintendoSDK subrepo: subdir: "lib/NintendoSDK" merged: "9ee21399f" upstream: origin: "https://github.com/open-ead/nnheaders" branch: "master" commit: "9ee21399f" git-subrepo: version: "0.4.3" origin: "ssh://git@github.com/ingydotnet/git-subrepo" commit: "2f68596" git subrepo clone https://github.com/open-ead/agl lib/agl subrepo: subdir: "lib/agl" merged: "7c063271b" upstream: origin: "https://github.com/open-ead/agl" branch: "master" commit: "7c063271b" git-subrepo: version: "0.4.3" origin: "ssh://git@github.com/ingydotnet/git-subrepo" commit: "2f68596" git subrepo clone https://github.com/open-ead/EventFlow lib/EventFlow subrepo: subdir: "lib/EventFlow" merged: "c35d21b34" upstream: origin: "https://github.com/open-ead/EventFlow" branch: "master" commit: "c35d21b34" git-subrepo: version: "0.4.3" origin: "ssh://git@github.com/ingydotnet/git-subrepo" commit: "2f68596"
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
#pragma once
|
||||
|
||||
#include <ore/StringView.h>
|
||||
#include <ore/Types.h>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace ore {
|
||||
|
||||
template <typename T>
|
||||
constexpr T AlignUpToPowerOf2(T val, int base) {
|
||||
return val + base - 1 & static_cast<unsigned int>(-base);
|
||||
}
|
||||
|
||||
struct RelocationTable;
|
||||
|
||||
struct BinaryBlockHeader {
|
||||
BinaryBlockHeader* FindNextBlock(int type);
|
||||
const BinaryBlockHeader* FindNextBlock(int type) const;
|
||||
BinaryBlockHeader* GetNextBlock();
|
||||
const BinaryBlockHeader* GetNextBlock() const;
|
||||
void SetNextBlock(BinaryBlockHeader* block);
|
||||
|
||||
u32 magic;
|
||||
int next_block_offset;
|
||||
};
|
||||
|
||||
struct BinaryFileHeader {
|
||||
bool IsValid(s64 magic_, int ver_major_, int ver_minor_, int ver_patch_, int ver_sub_) const;
|
||||
bool IsSignatureValid(s64 magic_) const;
|
||||
bool IsVersionValid(int major, int minor, int patch, int sub) const;
|
||||
bool IsEndianReverse() const;
|
||||
bool IsEndianValid() const;
|
||||
|
||||
bool IsAlignmentValid() const;
|
||||
int GetAlignment() const;
|
||||
void SetAlignment(int alignment_);
|
||||
|
||||
bool IsRelocated() const;
|
||||
void SetRelocated(bool relocated);
|
||||
|
||||
void SetByteOrderMark();
|
||||
|
||||
int GetFileSize() const;
|
||||
void SetFileSize(int size);
|
||||
|
||||
StringView GetFileName() const;
|
||||
void SetFileName(const StringView& name);
|
||||
|
||||
RelocationTable* GetRelocationTable();
|
||||
void SetRelocationTable(RelocationTable* table);
|
||||
|
||||
BinaryBlockHeader* GetFirstBlock();
|
||||
const BinaryBlockHeader* GetFirstBlock() const;
|
||||
void SetFirstBlock(BinaryBlockHeader* block);
|
||||
|
||||
BinaryBlockHeader* FindFirstBlock(int type);
|
||||
const BinaryBlockHeader* FindFirstBlock(int type) const;
|
||||
|
||||
u64 magic;
|
||||
u8 ver_major;
|
||||
u8 ver_minor;
|
||||
u8 ver_patch;
|
||||
u8 ver_sub;
|
||||
s16 bom;
|
||||
u8 alignment;
|
||||
u8 _f;
|
||||
int file_name_offset;
|
||||
u16 relocation_flags;
|
||||
u16 first_block_offset;
|
||||
int relocation_table_offset;
|
||||
int file_size;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct BinTString {
|
||||
// Make it impossible to accidentally construct a (partial, broken) copy.
|
||||
BinTString(const BinTString&) = delete;
|
||||
auto operator=(const BinTString&) = delete;
|
||||
|
||||
T* data() { return chars; }
|
||||
const T* data() const { return chars; }
|
||||
|
||||
T& operator[](size_t idx) { return data()[idx]; }
|
||||
const T& operator[](size_t idx) const { return data()[idx]; }
|
||||
|
||||
auto begin() { return data(); }
|
||||
auto begin() const { return data(); }
|
||||
|
||||
auto end() { return data() + length; }
|
||||
auto end() const { return data() + length; }
|
||||
|
||||
bool empty() const { return length == 0; }
|
||||
|
||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
operator TStringView<T>() const { return {data(), length}; }
|
||||
|
||||
BinTString* NextString() { return const_cast<BinTString*>(std::as_const(*this).NextString()); }
|
||||
|
||||
const BinTString* NextString() const {
|
||||
// XXX: this shouldn't have to be a separate case.
|
||||
if constexpr (std::is_same_v<T, wchar_t>) {
|
||||
const auto offset = ((2 + (4 * (length + 1) - 1)) & -4) + 2;
|
||||
return reinterpret_cast<const BinTString*>(reinterpret_cast<const char*>(this) +
|
||||
offset);
|
||||
|
||||
} else {
|
||||
// + 1 for the null terminator
|
||||
const auto offset = offsetof(BinTString, chars) + sizeof(T) * (length + 1);
|
||||
return reinterpret_cast<const BinTString*>(
|
||||
reinterpret_cast<const char*>(this) +
|
||||
AlignUpToPowerOf2(offset, alignof(BinTString)));
|
||||
}
|
||||
}
|
||||
|
||||
u16 length;
|
||||
T chars[1];
|
||||
};
|
||||
|
||||
using BinString = BinTString<char>;
|
||||
using BinWString = BinTString<wchar_t>;
|
||||
|
||||
template <typename T>
|
||||
struct BinTPtr {
|
||||
void Clear() { offset_or_ptr = 0; }
|
||||
void Set(T* ptr) { offset_or_ptr = reinterpret_cast<u64>(ptr); }
|
||||
|
||||
// Only use this after relocation.
|
||||
T* Get() { return reinterpret_cast<T*>(offset_or_ptr); }
|
||||
const T* Get() const { return reinterpret_cast<const T*>(offset_or_ptr); }
|
||||
|
||||
void SetOffset(void* base, void* ptr) {
|
||||
offset_or_ptr = static_cast<int>(ptr ? uintptr_t(ptr) - uintptr_t(base) : 0);
|
||||
}
|
||||
|
||||
u64 GetOffset() const { return offset_or_ptr; }
|
||||
|
||||
T* ToPtr(void* base) const {
|
||||
const auto offset = static_cast<int>(offset_or_ptr);
|
||||
if (offset == 0)
|
||||
return nullptr;
|
||||
return reinterpret_cast<T*>(reinterpret_cast<char*>(base) + offset);
|
||||
}
|
||||
|
||||
void Relocate(void* base) { Set(ToPtr(base)); }
|
||||
void Unrelocate(void* base) { SetOffset(base, Get()); }
|
||||
|
||||
u64 offset_or_ptr;
|
||||
};
|
||||
|
||||
static_assert(sizeof(u64) >= sizeof(void*));
|
||||
|
||||
} // namespace ore
|
||||
Reference in New Issue
Block a user