apfl/src/io.c

92 lines
1.8 KiB
C
Raw Normal View History

2023-03-05 16:02:42 +00:00
#include <assert.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#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);
}