-
-
Notifications
You must be signed in to change notification settings - Fork 23
/
count_reader.go
122 lines (107 loc) · 3.36 KB
/
count_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
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
/*
CountReader implementation.
*/
package bitio
import (
"io"
)
// CountReader is an improved version of Reader that also keeps track
// of the number of processed bits. If you don't need the number
// of processed bits, use the faster Reader.
//
// For convenience, it also implements io.Reader and io.ByteReader.
type CountReader struct {
*Reader
BitsCount int64 // Total number of bits read
}
// NewCountReader returns a new CountReader using the specified io.Reader as
// the input (source).
func NewCountReader(in io.Reader) *CountReader {
return &CountReader{NewReader(in), 0}
}
// Read reads up to len(p) bytes (8 * len(p) bits) from the underlying reader,
// and counts the number of bits read.
//
// Read implements io.Reader, and gives a byte-level view of the bit stream.
// This will give best performance if the underlying io.Reader is aligned
// to a byte boundary (else all the individual bytes are assembled from multiple bytes).
// Byte boundary can be ensured by calling Align().
func (r *CountReader) Read(p []byte) (n int, err error) {
n, err = r.Reader.Read(p)
r.BitsCount += int64(n) * 8
return
}
// ReadBits reads n bits and returns them as the lowest n bits of u.
func (r *CountReader) ReadBits(n uint8) (u uint64, err error) {
u, err = r.Reader.ReadBits(n)
if err == nil {
r.BitsCount += int64(n)
}
return
}
// ReadByte reads the next 8 bits and returns them as a byte.
//
// ReadByte implements io.ByteReader.
func (r *CountReader) ReadByte() (b byte, err error) {
b, err = r.Reader.ReadByte()
if err == nil {
r.BitsCount += 8
}
return
}
// ReadBool reads the next bit, and returns true if it is 1.
func (r *CountReader) ReadBool() (b bool, err error) {
b, err = r.Reader.ReadBool()
if err == nil {
r.BitsCount += 1
}
return
}
// Align aligns the bit stream to a byte boundary,
// so next read will read/use data from the next byte.
// Returns the number of unread / skipped bits.
func (r *CountReader) Align() (skipped uint8) {
skipped = r.Reader.Align()
r.BitsCount += int64(skipped)
return
}
// TryRead tries to read up to len(p) bytes (8 * len(p) bits) from the underlying reader.
//
// If there was a previous TryError, it does nothing. Else it calls Read(),
// returns the data it provides and stores the error in the TryError field.
func (r *CountReader) TryRead(p []byte) (n int) {
if r.TryError == nil {
n, r.TryError = r.Read(p)
}
return
}
// TryReadBits tries to read n bits.
//
// If there was a previous TryError, it does nothing. Else it calls ReadBits(),
// returns the data it provides and stores the error in the TryError field.
func (r *CountReader) TryReadBits(n uint8) (u uint64) {
if r.TryError == nil {
u, r.TryError = r.ReadBits(n)
}
return
}
// TryReadByte tries to read the next 8 bits and return them as a byte.
//
// If there was a previous TryError, it does nothing. Else it calls ReadByte(),
// returns the data it provides and stores the error in the TryError field.
func (r *CountReader) TryReadByte() (b byte) {
if r.TryError == nil {
b, r.TryError = r.ReadByte()
}
return
}
// TryReadBool tries to read the next bit, and return true if it is 1.
//
// If there was a previous TryError, it does nothing. Else it calls ReadBool(),
// returns the data it provides and stores the error in the TryError field.
func (r *CountReader) TryReadBool() (b bool) {
if r.TryError == nil {
b, r.TryError = r.ReadBool()
}
return
}