2019独角兽企业重金招聘Python工程师标准>>>
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
#include
#include
#include
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
struct Int2Type
{
enum { Value = size };
};
#define INT2TYPE(size) Int2Type()
#define ARRAY(type,size) std::array
#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){return name;} const type & getValue(Int2Type) const {return name;}
#define GET_NAME(index,name) const char* getName(Int2Type) const { return #name;}
template
struct THaveLeghtField
{
template
static char __is_field_struct(...);
template
static int __is_field_struct(typename type::traits_type *);
template
static int __is_field_struct(Int2Type *);
enum { Value = (sizeof(__is_field_struct(0)) == sizeof(int)) };
};
#endif
#define PB_INDEX(index,type,label,pbro,pbtype) std::array getLabelObject(Int2Type); Int2Type getIndex(Int2Type){ return Int2Type(); } int getLabel(Int2Type) { return label;} enPbROP getPbROP(Int2Type){return pbro; } enPbTypeFlag getPbTypeFlag(Int2Type){return pbtype;} Int2Type getPbTypeObject(Int2Type){return Int2Type();}
#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){ static type dflt; return dflt;} int GetFieldByteSize(Int2Type){ return 0;} void SetFieldByteSize(Int2Type,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){return dflt;} int GetFieldByteSize(Int2Type){ return 0;} void SetFieldByteSize(Int2Type,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){ static type dflt; return dflt;} int value##_byteSize_; int GetFieldByteSize(Int2Type){ return value##_byteSize_;} void SetFieldByteSize(Int2Type,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,value,label)
#define REPEATED_S(type,value,label) OPTIONAL_S(std::vector,value,label)
#define REPEATED_F(type,value,label) OPTIONAL_F(std::vector,value,label)
#define REPEATED_P(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),std::vector,value,label,enPbROP_Packed,enPbTypeFlag_Default)
#define REPEATED_PS(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),std::vector,value,label,enPbROP_Packed,enPbTypeFlag_Signed)
#define REPEATED_SP(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),std::vector,value,label,enPbROP_Packed,enPbTypeFlag_Signed)
#define REPEATED_PF(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),std::vector,value,label,enPbROP_Packed,enPbTypeFlag_Fixed)
#define REPEATED_FP(type,value,label) PB_FIELD_INDEX(AUTO_INDEX(),std::vector,value,label,enPbROP_Packed,enPbTypeFlag_Fixed)
#define REPEATED_PB(type,value,label) PB_FIELD_INDEX_B(AUTO_INDEX(),std::vector,value,label,enPbROP_Packed,enPbTypeFlag_Default)
#define REPEATED_PSB(type,value,label) PB_FIELD_INDEX_B(AUTO_INDEX(),std::vector,value,label,enPbROP_Packed,enPbTypeFlag_Signed)
#define REPEATED_SPB(type,value,label) PB_FIELD_INDEX_B(AUTO_INDEX(),std::vector,value,label,enPbROP_Packed,enPbTypeFlag_Signed)
#define REPEATED_PFB(type,value,label) PB_FIELD_INDEX_B(AUTO_INDEX(),std::vector,value,label,enPbROP_Packed,enPbTypeFlag_Fixed)
#define REPEATED_FPB(type,value,label) PB_FIELD_INDEX_B(AUTO_INDEX(),std::vector,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()); return std::move(ob.ToString());} \
int SerializePartialToArray(void* pData, int len){ OPB ob((char*)pData, len);ob.Write(*this, Int2Type()); 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()); 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()); return std::move(ob.ToString());} \
int SerializePartialToArray(void* pData, int len){ OPB ob((char*)pData, len);ob.Write(*this, Int2Type()); 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()); 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(this, label, EncodeType,pData,len,Int2Type()); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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(n & 1))
#define UNZIGZAG64(n) ((n >> 1) ^ -static_cast(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
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 ByteSzieObject(type & obj,Int2Type ind)
{
int bytesize = ByteSzieObject(obj, Int2Type ());
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(), obj.getPbTypeObject(ind), obj.getPbROP(ind), &contextLen);
if (contextLen > 0)
{
obj.SetFieldByteSize(ind, contextLen);
}
obj.set_byteSize(bytesize);
return bytesize;
}
/////////////////////////////////////////////////////////////////////////////
template
int ByteSize(int32 obj, Int2Type label , Int2Type TypeFlag, enPbROP pbRop,int * pContextLen=0)
{
return (unsigned int)TLabelSize::Size + FieldByteSize(obj, TypeFlag);
}
template
int ByteSize(uint32 obj, Int2Type label, Int2Type TypeFlag, enPbROP pbRop, int * pContextLen = 0)
{
return (unsigned int)TLabelSize::Size + FieldByteSize(obj, TypeFlag);
}
template
int ByteSize(int64 obj, Int2Type label, Int2Type TypeFlag, enPbROP pbRop, int * pContextLen = 0)
{
return (unsigned int)TLabelSize::Size + FieldByteSize(obj, TypeFlag);
}
template
int ByteSize(uint64 obj, Int2Type label, Int2Type TypeFlag, enPbROP pbRop, int * pContextLen = 0)
{
return (unsigned int)TLabelSize::Size + FieldByteSize(obj, TypeFlag);
}
template
int ByteSize(float obj, Int2Type label, Int2Type TypeFlag, enPbROP pbRop, int * pContextLen = 0)
{
return (unsigned int)TLabelSize::Size + FieldByteSize(obj, TypeFlag);
}
template
int ByteSize(double obj, Int2Type label, Int2Type TypeFlag, enPbROP pbRop, int * pContextLen = 0)
{
return (unsigned int)TLabelSize::Size + FieldByteSize(obj, TypeFlag);
}
template
int ByteSize(bool obj, Int2Type label, Int2Type TypeFlag, enPbROP pbRop, int * pContextLen = 0)
{
return (unsigned int)TLabelSize::Size + FieldByteSize(obj, TypeFlag);
}
template
int ByteSize(string & obj, Int2Type label, Int2Type TypeFlag, enPbROP pbRop, int * pContextLen = 0)
{
int size = obj.length();
if(pContextLen) *pContextLen = size;
return (unsigned int)TLabelSize::Size + size + this->VarintSize32(size);
}
template
int ByteSize(std::vector & obj, Int2Type label, Int2Type TypeFlag, enPbROP pbRop, int * pContextLen = 0)
{
int total = 0;
if (obj.empty() == false)
{
if (pbRop == enPbROP_Packed)
{
if (THaveLeghtField::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::Size + VarintSize32(total);
}
else
{
if (THaveLeghtField::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::Size*obj.size();
}
}
return total;
}
template
int ByteSize(type & obj, Int2Type label, Int2Type TypeFlag, enPbROP pbRop, int * pContextLen = 0)
{
int total = obj.ByteSize();
if (pContextLen)
{
*pContextLen = total;
}
return (unsigned int)TLabelSize::Size + total + VarintSize32(total);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template
int FieldByteSize(int32 obj, Int2Type TypeFlag)
{
return ByteSize32(obj, TypeFlag);
}
template
int FieldByteSize(uint32 obj, Int2Type TypeFlag)
{
return ByteSize32(obj, TypeFlag);
}
template
int FieldByteSize(int64 obj, Int2Type TypeFlag)
{
return ByteSize64(obj, TypeFlag);
}
template
int FieldByteSize(uint64 obj, Int2Type TypeFlag)
{
return ByteSize64(obj, TypeFlag);
}
template
int FieldByteSize(float obj, Int2Type TypeFlag)
{
return sizeof(obj);
}
template
int FieldByteSize(double obj,Int2Type TypeFlag)
{
return sizeof(obj);
}
template
int FieldByteSize(bool obj, Int2Type 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 TypeFlag)
{
if (obj < 0)
{
return VarintSize64(obj);
}
return VarintSize32(obj);
}
int ByteSize32(uint32 obj, Int2Type TypeFlag)
{
return VarintSize32(obj);
}
int ByteSize32(int32 obj, Int2Type TypeFlag)
{
return ByteSize32((int32)ZIGZAG32(obj), Int2Type());
}
int ByteSize32(uint32 obj, Int2Type TypeFlag)
{
return ByteSize32((uint32)ZIGZAG32(obj), Int2Type());
}
int ByteSize32(int32 obj, Int2Type TypeFlag)
{
return sizeof(int32);
}
int ByteSize32(uint32 obj, Int2Type TypeFlag)
{
return sizeof(uint32);
}
int ByteSize64(int64 obj, Int2Type TypeFlag)
{
return VarintSize64(obj);
}
int ByteSize64(uint64 obj, Int2Type TypeFlag)
{
return VarintSize64(obj);
}
int ByteSize64(int64 obj, Int2Type TypeFlag)
{
return VarintSize64(ZIGZAG64(obj));
}
int ByteSize64(uint64 obj, Int2Type TypeFlag)
{
return VarintSize64(ZIGZAG64(obj));
}
int ByteSize64(int64 obj, Int2Type TypeFlag)
{
return sizeof(int64);
}
int ByteSize64(uint64 obj, Int2Type TypeFlag)
{
return sizeof(uint64);
}
};
//输出buffer
template
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 TakeData()
{
std::vector 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());
}
return byte_size;
}
template< typename type> bool Write(type & obj, Int2Type<0> ind)
{
return true;
}
template bool Write(type & obj, Int2Type ind)
{
if (Write(obj, Int2Type()) == 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(), obj.getPbTypeObject(ind), obj.getPbROP(ind), obj.GetFieldByteSize(ind));
return this->Error() == false;
}
/////////////////////////////////////////////////
template
void Write(ValueType & obj, Int2Type label , Int2Type TypeFlag , enPbROP pbRop = enPbROP_Required, int byteSize = 0)
{
WriteKey(Int2Type(), label,Int2Type::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
void Write(int obj, Int2Type label , Int2Type TypeFlag , enPbROP pbRop = enPbROP_Required, int byteSize = 0)
{
Write32bit((long)obj, label, TypeFlag);
}
template
void Write(unsigned int obj, Int2Type label, Int2Type TypeFlag , enPbROP pbRop = enPbROP_Required, int byteSize = 0)
{
Write32bit((unsigned long)obj, label, TypeFlag);
}
template
void Write(long long obj, Int2Type label , Int2Type TypeFlag, enPbROP pbRop = enPbROP_Required, int byteSize = 0)
{
Write64bit(obj, label, TypeFlag);
}
template
void Write(unsigned long long & obj, Int2Type label , Int2Type TypeFlag , enPbROP pbRop = enPbROP_Required, int byteSize = 0)
{
Write64bit(obj, label, TypeFlag);
}
template
void Write(bool obj, Int2Type label , Int2Type TypeFlag, enPbROP pbRop = enPbROP_Required, int byteSize = 0)
{
long value = obj;
Write32bit(value, label, TypeFlag);
}
template
void Write(float & obj, Int2Type label , Int2Type TypeFlag , enPbROP pbRop = enPbROP_Required, int byteSize = 0)
{
unsigned long value = *(unsigned long*)(void*)&obj;
Write32bit(value, label, Int2Type());
}
template
void Write(double & obj, Int2Type label, Int2Type TypeFlag, enPbROP pbRop = enPbROP_Required, int byteSize = 0)
{
unsigned long long value = *(unsigned long long*)(void*)&obj;
Write64bit(value, label, Int2Type());
}
template
void Write(std::string & obj, Int2Type label , Int2Type TypeFlag, enPbROP pbRop = enPbROP_Required, int byteSize = 0)
{
unsigned long size = obj.length();
WriteKey(Int2Type(), label, Int2Type::Size>());
WriteVarint32(size);
Push(obj.data(), size);
}
template
void Write(std::vector & obj, Int2Type label, Int2Type TypeFlag , enPbROP pbRop = enPbROP_Required, int byteSize = 0)
{
int obj_len = obj.size();
if (obj_len==0)
{
return ;
}
if (enPbROP_Packed == pbRop)
{
WriteKey(Int2Type(), label, Int2Type::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
void Write32bit( long obj, Int2Type label , Int2Type)
{
WriteKey(Int2Type(), label, Int2Type::Size>());
if (obj > 0)
{
WriteVarint32(obj);
}
else
{
WriteVarint64(obj);
}
}
template
void Write32bit( long obj, Int2Type label, Int2Type)
{
obj = ZIGZAG32(obj);
WriteKey(Int2Type(), label, Int2Type::Size>());
if (obj > 0)
{
WriteVarint32(obj);
}
else
{
WriteVarint64(obj);
}
}
template
void Write32bit( long obj, Int2Type label , Int2Type)
{
WriteKey(Int2Type(), label, Int2Type::Size>());
WriteInt(obj);
}
template
void Write32bit(unsigned long obj, Int2Type label, Int2Type)
{
WriteKey(Int2Type(), label, Int2Type::Size>());
WriteVarint32(obj);
}
template
void Write32bit(unsigned long obj, Int2Type label, Int2Type)
{
obj = ZIGZAG32(obj);
WriteKey(Int2Type(), label, Int2Type::Size>());
WriteVarint32(obj);
}
template
void Write32bit(unsigned long obj, Int2Type label , Int2Type)
{
WriteKey(Int2Type(), label, Int2Type::Size>());
WriteInt(obj);
}
template
void Write64bit( long long obj, Int2Type label , Int2Type )
{
WriteKey(Int2Type(), label, Int2Type::Size>());
WriteVarint64(obj);
}
template
void Write64bit( long long obj, Int2Type label , Int2Type )
{
obj = ZIGZAG64(obj);
WriteKey(Int2Type(), label, Int2Type::Size>());
WriteVarint64(obj);
}
template
void Write64bit( long long obj, Int2Type label , Int2Type )
{
WriteKey(Int2Type(), label, Int2Type::Size>());
WriteInt64(obj);
}
template
void Write64bit(unsigned long long obj, Int2Type label, Int2Type)
{
WriteKey(Int2Type(), label, Int2Type::Size>());
WriteVarint64(obj);
}
template
void Write64bit(unsigned long long obj, Int2Type label , Int2Type)
{
obj = ZIGZAG64(obj);
WriteKey(Int2Type(), label, Int2Type::Size>());
WriteVarint64(obj);
}
template
void Write64bit(unsigned long long obj, Int2Type label , Int2Type )
{
WriteKey(Int2Type() , label,Int2Type