view: allow longer words for byte views
This commit is contained in:
parent
e1e036e776
commit
07e66f20d3
44
view.hpp
44
view.hpp
@ -575,6 +575,9 @@ namespace cruft {
|
||||
auto
|
||||
make_byte_view (T &t)
|
||||
{
|
||||
static_assert (std::is_integral_v<ByteT>);
|
||||
static_assert (sizeof (T) % sizeof (ByteT) == 0);
|
||||
|
||||
using cursor_type = std::conditional_t<
|
||||
std::is_const_v<T>,
|
||||
ByteT const*,
|
||||
@ -582,40 +585,43 @@ namespace cruft {
|
||||
>;
|
||||
|
||||
return view {
|
||||
reinterpret_cast<cursor_type> (&t),
|
||||
sizeof (T)
|
||||
cast::alignment<cursor_type> (&t),
|
||||
sizeof (T) / sizeof (ByteT)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
/// returns a reference to a value of the designated type at the front of
|
||||
/// the byte-view. if there is insufficient data for the extraction an
|
||||
/// Returns a reference to a value of the designated type at the front of
|
||||
/// the word-view. if there is insufficient data for the extraction an
|
||||
/// exception will be thrown.
|
||||
///
|
||||
/// there are no validity or other checks performed on the returned data
|
||||
/// There are no validity or other checks performed on the returned data
|
||||
/// this is deliberate, so that the function is safe to call on user
|
||||
/// supplied data during parsing routines. it is up to the user to ensure
|
||||
/// the object is valid.
|
||||
///
|
||||
/// the buffer object is advanced in place so that it no longer covers
|
||||
/// The buffer object is advanced in place so that it no longer covers
|
||||
/// the extract value
|
||||
///
|
||||
/// it is assumed the user has taken care of alignment concerns
|
||||
/// It is assumed the user has taken care of alignment concerns
|
||||
template <
|
||||
typename ValueT,
|
||||
typename ByteT,
|
||||
typename = std::enable_if_t<sizeof (ByteT) == 1>
|
||||
typename WordT,
|
||||
// Only allow calls if the value is a multiple of the word size. It's
|
||||
// useful to allow non-unit words for areas like TCP/IP which tend to
|
||||
// operate on u16 words.
|
||||
typename = std::enable_if_t<sizeof (ValueT) % sizeof (WordT) == 0>
|
||||
>
|
||||
ValueT const&
|
||||
extract (view<const ByteT*> &buffer)
|
||||
extract (view<WordT const*> &buffer)
|
||||
{
|
||||
if (unlikely (sizeof (ValueT) > buffer.size ()))
|
||||
if (unlikely (sizeof (ValueT) > buffer.size () * sizeof (WordT)))
|
||||
throw std::runtime_error ("insufficient data for extraction");
|
||||
|
||||
ValueT const &res = *cast::alignment<ValueT const*> (buffer.data ());
|
||||
buffer = buffer.consume (sizeof (ValueT));
|
||||
return res;
|
||||
auto const ptr = cast::alignment<ValueT const*> (buffer.data ());
|
||||
buffer = buffer.consume (sizeof (ValueT) / sizeof (WordT));
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
|
||||
@ -626,11 +632,11 @@ namespace cruft {
|
||||
/// view, making the operation alignment safe.
|
||||
template <
|
||||
typename ValueT,
|
||||
typename ByteT,
|
||||
typename = std::enable_if_t<sizeof(ByteT) == 1>
|
||||
typename WordT,
|
||||
typename = std::enable_if_t<sizeof (ValueT) % sizeof(WordT) == 0>
|
||||
>
|
||||
ValueT
|
||||
read (view<ByteT*> &buffer)
|
||||
read (view<WordT*> &buffer)
|
||||
{
|
||||
// we disable the class-memaccess warning so that we can memcpy into
|
||||
// types that we know are safe but the compiler will complain about.
|
||||
@ -640,12 +646,12 @@ namespace cruft {
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wclass-memaccess"
|
||||
#endif
|
||||
if (unlikely (sizeof (ValueT) > buffer.size ()))
|
||||
if (unlikely (sizeof (ValueT) > buffer.size () * sizeof (WordT)))
|
||||
throw std::runtime_error ("insufficient data for extraction");
|
||||
|
||||
ValueT res;
|
||||
memcpy (&res, buffer.data (), sizeof (ValueT));
|
||||
buffer = buffer.consume (sizeof (ValueT));
|
||||
buffer = buffer.consume (sizeof (ValueT) / sizeof (WordT));
|
||||
return res;
|
||||
#if defined(COMPILER_GCC)
|
||||
#pragma GCC diagnostic pop
|
||||
|
Loading…
Reference in New Issue
Block a user