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

     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

你可能感兴趣的:(C++,模板,Google,pb)