Change struct & sjson to use integers. This is slightly more complex (#3222)
* Change struct to use integers. This is slightly more complex as we have to deal with Unsigned 32-bit integers (that aren't lua integers) * Use int64 in struct rather than double. * Fix sjson to do the right things in LUA5.3 with integers and floats
This commit is contained in:
parent
64ece47ff6
commit
0e02c0e5f3
|
@ -97,7 +97,7 @@ create_new_element(jsonsl_t jsn,
|
||||||
lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref());
|
lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref());
|
||||||
if (data->hkey_ref == LUA_NOREF) {
|
if (data->hkey_ref == LUA_NOREF) {
|
||||||
// list, so append
|
// list, so append
|
||||||
lua_pushnumber(data->L, get_parent_object_used_count_pre_inc());
|
lua_pushinteger(data->L, get_parent_object_used_count_pre_inc());
|
||||||
DBG_PRINTF("Adding array element\n");
|
DBG_PRINTF("Adding array element\n");
|
||||||
} else {
|
} else {
|
||||||
// object, so
|
// object, so
|
||||||
|
@ -108,7 +108,7 @@ create_new_element(jsonsl_t jsn,
|
||||||
}
|
}
|
||||||
if (data->pos_ref != LUA_NOREF && state->level > 1) {
|
if (data->pos_ref != LUA_NOREF && state->level > 1) {
|
||||||
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref);
|
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref);
|
||||||
lua_pushnumber(data->L, state->level - 1);
|
lua_pushinteger(data->L, state->level - 1);
|
||||||
lua_pushvalue(data->L, -3); // get the key
|
lua_pushvalue(data->L, -3); // get the key
|
||||||
lua_settable(data->L, -3);
|
lua_settable(data->L, -3);
|
||||||
lua_pop(data->L, 1);
|
lua_pop(data->L, 1);
|
||||||
|
@ -152,10 +152,21 @@ create_new_element(jsonsl_t jsn,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void push_number(JSN_DATA *data, struct jsonsl_state_st *state) {
|
static void push_number(JSN_DATA *data, struct jsonsl_state_st *state) {
|
||||||
lua_pushlstring(data->L, get_state_buffer(data, state), state->pos_cur - state->pos_begin);
|
const char *start = get_state_buffer(data, state);
|
||||||
LUA_NUMBER r = lua_tonumber(data->L, -1);
|
const char *end = start + state->pos_cur - state->pos_begin;
|
||||||
|
lua_pushlstring(data->L, start, end - start);
|
||||||
|
#if LUA_VERSION_NUM >= 503
|
||||||
|
int sz = lua_stringtonumber(data->L, lua_tostring(data->L, -1));
|
||||||
|
if (sz) {
|
||||||
|
lua_pop(data->L, 1);
|
||||||
|
} else {
|
||||||
|
luaL_error(data->L, "Invalid number");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
lua_Number result = lua_tonumber(data->L, -1);
|
||||||
lua_pop(data->L, 1);
|
lua_pop(data->L, 1);
|
||||||
lua_pushnumber(data->L, r);
|
lua_pushnumber(data->L, result);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fromhex(char c) {
|
static int fromhex(char c) {
|
||||||
|
@ -241,7 +252,7 @@ cleanup_closing_element(jsonsl_t jsn,
|
||||||
lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref());
|
lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref());
|
||||||
if (data->hkey_ref == LUA_NOREF) {
|
if (data->hkey_ref == LUA_NOREF) {
|
||||||
// list, so append
|
// list, so append
|
||||||
lua_pushnumber(data->L, get_parent_object_used_count_pre_inc());
|
lua_pushinteger(data->L, get_parent_object_used_count_pre_inc());
|
||||||
} else {
|
} else {
|
||||||
// object, so
|
// object, so
|
||||||
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
|
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
|
||||||
|
@ -272,7 +283,7 @@ cleanup_closing_element(jsonsl_t jsn,
|
||||||
lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref());
|
lua_rawgeti(data->L, LUA_REGISTRYINDEX, get_parent_object_ref());
|
||||||
if (data->hkey_ref == LUA_NOREF) {
|
if (data->hkey_ref == LUA_NOREF) {
|
||||||
// list, so append
|
// list, so append
|
||||||
lua_pushnumber(data->L, get_parent_object_used_count_pre_inc());
|
lua_pushinteger(data->L, get_parent_object_used_count_pre_inc());
|
||||||
} else {
|
} else {
|
||||||
// object, so
|
// object, so
|
||||||
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
|
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->hkey_ref);
|
||||||
|
@ -291,7 +302,7 @@ cleanup_closing_element(jsonsl_t jsn,
|
||||||
state->lua_object_ref = LUA_NOREF;
|
state->lua_object_ref = LUA_NOREF;
|
||||||
if (data->pos_ref != LUA_NOREF) {
|
if (data->pos_ref != LUA_NOREF) {
|
||||||
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref);
|
lua_rawgeti(data->L, LUA_REGISTRYINDEX, data->pos_ref);
|
||||||
lua_pushnumber(data->L, state->level);
|
lua_pushinteger(data->L, state->level);
|
||||||
lua_pushnil(data->L);
|
lua_pushnil(data->L);
|
||||||
lua_settable(data->L, -3);
|
lua_settable(data->L, -3);
|
||||||
lua_pop(data->L, 1);
|
lua_pop(data->L, 1);
|
||||||
|
@ -719,7 +730,11 @@ static void encode_lua_object(lua_State *L, ENC_DATA *data, int argno, const cha
|
||||||
char value[len + 1];
|
char value[len + 1];
|
||||||
strcpy(value, str);
|
strcpy(value, str);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
luaL_addstring(&b, value);
|
if (strcmp(value, "-Infinity") == 0 || strcmp(value, "NaN") == 0 || strcmp(value, "Infinity") == 0) {
|
||||||
|
luaL_addstring(&b, "null"); // According to ECMA-262 section 24.5.2 Note 4
|
||||||
|
} else {
|
||||||
|
luaL_addstring(&b, value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,14 @@ typedef unsigned STRUCT_INT Uinttype;
|
||||||
#define MAXINTSIZE 32
|
#define MAXINTSIZE 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef LUA_MININTEGER
|
||||||
|
#define LUA_MININTEGER INT_MIN
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LUA_MAXINTEGER
|
||||||
|
#define LUA_MAXINTEGER INT_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
/* is 'x' a power of 2? */
|
/* is 'x' a power of 2? */
|
||||||
#define isp2(x) ((x) > 0 && ((x) & ((x) - 1)) == 0)
|
#define isp2(x) ((x) > 0 && ((x) & ((x) - 1)) == 0)
|
||||||
|
|
||||||
|
@ -170,7 +178,7 @@ static void controloptions (lua_State *L, int opt, const char **fmt,
|
||||||
|
|
||||||
static void putinteger (lua_State *L, luaL_Buffer *b, int arg, int endian,
|
static void putinteger (lua_State *L, luaL_Buffer *b, int arg, int endian,
|
||||||
int size) {
|
int size) {
|
||||||
lua_Number n = luaL_checknumber(L, arg);
|
int32_t n = luaL_checkinteger(L, arg);
|
||||||
Uinttype value;
|
Uinttype value;
|
||||||
char buff[MAXINTSIZE];
|
char buff[MAXINTSIZE];
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
|
@ -267,29 +275,29 @@ static int b_pack (lua_State *L) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static lua_Number getinteger (const char *buff, int endian,
|
static int64_t getinteger (const char *buff, int endian,
|
||||||
int issigned, int size) {
|
int issigned, int size) {
|
||||||
Uinttype l = 0;
|
uint64_t l = 0;
|
||||||
int i;
|
int i;
|
||||||
if (endian == BIG) {
|
if (endian == BIG) {
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
l <<= 8;
|
l <<= 8;
|
||||||
l |= (Uinttype)(unsigned char)buff[i];
|
l |= (unsigned char)buff[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (i = size - 1; i >= 0; i--) {
|
for (i = size - 1; i >= 0; i--) {
|
||||||
l <<= 8;
|
l <<= 8;
|
||||||
l |= (Uinttype)(unsigned char)buff[i];
|
l |= (unsigned char)buff[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!issigned)
|
if (!issigned)
|
||||||
return (lua_Number)l;
|
return (int64_t)l;
|
||||||
else { /* signed format */
|
else { /* signed format */
|
||||||
Uinttype mask = (Uinttype)(~((Uinttype)0)) << (size*8 - 1);
|
uint64_t mask = (uint64_t)(~((uint64_t)0)) << (size*8 - 1);
|
||||||
if (l & mask) /* negative value? */
|
if (l & mask) /* negative value? */
|
||||||
l |= mask; /* signal extension */
|
l |= mask; /* signal extension */
|
||||||
return (lua_Number)(Inttype)l;
|
return (int64_t)l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,8 +320,12 @@ static int b_unpack (lua_State *L) {
|
||||||
case 'b': case 'B': case 'h': case 'H':
|
case 'b': case 'B': case 'h': case 'H':
|
||||||
case 'l': case 'L': case 'T': case 'i': case 'I': { /* integer types */
|
case 'l': case 'L': case 'T': case 'i': case 'I': { /* integer types */
|
||||||
int issigned = islower(opt);
|
int issigned = islower(opt);
|
||||||
lua_Number res = getinteger(data+pos, h.endian, issigned, size);
|
int64_t res = getinteger(data+pos, h.endian, issigned, size);
|
||||||
lua_pushnumber(L, res);
|
if (res >= LUA_MININTEGER && res <= LUA_MAXINTEGER) {
|
||||||
|
lua_pushinteger(L, res);
|
||||||
|
} else {
|
||||||
|
lua_pushnumber(L, res);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'x': {
|
case 'x': {
|
||||||
|
@ -339,7 +351,7 @@ static int b_unpack (lua_State *L) {
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
if (!lua_isnumber(L, -1))
|
if (!lua_isnumber(L, -1))
|
||||||
luaL_error(L, "format `c0' needs a previous size");
|
luaL_error(L, "format `c0' needs a previous size");
|
||||||
size = lua_tonumber(L, -1);
|
size = lua_tointeger(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
luaL_argcheck(L, pos+size <= ld, 2, "data string too short");
|
luaL_argcheck(L, pos+size <= ld, 2, "data string too short");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue