lmtlzo.c /size: 3207 b    last modification: 2024-01-16 10:22
1/*
2    See license.txt in the root of this project.
3*/
4
5# include <stdlib.h>
6
7# include "luametatex.h"
8# include "lmtoptional.h"
9
10# define lzo_output_length(n)  (n + n / 16 + 64 + 64) /* we add 64 instead of 3 */
11
12# define LZO_E_OK 0
13
14typedef struct lzolib_state_info {
15
16    int initialized;
17    int padding;
18
19    int (*lzo1x_1_compress)      (const char *source, size_t sourcesize, char *target, size_t *targetsize, void *wrkmem);
20    int (*lzo1x_decompress_safe) (const char *source, size_t sourcesize, char *target, size_t *targetsize, void *wrkmem);
21
22} lzolib_state_info;
23
24static lzolib_state_info lzolib_state = {
25
26    .initialized           = 0,
27    .padding               = 0,
28
29    .lzo1x_1_compress      = NULL,
30    .lzo1x_decompress_safe = NULL,
31
32};
33
34static int lzolib_compress(lua_State *L)
35{
36    if (lzolib_state.initialized) {
37        char *wrkmem = lmt_memory_malloc(16384 + 32); /* we some plenty of slack, normally 2 seemss enough */
38        size_t sourcesize = 0;
39        const char *source = luaL_checklstring(L, 1, &sourcesize);
40        luaL_Buffer buffer;
41        size_t targetsize = lzo_output_length(sourcesize);
42        char *target = luaL_buffinitsize(L, &buffer, targetsize);
43        int result = lzolib_state.lzo1x_1_compress(source, sourcesize, target, &targetsize, wrkmem);
44        if (result == LZO_E_OK) {
45            luaL_pushresultsize(&buffer, targetsize);
46        } else {
47            lua_pushnil(L);
48        }
49        lmt_memory_free(wrkmem);
50        return 1;
51    } else {
52        return 0;
53    }
54}
55
56static int lzolib_decompresssize(lua_State *L)
57{
58    if (lzolib_state.initialized) {
59        size_t sourcesize = 0;
60        const char *source = luaL_checklstring(L, 1, &sourcesize);
61        size_t targetsize = luaL_checkinteger(L, 2);
62        if (source && targetsize > 0) {
63            luaL_Buffer buffer;
64            char *target = luaL_buffinitsize(L, &buffer, targetsize);
65            int result = lzolib_state.lzo1x_decompress_safe(source, sourcesize, target, &targetsize, NULL);
66            if (result == LZO_E_OK) {
67                luaL_pushresultsize(&buffer, targetsize);
68            } else {
69                lua_pushnil(L);
70            }
71        } else {
72            lua_pushnil(L);
73        }
74        return 1;
75    } else {
76        return 0;
77    }
78}
79
80static int lzolib_initialize(lua_State *L)
81{
82    if (! lzolib_state.initialized) {
83        const char *filename = lua_tostring(L, 1);
84        if (filename) {
85
86            lmt_library lib = lmt_library_load(filename);
87
88            lzolib_state.lzo1x_1_compress      = lmt_library_find(lib, "lzo1x_1_compress");
89            lzolib_state.lzo1x_decompress_safe = lmt_library_find(lib, "lzo1x_decompress_safe");
90
91            lzolib_state.initialized = lmt_library_okay(lib);
92        }
93    }
94    lua_pushboolean(L, lzolib_state.initialized);
95    return 1;
96}
97
98static struct luaL_Reg lzolib_function_list[] = {
99    { "initialize",     lzolib_initialize     },
100    { "compress",       lzolib_compress       },
101    { "decompresssize", lzolib_decompresssize },
102    { NULL,             NULL                  },
103};
104
105int luaopen_lzo(lua_State * L)
106{
107    lmt_library_register(L, "lzo", lzolib_function_list);
108    return 0;
109}
110