support lua 5.3 lua_Integer

This commit is contained in:
Cloud Wu
2015-01-05 18:17:52 +08:00
parent da9e8fec20
commit d06aa9b27d
2 changed files with 132 additions and 89 deletions

View File

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