lmtzstd.c /size: 4160 b    last modification: 2024-01-16 10:22
1/*
2    See license.txt in the root of this project.
3*/
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 /* int         (*ZSTD_minCLevel)               (void);        */
20 /* int         (*ZSTD_maxCLevel)               (void);        */
21 /* unsigned    (*ZSTD_isError)                 (size_t code); */
22 /* const char *(*ZSTD_getErrorName)            (size_t code); */
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 /* .ZSTD_minCLevel           = NULL, */
36 /* .ZSTD_maxCLevel           = NULL, */
37 /* .ZSTD_isError             = NULL, */
38 /* .ZSTD_getErrorName        = NULL, */
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         /* zstdlib_state.ZSTD_minCLevel           = lmt_library_find(lib, "ZSTD_minCLevel"); */
96         /* zstdlib_state.ZSTD_maxCLevel           = lmt_library_find(lib, "ZSTD_maxCLevel"); */
97         /* zstdlib_state.ZSTD_isError             = lmt_library_find(lib, "ZSTD_isError"); */
98         /* zstdlib_state.ZSTD_getErrorName        = lmt_library_find(lib, "ZSTD_getErrorName"); */
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