1
4
5# include "luametatex.h"
6# include "lmtoptional.h"
7
8# define ZSTD_DEFAULTCLEVEL 3
9
10typedef struct zstdlib_state_info {
11
12 int initialized;
13 int padding;
14
15 size_t (*ZSTD_compressBound) (size_t srcSize);
16 size_t (*ZSTD_getFrameContentSize) (const void *, size_t);
17 size_t (*ZSTD_compress) (void *dst, size_t dstCapacity, const void *src, size_t srcSize, int compressionLevel);
18 size_t (*ZSTD_decompress) (void *dst, size_t dstCapacity, const void *src, size_t compressedSize);
19
20
21
22
23
24} zstdlib_state_info;
25
26static zstdlib_state_info zstdlib_state = {
27
28 .initialized = 0,
29 .padding = 0,
30
31 .ZSTD_compressBound = NULL,
32 .ZSTD_getFrameContentSize = NULL,
33 .ZSTD_compress = NULL,
34 .ZSTD_decompress = NULL,
35
36
37
38
39
40};
41
42static int zstdlib_compress(lua_State *L)
43{
44 if (zstdlib_state.initialized) {
45 size_t sourcesize = 0;
46 const char *source = luaL_checklstring(L, 1, &sourcesize);
47 int level = lmt_optinteger(L, 2, ZSTD_DEFAULTCLEVEL);
48 size_t targetsize = zstdlib_state.ZSTD_compressBound(sourcesize);
49 luaL_Buffer buffer;
50 char *target = luaL_buffinitsize(L, &buffer, targetsize);
51 size_t result = zstdlib_state.ZSTD_compress(target, targetsize, source, sourcesize, level);
52 if (result > 0) {
53 luaL_pushresultsize(&buffer, result);
54 } else {
55 lua_pushnil(L);
56 }
57 return 1;
58 } else {
59 return 0;
60 }
61}
62
63static int zstdlib_decompress(lua_State *L)
64{
65 if (zstdlib_state.initialized) {
66 size_t sourcesize = 0;
67 const char *source = luaL_checklstring(L, 1, &sourcesize);
68 size_t targetsize = zstdlib_state.ZSTD_getFrameContentSize(source, sourcesize);
69 luaL_Buffer buffer;
70 char *target = luaL_buffinitsize(L, &buffer, targetsize);
71 size_t result = zstdlib_state.ZSTD_decompress(target, targetsize, source, sourcesize);
72 if (result > 0) {
73 luaL_pushresultsize(&buffer, result);
74 } else {
75 lua_pushnil(L);
76 }
77 return 1;
78 } else {
79 return 0;
80 }
81}
82
83static int zstdlib_initialize(lua_State *L)
84{
85 if (! zstdlib_state.initialized) {
86 const char *filename = lua_tostring(L, 1);
87 if (filename) {
88
89 lmt_library lib = lmt_library_load(filename);
90
91 zstdlib_state.ZSTD_compressBound = lmt_library_find(lib, "ZSTD_compressBound");
92 zstdlib_state.ZSTD_getFrameContentSize = lmt_library_find(lib, "ZSTD_getFrameContentSize");
93 zstdlib_state.ZSTD_compress = lmt_library_find(lib, "ZSTD_compress");
94 zstdlib_state.ZSTD_decompress = lmt_library_find(lib, "ZSTD_decompress");
95
96
97
98
99
100 zstdlib_state.initialized = lmt_library_okay(lib);
101 }
102 }
103 lua_pushboolean(L, zstdlib_state.initialized);
104 return 1;
105}
106
107static struct luaL_Reg zstdlib_function_list[] = {
108 { "initialize", zstdlib_initialize },
109 { "compress", zstdlib_compress },
110 { "decompress", zstdlib_decompress },
111 { NULL, NULL },
112};
113
114int luaopen_zstd(lua_State * L)
115{
116 lmt_library_register(L, "zstd", zstdlib_function_list);
117 return 0;
118}
119 |