meta: add compress module for (de)compressing data
This commit is contained in:
131
compress/compressor.c
Normal file
131
compress/compressor.c
Normal file
@@ -0,0 +1,131 @@
|
||||
#include "compressor.h"
|
||||
|
||||
#include "function.h"
|
||||
|
||||
#include <blue/compress/compressor.h>
|
||||
#include <blue/core/ringbuffer.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
enum b_status b_compressor_create(
|
||||
const struct b_compression_function *func, enum b_compressor_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;
|
||||
}
|
||||
|
||||
enum b_status b_compressor_compress(struct b_compressor *compressor)
|
||||
{
|
||||
if (compressor->c_mode != B_COMPRESSOR_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);
|
||||
}
|
||||
|
||||
enum b_status b_compressor_compress_end(struct b_compressor *compressor)
|
||||
{
|
||||
if (compressor->c_mode != B_COMPRESSOR_MODE_COMPRESS) {
|
||||
return B_ERR_BAD_STATE;
|
||||
}
|
||||
|
||||
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_compress(compressor);
|
||||
if (!B_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return compressor->c_func->f_compress_end(compressor);
|
||||
}
|
||||
|
||||
enum b_status b_compressor_decompress(struct b_compressor *compressor)
|
||||
{
|
||||
if (compressor->c_mode != B_COMPRESSOR_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_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;
|
||||
}
|
||||
Reference in New Issue
Block a user