+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "input.h"
+
+void init_data_source(struct data_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 data_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 <= 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;
+ }
+}