]> git.sesse.net Git - fjl/commitdiff
The bit source needs to actually consume the data it passes by...
authorSteinar H. Gunderson <sesse@debian.org>
Sat, 3 Jan 2009 13:14:16 +0000 (14:14 +0100)
committerSteinar H. Gunderson <sesse@debian.org>
Sat, 3 Jan 2009 13:14:16 +0000 (14:14 +0100)
bitsource.c
bitsource.h

index 72b143bf7092b666669b3eafb19baf1b7d3bd670..6cc627c70b08b462b0d0c9c7e0a4ec3d25cdceed 100644 (file)
@@ -12,15 +12,20 @@ void init_bit_source(struct bit_source* source, input_func_t* input_func, void*
 {
        memset(source, 0, sizeof(*source));
        source->bytes = (uint8_t*)malloc(BYTERESERVOIR_SIZE);
 {
        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)
 {
        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->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;
        // 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;
@@ -50,8 +55,8 @@ void possibly_refill_slow_path(struct bit_source* source, unsigned num_bits)
        while (source->bits_available < num_bits) {
                assert(source->bytes_available > 0);
                assert(source->bits_available + 8 <= BITRESERVOIR_SIZE);
        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;
                --source->bytes_available;
                source->bits |= ((bitreservoir_t)byte << (BITRESERVOIR_SIZE - source->bits_available - 8));
                source->bits_available += 8;
index 6cabbf004245139d6f3f5a8f5f5fac5cfdb646e6..bb3a6d246e62016665e5560ac048397b15f7f8e9 100644 (file)
@@ -34,6 +34,7 @@ struct bit_source {
        // When this is empty, it needs to be refilled from the input
        // stream.
        uint8_t* bytes;
        // 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.
        unsigned bytes_available;
 
        // Data source.
@@ -62,8 +63,8 @@ static inline void possibly_refill(struct bit_source* source, unsigned num_bits)
        // Slower path (~99% of remaining invocations?)
        assert(source->bits_available + BITRESERVOIR_FILL_SIZE < BITRESERVOIR_SIZE);
        if (source->bytes_available >= sizeof(bitreservoir_fill_t)) {
        // 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;
                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;