compress: compressor: convert b_compressor to a b_object interface

This commit is contained in:
2025-10-28 15:19:30 +00:00
parent b58015baff
commit f3dd0ddd48
8 changed files with 386 additions and 275 deletions

View File

@@ -1,145 +1,239 @@
#include "compressor.h"
#include "function.h"
#include <assert.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_compression_mode mode,
struct b_ringbuffer *inbuf, struct b_ringbuffer *outbuf,
struct b_compressor **out)
#define COMPRESSOR_DISPATCH_STATIC(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, __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;
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;
out->c_obj = compressor;
return b_object_get_data(
compressor, B_TYPE_COMPRESSOR, NULL, (void **)&out->c_data,
(void **)&out->c_ops);
}
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 (compressor->c_func->f_fini) {
status = compressor->c_func->f_fini(compressor);
if (out) {
*out = p->c_data->c_mode;
}
if (!B_OK(status)) {
return status;
}
free(compressor);
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) {
return B_ERR_BAD_STATE;
}
if (!compressor->c_func->f_compress) {
if (!p->c_ops->c_set_mode) {
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;
}
if (!compressor->c_func->f_decompress) {
if (!p->c_ops->c_compress) {
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) {
case B_COMPRESSION_MODE_COMPRESS:
return compress(compressor);
case B_COMPRESSION_MODE_DECOMPRESS:
return decompress(compressor);
if (p->c_data->c_mode != B_COMPRESSOR_MODE_DECOMPRESS) {
return B_ERR_BAD_STATE;
}
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:
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;
}
if (!compressor->c_func->f_compress_end) {
if (!p->c_ops->c_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)) {
while (b_ringbuffer_available_data_remaining(p->c_data->c_in)) {
if (!b_ringbuffer_write_capacity_remaining(p->c_data->c_out)) {
return B_ERR_NO_SPACE;
}
enum b_status status = b_compressor_step(compressor);
enum b_status status = compressor_step(p);
if (!B_OK(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) {
return compressor->c_func->f_reset(compressor);
if (p->c_ops->c_reset) {
return p->c_ops->c_reset(p->c_obj);
}
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);
unsigned char *p = (unsigned char *)compressor;
p += sizeof *compressor;
return p;
b_class *c = b_class_get(type);
if (!c) {
return B_ERR_INVALID_ARGUMENT;
}
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)