13 #include <type_traits>
26 template<
typename T,
class Allocator = std::allocator<T>>
29 using BufferT = std::vector<T, Allocator>;
37 : compact_threshold_(compact_threshold)
52 parsed_data_.emplace<D>();
63 parsed_dataB_.emplace<D>();
75 parsed_data_.emplace<D>();
76 parsed_data_type_ = type;
92 return std::any_cast<D&>(parsed_data_);
104 return std::any_cast<D&>(parsed_dataB_);
111 std::optional<uint64_t>
GetAnyType() {
return parsed_data_type_; }
133 parsed_data_.reset();
134 parsed_dataB_.reset();
135 parsed_data_type_ = std::nullopt;
160 bool Empty() const noexcept {
return read_offset_ >= buffer_.size(); }
163 size_t Size() noexcept {
return read_offset_ >= buffer_.size() ? 0 : buffer_.size() - read_offset_; }
175 return { buffer_.data() + read_offset_, 1 };
186 std::span<const T>
Front(std::size_t length) noexcept
192 const auto logical_size = buffer_.size() - read_offset_;
193 return logical_size < length ? std::span<const T>{}
194 : std::span<const T>{ buffer_.data() + read_offset_, length };
202 std::span<const T>
Data() noexcept
208 return { buffer_.data() + read_offset_, buffer_.size() - read_offset_ };
227 if (read_offset_ == 0) {
228 taken = std::move(buffer_);
230 taken.assign(buffer_.begin() +
static_cast<std::ptrdiff_t
>(read_offset_), buffer_.end());
254 void Pop(std::size_t length)
256 if (length == 0 ||
Empty()) {
272 return length == 0 || (read_offset_ < buffer_.size() && buffer_.size() - read_offset_ >= length);
282 CompactFrontIfNeeded();
284 buffer_.push_back(value);
294 CompactFrontIfNeeded();
296 buffer_.push_back(std::move(value));
305 void Push(std::span<const T> value)
307 CompactFrontIfNeeded();
309 buffer_.insert(buffer_.end(), value.begin(), value.end());
320 CompactFrontIfNeeded();
322 UintVar len(
static_cast<uint64_t
>(value.size()));
323 buffer_.insert(buffer_.end(), len.
begin(), len.
end());
324 buffer_.insert(buffer_.end(), value.begin(), value.end());
341 return uint64_t(*uintv);
362 const auto& uv_msb = buffer_[read_offset_];
365 const auto logical_size = buffer_.size() - read_offset_;
366 if (logical_size >= uv_len) {
367 auto val =
UintVar(std::span<const T>{ buffer_.data() + read_offset_, uv_len });
396 const auto& uv_msb = buffer_[read_offset_];
399 auto logical_size = buffer_.size() - read_offset_;
400 if (logical_size >= uv_len) {
401 auto len =
UintVar(std::span<const T>{ buffer_.data() + read_offset_, uv_len });
402 if (logical_size >= uv_len + uint64_t(len)) {
404 auto v = std::span<const T>{ buffer_.data() + read_offset_, uint64_t(len) };
405 auto bytes = std::vector<uint8_t>(v.begin(), v.end());
406 PopInternal(uint64_t(len));
416 void CompactFrontIfNeeded()
419 if (read_offset_ == 0) {
423 const std::size_t logical_size = buffer_.size() - read_offset_;
425 if (read_offset_ < compact_threshold_ && read_offset_ <= logical_size) {
429 if (read_offset_ >= buffer_.size()) {
435 if constexpr (std::is_trivially_copyable_v<T>) {
436 std::memmove(buffer_.data(), buffer_.data() + read_offset_, logical_size *
sizeof(T));
438 std::move(buffer_.begin() +
static_cast<std::ptrdiff_t
>(read_offset_), buffer_.end(), buffer_.begin());
441 buffer_.resize(logical_size);
445 void PopInternal(std::size_t length)
447 if (read_offset_ >= buffer_.size() || length >= buffer_.size() - read_offset_) {
453 read_offset_ += length;
458 std::any parsed_data_;
459 std::any parsed_dataB_;
460 std::optional<uint64_t> parsed_data_type_;
461 std::size_t read_offset_{ 0 };
462 std::size_t compact_threshold_{ 4096 };
Contiguous append-only stream accumulator with a logical read offset and parser scratch state.
Definition: stream_buffer.h:28
void Push(std::span< const T > value)
Appends a copy of a contiguous value range.
Definition: stream_buffer.h:305
std::optional< std::vector< uint8_t > > DecodeBytes()
Definition: stream_buffer.h:390
std::optional< uint64_t > DecodeUintV(bool pop=true)
Definition: stream_buffer.h:337
void PushLengthBytes(std::span< const T > value)
Appends a QUIC variable-length count followed by the supplied values.
Definition: stream_buffer.h:318
void Push(T &&value)
Moves one value to the back of the stream.
Definition: stream_buffer.h:292
void Clear()
Clears unread data and all parser scratch state.
Definition: stream_buffer.h:123
std::span< const T > Front() noexcept
Get the first data byte in stream buffer.
Definition: stream_buffer.h:169
bool Available(std::size_t length) const noexcept
Checks if length bytes are available for front.
Definition: stream_buffer.h:270
StreamBuffer(std::size_t compact_threshold=4096)
Constructs an empty stream buffer.
Definition: stream_buffer.h:36
void ResetAnyB()
Replaces the secondary parser scratch object with a default-constructed D.
Definition: stream_buffer.h:147
void ResetAny()
Clears both parser scratch objects and the optional parser type without changing stream data.
Definition: stream_buffer.h:131
void ResetAnyB()
Clears only the secondary parser scratch object.
Definition: stream_buffer.h:139
bool Empty() const noexcept
Definition: stream_buffer.h:160
bool AnyHasValueB()
Definition: stream_buffer.h:157
void InitAny()
Initialize the parsed data.
Definition: stream_buffer.h:50
std::span< const T > Front(std::size_t length) noexcept
Front length number of data bytes.
Definition: stream_buffer.h:186
void SetAnyType(uint64_t type)
Set the user-defined parsed data type value.
Definition: stream_buffer.h:117
void Pop(std::size_t length)
Consumes up to length unread elements.
Definition: stream_buffer.h:254
std::optional< uint64_t > GetAnyType()
Get the user defined parsed type value.
Definition: stream_buffer.h:111
void InitAnyB()
Initializes the secondary parser scratch object as D.
Definition: stream_buffer.h:61
BufferT TakeAll()
Surrender everything not yet read, leaving the buffer empty.
Definition: stream_buffer.h:224
std::optional< UintVar > ReadUintV(bool pop=true)
Definition: stream_buffer.h:356
void InitAny(uint64_t type)
Initialize the parsed data and type.
Definition: stream_buffer.h:73
bool AnyHasValue()
Definition: stream_buffer.h:154
std::span< const T > Data() noexcept
All readable data bytes in the stream buffer.
Definition: stream_buffer.h:202
D & GetAny()
Get the parsed data.
Definition: stream_buffer.h:90
size_t Size() noexcept
Definition: stream_buffer.h:163
D & GetAnyB()
Gets the secondary parser scratch object.
Definition: stream_buffer.h:102
void Pop()
Consumes one unread element, or does nothing when empty.
Definition: stream_buffer.h:240
void Push(const T &value)
Copies one value to the back of the stream.
Definition: stream_buffer.h:280
constexpr auto end() const noexcept
Definition: uintvar.h:166
constexpr std::size_t Size() const noexcept
Definition: uintvar.h:153
constexpr auto begin() const noexcept
Definition: uintvar.h:163
Definition: attributes.h:13