# HG changeset patch # User jbe # Date 1407690378 -7200 # Node ID 00fee67a0c2734cb878459ee7f0bd7fae990cbef # Parent fbfdd4f979d5deff090f792a9271cec84ff7ab13 Added comments to json.export(...) function diff -r fbfdd4f979d5 -r 00fee67a0c27 libraries/json/json.c --- a/libraries/json/json.c Sun Aug 10 18:24:05 2014 +0200 +++ b/libraries/json/json.c Sun Aug 10 19:06:18 2014 +0200 @@ -1013,9 +1013,10 @@ #define json_export_stackswap_idx 6 #define json_export_luacontainer_idx 7 #define json_export_ccontainer_idx 8 +#define json_export_buffer_idx 9 // encodes a JSON document (passed as first argument) -// optionally using indentation (indentation string passed as second argument) +// optionally using indentation (indentation string or true passed as second argument) static int json_export(lua_State *L) { int pretty; // pretty printing on? (i.e. printing with indentation) luaL_Buffer buf; // Lua buffer containing result string @@ -1034,12 +1035,6 @@ int stackswapidx = 0; // elements in stack swap table int containerkey = 0; // temporarily set to 1, if a container key is being encoded json_container_t *container = NULL; // pointer to current C struct for container information -/* - int level; // current depth level - int anyelement = 0; // set to 1 if at least one array element has been processed - json_key_t *keybuf = NULL; // temporary buffer to store (and sort) string keys of objects - lua_Integer arrayidx; // index to iterate through arrays -*/ // stack shall contain two function arguments: lua_settop(L, 2); // use default indentation if indentation argument is (boolean) true: @@ -1061,7 +1056,7 @@ // push table for stack swapping onto stack position 6: lua_newtable(L); // create placeholders on stack positions 7 through 8: - lua_settop(L, 9); + lua_settop(L, json_export_buffer_idx); // create Lua string buffer: luaL_buffinit(L, &buf); // loop: @@ -1146,11 +1141,13 @@ lua_rawget(L, json_export_shadowtbl_idx); if (lua_isnil(L, -1)) lua_pop(L, 1); else lua_replace(L, json_export_luacontainer_idx); - // reset keycount variable: + // check if type of table is still undetermined + // and optionally calculate number of string keys (keycount) + // or set keycount to zero: keycount = 0; - // check if type of table is still undetermined: if (tabletype == JSON_TABLETYPE_UNKNOWN) { - // if yes, iterate over all keys: + // if type of table is undetermined, + // iterate over all keys: for (lua_pushnil(L); lua_next(L, json_export_luacontainer_idx); lua_pop(L, 1)) { switch (lua_type(L, -2)) { case LUA_TSTRING: @@ -1198,14 +1195,16 @@ } // allocate memory for C structure containing string keys and container iteration state: container = lua_newuserdata(L, sizeof(json_container_t) + (keycount-1) * sizeof(json_key_t)); - // store reference on designated stack position: + // store reference to C structure on designated stack position: lua_replace(L, json_export_ccontainer_idx); // initialize C structure for container state: container->type = JSON_TABLETYPE_OBJECT; container->count = keycount; container->pos = 0; + // check if object contains any keys: if (keycount) { - // copy all string keys to the C structure and reset container->pos again: + // if yes, + // copy all string keys to the C structure (and reset container->pos again): for (lua_pushnil(L); lua_next(L, json_export_luacontainer_idx); lua_pop(L, 1)) { if (lua_type(L, -2) == LUA_TSTRING) { json_key_t *key = &container->keys[container->pos++]; @@ -1221,8 +1220,11 @@ break; // JSON array: case JSON_TABLETYPE_ARRAY: + // allocate memory for C structure for container iteration state: container = lua_newuserdata(L, sizeof(json_container_t) - sizeof(json_key_t)); + // store reference to C structure on designated stack position: lua_replace(L, json_export_ccontainer_idx); + // initialize C structure for container state: container->type = JSON_TABLETYPE_ARRAY; container->pos = 0; // add opening bracket to output buffer: @@ -1238,50 +1240,80 @@ // all other datatypes are considered an error: return luaL_error(L, "JSON export not possible for values of type \"%s\"", lua_typename(L, lua_type(L, json_export_value_idx))); } + // check if a container is being processed: if (container) { + // if yes, + // execute code for container iteration: json_export_container: + // distinguish between JSON objects and JSON arrays: switch (container->type) { + // JSON object: case JSON_TABLETYPE_OBJECT: + // finish iteration if all string keys have been processed: if (container->pos == container->count) goto json_export_close; + // push current string key on top of stack: key = &container->keys[container->pos]; lua_pushlstring(L, key->data, key->length); + // check if the key has already been exported: if (!containerkey) { + // if no, + // add a comma to the output buffer if necessary: if (container->pos) luaL_addchar(&buf, ','); + // set containerkey variable to true: containerkey = 1; } else { + // if a key has already been exported, + // add a colon to the output buffer: luaL_addchar(&buf, ':'); + // add a space to the output buffer for pretty results: if (pretty) luaL_addchar(&buf, ' '); + // replace string key on top of stack with corresponding value: lua_rawget(L, json_export_luacontainer_idx); + // reset containerkey variable containerkey = 0; + // increase number of processed key value pairs: container->pos++; } + // store key or value on top of stack in designated stack position: lua_replace(L, json_export_value_idx); break; + // JSON array: case JSON_TABLETYPE_ARRAY: + // store next value in designated stack position: lua_rawgeti(L, json_export_luacontainer_idx, container->pos+1); lua_replace(L, json_export_value_idx); + // finish iteration if value is nil: if (lua_isnil(L, json_export_value_idx)) goto json_export_close; + // add a comma to the output buffer if necessary: if (container->pos) luaL_addchar(&buf, ','); + // increase number of processed values: container->pos++; break; + // common code for closing JSON objects or JSON arrays: json_export_close: + // decrement level variable: level--; - if (pretty) { - if (container->pos) { - luaL_addchar(&buf, '\n'); - for (i=0; ipos) { + luaL_addchar(&buf, '\n'); + for (i=0; itype == JSON_TABLETYPE_OBJECT ? '}' : ']'); + // finish export if last level has been closed: if (!level) goto json_export_finish; + // otherwise, + // recall previous container information from stack swap + // and set C pointer to corresponding C struct: lua_rawgeti(L, json_export_stackswap_idx, stackswapidx--); lua_replace(L, json_export_ccontainer_idx); container = lua_touserdata(L, json_export_ccontainer_idx); lua_rawgeti(L, json_export_stackswap_idx, stackswapidx--); lua_replace(L, json_export_luacontainer_idx); + // repeat code for container iteration: goto json_export_container; } // handle indentation for pretty results: @@ -1293,9 +1325,12 @@ } } } else { + // if no container is being processed, + // finish export: json_export_finish: // for pretty results, add final newline character if outermost container is processed: if (pretty) luaL_addchar(&buf, '\n'); + // create and return Lua string from buffer contents luaL_pushresult(&buf); return 1; }