"refactor(common): 重构序列化工具包,将serialize重命名为utils并添加bitset组件"
This commit is contained in:
524
common/utils/bytearray/bytearray.go
Normal file
524
common/utils/bytearray/bytearray.go
Normal file
@@ -0,0 +1,524 @@
|
||||
package bytearray
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"math"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ByteArray 提供字节数组的读写操作,支持大小端字节序
|
||||
type ByteArray struct {
|
||||
buf []byte
|
||||
posWrite int
|
||||
posRead int
|
||||
endian binary.ByteOrder
|
||||
}
|
||||
|
||||
// 默认使用大端字节序
|
||||
var defaultEndian binary.ByteOrder = binary.BigEndian
|
||||
|
||||
// bufferpool 用于重用ByteArray实例
|
||||
var bufferpool = &sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &ByteArray{endian: defaultEndian}
|
||||
},
|
||||
}
|
||||
|
||||
// CreateByteArray 创建一个新的ByteArray实例,使用指定的字节数组
|
||||
func CreateByteArray(bytes ...[]byte) *ByteArray {
|
||||
var ba *ByteArray
|
||||
if len(bytes) == 0 { //如果是0,则为新创建
|
||||
ba = bufferpool.Get().(*ByteArray)
|
||||
} else { //读序列
|
||||
ba = &ByteArray{endian: defaultEndian}
|
||||
}
|
||||
|
||||
for _, num := range bytes {
|
||||
ba.buf = append(ba.buf, num...)
|
||||
}
|
||||
|
||||
ba.ResetPos()
|
||||
return ba
|
||||
}
|
||||
|
||||
// releaseByteArray 将ByteArray实例放回池中以便重用
|
||||
func releaseByteArray(ba *ByteArray) {
|
||||
ba.Reset()
|
||||
bufferpool.Put(ba)
|
||||
}
|
||||
|
||||
// Length 返回字节数组的总长度
|
||||
func (ba *ByteArray) Length() int {
|
||||
return len(ba.buf)
|
||||
}
|
||||
|
||||
// Available 返回可读取的字节数
|
||||
func (ba *ByteArray) Available() int {
|
||||
return ba.Length() - ba.posRead
|
||||
}
|
||||
|
||||
// SetEndian 设置字节序(大端或小端)
|
||||
func (ba *ByteArray) SetEndian(endian binary.ByteOrder) {
|
||||
ba.endian = endian
|
||||
}
|
||||
|
||||
// GetEndian 获取当前字节序
|
||||
func (ba *ByteArray) GetEndian() binary.ByteOrder {
|
||||
if ba.endian == nil {
|
||||
return defaultEndian
|
||||
}
|
||||
return ba.endian
|
||||
}
|
||||
|
||||
// Grow 确保缓冲区有足够的空间
|
||||
func (ba *ByteArray) Grow(size int) {
|
||||
if size <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
required := ba.posWrite + size
|
||||
if len(ba.buf) >= required {
|
||||
return
|
||||
}
|
||||
|
||||
newBuf := make([]byte, required)
|
||||
copy(newBuf, ba.buf)
|
||||
ba.buf = newBuf
|
||||
}
|
||||
|
||||
// SetWritePos 设置写指针位置
|
||||
func (ba *ByteArray) SetWritePos(pos int) error {
|
||||
if pos < 0 || pos > ba.Length() {
|
||||
return io.EOF
|
||||
}
|
||||
ba.posWrite = pos
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetWriteEnd 将写指针设置到末尾
|
||||
func (ba *ByteArray) SetWriteEnd() {
|
||||
ba.posWrite = ba.Length()
|
||||
}
|
||||
|
||||
// GetWritePos 获取写指针位置
|
||||
func (ba *ByteArray) GetWritePos() int {
|
||||
return ba.posWrite
|
||||
}
|
||||
|
||||
// SetReadPos 设置读指针位置
|
||||
func (ba *ByteArray) SetReadPos(pos int) error {
|
||||
if pos < 0 || pos > ba.Length() {
|
||||
return io.EOF
|
||||
}
|
||||
ba.posRead = pos
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetReadEnd 将读指针设置到末尾
|
||||
func (ba *ByteArray) SetReadEnd() {
|
||||
ba.posRead = ba.Length()
|
||||
}
|
||||
|
||||
// GetReadPos 获取读指针位置
|
||||
func (ba *ByteArray) GetReadPos() int {
|
||||
return ba.posRead
|
||||
}
|
||||
|
||||
// ResetPos 重置读写指针到开始位置
|
||||
func (ba *ByteArray) ResetPos() {
|
||||
ba.posWrite = 0
|
||||
ba.posRead = 0
|
||||
}
|
||||
|
||||
// Reset 重置ByteArray,清空缓冲区并重置指针
|
||||
func (ba *ByteArray) Reset() {
|
||||
ba.buf = nil
|
||||
ba.ResetPos()
|
||||
}
|
||||
|
||||
// Bytes 返回完整的字节数组
|
||||
func (ba *ByteArray) Bytes() []byte {
|
||||
defer releaseByteArray(ba) //这里是写数组,写完后退出时释放线程池
|
||||
return ba.buf
|
||||
}
|
||||
|
||||
// BytesAvailable 返回从当前读指针位置到末尾的字节数组
|
||||
func (ba *ByteArray) BytesAvailable() []byte {
|
||||
return ba.buf[ba.posRead:]
|
||||
}
|
||||
|
||||
// ========== 写入方法 ==========
|
||||
|
||||
// Write 写入字节数组
|
||||
func (ba *ByteArray) Write(bytes []byte) (int, error) {
|
||||
if len(bytes) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
ba.Grow(len(bytes))
|
||||
n := copy(ba.buf[ba.posWrite:], bytes)
|
||||
ba.posWrite += n
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// WriteByte 写入单个字节
|
||||
func (ba *ByteArray) WriteByte(b byte) error {
|
||||
ba.Grow(1)
|
||||
ba.buf[ba.posWrite] = b
|
||||
ba.posWrite++
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteInt8 写入int8
|
||||
func (ba *ByteArray) WriteInt8(value int8) error {
|
||||
return ba.WriteByte(byte(value))
|
||||
}
|
||||
|
||||
// WriteInt16 写入int16,根据当前字节序处理
|
||||
func (ba *ByteArray) WriteInt16(value int16) error {
|
||||
return ba.writeNumber(value)
|
||||
}
|
||||
|
||||
// WriteUInt16 写入uint16,根据当前字节序处理
|
||||
func (ba *ByteArray) WriteUInt16(value uint16) error {
|
||||
return ba.writeNumber(value)
|
||||
}
|
||||
|
||||
// WriteInt32 写入int32,根据当前字节序处理
|
||||
func (ba *ByteArray) WriteInt32(value int32) error {
|
||||
return ba.writeNumber(value)
|
||||
}
|
||||
|
||||
// WriteUInt32 写入uint32,根据当前字节序处理
|
||||
func (ba *ByteArray) WriteUInt32(value uint32) error {
|
||||
return ba.writeNumber(value)
|
||||
}
|
||||
|
||||
// WriteInt64 写入int64,根据当前字节序处理
|
||||
func (ba *ByteArray) WriteInt64(value int64) error {
|
||||
return ba.writeNumber(value)
|
||||
}
|
||||
|
||||
// Writeuint32 写入uint32,根据当前字节序处理
|
||||
func (ba *ByteArray) Writeuint32(value uint32) error {
|
||||
return ba.writeNumber(value)
|
||||
}
|
||||
|
||||
// WriteFloat32 写入float32,根据当前字节序处理
|
||||
func (ba *ByteArray) WriteFloat32(value float32) error {
|
||||
return ba.writeNumber(math.Float32bits(value))
|
||||
}
|
||||
|
||||
// WriteFloat64 写入float64,根据当前字节序处理
|
||||
func (ba *ByteArray) WriteFloat64(value float64) error {
|
||||
return ba.writeNumber(math.Float64bits(value))
|
||||
}
|
||||
|
||||
// WriteBool 写入布尔值
|
||||
func (ba *ByteArray) WriteBool(value bool) error {
|
||||
var b byte
|
||||
if value {
|
||||
b = 1
|
||||
} else {
|
||||
b = 0
|
||||
}
|
||||
return ba.WriteByte(b)
|
||||
}
|
||||
|
||||
// WriteString 写入字符串
|
||||
func (ba *ByteArray) WriteString(value string) error {
|
||||
_, err := ba.Write([]byte(value))
|
||||
return err
|
||||
}
|
||||
|
||||
// WriteUTF 写入UTF字符串(带长度前缀)
|
||||
func (ba *ByteArray) WriteUTF(value string) error {
|
||||
bytes := []byte(value)
|
||||
if err := ba.WriteUInt16(uint16(len(bytes))); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := ba.Write(bytes)
|
||||
return err
|
||||
}
|
||||
|
||||
// ReadUTF8Array 读取 UTF8 字符串数组(格式:先读取 Int32 长度,再读取多个 UTF 字符串)
|
||||
func (ba *ByteArray) ReadUTF8Array() ([]string, error) {
|
||||
count, err := ba.ReadInt32()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count < 0 {
|
||||
return nil, errors.New("invalid array length")
|
||||
}
|
||||
|
||||
array := make([]string, 0, count)
|
||||
for i := 0; i < int(count); i++ {
|
||||
str, err := ba.ReadUTF()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
array = append(array, str)
|
||||
}
|
||||
return array, nil
|
||||
}
|
||||
|
||||
// ReadInt32Array 读取 Int32 数组(格式:先读取 Int32 长度,再读取多个 Int32)
|
||||
func (ba *ByteArray) ReadInt32Array() ([]int32, error) {
|
||||
count, err := ba.ReadInt32()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count < 0 {
|
||||
return nil, errors.New("invalid array length")
|
||||
}
|
||||
|
||||
array := make([]int32, 0, count)
|
||||
for i := 0; i < int(count); i++ {
|
||||
val, err := ba.ReadInt32()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
array = append(array, val)
|
||||
}
|
||||
return array, nil
|
||||
}
|
||||
|
||||
// WriteUTF8 写入UTF8字符串(不带长度前缀)
|
||||
func (ba *ByteArray) WriteUTF8(value string) error {
|
||||
_, err := ba.Write([]byte(value))
|
||||
return err
|
||||
}
|
||||
|
||||
// 通用写入数值方法
|
||||
func (ba *ByteArray) writeNumber(value interface{}) error {
|
||||
var size int
|
||||
switch value.(type) {
|
||||
case int8, uint8:
|
||||
size = 1
|
||||
case int16, uint16:
|
||||
size = 2
|
||||
case int32, uint32, float32:
|
||||
size = 4
|
||||
case int64, uint64, float64:
|
||||
size = 8
|
||||
default:
|
||||
return errors.New("unsupported number type")
|
||||
}
|
||||
|
||||
ba.Grow(size)
|
||||
|
||||
switch v := value.(type) {
|
||||
case int8:
|
||||
ba.buf[ba.posWrite] = byte(v)
|
||||
case uint8:
|
||||
ba.buf[ba.posWrite] = v
|
||||
case int16:
|
||||
ba.endian.PutUint16(ba.buf[ba.posWrite:], uint16(v))
|
||||
case uint16:
|
||||
ba.endian.PutUint16(ba.buf[ba.posWrite:], v)
|
||||
case int32:
|
||||
ba.endian.PutUint32(ba.buf[ba.posWrite:], uint32(v))
|
||||
case uint32:
|
||||
ba.endian.PutUint32(ba.buf[ba.posWrite:], v)
|
||||
case int64:
|
||||
ba.endian.PutUint64(ba.buf[ba.posWrite:], uint64(v))
|
||||
case uint64:
|
||||
ba.endian.PutUint64(ba.buf[ba.posWrite:], v)
|
||||
case float32:
|
||||
ba.endian.PutUint32(ba.buf[ba.posWrite:], math.Float32bits(v))
|
||||
case float64:
|
||||
ba.endian.PutUint64(ba.buf[ba.posWrite:], math.Float64bits(v))
|
||||
}
|
||||
|
||||
ba.posWrite += size
|
||||
return nil
|
||||
}
|
||||
|
||||
// ========== 读取方法 ==========
|
||||
|
||||
// Read 读取字节数组到指定缓冲区
|
||||
func (ba *ByteArray) Read(bytes []byte) (int, error) {
|
||||
if len(bytes) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if ba.posRead+len(bytes) > ba.Length() {
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
n := copy(bytes, ba.buf[ba.posRead:])
|
||||
ba.posRead += n
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// ReadByte 读取单个字节
|
||||
func (ba *ByteArray) ReadByte() (byte, error) {
|
||||
if ba.posRead >= ba.Length() {
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
b := ba.buf[ba.posRead]
|
||||
ba.posRead++
|
||||
return b, nil
|
||||
}
|
||||
|
||||
// ReadInt8 读取int8
|
||||
func (ba *ByteArray) ReadInt8() (int8, error) {
|
||||
b, err := ba.ReadByte()
|
||||
return int8(b), err
|
||||
}
|
||||
|
||||
// ReadUInt8 读取uint8
|
||||
func (ba *ByteArray) ReadUInt8() (uint8, error) {
|
||||
return ba.ReadByte()
|
||||
}
|
||||
|
||||
// ReadInt16 读取int16,根据当前字节序处理
|
||||
func (ba *ByteArray) ReadInt16() (int16, error) {
|
||||
var v uint16
|
||||
if err := ba.readNumber(&v); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int16(v), nil
|
||||
}
|
||||
|
||||
// ReadUInt16 读取uint16,根据当前字节序处理
|
||||
func (ba *ByteArray) ReadUInt16() (uint16, error) {
|
||||
var v uint16
|
||||
if err := ba.readNumber(&v); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// ReadInt32 读取int32,根据当前字节序处理
|
||||
func (ba *ByteArray) ReadInt32() (int32, error) {
|
||||
var v uint32
|
||||
if err := ba.readNumber(&v); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int32(v), nil
|
||||
}
|
||||
|
||||
// ReadUInt32 读取uint32,根据当前字节序处理
|
||||
func (ba *ByteArray) ReadUInt32() (uint32, error) {
|
||||
var v uint32
|
||||
if err := ba.readNumber(&v); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// ReadInt64 读取int64,根据当前字节序处理
|
||||
func (ba *ByteArray) ReadInt64() (int64, error) {
|
||||
var v uint32
|
||||
if err := ba.readNumber(&v); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int64(v), nil
|
||||
}
|
||||
|
||||
// Readuint32 读取uint32,根据当前字节序处理
|
||||
func (ba *ByteArray) Readuint32() (uint32, error) {
|
||||
var v uint32
|
||||
if err := ba.readNumber(&v); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// ReadFloat32 读取float32,根据当前字节序处理
|
||||
func (ba *ByteArray) ReadFloat32() (float32, error) {
|
||||
var v uint32
|
||||
if err := ba.readNumber(&v); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return math.Float32frombits(v), nil
|
||||
}
|
||||
|
||||
// ReadFloat64 读取float64,根据当前字节序处理
|
||||
func (ba *ByteArray) ReadFloat64() (float64, error) {
|
||||
var v uint64
|
||||
if err := ba.readNumber(&v); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return math.Float64frombits(v), nil
|
||||
}
|
||||
|
||||
// ReadBool 读取布尔值
|
||||
func (ba *ByteArray) ReadBool() (bool, error) {
|
||||
b, err := ba.ReadByte()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return b != 0, nil
|
||||
}
|
||||
|
||||
// ReadString 读取指定长度的字符串
|
||||
func (ba *ByteArray) ReadString(length int) (string, error) {
|
||||
if length < 0 {
|
||||
return "", errors.New("invalid string length")
|
||||
}
|
||||
|
||||
if ba.posRead+length > ba.Length() {
|
||||
return "", io.EOF
|
||||
}
|
||||
|
||||
str := string(ba.buf[ba.posRead : ba.posRead+length])
|
||||
ba.posRead += length
|
||||
return str, nil
|
||||
}
|
||||
|
||||
// ReadUTF 读取UTF字符串(带长度前缀)
|
||||
func (ba *ByteArray) ReadUTF() (string, error) {
|
||||
length, err := ba.ReadUInt16()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ba.ReadString(int(length))
|
||||
}
|
||||
|
||||
// 通用读取数值方法
|
||||
func (ba *ByteArray) readNumber(value interface{}) error {
|
||||
var size int
|
||||
switch value.(type) {
|
||||
case *int16, *uint16:
|
||||
size = 2
|
||||
case *int32, *uint32, *float32:
|
||||
size = 4
|
||||
case *int64, *uint64, *float64:
|
||||
size = 8
|
||||
default:
|
||||
return errors.New("unsupported number type")
|
||||
}
|
||||
|
||||
if ba.posRead+size > ba.Length() {
|
||||
return io.EOF
|
||||
}
|
||||
|
||||
buf := ba.buf[ba.posRead : ba.posRead+size]
|
||||
ba.posRead += size
|
||||
|
||||
switch v := value.(type) {
|
||||
case *int16:
|
||||
*v = int16(ba.endian.Uint16(buf))
|
||||
case *uint16:
|
||||
*v = ba.endian.Uint16(buf)
|
||||
case *int32:
|
||||
*v = int32(ba.endian.Uint32(buf))
|
||||
case *uint32:
|
||||
*v = ba.endian.Uint32(buf)
|
||||
case *int64:
|
||||
*v = int64(ba.endian.Uint64(buf))
|
||||
case *uint64:
|
||||
*v = ba.endian.Uint64(buf)
|
||||
case *float32:
|
||||
*v = math.Float32frombits(ba.endian.Uint32(buf))
|
||||
case *float64:
|
||||
*v = math.Float64frombits(ba.endian.Uint64(buf))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
21
common/utils/bytearray/bytearray_test.go
Normal file
21
common/utils/bytearray/bytearray_test.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package bytearray
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkByteArray(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
//写入
|
||||
testbyte:=CreateByteArray()
|
||||
for i := 0; i < b.N; i++ {
|
||||
testbyte.writeNumber(42)
|
||||
testbyte.writeNumber(12345.4)
|
||||
testbyte.writeNumber(123456789)
|
||||
testbyte.writeNumber(1234567890123456789)
|
||||
testbyte.WriteString("test string")
|
||||
testbyte.Bytes()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
3
common/utils/bytearray/go.mod
Normal file
3
common/utils/bytearray/go.mod
Normal file
@@ -0,0 +1,3 @@
|
||||
module blazing/common/utils/bytearray
|
||||
|
||||
go 1.20
|
||||
Reference in New Issue
Block a user