mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-09 14:49:53 +08:00
Added callback functionality to bit_stream_writer
This commit is contained in:
parent
be9d64f5fc
commit
0ae71fb797
@ -510,11 +510,11 @@ namespace etl
|
||||
bits_remaining -= nbits;
|
||||
}
|
||||
|
||||
unsigned char *pdata; ///< The start of 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.
|
||||
unsigned char *pdata; ///< The start of 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.
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
@ -525,8 +525,9 @@ namespace etl
|
||||
public:
|
||||
|
||||
typedef const unsigned char* const_iterator;
|
||||
typedef char callback_parameter_type;
|
||||
typedef etl::delegate<void(char)> callback_type;
|
||||
|
||||
typedef etl::span<char> callback_parameter_type;
|
||||
typedef etl::delegate<void(callback_parameter_type)> callback_type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Construct from span.
|
||||
@ -785,7 +786,7 @@ namespace etl
|
||||
{
|
||||
size_t s = char_index;
|
||||
|
||||
// Is the current byte used?
|
||||
// Is the current byte partially used?
|
||||
if (bits_available_in_char != CHAR_BIT)
|
||||
{
|
||||
++s;
|
||||
@ -888,13 +889,19 @@ namespace etl
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Finalizes the stream and calls the callback, if set.
|
||||
/// Flush the last byte, if partially filled, to the callback, if valid.
|
||||
//***************************************************************************
|
||||
void finalize()
|
||||
void flush()
|
||||
{
|
||||
if (bits_remaining != 0U)
|
||||
if (callback.is_valid())
|
||||
{
|
||||
callback.call_if(pdata[char_index]);
|
||||
if (bits_available_in_char != 0U)
|
||||
{
|
||||
char_index = 1U;
|
||||
flush_full_bytes();
|
||||
char_index = 0U;
|
||||
bits_available_in_char = CHAR_BIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -934,6 +941,11 @@ namespace etl
|
||||
|
||||
write_chunk(static_cast<unsigned char>(chunk), mask_width);
|
||||
}
|
||||
|
||||
if (callback.is_valid())
|
||||
{
|
||||
flush_full_bytes();
|
||||
}
|
||||
}
|
||||
|
||||
#if ETL_USING_64BIT_TYPES
|
||||
@ -955,6 +967,13 @@ namespace etl
|
||||
|
||||
write_chunk(static_cast<unsigned char>(chunk), mask_width);
|
||||
}
|
||||
|
||||
size_t end_index = char_index;
|
||||
|
||||
if (callback.is_valid())
|
||||
{
|
||||
flush_full_bytes();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -973,6 +992,27 @@ namespace etl
|
||||
step(nbits);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Flush full bytes to the callback, if valid.
|
||||
/// Resets the
|
||||
//***************************************************************************
|
||||
void flush_full_bytes()
|
||||
{
|
||||
// Is the first byte fully filled?
|
||||
if (char_index > 0U)
|
||||
{
|
||||
callback(callback_parameter_type((char*)pdata, (char*)pdata + char_index));
|
||||
|
||||
if (bits_available_in_char != 0U)
|
||||
{
|
||||
// Move a partially filled last byte to the start of the buffer.
|
||||
pdata[0] = pdata[char_index];
|
||||
}
|
||||
|
||||
char_index = 0U;
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Convert to bytes.
|
||||
//***************************************************************************
|
||||
|
||||
@ -58,7 +58,7 @@ namespace etl
|
||||
|
||||
typedef const char* const_iterator;
|
||||
typedef etl::span<char> callback_parameter_type;
|
||||
typedef etl::delegate<void(etl::span<char>)> callback_type;
|
||||
typedef etl::delegate<void(callback_parameter_type)> callback_type;
|
||||
|
||||
//***************************************************************************
|
||||
/// Construct from span.
|
||||
|
||||
@ -31,6 +31,7 @@ SOFTWARE.
|
||||
#include "etl/bit_stream.h"
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <numeric>
|
||||
|
||||
namespace
|
||||
@ -85,6 +86,30 @@ namespace etl
|
||||
|
||||
namespace
|
||||
{
|
||||
class Accumulator
|
||||
{
|
||||
public:
|
||||
|
||||
void Add(etl::bit_stream_writer::callback_parameter_type s)
|
||||
{
|
||||
data.insert(data.end(), s.begin(), s.end());
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
data.clear();
|
||||
}
|
||||
|
||||
const std::vector<char>& GetData() const
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::vector<char> data;
|
||||
};
|
||||
|
||||
SUITE(test_bit_stream)
|
||||
{
|
||||
//*************************************************************************
|
||||
@ -648,7 +673,7 @@ namespace
|
||||
CHECK_EQUAL((int)expected_data[13], (int)storage[13]);
|
||||
}
|
||||
|
||||
////*************************************************************************
|
||||
//*************************************************************************
|
||||
TEST(test_write_multiple_variable_size)
|
||||
{
|
||||
char c1 = 90; // 0x5A 6 bits
|
||||
@ -692,6 +717,53 @@ namespace
|
||||
CHECK_EQUAL((int)expected_data[10], (int)storage[10]);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_write_multiple_variable_size_with_callback)
|
||||
{
|
||||
Accumulator accumulator;
|
||||
|
||||
char c1 = 90; // 0x5A 6 bits
|
||||
char c2 = -91; // 0xA5 7 bits
|
||||
unsigned short s1 = 4660U; // 0x1234 13 bits
|
||||
unsigned short s2 = 22136U; // 0x5678 11 bits
|
||||
int32_t i1 = 2309737967L; // 0x89ABCDEF 23 bits
|
||||
int32_t i2 = 4275878552L; // 0xFEDCBA98 25 bits
|
||||
|
||||
std::array<char, 14> storage;
|
||||
storage.fill(0);
|
||||
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) };
|
||||
|
||||
auto callback = etl::bit_stream_writer::callback_type::create<Accumulator, &Accumulator::Add>(accumulator);
|
||||
|
||||
etl::bit_stream_writer bit_stream(storage.data(), storage.size(), callback);
|
||||
|
||||
// Insert into the stream.
|
||||
bit_stream.write(c1, 6);
|
||||
bit_stream.write(s1, 13);
|
||||
bit_stream.write(i1, 23);
|
||||
bit_stream.write(i2, 25);
|
||||
bit_stream.write(s2, 11);
|
||||
bit_stream.write(c2, 7);
|
||||
bit_stream.flush();
|
||||
|
||||
CHECK_EQUAL(11U, accumulator.GetData().size());
|
||||
|
||||
CHECK_EQUAL((int)expected_data[0], (int)accumulator.GetData()[0]);
|
||||
CHECK_EQUAL((int)expected_data[1], (int)accumulator.GetData()[1]);
|
||||
CHECK_EQUAL((int)expected_data[2], (int)accumulator.GetData()[2]);
|
||||
CHECK_EQUAL((int)expected_data[3], (int)accumulator.GetData()[3]);
|
||||
CHECK_EQUAL((int)expected_data[4], (int)accumulator.GetData()[4]);
|
||||
CHECK_EQUAL((int)expected_data[5], (int)accumulator.GetData()[5]);
|
||||
CHECK_EQUAL((int)expected_data[6], (int)accumulator.GetData()[6]);
|
||||
CHECK_EQUAL((int)expected_data[7], (int)accumulator.GetData()[7]);
|
||||
CHECK_EQUAL((int)expected_data[8], (int)accumulator.GetData()[8]);
|
||||
CHECK_EQUAL((int)expected_data[9], (int)accumulator.GetData()[9]);
|
||||
CHECK_EQUAL((int)expected_data[10], (int)accumulator.GetData()[10]);
|
||||
|
||||
}
|
||||
|
||||
////*************************************************************************
|
||||
//TEST(put_get_object_global)
|
||||
//{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user