...
1
2
3
4
5
6 package huff0
7
8 import (
9 "encoding/binary"
10 "errors"
11 "fmt"
12 "io"
13 )
14
15
16
17
18 type bitReaderBytes struct {
19 in []byte
20 off uint
21 value uint64
22 bitsRead uint8
23 }
24
25
26 func (b *bitReaderBytes) init(in []byte) error {
27 if len(in) < 1 {
28 return errors.New("corrupt stream: too short")
29 }
30 b.in = in
31 b.off = uint(len(in))
32
33 v := in[len(in)-1]
34 if v == 0 {
35 return errors.New("corrupt stream, did not find end of stream")
36 }
37 b.bitsRead = 64
38 b.value = 0
39 if len(in) >= 8 {
40 b.fillFastStart()
41 } else {
42 b.fill()
43 b.fill()
44 }
45 b.advance(8 - uint8(highBit32(uint32(v))))
46 return nil
47 }
48
49
50
51 func (b *bitReaderBytes) peekByteFast() uint8 {
52 got := uint8(b.value >> 56)
53 return got
54 }
55
56 func (b *bitReaderBytes) advance(n uint8) {
57 b.bitsRead += n
58 b.value <<= n & 63
59 }
60
61
62
63 func (b *bitReaderBytes) fillFast() {
64 if b.bitsRead < 32 {
65 return
66 }
67
68
69 v := b.in[b.off-4 : b.off]
70 low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
71 b.value |= uint64(low) << (b.bitsRead - 32)
72 b.bitsRead -= 32
73 b.off -= 4
74 }
75
76
77 func (b *bitReaderBytes) fillFastStart() {
78
79 b.value = binary.LittleEndian.Uint64(b.in[b.off-8:])
80 b.bitsRead = 0
81 b.off -= 8
82 }
83
84
85 func (b *bitReaderBytes) fill() {
86 if b.bitsRead < 32 {
87 return
88 }
89 if b.off > 4 {
90 v := b.in[b.off-4 : b.off]
91 low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
92 b.value |= uint64(low) << (b.bitsRead - 32)
93 b.bitsRead -= 32
94 b.off -= 4
95 return
96 }
97 for b.off > 0 {
98 b.value |= uint64(b.in[b.off-1]) << (b.bitsRead - 8)
99 b.bitsRead -= 8
100 b.off--
101 }
102 }
103
104
105 func (b *bitReaderBytes) finished() bool {
106 return b.off == 0 && b.bitsRead >= 64
107 }
108
109 func (b *bitReaderBytes) remaining() uint {
110 return b.off*8 + uint(64-b.bitsRead)
111 }
112
113
114 func (b *bitReaderBytes) close() error {
115
116 b.in = nil
117 if b.remaining() > 0 {
118 return fmt.Errorf("corrupt input: %d bits remain on stream", b.remaining())
119 }
120 if b.bitsRead > 64 {
121 return io.ErrUnexpectedEOF
122 }
123 return nil
124 }
125
126
127
128
129 type bitReaderShifted struct {
130 in []byte
131 off uint
132 value uint64
133 bitsRead uint8
134 }
135
136
137 func (b *bitReaderShifted) init(in []byte) error {
138 if len(in) < 1 {
139 return errors.New("corrupt stream: too short")
140 }
141 b.in = in
142 b.off = uint(len(in))
143
144 v := in[len(in)-1]
145 if v == 0 {
146 return errors.New("corrupt stream, did not find end of stream")
147 }
148 b.bitsRead = 64
149 b.value = 0
150 if len(in) >= 8 {
151 b.fillFastStart()
152 } else {
153 b.fill()
154 b.fill()
155 }
156 b.advance(8 - uint8(highBit32(uint32(v))))
157 return nil
158 }
159
160
161
162 func (b *bitReaderShifted) peekBitsFast(n uint8) uint16 {
163 return uint16(b.value >> ((64 - n) & 63))
164 }
165
166 func (b *bitReaderShifted) advance(n uint8) {
167 b.bitsRead += n
168 b.value <<= n & 63
169 }
170
171
172
173 func (b *bitReaderShifted) fillFast() {
174 if b.bitsRead < 32 {
175 return
176 }
177
178
179 v := b.in[b.off-4 : b.off]
180 low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
181 b.value |= uint64(low) << ((b.bitsRead - 32) & 63)
182 b.bitsRead -= 32
183 b.off -= 4
184 }
185
186
187 func (b *bitReaderShifted) fillFastStart() {
188
189 b.value = binary.LittleEndian.Uint64(b.in[b.off-8:])
190 b.bitsRead = 0
191 b.off -= 8
192 }
193
194
195 func (b *bitReaderShifted) fill() {
196 if b.bitsRead < 32 {
197 return
198 }
199 if b.off > 4 {
200 v := b.in[b.off-4 : b.off]
201 low := (uint32(v[0])) | (uint32(v[1]) << 8) | (uint32(v[2]) << 16) | (uint32(v[3]) << 24)
202 b.value |= uint64(low) << ((b.bitsRead - 32) & 63)
203 b.bitsRead -= 32
204 b.off -= 4
205 return
206 }
207 for b.off > 0 {
208 b.value |= uint64(b.in[b.off-1]) << ((b.bitsRead - 8) & 63)
209 b.bitsRead -= 8
210 b.off--
211 }
212 }
213
214 func (b *bitReaderShifted) remaining() uint {
215 return b.off*8 + uint(64-b.bitsRead)
216 }
217
218
219 func (b *bitReaderShifted) close() error {
220
221 b.in = nil
222 if b.remaining() > 0 {
223 return fmt.Errorf("corrupt input: %d bits remain on stream", b.remaining())
224 }
225 if b.bitsRead > 64 {
226 return io.ErrUnexpectedEOF
227 }
228 return nil
229 }
230
View as plain text