google protocol buffer (下面简称gpb)功能强大,应用广泛,但在实际应用中,gpb需要写.proto脚本文件,需要依赖.lib库,还需要为每个消息体生成一大堆难以阅读的C++代码。有时候想看一下消息体有哪些字段,需要找原始的.proto文件来查看,很不方便。于是我用了不到2000行代码实现了一个轻量级C++版gpb,命名为:LightPb。LightPb有以下特点:
1、不需要.proto文件和.lib库,只需要包含一个头文件LightPb.h。
2、兼容bpb大部份功能,序列化后生成的二进制文件与gpb一至。
3、可扩展repeated [packed=true]功能,使得该选项可以应用于消息体和string。
4、定义消息体的语法与gpb相似,简单易学。
5、性能比gpb更优。
下面是一个使用LightPb的例子:
1、首先在一个testLight.h文件中定义一个结构体SubPbC:
struct SubPbC { PB_BEGIN() REQUIRED(int, m_int32, 2); REQUIRED_S(int, m_sint32, 3); REQUIRED(std::string, m_str, 4); PB_END() };
该结构体包含三个字段,结构体字段的需要用REQUIRED或OPTIONAL以及REPEATED三个宏中之一来定义。含义与gpb中的required、optional、repeated是一样的。这些宏有三个参数,分别是字段类型、字段名、和标签。与之对应的proto消息体是:(本例子中不需要定义该消息体,只是用以说明SubPbC对应的proto结构体)
message SubPb { required int32 m_int32 = 2; required sint32 m_sint32 = 3; required string m_str = 4; }
对C++程序员来说,上面的结构体定义和下面的结构体定义是一样的:
struct SubPbC { int m_int32; int m_sint32; std::string m_str; std::string SerializeAsString(); //序列化函数 bool ParseFromArray(const void* pData, int size); //反序列化函数 };
2 在.cpp文件使用该结构体
#include "LightPb.h" //LightPb项目的头文件 #include "testLight.h" //应用层定义的消息体 void main() { SubPbC obj; obj.m_int32 = 10; //像普通结构体一样赋值 obj.m_sint32 = -10; obj.m_str = "ok LightPb"; //序列化 std::string str = obj.SerializeAsString(); //反序列化 SubPbC obj2; if (obj2.ParseFromArray(str.data(), str.length()) == false) { printf("test fail!\n"); } return; }
就这么简单!
一个和googe pb性能比较的例子:
http://www.oschina.net/code/snippet_2504104_51823
LightPb.h文件定义如下:
/*************************************************************************************************** 转载请注明出处,作者联系方式:[email protected] V 1.0 Date:2015-10-28 *****************************************************************************************************/ #ifndef __BCL_LIGHT_PB_H__ #define __BCL_LIGHT_PB_H__ #include <memory> #include <string> #include <vector> #include <array> typedef int int32; typedef unsigned int uint32; typedef long long int64; typedef unsigned long long uint64; typedef std::string string; typedef std::string bytes; typedef int sint32; typedef long long sint64; typedef unsigned int fixed32; typedef unsigned long long fixed64; typedef int sfixed32; typedef long long sfixed64; typedef char int8; typedef unsigned char uint8; //#define USE_REPEATED_PACKED_EXTEND //如果使用repeated packd=true扩展,请定义该宏 #ifndef _FIELD_DEF_ #define _FIELD_DEF_ template <size_t size> struct Int2Type { enum { Value = size }; }; #define INT2TYPE(size) Int2Type<size>() #define ARRAY(type,size) std::array<type,size> #define FIELD_INDEX_BEGIN() enum {INDEX_BEGIN=__COUNTER__,}; #define FIELD_INDEX_END() enum {INDEX_END=__COUNTER__,Size=INDEX_END-INDEX_BEGIN-1,}; #define AUTO_INDEX() (__COUNTER__-INDEX_BEGIN) #define FIELD_BEGIN() FIELD_INDEX_BEGIN() #define FIELD_END() FIELD_INDEX_END() #define FIELD(type,name) FIELD_INDEX(AUTO_INDEX(),type,name) #define FIELD_INDEX(index,type,name) DEF_VALUE(type,name) GET_VALUE(index,type,name) GET_NAME(index,name) #define DEF_VALUE(type,name) type name; #define GET_VALUE(index,type,name) type & getValue(Int2Type<index>){return name;} const type & getValue(Int2Type<index>) const {return name;} #define GET_NAME(index,name) const char* getName(Int2Type<index>) const { return #name;} template<typename T> struct THaveLeghtField { template<typename type> static char __is_field_struct(...); template<typename type> static int __is_field_struct(typename type::traits_type *); template<typename type> static int __is_field_struct(Int2Type<type::Size> *); enum { Value = (sizeof(__is_field_struct<T>(0)) == sizeof(int)) }; }; #endif #define PB_INDEX(index,type,label,pbro,pbtype) std::array<char,label> getLabelObject(Int2Type<index>); Int2Type<index> getIndex(Int2Type<label>){ return Int2Type<index>(); } int getLabel(Int2Type<index>) { return label;} enPbROP getPbROP(Int2Type<index>){return pbro; } enPbTypeFlag getPbTypeFlag(Int2Type<index>){return pbtype;} Int2Type<pbtype> getPbTypeObject(Int2Type<index>){return Int2Type<pbtype>();} #define PB_FIELD_INDEX(index,type,value,label,pbro,pbtype) FIELD_INDEX(index,type,value); PB_INDEX(index,type,label,pbro,pbtype) type & getDefault(Int2Type<index>){ static type dflt; return dflt;} int GetFieldByteSize(Int2Type<index>){ return 0;} void SetFieldByteSize(Int2Type<index>,int size){} #define PB_FIELD_INDEX_D(index,type,value,label,pbro,dflt,pbtype) FIELD_INDEX(index,type,value); PB_INDEX(index,type,label,pbro,pbtype) type & getDefault(Int2Type<index>){return dflt;} int GetFieldByteSize(Int2Type<index>){ return 0;} void SetFieldByteSize(Int2Type<index>,int size){} #define PB_FIELD_INDEX_B(index,type,value,label,pbro,pbtype) FIELD_INDEX(index,type,value); PB_INDEX(index,type,label,pbro,pbtype) type & getDefault(Int2Type<index>){ static type dflt; return dflt;} int value##_byteSize_; int GetFieldByteSize(Int2Type<index>){ return value##_byteSize_;} void SetFieldByteSize(Int2Type<index>,int size){value##_byteSize_ = size;} #define REQUIRED(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),type,value,label,enPbROP_Required,enPbTypeFlag_Default) #define REQUIRED_D(type,value,label,dflt) PB_FIELD_INDEX_D(AUTO_INDEX(),type,value,label,enPbROP_Required,dflt,enPbTypeFlag_Default) #define REQUIRED_S(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),type,value,label,enPbROP_Required,enPbTypeFlag_Signed) #define REQUIRED_DS(type,value,label,dflt) PB_FIELD_INDEX_D(AUTO_INDEX(),type,value,label,enPbROP_Required,dflt,enPbTypeFlag_Signed) #define REQUIRED_SD(type,value,label,dflt) PB_FIELD_INDEX_D(AUTO_INDEX(),type,value,label,enPbROP_Required,dflt,enPbTypeFlag_Signed) #define REQUIRED_F(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),type,value,label,enPbROP_Required,enPbTypeFlag_Fixed) #define REQUIRED_DF(type,value,label,dflt) PB_FIELD_INDEX_D(AUTO_INDEX(),type,value,label,enPbROP_Required,dflt,enPbTypeFlag_Fixed) #define REQUIRED_FD(type,value,label,dflt) PB_FIELD_INDEX_D(AUTO_INDEX(),type,value,label,enPbROP_Required,dflt,enPbTypeFlag_Fixed) #define OPTIONAL(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),type,value,label,enPbROP_Optional,enPbTypeFlag_Default) #define OPTIONAL_D(type,value,label,dflt) PB_FIELD_INDEX_D(AUTO_INDEX(),type,value,label,enPbROP_Optional,dflt,enPbTypeFlag_Default) #define OPTIONAL_DS(type,value,label,dflt) PB_FIELD_INDEX_D(AUTO_INDEX(),type,value,label,enPbROP_Optional,dflt,enPbTypeFlag_Signed) #define OPTIONAL_SD(type,value,label,dflt) PB_FIELD_INDEX_D(AUTO_INDEX(),type,value,label,enPbROP_Optional,dflt,enPbTypeFlag_Signed) #define OPTIONAL_S(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),type,value,label,enPbROP_Optional,enPbTypeFlag_Signed) #define OPTIONAL_DF(type,value,label,dflt) PB_FIELD_INDEX_D(AUTO_INDEX(),type,value,label,enPbROP_Optional,dflt,enPbTypeFlag_Fixed) #define OPTIONAL_FD(type,value,label,dflt) PB_FIELD_INDEX_D(AUTO_INDEX(),type,value,label,enPbROP_Optional,dflt,enPbTypeFlag_Fixed) #define OPTIONAL_F(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),type,value,label,enPbROP_Optional,enPbTypeFlag_Fixed) #define REPEATED(type,value,label) OPTIONAL(std::vector<type>,value,label) #define REPEATED_S(type,value,label) OPTIONAL_S(std::vector<type>,value,label) #define REPEATED_F(type,value,label) OPTIONAL_F(std::vector<type>,value,label) #define REPEATED_P(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),std::vector<type>,value,label,enPbROP_Packed,enPbTypeFlag_Default) #define REPEATED_PS(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),std::vector<type>,value,label,enPbROP_Packed,enPbTypeFlag_Signed) #define REPEATED_SP(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),std::vector<type>,value,label,enPbROP_Packed,enPbTypeFlag_Signed) #define REPEATED_PF(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),std::vector<type>,value,label,enPbROP_Packed,enPbTypeFlag_Fixed) #define REPEATED_FP(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),std::vector<type>,value,label,enPbROP_Packed,enPbTypeFlag_Fixed) #define REPEATED_PB(type,value,label) PB_FIELD_INDEX_B(AUTO_INDEX(),std::vector<type>,value,label,enPbROP_Packed,enPbTypeFlag_Default) #define REPEATED_PSB(type,value,label) PB_FIELD_INDEX_B(AUTO_INDEX(),std::vector<type>,value,label,enPbROP_Packed,enPbTypeFlag_Signed) #define REPEATED_SPB(type,value,label) PB_FIELD_INDEX_B(AUTO_INDEX(),std::vector<type>,value,label,enPbROP_Packed,enPbTypeFlag_Signed) #define REPEATED_PFB(type,value,label) PB_FIELD_INDEX_B(AUTO_INDEX(),std::vector<type>,value,label,enPbROP_Packed,enPbTypeFlag_Fixed) #define REPEATED_FPB(type,value,label) PB_FIELD_INDEX_B(AUTO_INDEX(),std::vector<type>,value,label,enPbROP_Packed,enPbTypeFlag_Fixed) #define PB_BEGIN_B() FIELD_BEGIN() \ public: bool ParseFromArray(const void* pData,int size){ unsigned long long len = 0;IPbBuffer ib((const char*)pData,size); return ib.Parse(this);} \ std::string SerializeAsString(){ OPB ob(ByteSize()); ob.Write(*this, Int2Type<Size>()); return std::move(ob.ToString());} \ int SerializePartialToArray(void* pData, int len){ OPB ob((char*)pData, len);ob.Write(*this, Int2Type<Size>()); return ob.Error() ? 0 : ob.Size();} \ int m_byteSize; void set_byteSize(int size) {m_byteSize = size;} int & get_byteSize(){return m_byteSize;} int ByteSize(){OPBByteSize object; m_byteSize = 0; object.ByteSzieObject(*this,Int2Type<Size>()); return m_byteSize;} #define PB_BEGIN() FIELD_BEGIN() \ public: bool ParseFromArray(const void* pData,int size){ unsigned long long len = 0;IPbBuffer ib((const char*)pData,size); return ib.Parse(this);} \ std::string SerializeAsString(){ OPB ob(ByteSize()); ob.Write(*this, Int2Type<Size>()); return std::move(ob.ToString());} \ int SerializePartialToArray(void* pData, int len){ OPB ob((char*)pData, len);ob.Write(*this, Int2Type<Size>()); return ob.Error() ? 0 : ob.Size();} \ void set_byteSize(int size) {} int get_byteSize() { return 0; } int ByteSize() { OPBByteSize object; int len = object.ByteSzieObject(*this, Int2Type<Size>()); set_byteSize(len); return len; } #define PB_END() FIELD_END() bool ParseFromBuffer(IPbBuffer* pIpb, unsigned int label, enPBEncodeType EncodeType,const char* pData,unsigned long long & len){ return pIpb->ReadField<Size>(this, label, EncodeType,pData,len,Int2Type<Size>()); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// enum enPbROP { enPbROP_Required = 0, enPbROP_Optional = 1, enPbROP_Packed = 2, }; //PB数据类标志 enum enPbTypeFlag { enPbTypeFlag_Default = 0, enPbTypeFlag_Signed, enPbTypeFlag_Fixed, }; /* Type Meaning Used For 0 Varint int32, int64, uint32, uint64, sint32, sint64, bool, enum 1 64-bit fixed64, sfixed64, double 2 Length-delimi string, bytes, embedded messages, packed repeated fields 3 Start group Groups (deprecated) 4 End group Groups (deprecated) 5 32-bit fixed32, sfixed32, float */ //PB 编码类型 enum enPBEncodeType { enPBEncodeType_Varint = 0, enPBEncodeType_64bit = 1, enPBEncodeType_Length = 2, enPBEncodeType_StartGroup = 3, enPBEncodeType_EndGroup = 4, enPBEncodeType_32bit = 5, }; #define ZIGZAG32(n) (((n) << 1) ^ ((n) >> 31)) #define ZIGZAG64(n) (((n) << 1) ^ ((n) >> 63)) #define UNZIGZAG32(n) ((n >> 1) ^ -static_cast<int32>(n & 1)) #define UNZIGZAG64(n) ((n >> 1) ^ -static_cast<int64>(n & 1)) #define PB_KEY(wirte_type,label) (unsigned int)((label << 3) | wirte_type) #define PB_ENCODETYPE(key) (key&0x00000007) #define PB_LABEL(key) ((unsigned int)key>>3) // 消除警告:将值强制为布尔值“true”或“false”(性能警告) #pragma warning(disable:4800) template<unsigned int label> struct TLabelSize { enum { Size = (label==0)? 0 : ((label < (1 << 4)) ? 1 : ((label < (1 << 11)) ? 2 : ((label < (1 << 18)) ? 3 : ((label < (1 << 25)) ? 4 : (5))))) }; }; class OPBByteSize { public: template< typename type> int ByteSzieObject(type & obj, Int2Type<0> ind) { return 0; } template<int size, typename type> int ByteSzieObject(type & obj,Int2Type<size> ind) { int bytesize = ByteSzieObject(obj, Int2Type<size-1> ()); if (enPbROP_Optional == obj.getPbROP(ind) && memcmp(&obj.getValue(ind), &obj.getDefault(ind), sizeof(obj.getValue(ind))) == 0 ) { obj.set_byteSize(bytesize); return bytesize; } int contextLen = 0; bytesize += ByteSize(obj.getValue(ind), Int2Type<sizeof(obj.getLabelObject(ind))>(), obj.getPbTypeObject(ind), obj.getPbROP(ind), &contextLen); if (contextLen > 0) { obj.SetFieldByteSize(ind, contextLen); } obj.set_byteSize(bytesize); return bytesize; } ///////////////////////////////////////////////////////////////////////////// template<int PbTypeFlag,unsigned int LabelSize> int ByteSize(int32 obj, Int2Type<LabelSize> label , Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop,int * pContextLen=0) { return (unsigned int)TLabelSize<LabelSize>::Size + FieldByteSize(obj, TypeFlag); } template<int PbTypeFlag, unsigned int LabelSize> int ByteSize(uint32 obj, Int2Type<LabelSize> label, Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop, int * pContextLen = 0) { return (unsigned int)TLabelSize<LabelSize>::Size + FieldByteSize(obj, TypeFlag); } template<int PbTypeFlag, unsigned int LabelSize> int ByteSize(int64 obj, Int2Type<LabelSize> label, Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop, int * pContextLen = 0) { return (unsigned int)TLabelSize<LabelSize>::Size + FieldByteSize(obj, TypeFlag); } template<int PbTypeFlag, unsigned int LabelSize> int ByteSize(uint64 obj, Int2Type<LabelSize> label, Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop, int * pContextLen = 0) { return (unsigned int)TLabelSize<LabelSize>::Size + FieldByteSize(obj, TypeFlag); } template<int PbTypeFlag, unsigned int LabelSize> int ByteSize(float obj, Int2Type<LabelSize> label, Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop, int * pContextLen = 0) { return (unsigned int)TLabelSize<LabelSize>::Size + FieldByteSize(obj, TypeFlag); } template<int PbTypeFlag, unsigned int LabelSize> int ByteSize(double obj, Int2Type<LabelSize> label, Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop, int * pContextLen = 0) { return (unsigned int)TLabelSize<LabelSize>::Size + FieldByteSize(obj, TypeFlag); } template<int PbTypeFlag, unsigned int LabelSize> int ByteSize(bool obj, Int2Type<LabelSize> label, Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop, int * pContextLen = 0) { return (unsigned int)TLabelSize<LabelSize>::Size + FieldByteSize(obj, TypeFlag); } template<int PbTypeFlag, unsigned int LabelSize> int ByteSize(string & obj, Int2Type<LabelSize> label, Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop, int * pContextLen = 0) { int size = obj.length(); if(pContextLen) *pContextLen = size; return (unsigned int)TLabelSize<LabelSize>::Size + size + this->VarintSize32(size); } template<typename type,int PbTypeFlag,unsigned int LabelSize> int ByteSize(std::vector<type> & obj, Int2Type<LabelSize> label, Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop, int * pContextLen = 0) { int total = 0; if (obj.empty() == false) { if (pbRop == enPbROP_Packed) { if (THaveLeghtField<type>::Value || PbTypeFlag != enPbTypeFlag_Fixed) { for (int i = 0; i < obj.size();i++) { total += ByteSize(obj[i], Int2Type<0>(), TypeFlag, pbRop); } } else { total += sizeof(type)*obj.size(); } #ifdef USE_REPEATED_PACKED_EXTEND total += VarintSize32(obj.size()); #endif if(pContextLen) *pContextLen = total; total += (unsigned int)TLabelSize<LabelSize>::Size + VarintSize32(total); } else { if (THaveLeghtField<type>::Value || PbTypeFlag != enPbTypeFlag_Fixed) { for (int i = 0; i < obj.size();i++) { total += ByteSize(obj[i], Int2Type<0>(), TypeFlag, pbRop); } } else { total += sizeof(type)*obj.size(); } total += (unsigned int)TLabelSize<LabelSize>::Size*obj.size(); } } return total; } template<typename type, int PbTypeFlag, unsigned int LabelSize> int ByteSize(type & obj, Int2Type<LabelSize> label, Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop, int * pContextLen = 0) { int total = obj.ByteSize(); if (pContextLen) { *pContextLen = total; } return (unsigned int)TLabelSize<LabelSize>::Size + total + VarintSize32(total); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// template<int PbTypeFlag> int FieldByteSize(int32 obj, Int2Type<PbTypeFlag> TypeFlag) { return ByteSize32(obj, TypeFlag); } template<int PbTypeFlag> int FieldByteSize(uint32 obj, Int2Type<PbTypeFlag> TypeFlag) { return ByteSize32(obj, TypeFlag); } template<int PbTypeFlag> int FieldByteSize(int64 obj, Int2Type<PbTypeFlag> TypeFlag) { return ByteSize64(obj, TypeFlag); } template<int PbTypeFlag> int FieldByteSize(uint64 obj, Int2Type<PbTypeFlag> TypeFlag) { return ByteSize64(obj, TypeFlag); } template<int PbTypeFlag> int FieldByteSize(float obj, Int2Type<PbTypeFlag> TypeFlag) { return sizeof(obj); } template<int PbTypeFlag> int FieldByteSize(double obj,Int2Type<PbTypeFlag> TypeFlag) { return sizeof(obj); } template<int PbTypeFlag> int FieldByteSize(bool obj, Int2Type<PbTypeFlag> TypeFlag) { return this->VarintSize32(obj); } ///////////////////////////////////////////////////////////////////////////////////// private: int VarintSize32(unsigned long value) { if (value < (1 << 7)) { return 1; } else if (value < (1 << 14)) { return 2; } else if (value < (1 << 21)) { return 3; } else if (value < (1 << 28)) { return 4; } else { return 5; } } int VarintSize64(unsigned long long value) { if (value < (1ull << 35)) { if (value < (1ull << 7)) { return 1; } else if (value < (1ull << 14)) { return 2; } else if (value < (1ull << 21)) { return 3; } else if (value < (1ull << 28)) { return 4; } else { return 5; } } else { if (value < (1ull << 42)) { return 6; } else if (value < (1ull << 49)) { return 7; } else if (value < (1ull << 56)) { return 8; } else if (value < (1ull << 63)) { return 9; } else { return 10; } } } int ByteSize32(int32 obj, Int2Type<enPbTypeFlag_Default> TypeFlag) { if (obj < 0) { return VarintSize64(obj); } return VarintSize32(obj); } int ByteSize32(uint32 obj, Int2Type<enPbTypeFlag_Default> TypeFlag) { return VarintSize32(obj); } int ByteSize32(int32 obj, Int2Type<enPbTypeFlag_Signed> TypeFlag) { return ByteSize32((int32)ZIGZAG32(obj), Int2Type<enPbTypeFlag_Default>()); } int ByteSize32(uint32 obj, Int2Type<enPbTypeFlag_Signed> TypeFlag) { return ByteSize32((uint32)ZIGZAG32(obj), Int2Type<enPbTypeFlag_Default>()); } int ByteSize32(int32 obj, Int2Type<enPbTypeFlag_Fixed> TypeFlag) { return sizeof(int32); } int ByteSize32(uint32 obj, Int2Type<enPbTypeFlag_Fixed> TypeFlag) { return sizeof(uint32); } int ByteSize64(int64 obj, Int2Type<enPbTypeFlag_Default> TypeFlag) { return VarintSize64(obj); } int ByteSize64(uint64 obj, Int2Type<enPbTypeFlag_Default> TypeFlag) { return VarintSize64(obj); } int ByteSize64(int64 obj, Int2Type<enPbTypeFlag_Signed> TypeFlag) { return VarintSize64(ZIGZAG64(obj)); } int ByteSize64(uint64 obj, Int2Type<enPbTypeFlag_Signed> TypeFlag) { return VarintSize64(ZIGZAG64(obj)); } int ByteSize64(int64 obj, Int2Type<enPbTypeFlag_Fixed> TypeFlag) { return sizeof(int64); } int ByteSize64(uint64 obj, Int2Type<enPbTypeFlag_Fixed> TypeFlag) { return sizeof(uint64); } }; //输出buffer template<size_t static_size> class OPbBuffer { public: OPbBuffer() { __Init(); } explicit OPbBuffer(char * pData,size_t len) { __Init(); this->m_ptrBegin = this->m_ptrCur = pData; this->m_Size = len; } //预分配容量 explicit OPbBuffer(size_t len) { __Init(); if (len == 0) { len = 1024; } ResetCapacity(len); } ~OPbBuffer() { __Init(); } //复位 void Reset() { m_bError = false; m_Size = 0; m_ptrCur = m_ptrBegin = NULL; } size_t GetStaticSize() { return static_size; } //返回从pos开始的内存 const char * Buffer(size_t pos=0) const { if (pos >= m_Size) { return nullptr; } return m_ptrBegin + pos; } char * CurrentBuffer() { return m_ptrCur; } char * Skip(size_t len) { char* pOld = m_ptrCur; m_ptrCur += len; return pOld; } //获得数据大小 size_t Size() const { return m_ptrCur - m_ptrBegin; } //当前容量 size_t Capacity() const { return m_Size; } //余下空间 size_t Remain() const { return m_Size - (m_ptrCur - m_ptrBegin); } //注意:内存所有权会转移 std::vector<char> TakeData() { std::vector<char> vect; vect.insert(vect.begin(), m_ptrBegin, m_ptrCur); return std::move(vect); } std::string ToString() { if (m_ptrBegin == m_strData.data()) { m_strData.resize(m_ptrCur - m_ptrBegin); return std::move(m_strData); } else { return std::move(std::string(m_ptrBegin, m_ptrCur)); } } //扩展内存 bool ResetCapacity(size_t len) { int old_size = this->Size(); if (old_size >= len) { return true; } if (m_strData.data() == m_ptrBegin) { m_strData.resize(len); } else { m_strData.resize(len); if (old_size > 0) { memcpy((char*)m_strData.data(), m_ptrBegin, old_size); } } this->m_Size = len; this->m_ptrBegin = (char*)m_strData.data(); this->m_ptrCur = m_ptrBegin + old_size; return true; } //是否产生了错误 bool Error() const { return m_bError; } //push二进制内存 void Push(const void* pData, int len) { memcpy(this->m_ptrCur, pData, len); this->m_ptrCur += len; } //写整数 void WriteInt8(char value) { char * ptr = Skip(sizeof(value)); *(char*)ptr = value; } void WriteInt16(short value) { char * ptr = Skip(sizeof(value)); *(short*)ptr = value; } void WriteInt(int value) { char * ptr = Skip(sizeof(value)); *(int*)ptr = value; } void WriteInt64(long long value) { char * ptr = Skip(sizeof(value)); *(long long *)ptr = value; } public: template< typename type> int Write(type & obj) { int byte_size = obj.ByteSize(); if (byte_size <= static_size) { this->m_ptrBegin = this->m_ptrCur = this->m_static_data; this->m_Size = static_size; Write(obj, Int2Type<type::Size>()); } return byte_size; } template< typename type> bool Write(type & obj, Int2Type<0> ind) { return true; } template<int size, typename type> bool Write(type & obj, Int2Type<size> ind) { if (Write(obj, Int2Type<size - 1>()) == false) { return false; } if (enPbROP_Optional == obj.getPbROP(ind) && memcmp(&obj.getValue(ind),&obj.getDefault(ind),sizeof(obj.getValue(ind)))==0) { return true; } Write(obj.getValue(ind), Int2Type<sizeof(obj.getLabelObject(ind))>(), obj.getPbTypeObject(ind), obj.getPbROP(ind), obj.GetFieldByteSize(ind)); return this->Error() == false; } ///////////////////////////////////////////////// template<typename ValueType, int PbTypeFlag, unsigned int LabelSize> void Write(ValueType & obj, Int2Type<LabelSize> label , Int2Type<PbTypeFlag> TypeFlag , enPbROP pbRop = enPbROP_Required, int byteSize = 0) { WriteKey(Int2Type<enPBEncodeType_Length>(), label,Int2Type<TLabelSize<LabelSize>::Size>()); unsigned long size = obj.get_byteSize(); if (size == 0) { size = obj.ByteSize(); } WriteVarint32(size); this->m_ptrCur += obj.SerializePartialToArray(this->m_ptrCur, this->Remain()); } template<int PbTypeFlag, unsigned int LabelSize> void Write(int obj, Int2Type<LabelSize> label , Int2Type<PbTypeFlag> TypeFlag , enPbROP pbRop = enPbROP_Required, int byteSize = 0) { Write32bit((long)obj, label, TypeFlag); } template<int PbTypeFlag, unsigned int LabelSize> void Write(unsigned int obj, Int2Type<LabelSize> label, Int2Type<PbTypeFlag> TypeFlag , enPbROP pbRop = enPbROP_Required, int byteSize = 0) { Write32bit((unsigned long)obj, label, TypeFlag); } template<int PbTypeFlag, unsigned int LabelSize> void Write(long long obj, Int2Type<LabelSize> label , Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop = enPbROP_Required, int byteSize = 0) { Write64bit(obj, label, TypeFlag); } template<int PbTypeFlag, unsigned int LabelSize> void Write(unsigned long long & obj, Int2Type<LabelSize> label , Int2Type<PbTypeFlag> TypeFlag , enPbROP pbRop = enPbROP_Required, int byteSize = 0) { Write64bit(obj, label, TypeFlag); } template<int PbTypeFlag, unsigned int LabelSize> void Write(bool obj, Int2Type<LabelSize> label , Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop = enPbROP_Required, int byteSize = 0) { long value = obj; Write32bit(value, label, TypeFlag); } template<int PbTypeFlag, unsigned int LabelSize> void Write(float & obj, Int2Type<LabelSize> label , Int2Type<PbTypeFlag> TypeFlag , enPbROP pbRop = enPbROP_Required, int byteSize = 0) { unsigned long value = *(unsigned long*)(void*)&obj; Write32bit(value, label, Int2Type<enPbTypeFlag_Fixed>()); } template<int PbTypeFlag, unsigned int LabelSize> void Write(double & obj, Int2Type<LabelSize> label, Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop = enPbROP_Required, int byteSize = 0) { unsigned long long value = *(unsigned long long*)(void*)&obj; Write64bit(value, label, Int2Type<enPbTypeFlag_Fixed>()); } template<int PbTypeFlag, unsigned int LabelSize> void Write(std::string & obj, Int2Type<LabelSize> label , Int2Type<PbTypeFlag> TypeFlag, enPbROP pbRop = enPbROP_Required, int byteSize = 0) { unsigned long size = obj.length(); WriteKey(Int2Type<enPBEncodeType_Length>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); WriteVarint32(size); Push(obj.data(), size); } template<typename type, int PbTypeFlag, unsigned int LabelSize> void Write(std::vector<type> & obj, Int2Type<LabelSize> label, Int2Type<PbTypeFlag> TypeFlag , enPbROP pbRop = enPbROP_Required, int byteSize = 0) { int obj_len = obj.size(); if (obj_len==0) { return ; } if (enPbROP_Packed == pbRop) { WriteKey(Int2Type<enPBEncodeType_Length>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); if (byteSize == 0) { OPBByteSize ByteSizeObj; ByteSizeObj.ByteSize(obj, Int2Type<0>(), TypeFlag, pbRop,&byteSize); } WriteVarint32(byteSize); #ifdef USE_REPEATED_PACKED_EXTEND WriteVarint32(obj.size()); #endif for (int i = 0; i < obj_len;i++) { Write(obj[i], Int2Type<0>(), TypeFlag); } } else { for (int i = 0; i < obj_len;i++) { Write(obj[i], label, TypeFlag, pbRop); } } } private: template<unsigned int LabelSize> void Write32bit( long obj, Int2Type<LabelSize> label , Int2Type<enPbTypeFlag_Default>) { WriteKey(Int2Type<enPBEncodeType_Varint>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); if (obj > 0) { WriteVarint32(obj); } else { WriteVarint64(obj); } } template<unsigned int LabelSize> void Write32bit( long obj, Int2Type<LabelSize> label, Int2Type<enPbTypeFlag_Signed>) { obj = ZIGZAG32(obj); WriteKey(Int2Type<enPBEncodeType_Varint>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); if (obj > 0) { WriteVarint32(obj); } else { WriteVarint64(obj); } } template<unsigned int LabelSize> void Write32bit( long obj, Int2Type<LabelSize> label , Int2Type<enPbTypeFlag_Fixed>) { WriteKey(Int2Type<enPBEncodeType_32bit>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); WriteInt(obj); } template<unsigned int LabelSize> void Write32bit(unsigned long obj, Int2Type<LabelSize> label, Int2Type<enPbTypeFlag_Default>) { WriteKey(Int2Type<enPBEncodeType_Varint>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); WriteVarint32(obj); } template<unsigned int LabelSize> void Write32bit(unsigned long obj, Int2Type<LabelSize> label, Int2Type<enPbTypeFlag_Signed>) { obj = ZIGZAG32(obj); WriteKey(Int2Type<enPBEncodeType_Varint>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); WriteVarint32(obj); } template<unsigned int LabelSize> void Write32bit(unsigned long obj, Int2Type<LabelSize> label , Int2Type<enPbTypeFlag_Fixed>) { WriteKey(Int2Type<enPBEncodeType_32bit>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); WriteInt(obj); } template<unsigned int LabelSize> void Write64bit( long long obj, Int2Type<LabelSize> label , Int2Type<enPbTypeFlag_Default> ) { WriteKey(Int2Type<enPBEncodeType_Varint>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); WriteVarint64(obj); } template<unsigned int LabelSize> void Write64bit( long long obj, Int2Type<LabelSize> label , Int2Type<enPbTypeFlag_Signed> ) { obj = ZIGZAG64(obj); WriteKey(Int2Type<enPBEncodeType_Varint>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); WriteVarint64(obj); } template<unsigned int LabelSize> void Write64bit( long long obj, Int2Type<LabelSize> label , Int2Type<enPbTypeFlag_Fixed> ) { WriteKey(Int2Type<enPBEncodeType_64bit>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); WriteInt64(obj); } template<unsigned int LabelSize> void Write64bit(unsigned long long obj, Int2Type<LabelSize> label, Int2Type<enPbTypeFlag_Default>) { WriteKey(Int2Type<enPBEncodeType_Varint>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); WriteVarint64(obj); } template<unsigned int LabelSize> void Write64bit(unsigned long long obj, Int2Type<LabelSize> label , Int2Type<enPbTypeFlag_Signed>) { obj = ZIGZAG64(obj); WriteKey(Int2Type<enPBEncodeType_Varint>(), label, Int2Type<TLabelSize<LabelSize>::Size>()); WriteVarint64(obj); } template<unsigned int LabelSize> void Write64bit(unsigned long long obj, Int2Type<LabelSize> label , Int2Type<enPbTypeFlag_Fixed> ) { WriteKey(Int2Type<enPBEncodeType_64bit>() , label,Int2Type<TLabelSize<LabelSize>::Size>()); WriteInt64(obj); } private: template< int EncodeTYpe> void WriteKey(Int2Type<EncodeTYpe>, Int2Type<0> labelObject, Int2Type<0>) { } template< int EncodeTYpe, unsigned int LabelSize > void WriteKey(Int2Type<EncodeTYpe> , Int2Type<LabelSize> labelObject,Int2Type<1> ) { *((unsigned char*)m_ptrCur++) = static_cast<unsigned char>(LabelSize<<3| EncodeTYpe); } template< int EncodeTYpe, unsigned int LabelSize > void WriteKey(Int2Type<EncodeTYpe>, Int2Type<LabelSize> labelObject, Int2Type<2>) { m_ptrCur[0] = static_cast<unsigned char>((LabelSize << 3) | 0x80 | EncodeTYpe); m_ptrCur[1] = static_cast<unsigned char>(LabelSize >> 4); m_ptrCur += 2; } template< int EncodeTYpe, unsigned int LabelSize ,int size> void WriteKey(Int2Type<EncodeTYpe>, Int2Type<LabelSize> labelObject, Int2Type<size>) { unsigned long key = PB_KEY(EncodeTYpe, LabelSize); unsigned char * end = WriteVarint32FallbackToArrayInline(key, (unsigned char*)this->m_ptrCur); m_ptrCur += (end - (unsigned char*)m_ptrCur); } void WriteVarint32(unsigned long value) { if (value < (1 << 7)) { *((unsigned char*)m_ptrCur++) = static_cast<unsigned char>(value); } else if(this->Remain()>4) { unsigned char * end = WriteVarint32FallbackToArrayInline(value, (unsigned char*)this->m_ptrCur); m_ptrCur += (end - (unsigned char*)m_ptrCur); } else { unsigned char bytes[5]; unsigned char * end = WriteVarint32FallbackToArrayInline(value, bytes); memcpy(m_ptrCur,bytes, end - bytes); m_ptrCur += (end - bytes); } } inline unsigned char* WriteVarint32FallbackToArrayInline( unsigned long value, unsigned char* target) { target[0] = static_cast<unsigned char>(value | 0x80); if (value >= (1 << 7)) { target[1] = static_cast<unsigned char>((value >> 7) | 0x80); if (value >= (1 << 14)) { target[2] = static_cast<unsigned char>((value >> 14) | 0x80); if (value >= (1 << 21)) { target[3] = static_cast<unsigned char>((value >> 21) | 0x80); if (value >= (1 << 28)) { target[4] = static_cast<unsigned char>(value >> 28); return target + 5; } else { target[3] &= 0x7F; return target + 4; } } else { target[2] &= 0x7F; return target + 3; } } else { target[1] &= 0x7F; return target + 2; } } else { target[0] &= 0x7F; return target + 1; } } void WriteVarint64(unsigned long long value) { if (value < (1 << 7)) { *((unsigned char*)m_ptrCur++) = static_cast<unsigned char>(value); } else if(this->Remain()>9) { unsigned char * end = WriteVarint64ToArrayInline(value, (unsigned char*)this->m_ptrCur); m_ptrCur += (end - (unsigned char*)m_ptrCur); } else { unsigned char bytes[10]; unsigned char * end = WriteVarint64ToArrayInline(value, bytes); memcpy(m_ptrCur, bytes, end - bytes); m_ptrCur += (end - bytes); } } inline unsigned char * WriteVarint64ToArrayInline( unsigned long long value, unsigned char* target) { unsigned int part0 = static_cast<unsigned int>(value); unsigned int part1 = static_cast<unsigned int>(value >> 28); unsigned int part2 = static_cast<unsigned int>(value >> 56); int size; if (part2 == 0) { if (part1 == 0) { if (part0 < (1 << 14)) { if (part0 < (1 << 7)) { size = 1; goto size1; } else { size = 2; goto size2; } } else { if (part0 < (1 << 21)) { size = 3; goto size3; } else { size = 4; goto size4; } } } else { if (part1 < (1 << 14)) { if (part1 < (1 << 7)) { size = 5; goto size5; } else { size = 6; goto size6; } } else { if (part1 < (1 << 21)) { size = 7; goto size7; } else { size = 8; goto size8; } } } } else { if (part2 < (1 << 7)) { size = 9; goto size9; } else { size = 10; goto size10; } } size10: target[9] = static_cast<unsigned char>((part2 >> 7) | 0x80); size9: target[8] = static_cast<unsigned char>((part2) | 0x80); size8: target[7] = static_cast<unsigned char>((part1 >> 21) | 0x80); size7: target[6] = static_cast<unsigned char>((part1 >> 14) | 0x80); size6: target[5] = static_cast<unsigned char>((part1 >> 7) | 0x80); size5: target[4] = static_cast<unsigned char>((part1) | 0x80); size4: target[3] = static_cast<unsigned char>((part0 >> 21) | 0x80); size3: target[2] = static_cast<unsigned char>((part0 >> 14) | 0x80); size2: target[1] = static_cast<unsigned char>((part0 >> 7) | 0x80); size1: target[0] = static_cast<unsigned char>((part0) | 0x80); target[size - 1] &= 0x7F; return target + size; } private: OPbBuffer(const OPbBuffer& Other) = delete; OPbBuffer & operator =(const OPbBuffer&) = delete; private: //初始化 void __Init() { m_Size = 0; m_ptrCur = m_ptrBegin = NULL; m_bError = false; } private: char m_static_data[static_size]; std::string m_strData; int m_Size; char* m_ptrCur; char* m_ptrBegin; bool m_bError ; //是否产生了错误 }; //输入Buffer class IPbBuffer { public: template<typename type = PBParseSink> bool Parse(type * pObj = NULL) { if (this->Remain() == 0) { return false; } while (this->Remain() > 0) { enPBEncodeType EncodeType; unsigned int Label = 0; if (ReadKey(EncodeType, Label) == false) { m_bError = true; return false; } unsigned long long len = 0; unsigned long Value32 = 0; const char * pData = NULL; switch (EncodeType) { case enPBEncodeType_Varint: if (ReadVarint(len) == false) { m_bError = true; return false; } break; case enPBEncodeType_64bit: if (ReadFixed64(len) == false) { return false; } break; case enPBEncodeType_Length: if (ReadVarint(len) == false) { m_bError = true; return false; } if (len > this->Remain()) { m_bError = true; return false; } pData = (const int8*)this->CurrentBuffer(); this->Skip(len); break; case enPBEncodeType_StartGroup: return false; break; case enPBEncodeType_EndGroup: return false; break; case enPBEncodeType_32bit: if (ReadFixed32(Value32) == false) { return false; } len = Value32; break; default: break; } if (pObj->ParseFromBuffer(this, Label, EncodeType, pData, len) == false) { return false; } } return this->Error() == false; } IPbBuffer(const char* pData, int len) { this->m_pCurr = m_ptrBegin = (const uint8*)pData; this->m_pEnd = m_ptrBegin + len; m_bError = false; } IPbBuffer(const std::vector<char> & vectData) { this->m_pCurr = m_ptrBegin = (const uint8*)vectData.data(); this->m_pEnd = m_ptrBegin + vectData.size(); m_bError = false; } template<size_t size> IPbBuffer(const OPbBuffer<size> & ob) { this->m_pCurr = m_ptrBegin = (const uint8*)ob.Buffer(); this->m_pEnd = m_ptrBegin + ob.Size(); m_bError = false; } ~IPbBuffer() { m_bError = false; } //总长度 int Capacity() { return this->m_pEnd - m_ptrBegin; } //余下未读数据 int Remain() { return this->m_pEnd - m_pCurr; } //已读数据 int Size() const { return this->m_pCurr - m_ptrBegin; } //返回从len字节开始的内存 const uint8 * Buffer(int len = 0) { if (len>Capacity()) return NULL; return m_ptrBegin + len; } //返回未读buffer const uint8 * CurrentBuffer() { return m_pCurr; } //跳过len字节,返回移动前的地址 const uint8 * Skip(int len) { const uint8 * ptr = m_pCurr; m_pCurr += len; return ptr; } //是否产生了错误 bool Error() { return m_bError; } bool ReadKey(enPBEncodeType & EncodeTYpe, unsigned int & label) { unsigned long long key = 0; if (ReadVarint(key) == false) { return false; } unsigned int cc = key; EncodeTYpe = (enPBEncodeType)PB_ENCODETYPE(cc); label = PB_LABEL(cc); return (this->Error() == false); } bool ReadFixed32(unsigned long & value) { if (this->Remain() < sizeof(unsigned long)) { m_bError = true; return false; } value = *(const unsigned long*)this->CurrentBuffer(); this->Skip(sizeof(unsigned long)); return this->Error() == false; } bool ReadFixed64(unsigned long long & value) { if (this->Remain() < sizeof(unsigned long long)) { m_bError = true; return false; } value = *(const unsigned long long*)this->CurrentBuffer(); this->Skip(sizeof(unsigned long long)); return this->Error() == false; } int SkipVarint() { const uint8 * ptr = m_pCurr; while (m_pCurr < this->m_pEnd && *m_pCurr++ & 0x80) { NULL; } return m_pCurr - ptr; } bool ReadVarint(unsigned long long & value) { if (!(m_pCurr < this->m_pEnd)) { return false; } if ((value = *m_pCurr++) < 0x80) { return true; } else { value = (unsigned char)value & 0x7f; } int i = 1; unsigned char cc; this->m_bError = true; while (m_pCurr < this->m_pEnd && i<10) { cc = *m_pCurr++; value += ((unsigned long long)(cc & 0x7f)) << (i * 7); ++i; if (!(cc & 0x80)) { m_bError = false; return true; } } return (m_bError == false); } //读取 template<typename type> bool Read(type & value, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, unsigned int label = 0, enPbTypeFlag TypeFlag = enPbTypeFlag_Default, enPbROP pbRop = enPbROP_Required) { IPB ipb(pData, len); return ipb.Parse(&value); } bool Read(int & value, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, unsigned int label = 0, enPbTypeFlag TypeFlag = enPbTypeFlag_Default, enPbROP pbRop = enPbROP_Required) { return ReadNumber(value, len, TypeFlag); } bool Read(unsigned int & value, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, unsigned int label = 0, enPbTypeFlag TypeFlag = enPbTypeFlag_Default, enPbROP pbRop = enPbROP_Required) { return ReadNumber(value, len, TypeFlag); } bool Read(long long & value, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, unsigned int label = 0, enPbTypeFlag TypeFlag = enPbTypeFlag_Default, enPbROP pbRop = enPbROP_Required) { return ReadNumber(value, len, TypeFlag); } bool Read(unsigned long long & value, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, unsigned int label = 0, enPbTypeFlag TypeFlag = enPbTypeFlag_Default, enPbROP pbRop = enPbROP_Required) { return ReadNumber(value, len, TypeFlag); } bool Read(bool & value, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, unsigned int label = 0, enPbTypeFlag TypeFlag = enPbTypeFlag_Default, enPbROP pbRop = enPbROP_Required) { return ReadNumber(value, len, TypeFlag); } bool Read(float & value, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, unsigned int label = 0, enPbTypeFlag TypeFlag = enPbTypeFlag_Default, enPbROP pbRop = enPbROP_Required) { unsigned long long obj = 0; if (ReadNumber(obj, len, enPbTypeFlag_Fixed) == false) { return false; } unsigned long l = obj; value = *(float*)(void*)&l; return true; } bool Read(double & value, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, unsigned int label = 0, enPbTypeFlag TypeFlag = enPbTypeFlag_Default, enPbROP pbRop = enPbROP_Required) { unsigned long long obj = 0; if (ReadNumber(obj, len, enPbTypeFlag_Fixed) == false) { return false; } unsigned long long l = obj; value = *(double*)(void*)&l; return true; } bool Read(std::string & value, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, unsigned int label = 0, enPbTypeFlag TypeFlag = enPbTypeFlag_Default, enPbROP pbRop = enPbROP_Required) { if (pData != NULL || len > 0) { value.assign(pData, pData + len); } return true; } template<typename type> bool Read(std::vector<type> & value, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, unsigned int label = 0, enPbTypeFlag TypeFlag = enPbTypeFlag_Default, enPbROP pbRop = enPbROP_Required) { if (pbRop == enPbROP_Packed) { IPB ipb(pData, len); #ifdef USE_REPEATED_PACKED_EXTEND unsigned long long elem_size; ipb.ReadVarint(elem_size); int old_size = value.size(); value.resize(elem_size+ old_size); int total_size = old_size + elem_size; unsigned long long obj_len = 0; if (THaveLeghtField<type>::Value) { for (int i = old_size; i < total_size; ++i) { ipb.ReadVarint(obj_len); int remian = ipb.Remain(); if (remian < obj_len) { return false; } if (ipb.Read(value[i], EncodeType, (const int8*)ipb.CurrentBuffer(), obj_len, 0, TypeFlag, pbRop)==false) { return false; } ipb.Skip(obj_len); } } else { if (TypeFlag == enPbTypeFlag_Fixed) { if (sizeof(type) == sizeof(long long)) { unsigned long long temp = 0; for (int i = old_size; i < total_size; ++i) { if (ipb.ReadFixed64(temp)==false || ipb.Read(value[i], EncodeType, NULL, temp, label, TypeFlag, pbRop) == false) { return false; } } } else { unsigned long temp = 0; for (int i = old_size; i < total_size; ++i) { if (ipb.ReadFixed32(temp)) { unsigned long long ll = temp; if (ipb.Read(value[i], EncodeType, NULL, ll, label, TypeFlag, pbRop) == false) { return false; } } else { return false; } } } } else { for (int i = old_size; i < total_size; ++i) { if (ipb.ReadVarint(obj_len)==false || ipb.Read(value[i], EncodeType, (const int8*)ipb.CurrentBuffer(), obj_len, 0, TypeFlag, pbRop)==false) { return false; } } } } #else if (TypeFlag == enPbTypeFlag_Fixed) { if (sizeof(type) == sizeof(long long)) { value.reserve(len / sizeof(long long)); type obj; unsigned long long temp = 0; while (ipb.ReadFixed64(temp)) { if (ipb.Read(obj, EncodeType, NULL, temp, label, TypeFlag, pbRop) == false) { return false; } } value.push_back(obj); } else { value.reserve(len / sizeof(long)); type obj; unsigned long temp = 0; while (ipb.ReadFixed32(temp)) { unsigned long long ll = temp; if (ipb.Read(obj, EncodeType, NULL, ll, label, TypeFlag, pbRop) == false) { return false; } value.push_back(obj); } } } else { //先计算长度 int count = 0; while (ipb.SkipVarint()) { count++; } value.reserve(count); //复位 ipb.Skip(0 - (len - ipb.Remain())); unsigned long long temp = 0; while (ipb.ReadVarint(temp)) { type obj; if (ipb.Read(obj, EncodeType, NULL, temp, label, TypeFlag, pbRop) == false) { return false; } value.push_back(obj); } } #endif } else { type obj; if (this->Read(obj, EncodeType,pData, len, TypeFlag)) { int key_len = 0; bool bEnd; int obj_size = GetCountWithLabel(label, EncodeType, key_len, bEnd); value.reserve(value.size() + bEnd? obj_size : obj_size*2 + 1); value.push_back(obj); unsigned long Value32 = 0; switch (EncodeType) { case enPBEncodeType_Varint: while (obj_size-- > 0) { this->Skip(key_len); if (ReadVarint(len) == false) { return false; } type obj; if (this->Read(obj, EncodeType, pData, len, TypeFlag)) { value.push_back(obj); } } break; case enPBEncodeType_64bit: while (obj_size-- > 0) { this->Skip(key_len); if (ReadFixed64(len) == false) { m_bError = true; return false; } type obj; if (this->Read(obj, EncodeType, pData, len, TypeFlag)) { value.push_back(obj); } } break; case enPBEncodeType_32bit: while (obj_size-- > 0) { this->Skip(key_len); if (ReadFixed32(Value32) == false) { m_bError = true; return false; } len = Value32; type obj; if (this->Read(obj, EncodeType, pData, len, TypeFlag)) { value.push_back(obj); } } break; case enPBEncodeType_Length: while (obj_size-- > 0) { this->Skip(key_len); if (ReadVarint(len) == false) { m_bError = true; return false; } if (len > this->Remain()) { m_bError = true; return false; } pData = (const int8*)this->CurrentBuffer(); this->Skip(len); type obj; if (this->Read(obj, EncodeType, pData, len, TypeFlag)) { value.push_back(obj); } } break; } } else { return false; } } return true; } /* template<typename type> bool Read(std::vector<type> & value, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, unsigned int label = 0, enPbTypeFlag TypeFlag = enPbTypeFlag_Default, enPbROP pbRop = enPbROP_Required) { if (pbRop == enPbROP_Packed) { IPB ipb(pData, len); type obj; if (TypeFlag == enPbTypeFlag_Fixed) { if (sizeof(type) == sizeof(long long)) { value.reserve(len / sizeof(long long)); unsigned long long temp = 0; while (ipb.ReadFixed64(temp)) { if (ipb.Read(obj, EncodeType, NULL, temp, label, TypeFlag, pbRop) == false) { return false; } } value.push_back(obj); } else { value.reserve(len / sizeof(long)); unsigned long temp = 0; while (ipb.ReadFixed32(temp)) { unsigned long long ll = temp; if (ipb.Read(obj, EncodeType, NULL, ll, label, TypeFlag, pbRop) == false) { return false; } value.push_back(obj); } } } else { //先计算长度 int count = len/2; value.reserve(count); //复位 ipb.Skip(0 - (len - ipb.Remain())); unsigned long long temp = 0; while (ipb.ReadVarint(temp)) { if (ipb.Read(obj, EncodeType, NULL, temp, label, TypeFlag, pbRop) == false) { return false; } value.push_back(obj); } } } else { type obj; if (this->Read(obj, EncodeType, pData, len, TypeFlag)) { value.push_back(obj); unsigned int LabelNext = 0; unsigned long Value32 = 0; const uint8 * pCurr = this->CurrentBuffer(); switch (EncodeType) { case enPBEncodeType_Varint: while (this->ReadKey(EncodeType, LabelNext)) { if (LabelNext != label) { this->Skip(pCurr - this->CurrentBuffer()); return true; } if (ReadVarint(len) == false) { m_bError = true; return false; } type obj; if (this->Read(obj, EncodeType, pData, len, TypeFlag)) { if (value.capacity() == value.size()) { value.reserve(value.size() * 2); } value.push_back(obj); pCurr = this->CurrentBuffer(); } } break; case enPBEncodeType_64bit: while (this->ReadKey(EncodeType, LabelNext)) { if (LabelNext != label) { this->Skip(pCurr - this->CurrentBuffer()); return true; } if (ReadFixed64(len) == false) { m_bError = true; return false; } type obj; if (this->Read(obj, EncodeType, pData, len, TypeFlag)) { if (value.capacity() == value.size()) { value.reserve(value.size() * 2); } value.push_back(obj); pCurr = this->CurrentBuffer(); } } break; case enPBEncodeType_32bit: while (this->ReadKey(EncodeType, LabelNext)) { if (LabelNext != label) { this->Skip(pCurr - this->CurrentBuffer()); return true; } if (ReadFixed32(Value32) == false) { m_bError = true; return false; } len = Value32; type obj; if (this->Read(obj, EncodeType, pData, len, TypeFlag)) { if (value.capacity() == value.size()) { value.reserve(value.size() * 2); } value.push_back(obj); pCurr = this->CurrentBuffer(); } } break; case enPBEncodeType_Length: while (this->ReadKey(EncodeType, LabelNext)) { if (LabelNext != label) { this->Skip(pCurr - this->CurrentBuffer()); return true; } if (ReadVarint(len) == false) { m_bError = true; return false; } if (len > this->Remain()) { m_bError = true; return false; } pData = (const int8*)this->CurrentBuffer(); this->Skip(len); type obj; if (this->Read(obj, EncodeType, pData, len, TypeFlag)) { if (value.capacity() == value.size()) { value.reserve(value.size() * 2); } value.push_back(obj); pCurr = this->CurrentBuffer(); } } break; } } else { return false; } } return true; } */ int GetCountWithLabel(unsigned int label,enPBEncodeType EncodeType,int & key_len,bool & bEnd ) { const uint8 * pBegin = this->CurrentBuffer(); int count = 0; unsigned long long len = 0; unsigned int LabelNext = 0; if (this->Remain()==0 || ReadKey(EncodeType, LabelNext) == false || LabelNext != label) { this->Skip(pBegin - this->CurrentBuffer()); return 0; } bEnd = false; key_len = this->CurrentBuffer() - pBegin; switch (EncodeType) { case enPBEncodeType_Varint: do { SkipVarint(); ++count; if (this->Remain() < key_len || memcmp(pBegin, this->CurrentBuffer(), key_len)) { bEnd = true; break; } this->Skip(key_len); } while (count<100); break; case enPBEncodeType_64bit: do { this->Skip(sizeof(long long)); ++count; if (this->Remain() < key_len || memcmp(pBegin, this->CurrentBuffer(), key_len)) { bEnd = true; break; } this->Skip(key_len); } while (count<100); break; case enPBEncodeType_32bit: do { this->Skip(sizeof(long)); ++count; if (this->Remain() < key_len || memcmp(pBegin, this->CurrentBuffer(), key_len)) { bEnd = true; break; } this->Skip(key_len); } while (count<100); break; case enPBEncodeType_Length: do { if (ReadVarint(len) == false) { break; } this->Skip(len); ++count; if (this->Remain() < key_len || memcmp(pBegin, this->CurrentBuffer(), key_len)) { bEnd = true; break; } this->Skip(key_len); } while (count<100); break; } this->Skip(pBegin - this->CurrentBuffer()); return count; } template<int index, typename type> bool ReadField(type * pObj, int label, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, Int2Type<index> ind) { if (sizeof(pObj->getLabelObject(ind)) == label) { return Read(pObj->getValue(ind), EncodeType,pData, len, label, pObj->getPbTypeFlag(ind), pObj->getPbROP(ind)); } return ReadField<index - 1, type>(pObj, label, EncodeType, pData, len, Int2Type<index - 1>());; } template<int index, typename type> bool ReadField(type * pObj, int label, enPBEncodeType EncodeType, const char* pData, unsigned long long & len, Int2Type<0> ind) { return true; } private: template<typename type> bool ReadNumber(type & obj, unsigned long long & len, enPbTypeFlag TypeFlag = enPbTypeFlag_Default) { unsigned long long value = len; if (TypeFlag == enPbTypeFlag_Signed) { value = UNZIGZAG64(len); } obj = value; return true; } private: const uint8 * m_ptrBegin; //开始数据 const uint8 * m_pCurr; //当前读数据 const uint8 * m_pEnd; //结束数据 bool m_bError; //是否产生了错误 }; typedef OPbBuffer<1> OPB; typedef IPbBuffer IPB; #endif