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());
|
||||
if (data->hkey_ref == LUA_NOREF) {
|
||||
// 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");
|
||||
} else {
|
||||
// object, so
|
||||
|
@ -108,7 +108,7 @@ create_new_element(jsonsl_t jsn,
|
|||
}
|
||||
if (data->pos_ref != LUA_NOREF && state->level > 1) {
|
||||
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_settable(data->L, -3);
|
||||
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) {
|
||||
lua_pushlstring(data->L, get_state_buffer(data, state), state->pos_cur - state->pos_begin);
|
||||
LUA_NUMBER r = lua_tonumber(data->L, -1);
|
||||
const char *start = get_state_buffer(data, state);
|
||||
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_pushnumber(data->L, r);
|
||||
lua_pushnumber(data->L, result);
|
||||
#endif
|
||||
}
|
||||
|
||||
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());
|
||||
if (data->hkey_ref == LUA_NOREF) {
|
||||
// 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 {
|
||||
// object, so
|
||||
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());
|
||||
if (data->hkey_ref == LUA_NOREF) {
|
||||
// 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 {
|
||||
// object, so
|
||||
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;
|
||||
if (data->pos_ref != LUA_NOREF) {
|
||||
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_settable(data->L, -3);
|
||||
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];
|
||||
strcpy(value, str);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,14 @@ typedef unsigned STRUCT_INT Uinttype;
|
|||
#define MAXINTSIZE 32
|
||||
#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? */
|
||||
#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,
|
||||
int size) {
|
||||
lua_Number n = luaL_checknumber(L, arg);
|
||||
int32_t n = luaL_checkinteger(L, arg);
|
||||
Uinttype value;
|
||||
char buff[MAXINTSIZE];
|
||||
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) {
|
||||
Uinttype l = 0;
|
||||
uint64_t l = 0;
|
||||
int i;
|
||||
if (endian == BIG) {
|
||||
for (i = 0; i < size; i++) {
|
||||
l <<= 8;
|
||||
l |= (Uinttype)(unsigned char)buff[i];
|
||||
l |= (unsigned char)buff[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = size - 1; i >= 0; i--) {
|
||||
l <<= 8;
|
||||
l |= (Uinttype)(unsigned char)buff[i];
|
||||
l |= (unsigned char)buff[i];
|
||||
}
|
||||
}
|
||||
if (!issigned)
|
||||
return (lua_Number)l;
|
||||
return (int64_t)l;
|
||||
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? */
|
||||
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 'l': case 'L': case 'T': case 'i': case 'I': { /* integer types */
|
||||
int issigned = islower(opt);
|
||||
lua_Number res = getinteger(data+pos, h.endian, issigned, size);
|
||||
lua_pushnumber(L, res);
|
||||
int64_t res = getinteger(data+pos, h.endian, issigned, size);
|
||||
if (res >= LUA_MININTEGER && res <= LUA_MAXINTEGER) {
|
||||
lua_pushinteger(L, res);
|
||||
} else {
|
||||
lua_pushnumber(L, res);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'x': {
|
||||
|
@ -339,7 +351,7 @@ static int b_unpack (lua_State *L) {
|
|||
if (size == 0) {
|
||||
if (!lua_isnumber(L, -1))
|
||||
luaL_error(L, "format `c0' needs a previous size");
|
||||
size = lua_tonumber(L, -1);
|
||||
size = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
luaL_argcheck(L, pos+size <= ld, 2, "data string too short");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue