-
Notifications
You must be signed in to change notification settings - Fork 0
/
bit_buffer.go
147 lines (116 loc) · 3.19 KB
/
bit_buffer.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package bit_buffer
import (
"strings"
)
const BitBeginOffset = 7
// BitBuffer 在bit级别提供一些便于操作的API
type BitBuffer struct {
// 下一个要操作的byte的下标
nextIndex int
// 下一个要操作的byte的offset
nextBitOffset int
// buff当前对应的字节数组
bytes []byte
}
// New 创建一个可以用来写数据的位缓存空间
func New() *BitBuffer {
return &BitBuffer{
nextIndex: 0,
nextBitOffset: BitBeginOffset,
bytes: make([]byte, 1),
}
}
// SetBytes 设置buff底层的字节数组
func (x *BitBuffer) SetBytes(bytes []byte) *BitBuffer {
x.bytes = bytes
return x
}
// SeekHead 移动操作指针到头部
func (x *BitBuffer) SeekHead() *BitBuffer {
return x.Seek(0)
}
// SeekTail 移动指针到尾部
func (x *BitBuffer) SeekTail() *BitBuffer {
return x.Seek(len(x.bytes) * 8)
}
// Seek 移动指针到指定的position
func (x *BitBuffer) Seek(offset int) *BitBuffer {
// 保证空间是足够的
x.nextIndex = offset / 8
for len(x.bytes) <= x.nextIndex {
x.bytes = append(x.bytes, byte(0))
}
// 把便宜设置正确
x.nextBitOffset = BitBeginOffset - (offset % 8)
return x
}
// GetSeek 获取当前写指针
func (x *BitBuffer) GetSeek() int {
return x.nextIndex*8 + (BitBeginOffset - x.nextBitOffset)
}
// Capacity 获取当前的容量
func (x *BitBuffer) Capacity() int {
return len(x.bytes) * 8
}
// WriteBit 往缓存空间追加一个bit,会获取 bitValue 的最低位的bit值,1或者0
func (x *BitBuffer) WriteBit(bitValue int) *BitBuffer {
// 字节数组在需要的时候扩容
if x.nextIndex >= len(x.bytes) {
x.bytes = append(x.bytes, byte(0x0))
}
// 写入对应偏移的bit值,其他的bit位保持原值
x.bytes[x.nextIndex] = byte((bitValue&0x01)<<x.nextBitOffset) | (x.bytes[x.nextIndex] & ((0x1 << x.nextBitOffset) ^ 0xFF))
// 移动指针
x.nextBitOffset--
if x.nextBitOffset < 0 {
x.nextBitOffset = BitBeginOffset
x.nextIndex++
}
return x
}
// WriteByte 往缓存空间一次追加一个byte
func (x *BitBuffer) WriteByte(b byte) *BitBuffer {
for offset := BitBeginOffset; offset >= 0; offset-- {
x.WriteBit((int(b) >> offset) & 0x1)
}
return x
}
// ReadBit 从seek读取一个bit
func (x *BitBuffer) ReadBit() int {
// 读取对应offset的bit值
value := (x.bytes[x.nextIndex] & (0x1 << x.nextBitOffset)) >> x.nextBitOffset
// offset往后移动
x.nextBitOffset--
if x.nextBitOffset < 0 {
x.nextBitOffset = BitBeginOffset
x.nextIndex++
}
return int(value)
}
// IsTail 是否已经存在尾部了
func (x *BitBuffer) IsTail() bool {
return x.GetSeek() == x.Capacity()
}
// Bytes 返回当前缓存空间所对应的字节数组
func (x *BitBuffer) Bytes() []byte {
return x.bytes
}
// ToBinaryString 把当前的缓存空间转换为二进制字符串
func (x *BitBuffer) ToBinaryString() string {
buff := strings.Builder{}
loop:
for index, b := range x.bytes {
for offset := BitBeginOffset; offset >= 0; offset-- {
// 没有写内容的部分就不转换到字符串中了
if index == x.nextIndex && offset <= x.nextBitOffset {
break loop
}
if ((b >> offset) & 0x1) == 1 {
buff.WriteRune('1')
} else {
buff.WriteRune('0')
}
}
}
return buff.String()
}