diff --git a/AK/StringBuilder.cpp b/AK/StringBuilder.cpp index 22bcf56389c..524f0a3d9cd 100644 --- a/AK/StringBuilder.cpp +++ b/AK/StringBuilder.cpp @@ -1,12 +1,11 @@ /* - * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2018-2021, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #include #include -#include #include #include #include @@ -38,23 +37,40 @@ StringBuilder::StringBuilder(size_t initial_capacity) m_buffer.ensure_capacity(initial_capacity); } -void StringBuilder::append(StringView str) +ErrorOr StringBuilder::try_append(StringView string) { - if (str.is_empty()) - return; - MUST(will_append(str.length())); - MUST(m_buffer.try_append(str.characters_without_null_termination(), str.length())); + if (string.is_empty()) + return {}; + TRY(will_append(string.length())); + TRY(m_buffer.try_append(string.characters_without_null_termination(), string.length())); + return {}; +} + +ErrorOr 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 StringBuilder::try_append(char const* characters, size_t length) +{ + return try_append(StringView { characters, length }); } void StringBuilder::append(char const* characters, size_t length) { - append(StringView { characters, length }); + MUST(try_append(characters, length)); } void StringBuilder::append(char ch) { - MUST(will_append(1)); - MUST(m_buffer.try_append(&ch, 1)); + MUST(try_append(ch)); } void StringBuilder::appendvf(char const* fmt, va_list ap) @@ -93,32 +109,50 @@ void StringBuilder::clear() m_buffer.clear(); } -void StringBuilder::append_code_point(u32 code_point) +ErrorOr StringBuilder::try_append_code_point(u32 code_point) { auto nwritten = AK::UnicodeUtils::code_point_to_utf8(code_point, [this](char c) { append(c); }); if (nwritten < 0) { - append(0xef); - append(0xbf); - append(0xbd); + TRY(try_append(0xef)); + TRY(try_append(0xbf)); + TRY(try_append(0xbd)); } + return {}; +} + +void StringBuilder::append_code_point(u32 code_point) +{ + MUST(try_append_code_point(code_point)); +} + +ErrorOr 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) { - for (size_t i = 0; i < utf16_view.length_in_code_units();) { - auto code_point = utf16_view.code_point_at(i); - append_code_point(code_point); + MUST(try_append(utf16_view)); +} - i += (code_point > 0xffff ? 2 : 1); +ErrorOr 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) { - for (size_t i = 0; i < utf32_view.length(); ++i) { - auto code_point = utf32_view.code_points()[i]; - append_code_point(code_point); - } + MUST(try_append(utf32_view)); } void StringBuilder::append_as_lowercase(char ch) diff --git a/AK/StringBuilder.h b/AK/StringBuilder.h index 36019dffa7e..d154c8be3e8 100644 --- a/AK/StringBuilder.h +++ b/AK/StringBuilder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2018-2021, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -21,6 +21,19 @@ public: explicit StringBuilder(size_t initial_capacity = inline_capacity); ~StringBuilder() = default; + ErrorOr try_append(StringView); + ErrorOr try_append(Utf16View const&); + ErrorOr try_append(Utf32View const&); + ErrorOr try_append_code_point(u32); + ErrorOr try_append(char); + template + ErrorOr try_appendff(CheckedFormatString&& fmtstr, Parameters const&... parameters) + { + VariadicFormatParams variadic_format_params { parameters... }; + return vformat(*this, fmtstr.view(), variadic_format_params); + } + ErrorOr try_append(char const*, size_t); + void append(StringView); void append(Utf16View const&); void append(Utf32View const&);