blob: 95d94e74aa0c7ce88e09167c3a0f4bea44ad2b41 [file] [log] [blame]
// Copyright 2019 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package flatecut
import (
"compress/flate"
"io"
"testing"
"github.com/google/wuffs/internal/testcut"
)
func TestCut(t *testing.T) {
testcut.Test(t, SmallestValidMaxEncodedLen, Cut, newReader, []string{
"artificial/deflate-backref-crosses-blocks.deflate",
"artificial/deflate-distance-32768.deflate",
"romeo.txt.deflate",
"romeo.txt.fixed-huff.deflate",
})
}
func BenchmarkCut(b *testing.B) {
testcut.Benchmark(b, SmallestValidMaxEncodedLen, Cut, newReader,
"pi.txt.zlib", 2, 4, 100003)
}
func newReader(r io.Reader) (io.ReadCloser, error) {
return flate.NewReader(r), nil
}
func TestHuffmanDecode(t *testing.T) {
// This exercises the "ABCDEFGH" example from RFC 1951 section 3.2.2,
// discussed in the "type huffman" doc comment.
const src = "HEADFACE"
codes := []string{
'A': " 010",
'B': " 011",
'C': " 100",
'D': " 101",
'E': " 110",
'F': " 00",
'G': "1110",
'H': "1111",
}
encoded := []byte(nil)
encBits := uint32(0)
encNBits := uint32(0)
for _, s := range src {
for _, c := range codes[s] {
if c == ' ' {
continue
}
if c == '1' {
encBits |= 1 << encNBits
}
encNBits++
if encNBits == 8 {
encoded = append(encoded, uint8(encBits))
encBits = 0
encNBits = 0
}
}
}
if encNBits > 0 {
encoded = append(encoded, uint8(encBits))
}
h := huffman{
counts: [maxCodeBits + 1]uint32{
2: 1, 3: 5, 4: 2,
},
symbols: [maxNumCodes]int32{
0: 'F', 1: 'A', 2: 'B', 3: 'C', 4: 'D', 5: 'E', 6: 'G', 7: 'H',
},
}
h.constructLookUpTable()
b := &bitstream{
bytes: encoded,
}
decoded := []byte(nil)
for _ = range src {
c := h.decode(b)
if c < 0 {
decoded = append(decoded, '!')
break
}
decoded = append(decoded, uint8(c))
}
if got, want := string(decoded), src; got != want {
t.Fatalf("got %q, want %q", got, want)
}
}