1#ifndef BLUETOE_LINK_LAYER_RING_BUFFER_HPP
2#define BLUETOE_LINK_LAYER_RING_BUFFER_HPP
8#include <bluetoe/buffer.hpp>
9#include <bluetoe/default_pdu_layout.hpp>
26 template < std::
size_t Size,
typename Buffer = read_buffer,
typename Layout = default_pdu_layout >
33 static constexpr std::size_t
size = Size;
47 void reset( std::uint8_t* buffer );
73 void push_front( std::uint8_t* buffer,
const Buffer& pdu );
95 static constexpr std::size_t ll_header_size = 2;
96 static constexpr std::uint16_t wrap_mark = 0;
99 static std::uint8_t pdu_length(
const P& pdu );
101 template <
typename P >
102 static std::size_t pdu_length( P* );
111 std::uint8_t* front_;
114 template < std::
size_t Size,
typename Buffer,
typename Layout >
120 template < std::
size_t Size,
typename Buffer,
typename Layout >
127 Layout::header( buffer, wrap_mark );
130 template < std::
size_t Size,
typename Buffer,
typename Layout >
134 assert( size >= Layout::data_channel_pdu_memory_size( 0 ) );
137 if ( end_ > front_ &&
static_cast< std::ptrdiff_t
>( size ) < end_ - front_ )
139 return Buffer{ front_, size };
142 if ( front_ >= end_ )
144 const std::uint8_t* end_of_buffer = buffer + Size;
147 if (
static_cast< std::ptrdiff_t
>( size ) <= end_of_buffer - front_ )
149 return Buffer{ front_, size };
153 if (
static_cast< std::ptrdiff_t
>( size ) < end_ - buffer )
155 return Buffer{ buffer, size };
159 return Buffer{ 0, 0 };
162 template < std::
size_t Size,
typename Buffer,
typename Layout >
165 assert( pdu.size >= pdu_length( pdu ) );
167 const std::uint8_t* end_of_buffer = buffer + Size;
170 if ( front_ != pdu.buffer && front_ + 1 < end_of_buffer )
172 Layout::header( front_, wrap_mark );
175 const bool was_empty = front_ == end_;
177 front_ = pdu.buffer + pdu_length( pdu );
184 template < std::
size_t Size,
typename Buffer,
typename Layout >
187 return front_ == end_
189 : Buffer{ end_, pdu_length( end_ ) };
192 template < std::
size_t Size,
typename Buffer,
typename Layout >
195 end_ += pdu_length( end_ );
197 const std::uint8_t* end_of_buffer = buffer + Size;
200 if ( end_ != front_ && ( end_ + 1 >= end_of_buffer || end_[ 1 ] == wrap_mark ) )
204 template < std::
size_t Size,
typename Buffer,
typename Layout >
208 return pdu_length( pdu.buffer );
211 template < std::
size_t Size,
typename Buffer,
typename Layout >
212 template <
typename P >
213 std::size_t pdu_ring_buffer< Size, Buffer, Layout >::pdu_length( P* p )
215 return Layout::data_channel_pdu_memory_size( Layout::header( p ) >> 8 );
218 template < std::
size_t Size,
typename Buffer,
typename Layout >
221 return end_ != front_ && ( end_ + pdu_length( end_) ) != front_;
structure, able to store variable sized link layer PDUs in a fixed size ring.
Definition: ring_buffer.hpp:28
bool more_than_one() const
returns true, if the buffer contains at least 2 elements
Definition: ring_buffer.hpp:219
void pop_end(std::uint8_t *buffer)
frees the last PDU at the end of the ring
Definition: ring_buffer.hpp:193
Buffer alloc_front(std::uint8_t *buffer, std::size_t size) const
return a writeable PDU buffer of at least size bytes at the front of the ring
Definition: ring_buffer.hpp:131
pdu_ring_buffer(std::uint8_t *buffer)
sets up the ring to be empty
Definition: ring_buffer.hpp:115
Buffer next_end() const
returns the next PDU from the ring.
Definition: ring_buffer.hpp:185
void reset(std::uint8_t *buffer)
resets the ring to be empty
Definition: ring_buffer.hpp:121
static constexpr std::size_t size
the size of the buffer in bytes
Definition: ring_buffer.hpp:33
void push_front(std::uint8_t *buffer, const Buffer &pdu)
stores the allocated PDU in the ring.
Definition: ring_buffer.hpp:163