26 #ifndef INCLUDED_Buffer_h_GUID_55EB8AAF_57A7_49A4_3A3A_49293A72211D
27 #define INCLUDED_Buffer_h_GUID_55EB8AAF_57A7_49A4_3A3A_49293A72211D
34 #include <boost/version.hpp>
35 #include <boost/type_traits.hpp>
37 #if BOOST_VERSION >= 105600
38 #include <boost/align/aligned_allocator.hpp>
57 #if BOOST_VERSION >= 105600
65 typedef boost::alignment::aligned_allocator<
75 static const size_t value = 1;
90 template <
typename ElementType = BufferElement>
93 typedef ElementType
const *const_iterator;
94 typedef ElementType value_type;
97 : m_buf(buf), m_size(size) {}
99 const_iterator begin()
const {
return m_buf; }
101 const_iterator end()
const {
return m_buf + m_size; }
103 size_t size()
const {
return m_size; }
106 ElementType
const *m_buf;
108 static_assert(
sizeof(ElementType) == 1,
109 "Container must have byte-sized elements");
119 typedef typename ContainerType::const_iterator const_iterator;
120 typedef typename ContainerType::value_type ElementType;
123 : m_begin(buf.begin()), m_readIter(buf.begin()), m_end(buf.end()) {}
125 size_t bytesRead()
const {
return m_readIter - m_begin; }
126 size_t bytesRemaining()
const {
return m_end - m_readIter; }
128 template <
typename T>
void read(T &v) {
129 if (bytesRemaining() <
sizeof(T)) {
130 throw std::runtime_error(
131 "Not enough data in the buffer to read this type!");
135 ElementType *dest =
reinterpret_cast<ElementType *
>(&v);
137 auto readEnd = m_readIter +
sizeof(T);
138 std::copy(m_readIter, readEnd, dest);
139 m_readIter = readEnd;
145 if (bytesRemaining() < n) {
146 throw std::runtime_error(
147 "Not enough data in the buffer to read that many bytes!");
149 auto ret = m_readIter;
157 template <
typename T>
void readAligned(T &v,
size_t const alignment) {
166 size_t const alignment) {
177 if (bytesRemaining() < bytes) {
178 throw std::runtime_error(
"Can't skip that many padding "
179 "bytes, not that many bytes "
186 const_iterator m_begin;
187 const_iterator m_readIter;
188 const_iterator m_end;
189 static_assert(
sizeof(ElementType) == 1,
190 "Container must have byte-sized elements");
196 template <
typename CharType>
197 inline BufferReader<ExternalBufferReadingWrapper<CharType> >
206 template <
typename ContainerType = BufferByteVector>
class Buffer {
220 explicit Buffer(ContainerType
const &buf) : m_buf(buf) {}
227 template <
typename InputIterator>
228 Buffer(InputIterator beginIt, InputIterator endIt)
229 : m_buf(beginIt, endIt) {}
234 template <
typename T>
void append(T
const v) {
235 static_assert(!boost::is_pointer<T>::value,
236 "Cannot append the value of a pointer!");
239 ElementType
const *src =
reinterpret_cast<ElementType
const *
>(&v);
240 m_buf.insert(m_buf.end(), src, src +
sizeof(T));
248 template <
typename T>
255 void append(ElementType
const *v,
size_t const n) {
256 m_buf.insert(m_buf.end(), v, v + n);
263 size_t const alignment) {
273 m_buf.insert(m_buf.end(), bytes,
'\0');
282 size_t size()
const {
return m_buf.size(); }
288 ElementType
const *
data()
const {
return m_buf.data(); }
292 static_assert(
sizeof(ElementType) == 1,
293 "Container must have byte-sized elements");
297 #endif // INCLUDED_Buffer_h_GUID_55EB8AAF_57A7_49A4_3A3A_49293A72211D
const_iterator readBytesAligned(size_t const n, size_t const alignment)
Returns an iterator into the buffer valid for n elements, after skipping the necessary number of byte...
Buffer(ContainerType const &buf)
Constructs a buffer wrapper by copy-constructing the contained type.
BufferReader< ContainerType > Reader
The corresponding BufferReader type.
void skipPadding(size_t const bytes)
Skip reading the given number of bytes, assumed to be padding.
char BufferElement
The single-byte element in a buffer.
void appendAligned(ElementType const *v, size_t const n, size_t const alignment)
Append a byte-array's contents, after adding the necessary number of padding bytes to begin the write...
ElementType const * data() const
Provides access to the underlying data.
Traits class specifying the (potentially platform-specific!) preferred alignment for Buffer...
void readAligned(T &v, size_t const alignment)
Get the binary representation of a type from a buffer, after skipping the necessary number of bytes t...
ContainerType & getContents()
Provides access to the underlying container.
size_t computeAlignmentPadding(size_t alignment, size_t currentSize)
Given an alignment in bytes, and a current size of a buffer, return the number of bytes of padding re...
size_t size() const
Gets the current size, in bytes.
Class wrapping an externally-owned and controlled buffer with the vector-like functionality needed to...
void append(ElementType const *v, size_t const n)
Append a byte-array's contents.
Buffer()
Constructs an empty buffer.
A buffer of bytes, built on a byte-vector-like container. Provides methods for easily appending to th...
void appendAligned(T const v, size_t const alignment)
Append the binary representation of a value, after adding the necessary number of padding bytes to be...
std::vector< BufferElement, BufferAllocator > BufferByteVector
A typedef for a vector of bytes usable as a buffer, that might be "over-aligned" in some desirable wa...
std::allocator< BufferElement > BufferAllocator
Allocator type for Buffer - might be usefully aligned.
static const size_t value
Alignment in bytes.
ContainerType::value_type ElementType
The (necessarily byte-size) type of elements in the underlying container.
Provides for a single reading pass over a buffer. It is important that the buffer not change while a ...
void read(T &v)
Get the binary representation of a type from a buffer.
void append(T const v)
Append the binary representation of a value.
Buffer(InputIterator beginIt, InputIterator endIt)
Constructs a buffer by copying from two input iterators, representing a half-open range [beginIt...
Traits class describing actual alignment of Buffer.
BufferReader< ExternalBufferReadingWrapper< CharType > > readExternalBuffer(const CharType *buf, size_t len)
Constructs and returns a buffer reader for an externally-allocated buffer: it's on you to supply a va...
void appendPadding(size_t const bytes)
Append the specified number of bytes of padding.
Reader startReading() const
Returns a reader object, for making a single read pass over the buffer. Do not modify this buffer dur...
const_iterator readBytes(size_t const n)
Returns an iterator into the buffer valid for n elements, and assumes you'll take care of copying the...