mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-09 14:49:53 +08:00
Initial bit_stream_writer code
This commit is contained in:
parent
2695cd8fb8
commit
cace71c3f7
@ -38,6 +38,9 @@ SOFTWARE.
|
||||
#include "algorithm.h"
|
||||
#include "iterator.h"
|
||||
#include "memory.h"
|
||||
#include "delegate.h"
|
||||
#include "span.h"
|
||||
#include "endianness.h"
|
||||
|
||||
#include "private/minmax_push.h"
|
||||
|
||||
@ -58,7 +61,7 @@ namespace etl
|
||||
//***************************************************************************
|
||||
bit_stream()
|
||||
: pdata(ETL_NULLPTR),
|
||||
length(0U)
|
||||
length_chars(0U)
|
||||
{
|
||||
restart();
|
||||
}
|
||||
@ -68,7 +71,7 @@ namespace etl
|
||||
//***************************************************************************
|
||||
bit_stream(void* begin_, void* end_)
|
||||
: pdata(reinterpret_cast<unsigned char*>(begin_)),
|
||||
length(etl::distance(reinterpret_cast<unsigned char*>(begin_), reinterpret_cast<unsigned char*>(end_)))
|
||||
length_chars(etl::distance(reinterpret_cast<unsigned char*>(begin_), reinterpret_cast<unsigned char*>(end_)))
|
||||
{
|
||||
restart();
|
||||
}
|
||||
@ -78,7 +81,7 @@ namespace etl
|
||||
//***************************************************************************
|
||||
bit_stream(void* begin_, size_t length_)
|
||||
: pdata(reinterpret_cast<unsigned char*>(begin_)),
|
||||
length(length_)
|
||||
length_chars(length_)
|
||||
{
|
||||
restart();
|
||||
}
|
||||
@ -89,7 +92,7 @@ namespace etl
|
||||
void set_stream(void* begin_, size_t length_)
|
||||
{
|
||||
pdata = reinterpret_cast<unsigned char*>(begin_);
|
||||
length = length_;
|
||||
length_chars = length_;
|
||||
restart();
|
||||
}
|
||||
|
||||
@ -106,9 +109,9 @@ namespace etl
|
||||
//***************************************************************************
|
||||
void restart()
|
||||
{
|
||||
bits_in_byte = 8;
|
||||
byte_index = 0U;
|
||||
bits_remaining = CHAR_BIT * length;
|
||||
bits_available_in_char = 8;
|
||||
char_index = 0U;
|
||||
bits_remaining = CHAR_BIT * length_chars;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -120,7 +123,7 @@ namespace etl
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Puts a boolean to the stream
|
||||
/// Writes a boolean to the stream
|
||||
//***************************************************************************
|
||||
bool put(bool value)
|
||||
{
|
||||
@ -144,26 +147,26 @@ namespace etl
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
typename etl::enable_if<etl::is_integral<T>::value, bool>::type
|
||||
put(T value, uint_least8_t width = CHAR_BIT * sizeof(T))
|
||||
put(T value, uint_least8_t nbits = CHAR_BIT * sizeof(T))
|
||||
{
|
||||
return put_integral(static_cast<uint32_t>(value), width);
|
||||
return put_integral(static_cast<uint32_t>(value), nbits);
|
||||
}
|
||||
|
||||
#if ETL_USING_64BIT_TYPES
|
||||
//***************************************************************************
|
||||
/// For 64bit integral types
|
||||
//***************************************************************************
|
||||
bool put(int64_t value, uint_least8_t width = CHAR_BIT * sizeof(int64_t))
|
||||
bool put(int64_t value, uint_least8_t nbits = CHAR_BIT * sizeof(int64_t))
|
||||
{
|
||||
return put_integral(uint64_t(value), width);
|
||||
return put_integral(uint64_t(value), nbits);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// For 64bit integral types
|
||||
//***************************************************************************
|
||||
bool put(uint64_t value, uint_least8_t width = CHAR_BIT * sizeof(uint64_t))
|
||||
bool put(uint64_t value, uint_least8_t nbits = CHAR_BIT * sizeof(uint64_t))
|
||||
{
|
||||
return put_integral(value, width);
|
||||
return put_integral(value, nbits);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -215,28 +218,28 @@ namespace etl
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
typename etl::enable_if<etl::is_integral<T>::value, bool>::type
|
||||
get(T& value, uint_least8_t width = CHAR_BIT * sizeof(T))
|
||||
get(T& value, uint_least8_t nbits = CHAR_BIT * sizeof(T))
|
||||
{
|
||||
bool success = false;
|
||||
uint_least8_t bits = width;
|
||||
uint_least8_t bits = nbits;
|
||||
|
||||
if (pdata != ETL_NULLPTR)
|
||||
{
|
||||
// Do we have enough bits?
|
||||
if (bits_remaining >= width)
|
||||
if (bits_remaining >= nbits)
|
||||
{
|
||||
value = 0;
|
||||
|
||||
// Get the bits from the stream.
|
||||
while (width != 0)
|
||||
while (nbits != 0)
|
||||
{
|
||||
unsigned char mask_width = static_cast<unsigned char>(etl::min(width, bits_in_byte));
|
||||
unsigned char mask_width = static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
|
||||
|
||||
typedef typename etl::make_unsigned<T>::type chunk_t;
|
||||
chunk_t chunk = get_chunk(mask_width);
|
||||
|
||||
width -= mask_width;
|
||||
value |= static_cast<T>(chunk << width);
|
||||
nbits -= mask_width;
|
||||
value |= static_cast<T>(chunk << nbits);
|
||||
}
|
||||
|
||||
success = true;
|
||||
@ -264,10 +267,10 @@ namespace etl
|
||||
|
||||
if (pdata != ETL_NULLPTR)
|
||||
{
|
||||
uint_least8_t width = CHAR_BIT * sizeof(T);
|
||||
uint_least8_t nbits = CHAR_BIT * sizeof(T);
|
||||
|
||||
// Do we have enough bits?
|
||||
if (bits_remaining >= width)
|
||||
if (bits_remaining >= nbits)
|
||||
{
|
||||
// Temporary storage.
|
||||
etl::uninitialized_buffer_of<T, 1U> data;
|
||||
@ -291,10 +294,10 @@ namespace etl
|
||||
//***************************************************************************
|
||||
size_t size() const
|
||||
{
|
||||
size_t s = byte_index;
|
||||
size_t s = char_index;
|
||||
|
||||
// Current byte is used?
|
||||
if (bits_in_byte != CHAR_BIT)
|
||||
if (bits_available_in_char != CHAR_BIT)
|
||||
{
|
||||
++s;
|
||||
}
|
||||
@ -307,7 +310,7 @@ namespace etl
|
||||
//***************************************************************************
|
||||
size_t bits() const
|
||||
{
|
||||
return (length * CHAR_BIT) - bits_remaining;
|
||||
return (length_chars * CHAR_BIT) - bits_remaining;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -331,25 +334,25 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// For unsigned integral types
|
||||
//***************************************************************************
|
||||
bool put_integral(uint32_t value, uint_least8_t width)
|
||||
bool put_integral(uint32_t value, uint_least8_t nbits)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (pdata != ETL_NULLPTR)
|
||||
{
|
||||
// Do we have enough bits?
|
||||
if (bits_remaining >= width)
|
||||
if (bits_remaining >= nbits)
|
||||
{
|
||||
// Send the bits to the stream.
|
||||
while (width != 0)
|
||||
while (nbits != 0)
|
||||
{
|
||||
unsigned char mask_width = static_cast<unsigned char>(etl::min(width, bits_in_byte));
|
||||
width -= mask_width;
|
||||
uint32_t mask = ((uint32_t(1U) << mask_width) - 1U) << width;
|
||||
unsigned char mask_width = static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
|
||||
nbits -= mask_width;
|
||||
uint32_t mask = ((uint32_t(1U) << mask_width) - 1U) << nbits;
|
||||
|
||||
// Move chunk to lowest char bits.
|
||||
// Chunks are never larger than one char.
|
||||
uint32_t chunk = ((value & mask) >> width) << (bits_in_byte - mask_width);
|
||||
uint32_t chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width);
|
||||
|
||||
put_chunk(static_cast<unsigned char>(chunk), mask_width);
|
||||
}
|
||||
@ -365,25 +368,25 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// For unsigned integral types. 64bit
|
||||
//***************************************************************************
|
||||
bool put_integral(uint64_t value, uint_least8_t width)
|
||||
bool put_integral(uint64_t value, uint_least8_t nbits)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (pdata != ETL_NULLPTR)
|
||||
{
|
||||
// Do we have enough bits?
|
||||
if (bits_remaining >= width)
|
||||
if (bits_remaining >= nbits)
|
||||
{
|
||||
// Send the bits to the stream.
|
||||
while (width != 0)
|
||||
while (nbits != 0)
|
||||
{
|
||||
unsigned char mask_width = static_cast<unsigned char>(etl::min(width, bits_in_byte));
|
||||
width -= mask_width;
|
||||
uint64_t mask = ((uint64_t(1U) << mask_width) - 1U) << width;
|
||||
unsigned char mask_width = static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
|
||||
nbits -= mask_width;
|
||||
uint64_t mask = ((uint64_t(1U) << mask_width) - 1U) << nbits;
|
||||
|
||||
// Move chunk to lowest char bits.
|
||||
// Chunks are never larger than one char.
|
||||
uint64_t chunk = ((value & mask) >> width) << (bits_in_byte - mask_width);
|
||||
uint64_t chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width);
|
||||
|
||||
put_chunk(static_cast<unsigned char>(chunk), mask_width);
|
||||
}
|
||||
@ -399,41 +402,41 @@ namespace etl
|
||||
//***************************************************************************
|
||||
/// Put a data chunk to the stream
|
||||
//***************************************************************************
|
||||
void put_chunk(unsigned char chunk, unsigned char width)
|
||||
void put_chunk(unsigned char chunk, unsigned char nbits)
|
||||
{
|
||||
// Clear if new byte.
|
||||
if (bits_in_byte == 8)
|
||||
if (bits_available_in_char == 8U)
|
||||
{
|
||||
pdata[byte_index] = 0U;
|
||||
pdata[char_index] = 0U;
|
||||
}
|
||||
|
||||
pdata[byte_index] |= chunk;
|
||||
step(width);
|
||||
pdata[char_index] |= chunk;
|
||||
step(nbits);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Get a data chunk from the stream
|
||||
//***************************************************************************
|
||||
unsigned char get_chunk(unsigned char width)
|
||||
unsigned char get_chunk(unsigned char nbits)
|
||||
{
|
||||
unsigned char value = pdata[byte_index];
|
||||
unsigned char value = pdata[char_index];
|
||||
|
||||
value >>= (bits_in_byte - width);
|
||||
value >>= (bits_available_in_char - nbits);
|
||||
|
||||
unsigned char mask;
|
||||
|
||||
if (width == CHAR_BIT)
|
||||
if (nbits == CHAR_BIT)
|
||||
{
|
||||
mask = etl::integral_limits<unsigned char>::max;
|
||||
}
|
||||
else
|
||||
{
|
||||
mask = (1U << width) - 1;
|
||||
mask = (1U << nbits) - 1;
|
||||
}
|
||||
|
||||
value &= mask;
|
||||
|
||||
step(width);
|
||||
step(nbits);
|
||||
|
||||
return value;
|
||||
}
|
||||
@ -443,7 +446,7 @@ namespace etl
|
||||
//***************************************************************************
|
||||
bool get_bit()
|
||||
{
|
||||
bool result = (pdata[byte_index] & (1U << (bits_in_byte - 1U))) != 0U;
|
||||
bool result = (pdata[char_index] & (1U << (bits_available_in_char - 1U))) != 0U;
|
||||
|
||||
step(1U);
|
||||
|
||||
@ -492,27 +495,547 @@ namespace etl
|
||||
|
||||
//***************************************************************************
|
||||
/// Step the specified number of bits along the stream.
|
||||
/// The width will never be larger than 'bits_in_byte'.
|
||||
/// The nbits will never be larger than 'bits_available_in_char'.
|
||||
//***************************************************************************
|
||||
void step(unsigned char width)
|
||||
void step(unsigned char nbits)
|
||||
{
|
||||
bits_in_byte -= width;
|
||||
bits_available_in_char -= nbits;
|
||||
|
||||
if (bits_in_byte == 0)
|
||||
if (bits_available_in_char == 0)
|
||||
{
|
||||
++byte_index;
|
||||
bits_in_byte = 8;
|
||||
++char_index;
|
||||
bits_available_in_char = 8;
|
||||
}
|
||||
|
||||
bits_remaining -= width;
|
||||
bits_remaining -= nbits;
|
||||
}
|
||||
|
||||
unsigned char *pdata; ///< The start of the bitstream buffer.
|
||||
size_t length; ///< The length, in unsigned char, of the bitstream buffer.
|
||||
unsigned char bits_in_byte; ///< The number of available bits in the current char.
|
||||
size_t byte_index; ///< The index of the char in the bitstream buffer.
|
||||
size_t length_chars; ///< The length, in char, of the bitstream buffer.
|
||||
unsigned char bits_available_in_char; ///< The number of available bits in the current char.
|
||||
size_t char_index; ///< The index of the char in the bitstream buffer.
|
||||
size_t bits_remaining; ///< The number of bits still available in the bitstream buffer.
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Writes bits streams.
|
||||
//***************************************************************************
|
||||
class bit_stream_writer
|
||||
{
|
||||
public:
|
||||
|
||||
typedef const unsigned char* const_iterator;
|
||||
typedef char callback_parameter_type;
|
||||
typedef etl::delegate<void(char)> callback_type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Construct from span.
|
||||
//***************************************************************************
|
||||
bit_stream_writer(etl::span<char> span_, callback_type callback_ = callback_type())
|
||||
: pdata(reinterpret_cast<unsigned char*>(span_.begin()))
|
||||
, length_chars(span_.size_bytes())
|
||||
, callback(callback_)
|
||||
{
|
||||
restart();
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Construct from span.
|
||||
//***************************************************************************
|
||||
bit_stream_writer(etl::span<unsigned char> span_, callback_type callback_ = callback_type())
|
||||
: pdata(span_.begin())
|
||||
, length_chars(span_.size_bytes())
|
||||
, callback(callback_)
|
||||
{
|
||||
restart();
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Construct from range.
|
||||
//***************************************************************************
|
||||
bit_stream_writer(void* begin_, void* end_, callback_type callback_ = callback_type())
|
||||
: pdata(reinterpret_cast<unsigned char*>(begin_))
|
||||
, length_chars(etl::distance(reinterpret_cast<unsigned char*>(begin_), reinterpret_cast<unsigned char*>(end_)))
|
||||
, callback(callback_)
|
||||
{
|
||||
restart();
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Construct from begin and length.
|
||||
//***************************************************************************
|
||||
bit_stream_writer(void* begin_, size_t length_chars_, callback_type callback_ = callback_type())
|
||||
: pdata(reinterpret_cast<unsigned char*>(begin_))
|
||||
, length_chars(length_chars_)
|
||||
, callback(callback_)
|
||||
{
|
||||
restart();
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Sets the indexes back to the beginning of the stream.
|
||||
//***************************************************************************
|
||||
void restart()
|
||||
{
|
||||
bits_available_in_char = 8;
|
||||
char_index = 0U;
|
||||
bits_remaining = CHAR_BIT * length_chars;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns the maximum capacity in bits.
|
||||
//***************************************************************************
|
||||
size_t capacity_bytes() const
|
||||
{
|
||||
return length_chars;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
size_t capacity_bits() const
|
||||
{
|
||||
return length_chars * CHAR_BIT;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns <b>true</b> if the bitsteam indexes have been reset.
|
||||
//***************************************************************************
|
||||
bool empty() const
|
||||
{
|
||||
return (bits_remaining == length_chars);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns <b>true</b> if the bitsteam indexes have reached the end.
|
||||
//***************************************************************************
|
||||
bool full() const
|
||||
{
|
||||
return (bits_remaining == 0U);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Writes a boolean to the stream
|
||||
//***************************************************************************
|
||||
void write_unchecked(bool value)
|
||||
{
|
||||
unsigned char chunk = value ? 1 : 0;
|
||||
write_integral(uint32_t(chunk), 1);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Writes a boolean to the stream
|
||||
//***************************************************************************
|
||||
bool write(bool value)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (available<1U>() > 0U)
|
||||
{
|
||||
write_unchecked(value);
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// For integral types
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
typename etl::enable_if<etl::is_integral<T>::value, void>::type
|
||||
write_unchecked(T value, uint_least8_t nbits = CHAR_BIT * sizeof(T))
|
||||
{
|
||||
write_integral(static_cast<uint32_t>(value), nbits);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// For integral types
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
typename etl::enable_if<etl::is_integral<T>::value, bool>::type
|
||||
write(T value, uint_least8_t nbits = CHAR_BIT * sizeof(T))
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (available(nbits) > 0U)
|
||||
{
|
||||
write_unchecked(value, nbits);
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
#if ETL_USING_64BIT_TYPES
|
||||
//***************************************************************************
|
||||
/// For signed 64bit integral types
|
||||
//***************************************************************************
|
||||
void write_unchecked(int64_t value, uint_least8_t nbits = CHAR_BIT * sizeof(int64_t))
|
||||
{
|
||||
write_integral(uint64_t(value), nbits);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// For signed 64bit integral types
|
||||
//***************************************************************************
|
||||
bool write(int64_t value, uint_least8_t nbits = CHAR_BIT * sizeof(uint64_t))
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (available(nbits) > 0U)
|
||||
{
|
||||
write_unchecked(value, nbits);
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// For unsigned 64bit integral types
|
||||
//***************************************************************************
|
||||
void write_unchecked(uint64_t value, uint_least8_t nbits = CHAR_BIT * sizeof(int64_t))
|
||||
{
|
||||
write_integral(uint64_t(value), nbits);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// For unsigned 64bit integral types
|
||||
//***************************************************************************
|
||||
bool write(uint64_t value, uint_least8_t nbits = CHAR_BIT * sizeof(uint64_t))
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (available(nbits) > 0U)
|
||||
{
|
||||
write_unchecked(value, nbits);
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// For floating point types
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
typename etl::enable_if<etl::is_floating_point<T>::value, void>::type
|
||||
write_unchecked(T value)
|
||||
{
|
||||
unsigned char data[sizeof(T)];
|
||||
to_bytes(value, data);
|
||||
|
||||
for (size_t i = 0UL; i < sizeof(T); ++i)
|
||||
{
|
||||
write_integral(uint32_t(data[i]), CHAR_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// For floating point types
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
typename etl::enable_if<etl::is_floating_point<T>::value, bool>::type
|
||||
write(T value)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (available<T>())
|
||||
{
|
||||
write_unchecked(value);
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Skip n bits, up to the maximum space available.
|
||||
/// Returns <b>true</b> if the skip was possible.
|
||||
/// Returns <b>false</b> if the full skip size was not possible.
|
||||
//***************************************************************************
|
||||
bool skip(size_t nbits)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
if (nbits > available_bits())
|
||||
{
|
||||
nbits = available_bits();
|
||||
success = false;
|
||||
}
|
||||
|
||||
while (nbits > bits_available_in_char)
|
||||
{
|
||||
step(bits_available_in_char);
|
||||
nbits -= bits_available_in_char;
|
||||
}
|
||||
|
||||
if (nbits != 0U)
|
||||
{
|
||||
step(unsigned char(nbits));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns the number of bytes used in the stream.
|
||||
//***************************************************************************
|
||||
size_t size_bytes() const
|
||||
{
|
||||
size_t s = char_index;
|
||||
|
||||
// Is the current byte used?
|
||||
if (bits_available_in_char != CHAR_BIT)
|
||||
{
|
||||
++s;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns the number of bits used in the stream.
|
||||
//***************************************************************************
|
||||
size_t size_bits() const
|
||||
{
|
||||
return capacity_bits() - available_bits();
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// The number of 'bit nbits' available in the stream.
|
||||
/// Compile time.
|
||||
//***************************************************************************
|
||||
template <size_t Nbits>
|
||||
size_t available() const
|
||||
{
|
||||
return bits_remaining / Nbits;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// The number of T available in the stream.
|
||||
/// Compile time.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
size_t available() const
|
||||
{
|
||||
return available<CHAR_BIT * sizeof(T)>();
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// The number of 'bit width' available in the stream.
|
||||
/// Run time.
|
||||
//***************************************************************************
|
||||
size_t available(size_t nbits) const
|
||||
{
|
||||
return bits_remaining / nbits;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// The number of bits left in the stream.
|
||||
//***************************************************************************
|
||||
size_t available_bits() const
|
||||
{
|
||||
return bits_remaining;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns start of the stream.
|
||||
//***************************************************************************
|
||||
const_iterator begin() const
|
||||
{
|
||||
return pdata;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns start of the stream.
|
||||
//***************************************************************************
|
||||
const_iterator cbegin() const
|
||||
{
|
||||
return pdata;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns end of the stream.
|
||||
//***************************************************************************
|
||||
const_iterator end() const
|
||||
{
|
||||
return pdata + size_bytes();
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns end of the stream.
|
||||
//***************************************************************************
|
||||
const_iterator cend() const
|
||||
{
|
||||
return pdata + size_bytes();
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns a span of the used portion of the stream.
|
||||
//***************************************************************************
|
||||
etl::span<char> used_data() const
|
||||
{
|
||||
return etl::span<char>(reinterpret_cast<char*>(pdata), reinterpret_cast<char*>(pdata) + size_bytes());
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Returns a span of whole the stream.
|
||||
//***************************************************************************
|
||||
etl::span<char> data() const
|
||||
{
|
||||
return etl::span<char>(reinterpret_cast<char*>(pdata), reinterpret_cast<char*>(pdata) + length_chars);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Finalizes the stream and calls the callback, if set.
|
||||
//***************************************************************************
|
||||
void finalize()
|
||||
{
|
||||
if (bits_remaining != 0U)
|
||||
{
|
||||
callback.call_if(pdata[char_index]);
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Sets the function to call afer every write.
|
||||
//***************************************************************************
|
||||
void set_callback(callback_type callback_)
|
||||
{
|
||||
callback = callback_;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Gets the function to call afer every write.
|
||||
//***************************************************************************
|
||||
callback_type get_callback() const
|
||||
{
|
||||
return callback;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//***************************************************************************
|
||||
/// For unsigned integral types
|
||||
//***************************************************************************
|
||||
void write_integral(uint32_t value, uint_least8_t nbits)
|
||||
{
|
||||
// Send the bits to the stream.
|
||||
while (nbits != 0)
|
||||
{
|
||||
unsigned char mask_width = static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
|
||||
nbits -= mask_width;
|
||||
uint32_t mask = ((uint32_t(1U) << mask_width) - 1U) << nbits;
|
||||
|
||||
// Move chunk to lowest char bits.
|
||||
// Chunks are never larger than one char.
|
||||
uint32_t chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width);
|
||||
|
||||
write_chunk(static_cast<unsigned char>(chunk), mask_width);
|
||||
}
|
||||
}
|
||||
|
||||
#if ETL_USING_64BIT_TYPES
|
||||
//***************************************************************************
|
||||
/// For unsigned integral types. 64bit
|
||||
//***************************************************************************
|
||||
void write_integral(uint64_t value, uint_least8_t nbits)
|
||||
{
|
||||
// Send the bits to the stream.
|
||||
while (nbits != 0)
|
||||
{
|
||||
unsigned char mask_width = static_cast<unsigned char>(etl::min(nbits, bits_available_in_char));
|
||||
nbits -= mask_width;
|
||||
uint64_t mask = ((uint64_t(1U) << mask_width) - 1U) << nbits;
|
||||
|
||||
// Move chunk to lowest char bits.
|
||||
// Chunks are never larger than one char.
|
||||
uint64_t chunk = ((value & mask) >> nbits) << (bits_available_in_char - mask_width);
|
||||
|
||||
write_chunk(static_cast<unsigned char>(chunk), mask_width);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
/// Write a data chunk to the stream
|
||||
//***************************************************************************
|
||||
void write_chunk(unsigned char chunk, unsigned char nbits)
|
||||
{
|
||||
// Clear if new byte.
|
||||
if (bits_available_in_char == CHAR_BIT)
|
||||
{
|
||||
pdata[char_index] = 0U;
|
||||
}
|
||||
|
||||
pdata[char_index] |= chunk;
|
||||
step(nbits);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Convert to bytes.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
void to_bytes(T value, unsigned char* data)
|
||||
{
|
||||
unsigned char* pf = reinterpret_cast<unsigned char*>(&value);
|
||||
|
||||
// Host to network.
|
||||
if (etl::endianness::value() == etl::endian::little)
|
||||
{
|
||||
etl::reverse_copy(pf, pf + sizeof(T), data);
|
||||
}
|
||||
else
|
||||
{
|
||||
etl::copy(pf, pf + sizeof(T), data);
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Step the specified number of bits along the stream.
|
||||
/// The width will never be larger than 'bits_available_in_char'.
|
||||
//***************************************************************************
|
||||
void step(unsigned char nbits)
|
||||
{
|
||||
bits_available_in_char -= nbits;
|
||||
|
||||
if (bits_available_in_char == 0)
|
||||
{
|
||||
++char_index;
|
||||
bits_available_in_char = CHAR_BIT;
|
||||
}
|
||||
|
||||
bits_remaining -= nbits;
|
||||
}
|
||||
|
||||
unsigned char* const pdata; ///< The start of the bitstream buffer.
|
||||
const size_t length_chars; ///< The length, in unsigned char, of the bitstream buffer.
|
||||
unsigned char bits_available_in_char; ///< The number of available bits in the current char.
|
||||
size_t char_index; ///< The index of the char in the bitstream buffer.
|
||||
size_t bits_remaining; ///< The number of bits still available in the bitstream buffer.
|
||||
callback_type callback; ///< An optional callback on every filled byte on the write buffer.
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Default implementation of the write function.
|
||||
/// For integral and floating point types only.
|
||||
/// Overload this to support custom types.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
void write_unchecked(etl::bit_stream_writer& stream, const T& value, uint_least8_t nbits = CHAR_BIT * sizeof(T))
|
||||
{
|
||||
stream.write_unchecked(value, nbits);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Implementation of the write function.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
bool write(etl::bit_stream_writer& stream, const T& value, uint_least8_t nbits = CHAR_BIT * sizeof(T))
|
||||
{
|
||||
return stream.write(value, nbits);
|
||||
}
|
||||
}
|
||||
|
||||
#include "private/minmax_pop.h"
|
||||
|
||||
@ -72,6 +72,18 @@ namespace etl
|
||||
{
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Construct from span.
|
||||
//***************************************************************************
|
||||
byte_stream_writer(etl::span<unsigned char> span_, etl::endian buffer_endianness_, callback_type callback_ = callback_type())
|
||||
: pdata(reinterpret_cast<char*>(span_.begin()))
|
||||
, pcurrent(reinterpret_cast<char*>(span_.begin()))
|
||||
, length(span_.size_bytes())
|
||||
, buffer_endianness(buffer_endianness_)
|
||||
, callback(callback_)
|
||||
{
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Construct from range.
|
||||
//***************************************************************************
|
||||
@ -370,6 +382,22 @@ namespace etl
|
||||
callback = callback_;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Gets the function to call afer every write.
|
||||
//***************************************************************************
|
||||
callback_type get_callback() const
|
||||
{
|
||||
return callback;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Gets the endianness of the stream.
|
||||
//***************************************************************************
|
||||
etl::endian get_endianness() const
|
||||
{
|
||||
return buffer_endianness;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//***************************************************************************
|
||||
|
||||
746
test/test_bit_stream_writer.cpp
Normal file
746
test/test_bit_stream_writer.cpp
Normal file
@ -0,0 +1,746 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2022 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "unit_test_framework.h"
|
||||
|
||||
#include "etl/bit_stream.h"
|
||||
|
||||
#include <array>
|
||||
#include <numeric>
|
||||
|
||||
namespace
|
||||
{
|
||||
//***********************************
|
||||
struct Object
|
||||
{
|
||||
int16_t i;
|
||||
double d;
|
||||
uint8_t c;
|
||||
};
|
||||
|
||||
bool operator ==(const Object& lhs, const Object& rhs)
|
||||
{
|
||||
return (lhs.i == rhs.i) &&
|
||||
(lhs.d == rhs.d) &&
|
||||
(lhs.c == rhs.c);
|
||||
}
|
||||
|
||||
std::ostream& operator << (std::ostream& os, const Object& object)
|
||||
{
|
||||
os << object.i << "," << object.d << "," << (int)object.c;
|
||||
return os;
|
||||
}
|
||||
}
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***********************************
|
||||
bool write(etl::bit_stream_writer& stream, const Object& object)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
if (!stream.write(object.i, 14))
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (!stream.write(object.d))
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (!stream.write(object.c))
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
SUITE(test_bit_stream)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(test_bit_stream_writer_construction)
|
||||
{
|
||||
std::array<char, 256> storage;
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
CHECK_EQUAL(storage.size(), bit_stream.available(CHAR_BIT));
|
||||
CHECK_EQUAL(storage.size(), bit_stream.available<CHAR_BIT>());
|
||||
CHECK_EQUAL(storage.size(), bit_stream.available<unsigned char>());
|
||||
|
||||
CHECK_EQUAL(storage.size() * CHAR_BIT, bit_stream.available_bits());
|
||||
|
||||
CHECK_EQUAL(0U, bit_stream.size_bits());
|
||||
CHECK_EQUAL(0U, bit_stream.size_bytes());
|
||||
|
||||
CHECK_EQUAL(storage.size(), bit_stream.data().size());
|
||||
CHECK_EQUAL(0U, bit_stream.used_data().size());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_bool)
|
||||
{
|
||||
unsigned char storage = 0;
|
||||
unsigned char expected_data = 0x5AU;
|
||||
|
||||
etl::bit_stream_writer bit_stream(&storage, 1U);
|
||||
|
||||
CHECK(bit_stream.write(false));
|
||||
CHECK_EQUAL(1U, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(true));
|
||||
CHECK_EQUAL(1U, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(false));
|
||||
CHECK_EQUAL(1U, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(true));
|
||||
CHECK_EQUAL(1U, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(true));
|
||||
CHECK_EQUAL(1U, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(false));
|
||||
CHECK_EQUAL(1U, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(true));
|
||||
CHECK_EQUAL(1U, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(false));
|
||||
CHECK_EQUAL(1U, bit_stream.used_data().size());
|
||||
|
||||
// One too many.
|
||||
CHECK(!bit_stream.write(true));
|
||||
|
||||
CHECK_EQUAL(1U, bit_stream.data().size());
|
||||
CHECK_EQUAL(1U, bit_stream.used_data().size());
|
||||
|
||||
CHECK_EQUAL(int(expected_data), int(storage));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_int8_t)
|
||||
{
|
||||
std::array<char, 256U> storage;
|
||||
|
||||
std::array<char, 256U> expected_data;
|
||||
std::iota(expected_data.begin(), expected_data.end(), 0);
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
for (size_t i = 0UL; i < 256UL; ++i)
|
||||
{
|
||||
CHECK(bit_stream.write(int8_t(i)));
|
||||
CHECK_EQUAL(i + 1U, bit_stream.used_data().size());
|
||||
}
|
||||
|
||||
// One too many.
|
||||
CHECK(!bit_stream.write(int8_t(0)));
|
||||
|
||||
CHECK_EQUAL(256U, bit_stream.data().size());
|
||||
CHECK_EQUAL(256U, bit_stream.used_data().size());
|
||||
|
||||
for (size_t i = 0UL; i < storage.size(); ++i)
|
||||
{
|
||||
CHECK_EQUAL(int(expected_data[i]), int(storage[i]));
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_uint8_t)
|
||||
{
|
||||
std::array<char, 256> storage;
|
||||
|
||||
std::array<char, 256> expected_data;
|
||||
std::iota(expected_data.begin(), expected_data.end(), 0);
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
for (size_t i = 0UL; i < 256UL; ++i)
|
||||
{
|
||||
CHECK(bit_stream.write(uint8_t(i)));
|
||||
CHECK_EQUAL(i + 1U, bit_stream.used_data().size());
|
||||
}
|
||||
|
||||
// One too many.
|
||||
CHECK(!bit_stream.write(int8_t(0)));
|
||||
|
||||
CHECK_EQUAL(256U, bit_stream.data().size());
|
||||
CHECK_EQUAL(256U, bit_stream.used_data().size());
|
||||
|
||||
for (size_t i = 0UL; i < storage.size(); ++i)
|
||||
{
|
||||
CHECK_EQUAL(int(expected_data[i]), int(storage[i]));
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_int16_t)
|
||||
{
|
||||
// Tests assume big endian.
|
||||
std::array<char, sizeof(int16_t) * 4> storage;
|
||||
std::array<char, sizeof(int16_t) * 4> expected_data = { char(0x00), char(0x01),
|
||||
char(0x5A), char(0xA5),
|
||||
char(0xA5), char(0x5A),
|
||||
char(0xFF), char(0xFF) };
|
||||
|
||||
CHECK(expected_data.size() == storage.size());
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
CHECK(bit_stream.write(int16_t(0x0001)));
|
||||
CHECK_EQUAL(sizeof(int16_t) * 1, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(int16_t(0x5AA5)));
|
||||
CHECK_EQUAL(sizeof(int16_t) * 2, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(int16_t(0xA55A)));
|
||||
CHECK_EQUAL(sizeof(int16_t) * 3, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(int16_t(0xFFFF)));
|
||||
CHECK_EQUAL(sizeof(int16_t) * 4, bit_stream.used_data().size());
|
||||
|
||||
// One too many.
|
||||
CHECK(!bit_stream.write(int16_t(0)));
|
||||
|
||||
CHECK_EQUAL(sizeof(int16_t) * 4, bit_stream.data().size());
|
||||
CHECK_EQUAL(sizeof(int16_t) * 4, bit_stream.used_data().size());
|
||||
|
||||
for (size_t i = 0UL; i < storage.size(); ++i)
|
||||
{
|
||||
CHECK_EQUAL(int(expected_data[i]), int(storage[i]));
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_uint16_t)
|
||||
{
|
||||
// Tests assume big endian.
|
||||
std::array<char, sizeof(uint16_t) * 4> storage;
|
||||
std::array<char, sizeof(uint16_t) * 4> expected_data = { char(0x00), char(0x01),
|
||||
char(0x5A), char(0xA5),
|
||||
char(0xA5), char(0x5A),
|
||||
char(0xFF), char(0xFF) };
|
||||
|
||||
CHECK(expected_data.size() == storage.size());
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
CHECK(bit_stream.write(uint16_t(0x0001)));
|
||||
CHECK_EQUAL(sizeof(uint16_t) * 1, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(uint16_t(0x5AA5)));
|
||||
CHECK_EQUAL(sizeof(uint16_t) * 2, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(uint16_t(0xA55A)));
|
||||
CHECK_EQUAL(sizeof(uint16_t) * 3, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(uint16_t(0xFFFF)));
|
||||
CHECK_EQUAL(sizeof(uint16_t) * 4, bit_stream.used_data().size());
|
||||
|
||||
// One too many.
|
||||
CHECK(!bit_stream.write(uint16_t(0)));
|
||||
|
||||
CHECK_EQUAL(sizeof(uint16_t) * 4, bit_stream.data().size());
|
||||
CHECK_EQUAL(sizeof(uint16_t) * 4, bit_stream.used_data().size());
|
||||
|
||||
for (size_t i = 0UL; i < storage.size(); ++i)
|
||||
{
|
||||
CHECK_EQUAL(int(expected_data[i]), int(storage[i]));
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_int32_t)
|
||||
{
|
||||
// Tests assume big endian.
|
||||
std::array<char, sizeof(int32_t) * 4> storage;
|
||||
std::array<char, sizeof(int32_t) * 4> expected_data = { char(0x00), char(0x00), char(0x00), char(0x01),
|
||||
char(0x5A), char(0xA5), char(0xA5), char(0x5A),
|
||||
char(0xA5), char(0x5A), char(0x5A), char(0xA5),
|
||||
char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
|
||||
|
||||
CHECK(expected_data.size() == storage.size());
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
CHECK(bit_stream.write(int32_t(0x00000001)));
|
||||
CHECK_EQUAL(sizeof(int32_t) * 1, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(int32_t(0x5AA5A55A)));
|
||||
CHECK_EQUAL(sizeof(int32_t) * 2, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(int32_t(0xA55A5AA5)));
|
||||
CHECK_EQUAL(sizeof(int32_t) * 3, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(int32_t(0xFFFFFFFF)));
|
||||
CHECK_EQUAL(sizeof(int32_t) * 4, bit_stream.used_data().size());
|
||||
|
||||
// One too many.
|
||||
CHECK(!bit_stream.write(int32_t(0)));
|
||||
|
||||
CHECK_EQUAL(sizeof(int32_t) * 4, bit_stream.data().size());
|
||||
CHECK_EQUAL(sizeof(int32_t) * 4, bit_stream.used_data().size());
|
||||
|
||||
for (size_t i = 0UL; i < storage.size(); ++i)
|
||||
{
|
||||
CHECK_EQUAL(int(expected_data[i]), int(storage[i]));
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_uint32_t)
|
||||
{
|
||||
// Tests assume big endian.
|
||||
std::array<char, sizeof(uint32_t) * 4> storage;
|
||||
std::array<char, sizeof(uint32_t) * 4> expected_data = { char(0x00), char(0x00), char(0x00), char(0x01),
|
||||
char(0x5A), char(0xA5), char(0xA5), char(0x5A),
|
||||
char(0xA5), char(0x5A), char(0x5A), char(0xA5),
|
||||
char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
|
||||
|
||||
CHECK(expected_data.size() == storage.size());
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
CHECK(bit_stream.write(uint32_t(0x00000001)));
|
||||
CHECK_EQUAL(sizeof(uint32_t) * 1, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(uint32_t(0x5AA5A55A)));
|
||||
CHECK_EQUAL(sizeof(uint32_t) * 2, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(uint32_t(0xA55A5AA5)));
|
||||
CHECK_EQUAL(sizeof(uint32_t) * 3, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(uint32_t(0xFFFFFFFF)));
|
||||
CHECK_EQUAL(sizeof(uint32_t) * 4, bit_stream.used_data().size());
|
||||
|
||||
// One too many.
|
||||
CHECK(!bit_stream.write(uint32_t(0)));
|
||||
|
||||
CHECK_EQUAL(sizeof(uint32_t) * 4, bit_stream.data().size());
|
||||
CHECK_EQUAL(sizeof(uint32_t) * 4, bit_stream.used_data().size());
|
||||
|
||||
for (size_t i = 0UL; i < storage.size(); ++i)
|
||||
{
|
||||
CHECK_EQUAL(int(expected_data[i]), int(storage[i]));
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_int64_t)
|
||||
{
|
||||
// Tests assume big endian.
|
||||
std::array<char, sizeof(int64_t) * 4> storage;
|
||||
std::array<char, sizeof(int64_t) * 4> expected_data = { char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x01),
|
||||
char(0x5A), char(0xA5), char(0xA5), char(0x5A), char(0xA5), char(0x5A), char(0x5A), char(0xA5),
|
||||
char(0xA5), char(0x5A), char(0x5A), char(0xA5), char(0x5A), char(0xA5), char(0xA5), char(0x5A),
|
||||
char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
|
||||
|
||||
CHECK(expected_data.size() == storage.size());
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
CHECK(bit_stream.write(int64_t(0x0000000000000001LL)));
|
||||
CHECK_EQUAL(sizeof(int64_t) * 1, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(int64_t(0x5AA5A55AA55A5AA5LL)));
|
||||
CHECK_EQUAL(sizeof(int64_t) * 2, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(int64_t(0xA55A5AA55AA5A55ALL)));
|
||||
CHECK_EQUAL(sizeof(int64_t) * 3, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(int64_t(0xFFFFFFFFFFFFFFFFLL)));
|
||||
CHECK_EQUAL(sizeof(int64_t) * 4, bit_stream.used_data().size());
|
||||
|
||||
// One too many.
|
||||
CHECK(!bit_stream.write(int64_t(0)));
|
||||
|
||||
CHECK_EQUAL(sizeof(int64_t) * 4, bit_stream.data().size());
|
||||
CHECK_EQUAL(sizeof(int64_t) * 4, bit_stream.used_data().size());
|
||||
|
||||
for (size_t i = 0UL; i < storage.size(); ++i)
|
||||
{
|
||||
CHECK_EQUAL(int(expected_data[i]), int(storage[i]));
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_uint64_t)
|
||||
{
|
||||
// Tests assume big endian.
|
||||
std::array<char, sizeof(uint64_t) * 4> storage;
|
||||
std::array<char, sizeof(uint64_t) * 4> expected_data = { char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x00), char(0x01),
|
||||
char(0x5A), char(0xA5), char(0xA5), char(0x5A), char(0xA5), char(0x5A), char(0x5A), char(0xA5),
|
||||
char(0xA5), char(0x5A), char(0x5A), char(0xA5), char(0x5A), char(0xA5), char(0xA5), char(0x5A),
|
||||
char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF), char(0xFF) };
|
||||
|
||||
CHECK(expected_data.size() == storage.size());
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
CHECK(bit_stream.write(uint64_t(0x0000000000000001LL)));
|
||||
CHECK_EQUAL(sizeof(uint64_t) * 1, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(uint64_t(0x5AA5A55AA55A5AA5LL)));
|
||||
CHECK_EQUAL(sizeof(uint64_t) * 2, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(uint64_t(0xA55A5AA55AA5A55ALL)));
|
||||
CHECK_EQUAL(sizeof(uint64_t) * 3, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(uint64_t(0xFFFFFFFFFFFFFFFFLL)));
|
||||
CHECK_EQUAL(sizeof(uint64_t) * 4, bit_stream.used_data().size());
|
||||
|
||||
// One too many.
|
||||
CHECK(!bit_stream.write(uint64_t(0)));
|
||||
|
||||
CHECK_EQUAL(sizeof(uint64_t) * 4, bit_stream.data().size());
|
||||
CHECK_EQUAL(sizeof(uint64_t) * 4, bit_stream.used_data().size());
|
||||
|
||||
for (size_t i = 0UL; i < storage.size(); ++i)
|
||||
{
|
||||
CHECK_EQUAL(int(expected_data[i]), int(storage[i]));
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_int8_t_5bits)
|
||||
{
|
||||
std::array<char, 4 * sizeof(char)> storage;
|
||||
std::array<int8_t, 4> write_data = { int8_t(0x01), int8_t(0xF5), int8_t(0x05), int8_t(0xFF) }; // 1, -11, 10, -1
|
||||
std::array<char, 4> expected_data = { char(0x0D), char(0x4B), char(0xF0), char(0x00) }; // 1, -11, 10, -1
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
// Insert into the stream
|
||||
CHECK(bit_stream.write(write_data[0], 5));
|
||||
CHECK_EQUAL(1, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(write_data[1], 5));
|
||||
CHECK_EQUAL(2, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(write_data[2], 5));
|
||||
CHECK_EQUAL(2, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(write_data[3], 5));
|
||||
CHECK_EQUAL(3, bit_stream.used_data().size());
|
||||
|
||||
CHECK_EQUAL((int)expected_data[0], (int)storage[0]);
|
||||
CHECK_EQUAL((int)expected_data[1], (int)storage[1]);
|
||||
CHECK_EQUAL((int)expected_data[2], (int)storage[2]);
|
||||
// 4th byte not used.
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_int16_t_10bits)
|
||||
{
|
||||
std::array<char, 4 * sizeof(int16_t)> storage;
|
||||
std::array<int16_t, 4> write_data = { int16_t(0x0001), int16_t(0xA55A), int16_t(0x5AA5), int16_t(0xFFFF) };
|
||||
std::array<char, 4 * sizeof(int16_t)> expected_data = { char(0x00), char(0x55), char(0xAA), char(0x97),
|
||||
char(0xFF), char(0x00), char(0x00), char(0x00) };
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
// Insert into the stream
|
||||
CHECK(bit_stream.write(write_data[0], 10));
|
||||
CHECK_EQUAL(2, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(write_data[1], 10));
|
||||
CHECK_EQUAL(3, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(write_data[2], 10));
|
||||
CHECK_EQUAL(4, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(write_data[3], 10));
|
||||
CHECK_EQUAL(5, bit_stream.used_data().size());
|
||||
|
||||
CHECK_EQUAL((int)expected_data[0], (int)storage[0]);
|
||||
CHECK_EQUAL((int)expected_data[1], (int)storage[1]);
|
||||
CHECK_EQUAL((int)expected_data[2], (int)storage[2]);
|
||||
CHECK_EQUAL((int)expected_data[3], (int)storage[3]);
|
||||
CHECK_EQUAL((int)expected_data[4], (int)storage[4]);
|
||||
// 6th to 8th bytes not used.
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_uint32_t_22bits)
|
||||
{
|
||||
std::array<char, 4 * sizeof(uint32_t)> storage;
|
||||
std::array<uint32_t, 4> write_data = { uint32_t(0x00000001UL), uint32_t(0xA55AA55AUL), uint32_t(0x5AA55AA5UL), uint32_t(0xFFFFFFFFUL) };
|
||||
std::array<char, 4 * sizeof(uint32_t)> expected_data = { char(0x00), char(0x00), char(0x05), char(0xAA),
|
||||
char(0x55), char(0xA9), char(0x56), char(0xA9),
|
||||
char(0x7F), char(0xFF), char(0xFF), char(0x00),
|
||||
char(0x00), char(0x00), char(0x00), char(0x00) };
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
// Insert into the stream
|
||||
CHECK(bit_stream.write(write_data[0], 22));
|
||||
CHECK_EQUAL(3, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(write_data[1], 22));
|
||||
CHECK_EQUAL(6, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(write_data[2], 22));
|
||||
CHECK_EQUAL(9, bit_stream.used_data().size());
|
||||
CHECK(bit_stream.write(write_data[3], 22));
|
||||
CHECK_EQUAL(11, bit_stream.used_data().size());
|
||||
|
||||
CHECK_EQUAL((int)expected_data[0], (int)storage[0]);
|
||||
CHECK_EQUAL((int)expected_data[1], (int)storage[1]);
|
||||
CHECK_EQUAL((int)expected_data[2], (int)storage[2]);
|
||||
CHECK_EQUAL((int)expected_data[3], (int)storage[3]);
|
||||
CHECK_EQUAL((int)expected_data[4], (int)storage[4]);
|
||||
CHECK_EQUAL((int)expected_data[5], (int)storage[5]);
|
||||
CHECK_EQUAL((int)expected_data[6], (int)storage[6]);
|
||||
CHECK_EQUAL((int)expected_data[7], (int)storage[7]);
|
||||
CHECK_EQUAL((int)expected_data[8], (int)storage[8]);
|
||||
CHECK_EQUAL((int)expected_data[9], (int)storage[9]);
|
||||
CHECK_EQUAL((int)expected_data[10], (int)storage[10]);
|
||||
// 12th to 16th to bytes not used.
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_int64_t_47bits)
|
||||
{
|
||||
std::array<char, 4 * sizeof(int64_t)> storage;
|
||||
std::array<int64_t, 4> write_data = { int64_t(0x0000000000000001LL), int64_t(0xA55AA55AA55AA55ALL), int64_t(0x5AA55AA55AA55AA5LL), int64_t(0xFFFFFFFFFFFFFFFFLL) };
|
||||
std::array<char, 4 * sizeof(int64_t)> expected_data = { char(0x00), char(0x00), char(0x00), char(0x00),
|
||||
char(0x00), char(0x02), char(0x95), char(0x6A),
|
||||
char(0x95), char(0x6A), char(0x95), char(0x6A),
|
||||
char(0xD5), char(0x2A), char(0xD5), char(0x2A),
|
||||
char(0xD5), char(0x2F), char(0xFF), char(0xFF),
|
||||
char(0xFF), char(0xFF), char(0xFF), char(0xF0) };
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
// Insert into the stream
|
||||
bit_stream.write(write_data[0], 47);
|
||||
CHECK_EQUAL(6, bit_stream.used_data().size());
|
||||
bit_stream.write(write_data[1], 47);
|
||||
CHECK_EQUAL(12, bit_stream.used_data().size());
|
||||
bit_stream.write(write_data[2], 47);
|
||||
CHECK_EQUAL(18, bit_stream.used_data().size());
|
||||
bit_stream.write(write_data[3], 47);
|
||||
CHECK_EQUAL(24, bit_stream.used_data().size());
|
||||
|
||||
CHECK_EQUAL((int)expected_data[0], (int)storage[0]);
|
||||
CHECK_EQUAL((int)expected_data[1], (int)storage[1]);
|
||||
CHECK_EQUAL((int)expected_data[2], (int)storage[2]);
|
||||
CHECK_EQUAL((int)expected_data[3], (int)storage[3]);
|
||||
CHECK_EQUAL((int)expected_data[4], (int)storage[4]);
|
||||
CHECK_EQUAL((int)expected_data[5], (int)storage[5]);
|
||||
CHECK_EQUAL((int)expected_data[6], (int)storage[6]);
|
||||
CHECK_EQUAL((int)expected_data[7], (int)storage[7]);
|
||||
CHECK_EQUAL((int)expected_data[8], (int)storage[8]);
|
||||
CHECK_EQUAL((int)expected_data[9], (int)storage[9]);
|
||||
CHECK_EQUAL((int)expected_data[10], (int)storage[10]);
|
||||
CHECK_EQUAL((int)expected_data[11], (int)storage[11]);
|
||||
CHECK_EQUAL((int)expected_data[12], (int)storage[12]);
|
||||
CHECK_EQUAL((int)expected_data[13], (int)storage[13]);
|
||||
CHECK_EQUAL((int)expected_data[14], (int)storage[14]);
|
||||
CHECK_EQUAL((int)expected_data[15], (int)storage[15]);
|
||||
CHECK_EQUAL((int)expected_data[16], (int)storage[16]);
|
||||
CHECK_EQUAL((int)expected_data[17], (int)storage[17]);
|
||||
CHECK_EQUAL((int)expected_data[18], (int)storage[18]);
|
||||
CHECK_EQUAL((int)expected_data[19], (int)storage[19]);
|
||||
CHECK_EQUAL((int)expected_data[20], (int)storage[20]);
|
||||
CHECK_EQUAL((int)expected_data[21], (int)storage[21]);
|
||||
CHECK_EQUAL((int)expected_data[22], (int)storage[22]);
|
||||
CHECK_EQUAL((int)expected_data[23], (int)storage[23]);
|
||||
// 25th to 32nd bytes not used.
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_uint64_t_47bits)
|
||||
{
|
||||
std::array<char, 4 * sizeof(uint64_t)> storage;
|
||||
std::array<uint64_t, 4> write_data = { uint64_t(0x0000000000000001ULL), uint64_t(0xA55AA55AA55AA55AULL), uint64_t(0x5AA55AA55AA55AA5ULL), uint64_t(0xFFFFFFFFFFFFFFFFULL) };
|
||||
std::array<char, 4 * sizeof(uint64_t)> expected_data = { char(0x00), char(0x00), char(0x00), char(0x00),
|
||||
char(0x00), char(0x02), char(0x95), char(0x6A),
|
||||
char(0x95), char(0x6A), char(0x95), char(0x6A),
|
||||
char(0xD5), char(0x2A), char(0xD5), char(0x2A),
|
||||
char(0xD5), char(0x2F), char(0xFF), char(0xFF),
|
||||
char(0xFF), char(0xFF), char(0xFF), char(0xF0) };
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
// Insert into the stream
|
||||
bit_stream.write(write_data[0], 47);
|
||||
CHECK_EQUAL(6, bit_stream.used_data().size());
|
||||
bit_stream.write(write_data[1], 47);
|
||||
CHECK_EQUAL(12, bit_stream.used_data().size());
|
||||
bit_stream.write(write_data[2], 47);
|
||||
CHECK_EQUAL(18, bit_stream.used_data().size());
|
||||
bit_stream.write(write_data[3], 47);
|
||||
CHECK_EQUAL(24, bit_stream.used_data().size());
|
||||
|
||||
CHECK_EQUAL((int)expected_data[0], (int)storage[0]);
|
||||
CHECK_EQUAL((int)expected_data[1], (int)storage[1]);
|
||||
CHECK_EQUAL((int)expected_data[2], (int)storage[2]);
|
||||
CHECK_EQUAL((int)expected_data[3], (int)storage[3]);
|
||||
CHECK_EQUAL((int)expected_data[4], (int)storage[4]);
|
||||
CHECK_EQUAL((int)expected_data[5], (int)storage[5]);
|
||||
CHECK_EQUAL((int)expected_data[6], (int)storage[6]);
|
||||
CHECK_EQUAL((int)expected_data[7], (int)storage[7]);
|
||||
CHECK_EQUAL((int)expected_data[8], (int)storage[8]);
|
||||
CHECK_EQUAL((int)expected_data[9], (int)storage[9]);
|
||||
CHECK_EQUAL((int)expected_data[10], (int)storage[10]);
|
||||
CHECK_EQUAL((int)expected_data[11], (int)storage[11]);
|
||||
CHECK_EQUAL((int)expected_data[12], (int)storage[12]);
|
||||
CHECK_EQUAL((int)expected_data[13], (int)storage[13]);
|
||||
CHECK_EQUAL((int)expected_data[14], (int)storage[14]);
|
||||
CHECK_EQUAL((int)expected_data[15], (int)storage[15]);
|
||||
CHECK_EQUAL((int)expected_data[16], (int)storage[16]);
|
||||
CHECK_EQUAL((int)expected_data[17], (int)storage[17]);
|
||||
CHECK_EQUAL((int)expected_data[18], (int)storage[18]);
|
||||
CHECK_EQUAL((int)expected_data[19], (int)storage[19]);
|
||||
CHECK_EQUAL((int)expected_data[20], (int)storage[20]);
|
||||
CHECK_EQUAL((int)expected_data[21], (int)storage[21]);
|
||||
CHECK_EQUAL((int)expected_data[22], (int)storage[22]);
|
||||
CHECK_EQUAL((int)expected_data[23], (int)storage[23]);
|
||||
// 25th to 32nd bytes not used.
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_multiple_full_size)
|
||||
{
|
||||
char c1 = 90; // 0x5A
|
||||
char c2 = -91; // 0xA5
|
||||
unsigned short s1 = 4660; // 0x1234
|
||||
unsigned short s2 = 22136; // 0x5678
|
||||
int32_t i1 = 2309737967L; // 0x89ABCDEF
|
||||
int32_t i2 = 4275878552L; // 0xFEDCBA98
|
||||
|
||||
std::array<char, 14> storage;
|
||||
std::array<char, 14> expected_data = { char(0x5A),
|
||||
char(0x12), char(0x34),
|
||||
char(0x89), char(0xAB), char(0xCD), char(0xEF),
|
||||
char(0xFE), char(0xDC), char(0xBA), char(0x98),
|
||||
char(0x56), char(0x78),
|
||||
char(0xA5) };
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
// Insert into the stream.
|
||||
bit_stream.write(c1);
|
||||
CHECK_EQUAL(1, bit_stream.used_data().size());
|
||||
bit_stream.write(s1);
|
||||
CHECK_EQUAL(3, bit_stream.used_data().size());
|
||||
bit_stream.write(i1);
|
||||
CHECK_EQUAL(7, bit_stream.used_data().size());
|
||||
bit_stream.write(i2);
|
||||
CHECK_EQUAL(11, bit_stream.used_data().size());
|
||||
bit_stream.write(s2);
|
||||
CHECK_EQUAL(13, bit_stream.used_data().size());
|
||||
bit_stream.write(c2);
|
||||
CHECK_EQUAL(14, bit_stream.used_data().size());
|
||||
|
||||
CHECK_EQUAL((int)expected_data[0], (int)storage[0]);
|
||||
CHECK_EQUAL((int)expected_data[1], (int)storage[1]);
|
||||
CHECK_EQUAL((int)expected_data[2], (int)storage[2]);
|
||||
CHECK_EQUAL((int)expected_data[3], (int)storage[3]);
|
||||
CHECK_EQUAL((int)expected_data[4], (int)storage[4]);
|
||||
CHECK_EQUAL((int)expected_data[5], (int)storage[5]);
|
||||
CHECK_EQUAL((int)expected_data[6], (int)storage[6]);
|
||||
CHECK_EQUAL((int)expected_data[7], (int)storage[7]);
|
||||
CHECK_EQUAL((int)expected_data[8], (int)storage[8]);
|
||||
CHECK_EQUAL((int)expected_data[9], (int)storage[9]);
|
||||
CHECK_EQUAL((int)expected_data[10], (int)storage[10]);
|
||||
CHECK_EQUAL((int)expected_data[11], (int)storage[11]);
|
||||
CHECK_EQUAL((int)expected_data[12], (int)storage[12]);
|
||||
CHECK_EQUAL((int)expected_data[13], (int)storage[13]);
|
||||
}
|
||||
|
||||
////*************************************************************************
|
||||
TEST(test_write_multiple_variable_size)
|
||||
{
|
||||
char c1 = 90; // 0x5A 6 bits
|
||||
char c2 = -91; // 0xA5 7 bits
|
||||
unsigned short s1 = 4660; // 0x1234 13 bits
|
||||
unsigned short s2 = 22136; // 0x5678 11 bits
|
||||
int32_t i1 = 2309737967L; // 0x89ABCDEF 23 bits
|
||||
int32_t i2 = 4275878552L; // 0xFEDCBA98 25 bits
|
||||
|
||||
std::array<char, 14> storage;
|
||||
std::array<char, 14> expected_data = { char(0x6A), char(0x46), char(0x8A), char(0xF3),
|
||||
char(0x7B), char(0xDB), char(0x97), char(0x53),
|
||||
char(0x19), char(0xE1), char(0x28) };
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size());
|
||||
|
||||
// Insert into the stream.
|
||||
bit_stream.write(c1, 6);
|
||||
CHECK_EQUAL(1, bit_stream.used_data().size());
|
||||
bit_stream.write(s1, 13);
|
||||
CHECK_EQUAL(3, bit_stream.used_data().size());
|
||||
bit_stream.write(i1, 23);
|
||||
CHECK_EQUAL(6, bit_stream.used_data().size());
|
||||
bit_stream.write(i2, 25);
|
||||
CHECK_EQUAL(9, bit_stream.used_data().size());
|
||||
bit_stream.write(s2, 11);
|
||||
CHECK_EQUAL(10, bit_stream.used_data().size());
|
||||
bit_stream.write(c2, 7);
|
||||
CHECK_EQUAL(11, bit_stream.used_data().size());
|
||||
|
||||
CHECK_EQUAL((int)expected_data[0], (int)storage[0]);
|
||||
CHECK_EQUAL((int)expected_data[1], (int)storage[1]);
|
||||
CHECK_EQUAL((int)expected_data[2], (int)storage[2]);
|
||||
CHECK_EQUAL((int)expected_data[3], (int)storage[3]);
|
||||
CHECK_EQUAL((int)expected_data[4], (int)storage[4]);
|
||||
CHECK_EQUAL((int)expected_data[5], (int)storage[5]);
|
||||
CHECK_EQUAL((int)expected_data[6], (int)storage[6]);
|
||||
CHECK_EQUAL((int)expected_data[7], (int)storage[7]);
|
||||
CHECK_EQUAL((int)expected_data[8], (int)storage[8]);
|
||||
CHECK_EQUAL((int)expected_data[9], (int)storage[9]);
|
||||
CHECK_EQUAL((int)expected_data[10], (int)storage[10]);
|
||||
}
|
||||
|
||||
////*************************************************************************
|
||||
//TEST(put_get_object_global)
|
||||
//{
|
||||
// std::array<char, 2 * sizeof(Object)> storage;
|
||||
|
||||
// etl::bit_stream bit_stream(storage.data(), storage.size());
|
||||
|
||||
// Object object1 = { -1234, 2.71578369, 250 };
|
||||
// Object object2 = { 5678, 5.24685744, 126 };
|
||||
|
||||
// CHECK(etl::bit_stream_put(bit_stream, object1));
|
||||
// CHECK(etl::bit_stream_put(bit_stream, object2));
|
||||
|
||||
// Object object1a;
|
||||
// Object object2a;
|
||||
|
||||
// bit_stream.restart();
|
||||
|
||||
// CHECK(etl::bit_stream_get(bit_stream, object1a));
|
||||
// CHECK(etl::bit_stream_get(bit_stream, object2a));
|
||||
|
||||
// CHECK_EQUAL(object1, object1a);
|
||||
// CHECK_EQUAL(object2, object2a);
|
||||
//}
|
||||
|
||||
////*************************************************************************
|
||||
//TEST(put_get_multiple_float)
|
||||
//{
|
||||
|
||||
// float f = 3.1415927f;
|
||||
// double d = 3.1415927;
|
||||
|
||||
// std::array<char, 12> storage;
|
||||
|
||||
// etl::bit_stream bit_stream(storage.data(), storage.size());
|
||||
|
||||
// bit_stream.put(f);
|
||||
// bit_stream.put(d);
|
||||
|
||||
// bit_stream.restart();
|
||||
|
||||
// float rf;
|
||||
// double rd;
|
||||
|
||||
// CHECK(bit_stream.get(rf));
|
||||
// CHECK_CLOSE(f, rf, 0.1f);
|
||||
|
||||
// CHECK(bit_stream.get(rd));
|
||||
// CHECK_CLOSE(f, rd, 0.1f);
|
||||
//}
|
||||
};
|
||||
}
|
||||
@ -10912,6 +10912,7 @@
|
||||
<ClCompile Include="..\test_atomic_clang_sync.cpp" />
|
||||
<ClCompile Include="..\test_atomic_gcc_sync.cpp" />
|
||||
<ClCompile Include="..\test_bit.cpp" />
|
||||
<ClCompile Include="..\test_bit_stream_writer.cpp" />
|
||||
<ClCompile Include="..\test_bresenham_line.cpp" />
|
||||
<ClCompile Include="..\test_buffer_descriptors.cpp" />
|
||||
<ClCompile Include="..\test_byte.cpp" />
|
||||
|
||||
@ -3254,6 +3254,9 @@
|
||||
<ClCompile Include="..\sanity-check\delegate_cpp03.h.t.cpp">
|
||||
<Filter>Tests\Sanity Checks\Source</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test_bit_stream_writer.cpp">
|
||||
<Filter>Tests\Binary</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\library.properties">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user