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:
Lioncash 2019-06-12 17:27:06 -04:00
parent 7e2bcf04b4
commit a62088539e
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7
11 changed files with 40 additions and 39 deletions

View File

@ -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,

View File

@ -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;
} }

View File

@ -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;

View File

@ -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));

View File

@ -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));

View File

@ -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,

View File

@ -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)) {

View File

@ -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;

View File

@ -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));
} }
} }

View File

@ -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;

View File

@ -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());
} }
} }