diff options
| author | ruki <[email protected]> | 2022-05-08 19:02:02 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2022-05-08 19:02:02 +0800 |
| commit | 48e5fa5a58685b7c77c0576d55f43d0eb53b062f (patch) | |
| tree | c52a40f734b230d15d139e92adcaf790da8e695e /core/src | |
| parent | 4045ac9d0c0e49c04794e2f8a253e81d6d29287c (diff) | |
impl lz4 compress and decompress
Diffstat (limited to 'core/src')
| -rw-r--r-- | core/src/lz4/xmake.lua | 2 | ||||
| -rw-r--r-- | core/src/xmake/lz4/compress.c | 50 | ||||
| -rw-r--r-- | core/src/xmake/lz4/decompress.c | 65 | ||||
| -rw-r--r-- | core/src/xmake/lz4/prefix.h | 4 |
4 files changed, 117 insertions, 4 deletions
diff --git a/core/src/lz4/xmake.lua b/core/src/lz4/xmake.lua index 6cdcaabf2..8079d6933 100644 --- a/core/src/lz4/xmake.lua +++ b/core/src/lz4/xmake.lua @@ -8,7 +8,7 @@ target("lz4") end -- add header files - add_headerfiles("lz4/lib/(*.h)", {prefixdir = "lz4"}) + add_headerfiles("lz4/lib/(*.h)") -- add include directories add_includedirs("lz4", {public = true}) diff --git a/core/src/xmake/lz4/compress.c b/core/src/xmake/lz4/compress.c index 0d3f42e86..e51c991f6 100644 --- a/core/src/xmake/lz4/compress.c +++ b/core/src/xmake/lz4/compress.c @@ -38,5 +38,53 @@ tb_int_t xm_lz4_compress(lua_State* lua) // check tb_assert_and_check_return_val(lua, 0); - return 0; + // get data and size + tb_size_t size = 0; + tb_byte_t const* data = tb_null; + if (lua_isnumber(lua, 1)) data = (tb_byte_t const*)(tb_size_t)(tb_long_t)lua_tonumber(lua, 1); + if (lua_isnumber(lua, 2)) size = (tb_size_t)lua_tonumber(lua, 2); + if (!data || !size) + { + lua_pushnil(lua); + lua_pushfstring(lua, "invalid data(%p) and size(%d)!", data, (tb_int_t)size); + return 2; + } + + // do compress + tb_bool_t ok = tb_false; + tb_char_t const* error = tb_null; + tb_byte_t* output_data = tb_null; + tb_byte_t buffer[8192]; + do + { + tb_size_t output_size = LZ4F_compressFrameBound(size, tb_null); + tb_assert_and_check_break(output_size); + + output_data = output_size <= sizeof(buffer)? buffer : tb_malloc(output_size); + tb_assert_and_check_break(output_data); + + tb_size_t err = LZ4F_compressFrame(output_data, output_size, data, size, tb_null); + if (LZ4F_isError(err)) + { + error = LZ4F_getErrorName(err); + break; + } + + lua_pushlstring(lua, (tb_char_t const*)output_data, output_size); + ok = tb_true; + } while (0); + + if (output_data && output_data != buffer) + { + tb_free(output_data); + output_data = tb_null; + } + + if (!ok) + { + lua_pushnil(lua); + lua_pushstring(lua, error? error : "unknown"); + return 2; + } + return 1; } diff --git a/core/src/xmake/lz4/decompress.c b/core/src/xmake/lz4/decompress.c index d18d02f7e..2fad208a2 100644 --- a/core/src/xmake/lz4/decompress.c +++ b/core/src/xmake/lz4/decompress.c @@ -38,6 +38,69 @@ tb_int_t xm_lz4_decompress(lua_State* lua) // check tb_assert_and_check_return_val(lua, 0); - return 0; + // get data and size + tb_size_t size = 0; + tb_byte_t const* data = tb_null; + if (lua_isnumber(lua, 1)) data = (tb_byte_t const*)(tb_size_t)(tb_long_t)lua_tonumber(lua, 1); + if (lua_isnumber(lua, 2)) size = (tb_size_t)lua_tonumber(lua, 2); + if (!data || !size) + { + lua_pushnil(lua); + lua_pushfstring(lua, "invalid data(%p) and size(%d)!", data, (tb_int_t)size); + return 2; + } + + // do decompress + tb_bool_t ok = tb_false; + LZ4F_errorCode_t code; + LZ4F_decompressionContext_t ctx = tb_null; + tb_buffer_t result; + do + { + tb_buffer_init(&result); + + code = LZ4F_createDecompressionContext(&ctx, LZ4F_VERSION); + if (LZ4F_isError(code)) break; + + tb_byte_t buffer[8192]; + tb_bool_t failed = tb_false; + while (1) + { + tb_size_t advance = size; + size_t buffer_size = sizeof(buffer); + code = LZ4F_decompress(ctx, buffer, &buffer_size, data, &advance, tb_null); + if (LZ4F_isError(code)) + { + failed = tb_true; + break; + } + + if (buffer_size == 0) break; + data += advance; + size -= advance; + + tb_buffer_memncat(&result, buffer, buffer_size); + } + tb_assert_and_check_break(!failed && tb_buffer_size(&result)); + + lua_pushlstring(lua, (tb_char_t const*)tb_buffer_data(&result), tb_buffer_size(&result)); + ok = tb_true; + } while (0); + + if (ctx) + { + LZ4F_freeDecompressionContext(ctx); + ctx = tb_null; + } + tb_buffer_exit(&result); + + if (!ok) + { + tb_char_t const* error = LZ4F_getErrorName(code); + lua_pushnil(lua); + lua_pushstring(lua, error? error : "unknown"); + return 2; + } + return 1; } diff --git a/core/src/xmake/lz4/prefix.h b/core/src/xmake/lz4/prefix.h index b0a8d06d0..aeb40da38 100644 --- a/core/src/xmake/lz4/prefix.h +++ b/core/src/xmake/lz4/prefix.h @@ -25,7 +25,9 @@ * includes */ #include "../prefix.h" - +#include "lz4frame.h" +#include "lz4.h" +#include "lz4hc.h" #endif |
