1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-28 14:07:45 +00:00

LibCore+Everywhere: Make Core::Stream::read() return Bytes

A mistake I've repeatedly made is along these lines:
```c++
auto nread = TRY(source_file->read(buffer));
TRY(destination_file->write(buffer));
```

It's a little clunky to have to create a Bytes or StringView from the
buffer's data pointer and the nread, and easy to forget and just use
the buffer. So, this patch changes the read() function to return a
Bytes of the data that were just read.

The other read_foo() methods will be modified in the same way in
subsequent commits.

Fixes #13687
This commit is contained in:
Sam Atkins 2022-04-15 13:33:02 +01:00 committed by Tim Flynn
parent 6654efcd82
commit 3b1e063d30
22 changed files with 103 additions and 103 deletions

View file

@ -114,7 +114,7 @@ MaybeLoaderError FlacLoaderPlugin::parse_header()
[[maybe_unused]] u128 md5_checksum;
VERIFY(streaminfo_data->is_aligned_to_byte_boundary());
auto md5_bytes_read = LOADER_TRY(streaminfo_data->read(md5_checksum.bytes()));
FLAC_VERIFY(md5_bytes_read == md5_checksum.my_size(), LoaderError::Category::IO, "MD5 Checksum size");
FLAC_VERIFY(md5_bytes_read.size() == md5_checksum.my_size(), LoaderError::Category::IO, "MD5 Checksum size");
md5_checksum.bytes().copy_to({ m_md5_checksum, sizeof(m_md5_checksum) });
// Parse other blocks

View file

@ -162,31 +162,31 @@ private:
#ifdef __serenity__
m_socket->on_ready_to_read = [this] {
u32 length;
auto maybe_nread = m_socket->read({ (u8*)&length, sizeof(length) });
if (maybe_nread.is_error()) {
dbgln("InspectorServerConnection: Failed to read message length from inspector server connection: {}", maybe_nread.error());
auto maybe_bytes_read = m_socket->read({ (u8*)&length, sizeof(length) });
if (maybe_bytes_read.is_error()) {
dbgln("InspectorServerConnection: Failed to read message length from inspector server connection: {}", maybe_bytes_read.error());
shutdown();
return;
}
auto nread = maybe_nread.release_value();
if (nread == 0) {
auto bytes_read = maybe_bytes_read.release_value();
if (bytes_read.is_empty()) {
dbgln_if(EVENTLOOP_DEBUG, "RPC client disconnected");
shutdown();
return;
}
VERIFY(nread == sizeof(length));
VERIFY(bytes_read.size() == sizeof(length));
auto request_buffer = ByteBuffer::create_uninitialized(length).release_value();
maybe_nread = m_socket->read(request_buffer.bytes());
if (maybe_nread.is_error()) {
dbgln("InspectorServerConnection: Failed to read message content from inspector server connection: {}", maybe_nread.error());
maybe_bytes_read = m_socket->read(request_buffer.bytes());
if (maybe_bytes_read.is_error()) {
dbgln("InspectorServerConnection: Failed to read message content from inspector server connection: {}", maybe_bytes_read.error());
shutdown();
return;
}
nread = maybe_nread.release_value();
bytes_read = maybe_bytes_read.release_value();
auto request_json = JsonValue::from_string(request_buffer);
if (request_json.is_error() || !request_json.value().is_object()) {

View file

@ -31,7 +31,7 @@ public:
// ^Stream
virtual bool is_readable() const override { return m_stream.is_readable(); }
virtual ErrorOr<size_t> read(Bytes bytes) override
virtual ErrorOr<Bytes> read(Bytes bytes) override
{
if (m_current_byte.has_value() && is_aligned_to_byte_boundary()) {
bytes[0] = m_current_byte.release_value();

View file

@ -29,15 +29,15 @@ public:
// FIXME: It doesn't make sense to truncate a memory stream. Therefore, we don't do anything here. Is that fine?
virtual ErrorOr<void> truncate(off_t) override { return Error::from_errno(ENOTSUP); }
virtual ErrorOr<size_t> read(Bytes bytes) override
virtual ErrorOr<Bytes> read(Bytes bytes) override
{
auto to_read = min(remaining(), bytes.size());
if (to_read == 0)
return 0;
return Bytes {};
m_bytes.slice(m_offset, to_read).copy_to(bytes);
m_offset += to_read;
return bytes.size();
return bytes.trim(to_read);
}
virtual ErrorOr<off_t> seek(i64 offset, SeekMode seek_mode = SeekMode::SetPosition) override

View file

@ -107,7 +107,7 @@ ErrorOr<void> send_version_identifier_and_method_selection_message(Core::Stream:
return Error::from_string_literal("SOCKS negotiation failed: Failed to send version identifier and method selection message");
Socks5InitialResponse response;
size = TRY(socket.read({ &response, sizeof(response) }));
size = TRY(socket.read({ &response, sizeof(response) })).size();
if (size != sizeof(response))
return Error::from_string_literal("SOCKS negotiation failed: Failed to receive initial response");
@ -169,7 +169,7 @@ ErrorOr<Reply> send_connect_request_message(Core::Stream::Socket& socket, Core::
return Error::from_string_literal("SOCKS negotiation failed: Failed to send connect request");
Socks5ConnectResponseHeader response_header;
size = TRY(socket.read({ &response_header, sizeof(response_header) }));
size = TRY(socket.read({ &response_header, sizeof(response_header) })).size();
if (size != sizeof(response_header))
return Error::from_string_literal("SOCKS negotiation failed: Failed to receive connect response header");
@ -177,26 +177,26 @@ ErrorOr<Reply> send_connect_request_message(Core::Stream::Socket& socket, Core::
return Error::from_string_literal("SOCKS negotiation failed: Invalid version identifier");
u8 response_address_type;
size = TRY(socket.read({ &response_address_type, sizeof(response_address_type) }));
size = TRY(socket.read({ &response_address_type, sizeof(response_address_type) })).size();
if (size != sizeof(response_address_type))
return Error::from_string_literal("SOCKS negotiation failed: Failed to receive connect response address type");
switch (AddressType(response_address_type)) {
case AddressType::IPV4: {
u8 response_address_data[4];
size = TRY(socket.read({ response_address_data, sizeof(response_address_data) }));
size = TRY(socket.read({ response_address_data, sizeof(response_address_data) })).size();
if (size != sizeof(response_address_data))
return Error::from_string_literal("SOCKS negotiation failed: Failed to receive connect response address data");
break;
}
case AddressType::DomainName: {
u8 response_address_length;
size = TRY(socket.read({ &response_address_length, sizeof(response_address_length) }));
size = TRY(socket.read({ &response_address_length, sizeof(response_address_length) })).size();
if (size != sizeof(response_address_length))
return Error::from_string_literal("SOCKS negotiation failed: Failed to receive connect response address length");
ByteBuffer buffer;
buffer.resize(response_address_length);
size = TRY(socket.read(buffer));
size = TRY(socket.read(buffer)).size();
if (size != response_address_length)
return Error::from_string_literal("SOCKS negotiation failed: Failed to receive connect response address data");
break;
@ -207,7 +207,7 @@ ErrorOr<Reply> send_connect_request_message(Core::Stream::Socket& socket, Core::
}
u16 bound_port;
size = TRY(socket.read({ &bound_port, sizeof(bound_port) }));
size = TRY(socket.read({ &bound_port, sizeof(bound_port) })).size();
if (size != sizeof(bound_port))
return Error::from_string_literal("SOCKS negotiation failed: Failed to receive connect response bound port");
@ -247,7 +247,7 @@ ErrorOr<u8> send_username_password_authentication_message(Core::Stream::Socket&
return Error::from_string_literal("SOCKS negotiation failed: Failed to send username/password authentication message");
Socks5UsernamePasswordResponse response;
size = TRY(socket.read({ &response, sizeof(response) }));
size = TRY(socket.read({ &response, sizeof(response) })).size();
if (size != sizeof(response))
return Error::from_string_literal("SOCKS negotiation failed: Failed to receive username/password authentication response");

View file

@ -37,7 +37,7 @@ public:
virtual ~SOCKSProxyClient() override;
// ^Stream::Stream
virtual ErrorOr<size_t> read(Bytes bytes) override { return m_socket.read(bytes); }
virtual ErrorOr<Bytes> read(Bytes bytes) override { return m_socket.read(bytes); }
virtual ErrorOr<size_t> write(ReadonlyBytes bytes) override { return m_socket.write(bytes); }
virtual bool is_eof() const override { return m_socket.is_eof(); }
virtual bool is_open() const override { return m_socket.is_open(); }

View file

@ -41,7 +41,7 @@ bool Stream::read_or_error(Bytes buffer)
return false;
}
nread += result.value();
nread += result.value().size();
} while (nread < buffer.size());
return true;
@ -156,7 +156,7 @@ ErrorOr<void> File::open_path(StringView filename, mode_t permissions)
bool File::is_readable() const { return has_flag(m_mode, OpenMode::Read); }
bool File::is_writable() const { return has_flag(m_mode, OpenMode::Write); }
ErrorOr<size_t> File::read(Bytes buffer)
ErrorOr<Bytes> File::read(Bytes buffer)
{
if (!has_flag(m_mode, OpenMode::Read)) {
// NOTE: POSIX says that if the fd is not open for reading, the call
@ -167,7 +167,7 @@ ErrorOr<size_t> File::read(Bytes buffer)
ssize_t nread = TRY(System::read(m_fd, buffer));
m_last_read_was_eof = nread == 0;
return nread;
return buffer.trim(nread);
}
ErrorOr<size_t> File::write(ReadonlyBytes buffer)
@ -322,7 +322,7 @@ ErrorOr<void> Socket::connect_inet(int fd, SocketAddress const& address)
return System::connect(fd, bit_cast<struct sockaddr*>(&addr), sizeof(addr));
}
ErrorOr<size_t> PosixSocketHelper::read(Bytes buffer, int flags)
ErrorOr<Bytes> PosixSocketHelper::read(Bytes buffer, int flags)
{
if (!is_open()) {
return Error::from_errno(ENOTCONN);
@ -337,7 +337,7 @@ ErrorOr<size_t> PosixSocketHelper::read(Bytes buffer, int flags)
if (m_last_read_was_eof && m_notifier)
m_notifier->set_enabled(false);
return nread;
return buffer.trim(nread);
}
ErrorOr<size_t> PosixSocketHelper::write(ReadonlyBytes buffer)
@ -554,7 +554,7 @@ ErrorOr<pid_t> LocalSocket::peer_pid() const
ErrorOr<size_t> LocalSocket::read_without_waiting(Bytes buffer)
{
return m_helper.read(buffer, MSG_DONTWAIT);
return TRY(m_helper.read(buffer, MSG_DONTWAIT)).size();
}
ErrorOr<int> LocalSocket::release_fd()

View file

@ -31,9 +31,9 @@ public:
virtual bool is_readable() const { return false; }
/// Reads into a buffer, with the maximum size being the size of the buffer.
/// The amount of bytes read can be smaller than the size of the buffer.
/// Returns either the amount of bytes read, or an errno in the case of
/// Returns either the bytes that were read, or an errno in the case of
/// failure.
virtual ErrorOr<size_t> read(Bytes) = 0;
virtual ErrorOr<Bytes> read(Bytes) = 0;
/// Tries to fill the entire buffer through reading. Returns whether the
/// buffer was filled without an error.
virtual bool read_or_error(Bytes);
@ -194,7 +194,7 @@ public:
}
virtual bool is_readable() const override;
virtual ErrorOr<size_t> read(Bytes) override;
virtual ErrorOr<Bytes> read(Bytes) override;
virtual bool is_writable() const override;
virtual ErrorOr<size_t> write(ReadonlyBytes) override;
virtual bool is_eof() const override;
@ -243,7 +243,7 @@ public:
int fd() const { return m_fd; }
void set_fd(int fd) { m_fd = fd; }
ErrorOr<size_t> read(Bytes, int flags = 0);
ErrorOr<Bytes> read(Bytes, int flags = 0);
ErrorOr<size_t> write(ReadonlyBytes);
bool is_eof() const { return !is_open() || m_last_read_was_eof; }
@ -292,7 +292,7 @@ public:
virtual bool is_readable() const override { return is_open(); }
virtual bool is_writable() const override { return is_open(); }
virtual ErrorOr<size_t> read(Bytes buffer) override { return m_helper.read(buffer); }
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_helper.read(buffer); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_helper.write(buffer); }
virtual bool is_eof() const override { return m_helper.is_eof(); }
virtual bool is_open() const override { return m_helper.is_open(); };
@ -351,7 +351,7 @@ public:
return *this;
}
virtual ErrorOr<size_t> read(Bytes buffer) override
virtual ErrorOr<Bytes> read(Bytes buffer) override
{
auto pending_bytes = TRY(this->pending_bytes());
if (pending_bytes > buffer.size()) {
@ -426,7 +426,7 @@ public:
virtual bool is_readable() const override { return is_open(); }
virtual bool is_writable() const override { return is_open(); }
virtual ErrorOr<size_t> read(Bytes buffer) override { return m_helper.read(buffer); }
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_helper.read(buffer); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_helper.write(buffer); }
virtual bool is_eof() const override { return m_helper.is_eof(); }
virtual bool is_open() const override { return m_helper.is_open(); }
@ -523,7 +523,7 @@ public:
T& stream() { return *m_stream; }
T const& stream() const { return *m_stream; }
ErrorOr<size_t> read(Bytes buffer)
ErrorOr<Bytes> read(Bytes buffer)
{
if (!stream().is_open())
return Error::from_errno(ENOTCONN);
@ -552,7 +552,7 @@ public:
m_buffered_size -= amount_to_take;
}
return buffer_nread;
return Bytes { buffer.data(), buffer_nread };
}
// Reads into the buffer until \n is encountered.
@ -715,7 +715,7 @@ private:
break;
return result.error();
}
auto read_size = result.value();
auto read_size = result.value().size();
m_buffered_size += read_size;
nread += read_size;
break;
@ -752,7 +752,7 @@ public:
BufferedSeekable& operator=(BufferedSeekable&& other) = default;
virtual bool is_readable() const override { return m_helper.stream().is_readable(); }
virtual ErrorOr<size_t> read(Bytes buffer) override { return m_helper.read(move(buffer)); }
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_helper.read(move(buffer)); }
virtual bool is_writable() const override { return m_helper.stream().is_writable(); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_helper.stream().write(buffer); }
virtual bool is_eof() const override { return m_helper.is_eof(); }
@ -823,7 +823,7 @@ public:
}
virtual bool is_readable() const override { return m_helper.stream().is_readable(); }
virtual ErrorOr<size_t> read(Bytes buffer) override { return m_helper.read(move(buffer)); }
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_helper.read(move(buffer)); }
virtual bool is_writable() const override { return m_helper.stream().is_writable(); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_helper.stream().write(buffer); }
virtual bool is_eof() const override { return m_helper.is_eof(); }
@ -911,7 +911,7 @@ public:
}
virtual bool is_readable() const override { return m_socket.is_readable(); }
virtual ErrorOr<size_t> read(Bytes buffer) override { return m_socket.read(move(buffer)); }
virtual ErrorOr<Bytes> read(Bytes buffer) override { return m_socket.read(move(buffer)); }
virtual bool is_writable() const override { return m_socket.is_writable(); }
virtual ErrorOr<size_t> write(ReadonlyBytes buffer) override { return m_socket.write(buffer); }
virtual bool is_eof() const override { return m_socket.is_eof(); }

View file

@ -63,7 +63,7 @@ String Job::read_line(size_t size)
ByteBuffer Job::receive(size_t size)
{
ByteBuffer buffer = ByteBuffer::create_uninitialized(size).release_value_but_fixme_should_propagate_errors();
auto nread = MUST(m_socket->read(buffer));
auto nread = MUST(m_socket->read(buffer)).size();
return buffer.slice(0, nread);
}

View file

@ -172,7 +172,7 @@ ErrorOr<ByteBuffer> Job::receive(size_t size)
auto result = m_socket->read(buffer);
if (result.is_error() && result.error().is_errno() && result.error().code() == EINTR)
continue;
nread = TRY(result);
nread = TRY(result).size();
break;
} while (true);
return buffer.slice(0, nread);

View file

@ -51,10 +51,10 @@ void Request::stream_into_impl(T& stream)
break;
if (result.is_error())
continue;
auto nread = result.value();
if (nread == 0)
auto read_bytes = result.release_value();
if (read_bytes.is_empty())
break;
if (!stream.write_or_error({ buf, nread })) {
if (!stream.write_or_error(read_bytes)) {
// FIXME: What do we do here?
TODO();
}

View file

@ -18,18 +18,18 @@ constexpr static size_t MaximumApplicationDataChunkSize = 16 * KiB;
namespace TLS {
ErrorOr<size_t> TLSv12::read(Bytes bytes)
ErrorOr<Bytes> TLSv12::read(Bytes bytes)
{
m_eof = false;
auto size_to_read = min(bytes.size(), m_context.application_buffer.size());
if (size_to_read == 0) {
m_eof = true;
return 0;
return Bytes {};
}
m_context.application_buffer.span().slice(0, size_to_read).copy_to(bytes);
m_context.application_buffer = m_context.application_buffer.slice(size_to_read, m_context.application_buffer.size() - size_to_read);
return size_to_read;
return Bytes { bytes.data(), size_to_read };
}
String TLSv12::read_line(size_t max_size)
@ -186,7 +186,7 @@ ErrorOr<void> TLSv12::read_from_socket()
u8 buffer[16 * KiB];
Bytes bytes { buffer, array_size(buffer) };
size_t nread = 0;
Bytes read_bytes {};
auto& stream = underlying_stream();
do {
auto result = stream.read(bytes);
@ -198,9 +198,9 @@ ErrorOr<void> TLSv12::read_from_socket()
}
continue;
}
nread = result.release_value();
consume(bytes.slice(0, nread));
} while (nread > 0 && !m_context.critical_error);
read_bytes = result.release_value();
consume(read_bytes);
} while (!read_bytes.is_empty() && !m_context.critical_error);
return {};
}

View file

@ -356,9 +356,9 @@ public:
/// Reads into a buffer, with the maximum size being the size of the buffer.
/// The amount of bytes read can be smaller than the size of the buffer.
/// Returns either the amount of bytes read, or an errno in the case of
/// Returns either the bytes that were read, or an errno in the case of
/// failure.
virtual ErrorOr<size_t> read(Bytes) override;
virtual ErrorOr<Bytes> read(Bytes) override;
/// Tries to write the entire contents of the buffer. It is possible for
/// less than the full buffer to be written. Returns either the amount of

View file

@ -56,8 +56,8 @@ void WebSocketImpl::connect(ConnectionInfo const& connection_info)
ErrorOr<ByteBuffer> WebSocketImpl::read(int max_size)
{
auto buffer = TRY(ByteBuffer::create_uninitialized(max_size));
auto nread = TRY(m_socket->read(buffer));
return buffer.slice(0, nread);
auto read_bytes = TRY(m_socket->read(buffer));
return buffer.slice(0, read_bytes.size());
}
ErrorOr<String> WebSocketImpl::read_line(size_t size)