只用2000行代码实现google protocol buffer c++版的功能

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

     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文件定义如下:

 
/***************************************************************************************************
转载请注明出处,作者联系方式:3181356737@qq.com
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_EXTENDtotal += VarintSize32(obj.size());#endifif(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_EXTENDWriteVarint32(obj.size());#endiffor (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;}//返回未读bufferconst 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_EXTENDunsigned 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;}}}}
#elseif (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

转载于:https://my.oschina.net/u/2504104/blog/524370

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/459596.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

流控思路——多消费者定量生产(第100篇)

为什么80%的码农都做不了架构师&#xff1f;>>> 多线程消费队列到指定个数时触发一个生产线程往队列中补充元素&#xff0c;保证队列中有足够的数据供消费&#xff0c;不至于使消费线程等待&#xff0c;也不至于在队列中堆得过多。假设10人消费&#xff0c;先放2个…

使用JetBrains dotMemory 4.0分析内存

安装下载地址&#xff1a;http://www.jetbrains.com/profiler/ 1.在本地启动web应用后&#xff0c;打开dotMemory,附加进程 2.附加后会看到集中颜色得粗条&#xff0c;不断往左边走动&#xff0c;这是内存运行情况&#xff0c; 3.Get snapshot,抓取两次快照&#xff0c;等自动信…

AutoHomeRefreshListView仿汽车之家下拉刷新 《IT蓝豹》

2019独角兽企业重金招聘Python工程师标准>>> AutoHomeRefreshListView仿汽车之家下拉刷新 AutoHomeRefreshListView 高仿汽车之家下拉刷新 &#xff0c;下拉的时候出现很不错的效果。本项目来自&#xff1a;https://github.com/nugongshou110/AutoHomeRefreshListVi…

Java JVM、JNI、Native Function Interface、Create New Process Native Function API Analysis

目录 1. JAVA JVM 2. Java JNI: Java Native Interface 3. Java Create New Process Native Function API Analysis In Linux 4. Java Create New Process Native Function API Analysis In Windows 1. JAVA JVM 0x1: JVM架构简介 JVM是Java Virtual Machine(Java虚拟机)的缩写…

小android模拟器,小姚Android模拟器工作室版本v6.2.7.0正式版

逍遥Android Emulator Studio Edition是高质量的Android模拟器. 此版本是特殊版本&#xff0c;支持无限的多打开&#xff0c;智能管理和组控制模式. 它是专门为需要商业营销的用户设计的. Xiaoyao Android Emulator Studio Edition具有强大的引擎和良好的兼容性全能营销王 安卓…

html5carousel图片轮播,jQuery响应式轮播图插件VM Carousel

插件描述&#xff1a;VM Carousel是一款jQuery响应式轮播图插件。该jquery轮播图插件支持自动播放模式&#xff0c;支持动态改变图片尺寸&#xff0c;支持居中模式&#xff0c;以及无限循环等。使用方法在页面中引入jquery.vm-carousel.css&#xff0c;jquery和jquery.vm-carou…

那是计算机房吗英语否定回答,【微课+教材+听力+知识点】PEP四年级英语下册 Unit 1...

原标题&#xff1a;【微课教材听力知识点】PEP四年级英语下册 Unit 1微课&#xff1a;Unit 1-PartA微课&#xff1a;Unit 1-PartB微课&#xff1a;Unit 1-PartC课文教材动画教材听力Unit 1 My schoolUnit 1 单词▲点右上方绿标即可收听Words in Unit 1first floor [ˌfɜːst ˈ…

PropertyGrid控件 分类(Category)及属性(Property)排序

最近在做表单设计器&#xff0c;设计器上的控件都是我们自己封装的&#xff0c;但每个属性类别里的属性是按照属性的拼音排序的&#xff0c;现在想按照PropertyIndex标识进行排序&#xff08;PropertyIndex的后三位是用来标识编辑器的&#xff09;。 具体实现如下&#xff1a; …

用计算机计算出密码,自带计算器的密码

手机、电脑都会有自带的计算器&#xff0c;用惯了简易的计算器功能&#xff0c;不知道有没有感觉 iPhone 自带的计算器难用&#xff1f;后来才发现原来它还可以使用科学计算器进行指数函数、对数函数和三角函数的计算。只需要将 iPhone 转到横排模式就可以&#xff1a;这算不算…

shopify在哪里填写html,[Shopify开店教程]添加嵌入代码

添加嵌入代码在Shopify管理员中创建购买按钮后&#xff0c;您就可以将其添加到您自己的网站或博客中。将嵌入代码添加到您网站的源HTML的过程有所不同&#xff0c;具体取决于您希望购买按钮和购物车在您的发布平台上显示的方式和位置&#xff0c;以及有时您在该平台上使用的主题…

activity生命周期图

转载于:https://www.cnblogs.com/aqianglala/p/4344431.html

华硕台式计算机光盘怎么启动不了,华硕笔记本怎么用光盘重装系统 笔记本重装系统失败怎么办...

华硕笔记本是现在非常热门的笔记本品牌&#xff0c;很多的华硕笔记本用户在重装系统的时候&#xff0c;大多数会用上光盘&#xff0c;这种重装方式较为简单&#xff0c;所以备受青眯&#xff0c;不过呢还是有很多电脑用户不知道怎么用光盘重装系统&#xff0c;没关系&#xff0…

怎么安装Win10,硬盘安装Win10系统图文教程

2019独角兽企业重金招聘Python工程师标准>>> http://jingyan.baidu.com/article/f25ef254613ffd482c1b8236.html 分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友…

游戏计算机重要参数,这真的很重要吗 游戏鼠标三大参数之谜

1游戏鼠标三大参数&#xff1a;采样率[中关村在线键鼠频道原创]游戏鼠标作为目前最受消费者关注的外设产品&#xff0c;其销量以及利润在市场上也是表现最为出色的&#xff0c;众多游戏外设厂商也推出各种各样的游戏鼠标&#xff0c;各种霸气的名字更是让我们看的眼花缭乱&…

桌面上的文件使计算机变慢吗,电脑用久了会变卡怎么办?让电脑变得流畅方法图解...

工作生活中我们的电脑时间用久了&#xff0c;就会变得很卡&#xff0c;那么如何做会让电脑变得流畅一点呢&#xff0c;小编教大家几招。步骤首先要保持windows桌面整洁&#xff0c;尽量少放一些文件&#xff0c;因为桌面上的文件都是放在C盘&#xff0c;电脑系统一般也是装在C盘…

美图秀秀计算机教程,美图秀秀怎么抠图 美图秀秀抠图详细教程

怎么抠图&#xff1f;这是很多人在进行图片处理过程中经常处理的问题。对于那些专业人士来说&#xff0c;他们大多数用的是PS软件。但是对于绝大多数没有接触过PS的小白来说&#xff0c;怎么抠图成为了一大难题。其实&#xff0c;用过美图秀秀这款软件的朋友来说&#xff0c;它…

磁盘及文件系统的管理

分区是为了创建文件系统MBR&#xff1a;创建分区后&#xff0c;为了能够快速的存取文件就有了文件系统inode&#xff1a;中存储了文件属组&#xff0c;等与文件数据没有关系的文件属性信息&#xff0c;但是没有文件名每次访问某个目录的文件时是会进行缓存的&#xff0c;在一定…

Cocos2d-x 3.8.1+Cocos Studio 2.3.2捉虫记之控制场景文件中的骨骼动画

Cocos2d-x 3.8.1Cocos Studio 2.3.2捉虫记之控制场景文件中的骨骼动画引子这段时间一直努力在把早期版本的拇指接龙游戏&#xff08;Cocos2d-x 2.2.3CocoStudio 1.4.0.1&#xff09;升级到当前相对稳定的高大上环境——Cocos2d-x 3.8.1Cocos Studio 2.3.2。行程中遇到不少麻烦&…

用JSmooth制作java jar文件的可运行exe文件教程【图文】

这是我之前在个人博客3yj上面写的一篇文章&#xff0c;如今转载过来&#xff0c;原文地址 &#xff08;这不是广告哦&#xff09; 几年前&#xff0c;刚接触java的是&#xff0c;就想用一些方法把自己的劳动果实保护起来&#xff0c;曾经也用过非常多这种工具&#xff0c;有一个…

全国计算机vb考试经典程序设计,全国计算机二级《VB语言程序设计》考试要点...

全国计算机二级《VB语言程序设计》考试要点VB语言程序设计是计算机二级考试的科目之一&#xff0c;考生们在备考是要熟悉科目的知识要点&#xff0c;有针对性地进行备考。下面百分网小编为大家搜索整理了关于二级《VB语言程序设计》考试要点&#xff0c;欢迎参考练习&#xff0…