代码拉取完成,页面将自动刷新
package zmlink
import (
"bytes"
"encoding/binary"
"errors"
"io"
"math"
"sync/atomic"
)
type Payload interface {
Size() uint32
Bytes() []byte
Type() int8
SetPkgIdx(i uint64)
GetPkgIdx() uint64
Ack(data []byte) Payload
}
/*
| 头 | 长度位 | 类型位 | 报文编号 | 载荷 |
|:----|:----|:----|:----|:----|
| ZM | uint32 | int8 | uint64 | string |
*/
const (
payloadHeader = "ZM"
payloadHeaderLen = len(payloadHeader)
)
var payloadIdx uint64
// BytesPayload bytes payload
type BytesPayload struct {
pkgType int8
pkgIdx uint64
data []byte // 荷载 (V)
}
func (b *BytesPayload) Ack(data []byte) Payload {
return &BytesPayload{
pkgType: -b.pkgType,
pkgIdx: b.pkgIdx,
data: data,
}
}
func (b *BytesPayload) SetPkgIdx(i uint64) {
b.pkgIdx = i
}
func (b *BytesPayload) GetPkgIdx() uint64 {
if b.pkgIdx == 0 {
b.pkgIdx = atomic.AddUint64(&payloadIdx, 1)
}
return b.pkgIdx
}
func (b *BytesPayload) Size() uint32 {
return uint32(payloadHeaderLen + 4 + 1 + 8 + len(b.Bytes()))
}
func (b *BytesPayload) Bytes() []byte {
return b.data
}
func (b *BytesPayload) Type() int8 {
return b.pkgType
}
// NewBytesPayload 构建一个 []byte 荷载
func NewBytesPayload(t int8, data []byte) (Payload, error) {
if len(data) > math.MaxUint32-(payloadHeaderLen+4+1+8) {
return nil, errors.New("data length must be less than uint32")
}
return &BytesPayload{
pkgType: t,
data: data,
}, nil
}
func DecodePayLoad(data []byte) (Payload, error) {
buffer := bytes.NewReader(data)
header := make([]byte, payloadHeaderLen)
_, _ = buffer.Read(header)
size := make([]byte, 4)
_, _ = buffer.Read(size)
pkgType, err := buffer.ReadByte()
if err != nil {
return nil, err
}
pkgIdx := make([]byte, 8)
_, _ = buffer.Read(pkgIdx)
pData, _ := io.ReadAll(buffer)
payload, err := NewBytesPayload(int8(pkgType), pData)
if err != nil {
return nil, err
}
payload.SetPkgIdx(binary.BigEndian.Uint64(pkgIdx))
return payload, nil
}
func EncodePayLoad(payload Payload) ([]byte, error) {
// header
buffer := bytes.NewBuffer([]byte(payloadHeader))
// pkgSize
b := make([]byte, 4)
binary.BigEndian.PutUint32(b, payload.Size())
buffer.Write(b)
// type
buffer.WriteByte(byte(payload.Type()))
// pkgIndex
b = make([]byte, 8)
binary.BigEndian.PutUint64(b, payload.GetPkgIdx())
buffer.Write(b)
// data
buffer.Write(payload.Bytes())
buffer.Bytes()
return io.ReadAll(buffer)
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。