Files
bl/logic/service/common/pack.go

95 lines
2.5 KiB
Go
Raw Normal View History

package common
import (
"bytes"
"encoding/binary"
"fmt"
"github.com/lunixbochs/struc"
"github.com/valyala/bytebufferpool"
)
// TomeeHeader 结构体字段定义
type TomeeHeader struct {
Len uint32 `json:"len"`
Version byte `json:"version" struc:"[1]byte"`
CMD uint32 `json:"cmdId" struc:"uint32"`
UserID uint32 `json:"userId"`
//Error uint32 `json:"error" struc:"skip"`
Result uint32 `json:"result"`
Data *bytebufferpool.ByteBuffer `json:"data" struc:"skip"` //组包忽略此字段// struc:"skip"
Res []byte `struc:"skip"`
//Return []byte `struc:"skip"` //返回记录
}
func NewTomeeHeader(cmd uint32, userid uint32) *TomeeHeader {
return &TomeeHeader{
CMD: cmd,
// Len: 0,
Version: 49,
Result: 0,
}
}
// Pack 组包方法手动编码字节流兼容interface{}、nil、多层指针/接口
func (h *TomeeHeader) Pack(data any) []byte {
if data == nil {
return h.packHeaderWithData([]byte{})
}
var data1 bytes.Buffer
err := struc.Pack(&data1, data)
if err != nil {
fmt.Println(err)
}
if len(data1.Bytes()) == 0 {
// fmt.Println("数据为空")
}
//datar = data1.Bytes()
// 4. 手动打包包头+数据体
return h.packHeaderWithData(data1.Bytes())
}
// packHeaderWithData 手动编码包头和数据体(静态指定偏移量,无自增变量)
// 包头固定结构(大端序):
// - 0-3 字节Len (uint32)
// - 4 字节Version (byte)
// - 5-8 字节CMD (uint32从uint64截断)
// - 9-12 字节UserID (uint32)
// - 13-16 字节Result (uint32)
// 17字节后数据体
func (h *TomeeHeader) packHeaderWithData(data []byte) []byte {
// 计算总长度包头17字节 + 数据体长度
dataLen := len(data)
h.Len = uint32(17 + dataLen)
// 预分配切片(总长度 = 包头 + 数据体),避免多次扩容
buf := make([]byte, h.Len)
// 1. 写入Len固定偏移0-3 字节,大端序)
binary.BigEndian.PutUint32(buf[0:4], h.Len)
// 2. 写入Version固定偏移4 字节)
buf[4] = h.Version
// 3. 写入CMD固定偏移5-8 字节,大端序)
binary.BigEndian.PutUint32(buf[5:9], uint32(h.CMD))
// 4. 写入UserID固定偏移9-12 字节,大端序)
binary.BigEndian.PutUint32(buf[9:13], h.UserID)
// 5. 写入Result固定偏移13-16 字节,大端序)
binary.BigEndian.PutUint32(buf[13:17], h.Result)
// 6. 写入数据体固定起始偏移17 字节,若有数据则拷贝)
if dataLen > 0 {
copy(buf[17:], data)
}
return buf
}