Files
ec3/src/pipeline.c

157 lines
3.1 KiB
C
Raw Normal View History

2025-01-30 18:10:38 +00:00
#include "pipeline.h"
#include <stdlib.h>
#include <string.h>
extern const struct ec3_pipeline_stage_type pipeline_zstd;
extern const struct ec3_pipeline_stage_type pipeline_aes256;
extern const struct ec3_pipeline_stage_type pipeline_file;
static const struct ec3_pipeline_stage_type *stage_types[] = {
[EC3_PIPELINE_ZSTD] = &pipeline_zstd,
[EC3_PIPELINE_AES256] = &pipeline_aes256,
[EC3_PIPELINE_FILE] = &pipeline_file,
};
static const size_t nr_stage_types = sizeof stage_types / sizeof stage_types[0];
static enum ec3_status create_pipeline_stage(
const struct ec3_pipeline_stage_type *type,
size_t cluster_size,
void *arg,
struct ec3_pipeline_stage **out)
{
struct ec3_pipeline_stage *stage = malloc(sizeof *stage);
if (!stage) {
return EC3_ERR_NO_MEMORY;
}
memset(stage, 0x0, sizeof *stage);
stage->s_type = type;
stage->s_arg = arg;
if (type->t_flags & EC3_PIPELINE_F_BUFFERED) {
stage->s_buf = malloc(cluster_size);
if (!stage) {
free(stage);
return EC3_ERR_NO_MEMORY;
}
memset(stage->s_buf, 0x0, cluster_size);
}
*out = stage;
return EC3_SUCCESS;
}
extern enum ec3_status ec3_pipeline_create(
struct ec3_pipeline_stage_args stages[],
size_t nr_stages,
size_t cluster_size,
struct ec3_pipeline **out)
{
enum ec3_status status = EC3_SUCCESS;
struct ec3_pipeline *pipeline = malloc(sizeof *pipeline);
if (!pipeline) {
return EC3_ERR_NO_MEMORY;
}
memset(pipeline, 0x0, sizeof *pipeline);
for (size_t i = 0; i < nr_stages; i++) {
struct ec3_pipeline_stage_args *args = &stages[i];
if (args->type == EC3_PIPELINE_NONE) {
continue;
}
if (args->type < 0 || args->type >= nr_stage_types) {
return EC3_ERR_NOT_SUPPORTED;
}
const struct ec3_pipeline_stage_type *type
= stage_types[stages[i].type];
if (!type) {
return EC3_ERR_NOT_SUPPORTED;
}
struct ec3_pipeline_stage *stage = NULL;
status = create_pipeline_stage(
type,
cluster_size,
args->arg,
&stage);
if (status != EC3_SUCCESS) {
return status;
}
b_queue_push_back(&pipeline->p_stages, &stage->s_entry);
}
*out = pipeline;
return status;
}
void ec3_pipeline_destroy(struct ec3_pipeline *p)
{
}
enum ec3_status ec3_pipeline_data_out(
struct ec3_pipeline *pipeline,
void *p,
size_t len,
size_t *nr_written)
{
b_queue_entry *cur = b_queue_first(&pipeline->p_stages);
enum ec3_status status = EC3_SUCCESS;
void *src = p;
size_t stage_in_size = len;
size_t stage_out_size = 0;
while (cur) {
struct ec3_pipeline_stage *stage
= b_unbox(struct ec3_pipeline_stage, cur, s_entry);
void *dest;
if (stage->s_type->t_flags & EC3_PIPELINE_F_BUFFERED) {
dest = stage->s_buf;
} else {
dest = src;
}
status = stage->s_type->t_data_out(
stage,
src,
stage_in_size,
dest,
&stage_out_size);
if (status != EC3_SUCCESS) {
return status;
}
src = dest;
stage_in_size = stage_out_size;
cur = b_queue_next(cur);
}
if (nr_written) {
*nr_written = stage_out_size;
}
return EC3_SUCCESS;
}
enum ec3_status ec3_pipeline_data_in(
struct ec3_pipeline *pipeline,
void *p,
size_t max,
size_t *nr_read)
{
return EC3_ERR_NOT_SUPPORTED;
}