luat_lib_fastlz.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. @module fastlz
  3. @summary FastLZ压缩
  4. @version 1.0
  5. @date 2023.7.38
  6. @tag LUAT_USE_FASTLZ
  7. @usage
  8. -- 与miniz库的差异
  9. -- 内存需求量小很多, miniz库接近200k, fastlz只需要32k+原始数据大小
  10. -- 压缩比, miniz的压缩比要好于fastlz
  11. -- 准备好数据
  12. local bigdata = "123jfoiq4hlkfjbnasdilfhuqwo;hfashfp9qw38hrfaios;hfiuoaghfluaeisw"
  13. -- 压缩之
  14. local cdata = fastlz.compress(bigdata)
  15. -- lua 的 字符串相当于有长度的char[],可存放包括0x00的一切数据
  16. if cdata then
  17. -- 检查压缩前后的数据大小
  18. log.info("fastlz", "before", #bigdata, "after", #cdata)
  19. log.info("fastlz", "cdata as hex", cdata:toHex())
  20. -- 解压, 得到原文
  21. local udata = fastlz.uncompress(cdata)
  22. log.info("fastlz", "udata", udata)
  23. end
  24. */
  25. #include "luat_base.h"
  26. #include "luat_mem.h"
  27. #define LUAT_LOG_TAG "fastlz"
  28. #include "luat_log.h"
  29. #include "fastlz.h"
  30. #define HASH_LOG 13
  31. #define HASH_SIZE (1 << HASH_LOG)
  32. #define HASH_MASK (HASH_SIZE - 1)
  33. /*
  34. 快速压缩
  35. @api fastlz.compress(data, level)
  36. @string 待压缩的数据, 少于400字节的数据不建议压缩, 且压缩后的数据不能大于32k
  37. @int 压缩级别,默认1, 可选1或者2, 2的压缩比更高(有时候)
  38. @return string 若压缩成功,返回数据字符串, 否则返回nil
  39. @usage
  40. -- 注意, 压缩过程的内存消耗如下
  41. -- 系统内存, 固定32k
  42. -- lua内存, 原始数据的大小的1.05倍,最小占用1024字节.
  43. */
  44. static int l_fastlz_compress(lua_State* L) {
  45. size_t len = 0;
  46. const char* data = luaL_checklstring(L, 1, &len);
  47. int level = luaL_optinteger(L, 2, 1);
  48. luaL_Buffer buff;
  49. luaL_buffinitsize(L, &buff, len > 512 ? (int)(len * 1.05) : (1024));
  50. uint32_t *htab = luat_heap_malloc( sizeof(uint32_t) * HASH_SIZE);
  51. if (htab) {
  52. int ret = fastlz_compress_level(level, data, len, buff.b, htab);
  53. luat_heap_free(htab);
  54. if (ret > 0) {
  55. luaL_pushresultsize(&buff, ret);
  56. return 1;
  57. }
  58. }
  59. return 0;
  60. }
  61. /*
  62. 快速解压
  63. @api fastlz.uncompress(data, maxout)
  64. @string 待解压的数据
  65. @int 解压后的最大大小, 默认是4k, 可按需调整
  66. @return string 若解压成功,返回数据字符串, 否则返回nil
  67. */
  68. static int l_fastlz_uncompress(lua_State* L) {
  69. size_t len = 0;
  70. const char* data = luaL_checklstring(L, 1, &len);
  71. size_t maxout = luaL_optinteger(L, 2, 4096);
  72. luaL_Buffer buff;
  73. luaL_buffinitsize(L, &buff, maxout);
  74. uint32_t *htab = luat_heap_malloc( sizeof(uint32_t) * HASH_SIZE);
  75. if (htab) {
  76. int ret = fastlz_decompress(data, len, buff.b, maxout);
  77. luat_heap_free(htab);
  78. if (ret > 0) {
  79. luaL_pushresultsize(&buff, ret);
  80. return 1;
  81. }
  82. }
  83. return 0;
  84. }
  85. #include "rotable2.h"
  86. static const rotable_Reg_t reg_fastlz[] = {
  87. {"compress", ROREG_FUNC(l_fastlz_compress)},
  88. {"uncompress", ROREG_FUNC(l_fastlz_uncompress)},
  89. {NULL, ROREG_INT(0)}
  90. };
  91. LUAMOD_API int luaopen_fastlz( lua_State *L ) {
  92. luat_newlib2(L, reg_fastlz);
  93. return 1;
  94. }