webmcp
changeset 171:ce208edffcc9
Code cleanup in json.object and json.array functions
author | jbe |
---|---|
date | Fri Aug 01 16:40:10 2014 +0200 (2014-08-01) |
parents | c055d6d64586 |
children | a83164390355 |
files | libraries/json/json.c |
line diff
1.1 --- a/libraries/json/json.c Fri Aug 01 13:09:15 2014 +0200 1.2 +++ b/libraries/json/json.c Fri Aug 01 16:40:10 2014 +0200 1.3 @@ -49,16 +49,21 @@ 1.4 // converts a Lua table to a JSON object or JSON array: 1.5 // (does never modify the argument, returns an empty object or array if argument is nil) 1.6 static int json_convert(lua_State *L, int array) { 1.7 - lua_settop(L, 1); 1.8 + int arrayidx = 0; 1.9 + // determine is argument is given: 1.10 if (lua_isnoneornil(L, json_convert_source_idx)) { 1.11 + // if no argument is given (or if argument is nil), 1.12 + // create table with shadow table, and leave first table on top of stack: 1.13 json_regfetch(L, shadowtbl); 1.14 lua_newtable(L); 1.15 lua_pushvalue(L, -1); 1.16 lua_newtable(L); 1.17 lua_rawset(L, -4); 1.18 } else { 1.19 - // push iterator function on stack position 2 if existent, 1.20 + // if an argument was given, 1.21 + // push its iterator function on stack position 2 if existent, 1.22 // else push null for normal tables: 1.23 + lua_settop(L, 1); 1.24 if (lua_getmetatable(L, json_convert_source_idx)) { 1.25 lua_getfield(L, -1, array ? "__ipairs" : "__pairs"); 1.26 if (lua_isnil(L, -1)) luaL_checktype(L, 1, LUA_TTABLE); 1.27 @@ -68,7 +73,7 @@ 1.28 } else { 1.29 lua_pushnil(L); 1.30 } 1.31 - // create table on stack position 3: 1.32 + // create result table on stack position 3: 1.33 lua_newtable(L); 1.34 // create shadow table on stack position 4: 1.35 json_regfetch(L, shadowtbl); 1.36 @@ -77,22 +82,47 @@ 1.37 lua_pushvalue(L, -2); 1.38 lua_rawset(L, -4); 1.39 lua_replace(L, -2); 1.40 + // check if iterator function exists: 1.41 if (lua_isnil(L, json_convert_iterator_idx)) { 1.42 - for (lua_pushnil(L); lua_next(L, json_convert_source_idx); lua_pop(L, 1)) { 1.43 - lua_pushvalue(L, -2); 1.44 - lua_pushvalue(L, -2); 1.45 - lua_rawset(L, json_convert_shadow_idx); 1.46 + // if there is no iterator function, 1.47 + // distinguish between objects and arrays: 1.48 + if (array == 0) { 1.49 + // for an object, copy all string key value pairs to shadow table: 1.50 + for (lua_pushnil(L); lua_next(L, json_convert_source_idx); lua_pop(L, 1)) { 1.51 + if (lua_type(L, -2) == LUA_TSTRING) { 1.52 + lua_pushvalue(L, -2); 1.53 + lua_pushvalue(L, -2); 1.54 + lua_rawset(L, json_convert_shadow_idx); 1.55 + } 1.56 + } 1.57 + } else { 1.58 + // for an array, copy consecutive integer value pairs to shadow table: 1.59 + while (1) { 1.60 + // TODO: Lua 5.3 may support more elements 1.61 + if (arrayidx == INT_MAX) { 1.62 + lua_pushnumber(L, (size_t)INT_MAX+1); 1.63 + lua_rawget(L, json_convert_source_idx); 1.64 + if (lua_isnil(L, -1)) break; 1.65 + return luaL_error(L, "Array exceeded length of %d elements", INT_MAX); 1.66 + } 1.67 + arrayidx++; 1.68 + lua_rawgeti(L, json_convert_source_idx, arrayidx); 1.69 + if (lua_isnil(L, -1)) break; 1.70 + lua_rawseti(L, json_convert_shadow_idx, arrayidx); 1.71 + } 1.72 } 1.73 } else { 1.74 + // TODO: implement conversion using iterator metamethods 1.75 return luaL_error(L, "Using %s metamethod not implemented yet", array ? "__ipairs" : "__pairs"); 1.76 } 1.77 + // let result table be on top of stack: 1.78 lua_settop(L, json_convert_output_idx); 1.79 } 1.80 - // set metatable: 1.81 - if (array) json_regfetch(L, arraymt); 1.82 - else json_regfetch(L, objectmt); 1.83 + // set metatable (for result table on top of stack): 1.84 + if (array == 0) json_regfetch(L, objectmt); 1.85 + else json_regfetch(L, arraymt); 1.86 lua_setmetatable(L, -2); 1.87 - // return table: 1.88 + // return table on top of stack: 1.89 return 1; 1.90 } 1.91