From 7d863091bb5812868dcb90f16430507190e98a9a Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Thu, 21 Dec 2017 20:37:38 -0700 Subject: [PATCH] ircd::buffer: Add the stream_buffer. --- include/ircd/buffer.h | 48 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/include/ircd/buffer.h b/include/ircd/buffer.h index 2f8c0cc75..37992f45f 100644 --- a/include/ircd/buffer.h +++ b/include/ircd/buffer.h @@ -57,6 +57,7 @@ namespace ircd::buffer struct mutable_raw_buffer; template struct fixed_buffer; template struct unique_buffer; + struct stream_buffer; template using fixed_const_buffer = fixed_buffer; template using fixed_mutable_buffer = fixed_buffer; @@ -100,7 +101,7 @@ namespace ircd::buffer template class I, class T> size_t copy(const mutable_raw_buffer &, const I &buffer); template class I, class T> size_t consume(I &buffers, const size_t &bytes); - // Convenience copy to stream + // Convenience copy to std stream template std::ostream &operator<<(std::ostream &s, const buffer &buffer); template class I, class T> std::ostream &operator<<(std::ostream &s, const I &buffers); } @@ -115,6 +116,7 @@ namespace ircd using buffer::fixed_buffer; using buffer::unique_buffer; using buffer::null_buffer; + using buffer::stream_buffer; using buffer::fixed_const_buffer; using buffer::fixed_mutable_buffer; using buffer::fixed_const_raw_buffer; @@ -386,6 +388,50 @@ static_assert "ircd::buffer::fixed_buffer must be standard layout" ); +struct ircd::buffer::stream_buffer +:mutable_buffer +{ + mutable_buffer base; + + /// Bytes remaining for writes to the stream buffer (same as size(*this)) + size_t remaining() const + { + assert(begin() <= base.end()); + const size_t ret(std::distance(begin(), base.end())); + assert(ret == size(*this)); + return ret; + } + + /// Bytes used by writes to the stream buffer + size_t consumed() const + { + assert(begin() >= base.begin()); + assert(begin() <= base.end()); + return std::distance(base.begin(), begin()); + } + + /// View the completed portion of the stream + const_buffer completed() const + { + assert(base.begin() <= begin()); + assert(base.begin() + consumed() <= base.end()); + return { base.begin(), base.begin() + consumed() }; + } + + /// Convenience closure presenting the writable window and advancing the + /// window with a consume() for the bytes written in the closure. + using closure = std::function; + void operator()(const closure &closure) + { + consume(*this, closure(*this)); + } + + stream_buffer(const mutable_buffer &base) + :mutable_buffer{base} + ,base{base} + {} +}; + /// Like unique_ptr, this template holds ownership of an allocated buffer /// ///