-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathmain.go
More file actions
110 lines (94 loc) · 2.32 KB
/
Copy pathmain.go
File metadata and controls
110 lines (94 loc) · 2.32 KB
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"flag"
"fmt"
"os"
"strings"
"github.com/consensys/compress/lzss"
)
var (
flagDecompress = flag.Bool("d", false, "decompress")
flagIn = flag.String("i", "", "input file (required)")
flagOut = flag.String("o", "", "output file")
flagNoOut = flag.Bool("no_out", false, "no output")
flagReport = flag.Bool("r", false, "report compression ratio")
flagDict = flag.String("dict", "", "compression dictionary")
flagTable = flag.String("table", "", "Huffman table (required)")
flagVersion = flag.Bool("version", false, "report executable version")
)
const (
extension = ".linzip"
version = "0.4.0"
)
func quitF(format string, args ...interface{}) {
if _, err := fmt.Fprintf(os.Stderr, format, args...); err != nil {
panic(err)
}
os.Exit(1)
}
func assertNoError(err error) {
if err != nil {
quitF("%v\n", err)
}
}
func main() {
flag.Parse()
if *flagVersion {
fmt.Println("linzip v" + version)
os.Exit(0)
}
if *flagIn == "" {
quitF("no input file specified\n")
}
if *flagTable == "" {
quitF("no Huffman table specified\n")
}
in, err := os.ReadFile(*flagIn)
assertNoError(err)
var (
dict, out []byte
lenC, lenD int
)
if *flagDict != "" {
dict, err = os.ReadFile(*flagDict)
assertNoError(err)
}
tableData, err := os.ReadFile(*flagTable)
assertNoError(err)
table, err := lzss.NewHuffmanTable(tableData)
assertNoError(err)
if *flagOut != "" && *flagNoOut {
quitF("options -no_out and -o are mutually exclusive\n")
}
if *flagOut == "" { // construct a file name from the input name
if *flagDecompress {
if strings.HasSuffix(*flagIn, extension) {
*flagOut = (*flagIn)[:len(*flagIn)-len(extension)]
} else {
*flagOut = *flagIn + ".decompressed"
}
} else {
*flagOut = *flagIn + extension
}
}
if *flagDecompress {
out, err = lzss.Decompress(in, dict, table)
assertNoError(err)
lenC, lenD = len(in), len(out)
} else {
c, err := lzss.NewCompressor(dict, table)
assertNoError(err)
out, err = c.Compress(in)
assertNoError(err)
lenC, lenD = len(out), len(in)
}
if *flagNoOut {
*flagOut = ""
} else {
assertNoError(os.WriteFile(*flagOut, out, 0600))
}
if *flagReport {
ratioPct := lenD * 100 / lenC
fmt.Printf("%d B -> %d B compression ratio %d.%02d\n", len(in), len(out), ratioPct/100, ratioPct%100)
}
}