libropkg: convert pkg writer to use bluelib compression streams
This commit is contained in:
@@ -1,86 +0,0 @@
|
|||||||
#include "compress.h"
|
|
||||||
|
|
||||||
#include <ropkg/compress.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
extern const struct ropkg_compression_function ropkg_zstd;
|
|
||||||
|
|
||||||
static const struct ropkg_compression_function *functions[] = {
|
|
||||||
[ROPKG_COMPRESSION_ZSTD] = &ropkg_zstd,
|
|
||||||
};
|
|
||||||
static const size_t nr_functions = sizeof functions / sizeof functions[0];
|
|
||||||
|
|
||||||
const struct ropkg_compression_function *ropkg_compression_function_for_type(
|
|
||||||
enum ropkg_compression_type type)
|
|
||||||
{
|
|
||||||
if (type >= nr_functions) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return functions[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ropkg_status ropkg_compression_function_get_buffer_size(
|
|
||||||
const struct ropkg_compression_function *func,
|
|
||||||
enum ropkg_compression_stream_mode mode,
|
|
||||||
size_t *in_buffer_size,
|
|
||||||
size_t *out_buffer_size)
|
|
||||||
{
|
|
||||||
if (!func->f_buffer_size) {
|
|
||||||
return ROPKG_ERR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return func->f_buffer_size(mode, in_buffer_size, out_buffer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *ropkg_compression_function_get_file_extension(
|
|
||||||
const struct ropkg_compression_function *func)
|
|
||||||
{
|
|
||||||
return func->f_extension;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ropkg_status ropkg_compression_stream_open(
|
|
||||||
const struct ropkg_compression_function *func,
|
|
||||||
void *in_buffer,
|
|
||||||
size_t in_max,
|
|
||||||
void *out_buffer,
|
|
||||||
size_t out_max,
|
|
||||||
enum ropkg_compression_stream_mode mode,
|
|
||||||
struct ropkg_compression_stream **out)
|
|
||||||
{
|
|
||||||
if (!func->f_open) {
|
|
||||||
return ROPKG_ERR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return func->f_open(
|
|
||||||
func,
|
|
||||||
mode,
|
|
||||||
in_buffer,
|
|
||||||
in_max,
|
|
||||||
out_buffer,
|
|
||||||
out_max,
|
|
||||||
out);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ropkg_status ropkg_compression_stream_process(
|
|
||||||
struct ropkg_compression_stream *stream,
|
|
||||||
size_t in_size,
|
|
||||||
enum ropkg_compression_stream_op op,
|
|
||||||
size_t *out_size)
|
|
||||||
{
|
|
||||||
if (!stream->s_func->f_process) {
|
|
||||||
return ROPKG_ERR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return stream->s_func->f_process(stream, in_size, op, out_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ropkg_status ropkg_compression_stream_close(
|
|
||||||
struct ropkg_compression_stream *stream)
|
|
||||||
{
|
|
||||||
if (!stream->s_func->f_close) {
|
|
||||||
return ROPKG_ERR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return stream->s_func->f_close(stream);
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#ifndef COMPRESS_H_
|
|
||||||
#define COMPRESS_H_
|
|
||||||
|
|
||||||
#include <ropkg/compress.h>
|
|
||||||
|
|
||||||
struct ropkg_compression_function {
|
|
||||||
const char *f_name;
|
|
||||||
const char *f_extension;
|
|
||||||
enum ropkg_status (*f_buffer_size)(
|
|
||||||
enum ropkg_compression_stream_mode,
|
|
||||||
size_t *,
|
|
||||||
size_t *);
|
|
||||||
enum ropkg_status (*f_open)(
|
|
||||||
const struct ropkg_compression_function *,
|
|
||||||
enum ropkg_compression_stream_mode,
|
|
||||||
void *,
|
|
||||||
size_t,
|
|
||||||
void *,
|
|
||||||
size_t,
|
|
||||||
struct ropkg_compression_stream **);
|
|
||||||
enum ropkg_status (*f_close)(struct ropkg_compression_stream *);
|
|
||||||
enum ropkg_status (*f_process)(
|
|
||||||
struct ropkg_compression_stream *,
|
|
||||||
size_t,
|
|
||||||
enum ropkg_compression_stream_op,
|
|
||||||
size_t *);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ropkg_compression_stream {
|
|
||||||
const struct ropkg_compression_function *s_func;
|
|
||||||
enum ropkg_compression_stream_mode s_mode;
|
|
||||||
void *s_in, *s_out;
|
|
||||||
size_t s_in_max, s_out_max;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
#ifndef ROPKG_COMPRESS_H_
|
|
||||||
#define ROPKG_COMPRESS_H_
|
|
||||||
|
|
||||||
#include <ropkg/misc.h>
|
|
||||||
#include <ropkg/status.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
struct ropkg_compression_function;
|
|
||||||
struct ropkg_compression_stream;
|
|
||||||
|
|
||||||
enum ropkg_compression_stream_mode {
|
|
||||||
ROPKG_COMPRESSION_MODE_COMPRESS = 0,
|
|
||||||
ROPKG_COMPRESSION_MODE_DECOMPRESS,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ropkg_compression_stream_op {
|
|
||||||
ROPKG_COMPRESSION_OP_CONTINUE = 0,
|
|
||||||
ROPKG_COMPRESSION_OP_END,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ropkg_compression_type {
|
|
||||||
ROPKG_COMPRESSION_NONE = 0,
|
|
||||||
ROPKG_COMPRESSION_ZSTD,
|
|
||||||
};
|
|
||||||
|
|
||||||
ROPKG_API const struct ropkg_compression_function *
|
|
||||||
ropkg_compression_function_for_type(enum ropkg_compression_type type);
|
|
||||||
|
|
||||||
ROPKG_API enum ropkg_status ropkg_compression_function_get_buffer_size(
|
|
||||||
const struct ropkg_compression_function *func,
|
|
||||||
enum ropkg_compression_stream_mode mode,
|
|
||||||
size_t *in_buffer_size,
|
|
||||||
size_t *out_buffer_size);
|
|
||||||
ROPKG_API const char *ropkg_compression_function_get_file_extension(
|
|
||||||
const struct ropkg_compression_function *func);
|
|
||||||
|
|
||||||
ROPKG_API enum ropkg_status ropkg_compression_stream_open(
|
|
||||||
const struct ropkg_compression_function *func,
|
|
||||||
void *in_buffer,
|
|
||||||
size_t in_max,
|
|
||||||
void *out_buffer,
|
|
||||||
size_t out_max,
|
|
||||||
enum ropkg_compression_stream_mode mode,
|
|
||||||
struct ropkg_compression_stream **out);
|
|
||||||
ROPKG_API enum ropkg_status ropkg_compression_stream_process(
|
|
||||||
struct ropkg_compression_stream *stream,
|
|
||||||
size_t in_size,
|
|
||||||
enum ropkg_compression_stream_op op,
|
|
||||||
size_t *out_size);
|
|
||||||
ROPKG_API enum ropkg_status ropkg_compression_stream_close(
|
|
||||||
struct ropkg_compression_stream *stream);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
#ifndef ROPKG_STREAM_H_
|
|
||||||
#define ROPKG_STREAM_H_
|
|
||||||
|
|
||||||
#include <ropkg/misc.h>
|
|
||||||
#include <ropkg/status.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
struct ropkg_stream;
|
|
||||||
struct ropkg_compression_function;
|
|
||||||
|
|
||||||
enum ropkg_stream_mode {
|
|
||||||
ROPKG_STREAM_READ,
|
|
||||||
ROPKG_STREAM_WRITE,
|
|
||||||
};
|
|
||||||
|
|
||||||
ROPKG_API enum ropkg_status ropkg_stream_open(
|
|
||||||
FILE *fp,
|
|
||||||
const struct ropkg_compression_function *func,
|
|
||||||
enum ropkg_stream_mode mode,
|
|
||||||
struct ropkg_stream **out);
|
|
||||||
ROPKG_API enum ropkg_status ropkg_stream_close(struct ropkg_stream *stream);
|
|
||||||
|
|
||||||
ROPKG_API enum ropkg_status ropkg_stream_begin_compressed_section(
|
|
||||||
struct ropkg_stream *stream);
|
|
||||||
ROPKG_API enum ropkg_status ropkg_stream_end_compressed_section(
|
|
||||||
struct ropkg_stream *stream,
|
|
||||||
size_t *out_nr_written_compressed,
|
|
||||||
size_t *out_nr_written_uncompressed);
|
|
||||||
|
|
||||||
ROPKG_API enum ropkg_status ropkg_stream_read(
|
|
||||||
struct ropkg_stream *stream,
|
|
||||||
void *p,
|
|
||||||
size_t len,
|
|
||||||
size_t *nr_read);
|
|
||||||
ROPKG_API enum ropkg_status ropkg_stream_write(
|
|
||||||
struct ropkg_stream *stream,
|
|
||||||
const void *p,
|
|
||||||
size_t len,
|
|
||||||
size_t *nr_written);
|
|
||||||
|
|
||||||
ROPKG_API size_t ropkg_stream_get_cursor_position(struct ropkg_stream *stream);
|
|
||||||
ROPKG_API enum ropkg_status ropkg_stream_set_cursor_position(
|
|
||||||
struct ropkg_stream *stream,
|
|
||||||
size_t pos);
|
|
||||||
ROPKG_API enum ropkg_status ropkg_stream_restore_cursor_position(
|
|
||||||
struct ropkg_stream *stream);
|
|
||||||
|
|
||||||
ROPKG_API bool ropkg_stream_is_in_compressed_section(
|
|
||||||
struct ropkg_stream *stream);
|
|
||||||
|
|
||||||
ROPKG_API size_t ropkg_stream_get_nr_written(struct ropkg_stream *stream);
|
|
||||||
ROPKG_API size_t
|
|
||||||
ropkg_stream_get_nr_written_compressed(struct ropkg_stream *stream);
|
|
||||||
ROPKG_API size_t
|
|
||||||
ropkg_stream_get_nr_written_uncompressed(struct ropkg_stream *stream);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -10,14 +10,14 @@
|
|||||||
#define ROPKG_PATH_META "meta.tar"
|
#define ROPKG_PATH_META "meta.tar"
|
||||||
|
|
||||||
struct ropkg_writer;
|
struct ropkg_writer;
|
||||||
struct ropkg_stream;
|
struct b_cstream;
|
||||||
|
|
||||||
struct ropkg_writer_file_info {
|
struct ropkg_writer_file_info {
|
||||||
size_t f_length;
|
size_t f_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
ROPKG_API enum ropkg_status ropkg_writer_open(
|
ROPKG_API enum ropkg_status ropkg_writer_open(
|
||||||
struct ropkg_stream *fp,
|
struct b_cstream *fp,
|
||||||
struct ropkg_writer **out);
|
struct ropkg_writer **out);
|
||||||
ROPKG_API enum ropkg_status ropkg_writer_close(struct ropkg_writer *pkg);
|
ROPKG_API enum ropkg_status ropkg_writer_close(struct ropkg_writer *pkg);
|
||||||
|
|
||||||
|
|||||||
@@ -1,355 +0,0 @@
|
|||||||
#include "stream.h"
|
|
||||||
|
|
||||||
#include <ropkg/compress.h>
|
|
||||||
#include <ropkg/stream.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
enum ropkg_status ropkg_stream_open(
|
|
||||||
FILE *fp,
|
|
||||||
const struct ropkg_compression_function *func,
|
|
||||||
enum ropkg_stream_mode mode,
|
|
||||||
struct ropkg_stream **out)
|
|
||||||
{
|
|
||||||
switch (mode) {
|
|
||||||
case ROPKG_STREAM_READ:
|
|
||||||
case ROPKG_STREAM_WRITE:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return ROPKG_ERR_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ropkg_stream *stream = malloc(sizeof *stream);
|
|
||||||
if (!stream) {
|
|
||||||
return ROPKG_ERR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(stream, 0x0, sizeof *stream);
|
|
||||||
|
|
||||||
stream->s_fp = fp;
|
|
||||||
stream->s_mode = mode;
|
|
||||||
|
|
||||||
if (!func) {
|
|
||||||
*out = stream;
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ropkg_stream_compressor *c = &stream->s_compressor;
|
|
||||||
enum ropkg_compression_stream_mode c_mode;
|
|
||||||
switch (mode) {
|
|
||||||
case ROPKG_STREAM_READ:
|
|
||||||
c_mode = ROPKG_COMPRESSION_MODE_DECOMPRESS;
|
|
||||||
break;
|
|
||||||
case ROPKG_STREAM_WRITE:
|
|
||||||
c_mode = ROPKG_COMPRESSION_MODE_COMPRESS;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* this won't happen */
|
|
||||||
return ROPKG_ERR_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ropkg_status status = ropkg_compression_function_get_buffer_size(
|
|
||||||
func,
|
|
||||||
c_mode,
|
|
||||||
&c->c_in_max,
|
|
||||||
&c->c_out_max);
|
|
||||||
if (status != ROPKG_SUCCESS) {
|
|
||||||
free(stream);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->c_in_buf = malloc(c->c_in_max);
|
|
||||||
if (!c->c_in_buf) {
|
|
||||||
free(stream);
|
|
||||||
return ROPKG_ERR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->c_out_buf = malloc(c->c_out_max);
|
|
||||||
if (!c->c_out_buf) {
|
|
||||||
free(c->c_in_buf);
|
|
||||||
free(stream);
|
|
||||||
return ROPKG_ERR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = ropkg_compression_stream_open(
|
|
||||||
func,
|
|
||||||
c->c_in_buf,
|
|
||||||
c->c_in_max,
|
|
||||||
c->c_out_buf,
|
|
||||||
c->c_out_max,
|
|
||||||
c_mode,
|
|
||||||
&c->c_stream);
|
|
||||||
|
|
||||||
if (status != ROPKG_SUCCESS) {
|
|
||||||
free(c->c_in_buf);
|
|
||||||
free(c->c_out_buf);
|
|
||||||
free(stream);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->c_func = func;
|
|
||||||
|
|
||||||
*out = stream;
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ropkg_status ropkg_stream_close(struct ropkg_stream *stream)
|
|
||||||
{
|
|
||||||
while (stream->s_compression_depth > 0) {
|
|
||||||
ropkg_stream_end_compressed_section(stream, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream->s_compressor.c_in_buf) {
|
|
||||||
free(stream->s_compressor.c_in_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream->s_compressor.c_out_buf) {
|
|
||||||
free(stream->s_compressor.c_out_buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream->s_compressor.c_stream) {
|
|
||||||
ropkg_compression_stream_close(stream->s_compressor.c_stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(stream);
|
|
||||||
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ropkg_status ropkg_stream_begin_compressed_section(
|
|
||||||
struct ropkg_stream *stream)
|
|
||||||
{
|
|
||||||
if (stream->s_flags & ROPKG_STREAM_F_CURSOR_MOVED) {
|
|
||||||
return ROPKG_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream->s_compression_depth > 0) {
|
|
||||||
stream->s_compression_depth++;
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->s_compression_depth = 1;
|
|
||||||
stream->s_compressor.c_in_count = 0;
|
|
||||||
stream->s_compressor.c_nr_written_compressed = 0;
|
|
||||||
stream->s_compressor.c_nr_written_uncompressed = 0;
|
|
||||||
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ropkg_status ropkg_stream_end_compressed_section(
|
|
||||||
struct ropkg_stream *stream,
|
|
||||||
size_t *out_nr_written_compressed,
|
|
||||||
size_t *out_nr_written_uncompressed)
|
|
||||||
{
|
|
||||||
if (stream->s_flags & ROPKG_STREAM_F_CURSOR_MOVED) {
|
|
||||||
return ROPKG_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream->s_compression_depth == 0) {
|
|
||||||
return ROPKG_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream->s_compression_depth > 1) {
|
|
||||||
stream->s_compression_depth--;
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->s_compression_depth = 0;
|
|
||||||
struct ropkg_stream_compressor *c = &stream->s_compressor;
|
|
||||||
if (out_nr_written_compressed) {
|
|
||||||
*out_nr_written_compressed = c->c_nr_written_compressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out_nr_written_uncompressed) {
|
|
||||||
*out_nr_written_uncompressed = c->c_nr_written_uncompressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c->c_nr_written_uncompressed == 0) {
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t out_size = 0;
|
|
||||||
|
|
||||||
ropkg_compression_stream_process(
|
|
||||||
c->c_stream,
|
|
||||||
c->c_in_count,
|
|
||||||
ROPKG_COMPRESSION_OP_END,
|
|
||||||
&out_size);
|
|
||||||
|
|
||||||
size_t nr_written = fwrite(c->c_out_buf, 1, out_size, stream->s_fp);
|
|
||||||
if (nr_written != out_size) {
|
|
||||||
return ROPKG_ERR_IO_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->c_nr_written_compressed += nr_written;
|
|
||||||
stream->s_nr_written += out_size;
|
|
||||||
if (out_nr_written_compressed) {
|
|
||||||
*out_nr_written_compressed = c->c_nr_written_compressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->s_compressor.c_in_count = 0;
|
|
||||||
stream->s_compressor.c_nr_written_compressed = 0;
|
|
||||||
stream->s_compressor.c_nr_written_uncompressed = 0;
|
|
||||||
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ropkg_status ropkg_stream_read(
|
|
||||||
struct ropkg_stream *stream,
|
|
||||||
void *p,
|
|
||||||
size_t len,
|
|
||||||
size_t *nr_read)
|
|
||||||
{
|
|
||||||
if (stream->s_mode != ROPKG_STREAM_READ) {
|
|
||||||
return ROPKG_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum ropkg_status flush_compressed_buffer(struct ropkg_stream *stream)
|
|
||||||
{
|
|
||||||
struct ropkg_stream_compressor *c = &stream->s_compressor;
|
|
||||||
|
|
||||||
size_t out_size;
|
|
||||||
enum ropkg_status status = ropkg_compression_stream_process(
|
|
||||||
c->c_stream,
|
|
||||||
c->c_in_count,
|
|
||||||
ROPKG_COMPRESSION_OP_CONTINUE,
|
|
||||||
&out_size);
|
|
||||||
|
|
||||||
if (status != ROPKG_SUCCESS) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t written = fwrite(c->c_out_buf, 1, out_size, stream->s_fp);
|
|
||||||
|
|
||||||
c->c_nr_written_compressed += c->c_in_count;
|
|
||||||
stream->s_nr_written_compressed = c->c_in_count;
|
|
||||||
stream->s_nr_written += out_size;
|
|
||||||
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ropkg_status ropkg_stream_write(
|
|
||||||
struct ropkg_stream *stream,
|
|
||||||
const void *p,
|
|
||||||
size_t len,
|
|
||||||
size_t *nr_written)
|
|
||||||
{
|
|
||||||
if (stream->s_mode != ROPKG_STREAM_WRITE) {
|
|
||||||
return ROPKG_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t w = 0;
|
|
||||||
if (stream->s_compression_depth == 0) {
|
|
||||||
w = fwrite(p, 1, len, stream->s_fp);
|
|
||||||
|
|
||||||
*nr_written = w;
|
|
||||||
if (w != len) {
|
|
||||||
return ROPKG_ERR_IO_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(stream->s_flags & ROPKG_STREAM_F_CURSOR_MOVED)) {
|
|
||||||
stream->s_nr_written_uncompressed += w;
|
|
||||||
stream->s_nr_written += w;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream->s_flags & ROPKG_STREAM_F_CURSOR_MOVED) {
|
|
||||||
return ROPKG_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ropkg_stream_compressor *c = &stream->s_compressor;
|
|
||||||
const unsigned char *src = p;
|
|
||||||
enum ropkg_status status = ROPKG_SUCCESS;
|
|
||||||
|
|
||||||
size_t remaining = len;
|
|
||||||
while (remaining > 0 && status == ROPKG_SUCCESS) {
|
|
||||||
unsigned char *dest = c->c_in_buf + c->c_in_count;
|
|
||||||
size_t space_remaining = c->c_in_max - c->c_in_count;
|
|
||||||
|
|
||||||
size_t to_copy = remaining;
|
|
||||||
if (to_copy > space_remaining) {
|
|
||||||
to_copy = space_remaining;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(dest, src, to_copy);
|
|
||||||
|
|
||||||
c->c_in_count += to_copy;
|
|
||||||
c->c_nr_written_uncompressed += to_copy;
|
|
||||||
stream->s_nr_written_uncompressed += to_copy;
|
|
||||||
space_remaining -= to_copy;
|
|
||||||
remaining -= to_copy;
|
|
||||||
w += to_copy;
|
|
||||||
|
|
||||||
if (space_remaining == 0) {
|
|
||||||
status = flush_compressed_buffer(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*nr_written = w;
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ropkg_stream_get_cursor_position(struct ropkg_stream *stream)
|
|
||||||
{
|
|
||||||
return ftell(stream->s_fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ropkg_status ropkg_stream_set_cursor_position(
|
|
||||||
struct ropkg_stream *stream,
|
|
||||||
size_t pos)
|
|
||||||
{
|
|
||||||
if (stream->s_flags & ROPKG_STREAM_F_CURSOR_MOVED) {
|
|
||||||
return ROPKG_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stream->s_compression_depth > 0) {
|
|
||||||
return ROPKG_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->s_saved_cursor = ftell(stream->s_fp);
|
|
||||||
fseek(stream->s_fp, pos, SEEK_SET);
|
|
||||||
|
|
||||||
stream->s_flags |= ROPKG_STREAM_F_CURSOR_MOVED;
|
|
||||||
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ropkg_status ropkg_stream_restore_cursor_position(
|
|
||||||
struct ropkg_stream *stream)
|
|
||||||
{
|
|
||||||
if (!(stream->s_flags & ROPKG_STREAM_F_CURSOR_MOVED)) {
|
|
||||||
return ROPKG_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
fseek(stream->s_fp, stream->s_saved_cursor, SEEK_SET);
|
|
||||||
stream->s_saved_cursor = 0;
|
|
||||||
|
|
||||||
stream->s_flags &= ~ROPKG_STREAM_F_CURSOR_MOVED;
|
|
||||||
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ropkg_stream_is_in_compressed_section(struct ropkg_stream *stream)
|
|
||||||
{
|
|
||||||
return stream->s_compression_depth > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ropkg_stream_get_nr_written(struct ropkg_stream *stream)
|
|
||||||
{
|
|
||||||
return stream->s_nr_written;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ropkg_stream_get_nr_written_compressed(struct ropkg_stream *stream)
|
|
||||||
{
|
|
||||||
return stream->s_nr_written_compressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ropkg_stream_get_nr_written_uncompressed(struct ropkg_stream *stream)
|
|
||||||
{
|
|
||||||
return stream->s_nr_written_uncompressed;
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#ifndef _ROPKG_STREAM_H_
|
|
||||||
#define _ROPKG_STREAM_H_
|
|
||||||
|
|
||||||
#include <ropkg/stream.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
struct ropkg_compression_function;
|
|
||||||
struct ropkg_compression_stream;
|
|
||||||
|
|
||||||
enum ropkg_stream_flags {
|
|
||||||
ROPKG_STREAM_F_CURSOR_MOVED = 0x01u,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ropkg_stream_compressor {
|
|
||||||
const struct ropkg_compression_function *c_func;
|
|
||||||
struct ropkg_compression_stream *c_stream;
|
|
||||||
|
|
||||||
size_t c_in_max, c_out_max;
|
|
||||||
void *c_in_buf, *c_out_buf;
|
|
||||||
size_t c_in_count;
|
|
||||||
|
|
||||||
size_t c_nr_written_compressed, c_nr_written_uncompressed;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ropkg_stream {
|
|
||||||
FILE *s_fp;
|
|
||||||
enum ropkg_stream_flags s_flags;
|
|
||||||
enum ropkg_stream_mode s_mode;
|
|
||||||
|
|
||||||
unsigned int s_compression_depth;
|
|
||||||
struct ropkg_stream_compressor s_compressor;
|
|
||||||
|
|
||||||
size_t s_saved_cursor;
|
|
||||||
size_t s_nr_written;
|
|
||||||
size_t s_nr_written_compressed;
|
|
||||||
size_t s_nr_written_uncompressed;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
24
libropkg/tar.h
Normal file
24
libropkg/tar.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef _TAR_H_
|
||||||
|
#define _TAR_H_
|
||||||
|
|
||||||
|
struct ustar_header {
|
||||||
|
char tar_filename[100];
|
||||||
|
char tar_mode[8];
|
||||||
|
char tar_uid[8];
|
||||||
|
char tar_gid[8];
|
||||||
|
char tar_filesize[12];
|
||||||
|
char tar_mtime[12];
|
||||||
|
char tar_checksum[8];
|
||||||
|
char tar_type[1];
|
||||||
|
char tar_linkname[100];
|
||||||
|
char tar_ustar_id[6];
|
||||||
|
char tar_ustar_version[2];
|
||||||
|
char tar_owner_name[32];
|
||||||
|
char tar_owner_group[32];
|
||||||
|
char tar_dev_major[8];
|
||||||
|
char tar_dev_minor[8];
|
||||||
|
char tar_filename_prefix[155];
|
||||||
|
char tar_padding[12];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,31 +1,12 @@
|
|||||||
#include <ropkg/compress.h>
|
#include "tar.h"
|
||||||
#include <ropkg/stream.h>
|
|
||||||
|
#include <blue/compress/cstream.h>
|
||||||
#include <ropkg/writer.h>
|
#include <ropkg/writer.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct ustar_header {
|
|
||||||
char tar_filename[100];
|
|
||||||
char tar_mode[8];
|
|
||||||
char tar_uid[8];
|
|
||||||
char tar_gid[8];
|
|
||||||
char tar_filesize[12];
|
|
||||||
char tar_mtime[12];
|
|
||||||
char tar_checksum[8];
|
|
||||||
char tar_type[1];
|
|
||||||
char tar_linkname[100];
|
|
||||||
char tar_ustar_id[6];
|
|
||||||
char tar_ustar_version[2];
|
|
||||||
char tar_owner_name[32];
|
|
||||||
char tar_owner_group[32];
|
|
||||||
char tar_dev_major[8];
|
|
||||||
char tar_dev_minor[8];
|
|
||||||
char tar_filename_prefix[155];
|
|
||||||
char tar_padding[12];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ropkg_writer {
|
struct ropkg_writer {
|
||||||
struct ropkg_stream *w_fp;
|
b_cstream *w_fp;
|
||||||
|
|
||||||
struct ustar_header w_file_header;
|
struct ustar_header w_file_header;
|
||||||
size_t w_file_header_offset;
|
size_t w_file_header_offset;
|
||||||
@@ -34,9 +15,7 @@ struct ropkg_writer {
|
|||||||
|
|
||||||
static const char zero_padding[512] = {0};
|
static const char zero_padding[512] = {0};
|
||||||
|
|
||||||
enum ropkg_status ropkg_writer_open(
|
enum ropkg_status ropkg_writer_open(b_cstream *fp, struct ropkg_writer **out)
|
||||||
struct ropkg_stream *fp,
|
|
||||||
struct ropkg_writer **out)
|
|
||||||
{
|
{
|
||||||
struct ropkg_writer *writer = malloc(sizeof *writer);
|
struct ropkg_writer *writer = malloc(sizeof *writer);
|
||||||
if (!writer) {
|
if (!writer) {
|
||||||
@@ -56,24 +35,24 @@ enum ropkg_status ropkg_writer_close(struct ropkg_writer *pkg)
|
|||||||
memset(&pkg->w_file_header, 0x0, sizeof pkg->w_file_header);
|
memset(&pkg->w_file_header, 0x0, sizeof pkg->w_file_header);
|
||||||
|
|
||||||
size_t nr_written;
|
size_t nr_written;
|
||||||
enum ropkg_status status = ropkg_stream_write(
|
b_status status = b_cstream_write(
|
||||||
pkg->w_fp,
|
pkg->w_fp,
|
||||||
&pkg->w_file_header,
|
&pkg->w_file_header,
|
||||||
sizeof pkg->w_file_header,
|
sizeof pkg->w_file_header,
|
||||||
&nr_written);
|
&nr_written);
|
||||||
|
|
||||||
if (status != ROPKG_SUCCESS) {
|
if (!B_OK(status)) {
|
||||||
return status;
|
return ROPKG_ERR_IO_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = ropkg_stream_write(
|
status = b_cstream_write(
|
||||||
pkg->w_fp,
|
pkg->w_fp,
|
||||||
&pkg->w_file_header,
|
&pkg->w_file_header,
|
||||||
sizeof pkg->w_file_header,
|
sizeof pkg->w_file_header,
|
||||||
&nr_written);
|
&nr_written);
|
||||||
|
|
||||||
if (status != ROPKG_SUCCESS) {
|
if (!B_OK(status)) {
|
||||||
return status;
|
return ROPKG_ERR_IO_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nr_written != sizeof pkg->w_file_header) {
|
if (nr_written != sizeof pkg->w_file_header) {
|
||||||
@@ -129,12 +108,12 @@ enum ropkg_status ropkg_writer_begin_file(
|
|||||||
const char *path,
|
const char *path,
|
||||||
const struct ropkg_writer_file_info *info)
|
const struct ropkg_writer_file_info *info)
|
||||||
{
|
{
|
||||||
if (ropkg_stream_is_in_compressed_section(pkg->w_fp)) {
|
if (b_cstream_in_compressed_section(pkg->w_fp)) {
|
||||||
pkg->w_file_header_offset
|
b_cstream_tx_bytes_uncompressed(
|
||||||
= ropkg_stream_get_nr_written_uncompressed(pkg->w_fp);
|
pkg->w_fp,
|
||||||
|
&pkg->w_file_header_offset);
|
||||||
} else {
|
} else {
|
||||||
pkg->w_file_header_offset
|
b_cstream_tx_bytes(pkg->w_fp, &pkg->w_file_header_offset);
|
||||||
= ropkg_stream_get_nr_written(pkg->w_fp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ropkg_status status
|
enum ropkg_status status
|
||||||
@@ -144,14 +123,14 @@ enum ropkg_status ropkg_writer_begin_file(
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t nr_written;
|
size_t nr_written;
|
||||||
status = ropkg_stream_write(
|
b_status status2 = b_cstream_write(
|
||||||
pkg->w_fp,
|
pkg->w_fp,
|
||||||
&pkg->w_file_header,
|
&pkg->w_file_header,
|
||||||
sizeof pkg->w_file_header,
|
sizeof pkg->w_file_header,
|
||||||
&nr_written);
|
&nr_written);
|
||||||
|
|
||||||
if (status != ROPKG_SUCCESS) {
|
if (!B_OK(status2)) {
|
||||||
return status;
|
return ROPKG_ERR_IO_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nr_written != sizeof pkg->w_file_header) {
|
if (nr_written != sizeof pkg->w_file_header) {
|
||||||
@@ -163,26 +142,26 @@ enum ropkg_status ropkg_writer_begin_file(
|
|||||||
|
|
||||||
enum ropkg_status ropkg_writer_end_file(struct ropkg_writer *pkg)
|
enum ropkg_status ropkg_writer_end_file(struct ropkg_writer *pkg)
|
||||||
{
|
{
|
||||||
enum ropkg_status status;
|
b_status status;
|
||||||
size_t written, file_length, pos;
|
size_t written, file_length, pos;
|
||||||
if (ropkg_stream_is_in_compressed_section(pkg->w_fp)) {
|
if (b_cstream_in_compressed_section(pkg->w_fp)) {
|
||||||
pos = ropkg_stream_get_nr_written_uncompressed(pkg->w_fp);
|
b_cstream_tx_bytes_uncompressed(pkg->w_fp, &pos);
|
||||||
} else {
|
} else {
|
||||||
pos = ropkg_stream_get_nr_written(pkg->w_fp);
|
b_cstream_tx_bytes(pkg->w_fp, &pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
file_length
|
file_length
|
||||||
= pos - pkg->w_file_header_offset - sizeof pkg->w_file_header;
|
= pos - pkg->w_file_header_offset - sizeof pkg->w_file_header;
|
||||||
|
|
||||||
size_t required_padding = 512 - (file_length % 512);
|
size_t required_padding = 512 - (file_length % 512);
|
||||||
status = ropkg_stream_write(
|
status = b_cstream_write(
|
||||||
pkg->w_fp,
|
pkg->w_fp,
|
||||||
zero_padding,
|
zero_padding,
|
||||||
required_padding,
|
required_padding,
|
||||||
&written);
|
&written);
|
||||||
|
|
||||||
if (status != ROPKG_SUCCESS) {
|
if (!B_OK(status)) {
|
||||||
return status;
|
return ROPKG_ERR_IO_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
to_octal(
|
to_octal(
|
||||||
@@ -191,16 +170,16 @@ enum ropkg_status ropkg_writer_end_file(struct ropkg_writer *pkg)
|
|||||||
sizeof pkg->w_file_header.tar_filesize);
|
sizeof pkg->w_file_header.tar_filesize);
|
||||||
refresh_header_checksum(&pkg->w_file_header);
|
refresh_header_checksum(&pkg->w_file_header);
|
||||||
|
|
||||||
status = ropkg_stream_set_cursor_position(
|
status = b_cstream_set_cursor_position(
|
||||||
pkg->w_fp,
|
pkg->w_fp,
|
||||||
pkg->w_file_header_offset);
|
pkg->w_file_header_offset);
|
||||||
if (status == ROPKG_SUCCESS) {
|
if (B_OK(status)) {
|
||||||
ropkg_stream_write(
|
b_cstream_write(
|
||||||
pkg->w_fp,
|
pkg->w_fp,
|
||||||
&pkg->w_file_header,
|
&pkg->w_file_header,
|
||||||
sizeof pkg->w_file_header,
|
sizeof pkg->w_file_header,
|
||||||
&written);
|
&written);
|
||||||
ropkg_stream_restore_cursor_position(pkg->w_fp);
|
b_cstream_restore_cursor_position(pkg->w_fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ROPKG_SUCCESS;
|
return ROPKG_SUCCESS;
|
||||||
@@ -212,10 +191,9 @@ enum ropkg_status ropkg_writer_write(
|
|||||||
size_t len,
|
size_t len,
|
||||||
size_t *nr_written)
|
size_t *nr_written)
|
||||||
{
|
{
|
||||||
enum ropkg_status status
|
b_status status = b_cstream_write(pkg->w_fp, p, len, nr_written);
|
||||||
= ropkg_stream_write(pkg->w_fp, p, len, nr_written);
|
if (!B_OK(status)) {
|
||||||
if (status != ROPKG_SUCCESS) {
|
return ROPKG_ERR_IO_FAILURE;
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pkg->w_file_nr_written += len;
|
pkg->w_file_nr_written += len;
|
||||||
|
|||||||
203
libropkg/zstd.c
203
libropkg/zstd.c
@@ -1,203 +0,0 @@
|
|||||||
#include "compress.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <zstd.h>
|
|
||||||
|
|
||||||
struct zstd_stream {
|
|
||||||
struct ropkg_compression_stream s_base;
|
|
||||||
union {
|
|
||||||
ZSTD_CCtx *c;
|
|
||||||
ZSTD_DCtx *d;
|
|
||||||
} s_ctx;
|
|
||||||
};
|
|
||||||
|
|
||||||
static enum ropkg_status zstd_buffer_size(
|
|
||||||
enum ropkg_compression_stream_mode mode,
|
|
||||||
size_t *in_buffer_size,
|
|
||||||
size_t *out_buffer_size)
|
|
||||||
{
|
|
||||||
switch (mode) {
|
|
||||||
case ROPKG_COMPRESSION_MODE_COMPRESS:
|
|
||||||
if (in_buffer_size) {
|
|
||||||
*in_buffer_size = ZSTD_CStreamInSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out_buffer_size) {
|
|
||||||
*out_buffer_size = ZSTD_CStreamOutSize();
|
|
||||||
}
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
case ROPKG_COMPRESSION_MODE_DECOMPRESS:
|
|
||||||
if (in_buffer_size) {
|
|
||||||
*in_buffer_size = ZSTD_DStreamInSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out_buffer_size) {
|
|
||||||
*out_buffer_size = ZSTD_DStreamOutSize();
|
|
||||||
}
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
default:
|
|
||||||
return ROPKG_ERR_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum ropkg_status zstd_open(
|
|
||||||
const struct ropkg_compression_function *func,
|
|
||||||
enum ropkg_compression_stream_mode mode,
|
|
||||||
void *in_buffer,
|
|
||||||
size_t in_max,
|
|
||||||
void *out_buffer,
|
|
||||||
size_t out_max,
|
|
||||||
struct ropkg_compression_stream **out)
|
|
||||||
{
|
|
||||||
struct zstd_stream *stream = malloc(sizeof *stream);
|
|
||||||
if (!stream) {
|
|
||||||
return ROPKG_ERR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(stream, 0x0, sizeof *stream);
|
|
||||||
|
|
||||||
stream->s_base.s_in = in_buffer;
|
|
||||||
stream->s_base.s_in_max = in_max;
|
|
||||||
stream->s_base.s_out = out_buffer;
|
|
||||||
stream->s_base.s_out_max = out_max;
|
|
||||||
stream->s_base.s_func = func;
|
|
||||||
stream->s_base.s_mode = mode;
|
|
||||||
|
|
||||||
switch (mode) {
|
|
||||||
case ROPKG_COMPRESSION_MODE_COMPRESS:
|
|
||||||
stream->s_ctx.c = ZSTD_createCCtx();
|
|
||||||
|
|
||||||
if (!stream->s_ctx.c) {
|
|
||||||
free(stream);
|
|
||||||
return ROPKG_ERR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
ZSTD_CCtx_setParameter(
|
|
||||||
stream->s_ctx.c,
|
|
||||||
ZSTD_c_compressionLevel,
|
|
||||||
10);
|
|
||||||
ZSTD_CCtx_setParameter(stream->s_ctx.c, ZSTD_c_checksumFlag, 1);
|
|
||||||
break;
|
|
||||||
case ROPKG_COMPRESSION_MODE_DECOMPRESS:
|
|
||||||
stream->s_ctx.d = ZSTD_createDCtx();
|
|
||||||
|
|
||||||
if (!stream->s_ctx.d) {
|
|
||||||
free(stream);
|
|
||||||
return ROPKG_ERR_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
free(stream);
|
|
||||||
return ROPKG_ERR_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out = &stream->s_base;
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum ropkg_status zstd_close(struct ropkg_compression_stream *stream)
|
|
||||||
{
|
|
||||||
struct zstd_stream *zstream = (struct zstd_stream *)stream;
|
|
||||||
switch (stream->s_mode) {
|
|
||||||
case ROPKG_COMPRESSION_MODE_COMPRESS:
|
|
||||||
ZSTD_freeCCtx(zstream->s_ctx.c);
|
|
||||||
break;
|
|
||||||
case ROPKG_COMPRESSION_MODE_DECOMPRESS:
|
|
||||||
ZSTD_freeDCtx(zstream->s_ctx.d);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return ROPKG_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(stream);
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum ropkg_status zstd_compress(
|
|
||||||
struct zstd_stream *zstream,
|
|
||||||
enum ropkg_compression_stream_op op,
|
|
||||||
ZSTD_inBuffer *in,
|
|
||||||
ZSTD_outBuffer *out)
|
|
||||||
{
|
|
||||||
ZSTD_EndDirective zop;
|
|
||||||
|
|
||||||
switch (op) {
|
|
||||||
case ROPKG_COMPRESSION_OP_CONTINUE:
|
|
||||||
zop = ZSTD_e_continue;
|
|
||||||
break;
|
|
||||||
case ROPKG_COMPRESSION_OP_END:
|
|
||||||
zop = ZSTD_e_end;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return ROPKG_ERR_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
size_t ret
|
|
||||||
= ZSTD_compressStream2(zstream->s_ctx.c, out, in, zop);
|
|
||||||
|
|
||||||
if (ret == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (in->pos < in->size);
|
|
||||||
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum ropkg_status zstd_decompress(
|
|
||||||
struct zstd_stream *zstream,
|
|
||||||
ZSTD_inBuffer *in,
|
|
||||||
ZSTD_outBuffer *out)
|
|
||||||
{
|
|
||||||
size_t ret = 0;
|
|
||||||
|
|
||||||
while (in->pos < in->size) {
|
|
||||||
ret = ZSTD_decompressStream(zstream->s_ctx.d, out, in);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret != 0) {
|
|
||||||
return ROPKG_ERR_INTERNAL_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum ropkg_status zstd_process(
|
|
||||||
struct ropkg_compression_stream *stream,
|
|
||||||
size_t in_size,
|
|
||||||
enum ropkg_compression_stream_op op,
|
|
||||||
size_t *out_size)
|
|
||||||
{
|
|
||||||
struct zstd_stream *zstream = (struct zstd_stream *)stream;
|
|
||||||
ZSTD_inBuffer in = {.src = stream->s_in, .size = in_size};
|
|
||||||
ZSTD_outBuffer out = {.dst = stream->s_out, .size = stream->s_out_max};
|
|
||||||
|
|
||||||
enum ropkg_status status;
|
|
||||||
switch (stream->s_mode) {
|
|
||||||
case ROPKG_COMPRESSION_MODE_COMPRESS:
|
|
||||||
status = zstd_compress(zstream, op, &in, &out);
|
|
||||||
break;
|
|
||||||
case ROPKG_COMPRESSION_MODE_DECOMPRESS:
|
|
||||||
status = zstd_decompress(zstream, &in, &out);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return ROPKG_ERR_BAD_STATE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out_size) {
|
|
||||||
*out_size = out.pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ROPKG_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct ropkg_compression_function ropkg_zstd = {
|
|
||||||
.f_name = "zstd",
|
|
||||||
.f_extension = ".zst",
|
|
||||||
.f_buffer_size = zstd_buffer_size,
|
|
||||||
.f_open = zstd_open,
|
|
||||||
.f_close = zstd_close,
|
|
||||||
.f_process = zstd_process,
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user