【TARS】TARS协议的编解码

目录

 

0.现有编解码方式

1.编解码

2.TARS底层协议

3.TUP

3.1TUP是什么

3.2TUP能做什么

3.3TUP不能做什么

3.4依赖和约束 

4.TARS协议的序列化与反序列化调用的函数

5.源码分布

扫描二维码关注公众号,回复: 12730558 查看本文章

6.协议序列化分析(以响应报文为例)

6.0如何进行序列化

6.1响应包体

6.2响应包体中每个成员变量的序列化后的组成部分HEAD+BUF

6.3分析HEAD

6.3.1HEAD的组成

6.3.2TAG的取值逻辑

6.3.3 TYPE的取值范围与取值逻辑

7.响应协议反序列化

7.1理解反序列化

7.2路小饭的协议反序列化测试示例

8.我自己写的测试序列化和反序列化的测试程序及逻辑说明

 

 


 

0.现有编解码方式

序列化与反序列化编码原理--阅读链接--感谢作者!

1.编解码

引用阅读

官方引用阅读-02-关于协议,Tars文件以及翻译工具tars2node的说明

宝藏文章!

统一通信协议 TarsTup

宝藏路小饭

路小饭对于TARS的编解码的讲解

路小饭对TARS的编解码的测试用例

编码-序列化
解码-反序列化

序列化:将对象变为二进制内容,写入到IO流中;
反序列化:从IO流获取到二进制内容,将其恢复为对象.

tars序列化过程:TARS编码协议是一种数据编解码规则,它将整形、枚举值、字符串、序列、字典、自定义结构
体等数据类型按照一定的规则编码到二进制数据流中。对端接收到二进制数据流之后,按照相应的规则反序列化
可得到原始数值。简单理解,TARS编码协议提供了一种将数据序列化、反序列化的方法。其角色和我们认识的
protobuf、json、xml等同.

2.TARS底层协议

Tars服务之间通讯的底层协议格式, 具体参见RequestF.tars & BaseF.tars.

RequestPacket和ResponsePacket 是两个Tars服务通信的底层协议, 简单的说如果不通过Tars的
Communicator来通信, 你可以自己组包来完成和Tars服务的通信(当然这会有相当的难度, 需要你
对Tars底层协议非常熟悉), 因此为了方便TUP构建出来解决这种问题.


module tars
{
    //请求包体
    struct RequestPacket
    {
        1  require short        iVersion;
        2  require byte         cPacketType  = 0;
        3  require int          iMessageType = 0;
        4  require int          iRequestId;
        5  require string       sServantName = "";
        6  require string       sFuncName    = "";
        7  require vector<byte> sBuffer;
        8  require int          iTimeout     = 0;
        9  require map<string, string> context;
        10 require map<string, string> status;
    };

    //响应包体
    struct ResponsePacket
    {
        1 require short         iVersion;
        2 require byte          cPacketType  = 0;
        3 require int           iRequestId;
        4 require int           iMessageType = 0;
        5 require int           iRet         = 0;
        6 require vector<byte>  sBuffer;
        7 require map<string, string> status;
        8 optional string        sResultDesc;
        9 optional map<string, string> context;
    };
};
module tars
{
    
    // 定义协议的版本号

    const short TARSVERSION  = 0x01;
    const short TUPVERSION  = 0x03;

    
    // 定义消息的类型

    // 普通调用
    const byte TARSNORMAL  = 0x00;

    // 单向调用
    const byte TARSONEWAY  = 0x01;

    
    // TARS定义的返回码

    const int TARSSERVERSUCCESS       = 0;       //服务器端处理成功
    const int TARSSERVERDECODEERR     = -1;      //服务器端解码异常
    const int TARSSERVERENCODEERR     = -2;      //服务器端编码异常
    const int TARSSERVERNOFUNCERR     = -3;      //服务器端没有该函数
    const int TARSSERVERNOSERVANTERR  = -4;      //服务器端没有该Servant对象
    const int TARSSERVERRESETGRID     = -5;      //服务器端灰度状态不一致
    const int TARSSERVERQUEUETIMEOUT  = -6;      //服务器队列超过限制
    const int TARSASYNCCALLTIMEOUT    = -7;      //异步调用超时
    const int TARSINVOKETIMEOUT       = -7;      //调用超时
    const int TARSPROXYCONNECTERR     = -8;      //proxy链接异常
    const int TARSSERVEROVERLOAD      = -9;      //服务器端超负载,超过队列长度
    const int TARSADAPTERNULL         = -10;     //客户端选路为空,服务不存在或者所有服务down掉了
    const int TARSINVOKEBYINVALIDESET = -11;     //客户端按set规则调用非法
    const int TARSCLIENTDECODEERR     = -12;     //客户端解码异常
    const int TARSSERVERUNKNOWNERR    = -99;     //服务器端位置异常

    /
    // 定义按位的消息状态类型,可复合

    const int TARSMESSAGETYPENULL     = 0x00;    //无状态
    const int TARSMESSAGETYPEHASH     = 0x01;    //HASH消息
    const int TARSMESSAGETYPEGRID     = 0x02;    //灰度消息
    const int TARSMESSAGETYPEDYED     = 0x04;    //染色消息
    const int TARSMESSAGETYPESAMPLE   = 0x08;    //stat采样消息
    const int TARSMESSAGETYPEASYNC    = 0x10;    //异步调用程序
    //const int TARSMESSAGETYPELOADED = 0x20;    //按负载值调用程序
    //const int TARSMESSAGETYPESETED = 0x40;     //按set规则调用类型,此字段后面将不使用
    const int TARSMESSAGETYPESETNAME = 0x80;     //按setname规则调用类型
    const int TARSMESSAGETYPETRACK   = 0x100;    //track调用链消息
    /
}

3.TUP

3.1TUP是什么

TUP(Tars Uni-Protocol的简称),Tars统一协议,是基于Tars编码的命令字(Command)层协议的封装。
它的存在最早是为了方便各语言客户端调用Tars服务, 只提供了编解码, 网路通讯需要自己实现, 当然如果
Tars提供了这个语言的客户端, 那么就不需要再使用TUP协议来调用Tars服务了.


在正式使用中, 我们有这种场景, 以供大家参考:

(1)后端服务使用Tars服务实现;
(2)实现一个HTTP+TUP协议的全异步代理, 即入口是HTTP+TUP, 出口是TARS协议的代理;
(3)Android/Ios通过TUP协议, 并通过这个代理服务, 完成和后台任何Tars服务的通信.

3.2TUP能做什么

1.支持java、c++等语言;

2.支持对象的序列化和反序列化;

3.支持协议动态扩展;

4.提供put/get泛型接口,快速实现客户端/服务端的编解码;

5.支持直接调用Tars的服务端.

3.3TUP不能做什么

1.只做协议封装,不包含网络层;

2.不支持数据压缩(可在业务层处理);

3.不支持加密协议(可在业务层处理).

3.4依赖和约束 

1.依赖Tars协议,TUP用到的结构体对象必须通过Tars定义后生成;
2.依赖各个语言的代码生成工具,如:tars2cpp/tars2java等;
3.TarsUniPacket中封装的Tars相关的接口(如getTars.../setTars...),只有在调用Tars服务是需要用到
4.使用过程中,使用UniPacket完成请求与相应的数据传递,其中ServantName(服务对象名) 与FuncName
(接口名)为必须设定的参数,否则编码失败
5.不建议get/put太多数据,如果有比较多数据,建议在tars文件中组成一个struct,然后put/get到
UniPacket中,便于提高效率和减少网络包大小;
6.UniPacket编码后的结果在包头包含了4个字节网络字节序的包长信息,长度包括包头,接收方收到包后需根据
包头的内容,判断包长,确保包完整后,传入解码接口进行解码(无需去掉包头);
7.Tars c++语言的string 类型接口建议不要包含二进制数据,二进制数据用vector传输.

4.TARS协议的序列化与反序列化调用的函数

序列化数据使用的是:  ResponsePacket.writeTo()
反序列化数据使用的是:ResponsePacket.readFrom()
代码路径:D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\RequestF.h
struct RequestPacket
{
  ...

        template<typename WriterT>
        void writeTo(tars::TarsOutputStream<WriterT>& _os) const
        {
            _os.write(iVersion, 1);
            _os.write(cPacketType, 2);
            _os.write(iMessageType, 3);
            _os.write(iRequestId, 4);
            _os.write(sServantName, 5);
            _os.write(sFuncName, 6);
            _os.write(sBuffer, 7);
            _os.write(iTimeout, 8);
            _os.write(context, 9);
            _os.write(status, 10);
        }
        template<typename ReaderT>
        void readFrom(tars::TarsInputStream<ReaderT>& _is)
        {
            resetDefautlt();
            _is.read(iVersion, 1, true);
            _is.read(cPacketType, 2, true);
            _is.read(iMessageType, 3, true);
            _is.read(iRequestId, 4, true);
            _is.read(sServantName, 5, true);
            _is.read(sFuncName, 6, true);
            _is.read(sBuffer, 7, true);
            _is.read(iTimeout, 8, true);
            _is.read(context, 9, true);
            _is.read(status, 10, true);
        }
...
}


 struct ResponsePacket {
...
        template<typename WriterT>
        void writeTo(tars::TarsOutputStream<WriterT>& _os) const
        {
            _os.write(iVersion, 1);
            _os.write(cPacketType, 2);
            _os.write(iRequestId, 3);
            _os.write(iMessageType, 4);
            _os.write(iRet, 5);
            _os.write(sBuffer, 6);
            _os.write(status, 7);
            if (sResultDesc != "")
            {
                _os.write(sResultDesc, 8);
            }
            if (context.size() > 0)
            {
                _os.write(context, 9);
            }
        }
        template<typename ReaderT>
        void readFrom(tars::TarsInputStream<ReaderT>& _is)
        {
            resetDefautlt();
            _is.read(iVersion, 1, true);
            _is.read(cPacketType, 2, true);
            _is.read(iRequestId, 3, true);
            _is.read(iMessageType, 4, true);
            _is.read(iRet, 5, true);
            _is.read(sBuffer, 6, true);
            _is.read(status, 7, true);
            _is.read(sResultDesc, 8, false);
            _is.read(context, 9, false);
        }




...
}

5.源码分布

D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\tup.h
D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\Tars.h
D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\RequestF.h

6.协议序列化分析(以响应报文为例)

6.0如何进行序列化

把结构化数据序列化,就是想办法把不同类型的数据按照顺序放在一个字符串里,反序列化就是还能从这个字符
串里把类型和数据正确解析出来,一般来说,要达成正确的效果,必须考虑三点:

(1)标记数据的位置,例如是位于字符串头部还是字符串末尾,或者中间某个部分.
(2)标记数据的类型,例如int char float vector等
(3)标记数据内容.

6.1响应包体

struct ResponsePacket
{
        1 require short         iVersion;
        2 require byte          cPacketType  = 0;
        3 require int           iRequestId;
        4 require int           iMessageType = 0;
        5 require int           iRet         = 0;
        6 require vector<byte>  sBuffer;
        7 require map<string, string> status;
        8 optional string        sResultDesc;
        9 optional map<string, string> context;
};

6.2响应包体中每个成员变量的序列化后的组成部分HEAD+BUF

每个成员变量的数据是由两部分组成:
HEAD + BUF 

HEAD为头部信息(包含了数据位置和数据类型),BUF为实际数据.
注意BUF里可以继续嵌套| HEAD | BUF |这样的类型,以满足复杂数据结构的需要.
像char、short、int之类的简单类型时,只需要:| HEAD | BUF |
当数据类型为vector< char >时,就变为了| HEAD1 | HEAD2 | BUF |,这时候HEAD1 存储vector类型,HEAD2 存储char类型

6.3分析HEAD

6.3.1HEAD的组成

HEAD的构成为:
| TAG1(4 bits) | TYPE(4 bits) | TAG2(1 byte或者8 bits).
D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\RequestF.h
响应报文的序列化源码:        
struct ResponsePacket 
{
        ...
        template<typename WriterT> // line 204 ,ver 2-14-2
        void writeTo(tars::TarsOutputStream<WriterT>& _os) const
        {
            _os.write(iVersion, 1);
            _os.write(cPacketType, 2);
            _os.write(iRequestId, 3);
            _os.write(iMessageType, 4);
            _os.write(iRet, 5);
            _os.write(sBuffer, 6);
            _os.write(status, 7);
            if (sResultDesc != "")
            {
                _os.write(sResultDesc, 8);
            }
            if (context.size() > 0)
            {
                _os.write(context, 9);
            }
}





write的第一个参数的值是每个变量对应的value值,第二个参数对应的值是每个变量对应的tag值.
要注意每个变量还自己带了一个属性值,就是它的数据类型.

write函数给出了很多重载形式:
如:

6.3.2TAG的取值逻辑

#define TarsWriteToHead(os, type, tag) \
do { \
    if (tars_likely((tag) < 15)) \
    { \
        //当tag的值小于15的时候只有TAG1
        TarsWriteUInt8TTypeBuf( os, (type) + ((tag)<<4) , (os)._len); \
    } \
    else \
    { \
        //当tag的值小于15的时候有TAG1还有TAG2
        TarsWriteUInt8TTypeBuf( os, (type) + (240) , (os)._len); \
        TarsWriteUInt8TTypeBuf( os, (tag),  (os)._len);\
    } \
} while(0)


#define TarsWriteUInt8TTypeBuf(os, val, osLen) \
do { \
    TarsReserveBuf(os, (osLen)+sizeof(uint8_t)); \
    (*(uint8_t *)((os)._buf + (osLen))) = (val); \
    (osLen) += sizeof(uint8_t); \
} while(0)


【具体看个TAG小于14的例子:TAG1为1,TYPE为TarsHeadeInt32(2),用二进制表示的话,TAG1为0001,
TYPE为0010,HEAD组成方式是将TAG1二进制和TYPE二进制拼接起来,即:
00010010 换算为10进制是18。 前4位为TAG1,后4位为TYPE,从这样的拼接方式中可以看到,相当于是把
TAG1右移了4位再加上TYPE
从上面贴出的代码中我们也可以看到拼接方式的表示:"(type) + ((tag)<<4)",即:HEAD = 2 + (1<<4) 
= 2 + 16 = 18。就这样Tars协议可以用1byte同时表示数据类型和数据位置.

再看个TAG大于14的例子:TAG1为240(固定值),TAG2为200,TYPE为TarsHeadeInt32(2),HEAD的二进制表示为:
11110010 11001000 用10进制表示为242 200 前八位中,1111代表TAG1的值240(即11110000),0010代
表TYPE的值2(即0010)。后八位为TAG2的值200(即11001000)
】


6.3.3 TYPE的取值范围与取值逻辑

TYPE表示类型,用4个二进制位表示,取值范围是0~15,用来标识数据类型,也就是下面的值中的一个.
//数据头类型
#define TarsHeadeChar  0        // 0000
#define TarsHeadeShort 1        // 0001
#define TarsHeadeInt32 2        // 0010
#define TarsHeadeInt64 3        // 0011
#define TarsHeadeFloat 4        // 0100
#define TarsHeadeDouble 5       // 0101
#define TarsHeadeString1 6      // 0110
#define TarsHeadeString4 7      // 0111
#define TarsHeadeMap 8          // 1000
#define TarsHeadeList 9         // 1001
#define TarsHeadeStructBegin 10 // 1010
#define TarsHeadeStructEnd 11   // 1011
#define TarsHeadeZeroTag 12     // 1100
#define TarsHeadeSimpleList 13  // 1101


D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\Tars.h
此处版本是2-14-2.从64行开始声明

7.响应协议反序列化

7.1理解反序列化

理解了协议的序列化,反序列化就比较简单了,假设已经知道iVersion的反序列化数据为^P^A,其中|HEAD|为
^P(注意,HEAD只占一个Byte)

^P转为十进制整数为16,转为二进制为00010000
将数据00010000右移4位为00000001,这就是TAG的值1
将数据00010000做与运算:00010000 & 0x0F = 0, 这就是TYPE的值0,即TarsHeadeChar
知道了TYPE的值,后面|BUF|所占长度可由TYPE得到,本例中也占一个字节,及^A,转为十进制整数为1
这样就完成了iVersion的反序列化

7.2路小饭的协议反序列化测试示例

路小饭的文章链接-访问原文可以看到路小饭提供的测试代码-谢谢路小饭啦

//learn-tars/tup/main.cpp
 56 //反序列化
 57 
 58     list<ResponsePacket> done;
 59 
 60     ProxyProtocol   _proxyProtocol;
 61 
 62     _proxyProtocol.responseFunc = ProxyProtocol::tarsResponse;
 63 
 64     const char* data = s.c_str();
 65 
 66     size_t len = s.size();
 67 
        //反序列化方法,反序列化完的数据放入done中
 68     size_t pos = _proxyProtocol.responseFunc(data, len, done);


这里的responseExFunc来自ProxyProtocol::tarsResponse,其中最主要的逻辑是
//learn-tars/tup/AppProtocal.h
451                 ResponsePacket rsp;
452                 rsp.readFrom(is);

rsp.readFrom(is)中readFrom的实现代码如下:
//learn-tars/tup/RequestF.h
166         template<typename ReaderT>
167         void readFrom(tars::TarsInputStream<ReaderT>& _is)
168         {
169             resetDefautlt();
170             _is.read(iVersion, 1, true);
171             _is.read(cPacketType, 2, true);
172             _is.read(iRequestId, 3, true);
173             _is.read(iMessageType, 4, true);
174             _is.read(iRet, 5, true);
175             _is.read(sBuffer, 6, true);
176             _is.read(status, 7, true);
177             _is.read(sResultDesc, 8, false);
178             _is.read(context, 9, false);
179         }

同样以iVersion为例,简要说明代码处理流程:

上面170行代码会调用:
//learn-tars/tup/Tars.h
1105         void read(Short& n, uint8_t tag, bool isRequire = true)
1106         {
1107             std::cout<<"read Short "<<std::endl;
1108             uint8_t headType = 0, headTag = 0;
1109             bool skipFlag = false;
                 //TarsSkipToTag方法会确认TYPE和TAG的值
1110             TarsSkipToTag(skipFlag, tag, headType, headTag);
1111             if (tars_likely(skipFlag))
1112             {
                     //根据headType的值确定后面|BUF|内容的长度
1113                 switch (headType)
1114                 {
1115                 case TarsHeadeZeroTag:
1116                 std::cout<<"read Short TarsHeadeZeroTag"<<std::endl;
1117                     n = 0;
1118                     break;
1119                 case TarsHeadeChar:
1120                 std::cout<<"read Char TarsHeadeChar"<<std::endl;
1121                     TarsReadTypeBuf(*this, n, Char);
1122                     break;
1123                 case TarsHeadeShort:
1124                 std::cout<<"read Short TarsHeadeShort"<<std::endl;
1125                     TarsReadTypeBuf(*this, n, Short);
1126                     n = ntohs(n);
1127                     break;
1128                 default:
1129                     {
1130                         char s[64];
1131                         snprintf(s, sizeof(s), "read 'Short' type mism
     atch, tag: %d, get type: %d.", tag, headType);
1132                         throw TarsDecodeMismatch(s);
1133                     }
1134                 }
1135             }
1136             else if (tars_unlikely(isRequire))
1137             {
1138                 char s[64];
1139                 snprintf(s, sizeof(s), "require field not exist, tag: 
     %d, headTag: %d", tag, headTag);
1140                 throw TarsDecodeRequireNotExist(s);
1141             }
1142             std::cout<<"read Short n is "<<n<<std::endl;
1143 
1144         }


1110行函数TarsSkipToTag会确认TYPE和TAG的值
1113行会根据headType的值确定后面|BUF|内容的长度
再看下TarsSkipToTag是怎么处理的:

//learn-tars/tup/Tars.h
335 #define TarsSkipToTag(flag, tag, retHeadType, retHeadTag) \
 336 do { \
 337     try \
 338     { \
 339         uint8_t nextHeadType, nextHeadTag; \
 340         while (!ReaderT::hasEnd()) \
 341         { \
 342             size_t len = 0; \
                 //TarsPeekFromHead里进行了运算,得到TYPE和TAGE
 343             TarsPeekFromHead(*this, nextHeadType, nextHeadTag, len); \
 344             if (tars_unlikely(nextHeadType == TarsHeadeStructEnd || ta
     g < nextHeadTag)) \
 345             { \
 346                 break; \
 347             } \
 348             if (tag == nextHeadTag) \
 349             { \
 350                 std::cout<<"TarsSkipToTag tag == nextHeadTag"<<std::en
     dl; \
 351                 (retHeadType) = nextHeadType; \
 352                 (retHeadTag) = nextHeadTag; \
 353                 TarsReadHeadSkip(*this, len); \
 354                 (flag) = true; \
 355                 break; \
 356             } \
 357             std::cout<<"TarsSkipToTag tag != nextHeadTag"<<std::endl; 
     \
 358             TarsReadHeadSkip(*this, len); \
 359             skipField(nextHeadType); \
 360         } \
 361     } \
 362     catch (TarsDecodeException& e) \
 363     { \
 364     } \
 365 } while(0)


343 行TarsPeekFromHead函数里得到了nextHeadType和nextHeadTag,对应着9.2.7节中的运算

//learn-tars/tup/Tars.h
 255 #define TarsPeekFromHead(is, type, tag, n) \
 256 do { \
 257     std::cout<<"TarsPeekFromHead begin"<<std::endl; \
 258     (n) = 1; \
 259     uint8_t typeTag, tmpTag; \
 260     TarsPeekTypeBuf(is, typeTag, 0, uint8_t); \
 261     std::cout<<"TarsPeekFromHead typeTag "<<(int)typeTag<<std::endl; \
 262     tmpTag = typeTag >> 4; \
 263     std::cout<<"TarsPeekFromHead tmpTag "<<(int)tmpTag<<std::endl; \
 264     (type) = (typeTag & 0x0F); \
 265     std::cout<<"TarsPeekFromHead type "<<(int)type<<std::endl; \
 266     if(tars_unlikely(tmpTag == 15)) \
 267     { \
 268         std::cout<<"TarsPeekFromHead unlikely tmpTag "<<(int)tmpTag<<s
     td::endl; \
 269         TarsPeekTypeBuf(is, tag, 1, uint8_t); \
 270         (n) += 1; \
 271     } \
 272     else \
 273     { \
 274         (tag) = tmpTag; \
 275     } \
 276 } while(0)

路小饭于2019-04-12

8.我自己写的测试序列化和反序列化的测试程序及逻辑说明

// 编译的时候加上-std=c++11

#include <iostream>
#include <cassert>
#include <vector>
#include <map>
#include <string>
#include <stdexcept>
#include <functional>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <bitset>
#include <list>
#include <memory>

using namespace std;
typedef bool    Bool;
typedef char    Char;
typedef short   Short;
typedef float   Float;
typedef double  Double;
typedef int     Int32;
typedef long long   Int64;
struct TarsStructBase;

typedef unsigned char   UInt8;
typedef unsigned short  UInt16;
typedef unsigned int    UInt32;
const Char TARSNORMAL = 0;
const Short TARSVERSION = 1;

//Int32 iVersion;
Short iVersion;
Char cPacketType;
Int32 iMessageType;
Int32 iRequestId;
string sServantName;
string sFuncName;
std::string sResultDesc;
vector<Char> sBuffer;
Int32 iTimeout;
map<std::string, std::string> context;
map<std::string, std::string> status;
Int32 iRet;


#ifndef tars_unlikely
#if defined(__GNUC__) && __GNUC__ >= 4
#define tars_unlikely(x)            (__builtin_expect(!!(x),0))
#else
#define tars_unlikely(x)   (x)
#endif
#endif
#define TarsHeadeChar  0
#define TarsHeadeShort 1
#define TarsHeadeInt32 2
#define TarsHeadeInt64 3
#define TarsHeadeFloat 4
#define TarsHeadeDouble 5
#define TarsHeadeString1 6
#define TarsHeadeString4 7
#define TarsHeadeMap 8
#define TarsHeadeList 9
#define TarsHeadeStructBegin 10
#define TarsHeadeStructEnd 11
#define TarsHeadeZeroTag 12
#define TarsHeadeSimpleList 13


string StrToBitStr(const char* str)
{
	// cout << "str is" << str <<endl;
	bitset<128> bstr ;
	for(int i=0;i<16;i++)
	{   
		//cout << "str["<<i<<"] is " << str[i] << endl;
		bitset<8> bits =  bitset<8>(str[i]);
		for(int j = 0;j<8;j++)
		{
			bstr[i*8+j] = bits[j];
			//cout << "i*8 + j = " <<i*8 + j<<", bstr[i*8+j]" << bstr[i*8+j] <<endl;
		}
	}   
	return bstr.to_string();
}



#ifndef TARS_MAX_STRING_LENGTH
#define TARS_MAX_STRING_LENGTH   (100 * 1024 * 1024)
#endif
class DataHead
{
	uint8_t _type;
	uint8_t _tag;
	public:
	enum
	{
		eChar = 0,
		eShort = 1,
		eInt32 = 2,
		eInt64 = 3,
		eFloat = 4,
		eDouble = 5,
		eString1 = 6,
		eString4 = 7,
		eMap = 8,
		eList = 9,
		eStructBegin = 10,
		eStructEnd = 11,
		eZeroTag = 12,
		eSimpleList = 13,
	};
#pragma pack(1)
	struct helper
	{
		uint8_t     type : 4;
		uint8_t     tag  : 4;
	};
#pragma pack()
	public:
	DataHead() : _type(0), _tag(0) {}
	DataHead(uint8_t type, uint8_t tag) : _type(type), _tag(tag) {}

	uint8_t getTag() const      { return _tag;}
	void setTag(uint8_t t)      { _tag = t;}
	uint8_t getType() const     { return _type;}
	void setType(uint8_t t)     { _type = t;}
	/// 读取数据头信息
	template<typename InputStreamT>
		void readFrom(InputStreamT& is)
		{
			size_t n = peekFrom(is);
			is.skip(n);
		}
	/// 读取头信息,但不前移流的偏移量
	template<typename InputStreamT>
		size_t peekFrom(InputStreamT& is)
		{
			helper h;
			size_t n = sizeof(h);
			is.peekBuf(&h, sizeof(h));
			_type = h.type;
			if (h.tag == 15)
			{
				is.peekBuf(&_tag, sizeof(_tag), sizeof(h));
				n += sizeof(_tag);
			}
			else
			{
				_tag = h.tag;
			}
			return n;
		}

	/// 写入数据头信息
	template<typename OutputStreamT>
		void writeTo(OutputStreamT& os)
		{
			/*
			   helper h;
			   h.type = _type;
			   if(_tag < 15){
			   h.tag = _tag;
			   os.writeBuf(&h, sizeof(h));
			   }else{
			   h.tag = 15;
			   os.writeBuf(&h, sizeof(h));
			   os.writeBuf(&_tag, sizeof(_tag));
			   }
			   */
			writeTo(os, _type, _tag);
		}

	/// 写入数据头信息
	template<typename OutputStreamT>
		static void writeTo(OutputStreamT& os, uint8_t type, uint8_t tag)
		{
			helper h;  h.type = type;
			if (tag < 15)
			{
				h.tag = tag;
				os.writeBuf((const char *)&h, sizeof(h));
			}
			else{
				h.tag = 15;os.writeBuf((const char *)&h, sizeof(h));os.writeBuf((const char *)&tag, sizeof(tag));						}
		}
};



// 编码相应的宏
/*
   (os)._reserve(os, len1)我的代码这里实例化之后调用的原型是std::function<char*(BufferWriter &, size_t)>  _reserve = BufferWriter::reserve;
   (os)._reserve(os, len1);中的第二个参数值是要申请的字节数,如果len1小于128,则将len1赋值为128,如果len1>=128,则就取len1的值为要申请的字节数.
   在D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\Tars.h中
   */
#define TarsReserveBuf(os, len) \
	do{ \
		if(tars_likely((os)._buf_len < (len))) \
		{ \
			cout << "line = 196 TarsReserveBuf ,len is "<<len<<endl;\
			size_t len1 = (len)<<1; \
			cout << "line = 198 TarsReserveBuf ,经过(len)<<1计算的len1 的值是 "<<len1<<endl;\
			if(len1<128) len1=128; \
			cout << "line = 200 TarsReserveBuf ,最后经过逻辑赋值的len1的值是 "<<len1<<", will enter BufferWriter::reserve function "<<endl;\
			(os)._buf = (os)._reserve(os, len1); \
			(os)._buf_len = (len1); \
			cout << "line = 203,经过BufferWriter::reserve后(os)._buf is [ "<<(os)._buf<<"], (os)._buf_len is "<< (os)._buf_len<<",(os)_len is "<<(os)._len <<endl;\
		} \
	}while(0)

/*
   TAG由TAG1和TAG2一起组成,标识数据的位置。当TAG值不超过14时候,只需要TAG1,当TAG值超过14时候,TAG1为240,TAG2标识TAG的值。下面的代码标明了这个逻辑:
   具体看个TAG小于14的例子:TAG1为1,TYPE为TarsHeadeInt32(2),用二进制表示的话,TAG1为0001,TYPE为0010,HEAD组成方式是将TAG1二进制和TYPE二进制拼接起来,
   即:
   00010010 换算为10进制是18。 前4位为TAG1,后4位为TYPE,从这样的拼接方式中可以看到,相当于是把TAG1右移了4位再加上TYPE
   从上面贴出的代码中我们也可以看到拼接方式的表示:"(type) + ((tag)<<4)",即:HEAD = 2 + (1<<4) = 2 + 16 = 18.
   就这样Tars协议可以用1byte同时表示数据类型和数据位置


   再看个TAG大于14的例子:TAG1为240(固定值),TAG2为200,TYPE为TarsHeadeInt32(2),HEAD的二进制表示为:
   11110010 11001000 用10进制表示为242 200 前八位中,1111代表TAG1的值240(即11110000),0010代表TYPE的值2(即0010)。后八位为TAG2的值200(即11001000)
   tars_likely((tag) < 15)时候只有TAG1,当tars_likely((tag) >= 15)的时候有tag1也有tag2


*/


//TarsWriteToHead在代码D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\Tars.h中,写协议头的宏函数
#define TarsWriteToHead(os, type, tag) \
	do { \
		if (tars_likely((tag) < 15)) \
		{ \
			cout << "line = 229 ,will call TarsWriteUInt8TTypeBuf function,type is "<<(int)type <<",注意注意,您已进入写协议头的函数,此次只有tag1噢,type is "<<(int)type << ",tag is "<<(int)tag <<". (type) + ((tag)<<4) is "<< (type) + ((tag)<<4) << endl;\
			TarsWriteUInt8TTypeBuf( os, (type) + ((tag)<<4) , (os)._len); \
			cout << "line = 231 ,type is "<<type << ",tag is ["<< (int)tag <<"]"<< endl;\
		} \
		else \
		{ \
			cout << "line = 235 "<<__LINE__<<",type is "<<type << "tag is "<< tag <<",注意注意,您已进入写协议头的函数,此次会有两个tag噢,tag is "<<(int)tag<< endl;\
			TarsWriteUInt8TTypeBuf( os, (type) + (240) , (os)._len); \
			TarsWriteUInt8TTypeBuf( os, (tag),  (os)._len);\
		} \
	} while(0)//TarsWriteCharTypeBuf(*this, n, (*this)._len),在调用TarsWriteCharTypeBuf的时候第三个参数传递的是指针,osLen变化会导致(*this)._len的变化



#define TarsWriteCharTypeBuf(os, val, osLen) \
	do { \
		cout << "line = 245, val is ["<< (int)val << "],osLen is "<< osLen<<","<<",将要开始调用TarsReserveBuf,(os)._buf_len is "<< (os)._buf_len <<",(osLen)+sizeof(Char) is "<<(osLen)+sizeof(Char) <<endl;\
		TarsReserveBuf(os, (osLen)+sizeof(Char)); \
		(*(Char *)((os)._buf + (osLen))) = (val); \
		cout << "line 248,(os)._buf is "<< (os)._buf<<"(os)._len is "<<(os)._len << endl;\
		(osLen) += sizeof(Char); \
		cout << "line 250,(os)._buf is "<< (os)._buf<<"(os)._len is "<<(os)._len << endl;\
	} while(0)




#define TarsWriteInt32TypeBuf(os, val, osLen) \
	do { \
		cout << "line = 258 "<<__LINE__<<endl;\
		TarsReserveBuf(os, (osLen)+sizeof(Int32)); \
		(*(Int32 *)((os)._buf + (osLen))) = (val); \
		(osLen) += sizeof(Int32); \
	} while(0)

#define TarsWriteInt64TypeBuf(os, val, osLen) \
	do { \
		cout << "line = 266 "<<__LINE__<<endl;\
		TarsReserveBuf(os, (osLen)+sizeof(Int64)); \
		(*(Int64 *)((os)._buf + (osLen))) = (val); \
		(osLen) += sizeof(Int64); \
	} while(0)

#define TarsWriteFloatTypeBuf(os, val, osLen) \
	do { \
		cout << "line = 274 "<<__LINE__<<endl;\
		TarsReserveBuf(os, (osLen)+sizeof(Float)); \
		(*(Float *)((os)._buf + (osLen))) = (val); \
		(osLen) += sizeof(Float); \
	} while(0)

#define TarsWriteDoubleTypeBuf(os, val, osLen) \
	do { \
		cout << "line = 282 "<<__LINE__<<endl;\
		TarsReserveBuf(os, (osLen)+sizeof(Double)); \
		(*(Double *)((os)._buf + (osLen))) = (val); \
		(osLen) += sizeof(Double); \
	} while(0)

#define TarsWriteUInt32TTypeBuf(os, val, osLen) \
	do { \
		cout << "line = 290 "<<__LINE__<<endl;\
		TarsReserveBuf(os, (osLen)+sizeof(uint32_t)); \
		(*(uint32_t *)((os)._buf + (osLen))) = (val); \
		(osLen) += sizeof(uint32_t); \
	} while(0)




// 调用方法:TarsWriteUInt8TTypeBuf(*this, n, (*this)._len);
#define TarsWriteUInt8TTypeBuf(os, val, osLen) \
	do { \
		cout << "line = 302,TarsWriteUInt8TTypeBuf ,val is "<< (int)val <<", osLen is "<<osLen<<",  [(osLen)+sizeof(uint8_t)] is "<<( (osLen)+sizeof(uint8_t) )<<endl;\
		cout << "line 303,(os)._len is "<<(os)._len << endl;\
		TarsReserveBuf(os, (osLen)+sizeof(uint8_t)); \
		cout << "line 305,(os)._buf is 【"<< (os)._buf<<"】,(os)._len is "<<(os)._len <<", StrToBitStr((os)._buf) is   "<< StrToBitStr((os)._buf)<< endl;\
		(*(uint8_t *)((os)._buf + (osLen))) = (val); \
		(osLen) += sizeof(uint8_t); \
		cout << "line 308 ,(os)._buf is 【"<< (char*)(os)._buf<<"】,(os)._len is "<<(os)._len <<", StrToBitStr((os)._buf) is "<< StrToBitStr((os)._buf)<< endl;\
	} while(0)

#define TarsWriteUIntTypeBuf(os, val, osLen) \
	do { \
		cout << "line = 312 "<<__LINE__<<endl;\
		TarsReserveBuf(os, (osLen)+sizeof(unsigned int)); \
		(*(unsigned int *)((os)._buf + (osLen))) = (val); \
		(osLen) += sizeof(unsigned int); \
	} while(0)

#define TarsWriteShortTypeBuf(os, val, osLen) \
	do { \
		cout << "line = 320 "<<endl;\
		TarsReserveBuf(os, (osLen)+sizeof(Short)); \
		(*(Short *)((os)._buf + (osLen))) = (val); \
		(osLen) += sizeof(Short); \
	} while(0)

//memcpy(p, (os)._buf, (os)._len);//void *memcpy(void *dest, void *src, unsigned int count);把资源内存(src所指向的内存区域) 拷贝到目标内存(dest所指向的内存区域);拷贝多少个?有一个count变量控制
#define TarsWriteTypeBuf(os, buf, len) \
	do { \
		cout << "line = 347 ,len is  "<<len<<", buf is 【" << (char *)(buf)<< "】"<<"StrToBitStr(((char *)(buf)) is "<<StrToBitStr(buf) <<",(os)._len is "<<(os)._len<< endl;\
		TarsReserveBuf(os, (os)._len + (len)); \
		cout<< "line = 349 StrToBitStr((os)._buf) is "<< StrToBitStr((os)._buf)<<",(os)._buf  is"<< (os)._buf  << ",(os)._len "<< (os)._len << endl;\
		cout << "line = 350 ,buf is "<< buf <<endl;\
		memcpy((os)._buf + (os)._len, (const void *)(buf), (len)); \
		(os)._len += (len); \
		cout << "line = 353,(os)._len = "<<(os)._len<<", (os)._buf[9] = "<< (os)._buf[9]<<", (os)._buf[10] = "<< (os)._buf[10]<<", (os)._buf[11] = "<< (os)._buf[11]<<endl;\
		cout << "line = 353,(os)._len = "<<(os)._len<<", (os)._buf[12] = "<< (int)((os)._buf[12])<<", (os)._buf[13] = "<< (os)._buf[13]<<", (os)._buf[14] = "<< (os)._buf[14]<<", (os)._buf[15] = "<< (os)._buf[15]<<endl;\
		cout<< "line = 354 StrToBitStr((os)._buf) is "<< StrToBitStr((os)._buf)<< endl;\
	} while(0)






namespace detail
{
	union bswap_helper
	{
		Int64   i64;
		Int32   i32[2];
	};   
	// is_convertible
	template<int N> struct type_of_size { char elements[N]; };

	typedef type_of_size<1>     yes_type;
	typedef type_of_size<2>     no_type;

	namespace meta_detail
	{
		struct any_conversion
		{
			template <typename T> any_conversion(const volatile T&);
			template <typename T> any_conversion(T&);
		};

		template <typename T> struct conversion_checker
		{
			static no_type _m_check(any_conversion ...);
			static yes_type _m_check(T, int);
		};
	}

	template<typename From, typename To> 
		class is_convertible
		{
			static From _m_from;
			public:
			enum { value = sizeof( meta_detail::conversion_checker<To>::_m_check(_m_from, 0) ) == sizeof(yes_type) };
		};

	template<typename T> 
		struct type2type { typedef T type; };

	template<typename T, typename U> 
		struct is_same_type
		{
			enum { value = is_convertible< type2type<T>, type2type<U> >::value };
		};

	// enable_if
	template<bool B, class T = void> struct enable_if_c { typedef T type; };

	template<class T> struct enable_if_c<false, T> {};

	template<class Cond, class T = void> 
		struct enable_if : public enable_if_c<Cond::value, T> {};

	template<bool B, class T = void> struct disable_if_c { typedef T type; };

	template<class T> struct disable_if_c<true, T> {};

	template<class Cond, class T = void> 
		struct disable_if : public disable_if_c<Cond::value, T> {};
}



inline Int64 tars_htonll(Int64 x)
{
	detail::bswap_helper h;
	h.i64 = x;
	Int32 tmp = htonl(h.i32[1]);
	h.i32[1] = htonl(h.i32[0]);
	h.i32[0] = tmp;
	return h.i64;
}


inline Float tars_ntohf(Float x)
{
	union {
		Float f;
		Int32 i32;
	} helper;

	helper.f = x;
	helper.i32 = htonl( helper.i32 );

	return helper.f;
}
#       define tars_htonf(x)     tars_ntohf(x)


inline Double tars_ntohd(Double x)
{
	union {
		Double d;
		Int64 i64;
	} helper;

	helper.d = x;
	helper.i64 = tars_htonll( helper.i64 );

	return helper.d;
}
#       define tars_htond(x)     tars_ntohd(x)



#define tars_likely(x)   (x)

class BufferWriter
{
	public:
		char *  _buf;
		size_t  _len;
		size_t  _buf_len;
		std::function<char*(BufferWriter &, size_t)>  _reserve = BufferWriter::reserve;    //扩展空间

		static char* reserve(BufferWriter &os, size_t len)
		{
			char * p = new char[(len)]; cout << "You haved entered function BufferWriter::reserve. (os)._len is "<< (os)._len <<endl; if((os)._buf == NULL) cout << "(os)._buf is NULL"<<endl;
			memcpy(p, (os)._buf, (os)._len);//void *memcpy(void *dest, void *src, unsigned int count);把资源内存(src所指向的内存区域) 拷贝到目标内存(dest所指向的内存区域);拷贝多少个?有一个count变量控制
			delete[] (os)._buf;
			return p;
		}

	private:
		BufferWriter(const BufferWriter & bw);
		BufferWriter& operator=(const BufferWriter& buf);

	public:
		BufferWriter()
			: _buf(NULL)
			  , _len(0)
			  , _buf_len(0)
	        {}
		~BufferWriter()
		{
			delete[] _buf;
		}

		void reset() { _len = 0;}
		void writeBuf(const char * buf, size_t len)
		{
			TarsReserveBuf(*this, _len + len);
			memcpy(_buf + _len, buf, len);
			_len += len;
		}
		std::vector<char> getByteBuffer() const       { return std::vector<char>(_buf, _buf + _len);}
		const char * getBuffer() const                { return _buf;}
             size_t getLength() const                     { return _len;}  
             void swap(std::vector<char>& v)              { v.assign(_buf, _buf + _len); }
             void swap(std::string& v)                    { v.assign(_buf, _len); }
             void swap(BufferWriter& buf)
                 {
	             std::swap(_buf, buf._buf);
	             std::swap(_buf_len, buf._buf_len);
	             std::swap(_len, buf._len);
                 }
};

template<typename WriterT = BufferWriter>
class TarsOutputStream : public WriterT
{
	public:
		void writeUnknown(const std::string& s)
		{
			cout << "line = "<< __LINE__<< ", call func " <<__func__<< endl;
			this->writeBuf(s.data(), s.size());
		}
		void writeUnknownV2(const std::string& s)
		{
			cout << "line = "<< __LINE__<< ", call func " <<__func__<< endl;
			DataHead::writeTo(*this, DataHead::eStructBegin, 0);
			this->writeBuf(s.data(), s.size());
			DataHead::writeTo(*this, DataHead::eStructEnd, 0);
		}
		void write(Bool b, uint8_t tag)
		{
			cout << "line = "<< __LINE__<< ", call func " <<__func__<< endl;
			write((Char) b, tag);
		}

		void write(Char n, uint8_t tag)//D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\Tars.h
		{

			cout << "line = "<< __LINE__<< ", enter function write(Char,uint8_t). ,n is "<< (int)n << ",tag is "<<(int)tag << endl;
			if (tars_unlikely(n == 0))
                        {
				cout << "line = "<< __LINE__<< ", n == 0, it will call func TarsWriteToHead ," <<"tag is "<<(int)tag<<",TarsHeadeZeroTag is "<<TarsHeadeZeroTag<< endl;
				TarsWriteToHead(*this, TarsHeadeZeroTag, tag);
				cout << "line = "<< __LINE__<< ", 经过写头BUF 的信息之后,序列化为:【"<< StrToBitStr((*this)._buf)<<"】."<<endl;
			}
			else
                        {
				cout << "line = "<< __LINE__<< ", it will call func TarsWriteToHead ," <<"tag is "<<(int)tag<<",TarsHeadeChar is "<<TarsHeadeChar<< endl;
				TarsWriteToHead(*this, TarsHeadeChar, tag);
				cout << "line = "<< __LINE__<< ", 经过写头HEAD的信息之后,序列化为:【"<< StrToBitStr((*this)._buf)<<"】, it will call func  TarsWriteCharTypeBuf"<<endl;
				TarsWriteCharTypeBuf(*this, n, (*this)._len);
				cout << "line = "<< __LINE__<< ", 经过写头BUF 的信息之后,序列化为:【"<< StrToBitStr((*this)._buf)<<"】."<<endl;
			}  
		}

		void write(UInt8 n, uint8_t tag)
		{
			cout << "line = "<< __LINE__<< ", call func " <<__func__<< endl;
			write((Short) n, tag);
		}

		void write(Short n, uint8_t tag)
		{
			cout << "line = "<< __LINE__<< ", n = " <<n<<",call func write(Short,uint8_t),tag is ["<<(int)tag<<"]"<< endl;
			if (n >= (-128) && n <= 127)
			{
				cout << "line = "<< __LINE__<< ",n>=(-128) & n <= 127" <<endl;
				write((Char) n, tag);
			}
			else
			{
				cout << "line = "<< __LINE__<< ", it will call func TarsWriteToHead ," <<"tag is "<<(int)tag<<",TarsHeadeShort is "<<TarsHeadeShort<< endl;
				TarsWriteToHead(*this, TarsHeadeShort, tag);
				cout << "line = "<< __LINE__<< ", 经过写头HEAD的信息之后,序列化为:【"<< StrToBitStr((*this)._buf)<<"】, it will call func  TarsWriteShortTypeBuf"<<endl;
				n = htons(n);
				TarsWriteShortTypeBuf(*this, n, (*this)._len);
				cout << "line = "<< __LINE__<< ", 经过写头BUF 的信息之后,序列化为:【"<< StrToBitStr((*this)._buf)<<"】."<<endl;
			}
		}

		void write(UInt16 n, uint8_t tag)
		{
			cout << "line = "<< __LINE__<< ", call func " <<__func__<< endl;
			write((Int32) n, tag);
		}

		void write(Int32 n, uint8_t tag)
		{
			cout << "line = "<< __LINE__<< ", call func write, n is Int32(0010),tage is " <<(int)tag<< endl;
			if (n >= (-32768) && n <= 32767)
			{
				cout << "line = "<< __LINE__<< ", convert call write(Int32,uint8_t) to call write(Short,uint8_t), n is Short(0011),tage is " <<(int)tag<< endl;
				write((Short) n, tag);
			}
			else
			{  
				cout << "line = "<< __LINE__<< ", call func TarsWriteToHead, htonl, TarsWriteInt32TypeBuf" << endl;
				TarsWriteToHead(*this, TarsHeadeInt32, tag);
				cout << "line = "<< __LINE__<< ", 经过写头HEAD的信息之后,序列化为:【"<< StrToBitStr((*this)._buf)<<"】, it will call func  TarsWriteInt32TypeBuf"<<endl;
				n = htonl(n);
				TarsWriteInt32TypeBuf(*this, n, (*this)._len);
				cout << "line = "<< __LINE__<< ", 经过写头BUF 的信息之后,序列化为:【"<< StrToBitStr((*this)._buf)<<"】."<<endl;
			}
		}

		void write(UInt32 n, uint8_t tag)
		{
			cout << "line = "<< __LINE__<< ", call func " <<__func__<< endl;
			write((Int64) n, tag);
		}

		void write(Int64 n, uint8_t tag)
		{
			cout << "line = "<< __LINE__<< ", call func " <<__func__<< endl;
			if (n >= (-2147483647-1) && n <= 2147483647)
			{
				write((Int32) n, tag);
			}
			else
			{
				cout << "line = "<< __LINE__<< ", n == 0, it will call func TarsWriteToHead ," <<"tag is "<<(int)tag<<",TarsHeadeInt64 is "<<TarsHeadeInt64<< endl;
				TarsWriteToHead(*this, TarsHeadeInt64, tag);
				cout << "line = "<< __LINE__<< ", 经过写头HEAD的信息之后,序列化为:【"<< StrToBitStr((*this)._buf)<<"】, it will call func  TarsWriteInt64TypeBuf"<<endl;
				n = tars_htonll(n);
				TarsWriteInt64TypeBuf(*this, n, (*this)._len);
				cout << "line = "<< __LINE__<< ", 经过写头BUF 的信息之后,序列化为:【"<< StrToBitStr((*this)._buf)<<"】."<<endl;
			}
		}

		void write(Float n, uint8_t tag)
		{
			cout << "line = "<< __LINE__<< ", call func " <<__func__<< endl;
			TarsWriteToHead(*this, TarsHeadeFloat, tag);
			n = tars_htonf(n);
			TarsWriteFloatTypeBuf(*this, n, (*this)._len);
		}

		void write(Double n, uint8_t tag)
		{
			cout << "line = "<< __LINE__<< ", call func " <<__func__<< endl;
			TarsWriteToHead(*this, TarsHeadeDouble, tag);
			n = tars_htond(n);
			TarsWriteDoubleTypeBuf(*this, n, (*this)._len);
		}

		void write(const std::string& s, uint8_t tag)
		{
			cout << "line = "<< __LINE__<< ", call func write(const std::string&,uint8_t). s.size() is  "<< s.size()<< endl;
			if (tars_unlikely(s.size() > 255))
			{  
				cout << "line = "<< __LINE__<< ", tars_unlikely(s.size() > 255  "<< endl;
				if (tars_unlikely(s.size() > TARS_MAX_STRING_LENGTH))
				{
					char ss[128];
					snprintf(ss, sizeof(ss), "invalid string size, tag: %d, size: %u", tag, (uint32_t)s.size());
					//throw TarsDecodeInvalidValue(ss);
					cout << ss << endl;
				}
				TarsWriteToHead(*this, TarsHeadeString4, tag);
				uint32_t n = htonl((uint32_t)s.size());
				TarsWriteUInt32TTypeBuf(*this, n, (*this)._len);
				TarsWriteTypeBuf(*this, s.data(), s.size());
			}
			else
			{
				cout << "line = "<< __LINE__<< ", tars_unlikely(s.size() <= 255  "<< endl;
				TarsWriteToHead(*this, TarsHeadeString1, tag);
				cout << "line = "<< __LINE__<< ", 经过字段的HEAD的信息之后,序列化为:【"<< StrToBitStr((*this)._buf)<<"】, it will call func  TarsWriteUInt8TTypeBuf and TarsWriteTypeBuf"<<endl;
				uint8_t n = (uint8_t)s.size();
				cout << "line = "<< __LINE__<< ", n =   "<<(int)n<< endl;
				TarsWriteUInt8TTypeBuf(*this, n, (*this)._len);
				TarsWriteTypeBuf(*this, s.data(), s.size());
				cout << "line = "<< __LINE__<< ", 经过写头BUF 的信息之后,序列化为:【"<< StrToBitStr((*this)._buf)<<"】."<<endl;
			}
		}

		void write(const char *buf, const UInt32 len, uint8_t tag)
		{
			cout << "line = "<< __LINE__<< ", call func " <<__func__<< endl;
			TarsWriteToHead(*this, TarsHeadeSimpleList, tag);
			TarsWriteToHead(*this, TarsHeadeChar, 0);
			write(len, 0);
			TarsWriteTypeBuf(*this, buf, len);
		}

		template<typename K, typename V, typename Cmp, typename Alloc>
			void write(const std::map<K, V, Cmp, Alloc>& m, uint8_t tag)
			{
				cout << "line = "<< __LINE__<< ", call func write(const std::map<K,V,Cmp,Alloc>,uint8_t)." << endl;
				TarsWriteToHead(*this, TarsHeadeMap, tag);
				Int32 n = (Int32)m.size();
				cout << "line = "<< __LINE__<< ", func write(const std::map<K,V,Cmp,Alloc>,uint8_t)中将要调用write(n, 0)并将要遍历容器map的对象m并且将调用write(i->first, 0)和write(i->second, 1)" << endl;
				write(n, 0);
				typedef typename std::map<K, V, Cmp, Alloc>::const_iterator IT;
				for (IT i = m.begin(); i != m.end(); ++i)
				{
					write(i->first, 0);
					write(i->second, 1);
				}
			}

		template<typename T, typename Alloc>
			void write(const std::vector<T, Alloc>& v, uint8_t tag)
			{
				cout << "line = "<< __LINE__<< ", call func write(const std::vector<T, Alloc>& v, uint8_t tag." << endl;
                         TarsWriteToHead(*this, TarsHeadeList, tag);
				Int32 n = (Int32)v.size();
				write(n, 0);
				typedef typename std::vector<T, Alloc>::const_iterator IT;
				for (IT i = v.begin(); i != v.end(); ++i)
					write(*i, 0);
			}

		template<typename T>
			void write(const T *v, const UInt32 len, uint8_t tag)
			{
				cout << "line = "<< __LINE__<< ", call func write(const T *v, const UInt32 len, uint8_t tag)." << endl;
                         TarsWriteToHead(*this, TarsHeadeList, tag);
				write(len, 0);
				for (Int32 i = 0; i < (Int32)len; ++i)
				{
					write(v[i], 0);
				}
			}





		template<typename Alloc>
			void write(const std::vector<Char, Alloc>& v, uint8_t tag)
			{
				cout << "line = "<< __LINE__<< ", call func write(const std::vector<Char, Alloc>& v, uint8_t tag).it will call TarsWriteToHead(*this, TarsHeadeSimpleList, tag)" << endl;
                         TarsWriteToHead(*this, TarsHeadeSimpleList, tag);//标记 TarsHeadeSimpleList
                         cout << "line = "<< __LINE__<< ", call func write(const std::vector<Char, Alloc>& v, uint8_t tag).it will call TarsWriteToHead(*this, TarsHeadeChar, 0)" << endl;
				TarsWriteToHead(*this, TarsHeadeChar, 0);// 标记 TarsHeadeSimpleList
				Int32 n = (Int32)v.size(); 
				write(n, 0); // 将vector的size的大小写道序列中,用Int32的变量来接住这个大小,然后再写进序列中
				TarsWriteTypeBuf(*this, v.data(), v.size());
			}






		template<typename T>
			void write(const T& v, uint8_t tag, typename detail::disable_if<detail::is_convertible<T*, TarsStructBase*>, void ***>::type dummy = 0)
			{
				write((Int32) v, tag);
			}

		template<typename T>
			void write(const T& v, uint8_t tag, typename detail::enable_if<detail::is_convertible<T*, TarsStructBase*>, void ***>::type dummy = 0)
			{
				TarsWriteToHead(*this, TarsHeadeStructBegin, tag);
				v.writeTo(*this);
				TarsWriteToHead(*this, TarsHeadeStructEnd, 0);
			}
};


// 这里用的是ResponsePacket那一部分的代码,编码,代码路径D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\Tars.h
template<typename WriterT>
void writeTo(TarsOutputStream<WriterT>& _os)    
{ 
	cout << "line = "<<__LINE__<<",_os.write(iVersion, 1) ====================================================================================================================" <<endl;
	_os.write(iVersion, 1);

	cout << "line = "<<__LINE__<<",_os.write(cPacketType, 2)==================================================================================================================" <<endl;
	_os.write(cPacketType, 2);

	cout << "line = "<<__LINE__<<",_os.write(iRequestId, 3)==================================================================================================================" <<endl;
	_os.write(iRequestId, 3);

	cout << "line = "<<__LINE__<<",_os.write(iMessageType, 4)=================================================================================================================="<<endl;
	_os.write(iMessageType, 4);

	cout << "line = "<<__LINE__<<",_os.write(iRet, 5)==========================================================================================================================" <<endl;
	_os.write(iRet, 5);

	cout << "line = "<<__LINE__<<",_os.write(sBuffer, 6)=======================================================================================================================" <<endl;
	_os.write(sBuffer, 6);
	/*
	  cout << "line = "<<__LINE__<<",_os.write(status, 7)=========================================================================================================================" <<endl;
	   _os.write(status, 7);
	   if (sResultDesc != "")
	   {
	  cout << "line = "<<__LINE__<<",_os.write(sResultDesc, 8)==================================================================================================================" <<endl;
	   _os.write(sResultDesc, 8);
	   }
	   if (context.size() > 0)
	   {
	  cout << "line = "<<__LINE__<<",_os.write(sResultDesc, 9)=================================================================================================================="<<endl;
	   _os.write(sResultDesc, 9);
	   }
	  cout << "line = "<<__LINE__<<",_os.write(iVersion, 16) ====================================================================================================================" <<endl;
	   _os.write(iVersion, 16);
	 */

}



// 定义一些异常类
struct TarsProtoException : public std::runtime_error
{
	TarsProtoException(const std::string& s) : std::runtime_error(s) {}
};

struct TarsEncodeException : public TarsProtoException
{
	TarsEncodeException(const std::string& s) : TarsProtoException(s) {}
};

struct TarsDecodeException : public TarsProtoException
{
	TarsDecodeException(const std::string& s) : TarsProtoException(s) {}
};

struct TarsDecodeMismatch : public TarsDecodeException
{
	TarsDecodeMismatch(const std::string & s) : TarsDecodeException(s) {}
};

struct TarsDecodeRequireNotExist : public TarsDecodeException
{
	TarsDecodeRequireNotExist(const std::string & s) : TarsDecodeException(s) {}
};

struct TarsDecodeInvalidValue : public TarsDecodeException
{
	TarsDecodeInvalidValue(const std::string & s) : TarsDecodeException(s) {}
};

struct TarsNotEnoughBuff : public TarsProtoException
{
	TarsNotEnoughBuff(const std::string & s) : TarsProtoException(s) {}
};




//解码相应的宏
#define TarsPeekTypeBuf(is, buf, offset, type) \
do { \
    if(tars_unlikely((is)._cur+(offset)+sizeof(type)>(is)._buf_len) )\
    { \
        char s[64]; \
        snprintf(s, sizeof(s), "buffer overflow when peekBuf, over %u.", (uint32_t)((is)._buf_len)); \
        throw TarsDecodeException(s); \
    } \
    (buf) = (*((type *)((is)._buf+(is)._cur+(offset)))); \
} while(0)

#define TarsPeekTypeBufNoTag(is, offset, type) \
do { \
    if(tars_unlikely((is)._cur+(offset)+sizeof(type)>(is)._buf_len) )\
    { \
        char s[64]; \
        snprintf(s, sizeof(s), "buffer overflow when peekBuf, over %u.", (uint32_t)((is)._buf_len)); \
        throw TarsDecodeException(s); \
    } \
} while(0)

#define TarsReadCharTypeBuf(is, buf) \
do { \
    TarsPeekTypeBuf(is, buf, 0, Char); \
    (is)._cur += sizeof(Char); \
} while(0)

#define TarsReadShortTypeBuf(is, buf) \
do { \
    TarsPeekTypeBuf(is, buf, 0, Short); \
    (is)._cur += sizeof(Short); \
} while(0)

#define TarsReadInt32TypeBuf(is, buf) \
do { \
    TarsPeekTypeBuf(is, buf, 0, Int32); \
    (is)._cur += sizeof(Int32); \
} while(0)

#define TarsReadInt64TypeBuf(is, buf) \
do { \
    TarsPeekTypeBuf(is, buf, 0, Int64); \
    (is)._cur += sizeof(Int64); \
} while(0)

#define TarsReadFloatTypeBuf(is, buf) \
do { \
    TarsPeekTypeBuf(is, buf, 0, Float); \
    (is)._cur += sizeof(Float); \
} while(0)

#define TarsReadDoubleTypeBuf(is, buf) \
do { \
    TarsPeekTypeBuf(is, buf, 0, Double); \
    (is)._cur += sizeof(Double); \
} while(0)

#define TarsReadTypeBuf(is, buf, type) \
do { \
    TarsPeekTypeBuf(is, buf, 0, type); \
    (is)._cur += sizeof(type); \
} while(0)

#define TarsReadHeadSkip(is, len) \
do {\
    (is)._cur += (len); \
} while(0)

#define TarsPeekFromHead(is, type, tag, n) \
do { \
    (n) = 1; \
    uint8_t typeTag, tmpTag; \
    TarsPeekTypeBuf(is, typeTag, 0, uint8_t); \
    tmpTag = typeTag >> 4; \
    (type) = (typeTag & 0x0F); \
    if(tars_unlikely(tmpTag == 15)) \
    { \
        TarsPeekTypeBuf(is, tag, 1, uint8_t); \
        (n) += 1; \
    } \
    else \
    { \
        (tag) = tmpTag; \
    } \
} while(0)

#define readFromHead(is, type ,tag) \
do { \
    size_t n = 0; \
    TarsPeekFromHead(is, type, tag, n); \
    TarsReadHeadSkip(is, n); \
} while(0)

#define TarsPeekFromHeadNoTag(is, type, n) \
do { \
    (n) = 1; \
    uint8_t typeTag, tmpTag; \
    TarsPeekTypeBuf(is, typeTag, 0, uint8_t); \
    tmpTag = typeTag >> 4; \
    (type) = (typeTag & 0x0F); \
    if(tars_unlikely(tmpTag == 15)) \
    { \
        TarsPeekTypeBufNoTag(is, 1, uint8_t); \
        (n) += 1; \
    } \
} while(0)

#define readFromHeadNoTag(is, type) \
do { \
    size_t n = 0; \
    TarsPeekFromHeadNoTag(is, type, n); \
    TarsReadHeadSkip(is, n); \
} while(0)

#define TarsPeekBuf(is ,buf, len, offset) \
do {\
    if (tars_unlikely((is)._cur + (offset) + (len) > (is)._buf_len)) \
    { \
        char s[64]; \
        snprintf(s, sizeof(s), "buffer overflow when peekBuf, over %u.", (uint32_t)((is)._buf_len)); \
        throw TarsDecodeException(s); \
    } \
    ::memcpy(buf, (is)._buf + (is)._cur + (offset), (len)); \
} while(0)

#define TarsReadBuf(is, buf, len) \
do { \
    cout << "line = 956 in mocro function TarsReadBuf" <<endl;\
    TarsPeekBuf(is, buf, len, 0); \
    (is)._cur += (len); \
} while(0)

#define TarsReadStringBuf(is, str, len) \
do{\
    if (tars_unlikely((is)._cur + (len) > (is)._buf_len)) \
    { \
        char s[64]; \
        snprintf(s, sizeof(s), "buffer overflow when peekBuf, over %u.", (uint32_t)((is)._buf_len)); \
        throw TarsDecodeException(s); \
    } \
    str.assign((is)._buf + (is)._cur, (is)._buf + (is)._cur + (len)); \
    (is)._cur += len; \
} while (0)


/*line 984 TarsPeekFromHead里进行了运算,得到TYPE和TAGE
  this指针指向TarsInputStream一个对象,在这个对象继承自ReaderT,ReaderT=BufferReader,
  BufferReader中有:
  const char *        _buf;        ///< 缓冲区
  size_t              _buf_len;    ///< 缓冲区长度
  size_t              _cur;        ///< 当前位置

*/
#define TarsSkipToTag(flag, tag, retHeadType, retHeadTag) \
do { \
    try \
    { \
       cout << "line = 985 in mocro function TarsSkipToTag" <<endl;\
       uint8_t nextHeadType, nextHeadTag; \
       while (!ReaderT::hasEnd()) \
        { \
            cout << "line = 989 in mocro function TarsSkipToTag,  ReaderT::hasEnd() is false" <<endl;\
            size_t len = 0; \
            cout << "line = 991 in mocro function TarsSkipToTag,  will start function TarsPeekFromHead" <<endl;\
            TarsPeekFromHead(*this, nextHeadType, nextHeadTag, len); \
            cout << "line = 993 in mocro function TarsSkipToTag,  this->_buf is 【"<< this->_buf <<"】,this->_buf_len is "<<this->_buf_len<<",this->_cur is "<< this->_cur<<endl;\
            if (tars_unlikely(nextHeadType == TarsHeadeStructEnd || tag < nextHeadTag)) \
               { \
                break; \
               } \
            if (tag == nextHeadTag) \
               { \
                (retHeadType) = nextHeadType; \
                (retHeadTag) = nextHeadTag; \
                TarsReadHeadSkip(*this, len); \
                (flag) = true; \
                break; \
               } \
            TarsReadHeadSkip(*this, len); \
            skipField(nextHeadType); \
        } \
    } \
    catch (TarsDecodeException& e) \
    { \
    } \
} while(0)


#if __BYTE_ORDER == __BIG_ENDIAN
#   define tars_ntohll(x)    (x)
#   define tars_htonll(x)    (x)
#   define tars_ntohf(x)     (x)
#   define tars_htonf(x)     (x)
#   define tars_ntohd(x)     (x)
#   define tars_htond(x)     (x)
#else
#   if __BYTE_ORDER == __LITTLE_ENDIAN
#       define tars_ntohll(x)    tars_htonll(x)
#       define tars_htonf(x)     tars_ntohf(x)
#       define tars_htond(x)     tars_ntohd(x)
#   endif
#endif





// 缓冲区读取封装器
class BufferReader
{
private:
	BufferReader(const BufferReader&);

	BufferReader& operator=(const BufferReader&);

public:
	const char *        _buf;        ///< 缓冲区
	size_t              _buf_len;    ///< 缓冲区长度
	size_t              _cur;        ///< 当前位置

public:

	BufferReader() : _buf(NULL),_buf_len(0),_cur(0) {}

	void reset() { _cur = 0;}

	/// 读取缓存
	void readBuf(void * buf, size_t len)
	{
		if(len <= _buf_len && (_cur + len) <= _buf_len)
		{
			peekBuf(buf, len);
			_cur += len;
		}
		else
		{
			char s[64];
			snprintf(s, sizeof(s), "buffer overflow when skip, over %u.", (uint32_t)_buf_len);
			throw TarsDecodeException(s);
		}
	}

	/// 读取缓存,但不改变偏移量
	void peekBuf(void * buf, size_t len, size_t offset = 0)
	{
		if (_cur + offset + len > _buf_len)
		{
			char s[64];
			snprintf(s, sizeof(s), "buffer overflow when peekBuf, over %u.", (uint32_t)_buf_len);
			throw TarsDecodeException(s);
		}
		::memcpy(buf, _buf + _cur + offset, len);
	}

	/// 读取缓存 for vector<char>
	template <typename Alloc>
	void readBuf(std::vector<Char, Alloc>& v, size_t len)
	{
		if(len <= _buf_len && (_cur + len) <= _buf_len)
		{
			peekBuf(v, len);
			_cur += len;
		}
		else
		{
			char s[64];
			snprintf(s, sizeof(s), "buffer overflow when skip, over %u.", (uint32_t)_buf_len);
			throw TarsDecodeException(s);
		}
	}

	/// 读取缓存,但不改变偏移量 for vector<char>
	template <typename Alloc>
	void peekBuf(std::vector<Char, Alloc>& v, size_t len, size_t offset = 0)
	{
		if (_cur + offset + len > _buf_len)
		{
			char s[64];
			snprintf(s, sizeof(s), "buffer overflow when peekBuf, over %u.", (uint32_t)_buf_len);
			throw TarsDecodeException(s);
		}

		const char* begin = _buf + _cur + offset;
		v.assign(begin, begin + len);
	}

	/// 跳过len个字节
	void skip(size_t len)
	{
		if(len <= _buf_len && (_cur + len) <= _buf_len)
		{
			_cur += len;
		}
		else
		{
			char s[64];
			snprintf(s, sizeof(s), "buffer overflow when skip, over %u.", (uint32_t)_buf_len);
			throw TarsDecodeException(s);
		}
	}

	/// 设置缓存
	void setBuffer(const char * buf, size_t len)
	{
		_buf = buf;
		_buf_len = len;
		_cur = 0;
	}

	/// 设置缓存
	template<typename Alloc>
	void setBuffer(const std::vector<char,Alloc> &buf)
	{
		_buf = buf.data();
		_buf_len = buf.size();
		_cur = 0;
	}

	/**
	 * 判断是否已经到BUF的末尾
	 */
	bool hasEnd()
	{
		if(_cur > _buf_len)
		{
			char s[64];
			snprintf(s, sizeof(s), "buffer overflow when skip, over %u.", (uint32_t)_buf_len);
			throw TarsDecodeException(s);
		}
		return _cur >= _buf_len;
	}
	size_t tellp() const
	{
		return _cur;
	}
	const char* base() const
	{
		return _buf;
	}
	size_t size() const
	{
		return _buf_len;
	}
};


// TARS输入流的类的定义,代码路径D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\Tars.h
template<typename ReaderT = BufferReader>
class TarsInputStream : public ReaderT
{
public:

	/// 跳到指定标签的元素前
	bool skipToTag(uint8_t tag)
	{
		try
		{
			uint8_t headType = 0, headTag = 0;
			while (!ReaderT::hasEnd())
			{
				size_t len = 0;
				TarsPeekFromHead(*this, headType, headTag, len);
				if (tag <= headTag || headType == TarsHeadeStructEnd)
					return headType == TarsHeadeStructEnd?false:(tag == headTag);
				TarsReadHeadSkip(*this, len);
				skipField(headType);
			}
		}
		catch (TarsDecodeException& e)
		{
		}
		return false;
	}

	/// 跳到当前结构的结束
	void skipToStructEnd()
	{
		uint8_t headType = 0;
		do
		{
			readFromHeadNoTag(*this, headType);
			skipField(headType);
		}while (headType != TarsHeadeStructEnd);
	}

	/// 跳过一个字段
	void skipField()
	{
		uint8_t headType = 0;
		readFromHeadNoTag(*this, headType);
		skipField(headType);
	}

	/// 跳过一个字段,不包含头信息
	void skipField(uint8_t type)
	{
		switch (type)
		{
			case TarsHeadeChar:
				TarsReadHeadSkip(*this, sizeof(Char));
				break;
			case TarsHeadeShort:
				TarsReadHeadSkip(*this, sizeof(Short));
				break;
			case TarsHeadeInt32:
				TarsReadHeadSkip(*this, sizeof(Int32));
				break;
			case TarsHeadeInt64:
				TarsReadHeadSkip(*this, sizeof(Int64));
				break;
			case TarsHeadeFloat:
				TarsReadHeadSkip(*this, sizeof(Float));
				break;
			case TarsHeadeDouble:
				TarsReadHeadSkip(*this, sizeof(Double));
				break;
			case TarsHeadeString1:
			{
				size_t len = 0;
				TarsReadTypeBuf(*this, len, uint8_t);
				TarsReadHeadSkip(*this, len);
			}
				break;
			case TarsHeadeString4:
			{
				size_t len = 0;
				TarsReadTypeBuf(*this, len, uint32_t);
				len = ntohl((uint32_t)len);
				TarsReadHeadSkip(*this, len);
			}
				break;
			case TarsHeadeMap:
			{
				UInt32 size = 0;
				read(size, 0);
				for (UInt32 i = 0; i < size * 2; ++i)
					skipField();
			}
				break;
			case TarsHeadeList:
			{
				UInt32 size = 0;
				read(size, 0);
				for (UInt32 i = 0; i < size; ++i)
					skipField();
			}
				break;
			case TarsHeadeSimpleList:
			{
				
                         uint8_t headType = 0, headTag = 0;
				readFromHead(*this, headType, headTag);
				if (tars_unlikely(headType != TarsHeadeChar))
				{
					char s[64];
					snprintf(s, sizeof(s), "skipField with invalid type, type value: %d, %d, %d.", type, headType, headTag);
					throw TarsDecodeMismatch(s);
				}
				UInt32 size = 0;
				read(size, 0);
				TarsReadHeadSkip(*this, size);
			}
				break;
			case TarsHeadeStructBegin:
				skipToStructEnd();
				break;
			case TarsHeadeStructEnd:
			case TarsHeadeZeroTag:
				break;
			default:
			{
				char s[64];
				snprintf(s, sizeof(s), "skipField with invalid type, type value:%d.", type);
				throw TarsDecodeMismatch(s);
			}
		}
	}

	/// 读取一个指定类型的数据(基本类型)
	template<typename T>
	inline T readByType()
	{
		T n;
		this->readBuf(&n, sizeof(n));
		return n;
	}
	void readUnknown(std::string & sUnkown, uint8_t tag)
	{

		size_t start = ReaderT::tellp();
		size_t last  = start;
		try
		{
			uint8_t lasttag = tag;
			DataHead h;
			while (!ReaderT::hasEnd())
			{
				size_t len = h.peekFrom(*this);
				if ( h.getTag() <=lasttag)
				{
					break;
				}
				lasttag = h.getTag();
				this->skip(len);
				skipField(h.getType());
				last = ReaderT::tellp(); //记录下最后一次正常到达的位置
			}
		}
		catch (...) //
		{
			throw;
		}
		std::string s(ReaderT::base() +start, last - start);
		sUnkown = s;
		return ;

	}
	friend class XmlProxyCallback;

	void read(Bool& b, uint8_t tag, bool isRequire = true)
	{
		Char c = b;
		read(c, tag, isRequire);
		b = c ? true : false;
	}

	void read(Char& c, uint8_t tag, bool isRequire = true)
	{
		uint8_t headType = 0, headTag = 0;
		bool skipFlag = false;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
		if (tars_likely(skipFlag))
		{
			switch (headType)
			{
				case TarsHeadeZeroTag:
					c = 0;
					break;
				case TarsHeadeChar:
					TarsReadTypeBuf(*this, c, Char);
					break;
				default:
				{
					char s[64];
					snprintf(s, sizeof(s), "read 'Char' type mismatch, tag: %d, get type: %d.", tag, headType);
					throw TarsDecodeMismatch(s);
				}

			}
		}
		else if (tars_unlikely(isRequire))
		{
			char s[64];
			snprintf(s, sizeof(s), "require field not exist, tag: %d, headTag: %d.", tag, headTag);
                        cout << "line = "<<__LINE__<< ", require field not exist, tag:"<< tag << ",headTag is "<< headTag<<endl;
			throw TarsDecodeRequireNotExist(s);
		}
	}

	void read(UInt8& n, uint8_t tag, bool isRequire = true)
	{
		Short i = (Short)n;
		read(i,tag,isRequire);
		n = (UInt8)i;
	}

	void read(Short& n, uint8_t tag, bool isRequire = true)
	{
		uint8_t headType = 0, headTag = 0;
		bool skipFlag = false;
             cout << "line = "<<__LINE__<<",skipFlag is "<< skipFlag<< ", isRequire is "<<isRequire <<", n is "<< n << ", tag  is "<< (int)tag <<endl;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
            cout << "line = "<<__LINE__<<",skipFlag is "<< skipFlag<< ", isRequire is "<<isRequire <<", n is "<< n << ", tag  is "<< (int)tag <<endl;
		if (tars_likely(skipFlag))
		{
			switch (headType)
			{
				case TarsHeadeZeroTag:
					n = 0;
					break;
				case TarsHeadeChar:
					TarsReadTypeBuf(*this, n, Char);
					break;
				case TarsHeadeShort:
					TarsReadTypeBuf(*this, n, Short);
					n = ntohs(n);
					break;
				default:
				{
					char s[64];
					snprintf(s, sizeof(s), "read 'Short' type mismatch, tag: %d, get type: %d.", tag, headType);
					throw TarsDecodeMismatch(s);
				}
			}
		}
		else if (tars_unlikely(isRequire))
		{
			char s[64];
                   cout<<"line = "<<__LINE__<<", require field not exist"<<endl;
			snprintf(s, sizeof(s), "require field not exist, tag: %d, headTag: %d", tag, headTag);
			throw TarsDecodeRequireNotExist(s);
		}
            std::cout<<"read Short n is "<<n<<std::endl;
	}

	void read(UInt16& n, uint8_t tag, bool isRequire = true)
	{
		Int32 i = (Int32)n;
		read(i,tag,isRequire);
		n = (UInt16)i;
	}

	void read(Int32& n, uint8_t tag, bool isRequire = true)
	{
		uint8_t headType = 1, headTag = 1;
		bool skipFlag = false;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
		if (tars_likely(skipFlag))
		{
			switch (headType)
			{
				case TarsHeadeZeroTag:
					n = 0;
					break;
				case TarsHeadeChar:
					TarsReadTypeBuf(*this, n, Char);
					break;
				case TarsHeadeShort:
					TarsReadTypeBuf(*this, n, Short);
					n = (Short)ntohs(n);
					break;
				case TarsHeadeInt32:
					TarsReadTypeBuf(*this, n, Int32);
					n = ntohl(n);
					break;
				default:
				{
					char s[64];
					snprintf(s, sizeof(s), "read 'Int32' type mismatch, tag: %d, get type: %d.", tag, headType);
					throw TarsDecodeMismatch(s);
				}
			}
		}
		else if (tars_unlikely(isRequire))
		{
			char s[64];
			snprintf(s, sizeof(s), "require field not exist, tag: %d headType: %d, headTag: %d", tag, headType, headTag);
			throw TarsDecodeRequireNotExist(s);
		}
            std::cout<<"read Int32 n is "<<n<<std::endl;
	}

	void read(UInt32& n, uint8_t tag, bool isRequire = true)
	{
		Int64 i = (Int64)n;
		read(i,tag,isRequire);
		n = (UInt32)i;
	}

	void read(Int64& n, uint8_t tag, bool isRequire = true)
	{
		uint8_t headType = 0, headTag = 0;
		bool skipFlag = false;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
		if (tars_likely(skipFlag))
		{
			switch(headType)
			{
				case TarsHeadeZeroTag:
					n = 0;
					break;
				case TarsHeadeChar:
					TarsReadTypeBuf(*this, n, Char);
					break;
				case TarsHeadeShort:
					TarsReadTypeBuf(*this, n, Short);
					n = (Short) ntohs(n);
					break;
				case TarsHeadeInt32:
					TarsReadTypeBuf(*this, n, Int32);
					n = (Int32) ntohl(n);
					break;
				case TarsHeadeInt64:
					TarsReadTypeBuf(*this, n, Int64);
					n = tars_ntohll(n);
					break;
				default:
				{
					char s[64];
					snprintf(s, sizeof(s), "read 'Int64' type mismatch, tag: %d, get type: %d.", tag, headType);
					throw TarsDecodeMismatch(s);
				}

			}
		}
		else if (tars_unlikely(isRequire))
		{
			char s[64];
			snprintf(s, sizeof(s), "require field not exist, tag: %d, headTag: %d", tag, headTag);
			throw TarsDecodeRequireNotExist(s);
		}
            std::cout<<"read Int64 n is "<<n<<std::endl;
	}

	void read(Float& n, uint8_t tag, bool isRequire = true)
	{
		uint8_t headType = 0, headTag = 0;
		bool skipFlag = false;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
		if (tars_likely(skipFlag))
		{
			switch(headType)
			{
				case TarsHeadeZeroTag:
					n = 0;
					break;
				case TarsHeadeFloat:
					TarsReadTypeBuf(*this, n, float);
					n = tars_ntohf(n);
					break;
				default:
				{
					char s[64];
					snprintf(s, sizeof(s), "read 'Float' type mismatch, tag: %d, get type: %d.", tag, headType);
					throw TarsDecodeMismatch(s);
				}
			}
		}
		else if (tars_unlikely(isRequire))
		{
			char s[64];
			snprintf(s, sizeof(s), "require field not exist, tag: %d, headTag: %d", tag, headTag);
			throw TarsDecodeRequireNotExist(s);
		}
	}

	void read(Double& n, uint8_t tag, bool isRequire = true)
	{
		uint8_t headType = 0, headTag = 0;
		bool skipFlag = false;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
		if (tars_likely(skipFlag))
		{
			switch(headType)
			{
				case TarsHeadeZeroTag:
					n = 0;
					break;
				case TarsHeadeFloat:
					TarsReadTypeBuf(*this, n, float);
					n = tars_ntohf(n);
					break;
				case TarsHeadeDouble:
					TarsReadTypeBuf(*this, n, double);
					n = tars_ntohd(n);
					break;
				default:
				{
					char s[64];
					snprintf(s, sizeof(s), "read 'Double' type mismatch, tag: %d, get type: %d.", tag, headType);
					throw TarsDecodeMismatch(s);
				}
			}
		}
		else if (tars_unlikely(isRequire))
		{
			char s[64];
			snprintf(s, sizeof(s), "require field not exist, tag: %d, headTag: %d", tag, headTag);
			throw TarsDecodeRequireNotExist(s);
		}
	}
	void read(std::string& s, uint8_t tag, bool isRequire = true)
	{
		uint8_t headType = 0, headTag = 0;
		bool skipFlag = false;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
		if (tars_likely(skipFlag))
		{
			uint32_t strLength = 0;
			switch (headType)
			{
				case TarsHeadeString1:
				{
					TarsReadTypeBuf(*this, strLength, uint8_t);
				}
					break;
				case TarsHeadeString4:
				{
					TarsReadTypeBuf(*this, strLength, uint32_t);
					strLength = ntohl(strLength);
					if (tars_unlikely(strLength > TARS_MAX_STRING_LENGTH))
					{
						char s[128];
						snprintf(s, sizeof(s), "invalid string size, tag: %d, size: %d", tag, strLength);
						throw TarsDecodeInvalidValue(s);
					}
				}
					break;
				default:
				{
					char s[64];
					snprintf(s, sizeof(s), "read 'string' type mismatch, tag: %d, get type: %d, tag: %d.", tag, headType, headTag);
					throw TarsDecodeMismatch(s);
				}
			}
			TarsReadStringBuf(*this, s, strLength);
		}
		else if (tars_unlikely(isRequire))
		{
			char s[64];
			snprintf(s, sizeof(s), "require field not exist, tag: %d", tag);
			throw TarsDecodeRequireNotExist(s);
		}
	}

	void read(char *buf, const UInt32 bufLen, UInt32 & readLen, uint8_t tag, bool isRequire = true)
	{
		uint8_t headType = 0, headTag = 0;
		bool skipFlag = false;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
		if (tars_likely(skipFlag))
		{
			switch(headType)
			{
				case TarsHeadeSimpleList:
				{
					uint8_t hheadType, hheadTag;
					readFromHead(*this, hheadType, hheadTag);
					if (tars_unlikely(hheadType != TarsHeadeChar))
					{
						char s[128];
						snprintf(s, sizeof(s), "type mismatch, tag: %d, type: %d, %d, %d", tag, headType, hheadType, hheadTag);
						throw TarsDecodeMismatch(s);
					}
					UInt32 size = 0;
					read(size, 0);
					if (tars_unlikely(size > bufLen))
					{
						char s[128];
						snprintf(s, sizeof(s), "invalid size, tag: %d, type: %d, %d, size: %d", tag, headType, hheadType, size);
						throw TarsDecodeInvalidValue(s);
					}
					//TarsReadTypeBuf(*this, size, UInt32);
					this->readBuf(buf, size);
					readLen = size;
				}
					break;

				default:
				{
					char s[128];
					snprintf(s, sizeof(s), "type mismatch, tag: %d, type: %d", tag, headType);
					throw TarsDecodeMismatch(s);
				}
			}
		}
		else if (tars_unlikely(isRequire))
		{
			char s[128];
			snprintf(s, sizeof(s), "require field not exist, tag: %d, headTag: %d", tag, headTag);
			throw TarsDecodeRequireNotExist(s);
		}
	}


	template<typename K, typename V, typename Cmp, typename Alloc>
	void read(std::map<K, V, Cmp, Alloc>& m, uint8_t tag, bool isRequire = true)
	{
		uint8_t headType = 0, headTag = 0;
		bool skipFlag = false;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
		if (tars_likely(skipFlag))
		{
			switch(headType)
			{
				case TarsHeadeMap:
				{
					UInt32 size = 0;
					read(size, 0);
					if (tars_unlikely(size > this->size()))
					{
						char s[128];
						snprintf(s, sizeof(s), "invalid map, tag: %d, size: %d", tag, size);
						throw TarsDecodeInvalidValue(s);
					}
					m.clear();

					for (UInt32 i = 0; i < size; ++i)
					{
						std::pair<K, V> pr;
						read(pr.first, 0);
						read(pr.second, 1);
						m.insert(pr);
					}
				}
					break;
				default:
				{
					char s[64];
					snprintf(s, sizeof(s), "read 'map' type mismatch, tag: %d, get type: %d.", tag, headType);
					throw TarsDecodeMismatch(s);
				}
			}
		}
		else if (tars_unlikely(isRequire))
		{
			char s[64];
			snprintf(s, sizeof(s), "require field not exist, tag: %d, headTag: %d", tag, headTag);
			throw TarsDecodeRequireNotExist(s);
		}
	}

	template<typename Alloc>
	void read(std::vector<Char, Alloc>& v, uint8_t tag, bool isRequire = true)
	{
	      cout << "line = "<<__LINE__<<", 调用了read(std::vector<Char, Alloc>& v, uint8_t tag, bool isRequire = true)"<<endl;
            uint8_t headType = 0, headTag = 0;
		bool skipFlag = false;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
		if (tars_likely(skipFlag))
		{
			switch(headType)
			{
				case TarsHeadeSimpleList:
				{
					uint8_t hheadType, hheadTag;
					readFromHead(*this, hheadType, hheadTag);
					if (tars_unlikely(hheadType != TarsHeadeChar))
					{
						char s[128];
						snprintf(s, sizeof(s), "type mismatch, tag: %d, type: %d, %d, %d", tag, headType, hheadType, hheadTag);
						throw TarsDecodeMismatch(s);
					}
					UInt32 size = 0;
					read(size, 0);
					if (tars_unlikely(size > this->size()))
					{
						char s[128];
						snprintf(s, sizeof(s), "invalid size, tag: %d, type: %d, %d, size: %d", tag, headType, hheadType, size);
						throw TarsDecodeInvalidValue(s);
					}

					this->readBuf(v, size);
				}
					break;
				case TarsHeadeList:
				{
					UInt32 size = 0;
					read(size, 0);
					if (tars_unlikely(size > this->size()))
					{
						char s[128];
						snprintf(s, sizeof(s), "invalid size, tag: %d, type: %d, size: %d", tag, headType, size);
						throw TarsDecodeInvalidValue(s);
					}
					v.reserve(size);
					v.resize(size);
					for (UInt32 i = 0; i < size; ++i)
						read(v[i], 0);
				}
					break;
				default:
				{
					char s[128];
					snprintf(s, sizeof(s), "type mismatch, tag: %d, type: %d", tag, headType);
					throw TarsDecodeMismatch(s);
				}
			}
                
                int i = v.size();
                for(i = 0;i<v.size();i++)
                     {
                  cout <<"line = "<<__LINE__<<", v["<<i<<"] is "<<v[i]<<endl;
                     }
                     
                 cout << "line = "<<__LINE__<<", read(std::vector<Char, Alloc>& v, uint8_t tag, bool isRequire = true) 快要调用结束啦"<<endl;
		}
		else if (tars_unlikely(isRequire))
		{
			char s[128];
			snprintf(s, sizeof(s), "require field not exist, tag: %d, headTag: %d", tag, headTag);
			throw TarsDecodeRequireNotExist(s);
		}
	}

	template<typename T, typename Alloc>
	void read(std::vector<T, Alloc>& v, uint8_t tag, bool isRequire = true)
	{
            cout << "line = "<<__LINE__<<",调用了read(std::vector<T, Alloc>& v, uint8_t tag, bool isRequire = true)"<<endl;
		uint8_t headType = 0, headTag = 0;
		bool skipFlag = false;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
		if (tars_likely(skipFlag))
		{
			switch(headType)
			{
				case TarsHeadeList:
				{
					UInt32 size = 0;
					read(size, 0);
					if (tars_unlikely(size > this->size()))
					{
						char s[128];
						snprintf(s, sizeof(s), "invalid size, tag: %d, type: %d, size: %d", tag, headType, size);
						throw TarsDecodeInvalidValue(s);
					}
					v.reserve(size);
					v.resize(size);
					for (UInt32 i = 0; i < size; ++i)
						read(v[i], 0);
				}
					break;
				default:
				{
					char s[64];
					snprintf(s, sizeof(s), "read 'vector' type mismatch, tag: %d, get type: %d.", tag, headType);
					throw TarsDecodeMismatch(s);
				}
			}
		}
		else if (tars_unlikely(isRequire))
		{
			char s[64];
			snprintf(s, sizeof(s), "require field not exist, tag: %d, headTag: %d", tag, headTag);
			throw TarsDecodeRequireNotExist(s);
		}
	}

	/// 读取结构数组
	template<typename T>
	void read(T* v, const UInt32 len, UInt32 & readLen, uint8_t tag, bool isRequire = true)
	{
		uint8_t headType = 0, headTag = 0;
		bool skipFlag = false;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
		if (tars_likely(skipFlag))
		{
			switch(headType)
			{
				case TarsHeadeList:
				{
					UInt32 size = 0;
					read(size, 0);
					if (tars_unlikely(size > this->size()))
					{
						char s[128];
						snprintf(s, sizeof(s), "invalid size, tag: %d, type: %d, size: %d", tag, headType, size);
						throw TarsDecodeInvalidValue(s);
					}
					for (UInt32 i = 0; i < size; ++i)
						read(v[i], 0);
					readLen = size;
				}
					break;
				default:
				{
					char s[64];
					snprintf(s, sizeof(s), "read 'vector struct' type mismatch, tag: %d, get type: %d.", tag, headType);
					throw TarsDecodeMismatch(s);
				}
			}
		}
		else if (tars_unlikely(isRequire))
		{
			char s[64];
			snprintf(s, sizeof(s), "require field not exist, tag: %d, headTag: %d", tag, headTag);
			throw TarsDecodeRequireNotExist(s);
		}
	}

	template<typename T>
	void read(T& v, uint8_t tag, bool isRequire = true, typename detail::disable_if<detail::is_convertible<T*, TarsStructBase*>, void ***>::type dummy = 0)
	{
		Int32 n = 0;
		read(n, tag, isRequire);
		v = (T) n;
	}

	/// 读取结构
	template<typename T>
	void read(T& v, uint8_t tag, bool isRequire = true, typename detail::enable_if<detail::is_convertible<T*, TarsStructBase*>, void ***>::type dummy = 0)
	{
		uint8_t headType = 0, headTag = 0;
		bool skipFlag = false;
		TarsSkipToTag(skipFlag, tag, headType, headTag);
		if (tars_likely(skipFlag))
		{
			if (tars_unlikely(headType != TarsHeadeStructBegin))
			{
				char s[64];
				snprintf(s, sizeof(s), "read 'struct' type mismatch, tag: %d, get type: %d.", tag, headType);
				throw TarsDecodeMismatch(s);
			}
			v.readFrom(*this);
			skipToStructEnd();
		}
		else if (tars_unlikely(isRequire))
		{
			char s[64];
			snprintf(s, sizeof(s), "require field not exist, tag: %d, headTag: %d", tag, headTag);
			throw TarsDecodeRequireNotExist(s);
		}
	}
};

void resetDefautlt()
{
            iVersion = 0;
            cPacketType = 0;
            iRequestId = 0;
            iMessageType = 0;
            iRet = 0;
}





class Buffer
{

    public:
	    Buffer() { }
	    Buffer(const vector<char> &sBuffer) : _buffer(sBuffer) {}
	    Buffer(const char *sBuffer, size_t length) : _buffer(sBuffer, sBuffer+length) {}

        void swap(vector<char> &buff, size_t pos = 0)
        {
	    	if(_pos != 0)
		{
	    	    buff.resize(length());
	    	    memcpy(&buff[0], buffer(), length());
		}
	      else
                {
			    buff.swap(_buffer);
		}
	      _pos = pos;
        }

        void clear()
        {
            _buffer.clear();
	        _pos = 0;
        }

        bool empty() const
        {
            return _buffer.size() <= _pos;
        }

        void addBuffer(const vector<char> &buffer)
        {
            _buffer.insert(_buffer.end(), buffer.begin(), buffer.end());
        }

        void assign(const char *buffer, size_t length, size_t pos = 0)
        {
            _buffer.assign(buffer, buffer + length);
	        _pos = pos;
        }

        void setBuffer(const vector<char> &buff, size_t pos = 0)
        {
	        _buffer  = buff;
	        _pos     = pos;
        }

	    char *buffer() { return _buffer.data() + _pos; }

        const char *buffer() const { return _buffer.data() + _pos; }

        size_t length() const { return _buffer.size() - _pos; }

        size_t pos() const { return _pos; }

        char &at(size_t offset)
        {
	    	if(_pos + offset >= _buffer.size() )
               {
                    cout << "line ="<<__LINE__<<"[TC_NetWorkBuffer::Buffer] at offset overflow" <<endl;
                         exit(1);
               }
	    		
	    	return _buffer[_pos + offset];
        }

	    char at(size_t offset) const
	    {
		    if(_pos + offset >= _buffer.size() )
		     {
                           cout << "line ="<<__LINE__<<"[TC_NetWorkBuffer::Buffer] at offset overflow" <<endl;
                           exit(1);
                      }
		    return _buffer[_pos + offset];
	    }

	    void add(uint32_t ret)
        {
	        _pos += ret;
            assert(_pos <= _buffer.size());
        }

    protected:
	    vector<char>    _buffer;
	    size_t          _pos = 0;

    };


enum PACKET_TYPE
{
        PACKET_LESS = 0,
        PACKET_FULL = 1,
	  PACKET_FULL_CLOSE = 2,  ///< get whole package, and need close connection, for example: http
        PACKET_ERR  = -1,   
};

size_t _length = 0;

std::list<std::shared_ptr<Buffer>> _bufferList;

size_t getBufferLength()
{
    cout<<"line is "<<__LINE__<<"_length is "<<_length<< endl;
    return _length;
}




template<typename T>
T getHeader(size_t len) 
{
		if(getBufferLength() < len)
		{
			cout<<"line is "<<__LINE__<< "[TC_NetWorkBuffer::getHeader] no enough buff "<<endl;
                   exit(0);
		}

		T buffer;

		if(len == 0)
		{
			return buffer;
		}

		buffer.resize(len);

		getBuffers(&buffer[0], len);

		return buffer;
}

size_t getBuffers(char *buffer, size_t length) 
{
	assert(length <= getBufferLength());

	auto it = _bufferList.begin();

	size_t left = length;
	size_t pos = 0;

	while(it != _bufferList.end() && left != 0)
	{
		size_t len = min(left, (*it)->length());

		memcpy(buffer + pos, (*it)->buffer(), len);

		left -= len;
		pos += len;

		++it;
	}

	return pos;
}


vector<char> getBuffers() 
{
    vector<char> buffer;

    buffer.resize(_length);

	getBuffers(&buffer[0], _length);

	return buffer;
}


bool getHeader(size_t len, std::string &buffer)
{
    cout<<"line is "<<__LINE__<< endl;
    if(getBufferLength() < len)
        return false;
  
    cout<<"line is "<<__LINE__<< endl;
    buffer.clear();
 
    cout<<"line is "<<__LINE__<< endl;

    if(len == 0)
    {
        return true;
    }

    cout<<"line is "<<__LINE__<< endl;
    buffer.resize(len);

    cout<<"line is "<<__LINE__<< endl;
    getBuffers(&buffer[0], len);

    return true;
}

bool getHeader(size_t len, std::vector<char> &buffer)
{
    if(getBufferLength() < len)
        return false;

    buffer.clear();

    if(len == 0)
    {
        return true;
    }

    buffer.resize(len);

	getBuffers(&buffer[0], len);

    return true;
}

bool moveHeader(size_t len)
{
    if(getBufferLength() < len)
     {
       cout << "line = "<<__LINE__<<",getBufferLength()  is "<< getBufferLength() << ", len is "<< len <<endl; 
       return false;
     }
        

    if(len == 0)
     {
       cout << "line = "<<__LINE__<<", len is 0"<<endl; 
       return true;
     }


    auto it = _bufferList.begin();

//    assert(it->size() >= _pos);

    size_t left = (*it)->length();

    if(left > len)
    {
	    (*it)->add(len);
        _length -= len;
    }
    else if(left == len)
    {
        _length -= len;
        _bufferList.erase(it);
    }
    else
    {
        _length -= left;

        _bufferList.erase(it);

        return moveHeader(len - left);
    }
    return true;
}



template<typename T>
T getValue()
{
	  vector<char> buffer;

        if(getHeader(sizeof(T), buffer))
        {
            if(sizeof(T) == 2)
            {
                return ntohs(*(uint16_t*)buffer.data());
            }
            else if(sizeof(T) == 4)
            {
                return ntohl(*(uint32_t*)buffer.data());
            }
            return *((T*)buffer.data());
        }
        return 0;
 }

 

template<typename T>
PACKET_TYPE parseBuffer(vector<char> &buffer, T minLength, T maxLength)
{
      cout <<"line = "<<__LINE__<<", enter function parseBuffer" << endl;
      if(getBufferLength() < sizeof(T))
        {
            cout <<"line = "<<__LINE__<<", getBufferLength() is "<< _length << ",sizeof(T) is "<< sizeof(T) << endl;
            return PACKET_LESS;
        }
      cout <<"line = "<<__LINE__ << endl;
        if(minLength < sizeof(T))
            minLength = sizeof(T);
      
      cout <<"line = "<<__LINE__ << endl;
        T length = getValue<T>();
        
      cout <<"line = "<<__LINE__ << endl;
      if(length < minLength || length > maxLength)
        {
            return PACKET_ERR;
        }

        if(getBufferLength() < length)
        {
            return PACKET_LESS;
        }

        //往后移动
		//move backward
        moveHeader(sizeof(T));

        //读取length长度的buffer
	//Read buffer of length length
        if(!getHeader(length - sizeof(T), buffer))
        {
            return PACKET_LESS;
        }

        moveHeader(length - sizeof(T));
        return PACKET_FULL;
}

PACKET_TYPE parseBufferOf4(vector<char> &buffer, uint32_t minLength, uint32_t maxLength)
{
     cout <<"line = "<<__LINE__<<", enter function parseBufferOf4" << endl;
     return parseBuffer<uint32_t>(buffer, minLength, maxLength);
}

// 这里用的是ResponsePacket那一部分的代码,解码,代码路径D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\Tars.h
template<typename ReaderT>
void readFrom(TarsInputStream<ReaderT>& _is)
{
               
            resetDefautlt();
            cout <<"line = "<<__LINE__<<" ,start to  _is.read(iVersion, 1, true);====================================================================================================" << endl; 
            _is.read(iVersion, 1, true);


            cout <<"line = "<<__LINE__<<" ,start to  _is.read(cPacketType, 2, true);====================================================================================================" << endl; 
            _is.read(cPacketType, 2, true);


            cout <<"line = "<<__LINE__<<" ,start to  _is.read(iRequestId, 3, true);====================================================================================================" << endl; 
            _is.read(iRequestId, 3, true);


            cout <<"line = "<<__LINE__<<" ,start to  _is.read(iMessageType, 4, true);====================================================================================================" << endl; 
            _is.read(iMessageType, 4, true);


            cout <<"line = "<<__LINE__<<" ,start to  _is.read(iRet, 5, true);====================================================================================================" << endl;
            _is.read(iRet, 5, true);

               
            cout <<"line = "<<__LINE__<<" ,start to  _is.read(sBuffer, 6, true);====================================================================================================" << endl;
            _is.read(sBuffer, 6, true);
            //_is.read(status, 7, true);
            //_is.read(sResultDesc, 8, false);
            //_is.read(context, 9, false);
}



int main(){
	printf("__GNUC__ = %d\n",__GNUC__); 
	TarsOutputStream<BufferWriter> os;
	vector<char> buffer;
	string res = "aaaa";
	buffer.assign(res.begin(),res.end());// 将res的值赋值到buffer中
	status["status"] = "status";
	map<string, string> _responseContext;
	_responseContext["context"] = "context";

	iVersion       = TARSVERSION;//tag 1   value1  type Short
	cPacketType    = TARSNORMAL; //tage2   value0  type Char
	iRequestId     = 1;          //tag 3   value1  type Int32 
	iMessageType   = 0;          //tag 4   value0  type Int32
	iRet = 1;                    //tag 5   value1
	//iRet = 0;                    //tag 5   value0
	sBuffer        = buffer;     //tage 6  value(aaaa) 将buffer的值赋值给sBuffer,后续会调用_os.write(sBuffer, 6);
	status         = status;     //tage 7  value(<"status","status">)        type map<std::string, std::string>
	sResultDesc    = "123";            //tag  8  value("123") type std::string
	context        = _responseContext; //tag  9  value(<"context","context">)  
      cout <<"line is "<<__LINE__<< ",开始解码啦***************************************************************************************************************************************************"<<endl;
      cout <<endl<<endl<<endl<<endl;
	writeTo(os); 
	cout <<"os._buf is  ["<< os._buf<<"],os._len  "<< os._len << ",os._buf_len is "<< os._buf_len << endl;
	cout <<"os._buf is "<<StrToBitStr(os._buf)<<endl;
          


      cout <<endl<<endl<<endl<<endl;
      cout <<"line is "<<__LINE__<< ",开始解码啦****************************************************************************************************************************************************"<<endl;
      cout <<endl<<endl<<endl<<endl; 
 
       TarsInputStream<BufferReader> is;
        // 设置读的缓存,void setBuffer(const char * buf, size_t len), D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\tup\Tars.h中的609行
       is.setBuffer(os._buf, os._buf_len);
	 

	 readFrom(is);
                           /* 
                        static TC_NetWorkBuffer::PACKET_TYPE tarsResponseLen(TC_NetWorkBuffer &in, ResponsePacket& rsp) 这个函数对应着呆小板所说的那个responseFunc
                        D:\005-02-代码\016-TARS\TARS\TarsFramework\tarscpp\servant\servant\AppProtocol.h
                           */
         
     




}

/*
//Int32 iVersion;
Short iVersion;
Char cPacketType;
Int32 iMessageType;
Int32 iRequestId;
string sServantName;
string sFuncName;
std::string sResultDesc;
vector<Char> sBuffer;
Int32 iTimeout;
map<std::string, std::string> context;
map<std::string, std::string> status;
Int32 iRet;
*/




 

 

猜你喜欢

转载自blog.csdn.net/Edidaughter/article/details/113852338
今日推荐