From 8af38da097b8358cb273baa37c748120461c718e Mon Sep 17 00:00:00 2001
From: pacien
Date: Fri, 30 Nov 2018 16:57:32 +0100
Subject: isolate bit IO
---
src/bitio/bitreader.nim | 57 +++++++++++++++++
src/bitio/bitwriter.nim | 59 ++++++++++++++++++
src/bitreader.nim | 57 -----------------
src/bitwriter.nim | 59 ------------------
src/huffmandecoder.nim | 2 +-
src/huffmanencoder.nim | 2 +-
src/huffmantree.nim | 2 +-
src/lzssblock.nim | 2 +-
src/main.nim | 2 +-
src/rawblock.nim | 2 +-
src/streamblock.nim | 2 +-
tests/tbitio.nim | 152 ++++++++++++++++++++++++++++++++++++++++++++++
tests/tbitreader.nim | 84 -------------------------
tests/tbitwriter.nim | 85 --------------------------
tests/thuffmandecoder.nim | 2 +-
tests/thuffmanencoder.nim | 2 +-
tests/thuffmantree.nim | 2 +-
tests/trawblock.nim | 2 +-
tests/tstreamblock.nim | 2 +-
19 files changed, 280 insertions(+), 297 deletions(-)
create mode 100644 src/bitio/bitreader.nim
create mode 100644 src/bitio/bitwriter.nim
delete mode 100644 src/bitreader.nim
delete mode 100644 src/bitwriter.nim
create mode 100644 tests/tbitio.nim
delete mode 100644 tests/tbitreader.nim
delete mode 100644 tests/tbitwriter.nim
diff --git a/src/bitio/bitreader.nim b/src/bitio/bitreader.nim
new file mode 100644
index 0000000..e4ad225
--- /dev/null
+++ b/src/bitio/bitreader.nim
@@ -0,0 +1,57 @@
+# gzip-like LZSS compressor
+# Copyright (C) 2018 Pacien TRAN-GIRARD
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+import streams
+import ../integers
+
+type BitReader* = ref object
+ stream: Stream
+ bitOffset: int
+ overflowBuffer: uint8
+
+proc bitReader*(stream: Stream): BitReader =
+ BitReader(stream: stream, bitOffset: 0, overflowBuffer: 0)
+
+proc atEnd*(bitReader: BitReader): bool =
+ bitReader.bitOffset == 0 and bitReader.stream.atEnd()
+
+proc readBits*[T: SomeUnsignedInt](bitReader: BitReader, bits: int, to: typedesc[T]): T =
+ if bits < 0 or bits > sizeof(T) * wordBitLength: raise newException(RangeError, "invalid bit length")
+ if bits == 0: return 0
+ var bitsRead = 0
+ if bitReader.bitOffset > 0:
+ let bitsFromBuffer = min(bits, wordBitLength - bitReader.bitOffset)
+ result = (bitReader.overflowBuffer shr bitReader.bitOffset).leastSignificantBits(bitsFromBuffer)
+ bitReader.bitOffset = (bitReader.bitOffset + bitsFromBuffer) mod wordBitLength
+ bitsRead += bitsFromBuffer
+ while bits - bitsRead >= wordBitLength:
+ result = result or (bitReader.stream.readUint8().T shl bitsRead)
+ bitsRead += wordBitLength
+ if bits - bitsRead > 0:
+ bitReader.overflowBuffer = bitReader.stream.readUint8()
+ bitReader.bitOffset = bits - bitsRead
+ result = result or (bitReader.overflowBuffer.leastSignificantBits(bitReader.bitOffset).T shl bitsRead)
+
+proc readBool*(bitReader: BitReader): bool =
+ bitReader.readBits(1, uint8) != 0
+
+proc readSeq*[T: SomeUnsignedInt](bitReader: BitReader, maxBitLength: int, to: typedesc[T]): tuple[bitLength: int, data: seq[T]] =
+ result = (0, newSeqOfCap[T](maxBitLength /^ (sizeof(T) * wordBitLength)))
+ for _, chunkBitLength in chunks(maxBitLength, T):
+ if bitReader.atEnd(): return
+ let bitsToRead = if bitReader.stream.atEnd(): sizeof(T) * wordBitLength - bitReader.bitOffset else: chunkBitLength
+ result.bitLength += bitsToRead
+ result.data.add(bitReader.readBits(bitsToRead, T))
diff --git a/src/bitio/bitwriter.nim b/src/bitio/bitwriter.nim
new file mode 100644
index 0000000..f1b44ca
--- /dev/null
+++ b/src/bitio/bitwriter.nim
@@ -0,0 +1,59 @@
+# gzip-like LZSS compressor
+# Copyright (C) 2018 Pacien TRAN-GIRARD
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+import streams
+import ../integers
+
+type BitWriter* = ref object
+ stream: Stream
+ bitOffset: int
+ writeBuffer: uint8
+
+proc bitWriter*(stream: Stream): BitWriter =
+ BitWriter(stream: stream, bitOffset: 0, writeBuffer: 0)
+
+proc flush*(bitWriter: BitWriter) =
+ if bitWriter.bitOffset == 0: return
+ bitWriter.stream.write(bitWriter.writeBuffer)
+ bitWriter.stream.flush()
+ (bitWriter.bitOffset, bitWriter.writeBuffer) = (0, 0'u8)
+
+proc atEnd*(bitWriter: BitWriter): bool =
+ bitWriter.stream.atEnd()
+
+proc writeBits*(bitWriter: BitWriter, bits: int, value: SomeUnsignedInt) =
+ let valueContainerBitLength = sizeof(value) * wordBitLength
+ if bits < 0 or bits > valueContainerBitLength:
+ raise newException(RangeError, "invalid bit length")
+ var bitsToWrite = bits
+ if bitsToWrite + bitWriter.bitOffset >= wordBitLength:
+ bitWriter.stream.write(truncateToUint8(value shl bitWriter.bitOffset) or bitWriter.writeBuffer)
+ bitsToWrite -= wordBitLength - bitWriter.bitOffset
+ (bitWriter.bitOffset, bitWriter.writeBuffer) = (0, 0'u8)
+ while bitsToWrite >= wordBitLength:
+ bitWriter.stream.write(truncateToUint8(value shr (bits - bitsToWrite)))
+ bitsToWrite -= wordBitLength
+ if bitsToWrite > 0:
+ let left = truncateToUint8((value shl (valueContainerBitLength - bits)) shr (valueContainerBitLength - bitsToWrite))
+ bitWriter.writeBuffer = (left shl bitWriter.bitOffset) or bitWriter.writeBuffer
+ bitWriter.bitOffset = (bitWriter.bitOffset + bitsToWrite) mod wordBitLength
+
+proc writeBool*(bitWriter: BitWriter, value: bool) =
+ bitWriter.writeBits(1, value.uint8)
+
+proc writeSeq*[T: SomeUnsignedInt](bitWriter: BitWriter, bitLength: int, data: seq[T]) =
+ for i, chunkBitLength in chunks(bitLength, T):
+ bitWriter.writeBits(chunkBitLength, data[i])
diff --git a/src/bitreader.nim b/src/bitreader.nim
deleted file mode 100644
index baa8bf8..0000000
--- a/src/bitreader.nim
+++ /dev/null
@@ -1,57 +0,0 @@
-# gzip-like LZSS compressor
-# Copyright (C) 2018 Pacien TRAN-GIRARD
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-
-import streams
-import integers
-
-type BitReader* = ref object
- stream: Stream
- bitOffset: int
- overflowBuffer: uint8
-
-proc bitReader*(stream: Stream): BitReader =
- BitReader(stream: stream, bitOffset: 0, overflowBuffer: 0)
-
-proc atEnd*(bitReader: BitReader): bool =
- bitReader.bitOffset == 0 and bitReader.stream.atEnd()
-
-proc readBits*[T: SomeUnsignedInt](bitReader: BitReader, bits: int, to: typedesc[T]): T =
- if bits < 0 or bits > sizeof(T) * wordBitLength: raise newException(RangeError, "invalid bit length")
- if bits == 0: return 0
- var bitsRead = 0
- if bitReader.bitOffset > 0:
- let bitsFromBuffer = min(bits, wordBitLength - bitReader.bitOffset)
- result = (bitReader.overflowBuffer shr bitReader.bitOffset).leastSignificantBits(bitsFromBuffer)
- bitReader.bitOffset = (bitReader.bitOffset + bitsFromBuffer) mod wordBitLength
- bitsRead += bitsFromBuffer
- while bits - bitsRead >= wordBitLength:
- result = result or (bitReader.stream.readUint8().T shl bitsRead)
- bitsRead += wordBitLength
- if bits - bitsRead > 0:
- bitReader.overflowBuffer = bitReader.stream.readUint8()
- bitReader.bitOffset = bits - bitsRead
- result = result or (bitReader.overflowBuffer.leastSignificantBits(bitReader.bitOffset).T shl bitsRead)
-
-proc readBool*(bitReader: BitReader): bool =
- bitReader.readBits(1, uint8) != 0
-
-proc readSeq*[T: SomeUnsignedInt](bitReader: BitReader, maxBitLength: int, to: typedesc[T]): tuple[bitLength: int, data: seq[T]] =
- result = (0, newSeqOfCap[T](maxBitLength /^ (sizeof(T) * wordBitLength)))
- for _, chunkBitLength in chunks(maxBitLength, T):
- if bitReader.atEnd(): return
- let bitsToRead = if bitReader.stream.atEnd(): sizeof(T) * wordBitLength - bitReader.bitOffset else: chunkBitLength
- result.bitLength += bitsToRead
- result.data.add(bitReader.readBits(bitsToRead, T))
diff --git a/src/bitwriter.nim b/src/bitwriter.nim
deleted file mode 100644
index 4fe499a..0000000
--- a/src/bitwriter.nim
+++ /dev/null
@@ -1,59 +0,0 @@
-# gzip-like LZSS compressor
-# Copyright (C) 2018 Pacien TRAN-GIRARD
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-
-import streams
-import integers
-
-type BitWriter* = ref object
- stream: Stream
- bitOffset: int
- writeBuffer: uint8
-
-proc bitWriter*(stream: Stream): BitWriter =
- BitWriter(stream: stream, bitOffset: 0, writeBuffer: 0)
-
-proc flush*(bitWriter: BitWriter) =
- if bitWriter.bitOffset == 0: return
- bitWriter.stream.write(bitWriter.writeBuffer)
- bitWriter.stream.flush()
- (bitWriter.bitOffset, bitWriter.writeBuffer) = (0, 0'u8)
-
-proc atEnd*(bitWriter: BitWriter): bool =
- bitWriter.stream.atEnd()
-
-proc writeBits*(bitWriter: BitWriter, bits: int, value: SomeUnsignedInt) =
- let valueContainerBitLength = sizeof(value) * wordBitLength
- if bits < 0 or bits > valueContainerBitLength:
- raise newException(RangeError, "invalid bit length")
- var bitsToWrite = bits
- if bitsToWrite + bitWriter.bitOffset >= wordBitLength:
- bitWriter.stream.write(truncateToUint8(value shl bitWriter.bitOffset) or bitWriter.writeBuffer)
- bitsToWrite -= wordBitLength - bitWriter.bitOffset
- (bitWriter.bitOffset, bitWriter.writeBuffer) = (0, 0'u8)
- while bitsToWrite >= wordBitLength:
- bitWriter.stream.write(truncateToUint8(value shr (bits - bitsToWrite)))
- bitsToWrite -= wordBitLength
- if bitsToWrite > 0:
- let left = truncateToUint8((value shl (valueContainerBitLength - bits)) shr (valueContainerBitLength - bitsToWrite))
- bitWriter.writeBuffer = (left shl bitWriter.bitOffset) or bitWriter.writeBuffer
- bitWriter.bitOffset = (bitWriter.bitOffset + bitsToWrite) mod wordBitLength
-
-proc writeBool*(bitWriter: BitWriter, value: bool) =
- bitWriter.writeBits(1, value.uint8)
-
-proc writeSeq*[T: SomeUnsignedInt](bitWriter: BitWriter, bitLength: int, data: seq[T]) =
- for i, chunkBitLength in chunks(bitLength, T):
- bitWriter.writeBits(chunkBitLength, data[i])
diff --git a/src/huffmandecoder.nim b/src/huffmandecoder.nim
index 4df712a..5cf4ca5 100644
--- a/src/huffmandecoder.nim
+++ b/src/huffmandecoder.nim
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-import huffmantree, bitreader
+import huffmantree, bitio/bitreader
type HuffmanDecoder*[T: SomeUnsignedInt] = object
tree: HuffmanTreeNode[T]
diff --git a/src/huffmanencoder.nim b/src/huffmanencoder.nim
index 60c3d46..05ed64f 100644
--- a/src/huffmanencoder.nim
+++ b/src/huffmanencoder.nim
@@ -15,7 +15,7 @@
# along with this program. If not, see .
import tables
-import integers, huffmantree, bitwriter
+import integers, huffmantree, bitio/bitwriter
type HuffmanEncoder*[T, U: SomeUnsignedInt] = object
codebook: TableRef[T, U]
diff --git a/src/huffmantree.nim b/src/huffmantree.nim
index 0266dfb..6208ecf 100644
--- a/src/huffmantree.nim
+++ b/src/huffmantree.nim
@@ -15,7 +15,7 @@
# along with this program. If not, see .
import tables, heapqueue
-import integers, bitreader, bitwriter
+import integers, bitio/bitreader, bitio/bitwriter
const valueLengthFieldBitLength* = 6 # 64
diff --git a/src/lzssblock.nim b/src/lzssblock.nim
index be8c4f0..317e768 100644
--- a/src/lzssblock.nim
+++ b/src/lzssblock.nim
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-import bitreader, bitwriter
+import bitio/bitreader, bitio/bitwriter
type LzssBlock* = object
discard
diff --git a/src/main.nim b/src/main.nim
index 4fc137f..450f52d 100644
--- a/src/main.nim
+++ b/src/main.nim
@@ -15,7 +15,7 @@
# along with this program. If not, see .
import os, streams, sugar
-import bitreader, bitwriter, streamblock
+import bitio/bitreader, bitio/bitwriter, streamblock
proc transform*(operation: (BitReader, BitWriter) -> void, input, output: string) =
let inputStream = openFileStream(input, fmRead)
diff --git a/src/rawblock.nim b/src/rawblock.nim
index 4a83b1d..b9a1e63 100644
--- a/src/rawblock.nim
+++ b/src/rawblock.nim
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see .
-import integers, bitreader, bitwriter
+import integers, bitio/bitreader, bitio/bitwriter
const maxDataBitLength = high(uint16).int
const bitLengthFieldBitLength = 2 * wordBitLength
diff --git a/src/streamblock.nim b/src/streamblock.nim
index 403687e..ff649b1 100644
--- a/src/streamblock.nim
+++ b/src/streamblock.nim
@@ -15,7 +15,7 @@
# along with this program. If not, see .
import sequtils
-import integers, bitreader, bitwriter
+import integers, bitio/bitreader, bitio/bitwriter
import rawblock, lzssblock
type BlockKind* = enum
diff --git a/tests/tbitio.nim b/tests/tbitio.nim
new file mode 100644
index 0000000..0391974
--- /dev/null
+++ b/tests/tbitio.nim
@@ -0,0 +1,152 @@
+# gzip-like LZSS compressor
+# Copyright (C) 2018 Pacien TRAN-GIRARD
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+
+import unittest, streams, sugar, sequtils
+import integers
+import bitio/bitreader, bitio/bitwriter
+
+suite "bitreader":
+ test "readBool":
+ let stream = newStringStream()
+ defer: stream.close()
+ stream.write(0b1001_1111'u8)
+ stream.write(0b0110_0000'u8)
+ stream.setPosition(0)
+
+ let bitReader = stream.bitReader()
+ check lc[bitReader.readBool() | (_ <- 0..<16), bool] == @[
+ true, true, true, true, true, false, false, true,
+ false, false, false, false, false, true, true, false]
+
+ expect IOError: discard bitReader.readBool()
+ check bitReader.atEnd()
+
+ test "readBits":
+ let stream = newStringStream()
+ defer: stream.close()
+ stream.write(0xF00F'u16)
+ stream.write(0x0FFF'u16)
+ stream.setPosition(0)
+
+ let bitReader = stream.bitReader()
+ check bitReader.readBits(8, uint8) == 0x0F'u8
+ check bitReader.readBits(16, uint16) == 0xFFF0'u16
+ check bitReader.readBits(8, uint8) == 0x0F'u8
+
+ expect RangeError: discard bitReader.readBits(9, uint8)
+ expect IOError: discard bitReader.readBits(16, uint16)
+ check bitReader.atEnd()
+
+ test "readBits (look-ahead overflow)":
+ let stream = newStringStream()
+ defer: stream.close()
+ stream.write(0xAB'u8)
+ stream.setPosition(0)
+
+ let bitReader = stream.bitReader()
+ check bitReader.readBits(4, uint16) == 0x000B'u16
+ check bitReader.readBits(4, uint16) == 0x000A'u16
+ check bitReader.atEnd()
+
+ test "readBits (from buffer composition)":
+ let stream = newStringStream()
+ defer: stream.close()
+ stream.write(0xABCD'u16)
+ stream.setPosition(0)
+
+ let bitReader = stream.bitReader()
+ check bitReader.readBits(4, uint16) == 0x000D'u16
+ check bitReader.readBits(8, uint16) == 0x00BC'u16
+ check bitReader.readBits(4, uint16) == 0x000A'u16
+ check bitReader.atEnd()
+
+ test "readSeq":
+ let stream = newStringStream()
+ defer: stream.close()
+ stream.write(0x0F00_F0FF_F0F0_F0F0'u64)
+ stream.setPosition(0)
+
+ let bitReader = stream.bitReader()
+ check bitReader.readSeq(32, uint16) == (32, @[0xF0F0'u16, 0xF0F0])
+ check bitReader.readSeq(40, uint8) == (32, @[0xFF'u8, 0xF0, 0x00, 0x0F])
+ check bitReader.atEnd()
+
+suite "bitwriter":
+ test "flush":
+ let stream = newStringStream()
+ defer: stream.close()
+ let bitWriter = stream.bitWriter()
+
+ bitWriter.writeBool(true)
+ stream.setPosition(0)
+ expect IOError: discard stream.peekUint8()
+
+ bitWriter.flush()
+ stream.setPosition(0)
+ check stream.readUint8() == 0x01'u8
+ check stream.atEnd()
+
+ bitWriter.flush()
+ check stream.atEnd()
+
+ test "writeBool":
+ let stream = newStringStream()
+ defer: stream.close()
+
+ let bitWriter = stream.bitWriter()
+ let booleanValues = @[
+ true, true, true, true, true, false, false, true,
+ false, false, false, false, false, true, true, false,
+ true, true, false, true]
+ for b in booleanValues: bitWriter.writeBool(b)
+ bitWriter.flush()
+
+ stream.setPosition(0)
+ check stream.readUint8() == 0b1001_1111'u8
+ check stream.readUint8() == 0b0110_0000'u8
+ check stream.readUint8() == 0b0000_1011'u8
+ expect IOError: discard stream.readUint8()
+ check stream.atEnd()
+
+ test "writeBits":
+ let stream = newStringStream()
+ defer: stream.close()
+
+ let bitWriter = stream.bitWriter()
+ bitWriter.writeBits(4, 0xF00F'u16)
+ bitWriter.writeBits(16, 0xF00F'u16)
+ bitWriter.writeBits(16, 0xFFFF'u16)
+ bitWriter.flush()
+
+ stream.setPosition(0)
+ check stream.readUint16() == 0x00FF'u16
+ check stream.readUint16() == 0xFFFF'u16
+ check stream.readUint8() == 0x0F'u8
+ expect IOError: discard stream.readUint8()
+ check stream.atEnd()
+
+ test "writeSeq":
+ let stream = newStringStream()
+ defer: stream.close()
+
+ let bitWriter = stream.bitWriter()
+ bitWriter.writeSeq(32, @[0xF0F0'u16, 0xF0F0])
+ bitWriter.writeSeq(28, @[0xFF'u8, 0xF0, 0x00, 0xFF])
+ bitWriter.flush()
+
+ stream.setPosition(0)
+ check stream.readUint64() == 0x0F00_F0FF_F0F0_F0F0'u64
+ check stream.atEnd()
diff --git a/tests/tbitreader.nim b/tests/tbitreader.nim
deleted file mode 100644
index 294f6c9..0000000
--- a/tests/tbitreader.nim
+++ /dev/null
@@ -1,84 +0,0 @@
-# gzip-like LZSS compressor
-# Copyright (C) 2018 Pacien TRAN-GIRARD
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-
-import unittest, streams, sugar, sequtils
-import integers, bitreader
-
-suite "bitreader":
- test "readBool":
- let stream = newStringStream()
- defer: stream.close()
- stream.write(0b1001_1111'u8)
- stream.write(0b0110_0000'u8)
- stream.setPosition(0)
-
- let bitReader = stream.bitReader()
- check lc[bitReader.readBool() | (_ <- 0..<16), bool] == @[
- true, true, true, true, true, false, false, true,
- false, false, false, false, false, true, true, false]
-
- expect IOError: discard bitReader.readBool()
- check bitReader.atEnd()
-
- test "readBits":
- let stream = newStringStream()
- defer: stream.close()
- stream.write(0xF00F'u16)
- stream.write(0x0FFF'u16)
- stream.setPosition(0)
-
- let bitReader = stream.bitReader()
- check bitReader.readBits(8, uint8) == 0x0F'u8
- check bitReader.readBits(16, uint16) == 0xFFF0'u16
- check bitReader.readBits(8, uint8) == 0x0F'u8
-
- expect RangeError: discard bitReader.readBits(9, uint8)
- expect IOError: discard bitReader.readBits(16, uint16)
- check bitReader.atEnd()
-
- test "readBits (look-ahead overflow)":
- let stream = newStringStream()
- defer: stream.close()
- stream.write(0xAB'u8)
- stream.setPosition(0)
-
- let bitReader = stream.bitReader()
- check bitReader.readBits(4, uint16) == 0x000B'u16
- check bitReader.readBits(4, uint16) == 0x000A'u16
- check bitReader.atEnd()
-
- test "readBits (from buffer composition)":
- let stream = newStringStream()
- defer: stream.close()
- stream.write(0xABCD'u16)
- stream.setPosition(0)
-
- let bitReader = stream.bitReader()
- check bitReader.readBits(4, uint16) == 0x000D'u16
- check bitReader.readBits(8, uint16) == 0x00BC'u16
- check bitReader.readBits(4, uint16) == 0x000A'u16
- check bitReader.atEnd()
-
- test "readSeq":
- let stream = newStringStream()
- defer: stream.close()
- stream.write(0x0F00_F0FF_F0F0_F0F0'u64)
- stream.setPosition(0)
-
- let bitReader = stream.bitReader()
- check bitReader.readSeq(32, uint16) == (32, @[0xF0F0'u16, 0xF0F0])
- check bitReader.readSeq(40, uint8) == (32, @[0xFF'u8, 0xF0, 0x00, 0x0F])
- check bitReader.atEnd()
diff --git a/tests/tbitwriter.nim b/tests/tbitwriter.nim
deleted file mode 100644
index 2c570af..0000000
--- a/tests/tbitwriter.nim
+++ /dev/null
@@ -1,85 +0,0 @@
-# gzip-like LZSS compressor
-# Copyright (C) 2018 Pacien TRAN-GIRARD
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-
-import unittest, streams
-import integers, bitwriter
-
-suite "bitwriter":
- test "flush":
- let stream = newStringStream()
- defer: stream.close()
- let bitWriter = stream.bitWriter()
-
- bitWriter.writeBool(true)
- stream.setPosition(0)
- expect IOError: discard stream.peekUint8()
-
- bitWriter.flush()
- stream.setPosition(0)
- check stream.readUint8() == 0x01'u8
- check stream.atEnd()
-
- bitWriter.flush()
- check stream.atEnd()
-
- test "writeBool":
- let stream = newStringStream()
- defer: stream.close()
-
- let bitWriter = stream.bitWriter()
- let booleanValues = @[
- true, true, true, true, true, false, false, true,
- false, false, false, false, false, true, true, false,
- true, true, false, true]
- for b in booleanValues: bitWriter.writeBool(b)
- bitWriter.flush()
-
- stream.setPosition(0)
- check stream.readUint8() == 0b1001_1111'u8
- check stream.readUint8() == 0b0110_0000'u8
- check stream.readUint8() == 0b0000_1011'u8
- expect IOError: discard stream.readUint8()
- check stream.atEnd()
-
- test "writeBits":
- let stream = newStringStream()
- defer: stream.close()
-
- let bitWriter = stream.bitWriter()
- bitWriter.writeBits(4, 0xF00F'u16)
- bitWriter.writeBits(16, 0xF00F'u16)
- bitWriter.writeBits(16, 0xFFFF'u16)
- bitWriter.flush()
-
- stream.setPosition(0)
- check stream.readUint16() == 0x00FF'u16
- check stream.readUint16() == 0xFFFF'u16
- check stream.readUint8() == 0x0F'u8
- expect IOError: discard stream.readUint8()
- check stream.atEnd()
-
- test "writeSeq":
- let stream = newStringStream()
- defer: stream.close()
-
- let bitWriter = stream.bitWriter()
- bitWriter.writeSeq(32, @[0xF0F0'u16, 0xF0F0])
- bitWriter.writeSeq(28, @[0xFF'u8, 0xF0, 0x00, 0xFF])
- bitWriter.flush()
-
- stream.setPosition(0)
- check stream.readUint64() == 0x0F00_F0FF_F0F0_F0F0'u64
- check stream.atEnd()
diff --git a/tests/thuffmandecoder.nim b/tests/thuffmandecoder.nim
index d4d81b4..9b44e9d 100644
--- a/tests/thuffmandecoder.nim
+++ b/tests/thuffmandecoder.nim
@@ -15,7 +15,7 @@
# along with this program. If not, see .
import unittest, streams
-import bitreader, bitwriter
+import bitio/bitreader, bitio/bitwriter
import huffmantree, huffmandecoder
suite "huffdecoder":
diff --git a/tests/thuffmanencoder.nim b/tests/thuffmanencoder.nim
index 04318b7..9c46eed 100644
--- a/tests/thuffmanencoder.nim
+++ b/tests/thuffmanencoder.nim
@@ -15,7 +15,7 @@
# along with this program. If not, see .
import unittest, streams, tables
-import bitreader, bitwriter
+import bitio/bitreader, bitio/bitwriter
import huffmantree, huffmanencoder
suite "huffencoder":
diff --git a/tests/thuffmantree.nim b/tests/thuffmantree.nim
index bc6a505..467fac5 100644
--- a/tests/thuffmantree.nim
+++ b/tests/thuffmantree.nim
@@ -15,7 +15,7 @@
# along with this program. If not, see .
import unittest, streams, sequtils, tables, heapqueue
-import bitreader, bitwriter, huffmantree
+import bitio/bitreader, bitio/bitwriter, huffmantree
suite "huffmantree":
let tree = huffmanBranch(
diff --git a/tests/trawblock.nim b/tests/trawblock.nim
index 2544199..0271e33 100644
--- a/tests/trawblock.nim
+++ b/tests/trawblock.nim
@@ -15,7 +15,7 @@
# along with this program. If not, see .
import unittest, streams
-import bitreader, bitwriter, rawblock
+import bitio/bitreader, bitio/bitwriter, rawblock
suite "rawblock":
test "serialise":
diff --git a/tests/tstreamblock.nim b/tests/tstreamblock.nim
index 89f69e0..57eaf3a 100644
--- a/tests/tstreamblock.nim
+++ b/tests/tstreamblock.nim
@@ -15,7 +15,7 @@
# along with this program. If not, see .
import unittest, streams
-import bitreader, bitwriter, streamblock
+import bitio/bitreader, bitio/bitwriter, streamblock
suite "streamblock":
test "serialise":
--
cgit v1.2.3