-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbits.go
121 lines (103 loc) · 1.88 KB
/
bits.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
package consent
type bitWriter struct {
data []byte
cur byte
used uint
}
func (b *bitWriter) AppendByte(add byte, size uint) {
if size+b.used > 8 {
b.cur |= add << (8 - size) >> b.used
b.data = append(b.data, b.cur)
size -= 8 - b.used
b.cur = 0
b.used = 0
}
b.cur |= add << (8 - size) >> b.used
b.used += size
}
func (b *bitWriter) AppendBools(bools []bool) {
for i := range bools {
var v byte
if bools[i] {
v = 1
}
b.AppendByte(v, 1)
}
}
func (b *bitWriter) AppendBit(x bool) {
var v byte
if x {
v = 1
}
b.AppendByte(v, 1)
}
func (b *bitWriter) AppendBits(bits bitWriter) {
for i := range bits.data {
b.AppendByte(bits.data[i], 8)
}
b.AppendByte(bits.cur>>(8-bits.used), bits.used)
}
func (b *bitWriter) AppendInt(add int64, size uint) {
for size > 0 {
byteSize := size
if byteSize > 8 {
byteSize = 8
}
size -= byteSize
b.AppendByte(byte(add>>size), byteSize)
}
}
func (b *bitWriter) Bytes() []byte {
if b.used == 0 {
return b.data
}
return append(b.data, b.cur)
}
type bitReader struct {
cur byte
left uint
data []byte
}
func newBitReader(buf []byte) bitReader {
return bitReader{
data: buf,
}
}
func (b *bitReader) ReadByte(size uint) (byte, bool) {
if size <= b.left {
out := b.cur >> (8 - size)
b.cur = b.cur << size
b.left -= size
return out, true
}
if len(b.data) == 0 {
return 0, false
}
out := b.cur >> (8 - size)
size -= b.left
out |= b.data[0] >> (8 - size)
b.cur = b.data[0] << size
b.data = b.data[1:]
b.left = 8 - size
return out, true
}
func (b *bitReader) ReadInt(size uint) (int64, bool) {
var out int64
for size > 0 {
bitSize := size
if bitSize > 8 {
bitSize = 8
}
size -= bitSize
v, ok := b.ReadByte(bitSize)
if !ok {
return 0, false
}
out = out<<bitSize | int64(v)
}
return out, true
}
func (b *bitReader) ReadBit() (bool, bool) {
v, ok := b.ReadByte(1)
return v > 0, ok
}