diff options
Diffstat (limited to 'src/zencore/include')
| -rw-r--r-- | src/zencore/include/zencore/string.h | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/zencore/include/zencore/string.h b/src/zencore/include/zencore/string.h index b4926070c..a1c7a3914 100644 --- a/src/zencore/include/zencore/string.h +++ b/src/zencore/include/zencore/string.h @@ -1349,6 +1349,70 @@ std::string HideSensitiveString(std::string_view String); ////////////////////////////////////////////////////////////////////////// +/// Owns a heap-allocated, null-terminated string buffer. +/// Lightweight alternative to std::string when only immutable +/// storage and string_view access are needed. +/// +/// The buffer layout is [length-prefix][chars...][NUL]. The first +/// byte stores the string length for strings shorter than 255 bytes, +/// avoiding strlen() on every access. A sentinel value of 0xFF +/// indicates a longer string; Size() then returns 255 + strlen() +/// starting at the 256th character, skipping the known prefix. +class CompactString +{ +public: + CompactString() = default; + + explicit CompactString(std::string_view Str) : m_Data(new char[1 + Str.size() + 1]) + { + m_Data[0] = static_cast<char>(Str.size() < LengthFallbackSentinel ? Str.size() : LengthFallbackSentinel); + memcpy(m_Data + 1, Str.data(), Str.size()); + m_Data[1 + Str.size()] = '\0'; + } + + ~CompactString() { delete[] m_Data; } + + CompactString(const CompactString&) = delete; + CompactString& operator=(const CompactString&) = delete; + + CompactString(CompactString&& Other) noexcept : m_Data(Other.m_Data) { Other.m_Data = nullptr; } + + CompactString& operator=(CompactString&& Other) noexcept + { + if (this != &Other) + { + delete[] m_Data; + m_Data = Other.m_Data; + Other.m_Data = nullptr; + } + return *this; + } + + const char* c_str() const { return m_Data ? m_Data + 1 : ""; } + + size_t Size() const + { + if (!m_Data) + { + return 0; + } + uint8_t Prefix = static_cast<uint8_t>(m_Data[0]); + return Prefix < LengthFallbackSentinel ? Prefix : LengthFallbackSentinel + strlen(m_Data + 1 + LengthFallbackSentinel); + } + + std::string_view ToView() const { return {c_str(), Size()}; } + bool IsEmpty() const { return m_Data == nullptr || m_Data[1] == '\0'; } + + operator std::string_view() const { return ToView(); } + +private: + static constexpr uint8_t LengthFallbackSentinel = 0xFF; + + char* m_Data = nullptr; +}; + +////////////////////////////////////////////////////////////////////////// + void string_forcelink(); // internal } // namespace zen |