zoukankan      html  css  js  c++  java
  • 通信编码解码 c11 实现 [ lua 专用版]

    #include <istream>
    #include <ostream>
    #include <iostream>
    #include <strstream>
    #include <list>
    #include <map>
    #include "cocos2d.h"
    #include <math.h>
    
    #define ENCODE_LUA_API 1
    
    #ifndef LUA
    #   define LUA
    #endif
    
    #if defined(LUA) && (ENCODE_LUA_API > 0)
    #   define NEED_DEFINE_ENCODE_LUA_API 1
    #endif
    
    extern "C" {
    #   include "lua.h"
    #   include "lauxlib.h"
    }
    
    int CIO2_Lua_Open(lua_State *state);
    
    using namespace std;
    using namespace cocos2d;
    
    
    //========================================= optimize =========================================
    char* nil = new char(0x00); //memory leaks.
    
    #define CIO_TYPE_NIL                0x7f //127
    #define CIO_TYPE_FALSE              0x00
    #define CIO_TYPE_TRUE               0x01
    #define CIO_TYPE_INT                0x04
    #define CIO_TYPE_STRING             0x05
    #define CIO_TYPE_CSTR               0x06
    #define CIO_TYPE_WSTR               0x07
    #define CIO_TYPE_TABLE              0x08
    #define CIO_TYPE_BYTES              0x09
    #define CIO_TYPE_LONG               0x0a
    #define CIO_TYPE_TIME               0x0b  //long (2000-01-01 00:00:00)
    #define CIO_TYPE_LIST               0x0c
    #define CIO_TYPE_INTEGER_ARRAY      0x0d
    #define CIO_TYPE_STRING_ARRAY       0x0e
    #define CIO_TYPE_DOUBLE             0x0f
    
    typedef std::map<char,char> STRING_MAP;
    #define STRING_MAP_PAIR(k,v) pair<char, char>(k,v)
    STRING_MAP TYPE_SHORT_STRING_MAP = {
        STRING_MAP_PAIR(50, 0),
        STRING_MAP_PAIR(51, 1),
        STRING_MAP_PAIR(52, 2),
        STRING_MAP_PAIR(53, 3),
        STRING_MAP_PAIR(54, 4),
        STRING_MAP_PAIR(55, 5),
        STRING_MAP_PAIR(56, 6),
        STRING_MAP_PAIR(57, 7),
        STRING_MAP_PAIR(58, 8),
        STRING_MAP_PAIR(59, 9),
        STRING_MAP_PAIR(60, 10),
        STRING_MAP_PAIR(61, 11),
        STRING_MAP_PAIR(62, 12),
        STRING_MAP_PAIR(63, 13),
        STRING_MAP_PAIR(64, 14),
        STRING_MAP_PAIR(65, 15),
        STRING_MAP_PAIR(66, 16),
        STRING_MAP_PAIR(67, 17),
        STRING_MAP_PAIR(68, 18),
        STRING_MAP_PAIR(69, 19),
        STRING_MAP_PAIR(70, 20),
        STRING_MAP_PAIR(71, 21),
        STRING_MAP_PAIR(72, 22),
        STRING_MAP_PAIR(73, 23),
        STRING_MAP_PAIR(74, 24),
        STRING_MAP_PAIR(75, 25),
        STRING_MAP_PAIR(76, 32),
    };
    
    STRING_MAP TYPE_SHORT_STRING_MAP2 = {
        STRING_MAP_PAIR(0, 50),
        STRING_MAP_PAIR(1, 51),
        STRING_MAP_PAIR(2, 52),
        STRING_MAP_PAIR(3, 53),
        STRING_MAP_PAIR(4, 54),
        STRING_MAP_PAIR(5, 55),
        STRING_MAP_PAIR(6, 56),
        STRING_MAP_PAIR(7, 57),
        STRING_MAP_PAIR(8, 58),
        STRING_MAP_PAIR(9, 59),
        STRING_MAP_PAIR(10, 60),
        STRING_MAP_PAIR(11, 61),
        STRING_MAP_PAIR(12, 62),
        STRING_MAP_PAIR(13, 63),
        STRING_MAP_PAIR(14, 64),
        STRING_MAP_PAIR(15, 65),
        STRING_MAP_PAIR(16, 66),
        STRING_MAP_PAIR(17, 67),
        STRING_MAP_PAIR(18, 68),
        STRING_MAP_PAIR(19, 69),
        STRING_MAP_PAIR(20, 70),
        STRING_MAP_PAIR(21, 71),
        STRING_MAP_PAIR(22, 72),
        STRING_MAP_PAIR(23, 73),
        STRING_MAP_PAIR(24, 74),
        STRING_MAP_PAIR(25, 75),
        STRING_MAP_PAIR(32, 76),
    };
    
    //=======================================end optimize =========================================
    
    class StreamBuf4Encodeing;
    namespace LuaArray {
        
        enum Type {
            STRING,
    //        NUMBER,
            INT,
            BOOLEAN,
        };
        
        class LuaArrayItem {
            friend class StreamBuf4Encodeing;
            
        public:
            virtual ~LuaArrayItem(){
                
            };
            
            virtual Type getType() const = 0;
            
        };
        
    //    class LuaArrayItemNumber : virtual public LuaArrayItem{
    //    private:
    //        lua_Number val;
    //    public:
    //        LuaArrayItemNumber(lua_Number val):val(val) { };
    //        virtual Type getType() const override { return Type::NUMBER;  };
    //        inline lua_Number getValue() const{   return this->val; };
    //    };
        
        class LuaArrayItemINT : virtual public LuaArrayItem{
        private:
            int val;
        public:
            LuaArrayItemINT(int val):val(val) { };
            virtual Type getType() const override { return Type::INT;  };
            inline int getValue() const{   return this->val; };
        };
        
        class LuaArrayItemString : virtual public LuaArrayItem{
        private:
            std::string val;
        public:
            LuaArrayItemString(std::string _val):val(_val) { };
            virtual Type getType() const override {  return Type::STRING; };
            inline std::string getValue() const{  return this->val;  };
        };
        
        class LuaArrayItemBoolean : virtual public LuaArrayItem{
        private:
            bool val;
        public:
            LuaArrayItemBoolean(bool val):val(val) { };
            virtual Type getType() const override {  return Type::BOOLEAN;  };
            inline bool getValue(){ return this->val; };
        };
        
        class LuaArray{
        private:
            std::list<LuaArrayItem*> _list;
        public:
            ~LuaArray(){
                for(auto &itr:_list){
                    delete itr;
                }
                _list.clear();
            };
            
            inline std::list<LuaArrayItem*>& getList(){
                return this->_list;
            };
        };
    }
    
    class StreamBuf4Encodeing {
    #   define DEFAULT_BUFFER_CAPACITY 2048
    private:
        char *buffer;
        size_t capacity;
        size_t pos ;
        size_t size;
    public:
        StreamBuf4Encodeing():buffer(nullptr),
        capacity(0),
        pos(0),
        size(0)
        {
            capacity = DEFAULT_BUFFER_CAPACITY;
            buffer = (char*)malloc(capacity);
        };
        
        StreamBuf4Encodeing(char * c,int n){
            new (this)StreamBuf4Encodeing();
            if(DEFAULT_BUFFER_CAPACITY < n ){
                if (buffer) free(buffer);
                capacity = DEFAULT_BUFFER_CAPACITY;
                buffer = (char*)malloc(capacity);
            }
            memcpy(buffer, c, n);
            size = n;
        };
        
        virtual ~StreamBuf4Encodeing(void) {
            free(buffer);
            size = 0;
            capacity = 0;
        }
        
        virtual std::string toString(){
            return std::string(buffer,size);
        }
        
    private:
        StreamBuf4Encodeing& operator << (LuaArray::LuaArrayItem * luaArrayItem){
            auto type = luaArrayItem->getType();
            switch (type) {
                case LuaArray::Type::INT : {
                    LuaArray::LuaArrayItemINT *numItr =
                                dynamic_cast<LuaArray::LuaArrayItemINT*>(luaArrayItem);
                    int num = numItr->getValue();
                    this->_write_int((int)(num));
                    break;
                }
                case LuaArray::Type::STRING : {
                    LuaArray::LuaArrayItemString *strItr =
                    dynamic_cast<LuaArray::LuaArrayItemString*>(luaArrayItem);
                    std::string str = strItr->getValue();
                    this->Write_str(str);
                    break;
                }
                case LuaArray::Type::BOOLEAN :{
                    LuaArray::LuaArrayItemBoolean *boolItr =
                    dynamic_cast<LuaArray::LuaArrayItemBoolean*>(luaArrayItem);
                    bool b = boolItr->getValue();
                    if(b) this->Write_true();
                    else this->Write_false();
                    break;
                }
                default:
                    break;
            }
            return *this;
        };
        
        inline StreamBuf4Encodeing& _write_type_head(unsigned char val) {
            return this->_write_char(val);
        };
        
        inline void remalloc(size_t cap){
            if(cap > this->size){
                char * rawBuf = this->buffer;
                char * newbuf = (char*)malloc(cap);
                this->buffer = newbuf;
                memcpy(this->buffer,rawBuf,this->size);
                free(rawBuf);
            }else if(cap < this->size / 2){
                char * rawBuf = this->buffer;
                char * newbuf = (char*)malloc(cap);
                this->buffer = newbuf;
                memcpy(this->buffer,rawBuf,cap); //会导致数据丢失
                this->size = cap;
                this->pos = cap - 1;
                free(rawBuf);
            }
        }
        
        inline StreamBuf4Encodeing& _write_chars(char* c,size_t len) {
            while(this->capacity < this->pos + len ){
                this->remalloc(this->capacity * 2);
            }
            memcpy((this->buffer + pos),c, len);
            pos+= len;
            size += len;
            return *this;
        }
        
        inline StreamBuf4Encodeing& _write_char(unsigned char val){
            char c;
            c = val;
            this->_write_chars(&c,1);
            return *this;
        };
        
        inline StreamBuf4Encodeing& _write_str(char *c,size_t len){
            this->_write_chars(c,len);
            return *this;
        };
        
        inline StreamBuf4Encodeing& _write_int(int i){
            char *c = (char*)(&i);
            this->_write_chars(c, sizeof(int));
            return *this;
        };
        
        inline StreamBuf4Encodeing& _write_str(const char *c,size_t len){
            char * vc = (char*)c;
            return this->_write_str(vc,len);
        };
        
    public:
        
        inline StreamBuf4Encodeing& Write_str(std::string val){
            int len =(int) val.length();
            if( TYPE_SHORT_STRING_MAP2.find(len) != TYPE_SHORT_STRING_MAP2.end()) {
                char tlen = TYPE_SHORT_STRING_MAP2[len];
                this->_write_char(tlen);
            }else {
                this->_write_type_head(CIO_TYPE_STRING);
                this->_write_int(len);
            }
            
            return this->_write_str(val.c_str(),val.length());
        };
        
        inline StreamBuf4Encodeing& Write_number(lua_Number val){
            if(floor(val) == val) {
                int v = (int)val;
                char * c = (char*) (&v);
                this->_write_type_head(CIO_TYPE_INT);
                this->_write_chars(c,sizeof(int));
            }else {
                this->_write_type_head(CIO_TYPE_DOUBLE);
                char * c = (char*) (&val);
                this->_write_chars(c, sizeof(lua_Number));
            }
            return *this;
        };
        
        inline StreamBuf4Encodeing& Write_false(){  return this ->_write_char(CIO_TYPE_FALSE); };
        
        inline StreamBuf4Encodeing& Write_true(){  return this ->_write_char(CIO_TYPE_TRUE); };
        
        inline StreamBuf4Encodeing& Write_nil(){  return this ->_write_char(CIO_TYPE_NIL); };
        
        inline StreamBuf4Encodeing& Write_int(int val){
            this->_write_type_head(CIO_TYPE_INT);
            return this->_write_int(val);
        };
        
        inline StreamBuf4Encodeing& Write_table(StreamBuf4Encodeing & encode,size_t len){
            this->_write_type_head(CIO_TYPE_TABLE);
            this->_write_int((int)len);
            std::string str = encode.toString();
            this ->_write_str(str.c_str(),str.length());
            return (*this) ;
        };
        
        
        inline StreamBuf4Encodeing& Write_int_array(StreamBuf4Encodeing & encode,size_t len){
            this->_write_type_head(CIO_TYPE_INTEGER_ARRAY);
            this->_write_int((int)len);
            std::string str = encode.toString();
            this ->_write_str(str.c_str(),str.length());
            return (*this);
        };
        
        inline StreamBuf4Encodeing& Write_string_array(StreamBuf4Encodeing & encode,size_t len){
            this->_write_type_head(CIO_TYPE_STRING_ARRAY);
            this->_write_int((int)len);
            std::string str = encode.toString();
            this ->_write_str(str.c_str(),str.length());
            return (*this);
        };
    };
    
    class StreamBuf4Dencodeing{
    private:
        char * buffer;
        int pos;
        int size;
    public:
        StreamBuf4Dencodeing(char* c,int n):size(n),pos(0){
            buffer = (char*)malloc(n);
            memcpy(buffer, c, n);
        };
        
        ~StreamBuf4Dencodeing(void){
            free(buffer);
        };
        
        unsigned char readChar() {
            char* ptr = buffer + pos;
    //        if(pos >40){
    //            char *temptr = buffer + pos - 40;
    //            int  i = 0;
    //        }
            pos++;
            return ptr[0];
        };
        
        void readStr(char* _buf,int len) {
            memcpy(_buf,buffer+pos,len);
            pos+= len;
        }
        
    public:
        
        int getPos() const {
            return this->pos;
        };
        
        bool eof(){
            return pos >= size;
        }
        
        unsigned char readType(){
            return this->readChar();
        }
        
        lua_Number readNum() {
            lua_Number num;
            char * c = (char*)(&num);
            this->readStr(c,sizeof(lua_Number));
            return num;
        };
        
        int readInt() {
            int num;
            char * c = (char*)(&num);
            this->readStr(c,sizeof(int));
            return num;
        };
        
        void moveCursor(int n){
            this->pos += n;
        }
        
        bool readBoolean() {
            return this->readChar();
        };
        //有bug.还会导致逻辑混乱。
    //    std::string readString() {
    //        
    //        char tlen = this->readChar();
    //        this->moveCursor(-1);//不能影响游标,只是用来做检测,确定是进入什么逻辑
    //        
    //        int len = 0;
    //        if(TYPE_SHORT_STRING_MAP.find(tlen) != TYPE_SHORT_STRING_MAP.end()) {
    //            char tlen = this->readChar();
    //            len = TYPE_SHORT_STRING_MAP[tlen];
    //        }else {
    //            len = this->readInt();
    //        }
    //        return this->readString(len);
    //    };
        
        std::string readString(int len) {
            char *c = (char*)malloc(len);
            this->readStr(c,len);
            std::string str(c,len);
            free(c);
            return str;
        };
    };
    
    extern "C" {
        
        static int      cio2_encode_table(lua_State *L, StreamBuf4Encodeing &encode) ;
        static void     cio2_encode_val(lua_State *L,int stackIdx, StreamBuf4Encodeing &encode);
        static int      cio_decode_array(lua_State *L,StreamBuf4Dencodeing& decoder,unsigned char type);
        static int      cio_decode_list(lua_State *L,StreamBuf4Dencodeing& decoder);
        static int      cio_decode_table(lua_State *L ,StreamBuf4Dencodeing& decoder,size_t len);
        static int      __gcReleaseLuaArray(lua_State *L);
        
        static int __gcReleaseLuaArray(lua_State* L) {
            int top = lua_gettop(L);
            int t = lua_type(L,top);
            if(t == LUA_TUSERDATA ) {
                void * ud = lua_touserdata(L, top);
                LuaArray::LuaArray **array = (LuaArray::LuaArray**)(ud);
                if(*array == nullptr) return 0;
                delete *array;
                *array = nullptr;
            }
            return 0;
        };
        
        
        static void cio2_encode_val(lua_State *L,int stackIdx, StreamBuf4Encodeing &encode){
            int nodeType = lua_type(L, stackIdx);
            switch (nodeType) {
                case LUA_TNUMBER:
                {
                    encode.Write_number(lua_tonumber(L, stackIdx));
                    break;
                }
                    
                case LUA_TSTRING:
                {
                    encode.Write_str(lua_tostring(L, stackIdx));
                    break;
                }
                    
                case LUA_TTABLE:
                {
                    cio2_encode_table(L,encode);
                    break;
                }
                    
                case LUA_TBOOLEAN:{
                    int _bool = lua_toboolean(L, stackIdx);
                    if(_bool) encode.Write_true();
                    else encode.Write_false();
                    break;
                }
                    
                case LUA_TUSERDATA:
                {
                    StreamBuf4Encodeing tencode;
                    LuaArray::LuaArray **array = (LuaArray::LuaArray**)lua_touserdata(L, stackIdx);
                    
                    char type = 0x00;
                    for(auto &itr: (*array)->getList()) {
                        switch(itr->getType()){
                            case LuaArray::Type::BOOLEAN: {
    //                            
    //                            LuaArray::LuaArrayItem *arrayItr = &(*itr);
    //                            LuaArray::LuaArrayItemBoolean *_bool = dynamic_cast<LuaArray::LuaArrayItemBoolean*>(arrayItr) ;
    //                            if(_bool->getValue()==true)  tencode.Write_true();
    //                            else tencode.Write_false();
                                printf("%s","不支持boolean 数组的解码!");
                                break;
                            }
                            case LuaArray::Type::INT : {
                                LuaArray::LuaArrayItem *arrayItr = &(*itr);
                                LuaArray::LuaArrayItemINT *num = dynamic_cast<LuaArray::LuaArrayItemINT*>(arrayItr) ;
                                tencode.Write_int(num->getValue());
                                type = CIO_TYPE_INTEGER_ARRAY;
                                break;
                            }
                            case LuaArray::Type::STRING :{
                                LuaArray::LuaArrayItem *arrayItr = &(*itr);
                                LuaArray::LuaArrayItemString *str = dynamic_cast<LuaArray::LuaArrayItemString*>(arrayItr) ;
                                tencode.Write_str(str->getValue());
                                type = CIO_TYPE_STRING_ARRAY;
                                break;
                            }
                        }
                    }
                    
                    //write to buffer;
                    switch(type){
                        case CIO_TYPE_INTEGER_ARRAY:{
                            encode.Write_int_array(tencode, (*array)->getList().size());
                            break;
                        }
                        case CIO_TYPE_STRING_ARRAY:{
                            encode.Write_string_array(tencode, (*array)->getList().size());
                            break;
                        }
                    }
                }
                default:
                    break;
            }
        }
        
        static int cio2_encode_table(lua_State *L, StreamBuf4Encodeing &encode) {
    
            int top = lua_gettop(L);
            int type = lua_type(L, top);
            
            if(type != LUA_TTABLE) {
                luaL_error(L,"%s","arg must a table.");
                return -1;
            }
            
            lua_pushnil(L);
            
            StreamBuf4Encodeing tencode;
            int len = 0 ;
            while (lua_next(L, top) != 0) {
                cio2_encode_val(L, -2, tencode); //key
                cio2_encode_val(L, -1, tencode); //value
                len++;
                lua_pop(L, 1); //clean processed.
            }
            encode.Write_table(tencode, len);
            return 0;
        };
        
        static int cio_encode(lua_State *L) {
            int RET_ARG_LEN = 1;
            int top = lua_gettop(L);
            int t = lua_type(L, top);
            if(t !=  LUA_TTABLE){
                luaL_error(L, "%s","argment must a table  when call "by cio_encode"");
                return RET_ARG_LEN;
            }
            StreamBuf4Encodeing ecode;
            int ret = cio2_encode_table(L, ecode);
            if(ret !=0){
                luaL_error(L, "%s","decode table fail by cio_encode.");
                return -1;
            }else {
                std::string str = ecode.toString();
                lua_pushlstring(L, str.c_str(), str.length());
                return RET_ARG_LEN;
            }
            return 0;
        }
    
        
        static int cio_table_toarray(lua_State *L) {
            
            int top = lua_gettop(L);
            int type =lua_type(L, top);
            
            if(type != LUA_TTABLE ) {
                luaL_error(L, "%s","arguments  must a table");
                return 0;
            }
            
            lua_pushnil(L);
            
            LuaArray::LuaArray *array = new LuaArray::LuaArray();
            
            while (lua_next(L, top) != 0) {
                int valtype = lua_type(L,-1);
                switch(valtype){
                    case LUA_TNUMBER:
                    {
                        lua_Number num = lua_tonumber(L, -1);
                        LuaArray::LuaArrayItemINT *udNum = new LuaArray::LuaArrayItemINT(num);
                        array->getList(). push_back(udNum);
                        break;
                    }
                        
                    case LUA_TSTRING:
                    {
                        const char* str = lua_tostring(L, -1);
                        LuaArray::LuaArrayItemString *udStr = new LuaArray::LuaArrayItemString(str);
                        array->getList().push_back(udStr);
                        break;
                    }
                        
                    case LUA_TBOOLEAN:
                    {
                        int num = lua_toboolean(L, -1);
                        LuaArray::LuaArrayItemBoolean *udBool = new LuaArray::LuaArrayItemBoolean(num);
                        array->getList().push_back(udBool);
                        break;
                    }
                }
    
                lua_pop(L, 1); //clean processed.
            }
    
            lua_pushnumber(L, 0);
            
            //new userdata.
            LuaArray::LuaArray ** array_userdata = (LuaArray::LuaArray **)lua_newuserdata(L, sizeof(LuaArray::LuaArray*));
            *array_userdata = array;
            //bing metatable
            luaL_getmetatable(L, "LuaArray");
            lua_setmetatable(L, -2);
            
            return 1;
        }
        
        
        static int cio_decode_val(lua_State* L,StreamBuf4Dencodeing& decoder){
            unsigned char type = decoder.readType();
            
            //优化操作
            if(TYPE_SHORT_STRING_MAP.find(type)!= TYPE_SHORT_STRING_MAP.end()){
                int len = TYPE_SHORT_STRING_MAP[type];
                std::string str = decoder.readString(len);
                lua_pushlstring(L, str.c_str(), len);
            }else{
    //            printf("--------%c",type);
                switch (type) {
                    case CIO_TYPE_NIL               : lua_pushnil(L); break;
                    case CIO_TYPE_FALSE             : lua_pushboolean(L, 0);break;
                    case CIO_TYPE_TRUE              : lua_pushboolean(L, 1);break;
                    case CIO_TYPE_INT               : lua_pushinteger(L, decoder.readInt()); break;
                    case CIO_TYPE_STRING            :
                    {
                        //std::string str = decoder.readString();
                        int len = decoder.readInt();
                        std::string str = decoder.readString(len);
                        lua_pushlstring(L, str.c_str(), str.length());
                        break;
                    }
                    case CIO_TYPE_CSTR              :break;
                    case CIO_TYPE_WSTR              :break;
                    case CIO_TYPE_TABLE             :{
                        //cio_decode_val(L,decoder);
                        int len = decoder.readInt();
    //                    decoder.moveCursor(-sizeof(int));
                        cio_decode_table(L,decoder,len);
                        break;
                    }
                    case CIO_TYPE_BYTES             :break;
                    case CIO_TYPE_LONG              :break;
                    case CIO_TYPE_TIME              :break;
                    
                    case CIO_TYPE_LIST              :
                    {
                        cio_decode_list(L,decoder);
                        break;
                    }
                    case CIO_TYPE_INTEGER_ARRAY     :
                    case CIO_TYPE_STRING_ARRAY      :
                    {
                        cio_decode_array(L,decoder,type);
                        break;
                    }
                    
                    case CIO_TYPE_DOUBLE            :  lua_pushnumber(L, decoder.readNum());break;
                    default:
                        break;
                }
            }
            return 0;
        };
        
        static int cio_decode_array(lua_State *L,StreamBuf4Dencodeing& decoder,unsigned char type){
            int len = decoder.readInt();
            lua_newtable(L);
            
            for( int i = 1 ;i <= len; i++) {
                lua_pushnumber(L, i);       //key
                cio_decode_val(L,decoder);  //value
                lua_settable(L, -3);
            }
            return 0;
            
        };
        
        static int cio_decode_list(lua_State *L,StreamBuf4Dencodeing& decoder){
            int len = decoder.readInt();
            lua_newtable(L);
            for( int i = 1 ;i <= len; i++) {
                lua_pushnumber(L, i);       //key
                cio_decode_val(L,decoder);  //value
                lua_settable(L, -3);
            }
            return 0;
            
        };
        
        static int i = 0;
        static int cio_decode_table(lua_State *L ,StreamBuf4Dencodeing& decoder,size_t len) {
            lua_newtable(L);
            while (!decoder.eof() && len) {
                cio_decode_val(L,decoder);       //key
                cio_decode_val(L,decoder);       //value
                lua_settable(L, -3);
                len --;
            }
            return 0;
        };
        
        static int cio_decode(lua_State *L) {
            int top = lua_gettop(L);
            int t = lua_type(L,top);
            
            if(t != LUA_TSTRING) {
                luaL_error(L,"%s","arg must string.");
                return -1;
            }
            
            size_t size;
            const char * c = lua_tolstring(L,top,&size);
            StreamBuf4Dencodeing decoder((char*)c,(int)size); //bug.长度丢失
            if(decoder.readType() != CIO_TYPE_TABLE ) {
                luaL_error(L, "%s","the encode is not encode from a lua table.");
                return -1;
            }
            int len = decoder.readInt();
            int ret = cio_decode_table(L, decoder,len);
            if(ret == 0){
                int processBuferLen = decoder.getPos();
                lua_pushnumber(L, processBuferLen); //已处理的长度
                return 2;
            }
            else luaL_error(L,"%s", "decode error!");
            return 1;
        }
    }
    
    #ifdef NEED_DEFINE_ENCODE_LUA_API
    
    int CIO2_Lua_Open(lua_State *L) {
        
        //register coi2 api
        const struct luaL_Reg cio2_libs [] = {
            {"Encode",cio_encode},
            {"Decode",cio_decode},
            {"ToArray",cio_table_toarray },
            {NULL,NULL}
        };
        
        luaL_register(L, "CIO2", cio2_libs);
        
        //register lua array metatable.
        const struct luaL_Reg cio2_lua_array [] = {
            {NULL,NULL}
        };
        //luaarray 元表
        luaL_newmetatable(L, "LuaArray");
        lua_pushvalue(L, -1);
        lua_setfield(L, -2, "__index");
        lua_pushcfunction(L, __gcReleaseLuaArray);
        lua_setfield(L,-2,"__gc");
        luaL_register(L, "LuaArray", cio2_lua_array);
        
        return 0;
    };
    
    #endif
  • 相关阅读:
    Mybatis Plus整合PageHelper分页的实现示例
    关于xlrd最新版本不支持.xlsx文件的解决办法
    mysql 错误解决大法 Specified key was too long; max key length is 767 bytes
    php连接redis
    flask通过request.path获取定义view函数的文件和行号
    使用bash内置命令complete来实现参数补全
    linux下对比两个文件夹下python文件的差异
    ssh登录后自动切换到原来的目录
    ssh &2>1 和重定向顺序问题
    wsl1(win10)中安装bochs
  • 原文地址:https://www.cnblogs.com/czjone/p/7753202.html
Copyright © 2011-2022 走看看