2021-12-16 21:49:41 +00:00
|
|
|
#include <assert.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include "apfl.h"
|
2022-02-08 21:53:13 +00:00
|
|
|
|
|
|
|
|
#include "alloc.h"
|
2021-12-16 21:49:41 +00:00
|
|
|
|
|
|
|
|
struct string_source_reader {
|
2022-02-08 21:53:13 +00:00
|
|
|
struct apfl_allocator allocator;
|
2021-12-16 21:49:41 +00:00
|
|
|
struct apfl_string_view sv;
|
|
|
|
|
size_t off;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
apfl_string_source_reader(void *opaque, char *buf, size_t *len, bool need)
|
|
|
|
|
{
|
|
|
|
|
(void)need;
|
|
|
|
|
|
|
|
|
|
struct string_source_reader *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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *
|
2022-02-08 21:53:13 +00:00
|
|
|
apfl_string_source_reader_new(struct apfl_allocator allocator, struct apfl_string_view sv)
|
2021-12-16 21:49:41 +00:00
|
|
|
{
|
2022-02-08 21:53:13 +00:00
|
|
|
struct string_source_reader *ctx = ALLOC_OBJ(allocator, struct string_source_reader);
|
2021-12-16 21:49:41 +00:00
|
|
|
if (ctx == NULL) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-08 21:53:13 +00:00
|
|
|
ctx->allocator = allocator;
|
2021-12-16 21:49:41 +00:00
|
|
|
ctx->sv = sv;
|
|
|
|
|
ctx->off = 0;
|
|
|
|
|
|
|
|
|
|
return ctx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
apfl_string_source_reader_destroy(void *opaque)
|
|
|
|
|
{
|
2022-02-08 21:53:13 +00:00
|
|
|
struct string_source_reader *ctx = opaque;
|
|
|
|
|
if (ctx == NULL) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FREE_OBJ(ctx->allocator, ctx);
|
2021-12-16 21:49:41 +00:00
|
|
|
}
|