Pigweed
 
Loading...
Searching...
No Matches
pw::multibuf::MultiBuf Class Reference

#include <multibuf.h>

Inheritance diagram for pw::multibuf::MultiBuf:
pw::multibuf::MultiBufChunks

Classes

class  const_iterator
 A const std::forward_iterator over the bytes of a MultiBuf. More...
 
class  iterator
 An std::forward_iterator over the bytes of a MultiBuf. More...
 

Public Types

using element_type = std::byte
 
using value_type = std::byte
 
using pointer = std::byte *
 
using const_pointer = const std::byte *
 
using reference = std::byte &
 
using const_reference = const std::byte &
 
using difference_type = std::ptrdiff_t
 
using size_type = std::size_t
 

Public Member Functions

 MultiBuf (const MultiBuf &)=delete
 
MultiBufoperator= (const MultiBuf &)=delete
 
constexpr MultiBuf (MultiBuf &&other) noexcept=default
 
MultiBufoperator= (MultiBuf &&other) noexcept=default
 
void Release () noexcept
 
 ~MultiBuf ()=default
 This destructor will acquire a mutex and is not IRQ safe.
 
size_t size () const
 
bool empty () const
 
bool IsContiguous () const
 
std::optional< ByteSpan > ContiguousSpan ()
 
std::optional< ConstByteSpan > ContiguousSpan () const
 
iterator begin ()
 Returns an iterator pointing to the first byte of this MultiBuf.
 
const_iterator begin () const
 Returns a const iterator pointing to the first byte of this MultiBuf.
 
const_iterator cbegin () const
 Returns a const iterator pointing to the first byte of this MultiBuf.
 
iterator end ()
 Returns an iterator pointing to the end of this MultiBuf.
 
const_iterator end () const
 Returns a const iterator pointing to the end of this MultiBuf.
 
const_iterator cend () const
 Returns a const iterator pointing to the end of this MultiBuf.
 
bool ClaimPrefix (size_t bytes_to_claim)
 
bool ClaimSuffix (size_t bytes_to_claim)
 
void DiscardPrefix (size_t bytes_to_discard)
 
void Slice (size_t begin, size_t end)
 
void Truncate (size_t len)
 
void TruncateAfter (iterator pos)
 
std::optional< MultiBufTakePrefix (size_t bytes_to_take)
 
std::optional< MultiBufTakeSuffix (size_t bytes_to_take)
 
void PushPrefix (MultiBuf &&front)
 
void PushSuffix (MultiBuf &&tail)
 
StatusWithSize CopyTo (ByteSpan dest, size_t position=0) const
 
StatusWithSize CopyFrom (ConstByteSpan source, size_t position=0)
 
StatusWithSize CopyFromAndTruncate (ConstByteSpan source, size_t position=0)
 
void PushFrontChunk (OwnedChunk &&chunk)
 
void PushBackChunk (OwnedChunk &&chunk)
 
OwnedChunk TakeFrontChunk ()
 
MultiBufChunks::iterator InsertChunk (MultiBufChunks::iterator position, OwnedChunk &&chunk)
 
std::tuple< MultiBufChunks::iterator, OwnedChunkTakeChunk (MultiBufChunks::iterator position)
 
constexpr MultiBufChunksChunks ()
 Returns a Chunk-oriented view of this MultiBuf.
 
constexpr const MultiBufChunksChunks () const
 Returns a const Chunk-oriented view of this MultiBuf.
 
constexpr const MultiBufChunksConstChunks () const
 Returns a const Chunk-oriented view of this MultiBuf.
 

Static Public Member Functions

static MultiBuf FromChunk (OwnedChunk &&chunk)
 

Detailed Description

A byte buffer optimized for zero-copy data transfer.

A MultiBuf consists of multiple Chunks of data.

MultiBuf inherits privately from MultiBufChunks. This allows one class to provide either a byte-oriented or a Chunk-oriented interface, and keeps those interfaces separate.

Member Function Documentation

◆ ClaimPrefix()

bool pw::multibuf::MultiBuf::ClaimPrefix ( size_t  bytes_to_claim)

Attempts to add bytes_to_claim to the front of this buffer by advancing its range backwards in memory. Returns true if the operation succeeded.

This will only succeed if the first Chunk in this buffer points to a section of a region that has unreferenced bytes preceding it. See also Chunk::ClaimPrefix.

This method will acquire a mutex and is not IRQ safe.

◆ ClaimSuffix()

bool pw::multibuf::MultiBuf::ClaimSuffix ( size_t  bytes_to_claim)

Attempts to add bytes_to_claim to the front of this buffer by advancing its range forwards in memory. Returns true if the operation succeeded.

This will only succeed if the last Chunk in this buffer points to a section of a region that has unreferenced bytes following it. See also Chunk::ClaimSuffix.

This method will acquire a mutex and is not IRQ safe.

◆ ContiguousSpan()

std::optional< ByteSpan > pw::multibuf::MultiBuf::ContiguousSpan ( )
inline

If the MultiBuf is contiguous, returns it as a span. The span will be empty if the MultiBuf is empty.

A MultiBuf is contiguous if it is comprised of either:

  • one non-empty chunk,
  • only empty chunks, or
  • no chunks at all.

◆ CopyFrom()

StatusWithSize pw::multibuf::MultiBuf::CopyFrom ( ConstByteSpan  source,
size_t  position = 0 
)
inline

Copies bytes from the provided buffer into the multibuf.

Parameters
[in]sourceData to copy into the MultiBuf.
[in]positionOffset in the MultiBuf from which to start.
Returns
embed:rst:leading-asterisk
 
* 
*  .. pw-status-codes::
* 
*     OK: All bytes were copied. The :cpp:class:`pw::StatusWithSize` includes
*     the number of bytes copied, which is the size of the `MultiBuf`.
* 
*     RESOURCE_EXHAUSTED: Some bytes were copied, but the source was larger
*     than the destination. The :cpp:class:`pw::StatusWithSize` includes the
*     number of bytes copied.
* 
*  

◆ CopyFromAndTruncate()

StatusWithSize pw::multibuf::MultiBuf::CopyFromAndTruncate ( ConstByteSpan  source,
size_t  position = 0 
)
inline

Copies bytes from the provided buffer into this MultiBuf and truncates it to the end of the copied data. This is a more efficient version of:

if (multibuf.CopyFrom(destination).ok()) {
multibuf.Truncate(destination.size());
}
Parameters
[in]sourceData to copy into the MultiBuf.
[in]positionOffset in the MultiBuf from which to start.
Returns
embed:rst:leading-asterisk
 
* 
*  .. pw-status-codes::
* 
*     OK: All bytes were copied and the :cpp:class:`MultiBuf` was truncated.
*     The :cpp:class:`pw::StatusWithSize` includes the new
*     :cpp:func:`MultiBuf::size`.
* 
*     RESOURCE_EXHAUSTED: Some bytes were copied, but the source buffer was
*     larger than the :cpp:class:`MultiBuf`. The returned
*     :cpp:class:`pw::StatusWithSize` includes the number of bytes copied,
*     which is the size of the :cpp:class:`MultiBuf`.
* 
*  

◆ CopyTo()

StatusWithSize pw::multibuf::MultiBuf::CopyTo ( ByteSpan  dest,
size_t  position = 0 
) const

Copies bytes from the multibuf into the provided buffer.

Parameters
[out]destDestination into which to copy data from the MultiBuf.
[in]positionOffset in the MultiBuf from which to start.
Returns
embed:rst:leading-asterisk
 
* 
*  .. pw-status-codes::
* 
*     OK: All bytes were copied into the destination. The
*     :cpp:class:`pw::StatusWithSize` includes the number of bytes copied,
*     which is the size of the :cpp:class:`MultiBuf`.
* 
*     RESOURCE_EXHAUSTED: Some bytes were copied, but the
*     :cpp:class:`MultiBuf` was larger than the destination buffer. The
*     :cpp:class:`pw::StatusWithSize` includes the number of bytes copied.
* 
*  

◆ DiscardPrefix()

void pw::multibuf::MultiBuf::DiscardPrefix ( size_t  bytes_to_discard)

Shrinks this handle to refer to the data beginning at offset bytes_to_discard.

Does not modify the underlying data. The discarded memory continues to be held by the underlying region as long as any Chunks exist within it. This allows the memory to be later reclaimed using ClaimPrefix.

This method will acquire a mutex and is not IRQ safe.

◆ empty()

bool pw::multibuf::MultiBuf::empty ( ) const

Returns whether the MultiBuf contains any bytes (size() == 0).

This method's complexity is O(Chunks().size()), but will be more efficient than size() == 0 in most cases.

◆ InsertChunk()

MultiBufChunks::iterator pw::multibuf::MultiBuf::InsertChunk ( MultiBufChunks::iterator  position,
OwnedChunk &&  chunk 
)
inline

Inserts chunk into the specified position in the MultiBuf. The Chunk at position will be after the new chunk.

This operation does not move any data and is O(Chunks().size()).

Returns an iterator pointing to the newly-inserted Chunk.

◆ IsContiguous()

bool pw::multibuf::MultiBuf::IsContiguous ( ) const
inline

Returns if the MultiBuf is contiguous. A MultiBuf is contiguous if it is comprised of either:

  • one non-empty chunk,
  • only empty chunks, or
  • no chunks at all.

◆ PushBackChunk()

void pw::multibuf::MultiBuf::PushBackChunk ( OwnedChunk &&  chunk)
inline

Pushes Chunk onto the end of the MultiBuf.

This operation does not move any data and is O(Chunks().size()).

◆ PushFrontChunk()

void pw::multibuf::MultiBuf::PushFrontChunk ( OwnedChunk &&  chunk)
inline

Pushes Chunk onto the front of the MultiBuf.

This operation does not move any data and is O(1).

◆ PushPrefix()

void pw::multibuf::MultiBuf::PushPrefix ( MultiBuf &&  front)

Pushes front onto the front of this MultiBuf.

This operation does not move any data and is O(front.Chunks().size()).

◆ PushSuffix()

void pw::multibuf::MultiBuf::PushSuffix ( MultiBuf &&  tail)
inline

Pushes tail onto the end of this MultiBuf.

This operation does not move any data and is O(Chunks().size()).

◆ Release()

void pw::multibuf::MultiBuf::Release ( )
inlinenoexcept

Decrements the reference count on the underlying chunks of data and empties this MultiBuf so that size() == 0.

Does not modify the underlying data, but may cause it to be deallocated.

This method is equivalent to { MultiBuf _unused = std::move(multibuf); }

This method will acquire a mutex and is not IRQ safe.

◆ size()

size_t pw::multibuf::MultiBuf::size ( ) const
inline

Returns the number of bytes in this container.

This method's complexity is O(Chunks().size()).

◆ Slice()

void pw::multibuf::MultiBuf::Slice ( size_t  begin,
size_t  end 
)

Shrinks this handle to refer to data in the range begin..<end.

Does not modify the underlying data. The discarded memory continues to be held by the underlying region as long as any Chunks exist within it. This allows the memory to be later reclaimed using ClaimPrefix or ClaimSuffix.

This method will acquire a mutex and is not IRQ safe.

◆ TakeChunk()

std::tuple< MultiBufChunks::iterator, OwnedChunk > pw::multibuf::MultiBuf::TakeChunk ( MultiBufChunks::iterator  position)
inline

Removes and returns Chunk from the specified position.

This operation does not move any data and is O(Chunks().size()).

Returns an iterator pointing to the Chunk after the removed Chunk, or Chunks().end() if this was the last Chunk in the MultiBuf.

◆ TakeFrontChunk()

OwnedChunk pw::multibuf::MultiBuf::TakeFrontChunk ( )
inline

Removes the first Chunk.

This operation does not move any data and is O(1).

◆ TakePrefix()

std::optional< MultiBuf > pw::multibuf::MultiBuf::TakePrefix ( size_t  bytes_to_take)

Attempts to shrink this handle to refer to the data beginning at offset bytes_to_take, returning the first bytes_to_take bytes as a new MultiBuf.

If the inner call to AllocateChunkClass fails, this function will return std::nullopt and this handle's span will not change.

This method will acquire a mutex and is not IRQ safe.

◆ TakeSuffix()

std::optional< MultiBuf > pw::multibuf::MultiBuf::TakeSuffix ( size_t  bytes_to_take)

Attempts to shrink this handle to refer only the first len - bytes_to_take bytes, returning the last bytes_to_take bytes as a new MultiBuf.

If the inner call to AllocateChunkClass fails, this function will return std::nullopt and this handle's span will not change.

This method will acquire a mutex and is not IRQ safe.

◆ Truncate()

void pw::multibuf::MultiBuf::Truncate ( size_t  len)

Shrinks this handle to refer to only the first len bytes.

Does not modify the underlying data. The discarded memory continues to be held by the underlying region as long as any Chunks exist within it. This allows the memory to be later reclaimed using ClaimSuffix.

This method will acquire a mutex and is not IRQ safe.

◆ TruncateAfter()

void pw::multibuf::MultiBuf::TruncateAfter ( iterator  pos)

Truncates the MultiBuf after the current iterator. All bytes following the iterator are removed.

Does not modify the underlying data.

This method will acquire a mutex and is not IRQ safe.


The documentation for this class was generated from the following file: