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 }