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

 
/***************************************************************************************************
转载请注明出处,作者联系方式: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_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

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

这个C++管理系统基本涵盖了“学生成绩管理系统”的所有功能,你可以从中借鉴到C++链表、类、封装、继承、文件操作、排序等等很多知识,极具借鉴意义,以下为本项目的功能介绍: 1. 建立文件 (1)可以使用默认文件名或指定文件名将记录存储到 (2)设置适当的标志位,作为对记录进操作的 (3)写同名文件将覆盖原来文件的 2.增加学生记录 (1) 可在已有记录后面追加新的记录 (2) 可以随时增加新的记录,它们仅保存在向量数组中 (3) 可以将一个文件读入,追加在已有记录之后 (4) 采取文件追加方式时,在没有保存到文件之前,将继续保持文件追加状态,以便实现连续追加操作方式 3. 新建学生信息文件 (1) 用来新建学生信息记录 (2) 如果已经有记录存在,可以覆盖原记录或者在原记录后面追加,也可以将原有记录信息保存 到一个指定文件,然后重新建立记录 (3) 给出相应的提示信息 4. 显示记录 (1) 如果没有记录可供显示,给出提示信息 (2) 可以随时显示内存中的记录 (3) 显示表头 5. 文件存储 (1) 可以按默认名字或指定名字存储记录文件 6. 读取文件 (1) 可以按默认名字或指定名字将记录文件读入内存 (2) 可以将指定或默认文件追加到现有记录的尾部 (3) 可以将文件连续追加到现有记录并更新记录中的“名次” 7. 删除记录 (1) 可以按“学号”、“姓名”或“名次”方式删除记录 (2) 标志将被删除的记录, 可以再次取消标志, 经确认后删除已经标志的记录(3) 如果记录是空表, 删除时应给出提示信息并返回主菜单 (4) 如果没有要删除的信息, 输出“没有找到”的信息 (5) 更新其他记录的名次 (6) 删除操作仅限于内存, 只有执存储操作时, 才能覆盖原记录 8. 修改记录 (1) 可以按“学号”、“姓名”或“名次”方式查找要修改的记录内容 (2) 给出将被修改记录的信息, 经确认后进修改 (3) 如果记录已经是空表,应给出提示信息并返回主菜单 (4) 如果没有找到需要修改的信息, 输出“没有找到”的信息 (5) 更新其他记录的名次 (6) 修改操作仅限于内存, 只有执存储操作时, 才能覆盖原记录 9. 查询记录 (1) 可以按“学号”、“姓名”或“名次”方式查询记录 (2) 能给出查询记录的信息 (3) 如果查询的信息不存在, 输出提示信息 10. 对记录进排序 (1) 可以按”学号”进升序和降序排列 (2) 可以按”姓名”进升序和降序排列 (3) 可以按”名次”进升序和降序排列 (4) 如果属于选择错误, 可以立即退出程序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值