webmcp
changeset 134:a1507b499fa5
Implemented ipairs metamethod for sparse JSON arrays
author | jbe |
---|---|
date | Sun Jul 27 22:42:52 2014 +0200 (2014-07-27) |
parents | 214e11b72907 |
children | 663722e35330 |
files | libraries/json/json.c |
line diff
1.1 --- a/libraries/json/json.c Sun Jul 27 22:10:28 2014 +0200 1.2 +++ b/libraries/json/json.c Sun Jul 27 22:42:52 2014 +0200 1.3 @@ -7,6 +7,7 @@ 1.4 #define JSON_UPVAL_SHADOWTBL lua_upvalueindex(2) 1.5 #define JSON_UPVAL_TYPES lua_upvalueindex(3) 1.6 #define JSON_UPVAL_METATABLE lua_upvalueindex(4) 1.7 +#define JSON_UPVAL_IPAIRS_ITERFUNC lua_upvalueindex(5) 1.8 1.9 #define JSON_STATE_VALUE 0 1.10 #define JSON_STATE_OBJECT_KEY 1 1.11 @@ -354,6 +355,28 @@ 1.12 return 1; 1.13 } 1.14 1.15 +static int json_ipairs_iterfunc(lua_State *L) { 1.16 + int idx; 1.17 + lua_settop(L, 2); 1.18 + idx = lua_tointeger(L, 2) + 1; 1.19 + lua_pushvalue(L, 1); 1.20 + lua_rawget(L, JSON_UPVAL_SHADOWTBL); 1.21 + if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found"); 1.22 + lua_rawgeti(L, -1, idx); 1.23 + if (lua_isnil(L, -1)) return 0; 1.24 + lua_pushinteger(L, idx); 1.25 + if (lua_rawequal(L, -2, JSON_UPVAL_NULLMARK)) lua_pushnil(L); 1.26 + else lua_pushvalue(L, -2); 1.27 + return 2; 1.28 +} 1.29 + 1.30 +static int json_ipairs(lua_State *L) { 1.31 + lua_pushvalue(L, JSON_UPVAL_IPAIRS_ITERFUNC); 1.32 + lua_pushvalue(L, 1); 1.33 + lua_pushinteger(L, 0); 1.34 + return 3; 1.35 +} 1.36 + 1.37 static const struct luaL_Reg json_module_functions[] = { 1.38 {"object", json_object}, 1.39 {"array", json_array}, 1.40 @@ -369,6 +392,7 @@ 1.41 {"__len", json_len}, 1.42 {"__index", json_index}, 1.43 {"__newindex", json_newindex}, 1.44 + {"__ipairs", json_ipairs}, 1.45 {NULL, NULL} 1.46 }; 1.47 1.48 @@ -392,7 +416,15 @@ 1.49 lua_pushvalue(L, 3); 1.50 lua_pushvalue(L, 4); 1.51 lua_pushvalue(L, 5); 1.52 - luaL_setfuncs(L, json_metatable_functions, 4); 1.53 - luaL_setfuncs(L, json_module_functions, 4); 1.54 + lua_pushcclosure(L, json_ipairs_iterfunc, 4); // 6: iteration function for ipairs 1.55 + lua_pushvalue(L, 5); 1.56 + lua_pushvalue(L, 2); 1.57 + lua_pushvalue(L, 3); 1.58 + lua_pushvalue(L, 4); 1.59 + lua_pushvalue(L, 5); 1.60 + lua_pushvalue(L, 6); 1.61 + luaL_setfuncs(L, json_metatable_functions, 5); 1.62 + lua_pop(L, 1); 1.63 + luaL_setfuncs(L, json_module_functions, 5); 1.64 return 1; 1.65 }