diff --git a/src/common/small_string.cpp b/src/common/small_string.cpp index c941550a0..619e5edc4 100644 --- a/src/common/small_string.cpp +++ b/src/common/small_string.cpp @@ -181,16 +181,40 @@ void SmallStringBase::append(const char* str, u32 length) m_buffer[m_length] = 0; } -void SmallStringBase::append_hex(const void* data, size_t len) +void SmallStringBase::append_hex(const void* data, size_t len, bool comma_separate) { if (len == 0) return; - make_room_for(static_cast(len) * 4); + static constexpr auto hex_char = [](char x) { return (x >= 0xA) ? ((x - 0xA) + 'a') : (x + '0'); }; const u8* bytes = static_cast(data); - append_format("{:02X}", bytes[0]); - for (size_t i = 1; i < len; i++) - append_format(", {:02X}", bytes[i]); + + if (!comma_separate) + { + make_room_for(static_cast(len) * 2); + for (size_t i = 0; i < len; i++) + { + m_buffer[m_length++] = hex_char(bytes[i] >> 4); + m_buffer[m_length++] = hex_char(bytes[i] & 0xF); + } + } + else + { + make_room_for(4 + static_cast(len - 1) * 6); + m_buffer[m_length++] = '0'; + m_buffer[m_length++] = 'x'; + m_buffer[m_length++] = hex_char(bytes[0] >> 4); + m_buffer[m_length++] = hex_char(bytes[0] & 0xF); + for (size_t i = 1; i < len; i++) + { + m_buffer[m_length++] = ','; + m_buffer[m_length++] = ' '; + m_buffer[m_length++] = '0'; + m_buffer[m_length++] = 'x'; + m_buffer[m_length++] = hex_char(bytes[i] >> 4); + m_buffer[m_length++] = hex_char(bytes[i] & 0xF); + } + } } void SmallStringBase::prepend(const char* str, u32 length) diff --git a/src/common/small_string.h b/src/common/small_string.h index 16dfe507a..4a892b38f 100644 --- a/src/common/small_string.h +++ b/src/common/small_string.h @@ -67,7 +67,7 @@ public: void append_format(fmt::format_string fmt, T&&... args); // append hex string - void append_hex(const void* data, size_t len); + void append_hex(const void* data, size_t len, bool comma_separate = false); // append a single character to this string void prepend(char c); diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index d4ae21e46..940b06a60 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -169,13 +169,20 @@ std::optional> StringUtil::DecodeHex(const std::string_view in) return {data}; } -std::string StringUtil::EncodeHex(const u8* data, int length) +std::string StringUtil::EncodeHex(const void* data, size_t length) { - std::stringstream ss; - for (int i = 0; i < length; i++) - ss << std::hex << std::setfill('0') << std::setw(2) << static_cast(data[i]); + static constexpr auto hex_char = [](char x) { return (x >= 0xA) ? ((x - 0xA) + 'a') : (x + '0'); }; - return ss.str(); + const u8* bytes = static_cast(data); + + std::string ret; + ret.reserve(length * 2); + for (size_t i = 0; i < length; i++) + { + ret.push_back(hex_char(bytes[i] >> 4)); + ret.push_back(hex_char(bytes[i] & 0xF)); + } + return ret; } std::string_view StringUtil::StripWhitespace(const std::string_view str) diff --git a/src/common/string_util.h b/src/common/string_util.h index f4f8cbde5..da54338b3 100644 --- a/src/common/string_util.h +++ b/src/common/string_util.h @@ -204,7 +204,12 @@ inline std::string ToChars(bool value, int base) /// Encode/decode hexadecimal byte buffers std::optional> DecodeHex(const std::string_view str); -std::string EncodeHex(const u8* data, int length); +std::string EncodeHex(const void* data, size_t length); +template +ALWAYS_INLINE static std::string EncodeHex(const std::span data) +{ + return EncodeHex(data.data(), data.size_bytes()); +} /// Returns true if the character is a hexadecimal digit. template