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