diff --git a/src/read.c b/src/read.c new file mode 100644 index 0000000..3497a49 --- /dev/null +++ b/src/read.c @@ -0,0 +1,99 @@ +#include "read.h" +#include "bin.h" +#include "pipeline.h" + +#include + +struct ec3_reader { + unsigned short r_version; + unsigned short r_cluster_size; + size_t r_tag_table_offset; + size_t r_extent_table_offset; + size_t r_cluster_table_offset; + unsigned int r_nr_tags; + unsigned int r_nr_extents; + unsigned int r_nr_cluster_groups; + + uint64_t r_id; + + struct ec3_pipeline *r_pipeline; +}; + +static void decode_header(const struct ec3_header *in, struct ec3_reader *out) +{ + out->r_version = b_i16_btoh(in->h_version); + out->r_cluster_size = ec3_get_cluster_size(b_i16_btoh(in->h_cluster_size)); + out->r_tag_table_offset = b_i64_btoh(in->h_tag_table_offset); + out->r_extent_table_offset = b_i64_btoh(in->h_extent_table_offset); + out->r_cluster_table_offset = b_i64_btoh(in->h_cluster_table_offset); + out->r_nr_tags = b_i32_btoh(in->h_tag_count); + out->r_nr_extents = b_i32_btoh(in->h_tag_count); + out->r_nr_cluster_groups = b_i32_btoh(in->h_cluster_group_count); +} + +enum ec3_status ec3_reader_create(FILE *inp, struct ec3_reader **out) +{ + struct ec3_header header; + + fseek(inp, 0, SEEK_SET); + size_t r = fread(&header, sizeof header, 1, inp); + + if (r != 1) { + return ferror(inp) ? EC3_ERR_IO_FAILURE : EC3_ERR_BAD_FORMAT; + } + + if (b_i32_btoh(header.h_magic) != EC3_SIGNATURE) { + return EC3_ERR_BAD_FORMAT; + } + + struct ec3_reader *reader = malloc(sizeof *reader); + if (!reader) { + return EC3_ERR_NO_MEMORY; + } + + memset(reader, 0x0, sizeof *reader); + + decode_header(&header, reader); + + unsigned short compression = b_i16_btoh(header.h_compression); + unsigned short encryption = b_i16_btoh(header.h_encryption); + + struct ec3_pipeline_stage_args stages[3] = { 0 }; + stages[0].type = EC3_PIPELINE_FILE; + + if (encryption != EC3_ENCRYPTION_NONE) { + stages[1].type = ec3_get_pipeline_stage_for_encryption_func(encryption); + } + + if (compression != EC3_COMPRESSION_NONE) { + stages[2].type = ec3_get_pipeline_stage_for_compression_func(compression); + } + + enum ec3_status status = ec3_pipeline_create( + stages, + sizeof stages / sizeof stages[0], + reader->r_cluster_size, + &reader->r_pipeline); + + if (status != EC3_SUCCESS) { + free(reader); + return status; + } + + return EC3_SUCCESS; +} + +void ec3_reader_finish(struct ec3_reader *reader) +{ + +} + +enum ec3_status ec3_reader_open_tag(struct ec3_reader *reader, uint64_t tag_ident, struct ec3_tag_reader **out) +{ + +} + +enum ec3_status ec3_tag_reader_close(struct ec3_tag_reader *tag) +{ + +} \ No newline at end of file diff --git a/src/read.h b/src/read.h new file mode 100644 index 0000000..46df8ea --- /dev/null +++ b/src/read.h @@ -0,0 +1,19 @@ +#ifndef READ_H_ +#define READ_H_ + +#include "status.h" + +#include +#include + +struct ec3_reader; +struct ec3_tag_reader; + +extern enum ec3_status ec3_reader_create(FILE *inp, struct ec3_reader **out); +extern void ec3_reader_finish(struct ec3_reader *reader); + +extern enum ec3_status ec3_reader_open_tag(struct ec3_reader *reader, uint64_t tag_ident, struct ec3_tag_reader **out); + +extern enum ec3_status ec3_tag_reader_close(struct ec3_tag_reader *tag); + +#endif \ No newline at end of file diff --git a/src/status.h b/src/status.h index 1dcebf1..e948cb7 100644 --- a/src/status.h +++ b/src/status.h @@ -7,6 +7,7 @@ enum ec3_status { EC3_ERR_NO_ENTRY, EC3_ERR_NOT_SUPPORTED, EC3_ERR_BAD_STATE, + EC3_ERR_BAD_FORMAT, EC3_ERR_INVALID_VALUE, EC3_ERR_NAME_EXISTS, EC3_ERR_IO_FAILURE,