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
|
auto
|
||||||
make_byte_view (T &t)
|
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<
|
using cursor_type = std::conditional_t<
|
||||||
std::is_const_v<T>,
|
std::is_const_v<T>,
|
||||||
ByteT const*,
|
ByteT const*,
|
||||||
@ -582,40 +585,43 @@ namespace cruft {
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
return view {
|
return view {
|
||||||
reinterpret_cast<cursor_type> (&t),
|
cast::alignment<cursor_type> (&t),
|
||||||
sizeof (T)
|
sizeof (T) / sizeof (ByteT)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
/// returns a reference to a value of the designated type at the front of
|
/// 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
|
/// the word-view. if there is insufficient data for the extraction an
|
||||||
/// exception will be thrown.
|
/// 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
|
/// 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
|
/// supplied data during parsing routines. it is up to the user to ensure
|
||||||
/// the object is valid.
|
/// 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
|
/// 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 <
|
template <
|
||||||
typename ValueT,
|
typename ValueT,
|
||||||
typename ByteT,
|
typename WordT,
|
||||||
typename = std::enable_if_t<sizeof (ByteT) == 1>
|
// 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&
|
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");
|
throw std::runtime_error ("insufficient data for extraction");
|
||||||
|
|
||||||
ValueT const &res = *cast::alignment<ValueT const*> (buffer.data ());
|
auto const ptr = cast::alignment<ValueT const*> (buffer.data ());
|
||||||
buffer = buffer.consume (sizeof (ValueT));
|
buffer = buffer.consume (sizeof (ValueT) / sizeof (WordT));
|
||||||
return res;
|
return *ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -626,11 +632,11 @@ namespace cruft {
|
|||||||
/// view, making the operation alignment safe.
|
/// view, making the operation alignment safe.
|
||||||
template <
|
template <
|
||||||
typename ValueT,
|
typename ValueT,
|
||||||
typename ByteT,
|
typename WordT,
|
||||||
typename = std::enable_if_t<sizeof(ByteT) == 1>
|
typename = std::enable_if_t<sizeof (ValueT) % sizeof(WordT) == 0>
|
||||||
>
|
>
|
||||||
ValueT
|
ValueT
|
||||||
read (view<ByteT*> &buffer)
|
read (view<WordT*> &buffer)
|
||||||
{
|
{
|
||||||
// we disable the class-memaccess warning so that we can memcpy into
|
// we disable the class-memaccess warning so that we can memcpy into
|
||||||
// types that we know are safe but the compiler will complain about.
|
// 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 push
|
||||||
#pragma GCC diagnostic ignored "-Wclass-memaccess"
|
#pragma GCC diagnostic ignored "-Wclass-memaccess"
|
||||||
#endif
|
#endif
|
||||||
if (unlikely (sizeof (ValueT) > buffer.size ()))
|
if (unlikely (sizeof (ValueT) > buffer.size () * sizeof (WordT)))
|
||||||
throw std::runtime_error ("insufficient data for extraction");
|
throw std::runtime_error ("insufficient data for extraction");
|
||||||
|
|
||||||
ValueT res;
|
ValueT res;
|
||||||
memcpy (&res, buffer.data (), sizeof (ValueT));
|
memcpy (&res, buffer.data (), sizeof (ValueT));
|
||||||
buffer = buffer.consume (sizeof (ValueT));
|
buffer = buffer.consume (sizeof (ValueT) / sizeof (WordT));
|
||||||
return res;
|
return res;
|
||||||
#if defined(COMPILER_GCC)
|
#if defined(COMPILER_GCC)
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
Loading…
Reference in New Issue
Block a user