在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
#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; |
请发表评论