summaryrefslogtreecommitdiff
path: root/source/luametatex/source/luaoptional/lmtlzo.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/luametatex/source/luaoptional/lmtlzo.c')
-rw-r--r--source/luametatex/source/luaoptional/lmtlzo.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/source/luametatex/source/luaoptional/lmtlzo.c b/source/luametatex/source/luaoptional/lmtlzo.c
new file mode 100644
index 000000000..766e824ca
--- /dev/null
+++ b/source/luametatex/source/luaoptional/lmtlzo.c
@@ -0,0 +1,108 @@
+/*
+ See license.txt in the root of this project.
+*/
+
+# include <stdlib.h>
+
+# include "luametatex.h"
+
+# define lzo_output_length(n) (n + n / 16 + 64 + 64) /* we add 64 instead of 3 */
+
+# define LZO_E_OK 0
+
+typedef struct lzolib_state_info {
+
+ int initialized;
+ int padding;
+
+ int (*lzo1x_1_compress) (const char *source, size_t sourcesize, char *target, size_t *targetsize, void *wrkmem);
+ int (*lzo1x_decompress_safe) (const char *source, size_t sourcesize, char *target, size_t *targetsize, void *wrkmem);
+
+} lzolib_state_info;
+
+static lzolib_state_info lzolib_state = {
+
+ .initialized = 0,
+ .padding = 0,
+
+ .lzo1x_1_compress = NULL,
+ .lzo1x_decompress_safe = NULL,
+
+};
+
+static int lzolib_compress(lua_State *L)
+{
+ if (lzolib_state.initialized) {
+ char *wrkmem = lmt_memory_malloc(16384 + 32); /* we some plenty of slack, normally 2 seemss enough */
+ size_t sourcesize = 0;
+ const char *source = luaL_checklstring(L, 1, &sourcesize);
+ luaL_Buffer buffer;
+ size_t targetsize = lzo_output_length(sourcesize);
+ char *target = luaL_buffinitsize(L, &buffer, targetsize);
+ int result = lzolib_state.lzo1x_1_compress(source, sourcesize, target, &targetsize, wrkmem);
+ if (result == LZO_E_OK) {
+ luaL_pushresultsize(&buffer, targetsize);
+ } else {
+ lua_pushnil(L);
+ }
+ lmt_memory_free(wrkmem);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int lzolib_decompresssize(lua_State *L)
+{
+ if (lzolib_state.initialized) {
+ size_t sourcesize = 0;
+ const char *source = luaL_checklstring(L, 1, &sourcesize);
+ size_t targetsize = luaL_checkinteger(L, 2);
+ if (source && targetsize > 0) {
+ luaL_Buffer buffer;
+ char *target = luaL_buffinitsize(L, &buffer, targetsize);
+ int result = lzolib_state.lzo1x_decompress_safe(source, sourcesize, target, &targetsize, NULL);
+ if (result == LZO_E_OK) {
+ luaL_pushresultsize(&buffer, targetsize);
+ } else {
+ lua_pushnil(L);
+ }
+ } else {
+ lua_pushnil(L);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int lzolib_initialize(lua_State *L)
+{
+ if (! lzolib_state.initialized) {
+ const char *filename = lua_tostring(L, 1);
+ if (filename) {
+
+ lmt_library lib = lmt_library_load(filename);
+
+ lzolib_state.lzo1x_1_compress = lmt_library_find(lib, "lzo1x_1_compress");
+ lzolib_state.lzo1x_decompress_safe = lmt_library_find(lib, "lzo1x_decompress_safe");
+
+ lzolib_state.initialized = lmt_library_okay(lib);
+ }
+ }
+ lua_pushboolean(L, lzolib_state.initialized);
+ return 1;
+}
+
+static struct luaL_Reg lzolib_function_list[] = {
+ { "initialize", lzolib_initialize },
+ { "compress", lzolib_compress },
+ { "decompresssize", lzolib_decompresssize },
+ { NULL, NULL },
+};
+
+int luaopen_lzo(lua_State * L)
+{
+ lmt_library_register(L, "lzo", lzolib_function_list);
+ return 0;
+}