mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-22 17:12:55 +08:00
63 lines
2.0 KiB
C
63 lines
2.0 KiB
C
|
#include "_zlib.h"
|
||
|
#include "fastlz.h"
|
||
|
|
||
|
Arg* _zlib_compress(PikaObj* self, Arg* data, int level) {
|
||
|
if (arg_getType(data) != ARG_TYPE_BYTES) {
|
||
|
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
||
|
obj_setSysOut(self, "TypeError: a bytes is required");
|
||
|
return NULL;
|
||
|
}
|
||
|
Arg* aRet = NULL;
|
||
|
uint8_t* input = arg_getBytes(data);
|
||
|
size_t input_len = arg_getBytesSize(data);
|
||
|
size_t max_output_len =
|
||
|
input_len * 1.1 + 64; // Fastlz's maximum output size guideline
|
||
|
uint8_t* ret = pikaMalloc(max_output_len);
|
||
|
size_t ret_len = fastlz_compress_level(level, input, input_len, ret);
|
||
|
if (ret_len == 0) {
|
||
|
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
||
|
obj_setSysOut(self, "Compression failed");
|
||
|
aRet = NULL;
|
||
|
goto __exit;
|
||
|
}
|
||
|
aRet = arg_newBytes(ret, ret_len);
|
||
|
goto __exit;
|
||
|
__exit:
|
||
|
pikaFree(ret, max_output_len);
|
||
|
return aRet;
|
||
|
}
|
||
|
|
||
|
Arg* _zlib_decompress(PikaObj* self, Arg* data) {
|
||
|
if (arg_getType(data) != ARG_TYPE_BYTES) {
|
||
|
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
||
|
obj_setSysOut(self, "TypeError: a bytes is required");
|
||
|
return NULL;
|
||
|
}
|
||
|
uint8_t* input = arg_getBytes(data);
|
||
|
size_t input_len = arg_getBytesSize(data);
|
||
|
size_t max_output_len =
|
||
|
input_len * 4; // Assume the decompressed data is no more than 4 times
|
||
|
// the input data
|
||
|
size_t ret_len = 0;
|
||
|
uint8_t* ret = NULL;
|
||
|
Arg* aRet = NULL;
|
||
|
int multiplier = 1;
|
||
|
do {
|
||
|
multiplier *= 2;
|
||
|
max_output_len = input_len * multiplier;
|
||
|
ret = pikaMalloc(max_output_len);
|
||
|
ret_len = fastlz_decompress(input, input_len, ret, max_output_len);
|
||
|
if (ret_len == 0) {
|
||
|
pikaFree(ret, max_output_len);
|
||
|
}
|
||
|
} while (ret_len == 0 && multiplier <= 8);
|
||
|
if (ret_len == 0) {
|
||
|
obj_setErrorCode(self, PIKA_RES_ERR_INVALID_PARAM);
|
||
|
obj_setSysOut(self, "Decompression failed");
|
||
|
return NULL;
|
||
|
}
|
||
|
aRet = arg_newBytes(ret, ret_len);
|
||
|
pikaFree(ret, max_output_len);
|
||
|
return aRet;
|
||
|
}
|