diff options
Diffstat (limited to 'tests/deps/zip-0.2.1/zip/gzipfiles.nim')
-rw-r--r-- | tests/deps/zip-0.2.1/zip/gzipfiles.nim | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/tests/deps/zip-0.2.1/zip/gzipfiles.nim b/tests/deps/zip-0.2.1/zip/gzipfiles.nim new file mode 100644 index 000000000..82c412bc3 --- /dev/null +++ b/tests/deps/zip-0.2.1/zip/gzipfiles.nim @@ -0,0 +1,97 @@ +import os +import zlib +import streams +export streams + +## This module implements a gzipfile stream for reading, writing, appending. + +type + GzFileStream* = ref object of Stream + mode: FileMode + f: GzFile + +const SEEK_SET = 0.int32 # Seek from beginning of file. + +proc fsClose(s: Stream) = + if not GzFileStream(s).f.isNil: + discard gzclose(GzFileStream(s).f) + GzFileStream(s).f = nil + +proc fsFlush(s: Stream) = + # compiler flushFile also discard c_fflush + discard gzflush(GzFileStream(s).f, Z_FINISH) + +proc fsAtEnd(s: Stream): bool = + result = gzeof(GzFileStream(s).f) == 1 + +proc fsSetPosition(s: Stream, pos: int) = + if gzseek(GzFileStream(s).f, pos.ZOffT, SEEK_SET) == -1: + if GzFileStream(s).mode in {fmWrite, fmAppend}: + raise newException(IOError, "error in gzip stream while seeking! (file is in write/append mode!") + else: + raise newException(IOError, "error in gzip stream while seeking!") + +proc fsGetPosition(s: Stream): int = + result = gztell(GzFileStream(s).f).int + +proc fsReadData(s: Stream, buffer: pointer, bufLen: int): int = + result = gzread(GzFileStream(s).f, buffer, bufLen).int + if result == -1: + if GzFileStream(s).mode in {fmWrite, fmAppend}: + raise newException(IOError, "cannot read data from write-only gzip stream!") + else: + raise newException(IOError, "cannot read from stream!") + +proc fsPeekData(s: Stream, buffer: pointer, bufLen: int): int = + let gz = GzFileStream(s) + if gz.mode in {fmWrite, fmAppend}: + raise newException(IOError, "cannot peek data from write-only gzip stream!") + let pos = int(gztell(gz.f)) + result = fsReadData(s, buffer, bufLen) + fsSetPosition(s, pos) + +proc fsWriteData(s: Stream, buffer: pointer, bufLen: int) = + if gzwrite(GzFileStream(s).f, buffer, bufLen).int != bufLen: + if GzFileStream(s).mode in {fmWrite, fmAppend}: + raise newException(IOError, "cannot write data to gzip stream!") + else: + raise newException(IOError, "cannot write data to read-only gzip stream!") + + +proc newGzFileStream*(filename: string; mode=fmRead; level=Z_DEFAULT_COMPRESSION): GzFileStream = + ## Opens a Gzipfile as a file stream. `mode` can be + ## ``fmRead``, ``fmWrite`` or ``fmAppend``. + ## + ## Compression level can be set with ``level`` argument. Currently + ## ``Z_DEFAULT_COMPRESSION`` is 6. + ## + ## Note: ``level`` is ignored if ``mode`` is `fmRead` + ## + ## Note: There is only partial support for file seeking + ## - in fmRead mode, seeking randomly inside the gzip + ## file will lead to poor performance. + ## - in fmWrite, fmAppend mode, only forward seeking + ## is supported. + new(result) + case mode + of fmRead: result.f = gzopen(filename, "rb") + of fmWrite: result.f = gzopen(filename, "wb") + of fmAppend: result.f = gzopen(filename, "ab") + else: raise newException(IOError, "unsupported file mode '" & $mode & + "' for GzFileStream!") + if result.f.isNil: + let err = osLastError() + if err != OSErrorCode(0'i32): + raiseOSError(err) + if mode in {fmWrite, fmAppend}: + discard gzsetparams(result.f, level.int32, Z_DEFAULT_STRATEGY.int32) + + result.mode = mode + result.closeImpl = fsClose + result.atEndImpl = fsAtEnd + result.setPositionImpl = fsSetPosition + result.getPositionImpl = fsGetPosition + result.readDataImpl = fsReadData + result.peekDataImpl = fsPeekData + result.writeDataImpl = fsWriteData + result.flushImpl = fsFlush |