1
+ // TLV, which stands for Tag(Type)-Length-Value, is a simple and practical data transmission scheme.
2
+ // In the definition of TLV, it can be seen that it consists of three fields: the tag field (Tag), the length
3
+ // field (Length), and the value field (Value).
4
+ // The value of the length field is actually the length of the content field.
5
+ //
6
+ // Before decoding (20 bytes) After decoding (20 bytes)
7
+ // +------------+------------+-----------------+ +------------+------------+-----------------+
8
+ // | Tag | Length | Value |-----> | Tag | Length | Value |
9
+ // | 0x00000001 | 0x0000000C | "HELLO, WORLD" | | 0x00000001 | 0x0000000C | "HELLO, WORLD" |
10
+ // +------------+------------+-----------------+ +------------+------------+-----------------+
11
+ // Tag: uint32 type, occupies 4 bytes, Tag is set as MsgId, temporarily set to 1
12
+ // Length: uint32 type, occupies 4 bytes, Length marks the length of Value, which is 12(hex:0x0000000C)
13
+ // Value: 12 characters in total, occupies 12 bytes
14
+ //
15
+ // Explanation:
16
+ // lengthFieldOffset = 4 (The byte index of Length is 4) Length field offset
17
+ // lengthFieldLength = 4 (Length is 4 bytes) Length field length in bytes
18
+ // lengthAdjustment = 0 (Length only represents the length of Value. The program will read only Length bytes and end.
19
+ // If there is a crc of 2 bytes after Value, then this is 2. If Length marks the total length of
20
+ // Tag+Length+Value, then this is -8)
21
+ // initialBytesToStrip = 0 (This 0 means that the complete protocol content Tag+Length+Value is returned. If you only
22
+ // want to return the Value content, remove the 4 bytes of Tag and 4 bytes of Length, and
23
+ // this is 8) Number of bytes to strip from the decoded frame
24
+ // maxFrameLength = 2^32 + 4 + 4 (Since Length is of uint type, 2^32 represents the maximum length of Value. In addition,
25
+ // Tag and Length each occupy 4 bytes.)
26
+
27
+ // [简体中文]
1
28
// TLV,即Tag(Type)—Length—Value,是一种简单实用的数据传输方案。
2
29
//在TLV的定义中,可以知道它包括三个域,分别为:标签域(Tag),长度域(Length),内容域(Value)。这里的长度域的值实际上就是内容域的长度。
3
30
//
13
40
// 说明:
14
41
// lengthFieldOffset = 4 (Length的字节位索引下标是4) 长度字段的偏差
15
42
// lengthFieldLength = 4 (Length是4个byte) 长度字段占的字节数
16
- // lengthAdjustment = 0 (Length只表示Value长度,程序只会读取Length个字节就结束,后面没有来,故为0,若Value后面还有crc占2字节的话,那么此处就是2。若Length标记的是Tag+Length+Value总长度,那么此处是-8)
17
- // initialBytesToStrip = 0 (这个0表示返回完整的协议内容Tag+Length+Value,如果只想返回Value内容,去掉Tag的4字节和Length的4字节,此处就是8) 从解码帧中第一次去除的字节数
43
+ // lengthAdjustment = 0 (Length只表示Value长度,程序只会读取Length个字节就结束,后面没有来,故为0,
44
+ // 若Value后面还有crc占2字节的话,那么此处就是2。若Length标记的是Tag+Length+Value总长度,
45
+ // 那么此处是-8)
46
+ // initialBytesToStrip = 0 (这个0表示返回完整的协议内容Tag+Length+Value,如果只想返回Value内容,去掉Tag的4字节和Length
47
+ // 的4字节,此处就是8) 从解码帧中第一次去除的字节数
18
48
// maxFrameLength = 2^32 + 4 + 4 (Length为uint类型,故2^32次方表示Value最大长度,此外Tag和Length各占4字节)
19
49
20
50
package zdecoder
@@ -29,9 +59,9 @@ import (
29
59
const TLV_HEADER_SIZE = 8 //表示TLV空包长度
30
60
31
61
type TLVDecoder struct {
32
- Tag uint32 //消息类型
33
- Length uint32 //消息长度
34
- Value []byte //消息内容
62
+ Tag uint32 //T
63
+ Length uint32 //L
64
+ Value []byte //V
35
65
}
36
66
37
67
func NewTLVDecoder () ziface.IDecoder {
@@ -65,14 +95,14 @@ func (tlv *TLVDecoder) GetLengthField() *ziface.LengthField {
65
95
66
96
func (tlv * TLVDecoder ) decode (data []byte ) * TLVDecoder {
67
97
tlvData := TLVDecoder {}
68
- //获取T
98
+ //Get T
69
99
tlvData .Tag = binary .BigEndian .Uint32 (data [0 :4 ])
70
- //获取L
100
+ //Get L
71
101
tlvData .Length = binary .BigEndian .Uint32 (data [4 :8 ])
72
- //确定V的长度
102
+ //Determine the length of V. ( 确定V的长度)
73
103
tlvData .Value = make ([]byte , tlvData .Length )
74
104
75
- //5.获取V
105
+ //Get V
76
106
binary .Read (bytes .NewBuffer (data [8 :8 + tlvData .Length ]), binary .BigEndian , tlvData .Value )
77
107
78
108
//zlog.Ins().DebugF("TLV-DecodeData size:%d data:%+v\n", unsafe.Sizeof(data), tlvData)
@@ -81,30 +111,33 @@ func (tlv *TLVDecoder) decode(data []byte) *TLVDecoder {
81
111
82
112
func (tlv * TLVDecoder ) Intercept (chain ziface.IChain ) ziface.IcResp {
83
113
84
- //1. 获取zinx的IMessage
114
+ //1. Get the IMessage of zinx
85
115
iMessage := chain .GetIMessage ()
86
116
if iMessage == nil {
87
- //进入责任链下一层
117
+ // Go to the next layer in the chain of responsibility
88
118
return chain .ProceedWithIMessage (iMessage , nil )
89
119
}
90
120
91
- //2. 获取数据
121
+ //2. Get Data
92
122
data := iMessage .GetData ()
93
123
//zlog.Ins().DebugF("TLV-RawData size:%d data:%s\n", len(data), hex.EncodeToString(data))
94
124
95
- //3. 读取的数据不超过包头,直接进入下一层
125
+ //3. If the amount of data read is less than the length of the header, proceed to the next layer directly.
126
+ // (读取的数据不超过包头,直接进入下一层)
96
127
if len (data ) < TLV_HEADER_SIZE {
97
128
return chain .ProceedWithIMessage (iMessage , nil )
98
129
}
99
130
100
- //4. TLV解码
131
+ //4. TLV Decode
101
132
tlvData := tlv .decode (data )
102
133
103
- //5. 将解码后的数据重新设置到IMessage中, Zinx的Router需要MsgID来寻址
134
+ //5. Set the decoded data back to the IMessage, the Zinx Router needs MsgID for addressing
135
+ // (将解码后的数据重新设置到IMessage中, Zinx的Router需要MsgID来寻址)
104
136
iMessage .SetMsgID (tlvData .Tag )
105
137
iMessage .SetData (tlvData .Value )
106
138
iMessage .SetDataLen (tlvData .Length )
107
139
108
- //6. 将解码后的数据进入下一层
140
+ //6. Pass the decoded data to the next layer.
141
+ // (将解码后的数据进入下一层)
109
142
return chain .ProceedWithIMessage (iMessage , * tlvData )
110
143
}
0 commit comments