# HG changeset patch # User jbe # Date 1406509240 -7200 # Node ID 663722e35330f2360bcbdb5f1307824793709908 # Parent a1507b499fa52bbfc93fee42c0a212d44326c387 Added pairs metamethod for (sparse) JSON objects diff -r a1507b499fa5 -r 663722e35330 libraries/json/json.c --- a/libraries/json/json.c Sun Jul 27 22:42:52 2014 +0200 +++ b/libraries/json/json.c Mon Jul 28 03:00:40 2014 +0200 @@ -7,7 +7,8 @@ #define JSON_UPVAL_SHADOWTBL lua_upvalueindex(2) #define JSON_UPVAL_TYPES lua_upvalueindex(3) #define JSON_UPVAL_METATABLE lua_upvalueindex(4) -#define JSON_UPVAL_IPAIRS_ITERFUNC lua_upvalueindex(5) +#define JSON_UPVAL_PAIRS_ITERFUNC lua_upvalueindex(5) +#define JSON_UPVAL_IPAIRS_ITERFUNC lua_upvalueindex(6) #define JSON_STATE_VALUE 0 #define JSON_STATE_OBJECT_KEY 1 @@ -355,6 +356,27 @@ return 1; } +static int json_pairs_iterfunc(lua_State *L) { + lua_settop(L, 2); + lua_pushvalue(L, 1); + lua_rawget(L, JSON_UPVAL_SHADOWTBL); + if (lua_isnil(L, -1)) return luaL_error(L, "Shadow table not found"); + lua_pushvalue(L, 2); + if (!lua_next(L, -2)) return 0; + if (lua_rawequal(L, -1, JSON_UPVAL_NULLMARK)) { + lua_pop(L, 1); + lua_pushnil(L); + } + return 2; +} + +static int json_pairs(lua_State *L) { + lua_pushvalue(L, JSON_UPVAL_PAIRS_ITERFUNC); + lua_pushvalue(L, 1); + lua_pushnil(L); + return 3; +} + static int json_ipairs_iterfunc(lua_State *L) { int idx; lua_settop(L, 2); @@ -392,6 +414,7 @@ {"__len", json_len}, {"__index", json_index}, {"__newindex", json_newindex}, + {"__pairs", json_pairs}, {"__ipairs", json_ipairs}, {NULL, NULL} }; @@ -410,21 +433,25 @@ lua_setmetatable(L, 3); lua_setmetatable(L, 4); lua_newtable(L); // 5: metatable for JSON objects and JSON arrays - lua_pushvalue(L, 5); - lua_setfield(L, 1, "metatable"); lua_pushvalue(L, 2); lua_pushvalue(L, 3); lua_pushvalue(L, 4); lua_pushvalue(L, 5); - lua_pushcclosure(L, json_ipairs_iterfunc, 4); // 6: iteration function for ipairs + lua_pushcclosure(L, json_pairs_iterfunc, 4); // 6: iteration function for pairs + lua_pushvalue(L, 2); + lua_pushvalue(L, 3); + lua_pushvalue(L, 4); + lua_pushvalue(L, 5); + lua_pushcclosure(L, json_ipairs_iterfunc, 4); // 7: iteration function for ipairs lua_pushvalue(L, 5); lua_pushvalue(L, 2); lua_pushvalue(L, 3); lua_pushvalue(L, 4); lua_pushvalue(L, 5); lua_pushvalue(L, 6); - luaL_setfuncs(L, json_metatable_functions, 5); - lua_pop(L, 1); - luaL_setfuncs(L, json_module_functions, 5); + lua_pushvalue(L, 7); + luaL_setfuncs(L, json_metatable_functions, 6); + lua_setfield(L, 1, "metatable"); + luaL_setfuncs(L, json_module_functions, 6); return 1; }