Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 
0003 #include <string.h>
0004 
0005 #include "util/compress.h"
0006 #include "util/debug.h"
0007 
0008 int zstd_init(struct zstd_data *data, int level)
0009 {
0010     size_t ret;
0011 
0012     data->dstream = ZSTD_createDStream();
0013     if (data->dstream == NULL) {
0014         pr_err("Couldn't create decompression stream.\n");
0015         return -1;
0016     }
0017 
0018     ret = ZSTD_initDStream(data->dstream);
0019     if (ZSTD_isError(ret)) {
0020         pr_err("Failed to initialize decompression stream: %s\n", ZSTD_getErrorName(ret));
0021         return -1;
0022     }
0023 
0024     if (!level)
0025         return 0;
0026 
0027     data->cstream = ZSTD_createCStream();
0028     if (data->cstream == NULL) {
0029         pr_err("Couldn't create compression stream.\n");
0030         return -1;
0031     }
0032 
0033     ret = ZSTD_initCStream(data->cstream, level);
0034     if (ZSTD_isError(ret)) {
0035         pr_err("Failed to initialize compression stream: %s\n", ZSTD_getErrorName(ret));
0036         return -1;
0037     }
0038 
0039     return 0;
0040 }
0041 
0042 int zstd_fini(struct zstd_data *data)
0043 {
0044     if (data->dstream) {
0045         ZSTD_freeDStream(data->dstream);
0046         data->dstream = NULL;
0047     }
0048 
0049     if (data->cstream) {
0050         ZSTD_freeCStream(data->cstream);
0051         data->cstream = NULL;
0052     }
0053 
0054     return 0;
0055 }
0056 
0057 size_t zstd_compress_stream_to_records(struct zstd_data *data, void *dst, size_t dst_size,
0058                        void *src, size_t src_size, size_t max_record_size,
0059                        size_t process_header(void *record, size_t increment))
0060 {
0061     size_t ret, size, compressed = 0;
0062     ZSTD_inBuffer input = { src, src_size, 0 };
0063     ZSTD_outBuffer output;
0064     void *record;
0065 
0066     while (input.pos < input.size) {
0067         record = dst;
0068         size = process_header(record, 0);
0069         compressed += size;
0070         dst += size;
0071         dst_size -= size;
0072         output = (ZSTD_outBuffer){ dst, (dst_size > max_record_size) ?
0073                         max_record_size : dst_size, 0 };
0074         ret = ZSTD_compressStream(data->cstream, &output, &input);
0075         ZSTD_flushStream(data->cstream, &output);
0076         if (ZSTD_isError(ret)) {
0077             pr_err("failed to compress %ld bytes: %s\n",
0078                 (long)src_size, ZSTD_getErrorName(ret));
0079             memcpy(dst, src, src_size);
0080             return src_size;
0081         }
0082         size = output.pos;
0083         size = process_header(record, size);
0084         compressed += size;
0085         dst += size;
0086         dst_size -= size;
0087     }
0088 
0089     return compressed;
0090 }
0091 
0092 size_t zstd_decompress_stream(struct zstd_data *data, void *src, size_t src_size,
0093                   void *dst, size_t dst_size)
0094 {
0095     size_t ret;
0096     ZSTD_inBuffer input = { src, src_size, 0 };
0097     ZSTD_outBuffer output = { dst, dst_size, 0 };
0098 
0099     while (input.pos < input.size) {
0100         ret = ZSTD_decompressStream(data->dstream, &output, &input);
0101         if (ZSTD_isError(ret)) {
0102             pr_err("failed to decompress (B): %zd -> %zd, dst_size %zd : %s\n",
0103                    src_size, output.size, dst_size, ZSTD_getErrorName(ret));
0104             break;
0105         }
0106         output.dst  = dst + output.pos;
0107         output.size = dst_size - output.pos;
0108     }
0109 
0110     return output.pos;
0111 }