Skip to content

bzip2file stream for reading #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion tests/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
nimcache
ziptests
ziptests
zlibtests
gziptests
bzip2tests
18 changes: 18 additions & 0 deletions tests/bzip2tests.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import os, ../zip/bzip2files

proc readAllAndClose(f: Stream): string =
doAssert(not f.isNil, "error opening stream")
shallowCopy result, f.readAll()
f.close()

const path = currentSourcePath().splitPath().head

proc main() =
# reference text data
let text = newFileStream(path / "files/gzipfiletest.txt").readAllAndClose()
# reference BZIP2 archive (made with bzip2: stable 1.0.6 on OSX)
let arch_bz2 = newBz2FileStream(path / "files/gzipfiletest.txt.bz2").readAllAndClose()

doAssert(arch_bz2 == text)

main()
Binary file added tests/files/gzipfiletest.txt.bz2
Binary file not shown.
5 changes: 5 additions & 0 deletions zip.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ skipDirs = @["tests"]

requires "nim >= 0.10.0"

when defined(nimdistros):
import distros
foreignDep "bzip2"

task tests, "Run lib tests":
withDir "tests":
exec "nim c -r ziptests"
exec "nim c -r zlibtests"
exec "nim c -r gziptests"
exec "nim c -r bzip2tests"
25 changes: 25 additions & 0 deletions zip/bzip2.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
when defined(windows):
const libbz2 = "bzip2.dll"
elif defined(macosx):
const libbz2 = "libbz2.dylib"
else:
const libbz2 = "libbz2.so.1"

type
Pbytef* = cstring
Bz2File* = pointer

proc bz2libVersion*(): cstring {.cdecl, dynlib: libbz2,
importc: "BZ2_bzlibVersion".}

proc bz2open*(path: cstring, mode: cstring): Bz2File {.cdecl, dynlib: libbz2,
importc: "BZ2_bzopen".}

proc bz2read*(thefile: Bz2File, buf: pointer, length: int): int32 {.cdecl,
dynlib: libbz2, importc: "BZ2_bzread".}

proc bz2close*(thefile: Bz2File): int32 {.cdecl, dynlib: libbz2,
importc: "BZ2_bzclose".}

proc bz2error*(thefile: Bz2File, errnum: var int32): Pbytef {.cdecl,
dynlib: libbz2, importc: "BZ2_bzerror".}
37 changes: 37 additions & 0 deletions zip/bzip2files.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import os
import bzip2
import streams
export streams

## This module implements a bzip2file stream for reading.

type
Bz2FileStream* = ref object of Stream
mode: FileMode
f: Bz2File

proc fsClose(s: Stream) =
if not Bz2FileStream(s).f.isNil:
discard bz2close(Bz2FileStream(s).f)
Bz2FileStream(s).f = nil

proc fsReadData(s: Stream, buffer: pointer, bufLen: int): int =
result = bz2read(Bz2FileStream(s).f, buffer, bufLen).int
if result == -1:
raise newException(IOError, "cannot read from stream!")

proc newBz2FileStream*(filename: string, mode=fmRead): Bz2FileStream =
## Opens a Bz2file as a file stream. `mode` can only be ``fmRead``.
new(result)
case mode
of fmRead: result.f = bz2open(filename, "rb")
else: raise newException(IOError, "unsupported file mode '" & $mode &
"' for Bz2FileStream!")
if result.f.isNil:
let err = osLastError()
if err != OSErrorCode(0'i32):
raiseOSError(err)

result.mode = mode
result.closeImpl = fsClose
result.readDataImpl = fsReadData