通信编码解码 c11 实现 [ lua 专用版]
阅读原文时间:2023年07月10日阅读:1

#include
#include
#include
#include
#include
#include
#include "cocos2d.h"
#include

#define ENCODE_LUA_API 1

#ifndef LUA

define LUA

#endif

#if defined(LUA) && (ENCODE_LUA_API > 0)

define NEED_DEFINE_ENCODE_LUA_API

#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 //
#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 STRING_MAP;
#define STRING_MAP_PAIR(k,v) pair(k,v)
STRING_MAP TYPE_SHORT_STRING_MAP = {
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
};

STRING_MAP TYPE_SHORT_STRING_MAP2 = {
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
STRING_MAP_PAIR(, ),
};

//=======================================end optimize =========================================

class StreamBuf4Encodeing;
namespace LuaArray {

enum Type {  
    STRING,  

// NUMBER,
INT,
BOOLEAN,
};

class LuaArrayItem {  
    friend class StreamBuf4Encodeing;

public:  
    virtual ~LuaArrayItem(){

    };

    virtual Type getType() const = ;

};

// 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

private:
char *buffer;
size_t capacity;
size_t pos ;
size_t size;
public:
StreamBuf4Encodeing():buffer(nullptr),
capacity(),
pos(),
size()
{
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 = ;  
    capacity = ;  
}

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(luaArrayItem);
int num = numItr->getValue();
this->_write_int((int)(num));
break;
}
case LuaArray::Type::STRING : {
LuaArray::LuaArrayItemString *strItr =
dynamic_cast(luaArrayItem);
std::string str = strItr->getValue();
this->Write_str(str);
break;
}
case LuaArray::Type::BOOLEAN :{
LuaArray::LuaArrayItemBoolean *boolItr =
dynamic_cast(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 / ){  
        char \* rawBuf = this->buffer;  
        char \* newbuf = (char\*)malloc(cap);  
        this->buffer = newbuf;  
        memcpy(this->buffer,rawBuf,cap); //会导致数据丢失  
        this->size = cap;  
        this->pos = cap - ;  
        free(rawBuf);  
    }  
}

inline StreamBuf4Encodeing& \_write\_chars(char\* c,size\_t len) {  
    while(this->capacity < this->pos + len ){  
        this->remalloc(this->capacity \* );  
    }  
    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,);  
    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(){
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[];
};

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 ;  
        delete \*array;  
        \*array = nullptr;  
    }  
    return ;  
};

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(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(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(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 -;  
    }

    lua\_pushnil(L);

    StreamBuf4Encodeing tencode;  
    int len =  ;  
    while (lua\_next(L, top) != ) {  
        cio2\_encode\_val(L, -, tencode); //key  
        cio2\_encode\_val(L, -, tencode); //value  
        len++;  
        lua\_pop(L, ); //clean processed.  
    }  
    encode.Write\_table(tencode, len);  
    return ;  
};

static int cio\_encode(lua\_State \*L) {  
    int RET\_ARG\_LEN = ;  
    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 !=){  
        luaL\_error(L, "%s","decode table fail by cio\_encode.");  
        return -;  
    }else {  
        std::string str = ecode.toString();  
        lua\_pushlstring(L, str.c\_str(), str.length());  
        return RET\_ARG\_LEN;  
    }  
    return ;  
}

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 ;  
    }

    lua\_pushnil(L);

    LuaArray::LuaArray \*array = new LuaArray::LuaArray();

    while (lua\_next(L, top) != ) {  
        int valtype = lua\_type(L,-);  
        switch(valtype){  
            case LUA\_TNUMBER:  
            {  
                lua\_Number num = lua\_tonumber(L, -);  
                LuaArray::LuaArrayItemINT \*udNum = new LuaArray::LuaArrayItemINT(num);  
                array->getList(). push\_back(udNum);  
                break;  
            }

            case LUA\_TSTRING:  
            {  
                const char\* str = lua\_tostring(L, -);  
                LuaArray::LuaArrayItemString \*udStr = new LuaArray::LuaArrayItemString(str);  
                array->getList().push\_back(udStr);  
                break;  
            }

            case LUA\_TBOOLEAN:  
            {  
                int num = lua\_toboolean(L, -);  
                LuaArray::LuaArrayItemBoolean \*udBool = new LuaArray::LuaArrayItemBoolean(num);  
                array->getList().push\_back(udBool);  
                break;  
            }  
        }

        lua\_pop(L, ); //clean processed.  
    }

    lua\_pushnumber(L, );

    //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, -);

    return ;  
}

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, );break;
case CIO_TYPE_TRUE : lua_pushboolean(L, );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 ;  
};

static int cio\_decode\_array(lua\_State \*L,StreamBuf4Dencodeing& decoder,unsigned char type){  
    int len = decoder.readInt();  
    lua\_newtable(L);

    for( int i =  ;i <= len; i++) {  
        lua\_pushnumber(L, i);       //key  
        cio\_decode\_val(L,decoder);  //value  
        lua\_settable(L, -);  
    }  
    return ;

};

static int cio\_decode\_list(lua\_State \*L,StreamBuf4Dencodeing& decoder){  
    int len = decoder.readInt();  
    lua\_newtable(L);  
    for( int i =  ;i <= len; i++) {  
        lua\_pushnumber(L, i);       //key  
        cio\_decode\_val(L,decoder);  //value  
        lua\_settable(L, -);  
    }  
    return ;

};

static int i = ;  
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, -);  
        len --;  
    }  
    return ;  
};

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 -;  
    }

    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 -;  
    }  
    int len = decoder.readInt();  
    int ret = cio\_decode\_table(L, decoder,len);  
    if(ret == ){  
        int processBuferLen = decoder.getPos();  
        lua\_pushnumber(L, processBuferLen); //已处理的长度  
        return ;  
    }  
    else luaL\_error(L,"%s", "decode error!");  
    return ;  
}  

}

#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, -);  
lua\_setfield(L, -, "\_\_index");  
lua\_pushcfunction(L, \_\_gcReleaseLuaArray);  
lua\_setfield(L,-,"\_\_gc");  
luaL\_register(L, "LuaArray", cio2\_lua\_array);

return ;  

};

#endif