先上代码:
#ifndef _UNIL_H_
#define _UNIL_H_
#include <sstream>
#include <string>
#include<cstring>
#include <iostream>
#include "error.h"
using namespace std;
#define BYTE_LEN 8
#define SHORT_LEN 2
#define PROTO_BIG_ENDIAN
//#define PROTO_LITTLE_ENDIAN
namespace unil{
typedef signed char int8;
typedef short int16;
typedef int int32;
typedef long long int64;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long long uint64;
union Data
{
int16 shortData;
uint8 charData[2];
};
inline void Short2Bit(int16 data, uint8 *buf)
{
#ifdef LITTLE_ENDIAN
#ifdef PROTO_LITTLE_ENDIAN
memcpy(buf, &data, SHORT_LEN);
#else
buf[0] = data >> BYTE_LEN;
buf[1] = data;
#endif
#else
#ifdef PROTO_LITTLE_ENDIAN
buf[0] = data >> BYTE_LEN;
buf[1] = data;
#else
memcpy(buf, &data, SHORT_LEN);
#endif
#endif
}
inline int Bit2Short(const uint8* buff, uint32 beg, uint32 len, int16& outLen)
{
if(NULL == buff || len < SHORT_LEN)
return ERROR::ERROR_BIT2SHORT;
Data d;
#ifdef LITTLE_ENDIAN
#ifdef PROTO_LITTLE_ENDIAN
d.charData[0] = buff[beg];
d.charData[1] = buff[beg+1];
#else
d.charData[1] = buff[beg];
d.charData[0] = buff[beg+1];
#endif
#else
#ifdef PROTO_LITTLE_ENDIAN
d.charData[1] = buff[beg];
d.charData[0] = buff[beg+1];
#else
d.charData[0] = buff[beg];
d.charData[1] = buff[beg+1];
#endif
#endif
outLen = d.shortData;
return ERROR::SUCCESS_UNIL;
}
inline int String2Int(const string& str)
{
int number;
std::stringstream stream;
stream << str;
stream >> number;
return number;
}
inline string Int2String(uint32 data)
{
stringstream ss;
ss << data;
string result = ss.str();
return result;
}
};
#endif
#ifndef _PROTO_CPP_H_
#define _PROTO_CPP_H_
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#include <iostream>
#include <string>
#include "error.h"
#include "unil.h"
using namespace unil;
using namespace std;
using namespace google;
using namespace google::protobuf;
typedef unsigned int uint;
typedef short int sint;
class Proto{
public:
static Proto* getInstance();
ERROR pack(lua_State* L);
ERROR unpack(lua_State* L);
bool hasRes(const string& typeName);
ERROR setProto(const string& packFile,const string& unpackFile);
~Proto();
private:
ERROR packHeader(int &outType, lua_State* L,uint8 *&packBuf,uint &packBufLen);
ERROR packContent(int type, lua_State* L, uint8 *&packBuf,uint &packBufLen);
void pack(Message* message, const FieldDescriptor* pFieldDescriptor, lua_State* L);
ERROR unpackHeader(const uint8* buff, uint32 length, lua_State* L, int& outType, int& session,int& timestamp);
ERROR unpackContent(int type, int session, int timestamp,const uint8* buff, uint32 length, lua_State* L);
void unpack(const Message& message, lua_State* L);
void getValue(
const Reflection* reflection,
const FieldDescriptor* pFieldDescriptor,
const Message& message,
lua_State* L,
int index = 0
);
void setValue(
const Reflection* reflection,
const FieldDescriptor* pFieldDescriptor,
Message *message,
lua_State* L
);
void merage(uint8* des, uint8* src, uint beg, uint len);
const void* getBuffer(lua_State *L, int index, size_t *sz);
static Proto* instance;
string unpackProtoFileName;
string packProtoFileName;
const string headerProtoFileName;
private:
explicit Proto();
Proto(const Proto&){}
};
#endif
#include "pb.h"
#include "error.h"
#include <google/protobuf/dynamic_message.h>
#include <iostream>
#include <iomanip>
Proto* Proto::instance = nullptr;
Proto::Proto():
headerProtoFileName("protohead.proto")
{
}
Proto* Proto::getInstance()
{
if(nullptr == instance)
{
instance = new Proto();
}
return instance;
}
Proto::~Proto()
{
}
void Proto::merage(uint8* des, uint8* src, uint beg, uint len)
{
if(nullptr == des || nullptr == src)
return;
for(uint i = 0;i < len; ++i)
des[beg+i] = src[i];
}
ERROR Proto::setProto(const string& packFile,const string& unpackFile)
{
packProtoFileName = packFile;
unpackProtoFileName = unpackFile;
const FileDescriptor *packfileDescriptor = DescriptorPool::generated_pool()->FindFileByName(packProtoFileName);
if(nullptr == packfileDescriptor)
{
return ERROR::ERROR_PACK_FILE;
}
const FileDescriptor *unpackfileDescriptor = DescriptorPool::generated_pool()->FindFileByName(unpackProtoFileName);
if(nullptr == unpackfileDescriptor)
{
return ERROR::ERROR_UNPACK_FILE;
}
return ERROR_NONE;
}
ERROR Proto::pack(lua_State* L)
{
ERROR error = ERROR::SUCCESS_PACK;
int type = -1;
uint8* headerBuf = nullptr;
uint headerBufLen = 0;
error = packHeader(type, L, headerBuf, headerBufLen);
if(ERROR::SUCCESS_PACK != error)
{
return error;
}
uint8* contentBuf = nullptr;
uint contentBufLen = 0;
error = packContent(type, L, contentBuf, contentBufLen);
if(ERROR::SUCCESS_PACK != error)
{
return error;
}
uint8 headerLenBuf[HEADER_LEN] = {0};
uint8 contentLenBuf[CONTENT_LEN] = {0};
Short2Bit(headerBufLen, headerLenBuf);
Short2Bit(contentBufLen, contentLenBuf);
uint totalBufLen = headerBufLen + contentBufLen + HEADER_LEN + CONTENT_LEN;
uint8 *packBuf = new uint8 [totalBufLen];
merage(packBuf,headerLenBuf,0,HEADER_LEN);
merage(packBuf,headerBuf, HEADER_LEN, headerBufLen);
merage(packBuf,contentLenBuf, HEADER_LEN + headerBufLen, CONTENT_LEN);
merage(packBuf,contentBuf, HEADER_LEN + CONTENT_LEN + headerBufLen, contentBufLen);
lua_settop(L,0);
lua_pushlstring(L, (const char *)packBuf, totalBufLen);
delete []headerBuf;
delete []