diff --git a/AK/FlyString.cpp b/AK/FlyString.cpp index bd111dd027b..932a8a79af8 100644 --- a/AK/FlyString.cpp +++ b/AK/FlyString.cpp @@ -110,11 +110,6 @@ bool FlyString::operator==(char const* string) const return bytes_as_string_view() == string; } -void FlyString::did_destroy_fly_string_data(Badge, Detail::StringData const& string_data) -{ - all_fly_strings().remove(&string_data); -} - Detail::StringBase FlyString::data(Badge) const { return m_data; @@ -220,4 +215,13 @@ bool FlyString::ends_with_bytes(StringView bytes, CaseSensitivity case_sensitivi return bytes_as_string_view().ends_with(bytes, case_sensitivity); } +namespace Detail { + +void did_destroy_fly_string_data(Badge, Detail::StringData const& string_data) +{ + all_fly_strings().remove(&string_data); +} + +} + } diff --git a/AK/FlyString.h b/AK/FlyString.h index 53cdbaa7620..9b0e3b9ed38 100644 --- a/AK/FlyString.h +++ b/AK/FlyString.h @@ -50,7 +50,6 @@ public: [[nodiscard]] int operator<=>(FlyString const& other) const; - static void did_destroy_fly_string_data(Badge, Detail::StringData const&); [[nodiscard]] Detail::StringBase data(Badge) const; // This is primarily interesting to unit tests. @@ -104,6 +103,8 @@ private: bool is_invalid() const { return m_data.is_invalid(); } }; +void did_destroy_fly_string_data(Badge, Detail::StringData const&); + template<> class Optional : public OptionalBase { template diff --git a/AK/StringBase.cpp b/AK/StringBase.cpp index bb362078b85..be3ffd591b9 100644 --- a/AK/StringBase.cpp +++ b/AK/StringBase.cpp @@ -11,89 +11,6 @@ namespace AK::Detail { -ReadonlyBytes ShortString::bytes() const -{ - return { storage, byte_count() }; -} - -size_t ShortString::byte_count() const -{ - return byte_count_and_short_string_flag >> StringBase::SHORT_STRING_BYTE_COUNT_SHIFT_COUNT; -} - -StringBase::StringBase(NonnullRefPtr data) - : m_data(&data.leak_ref()) -{ -} - -StringBase::StringBase(StringBase const& other) - : m_data(other.m_data) -{ - if (!is_short_string()) - m_data->ref(); -} - -StringBase& StringBase::operator=(StringBase&& other) -{ - if (!is_short_string()) - m_data->unref(); - - m_data = exchange(other.m_data, nullptr); - other.m_short_string.byte_count_and_short_string_flag = SHORT_STRING_FLAG; - return *this; -} - -StringBase& StringBase::operator=(StringBase const& other) -{ - if (&other != this) { - if (!is_short_string()) - m_data->unref(); - - m_data = other.m_data; - if (!is_short_string()) - m_data->ref(); - } - return *this; -} - -ReadonlyBytes StringBase::bytes() const -{ - ASSERT(!is_invalid()); - if (is_short_string()) - return m_short_string.bytes(); - return m_data->bytes(); -} - -u32 StringBase::hash() const -{ - ASSERT(!is_invalid()); - if (is_short_string()) { - auto bytes = this->bytes(); - return string_hash(reinterpret_cast(bytes.data()), bytes.size()); - } - return m_data->hash(); -} - -size_t StringBase::byte_count() const -{ - ASSERT(!is_invalid()); - if (is_short_string()) - return m_short_string.byte_count_and_short_string_flag >> StringBase::SHORT_STRING_BYTE_COUNT_SHIFT_COUNT; - return m_data->byte_count(); -} - -bool StringBase::operator==(StringBase const& other) const -{ - ASSERT(!is_invalid()); - if (is_short_string()) - return m_data == other.m_data; - if (other.is_short_string()) - return false; - if (m_data->is_fly_string() && other.m_data->is_fly_string()) - return m_data == other.m_data; - return bytes() == other.bytes(); -} - void StringBase::replace_with_string_builder(StringBuilder& builder) { ASSERT(!is_invalid()); @@ -135,10 +52,4 @@ ErrorOr StringBase::substring_from_byte_offset_with_shared_superstri return StringBase { TRY(Detail::StringData::create_substring(*m_data, start, length)) }; } -void StringBase::destroy_string() -{ - if (!is_short_string()) - m_data->unref(); -} - } diff --git a/AK/StringBase.h b/AK/StringBase.h index 29bd51bd4be..492f2547fc7 100644 --- a/AK/StringBase.h +++ b/AK/StringBase.h @@ -9,13 +9,10 @@ #include #include #include +#include namespace AK::Detail { -class StringData; - -static constexpr size_t MAX_SHORT_STRING_BYTE_COUNT = sizeof(StringData*) - sizeof(u8); - struct ShortString { ReadonlyBytes bytes() const; size_t byte_count() const; @@ -142,4 +139,93 @@ private: }; }; +inline ReadonlyBytes ShortString::bytes() const +{ + return { storage, byte_count() }; +} + +inline size_t ShortString::byte_count() const +{ + return byte_count_and_short_string_flag >> StringBase::SHORT_STRING_BYTE_COUNT_SHIFT_COUNT; +} + +inline ReadonlyBytes StringBase::bytes() const +{ + ASSERT(!is_invalid()); + if (is_short_string()) + return m_short_string.bytes(); + return m_data->bytes(); +} + +inline u32 StringBase::hash() const +{ + ASSERT(!is_invalid()); + if (is_short_string()) { + auto bytes = this->bytes(); + return string_hash(reinterpret_cast(bytes.data()), bytes.size()); + } + return m_data->hash(); +} + +inline size_t StringBase::byte_count() const +{ + ASSERT(!is_invalid()); + if (is_short_string()) + return m_short_string.byte_count_and_short_string_flag >> StringBase::SHORT_STRING_BYTE_COUNT_SHIFT_COUNT; + return m_data->byte_count(); +} + +inline void StringBase::destroy_string() +{ + if (!is_short_string()) + m_data->unref(); +} + +inline StringBase::StringBase(NonnullRefPtr data) + : m_data(&data.leak_ref()) +{ +} + +inline StringBase::StringBase(StringBase const& other) + : m_data(other.m_data) +{ + if (!is_short_string()) + m_data->ref(); +} + +inline StringBase& StringBase::operator=(StringBase&& other) +{ + if (!is_short_string()) + m_data->unref(); + + m_data = exchange(other.m_data, nullptr); + other.m_short_string.byte_count_and_short_string_flag = SHORT_STRING_FLAG; + return *this; +} + +inline StringBase& StringBase::operator=(StringBase const& other) +{ + if (&other != this) { + if (!is_short_string()) + m_data->unref(); + + m_data = other.m_data; + if (!is_short_string()) + m_data->ref(); + } + return *this; +} + +inline bool StringBase::operator==(StringBase const& other) const +{ + ASSERT(!is_invalid()); + if (is_short_string()) + return m_data == other.m_data; + if (other.is_short_string()) + return false; + if (m_data->is_fly_string() && other.m_data->is_fly_string()) + return m_data == other.m_data; + return bytes() == other.bytes(); +} + } diff --git a/AK/StringData.h b/AK/StringData.h index c029afd6413..694158bff3b 100644 --- a/AK/StringData.h +++ b/AK/StringData.h @@ -7,15 +7,18 @@ #pragma once #include -#include #include #include -#include #include -#include namespace AK::Detail { +static constexpr size_t MAX_SHORT_STRING_BYTE_COUNT = sizeof(StringData*) - sizeof(u8); + +class StringData; + +void did_destroy_fly_string_data(Badge, StringData const&); + class StringData final : public RefCounted { public: static ErrorOr> create_uninitialized(size_t byte_count, u8*& buffer) @@ -63,7 +66,7 @@ public: void operator delete(void* ptr) { - kfree_sized(ptr, static_cast(ptr)->m_capacity); + free(ptr); } ~StringData() @@ -71,7 +74,7 @@ public: if (m_substring) substring_data().superstring->unref(); if (m_is_fly_string) - FlyString::did_destroy_fly_string_data({}, *this); + Detail::did_destroy_fly_string_data({}, *this); } SubstringData const& substring_data() const