91 lines
1.8 KiB
C
91 lines
1.8 KiB
C
#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);
|
|
}
|