]>
Commit | Line | Data |
---|---|---|
5133f00e ILT |
1 | // Copyright 2011 The Go Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style | |
3 | // license that can be found in the LICENSE file. | |
4 | ||
5 | package lzw | |
6 | ||
7 | import ( | |
8 | "io" | |
9 | "io/ioutil" | |
10 | "os" | |
8039ca76 | 11 | "runtime" |
5133f00e ILT |
12 | "testing" |
13 | ) | |
14 | ||
15 | var filenames = []string{ | |
16 | "../testdata/e.txt", | |
17 | "../testdata/pi.txt", | |
18 | } | |
19 | ||
20 | // testFile tests that compressing and then decompressing the given file with | |
21 | // the given options yields equivalent bytes to the original file. | |
22 | func testFile(t *testing.T, fn string, order Order, litWidth int) { | |
23 | // Read the file, as golden output. | |
405ca104 | 24 | golden, err := os.Open(fn) |
5133f00e ILT |
25 | if err != nil { |
26 | t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err) | |
27 | return | |
28 | } | |
29 | defer golden.Close() | |
30 | ||
31 | // Read the file again, and push it through a pipe that compresses at the write end, and decompresses at the read end. | |
405ca104 | 32 | raw, err := os.Open(fn) |
5133f00e ILT |
33 | if err != nil { |
34 | t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err) | |
35 | return | |
36 | } | |
37 | ||
38 | piper, pipew := io.Pipe() | |
39 | defer piper.Close() | |
40 | go func() { | |
41 | defer raw.Close() | |
42 | defer pipew.Close() | |
43 | lzww := NewWriter(pipew, order, litWidth) | |
44 | defer lzww.Close() | |
45 | var b [4096]byte | |
46 | for { | |
47 | n, err0 := raw.Read(b[:]) | |
2fd401c8 | 48 | if err0 != nil && err0 != io.EOF { |
5133f00e ILT |
49 | t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0) |
50 | return | |
51 | } | |
52 | _, err1 := lzww.Write(b[:n]) | |
5133f00e ILT |
53 | if err1 != nil { |
54 | t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1) | |
55 | return | |
56 | } | |
2fd401c8 | 57 | if err0 == io.EOF { |
5133f00e ILT |
58 | break |
59 | } | |
60 | } | |
61 | }() | |
62 | lzwr := NewReader(piper, order, litWidth) | |
63 | defer lzwr.Close() | |
64 | ||
65 | // Compare the two. | |
66 | b0, err0 := ioutil.ReadAll(golden) | |
67 | b1, err1 := ioutil.ReadAll(lzwr) | |
68 | if err0 != nil { | |
69 | t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err0) | |
70 | return | |
71 | } | |
72 | if err1 != nil { | |
73 | t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err1) | |
74 | return | |
75 | } | |
adb0401d ILT |
76 | if len(b1) != len(b0) { |
77 | t.Errorf("%s (order=%d litWidth=%d): length mismatch %d != %d", fn, order, litWidth, len(b1), len(b0)) | |
5133f00e ILT |
78 | return |
79 | } | |
80 | for i := 0; i < len(b0); i++ { | |
adb0401d ILT |
81 | if b1[i] != b0[i] { |
82 | t.Errorf("%s (order=%d litWidth=%d): mismatch at %d, 0x%02x != 0x%02x\n", fn, order, litWidth, i, b1[i], b0[i]) | |
5133f00e ILT |
83 | return |
84 | } | |
85 | } | |
86 | } | |
87 | ||
88 | func TestWriter(t *testing.T) { | |
89 | for _, filename := range filenames { | |
90 | for _, order := range [...]Order{LSB, MSB} { | |
91 | // The test data "2.71828 etcetera" is ASCII text requiring at least 6 bits. | |
92 | for _, litWidth := range [...]int{6, 7, 8} { | |
93 | testFile(t, filename, order, litWidth) | |
94 | } | |
95 | } | |
96 | } | |
97 | } | |
98 | ||
4ccad563 ILT |
99 | func TestWriterReturnValues(t *testing.T) { |
100 | w := NewWriter(ioutil.Discard, LSB, 8) | |
101 | n, err := w.Write([]byte("asdf")) | |
102 | if n != 4 || err != nil { | |
103 | t.Errorf("got %d, %v, want 4, nil", n, err) | |
104 | } | |
105 | } | |
106 | ||
8039ca76 | 107 | func benchmarkEncoder(b *testing.B, n int) { |
5133f00e | 108 | b.StopTimer() |
8039ca76 | 109 | b.SetBytes(int64(n)) |
4ccad563 ILT |
110 | buf0, err := ioutil.ReadFile("../testdata/e.txt") |
111 | if err != nil { | |
112 | b.Fatal(err) | |
113 | } | |
114 | if len(buf0) == 0 { | |
115 | b.Fatalf("test file has no data") | |
116 | } | |
8039ca76 ILT |
117 | buf1 := make([]byte, n) |
118 | for i := 0; i < n; i += len(buf0) { | |
4ccad563 ILT |
119 | if len(buf0) > n-i { |
120 | buf0 = buf0[:n-i] | |
121 | } | |
8039ca76 ILT |
122 | copy(buf1[i:], buf0) |
123 | } | |
124 | buf0 = nil | |
125 | runtime.GC() | |
5133f00e ILT |
126 | b.StartTimer() |
127 | for i := 0; i < b.N; i++ { | |
9ff56c95 | 128 | w := NewWriter(ioutil.Discard, LSB, 8) |
8039ca76 | 129 | w.Write(buf1) |
5133f00e ILT |
130 | w.Close() |
131 | } | |
132 | } | |
8039ca76 ILT |
133 | |
134 | func BenchmarkEncoder1e4(b *testing.B) { | |
135 | benchmarkEncoder(b, 1e4) | |
136 | } | |
137 | ||
138 | func BenchmarkEncoder1e5(b *testing.B) { | |
139 | benchmarkEncoder(b, 1e5) | |
140 | } | |
141 | ||
142 | func BenchmarkEncoder1e6(b *testing.B) { | |
143 | benchmarkEncoder(b, 1e6) | |
144 | } |