From 061f902f9523de36f2bb2a8eb05bfca4389ebee4 Mon Sep 17 00:00:00 2001 From: Dan Klishch Date: Mon, 22 Jan 2024 13:26:55 -0500 Subject: [PATCH] AK+Userland: Introduce ByteString::create_and_overwrite And replace two users of raw StringImpl with it. --- AK/ByteString.h | 17 +++++++++++++++++ Userland/Libraries/LibC/netdb.cpp | 12 +++++++----- Userland/Libraries/LibIPC/Decoder.cpp | 11 ++++------- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/AK/ByteString.h b/AK/ByteString.h index 34046f3e19..052e0571f8 100644 --- a/AK/ByteString.h +++ b/AK/ByteString.h @@ -93,6 +93,23 @@ public: static ByteString must_from_utf8(StringView string) { return MUST(from_utf8(string)); } static ByteString from_utf8_without_validation(StringView string) { return ByteString { string }; } + template< + typename F, + typename PossiblyErrorOr = decltype(declval()(declval())), + bool is_error_or = IsSpecializationOf, + typename ReturnType = Conditional, ByteString>> + static ReturnType create_and_overwrite(size_t length, F&& fill_function) + { + char* buffer; + auto impl = StringImpl::create_uninitialized(length, buffer); + + if constexpr (is_error_or) + TRY(fill_function(Bytes { buffer, length })); + else + fill_function(Bytes { buffer, length }); + return impl; + } + [[nodiscard]] static ByteString repeated(char, size_t count); [[nodiscard]] static ByteString repeated(StringView, size_t count); diff --git a/Userland/Libraries/LibC/netdb.cpp b/Userland/Libraries/LibC/netdb.cpp index 64b9ea32ef..f4a55ecf8f 100644 --- a/Userland/Libraries/LibC/netdb.cpp +++ b/Userland/Libraries/LibC/netdb.cpp @@ -394,10 +394,13 @@ hostent* gethostbyaddr(void const* addr, socklen_t addr_size, int type) return nullptr; } - char* buffer; - auto string_impl = StringImpl::create_uninitialized(response_header.name_length, buffer); + ssize_t nreceived; - if (auto nreceived = read(fd, buffer, response_header.name_length); nreceived < 0) { + gethostbyaddr_name_buffer = ByteString::create_and_overwrite(response_header.name_length, [&](Bytes bytes) { + nreceived = read(fd, bytes.data(), bytes.size()); + }); + + if (nreceived < 0) { h_errno = TRY_AGAIN; return nullptr; } else if (static_cast(nreceived) != response_header.name_length) { @@ -405,8 +408,7 @@ hostent* gethostbyaddr(void const* addr, socklen_t addr_size, int type) return nullptr; } - gethostbyaddr_name_buffer = move(string_impl); - __gethostbyaddr_buffer.h_name = buffer; + __gethostbyaddr_buffer.h_name = const_cast(gethostbyaddr_name_buffer.characters()); __gethostbyaddr_alias_list_buffer[0] = nullptr; __gethostbyaddr_buffer.h_aliases = __gethostbyaddr_alias_list_buffer; __gethostbyaddr_buffer.h_addrtype = AF_INET; diff --git a/Userland/Libraries/LibIPC/Decoder.cpp b/Userland/Libraries/LibIPC/Decoder.cpp index 9ef9dce529..f659897dd5 100644 --- a/Userland/Libraries/LibIPC/Decoder.cpp +++ b/Userland/Libraries/LibIPC/Decoder.cpp @@ -39,13 +39,10 @@ ErrorOr decode(Decoder& decoder) if (length == 0) return ByteString::empty(); - char* text_buffer = nullptr; - auto text_impl = StringImpl::create_uninitialized(length, text_buffer); - - Bytes bytes { text_buffer, length }; - TRY(decoder.decode_into(bytes)); - - return ByteString { *text_impl }; + return ByteString::create_and_overwrite(length, [&](Bytes bytes) -> ErrorOr { + TRY(decoder.decode_into(bytes)); + return {}; + }); } template<>