6#include <bond/core/config.h>
9#include <bond/core/exception.h>
10#include <bond/core/traits.h>
11#include <boost/static_assert.hpp>
20template <
typename T, u
int32_t Shift>
21struct VariableUnsignedUnchecked
23 BOOST_STATIC_ASSERT(Shift < 56);
24 static void Read(
const char*& p, T& value)
27 value |= (
byte & 0x7f) << Shift;
30 VariableUnsignedUnchecked<T, Shift + 7>::Read(p, value);
37struct VariableUnsignedUnchecked<T, 0>
39 static void Read(
const char*& p, T& value)
42 value = (
byte & 0x7f);
45 VariableUnsignedUnchecked<T, 7>::Read(p, value);
52struct VariableUnsignedUnchecked<uint16_t, 14>
54 static void Read(
const char*& p, uint16_t& value)
64struct VariableUnsignedUnchecked<uint32_t, 28>
66 static void Read(
const char*& p, uint32_t& value)
76struct VariableUnsignedUnchecked<uint64_t, 56>
78 static void Read(
const char*& p, uint64_t& value)
115 : _blob(buffer, length),
122 return _blob == rhs._blob
123 && _pointer == rhs._pointer;
127 void Read(uint8_t& value)
129 if (_blob.
length() == _pointer)
131 EofException(
sizeof(uint8_t));
134 value =
static_cast<const uint8_t
>(_blob.
content()[_pointer++]);
138 template <
typename T>
141 BOOST_STATIC_ASSERT(std::is_arithmetic<T>::value || std::is_enum<T>::value);
143 if (
sizeof(T) > _blob.
length() - _pointer)
145 EofException(
sizeof(T));
148#if defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86)
152 value = *
reinterpret_cast<const T*
>(_blob.
content() + _pointer);
158 const void*
const src = _blob.
content() + _pointer;
159 std::memcpy(&value, src,
sizeof(T));
162 _pointer +=
sizeof(T);
166 void Read(
void *buffer, uint32_t size)
168 if (size > _blob.
length() - _pointer)
173 const void*
const src = _blob.
content() + _pointer;
174 std::memcpy(buffer, src, size);
180 void Read(blob& blob, uint32_t size)
182 if (size > _blob.
length() - _pointer)
187 blob.assign(_blob, _pointer, size);
193 void Skip(uint32_t size)
195 if (size > _blob.
length() - _pointer)
206 return _pointer == _blob.
length();
210 template <
typename T>
211 void ReadVariableUnsigned(T& value)
213 if (_blob.
length() > _pointer +
sizeof(T) * 8 / 7)
215 const char* ptr = _blob.
content() + _pointer;
216 input_buffer::VariableUnsignedUnchecked<T, 0>::Read(ptr, value);
217 _pointer =
static_cast<uint32_t
>(ptr - _blob.
content());
221 GenericReadVariableUnsigned(*
this, value);
226 [[noreturn]]
void EofException(uint32_t size)
const
228 BOND_THROW(StreamException,
229 "Read out of bounds: " << size <<
" bytes requested, offset: "
230 << _pointer <<
", length: " << _blob.
length());
237 friend blob GetCurrentBuffer(
const InputBuffer& input)
239 return input._blob.range(input._pointer);
244inline InputBuffer CreateInputBuffer(
const InputBuffer& ,
const blob& blob)
246 return InputBuffer(blob);
249inline blob GetBufferRange(
const blob& begin,
const blob& end)
251 return begin.
range(0, begin.length() - end.length());
254BOND_DEFINE_BUFFER_MAGIC(InputBuffer, 0x4249 );
Memory blob.
Definition: blob.h:24
blob range(uint32_t offset, uint32_t length) const
Return a blob object for a range of this object.
Definition: blob.h:153
const char * content() const BOND_NOEXCEPT
Pointer to the content.
Definition: blob.h:192
uint32_t length() const BOND_NOEXCEPT
Length of the content.
Definition: blob.h:204
namespace bond
Definition: apply.h:17