Merge commit 'c46cd666ab76bad7bd05c6261d692cda5b380f32' as 'src/deps/src/lua-ffi-zlib'
This commit is contained in:
commit
909841ea63
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2016 Hamish Forbes
|
||||
|
||||
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.
|
|
@ -0,0 +1,133 @@
|
|||
# lua-ffi-zlib
|
||||
|
||||
A [Lua](http://www.lua.org) module using LuaJIT's [FFI](http://luajit.org/ext_ffi.html) feature to access zlib.
|
||||
Intended primarily for use within [OpenResty](http://openresty.org) to allow manipulation of gzip encoded HTTP responses.
|
||||
|
||||
# Methods
|
||||
|
||||
Basic methods allowing for simple compression or decompression of gzip data
|
||||
|
||||
## inflateGzip
|
||||
`Syntax: ok, err = inflateGzip(input, output, chunk?, windowBits?)`
|
||||
|
||||
* `input` should be a function that accepts a chunksize as its only argument and return that many bytes of the gzip stream
|
||||
* `output` will receive a string of decompressed data as its only argument, do with it as you will!
|
||||
* `chunk` is the size of the input and output buffers, optional and defaults to 16KB
|
||||
* `windowBits` is passed to `inflateInit2()`, should be left as default for most cases.
|
||||
See [zlib manual](http://zlib.net/manual.html) for details
|
||||
|
||||
On error returns `false` and the error message, otherwise `true` and the last status message
|
||||
|
||||
## deflateGzip
|
||||
`Syntax: ok, err = deflateGzip(input, output, chunk?, options?)`
|
||||
* `input` should be a function that accepts a chunksize as its only argument and return that many bytes of uncompressed data.
|
||||
* `output` will receive a string of compressed data as its only argument, do with it as you will!
|
||||
* `chunk` is the size of the input and output buffers, optional and defaults to 16KB
|
||||
* `options` is a table of options to pass to `deflateInit2()`
|
||||
Valid options are level, memLevel, strategy and windowBits, see [zlib manual](http://zlib.net/manual.html) for details
|
||||
|
||||
On error returns `false` and the error message, otherwise `true` and the last status message
|
||||
|
||||
# Example
|
||||
Reads a file and output the decompressed version.
|
||||
|
||||
Roughly equivalent to running `gzip -dc file.gz > out_file | tee`
|
||||
|
||||
```lua
|
||||
local table_insert = table.insert
|
||||
local table_concat = table.concat
|
||||
local zlib = require('lib.ffi-zlib')
|
||||
|
||||
local f = io.open(arg[1], "rb")
|
||||
local out_f = io.open(arg[2], "w")
|
||||
|
||||
local input = function(bufsize)
|
||||
-- Read the next chunk
|
||||
local d = f:read(bufsize)
|
||||
if d == nil then
|
||||
return nil
|
||||
end
|
||||
return d
|
||||
end
|
||||
|
||||
local output_table = {}
|
||||
local output = function(data)
|
||||
table_insert(output_table, data)
|
||||
local ok, err = out_f:write(data)
|
||||
if not ok then
|
||||
-- abort decompression when error occurs
|
||||
return nil, err
|
||||
end
|
||||
end
|
||||
|
||||
-- Decompress the data
|
||||
local ok, err = zlib.inflateGzip(input, output)
|
||||
if not ok then
|
||||
print(err)
|
||||
return
|
||||
end
|
||||
|
||||
local decompressed = table_concat(output_table,'')
|
||||
|
||||
print(decompressed)
|
||||
```
|
||||
# Advanced Usage
|
||||
|
||||
Several other methods are available for advanced usage.
|
||||
Some of these map directly to functions in the zlib library itself, see the [manual](http://zlib.net/manual.html) for full details.
|
||||
Others are lower level utility functions.
|
||||
|
||||
## createStream
|
||||
`Synax: stream, inbuf, outbuf = createStream(bufsize)`
|
||||
|
||||
Returns a z_stream struct, input buffer and output buffer of length `bufsize`
|
||||
|
||||
## initInflate
|
||||
`Syntax: ok = initInflate(stream, windowBits?)`
|
||||
|
||||
Calls zlib's inflateInit2 with given stream, defaults to automatic header detection.
|
||||
|
||||
## initDeflate
|
||||
`Syntax: ok = initDeflate(stream, options?)`
|
||||
|
||||
Calls zlib's deflateInit2 with the given stream.
|
||||
`options` is an optional table that can set level, memLevel, strategy and windowBits
|
||||
|
||||
## deflate
|
||||
`Syntax: ok, err = deflate(input, output, bufsize, stream, inbuf, outbuf)`
|
||||
|
||||
* `input` is a function that takes a chunk size argument and returns at most that many input bytes
|
||||
* `output` is a function that takes a string argument of output data
|
||||
* `bufsize` is the length of the output buffer
|
||||
* `inbuf` cdata input buffer
|
||||
* `outpuf` ccdata output buffer
|
||||
|
||||
This function will loop until all input data is consumed (`input` returns nil) or an error occurs.
|
||||
It will then clean up the stream and return an error code
|
||||
|
||||
## inflate
|
||||
`Syntax: ok, err = inflate(input, output, bufsize, stream, inbuf, outbuf)`
|
||||
|
||||
* `input` is a function that takes a chunk size argument and returns at most that many input bytes
|
||||
* `output` is a function that takes a string argument of output data
|
||||
* `bufsize` is the length of the output buffer
|
||||
* `inbuf` cdata input buffer
|
||||
* `outpuf` ccdata output buffer
|
||||
|
||||
This function will loop until all input data is consumed (`input` returns nil) or an error occurs.
|
||||
It will then clean up the stream and return an error code
|
||||
|
||||
## adler
|
||||
`Syntax: chksum = adler(str, chksum?)`
|
||||
|
||||
Computes an adler32 checksum for a string, updates an existing checksum if provided
|
||||
|
||||
## crc
|
||||
`Syntax: chksum = crc(str, chksum?)`
|
||||
|
||||
Computes an crc32 checksum for a string, updates an existing checksum if provided
|
||||
|
||||
## zlib_err
|
||||
`Syntax: err = zlib_err(code)`
|
||||
|
||||
Returns the string representation of a zlib error code
|
|
@ -0,0 +1,9 @@
|
|||
name=lua-ffi-zlib
|
||||
abstract=Luajit FFI binding for zlib
|
||||
author=Hamish Forbes
|
||||
is_original=yes
|
||||
license=mit
|
||||
lib_dir=lib
|
||||
repo_link=https://github.com/hamishforbes/lua-ffi-zlib
|
||||
main_module=lib/ffi-zlib.lua
|
||||
requires = luajit
|
|
@ -0,0 +1,330 @@
|
|||
local ffi = require "ffi"
|
||||
local ffi_new = ffi.new
|
||||
local ffi_str = ffi.string
|
||||
local ffi_sizeof = ffi.sizeof
|
||||
local ffi_copy = ffi.copy
|
||||
local tonumber = tonumber
|
||||
|
||||
local _M = {
|
||||
_VERSION = '0.5.0',
|
||||
}
|
||||
|
||||
local mt = { __index = _M }
|
||||
|
||||
|
||||
ffi.cdef([[
|
||||
enum {
|
||||
Z_NO_FLUSH = 0,
|
||||
Z_PARTIAL_FLUSH = 1,
|
||||
Z_SYNC_FLUSH = 2,
|
||||
Z_FULL_FLUSH = 3,
|
||||
Z_FINISH = 4,
|
||||
Z_BLOCK = 5,
|
||||
Z_TREES = 6,
|
||||
/* Allowed flush values; see deflate() and inflate() below for details */
|
||||
Z_OK = 0,
|
||||
Z_STREAM_END = 1,
|
||||
Z_NEED_DICT = 2,
|
||||
Z_ERRNO = -1,
|
||||
Z_STREAM_ERROR = -2,
|
||||
Z_DATA_ERROR = -3,
|
||||
Z_MEM_ERROR = -4,
|
||||
Z_BUF_ERROR = -5,
|
||||
Z_VERSION_ERROR = -6,
|
||||
/* Return codes for the compression/decompression functions. Negative values
|
||||
* are errors, positive values are used for special but normal events.
|
||||
*/
|
||||
Z_NO_COMPRESSION = 0,
|
||||
Z_BEST_SPEED = 1,
|
||||
Z_BEST_COMPRESSION = 9,
|
||||
Z_DEFAULT_COMPRESSION = -1,
|
||||
/* compression levels */
|
||||
Z_FILTERED = 1,
|
||||
Z_HUFFMAN_ONLY = 2,
|
||||
Z_RLE = 3,
|
||||
Z_FIXED = 4,
|
||||
Z_DEFAULT_STRATEGY = 0,
|
||||
/* compression strategy; see deflateInit2() below for details */
|
||||
Z_BINARY = 0,
|
||||
Z_TEXT = 1,
|
||||
Z_ASCII = Z_TEXT, /* for compatibility with 1.2.2 and earlier */
|
||||
Z_UNKNOWN = 2,
|
||||
/* Possible values of the data_type field (though see inflate()) */
|
||||
Z_DEFLATED = 8,
|
||||
/* The deflate compression method (the only one supported in this version) */
|
||||
Z_NULL = 0, /* for initializing zalloc, zfree, opaque */
|
||||
};
|
||||
|
||||
|
||||
typedef void* (* z_alloc_func)( void* opaque, unsigned items, unsigned size );
|
||||
typedef void (* z_free_func) ( void* opaque, void* address );
|
||||
|
||||
typedef struct z_stream_s {
|
||||
char* next_in;
|
||||
unsigned avail_in;
|
||||
unsigned long total_in;
|
||||
char* next_out;
|
||||
unsigned avail_out;
|
||||
unsigned long total_out;
|
||||
char* msg;
|
||||
void* state;
|
||||
z_alloc_func zalloc;
|
||||
z_free_func zfree;
|
||||
void* opaque;
|
||||
int data_type;
|
||||
unsigned long adler;
|
||||
unsigned long reserved;
|
||||
} z_stream;
|
||||
|
||||
|
||||
const char* zlibVersion();
|
||||
const char* zError(int);
|
||||
|
||||
int inflate(z_stream*, int flush);
|
||||
int inflateEnd(z_stream*);
|
||||
int inflateInit2_(z_stream*, int windowBits, const char* version, int stream_size);
|
||||
|
||||
int deflate(z_stream*, int flush);
|
||||
int deflateEnd(z_stream* );
|
||||
int deflateInit2_(z_stream*, int level, int method, int windowBits, int memLevel,int strategy, const char *version, int stream_size);
|
||||
|
||||
unsigned long adler32(unsigned long adler, const char *buf, unsigned len);
|
||||
unsigned long crc32(unsigned long crc, const char *buf, unsigned len);
|
||||
unsigned long adler32_combine(unsigned long, unsigned long, long);
|
||||
unsigned long crc32_combine(unsigned long, unsigned long, long);
|
||||
|
||||
]])
|
||||
|
||||
local zlib = ffi.load(ffi.os == "Windows" and "zlib1" or "z")
|
||||
_M.zlib = zlib
|
||||
|
||||
-- Default to 16k output buffer
|
||||
local DEFAULT_CHUNK = 16384
|
||||
|
||||
local Z_OK = zlib.Z_OK
|
||||
local Z_NO_FLUSH = zlib.Z_NO_FLUSH
|
||||
local Z_STREAM_END = zlib.Z_STREAM_END
|
||||
local Z_FINISH = zlib.Z_FINISH
|
||||
local Z_NEED_DICT = zlib.Z_NEED_DICT
|
||||
local Z_BUF_ERROR = zlib.Z_BUF_ERROR
|
||||
local Z_STREAM_ERROR = zlib.Z_STREAM_ERROR
|
||||
|
||||
local function zlib_err(err)
|
||||
return ffi_str(zlib.zError(err))
|
||||
end
|
||||
_M.zlib_err = zlib_err
|
||||
|
||||
local function createStream(bufsize)
|
||||
-- Setup Stream
|
||||
local stream = ffi_new("z_stream")
|
||||
|
||||
-- Create input buffer var
|
||||
local inbuf = ffi_new('char[?]', bufsize+1)
|
||||
stream.next_in, stream.avail_in = inbuf, 0
|
||||
|
||||
-- create the output buffer
|
||||
local outbuf = ffi_new('char[?]', bufsize)
|
||||
stream.next_out, stream.avail_out = outbuf, 0
|
||||
|
||||
return stream, inbuf, outbuf
|
||||
end
|
||||
_M.createStream = createStream
|
||||
|
||||
local function initInflate(stream, windowBits)
|
||||
-- Setup inflate process
|
||||
local windowBits = windowBits or (15 + 32) -- +32 sets automatic header detection
|
||||
local version = ffi_str(zlib.zlibVersion())
|
||||
|
||||
return zlib.inflateInit2_(stream, windowBits, version, ffi_sizeof(stream))
|
||||
end
|
||||
_M.initInflate = initInflate
|
||||
|
||||
local function initDeflate(stream, options)
|
||||
-- Setup deflate process
|
||||
local method = zlib.Z_DEFLATED
|
||||
local level = options.level or zlib.Z_DEFAULT_COMPRESSION
|
||||
local memLevel = options.memLevel or 8
|
||||
local strategy = options.strategy or zlib.Z_DEFAULT_STRATEGY
|
||||
local windowBits = options.windowBits or (15 + 16) -- +16 sets gzip wrapper not zlib
|
||||
local version = ffi_str(zlib.zlibVersion())
|
||||
|
||||
return zlib.deflateInit2_(stream, level, method, windowBits, memLevel, strategy, version, ffi_sizeof(stream))
|
||||
end
|
||||
_M.initDeflate = initDeflate
|
||||
|
||||
local function flushOutput(stream, bufsize, output, outbuf)
|
||||
-- Calculate available output bytes
|
||||
local out_sz = bufsize - stream.avail_out
|
||||
if out_sz == 0 then
|
||||
return
|
||||
end
|
||||
-- Read bytes from output buffer and pass to output function
|
||||
local ok, err = output(ffi_str(outbuf, out_sz))
|
||||
if not ok then
|
||||
return err
|
||||
end
|
||||
end
|
||||
|
||||
local function inflate(input, output, bufsize, stream, inbuf, outbuf)
|
||||
local zlib_flate = zlib.inflate
|
||||
local zlib_flateEnd = zlib.inflateEnd
|
||||
-- Inflate a stream
|
||||
local err = 0
|
||||
repeat
|
||||
-- Read some input
|
||||
local data = input(bufsize)
|
||||
if data ~= nil then
|
||||
ffi_copy(inbuf, data)
|
||||
stream.next_in, stream.avail_in = inbuf, #data
|
||||
else
|
||||
-- no more input data
|
||||
stream.avail_in = 0
|
||||
end
|
||||
|
||||
if stream.avail_in == 0 then
|
||||
-- When decompressing we *must* have input bytes
|
||||
zlib_flateEnd(stream)
|
||||
return false, "INFLATE: Data error, no input bytes"
|
||||
end
|
||||
|
||||
-- While the output buffer is being filled completely just keep going
|
||||
repeat
|
||||
stream.next_out = outbuf
|
||||
stream.avail_out = bufsize
|
||||
-- Process the stream, always Z_NO_FLUSH in inflate mode
|
||||
err = zlib_flate(stream, Z_NO_FLUSH)
|
||||
|
||||
-- Buffer errors are OK here
|
||||
if err == Z_BUF_ERROR then
|
||||
err = Z_OK
|
||||
end
|
||||
if err < Z_OK or err == Z_NEED_DICT then
|
||||
-- Error, clean up and return
|
||||
zlib_flateEnd(stream)
|
||||
return false, "INFLATE: "..zlib_err(err), stream
|
||||
end
|
||||
-- Write the data out
|
||||
local err = flushOutput(stream, bufsize, output, outbuf)
|
||||
if err then
|
||||
zlib_flateEnd(stream)
|
||||
return false, "INFLATE: "..err
|
||||
end
|
||||
until stream.avail_out ~= 0
|
||||
|
||||
until err == Z_STREAM_END
|
||||
|
||||
-- Stream finished, clean up and return
|
||||
zlib_flateEnd(stream)
|
||||
return true, zlib_err(err)
|
||||
end
|
||||
_M.inflate = inflate
|
||||
|
||||
local function deflate(input, output, bufsize, stream, inbuf, outbuf)
|
||||
local zlib_flate = zlib.deflate
|
||||
local zlib_flateEnd = zlib.deflateEnd
|
||||
|
||||
-- Deflate a stream
|
||||
local err = 0
|
||||
local mode = Z_NO_FLUSH
|
||||
repeat
|
||||
-- Read some input
|
||||
local data = input(bufsize)
|
||||
if data ~= nil then
|
||||
ffi_copy(inbuf, data)
|
||||
stream.next_in, stream.avail_in = inbuf, #data
|
||||
else
|
||||
-- EOF, try and finish up
|
||||
mode = Z_FINISH
|
||||
stream.avail_in = 0
|
||||
end
|
||||
|
||||
-- While the output buffer is being filled completely just keep going
|
||||
repeat
|
||||
stream.next_out = outbuf
|
||||
stream.avail_out = bufsize
|
||||
|
||||
-- Process the stream
|
||||
err = zlib_flate(stream, mode)
|
||||
|
||||
-- Only possible *bad* return value here
|
||||
if err == Z_STREAM_ERROR then
|
||||
-- Error, clean up and return
|
||||
zlib_flateEnd(stream)
|
||||
return false, "DEFLATE: "..zlib_err(err), stream
|
||||
end
|
||||
-- Write the data out
|
||||
local err = flushOutput(stream, bufsize, output, outbuf)
|
||||
if err then
|
||||
zlib_flateEnd(stream)
|
||||
return false, "DEFLATE: "..err
|
||||
end
|
||||
until stream.avail_out ~= 0
|
||||
|
||||
-- In deflate mode all input must be used by this point
|
||||
if stream.avail_in ~= 0 then
|
||||
zlib_flateEnd(stream)
|
||||
return false, "DEFLATE: Input not used"
|
||||
end
|
||||
|
||||
until err == Z_STREAM_END
|
||||
|
||||
-- Stream finished, clean up and return
|
||||
zlib_flateEnd(stream)
|
||||
return true, zlib_err(err)
|
||||
end
|
||||
_M.deflate = deflate
|
||||
|
||||
local function adler(str, chksum)
|
||||
local chksum = chksum or 0
|
||||
local str = str or ""
|
||||
return zlib.adler32(chksum, str, #str)
|
||||
end
|
||||
_M.adler = adler
|
||||
|
||||
local function crc(str, chksum)
|
||||
local chksum = chksum or 0
|
||||
local str = str or ""
|
||||
return zlib.crc32(chksum, str, #str)
|
||||
end
|
||||
_M.crc = crc
|
||||
|
||||
function _M.inflateGzip(input, output, bufsize, windowBits)
|
||||
local bufsize = bufsize or DEFAULT_CHUNK
|
||||
|
||||
-- Takes 2 functions that provide input data from a gzip stream and receives output data
|
||||
-- Returns uncompressed string
|
||||
local stream, inbuf, outbuf = createStream(bufsize)
|
||||
|
||||
local init = initInflate(stream, windowBits)
|
||||
if init == Z_OK then
|
||||
return inflate(input, output, bufsize, stream, inbuf, outbuf)
|
||||
else
|
||||
-- Init error
|
||||
zlib.inflateEnd(stream)
|
||||
return false, "INIT: "..zlib_err(init)
|
||||
end
|
||||
end
|
||||
|
||||
function _M.deflateGzip(input, output, bufsize, options)
|
||||
local bufsize = bufsize or DEFAULT_CHUNK
|
||||
options = options or {}
|
||||
|
||||
-- Takes 2 functions that provide plain input data and receives output data
|
||||
-- Returns gzip compressed string
|
||||
local stream, inbuf, outbuf = createStream(bufsize)
|
||||
|
||||
local init = initDeflate(stream, options)
|
||||
if init == Z_OK then
|
||||
return deflate(input, output, bufsize, stream, inbuf, outbuf)
|
||||
else
|
||||
-- Init error
|
||||
zlib.deflateEnd(stream)
|
||||
return false, "INIT: "..zlib_err(init)
|
||||
end
|
||||
end
|
||||
|
||||
function _M.version()
|
||||
return ffi_str(zlib.zlibVersion())
|
||||
end
|
||||
|
||||
return _M
|
|
@ -0,0 +1,20 @@
|
|||
package = "lua-ffi-zlib"
|
||||
version = "0.4-0"
|
||||
source = {
|
||||
url = "git://github.com/hamishforbes/lua-ffi-zlib",
|
||||
tag = "v0.4"
|
||||
}
|
||||
description = {
|
||||
summary = "A Lua module using LuaJIT's FFI feature to access zlib.",
|
||||
homepage = "https://github.com/hamishforbes/lua-ffi-zlib",
|
||||
maintainer = "Hamish Forbes"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["ffi-zlib"] = "lib/ffi-zlib.lua",
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package = "lua-ffi-zlib"
|
||||
version = "0.5-0"
|
||||
source = {
|
||||
url = "git://github.com/hamishforbes/lua-ffi-zlib",
|
||||
tag = "v0.5"
|
||||
}
|
||||
description = {
|
||||
summary = "A Lua module using LuaJIT's FFI feature to access zlib.",
|
||||
homepage = "https://github.com/hamishforbes/lua-ffi-zlib",
|
||||
maintainer = "Hamish Forbes"
|
||||
}
|
||||
dependencies = {
|
||||
"lua >= 5.1",
|
||||
}
|
||||
build = {
|
||||
type = "builtin",
|
||||
modules = {
|
||||
["ffi-zlib"] = "lib/ffi-zlib.lua",
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
local table_insert = table.insert
|
||||
local table_concat = table.concat
|
||||
|
||||
local zlib = require('lib.ffi-zlib')
|
||||
|
||||
local chunk = tonumber(arg[2]) or 16384
|
||||
local uncompressed = ''
|
||||
local input
|
||||
local f
|
||||
|
||||
local passing = true
|
||||
|
||||
local in_adler
|
||||
local out_adler
|
||||
local in_crc
|
||||
local out_crc
|
||||
|
||||
if arg[1] == nil then
|
||||
print("No file provided")
|
||||
return
|
||||
else
|
||||
f = io.open(arg[1], "rb")
|
||||
input = function(bufsize)
|
||||
local d = f:read(bufsize)
|
||||
if d == nil then
|
||||
return nil
|
||||
end
|
||||
in_crc = zlib.crc(d, in_crc)
|
||||
in_adler = zlib.adler(d, in_adler)
|
||||
uncompressed = uncompressed..d
|
||||
return d
|
||||
end
|
||||
end
|
||||
|
||||
print('zlib version: '..zlib.version())
|
||||
print()
|
||||
|
||||
local output_table = {}
|
||||
local output = function(data)
|
||||
out_crc = zlib.crc(data, out_crc)
|
||||
out_adler = zlib.adler(data, out_adler)
|
||||
table_insert(output_table, data)
|
||||
end
|
||||
|
||||
-- Compress the data
|
||||
print('Compressing')
|
||||
local ok, err = zlib.deflateGzip(input, output, chunk)
|
||||
if not ok then
|
||||
-- Err message
|
||||
print(err)
|
||||
end
|
||||
|
||||
local compressed = table_concat(output_table,'')
|
||||
|
||||
local orig_in_crc = in_crc
|
||||
local orig_in_adler = in_adler
|
||||
print('Input crc32: ', in_crc)
|
||||
print('Output crc32: ', out_crc)
|
||||
print('Input adler32: ', in_adler)
|
||||
print('Output adler32: ', out_adler)
|
||||
|
||||
-- Decompress it again
|
||||
print()
|
||||
print('Decompressing')
|
||||
-- Reset vars
|
||||
in_adler = nil
|
||||
out_adler = nil
|
||||
in_crc = nil
|
||||
out_crc = nil
|
||||
output_table = {}
|
||||
|
||||
local count = 0
|
||||
local input = function(bufsize)
|
||||
local start = count > 0 and bufsize*count or 1
|
||||
local finish = (bufsize*(count+1)-1)
|
||||
count = count + 1
|
||||
if bufsize == 1 then
|
||||
start = count
|
||||
finish = count
|
||||
end
|
||||
local data = compressed:sub(start, finish)
|
||||
in_crc = zlib.crc(data, in_crc)
|
||||
in_adler = zlib.adler(data, in_adler)
|
||||
return data
|
||||
end
|
||||
|
||||
local ok, err = zlib.inflateGzip(input, output, chunk)
|
||||
if not ok then
|
||||
-- Err message
|
||||
print(err)
|
||||
end
|
||||
local output_data = table_concat(output_table,'')
|
||||
|
||||
print('Input crc32: ', in_crc)
|
||||
print('Output crc32: ', out_crc)
|
||||
print('Input adler32: ', in_adler)
|
||||
print('Output adler32: ', out_adler)
|
||||
print()
|
||||
|
||||
if output_data ~= uncompressed then
|
||||
passing = false
|
||||
print("inflateGzip / deflateGzip failed")
|
||||
end
|
||||
|
||||
if orig_in_adler ~= out_adler then
|
||||
passing = false
|
||||
print("Adler checksum failed")
|
||||
end
|
||||
|
||||
if orig_in_crc ~= out_crc then
|
||||
passing = false
|
||||
print("CRC checksum failed")
|
||||
end
|
||||
|
||||
local bad_output = function(data)
|
||||
return nil, "bad output"
|
||||
end
|
||||
|
||||
if not passing then
|
||||
print(":(")
|
||||
else
|
||||
print(":)")
|
||||
end
|
||||
|
||||
local dump_input = function(bufsize)
|
||||
return compressed
|
||||
end
|
||||
|
||||
local ok, err = zlib.deflateGzip(dump_input, bad_output, chunk)
|
||||
if not ok then
|
||||
if err ~= "DEFLATE: bad output" then
|
||||
print(err)
|
||||
else
|
||||
print("abort deflation: ok")
|
||||
end
|
||||
end
|
||||
|
||||
local ok, err = zlib.inflateGzip(dump_input, bad_output, chunk)
|
||||
if not ok then
|
||||
if err ~= "INFLATE: bad output" then
|
||||
print(err)
|
||||
else
|
||||
print("abort inflation: ok")
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue