5#ifndef MLAB_BIN_DATA_HPP
6#define MLAB_BIN_DATA_HPP
19 [[nodiscard]]
constexpr std::uint8_t
operator""_b(
unsigned long long int n);
24#ifdef MLAB_TRACK_BIN_DATA
30 template <
class Iterator>
39 template <
class Container>
42 template <
class Jterator,
class =
typename std::enable_if<std::is_convertible_v<Jterator, Iterator>>::type>
45 template <class Jterator = Iterator, class = std::enable_if_t<std::is_same_v<typename std::iterator_traits<Jterator>::iterator_category, std::random_access_iterator_tag>>>
46 [[nodiscard]]
constexpr inline typename std::iterator_traits<Iterator>::difference_type
size()
const {
53 [[nodiscard]]
constexpr inline typename std::add_const_t<typename std::iterator_traits<Iterator>::pointer>
data()
const {
60 [[nodiscard]]
constexpr inline typename std::iterator_traits<Iterator>::pointer
data() {
64 [[nodiscard]]
constexpr inline Iterator
begin()
const {
return it_begin; }
66 [[nodiscard]]
constexpr inline Iterator
end()
const {
return it_end; }
69 template <
class Iterator>
74 template <
class Container>
79 template <
class, std::
size_t Size>
89 std::begin(t) != std::end(t);
91 std::next(std::begin(t));
101 template <
class T,
class = std::enable_if_t<std::is_same_v<T,
bool>>>
104 constexpr explicit operator bool()
const {
116 inline explicit operator bool()
const;
125 using bin_data_base = std::conditional_t<track_bin_data_mem, std::vector<std::uint8_t, tracker_allocator<std::uint8_t>>, std::vector<std::uint8_t>>;
131 inline bin_data(std::initializer_list<std::uint8_t>
data);
139 template <
class ByteIterator>
140 inline bin_data(ByteIterator begin, ByteIterator
end);
143 std::size_t start = 0,
144 std::size_t length = std::numeric_limits<std::size_t>::max())
const;
147 std::size_t start = 0,
148 std::size_t length = std::numeric_limits<std::size_t>::max());
151 std::size_t start = 0,
152 std::size_t length = std::numeric_limits<std::size_t>::max())
const;
155 std::size_t start = 0,
156 std::size_t length = std::numeric_limits<std::size_t>::max());
158 using bin_data_base::push_back;
160 template <
class... ByteOrByteContainers>
166 std::declval<bin_data &>() << t;
193 [[nodiscard]]
inline std::size_t
remaining()
const;
195 template <
class OutputIterator>
196 std::size_t
read(OutputIterator it, std::size_t n);
200 inline std::uint8_t
pop();
202 [[nodiscard]]
inline std::uint8_t
peek_one();
206 [[nodiscard]]
inline bool good()
const;
208 [[nodiscard]]
inline bool eof()
const;
210 [[nodiscard]]
inline bool bad()
const;
219 std::declval<bin_stream &>() >> t;
222 template <
unsigned Bits>
225 template <
unsigned Bits>
239 template <
unsigned BitSize,
byte_order Order>
244 template <
unsigned BitSize,
byte_order Order>
252 template <is_
signed_or_
unsigned_v Num,
unsigned BitSize,
byte_order Order>
253 bin_stream &
operator>>(ordered_extractor<BitSize, Order> e, Num &n);
255 template <is_
signed_or_
unsigned_v Num,
unsigned BitSize,
byte_order Order>
256 bin_data &
operator<<(ordered_injector<BitSize, Order> i, Num n);
259 template <
unsigned BitSize>
260 inline ordered_extractor<BitSize, byte_order::lsb_first>
operator>>(bin_stream &s, lsb_t<BitSize>);
262 template <
unsigned BitSize>
263 inline ordered_extractor<BitSize, byte_order::msb_first>
operator>>(bin_stream &s, msb_t<BitSize>);
265 template <
unsigned BitSize>
266 ordered_injector<BitSize, byte_order::lsb_first>
operator<<(bin_data &bd, lsb_t<BitSize>);
268 template <
unsigned BitSize>
269 ordered_injector<BitSize, byte_order::msb_first>
operator<<(bin_data &bd, msb_t<BitSize>);
271 inline bin_data &
operator<<(bin_data &bd, explicit_bool b);
273 inline bin_stream &
operator>>(bin_stream &s,
bool &b);
275 inline bin_stream &
operator>>(bin_stream &s, std::uint8_t &
byte);
277 template <std::
size_t Length>
278 bin_stream &
operator>>(bin_stream &s, std::array<std::uint8_t, Length> &out);
281 using underlying_t = std::conditional_t<std::is_enum_v<T>, std::underlying_type_t<T>, T>;
284 using range_value_t = std::decay_t<decltype(*std::begin(std::declval<T>()))>;
287 concept is_byte_enum = std::is_enum_v<T> and std::is_same_v<underlying_t<T>, std::uint8_t>;
295 template <is_
byte_enum Enum>
296 bin_stream &
operator>>(bin_stream &s, Enum &t);
301 template <is_
byte_sequence T>
302 bin_data &
operator<<(bin_data &bd, T
const &t);
317 { std::declval<bin_data &>() <<
lsb32 << std::uint32_t(t.size()) };
318 { std::declval<bin_data &>() << *std::begin(t) };
323 t.resize(std::uint32_t{});
324 { std::declval<bin_stream &>() >> *++std::begin(t) };
327 template <container_of_injectables Container>
330 template <container_of_extractables Container>
342 template <
class T, std::
size_t Size>
344 return std::equal(std::begin(*
this), std::end(*
this), std::begin(other));
347 template <
class T, std::
size_t Size>
362 template <
class ByteIterator>
366 bd.push_back(b ? 0x01 : 0x00);
370 template <
class... ByteOrByteContainers>
373 (retval << ... << others);
379 start = std::min(start, size());
380 length = std::min(length, size() - start);
381 return {begin() + difference_type(start), begin() + difference_type(start + length)};
385 start = std::min(start, size() - 1);
386 length = std::min(length, size() - start);
387 return {begin() + difference_type(start), begin() + difference_type(start + length)};
391 start = std::min(start, size());
392 length = std::min(length, size() - start);
393 return {
data() + start,
data() + start + length};
397 start = std::min(start, size() - 1);
398 length = std::min(length, size() - start);
399 return {
data() + start,
data() + start + length};
407 byte &= ~(1 <<
index);
413 bit_ref::operator bool()
const {
414 return 0 != (
byte & (1 << index));
425 if (
_data !=
nullptr) {
431 if (
_data !=
nullptr) {
434 return std::numeric_limits<std::size_t>::max();
438 if (
_data !=
nullptr) {
445 return _data->size();
448 return std::numeric_limits<std::size_t>::max();
463 const std::size_t old_pos =
_pos;
477 return not
bad() and not
eof();
516 template <
class OutputIterator>
519 std::copy(std::begin(
data), std::end(
data), it);
520 return std::end(
data) - std::begin(
data);
533 template <std::
size_t Length>
535 s.template read(std::begin(out), Length);
539 template <is_
byte_enum Enum>
541 using underlying_t =
typename std::underlying_type_t<Enum>;
545 t =
static_cast<Enum
>(value);
550 template <is_
byte_sequence T>
553 bd.push_back(
static_cast<std::uint8_t
>(t));
555 bd.reserve(bd.size() + std::distance(std::begin(t), std::end(t)));
556 for (
auto const item : t) {
560 bd.reserve(bd.size() + std::distance(std::begin(t), std::end(t)));
561 for (
auto const be : t) {
562 bd.push_back(
static_cast<std::uint8_t
>(be));
564 }
else if constexpr (std::is_same_v<T, std::uint8_t>) {
571 template <
unsigned BitSize>
576 template <
unsigned BitSize>
581 template <
unsigned BitSize>
582 ordered_injector<BitSize, byte_order::lsb_first>
operator<<(bin_data &bd, lsb_t<BitSize>) {
586 template <
unsigned BitSize>
587 ordered_injector<BitSize, byte_order::msb_first>
operator<<(bin_data &bd, msb_t<BitSize>) {
591 template <is_
signed_or_
unsigned_v Num,
unsigned BitSize,
byte_order Order>
593 static_assert(
sizeof(Num) * 8 >= BitSize);
594 if constexpr (BitSize == 0) {
597 std::array<std::uint8_t, BitSize / 8> b{};
604 template <is_
signed_or_
unsigned_v Num,
unsigned BitSize,
byte_order Order>
606 static_assert(
sizeof(Num) * 8 >= BitSize);
607 if constexpr (BitSize == 0) {
618 encode_length<bin_data>
operator<<(bin_data &bd, length_encoded_t) {
622 template <container_of_injectables Container>
625 for (
auto it = std::begin(c); it != std::end(c); ++it) {
631 template <container_of_extractables Container>
633 std::size_t size = 0;
638 if (size *
sizeof(
typename Container::value_type) > 10 * 1024 * 1024) {
639 LOGW(
"MLAB",
"Attempt at extracting > 10MB of data?! %zu items in encoded array.", size);
642 for (
auto it = std::begin(c); it != std::end(c); ++it) {
650 constexpr std::uint8_t
operator""_b(
unsigned long long int n) {
651 return std::uint8_t(n);
Definition bin_data.hpp:127
range< value_type const * > data_view(std::size_t start=0, std::size_t length=std::numeric_limits< std::size_t >::max()) const
Definition bin_data.hpp:390
static bin_data chain(ByteOrByteContainers &&...others)
Definition bin_data.hpp:371
range< bin_data::const_iterator > view(std::size_t start=0, std::size_t length=std::numeric_limits< std::size_t >::max()) const
Definition bin_data.hpp:378
Definition bin_data.hpp:177
bool _bad
Definition bin_data.hpp:180
range< bin_data::const_iterator > peek() const
Definition bin_data.hpp:451
bool good() const
Definition bin_data.hpp:476
std::uint8_t pop()
Definition bin_data.hpp:500
bool bad() const
Definition bin_data.hpp:484
std::size_t _pos
Definition bin_data.hpp:179
void set_bad()
Definition bin_data.hpp:488
bool eof() const
Definition bin_data.hpp:480
void seek(std::intptr_t offset, stream_ref ref=stream_ref::beg)
Definition bin_data.hpp:424
std::size_t remaining() const
Definition bin_data.hpp:496
std::uint8_t peek_one()
Definition bin_data.hpp:508
std::size_t tell(stream_ref ref=stream_ref::beg) const
Definition bin_data.hpp:430
void clear_bad()
Definition bin_data.hpp:492
std::size_t get_ref(stream_ref ref) const
Definition bin_data.hpp:437
std::size_t read(OutputIterator it, std::size_t n)
Definition bin_data.hpp:517
bin_data const * _data
Definition bin_data.hpp:178
Definition bin_data.hpp:316
Definition bin_data.hpp:293
Definition bin_data.hpp:287
Definition bin_data.hpp:290
Definition bin_data.hpp:299
Definition bin_data.hpp:165
Definition bin_data.hpp:88
Definition bin_data.hpp:250
#define LOGW(tag, format,...)
Definition log.hpp:37
Definition bin_data.hpp:18
std::decay_t< decltype(*std::begin(std::declval< T >()))> range_value_t
Definition bin_data.hpp:284
stream_ref
Definition bin_data.hpp:171
static constexpr lsb_t< 0 > lsb_auto
Definition bin_data.hpp:236
static constexpr msb_t< 32 > msb32
Definition bin_data.hpp:234
static constexpr msb_t< 0 > msb_auto
Definition bin_data.hpp:237
bool operator==(tracker_allocator< T > const &, tracker_allocator< U > const &) noexcept
Definition tracker_allocator.hpp:81
bin_data & operator<<(encode_length< bin_data > w, std::string_view sv)
Definition strutils.cpp:155
static constexpr msb_t< 24 > msb24
Definition bin_data.hpp:233
constexpr range< Iterator > make_range(Iterator begin, Iterator end)
Definition bin_data.hpp:70
std::array< std::uint8_t, Bits/8 > encode(Num n)
Definition byte_order.hpp:149
Num decode(std::array< std::uint8_t, Bits/8 > const &b)
Definition byte_order.hpp:168
static constexpr lsb_t< 16 > lsb16
Definition bin_data.hpp:228
static constexpr msb_t< 16 > msb16
Definition bin_data.hpp:232
bin_stream & operator>>(encode_length< bin_stream > w, std::string &c)
Definition strutils.cpp:159
static constexpr msb_t< 64 > msb64
Definition bin_data.hpp:235
static constexpr lsb_t< 64 > lsb64
Definition bin_data.hpp:231
struct mlab::length_encoded_t length_encoded
std::conditional_t< std::is_enum_v< T >, std::underlying_type_t< T >, T > underlying_t
Definition bin_data.hpp:281
static constexpr bool track_bin_data_mem
Definition bin_data.hpp:27
std::conditional_t< track_bin_data_mem, std::vector< std::uint8_t, tracker_allocator< std::uint8_t > >, std::vector< std::uint8_t > > bin_data_base
Definition bin_data.hpp:125
static constexpr lsb_t< 32 > lsb32
Definition bin_data.hpp:230
static constexpr lsb_t< 24 > lsb24
Definition bin_data.hpp:229
Definition bin_data.hpp:109
const std::uint8_t write_mask
Definition bin_data.hpp:112
std::uint8_t & byte
Definition bin_data.hpp:110
const std::uint8_t index
Definition bin_data.hpp:111
bit_ref & operator=(explicit_bool v)
Definition bin_data.hpp:402
Definition bin_data.hpp:308
T & s
Definition bin_data.hpp:309
Definition bin_data.hpp:98
bool v
Definition bin_data.hpp:99
constexpr explicit_bool(T v_)
Definition bin_data.hpp:102
Definition bin_data.hpp:304
Definition bin_data.hpp:223
Definition bin_data.hpp:226
Definition bin_data.hpp:240
bin_data & bd
Definition bin_data.hpp:241
Definition bin_data.hpp:119
constexpr prealloc(std::size_t size)
Definition bin_data.hpp:120
std::size_t requested_size
Definition bin_data.hpp:122
Definition bin_data.hpp:31
constexpr Iterator begin() const
Definition bin_data.hpp:64
constexpr range(Container &c)
Definition bin_data.hpp:40
constexpr range()=default
Iterator it_end
Definition bin_data.hpp:33
Iterator it_begin
Definition bin_data.hpp:32
constexpr range(range< Jterator > other)
Definition bin_data.hpp:43
constexpr std::iterator_traits< Iterator >::difference_type size() const
Definition bin_data.hpp:46
constexpr std::add_const_t< typename std::iterator_traits< Iterator >::pointer > data() const
Definition bin_data.hpp:53
constexpr std::iterator_traits< Iterator >::pointer data()
Definition bin_data.hpp:60
constexpr Iterator end() const
Definition bin_data.hpp:66
constexpr range(Iterator b, Iterator e)
Definition bin_data.hpp:37
Definition bin_data.hpp:80
static constexpr std::size_t array_size
Definition bin_data.hpp:81
bool operator==(tagged_array const &other) const
Definition bin_data.hpp:343
bool operator!=(tagged_array const &other) const
Definition bin_data.hpp:348