StringUtil: Speed up EncodeHex()/append_hex()
This commit is contained in:
parent
401295ebdb
commit
369599202c
|
@ -181,16 +181,40 @@ void SmallStringBase::append(const char* str, u32 length)
|
||||||
m_buffer[m_length] = 0;
|
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)
|
if (len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
make_room_for(static_cast<u32>(len) * 4);
|
static constexpr auto hex_char = [](char x) { return (x >= 0xA) ? ((x - 0xA) + 'a') : (x + '0'); };
|
||||||
const u8* bytes = static_cast<const u8*>(data);
|
const u8* bytes = static_cast<const u8*>(data);
|
||||||
append_format("{:02X}", bytes[0]);
|
|
||||||
for (size_t i = 1; i < len; i++)
|
if (!comma_separate)
|
||||||
append_format(", {:02X}", bytes[i]);
|
{
|
||||||
|
make_room_for(static_cast<u32>(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<u32>(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)
|
void SmallStringBase::prepend(const char* str, u32 length)
|
||||||
|
|
|
@ -67,7 +67,7 @@ public:
|
||||||
void append_format(fmt::format_string<T...> fmt, T&&... args);
|
void append_format(fmt::format_string<T...> fmt, T&&... args);
|
||||||
|
|
||||||
// append hex string
|
// 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
|
// append a single character to this string
|
||||||
void prepend(char c);
|
void prepend(char c);
|
||||||
|
|
|
@ -169,13 +169,20 @@ std::optional<std::vector<u8>> StringUtil::DecodeHex(const std::string_view in)
|
||||||
return {data};
|
return {data};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string StringUtil::EncodeHex(const u8* data, int length)
|
std::string StringUtil::EncodeHex(const void* data, size_t length)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
static constexpr auto hex_char = [](char x) { return (x >= 0xA) ? ((x - 0xA) + 'a') : (x + '0'); };
|
||||||
for (int i = 0; i < length; i++)
|
|
||||||
ss << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(data[i]);
|
|
||||||
|
|
||||||
return ss.str();
|
const u8* bytes = static_cast<const u8*>(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)
|
std::string_view StringUtil::StripWhitespace(const std::string_view str)
|
||||||
|
|
|
@ -204,7 +204,12 @@ inline std::string ToChars(bool value, int base)
|
||||||
|
|
||||||
/// Encode/decode hexadecimal byte buffers
|
/// Encode/decode hexadecimal byte buffers
|
||||||
std::optional<std::vector<u8>> DecodeHex(const std::string_view str);
|
std::optional<std::vector<u8>> DecodeHex(const std::string_view str);
|
||||||
std::string EncodeHex(const u8* data, int length);
|
std::string EncodeHex(const void* data, size_t length);
|
||||||
|
template<typename T>
|
||||||
|
ALWAYS_INLINE static std::string EncodeHex(const std::span<const T> data)
|
||||||
|
{
|
||||||
|
return EncodeHex(data.data(), data.size_bytes());
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the character is a hexadecimal digit.
|
/// Returns true if the character is a hexadecimal digit.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
Loading…
Reference in New Issue