[feat] package bits: new struct BitWriter

pull/2/head
q191201771 5 years ago
parent 4ac6c19305
commit e05f504b03

@ -12,8 +12,8 @@ package nazabits
type BitReader struct {
core []byte
index int
pos int // 从左往右
index uint
pos uint // 从左往右
}
func NewBitReader(b []byte) BitReader {
@ -22,7 +22,7 @@ func NewBitReader(b []byte) BitReader {
}
}
func (br *BitReader) ReadBit() int {
func (br *BitReader) ReadBit() uint8 {
res := GetBit8(br.core[br.index], 7-br.pos)
br.pos++
if br.pos == 8 {
@ -32,19 +32,49 @@ func (br *BitReader) ReadBit() int {
return res
}
// 从高位(左边)开始读取
func (br *BitReader) ReadBits(n int) int {
var res int
for i := 0; i < n; i++ {
res = (res << 1) | br.ReadBit()
// 目前限制一次最多读8位大于8位可以分多次读或者以后把限制放开
func (br *BitReader) ReadBits(n uint) (r uint8) {
var i uint
for i = 0; i < n; i++ {
r = (r << 1) | br.ReadBit()
}
return
}
// ----------------------------------------------------------------------------
type BitWriter struct {
core []byte
index int
pos uint // 从左往右
}
func NewBitWriter(b []byte) BitWriter {
return BitWriter{
core: b,
}
}
func (bw *BitWriter) WriteBit(b uint8) {
bw.core[bw.index] |= b << (7 - bw.pos)
bw.pos++
if bw.pos == 8 {
bw.pos = 0
bw.index++
}
}
// 目前限制一次最多写8位大于8位可以分多次写或者以后把限制放开
func (bw *BitWriter) WriteBits(n int, v uint8) {
for i := n - 1; i >= 0; i-- {
bw.WriteBit(v >> uint8(i))
}
return res
}
// ----------------------------------------------------------------------------
// @param pos: 取值范围 [0, 7]0表示最低位
func GetBit8(v uint8, pos int) int {
func GetBit8(v uint8, pos uint) uint8 {
return GetBits8(v, pos, 1)
}
@ -56,26 +86,26 @@ func GetBit8(v uint8, pos int) int {
// pos: 2
// n: .. ..
//
func GetBits8(v uint8, pos int, n int) int {
return int(v >> uint(pos) & m[n])
func GetBits8(v uint8, pos uint, n uint) uint8 {
return v >> pos & m[n]
}
func GetBit16(v []byte, pos int) int {
func GetBit16(v []byte, pos uint) uint8 {
if pos < 8 {
return GetBit8(v[1], pos)
}
return GetBit8(v[0], pos-8)
}
func GetBits16(v []byte, pos int, n int) int {
func GetBits16(v []byte, pos uint, n uint) uint16 {
if pos < 8 {
if pos+n < 9 {
return GetBits8(v[1], pos, n)
return uint16(GetBits8(v[1], pos, n))
}
return GetBits8(v[1], pos, 8-pos) | GetBits8(v[0], 0, pos+n-8)<<(8-uint8(pos))
return uint16(GetBits8(v[1], pos, 8-pos)) | uint16(GetBits8(v[0], 0, pos+n-8))<<(8-pos)
}
return GetBits8(v[0], pos-8, n)
return uint16(GetBits8(v[0], pos-8, n))
}
var m []uint8

@ -16,75 +16,75 @@ import (
)
func TestGetBit8(t *testing.T) {
assert.Equal(t, 0, nazabits.GetBit8(0, 0))
assert.Equal(t, 1, nazabits.GetBit8(1<<1, 1))
assert.Equal(t, 1, nazabits.GetBit8(1<<1+1<<2, 2))
assert.Equal(t, 1, nazabits.GetBit8(1<<3+1<<4+1<<5, 3))
assert.Equal(t, 0, nazabits.GetBit8(0, 4))
assert.Equal(t, 1, nazabits.GetBit8(1<<5, 5))
assert.Equal(t, 0, nazabits.GetBit8(1+1<<5+1<<7, 6))
assert.Equal(t, 0, nazabits.GetBit8(0, 7))
assert.Equal(t, uint8(0), nazabits.GetBit8(0, 0))
assert.Equal(t, uint8(1), nazabits.GetBit8(1<<1, 1))
assert.Equal(t, uint8(1), nazabits.GetBit8(1<<1+1<<2, 2))
assert.Equal(t, uint8(1), nazabits.GetBit8(1<<3+1<<4+1<<5, 3))
assert.Equal(t, uint8(0), nazabits.GetBit8(0, 4))
assert.Equal(t, uint8(1), nazabits.GetBit8(1<<5, 5))
assert.Equal(t, uint8(0), nazabits.GetBit8(1+1<<5+1<<7, 6))
assert.Equal(t, uint8(0), nazabits.GetBit8(0, 7))
}
func TestGetBits8(t *testing.T) {
// 0110 1001 = 1 + 8 + 32 + 64 = 105
v := uint8(105)
assert.Equal(t, 1, nazabits.GetBits8(v, 0, 1))
assert.Equal(t, 0, nazabits.GetBits8(v, 7, 1))
assert.Equal(t, 1, nazabits.GetBits8(v, 0, 2))
assert.Equal(t, 1, nazabits.GetBits8(v, 6, 2))
assert.Equal(t, 1, nazabits.GetBits8(v, 0, 3))
assert.Equal(t, 5, nazabits.GetBits8(v, 3, 3))
assert.Equal(t, 10, nazabits.GetBits8(v, 2, 4))
assert.Equal(t, 26, nazabits.GetBits8(v, 2, 5))
assert.Equal(t, 26, nazabits.GetBits8(v, 2, 6))
assert.Equal(t, 105, nazabits.GetBits8(v, 0, 7))
assert.Equal(t, 105, nazabits.GetBits8(v, 0, 8))
assert.Equal(t, uint8(1), nazabits.GetBits8(v, 0, 1))
assert.Equal(t, uint8(0), nazabits.GetBits8(v, 7, 1))
assert.Equal(t, uint8(1), nazabits.GetBits8(v, 0, 2))
assert.Equal(t, uint8(1), nazabits.GetBits8(v, 6, 2))
assert.Equal(t, uint8(1), nazabits.GetBits8(v, 0, 3))
assert.Equal(t, uint8(5), nazabits.GetBits8(v, 3, 3))
assert.Equal(t, uint8(10), nazabits.GetBits8(v, 2, 4))
assert.Equal(t, uint8(26), nazabits.GetBits8(v, 2, 5))
assert.Equal(t, uint8(26), nazabits.GetBits8(v, 2, 6))
assert.Equal(t, uint8(105), nazabits.GetBits8(v, 0, 7))
assert.Equal(t, uint8(105), nazabits.GetBits8(v, 0, 8))
}
func TestGetBit16(t *testing.T) {
v := []byte{48, 57} // 12345 {0011 0000, 0011 1001}
assert.Equal(t, 1, nazabits.GetBit16(v, 0))
assert.Equal(t, 0, nazabits.GetBit16(v, 1))
assert.Equal(t, 0, nazabits.GetBit16(v, 2))
assert.Equal(t, 1, nazabits.GetBit16(v, 3))
assert.Equal(t, 1, nazabits.GetBit16(v, 4))
assert.Equal(t, 1, nazabits.GetBit16(v, 5))
assert.Equal(t, 0, nazabits.GetBit16(v, 6))
assert.Equal(t, 0, nazabits.GetBit16(v, 7))
assert.Equal(t, 0, nazabits.GetBit16(v, 8))
assert.Equal(t, 0, nazabits.GetBit16(v, 9))
assert.Equal(t, 0, nazabits.GetBit16(v, 10))
assert.Equal(t, 0, nazabits.GetBit16(v, 11))
assert.Equal(t, 1, nazabits.GetBit16(v, 12))
assert.Equal(t, 1, nazabits.GetBit16(v, 13))
assert.Equal(t, 0, nazabits.GetBit16(v, 14))
assert.Equal(t, 0, nazabits.GetBit16(v, 15))
assert.Equal(t, uint8(1), nazabits.GetBit16(v, 0))
assert.Equal(t, uint8(0), nazabits.GetBit16(v, 1))
assert.Equal(t, uint8(0), nazabits.GetBit16(v, 2))
assert.Equal(t, uint8(1), nazabits.GetBit16(v, 3))
assert.Equal(t, uint8(1), nazabits.GetBit16(v, 4))
assert.Equal(t, uint8(1), nazabits.GetBit16(v, 5))
assert.Equal(t, uint8(0), nazabits.GetBit16(v, 6))
assert.Equal(t, uint8(0), nazabits.GetBit16(v, 7))
assert.Equal(t, uint8(0), nazabits.GetBit16(v, 8))
assert.Equal(t, uint8(0), nazabits.GetBit16(v, 9))
assert.Equal(t, uint8(0), nazabits.GetBit16(v, 10))
assert.Equal(t, uint8(0), nazabits.GetBit16(v, 11))
assert.Equal(t, uint8(1), nazabits.GetBit16(v, 12))
assert.Equal(t, uint8(1), nazabits.GetBit16(v, 13))
assert.Equal(t, uint8(0), nazabits.GetBit16(v, 14))
assert.Equal(t, uint8(0), nazabits.GetBit16(v, 15))
}
func TestGetBits16(t *testing.T) {
v := []byte{48, 57} // 12345 {0011 0000, 0011 1001}
assert.Equal(t, 12345, nazabits.GetBits16(v, 0, 16))
assert.Equal(t, 1, nazabits.GetBits16(v, 0, 1))
assert.Equal(t, 0, nazabits.GetBits16(v, 1, 2))
assert.Equal(t, 6, nazabits.GetBits16(v, 2, 3))
assert.Equal(t, 7, nazabits.GetBits16(v, 3, 4))
assert.Equal(t, 3, nazabits.GetBits16(v, 4, 5))
assert.Equal(t, 1, nazabits.GetBits16(v, 5, 6))
assert.Equal(t, 64, nazabits.GetBits16(v, 6, 7))
assert.Equal(t, 96, nazabits.GetBits16(v, 7, 8))
assert.Equal(t, 0, nazabits.GetBits16(v, 8, 1))
assert.Equal(t, 0, nazabits.GetBits16(v, 9, 2))
assert.Equal(t, 4, nazabits.GetBits16(v, 10, 3))
assert.Equal(t, 6, nazabits.GetBits16(v, 11, 4))
assert.Equal(t, 3, nazabits.GetBits16(v, 12, 3))
assert.Equal(t, 1, nazabits.GetBits16(v, 13, 2))
assert.Equal(t, 0, nazabits.GetBits16(v, 14, 1))
assert.Equal(t, 0, nazabits.GetBits16(v, 15, 1))
assert.Equal(t, uint16(12345), nazabits.GetBits16(v, 0, 16))
assert.Equal(t, uint16(1), nazabits.GetBits16(v, 0, 1))
assert.Equal(t, uint16(0), nazabits.GetBits16(v, 1, 2))
assert.Equal(t, uint16(6), nazabits.GetBits16(v, 2, 3))
assert.Equal(t, uint16(7), nazabits.GetBits16(v, 3, 4))
assert.Equal(t, uint16(3), nazabits.GetBits16(v, 4, 5))
assert.Equal(t, uint16(1), nazabits.GetBits16(v, 5, 6))
assert.Equal(t, uint16(64), nazabits.GetBits16(v, 6, 7))
assert.Equal(t, uint16(96), nazabits.GetBits16(v, 7, 8))
assert.Equal(t, uint16(0), nazabits.GetBits16(v, 8, 1))
assert.Equal(t, uint16(0), nazabits.GetBits16(v, 9, 2))
assert.Equal(t, uint16(4), nazabits.GetBits16(v, 10, 3))
assert.Equal(t, uint16(6), nazabits.GetBits16(v, 11, 4))
assert.Equal(t, uint16(3), nazabits.GetBits16(v, 12, 3))
assert.Equal(t, uint16(1), nazabits.GetBits16(v, 13, 2))
assert.Equal(t, uint16(0), nazabits.GetBits16(v, 14, 1))
assert.Equal(t, uint16(0), nazabits.GetBits16(v, 15, 1))
}
func TestBitReader_ReadBit(t *testing.T) {
res := []int{0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1}
res := []uint8{0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1}
v := []byte{48, 57} // 12345 {0011 0000, 0011 1001}
br := nazabits.NewBitReader(v)
for _, b := range res {
@ -97,19 +97,43 @@ func TestBitReader_ReadBits8(t *testing.T) {
br := nazabits.NewBitReader(v)
// {0 01 1 00 00, 00 11 100 1, 0011 0 000, 0011 1001}
// 0,01,1 00,00 00, 11 100,100110, 0000011,
assert.Equal(t, 0, br.ReadBits(1))
assert.Equal(t, 1, br.ReadBits(2))
assert.Equal(t, 4, br.ReadBits(3))
assert.Equal(t, 0, br.ReadBits(4))
assert.Equal(t, 28, br.ReadBits(5))
assert.Equal(t, 38, br.ReadBits(6))
assert.Equal(t, 3, br.ReadBits(7))
assert.Equal(t, uint8(0), br.ReadBits(1))
assert.Equal(t, uint8(1), br.ReadBits(2))
assert.Equal(t, uint8(4), br.ReadBits(3))
assert.Equal(t, uint8(0), br.ReadBits(4))
assert.Equal(t, uint8(28), br.ReadBits(5))
assert.Equal(t, uint8(38), br.ReadBits(6))
assert.Equal(t, uint8(3), br.ReadBits(7))
br = nazabits.NewBitReader(v)
// {0011 0000, 0011 1001, 0 011 0000, 0011 1001}
assert.Equal(t, 48, br.ReadBits(8))
assert.Equal(t, 114, br.ReadBits(9))
assert.Equal(t, 385, br.ReadBits(10))
assert.Equal(t, uint8(48), br.ReadBits(8))
//assert.Equal(t, uint8(114), br.ReadBits(9))
//assert.Equal(t, uint8(385), br.ReadBits(10))
}
func TestBitWriter_WriteBit(t *testing.T) {
v := make([]byte, 2)
bw := nazabits.NewBitWriter(v)
bs := []uint8{0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1}
for _, b := range bs {
bw.WriteBit(b)
}
assert.Equal(t, uint8(48), v[0])
assert.Equal(t, uint8(57), v[1])
}
func TestBitWriter_WriteBits(t *testing.T) {
v := make([]byte, 2)
bw := nazabits.NewBitWriter(v)
bw.WriteBits(1, 0)
bw.WriteBits(2, 1)
bw.WriteBits(3, 4)
bw.WriteBits(4, 0)
bw.WriteBits(5, 28)
bw.WriteBits(1, 1)
assert.Equal(t, uint8(48), v[0])
assert.Equal(t, uint8(57), v[1])
}
func BenchmarkGetBits16(b *testing.B) {
@ -126,3 +150,11 @@ func BenchmarkBitReader_ReadBits(b *testing.B) {
br.ReadBits(9)
}
}
func BenchmarkBitWriter_WriteBits(b *testing.B) {
v := make([]byte, 2)
for i := 0; i < b.N; i++ {
bw := nazabits.NewBitWriter(v)
bw.WriteBits(9, 28)
}
}

Loading…
Cancel
Save