-
Notifications
You must be signed in to change notification settings - Fork 0
/
bits.go
99 lines (88 loc) · 1.97 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
package rye
// Bits supports reading and writing individual bits.
type Bits struct {
Data []byte
Idx int
Ln int
}
// Copy the Bits.
func (b *Bits) Copy() *Bits {
out := &Bits{
Data: make([]byte, len(b.Data)),
Idx: b.Idx,
Ln: b.Ln,
}
copy(out.Data, b.Data)
return out
}
// ShallowCopy shares the underlying Data, but not the Ln or Idx values.
func (b *Bits) ShallowCopy() *Bits {
return &Bits{
Data: b.Data,
Idx: b.Idx,
Ln: b.Ln,
}
}
// Reset the Idx to 0. Syntactic sugar.
func (b *Bits) Reset() *Bits {
b.Idx = 0
return b
}
// Write a single bit to Bits.
func (b *Bits) Write(bit byte) *Bits {
idx := b.Idx / 8
for idx >= len(b.Data) {
b.Data = append(b.Data, 0)
}
b.Data[b.Idx/8] |= ((bit & 1) << (b.Idx % 8))
b.Idx++
if b.Idx > b.Ln {
b.Ln = b.Idx
}
return b
}
// WriteBits takes all the bits in "from" starting at from.Idx to from.Ln and
// writes them to b. The value of from.Idx is reset to 0 after this.
func (b *Bits) WriteBits(from *Bits) *Bits {
for from.Idx < from.Ln {
b.Write(from.Read())
}
from.Reset()
return b
}
// Read a single bit.
func (b *Bits) Read() byte {
bit := (b.Data[b.Idx/8] >> (b.Idx % 8)) & 1
b.Idx++
return bit
}
// ReadUint of n bits.
func (b *Bits) ReadUint(n byte) uint64 {
var u uint64
for i := byte(0); i < n; i++ {
u |= uint64(b.Read()) << i
}
return u
}
// WriteUint u as n bits.
func (b *Bits) WriteUint(u uint64, n byte) {
for i := byte(0); i < n; i++ {
b.Write(byte(u & 1))
u >>= 1
}
}
// WriteSubBits writes contents of sub with the length encoded with bitLn bits.
// This can be used to combine multiple *Bits all encoded with a common bitLn.
func (b *Bits) WriteSubBits(sub *Bits, bitLn byte) {
b.WriteUint(uint64(sub.Ln), bitLn)
b.WriteBits(sub.Reset())
}
// ReadSubBits reads a *Bits using bitLn to decode the length of the Bits.
func (b *Bits) ReadSubBits(bitLn byte) *Bits {
bln := uint(b.ReadUint(bitLn))
bi := &Bits{}
for j := uint(0); j < bln; j++ {
bi.Write(b.Read())
}
return bi
}