From 1e9afdc289b339e1428091b6314fe4c42bf274e4 Mon Sep 17 00:00:00 2001 From: Eladash Date: Sat, 17 Jul 2021 11:36:27 +0300 Subject: [PATCH] Formatting Library: Implement byte arrays formatting --- Utilities/StrFmt.cpp | 31 +++++++++++++++++++++++++ Utilities/StrFmt.h | 32 +++++++++++++++++++++++++- rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp | 16 +------------ 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/Utilities/StrFmt.cpp b/Utilities/StrFmt.cpp index 8297e7ef38..0b1fae4f0e 100644 --- a/Utilities/StrFmt.cpp +++ b/Utilities/StrFmt.cpp @@ -173,6 +173,37 @@ void fmt_class_string>::format(std::string& out, u64 arg) out.append(obj.cbegin(), obj.cend()); } +void format_byte_array(std::string& out, const uchar* data, usz size) +{ + if (!size) + { + out += "{ EMPTY }"; + return; + } + + out += "{ "; + + for (usz i = 0;; i++) + { + if (i == size - 1) + { + fmt::append(out, "%02X", data[i]); + break; + } + + if (i % 4) + { + // Place a comma each 4 bytes for ease of byte placement finding + fmt::append(out, "%02X ", data[i]); + continue; + } + + fmt::append(out, "%02X, ", data[i]); + } + + out += " }"; +} + template <> void fmt_class_string::format(std::string& out, u64 arg) { diff --git a/Utilities/StrFmt.h b/Utilities/StrFmt.h index d78ecd7468..f25616d42f 100644 --- a/Utilities/StrFmt.h +++ b/Utilities/StrFmt.h @@ -86,7 +86,13 @@ struct fmt_unveil } }; -template +namespace fmt +{ + template + concept CharT = (std::is_same_v || std::is_same_v); +} + +template struct fmt_unveil { using type = std::add_const_t*; @@ -215,6 +221,30 @@ struct fmt_class_string : fmt_class_string { }; +namespace fmt +{ + // Both uchar and std::byte are allowed + template + concept ByteArray = requires (T& t) { static_cast, std::byte, uchar>&>(std::data(t)[0]); }; +} + +template +struct fmt_class_string +{ + static FORCE_INLINE SAFE_BUFFERS(const T&) get_object(u64 arg) + { + return *reinterpret_cast(static_cast(arg)); + } + + static void format(std::string& out, u64 arg) + { + const auto& obj = get_object(arg); + + void format_byte_array(std::string&, const uchar*, usz); + format_byte_array(out, reinterpret_cast(std::data(obj)), std::size(obj)); + } +}; + struct fmt_type_info { decltype(&fmt_class_string::format) fmt_string; diff --git a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp index 87bcf54b93..9c3e1b15d6 100644 --- a/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp @@ -160,21 +160,7 @@ void fmt_class_string::format(std::string& out, u64 { const auto& sign = get_object(arg); - // Format as a C byte array for ease of use - fmt::append(out, "{ "); - - for (usz i = 0;; i++) - { - if (i == std::size(sign.data) - 1) - { - fmt::append(out, "0x%02X", sign.data[i]); - break; - } - - fmt::append(out, "0x%02X, ", sign.data[i]); - } - - fmt::append(out, " }"); + fmt::append(out, "%s", sign.data); } // Helpers