mirror of
https://github.com/RGBCube/serenity
synced 2025-09-14 19:36:17 +00:00
AK+Everywhere: Remove the null state of DeprecatedString
This commit removes DeprecatedString's "null" state, and replaces all its users with one of the following: - A normal, empty DeprecatedString - Optional<DeprecatedString> Note that null states of DeprecatedFlyString/StringView/etc are *not* affected by this commit. However, DeprecatedString::empty() is now considered equal to a null StringView.
This commit is contained in:
parent
daf6d8173c
commit
aeee98b3a1
189 changed files with 597 additions and 652 deletions
|
@ -38,8 +38,6 @@ void DeprecatedFlyString::did_destroy_impl(Badge<StringImpl>, StringImpl& impl)
|
|||
|
||||
DeprecatedFlyString::DeprecatedFlyString(DeprecatedString const& string)
|
||||
{
|
||||
if (string.is_null())
|
||||
return;
|
||||
if (string.impl()->is_fly()) {
|
||||
m_impl = string.impl();
|
||||
return;
|
||||
|
@ -60,7 +58,7 @@ DeprecatedFlyString::DeprecatedFlyString(StringView string)
|
|||
if (string.is_null())
|
||||
return;
|
||||
auto it = fly_impls().find(string.hash(), [&](auto& candidate) {
|
||||
return string == candidate;
|
||||
return string == *candidate;
|
||||
});
|
||||
if (it == fly_impls().end()) {
|
||||
auto new_string = string.to_deprecated_string();
|
||||
|
|
|
@ -28,6 +28,9 @@ bool DeprecatedString::operator==(DeprecatedString const& other) const
|
|||
|
||||
bool DeprecatedString::operator==(StringView other) const
|
||||
{
|
||||
if (other.is_null())
|
||||
return is_empty();
|
||||
|
||||
return view() == other;
|
||||
}
|
||||
|
||||
|
@ -55,9 +58,7 @@ bool DeprecatedString::copy_characters_to_buffer(char* buffer, size_t buffer_siz
|
|||
|
||||
DeprecatedString DeprecatedString::isolated_copy() const
|
||||
{
|
||||
if (!m_impl)
|
||||
return {};
|
||||
if (!m_impl->length())
|
||||
if (m_impl->length() == 0)
|
||||
return empty();
|
||||
char* buffer;
|
||||
auto impl = StringImpl::create_uninitialized(length(), buffer);
|
||||
|
@ -69,7 +70,6 @@ DeprecatedString DeprecatedString::substring(size_t start, size_t length) const
|
|||
{
|
||||
if (!length)
|
||||
return DeprecatedString::empty();
|
||||
VERIFY(m_impl);
|
||||
VERIFY(!Checked<size_t>::addition_would_overflow(start, length));
|
||||
VERIFY(start + length <= m_impl->length());
|
||||
return { characters() + start, length };
|
||||
|
@ -77,14 +77,12 @@ DeprecatedString DeprecatedString::substring(size_t start, size_t length) const
|
|||
|
||||
DeprecatedString DeprecatedString::substring(size_t start) const
|
||||
{
|
||||
VERIFY(m_impl);
|
||||
VERIFY(start <= length());
|
||||
return { characters() + start, length() - start };
|
||||
}
|
||||
|
||||
StringView DeprecatedString::substring_view(size_t start, size_t length) const
|
||||
{
|
||||
VERIFY(m_impl);
|
||||
VERIFY(!Checked<size_t>::addition_would_overflow(start, length));
|
||||
VERIFY(start + length <= m_impl->length());
|
||||
return { characters() + start, length };
|
||||
|
@ -92,7 +90,6 @@ StringView DeprecatedString::substring_view(size_t start, size_t length) const
|
|||
|
||||
StringView DeprecatedString::substring_view(size_t start) const
|
||||
{
|
||||
VERIFY(m_impl);
|
||||
VERIFY(start <= length());
|
||||
return { characters() + start, length() - start };
|
||||
}
|
||||
|
@ -157,8 +154,6 @@ Vector<StringView> DeprecatedString::split_view(char const separator, SplitBehav
|
|||
|
||||
ByteBuffer DeprecatedString::to_byte_buffer() const
|
||||
{
|
||||
if (!m_impl)
|
||||
return {};
|
||||
// FIXME: Handle OOM failure.
|
||||
return ByteBuffer::copy(bytes()).release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
|
@ -379,21 +374,17 @@ DeprecatedString escape_html_entities(StringView html)
|
|||
}
|
||||
|
||||
DeprecatedString::DeprecatedString(DeprecatedFlyString const& string)
|
||||
: m_impl(string.impl())
|
||||
: m_impl(*string.impl())
|
||||
{
|
||||
}
|
||||
|
||||
DeprecatedString DeprecatedString::to_lowercase() const
|
||||
{
|
||||
if (!m_impl)
|
||||
return {};
|
||||
return m_impl->to_lowercase();
|
||||
}
|
||||
|
||||
DeprecatedString DeprecatedString::to_uppercase() const
|
||||
{
|
||||
if (!m_impl)
|
||||
return {};
|
||||
return m_impl->to_uppercase();
|
||||
}
|
||||
|
||||
|
@ -414,6 +405,9 @@ DeprecatedString DeprecatedString::invert_case() const
|
|||
|
||||
bool DeprecatedString::operator==(char const* cstring) const
|
||||
{
|
||||
if (!cstring)
|
||||
return is_empty();
|
||||
|
||||
return view() == cstring;
|
||||
}
|
||||
|
||||
|
@ -438,7 +432,7 @@ ErrorOr<DeprecatedString> DeprecatedString::from_utf8(ReadonlyBytes bytes)
|
|||
{
|
||||
if (!Utf8View(bytes).validate())
|
||||
return Error::from_string_literal("DeprecatedString::from_utf8: Input was not valid UTF-8");
|
||||
return DeprecatedString { StringImpl::create(bytes) };
|
||||
return DeprecatedString { *StringImpl::create(bytes) };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,10 +40,13 @@ class DeprecatedString {
|
|||
public:
|
||||
~DeprecatedString() = default;
|
||||
|
||||
DeprecatedString() = default;
|
||||
DeprecatedString()
|
||||
: m_impl(StringImpl::the_empty_stringimpl())
|
||||
{
|
||||
}
|
||||
|
||||
DeprecatedString(StringView view)
|
||||
: m_impl(StringImpl::create(view.characters_without_null_termination(), view.length()))
|
||||
: m_impl(*StringImpl::create(view.characters_without_null_termination(), view.length()))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -55,20 +58,21 @@ public:
|
|||
DeprecatedString(DeprecatedString&& other)
|
||||
: m_impl(move(other.m_impl))
|
||||
{
|
||||
other.m_impl = StringImpl::the_empty_stringimpl();
|
||||
}
|
||||
|
||||
DeprecatedString(char const* cstring, ShouldChomp shouldChomp = NoChomp)
|
||||
: m_impl(StringImpl::create(cstring, shouldChomp))
|
||||
: m_impl(*StringImpl::create(cstring, shouldChomp))
|
||||
{
|
||||
}
|
||||
|
||||
DeprecatedString(char const* cstring, size_t length, ShouldChomp shouldChomp = NoChomp)
|
||||
: m_impl(StringImpl::create(cstring, length, shouldChomp))
|
||||
: m_impl(*StringImpl::create(cstring, length, shouldChomp))
|
||||
{
|
||||
}
|
||||
|
||||
explicit DeprecatedString(ReadonlyBytes bytes, ShouldChomp shouldChomp = NoChomp)
|
||||
: m_impl(StringImpl::create(bytes, shouldChomp))
|
||||
: m_impl(*StringImpl::create(bytes, shouldChomp))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -77,18 +81,8 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
DeprecatedString(StringImpl const* impl)
|
||||
: m_impl(impl)
|
||||
{
|
||||
}
|
||||
|
||||
DeprecatedString(RefPtr<StringImpl const>&& impl)
|
||||
: m_impl(move(impl))
|
||||
{
|
||||
}
|
||||
|
||||
DeprecatedString(NonnullRefPtr<StringImpl const>&& impl)
|
||||
: m_impl(move(impl))
|
||||
: m_impl(*move(impl))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -174,31 +168,25 @@ public:
|
|||
[[nodiscard]] StringView substring_view(size_t start, size_t length) const;
|
||||
[[nodiscard]] StringView substring_view(size_t start) const;
|
||||
|
||||
[[nodiscard]] bool is_null() const { return !m_impl; }
|
||||
[[nodiscard]] ALWAYS_INLINE bool is_empty() const { return length() == 0; }
|
||||
[[nodiscard]] ALWAYS_INLINE size_t length() const { return m_impl ? m_impl->length() : 0; }
|
||||
// Includes NUL-terminator, if non-nullptr.
|
||||
[[nodiscard]] ALWAYS_INLINE char const* characters() const { return m_impl ? m_impl->characters() : nullptr; }
|
||||
[[nodiscard]] ALWAYS_INLINE size_t length() const { return m_impl->length(); }
|
||||
// Includes NUL-terminator.
|
||||
[[nodiscard]] ALWAYS_INLINE char const* characters() const { return m_impl->characters(); }
|
||||
|
||||
[[nodiscard]] bool copy_characters_to_buffer(char* buffer, size_t buffer_size) const;
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE ReadonlyBytes bytes() const
|
||||
{
|
||||
if (m_impl) {
|
||||
return m_impl->bytes();
|
||||
}
|
||||
return {};
|
||||
return m_impl->bytes();
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE char const& operator[](size_t i) const
|
||||
{
|
||||
VERIFY(!is_null());
|
||||
return (*m_impl)[i];
|
||||
}
|
||||
|
||||
[[nodiscard]] ALWAYS_INLINE u8 byte_at(size_t i) const
|
||||
{
|
||||
VERIFY(!is_null());
|
||||
return bit_cast<u8>((*m_impl)[i]);
|
||||
}
|
||||
|
||||
|
@ -251,22 +239,15 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
DeprecatedString& operator=(nullptr_t)
|
||||
template<OneOf<ReadonlyBytes, Bytes> T>
|
||||
DeprecatedString& operator=(T bytes)
|
||||
{
|
||||
m_impl = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DeprecatedString& operator=(ReadonlyBytes bytes)
|
||||
{
|
||||
m_impl = StringImpl::create(bytes);
|
||||
m_impl = *StringImpl::create(bytes);
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] u32 hash() const
|
||||
{
|
||||
if (!m_impl)
|
||||
return 0;
|
||||
return m_impl->hash();
|
||||
}
|
||||
|
||||
|
@ -323,7 +304,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
RefPtr<StringImpl const> m_impl;
|
||||
NonnullRefPtr<StringImpl const> m_impl;
|
||||
};
|
||||
|
||||
template<>
|
||||
|
|
|
@ -129,7 +129,7 @@ StringView GenericLexer::consume_quoted_string(char escape_char)
|
|||
}
|
||||
|
||||
#ifndef KERNEL
|
||||
DeprecatedString GenericLexer::consume_and_unescape_string(char escape_char)
|
||||
Optional<DeprecatedString> GenericLexer::consume_and_unescape_string(char escape_char)
|
||||
{
|
||||
auto view = consume_quoted_string(escape_char);
|
||||
if (view.is_null())
|
||||
|
|
|
@ -119,7 +119,7 @@ public:
|
|||
StringView consume_until(StringView);
|
||||
StringView consume_quoted_string(char escape_char = 0);
|
||||
#ifndef KERNEL
|
||||
DeprecatedString consume_and_unescape_string(char escape_char = '\\');
|
||||
Optional<DeprecatedString> consume_and_unescape_string(char escape_char = '\\');
|
||||
#endif
|
||||
|
||||
enum class UnicodeEscapeError {
|
||||
|
|
|
@ -132,8 +132,6 @@ ErrorOr<JsonValue> JsonParser::parse_object()
|
|||
break;
|
||||
ignore_while(is_space);
|
||||
auto name = TRY(consume_and_unescape_string());
|
||||
if (name.is_null())
|
||||
return Error::from_string_literal("JsonParser: Expected object property name");
|
||||
ignore_while(is_space);
|
||||
if (!consume_specific(':'))
|
||||
return Error::from_string_literal("JsonParser: Expected ':'");
|
||||
|
|
|
@ -174,13 +174,9 @@ JsonValue::JsonValue(double value)
|
|||
|
||||
JsonValue::JsonValue(DeprecatedString const& value)
|
||||
{
|
||||
if (value.is_null()) {
|
||||
m_type = Type::Null;
|
||||
} else {
|
||||
m_type = Type::String;
|
||||
m_value.as_string = const_cast<StringImpl*>(value.impl());
|
||||
m_value.as_string->ref();
|
||||
}
|
||||
m_type = Type::String;
|
||||
m_value.as_string = const_cast<StringImpl*>(value.impl());
|
||||
m_value.as_string->ref();
|
||||
}
|
||||
|
||||
JsonValue::JsonValue(StringView value)
|
||||
|
|
|
@ -90,9 +90,6 @@ bool LexicalPath::is_child_of(LexicalPath const& possible_parent) const
|
|||
|
||||
DeprecatedString LexicalPath::canonicalized_path(DeprecatedString path)
|
||||
{
|
||||
if (path.is_null())
|
||||
return {};
|
||||
|
||||
// NOTE: We never allow an empty m_string, if it's empty, we just set it to '.'.
|
||||
if (path.is_empty())
|
||||
return ".";
|
||||
|
|
|
@ -47,9 +47,6 @@ NonnullRefPtr<StringImpl const> StringImpl::create_uninitialized(size_t length,
|
|||
|
||||
RefPtr<StringImpl const> StringImpl::create(char const* cstring, size_t length, ShouldChomp should_chomp)
|
||||
{
|
||||
if (!cstring)
|
||||
return nullptr;
|
||||
|
||||
if (should_chomp) {
|
||||
while (length) {
|
||||
char last_ch = cstring[length - 1];
|
||||
|
@ -72,10 +69,7 @@ RefPtr<StringImpl const> StringImpl::create(char const* cstring, size_t length,
|
|||
|
||||
RefPtr<StringImpl const> StringImpl::create(char const* cstring, ShouldChomp shouldChomp)
|
||||
{
|
||||
if (!cstring)
|
||||
return nullptr;
|
||||
|
||||
if (!*cstring)
|
||||
if (!cstring || !*cstring)
|
||||
return the_empty_stringimpl();
|
||||
|
||||
return create(cstring, strlen(cstring), shouldChomp);
|
||||
|
@ -88,8 +82,6 @@ RefPtr<StringImpl const> StringImpl::create(ReadonlyBytes bytes, ShouldChomp sho
|
|||
|
||||
RefPtr<StringImpl const> StringImpl::create_lowercased(char const* cstring, size_t length)
|
||||
{
|
||||
if (!cstring)
|
||||
return nullptr;
|
||||
if (!length)
|
||||
return the_empty_stringimpl();
|
||||
char* buffer;
|
||||
|
@ -101,8 +93,6 @@ RefPtr<StringImpl const> StringImpl::create_lowercased(char const* cstring, size
|
|||
|
||||
RefPtr<StringImpl const> StringImpl::create_uppercased(char const* cstring, size_t length)
|
||||
{
|
||||
if (!cstring)
|
||||
return nullptr;
|
||||
if (!length)
|
||||
return the_empty_stringimpl();
|
||||
char* buffer;
|
||||
|
|
|
@ -178,12 +178,12 @@ bool StringView::equals_ignoring_ascii_case(StringView other) const
|
|||
#ifndef KERNEL
|
||||
DeprecatedString StringView::to_lowercase_string() const
|
||||
{
|
||||
return StringImpl::create_lowercased(characters_without_null_termination(), length());
|
||||
return StringImpl::create_lowercased(characters_without_null_termination(), length()).release_nonnull();
|
||||
}
|
||||
|
||||
DeprecatedString StringView::to_uppercase_string() const
|
||||
{
|
||||
return StringImpl::create_uppercased(characters_without_null_termination(), length());
|
||||
return StringImpl::create_uppercased(characters_without_null_termination(), length()).release_nonnull();
|
||||
}
|
||||
|
||||
DeprecatedString StringView::to_titlecase_string() const
|
||||
|
|
12
AK/URL.cpp
12
AK/URL.cpp
|
@ -191,13 +191,11 @@ URL URL::create_with_file_scheme(DeprecatedString const& path, DeprecatedString
|
|||
|
||||
URL url;
|
||||
url.set_scheme("file"_string);
|
||||
// NOTE: If the hostname is localhost (or null, which implies localhost), it should be set to the empty string.
|
||||
// This is because a file URL always needs a non-null hostname.
|
||||
url.set_host(hostname.is_null() || hostname == "localhost" ? String {} : String::from_deprecated_string(hostname).release_value_but_fixme_should_propagate_errors());
|
||||
url.set_host(hostname == "localhost" ? String {} : String::from_deprecated_string(hostname).release_value_but_fixme_should_propagate_errors());
|
||||
url.set_paths(lexical_path.parts());
|
||||
if (path.ends_with('/'))
|
||||
url.append_slash();
|
||||
if (!fragment.is_null())
|
||||
if (!fragment.is_empty())
|
||||
url.set_fragment(String::from_deprecated_string(fragment).release_value_but_fixme_should_propagate_errors());
|
||||
return url;
|
||||
}
|
||||
|
@ -208,14 +206,12 @@ URL URL::create_with_help_scheme(DeprecatedString const& path, DeprecatedString
|
|||
|
||||
URL url;
|
||||
url.set_scheme("help"_string);
|
||||
// NOTE: If the hostname is localhost (or null, which implies localhost), it should be set to the empty string.
|
||||
// This is because a file URL always needs a non-null hostname.
|
||||
url.set_host(hostname.is_null() || hostname == "localhost" ? String {} : String::from_deprecated_string(hostname).release_value_but_fixme_should_propagate_errors());
|
||||
url.set_host(hostname == "localhost" ? String {} : String::from_deprecated_string(hostname).release_value_but_fixme_should_propagate_errors());
|
||||
|
||||
url.set_paths(lexical_path.parts());
|
||||
if (path.ends_with('/'))
|
||||
url.append_slash();
|
||||
if (!fragment.is_null())
|
||||
if (!fragment.is_empty())
|
||||
url.set_fragment(String::from_deprecated_string(fragment).release_value_but_fixme_should_propagate_errors());
|
||||
return url;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue