diff --git a/lualib-src/lua-seri.c b/lualib-src/lua-seri.c index c41456be..9b2af465 100644 --- a/lualib-src/lua-seri.c +++ b/lualib-src/lua-seri.c @@ -15,7 +15,14 @@ #define TYPE_BOOLEAN 1 // hibits 0 false 1 true #define TYPE_NUMBER 2 -// hibits 0 : 0 , 1: byte, 2:word, 4: dword, 8 : double +// hibits 0 : 0 , 1: byte, 2:word, 4: dword, 6: qword, 8 : double +#define TYPE_NUMBER_ZERO 0 +#define TYPE_NUMBER_BYTE 1 +#define TYPE_NUMBER_WORD 2 +#define TYPE_NUMBER_DWORD 4 +#define TYPE_NUMBER_QWORD 6 +#define TYPE_NUMBER_REAL 8 + #define TYPE_USERDATA 3 #define TYPE_SHORT_STRING 4 // hibits 0~31 : len @@ -107,7 +114,7 @@ rball_init(struct read_block * rb, char * buffer, int size) { } static void * -rb_read(struct read_block *rb, void *buffer, int sz) { +rb_read(struct read_block *rb, int sz) { if (rb->len < sz) { return NULL; } @@ -131,36 +138,44 @@ wb_boolean(struct write_block *wb, int boolean) { } static inline void -wb_integer(struct write_block *wb, int v, int type) { +wb_integer(struct write_block *wb, lua_Integer v) { + int type = TYPE_NUMBER; if (v == 0) { - uint8_t n = COMBINE_TYPE(type , 0); + uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_ZERO); wb_push(wb, &n, 1); - } else if (v<0) { - uint8_t n = COMBINE_TYPE(type , 4); + } else if (v != (int32_t)v) { + uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_QWORD); + int64_t v64 = v; wb_push(wb, &n, 1); - wb_push(wb, &v, 4); + wb_push(wb, &v64, sizeof(v64)); + } else if (v < 0) { + int32_t v32 = (int32_t)v; + uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_DWORD); + wb_push(wb, &n, 1); + wb_push(wb, &v32, sizeof(v32)); } else if (v<0x100) { - uint8_t n = COMBINE_TYPE(type , 1); + uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_BYTE); wb_push(wb, &n, 1); uint8_t byte = (uint8_t)v; - wb_push(wb, &byte, 1); + wb_push(wb, &byte, sizeof(byte)); } else if (v<0x10000) { - uint8_t n = COMBINE_TYPE(type , 2); + uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_WORD); wb_push(wb, &n, 1); uint16_t word = (uint16_t)v; - wb_push(wb, &word, 2); + wb_push(wb, &word, sizeof(word)); } else { - uint8_t n = COMBINE_TYPE(type , 4); + uint8_t n = COMBINE_TYPE(type , TYPE_NUMBER_DWORD); wb_push(wb, &n, 1); - wb_push(wb, &v, 4); + uint32_t v32 = (uint32_t)v; + wb_push(wb, &v32, sizeof(v32)); } } static inline void -wb_number(struct write_block *wb, double v) { - uint8_t n = COMBINE_TYPE(TYPE_NUMBER , 8); +wb_real(struct write_block *wb, double v) { + uint8_t n = COMBINE_TYPE(TYPE_NUMBER , TYPE_NUMBER_REAL); wb_push(wb, &n, 1); - wb_push(wb, &v, 8); + wb_push(wb, &v, sizeof(v)); } static inline void @@ -203,7 +218,7 @@ wb_table_array(lua_State *L, struct write_block * wb, int index, int depth) { if (array_size >= MAX_COOKIE-1) { uint8_t n = COMBINE_TYPE(TYPE_TABLE, MAX_COOKIE-1); wb_push(wb, &n, 1); - wb_integer(wb, array_size,TYPE_NUMBER); + wb_integer(wb, array_size); } else { uint8_t n = COMBINE_TYPE(TYPE_TABLE, array_size); wb_push(wb, &n, 1); @@ -224,11 +239,12 @@ wb_table_hash(lua_State *L, struct write_block * wb, int index, int depth, int a lua_pushnil(L); while (lua_next(L, index) != 0) { if (lua_type(L,-2) == LUA_TNUMBER) { - lua_Number k = lua_tonumber(L,-2); - int32_t x = (int32_t)lua_tointeger(L,-2); - if (k == (lua_Number)x && x>0 && x<=array_size) { - lua_pop(L,1); - continue; + if (lua_isinteger(L, -2)) { + lua_Integer x = lua_tointeger(L,-2); + if (x>0 && x<=array_size) { + lua_pop(L,1); + continue; + } } } pack_one(L,wb,-2,depth); @@ -259,12 +275,12 @@ pack_one(lua_State *L, struct write_block *b, int index, int depth) { wb_nil(b); break; case LUA_TNUMBER: { - int32_t x = (int32_t)lua_tointeger(L,index); - lua_Number n = lua_tonumber(L,index); - if ((lua_Number)x==n) { - wb_integer(b, x, TYPE_NUMBER); + if (lua_isinteger(L, index)) { + lua_Integer x = lua_tointeger(L,index); + wb_integer(b, x); } else { - wb_number(b,n); + lua_Number n = lua_tonumber(L,index); + wb_real(b,n); } break; } @@ -310,31 +326,42 @@ invalid_stream_line(lua_State *L, struct read_block *rb, int line) { #define invalid_stream(L,rb) invalid_stream_line(L,rb,__LINE__) -static int +static lua_Integer get_integer(lua_State *L, struct read_block *rb, int cookie) { switch (cookie) { - case 0: + case TYPE_NUMBER_ZERO: return 0; - case 1: { - uint8_t n = 0; - uint8_t * pn = rb_read(rb,&n,1); + case TYPE_NUMBER_BYTE: { + uint8_t n; + uint8_t * pn = rb_read(rb,sizeof(n)); if (pn == NULL) invalid_stream(L,rb); - return *pn; + n = *pn; + return n; } - case 2: { - uint16_t n = 0; - uint16_t * pn = rb_read(rb,&n,2); + case TYPE_NUMBER_WORD: { + uint16_t n; + uint16_t * pn = rb_read(rb,sizeof(n)); if (pn == NULL) invalid_stream(L,rb); - return *pn; + memcpy(&n, pn, sizeof(n)); + return n; } - case 4: { - int n = 0; - int * pn = rb_read(rb,&n,4); + case TYPE_NUMBER_DWORD: { + int32_t n; + int32_t * pn = rb_read(rb,sizeof(n)); if (pn == NULL) invalid_stream(L,rb); - return *pn; + memcpy(&n, pn, sizeof(n)); + return n; + } + case TYPE_NUMBER_QWORD: { + int64_t n; + int64_t * pn = rb_read(rb,sizeof(n)); + if (pn == NULL) + invalid_stream(L,rb); + memcpy(&n, pn, sizeof(n)); + return n; } default: invalid_stream(L,rb); @@ -343,32 +370,29 @@ get_integer(lua_State *L, struct read_block *rb, int cookie) { } static double -get_number(lua_State *L, struct read_block *rb, int cookie) { - if (cookie == 8) { - double n = 0; - double * pn = rb_read(rb,&n,8); - if (pn == NULL) - invalid_stream(L,rb); - return *pn; - } else { - return (double)get_integer(L,rb,cookie); - } +get_real(lua_State *L, struct read_block *rb) { + double n; + double * pn = rb_read(rb,sizeof(n)); + if (pn == NULL) + invalid_stream(L,rb); + memcpy(&n, pn, sizeof(n)); + return n; } static void * get_pointer(lua_State *L, struct read_block *rb) { void * userdata = 0; - void ** v = (void **)rb_read(rb,&userdata,sizeof(userdata)); + void ** v = (void **)rb_read(rb,sizeof(userdata)); if (v == NULL) { invalid_stream(L,rb); } - return *v; + memcpy(&userdata, v, sizeof(userdata)); + return userdata; } static void get_buffer(lua_State *L, struct read_block *rb, int len) { - char tmp[len]; - char * p = rb_read(rb,tmp,len); + char * p = rb_read(rb,len); if (p == NULL) { invalid_stream(L,rb); } @@ -380,12 +404,17 @@ static void unpack_one(lua_State *L, struct read_block *rb); static void unpack_table(lua_State *L, struct read_block *rb, int array_size) { if (array_size == MAX_COOKIE-1) { - uint8_t type = 0; - uint8_t *t = rb_read(rb, &type, 1); - if (t==NULL || (*t & 7) != TYPE_NUMBER) { + uint8_t type; + uint8_t *t = rb_read(rb, sizeof(type)); + if (t==NULL) { invalid_stream(L,rb); } - array_size = (int)get_number(L,rb,*t >> 3); + type = *t; + int cookie = type >> 3; + if ((type & 7) != TYPE_NUMBER || cookie == TYPE_NUMBER_REAL) { + invalid_stream(L,rb); + } + array_size = get_integer(L,rb,cookie); } lua_createtable(L,array_size,0); int i; @@ -414,7 +443,11 @@ push_value(lua_State *L, struct read_block *rb, int type, int cookie) { lua_pushboolean(L,cookie); break; case TYPE_NUMBER: - lua_pushnumber(L,get_number(L,rb,cookie)); + if (cookie == TYPE_NUMBER_REAL) { + lua_pushnumber(L,get_real(L,rb)); + } else { + lua_pushinteger(L, get_integer(L, rb, cookie)); + } break; case TYPE_USERDATA: lua_pushlightuserdata(L,get_pointer(L,rb)); @@ -423,22 +456,25 @@ push_value(lua_State *L, struct read_block *rb, int type, int cookie) { get_buffer(L,rb,cookie); break; case TYPE_LONG_STRING: { - uint32_t len; if (cookie == 2) { - uint16_t *plen = rb_read(rb, &len, 2); + uint16_t *plen = rb_read(rb, 2); if (plen == NULL) { invalid_stream(L,rb); } - get_buffer(L,rb,(int)*plen); + uint16_t n; + memcpy(&n, plen, sizeof(n)); + get_buffer(L,rb,n); } else { if (cookie != 4) { invalid_stream(L,rb); } - uint32_t *plen = rb_read(rb, &len, 4); + uint32_t *plen = rb_read(rb, 4); if (plen == NULL) { invalid_stream(L,rb); } - get_buffer(L,rb,(int)*plen); + uint32_t n; + memcpy(&n, plen, sizeof(n)); + get_buffer(L,rb,n); } break; } @@ -455,12 +491,13 @@ push_value(lua_State *L, struct read_block *rb, int type, int cookie) { static void unpack_one(lua_State *L, struct read_block *rb) { - uint8_t type = 0; - uint8_t *t = rb_read(rb, &type, 1); + uint8_t type; + uint8_t *t = rb_read(rb, sizeof(type)); if (t==NULL) { invalid_stream(L, rb); } - push_value(L, rb, *t & 0x7, *t>>3); + type = *t; + push_value(L, rb, type & 0x7, type>>3); } static void @@ -516,10 +553,11 @@ _luaseri_unpack(lua_State *L) { lua_checkstack(L,i); } uint8_t type = 0; - uint8_t *t = rb_read(&rb, &type, 1); + uint8_t *t = rb_read(&rb, sizeof(type)); if (t==NULL) break; - push_value(L, &rb, *t & 0x7, *t>>3); + type = *t; + push_value(L, &rb, type & 0x7, type>>3); } // Need not free buffer diff --git a/lualib-src/lua-sharedata.c b/lualib-src/lua-sharedata.c index 950d3f50..f0eb046f 100644 --- a/lualib-src/lua-sharedata.c +++ b/lualib-src/lua-sharedata.c @@ -1,5 +1,3 @@ -// build: gcc -O2 -Wall --shared -o conf.so luaconf.c - #include #include #include @@ -11,15 +9,17 @@ #define KEYTYPE_STRING 1 #define VALUETYPE_NIL 0 -#define VALUETYPE_NUMBER 1 +#define VALUETYPE_REAL 1 #define VALUETYPE_STRING 2 #define VALUETYPE_BOOLEAN 3 #define VALUETYPE_TABLE 4 +#define VALUETYPE_INTEGER 5 struct table; union value { lua_Number n; + lua_Integer d; struct table * tbl; int string; int boolean; @@ -71,11 +71,10 @@ countsize(lua_State *L, int sizearray) { int type = lua_type(L, -2); ++n; if (type == LUA_TNUMBER) { - lua_Number key = lua_tonumber(L, -2); - int nkey = (int)key; - if ((lua_Number)nkey != key) { - luaL_error(L, "Invalid key %f", key); + if (!lua_isinteger(L, -2)) { + luaL_error(L, "Invalid key %f", lua_tonumber(L, -2)); } + lua_Integer nkey = lua_tointeger(L, -2); if (nkey > 0 && nkey <= sizearray) { --n; } @@ -129,8 +128,13 @@ setvalue(struct context * ctx, lua_State *L, int index, struct node *n) { n->valuetype = VALUETYPE_NIL; break; case LUA_TNUMBER: - n->v.n = lua_tonumber(L, index); - n->valuetype = VALUETYPE_NUMBER; + if (lua_isinteger(L, index)) { + n->v.d = lua_tointeger(L, index); + n->valuetype = VALUETYPE_INTEGER; + } else { + n->v.n = lua_tonumber(L, index); + n->valuetype = VALUETYPE_REAL; + } break; case LUA_TSTRING: { size_t sz = 0; @@ -468,9 +472,12 @@ ldeleteconf(lua_State *L) { static void pushvalue(lua_State *L, lua_State *sL, uint8_t vt, union value *v) { switch(vt) { - case VALUETYPE_NUMBER: + case VALUETYPE_REAL: lua_pushnumber(L, v->n); break; + case VALUETYPE_INTEGER: + lua_pushinteger(L, v->d); + break; case VALUETYPE_STRING: { size_t sz = 0; const char *str = lua_tolstring(sL, v->string, &sz); @@ -530,16 +537,15 @@ lindexconf(lua_State *L) { size_t sz = 0; const char * str = NULL; if (kt == LUA_TNUMBER) { - lua_Number k = lua_tonumber(L, 2); - key = (int)k; - if ((lua_Number)key != k) { - return luaL_error(L, "Invalid key %f", k); + if (!lua_isinteger(L, 2)) { + return luaL_error(L, "Invalid key %f", lua_tonumber(L, 2)); } + lua_Integer key = lua_tointeger(L, 2); if (key > 0 && key <= tbl->sizearray) { --key; pushvalue(L, tbl->L, tbl->arraytype[key], &tbl->array[key]); return 1; - } + } keytype = KEYTYPE_INTEGER; keyhash = (uint32_t)key; } else { @@ -601,13 +607,12 @@ lnextkey(lua_State *L) { const char *str = NULL; int sizearray = tbl->sizearray; if (kt == LUA_TNUMBER) { - lua_Number k = lua_tonumber(L,2); - key = (int)k; - if ((lua_Number)key != k) { + if (!lua_isinteger(L, 2)) { return 0; } + lua_Integer key = lua_tointeger(L, 2); if (key > 0 && key <= sizearray) { - int i; + lua_Integer i; for (i=key;iarraytype[i] != VALUETYPE_NIL) { lua_pushinteger(L, i+1);