protobuf for lua 实现

先上代码:


#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 []
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值