compress: compressor: convert b_compressor to a b_object interface
This commit is contained in:
@@ -1,145 +1,239 @@
|
|||||||
#include "compressor.h"
|
|
||||||
|
|
||||||
#include "function.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <blue/compress/compressor.h>
|
#include <blue/compress/compressor.h>
|
||||||
#include <blue/core/ringbuffer.h>
|
#include <blue/core/ringbuffer.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
enum b_status b_compressor_create(
|
#define COMPRESSOR_DISPATCH_STATIC(func, compressor, ...) \
|
||||||
const struct b_compression_function *func, enum b_compression_mode mode,
|
do { \
|
||||||
struct b_ringbuffer *inbuf, struct b_ringbuffer *outbuf,
|
struct compressor_data _compressor; \
|
||||||
struct b_compressor **out)
|
enum b_status status \
|
||||||
|
= compressor_get_data(compressor, &_compressor); \
|
||||||
|
if (!B_OK(status)) { \
|
||||||
|
return status; \
|
||||||
|
} \
|
||||||
|
return func(&_compressor, __VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
#define COMPRESSOR_DISPATCH_STATIC_0(func, compressor) \
|
||||||
|
do { \
|
||||||
|
struct compressor_data _compressor; \
|
||||||
|
enum b_status status \
|
||||||
|
= compressor_get_data(compressor, &_compressor); \
|
||||||
|
if (!B_OK(status)) { \
|
||||||
|
return status; \
|
||||||
|
} \
|
||||||
|
return func(&_compressor); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/*** PRIVATE DATA *************************************************************/
|
||||||
|
|
||||||
|
struct compressor_data {
|
||||||
|
b_compressor *c_obj;
|
||||||
|
b_compressor_class *c_ops;
|
||||||
|
b_compressor_data *c_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*** PRIVATE FUNCTIONS ********************************************************/
|
||||||
|
|
||||||
|
static enum b_status compressor_get_data(
|
||||||
|
b_compressor *compressor, struct compressor_data *out)
|
||||||
{
|
{
|
||||||
size_t ctx_size = sizeof(struct b_compressor) + func->f_ctx_size;
|
out->c_obj = compressor;
|
||||||
struct b_compressor *compressor = malloc(ctx_size);
|
return b_object_get_data(
|
||||||
if (!compressor) {
|
compressor, B_TYPE_COMPRESSOR, NULL, (void **)&out->c_data,
|
||||||
return B_ERR_NO_MEMORY;
|
(void **)&out->c_ops);
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
static enum b_status compressor_get_mode(
|
||||||
|
struct compressor_data *p, enum b_compressor_mode *out)
|
||||||
{
|
{
|
||||||
enum b_status status = B_SUCCESS;
|
if (out) {
|
||||||
|
*out = p->c_data->c_mode;
|
||||||
if (compressor->c_func->f_fini) {
|
|
||||||
status = compressor->c_func->f_fini(compressor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!B_OK(status)) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(compressor);
|
|
||||||
|
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum b_status compress(struct b_compressor *compressor)
|
static enum b_status compressor_set_mode(
|
||||||
|
struct compressor_data *p, enum b_compressor_mode mode)
|
||||||
{
|
{
|
||||||
if (compressor->c_mode != B_COMPRESSION_MODE_COMPRESS) {
|
if (!p->c_ops->c_set_mode) {
|
||||||
return B_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!compressor->c_func->f_compress) {
|
|
||||||
return B_ERR_NOT_SUPPORTED;
|
return B_ERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compressor->c_func->f_compress(compressor);
|
return p->c_ops->c_set_mode(p->c_obj, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum b_status decompress(struct b_compressor *compressor)
|
static enum b_status compressor_set_buffer(
|
||||||
|
struct compressor_data *p, b_ringbuffer *inbuf, b_ringbuffer *outbuf)
|
||||||
{
|
{
|
||||||
if (compressor->c_mode != B_COMPRESSION_MODE_DECOMPRESS) {
|
p->c_data->c_in = inbuf;
|
||||||
|
p->c_data->c_out = outbuf;
|
||||||
|
|
||||||
|
return B_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum b_status compress(struct compressor_data *p)
|
||||||
|
{
|
||||||
|
if (p->c_data->c_mode != B_COMPRESSOR_MODE_COMPRESS) {
|
||||||
return B_ERR_BAD_STATE;
|
return B_ERR_BAD_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!compressor->c_func->f_decompress) {
|
if (!p->c_ops->c_compress) {
|
||||||
return B_ERR_NOT_SUPPORTED;
|
return B_ERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compressor->c_func->f_decompress(compressor);
|
return p->c_ops->c_compress(p->c_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum b_status b_compressor_step(struct b_compressor *compressor)
|
static enum b_status decompress(struct compressor_data *p)
|
||||||
{
|
{
|
||||||
switch (compressor->c_mode) {
|
if (p->c_data->c_mode != B_COMPRESSOR_MODE_DECOMPRESS) {
|
||||||
case B_COMPRESSION_MODE_COMPRESS:
|
return B_ERR_BAD_STATE;
|
||||||
return compress(compressor);
|
}
|
||||||
case B_COMPRESSION_MODE_DECOMPRESS:
|
|
||||||
return decompress(compressor);
|
if (!p->c_ops->c_decompress) {
|
||||||
|
return B_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return p->c_ops->c_decompress(p->c_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum b_status compressor_step(struct compressor_data *p)
|
||||||
|
{
|
||||||
|
switch (p->c_data->c_mode) {
|
||||||
|
case B_COMPRESSOR_MODE_COMPRESS:
|
||||||
|
return compress(p);
|
||||||
|
case B_COMPRESSOR_MODE_DECOMPRESS:
|
||||||
|
return decompress(p);
|
||||||
default:
|
default:
|
||||||
return B_ERR_BAD_STATE;
|
return B_ERR_BAD_STATE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum b_status b_compressor_end(struct b_compressor *compressor)
|
static enum b_status compressor_end(struct compressor_data *p)
|
||||||
{
|
{
|
||||||
if (compressor->c_mode != B_COMPRESSION_MODE_COMPRESS) {
|
if (p->c_data->c_mode != B_COMPRESSOR_MODE_COMPRESS) {
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!compressor->c_func->f_compress_end) {
|
if (!p->c_ops->c_compress_end) {
|
||||||
return B_ERR_NOT_SUPPORTED;
|
return B_ERR_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (b_ringbuffer_available_data_remaining(compressor->c_in)) {
|
while (b_ringbuffer_available_data_remaining(p->c_data->c_in)) {
|
||||||
if (!b_ringbuffer_write_capacity_remaining(compressor->c_out)) {
|
if (!b_ringbuffer_write_capacity_remaining(p->c_data->c_out)) {
|
||||||
return B_ERR_NO_SPACE;
|
return B_ERR_NO_SPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum b_status status = b_compressor_step(compressor);
|
enum b_status status = compressor_step(p);
|
||||||
if (!B_OK(status)) {
|
if (!B_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return compressor->c_func->f_compress_end(compressor);
|
return p->c_ops->c_compress_end(p->c_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum b_status b_compressor_reset(struct b_compressor *compressor)
|
static enum b_status compressor_reset(struct compressor_data *p)
|
||||||
{
|
{
|
||||||
compressor->c_flags &= ~COMPRESSOR_EOF;
|
p->c_data->c_flags &= ~B_COMPRESSOR_EOF;
|
||||||
|
|
||||||
if (compressor->c_func->f_reset) {
|
if (p->c_ops->c_reset) {
|
||||||
return compressor->c_func->f_reset(compressor);
|
return p->c_ops->c_reset(p->c_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool b_compressor_eof(const struct b_compressor *compressor)
|
static bool compressor_eof(const struct compressor_data *p)
|
||||||
{
|
{
|
||||||
return (compressor->c_flags & COMPRESSOR_EOF) != 0;
|
return (p->c_data->c_flags & B_COMPRESSOR_EOF) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *b_compressor_get_function_ctx(struct b_compressor *compressor)
|
/*** PUBLIC FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
enum b_status b_compressor_get_buffer_size(
|
||||||
|
b_type type, b_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size)
|
||||||
{
|
{
|
||||||
assert(compressor->c_func->f_buffer_size > 0);
|
b_class *c = b_class_get(type);
|
||||||
unsigned char *p = (unsigned char *)compressor;
|
if (!c) {
|
||||||
p += sizeof *compressor;
|
return B_ERR_INVALID_ARGUMENT;
|
||||||
return p;
|
}
|
||||||
|
|
||||||
|
b_compressor_class *ops = b_class_get_interface(c, B_TYPE_COMPRESSOR);
|
||||||
|
if (!ops) {
|
||||||
|
return B_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ops->c_buffer_size) {
|
||||||
|
return B_ERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ops->c_buffer_size(mode, inbuf_size, outbuf_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum b_status b_compressor_get_mode(
|
||||||
|
const b_compressor *compressor, enum b_compressor_mode *out)
|
||||||
|
{
|
||||||
|
COMPRESSOR_DISPATCH_STATIC(
|
||||||
|
compressor_get_mode, (b_compressor *)compressor, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_compressor_set_mode(
|
||||||
|
b_compressor *compressor, enum b_compressor_mode mode)
|
||||||
|
{
|
||||||
|
COMPRESSOR_DISPATCH_STATIC(compressor_set_mode, compressor, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_compressor_set_buffer(
|
||||||
|
b_compressor *compressor, b_ringbuffer *inbuf, b_ringbuffer *outbuf)
|
||||||
|
{
|
||||||
|
COMPRESSOR_DISPATCH_STATIC(compressor_set_buffer, compressor, inbuf, outbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_compressor_step(b_compressor *compressor)
|
||||||
|
{
|
||||||
|
COMPRESSOR_DISPATCH_STATIC_0(compressor_step, compressor);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_compressor_end(b_compressor *compressor)
|
||||||
|
{
|
||||||
|
COMPRESSOR_DISPATCH_STATIC_0(compressor_end, compressor);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum b_status b_compressor_reset(b_compressor *compressor)
|
||||||
|
{
|
||||||
|
COMPRESSOR_DISPATCH_STATIC_0(compressor_reset, compressor);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool b_compressor_eof(const b_compressor *compressor)
|
||||||
|
{
|
||||||
|
COMPRESSOR_DISPATCH_STATIC_0(compressor_eof, (b_compressor *)compressor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** VIRTUAL FUNCTIONS ********************************************************/
|
||||||
|
|
||||||
|
static void compressor_init(b_object *obj, void *priv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void compressor_fini(b_object *obj, void *priv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** CLASS DEFINITION *********************************************************/
|
||||||
|
|
||||||
|
B_TYPE_CLASS_DEFINITION_BEGIN(b_compressor)
|
||||||
|
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
|
||||||
|
B_INTERFACE_ENTRY(to_string) = NULL;
|
||||||
|
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
|
||||||
|
B_TYPE_CLASS_DEFINITION_END(b_compressor)
|
||||||
|
|
||||||
|
B_TYPE_DEFINITION_BEGIN(b_compressor)
|
||||||
|
B_TYPE_ID(0x452ee0f9, 0xfe12, 0x48a1, 0xb596, 0xad5b7a3940e7);
|
||||||
|
B_TYPE_CLASS(b_compressor_class);
|
||||||
|
B_TYPE_INSTANCE_PROTECTED(b_compressor_data);
|
||||||
|
B_TYPE_INSTANCE_INIT(compressor_init);
|
||||||
|
B_TYPE_INSTANCE_FINI(compressor_fini);
|
||||||
|
B_TYPE_DEFINITION_END(b_compressor)
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
#ifndef _COMPRESSOR_H_
|
|
||||||
#define _COMPRESSOR_H_
|
|
||||||
|
|
||||||
#include <blue/compress/compressor.h>
|
|
||||||
#include <blue/compress/function.h>
|
|
||||||
|
|
||||||
struct b_ringbuffer;
|
|
||||||
|
|
||||||
enum compressor_flags {
|
|
||||||
COMPRESSOR_EOF = 0x01u,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct b_compressor {
|
|
||||||
enum compressor_flags c_flags;
|
|
||||||
enum b_compression_mode c_mode;
|
|
||||||
const struct b_compression_function *c_func;
|
|
||||||
struct b_ringbuffer *c_in, *c_out;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern void *b_compressor_get_function_ctx(struct b_compressor *compressor);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
#include "function.h"
|
|
||||||
|
|
||||||
#include <blue/compress/compressor.h>
|
|
||||||
#include <blue/compress/function.h>
|
|
||||||
|
|
||||||
#ifdef B_COMPRESSOR_SUPPORTED_ZSTD
|
|
||||||
extern const struct b_compression_function z__b_compression_function_zstd;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static const struct b_compression_function *compressor_functions[] = {
|
|
||||||
#ifdef B_COMPRESSOR_SUPPORTED_ZSTD
|
|
||||||
[B_COMPRESSOR_FUNCTION_ZSTD] = &z__b_compression_function_zstd,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
static const size_t nr_compressor_functions
|
|
||||||
= sizeof compressor_functions / sizeof compressor_functions[0];
|
|
||||||
|
|
||||||
const struct b_compression_function *b_compression_function_get_by_id(
|
|
||||||
enum b_compression_function_id id)
|
|
||||||
{
|
|
||||||
if (id < 0 || id >= nr_compressor_functions) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return compressor_functions[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
enum b_status b_compression_function_get_buffer_size(
|
|
||||||
const struct b_compression_function *func, enum b_compression_mode mode,
|
|
||||||
size_t *inbuf_size, size_t *outbuf_size)
|
|
||||||
{
|
|
||||||
if (!func->f_buffer_size) {
|
|
||||||
return B_ERR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t in = 0, out = 0;
|
|
||||||
enum b_status status = func->f_buffer_size(mode, &in, &out);
|
|
||||||
|
|
||||||
if (inbuf_size) {
|
|
||||||
*inbuf_size = in;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (outbuf_size) {
|
|
||||||
*outbuf_size = out;
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#ifndef _FUNCTION_H_
|
|
||||||
#define _FUNCTION_H_
|
|
||||||
|
|
||||||
#include <blue/compress/compressor.h>
|
|
||||||
#include <blue/core/status.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
struct b_compressor;
|
|
||||||
|
|
||||||
struct b_compression_function {
|
|
||||||
const char *f_name;
|
|
||||||
size_t f_ctx_size;
|
|
||||||
|
|
||||||
enum b_status (*f_buffer_size)(enum b_compression_mode, size_t *, size_t *);
|
|
||||||
|
|
||||||
enum b_status (*f_init)(struct b_compressor *);
|
|
||||||
enum b_status (*f_fini)(struct b_compressor *);
|
|
||||||
enum b_status (*f_reset)(struct b_compressor *);
|
|
||||||
enum b_status (*f_compress)(struct b_compressor *);
|
|
||||||
enum b_status (*f_compress_end)(struct b_compressor *);
|
|
||||||
enum b_status (*f_decompress)(struct b_compressor *);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,25 +1,27 @@
|
|||||||
#include "../compressor.h"
|
#include <blue/compress/zstd.h>
|
||||||
#include "../function.h"
|
|
||||||
|
|
||||||
#include <blue/core/ringbuffer.h>
|
#include <blue/core/ringbuffer.h>
|
||||||
#include <zstd.h>
|
#include <zstd.h>
|
||||||
|
|
||||||
struct zstd_ctx {
|
/*** PRIVATE DATA *************************************************************/
|
||||||
|
|
||||||
|
struct b_zstd_compressor_p {
|
||||||
union {
|
union {
|
||||||
ZSTD_CCtx *zstd_c;
|
ZSTD_CCtx *zstd_c;
|
||||||
ZSTD_DCtx *zstd_d;
|
ZSTD_DCtx *zstd_d;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum b_status buffer_size(
|
/*** PUBLIC FUNCTIONS *********************************************************/
|
||||||
enum b_compression_mode mode, size_t *inbuf_size, size_t *outbuf_size)
|
|
||||||
|
b_status b_zstd_compressor_get_buffer_size(
|
||||||
|
b_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size)
|
||||||
{
|
{
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case B_COMPRESSION_MODE_COMPRESS:
|
case B_COMPRESSOR_MODE_COMPRESS:
|
||||||
*inbuf_size = ZSTD_CStreamInSize();
|
*inbuf_size = ZSTD_CStreamInSize();
|
||||||
*outbuf_size = ZSTD_CStreamOutSize();
|
*outbuf_size = ZSTD_CStreamOutSize();
|
||||||
break;
|
break;
|
||||||
case B_COMPRESSION_MODE_DECOMPRESS:
|
case B_COMPRESSOR_MODE_DECOMPRESS:
|
||||||
*inbuf_size = ZSTD_DStreamInSize();
|
*inbuf_size = ZSTD_DStreamInSize();
|
||||||
*outbuf_size = ZSTD_DStreamOutSize();
|
*outbuf_size = ZSTD_DStreamOutSize();
|
||||||
break;
|
break;
|
||||||
@@ -30,54 +32,44 @@ static enum b_status buffer_size(
|
|||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum b_status init(struct b_compressor *compressor)
|
/*** VIRTUAL FUNCTIONS ********************************************************/
|
||||||
{
|
|
||||||
struct zstd_ctx *ctx = b_compressor_get_function_ctx(compressor);
|
|
||||||
switch (compressor->c_mode) {
|
|
||||||
case B_COMPRESSION_MODE_COMPRESS:
|
|
||||||
ctx->zstd_c = ZSTD_createCCtx();
|
|
||||||
if (!ctx->zstd_c) {
|
|
||||||
return B_ERR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case B_COMPRESSION_MODE_DECOMPRESS:
|
|
||||||
ctx->zstd_d = ZSTD_createDCtx();
|
|
||||||
if (!ctx->zstd_d) {
|
|
||||||
return B_ERR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return B_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_SUCCESS;
|
static void zstd_compressor_init(b_object *obj, void *priv)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum b_status fini(struct b_compressor *compressor)
|
static void zstd_compressor_fini(b_object *obj, void *priv)
|
||||||
{
|
{
|
||||||
struct zstd_ctx *ctx = b_compressor_get_function_ctx(compressor);
|
b_compressor_data *c = b_object_get_protected(obj, B_TYPE_COMPRESSOR);
|
||||||
switch (compressor->c_mode) {
|
struct b_zstd_compressor_p *ctx = priv;
|
||||||
case B_COMPRESSION_MODE_COMPRESS:
|
switch (c->c_mode) {
|
||||||
|
case B_COMPRESSOR_MODE_COMPRESS:
|
||||||
ZSTD_freeCCtx(ctx->zstd_c);
|
ZSTD_freeCCtx(ctx->zstd_c);
|
||||||
break;
|
break;
|
||||||
case B_COMPRESSION_MODE_DECOMPRESS:
|
case B_COMPRESSOR_MODE_DECOMPRESS:
|
||||||
ZSTD_freeDCtx(ctx->zstd_d);
|
ZSTD_freeDCtx(ctx->zstd_d);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return B_ERR_BAD_STATE;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum b_status reset(struct b_compressor *compressor)
|
static enum b_status reset(b_compressor *compressor)
|
||||||
{
|
{
|
||||||
struct zstd_ctx *ctx = b_compressor_get_function_ctx(compressor);
|
struct b_zstd_compressor_p *ctx
|
||||||
switch (compressor->c_mode) {
|
= b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
|
||||||
case B_COMPRESSION_MODE_COMPRESS:
|
b_compressor_data *data
|
||||||
|
= b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
|
||||||
|
|
||||||
|
if (!ctx || !data) {
|
||||||
|
return B_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (data->c_mode) {
|
||||||
|
case B_COMPRESSOR_MODE_COMPRESS:
|
||||||
ZSTD_CCtx_reset(ctx->zstd_c, ZSTD_reset_session_only);
|
ZSTD_CCtx_reset(ctx->zstd_c, ZSTD_reset_session_only);
|
||||||
break;
|
break;
|
||||||
case B_COMPRESSION_MODE_DECOMPRESS:
|
case B_COMPRESSOR_MODE_DECOMPRESS:
|
||||||
ZSTD_DCtx_reset(ctx->zstd_d, ZSTD_reset_session_only);
|
ZSTD_DCtx_reset(ctx->zstd_d, ZSTD_reset_session_only);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -87,12 +79,20 @@ static enum b_status reset(struct b_compressor *compressor)
|
|||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum b_status compress(struct b_compressor *compressor)
|
static enum b_status compress(b_compressor *compressor)
|
||||||
{
|
{
|
||||||
enum b_status status = B_SUCCESS;
|
enum b_status status = B_SUCCESS;
|
||||||
struct zstd_ctx *ctx = b_compressor_get_function_ctx(compressor);
|
struct b_zstd_compressor_p *ctx
|
||||||
struct b_ringbuffer *in = compressor->c_in;
|
= b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
|
||||||
struct b_ringbuffer *out = compressor->c_out;
|
b_compressor_data *data
|
||||||
|
= b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
|
||||||
|
|
||||||
|
if (!ctx || !data) {
|
||||||
|
return B_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_ringbuffer *in = data->c_in;
|
||||||
|
b_ringbuffer *out = data->c_out;
|
||||||
|
|
||||||
if (b_ringbuffer_available_data_remaining(in) == 0) {
|
if (b_ringbuffer_available_data_remaining(in) == 0) {
|
||||||
return B_ERR_NO_DATA;
|
return B_ERR_NO_DATA;
|
||||||
@@ -156,12 +156,19 @@ static enum b_status compress(struct b_compressor *compressor)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum b_status compress_end(struct b_compressor *compressor)
|
static enum b_status compress_end(b_compressor *compressor)
|
||||||
{
|
{
|
||||||
enum b_status status = B_SUCCESS;
|
enum b_status status = B_SUCCESS;
|
||||||
struct zstd_ctx *ctx = b_compressor_get_function_ctx(compressor);
|
struct b_zstd_compressor_p *ctx
|
||||||
|
= b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
|
||||||
|
b_compressor_data *data
|
||||||
|
= b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
|
||||||
|
|
||||||
struct b_ringbuffer *out = compressor->c_out;
|
if (!ctx || !data) {
|
||||||
|
return B_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_ringbuffer *out = data->c_out;
|
||||||
if (b_ringbuffer_write_capacity_remaining(out) == 0) {
|
if (b_ringbuffer_write_capacity_remaining(out) == 0) {
|
||||||
return B_ERR_NO_SPACE;
|
return B_ERR_NO_SPACE;
|
||||||
}
|
}
|
||||||
@@ -192,7 +199,7 @@ static enum b_status compress_end(struct b_compressor *compressor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
compressor->c_flags |= COMPRESSOR_EOF;
|
data->c_flags |= B_COMPRESSOR_EOF;
|
||||||
finished = true;
|
finished = true;
|
||||||
}
|
}
|
||||||
} while (!finished && z_out.pos < z_out.size);
|
} while (!finished && z_out.pos < z_out.size);
|
||||||
@@ -203,12 +210,20 @@ static enum b_status compress_end(struct b_compressor *compressor)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum b_status decompress(struct b_compressor *compressor)
|
static enum b_status decompress(b_compressor *compressor)
|
||||||
{
|
{
|
||||||
enum b_status status = B_SUCCESS;
|
enum b_status status = B_SUCCESS;
|
||||||
struct zstd_ctx *ctx = b_compressor_get_function_ctx(compressor);
|
struct b_zstd_compressor_p *ctx
|
||||||
struct b_ringbuffer *in = compressor->c_in;
|
= b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
|
||||||
struct b_ringbuffer *out = compressor->c_out;
|
b_compressor_data *data
|
||||||
|
= b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
|
||||||
|
|
||||||
|
if (!ctx || !data) {
|
||||||
|
return B_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_ringbuffer *in = data->c_in;
|
||||||
|
b_ringbuffer *out = data->c_out;
|
||||||
|
|
||||||
if (b_ringbuffer_available_data_remaining(in) == 0) {
|
if (b_ringbuffer_available_data_remaining(in) == 0) {
|
||||||
return B_ERR_NO_DATA;
|
return B_ERR_NO_DATA;
|
||||||
@@ -220,7 +235,7 @@ static enum b_status decompress(struct b_compressor *compressor)
|
|||||||
|
|
||||||
size_t nr_consumed = 0;
|
size_t nr_consumed = 0;
|
||||||
|
|
||||||
while (!(compressor->c_flags & COMPRESSOR_EOF)) {
|
while (!(data->c_flags & B_COMPRESSOR_EOF)) {
|
||||||
size_t in_available = 0, out_capacity = 0;
|
size_t in_available = 0, out_capacity = 0;
|
||||||
const void *in_buf = NULL;
|
const void *in_buf = NULL;
|
||||||
void *out_buf = NULL;
|
void *out_buf = NULL;
|
||||||
@@ -258,7 +273,7 @@ static enum b_status decompress(struct b_compressor *compressor)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
compressor->c_flags |= COMPRESSOR_EOF;
|
data->c_flags |= B_COMPRESSOR_EOF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (z_in.pos < z_in.size && z_out.pos < z_out.size);
|
} while (z_in.pos < z_in.size && z_out.pos < z_out.size);
|
||||||
@@ -277,14 +292,71 @@ static enum b_status decompress(struct b_compressor *compressor)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct b_compression_function z__b_compression_function_zstd = {
|
static enum b_status set_mode(b_compressor *compressor, b_compressor_mode mode)
|
||||||
.f_name = "zstd",
|
{
|
||||||
.f_ctx_size = sizeof(struct zstd_ctx),
|
struct b_zstd_compressor_p *ctx
|
||||||
.f_buffer_size = buffer_size,
|
= b_object_get_private(compressor, B_TYPE_ZSTD_COMPRESSOR);
|
||||||
.f_init = init,
|
b_compressor_data *data
|
||||||
.f_fini = fini,
|
= b_object_get_protected(compressor, B_TYPE_COMPRESSOR);
|
||||||
.f_reset = reset,
|
|
||||||
.f_compress = compress,
|
if (!ctx || !data) {
|
||||||
.f_compress_end = compress_end,
|
return B_ERR_INVALID_ARGUMENT;
|
||||||
.f_decompress = decompress,
|
}
|
||||||
};
|
|
||||||
|
if (mode == data->c_mode) {
|
||||||
|
return B_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (data->c_mode) {
|
||||||
|
case B_COMPRESSOR_MODE_COMPRESS:
|
||||||
|
ZSTD_freeCCtx(ctx->zstd_c);
|
||||||
|
break;
|
||||||
|
case B_COMPRESSOR_MODE_DECOMPRESS:
|
||||||
|
ZSTD_freeDCtx(ctx->zstd_d);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
data->c_mode = mode;
|
||||||
|
|
||||||
|
switch (data->c_mode) {
|
||||||
|
case B_COMPRESSOR_MODE_COMPRESS:
|
||||||
|
ctx->zstd_c = ZSTD_createCCtx();
|
||||||
|
break;
|
||||||
|
case B_COMPRESSOR_MODE_DECOMPRESS:
|
||||||
|
ctx->zstd_d = ZSTD_createDCtx();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return B_ERR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** CLASS DEFINITION *********************************************************/
|
||||||
|
|
||||||
|
B_TYPE_CLASS_DEFINITION_BEGIN(b_zstd_compressor)
|
||||||
|
B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT)
|
||||||
|
B_INTERFACE_ENTRY(to_string) = NULL;
|
||||||
|
B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT)
|
||||||
|
|
||||||
|
B_TYPE_CLASS_INTERFACE_BEGIN(b_compressor, B_TYPE_COMPRESSOR)
|
||||||
|
B_INTERFACE_ENTRY(c_buffer_size)
|
||||||
|
= b_zstd_compressor_get_buffer_size;
|
||||||
|
B_INTERFACE_ENTRY(c_compress) = compress;
|
||||||
|
B_INTERFACE_ENTRY(c_compress_end) = compress_end;
|
||||||
|
B_INTERFACE_ENTRY(c_decompress) = decompress;
|
||||||
|
B_INTERFACE_ENTRY(c_reset) = reset;
|
||||||
|
B_INTERFACE_ENTRY(c_set_mode) = set_mode;
|
||||||
|
B_TYPE_CLASS_INTERFACE_END(b_compressor, B_TYPE_COMPRESSOR)
|
||||||
|
B_TYPE_CLASS_DEFINITION_END(b_zstd_compressor)
|
||||||
|
|
||||||
|
B_TYPE_DEFINITION_BEGIN(b_zstd_compressor)
|
||||||
|
B_TYPE_ID(0x51d437fc, 0xe789, 0x4105, 0xbac7, 0xe6b3f45df198);
|
||||||
|
B_TYPE_EXTENDS(B_TYPE_COMPRESSOR);
|
||||||
|
B_TYPE_CLASS(b_zstd_compressor_class);
|
||||||
|
B_TYPE_INSTANCE_PRIVATE(struct b_zstd_compressor_p);
|
||||||
|
B_TYPE_INSTANCE_INIT(zstd_compressor_init);
|
||||||
|
B_TYPE_INSTANCE_FINI(zstd_compressor_fini);
|
||||||
|
B_TYPE_DEFINITION_END(b_zstd_compressor)
|
||||||
|
|||||||
@@ -1,29 +1,67 @@
|
|||||||
#ifndef BLUELIB_COMPRESS_COMPRESSOR_H_
|
#ifndef BLUE_COMPRESS_COMPRESSOR_H_
|
||||||
#define BLUELIB_COMPRESS_COMPRESSOR_H_
|
#define BLUE_COMPRESS_COMPRESSOR_H_
|
||||||
|
|
||||||
|
#include <blue/core/macros.h>
|
||||||
#include <blue/core/misc.h>
|
#include <blue/core/misc.h>
|
||||||
|
#include <blue/core/ringbuffer.h>
|
||||||
#include <blue/core/status.h>
|
#include <blue/core/status.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
struct b_ringbuffer;
|
B_DECLS_BEGIN;
|
||||||
struct b_compression_function;
|
|
||||||
|
|
||||||
enum b_compression_mode;
|
typedef enum b_compressor_mode {
|
||||||
|
B_COMPRESSOR_MODE_NONE = 0,
|
||||||
|
B_COMPRESSOR_MODE_COMPRESS,
|
||||||
|
B_COMPRESSOR_MODE_DECOMPRESS,
|
||||||
|
} b_compressor_mode;
|
||||||
|
|
||||||
typedef struct b_compressor b_compressor;
|
typedef enum b_compressor_flags {
|
||||||
|
B_COMPRESSOR_EOF = 0x01u,
|
||||||
|
} b_compressor_flags;
|
||||||
|
|
||||||
|
#define B_TYPE_COMPRESSOR (b_compressor_get_type())
|
||||||
|
|
||||||
|
B_DECLARE_TYPE(b_compressor);
|
||||||
|
|
||||||
|
B_TYPE_CLASS_DECLARATION_BEGIN(b_compressor)
|
||||||
|
b_status (*c_buffer_size)(b_compressor_mode, size_t *, size_t *);
|
||||||
|
b_status (*c_set_mode)(b_compressor *, b_compressor_mode);
|
||||||
|
b_status (*c_compress)(b_compressor *);
|
||||||
|
b_status (*c_compress_end)(b_compressor *);
|
||||||
|
b_status (*c_decompress)(b_compressor *);
|
||||||
|
b_status (*c_reset)(b_compressor *);
|
||||||
|
B_TYPE_CLASS_DECLARATION_END(b_compressor)
|
||||||
|
|
||||||
|
typedef struct b_compressor_data {
|
||||||
|
b_compressor_flags c_flags;
|
||||||
|
b_compressor_mode c_mode;
|
||||||
|
b_ringbuffer *c_in, *c_out;
|
||||||
|
} b_compressor_data;
|
||||||
|
|
||||||
|
BLUE_API b_type b_compressor_get_type(void);
|
||||||
|
|
||||||
|
#if 0
|
||||||
BLUE_API b_status b_compressor_create(
|
BLUE_API b_status b_compressor_create(
|
||||||
const struct b_compression_function *func, enum b_compression_mode mode,
|
const struct b_compression_function *func, enum b_compression_mode mode,
|
||||||
struct b_ringbuffer *inbuf, struct b_ringbuffer *outbuf,
|
struct b_ringbuffer *inbuf, struct b_ringbuffer *outbuf,
|
||||||
b_compressor **out);
|
b_compressor **out);
|
||||||
BLUE_API b_status b_compressor_destroy(b_compressor *compressor);
|
#endif
|
||||||
|
|
||||||
BLUE_API b_status b_compressor_get_buffer_size(
|
BLUE_API b_status b_compressor_get_buffer_size(
|
||||||
const b_compressor *compressor, size_t *inbuf_size, size_t *outbuf_size);
|
b_type type, b_compressor_mode mode, size_t *inbuf_size,
|
||||||
|
size_t *outbuf_size);
|
||||||
|
|
||||||
|
BLUE_API b_status b_compressor_get_mode(
|
||||||
|
const b_compressor *compressor, b_compressor_mode *out);
|
||||||
|
BLUE_API b_status b_compressor_set_mode(
|
||||||
|
b_compressor *compressor, b_compressor_mode mode);
|
||||||
|
BLUE_API b_status b_compressor_set_buffer(
|
||||||
|
b_compressor *compressor, b_ringbuffer *inbuf, b_ringbuffer *outbuf);
|
||||||
BLUE_API b_status b_compressor_step(b_compressor *compressor);
|
BLUE_API b_status b_compressor_step(b_compressor *compressor);
|
||||||
BLUE_API b_status b_compressor_end(b_compressor *compressor);
|
BLUE_API b_status b_compressor_end(b_compressor *compressor);
|
||||||
BLUE_API b_status b_compressor_reset(b_compressor *compressor);
|
BLUE_API b_status b_compressor_reset(b_compressor *compressor);
|
||||||
BLUE_API bool b_compressor_eof(const b_compressor *compressor);
|
BLUE_API bool b_compressor_eof(const b_compressor *compressor);
|
||||||
|
|
||||||
|
B_DECLS_END;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
#ifndef BLUELIB_COMPRESS_FUNCTION_H_
|
|
||||||
#define BLUELIB_COMPRESS_FUNCTION_H_
|
|
||||||
|
|
||||||
#include <blue/core/misc.h>
|
|
||||||
#include <blue/core/status.h>
|
|
||||||
|
|
||||||
enum b_compressor_mode;
|
|
||||||
|
|
||||||
typedef struct b_compression_function b_compression_function;
|
|
||||||
|
|
||||||
typedef enum b_compression_function_id {
|
|
||||||
B_COMPRESSOR_FUNCTION_NONE = 0,
|
|
||||||
B_COMPRESSOR_FUNCTION_ZSTD,
|
|
||||||
} b_compression_function_id;
|
|
||||||
|
|
||||||
typedef enum b_compression_mode {
|
|
||||||
B_COMPRESSION_MODE_COMPRESS,
|
|
||||||
B_COMPRESSION_MODE_DECOMPRESS,
|
|
||||||
} b_compression_mode;
|
|
||||||
|
|
||||||
BLUE_API const b_compression_function *b_compression_function_get_by_id(
|
|
||||||
b_compression_function_id id);
|
|
||||||
BLUE_API b_status b_compression_function_get_buffer_size(
|
|
||||||
const b_compression_function *func, enum b_compression_mode mode,
|
|
||||||
size_t *inbuf_size, size_t *outbuf_size);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
28
compress/include/blue/compress/zstd.h
Normal file
28
compress/include/blue/compress/zstd.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef BLUE_COMPRESS_ZSTD_H_
|
||||||
|
#define BLUE_COMPRESS_ZSTD_H_
|
||||||
|
|
||||||
|
#include <blue/compress/compressor.h>
|
||||||
|
#include <blue/core/macros.h>
|
||||||
|
#include <blue/core/misc.h>
|
||||||
|
#include <blue/core/status.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
B_DECLS_BEGIN;
|
||||||
|
|
||||||
|
#define B_TYPE_ZSTD_COMPRESSOR (b_zstd_compressor_get_type())
|
||||||
|
|
||||||
|
B_DECLARE_TYPE(b_zstd_compressor);
|
||||||
|
|
||||||
|
B_TYPE_CLASS_DECLARATION_BEGIN(b_zstd_compressor)
|
||||||
|
B_TYPE_CLASS_DECLARATION_END(b_compressor)
|
||||||
|
|
||||||
|
BLUE_API b_type b_zstd_compressor_get_type(void);
|
||||||
|
|
||||||
|
BLUE_API b_status b_zstd_compressor_get_buffer_size(
|
||||||
|
b_compressor_mode mode, size_t *inbuf_size, size_t *outbuf_size);
|
||||||
|
|
||||||
|
B_TYPE_DEFAULT_CONSTRUCTOR(b_zstd_compressor, B_TYPE_ZSTD_COMPRESSOR);
|
||||||
|
|
||||||
|
B_DECLS_END;
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user