Formatting Library: Implement byte arrays formatting

This commit is contained in:
Eladash 2021-07-17 11:36:27 +03:00 committed by Megamouse
parent 1f6ca25820
commit 1e9afdc289
3 changed files with 63 additions and 16 deletions

View File

@ -173,6 +173,37 @@ void fmt_class_string<std::vector<char8_t>>::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<char>::format(std::string& out, u64 arg)
{

View File

@ -86,7 +86,13 @@ struct fmt_unveil<T*, void>
}
};
template <typename T, usz N>
namespace fmt
{
template <typename T>
concept CharT = (std::is_same_v<const T, const char> || std::is_same_v<const T, const char8_t>);
}
template <fmt::CharT T, usz N>
struct fmt_unveil<T[N], void>
{
using type = std::add_const_t<T>*;
@ -215,6 +221,30 @@ struct fmt_class_string<char8_t*, void> : fmt_class_string<const char8_t*>
{
};
namespace fmt
{
// Both uchar and std::byte are allowed
template <typename T>
concept ByteArray = requires (T& t) { static_cast<const std::conditional_t<std::is_same_v<decltype(std::as_const(t[0])), const std::byte&>, std::byte, uchar>&>(std::data(t)[0]); };
}
template <fmt::ByteArray T>
struct fmt_class_string<T, void>
{
static FORCE_INLINE SAFE_BUFFERS(const T&) get_object(u64 arg)
{
return *reinterpret_cast<const T*>(static_cast<uptr>(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<const uchar*>(std::data(obj)), std::size(obj));
}
};
struct fmt_type_info
{
decltype(&fmt_class_string<int>::format) fmt_string;

View File

@ -160,21 +160,7 @@ void fmt_class_string<SceNpCommunicationSignature>::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