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
50
51
52
53
54
55
56
|
# 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 <https://www.gnu.org/licenses/>.
import os, streams, sugar
import bitreader, bitwriter, streamblock
proc transform*(operation: (BitReader, BitWriter) -> void, input, output: string) =
let inputStream = openFileStream(input, fmRead)
defer: inputStream.close()
let outputStream = openFileStream(output, fmWrite)
defer: outputStream.close()
operation(inputStream.bitReader(), outputStream.bitWriter())
proc compress*(bitReader: BitReader, bitWriter: BitWriter) =
while not bitReader.atEnd():
let streamBlock = streamblock.readRaw(bitReader)
streamBlock.writeSerialisedTo(bitWriter)
bitWriter.flush()
proc decompress*(bitReader: BitReader, bitWriter: BitWriter) =
var hasMore = true
while hasMore:
let streamBlock = streamblock.readSerialised(bitReader)
streamBlock.writeRawTo(bitWriter)
hasMore = not streamBlock.isLast()
bitWriter.flush()
proc printUsage(output: File) =
output.writeLine("Usage: " & paramStr(0) & " <compress|decompress> <input file> <output file>")
when isMainModule:
if paramCount() != 3:
stderr.writeLine("Error: invalid argument count.")
printUsage(stderr)
quit(1)
case paramStr(1):
of "compress": compress.transform(paramStr(2), paramStr(3))
of "decompress": decompress.transform(paramStr(2), paramStr(3))
else:
stderr.writeLine("Error: invalid operation.")
printUsage(stderr)
quit(1)
|