#include #include #include #include #include "apfl.h" static bool file_read(void *opaque, unsigned char *buf, size_t *len) { FILE *f = opaque; size_t maxlen = *len; *len = fread(buf, 1, maxlen, f); if (*len == 0) { return feof(f); } return true; } struct apfl_io_reader apfl_io_file_reader(FILE *f) { return (struct apfl_io_reader) { .read = file_read, .opaque = f, }; } static bool string_reader_callback(void *opaque, unsigned char *buf, size_t *len) { struct apfl_io_string_reader_data *ctx = opaque; size_t maxlen = *len; size_t remain_len = ctx->sv.len - ctx->off; *len = maxlen < remain_len ? maxlen : remain_len; memcpy(buf, ctx->sv.bytes + ctx->off, *len); ctx->off += *len; assert(ctx->off <= ctx->sv.len); return true; } struct apfl_io_string_reader_data apfl_io_string_reader_create(struct apfl_string_view sv) { return (struct apfl_io_string_reader_data) { .sv = sv, .off = 0, }; } struct apfl_io_reader apfl_io_string_reader(struct apfl_io_string_reader_data *data) { return (struct apfl_io_reader) { .read = string_reader_callback, .opaque = data, }; } bool apfl_io_read_bytes(struct apfl_io_reader r, unsigned char *buf, size_t *len) { return r.read(r.opaque, buf, len); } bool apfl_io_read_bytes_exact_size(struct apfl_io_reader r, unsigned char *buf, size_t want) { while (want > 0) { size_t have = want; if (!apfl_io_read_bytes(r, buf, &have)) { return false; } if (have == 0) { return false; } want -= have; buf += have; } return true; } bool apfl_io_read_byte(struct apfl_io_reader r, unsigned char *byte) { return apfl_io_read_bytes_exact_size(r, byte, 1); }