/** * Tencent is pleased to support the open source community by making Tars available. * * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved. * * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * https://opensource.org/licenses/BSD-3-Clause * * Unless required by applicable law or agreed to in writing, software distributed * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ #ifndef __TARS_H__ #define __TARS_H__ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined _WIN32 || defined _WIN64 #pragma comment(lib,"ws2_32.lib") #else #include #endif //支持iphone #ifdef __APPLE__ #include "TarsType.h" #elif defined ANDROID // android #include "TarsType.h" #else #include "tup/TarsType.h" #endif #ifndef tars_likely #if defined(__GNUC__) && __GNUC__ >= 4 #define tars_likely(x) (__builtin_expect(!!(x),1)) #else #define tars_likely(x) (x) #endif #endif #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 ////////////////////////////////////////////////////////////////// //// 保留接口版本Tars宏定义 //编码相应的宏 #define TarsReserveBuf(os, len) \ do{ \ if(tars_likely((os)._buf_len < (len))) \ { \ size_t len1 = (len)<<1; \ if(len1<128) len1=128; \ (os)._buf = (os)._reserve(os, len1); \ (os)._buf_len = (len1); \ } \ }while(0) #define TarsWriteToHead(os, type, tag) \ do { \ if (tars_likely((tag) < 15)) \ { \ TarsWriteUInt8TTypeBuf( os, (type) + ((tag)<<4) , (os)._len); \ } \ else \ { \ TarsWriteUInt8TTypeBuf( os, (type) + (240) , (os)._len); \ TarsWriteUInt8TTypeBuf( os, (tag), (os)._len);\ } \ } while(0) #define TarsWriteCharTypeBuf(os, val, osLen) \ do { \ TarsReserveBuf(os, (osLen)+sizeof(Char)); \ (*(Char *)((os)._buf + (osLen))) = (val); \ (osLen) += sizeof(Char); \ } while(0) #define TarsWriteInt32TypeBuf(os, val, osLen) \ do { \ TarsReserveBuf(os, (osLen)+sizeof(Int32)); \ (*(Int32 *)((os)._buf + (osLen))) = (val); \ (osLen) += sizeof(Int32); \ } while(0) #define TarsWriteInt64TypeBuf(os, val, osLen) \ do { \ TarsReserveBuf(os, (osLen)+sizeof(Int64)); \ (*(Int64 *)((os)._buf + (osLen))) = (val); \ (osLen) += sizeof(Int64); \ } while(0) #define TarsWriteFloatTypeBuf(os, val, osLen) \ do { \ TarsReserveBuf(os, (osLen)+sizeof(Float)); \ (*(Float *)((os)._buf + (osLen))) = (val); \ (osLen) += sizeof(Float); \ } while(0) #define TarsWriteDoubleTypeBuf(os, val, osLen) \ do { \ TarsReserveBuf(os, (osLen)+sizeof(Double)); \ (*(Double *)((os)._buf + (osLen))) = (val); \ (osLen) += sizeof(Double); \ } while(0) #define TarsWriteUInt32TTypeBuf(os, val, osLen) \ do { \ TarsReserveBuf(os, (osLen)+sizeof(uint32_t)); \ (*(uint32_t *)((os)._buf + (osLen))) = (val); \ (osLen) += sizeof(uint32_t); \ } 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) #define TarsWriteUIntTypeBuf(os, val, osLen) \ do { \ TarsReserveBuf(os, (osLen)+sizeof(unsigned int)); \ (*(unsigned int *)((os)._buf + (osLen))) = (val); \ (osLen) += sizeof(unsigned int); \ } while(0) #define TarsWriteShortTypeBuf(os, val, osLen) \ do { \ TarsReserveBuf(os, (osLen)+sizeof(Short)); \ (*(Short *)((os)._buf + (osLen))) = (val); \ (osLen) += sizeof(Short); \ } while(0) #define TarsWriteTypeBuf(os, buf, len) \ do { \ TarsReserveBuf(os, (os)._len + (len)); \ memcpy((os)._buf + (os)._len, (const void *)(buf), (len)); \ (os)._len += (len); \ } while(0) //解码相应的宏 #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 { \ 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) #define TarsSkipToTag(flag, tag, retHeadType, retHeadTag) \ do { \ try \ { \ uint8_t nextHeadType, nextHeadTag; \ while (!ReaderT::hasEnd()) \ { \ size_t len = 0; \ TarsPeekFromHead(*this, nextHeadType, nextHeadTag, len); \ 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) namespace tars { ////////////////////////////////////////////////////////////////// struct TarsStructBase { protected: TarsStructBase() {} ~TarsStructBase() {} }; 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) {} }; ////////////////////////////////////////////////////////////////// namespace { /// 数据头信息的封装,包括类型和tag 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 void readFrom(InputStreamT& is) { size_t n = peekFrom(is); is.skip(n); } /// 读取头信息,但不前移流的偏移量 template 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 void writeTo(OutputStreamT& os) { writeTo(os, _type, _tag); } /// 写入数据头信息 template 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)); } } }; } ////////////////////////////////////////////////////////////////// /// 缓冲区读取器封装 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 template void readBuf(std::vector& 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 template void peekBuf(std::vector& 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 void setBuffer(const std::vector &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文件中含有指针型类型的数据用MapBufferReader读取 //在读数据时利用MapBufferReader提前分配的内存 减少运行过程中频繁内存分配 //结构中定义byte指针类型,指针用*来定义,如下: //byte *m; //指针类型使用时需要MapBufferReader提前设定预分配内存块setMapBuffer(), //指针需要内存时通过偏移指向预分配内存块,减少解码过程中的内存申请 class MapBufferReader : public BufferReader { private: MapBufferReader(const MapBufferReader&); MapBufferReader& operator=(const MapBufferReader&); public: MapBufferReader() : _buf_m(NULL),_buf_len_m(0),_cur_m(0) {} void reset() { _cur_m = 0; BufferReader::reset();} char* cur() { if (tars_unlikely(_buf_m == NULL)) { char s[64]; snprintf(s, sizeof(s), "MapBufferReader's buff not set,_buf = null"); throw TarsDecodeException(s); } return _buf_m+_cur_m; } size_t left(){return _buf_len_m-_cur_m;} /// 跳过len个字节 void mapBufferSkip(size_t len) { if (tars_unlikely(_cur_m + len > _buf_len_m)) { char s[64]; snprintf(s, sizeof(s), "MapBufferReader's buffer overflow when peekBuf, over %u.", (uint32_t)_buf_len_m); throw TarsDecodeException(s); } _cur_m += len; } /// 设置缓存 void setMapBuffer(char * buf, size_t len) { _buf_m = buf; _buf_len_m = len; _cur_m = 0; } /// 设置缓存 template void setMapBuffer(std::vector &buf) { _buf_m = buf.data(); _buf_len_m = buf.size(); _cur_m = 0; } public: char * _buf_m; ///< 缓冲区 size_t _buf_len_m; ///< 缓冲区长度 size_t _cur_m; ///< 当前位置 }; ////////////////////////////////////////////////////////////////// /// 缓冲区写入器封装 class BufferWriter { public: char * _buf; size_t _len; size_t _buf_len; std::function _reserve = BufferWriter::reserve; //扩展空间 static char* reserve(BufferWriter &os, size_t len) { char * p = new char[(len)]; memcpy(p, (os)._buf, (os)._len); 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 getByteBuffer() const { return std::vector(_buf, _buf + _len);} const char * getBuffer() const { return _buf;} size_t getLength() const { return _len;} void swap(std::vector& 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); } }; /////////////////////////////////////////////////////////////////////////////////////////////////// /// 实际buffer是std::string /// 可以swap, 把buffer交换出来, 避免一次内存copy class BufferWriterString { protected: mutable std::string _buffer; char * _buf; size_t _len; size_t _buf_len; std::function _reserve; private: //不让copy 复制 BufferWriterString(const BufferWriterString&); BufferWriterString& operator=(const BufferWriterString& buf); public: BufferWriterString() : _buf(NULL) , _len(0) , _buf_len(0) { #ifndef GEN_PYTHON_MASK //内存分配器 _reserve = [](BufferWriterString &os, size_t len) { os._buffer.resize(len); return (char*)os._buffer.data(); } ; #endif } ~BufferWriterString() { } void reset() { _len = 0;} void writeBuf(const char * buf, size_t len) { TarsReserveBuf(*this, _len + len); memcpy(_buf + _len, buf, len); _len += len; } const std::string &getByteBuffer() const { _buffer.resize(_len); return _buffer;} std::string &getByteBuffer() { _buffer.resize(_len); return _buffer;} const char * getBuffer() const { return _buf;} size_t getLength() const { return _len;} void swap(std::string& v) { _buffer.resize(_len); v.swap(_buffer); _buf = NULL; _buf_len = 0; _len = 0; } void swap(std::vector& v) { _buffer.resize(_len); v.assign(_buffer.c_str(), _buffer.c_str() + _buffer.size()); _buf = NULL; _buf_len = 0; _len = 0; } void swap(BufferWriterString& buf) { buf._buffer.swap(_buffer); std::swap(_buf, buf._buf); std::swap(_buf_len, buf._buf_len); std::swap(_len, buf._len); } }; /// 实际buffer是std::vector /// 可以swap, 把buffer交换出来, 避免一次内存copy class BufferWriterVector { protected: mutable std::vector _buffer; char * _buf; size_t _len; size_t _buf_len; std::function _reserve; private: //不让copy 复制 BufferWriterVector(const BufferWriterVector&); BufferWriterVector& operator=(const BufferWriterVector& buf); public: BufferWriterVector() : _buf(NULL) , _len(0) , _buf_len(0) { #ifndef GEN_PYTHON_MASK //内存分配器 _reserve = [](BufferWriterVector &os, size_t len) { os._buffer.resize(len); return os._buffer.data(); } ; #endif } ~BufferWriterVector() { } void reset() { _len = 0;} void writeBuf(const char * buf, size_t len) { TarsReserveBuf(*this, _len + len); memcpy(_buf + _len, buf, len); _len += len; } const std::vector &getByteBuffer() const { _buffer.resize(_len); return _buffer;} std::vector &getByteBuffer() { _buffer.resize(_len); return _buffer;} const char * getBuffer() const { return _buf;} size_t getLength() const { return _len;} void swap(std::string& v) { _buffer.resize(_len); v.assign(_buffer.data(), _buffer.size()); _buf = NULL; _buf_len = 0; _len = 0; } void swap(std::vector& v) { _buffer.resize(_len); v.swap(_buffer); _buf = NULL; _buf_len = 0; _len = 0; } void swap(BufferWriterVector& buf) { buf._buffer.swap(_buffer); std::swap(_buf, buf._buf); std::swap(_buf_len, buf._buf_len); std::swap(_len, buf._len); } }; ////////////////////////////////////////////////////////////////// template 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: { uint32_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 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; if (tag) { } //avoid compiler warning } 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); 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; 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 = 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]; snprintf(s, sizeof(s), "require field not exist, tag: %d, headTag: %d", tag, headTag); throw TarsDecodeRequireNotExist(s); } } 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); } } 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, headTag: %c, get type: %c.", tag, headTag, 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(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, headTag: %d.", tag, headType, headTag); 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, headType: %d.", tag, headType,headTag); 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, headTag: %d", tag, strLength, headTag); 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 void read(std::map& 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, headTag: %d", tag, size, headTag); throw TarsDecodeInvalidValue(s); } m.clear(); for (UInt32 i = 0; i < size; ++i) { std::pair 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 void read(std::unordered_map& 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 unordered_map, tag: %d, size: %d, headTag: %d", tag, size, headTag); throw TarsDecodeInvalidValue(s); } m.clear(); for (UInt32 i = 0; i < size; ++i) { std::pair 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", tag); throw TarsDecodeRequireNotExist(s); } } template void readEx(std::map& 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, headTag: %d", tag, size, headTag); throw TarsDecodeInvalidValue(s); } m.clear(); for (UInt32 i = 0; i < size; ++i) { std::pair pr; read(pr.first, 0); CV tmp(pr.second); read(tmp, 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", tag); throw TarsDecodeRequireNotExist(s); } } template void readEx(std::unordered_map& 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, headTag: %d", tag, size, headTag); throw TarsDecodeInvalidValue(s); } m.clear(); for (UInt32 i = 0; i < size; ++i) { std::pair pr; read(pr.first, 0); CV tmp(pr.second); read(tmp, 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", tag); throw TarsDecodeRequireNotExist(s); } } template void read(std::vector& v, 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 > 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); } v.reserve(size); v.resize(size); this->readBuf(v.data(), size); //TarsReadTypeBuf(*this, v[0], Int32); } 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); } } } 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 void read(std::vector& v, 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, headTag: %d", tag, headType, size, headTag); 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 void read(std::set& v, 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, headTag: %d", tag, headType, size, headTag); throw TarsDecodeInvalidValue(s); } // v.reserve(size); // v.resize(size); for (UInt32 i = 0; i < size; ++i) { T t; read(t, 0); v.insert(t); } } break; default: { char s[64]; snprintf(s, sizeof(s), "read 'set' 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", tag); throw TarsDecodeRequireNotExist(s); } } template void read(std::unordered_set& v, 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, headTag: %d", tag, headType, size, headTag); throw TarsDecodeInvalidValue(s); } // v.reserve(size); // v.resize(size); for (UInt32 i = 0; i < size; ++i) { T t; read(t, 0); v.insert(t); } } break; default: { char s[64]; snprintf(s, sizeof(s), "read 'set' 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", tag); throw TarsDecodeRequireNotExist(s); } } template void readEx(std::set& v, 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, headTag: %d", tag, headType, size, headTag); throw TarsDecodeInvalidValue(s); } // v.reserve(size); // v.resize(size); for (UInt32 i = 0; i < size; ++i) { T t; CV tmp(t); read(tmp, 0); v.insert(t); } } break; default: { char s[64]; snprintf(s, sizeof(s), "read 'set' 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", tag); throw TarsDecodeRequireNotExist(s); } } template void readEx(std::unordered_set& v, 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, headTag: %d", tag, headType, size, headTag); throw TarsDecodeInvalidValue(s); } // v.reserve(size); // v.resize(size); for (UInt32 i = 0; i < size; ++i) { T t; CV tmp(t); read(tmp, 0); v.insert(t); } } break; default: { char s[64]; snprintf(s, sizeof(s), "read 'set' 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", tag); throw TarsDecodeRequireNotExist(s); } } template void readEx(std::vector& v, 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, headTag: %d", tag, headType, size, headTag); throw TarsDecodeInvalidValue(s); } v.reserve(size); v.resize(size); for (UInt32 i = 0; i < size; ++i) { CV tmp(v[i]); read(tmp, 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", tag); throw TarsDecodeRequireNotExist(s); } } /// 读取结构数组 template 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 void read(T& v, uint8_t tag, bool isRequire = true, typename detail::disable_if, void ***>::type dummy = 0) { Int32 n = 0; read(n, tag, isRequire); v = (T) n; } template void read(T&& v, uint8_t tag, bool isRequire = true, typename detail::enable_if, 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, headTag: %d.", tag, headType, headTag); throw TarsDecodeMismatch(s); } // 精度保存恢复都在 readFrom 里面做 v.readFrom(*this); skipToStructEnd(); } else if (tars_unlikely(isRequire)) { char s[64]; snprintf(s, sizeof(s), "require field not exist, tag: %d", tag); throw TarsDecodeRequireNotExist(s); } } /// 读取结构 template void read(T& v, uint8_t tag, bool isRequire = true, typename detail::enable_if, 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: %c, headTag: %c.", tag, headType, headTag); 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); } } }; ////////////////////////////////////////////////////////////////// template class TarsOutputStream : public WriterT { public: void writeUnknown(const std::string& s) { this->writeBuf(s.data(), s.size()); } void writeUnknownV2(const std::string& s) { 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) { write((Char) b, tag); } void write(Char n, uint8_t tag) { if (tars_unlikely(n == 0)) { TarsWriteToHead(*this, TarsHeadeZeroTag, tag); } else { TarsWriteToHead(*this, TarsHeadeChar, tag); TarsWriteCharTypeBuf(*this, n, (*this)._len); } } void write(UInt8 n, uint8_t tag) { write((Short) n, tag); } void write(Short n, uint8_t tag) { if (n >= (-128) && n <= 127) { write((Char) n, tag); } else { TarsWriteToHead(*this, TarsHeadeShort, tag); n = htons(n); TarsWriteShortTypeBuf(*this, n, (*this)._len); } } void write(UInt16 n, uint8_t tag) { write((Int32) n, tag); } void write(Int32 n, uint8_t tag) { if (n >= (-32768) && n <= 32767) { write((Short) n, tag); } else { TarsWriteToHead(*this, TarsHeadeInt32, tag); n = htonl(n); TarsWriteInt32TypeBuf(*this, n, (*this)._len); } } void write(UInt32 n, uint8_t tag) { write((Int64) n, tag); } void write(Int64 n, uint8_t tag) { if (n >= (-2147483647-1) && n <= 2147483647) { write((Int32) n, tag); } else { TarsWriteToHead(*this, TarsHeadeInt64, tag); n = tars_htonll(n); TarsWriteInt64TypeBuf(*this, n, (*this)._len); } } void write(Float n, uint8_t tag) { //DataHead h(DataHead::eFloat, tag); //h.writeTo(*this); TarsWriteToHead(*this, TarsHeadeFloat, tag); n = tars_htonf(n); TarsWriteFloatTypeBuf(*this, n, (*this)._len); } void write(Double n, uint8_t tag) { TarsWriteToHead(*this, TarsHeadeDouble, tag); n = tars_htond(n); TarsWriteDoubleTypeBuf(*this, n, (*this)._len); } void write(const std::string& s, uint8_t tag) { if (tars_unlikely(s.size() > 255)) { 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); } TarsWriteToHead(*this, TarsHeadeString4, tag); uint32_t n = htonl((uint32_t)s.size()); TarsWriteUInt32TTypeBuf(*this, n, (*this)._len); TarsWriteTypeBuf(*this, s.data(), s.size()); } else { TarsWriteToHead(*this, TarsHeadeString1, tag); uint8_t n = (uint8_t)s.size(); TarsWriteUInt8TTypeBuf(*this, n, (*this)._len); TarsWriteTypeBuf(*this, s.data(), s.size()); } } void write(const char *buf, const UInt32 len, uint8_t tag) { TarsWriteToHead(*this, TarsHeadeSimpleList, tag); TarsWriteToHead(*this, TarsHeadeChar, 0); write(len, 0); TarsWriteTypeBuf(*this, buf, len); } template void write(const std::map& m, uint8_t tag) { TarsWriteToHead(*this, TarsHeadeMap, tag); Int32 n = (Int32)m.size(); write(n, 0); typedef typename std::map::const_iterator IT; for (IT i = m.begin(); i != m.end(); ++i) { write(i->first, 0); write(i->second, 1); } } template void write(const std::unordered_map& m, uint8_t tag) { { TarsWriteToHead(*this, TarsHeadeMap, tag); Int32 n = (Int32)m.size(); write(n, 0); typedef typename std::unordered_map::const_iterator IT; for (IT i = m.begin(); i != m.end(); ++i) { write(i->first, 0); write(i->second, 1); std::cout << "write:" << i->first << ", " << i->second << std::endl; } } } template< typename CV, typename K, typename V, typename Cmp, typename Alloc> void writeEx( const std::map& m, uint8_t tag) { { TarsWriteToHead(*this, TarsHeadeMap, tag); Int32 n = (Int32)m.size(); write(n, 0); typedef typename std::map::const_iterator IT; for (IT i = m.begin(); i != m.end(); ++i) { write(i->first, 0); CV cv(i->second); write(cv, 1); } } } template void write(const std::vector& v, uint8_t tag) { TarsWriteToHead(*this, TarsHeadeList, tag); Int32 n = (Int32)v.size(); write(n, 0); typedef typename std::vector::const_iterator IT; for (IT i = v.begin(); i != v.end(); ++i) write(*i, 0); } template void write(const std::set& v, uint8_t tag) { TarsWriteToHead(*this, TarsHeadeList, tag); Int32 n = (Int32)v.size(); write(n, 0); typedef typename std::set::const_iterator IT; for (IT i = v.begin(); i != v.end(); ++i) write(*i, 0); } template void write(const std::unordered_set& v, uint8_t tag) { TarsWriteToHead(*this, TarsHeadeList, tag); Int32 n = (Int32)v.size(); write(n, 0); typedef typename std::unordered_set::const_iterator IT; for (IT i = v.begin(); i != v.end(); ++i) write(*i, 0); } template void writeEx(const std::set& v, uint8_t tag) { TarsWriteToHead(*this, TarsHeadeList, tag); Int32 n = (Int32)v.size(); write(n, 0); typedef typename std::set::const_iterator IT; for (IT i = v.begin(); i != v.end(); ++i) { CV cv(*i); write(cv, 0); } } template void writeEx(const std::unordered_set& v, uint8_t tag) { TarsWriteToHead(*this, TarsHeadeList, tag); Int32 n = (Int32)v.size(); write(n, 0); typedef typename std::unordered_set::const_iterator IT; for (IT i = v.begin(); i != v.end(); ++i) { CV cv(*i); write(cv, 0); } } template< typename CV, typename T, typename Alloc> void writeEx(const std::vector& v, uint8_t tag) { TarsWriteToHead(*this, TarsHeadeList, tag); Int32 n = (Int32)v.size(); write(n, 0); typedef typename std::vector::const_iterator IT; for (IT i = v.begin(); i != v.end(); ++i) { CV cv(*i); write(cv, 0); } } template void write(const T *v, const UInt32 len, uint8_t tag) { TarsWriteToHead(*this, TarsHeadeList, tag); write(len, 0); for (Int32 i = 0; i < (Int32)len; ++i) { write(v[i], 0); } } template void write(const std::vector& v, uint8_t tag) { TarsWriteToHead(*this, TarsHeadeSimpleList, tag); TarsWriteToHead(*this, TarsHeadeChar, 0); Int32 n = (Int32)v.size(); write(n, 0); TarsWriteTypeBuf(*this, v.data(), v.size()); } template void write(const T& v, uint8_t tag, typename detail::disable_if, void ***>::type dummy = 0) { write((Int32) v, tag); } template void write(const T& v, uint8_t tag, typename detail::enable_if, void ***>::type dummy = 0) { TarsWriteToHead(*this, TarsHeadeStructBegin, tag); v.writeTo(*this); TarsWriteToHead(*this, TarsHeadeStructEnd, 0); } }; //////////////////////////////////////////////////////////////////////////////////////////////////// } //支持iphone #ifdef __APPLE__ #include "TarsDisplayer.h" #else #include "tup/TarsDisplayer.h" #endif #endif