{
memset(source, 0, sizeof(*source));
source->bytes = (uint8_t*)malloc(BYTERESERVOIR_SIZE);
+ source->byte_read_ptr = source->bytes;
source->input_func = input_func;
source->userdata = userdata;
}
void possibly_refill_slow_path(struct bit_source* source, unsigned num_bits)
{
- // First, make sure there's stuff in the byte reservoir if we can.
+ // First, move out the data we already read.
assert(source->bytes_available <= BYTERESERVOIR_SIZE);
+ assert(source->byte_read_ptr >= source->bytes);
+ memmove(source->bytes, source->byte_read_ptr, source->bytes_available);
+ source->byte_read_ptr = source->bytes;
+ // Then, make sure there's stuff in the byte reservoir if we can.
// Read data from the source until we have enough to satisfy the request.
while (source->bits_available + 8 * source->bytes_available < num_bits) {
const size_t bytes_to_read = BYTERESERVOIR_SIZE - source->bytes_available;
while (source->bits_available < num_bits) {
assert(source->bytes_available > 0);
assert(source->bits_available + 8 <= BITRESERVOIR_SIZE);
- uint8_t byte = *(source->bytes);
- ++source->bytes;
+ uint8_t byte = *(source->byte_read_ptr);
+ ++source->byte_read_ptr;
--source->bytes_available;
source->bits |= ((bitreservoir_t)byte << (BITRESERVOIR_SIZE - source->bits_available - 8));
source->bits_available += 8;
// When this is empty, it needs to be refilled from the input
// stream.
uint8_t* bytes;
+ uint8_t* byte_read_ptr;
unsigned bytes_available;
// Data source.
// Slower path (~99% of remaining invocations?)
assert(source->bits_available + BITRESERVOIR_FILL_SIZE < BITRESERVOIR_SIZE);
if (source->bytes_available >= sizeof(bitreservoir_fill_t)) {
- bitreservoir_fill_t fill = read_bitreservoir_fill(source->bytes);
- source->bytes += sizeof(bitreservoir_fill_t);
+ bitreservoir_fill_t fill = read_bitreservoir_fill(source->byte_read_ptr);
+ source->byte_read_ptr += sizeof(bitreservoir_fill_t);
source->bytes_available -= sizeof(bitreservoir_fill_t);
source->bits |= (bitreservoir_t)fill << (BITRESERVOIR_SIZE - BITRESERVOIR_FILL_SIZE - source->bits_available);
source->bits_available += BITRESERVOIR_FILL_SIZE;