26 #ifndef ETL_BIT_STREAM_INCLUDED
27 #define ETL_BIT_STREAM_INCLUDED
53 typedef const unsigned char* const_iterator;
69 : pdata(reinterpret_cast<unsigned char*>(begin_)),
70 length(
etl::distance(begin_, end_))
80 length(
etl::distance(begin_, end_))
89 : pdata(reinterpret_cast<unsigned char*>(begin_)),
110 pdata =
reinterpret_cast<unsigned char*
>(begin_);
130 set_stream(begin_, etl::distance(begin_, end_));
138 set_stream(begin_, etl::distance(begin_, end_));
148 bits_remaining = CHAR_BIT * length;
156 return (bits_remaining == 0U);
164 bool success =
false;
166 if (pdata != ETL_NULLPTR)
168 if (bits_remaining > 0)
170 unsigned char chunk = value ? 1 : 0;
171 put_integral(uint32_t(chunk), 1);
182 template <
typename T>
184 put(T value, uint_least8_t width = CHAR_BIT *
sizeof(T))
186 return put_integral(
static_cast<uint32_t
>(value), width);
189 #if ETL_USING_64BIT_TYPES
193 bool put(int64_t value, uint_least8_t width = CHAR_BIT *
sizeof(int64_t))
195 return put_integral(uint64_t(value), width);
201 bool put(uint64_t value, uint_least8_t width = CHAR_BIT *
sizeof(uint64_t))
203 return put_integral(value, width);
210 template <
typename T>
216 unsigned char data[
sizeof(T)];
217 to_bytes(value, data);
219 for (
size_t i = 0; i <
sizeof(T); ++i)
221 if (!put_integral(uint32_t(data[i]), CHAR_BIT))
235 bool success =
false;
237 if (pdata != ETL_NULLPTR)
240 if (bits_remaining > 0)
253 template <
typename T>
255 get(T& value, uint_least8_t width = CHAR_BIT *
sizeof(T))
257 bool success =
false;
258 uint_least8_t
bits = width;
260 if (pdata != ETL_NULLPTR)
263 if (bits_remaining >= width)
270 unsigned char mask_width =
static_cast<unsigned char>(etl::min(width, bits_in_byte));
271 unsigned char chunk = get_chunk(mask_width);
274 value |=
static_cast<T
>(chunk) << width;
284 typedef typename etl::make_signed<T>::type ST;
285 value = etl::sign_extend<ST, ST>(value,
bits);
294 template <
typename T>
298 bool success =
false;
300 if (pdata != ETL_NULLPTR)
302 uint_least8_t width = CHAR_BIT *
sizeof(T);
305 if (bits_remaining >= width)
308 unsigned char data[
sizeof(T)];
310 for (
size_t i = 0; i <
sizeof(T); ++i)
312 get(data[i], CHAR_BIT);
315 from_bytes(data, value);
329 size_t s = byte_index;
332 if (bits_in_byte != CHAR_BIT)
345 return (length * CHAR_BIT) - bits_remaining;
359 const_iterator
end()
const
361 return pdata +
size();
369 bool put_integral(uint32_t value, uint_least8_t width)
371 bool success =
false;
373 if (pdata != ETL_NULLPTR)
376 if (bits_remaining >= width)
381 unsigned char mask_width =
static_cast<unsigned char>(etl::min(width, bits_in_byte));
383 uint32_t mask = ((uint32_t(1U) << mask_width) - 1U) << width;
387 uint32_t chunk = ((value & mask) >> width) << (bits_in_byte - mask_width);
389 put_chunk(
static_cast<unsigned char>(chunk), mask_width);
399 #if ETL_USING_64BIT_TYPES
403 bool put_integral(uint64_t value, uint_least8_t width)
405 bool success =
false;
407 if (pdata != ETL_NULLPTR)
410 if (bits_remaining >= width)
415 unsigned char mask_width =
static_cast<unsigned char>(etl::min(width, bits_in_byte));
417 uint64_t mask = ((uint64_t(1U) << mask_width) - 1U) << width;
421 uint64_t chunk = ((value & mask) >> width) << (bits_in_byte - mask_width);
423 put_chunk(
static_cast<unsigned char>(chunk), mask_width);
437 void put_chunk(
unsigned char chunk,
unsigned char width)
440 if (bits_in_byte == 8)
442 pdata[byte_index] = 0U;
445 pdata[byte_index] |= chunk;
452 unsigned char get_chunk(
unsigned char width)
454 unsigned char value = pdata[byte_index];
456 value >>= (bits_in_byte - width);
460 if (width == CHAR_BIT)
466 mask = (1U << width) - 1;
481 bool result = (pdata[byte_index] & (1 << (bits_in_byte - 1))) != 0;
491 template <
typename T>
492 void from_bytes(
const unsigned char* data, T& value)
494 unsigned char temp[
sizeof(T)];
497 if (etl::endianness::value() == etl::endian::little)
499 etl::reverse_copy(data, data +
sizeof(T), temp);
503 etl::copy(data, data +
sizeof(T), temp);
506 value = *
reinterpret_cast<T*
>(temp);
512 template <
typename T>
513 void to_bytes(T value,
unsigned char* data)
515 unsigned char* pf =
reinterpret_cast<unsigned char*
>(&value);
518 if (etl::endianness::value() == etl::endian::little)
520 etl::reverse_copy(pf, pf +
sizeof(T), data);
524 etl::copy(pf, pf +
sizeof(T), data);
532 void step(
unsigned char width)
534 bits_in_byte -= width;
536 if (bits_in_byte == 0)
542 bits_remaining -= width;
545 unsigned char *pdata;
547 unsigned char bits_in_byte;
549 size_t bits_remaining;
Definition: bit_stream.h:50
bool put(uint64_t value, uint_least8_t width=CHAR_BIT *sizeof(uint64_t))
For 64bit integral types.
Definition: bit_stream.h:201
etl::enable_if< etl::is_integral< T >::value, bool >::type get(T &value, uint_least8_t width=CHAR_BIT *sizeof(T))
For integral types.
Definition: bit_stream.h:255
void set_stream(char *begin_, char *end_)
Construct from range.
Definition: bit_stream.h:128
bit_stream(char *begin_, size_t length_)
Construct from begin and length.
Definition: bit_stream.h:88
void restart()
Sets the indexes back to the beginning of the stream.
Definition: bit_stream.h:144
void set_stream(unsigned char *begin_, size_t length_)
Construct from begin and length.
Definition: bit_stream.h:118
bool put(int64_t value, uint_least8_t width=CHAR_BIT *sizeof(int64_t))
For 64bit integral types.
Definition: bit_stream.h:193
void set_stream(unsigned char *begin_, unsigned char *end_)
Construct from range.
Definition: bit_stream.h:136
size_t size() const
Returns the number of bytes used in the stream.
Definition: bit_stream.h:327
size_t bits() const
Returns the number of bits used in the stream.
Definition: bit_stream.h:343
etl::enable_if< etl::is_floating_point< T >::value, bool >::type get(T &value)
For floating point types.
Definition: bit_stream.h:296
bit_stream(unsigned char *begin_, size_t length_)
Construct from begin and length.
Definition: bit_stream.h:98
etl::enable_if< etl::is_floating_point< T >::value, bool >::type put(T value)
For floating point types.
Definition: bit_stream.h:212
bit_stream(unsigned char *begin_, unsigned char *end_)
Construct from range.
Definition: bit_stream.h:78
void set_stream(char *begin_, size_t length_)
Construct from begin and length.
Definition: bit_stream.h:108
bool at_end() const
Returns true if the bitsteam indexes have reached the end.
Definition: bit_stream.h:154
bool put(bool value)
Puts a boolean to the stream.
Definition: bit_stream.h:162
bit_stream()
Default constructor.
Definition: bit_stream.h:58
bool get(bool &value)
For bool types.
Definition: bit_stream.h:233
etl::enable_if< etl::is_integral< T >::value, bool >::type put(T value, uint_least8_t width=CHAR_BIT *sizeof(T))
For integral types.
Definition: bit_stream.h:184
const_iterator end() const
Returns end of the stream.
Definition: bit_stream.h:359
const_iterator begin() const
Returns start of the stream.
Definition: bit_stream.h:351
bit_stream(char *begin_, char *end_)
Construct from range.
Definition: bit_stream.h:68
Definition: integral_limits.h:54
enable_if
Definition: type_traits_generator.h:1228
is_signed
Definition: type_traits_generator.h:951
Definition: absolute.h:37