mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
AK: Add OutputBufferedStream
This class, in a similar fashion to what has been done with `InputBufferedStream`, postpones write to the stream until an internal buffer is full. This patch also adds the `OutputBufferedFile` alias.
This commit is contained in:
parent
8c34959b53
commit
af6dc267d3
Notes:
sideshowbarker
2024-07-16 23:05:02 +09:00
Author: https://github.com/LucasChollet Commit: https://github.com/SerenityOS/serenity/commit/af6dc267d3 Pull-request: https://github.com/SerenityOS/serenity/pull/18590 Reviewed-by: https://github.com/timschumi ✅
2 changed files with 76 additions and 0 deletions
|
@ -322,9 +322,84 @@ private:
|
|||
BufferedHelper<T> m_helper;
|
||||
};
|
||||
|
||||
template<StreamLike T>
|
||||
class OutputBufferedStream final : public Stream {
|
||||
public:
|
||||
static ErrorOr<NonnullOwnPtr<OutputBufferedStream<T>>> create(NonnullOwnPtr<T> stream, size_t buffer_size = 16 * KiB)
|
||||
{
|
||||
if (buffer_size == 0)
|
||||
return Error::from_errno(EINVAL);
|
||||
if (!stream->is_open())
|
||||
return Error::from_errno(ENOTCONN);
|
||||
|
||||
auto buffer = TRY(CircularBuffer::create_empty(buffer_size));
|
||||
|
||||
return adopt_nonnull_own_or_enomem(new OutputBufferedStream<T>(move(stream), move(buffer)));
|
||||
}
|
||||
|
||||
OutputBufferedStream(OutputBufferedStream&& other) = default;
|
||||
OutputBufferedStream& operator=(OutputBufferedStream&& other) = default;
|
||||
|
||||
virtual ErrorOr<Bytes> read_some(Bytes buffer) override
|
||||
{
|
||||
TRY(flush_buffer());
|
||||
return m_stream->read_some(buffer);
|
||||
}
|
||||
|
||||
virtual ErrorOr<size_t> write_some(ReadonlyBytes buffer) override
|
||||
{
|
||||
if (!m_stream->is_open())
|
||||
return Error::from_errno(ENOTCONN);
|
||||
|
||||
auto const written = m_buffer.write(buffer);
|
||||
|
||||
if (m_buffer.empty_space() == 0)
|
||||
TRY(m_buffer.flush_to_stream(*m_stream));
|
||||
|
||||
return written;
|
||||
}
|
||||
|
||||
virtual bool is_eof() const override
|
||||
{
|
||||
MUST(flush_buffer());
|
||||
return m_stream->is_eof();
|
||||
}
|
||||
|
||||
virtual bool is_open() const override { return m_stream->is_open(); }
|
||||
|
||||
virtual void close() override
|
||||
{
|
||||
MUST(flush_buffer());
|
||||
m_stream->close();
|
||||
}
|
||||
|
||||
ErrorOr<void> flush_buffer() const
|
||||
{
|
||||
while (m_buffer.used_space() > 0)
|
||||
TRY(m_buffer.flush_to_stream(*m_stream));
|
||||
return {};
|
||||
}
|
||||
|
||||
virtual ~OutputBufferedStream() override
|
||||
{
|
||||
MUST(flush_buffer());
|
||||
}
|
||||
|
||||
private:
|
||||
OutputBufferedStream(NonnullOwnPtr<T> stream, CircularBuffer buffer)
|
||||
: m_stream(move(stream))
|
||||
, m_buffer(move(buffer))
|
||||
{
|
||||
}
|
||||
|
||||
mutable NonnullOwnPtr<T> m_stream;
|
||||
mutable CircularBuffer m_buffer;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#if USING_AK_GLOBALLY
|
||||
using AK::BufferedHelper;
|
||||
using AK::InputBufferedSeekable;
|
||||
using AK::OutputBufferedStream;
|
||||
#endif
|
||||
|
|
|
@ -106,5 +106,6 @@ private:
|
|||
AK_ENUM_BITWISE_OPERATORS(File::OpenMode)
|
||||
|
||||
using InputBufferedFile = InputBufferedSeekable<File>;
|
||||
using OutputBufferedFile = OutputBufferedStream<File>;
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue