+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-
-#include "input.h"
-
-#define MARKER_CHAR 0xff
-#define STUFF_MARKER 0x00
-
-void init_bit_source(struct bit_source* source, input_func_t* input_func, void* userdata)
-{
- memset(source, 0, sizeof(*source));
- source->bytes = (uint8_t*)malloc(BYTERESERVOIR_SIZE);
- 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.
- assert(source->bytes_available <= BYTERESERVOIR_SIZE);
-
- // 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;
- const ssize_t bytes_read =
- (*source->input_func)(source->userdata,
- source->bytes + source->bytes_available,
- bytes_to_read);
- assert(bytes_read <= (ssize_t)bytes_to_read);
- assert(bytes_read >= (ssize_t)-1);
-
- // TODO: We need better error handling here. setjmp()/longjmp()
- // should hopefully do the trick, but we need to take care for
- // suspension.
- if (bytes_read == (ssize_t)-1) {
- fprintf(stderr, "Input function returned error\n");
- exit(1);
- }
- if (bytes_read == 0) {
- fprintf(stderr, "Premature EOF\n");
- exit(1);
- }
-
- source->bytes_available += bytes_read;
- }
-
- // Fill the bit reservoir one by one byte until we have enough.
- 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;
- --source->bytes_available;
- source->bits |= ((bitreservoir_t)byte << (BITRESERVOIR_SIZE - source->bits_available - 8));
- source->bits_available += 8;
- }
-}