feat(ltm): support custom data reader functions
All checks were successful
ci/woodpecker/push/build Pipeline was successful

This commit is contained in:
Jef Roosens 2023-12-16 23:00:00 +01:00
parent 53c2313953
commit dae8a2f30e
Signed by: Jef Roosens
GPG key ID: B75D4F293C7052DB
4 changed files with 90 additions and 8 deletions

View file

@ -86,6 +86,7 @@ ltm_err ltm_template_block_append(ltm_template *template,
typedef struct ltm_instance_block {
ltm_instance_block_type type;
ltm_data_fn fn;
struct {
void *ptr;
size_t len;

View file

@ -49,6 +49,7 @@ void ltm_instance_free(ltm_instance *instance) {
ltm_instance_free(block->data.ptr);
break;
case ltm_instance_block_type_file:
case ltm_instance_block_type_fn:
case ltm_instance_block_type_buf:;
}
@ -158,6 +159,48 @@ ltm_err ltm_instance_block_add_var(ltm_instance *instance, const char *name,
return ltm_err_ok;
}
ltm_err ltm_instance_block_add_var_fn(ltm_instance *instance, const char *name,
ltm_data_fn fn, void *data, size_t len) {
const ltm_template *template = instance->template;
ltm_template_block_name *block_name = NULL;
size_t i = 0;
for (i = 0; i < template->names.len; i++) {
block_name = &template->names.arr[i];
if (strncmp(name, block_name->name.s, block_name->name.len) == 0) {
break;
}
}
if (i == template->names.len) {
return ltm_err_not_found;
}
ltm_template_block *template_block = &template->blocks.arr[block_name->index];
if (template_block->type != ltm_template_block_type_var) {
return ltm_err_wrong_block_type;
}
ltm_instance_block *block;
LTM_RES(ltm_instance_block_init(&block));
block->type = ltm_instance_block_type_fn;
block->fn = fn;
block->data.ptr = data;
block->data.len = len;
// We insert the block in the linked list and replace its next pointer as the
// new attachment point for this variable
block->next = *instance->vars[i];
*instance->vars[i] = block;
instance->vars[i] = &block->next;
return ltm_err_ok;
}
ltm_err ltm_instance_block_add_nested(ltm_instance **out,
ltm_instance *instance,
const char *name) {
@ -211,6 +254,7 @@ size_t ltm_instance_size(const ltm_instance *instance) {
case ltm_instance_block_type_buf_owned:
case ltm_instance_block_type_file:
case ltm_instance_block_type_file_owned:
case ltm_instance_block_type_fn:
total += block->data.len;
break;
case ltm_instance_block_type_nested:
@ -264,6 +308,19 @@ ltm_err ltm_instance_write(size_t *written, char *buf, size_t len,
instance->written = 0;
}
} break;
case ltm_instance_block_type_fn: {
size_t cap =
LTM_MIN(current->data.len - instance->written, len - *written);
size_t fn_written = 0;
LTM_RES(current->fn(&fn_written, &buf[*written], cap, current->data.ptr));
*written += fn_written;
instance->written += fn_written;
if (instance->written == current->data.len) {
instance->blocks.current = current->next;
instance->written = 0;
}
} break;
case ltm_instance_block_type_nested: {
size_t nested_written = 0;
ltm_err res = ltm_instance_write(&nested_written, &buf[*written],