2022-10-11 17:36:09 +08:00
|
|
|
package frame
|
|
|
|
|
|
|
|
import (
|
2023-04-05 16:15:59 +08:00
|
|
|
"fmt"
|
2022-10-11 17:36:09 +08:00
|
|
|
coder "git.hpds.cc/Component/mq_coder"
|
2023-04-05 16:15:59 +08:00
|
|
|
"sync"
|
2022-10-11 17:36:09 +08:00
|
|
|
)
|
|
|
|
|
2023-04-05 16:15:59 +08:00
|
|
|
var dataFramePool sync.Pool
|
|
|
|
|
2022-10-11 17:36:09 +08:00
|
|
|
// DataFrame defines the data structure carried with user's data
|
|
|
|
type DataFrame struct {
|
|
|
|
metaFrame *MetaFrame
|
|
|
|
payloadFrame *PayloadFrame
|
|
|
|
}
|
|
|
|
|
2023-04-05 16:15:59 +08:00
|
|
|
func (d *DataFrame) String() string {
|
|
|
|
data := d.GetCarriage()
|
|
|
|
length := len(data)
|
|
|
|
if length > debugFrameSize {
|
|
|
|
data = data[:debugFrameSize]
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("tid=%s | tag=%#x | source=%s | data[%d]=%# x", d.metaFrame.tid, d.Tag(), d.SourceId(), length, data)
|
|
|
|
}
|
|
|
|
|
2022-10-11 17:36:09 +08:00
|
|
|
// NewDataFrame create `DataFrame` with a transactionId string,
|
|
|
|
// consider change transactionID to UUID type later
|
|
|
|
func NewDataFrame() *DataFrame {
|
2023-04-05 16:15:59 +08:00
|
|
|
data := newDataFrame()
|
|
|
|
data.metaFrame.tid = randString()
|
2022-10-11 17:36:09 +08:00
|
|
|
return data
|
|
|
|
}
|
|
|
|
|
2023-04-05 16:15:59 +08:00
|
|
|
func newDataFrame() (data *DataFrame) {
|
|
|
|
v := dataFramePool.Get()
|
|
|
|
if v == nil {
|
|
|
|
data = new(DataFrame)
|
|
|
|
data.metaFrame = new(MetaFrame)
|
|
|
|
data.payloadFrame = new(PayloadFrame)
|
|
|
|
} else {
|
|
|
|
data = v.(*DataFrame)
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clean cleans DataFrame.
|
|
|
|
// Note that:
|
|
|
|
// 1/ if the client is calling WriteFrame(), it will automatically invoke Clean(), so there is no need to call Clean() separately.
|
|
|
|
// 2/ The DataFrame will be unavailable after cleaned, do not access DataFrame after Clean() called.
|
|
|
|
func (d *DataFrame) Clean() {
|
|
|
|
// reset metadataFrame
|
|
|
|
d.metaFrame.tid = ""
|
|
|
|
d.metaFrame.metadata = d.metaFrame.metadata[:0]
|
|
|
|
d.metaFrame.sourceId = ""
|
|
|
|
d.metaFrame.broadcast = false
|
|
|
|
|
|
|
|
// reset payloadFrame
|
|
|
|
d.payloadFrame.Tag = Tag(0)
|
|
|
|
d.payloadFrame.Carriage = d.payloadFrame.Carriage[:0]
|
|
|
|
|
|
|
|
dataFramePool.Put(d)
|
|
|
|
}
|
|
|
|
|
2022-10-11 17:36:09 +08:00
|
|
|
// Type gets the type of Frame.
|
|
|
|
func (d *DataFrame) Type() Type {
|
|
|
|
return TagOfDataFrame
|
|
|
|
}
|
|
|
|
|
|
|
|
// Tag return the tag of carriage data.
|
2023-04-05 16:15:59 +08:00
|
|
|
func (d *DataFrame) Tag() Tag {
|
2022-10-11 17:36:09 +08:00
|
|
|
return d.payloadFrame.Tag
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetCarriage set user's raw data in `DataFrame`
|
2023-04-05 16:15:59 +08:00
|
|
|
func (d *DataFrame) SetCarriage(tag Tag, carriage []byte) {
|
|
|
|
d.payloadFrame = &PayloadFrame{
|
|
|
|
Tag: tag,
|
|
|
|
Carriage: carriage,
|
|
|
|
}
|
2022-10-11 17:36:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetCarriage return user's raw data in `DataFrame`
|
|
|
|
func (d *DataFrame) GetCarriage() []byte {
|
|
|
|
return d.payloadFrame.Carriage
|
|
|
|
}
|
|
|
|
|
|
|
|
// TransactionId return transactionId string
|
|
|
|
func (d *DataFrame) TransactionId() string {
|
|
|
|
return d.metaFrame.TransactionId()
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetTransactionId set transactionId string
|
2023-04-05 16:15:59 +08:00
|
|
|
func (d *DataFrame) SetTransactionId(transactionId string) {
|
|
|
|
d.metaFrame.SetTransactionId(transactionId)
|
2022-10-11 17:36:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// GetMetaFrame return MetaFrame.
|
|
|
|
func (d *DataFrame) GetMetaFrame() *MetaFrame {
|
|
|
|
return d.metaFrame
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetDataTag return the Tag of user's data
|
2023-04-05 16:15:59 +08:00
|
|
|
func (d *DataFrame) GetDataTag() Tag {
|
2022-10-11 17:36:09 +08:00
|
|
|
return d.payloadFrame.Tag
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetSourceId set the source id.
|
2023-04-05 16:15:59 +08:00
|
|
|
func (d *DataFrame) SetSourceId(sourceId string) {
|
|
|
|
d.metaFrame.SetSourceId(sourceId)
|
2022-10-11 17:36:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// SourceId returns source id
|
|
|
|
func (d *DataFrame) SourceId() string {
|
|
|
|
return d.metaFrame.SourceId()
|
|
|
|
}
|
|
|
|
|
2023-04-05 16:15:59 +08:00
|
|
|
// SetBroadcast set broadcast mode
|
|
|
|
func (d *DataFrame) SetBroadcast(enabled bool) {
|
|
|
|
d.metaFrame.SetBroadcast(enabled)
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsBroadcast returns the broadcast mode is enabled
|
|
|
|
func (d *DataFrame) IsBroadcast() bool {
|
|
|
|
return d.metaFrame.IsBroadcast()
|
|
|
|
}
|
|
|
|
|
2022-10-11 17:36:09 +08:00
|
|
|
// Encode return coder encoded bytes of `DataFrame`
|
|
|
|
func (d *DataFrame) Encode() []byte {
|
2023-03-26 23:18:55 +08:00
|
|
|
data := coder.NewNodePacketEncoder(byte(d.Type()))
|
2022-10-11 17:36:09 +08:00
|
|
|
// MetaFrame
|
|
|
|
data.AddBytes(d.metaFrame.Encode())
|
|
|
|
// PayloadFrame
|
|
|
|
data.AddBytes(d.payloadFrame.Encode())
|
|
|
|
|
|
|
|
return data.Encode()
|
|
|
|
}
|
|
|
|
|
|
|
|
// DecodeToDataFrame decode coder encoded bytes to `DataFrame`
|
|
|
|
func DecodeToDataFrame(buf []byte) (*DataFrame, error) {
|
|
|
|
packet := coder.NodePacket{}
|
|
|
|
_, err := coder.DecodeToNodePacket(buf, &packet)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2023-04-05 16:15:59 +08:00
|
|
|
data := new(DataFrame)
|
|
|
|
data.metaFrame = new(MetaFrame)
|
|
|
|
data.payloadFrame = new(PayloadFrame)
|
2022-10-11 17:36:09 +08:00
|
|
|
|
2023-03-26 23:18:55 +08:00
|
|
|
if metaBlock, ok := packet.NodePackets[byte(TagOfMetaFrame)]; ok {
|
2023-04-05 16:15:59 +08:00
|
|
|
err := DecodeToMetaFrame(metaBlock.GetRawBytes(), data.metaFrame)
|
2022-10-11 17:36:09 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-03-26 23:18:55 +08:00
|
|
|
if payloadBlock, ok := packet.NodePackets[byte(TagOfPayloadFrame)]; ok {
|
2023-04-05 16:15:59 +08:00
|
|
|
err := DecodeToPayloadFrame(payloadBlock.GetRawBytes(), data.payloadFrame)
|
2022-10-11 17:36:09 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return data, nil
|
|
|
|
}
|