static int lzstream_compress(lua_State *L) { z_stream *s = lzstream_check(L, 1, LZDEFLATE); s->next_in = (Bytef*)luaL_checkstring(L, 2); s->avail_in = lua_rawlen(L, 2); { int r; luaL_Buffer b; luaL_buffinit(L, &b); do { s->next_out = (Bytef*)luaL_prepbuffer(&b); s->avail_out = LUAL_BUFFERSIZE; /* bake some more */ if ((r = deflate(s, Z_NO_FLUSH)) != Z_OK) { lua_pushfstring(L, "failed to compress [%d]", r); lua_error(L); } /* push gathered data */ luaL_addsize(&b, LUAL_BUFFERSIZE - s->avail_out); /* until we have free space in the output buffer - meaning we are done */ } while (s->avail_out == 0); /* send gathered data if any */ luaL_pushresult(&b); } return 1; }
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 lzstream_reset(lua_State *L) { z_stream *s = lzstream_check(L, 1, LZANY); if (s->state == LZDEFLATE) lua_pushnumber(L, deflateReset(s)); else if (s->opaque == LZINFLATE) lua_pushnumber(L, inflateReset(s)); else { lua_pushliteral(L, "invalid zlib stream state"); lua_error(L); } return 1; }
static int lzstream_readline(lua_State *L) { lz_stream *s; int sucess; s = lzstream_check(L, lua_upvalueindex(1), LZ_INFLATE); sucess = lz_read_line(L, s); if (s->error != Z_OK) { return lz_pushresult(L, s); } if (sucess) { return 1; } else { /* EOF */ return 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_flush(lua_State *L) { z_stream *s = lzstream_check(L, 1, LZANY); if (s->opaque == LZINFLATE) { lua_pushliteral(L, ""); return 1; } s->next_in = (Bytef*)""; s->avail_in = 0; { int r = 0; luaL_Buffer b; luaL_buffinit(L, &b); do { s->next_out = (Bytef*)luaL_prepbuffer(&b); s->avail_out = LUAL_BUFFERSIZE; r = deflate(s, Z_FINISH); if (r != Z_OK && r != Z_STREAM_END) { lua_pushfstring(L, "failed to flush [%d]", r); lua_error(L); } /* push gathered data */ luaL_addsize(&b, LUAL_BUFFERSIZE - s->avail_out); } while (r != Z_STREAM_END); /* send gathered data if any */ luaL_pushresult(&b); } return 1; }
static int lzstream_adler(lua_State *L) { z_stream *s = lzstream_check(L, 1, LZANY); lua_pushnumber(L, s->adler); return 1; }
static int lzstream_close(lua_State *L) { z_stream *s = lzstream_check(L, 1, LZANY); lzstream_cleanup(L, s); return 0; }
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_lines(lua_State *L) { lzstream_check(L, 1, LZ_INFLATE); lua_settop(L, 1); lua_pushcclosure(L, lzstream_readline, 1); return 1; }