]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/engine: unpack JSON strings from modules to Lua tables
authorMarek Vavruša <marek.vavrusa@nic.cz>
Sun, 24 May 2015 21:03:43 +0000 (23:03 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Mon, 25 May 2015 11:49:17 +0000 (13:49 +0200)
daemon/daemon.mk
daemon/engine.c

index 8db997443e71027c3a57682332decc3432774ac0..5850de51b922016bf28295d5a27167a06273b057 100644 (file)
@@ -1,4 +1,7 @@
+kresolved_EMBED := \
+       contrib/ccan/json/json.c
 kresolved_SOURCES := \
+       $(kresolved_EMBED)   \
        daemon/io.c          \
        daemon/network.c     \
        daemon/engine.c      \
index 3bdbcf5d4d127c911011bc934ecbc47073889528..887cc36b9d30fdad3066780f4aaee111732941ed 100644 (file)
@@ -14,6 +14,7 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <ccan/json/json.h>
 #include <uv.h>
 #include <unistd.h>
 #include <libknot/internal/mempattern.h>
@@ -68,6 +69,29 @@ static int l_hostname(lua_State *L)
        return 1;
 }
 
+/** Unpack JSON object to table */
+static void l_unpack_json(lua_State *L, JsonNode *table)
+{
+       lua_newtable(L);
+       JsonNode *node = NULL;
+       json_foreach(node, table) {
+               /* Push node value */
+               switch(node->tag) {
+               case JSON_OBJECT: /* as array */
+               case JSON_ARRAY:  l_unpack_json(L, node); break;
+               case JSON_STRING: lua_pushstring(L, node->string_); break;
+               case JSON_NUMBER: lua_pushnumber(L, node->number_); break;
+               default: continue;
+               }
+               /* Set table key */
+               if (node->key) {
+                       lua_setfield(L, -2, node->key);
+               } else {
+                       lua_rawseti(L, -2, lua_rawlen(L, -2) + 1);
+               }
+       }
+}
+
 /** Trampoline function for module properties. */
 static int l_trampoline(lua_State *L)
 {
@@ -82,13 +106,25 @@ static int l_trampoline(lua_State *L)
        /* Now we only have property callback or config,
         * if we expand the callables, we might need a callback_type.
         */
+       const char *args = NULL;
+       if (lua_gettop(L) > 0) {
+               args = lua_tostring(L, 1);
+       }
        if (callback == module->config) {
-               const char *param = lua_tostring(L, 1);
-               module->config(module, param);
+               module->config(module, args);
        } else {
                kr_prop_cb *prop = (kr_prop_cb *)callback;
-               auto_free char *ret = prop(engine, module, lua_tostring(L, 1));
-               lua_pushstring(L, ret);
+               auto_free char *ret = prop(engine, module, args);
+               if (!ret) { /* No results */
+                       return 0;
+               }
+               JsonNode *root_node = json_decode(ret);
+               if (root_node->tag == JSON_OBJECT || root_node->tag == JSON_ARRAY) {
+                       l_unpack_json(L, root_node);
+               } else {
+                       lua_pushstring(L, ret);
+               }
+               json_delete(root_node);
                return 1;
        }