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  

Impressum / About Us