lua-zlib-1.4/0000775000175000017500000000000015126331021012407 5ustar sergeisergeilua-zlib-1.4/.luacheckrc0000664000175000017500000000024115126331021014511 0ustar sergeisergeistd = "max" include_files = { "**/*.lua", ".luacheckrc" } exclude_files = { ".install", ".lua", ".luarocks", "lua_modules" } max_line_length = false lua-zlib-1.4/CMakeLists.txt0000664000175000017500000000377515126331021015163 0ustar sergeisergei# Copyright (C) 2007-2009 LuaDist. # Submitted by David Manura # Redistribution and use of this file is allowed according to the # terms of the MIT license. # For details see the COPYRIGHT file distributed with LuaDist. # Please note that the package source code is licensed under its own # license. PROJECT(lua-zlib C) CMAKE_MINIMUM_REQUIRED (VERSION 2.6) option(USE_LUA "Use Lua (also called 'C' Lua) includes (default)" ON) option(USE_LUAJIT "Use LuaJIT includes instead of 'C' Lua ones (recommended, if you're using LuaJIT, but disabled by default)") set(USE_LUA_VERSION 5.1 CACHE STRING "Set the Lua version to use (default: 5.1)") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") if(USE_LUAJIT) # Find luajit find_package(LuaJIT REQUIRED) set(USE_LUA OFF) # / Find lua endif() if(USE_LUA) # Find lua find_package(Lua ${USE_LUA_VERSION} EXACT REQUIRED) # / Find lua endif() # Basic configurations SET(INSTALL_CMOD share/lua/cmod CACHE PATH "Directory to install Lua binary modules (configure lua via LUA_CPATH)") # / configs # Find zlib FIND_PACKAGE(ZLIB REQUIRED) # / Find zlib # Define how to build zlib.so: INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS} ${LUA_INCLUDE_DIR}) ADD_LIBRARY(cmod_zlib MODULE lua_zlib.c zlib.def) SET_TARGET_PROPERTIES(cmod_zlib PROPERTIES PREFIX "") SET_TARGET_PROPERTIES(cmod_zlib PROPERTIES OUTPUT_NAME zlib) TARGET_LINK_LIBRARIES(cmod_zlib ${ZLIB_LIBRARIES}) # / build zlib.so # Define how to test zlib.so: INCLUDE(CTest) SET(LUA_BIN "lua${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}") FIND_PROGRAM(LUA NAMES ${LUA_BIN} lua luajit lua.bat) ADD_TEST(basic ${LUA} ${CMAKE_CURRENT_SOURCE_DIR}/test.lua ${CMAKE_CURRENT_SOURCE_DIR}/ ${CMAKE_CURRENT_BINARY_DIR}/) SET_TESTS_PROPERTIES(basic PROPERTIES FAIL_REGULAR_EXPRESSION "not ok") # / test zlib.so # Where to install stuff INSTALL (TARGETS cmod_zlib DESTINATION ${INSTALL_CMOD}) # / Where to install. lua-zlib-1.4/tom_macwright.gz0000664000175000017500000000025015126331021015612 0ustar sergeisergeix[ 0E*fIg(NL#m[\scy*=&N:'I1Yi[pzU R?0JzQꁭ%Iw cǩ)˘lbgФ!ሌv򧮮K EF}Hlua-zlib-1.4/lua_zlib.c0000664000175000017500000011363315126331021014363 0ustar sergeisergei#include #include #include #include #include #include /* * ** compatibility with Lua 5.2 * */ #if (LUA_VERSION_NUM >= 502) #undef luaL_register #define luaL_register(L,n,f) \ { if ((n) == NULL) luaL_setfuncs(L,f,0); else luaL_newlib(L,f); } #endif #if (LUA_VERSION_NUM >= 503) #undef luaL_optint #define luaL_optint(L,n,d) ((int)luaL_optinteger(L,(n),(d))) #endif #ifdef LZLIB_COMPAT /**************** lzlib compatibility **********************************/ /* Taken from https://raw.githubusercontent.com/LuaDist/lzlib/93b88e931ffa7cd0a52a972b6b26d37628f479f3/lzlib.c */ /************************************************************************ * Author : Tiago Dionizio * * Library : lzlib - Lua 5 interface to access zlib library functions * * * * Permission is hereby granted, free of charge, to any person obtaining * * a copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to * * the following conditions: * * * * The above copyright notice and this permission notice shall be * * included in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.* * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ************************************************************************/ /* ** ========================================================================= ** compile time options which determine available functionality ** ========================================================================= */ /* TODO - also call flush on table/userdata when flush function is detected - remove io_cb check inflate_block if condition - only set eos when ZSTREAM_END is reached - check for stream errors to close stream when really needed */ /* ** ========================================================================= ** zlib stream metamethods ** ========================================================================= */ #define ZSTREAMMETA "zlib:zstream" #define LZ_ANY -1 #define LZ_NONE 0 #define LZ_DEFLATE 1 #define LZ_INFLATE 2 #if 0 #define LZ_BUFFER_SIZE LUAL_BUFFERSIZE #else #define LZ_BUFFER_SIZE 8192 #endif typedef struct { /* zlib structures */ z_stream zstream; /* stream state. LZ_DEFLATE | LZ_INFLATE */ int state; int error; int peek; int eos; /* user callback source for reading/writing */ int io_cb; /* input buffer */ int i_buffer_ref; size_t i_buffer_pos; size_t i_buffer_len; const char *i_buffer; /* output buffer */ size_t o_buffer_len; size_t o_buffer_max; char o_buffer[LZ_BUFFER_SIZE]; /* dictionary */ const Bytef *dictionary; size_t dictionary_len; } lz_stream; /* forward declarations */ static int lzstream_docompress(lua_State *L, lz_stream *s, int from, int to, int flush); static lz_stream *lzstream_new(lua_State *L, int src) { lz_stream *s = (lz_stream*)lua_newuserdata(L, sizeof(lz_stream)); luaL_getmetatable(L, ZSTREAMMETA); lua_setmetatable(L, -2); /* set metatable */ s->state = LZ_NONE; s->error = Z_OK; s->eos = 0; s->io_cb = LUA_REFNIL; s->i_buffer = NULL; s->i_buffer_ref = LUA_REFNIL; s->i_buffer_pos = 0; s->i_buffer_len = 0; s->peek = 0; s->o_buffer_len = 0; s->o_buffer_max = sizeof(s->o_buffer) / sizeof(s->o_buffer[0]); s->zstream.zalloc = Z_NULL; s->zstream.zfree = Z_NULL; /* prepare source */ if (lua_isstring(L, src)) { lua_pushvalue(L, src); s->i_buffer_ref = luaL_ref(L, LUA_REGISTRYINDEX); s->i_buffer = lua_tolstring(L, src, &s->i_buffer_len); } else { /* table | function | userdata */ lua_pushvalue(L, src); s->io_cb = luaL_ref(L, LUA_REGISTRYINDEX); } return s; } static void lzstream_cleanup(lua_State *L, lz_stream *s) { if (s && s->state != LZ_NONE) { if (s->state == LZ_INFLATE) { inflateEnd(&s->zstream); } if (s->state == LZ_DEFLATE) { deflateEnd(&s->zstream); } luaL_unref(L, LUA_REGISTRYINDEX, s->io_cb); luaL_unref(L, LUA_REGISTRYINDEX, s->i_buffer_ref); s->state = LZ_NONE; } } /* ====================================================================== */ static lz_stream *lzstream_get(lua_State *L, int index) { lz_stream *s = (lz_stream*)luaL_checkudata(L, index, ZSTREAMMETA); if (s == NULL) luaL_argerror(L, index, "bad zlib stream"); return s; } static lz_stream *lzstream_check(lua_State *L, int index, int state) { lz_stream *s = lzstream_get(L, index); if ((state != LZ_ANY && s->state != state) || s->state == LZ_NONE) { luaL_argerror(L, index, "attempt to use invalid zlib stream"); } return s; } /* ====================================================================== */ static int lzstream_tostring(lua_State *L) { lz_stream *s = (lz_stream*)luaL_checkudata(L, 1, ZSTREAMMETA); if (s == NULL) luaL_argerror(L, 1, "bad zlib stream"); if (s->state == LZ_NONE) { lua_pushstring(L, "zlib stream (closed)"); } else if (s->state == LZ_DEFLATE) { lua_pushfstring(L, "zlib deflate stream (%p)", (void*)s); } else if (s->state == LZ_INFLATE) { lua_pushfstring(L, "zlib inflate stream (%p)", (void*)s); } else { lua_pushfstring(L, "%p", (void*)s); } return 1; } /* ====================================================================== */ static int lzstream_gc(lua_State *L) { lz_stream *s = lzstream_get(L, 1); lzstream_cleanup(L, s); return 0; } /* ====================================================================== */ static int lzstream_close(lua_State *L) { lz_stream *s = lzstream_get(L, 1); if (s->state == LZ_DEFLATE) { lua_settop(L, 0); lua_pushliteral(L, ""); return lzstream_docompress(L, s, 1, 1, Z_FINISH); } lzstream_cleanup(L, s); lua_pushboolean(L, 1); return 1; } /* ====================================================================== */ static int lzstream_adler(lua_State *L) { lz_stream *s = lzstream_check(L, 1, LZ_ANY); lua_pushnumber(L, s->zstream.adler); return 1; } /* ====================================================================== */ /* zlib.deflate( sink: function | { write: function [, close: function, flush: function] }, compression level, [Z_DEFAILT_COMPRESSION] method, [Z_DEFLATED] windowBits, [15] memLevel, [8] strategy, [Z_DEFAULT_STRATEGY] dictionary: [""] ) */ static int lzlib_deflate(lua_State *L) { int level, method, windowBits, memLevel, strategy; lz_stream *s; const char *dictionary; size_t dictionary_len; if (lua_istable(L, 1) || lua_isuserdata(L, 1)) { /* is there a :write function? */ lua_getfield(L, 1, "write"); if (!lua_isfunction(L, -1)) { luaL_argerror(L, 1, "output parameter does not provide :write function"); } lua_pop(L, 1); } else if (!lua_isfunction(L, 1)) { luaL_argerror(L, 1, "output parameter must be a function, table or userdata value"); } level = (int) luaL_optinteger(L, 2, Z_DEFAULT_COMPRESSION); method = (int) luaL_optinteger(L, 3, Z_DEFLATED); windowBits = (int) luaL_optinteger(L, 4, 15); memLevel = (int) luaL_optinteger(L, 5, 8); strategy = (int) luaL_optinteger(L, 6, Z_DEFAULT_STRATEGY); dictionary = luaL_optlstring(L, 7, NULL, &dictionary_len); s = lzstream_new(L, 1); if (deflateInit2(&s->zstream, level, method, windowBits, memLevel, strategy) != Z_OK) { lua_pushliteral(L, "call to deflateInit2 failed"); lua_error(L); } if (dictionary) { if (deflateSetDictionary(&s->zstream, (const Bytef *) dictionary, dictionary_len) != Z_OK) { lua_pushliteral(L, "call to deflateSetDictionnary failed"); lua_error(L); } } s->state = LZ_DEFLATE; return 1; } /* zlib.inflate( source: string | function | { read: function, close: function }, windowBits: number, [15] dictionary: [""] ) */ static int lzlib_inflate(lua_State *L) { int windowBits; lz_stream *s; int have_peek = 0; const char *dictionary; size_t dictionary_len; if (lua_istable(L, 1) || lua_isuserdata(L, 1)) { /* is there a :read function? */ lua_getfield(L, 1, "read"); if (!lua_isfunction(L, -1)) { luaL_argerror(L, 1, "input parameter does not provide :read function"); } lua_pop(L, 1); /* check for peek function */ lua_getfield(L, 1, "peek"); have_peek = lua_isfunction(L, -1); lua_pop(L, 1); } else if (!lua_isstring(L, 1) && !lua_isfunction(L, 1)) { luaL_argerror(L, 1, "input parameter must be a string, function, table or userdata value"); } windowBits = (int) luaL_optinteger(L, 2, 15); dictionary = luaL_optlstring(L, 3, NULL, &dictionary_len); s = lzstream_new(L, 1); if (windowBits > 0 && windowBits < 16) { windowBits |= 32; } if (inflateInit2(&s->zstream, windowBits) != Z_OK) { lua_pushliteral(L, "call to inflateInit2 failed"); lua_error(L); } if (dictionary) { s->dictionary = (const Bytef *) dictionary; s->dictionary_len = dictionary_len; } s->peek = have_peek; s->state = LZ_INFLATE; return 1; } /* ====================================================================== */ static int lz_pushresult (lua_State *L, lz_stream *s) { if (s->error == Z_OK) { lua_pushboolean(L, 1); return 1; } else { lua_pushnil(L); lua_pushstring(L, zError(s->error)); lua_pushinteger(L, s->error); return 3; } } /* Get block to process: - top of stack gets */ static const char* lzstream_fetch_block(lua_State *L, lz_stream *s, int hint) { if (s->i_buffer_pos >= s->i_buffer_len) { luaL_unref(L, LUA_REGISTRYINDEX, s->i_buffer_ref); s->i_buffer_ref = LUA_NOREF; s->i_buffer = NULL; lua_rawgeti(L, LUA_REGISTRYINDEX, s->io_cb); if (!lua_isnil(L, -1)) { if (lua_isfunction(L, -1)) { lua_pushinteger(L, hint); lua_call(L, 1, 1); } else { lua_getfield(L, -1, (s->peek ? "peek" : "read")); lua_insert(L, -2); lua_pushinteger(L, hint); lua_call(L, 2, 1); } if (lua_isstring(L, -1)) { s->i_buffer_pos = 0; s->i_buffer = lua_tolstring(L, -1, &s->i_buffer_len); if (s->i_buffer_len > 0) { s->i_buffer_ref = luaL_ref(L, LUA_REGISTRYINDEX); } else { lua_pop(L, 1); } } else if (lua_isnil(L, -1)) { lua_pop(L, 1); } else { lua_pushliteral(L, "deflate callback must return string or nil"); lua_error(L); } } else { lua_pop(L, 1); } } return s->i_buffer; } static int lzstream_inflate_block(lua_State *L, lz_stream *s) { if (lzstream_fetch_block(L, s, LZ_BUFFER_SIZE) || !s->eos) { int r; if (s->i_buffer_len == s->i_buffer_pos) { s->zstream.next_in = NULL; s->zstream.avail_in = 0; } else { s->zstream.next_in = (unsigned char*)(s->i_buffer + s->i_buffer_pos); s->zstream.avail_in = s->i_buffer_len - s->i_buffer_pos; } s->zstream.next_out = (unsigned char*)s->o_buffer + s->o_buffer_len; s->zstream.avail_out = s->o_buffer_max - s->o_buffer_len; /* munch some more */ r = inflate(&s->zstream, Z_SYNC_FLUSH); if (r == Z_NEED_DICT) { if (s->dictionary == NULL) { lua_pushliteral(L, "no inflate dictionary provided"); lua_error(L); } if (inflateSetDictionary(&s->zstream, s->dictionary, s->dictionary_len) != Z_OK) { lua_pushliteral(L, "call to inflateSetDictionnary failed"); lua_error(L); } r = inflate(&s->zstream, Z_SYNC_FLUSH); } if (r != Z_OK && r != Z_STREAM_END && r != Z_BUF_ERROR) { lzstream_cleanup(L, s); s->error = r; #if 1 lua_pushfstring(L, "failed to decompress [%d]", r); lua_error(L); #endif } if (r == Z_STREAM_END) { luaL_unref(L, LUA_REGISTRYINDEX, s->i_buffer_ref); s->i_buffer_ref = LUA_NOREF; s->i_buffer = NULL; s->eos = 1; } /* number of processed bytes */ if (s->peek) { size_t processed = s->i_buffer_len - s->i_buffer_pos - s->zstream.avail_in; lua_rawgeti(L, LUA_REGISTRYINDEX, s->io_cb); lua_getfield(L, -1, "read"); lua_insert(L, -2); lua_pushinteger(L, processed); lua_call(L, 2, 0); } s->i_buffer_pos = s->i_buffer_len - s->zstream.avail_in; s->o_buffer_len = s->o_buffer_max - s->zstream.avail_out; } return s->o_buffer_len; } /* ** Remove n bytes from the output buffer. */ static void lzstream_remove(lz_stream *s, size_t n) { memmove(s->o_buffer, s->o_buffer + n, s->o_buffer_len - n); s->o_buffer_len -= n; } /* ** Copy at most n bytes to buffer b and remove them from the ** output stream buffer. */ static int lzstream_flush_buffer(lua_State *L, lz_stream *s, size_t n, luaL_Buffer *b) { /* check output */ if (n > s->o_buffer_len) { n = s->o_buffer_len; } if (n > 0) { lua_pushlstring(L, s->o_buffer, n); luaL_addvalue(b); lzstream_remove(s, n); } return n; } /* z:read( {number | '*l' | '*a'}* ) */ static int lz_test_eof(lua_State *L, lz_stream *s) { lua_pushlstring(L, NULL, 0); if (s->o_buffer_len > 0) { return 1; } else if (s->eos) { return 0; } else { return lzstream_inflate_block(L, s); } } static int lz_read_line(lua_State *L, lz_stream *s) { luaL_Buffer b; size_t l = 0, n; luaL_buffinit(L, &b); if (s->o_buffer_len > 0 || !s->eos) do { char *p = s->o_buffer; size_t len = s->o_buffer_len; /* find newline in output buffer */ for (n = 0; n < len; ++n, ++p) { if (*p == '\n' || *p == '\r') { int eat_nl = *p == '\r'; luaL_addlstring(&b, s->o_buffer, n); lzstream_remove(s, n+1); l += n; if (eat_nl && lzstream_inflate_block(L, s)) { if (s->o_buffer_len > 0 && *s->o_buffer == '\n') { lzstream_remove(s, 1); } } luaL_pushresult(&b); return 1; } } if (len > 0) { luaL_addlstring(&b, s->o_buffer, len); lzstream_remove(s, len); l += len; } } while (lzstream_inflate_block(L, s)); luaL_pushresult(&b); return l > 0 || !s->eos || s->o_buffer_len > 0; } static int lz_read_chars(lua_State *L, lz_stream *s, size_t n) { size_t len; luaL_Buffer b; luaL_buffinit(L, &b); if (s->o_buffer_len > 0 || !s->eos) do { size_t rlen = lzstream_flush_buffer(L, s, n, &b); n -= rlen; } while (n > 0 && lzstream_inflate_block(L, s)); luaL_pushresult(&b); lua_tolstring(L, -1, &len); return n == 0 || len > 0; } static int lzstream_decompress(lua_State *L) { lz_stream *s = lzstream_check(L, 1, LZ_INFLATE); int nargs = lua_gettop(L) - 1; int success; int n; if (nargs == 0) { /* no arguments? */ success = lz_read_line(L, s); n = 3; /* to return 1 result */ } else { /* ensure stack space for all results and for auxlib's buffer */ luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); success = 1; for (n = 2; nargs-- && success; n++) { if (lua_type(L, n) == LUA_TNUMBER) { size_t l = (size_t)lua_tointeger(L, n); success = (l == 0) ? lz_test_eof(L, s) : lz_read_chars(L, s, l); } else { const char *p = lua_tostring(L, n); luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); switch (p[1]) { case 'l': /* line */ success = lz_read_line(L, s); break; case 'a': /* file */ lz_read_chars(L, s, ~((size_t)0)); /* read MAX_SIZE_T chars */ success = 1; /* always success */ break; default: return luaL_argerror(L, n, "invalid format"); } } } } if (s->error != Z_OK) { return lz_pushresult(L, s); } if (!success) { lua_pop(L, 1); /* remove last result */ lua_pushnil(L); /* push nil instead */ } return n - 2; } static int lzstream_readline(lua_State *L) { lz_stream *s; int success; s = lzstream_check(L, lua_upvalueindex(1), LZ_INFLATE); success = lz_read_line(L, s); if (s->error != Z_OK) { return lz_pushresult(L, s); } if (success) { return 1; } else { /* EOF */ return 0; } } static int lzstream_lines(lua_State *L) { lzstream_check(L, 1, LZ_INFLATE); lua_settop(L, 1); lua_pushcclosure(L, lzstream_readline, 1); return 1; } /* ====================================================================== */ static int lzstream_docompress(lua_State *L, lz_stream *s, int from, int to, int flush) { int r, arg; int self = 0; size_t b_size = s->o_buffer_max; unsigned char *b = (unsigned char *)s->o_buffer; /* number of processed bytes */ lua_rawgeti(L, LUA_REGISTRYINDEX, s->io_cb); if (!lua_isfunction(L, -1)) { self = 1; lua_getfield(L, -1, "write"); } for (arg = from; arg <= to; arg++) { s->zstream.next_in = (unsigned char*)luaL_checklstring(L, arg, (size_t*)&s->zstream.avail_in); do { s->zstream.next_out = b; s->zstream.avail_out = b_size; /* bake some more */ r = deflate(&s->zstream, flush); if (r != Z_OK && r != Z_STREAM_END && r != Z_BUF_ERROR) { lzstream_cleanup(L, s); lua_pushboolean(L, 0); lua_pushfstring(L, "failed to compress [%d]", r); return 2; } if (s->zstream.avail_out != b_size) { /* write output */ lua_pushvalue(L, -1); /* function */ if (self) lua_pushvalue(L, -3); /* self */ lua_pushlstring(L, (char*)b, b_size - s->zstream.avail_out); /* data */ lua_call(L, (self ? 2 : 1), 0); } if (r == Z_STREAM_END) { lzstream_cleanup(L, s); break; } /* process all input */ } while (s->zstream.avail_in > 0 || s->zstream.avail_out == 0); } lua_pushboolean(L, 1); return 1; } static int lzstream_compress(lua_State *L) { lz_stream *s = lzstream_check(L, 1, LZ_DEFLATE); return lzstream_docompress(L, s, 2, lua_gettop(L), Z_NO_FLUSH); } /* ====================================================================== */ static int lzstream_flush(lua_State *L) { static int flush_values[] = { Z_SYNC_FLUSH, Z_FULL_FLUSH, Z_FINISH }; static const char *const flush_opts[] = { "sync", "full", "finish" }; lz_stream *s = lzstream_check(L, 1, LZ_DEFLATE); int flush = luaL_checkoption(L, 2, flush_opts[0], flush_opts); lua_settop(L, 0); lua_pushliteral(L, ""); return lzstream_docompress(L, s, 1, 1, flush_values[flush]); } /* ====================================================================== */ static int lzlib_compress(lua_State *L) { size_t avail_in; const char *next_in = luaL_checklstring(L, 1, &avail_in); int level = (int) luaL_optinteger(L, 2, Z_DEFAULT_COMPRESSION); int method = (int) luaL_optinteger(L, 3, Z_DEFLATED); int windowBits = (int) luaL_optinteger(L, 4, 15); int memLevel = (int) luaL_optinteger(L, 5, 8); int strategy = (int) luaL_optinteger(L, 6, Z_DEFAULT_STRATEGY); int ret; luaL_Buffer b; z_stream zs; luaL_buffinit(L, &b); zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.next_out = Z_NULL; zs.avail_out = 0; zs.next_in = Z_NULL; zs.avail_in = 0; ret = deflateInit2(&zs, level, method, windowBits, memLevel, strategy); if (ret != Z_OK) { lua_pushnil(L); lua_pushnumber(L, ret); return 2; } zs.next_in = (unsigned char*)next_in; zs.avail_in = avail_in; for(;;) { zs.next_out = (unsigned char*)luaL_prepbuffer(&b); zs.avail_out = LUAL_BUFFERSIZE; /* munch some more */ ret = deflate(&zs, Z_FINISH); /* push gathered data */ luaL_addsize(&b, LUAL_BUFFERSIZE - zs.avail_out); /* done processing? */ if (ret == Z_STREAM_END) break; /* error condition? */ if (ret != Z_OK) break; } /* cleanup */ deflateEnd(&zs); luaL_pushresult(&b); lua_pushnumber(L, ret); return 2; } /* ====================================================================== */ static int lzlib_decompress(lua_State *L) { size_t avail_in; const char *next_in = luaL_checklstring(L, 1, &avail_in); int windowBits = (int) luaL_optinteger(L, 2, 15); int ret; luaL_Buffer b; z_stream zs; luaL_buffinit(L, &b); zs.zalloc = Z_NULL; zs.zfree = Z_NULL; zs.next_out = Z_NULL; zs.avail_out = 0; zs.next_in = Z_NULL; zs.avail_in = 0; ret = inflateInit2(&zs, windowBits); if (ret != Z_OK) { lua_pushliteral(L, "failed to initialize zstream structures"); lua_error(L); } zs.next_in = (unsigned char*)next_in; zs.avail_in = avail_in; for (;;) { zs.next_out = (unsigned char*)luaL_prepbuffer(&b); zs.avail_out = LUAL_BUFFERSIZE; /* bake some more */ ret = inflate(&zs, Z_FINISH); /* push gathered data */ luaL_addsize(&b, LUAL_BUFFERSIZE - zs.avail_out); /* done processing? */ if (ret == Z_STREAM_END) break; if (ret != Z_OK && ret != Z_BUF_ERROR) { /* cleanup */ inflateEnd(&zs); lua_pushliteral(L, "failed to process zlib stream"); lua_error(L); } } /* cleanup */ inflateEnd(&zs); luaL_pushresult(&b); return 1; } #endif /**********************************************************************/ #define DEF_MEM_LEVEL 8 typedef uLong (*checksum_t) (uLong crc, const Bytef *buf, uInt len); typedef uLong (*checksum_combine_t)(uLong crc1, uLong crc2, z_off_t len2); static int lz_deflate(lua_State *L); static int lz_deflate_delete(lua_State *L); static int lz_inflate_delete(lua_State *L); static int lz_inflate(lua_State *L); static int lz_checksum(lua_State *L); static int lz_checksum_new(lua_State *L, checksum_t checksum, checksum_combine_t combine); static int lz_adler32(lua_State *L); static int lz_crc32(lua_State *L); static int lz_version(lua_State *L) { const char* version = zlibVersion(); int count = strlen(version) + 1; char* cur = (char*)memcpy(lua_newuserdata(L, count), version, count); count = 0; while ( *cur ) { char* begin = cur; /* Find all digits: */ while ( isdigit(*cur) ) cur++; if ( begin != cur ) { int is_end = *cur == '\0'; *cur = '\0'; lua_pushnumber(L, atoi(begin)); count++; if ( is_end ) break; cur++; } while ( *cur && ! isdigit(*cur) ) cur++; } return count; } static int lz_assert(lua_State *L, int result, const z_stream* stream, const char* file, int line) { /* Both of these are "normal" return codes: */ if ( result == Z_OK || result == Z_STREAM_END ) return result; switch ( result ) { case Z_NEED_DICT: lua_pushfstring(L, "RequiresDictionary: input stream requires a dictionary to be deflated (%s) at %s line %d", stream->msg, file, line); break; case Z_STREAM_ERROR: lua_pushfstring(L, "InternalError: inconsistent internal zlib stream (%s) at %s line %d", stream->msg, file, line); break; case Z_DATA_ERROR: lua_pushfstring(L, "InvalidInput: input string does not conform to zlib format or checksum failed at %s line %d", file, line); break; case Z_MEM_ERROR: lua_pushfstring(L, "OutOfMemory: not enough memory (%s) at %s line %d", stream->msg, file, line); break; case Z_BUF_ERROR: lua_pushfstring(L, "InternalError: no progress possible (%s) at %s line %d", stream->msg, file, line); break; case Z_VERSION_ERROR: lua_pushfstring(L, "IncompatibleLibrary: built with version %s, but dynamically linked with version %s (%s) at %s line %d", ZLIB_VERSION, zlibVersion(), stream->msg, file, line); break; default: lua_pushfstring(L, "ZLibError: unknown code %d (%s) at %s line %d", result, stream->msg, file, line); } lua_error(L); return result; } /** * @upvalue z_stream - Memory for the z_stream. * @upvalue remainder - Any remainder from the last deflate call. * * @param string - "print" to deflate stream. * @param int - flush output buffer? Z_SYNC_FLUSH, Z_FULL_FLUSH, or Z_FINISH. * * if no params, terminates the stream (as if we got empty string and Z_FINISH). */ static int lz_filter_impl(lua_State *L, int (*filter)(z_streamp, int), int (*end)(z_streamp), const char* name) { int flush = Z_NO_FLUSH, result; z_stream* stream; luaL_Buffer buff; size_t avail_in; if ( filter == deflate ) { const char *const opts[] = { "none", "sync", "full", "finish", NULL }; flush = luaL_checkoption(L, 2, opts[0], opts); if ( flush ) flush++; /* Z_NO_FLUSH(0) Z_SYNC_FLUSH(2), Z_FULL_FLUSH(3), Z_FINISH (4) */ /* No arguments or nil, we are terminating the stream: */ if ( lua_gettop(L) == 0 || lua_isnil(L, 1) ) { flush = Z_FINISH; } } stream = (z_stream*)lua_touserdata(L, lua_upvalueindex(1)); if ( stream == NULL ) { if ( lua_gettop(L) >= 1 && lua_isstring(L, 1) ) { lua_pushfstring(L, "IllegalState: calling %s function when stream was previously closed", name); lua_error(L); } lua_pushstring(L, ""); lua_pushboolean(L, 1); return 2; /* Ignore duplicate calls to "close". */ } luaL_buffinit(L, &buff); if ( lua_gettop(L) > 1 ) lua_pushvalue(L, 1); if ( lua_isstring(L, lua_upvalueindex(2)) ) { lua_pushvalue(L, lua_upvalueindex(2)); if ( lua_gettop(L) > 1 && lua_isstring(L, -2) ) { lua_concat(L, 2); } } /* Do the actual deflate'ing: */ if (lua_gettop(L) > 0) { stream->next_in = (unsigned char*)lua_tolstring(L, -1, &avail_in); } else { stream->next_in = NULL; avail_in = 0; } stream->avail_in = avail_in; if ( ! stream->avail_in && ! flush ) { /* Passed empty string, make it a noop instead of erroring out. */ lua_pushstring(L, ""); lua_pushboolean(L, 0); lua_pushinteger(L, stream->total_in); lua_pushinteger(L, stream->total_out); return 4; } do { stream->next_out = (unsigned char*)luaL_prepbuffer(&buff); stream->avail_out = LUAL_BUFFERSIZE; result = filter(stream, flush); if ( Z_BUF_ERROR != result ) { /* Ignore Z_BUF_ERROR since that just indicates that we * need a larger buffer in order to proceed. Thanks to * Tobias Markmann for finding this bug! */ lz_assert(L, result, stream, __FILE__, __LINE__); } luaL_addsize(&buff, LUAL_BUFFERSIZE - stream->avail_out); } while ( stream->avail_out == 0 ); /* Need to do this before we alter the stack: */ luaL_pushresult(&buff); /* Save remainder in lua_upvalueindex(2): */ if ( NULL != stream->next_in ) { lua_pushlstring(L, (char*)stream->next_in, stream->avail_in); lua_replace(L, lua_upvalueindex(2)); } /* "close" the stream/remove finalizer: */ if ( result == Z_STREAM_END ) { /* Clear-out the metatable so end is not called twice: */ lua_pushnil(L); lua_setmetatable(L, lua_upvalueindex(1)); /* nil the upvalue: */ lua_pushnil(L); lua_replace(L, lua_upvalueindex(1)); /* Close the stream: */ lz_assert(L, end(stream), stream, __FILE__, __LINE__); lua_pushboolean(L, 1); } else { lua_pushboolean(L, 0); } lua_pushinteger(L, stream->total_in); lua_pushinteger(L, stream->total_out); return 4; } static void lz_create_deflate_mt(lua_State *L) { luaL_newmetatable(L, "lz.deflate.meta"); /* {} */ lua_pushcfunction(L, lz_deflate_delete); lua_setfield(L, -2, "__gc"); lua_pop(L, 1); /* */ } static int lz_deflate_new(lua_State *L) { int level; int window_size; int result; #ifdef LZLIB_COMPAT if ( lua_istable(L, 1) || lua_isuserdata(L, 1) || lua_isfunction(L, 1) ) { return lzlib_deflate(L); } #endif level = luaL_optint(L, 1, Z_DEFAULT_COMPRESSION); window_size = luaL_optint(L, 2, MAX_WBITS); /* Allocate the stream: */ z_stream* stream = (z_stream*)lua_newuserdata(L, sizeof(z_stream)); stream->zalloc = Z_NULL; stream->zfree = Z_NULL; result = deflateInit2(stream, level, Z_DEFLATED, window_size, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); lz_assert(L, result, stream, __FILE__, __LINE__); /* Don't allow destructor to execute unless deflateInit2 was successful: */ luaL_getmetatable(L, "lz.deflate.meta"); lua_setmetatable(L, -2); lua_pushnil(L); lua_pushcclosure(L, lz_deflate, 2); return 1; } static int lz_deflate(lua_State *L) { return lz_filter_impl(L, deflate, deflateEnd, "deflate"); } static int lz_deflate_delete(lua_State *L) { z_stream* stream = (z_stream*)lua_touserdata(L, 1); /* Ignore errors. */ deflateEnd(stream); return 0; } static void lz_create_inflate_mt(lua_State *L) { luaL_newmetatable(L, "lz.inflate.meta"); /* {} */ lua_pushcfunction(L, lz_inflate_delete); lua_setfield(L, -2, "__gc"); lua_pop(L, 1); /* */ } static int lz_inflate_new(lua_State *L) { /* Allocate the stream */ z_stream* stream; #ifdef LZLIB_COMPAT int type = lua_type(L, 1); if ( type == LUA_TTABLE || type == LUA_TUSERDATA || type == LUA_TFUNCTION || type == LUA_TSTRING ) { return lzlib_inflate(L); } #endif stream = (z_stream*)lua_newuserdata(L, sizeof(z_stream)); /* By default, we will do gzip header detection w/ max window size */ int window_size = lua_isnumber(L, 1) ? lua_tointeger(L, 1) : MAX_WBITS + 32; stream->zalloc = Z_NULL; stream->zfree = Z_NULL; stream->next_in = Z_NULL; stream->avail_in = 0; lz_assert(L, inflateInit2(stream, window_size), stream, __FILE__, __LINE__); /* Don't allow destructor to execute unless deflateInit was successful: */ luaL_getmetatable(L, "lz.inflate.meta"); lua_setmetatable(L, -2); lua_pushnil(L); lua_pushcclosure(L, lz_inflate, 2); return 1; } static int lz_inflate(lua_State *L) { return lz_filter_impl(L, inflate, inflateEnd, "inflate"); } static int lz_inflate_delete(lua_State *L) { z_stream* stream = (z_stream*)lua_touserdata(L, 1); /* Ignore errors: */ inflateEnd(stream); return 0; } static int lz_checksum(lua_State *L) { if ( lua_gettop(L) <= 0 ) { lua_pushvalue(L, lua_upvalueindex(3)); lua_pushvalue(L, lua_upvalueindex(4)); } else if ( lua_isfunction(L, 1) ) { checksum_combine_t combine = (checksum_combine_t) lua_touserdata(L, lua_upvalueindex(2)); lua_pushvalue(L, 1); lua_call(L, 0, 2); if ( ! lua_isnumber(L, -2) || ! lua_isnumber(L, -1) ) { luaL_argerror(L, 1, "expected function to return two numbers"); } /* Calculate and replace the checksum */ lua_pushnumber(L, combine((uLong)lua_tonumber(L, lua_upvalueindex(3)), (uLong)lua_tonumber(L, -2), (z_off_t)lua_tonumber(L, -1))); lua_pushvalue(L, -1); lua_replace(L, lua_upvalueindex(3)); /* Calculate and replace the length */ lua_pushnumber(L, lua_tonumber(L, lua_upvalueindex(4)) + lua_tonumber(L, -2)); lua_pushvalue(L, -1); lua_replace(L, lua_upvalueindex(4)); } else { const Bytef* str; size_t len; checksum_t checksum = (checksum_t) lua_touserdata(L, lua_upvalueindex(1)); str = (const Bytef*)luaL_checklstring(L, 1, &len); /* Calculate and replace the checksum */ lua_pushnumber(L, checksum((uLong)lua_tonumber(L, lua_upvalueindex(3)), str, len)); lua_pushvalue(L, -1); lua_replace(L, lua_upvalueindex(3)); /* Calculate and replace the length */ lua_pushnumber(L, lua_tonumber(L, lua_upvalueindex(4)) + len); lua_pushvalue(L, -1); lua_replace(L, lua_upvalueindex(4)); } return 2; } static int lz_checksum_new(lua_State *L, checksum_t checksum, checksum_combine_t combine) { lua_pushlightuserdata(L, (void *)checksum); lua_pushlightuserdata(L, (void *)combine); lua_pushnumber(L, checksum(0L, Z_NULL, 0)); lua_pushnumber(L, 0); lua_pushcclosure(L, lz_checksum, 4); return 1; } static int lz_adler32(lua_State *L) { #ifdef LZLIB_COMPAT /* lzlib compat*/ if ( lua_gettop(L) != 0 ) { size_t len; int adler; const unsigned char* buf; if ( lua_isfunction(L, 1) ) { adler = adler32(0L, Z_NULL, 0); } else { adler = (int)luaL_checkinteger(L, 1); } buf = (unsigned char*)luaL_checklstring(L, 2, &len); lua_pushnumber(L, adler32(adler, buf, len)); return 1; } #endif return lz_checksum_new(L, adler32, adler32_combine); } static int lz_crc32(lua_State *L) { #ifdef LZLIB_COMPAT /* lzlib compat*/ if ( lua_gettop(L) != 0 ) { size_t len; int crc; const unsigned char* buf; if ( lua_isfunction(L, 1) ) { crc = crc32(0L, Z_NULL, 0); } else { crc = (int)luaL_checkinteger(L, 1); } buf = (unsigned char*)luaL_checklstring(L, 2, &len); lua_pushnumber(L, crc32(crc, buf, len)); return 1; } #endif return lz_checksum_new(L, crc32, crc32_combine); } static const luaL_Reg zlib_functions[] = { { "deflate", lz_deflate_new }, { "inflate", lz_inflate_new }, { "adler32", lz_adler32 }, { "crc32", lz_crc32 }, #ifdef LZLIB_COMPAT { "compress", lzlib_compress }, { "decompress", lzlib_decompress }, #endif { "version", lz_version }, { NULL, NULL } }; #define SETLITERAL(n,v) (lua_pushliteral(L, n), lua_pushliteral(L, v), lua_settable(L, -3)) #define SETINT(n,v) (lua_pushliteral(L, n), lua_pushinteger(L, v), lua_settable(L, -3)) LUALIB_API int luaopen_zlib(lua_State * const L) { lz_create_deflate_mt(L); lz_create_inflate_mt(L); luaL_register(L, "zlib", zlib_functions); SETINT("BEST_SPEED", Z_BEST_SPEED); SETINT("BEST_COMPRESSION", Z_BEST_COMPRESSION); SETLITERAL("_COPYRIGHT", "Copyright (c) 2009-2016 Brian Maher"); SETLITERAL("_DESCRIPTION", "Simple streaming interface to the zlib library"); SETLITERAL("_VERSION", "lua-zlib $Id: 7680c9e2cb89fde21519c1b81b7ff740bd2ca9e8 $"); /* Expose this to lua so we can do a test: */ SETINT("_TEST_BUFSIZ", LUAL_BUFFERSIZE); /* lzlib compatibility */ #ifdef LZLIB_COMPAT SETINT("NO_COMPRESSION", Z_NO_COMPRESSION); SETINT("DEFAULT_COMPRESSION", Z_DEFAULT_COMPRESSION); SETINT("FILTERED", Z_FILTERED); SETINT("HUFFMAN_ONLY", Z_HUFFMAN_ONLY); SETINT("RLE", Z_RLE); SETINT("FIXED", Z_FIXED); SETINT("DEFAULT_STRATEGY", Z_DEFAULT_STRATEGY); SETINT("MINIMUM_MEMLEVEL", 1); SETINT("MAXIMUM_MEMLEVEL", 9); SETINT("DEFAULT_MEMLEVEL", 8); SETINT("DEFAULT_WINDOWBITS", 15); SETINT("MINIMUM_WINDOWBITS", 8); SETINT("MAXIMUM_WINDOWBITS", 15); SETINT("GZIP_WINDOWBITS", 16); SETINT("RAW_WINDOWBITS", -1); #endif return 1; } lua-zlib-1.4/zlib.def0000664000175000017500000000002515126331021014024 0ustar sergeisergeiEXPORTS luaopen_zlib lua-zlib-1.4/rockspecs/0000775000175000017500000000000015126331021014403 5ustar sergeisergeilua-zlib-1.4/rockspecs/lua-zlib-0.4-1.rockspec0000664000175000017500000000144615126331021020317 0ustar sergeisergeipackage = "lua-zlib" version = "0.4-1" source = { url = "git://github.com/brimworks/lua-zlib.git", tag = "v0.4", } description = { summary = "Simple streaming interface to zlib for Lua.", detailed = [[ Simple streaming interface to zlib for Lua. Consists of two functions: inflate and deflate. Both functions return "stream functions" (takes a buffer of input and returns a buffer of output). This project is hosted on github. ]], homepage = "https://github.com/brimworks/lua-zlib", license = "MIT" } dependencies = { "lua >= 5.1, < 5.3" } external_dependencies = { ZLIB = { header = "zlib.h" } } build = { type = "builtin", modules = { zlib = { sources = { "lua_zlib.c" }; libraries = { "z" }, }; } } lua-zlib-1.4/rockspecs/lua-zlib-0.3-0.rockspec0000664000175000017500000000132415126331021020310 0ustar sergeisergeipackage = "lua-zlib" version = "0.3-0" source = { url = "https://github.com/brimworks/lua-zlib.git" } description = { summary = "Simple streaming interface to zlib for Lua.", detailed = [[ Simple streaming interface to zlib for Lua. Consists of two functions: inflate and deflate. Both functions return "stream functions" (takes a buffer of input and returns a buffer of output). This project is hosted on github. ]], homepage = "https://github.com/brimworks/lua-zlib", license = "MIT" } dependencies = { "lua >= 5.1, < 5.3" } external_dependencies = { ZLIB = { header = "zlib.h" } } build = { type = "builtin", modules = { zlib = "lua_zlib.c" } } lua-zlib-1.4/rockspecs/lua-zlib-1.2-1.rockspec0000664000175000017500000000210115126331021020303 0ustar sergeisergeipackage = "lua-zlib" version = "1.2-1" source = { url = "git://github.com/brimworks/lua-zlib.git", tag = "v1.2", } description = { summary = "Simple streaming interface to zlib for Lua.", detailed = [[ Simple streaming interface to zlib for Lua. Consists of two functions: inflate and deflate. Both functions return "stream functions" (takes a buffer of input and returns a buffer of output). This project is hosted on github. ]], homepage = "https://github.com/brimworks/lua-zlib", license = "MIT" } dependencies = { "lua >= 5.1, <= 5.4" } external_dependencies = { ZLIB = { header = "zlib.h" } } build = { type = "builtin", modules = { zlib = { sources = { "lua_zlib.c" }, libraries = { "z" }, defines = { "LZLIB_COMPAT" }, incdirs = { "$(ZLIB_INCDIR)" }, } }, platforms = { windows = { modules = { zlib = { libraries = { "$(ZLIB_LIBDIR)/zlib" -- Must full path to `"zlib"`, or else will cause the `LINK : fatal error LNK1149` } } } } } } lua-zlib-1.4/rockspecs/lua-zlib-1.1-0.rockspec0000664000175000017500000000210115126331021020301 0ustar sergeisergeipackage = "lua-zlib" version = "1.1-0" source = { url = "git://github.com/brimworks/lua-zlib.git", tag = "v1.1", } description = { summary = "Simple streaming interface to zlib for Lua.", detailed = [[ Simple streaming interface to zlib for Lua. Consists of two functions: inflate and deflate. Both functions return "stream functions" (takes a buffer of input and returns a buffer of output). This project is hosted on github. ]], homepage = "https://github.com/brimworks/lua-zlib", license = "MIT" } dependencies = { "lua >= 5.1, <= 5.3" } external_dependencies = { ZLIB = { header = "zlib.h" } } build = { type = "builtin", modules = { zlib = { sources = { "lua_zlib.c" }, libraries = { "z" }, defines = { "LZLIB_COMPAT" }, incdirs = { "$(ZLIB_INCDIR)" }, } }, platforms = { windows = { modules = { zlib = { libraries = { "$(ZLIB_LIBDIR)/zlib" -- Must full path to `"zlib"`, or else will cause the `LINK : fatal error LNK1149` } } } } } } lua-zlib-1.4/rockspecs/lua-zlib-1.2-0.rockspec0000664000175000017500000000210115126331021020302 0ustar sergeisergeipackage = "lua-zlib" version = "1.2-0" source = { url = "git://github.com/brimworks/lua-zlib.git", tag = "v1.2", } description = { summary = "Simple streaming interface to zlib for Lua.", detailed = [[ Simple streaming interface to zlib for Lua. Consists of two functions: inflate and deflate. Both functions return "stream functions" (takes a buffer of input and returns a buffer of output). This project is hosted on github. ]], homepage = "https://github.com/brimworks/lua-zlib", license = "MIT" } dependencies = { "lua >= 5.1, <= 5.3" } external_dependencies = { ZLIB = { header = "zlib.h" } } build = { type = "builtin", modules = { zlib = { sources = { "lua_zlib.c" }, libraries = { "z" }, defines = { "LZLIB_COMPAT" }, incdirs = { "$(ZLIB_INCDIR)" }, } }, platforms = { windows = { modules = { zlib = { libraries = { "$(ZLIB_LIBDIR)/zlib" -- Must full path to `"zlib"`, or else will cause the `LINK : fatal error LNK1149` } } } } } } lua-zlib-1.4/rockspecs/lua-zlib-0.3-1.rockspec0000664000175000017500000000134415126331021020313 0ustar sergeisergeipackage = "lua-zlib" version = "0.3-1" source = { url = "git://github.com/brimworks/lua-zlib.git", tag = "v0.3", } description = { summary = "Simple streaming interface to zlib for Lua.", detailed = [[ Simple streaming interface to zlib for Lua. Consists of two functions: inflate and deflate. Both functions return "stream functions" (takes a buffer of input and returns a buffer of output). This project is hosted on github. ]], homepage = "https://github.com/brimworks/lua-zlib", license = "MIT" } dependencies = { "lua >= 5.1, < 5.3" } external_dependencies = { ZLIB = { header = "zlib.h" } } build = { type = "builtin", modules = { zlib = "lua_zlib.c" } } lua-zlib-1.4/rockspecs/lua-zlib-1.2-2.rockspec0000664000175000017500000000210715126331021020312 0ustar sergeisergeipackage = "lua-zlib" version = "1.2-2" source = { url = "git+https://github.com/brimworks/lua-zlib.git", tag = "v1.2", } description = { summary = "Simple streaming interface to zlib for Lua.", detailed = [[ Simple streaming interface to zlib for Lua. Consists of two functions: inflate and deflate. Both functions return "stream functions" (takes a buffer of input and returns a buffer of output). This project is hosted on github. ]], homepage = "https://github.com/brimworks/lua-zlib", license = "MIT" } dependencies = { "lua >= 5.1, <= 5.4" } external_dependencies = { ZLIB = { header = "zlib.h" } } build = { type = "builtin", modules = { zlib = { sources = { "lua_zlib.c" }, libraries = { "z" }, defines = { "LZLIB_COMPAT" }, incdirs = { "$(ZLIB_INCDIR)" }, } }, platforms = { windows = { modules = { zlib = { libraries = { "$(ZLIB_LIBDIR)/zlib" -- Must full path to `"zlib"`, or else will cause the `LINK : fatal error LNK1149` } } } } } } lua-zlib-1.4/rockspecs/lua-zlib-1.0-0.rockspec0000664000175000017500000000151615126331021020311 0ustar sergeisergeipackage = "lua-zlib" version = "1.0-0" source = { url = "git://github.com/brimworks/lua-zlib.git", tag = "v1.0", } description = { summary = "Simple streaming interface to zlib for Lua.", detailed = [[ Simple streaming interface to zlib for Lua. Consists of two functions: inflate and deflate. Both functions return "stream functions" (takes a buffer of input and returns a buffer of output). This project is hosted on github. ]], homepage = "https://github.com/brimworks/lua-zlib", license = "MIT" } dependencies = { "lua >= 5.1, <= 5.3" } external_dependencies = { ZLIB = { header = "zlib.h" } } build = { type = "builtin", modules = { zlib = { sources = { "lua_zlib.c" }; libraries = { "z" }, defines = { "LZLIB_COMPAT" }, }; } } lua-zlib-1.4/rockspecs/lua-zlib-0.5-0.rockspec0000664000175000017500000000144715126331021020320 0ustar sergeisergeipackage = "lua-zlib" version = "0.5-0" source = { url = "git://github.com/brimworks/lua-zlib.git", tag = "v0.5", } description = { summary = "Simple streaming interface to zlib for Lua.", detailed = [[ Simple streaming interface to zlib for Lua. Consists of two functions: inflate and deflate. Both functions return "stream functions" (takes a buffer of input and returns a buffer of output). This project is hosted on github. ]], homepage = "https://github.com/brimworks/lua-zlib", license = "MIT" } dependencies = { "lua >= 5.1, <= 5.3" } external_dependencies = { ZLIB = { header = "zlib.h" } } build = { type = "builtin", modules = { zlib = { sources = { "lua_zlib.c" }; libraries = { "z" }, }; } } lua-zlib-1.4/rockspecs/lua-zlib-1.3-0.rockspec0000664000175000017500000000236615126331021020320 0ustar sergeisergeipackage = "lua-zlib" version = "1.3-0" source = { url = "git+https://github.com/brimworks/lua-zlib.git", tag = "v1.3", } description = { summary = "Simple streaming interface to zlib for Lua.", detailed = [[ Simple streaming interface to zlib for Lua. Consists of two functions: inflate and deflate. Both functions return "stream functions" (takes a buffer of input and returns a buffer of output). This project is hosted on github. ]], homepage = "https://github.com/brimworks/lua-zlib", license = "MIT" } dependencies = { "lua >= 5.1, <= 5.4" } external_dependencies = { ZLIB = { header = "zlib.h" } } build = { type = "builtin", modules = { zlib = { sources = { "lua_zlib.c" }, libraries = { "z" }, defines = { "LZLIB_COMPAT" }, incdirs = { "$(ZLIB_INCDIR)" }, libdirs = { "$(ZLIB_LIBDIR)" } } }, platforms = { windows = { modules = { zlib = { libraries = { "zlib" } } } }, mingw = { modules = { zlib = { libraries = { "zlib1" }, libdirs = { "$(ZLIB_INCDIR)/../bin" } } } } } } lua-zlib-1.4/LICENCE0000664000175000017500000000223615126331021013377 0ustar sergeisergeiAuthor : Brian Maher Library : lua_zlib - Lua 5.1 to Lua 5.5 interface to zlib The MIT License Copyright (c) 2025 Brian Maher Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. lua-zlib-1.4/tom_macwright.out0000664000175000017500000000036515126331021016010 0ustar sergeisergeicommit 234tree b0d387e58ba8f97e64e43e440d6e226a454cc60c parent 7457837869dbf40e91719b5801301f465867d1c3 author Tom MacWright 1313704231 -0400 committer Tom MacWright 1313704231 -0400 And those ones. lua-zlib-1.4/amnon_david.gz0000664000175000017500000000010115126331021015220 0ustar sergeisergei(ͱIOHWU(,VD=.}>D9Լ7lua-zlib-1.4/cmake/0000775000175000017500000000000015126331021013467 5ustar sergeisergeilua-zlib-1.4/cmake/Modules/0000775000175000017500000000000015126331021015077 5ustar sergeisergeilua-zlib-1.4/cmake/Modules/FindLuaJIT.cmake0000664000175000017500000000344315126331021017776 0ustar sergeisergei# Locate LuaJIT library # This module defines # LUAJIT_FOUND, if false, do not try to link to Lua # LUA_LIBRARIES # LUA_INCLUDE_DIR, where to find lua.h # LUAJIT_VERSION_STRING, the version of Lua found (since CMake 2.8.8) ## Copied from default CMake FindLua51.cmake find_path(LUA_INCLUDE_DIR luajit.h HINTS ENV LUA_DIR PATH_SUFFIXES include/luajit-2.0 include PATHS ~/Library/Frameworks /Library/Frameworks /sw # Fink /opt/local # DarwinPorts /opt/csw # Blastwave /opt ) find_library(LUA_LIBRARY NAMES luajit-5.1 HINTS ENV LUA_DIR PATH_SUFFIXES lib PATHS ~/Library/Frameworks /Library/Frameworks /sw /opt/local /opt/csw /opt ) if(LUA_LIBRARY) # include the math library for Unix if(UNIX AND NOT APPLE) find_library(LUA_MATH_LIBRARY m) set( LUA_LIBRARIES "${LUA_LIBRARY};${LUA_MATH_LIBRARY}" CACHE STRING "Lua Libraries") # For Windows and Mac, don't need to explicitly include the math library else() set( LUA_LIBRARIES "${LUA_LIBRARY}" CACHE STRING "Lua Libraries") endif() endif() if(LUA_INCLUDE_DIR AND EXISTS "${LUA_INCLUDE_DIR}/luajit.h") file(STRINGS "${LUA_INCLUDE_DIR}/luajit.h" luajit_version_str REGEX "^#define[ \t]+LUAJIT_VERSION[ \t]+\"LuaJIT .+\"") string(REGEX REPLACE "^#define[ \t]+LUAJIT_VERSION[ \t]+\"LuaJIT ([^\"]+)\".*" "\\1" LUAJIT_VERSION_STRING "${luajit_version_str}") unset(luajit_version_str) endif() include(FindPackageHandleStandardArgs) # handle the QUIETLY and REQUIRED arguments and set LUA_FOUND to TRUE if # all listed variables are TRUE FIND_PACKAGE_HANDLE_STANDARD_ARGS(LuaJIT REQUIRED_VARS LUA_LIBRARIES LUA_INCLUDE_DIR VERSION_VAR LUAJIT_VERSION_STRING) mark_as_advanced(LUA_INCLUDE_DIR LUA_LIBRARIES LUA_LIBRARY LUA_MATH_LIBRARY) lua-zlib-1.4/test.lua0000664000175000017500000001407615126331021014101 0ustar sergeisergeiprint "1..9" local src_dir, build_dir = ... src_dir = src_dir or "./" build_dir = build_dir or "./" package.path = src_dir .. "?.lua;" .. package.path package.cpath = build_dir .. "?.so;" .. package.cpath local tap = require("tap") local lz = require("zlib") local ok = tap.ok local table = require("table") local io = require("io") local function test_tom_macwright() local deflated = assert(io.open(src_dir.. "/tom_macwright.gz")):read("*a") local inflated = lz.inflate()(deflated) local expected_inflated = assert(io.open(src_dir.. "/tom_macwright.out")):read("*a") ok(expected_inflated == inflated, "Tom MacWright Test") end -- luacheck: ignore eof bytes_in bytes_out deflated local function test_amnon_david() local body = assert(io.open(src_dir.."/amnon_david.gz")):read("*a") local inflate = lz.inflate() local inflated, eof, bytes_in, bytes_out = inflate(body) local deflate = lz.deflate() local deflated, eof, bytes_in, bytes_out = deflate(inflated, "full") end local function test_stats() local string = ("one"):rep(20) local deflated, eof, bin, bout = lz.deflate()(string, 'finish') ok(eof == true, "eof is true (" .. tostring(eof) .. ")"); ok(bin > bout, "bytes in is greater than bytes out?") ok(#deflated == bout, "bytes out is the same size as deflated string length") ok(#string == bin, "bytes in is the same size as the input string length") end -- Thanks to Tobias Markmann for the bug report! We are trying to -- force inflate() to return a Z_BUF_ERROR (which should be recovered -- from). For some reason this only happens when the input is exactly -- LUAL_BUFFERSIZE (at least on my machine). local function test_buff_err() local text = ("X"):rep(lz._TEST_BUFSIZ); local deflated = lz.deflate()(text, 'finish') for i=1,#deflated do lz.inflate()(deflated:sub(1,i)) end end local function test_small_inputs() local text = ("X"):rep(lz._TEST_BUFSIZ); local deflated = lz.deflate()(text, 'finish') local inflated = {} local inflator = lz.inflate() for i=1,#deflated do local part = inflator(deflated:sub(i,i)) table.insert(inflated, part) end inflated = table.concat(inflated) ok(inflated == text, "Expected " .. #text .. " Xs got " .. #inflated) end local function test_basic() local test_string = "abcdefghijklmnopqrstuv" ok(lz.inflate()(lz.deflate()(), "finish") == "") -- Input to deflate is same as output to inflate: local deflated = lz.deflate()(test_string, "finish") local inflated = lz.inflate()(deflated, "finish") ok(test_string == inflated, "'" .. tostring(test_string) .. "' == '" .. tostring(inflated) .. "'") end local function test_large() -- Try a larger string: local numbers = "" for i=1, 100 do numbers = numbers .. string.format("%3d", i) end local numbers_table = {} for i=1, 10000 do numbers_table[i] = numbers end local test_string = table.concat(numbers_table, "\n") local deflated = lz.deflate()(test_string, "finish") local inflated = lz.inflate()(deflated, "finish") ok(test_string == inflated, "large string") end local function test_no_input() local stream = lz.deflate() local deflated = stream("") deflated = deflated .. stream("") deflated = deflated .. stream(nil, "finish") ok("" == lz.inflate()(deflated, "finish"), "empty string") end local function test_invalid_input() local stream = lz.inflate() local isok, err = pcall( function() stream("bad input") end) ok(not isok) ok(string.find(err, "^InvalidInput"), string.format("InvalidInput error (%s)", err)) end local function test_streaming() local shrink = lz.deflate(lz.BEST_COMPRESSION) local enlarge = lz.inflate() local expected = {} local got = {} local chant = "Isn't He great, isn't He wonderful?\n" for i=1,100 do if ( i == 100 ) then chant = nil print "EOF round" end local shrink_part, shrink_eof = shrink(chant) local enlarge_part, enlarge_eof = enlarge(shrink_part) if ( i == 100 ) then if not shrink_eof then error("expected eof after shrinking flush") end if not enlarge_eof then error("expected eof after enlarging") end else if shrink_eof then error("unexpected eof after shrinking") end if enlarge_eof then error("unexpected eof after enlarging") end end if enlarge_part then table.insert(got, enlarge_part) end if chant then table.insert(expected, chant) end end ok(table.concat(got) == table.concat(expected), "streaming works") end -- luacheck: ignore enlarge local function test_illegal_state() local stream = lz.deflate() stream("abc") stream() -- eof/close local _, emsg = pcall( function() stream("printing on 'closed' handle") end) ok(string.find(emsg, "^IllegalState"), string.format("IllegalState error (%s)", emsg)) local enlarge = lz.inflate() end local function test_checksum() for _, factory in pairs{lz.crc32, lz.adler32} do local csum = factory()("one two") -- Multiple calls: local compute = factory() compute("one") assert(csum == compute(" two")) -- Multiple compute_checksums joined: local compute1, compute2 = factory(), factory() compute1("one") compute2(" two") assert(csum == compute1(compute2)) end end local function test_version() local major, minor, patch = lz.version() ok(1 == major, "major version 1 == " .. major); ok(type(minor) == "number", "minor version is number (" .. minor .. ")") if ( patch == nil ) then ok(patch == nil, "patch version is empty or is number (empty)") else ok(type(patch) == "number", "patch version is empty or is number (" .. patch .. ")") end end local function main() test_stats() test_buff_err() test_small_inputs() test_basic() test_large() test_no_input() test_invalid_input() test_streaming() test_illegal_state() test_checksum() test_version() test_tom_macwright() test_amnon_david() end main() lua-zlib-1.4/Makefile0000664000175000017500000000311215126331021014044 0ustar sergeisergei# This Makefile is based on LuaSec's Makefile. Thanks to the LuaSec developers. # Inform the location to install the modules LUAPATH ?= /usr/share/lua/5.1 LUACPATH ?= /usr/lib/lua/5.1 INCDIR ?= -I/usr/include/lua5.1 LIBDIR ?= -L/usr/lib # For Mac OS X: set the system version MACOSX_VERSION = 10.4 CMOD = zlib.so OBJS = lua_zlib.o LIBS = -lz -llua -lm WARN = -Wall -pedantic BSD_CFLAGS = -O2 -fPIC $(WARN) $(INCDIR) $(DEFS) BSD_LDFLAGS = -O -shared -fPIC $(LIBDIR) LNX_CFLAGS = -O2 -fPIC $(WARN) $(INCDIR) $(DEFS) LNX_LDFLAGS = -O -shared -fPIC $(LIBDIR) MAC_ENV = env MACOSX_DEPLOYMENT_TARGET='$(MACVER)' MAC_CFLAGS = -O2 -fPIC -fno-common $(WARN) $(INCDIR) $(DEFS) MAC_LDFLAGS = -bundle -undefined dynamic_lookup -fPIC $(LIBDIR) CC = gcc LD = $(MYENV) gcc CFLAGS = $(MYCFLAGS) LDFLAGS = $(MYLDFLAGS) .PHONY: all clean install none linux bsd macosx all: @echo "Usage: $(MAKE) " @echo " * linux" @echo " * bsd" @echo " * macosx" install: $(CMOD) cp $(CMOD) $(LUACPATH) uninstall: rm $(LUACPATH)/zlib.so linux: @$(MAKE) $(CMOD) MYCFLAGS="$(LNX_CFLAGS)" MYLDFLAGS="$(LNX_LDFLAGS)" INCDIR="$(INCDIR)" LIBDIR="$(LIBDIR)" DEFS="$(DEFS)" bsd: @$(MAKE) $(CMOD) MYCFLAGS="$(BSD_CFLAGS)" MYLDFLAGS="$(BSD_LDFLAGS)" INCDIR="$(INCDIR)" LIBDIR="$(LIBDIR)" DEFS="$(DEFS)" macosx: @$(MAKE) $(CMOD) MYCFLAGS="$(MAC_CFLAGS)" MYLDFLAGS="$(MAC_LDFLAGS)" MYENV="$(MAC_ENV)" INCDIR="$(INCDIR)" LIBDIR="$(LIBDIR)" DEFS="$(DEFS)" clean: rm -f $(OBJS) $(CMOD) .c.o: $(CC) -c $(CFLAGS) $(DEFS) $(INCDIR) -o $@ $< $(CMOD): $(OBJS) $(LD) $(LDFLAGS) $(LIBDIR) $(OBJS) $(LIBS) -o $@ lua-zlib-1.4/lua-zlib-scm-0.rockspec0000664000175000017500000000237315126331021016603 0ustar sergeisergeipackage = "lua-zlib" version = "scm-0" source = { url = "git+https://github.com/brimworks/lua-zlib.git", branch = "master", } description = { summary = "Simple streaming interface to zlib for Lua.", detailed = [[ Simple streaming interface to zlib for Lua. Consists of two functions: inflate and deflate. Both functions return "stream functions" (takes a buffer of input and returns a buffer of output). This project is hosted on github. ]], homepage = "https://github.com/brimworks/lua-zlib", license = "MIT" } dependencies = { "lua >= 5.1, <= 5.5" } external_dependencies = { ZLIB = { header = "zlib.h" } } build = { type = "builtin", modules = { zlib = { sources = { "lua_zlib.c" }, libraries = { "z" }, defines = { "LZLIB_COMPAT" }, incdirs = { "$(ZLIB_INCDIR)" }, libdirs = { "$(ZLIB_LIBDIR)" } } }, platforms = { windows = { modules = { zlib = { libraries = { "zlib" } } } }, mingw = { modules = { zlib = { libraries = { "zlib1" }, libdirs = { "$(ZLIB_INCDIR)/../bin" } } } } } } lua-zlib-1.4/tap.lua0000664000175000017500000000066715126331021013707 0ustar sergeisergeilocal tap_module = {} local os = require("os") local counter = 1 local failed = false function tap_module.ok(assert_true, desc) local msg = ( assert_true and "ok " or "not ok " ) .. counter if ( not assert_true ) then failed = true end if ( desc ) then msg = msg .. " - " .. desc end print(msg) counter = counter + 1 end function tap_module.exit() os.exit(failed and 1 or 0) end return tap_module lua-zlib-1.4/.github/0000775000175000017500000000000015126331021013747 5ustar sergeisergeilua-zlib-1.4/.github/workflows/0000775000175000017500000000000015126331021016004 5ustar sergeisergeilua-zlib-1.4/.github/workflows/test.yml0000664000175000017500000000533715126331021017516 0ustar sergeisergeiname: Test on: [ push, pull_request ] jobs: test: strategy: fail-fast: false matrix: os: [ "ubuntu-24.04", "macos-15", "windows-2025" ] luaVersion: [ "5.5", "5.4", "5.3", "5.2", "5.1", "luajit", "luajit-openresty" ] runs-on: ${{ matrix.os }} env: LUAROCKS_WINDOWS_DEPS_DIR: C:\external WINDOWS_ZLIB_VERSION: 1.3.1 steps: - name: Checkout uses: actions/checkout@v6 - name: Setup MSVC command prompt if: ${{ runner.os == 'Windows' && !startsWith(matrix.luaVersion, 'luajit') }} uses: ilammy/msvc-dev-cmd@v1 - name: Setup ‘lua’ uses: luarocks/gh-actions-lua@816ec4c55af2f6dcb9dfcba372d93dd1fb5fa8f2 with: luaVersion: ${{ matrix.luaVersion }} - name: Setup ‘luarocks’ uses: luarocks/gh-actions-luarocks@e42874645a111d78a858c3dba7530bdd707b21a4 - name: Restore zlib tarball on Windows if: ${{ runner.os == 'Windows' }} id: restore-zlib-tarball uses: actions/cache/restore@v5 with: path: "zlib-${{ env.WINDOWS_ZLIB_VERSION }}.tar.gz" key: "zlib-${{ env.WINDOWS_ZLIB_VERSION }}" - name: Download zlib if: ${{ runner.os == 'Windows' && steps.restore-zlib-tarball.outputs.cache-hit != 'true' }} run: curl -L -O "https://zlib.net/fossils/zlib-${{ env.WINDOWS_ZLIB_VERSION }}.tar.gz" - name: Save zlib tarball if: ${{ runner.os == 'Windows' && steps.restore-zlib-tarball.outputs.cache-hit != 'true' }} uses: actions/cache/save@v5 with: path: "zlib-${{ env.WINDOWS_ZLIB_VERSION }}.tar.gz" key: "zlib-${{ env.WINDOWS_ZLIB_VERSION }}" - name: Extract, configure, build and install zlib on Windows shell: cmd if: ${{ runner.os == 'Windows' }} run: | tar -xf "zlib-${{ env.WINDOWS_ZLIB_VERSION }}.tar.gz" IF "${{ matrix.luaVersion }}"=="luajit" ( SET CMAKE_GENERATOR=MinGW Makefiles ) ELSE IF "${{ matrix.luaVersion }}"=="luajit-openresty" ( SET CMAKE_GENERATOR=MinGW Makefiles ) ELSE ( SET CMAKE_GENERATOR=NMake Makefiles ) cmake ^ -G "%CMAKE_GENERATOR%" ^ -DCMAKE_BUILD_TYPE=Release ^ -DBUILD_SHARED_LIBS=ON ^ --install-prefix "${{ env.LUAROCKS_WINDOWS_DEPS_DIR }}" ^ -S "zlib-${{ env.WINDOWS_ZLIB_VERSION }}" ^ -B build-zlib && ^ cmake --build build-zlib --config Release && ^ cmake --install build-zlib --config Release echo ${{ env.LUAROCKS_WINDOWS_DEPS_DIR }}\bin>>${{ github.path }} - name: Lint rockspec run: luarocks lint lua-zlib-scm-0.rockspec - name: Build & install run: luarocks make lua-zlib-scm-0.rockspec - name: Run tests run: lua test.lua lua-zlib-1.4/.github/workflows/luacheck.yml0000664000175000017500000000033315126331021020305 0ustar sergeisergeiname: Luacheck on: [ push, pull_request ] jobs: luacheck: runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v6 - name: Luacheck uses: lunarmodules/luacheck@v1 lua-zlib-1.4/README.md0000664000175000017500000001567015126331021013677 0ustar sergeisergei# lua-zlib Provides a functional, streaming interface to zlib. ## Prerequisites To use this library, you need zlib, get it here: * [https://zlib.net/](https://zlib.net/) ## Installing * **Debian/Ubuntu** `apt-get install lua-zlib` * **luarocks** `luarocks install lua-zlib` * **source** `make ` ## API ### Loading Dynamically linked: ```lua local zlib = require("zlib") ``` Statically linked: ```c luaopen_zlib(L); // zlib functions are now on the top of the Lua stack. ``` ### Query ZLib Version ```lua -- @return major (integer) -- @return minor (integer) -- @return patch (integer | nil) local major, minor, patch = zlib.version() ``` Returns numeric zlib version for the major, minor, and patch levels of the version linked in. ### Deflating Used for compressing a stream of bytes. ```lua -- @param compression_level (optional integer), defaults to -- `Z_DEFAULT_COMPRESSION` (6), this is a number between 1-9 where -- `zlib.BEST_SPEED` is 1 and `zlib.BEST_COMPRESSION` is 9. -- @param window_size (optional integer), base two logarithm of the window size -- (the size of the history buffer). It should be in the range of 8..15, -- larger values result in better compression at the expense of more memory -- used. This value can also be negative in order to indicate that "raw" -- compression is used, and thus the zlib header is omitted in the output. -- @return stream function documented below. The intent is to call the stream -- function multiple times for each chunk. local stream = zlib.deflate(compression_level, window_size) -- @param input (string) is a byte array to compress. -- @param flush_option (optional enum) may be `"sync"` | `"full"` | `"finish"` -- @return deflated (string) is a byte array that is compressed. -- @return eof (bool) indicates the `"finish"` flush_option was specified. -- @return bytes_in (integer) the total number of input bytes processed. -- @return bytes_out (integer) the total number of output bytes processed. local deflated, eof, bytes_in, bytes_out = stream(input, flush_option) ``` **Flush options:** * `"sync"` flush will force all pending output to be flushed to the return value and the output is aligned on a byte boundary, so that the decompressor can get all input data available so far. Flushing may degrade compression for some compression algorithms and so it should be used only when necessary. * `"full"` flush will flush all output as with `"sync"`, and the compression state is reset so that decompression can restart from this point if previous compressed data has been damaged or if random access is desired. Using this option too often can seriously degrade the compression. * `"finish"` flush will force all pending output to be processed and results in the stream become unusable. Any future attempts to call `stream()` with anything other than the empty string will result in an error that begins with IllegalState. ### Inflating Used for uncompressing a stream of bytes. ```lua -- @param window_size (optional integer) should match the window size specified -- when `zlib.deflate()` was called (absolute larger sizes are okay, but -- will consume more memory than necessary). If not specified, a zlib header -- is assumed to exist with information on what the correct window size to -- be used is. -- @return stream function documented below. The intent is to call the stream -- function multiple times for each chunk. local stream = zlib.inflate(window_size) -- @param input (string) is a byte array to decompress. -- @return inflated (string) is the decompressed byte array. -- @return eof (bool) indicates the zlib trailer was detected, and that all -- bytes have been processed. -- @return bytes_in (int) the total number of input bytes processed thus far. -- @return bytes_out (int) the total number of output bytes processed thus far. local inflated, eof, bytes_in, bytes_out = stream(input) ``` **Note:** The `stream()` function **must** not be called after `eof=true` is returned, otherwise this function will fail with an error that begins with IllegalState. No flush options are provided since the maximal amount of input is always processed. ### Inflating Concatenated Streams If multiple gzip files are concatenated, you will need to properly handle the `eof` and `bytes_in` returned values in order to avoid loosing data. This can be done like this: ```lua local source = io.open("allparts.gz") local dest = io.tmpfile() local inflate = lz.inflate() local shift = 0 while true do local data = source:read(4096) -- read in 4K chunks if not data then break end -- end if no more data local inflated, eos, bytes_in, bytes_out = inflate(data) dest:write(inflated) -- write inflated data if eos then -- end of current stream source:seek("set", shift + bytes_in) shift = shift + bytes_in -- update shift inflate = lz.inflate() -- new inflate per stream end end ``` In this example, the input file is `seek`ed backwards in order to preserve the unprocessed bytes of the input `data`. However, another way to accomplish this without requiring `seek`ing is to preserve the `bytes_in` between calls to `inflate()`. ### Checksums Due to the fact that zlib includes code to compute a checksum trailer, this library also provides access to this functionality. ```lua -- Function "factory" for a fresh adler32 checksum. -- @return compute_checksum (function) described below local compute_checksum = zlib.adler32() -- Function "factory" for a fresh crc32 checksum. -- @return compute_checksum (function) described below local compute_checksum = zlib.crc32() -- Updates the running checksum. -- @param input (string or function) if this is a function, it **must** -- be the result of `zlib.adler32()` or `zlib.crc32()`. -- @return checksum (integer) of the input local checksum = compute_checksum(input) ``` Here are some examples of using this API. These examples all compute the same checksum: ```lua -- All in one call: local csum = zlib.crc32()("one two") -- Multiple calls: local compute = zlib.crc32() compute("one") assert(csum == compute(" two")) -- Multiple compute_checksums joined: local compute1, compute2 = zlib.crc32(), zlib.crc32() compute1("one") compute2(" two") assert(csum == compute1(compute2)) ``` ### `lzlib` Compatibility API To avoid linking two Lua zlib libraries, we have opted to provide "lzlib" compatibility shims with this library which provide low-level APIs which are not documented here. Note that there are a few incompatibilities you may need to be aware of if trying to use this as a drop-in replacement for "lzlib": * zlib.version() in lzlib returns a string, but this library returns a numeric tuple (see above documentation). * zlib.{adler,crc}32() in lzlib returns the {adler,crc}32 initial value, however if this value is used with calls to adler32 it works in compatibility mode. To use this shim add the `-DLZLIB_COMPAT` compiler flag.