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_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_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; }
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_close(lua_State *L) { z_stream *s = lzstream_check(L, 1, LZANY); lzstream_cleanup(L, s); return 0; }
static int lzstream_gc(lua_State *L) { z_stream *s = lzstream_get(L, 1); lzstream_cleanup(L, s); return 0; }