forked from ShuriZma/suyu
common/hex_util: Combine HexVectorToString() and HexArrayToString()
These can be generified together by using a concept type to designate them. This also has the benefit of not making copies of potentially very large arrays.
This commit is contained in:
parent
7e2bcf04b4
commit
a62088539e
|
@ -30,13 +30,6 @@ std::vector<u8> HexStringToVector(std::string_view str, bool little_endian) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HexVectorToString(const std::vector<u8>& vector, bool upper) {
|
|
||||||
std::string out;
|
|
||||||
for (u8 c : vector)
|
|
||||||
out += fmt::format(upper ? "{:02X}" : "{:02x}", c);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::array<u8, 16> operator""_array16(const char* str, std::size_t len) {
|
std::array<u8, 16> operator""_array16(const char* str, std::size_t len) {
|
||||||
if (len != 32) {
|
if (len != 32) {
|
||||||
LOG_ERROR(Common,
|
LOG_ERROR(Common,
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -30,13 +31,15 @@ std::array<u8, Size> HexStringToArray(std::string_view str) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string HexVectorToString(const std::vector<u8>& vector, bool upper = true);
|
template <typename ContiguousContainer>
|
||||||
|
std::string HexToString(const ContiguousContainer& data, bool upper = true) {
|
||||||
|
static_assert(std::is_same_v<typename ContiguousContainer::value_type, u8>,
|
||||||
|
"Underlying type within the contiguous container must be u8.");
|
||||||
|
|
||||||
template <std::size_t Size>
|
|
||||||
std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) {
|
|
||||||
std::string out;
|
std::string out;
|
||||||
for (u8 c : array)
|
for (const u8 c : data) {
|
||||||
out += fmt::format(upper ? "{:02X}" : "{:02x}", c);
|
out += fmt::format(upper ? "{:02X}" : "{:02x}", c);
|
||||||
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -572,7 +572,7 @@ void KeyManager::WriteKeyToFile(KeyCategory category, std::string_view keyname,
|
||||||
<< "# If you are experiencing issues involving keys, it may help to delete this file\n";
|
<< "# If you are experiencing issues involving keys, it may help to delete this file\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
file << fmt::format("\n{} = {}", keyname, Common::HexArrayToString(key));
|
file << fmt::format("\n{} = {}", keyname, Common::HexToString(key));
|
||||||
AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, filename, category == KeyCategory::Title);
|
AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, filename, category == KeyCategory::Title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,7 +583,7 @@ void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) {
|
||||||
Key128 rights_id;
|
Key128 rights_id;
|
||||||
std::memcpy(rights_id.data(), &field2, sizeof(u64));
|
std::memcpy(rights_id.data(), &field2, sizeof(u64));
|
||||||
std::memcpy(rights_id.data() + sizeof(u64), &field1, sizeof(u64));
|
std::memcpy(rights_id.data() + sizeof(u64), &field1, sizeof(u64));
|
||||||
WriteKeyToFile(KeyCategory::Title, Common::HexArrayToString(rights_id), key);
|
WriteKeyToFile(KeyCategory::Title, Common::HexToString(rights_id), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto category = KeyCategory::Standard;
|
auto category = KeyCategory::Standard;
|
||||||
|
|
|
@ -295,7 +295,7 @@ void IPSwitchCompiler::Parse() {
|
||||||
LOG_INFO(Loader,
|
LOG_INFO(Loader,
|
||||||
"[IPSwitchCompiler ('{}')] - Patching value at offset 0x{:08X} "
|
"[IPSwitchCompiler ('{}')] - Patching value at offset 0x{:08X} "
|
||||||
"with byte string '{}'",
|
"with byte string '{}'",
|
||||||
patch_text->GetName(), offset, Common::HexVectorToString(replace));
|
patch_text->GetName(), offset, Common::HexToString(replace));
|
||||||
}
|
}
|
||||||
|
|
||||||
patch.records.insert_or_assign(offset, std::move(replace));
|
patch.records.insert_or_assign(offset, std::move(replace));
|
||||||
|
|
|
@ -142,7 +142,7 @@ std::vector<VirtualFile> PatchManager::CollectPatches(const std::vector<VirtualD
|
||||||
if (!compiler.IsValid())
|
if (!compiler.IsValid())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto this_build_id = Common::HexArrayToString(compiler.GetBuildID());
|
auto this_build_id = Common::HexToString(compiler.GetBuildID());
|
||||||
this_build_id =
|
this_build_id =
|
||||||
this_build_id.substr(0, this_build_id.find_last_not_of('0') + 1);
|
this_build_id.substr(0, this_build_id.find_last_not_of('0') + 1);
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ std::vector<u8> PatchManager::PatchNSO(const std::vector<u8>& nso, const std::st
|
||||||
return nso;
|
return nso;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto build_id_raw = Common::HexArrayToString(header.build_id);
|
const auto build_id_raw = Common::HexToString(header.build_id);
|
||||||
const auto build_id = build_id_raw.substr(0, build_id_raw.find_last_not_of('0') + 1);
|
const auto build_id = build_id_raw.substr(0, build_id_raw.find_last_not_of('0') + 1);
|
||||||
|
|
||||||
if (Settings::values.dump_nso) {
|
if (Settings::values.dump_nso) {
|
||||||
|
@ -219,7 +219,7 @@ std::vector<u8> PatchManager::PatchNSO(const std::vector<u8>& nso, const std::st
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PatchManager::HasNSOPatch(const std::array<u8, 32>& build_id_) const {
|
bool PatchManager::HasNSOPatch(const std::array<u8, 32>& build_id_) const {
|
||||||
const auto build_id_raw = Common::HexArrayToString(build_id_);
|
const auto build_id_raw = Common::HexToString(build_id_);
|
||||||
const auto build_id = build_id_raw.substr(0, build_id_raw.find_last_not_of('0') + 1);
|
const auto build_id = build_id_raw.substr(0, build_id_raw.find_last_not_of('0') + 1);
|
||||||
|
|
||||||
LOG_INFO(Loader, "Querying NSO patch existence for build_id={}", build_id);
|
LOG_INFO(Loader, "Querying NSO patch existence for build_id={}", build_id);
|
||||||
|
@ -235,7 +235,7 @@ bool PatchManager::HasNSOPatch(const std::array<u8, 32>& build_id_) const {
|
||||||
static std::optional<CheatList> ReadCheatFileFromFolder(const Core::System& system, u64 title_id,
|
static std::optional<CheatList> ReadCheatFileFromFolder(const Core::System& system, u64 title_id,
|
||||||
const std::array<u8, 0x20>& build_id_,
|
const std::array<u8, 0x20>& build_id_,
|
||||||
const VirtualDir& base_path, bool upper) {
|
const VirtualDir& base_path, bool upper) {
|
||||||
const auto build_id_raw = Common::HexArrayToString(build_id_, upper);
|
const auto build_id_raw = Common::HexToString(build_id_, upper);
|
||||||
const auto build_id = build_id_raw.substr(0, sizeof(u64) * 2);
|
const auto build_id = build_id_raw.substr(0, sizeof(u64) * 2);
|
||||||
const auto file = base_path->GetFile(fmt::format("{}.txt", build_id));
|
const auto file = base_path->GetFile(fmt::format("{}.txt", build_id));
|
||||||
|
|
||||||
|
|
|
@ -53,13 +53,14 @@ static bool FollowsNcaIdFormat(std::string_view name) {
|
||||||
|
|
||||||
static std::string GetRelativePathFromNcaID(const std::array<u8, 16>& nca_id, bool second_hex_upper,
|
static std::string GetRelativePathFromNcaID(const std::array<u8, 16>& nca_id, bool second_hex_upper,
|
||||||
bool within_two_digit) {
|
bool within_two_digit) {
|
||||||
if (!within_two_digit)
|
if (!within_two_digit) {
|
||||||
return fmt::format("/{}.nca", Common::HexArrayToString(nca_id, second_hex_upper));
|
return fmt::format("/{}.nca", Common::HexToString(nca_id, second_hex_upper));
|
||||||
|
}
|
||||||
|
|
||||||
Core::Crypto::SHA256Hash hash{};
|
Core::Crypto::SHA256Hash hash{};
|
||||||
mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0);
|
mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0);
|
||||||
return fmt::format("/000000{:02X}/{}.nca", hash[0],
|
return fmt::format("/000000{:02X}/{}.nca", hash[0],
|
||||||
Common::HexArrayToString(nca_id, second_hex_upper));
|
Common::HexToString(nca_id, second_hex_upper));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetCNMTName(TitleType type, u64 title_id) {
|
static std::string GetCNMTName(TitleType type, u64 title_id) {
|
||||||
|
@ -376,10 +377,11 @@ std::vector<ContentProviderEntry> RegisteredCache::ListEntriesFilter(
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<NCA> GetNCAFromNSPForID(const NSP& nsp, const NcaID& id) {
|
static std::shared_ptr<NCA> GetNCAFromNSPForID(const NSP& nsp, const NcaID& id) {
|
||||||
const auto file = nsp.GetFile(fmt::format("{}.nca", Common::HexArrayToString(id, false)));
|
auto file = nsp.GetFile(fmt::format("{}.nca", Common::HexToString(id, false)));
|
||||||
if (file == nullptr)
|
if (file == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return std::make_shared<NCA>(file);
|
}
|
||||||
|
return std::make_shared<NCA>(std::move(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
InstallResult RegisteredCache::InstallEntry(const XCI& xci, bool overwrite_if_exists,
|
InstallResult RegisteredCache::InstallEntry(const XCI& xci, bool overwrite_if_exists,
|
||||||
|
|
|
@ -235,16 +235,18 @@ void NSP::ReadNCAs(const std::vector<VirtualFile>& files) {
|
||||||
const auto section0 = nca->GetSubdirectories()[0];
|
const auto section0 = nca->GetSubdirectories()[0];
|
||||||
|
|
||||||
for (const auto& inner_file : section0->GetFiles()) {
|
for (const auto& inner_file : section0->GetFiles()) {
|
||||||
if (inner_file->GetExtension() != "cnmt")
|
if (inner_file->GetExtension() != "cnmt") {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
const CNMT cnmt(inner_file);
|
const CNMT cnmt(inner_file);
|
||||||
auto& ncas_title = ncas[cnmt.GetTitleID()];
|
auto& ncas_title = ncas[cnmt.GetTitleID()];
|
||||||
|
|
||||||
ncas_title[{cnmt.GetType(), ContentRecordType::Meta}] = nca;
|
ncas_title[{cnmt.GetType(), ContentRecordType::Meta}] = nca;
|
||||||
for (const auto& rec : cnmt.GetContentRecords()) {
|
for (const auto& rec : cnmt.GetContentRecords()) {
|
||||||
const auto id_string = Common::HexArrayToString(rec.nca_id, false);
|
const auto id_string = Common::HexToString(rec.nca_id, false);
|
||||||
const auto next_file = pfs->GetFile(fmt::format("{}.nca", id_string));
|
auto next_file = pfs->GetFile(fmt::format("{}.nca", id_string));
|
||||||
|
|
||||||
if (next_file == nullptr) {
|
if (next_file == nullptr) {
|
||||||
LOG_WARNING(Service_FS,
|
LOG_WARNING(Service_FS,
|
||||||
"NCA with ID {}.nca is listed in content metadata, but cannot "
|
"NCA with ID {}.nca is listed in content metadata, but cannot "
|
||||||
|
@ -253,9 +255,10 @@ void NSP::ReadNCAs(const std::vector<VirtualFile>& files) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto next_nca = std::make_shared<NCA>(next_file, nullptr, 0, keys);
|
auto next_nca = std::make_shared<NCA>(std::move(next_file), nullptr, 0, keys);
|
||||||
if (next_nca->GetType() == NCAContentType::Program)
|
if (next_nca->GetType() == NCAContentType::Program) {
|
||||||
program_status[cnmt.GetTitleID()] = next_nca->GetStatus();
|
program_status[cnmt.GetTitleID()] = next_nca->GetStatus();
|
||||||
|
}
|
||||||
if (next_nca->GetStatus() == Loader::ResultStatus::Success ||
|
if (next_nca->GetStatus() == Loader::ResultStatus::Success ||
|
||||||
(next_nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS &&
|
(next_nca->GetStatus() == Loader::ResultStatus::ErrorMissingBKTRBaseRomFS &&
|
||||||
(cnmt.GetTitleID() & 0x800) != 0)) {
|
(cnmt.GetTitleID() & 0x800) != 0)) {
|
||||||
|
|
|
@ -66,7 +66,7 @@ NAX::NAX(VirtualFile file_, std::array<u8, 0x10> nca_id)
|
||||||
Core::Crypto::SHA256Hash hash{};
|
Core::Crypto::SHA256Hash hash{};
|
||||||
mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0);
|
mbedtls_sha256(nca_id.data(), nca_id.size(), hash.data(), 0);
|
||||||
status = Parse(fmt::format("/registered/000000{:02X}/{}.nca", hash[0],
|
status = Parse(fmt::format("/registered/000000{:02X}/{}.nca", hash[0],
|
||||||
Common::HexArrayToString(nca_id, false)));
|
Common::HexToString(nca_id, false)));
|
||||||
}
|
}
|
||||||
|
|
||||||
NAX::~NAX() = default;
|
NAX::~NAX() = default;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <string>
|
#include <string_view>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/hex_util.h"
|
#include "common/hex_util.h"
|
||||||
|
@ -16,21 +16,21 @@
|
||||||
|
|
||||||
namespace Service::AM::Applets {
|
namespace Service::AM::Applets {
|
||||||
|
|
||||||
static void LogCurrentStorage(AppletDataBroker& broker, std::string prefix) {
|
static void LogCurrentStorage(AppletDataBroker& broker, std::string_view prefix) {
|
||||||
std::unique_ptr<IStorage> storage = broker.PopNormalDataToApplet();
|
std::unique_ptr<IStorage> storage = broker.PopNormalDataToApplet();
|
||||||
for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) {
|
for (; storage != nullptr; storage = broker.PopNormalDataToApplet()) {
|
||||||
const auto data = storage->GetData();
|
const auto data = storage->GetData();
|
||||||
LOG_INFO(Service_AM,
|
LOG_INFO(Service_AM,
|
||||||
"called (STUBBED), during {} recieved normal data with size={:08X}, data={}",
|
"called (STUBBED), during {} received normal data with size={:08X}, data={}",
|
||||||
prefix, data.size(), Common::HexVectorToString(data));
|
prefix, data.size(), Common::HexToString(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
storage = broker.PopInteractiveDataToApplet();
|
storage = broker.PopInteractiveDataToApplet();
|
||||||
for (; storage != nullptr; storage = broker.PopInteractiveDataToApplet()) {
|
for (; storage != nullptr; storage = broker.PopInteractiveDataToApplet()) {
|
||||||
const auto data = storage->GetData();
|
const auto data = storage->GetData();
|
||||||
LOG_INFO(Service_AM,
|
LOG_INFO(Service_AM,
|
||||||
"called (STUBBED), during {} recieved interactive data with size={:08X}, data={}",
|
"called (STUBBED), during {} received interactive data with size={:08X}, data={}",
|
||||||
prefix, data.size(), Common::HexVectorToString(data));
|
prefix, data.size(), Common::HexToString(data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -310,7 +310,7 @@ public:
|
||||||
if (!IsValidNROHash(hash)) {
|
if (!IsValidNROHash(hash)) {
|
||||||
LOG_ERROR(Service_LDR,
|
LOG_ERROR(Service_LDR,
|
||||||
"NRO hash is not present in any currently loaded NRRs (hash={})!",
|
"NRO hash is not present in any currently loaded NRRs (hash={})!",
|
||||||
Common::HexArrayToString(hash));
|
Common::HexToString(hash));
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ERROR_MISSING_NRR_HASH);
|
rb.Push(ERROR_MISSING_NRR_HASH);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -152,8 +152,8 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process,
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
const auto cheats = pm->CreateCheatList(system, nso_header.build_id);
|
const auto cheats = pm->CreateCheatList(system, nso_header.build_id);
|
||||||
if (!cheats.empty()) {
|
if (!cheats.empty()) {
|
||||||
system.RegisterCheatList(cheats, Common::HexArrayToString(nso_header.build_id),
|
system.RegisterCheatList(cheats, Common::HexToString(nso_header.build_id), load_base,
|
||||||
load_base, load_base + program_image.size());
|
load_base + program_image.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue