forked from mewkiz/flac
-
Notifications
You must be signed in to change notification settings - Fork 0
/
reader.go
84 lines (76 loc) · 1.58 KB
/
reader.go
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
// Package bits provides bit access operations and binary decoding algorithms.
package bits
import (
"fmt"
"io"
)
// A Reader handles bit reading operations. It buffers bits up to the next byte
// boundary.
type Reader struct {
// Underlying reader.
r io.Reader
// Temporary read buffer.
buf [8]uint8
// Between 0 and 7 buffered bits since previous read operations.
x uint8
// The number of buffered bits in x.
n uint
}
// NewReader returns a new Reader that reads bits from r.
func NewReader(r io.Reader) *Reader {
return &Reader{r: r}
}
// Read reads and returns the next n bits, at most 64. It buffers bits up to the
// next byte boundary.
func (br *Reader) Read(n uint) (x uint64, err error) {
if n == 0 {
return 0, nil
}
if n > 64 {
return 0, fmt.Errorf("bit.Reader.Read: invalid number of bits; n (%d) exceeds 64", n)
}
// Read buffered bits.
if br.n > 0 {
switch {
case br.n == n:
br.n = 0
return uint64(br.x), nil
case br.n > n:
br.n -= n
mask := ^uint8(0) << br.n
x = uint64(br.x&mask) >> br.n
br.x &^= mask
return x, nil
}
n -= br.n
x = uint64(br.x)
br.n = 0
}
// Fill the temporary buffer.
bytes := n / 8
bits := n % 8
if bits > 0 {
bytes++
}
_, err = io.ReadFull(br.r, br.buf[:bytes])
if err != nil {
return 0, err
}
// Read bits from the temporary buffer.
for _, b := range br.buf[:bytes-1] {
x <<= 8
x |= uint64(b)
}
b := br.buf[bytes-1]
if bits > 0 {
x <<= bits
br.n = 8 - bits
mask := ^uint8(0) << br.n
x |= uint64(b&mask) >> br.n
br.x = b & ^mask
} else {
x <<= 8
x |= uint64(b)
}
return x, nil
}