add ungzip implementation
This commit is contained in:
parent
addf0b55ea
commit
cfc45c3bab
|
@ -71,3 +71,39 @@ proc gzip*[T: byte|char](N: type, source: openArray[T]): N =
|
|||
|
||||
result.setLen(mz.total_out.int + 18)
|
||||
assert(mz.deflateEnd() == MZ_OK)
|
||||
|
||||
proc ungzip*[T: byte|char](N: type, data: openArray[T]): N =
|
||||
var mz = MzStream(
|
||||
next_in: if data.len == 0:
|
||||
nil
|
||||
else:
|
||||
cast[ptr cuchar](data[10].unsafeAddr),
|
||||
avail_in: data.len.cuint - 18
|
||||
)
|
||||
|
||||
const windowBits = MZ_RAW_DEFLATE
|
||||
doAssert(mz.inflateInit2(windowBits) == MZ_OK)
|
||||
var res: seq[byte]
|
||||
var buf: array[0xFFFF, byte]
|
||||
|
||||
while true:
|
||||
mz.next_out = cast[ptr cuchar](buf[0].addr)
|
||||
mz.avail_out = buf.len.cuint
|
||||
let r = mz.inflate(MZ_SYNC_FLUSH)
|
||||
let outSize = buf.len - mz.avail_out.int
|
||||
res.add toOpenArray(buf, 0, outSize-1)
|
||||
if r == MZ_STREAM_END:
|
||||
break
|
||||
elif r == MZ_OK:
|
||||
continue
|
||||
else:
|
||||
doAssert(false, "decompression error")
|
||||
|
||||
doAssert(mz.inflateEnd() == MZ_OK)
|
||||
|
||||
when N is string:
|
||||
cast[string](res)
|
||||
elif N is seq[byte]:
|
||||
res
|
||||
else:
|
||||
{.fatal: "unsupported output type".}
|
||||
|
|
|
@ -10,16 +10,29 @@
|
|||
import
|
||||
std/[unittest, os],
|
||||
../miniz/gzip
|
||||
|
||||
|
||||
proc toBytes(s: string): seq[byte] =
|
||||
result = newSeq[byte](s.len)
|
||||
if s.len > 0:
|
||||
copyMem(result[0].addr, s[0].unsafeAddr, s.len)
|
||||
|
||||
suite "gzip test suite":
|
||||
const
|
||||
const
|
||||
rawFolder = "tests" / "data"
|
||||
|
||||
|
||||
for path in walkDirRec(rawFolder):
|
||||
let parts = splitFile(path)
|
||||
test parts.name:
|
||||
let s = readFile(path)
|
||||
let str = string.gzip(s)
|
||||
let bytes = seq[byte].gzip(s)
|
||||
check bytes.len == str.len
|
||||
|
||||
let cstr = string.gzip(s)
|
||||
let cbytes = seq[byte].gzip(s)
|
||||
check cbytes.len == cstr.len
|
||||
|
||||
let dcstr = string.ungzip(cbytes)
|
||||
let dcstr2 = string.ungzip(cstr)
|
||||
let dcbytes = seq[byte].ungzip(cbytes)
|
||||
let dcbytes2 = seq[byte].ungzip(cstr)
|
||||
check dcbytes2 == s.toBytes
|
||||
check dcbytes == s.toBytes
|
||||
check dcstr2 == s
|
||||
check dcstr == s
|
||||
|
|
Loading…
Reference in New Issue