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(
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_, 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>
152 put(T value, uint_least8_t nbits = CHAR_BIT *
sizeof(T))
154 return put_integral(
static_cast<uint32_t
>(value), nbits);
157#if ETL_USING_64BIT_TYPES
161 bool put(int64_t value, uint_least8_t nbits = CHAR_BIT *
sizeof(int64_t))
163 return put_integral(uint64_t(value), nbits);
169 bool put(uint64_t value, uint_least8_t nbits = CHAR_BIT *
sizeof(uint64_t))
171 return put_integral(value, nbits);
178 template <
typename T>
184 unsigned char data[
sizeof(T)];
185 to_bytes(value, data);
187 for (
size_t i = 0UL; i <
sizeof(T); ++i)
189 if (!put_integral(uint32_t(data[i]), CHAR_BIT))
203 bool success =
false;
205 if (pdata != ETL_NULLPTR)
208 if (bits_available > 0U)
221 template <
typename T>
223 get(T& value, uint_least8_t nbits = CHAR_BIT *
sizeof(T))
225 bool success =
false;
226 uint_least8_t
bits = nbits;
228 if (pdata != ETL_NULLPTR)
231 if (bits_available >= nbits)
238 unsigned char mask_width =
static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
240 typedef typename etl::make_unsigned<T>::type chunk_t;
241 chunk_t chunk = get_chunk(mask_width);
244 value |=
static_cast<T
>(chunk << nbits);
254 typedef typename etl::make_signed<T>::type ST;
255 value = etl::sign_extend<ST, ST>(value,
bits);
264 template <
typename T>
268 bool success =
false;
270 if (pdata != ETL_NULLPTR)
272 uint_least8_t nbits = CHAR_BIT *
sizeof(T);
275 if (bits_available >= nbits)
280 for (
size_t i = 0UL; i <
sizeof(T); ++i)
282 get(data.raw[i], CHAR_BIT);
285 from_bytes(
reinterpret_cast<const unsigned char*
>(data.raw), value);
299 size_t s = char_index;
302 if (bits_available_in_char != CHAR_BIT)
315 return (length_chars * CHAR_BIT) - bits_available;
329 const_iterator
end()
const
331 return pdata +
size();
339 bool put_integral(uint32_t value, uint_least8_t nbits)
341 bool success =
false;
343 if (pdata != ETL_NULLPTR)
346 if (bits_available >= nbits)
351 unsigned char mask_width =
static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
353 uint32_t mask = ((uint32_t(1U) << mask_width) - 1U) << nbits;
357 uint32_t chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width);
359 put_chunk(
static_cast<unsigned char>(chunk), mask_width);
369#if ETL_USING_64BIT_TYPES
373 bool put_integral(uint64_t value, uint_least8_t nbits)
375 bool success =
false;
377 if (pdata != ETL_NULLPTR)
380 if (bits_available >= nbits)
385 unsigned char mask_width =
static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
387 uint64_t mask = ((uint64_t(1U) << mask_width) - 1U) << nbits;
391 uint64_t chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width);
393 put_chunk(
static_cast<unsigned char>(chunk), mask_width);
407 void put_chunk(
unsigned char chunk,
unsigned char nbits)
410 if (bits_available_in_char == 8U)
412 pdata[char_index] = 0U;
415 pdata[char_index] |= chunk;
422 unsigned char get_chunk(
unsigned char nbits)
424 unsigned char value = pdata[char_index];
426 value >>= (bits_available_in_char - nbits);
430 if (nbits == CHAR_BIT)
436 mask = (1U << nbits) - 1;
451 bool result = (pdata[char_index] & (1U << (bits_available_in_char - 1U))) != 0U;
461 template <
typename T>
462 void from_bytes(
const unsigned char* data, T& value)
467 if (etl::endianness::value() == etl::endian::little)
469 etl::reverse_copy(data, data +
sizeof(T), temp.raw);
473 etl::copy(data, data +
sizeof(T), temp.raw);
476 value = *
reinterpret_cast<T*
>(temp.raw);
482 template <
typename T>
483 void to_bytes(T value,
unsigned char* data)
485 unsigned char* pf =
reinterpret_cast<unsigned char*
>(&value);
488 if (etl::endianness::value() == etl::endian::little)
490 etl::reverse_copy(pf, pf +
sizeof(T), data);
494 etl::copy(pf, pf +
sizeof(T), data);
502 void step(
unsigned char nbits)
504 bits_available_in_char -= nbits;
506 if (bits_available_in_char == 0)
509 bits_available_in_char = 8;
512 bits_available -= nbits;
515 unsigned char *pdata;
517 unsigned char bits_available_in_char;
519 size_t bits_available;
529 typedef char value_type;
530 typedef value_type* iterator;
531 typedef const value_type* const_iterator;
539 : pdata(span_.
begin())
541 , stream_endianness(stream_endianness_)
551 : pdata(reinterpret_cast<char*>(span_.
begin()))
553 , stream_endianness(stream_endianness_)
563 : pdata(reinterpret_cast<char*>(begin_))
564 , length_chars(
etl::distance(reinterpret_cast<unsigned char*>(begin_), reinterpret_cast<unsigned char*>(end_)))
565 , stream_endianness(stream_endianness_)
575 : pdata(reinterpret_cast<char*>(begin_))
576 , length_chars(length_chars_)
577 , stream_endianness(stream_endianness_)
588 bits_available_in_char = CHAR_BIT;
590 bits_available = CHAR_BIT * length_chars;
602 size_t capacity_bits()
const
604 return length_chars * CHAR_BIT;
612 return (bits_available == length_chars);
620 return (bits_available == 0U);
628 unsigned char chunk = value ? 1 : 0;
629 write_data<unsigned char>(
static_cast<unsigned char>(chunk), 1);
637 bool success = (available<1U>() > 0U);
650 template <
typename T>
654 typedef typename etl::unsigned_type<T>::type unsigned_t;
656 write_data<unsigned_t>(
static_cast<unsigned_t
>(value), nbits);
662 template <
typename T>
664 write(T value, uint_least8_t nbits = CHAR_BIT *
sizeof(T))
687 while (nbits > bits_available_in_char)
689 step(bits_available_in_char);
690 nbits -= bits_available_in_char;
695 step(
static_cast<unsigned char>(nbits));
707 size_t s = char_index;
710 if (bits_available_in_char != CHAR_BIT)
730 template <
size_t Nbits>
733 return bits_available / Nbits;
740 template <
typename T>
743 return available<CHAR_BIT * sizeof(T)>();
752 return bits_available / nbits;
760 return bits_available;
798 const_iterator
end()
const
850 if (bits_available_in_char != 0U)
882 template <
typename T>
883 void write_data(T value, uint_least8_t nbits)
886 nbits = (nbits > (CHAR_BIT *
sizeof(T))) ? (CHAR_BIT *
sizeof(T)) : nbits;
888 if (stream_endianness == etl::endian::little)
891 value = value >> ((CHAR_BIT *
sizeof(T)) - nbits);
897 unsigned char mask_width =
static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
899 T mask = ((T(1U) << mask_width) - 1U) << nbits;
903 T chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width);
905 write_chunk(
static_cast<char>(chunk), mask_width);
908 if (callback.is_valid())
917 void write_chunk(
char chunk,
unsigned char nbits)
920 if (bits_available_in_char == CHAR_BIT)
922 pdata[char_index] = 0U;
925 pdata[char_index] |= chunk;
933 void flush_full_bytes()
938 callback(callback_parameter_type(pdata, pdata + char_index));
940 bits_available = CHAR_BIT * length_chars;
942 if (bits_available_in_char != 0U)
945 pdata[0] = pdata[char_index];
946 bits_available -= (CHAR_BIT - bits_available_in_char);
957 void step(
unsigned char nbits)
959 bits_available_in_char -= nbits;
961 if (bits_available_in_char == 0)
964 bits_available_in_char = CHAR_BIT;
967 bits_available -= nbits;
971 const size_t length_chars;
973 unsigned char bits_available_in_char;
975 size_t bits_available;
976 callback_type callback;
994 return stream.
write(value);
1002 template <
typename T>
1014 template <
typename T>
1018 return stream.
write(value, nbits);
1028 typedef char value_type;
1029 typedef const char* const_iterator;
1035 : pdata(span_.
begin())
1037 , stream_endianness(stream_endianness_)
1046 : pdata(reinterpret_cast<char*>(span_.
begin()))
1048 , stream_endianness(stream_endianness_)
1057 : pdata(reinterpret_cast<char*>(begin_))
1058 , length_chars(
etl::distance(reinterpret_cast<char*>(begin_), reinterpret_cast<char*>(end_)))
1059 , stream_endianness(stream_endianness_)
1068 : pdata(reinterpret_cast<char*>(begin_))
1069 , length_chars(length_)
1070 , stream_endianness(stream_endianness_)
1080 bits_available_in_char = CHAR_BIT;
1082 bits_available = CHAR_BIT * length_chars;
1088 template <
typename T>
1098 template <
typename T>
1104 if (bits_available > 0U)
1115 template <
typename T>
1119 typedef typename etl::unsigned_type<T>::type unsigned_t;
1123 return static_cast<T
>(value);
1129 template <
typename T>
1131 read(uint_least8_t nbits = CHAR_BIT *
sizeof(T))
1136 if (bits_available >= nbits)
1138 result = read_unchecked<T>(nbits);
1149 return length_chars;
1157 return length_chars * CHAR_BIT;
1207 bool success = (nbits <= bits_available);
1211 while (nbits > bits_available_in_char)
1213 nbits -= bits_available_in_char;
1214 step(bits_available_in_char);
1219 step(
static_cast<unsigned char>(nbits));
1232 template <
typename T>
1233 T read_value(uint_least8_t nbits,
bool is_signed)
1236 nbits = (nbits > (CHAR_BIT *
sizeof(T))) ? (CHAR_BIT *
sizeof(T)) : nbits;
1239 uint_least8_t bits = nbits;
1244 unsigned char mask_width =
static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
1246 T chunk = get_chunk(mask_width);
1248 nbits -= mask_width;
1249 value |=
static_cast<T
>(chunk << nbits);
1252 if (stream_endianness == etl::endian::little)
1254 value = value << ((CHAR_BIT *
sizeof(T)) - bits);
1258 if (is_signed && (bits != (CHAR_BIT *
sizeof(T))))
1260 value = etl::sign_extend<T, T>(value, bits);
1269 unsigned char get_chunk(
unsigned char nbits)
1271 unsigned char value = pdata[char_index];
1272 value >>= (bits_available_in_char - nbits);
1276 if (nbits == CHAR_BIT)
1282 mask = (1U << nbits) - 1;
1297 bool result = (pdata[char_index] & (1U << (bits_available_in_char - 1U))) != 0U;
1308 void step(
unsigned char nbits)
1310 bits_available_in_char -= nbits;
1312 if (bits_available_in_char == 0)
1315 bits_available_in_char = 8;
1318 bits_available -= nbits;
1322 size_t length_chars;
1324 unsigned char bits_available_in_char;
1326 size_t bits_available;
1332 template <
typename T>
1338 template <
typename T>
1347 template <
typename T>
1350 return stream.
read<T>();
1353 template <
typename T>
1356 return stream.
read<T>(nbits);
1374 return stream.
read<
bool>();
Reads bit streams.
Definition: bit_stream.h:1025
etl::enable_if< etl::is_same< bool, T >::value, etl::optional< bool > >::type read()
For bool types.
Definition: bit_stream.h:1100
const_iterator end() const
Returns end of the stream.
Definition: bit_stream.h:1179
const_iterator cend() const
Returns end of the stream.
Definition: bit_stream.h:1187
bit_stream_reader(void *begin_, void *end_, etl::endian stream_endianness_)
Construct from range.
Definition: bit_stream.h:1056
bit_stream_reader(void *begin_, size_t length_, etl::endian stream_endianness_)
Construct from begin and length.
Definition: bit_stream.h:1067
size_t size_bits() const
Returns the number of bits in the stream buffer.
Definition: bit_stream.h:1155
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:1117
bool skip(size_t nbits)
Definition: bit_stream.h:1205
bit_stream_reader(etl::span< char > span_, etl::endian stream_endianness_)
Construct from span.
Definition: bit_stream.h:1034
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:1131
void restart()
Sets the indexes back to the beginning of the stream.
Definition: bit_stream.h:1078
const_iterator cbegin() const
Returns start of the stream.
Definition: bit_stream.h:1171
etl::enable_if< etl::is_same< bool, T >::value, bool >::type read_unchecked()
For bool types.
Definition: bit_stream.h:1090
etl::span< const char > data() const
Returns a span of whole the stream.
Definition: bit_stream.h:1195
bit_stream_reader(etl::span< unsigned char > span_, etl::endian stream_endianness_)
Construct from span.
Definition: bit_stream.h:1045
const_iterator begin() const
Returns start of the stream.
Definition: bit_stream.h:1163
size_t size_bytes() const
Returns the number of bytes in the stream buffer.
Definition: bit_stream.h:1147
Writes bits streams.
Definition: bit_stream.h:526
bit_stream_writer(void *begin_, void *end_, etl::endian stream_endianness_, callback_type callback_=callback_type())
Construct from range.
Definition: bit_stream.h:562
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:664
size_t size_bytes() const
Returns the number of bytes used in the stream.
Definition: bit_stream.h:705
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:652
etl::span< const char > used_data() const
Returns a span of the used portion of the stream.
Definition: bit_stream.h:822
bool write(bool value)
Writes a boolean to the stream.
Definition: bit_stream.h:635
size_t size_bits() const
Returns the number of bits used in the stream.
Definition: bit_stream.h:721
size_t available_bits() const
The number of bits left in the stream.
Definition: bit_stream.h:758
const_iterator cend() const
Returns end of the stream.
Definition: bit_stream.h:806
callback_type get_callback() const
Gets the function to call afer every write.
Definition: bit_stream.h:871
bool empty() const
Returns true if the bitsteam indexes have been reset.
Definition: bit_stream.h:610
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:574
iterator end()
Returns end of the stream.
Definition: bit_stream.h:790
void set_callback(callback_type callback_)
Sets the function to call afer every write.
Definition: bit_stream.h:863
size_t available() const
Definition: bit_stream.h:731
etl::span< char > data()
Returns a span of whole the stream.
Definition: bit_stream.h:830
bool full() const
Returns true if the bitsteam indexes have reached the end.
Definition: bit_stream.h:618
bool skip(size_t nbits)
Definition: bit_stream.h:681
bit_stream_writer(etl::span< char > span_, etl::endian stream_endianness_, callback_type callback_=callback_type())
Construct from span.
Definition: bit_stream.h:538
etl::span< char > used_data()
Returns a span of the used portion of the stream.
Definition: bit_stream.h:814
size_t capacity_bytes() const
Returns the maximum capacity in bits.
Definition: bit_stream.h:596
etl::span< const char > data() const
Returns a span of whole the stream.
Definition: bit_stream.h:838
void restart()
Sets the indexes back to the beginning of the stream.
Definition: bit_stream.h:586
void write_unchecked(bool value)
Writes a boolean to the stream.
Definition: bit_stream.h:626
void flush()
Flush the last byte, if partially filled, to the callback, if valid.
Definition: bit_stream.h:846
const_iterator cbegin() const
Returns start of the stream.
Definition: bit_stream.h:782
size_t available(size_t nbits) const
Definition: bit_stream.h:750
const_iterator end() const
Returns end of the stream.
Definition: bit_stream.h:798
const_iterator begin() const
Returns start of the stream.
Definition: bit_stream.h:774
iterator begin()
Returns start of the stream.
Definition: bit_stream.h:766
bit_stream_writer(etl::span< unsigned char > span_, etl::endian stream_endianness_, callback_type callback_=callback_type())
Construct from span.
Definition: bit_stream.h:550
Definition: bit_stream.h:56
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:223
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:152
bool put(int64_t value, uint_least8_t nbits=CHAR_BIT *sizeof(int64_t))
For 64bit integral types.
Definition: bit_stream.h:161
etl::enable_if< etl::is_floating_point< T >::value, bool >::type put(T value)
For floating point types.
Definition: bit_stream.h:180
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:297
size_t bits() const
Returns the number of bits used in the stream.
Definition: bit_stream.h:313
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:169
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:266
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:201
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:329
const_iterator begin() const
Returns start of the stream.
Definition: bit_stream.h:321
Definition: callback.h:45
Declaration.
Definition: delegate_cpp03.h:175
Definition: optional.h:108
Span - Fixed Extent.
Definition: span.h:62
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:575
Definition: endianness.h:100
Definition: integral_limits.h:468
enable_if
Definition: type_traits_generator.h:1191
is_same
Definition: type_traits_generator.h:1041
is_signed
Definition: type_traits_generator.h:1011
bitset_ext
Definition: absolute.h:38
bool read_unchecked< bool >(etl::bit_stream_reader &stream)
Read an unchecked bool from a stream.
Definition: bit_stream.h:1363
etl::optional< T > read(etl::bit_stream_reader &stream)
Read a checked type from a stream.
Definition: bit_stream.h:1348
void write_unchecked(etl::bit_stream_writer &stream, bool value)
Definition: bit_stream.h:983
etl::optional< bool > read< bool >(etl::bit_stream_reader &stream)
Read a bool from a stream.
Definition: bit_stream.h:1372
T read_unchecked(etl::bit_stream_reader &stream)
Read an unchecked type from a stream.
Definition: bit_stream.h:1333
bool write(etl::bit_stream_writer &stream, bool value)
Definition: bit_stream.h:992