1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 07:57:49 +00:00

AK: Add failable try_* functions to StringBuilder

These will allow us to start using TRY() with StringBuilder operations.
This commit is contained in:
Andreas Kling 2021-11-16 00:47:54 +01:00
parent 11aad74dce
commit 008355c222
2 changed files with 70 additions and 23 deletions

View file

@ -1,12 +1,11 @@
/* /*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <AK/ByteBuffer.h> #include <AK/ByteBuffer.h>
#include <AK/Checked.h> #include <AK/Checked.h>
#include <AK/Memory.h>
#include <AK/PrintfImplementation.h> #include <AK/PrintfImplementation.h>
#include <AK/StdLibExtras.h> #include <AK/StdLibExtras.h>
#include <AK/String.h> #include <AK/String.h>
@ -38,23 +37,40 @@ StringBuilder::StringBuilder(size_t initial_capacity)
m_buffer.ensure_capacity(initial_capacity); m_buffer.ensure_capacity(initial_capacity);
} }
void StringBuilder::append(StringView str) ErrorOr<void> StringBuilder::try_append(StringView string)
{ {
if (str.is_empty()) if (string.is_empty())
return; return {};
MUST(will_append(str.length())); TRY(will_append(string.length()));
MUST(m_buffer.try_append(str.characters_without_null_termination(), str.length())); TRY(m_buffer.try_append(string.characters_without_null_termination(), string.length()));
return {};
}
ErrorOr<void> StringBuilder::try_append(char ch)
{
TRY(will_append(1));
TRY(m_buffer.try_append(&ch, 1));
return {};
}
void StringBuilder::append(StringView string)
{
MUST(try_append(string));
}
ErrorOr<void> StringBuilder::try_append(char const* characters, size_t length)
{
return try_append(StringView { characters, length });
} }
void StringBuilder::append(char const* characters, size_t length) void StringBuilder::append(char const* characters, size_t length)
{ {
append(StringView { characters, length }); MUST(try_append(characters, length));
} }
void StringBuilder::append(char ch) void StringBuilder::append(char ch)
{ {
MUST(will_append(1)); MUST(try_append(ch));
MUST(m_buffer.try_append(&ch, 1));
} }
void StringBuilder::appendvf(char const* fmt, va_list ap) void StringBuilder::appendvf(char const* fmt, va_list ap)
@ -93,32 +109,50 @@ void StringBuilder::clear()
m_buffer.clear(); m_buffer.clear();
} }
void StringBuilder::append_code_point(u32 code_point) ErrorOr<void> StringBuilder::try_append_code_point(u32 code_point)
{ {
auto nwritten = AK::UnicodeUtils::code_point_to_utf8(code_point, [this](char c) { append(c); }); auto nwritten = AK::UnicodeUtils::code_point_to_utf8(code_point, [this](char c) { append(c); });
if (nwritten < 0) { if (nwritten < 0) {
append(0xef); TRY(try_append(0xef));
append(0xbf); TRY(try_append(0xbf));
append(0xbd); TRY(try_append(0xbd));
} }
return {};
}
void StringBuilder::append_code_point(u32 code_point)
{
MUST(try_append_code_point(code_point));
}
ErrorOr<void> StringBuilder::try_append(Utf16View const& utf16_view)
{
for (size_t i = 0; i < utf16_view.length_in_code_units();) {
auto code_point = utf16_view.code_point_at(i);
TRY(try_append_code_point(code_point));
i += (code_point > 0xffff ? 2 : 1);
}
return {};
} }
void StringBuilder::append(Utf16View const& utf16_view) void StringBuilder::append(Utf16View const& utf16_view)
{ {
for (size_t i = 0; i < utf16_view.length_in_code_units();) { MUST(try_append(utf16_view));
auto code_point = utf16_view.code_point_at(i);
append_code_point(code_point);
i += (code_point > 0xffff ? 2 : 1);
} }
ErrorOr<void> StringBuilder::try_append(Utf32View const& utf32_view)
{
for (size_t i = 0; i < utf32_view.length(); ++i) {
auto code_point = utf32_view.code_points()[i];
TRY(try_append_code_point(code_point));
}
return {};
} }
void StringBuilder::append(Utf32View const& utf32_view) void StringBuilder::append(Utf32View const& utf32_view)
{ {
for (size_t i = 0; i < utf32_view.length(); ++i) { MUST(try_append(utf32_view));
auto code_point = utf32_view.code_points()[i];
append_code_point(code_point);
}
} }
void StringBuilder::append_as_lowercase(char ch) void StringBuilder::append_as_lowercase(char ch)

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* *
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
@ -21,6 +21,19 @@ public:
explicit StringBuilder(size_t initial_capacity = inline_capacity); explicit StringBuilder(size_t initial_capacity = inline_capacity);
~StringBuilder() = default; ~StringBuilder() = default;
ErrorOr<void> try_append(StringView);
ErrorOr<void> try_append(Utf16View const&);
ErrorOr<void> try_append(Utf32View const&);
ErrorOr<void> try_append_code_point(u32);
ErrorOr<void> try_append(char);
template<typename... Parameters>
ErrorOr<void> try_appendff(CheckedFormatString<Parameters...>&& fmtstr, Parameters const&... parameters)
{
VariadicFormatParams variadic_format_params { parameters... };
return vformat(*this, fmtstr.view(), variadic_format_params);
}
ErrorOr<void> try_append(char const*, size_t);
void append(StringView); void append(StringView);
void append(Utf16View const&); void append(Utf16View const&);
void append(Utf32View const&); void append(Utf32View const&);