summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorruki <[email protected]>2022-05-08 19:02:02 +0800
committerruki <[email protected]>2022-05-08 19:02:02 +0800
commit48e5fa5a58685b7c77c0576d55f43d0eb53b062f (patch)
treec52a40f734b230d15d139e92adcaf790da8e695e /core/src
parent4045ac9d0c0e49c04794e2f8a253e81d6d29287c (diff)
impl lz4 compress and decompress
Diffstat (limited to 'core/src')
-rw-r--r--core/src/lz4/xmake.lua2
-rw-r--r--core/src/xmake/lz4/compress.c50
-rw-r--r--core/src/xmake/lz4/decompress.c65
-rw-r--r--core/src/xmake/lz4/prefix.h4
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