webmcp

changeset 147:da5ab2c226dc

Fixes and documentation in json_setnull and json_length functions of JSON library
author jbe
date Wed Jul 30 22:19:34 2014 +0200 (2014-07-30)
parents 7912a05ebc3f
children 5354d836e6fb
files libraries/json/json.c
line diff
     1.1 --- a/libraries/json/json.c	Wed Jul 30 20:54:42 2014 +0200
     1.2 +++ b/libraries/json/json.c	Wed Jul 30 22:19:34 2014 +0200
     1.3 @@ -114,15 +114,15 @@
     1.4    luaL_Buffer luabuf;  // Lua buffer to decode JSON string values
     1.5    char *cbuf;          // C buffer to decode JSON string values
     1.6    size_t writepos;     // write position of decoded strings in C buffer
     1.7 -  // stack shall only contain one function argument:
     1.8 +  // stack shall contain one function argument:
     1.9    lua_settop(L, 1);
    1.10 -  // push objectmt on stack position 2:
    1.11 +  // push objectmt onto stack position 2:
    1.12    json_regfetch(L, objectmt);
    1.13 -  // push arraymt on stack position 3:
    1.14 +  // push arraymt onto stack position 3:
    1.15    json_regfetch(L, arraymt);
    1.16 -  // push shadowtbl on stack position 4:
    1.17 +  // push shadowtbl onto stack position 4:
    1.18    json_regfetch(L, shadowtbl);
    1.19 -  // push nullmark on stack position 5:
    1.20 +  // push nullmark onto stack position 5:
    1.21    json_pushlightref(L, nullmark);
    1.22    // require string as first argument:
    1.23    str = luaL_checklstring(L, 1, &total);
    1.24 @@ -363,17 +363,17 @@
    1.25    } else if (!strncmp(str+pos, "true", 4)) {
    1.26      // consume 4 input characters for "true":
    1.27      pos += 4;
    1.28 -    // put Lua true value on stack:
    1.29 +    // put Lua true value onto stack:
    1.30      lua_pushboolean(L, 1);
    1.31    } else if (!strncmp(str+pos, "false", 5)) {
    1.32      // consume 5 input characters for "false":
    1.33      pos += 5;
    1.34 -    // put Lua false value on stack:
    1.35 +    // put Lua false value onto stack:
    1.36      lua_pushboolean(L, 0);
    1.37    } else if (!strncmp(str+pos, "null", 4)) {
    1.38      // consume 4 input characters for "null":
    1.39      pos += 4;
    1.40 -    // put special null-marker on stack:
    1.41 +    // put special null-marker onto stack:
    1.42      lua_pushvalue(L, json_import_nullmark_idx);
    1.43    } else {
    1.44      // all other cases are a syntax error:
    1.45 @@ -427,14 +427,14 @@
    1.46  #define json_path_idxshift 2
    1.47  
    1.48  // gets a value or its type from a JSON document (passed as first argument)
    1.49 -// optionally using a path (passed as variable number of keys after first argument):
    1.50 +// using a path (passed as variable number of keys after first argument):
    1.51  static int json_path(lua_State *L, int type_mode) {
    1.52    int stacktop;                      // stack index of top of stack (after shifting)
    1.53    int idx = 2 + json_path_idxshift;  // stack index of current argument to process
    1.54 -  // insert json_shadowtbl on stack at position 1 (shifting the arguments):
    1.55 +  // insert json_shadowtbl into stack at position 1 (shifting the arguments):
    1.56    json_regfetch(L, shadowtbl);
    1.57    lua_insert(L, 1);
    1.58 -  // insert json_nullmark on stack at position 2 (shifting the arguments):
    1.59 +  // insert json_nullmark into stack at position 2 (shifting the arguments):
    1.60    json_pushlightref(L, nullmark);
    1.61    lua_insert(L, 2);
    1.62    // store stack index of top of stack:
    1.63 @@ -512,24 +512,27 @@
    1.64    return 1;
    1.65  }
    1.66  
    1.67 -// gets a value from a JSON document (first argument)
    1.68 -// optionally using a path (variable number of keys after first argument):
    1.69 +// gets a value from a JSON document (passed as first argument)
    1.70 +// using a path (passed as variable number of keys after first argument):
    1.71  static int json_get(lua_State *L) {
    1.72    return json_path(L, 0);
    1.73  }
    1.74  
    1.75 -// gets a value's type from a JSON document (first argument)
    1.76 -// optionally using a path (variable number of keys after first argument):
    1.77 +// gets a value's type from a JSON document (passed as first argument)
    1.78 +// using a path (variable number of keys after first argument):
    1.79  static int json_type(lua_State *L) {
    1.80    return json_path(L, 1);
    1.81  }
    1.82  
    1.83 -// checks if a value in a JSON document (first argument) is null:
    1.84 +// checks if a value in a JSON document (first argument) is
    1.85 +// explicitly set to null:
    1.86  static int json_isnull(lua_State *L) {
    1.87    const char *jsontype;
    1.88 +  // call json_type function with variable arguments:
    1.89    lua_pushcfunction(L, json_type);
    1.90    lua_insert(L, 1);
    1.91    lua_call(L, lua_gettop(L) - 1, 1);
    1.92 +  // return true if result equals to string "null", otherwise return false:
    1.93    jsontype = lua_tostring(L, -1);
    1.94    if (jsontype && !strcmp(jsontype, "null")) lua_pushboolean(L, 1);
    1.95    else lua_pushboolean(L, 0);
    1.96 @@ -542,47 +545,61 @@
    1.97  #define json_setnull_arraymt_idx 5
    1.98  #define json_setnull_shadowtbl_idx 6
    1.99  
   1.100 +// sets a value in a JSON object or JSON array explicitly to null:
   1.101 +// NOTE: JSON null is different than absence of a key
   1.102  static int json_setnull(lua_State *L) {
   1.103 -  // truncate stack to two elements:
   1.104 +  // stack shall contain two function arguments:
   1.105    lua_settop(L, 2);
   1.106 -  // push json_unknownmt to stack position 3:
   1.107 +  // push json_unknownmt onto stack position 3:
   1.108    json_regfetch(L, unknownmt);
   1.109 -  // push json_objectmt to stack position 4:
   1.110 +  // push json_objectmt onto stack position 4:
   1.111    json_regfetch(L, objectmt);
   1.112 -  // push json_arraymt to stack position 5:
   1.113 +  // push json_arraymt onto stack position 5:
   1.114    json_regfetch(L, arraymt);
   1.115 -  // push json_shadowtbl to stack position 6:
   1.116 +  // push json_shadowtbl onto stack position 6:
   1.117    json_regfetch(L, shadowtbl);
   1.118 -  //
   1.119 -  lua_getmetatable(L, 1);
   1.120 +  // set metatable if necessary (leaves unknown number of elements on stack):
   1.121    if (
   1.122 -    !lua_rawequal(L, -1, json_setnull_unknownmt_idx) &&
   1.123 -    !lua_rawequal(L, -1, json_setnull_objectmt_idx) &&
   1.124 -    !lua_rawequal(L, -1, json_setnull_arraymt_idx)
   1.125 +    !lua_getmetatable(L, 1) || (
   1.126 +      !lua_rawequal(L, -1, json_setnull_unknownmt_idx) &&
   1.127 +      !lua_rawequal(L, -1, json_setnull_objectmt_idx) &&
   1.128 +      !lua_rawequal(L, -1, json_setnull_arraymt_idx)
   1.129 +    )
   1.130    ) {
   1.131      lua_pushvalue(L, json_setnull_unknownmt_idx);
   1.132      lua_setmetatable(L, 1);
   1.133    }
   1.134 +  // try to get shadow table:
   1.135    lua_pushvalue(L, 1);
   1.136    lua_rawget(L, json_setnull_shadowtbl_idx);
   1.137    if (lua_isnil(L, -1)) {
   1.138 +    // if no shadow table is found,
   1.139 +    // create new shadow table (and leave it on top of stack):
   1.140      lua_newtable(L);
   1.141 +    // register shadow table:
   1.142      lua_pushvalue(L, 1);
   1.143      lua_pushvalue(L, -2);
   1.144      lua_rawset(L, json_setnull_shadowtbl_idx);
   1.145    }
   1.146 +  // push key (second argument) and null-marker after shadow table onto stack:
   1.147    lua_pushvalue(L, 2);
   1.148    json_pushlightref(L, nullmark);
   1.149 +  // store key and null-marker in shadow table:
   1.150    lua_rawset(L, -3);
   1.151 +  // return nothing:
   1.152    return 0;
   1.153  }
   1.154  
   1.155 +// returns the length of a JSON array (or zero for a table without numeric keys):
   1.156  static int json_len(lua_State *L) {
   1.157 +  // stack shall contain one function argument:
   1.158    lua_settop(L, 1);
   1.159 +  // push corresponding shadow table (for first argument) on top of stack:
   1.160    json_regfetch(L, shadowtbl);
   1.161    lua_pushvalue(L, 1);
   1.162    lua_rawget(L, -2);
   1.163 -  lua_pushinteger(L, lua_rawlen(L, lua_isnil(L, -1) ? 1 : -1));
   1.164 +  // if shadow table does not exist, return length of argument, else length of shadow table:
   1.165 +  lua_pushnumber(L, lua_rawlen(L, lua_isnil(L, -1) ? 1 : -1));
   1.166    return 1;
   1.167  }
   1.168  

Impressum / About Us