26#ifndef ETL_BIT_STREAM_INCLUDED
27#define ETL_BIT_STREAM_INCLUDED
59 typedef const unsigned char* const_iterator;
75 : pdata(reinterpret_cast<unsigned char*>(begin_))
76 , length_chars(static_cast<size_t>(
etl::distance(reinterpret_cast<unsigned char*>(begin_), reinterpret_cast<unsigned char*>(end_))))
85 : pdata(reinterpret_cast<unsigned char*>(begin_))
86 , length_chars(length_)
96 pdata =
reinterpret_cast<unsigned char*
>(begin_);
97 length_chars = length_;
106 set_stream(begin_,
static_cast<size_t>(etl::distance(
reinterpret_cast<unsigned char*
>(begin_),
reinterpret_cast<unsigned char*
>(end_))));
114 bits_available_in_char = CHAR_BIT;
116 bits_available = CHAR_BIT * length_chars;
124 return (bits_available == 0U);
132 bool success =
false;
134 if (pdata != ETL_NULLPTR)
136 if (bits_available > 0)
138 unsigned char chunk = value ? 1 : 0;
139 put_integral(uint32_t(chunk), 1);
150 template <
typename T>
151 typename etl::enable_if<etl::is_integral<T>::value,
bool>
::type put(T value, uint_least8_t nbits = CHAR_BIT *
sizeof(T))
153 return put_integral(
static_cast<uint32_t
>(value), nbits);
156#if ETL_USING_64BIT_TYPES
160 bool put(int64_t value, uint_least8_t nbits = CHAR_BIT *
sizeof(int64_t))
162 return put_integral(uint64_t(value), nbits);
168 bool put(uint64_t value, uint_least8_t nbits = CHAR_BIT *
sizeof(uint64_t))
170 return put_integral(value, nbits);
177 template <
typename T>
178 typename etl::enable_if<etl::is_floating_point<T>::value,
bool>
::type put(T value)
182 unsigned char data[
sizeof(T)];
183 to_bytes(value,
data);
185 for (
size_t i = 0UL; i <
sizeof(T); ++i)
187 if (!put_integral(uint32_t(
data[i]), CHAR_BIT))
201 bool success =
false;
203 if (pdata != ETL_NULLPTR)
206 if (bits_available > 0U)
219 template <
typename T>
220 typename etl::enable_if<etl::is_integral<T>::value,
bool>
::type get(T& value, uint_least8_t nbits = CHAR_BIT *
sizeof(T))
222 bool success =
false;
223 uint_least8_t
bits = nbits;
225 if (pdata != ETL_NULLPTR)
228 if (bits_available >= nbits)
235 unsigned char mask_width =
static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
237 typedef typename etl::make_unsigned<T>::type chunk_t;
238 chunk_t chunk = get_chunk(mask_width);
241 value |=
static_cast<T
>(chunk << nbits);
249 if (etl::is_signed<T>::value && (
bits != (CHAR_BIT *
sizeof(T))))
251 typedef typename etl::make_signed<T>::type ST;
261 template <
typename T>
262 typename etl::enable_if<etl::is_floating_point<T>::value,
bool>
::type get(T& value)
264 bool success =
false;
266 if (pdata != ETL_NULLPTR)
268 uint_least8_t nbits = CHAR_BIT *
sizeof(T);
271 if (bits_available >= nbits)
276 for (
size_t i = 0UL; i <
sizeof(T); ++i)
281 from_bytes(
reinterpret_cast<const unsigned char*
>(
data.raw), value);
295 size_t s = char_index;
298 if (bits_available_in_char != CHAR_BIT)
311 return (length_chars * CHAR_BIT) - bits_available;
325 const_iterator
end()
const
327 return pdata +
size();
335 bool put_integral(uint32_t value, uint_least8_t nbits)
337 bool success =
false;
339 if (pdata != ETL_NULLPTR)
342 if (bits_available >= nbits)
347 unsigned char mask_width =
static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
349 uint32_t mask = ((1U << mask_width) - 1U) << nbits;
354 uint32_t chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width);
356 put_chunk(
static_cast<unsigned char>(chunk), mask_width);
366#if ETL_USING_64BIT_TYPES
370 bool put_integral(uint64_t value, uint_least8_t nbits)
372 bool success =
false;
374 if (pdata != ETL_NULLPTR)
377 if (bits_available >= nbits)
382 unsigned char mask_width =
static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
384 uint64_t mask = ((uint64_t(1U) << mask_width) - 1U) << nbits;
388 uint64_t chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width);
390 put_chunk(
static_cast<unsigned char>(chunk), mask_width);
404 void put_chunk(
unsigned char chunk,
unsigned char nbits)
407 if (bits_available_in_char == 8U)
409 pdata[char_index] = 0U;
412 pdata[char_index] |= chunk;
419 unsigned char get_chunk(
unsigned char nbits)
421 unsigned char value =
static_cast<unsigned char>(pdata[char_index]);
423 value >>= (bits_available_in_char - nbits);
427 if (nbits == CHAR_BIT)
429 mask = etl::integral_limits<unsigned char>::max;
433 mask =
static_cast<unsigned char>((1U << nbits) - 1);
448 bool result = (
static_cast<unsigned char>(pdata[char_index]) & (1U << (bits_available_in_char - 1U))) != 0U;
458 template <
typename T>
459 void from_bytes(
const unsigned char*
data, T& value)
461 etl::uninitialized_buffer_of<T, 1U> temp;
464 if (etl::endianness::value() == etl::endian::little)
466 etl::reverse_copy(
data,
data +
sizeof(T),
reinterpret_cast<unsigned char*
>(temp.raw));
470 etl::copy(
data,
data +
sizeof(T),
reinterpret_cast<unsigned char*
>(temp.raw));
473 value = *
reinterpret_cast<T*
>(temp.raw);
479 template <
typename T>
480 void to_bytes(T value,
unsigned char*
data)
482 unsigned char* pf =
reinterpret_cast<unsigned char*
>(&value);
485 if (etl::endianness::value() == etl::endian::little)
487 etl::reverse_copy(pf, pf +
sizeof(T),
data);
491 etl::copy(pf, pf +
sizeof(T),
data);
499 void step(
unsigned char nbits)
501 bits_available_in_char -= nbits;
503 if (bits_available_in_char == 0)
506 bits_available_in_char = 8;
509 bits_available -= nbits;
512 unsigned char* pdata;
514 unsigned char bits_available_in_char;
517 size_t bits_available;
528 typedef char value_type;
529 typedef value_type* iterator;
530 typedef const value_type* const_iterator;
532 typedef etl::delegate<void(callback_parameter_type)> callback_type;
537 template <
size_t Length>
539 : pdata(span_.
begin())
541 , stream_endianness(stream_endianness_)
542 , callback(callback_)
550 template <
size_t Length>
552 : pdata(reinterpret_cast<char*>(span_.
begin()))
554 , stream_endianness(stream_endianness_)
555 , callback(callback_)
564 : pdata(reinterpret_cast<char*>(begin_))
565 , length_chars(static_cast<size_t>(
etl::distance(reinterpret_cast<unsigned char*>(begin_), reinterpret_cast<unsigned char*>(end_))))
566 , stream_endianness(stream_endianness_)
567 , callback(callback_)
576 : pdata(reinterpret_cast<char*>(begin_))
577 , length_chars(length_chars_)
578 , stream_endianness(stream_endianness_)
579 , callback(callback_)
589 bits_available_in_char = CHAR_BIT;
607 return length_chars * CHAR_BIT;
631 unsigned char chunk = value ? 1 : 0;
632 write_data<unsigned char>(chunk, 1);
653 template <
typename T>
654 typename etl::enable_if<etl::is_integral<T>::value,
void>
::type write_unchecked(T value, uint_least8_t nbits = CHAR_BIT *
sizeof(T))
656 typedef typename etl::unsigned_type<T>::type unsigned_t;
658 write_data<unsigned_t>(
static_cast<unsigned_t
>(value), nbits);
664 template <
typename T>
665 typename etl::enable_if<etl::is_integral<T>::value,
bool>
::type write(T value, uint_least8_t nbits = CHAR_BIT *
sizeof(T))
688 while (nbits > bits_available_in_char)
690 step(bits_available_in_char);
691 nbits -= bits_available_in_char;
696 step(
static_cast<unsigned char>(nbits));
708 size_t s = char_index;
711 if (bits_available_in_char != CHAR_BIT)
731 template <
size_t Nbits>
734 return bits_available / Nbits;
741 template <
typename T>
753 return bits_available / nbits;
761 return bits_available;
799 const_iterator
end()
const
849 if (callback.is_valid())
851 if (bits_available_in_char != 0U)
866 callback = callback_;
883 template <
typename T>
884 void write_data(T value, uint_least8_t nbits)
887 nbits = (nbits > (CHAR_BIT *
sizeof(T))) ? (CHAR_BIT *
sizeof(T)) : nbits;
889 if (stream_endianness == etl::endian::little)
892 value = value >> ((CHAR_BIT *
sizeof(T)) - nbits);
898 unsigned char mask_width =
static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
900 T mask = ((T(1U) << mask_width) - 1U) << nbits;
904 T chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width);
906 write_chunk(
static_cast<char>(chunk), mask_width);
909 if (callback.is_valid())
918 void write_chunk(
char chunk,
unsigned char nbits)
921 if (bits_available_in_char == CHAR_BIT)
923 pdata[char_index] = 0U;
926 pdata[char_index] |= chunk;
934 void flush_full_bytes()
939 callback(callback_parameter_type(pdata, pdata + char_index));
941 bits_available = CHAR_BIT * length_chars;
943 if (bits_available_in_char != 0U)
946 pdata[0] = pdata[char_index];
947 bits_available -= (CHAR_BIT - bits_available_in_char);
958 void step(
unsigned char nbits)
960 bits_available_in_char -= nbits;
962 if (bits_available_in_char == 0)
965 bits_available_in_char = CHAR_BIT;
968 bits_available -= nbits;
972 const size_t length_chars;
973 const etl::endian stream_endianness;
974 unsigned char bits_available_in_char;
977 size_t bits_available;
979 callback_type callback;
997 return stream.
write(value);
1005 template <
typename T>
1007 uint_least8_t nbits = CHAR_BIT *
sizeof(T))
1017 template <
typename T>
1019 uint_least8_t nbits = CHAR_BIT *
sizeof(T))
1021 return stream.
write(value, nbits);
1031 typedef char value_type;
1032 typedef const char* const_iterator;
1037 template <
size_t Length>
1039 : pdata(span_.
begin())
1041 , stream_endianness(stream_endianness_)
1049 template <
size_t Length>
1051 : pdata(reinterpret_cast<const char*>(span_.
begin()))
1053 , stream_endianness(stream_endianness_)
1061 template <
size_t Length>
1063 : pdata(span_.
begin())
1065 , stream_endianness(stream_endianness_)
1073 template <
size_t Length>
1075 : pdata(reinterpret_cast<const char*>(span_.
begin()))
1077 , stream_endianness(stream_endianness_)
1086 : pdata(reinterpret_cast<const char*>(begin_))
1087 , length_chars(static_cast<size_t>(
etl::distance(reinterpret_cast<const char*>(begin_), reinterpret_cast<const char*>(end_))))
1088 , stream_endianness(stream_endianness_)
1097 : pdata(reinterpret_cast<const char*>(begin_))
1098 , length_chars(length_)
1099 , stream_endianness(stream_endianness_)
1109 bits_available_in_char = CHAR_BIT;
1111 bits_available = CHAR_BIT * length_chars;
1117 template <
typename T>
1126 template <
typename T>
1131 if (bits_available > 0U)
1142 template <
typename T>
1143 typename etl::enable_if< etl::is_integral<T>::value && !etl::is_same<bool, T>::value, T>
::type read_unchecked(uint_least8_t nbits = CHAR_BIT
1146 typedef typename etl::unsigned_type<T>::type unsigned_t;
1148 T value =
static_cast<T
>(read_value<unsigned_t>(nbits, etl::is_signed<T>::value));
1150 return static_cast<T
>(value);
1156 template <
typename T>
1157 typename etl::enable_if<etl::is_integral<T>::value && !etl::is_same<bool, T>::value,
etl::optional<T> >
::type
1158 read(uint_least8_t nbits = CHAR_BIT *
sizeof(T))
1163 if (bits_available >= nbits)
1176 return length_chars;
1184 return length_chars * CHAR_BIT;
1234 bool success = (nbits <= bits_available);
1238 while (nbits > bits_available_in_char)
1240 nbits -= bits_available_in_char;
1241 step(bits_available_in_char);
1246 step(
static_cast<unsigned char>(nbits));
1259 template <
typename T>
1260 T read_value(uint_least8_t nbits,
bool is_signed)
1263 nbits = (nbits > (CHAR_BIT *
sizeof(T))) ? (CHAR_BIT *
sizeof(T)) : nbits;
1266 uint_least8_t bits = nbits;
1271 unsigned char mask_width =
static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
1273 T chunk = get_chunk(mask_width);
1275 nbits -= mask_width;
1276 value |=
static_cast<T
>(chunk << nbits);
1279 if (stream_endianness == etl::endian::little)
1281 value = value << ((CHAR_BIT *
sizeof(T)) - bits);
1285 if (is_signed && (bits != (CHAR_BIT *
sizeof(T))))
1296 unsigned char get_chunk(
unsigned char nbits)
1298 unsigned char value =
static_cast<unsigned char>(pdata[char_index]);
1299 value >>= (bits_available_in_char - nbits);
1303 if (nbits == CHAR_BIT)
1305 mask = etl::integral_limits<unsigned char>::max;
1309 mask =
static_cast<unsigned char>((1U << nbits) - 1);
1324 bool result = (
static_cast<unsigned char>(pdata[char_index]) & (1U << (bits_available_in_char - 1U))) != 0U;
1335 void step(
unsigned char nbits)
1337 bits_available_in_char -= nbits;
1339 if (bits_available_in_char == 0)
1342 bits_available_in_char = 8;
1345 bits_available -= nbits;
1349 size_t length_chars;
1350 const etl::endian stream_endianness;
1351 unsigned char bits_available_in_char;
1354 size_t bits_available;
1361 template <
typename T>
1367 template <
typename T>
1376 template <
typename T>
1379 return stream.
read<T>();
1382 template <
typename T>
1385 return stream.
read<T>(nbits);
1403 return stream.
read<
bool>();
Reads bit streams.
Definition bit_stream.h:1028
etl::enable_if< etl::is_same< bool, T >::value, etl::optional< bool > >::type read()
For bool types.
Definition bit_stream.h:1127
const_iterator end() const
Returns end of the stream.
Definition bit_stream.h:1206
bit_stream_reader(const etl::span< const unsigned char, Length > &span_, etl::endian stream_endianness_)
Construct from span.
Definition bit_stream.h:1074
const_iterator cend() const
Returns end of the stream.
Definition bit_stream.h:1214
bit_stream_reader(const etl::span< char, Length > &span_, etl::endian stream_endianness_)
Construct from span.
Definition bit_stream.h:1038
size_t size_bits() const
Returns the number of bits in the stream buffer.
Definition bit_stream.h:1182
etl::enable_if< etl::is_integral< T >::value &&!etl::is_same< bool, T >::value, T >::type read_unchecked(uint_least8_t nbits=CHAR_BIT *sizeof(T))
For integral types.
Definition bit_stream.h:1143
bit_stream_reader(const void *begin_, size_t length_, etl::endian stream_endianness_)
Construct from begin and length.
Definition bit_stream.h:1096
bool skip(size_t nbits)
Definition bit_stream.h:1232
bit_stream_reader(const etl::span< const char, Length > &span_, etl::endian stream_endianness_)
Construct from span.
Definition bit_stream.h:1062
bit_stream_reader(const void *begin_, const void *end_, etl::endian stream_endianness_)
Construct from range.
Definition bit_stream.h:1085
bit_stream_reader(const etl::span< unsigned char, Length > &span_, etl::endian stream_endianness_)
Construct from span.
Definition bit_stream.h:1050
etl::enable_if< etl::is_integral< T >::value &&!etl::is_same< bool, T >::value, etl::optional< T > >::type read(uint_least8_t nbits=CHAR_BIT *sizeof(T))
For integral types.
Definition bit_stream.h:1158
void restart()
Sets the indexes back to the beginning of the stream.
Definition bit_stream.h:1107
const_iterator cbegin() const
Returns start of the stream.
Definition bit_stream.h:1198
etl::enable_if< etl::is_same< bool, T >::value, bool >::type read_unchecked()
For bool types.
Definition bit_stream.h:1118
etl::span< const char > data() const
Returns a span of whole the stream.
Definition bit_stream.h:1222
const_iterator begin() const
Returns start of the stream.
Definition bit_stream.h:1190
size_t size_bytes() const
Returns the number of bytes in the stream buffer.
Definition bit_stream.h:1174
Writes bits streams.
Definition bit_stream.h:525
bit_stream_writer(void *begin_, void *end_, etl::endian stream_endianness_, callback_type callback_=callback_type())
Construct from range.
Definition bit_stream.h:563
etl::enable_if< etl::is_integral< T >::value, bool >::type write(T value, uint_least8_t nbits=CHAR_BIT *sizeof(T))
For integral types.
Definition bit_stream.h:665
size_t size_bytes() const
Returns the number of bytes used in the stream.
Definition bit_stream.h:706
etl::enable_if< etl::is_integral< T >::value, void >::type write_unchecked(T value, uint_least8_t nbits=CHAR_BIT *sizeof(T))
For integral types.
Definition bit_stream.h:654
etl::span< const char > used_data() const
Returns a span of the used portion of the stream.
Definition bit_stream.h:823
bool write(bool value)
Writes a boolean to the stream.
Definition bit_stream.h:638
size_t size_bits() const
Returns the number of bits used in the stream.
Definition bit_stream.h:722
size_t available_bits() const
The number of bits left in the stream.
Definition bit_stream.h:759
const_iterator cend() const
Returns end of the stream.
Definition bit_stream.h:807
callback_type get_callback() const
Gets the function to call after every write.
Definition bit_stream.h:872
bool empty() const
Returns true if the bitsteam indexes have been reset.
Definition bit_stream.h:613
bit_stream_writer(void *begin_, size_t length_chars_, etl::endian stream_endianness_, callback_type callback_=callback_type())
Construct from begin and length.
Definition bit_stream.h:575
bit_stream_writer(const etl::span< unsigned char, Length > &span_, etl::endian stream_endianness_, callback_type callback_=callback_type())
Construct from span.
Definition bit_stream.h:551
bit_stream_writer(const etl::span< char, Length > &span_, etl::endian stream_endianness_, callback_type callback_=callback_type())
Construct from span.
Definition bit_stream.h:538
iterator end()
Returns end of the stream.
Definition bit_stream.h:791
void set_callback(callback_type callback_)
Sets the function to call after every write.
Definition bit_stream.h:864
size_t available() const
Definition bit_stream.h:732
etl::span< char > data()
Returns a span of whole the stream.
Definition bit_stream.h:831
bool full() const
Returns true if the bitsteam indexes have reached the end.
Definition bit_stream.h:621
bool skip(size_t nbits)
Definition bit_stream.h:682
size_t capacity_bits() const
Returns the maximum capacity in bits.
Definition bit_stream.h:605
etl::span< char > used_data()
Returns a span of the used portion of the stream.
Definition bit_stream.h:815
size_t capacity_bytes() const
Returns the maximum capacity in bytes.
Definition bit_stream.h:597
etl::span< const char > data() const
Returns a span of whole the stream.
Definition bit_stream.h:839
void restart()
Sets the indexes back to the beginning of the stream.
Definition bit_stream.h:587
void write_unchecked(bool value)
Writes a boolean to the stream.
Definition bit_stream.h:629
void flush()
Flush the last byte, if partially filled, to the callback, if valid.
Definition bit_stream.h:847
const_iterator cbegin() const
Returns start of the stream.
Definition bit_stream.h:783
size_t available(size_t nbits) const
Definition bit_stream.h:751
const_iterator end() const
Returns end of the stream.
Definition bit_stream.h:799
const_iterator begin() const
Returns start of the stream.
Definition bit_stream.h:775
iterator begin()
Returns start of the stream.
Definition bit_stream.h:767
etl::enable_if< etl::is_integral< T >::value, bool >::type get(T &value, uint_least8_t nbits=CHAR_BIT *sizeof(T))
For integral types.
Definition bit_stream.h:220
etl::enable_if< etl::is_integral< T >::value, bool >::type put(T value, uint_least8_t nbits=CHAR_BIT *sizeof(T))
For integral types.
Definition bit_stream.h:151
bool put(int64_t value, uint_least8_t nbits=CHAR_BIT *sizeof(int64_t))
For 64bit integral types.
Definition bit_stream.h:160
etl::enable_if< etl::is_floating_point< T >::value, bool >::type put(T value)
For floating point types.
Definition bit_stream.h:178
void restart()
Sets the indexes back to the beginning of the stream.
Definition bit_stream.h:112
size_t size() const
Returns the number of bytes used in the stream.
Definition bit_stream.h:293
size_t bits() const
Returns the number of bits used in the stream.
Definition bit_stream.h:309
bit_stream(void *begin_, void *end_)
Construct from range.
Definition bit_stream.h:74
bool put(uint64_t value, uint_least8_t nbits=CHAR_BIT *sizeof(uint64_t))
For 64bit integral types.
Definition bit_stream.h:168
bit_stream(void *begin_, size_t length_)
Construct from begin and length.
Definition bit_stream.h:84
etl::enable_if< etl::is_floating_point< T >::value, bool >::type get(T &value)
For floating point types.
Definition bit_stream.h:262
bool at_end() const
Returns true if the bitsteam indexes have reached the end.
Definition bit_stream.h:122
bool put(bool value)
Writes a boolean to the stream.
Definition bit_stream.h:130
bit_stream()
Default constructor.
Definition bit_stream.h:64
bool get(bool &value)
For bool types.
Definition bit_stream.h:199
void set_stream(void *begin_, size_t length_)
Construct from begin and length.
Definition bit_stream.h:94
void set_stream(void *begin_, void *end_)
Construct from range.
Definition bit_stream.h:104
const_iterator end() const
Returns end of the stream.
Definition bit_stream.h:325
const_iterator begin() const
Returns start of the stream.
Definition bit_stream.h:317
Declaration.
Definition delegate_cpp03.h:191
Definition optional.h:1273
Span - Fixed Extent.
Definition span.h:208
ETL_CONSTEXPR14 etl::enable_if< etl::is_integral< T >::value &&etl::is_unsigned< T >::value &&(etl::integral_limits< T >::bits==16U), T >::type reverse_bits(T value)
Definition binary.h:542
ETL_CONSTEXPR14 TReturn sign_extend(TValue value)
Definition binary.h:273
Definition endianness.h:100
bitset_ext
Definition absolute.h:40
ETL_CONSTEXPR TContainer::pointer data(TContainer &container)
Definition iterator.h:1228
bool read_unchecked< bool >(etl::bit_stream_reader &stream)
Read an unchecked bool from a stream.
Definition bit_stream.h:1392
etl::optional< T > read(etl::bit_stream_reader &stream)
Read a checked type from a stream.
Definition bit_stream.h:1377
void write_unchecked(etl::bit_stream_writer &stream, bool value)
Definition bit_stream.h:986
etl::optional< bool > read< bool >(etl::bit_stream_reader &stream)
Read a bool from a stream.
Definition bit_stream.h:1401
T read_unchecked(etl::bit_stream_reader &stream)
Read an unchecked type from a stream.
Definition bit_stream.h:1362
bool write(etl::bit_stream_writer &stream, bool value)
Definition bit_stream.h:995
is_signed
Definition type_traits.h:458