#include "compressor.h" #include "function.h" #include #include #include #include enum b_status b_compressor_create( const struct b_compression_function *func, enum b_compression_mode mode, struct b_ringbuffer *inbuf, struct b_ringbuffer *outbuf, struct b_compressor **out) { size_t ctx_size = sizeof(struct b_compressor) + func->f_ctx_size; struct b_compressor *compressor = malloc(ctx_size); if (!compressor) { return B_ERR_NO_MEMORY; } memset(compressor, 0x0, ctx_size); compressor->c_func = func; compressor->c_in = inbuf; compressor->c_out = outbuf; compressor->c_mode = mode; enum b_status status = B_SUCCESS; if (func->f_init) { status = func->f_init(compressor); } if (!B_OK(status)) { free(compressor); compressor = NULL; } *out = compressor; return status; } enum b_status b_compressor_destroy(struct b_compressor *compressor) { enum b_status status = B_SUCCESS; if (compressor->c_func->f_fini) { status = compressor->c_func->f_fini(compressor); } if (!B_OK(status)) { return status; } free(compressor); return B_SUCCESS; } static enum b_status compress(struct b_compressor *compressor) { if (compressor->c_mode != B_COMPRESSION_MODE_COMPRESS) { return B_ERR_BAD_STATE; } if (!compressor->c_func->f_compress) { return B_ERR_NOT_SUPPORTED; } return compressor->c_func->f_compress(compressor); } static enum b_status decompress(struct b_compressor *compressor) { if (compressor->c_mode != B_COMPRESSION_MODE_DECOMPRESS) { return B_ERR_BAD_STATE; } if (!compressor->c_func->f_decompress) { return B_ERR_NOT_SUPPORTED; } return compressor->c_func->f_decompress(compressor); } enum b_status b_compressor_step(struct b_compressor *compressor) { switch (compressor->c_mode) { case B_COMPRESSION_MODE_COMPRESS: return compress(compressor); case B_COMPRESSION_MODE_DECOMPRESS: return decompress(compressor); default: return B_ERR_BAD_STATE; } } enum b_status b_compressor_end(struct b_compressor *compressor) { if (compressor->c_mode != B_COMPRESSION_MODE_COMPRESS) { return B_SUCCESS; } if (!compressor->c_func->f_compress_end) { return B_ERR_NOT_SUPPORTED; } while (b_ringbuffer_available_data_remaining(compressor->c_in)) { if (!b_ringbuffer_write_capacity_remaining(compressor->c_out)) { return B_ERR_NO_SPACE; } enum b_status status = b_compressor_step(compressor); if (!B_OK(status)) { return status; } } return compressor->c_func->f_compress_end(compressor); } enum b_status b_compressor_reset(struct b_compressor *compressor) { compressor->c_flags &= ~COMPRESSOR_EOF; if (compressor->c_func->f_reset) { return compressor->c_func->f_reset(compressor); } return B_SUCCESS; } bool b_compressor_eof(const struct b_compressor *compressor) { return (compressor->c_flags & COMPRESSOR_EOF) != 0; } void *b_compressor_get_function_ctx(struct b_compressor *compressor) { unsigned char *p = (unsigned char *)compressor; p += sizeof *compressor; return p; }