From 30cb3c0d5ebec39d0df67677dcb7ac67a0c39cf7 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Tue, 26 Apr 2022 11:19:59 +0200 Subject: [PATCH] Fixes for StringView to make working with non-null terminated strings easier --- src/String/StringView.hpp | 27 ++++++++++++++------------- src/String/StringViewLiteral.hpp | 10 +++++----- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/String/StringView.hpp b/src/String/StringView.hpp index 1442c76..31375ad 100644 --- a/src/String/StringView.hpp +++ b/src/String/StringView.hpp @@ -22,7 +22,8 @@ namespace ArbUt { public: __ConstStringCharHolder(const char* non_null value, size_t length) : _value(new char[length + 1]) { EnsureNotNull(value); - strncpy(_value, value, length + 1); + strncpy(_value, value, length); + _value[length] = 0; } ~__ConstStringCharHolder() noexcept { delete[] _value; } inline constexpr const char* non_null GetValue() const noexcept { return _value; } @@ -61,10 +62,10 @@ constexpr u32 crc_table[256] = { 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D}; inline static constexpr char charToLower(const char c) { return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c; } -static u32 constexpr Hash(std::string_view input) { +static u32 constexpr Hash(const char* non_null str, size_t size) { u32 crc = 0xffffffff; - for (auto c : input) { - crc = (crc >> 8) ^ crc_table[(crc ^ charToLower(c)) & 0xff]; + for (size_t i = 0; i < size; ++i) { + crc = (crc >> 8) ^ crc_table[(crc ^ charToLower(str[i])) & 0xff]; } return crc ^ 0xffffffff; }; @@ -84,13 +85,13 @@ namespace ArbUt { /// @brief Instantiate a StringView using a C string. /// @param str A null-terminated C string. StringView(const char* non_null str) - : BasicStringView(CalcLength(str), Hash(str)), _str(new __ConstStringCharHolder(str, CalcLength(str))) {} + : BasicStringView(CalcLength(str), Hash(str, CalcLength(str))), _str(new __ConstStringCharHolder(str, CalcLength(str))) {} /// @brief Instantiate a StringView using a C string, as well as it's length. /// @param str A null-terminated C string. /// @param length The length of the C string StringView(const char* non_null str, size_t length) - : BasicStringView(length, Hash(str)), _str(new __ConstStringCharHolder(str, length)) {} - StringView() noexcept : BasicStringView(0, Hash("")) {} + : BasicStringView(length, Hash(str, length)), _str(new __ConstStringCharHolder(str, length)) {} + StringView() noexcept : BasicStringView(0, Hash("", 0)) {} /* Copy operators */ /// @brief Copy operator @@ -126,29 +127,29 @@ namespace ArbUt { /// @brief Check equality with standard C++ string. inline constexpr bool operator==(const std::string_view& rhs) const noexcept final { - return _hash == Hash(rhs.data()); + return _hash == Hash(rhs.data(), rhs.size()); } /// @brief Check inequality with standard C++ string. inline constexpr bool operator!=(const std::string_view& rhs) const noexcept final { - return _hash != Hash(rhs.data()); + return _hash != Hash(rhs.data(), rhs.size()); } /// @brief Check equality with standard C style string. - inline constexpr bool operator==(const char* non_null rhs) const noexcept final { return _hash == Hash(rhs); } + inline constexpr bool operator==(const char* non_null rhs) const noexcept final { return _hash == Hash(rhs, CalcLength(rhs)); } /// @brief Check inequality with standard C style string. - inline constexpr bool operator!=(const char* non_null rhs) const noexcept final { return _hash != Hash(rhs); } + inline constexpr bool operator!=(const char* non_null rhs) const noexcept final { return _hash != Hash(rhs, CalcLength(rhs)); } /// @brief Calculates the hash for a given C string. /// @param val A null-terminated C string. /// @return A hash of the given string. [[maybe_unused]] [[nodiscard]] inline static constexpr u32 CalculateHash(const char* non_null val) noexcept { - return Hash(val); + return Hash(val, CalcLength(val)); } /// @brief Calculates the hash for a given std string. /// @param val A std string. /// @return A hash of the given string. [[maybe_unused]] [[nodiscard]] inline static constexpr u32 CalculateHash(const std::string_view& val) noexcept { - return Hash(val.data()); + return Hash(val.data(), val.size()); } /// @brief Returns an empty string. diff --git a/src/String/StringViewLiteral.hpp b/src/String/StringViewLiteral.hpp index 8c75760..05bffaf 100644 --- a/src/String/StringViewLiteral.hpp +++ b/src/String/StringViewLiteral.hpp @@ -16,7 +16,7 @@ namespace ArbUt { /// @param str A null terminated C string. /// @param size A The length of the string. constexpr StringViewLiteral(const char* non_null str, size_t size) noexcept - : BasicStringView(size, Hash(str)), _str(str) {} + : BasicStringView(size, Hash(str, size)), _str(str) {} /// @brief Compile time initialisation of a StringViewLiteral. Length is calculated at compile. /// @param str A null terminated C string. constexpr StringViewLiteral(const char* non_null str) noexcept : StringViewLiteral(str, CalcLength(str)){}; @@ -34,16 +34,16 @@ namespace ArbUt { /// @brief Check equality with standard C++ string. inline constexpr bool operator==(const std::string_view& rhs) const noexcept final { - return _hash == Hash(rhs.data()); + return _hash == Hash(rhs.data(), rhs.size()); } /// @brief Check inequality with standard C++ string. inline constexpr bool operator!=(const std::string_view& rhs) const noexcept final { - return _hash != Hash(rhs.data()); + return _hash != Hash(rhs.data(), rhs.size()); } /// @brief Check equality with standard C style string. - inline constexpr bool operator==(const char* non_null rhs) const noexcept final { return _hash == Hash(rhs); } + inline constexpr bool operator==(const char* non_null rhs) const noexcept final { return _hash == Hash(rhs, CalcLength(rhs)); } /// @brief Check inequality with standard C style string. - inline constexpr bool operator!=(const char* non_null rhs) const noexcept final { return _hash != Hash(rhs); } + inline constexpr bool operator!=(const char* non_null rhs) const noexcept final { return _hash != Hash(rhs, CalcLength(rhs)); } }; }