webmcp

changeset 187:00fee67a0c27

Added comments to json.export(...) function
author jbe
date Sun Aug 10 19:06:18 2014 +0200 (2014-08-10)
parents fbfdd4f979d5
children 433fa98329ec
files libraries/json/json.c
line diff
     1.1 --- a/libraries/json/json.c	Sun Aug 10 18:24:05 2014 +0200
     1.2 +++ b/libraries/json/json.c	Sun Aug 10 19:06:18 2014 +0200
     1.3 @@ -1013,9 +1013,10 @@
     1.4  #define json_export_stackswap_idx 6
     1.5  #define json_export_luacontainer_idx 7
     1.6  #define json_export_ccontainer_idx 8
     1.7 +#define json_export_buffer_idx 9
     1.8  
     1.9  // encodes a JSON document (passed as first argument)
    1.10 -// optionally using indentation (indentation string passed as second argument)
    1.11 +// optionally using indentation (indentation string or true passed as second argument)
    1.12  static int json_export(lua_State *L) {
    1.13    int pretty;           // pretty printing on? (i.e. printing with indentation)
    1.14    luaL_Buffer buf;      // Lua buffer containing result string
    1.15 @@ -1034,12 +1035,6 @@
    1.16    int stackswapidx = 0; // elements in stack swap table
    1.17    int containerkey = 0; // temporarily set to 1, if a container key is being encoded
    1.18    json_container_t *container = NULL; // pointer to current C struct for container information
    1.19 -/*
    1.20 -  int level;        // current depth level
    1.21 -  int anyelement = 0;         // set to 1 if at least one array element has been processed
    1.22 -  json_key_t *keybuf = NULL;  // temporary buffer to store (and sort) string keys of objects
    1.23 -  lua_Integer arrayidx;       // index to iterate through arrays
    1.24 -*/
    1.25    // stack shall contain two function arguments:
    1.26    lua_settop(L, 2);
    1.27    // use default indentation if indentation argument is (boolean) true:
    1.28 @@ -1061,7 +1056,7 @@
    1.29    // push table for stack swapping onto stack position 6:
    1.30    lua_newtable(L);
    1.31    // create placeholders on stack positions 7 through 8:
    1.32 -  lua_settop(L, 9);
    1.33 +  lua_settop(L, json_export_buffer_idx);
    1.34    // create Lua string buffer:
    1.35    luaL_buffinit(L, &buf);
    1.36    // loop:
    1.37 @@ -1146,11 +1141,13 @@
    1.38        lua_rawget(L, json_export_shadowtbl_idx);
    1.39        if (lua_isnil(L, -1)) lua_pop(L, 1);
    1.40        else lua_replace(L, json_export_luacontainer_idx);
    1.41 -      // reset keycount variable:
    1.42 +      // check if type of table is still undetermined
    1.43 +      // and optionally calculate number of string keys (keycount)
    1.44 +      // or set keycount to zero:
    1.45        keycount = 0;
    1.46 -      // check if type of table is still undetermined:
    1.47        if (tabletype == JSON_TABLETYPE_UNKNOWN) {
    1.48 -        // if yes, iterate over all keys:
    1.49 +        // if type of table is undetermined,
    1.50 +        // iterate over all keys:
    1.51          for (lua_pushnil(L); lua_next(L, json_export_luacontainer_idx); lua_pop(L, 1)) {
    1.52            switch (lua_type(L, -2)) {
    1.53            case LUA_TSTRING:
    1.54 @@ -1198,14 +1195,16 @@
    1.55          }
    1.56          // allocate memory for C structure containing string keys and container iteration state:
    1.57          container = lua_newuserdata(L, sizeof(json_container_t) + (keycount-1) * sizeof(json_key_t));
    1.58 -        // store reference on designated stack position:
    1.59 +        // store reference to C structure on designated stack position:
    1.60          lua_replace(L, json_export_ccontainer_idx);
    1.61          // initialize C structure for container state:
    1.62          container->type = JSON_TABLETYPE_OBJECT;
    1.63          container->count = keycount;
    1.64          container->pos = 0;
    1.65 +        // check if object contains any keys:
    1.66          if (keycount) {
    1.67 -          // copy all string keys to the C structure and reset container->pos again:
    1.68 +          // if yes,
    1.69 +          // copy all string keys to the C structure (and reset container->pos again):
    1.70            for (lua_pushnil(L); lua_next(L, json_export_luacontainer_idx); lua_pop(L, 1)) {
    1.71              if (lua_type(L, -2) == LUA_TSTRING) {
    1.72                json_key_t *key = &container->keys[container->pos++];
    1.73 @@ -1221,8 +1220,11 @@
    1.74          break;
    1.75        // JSON array:
    1.76        case JSON_TABLETYPE_ARRAY:
    1.77 +        // allocate memory for C structure for container iteration state:
    1.78          container = lua_newuserdata(L, sizeof(json_container_t) - sizeof(json_key_t));
    1.79 +        // store reference to C structure on designated stack position:
    1.80          lua_replace(L, json_export_ccontainer_idx);
    1.81 +        // initialize C structure for container state:
    1.82          container->type = JSON_TABLETYPE_ARRAY;
    1.83          container->pos = 0;
    1.84          // add opening bracket to output buffer:
    1.85 @@ -1238,50 +1240,80 @@
    1.86      // all other datatypes are considered an error:
    1.87      return luaL_error(L, "JSON export not possible for values of type \"%s\"", lua_typename(L, lua_type(L, json_export_value_idx)));
    1.88      }
    1.89 +    // check if a container is being processed:
    1.90      if (container) {
    1.91 +      // if yes,
    1.92 +      // execute code for container iteration:
    1.93        json_export_container:
    1.94 +      // distinguish between JSON objects and JSON arrays:
    1.95        switch (container->type) {
    1.96 +      // JSON object:
    1.97        case JSON_TABLETYPE_OBJECT:
    1.98 +        // finish iteration if all string keys have been processed:
    1.99          if (container->pos == container->count) goto json_export_close;
   1.100 +        // push current string key on top of stack:
   1.101          key = &container->keys[container->pos];
   1.102          lua_pushlstring(L, key->data, key->length);
   1.103 +        // check if the key has already been exported:
   1.104          if (!containerkey) {
   1.105 +          // if no,
   1.106 +          // add a comma to the output buffer if necessary:
   1.107            if (container->pos) luaL_addchar(&buf, ',');
   1.108 +          // set containerkey variable to true:
   1.109            containerkey = 1;
   1.110          } else {
   1.111 +          // if a key has already been exported,
   1.112 +          // add a colon to the output buffer:
   1.113            luaL_addchar(&buf, ':');
   1.114 +          // add a space to the output buffer for pretty results:
   1.115            if (pretty) luaL_addchar(&buf, ' ');
   1.116 +          // replace string key on top of stack with corresponding value:
   1.117            lua_rawget(L, json_export_luacontainer_idx);
   1.118 +          // reset containerkey variable
   1.119            containerkey = 0;
   1.120 +          // increase number of processed key value pairs:
   1.121            container->pos++;
   1.122          }
   1.123 +        // store key or value on top of stack in designated stack position:
   1.124          lua_replace(L, json_export_value_idx);
   1.125          break;
   1.126 +      // JSON array:
   1.127        case JSON_TABLETYPE_ARRAY:
   1.128 +        // store next value in designated stack position:
   1.129          lua_rawgeti(L, json_export_luacontainer_idx, container->pos+1);
   1.130          lua_replace(L, json_export_value_idx);
   1.131 +        // finish iteration if value is nil:
   1.132          if (lua_isnil(L, json_export_value_idx)) goto json_export_close;
   1.133 +        // add a comma to the output buffer if necessary:
   1.134          if (container->pos) luaL_addchar(&buf, ',');
   1.135 +        // increase number of processed values:
   1.136          container->pos++;
   1.137          break;
   1.138 +      // common code for closing JSON objects or JSON arrays:
   1.139        json_export_close:
   1.140 +        // decrement level variable:
   1.141          level--;
   1.142 -        if (pretty) {
   1.143 -          if (container->pos) {
   1.144 -            luaL_addchar(&buf, '\n');
   1.145 -            for (i=0; i<level; i++) {
   1.146 -              lua_pushvalue(L, json_export_indentstring_idx);
   1.147 -              luaL_addvalue(&buf);
   1.148 -            }
   1.149 +        // handle indentation for pretty results:
   1.150 +        if (pretty && container->pos) {
   1.151 +          luaL_addchar(&buf, '\n');
   1.152 +          for (i=0; i<level; i++) {
   1.153 +            lua_pushvalue(L, json_export_indentstring_idx);
   1.154 +            luaL_addvalue(&buf);
   1.155            }
   1.156          }
   1.157 +        // add closing bracket to output buffer:
   1.158          luaL_addchar(&buf, container->type == JSON_TABLETYPE_OBJECT ? '}' : ']');
   1.159 +        // finish export if last level has been closed:
   1.160          if (!level) goto json_export_finish;
   1.161 +        // otherwise,
   1.162 +        // recall previous container information from stack swap
   1.163 +        // and set C pointer to corresponding C struct:
   1.164          lua_rawgeti(L, json_export_stackswap_idx, stackswapidx--);
   1.165          lua_replace(L, json_export_ccontainer_idx);
   1.166          container = lua_touserdata(L, json_export_ccontainer_idx);
   1.167          lua_rawgeti(L, json_export_stackswap_idx, stackswapidx--);
   1.168          lua_replace(L, json_export_luacontainer_idx);
   1.169 +        // repeat code for container iteration:
   1.170          goto json_export_container;
   1.171        }
   1.172        // handle indentation for pretty results:
   1.173 @@ -1293,9 +1325,12 @@
   1.174          }
   1.175        }
   1.176      } else {
   1.177 +      // if no container is being processed,
   1.178 +      // finish export:
   1.179        json_export_finish:
   1.180        // for pretty results, add final newline character if outermost container is processed:
   1.181        if (pretty) luaL_addchar(&buf, '\n');
   1.182 +      // create and return Lua string from buffer contents
   1.183        luaL_pushresult(&buf);
   1.184        return 1;
   1.185      }

Impressum / About Us