forked from danielecook/seq-collection
-
Notifications
You must be signed in to change notification settings - Fork 0
/
gzip_stream.nim
49 lines (38 loc) · 1.34 KB
/
gzip_stream.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import zip/zlib
import streams
# Simple wrapper for exposing GzFile as a Stream.
# Based on https://stackoverflow.com/a/33104286
type
GZipStream* = object of StreamObj
f: GzFile
GzipStreamRef* = ref GZipStream
proc fsClose(s: Stream) =
discard gzclose(GZipStreamRef(s).f)
proc fsReadData(s: Stream, buffer: pointer, bufLen: int): int =
return gzread(GZipStreamRef(s).f, buffer, bufLen)
proc fsWriteData(s: Stream, buffer: pointer, bufLen: int) {.gcsafe.} =
discard gzwrite(GZipStreamRef(s).f, buffer, bufLen)
proc fsAtEnd(s: Stream): bool =
return gzeof(GZipStreamRef(s).f) != 0
proc newGZipStream*(f: GzFile): GZipStreamRef =
new result
result.f = f
result.closeImpl = fsClose
result.readDataImpl = fsReadData
result.writeDataImpl = fsWriteData
result.atEndImpl = fsAtEnd
proc newGZipStream*(filename: cstring, mode: cstring): GZipStreamRef =
var gz = gzopen(filename, mode)
if gz != nil: return newGZipStream(gz)
proc openGzRead*(fname: string): GZipStreamRef =
let s = newGZipStream(c_string(fname), "r")
if s == nil:
stderr.writeLine("Error opening ", fname, " for reading; exiting!")
quit(2)
return s
proc openGzWrite*(fname: string): GZipStreamRef =
let s = newGZipStream(c_string(fname), "w")
if s == nil:
stderr.writeLine("Error opening ", fname, " for writing; exiting!")
quit(2)
return s