mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-28 18:40:29 +00:00
AK: Add CircularBuffer::read_with_seekback
This commit is contained in:
parent
afc0e461e1
commit
d717a08003
Notes:
sideshowbarker
2024-07-17 05:19:06 +09:00
Author: https://github.com/timschumi Commit: https://github.com/SerenityOS/serenity/commit/d717a08003 Pull-request: https://github.com/SerenityOS/serenity/pull/16917 Reviewed-by: https://github.com/ADKaster ✅
2 changed files with 43 additions and 0 deletions
|
@ -71,6 +71,7 @@ void CircularBuffer::clear()
|
||||||
{
|
{
|
||||||
m_reading_head = 0;
|
m_reading_head = 0;
|
||||||
m_used_space = 0;
|
m_used_space = 0;
|
||||||
|
m_seekback_limit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bytes CircularBuffer::next_write_span()
|
Bytes CircularBuffer::next_write_span()
|
||||||
|
@ -85,6 +86,17 @@ ReadonlyBytes CircularBuffer::next_read_span() const
|
||||||
return m_buffer.span().slice(m_reading_head, min(capacity() - m_reading_head, m_used_space));
|
return m_buffer.span().slice(m_reading_head, min(capacity() - m_reading_head, m_used_space));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReadonlyBytes CircularBuffer::next_read_span_with_seekback(size_t distance) const
|
||||||
|
{
|
||||||
|
VERIFY(m_seekback_limit <= capacity());
|
||||||
|
VERIFY(distance <= m_seekback_limit);
|
||||||
|
|
||||||
|
// Note: We are adding the capacity once here to ensure that we can wrap around the negative space by using modulo.
|
||||||
|
auto read_offset = (capacity() + m_reading_head + m_used_space - distance) % capacity();
|
||||||
|
|
||||||
|
return m_buffer.span().slice(read_offset, min(capacity() - read_offset, m_seekback_limit));
|
||||||
|
}
|
||||||
|
|
||||||
size_t CircularBuffer::write(ReadonlyBytes bytes)
|
size_t CircularBuffer::write(ReadonlyBytes bytes)
|
||||||
{
|
{
|
||||||
auto remaining = bytes.size();
|
auto remaining = bytes.size();
|
||||||
|
@ -98,6 +110,10 @@ size_t CircularBuffer::write(ReadonlyBytes bytes)
|
||||||
|
|
||||||
m_used_space += written_bytes;
|
m_used_space += written_bytes;
|
||||||
|
|
||||||
|
m_seekback_limit += written_bytes;
|
||||||
|
if (m_seekback_limit > capacity())
|
||||||
|
m_seekback_limit = capacity();
|
||||||
|
|
||||||
remaining -= written_bytes;
|
remaining -= written_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +143,27 @@ Bytes CircularBuffer::read(Bytes bytes)
|
||||||
return bytes.trim(bytes.size() - remaining);
|
return bytes.trim(bytes.size() - remaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ErrorOr<Bytes> CircularBuffer::read_with_seekback(Bytes bytes, size_t distance)
|
||||||
|
{
|
||||||
|
if (distance > m_seekback_limit)
|
||||||
|
return Error::from_string_literal("Tried a seekback read beyond the seekback limit");
|
||||||
|
|
||||||
|
auto remaining = bytes.size();
|
||||||
|
|
||||||
|
while (remaining > 0) {
|
||||||
|
auto const next_span = next_read_span_with_seekback(distance);
|
||||||
|
if (next_span.size() == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
auto written_bytes = next_span.copy_trimmed_to(bytes.slice(bytes.size() - remaining));
|
||||||
|
|
||||||
|
distance -= written_bytes;
|
||||||
|
remaining -= written_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes.trim(bytes.size() - remaining);
|
||||||
|
}
|
||||||
|
|
||||||
ErrorOr<void> CircularBuffer::discard(size_t discarding_size)
|
ErrorOr<void> CircularBuffer::discard(size_t discarding_size)
|
||||||
{
|
{
|
||||||
if (m_used_space < discarding_size)
|
if (m_used_space < discarding_size)
|
||||||
|
|
|
@ -42,6 +42,10 @@ public:
|
||||||
Bytes read(Bytes bytes);
|
Bytes read(Bytes bytes);
|
||||||
ErrorOr<void> discard(size_t discarded_bytes);
|
ErrorOr<void> discard(size_t discarded_bytes);
|
||||||
|
|
||||||
|
/// Compared to `read()`, this starts reading from an offset that is `distance` bytes
|
||||||
|
/// before the current write pointer and allows for reading already-read data.
|
||||||
|
ErrorOr<Bytes> read_with_seekback(Bytes bytes, size_t distance);
|
||||||
|
|
||||||
[[nodiscard]] size_t empty_space() const;
|
[[nodiscard]] size_t empty_space() const;
|
||||||
[[nodiscard]] size_t used_space() const;
|
[[nodiscard]] size_t used_space() const;
|
||||||
[[nodiscard]] size_t capacity() const;
|
[[nodiscard]] size_t capacity() const;
|
||||||
|
@ -57,11 +61,13 @@ private:
|
||||||
|
|
||||||
[[nodiscard]] Bytes next_write_span();
|
[[nodiscard]] Bytes next_write_span();
|
||||||
[[nodiscard]] ReadonlyBytes next_read_span() const;
|
[[nodiscard]] ReadonlyBytes next_read_span() const;
|
||||||
|
[[nodiscard]] ReadonlyBytes next_read_span_with_seekback(size_t distance) const;
|
||||||
|
|
||||||
ByteBuffer m_buffer {};
|
ByteBuffer m_buffer {};
|
||||||
|
|
||||||
size_t m_reading_head {};
|
size_t m_reading_head {};
|
||||||
size_t m_used_space {};
|
size_t m_used_space {};
|
||||||
|
size_t m_seekback_limit {};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue