summaryrefslogtreecommitdiff
path: root/libgo/go/compress/flate/flate_test.go
blob: bfd3b8381d05c0582eebffa31d426cf395230aa3 (plain)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This test tests some internals of the flate package.
// The tests in package compress/gzip serve as the
// end-to-end test of the decompressor.

package flate

import (
	"bytes"
	"reflect"
	"testing"
)

// The Huffman code lengths used by the fixed-format Huffman blocks.
var fixedHuffmanBits = [...]int{
	// 0-143 length 8
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,

	// 144-255 length 9
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
	9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,

	// 256-279 length 7
	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
	7, 7, 7, 7, 7, 7, 7, 7,

	// 280-287 length 8
	8, 8, 8, 8, 8, 8, 8, 8,
}

type InitDecoderTest struct {
	in  []int
	out huffmanDecoder
	ok  bool
}

var initDecoderTests = []*InitDecoderTest{
	// Example from Connell 1973,
	&InitDecoderTest{
		[]int{3, 5, 2, 4, 3, 5, 5, 4, 4, 3, 4, 5},
		huffmanDecoder{
			2, 5,
			[maxCodeLen + 1]int{2: 0, 4, 13, 31},
			[maxCodeLen + 1]int{2: 0, 1, 6, 20},
			// Paper used different code assignment:
			// 2, 9, 4, 0, 10, 8, 3, 7, 1, 5, 11, 6
			// Reordered here so that codes of same length
			// are assigned to increasing numbers.
			[]int{2, 0, 4, 9, 3, 7, 8, 10, 1, 5, 6, 11},
		},
		true,
	},

	// Example from RFC 1951 section 3.2.2
	&InitDecoderTest{
		[]int{2, 1, 3, 3},
		huffmanDecoder{
			1, 3,
			[maxCodeLen + 1]int{1: 0, 2, 7},
			[maxCodeLen + 1]int{1: 0, 1, 4},
			[]int{1, 0, 2, 3},
		},
		true,
	},

	// Second example from RFC 1951 section 3.2.2
	&InitDecoderTest{
		[]int{3, 3, 3, 3, 3, 2, 4, 4},
		huffmanDecoder{
			2, 4,
			[maxCodeLen + 1]int{2: 0, 6, 15},
			[maxCodeLen + 1]int{2: 0, 1, 8},
			[]int{5, 0, 1, 2, 3, 4, 6, 7},
		},
		true,
	},

	// Static Huffman codes (RFC 1951 section 3.2.6)
	&InitDecoderTest{
		fixedHuffmanBits[0:],
		fixedHuffmanDecoder,
		true,
	},

	// Illegal input.
	&InitDecoderTest{
		[]int{},
		huffmanDecoder{},
		false,
	},

	// Illegal input.
	&InitDecoderTest{
		[]int{0, 0, 0, 0, 0, 0, 0},
		huffmanDecoder{},
		false,
	},
}

func TestInitDecoder(t *testing.T) {
	for i, tt := range initDecoderTests {
		var h huffmanDecoder
		if h.init(tt.in) != tt.ok {
			t.Errorf("test %d: init = %v", i, !tt.ok)
			continue
		}
		if !reflect.DeepEqual(&h, &tt.out) {
			t.Errorf("test %d:\nhave %v\nwant %v", i, h, tt.out)
		}
	}
}

func TestUncompressedSource(t *testing.T) {
	decoder := NewReader(bytes.NewBuffer([]byte{0x01, 0x01, 0x00, 0xfe, 0xff, 0x11}))
	output := make([]byte, 1)
	n, error := decoder.Read(output)
	if n != 1 || error != nil {
		t.Fatalf("decoder.Read() = %d, %v, want 1, nil", n, error)
	}
	if output[0] != 0x11 {
		t.Errorf("output[0] = %x, want 0x11", output[0])
	}
}