-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathbits.go
63 lines (51 loc) · 1.1 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
package iabtcfv2
type Bits struct {
Position uint
Bytes []byte
}
var (
bytePows = []byte{128, 64, 32, 16, 8, 4, 2, 1}
)
func NewBits(bytes []byte) *Bits {
return &Bits{Bytes: bytes, Position: 0}
}
func (b *Bits) ReadBool() bool {
byteIndex := b.Position / 8
bitIndex := b.Position % 8
b.Position++
return (b.Bytes[byteIndex] & bytePows[bitIndex]) != 0
}
func (b *Bits) WriteBool(v bool) {
byteIndex := b.Position / 8
shift := (byteIndex+1)*8 - b.Position - 1
b.Position++
if v {
b.Bytes[byteIndex] |= 1 << uint(shift)
} else {
b.Bytes[byteIndex] &^= 1 << uint(shift)
}
}
func (b *Bits) ReadInt(n uint) int {
v := 0
for i, shift := uint(0), n-1; i < n; i++ {
if b.ReadBool() {
v += 1 << uint(shift)
}
shift--
}
return v
}
func (b *Bits) WriteInt(v int, n uint) {
b.WriteNumber(int64(v), n)
}
func (b *Bits) WriteNumber(v int64, n uint) {
startOffset := int(b.Position)
for i := int(n) - 1; i >= 0; i-- {
index := startOffset + i
byteIndex := index / 8
shift := (byteIndex+1)*8 - index - 1
b.Bytes[byteIndex] |= byte(v%2) << uint(shift)
v /= 2
}
b.Position += n
}