标签:c style class code a color
TLV是一种可变格式,意思就是:
Type类型,
Lenght长度,Value值;
Type和Length的长度固定,一般那是2、4个字节(这里统一采用4个字节);
Value的长度有Length指定;
编码方法:
1.
将类型type用htonl转换为网络字节顺序,指针偏移+4
2.
将长度length用htonl转换为网络字节顺序,指针偏移+4
3.
若值value数据类型为int、char、short,则将其转换为网络字节顺序,指针偏移+4;若值为字符串类型,写进后,指针偏移+length
……继续处理后面的tlv;
解码方法:
1. 读取type
用ntohl转换为主机字节序得到类型,指针偏移+4
2.
读取lengh用ntohl转换为主机字节序得到长度;指针偏移+4
3.
根据得到的长度读取value,若value数据类型为int、char、short,用ntohl转换为主机字节序,指针偏移+4;若value数据类型为字符串类型,指针偏移+length
……继续处理后面的tlv;
类型(Type)字段是关于标签和编码格式的信息;
长度 (Length)字段定义数值的长度;
内容(Value)字段表示实际的数值。
因此,一个编码值又称TLV(Type,Length,Value)三元组。编码可以是基本型或结构型,如果它表示一个简单类型的、完整的显式值,那么编码就是基本型
(primitive);如果它表示的值具有嵌套结构,那么编码就是结构型 (constructed)。
- #include
<stdio.h>
- #include
<WinSock2.h>
- #include
<string>
-
- #pragma comment(lib,
"WS2_32")
-
- enum
emTLVNodeType
- {
- emTlvNNone = 0,
-
emTlvNRoot,
-
emTlvName,
-
emTlvAge,
-
emTlvColor
- };
-
-
- typedefstruct
_CAT_INFO
- {
- char szName[12];
- int
iAge;
- int iColor;
- }CAT_INFO,*LPCAT_INFO;
-
- class CTlvPacket
- {
- public:
- CTlvPacket(char *pBuf,unsigned int
len):m_pData(pBuf),m_uiLength(len),m_pEndData(m_pData+len),m_pWritePtr(m_pData),m_pReadPtr(m_pData)
{ }
- ~CTlvPacket() { }
-
- bool
WriteInt(int data,bool bMovePtr = true)
- {
- int tmp = htonl(data);
- return
Write(&tmp,sizeof(int));
- }
-
- bool
Write(constvoid *pDst,unsigned int
uiCount)
- {
-
::memcpy(m_pWritePtr,pDst,uiCount);
- m_pWritePtr
+= uiCount;
- return m_pWritePtr < m_pEndData ? true : false;
- }
-
- bool ReadInt(int *data,bool bMovePtr = true)
- {
-
Read(data,sizeof(int));
- *data =
ntohl(*data);
- returntrue;
- }
-
- bool
Read(void *pDst,unsigned
int uiCount)
- {
-
::memcpy(pDst,m_pReadPtr,uiCount);
- m_pReadPtr +=
uiCount;
- return m_pReadPtr < m_pEndData ? true : false;
- }
-
- private:
- char
*m_pData;
- unsigned int m_uiLength;
- char
*m_pEndData;
- char *m_pWritePtr;
- char
*m_pReadPtr;
- };
-
-
-
-
-
-
-
-
- int
TLV_EncodeCat(LPCAT_INFO pCatInfo, char *pBuf, int &iLen)
- {
- if
(!pCatInfo || !pBuf)
- {
- return
-1;
- }
-
- CTlvPacket enc(pBuf,iLen);
- enc.WriteInt(emTlvNRoot);
- enc.WriteInt(20+12+12);
-
- enc.WriteInt(emTlvName);
- enc.WriteInt(12);
- enc.Write(pCatInfo->szName,12);
-
- enc.WriteInt(emTlvAge);
- enc.WriteInt(4);
- enc.WriteInt(pCatInfo->iAge);
-
- enc.WriteInt(emTlvColor);
- enc.WriteInt(4);
- enc.WriteInt(pCatInfo->iColor);
-
- iLen = 8+20+12+12;
-
- return
0;
- }
-
- int
TLV_DecodeCat(char *pBuf,
int iLen, LPCAT_INFO
pCatInfo)
- {
- if
(!pCatInfo || !pBuf)
- {
- return
-1;
- }
-
- CTlvPacket encDec(pBuf,iLen);
- int iType;
- int
iSum,iLength;
-
- encDec.ReadInt(&iType);
- if
(emTlvNRoot != iType)
- {
- return
-2;
- }
- encDec.ReadInt(&iSum);
-
- while (iSum > 0)
- {
-
encDec.ReadInt(&iType);
-
encDec.ReadInt(&iLength);
- switch(iType)
- {
- case
emTlvName:
-
encDec.Read(pCatInfo->szName,12);
-
iSum -= 20;
-
break;
- case
emTlvAge:
-
encDec.ReadInt(&pCatInfo->iAge);
-
iSum -= 12;
-
break;
- case
emTlvColor:
-
encDec.ReadInt(&pCatInfo->iColor);
-
iSum -= 12;
-
break;
- default:
-
printf("TLV_DecodeCat unkonwn error.
\n");
-
break;
- }
- }
-
- return 0;
- }
-
- int main(int
argc, char* argv[])
- {
-
- int iRet, iLen;
- char
buf[256] = {0};
-
- CAT_INFO cat;
- memset(&cat,0,sizeof(cat));
- strcpy(cat.szName,"Tom");
- cat.iAge = 5;
- cat.iColor = 2;
-
- iRet = TLV_EncodeCat(&cat,buf,iLen);
- if
( 0 == iRet )
- {
- printf("TLV_EncodeCat ok, iLen = %d. \n",iLen);
- }
- else
- {
- printf("TLV_EncodeCat error \n");
- }
-
- memset(&cat,0,sizeof(cat));
- iRet =
TLV_DecodeCat(buf,iLen,&cat);
- if ( 0 == iRet
)
- {
- printf("TLV_DecodeCat
ok, cat name = %s, age = %d, color = %d.
\n",cat.szName,cat.iAge,cat.iColor);
- }
- else
- {
- printf("TLV_DecodeCat
error, code = %d. \n", iRet);
- }
-
- int iWait = getchar();
- return
0;
- }
转:TLV 格式及编解码示例,布布扣,bubuko.com
转:TLV 格式及编解码示例
标签:c style class code a color
原文地址:http://www.cnblogs.com/dancheblog/p/3759338.html