]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
daemon/engine: convert Lua tables to JSON for prop calls
authorMarek Vavruša <marek.vavrusa@nic.cz>
Sat, 13 Jun 2015 17:25:17 +0000 (19:25 +0200)
committerMarek Vavruša <marek.vavrusa@nic.cz>
Sat, 13 Jun 2015 17:25:17 +0000 (19:25 +0200)
daemon/engine.c

index 22203a027eed8fd45b0963b06870b4031eb32df8..33699df99904fa142d69b70f8515d9ad23e2095b 100644 (file)
@@ -87,6 +87,7 @@ static void l_unpack_json(lua_State *L, JsonNode *table)
                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;
+               case JSON_BOOL:   lua_pushboolean(L, node->bool_); break;
                default: continue;
                }
                /* Set table key */
@@ -98,6 +99,44 @@ static void l_unpack_json(lua_State *L, JsonNode *table)
        }
 }
 
+static JsonNode *l_pack_elem(lua_State *L, int top)
+{
+       if (lua_isstring(L, top)) {
+               return json_mkstring(lua_tostring(L, top));
+       }
+       if (lua_isnumber(L, top)) {
+               return json_mknumber(lua_tonumber(L, top));     
+       }
+       if (lua_isboolean(L, top)) {
+               return json_mkbool(lua_toboolean(L, top));      
+       }
+       return json_mknull();
+}
+
+static char *l_pack_json(lua_State *L, int top)
+{
+       JsonNode *root = json_mkobject();
+       if (!root) {
+               return NULL;
+       }
+       /* Iterate table on stack */
+       lua_pushnil(L);
+       while(lua_next(L, top)) {
+               JsonNode *val = l_pack_elem(L, -1);
+               if (lua_isstring(L, -2)) {
+                       json_append_member(root, lua_tostring(L, -2), val);
+               } else {
+                       json_append_element(root, val);
+               }
+               lua_pop(L, 1);
+       }
+       lua_pop(L, 1);
+       /* Serialize to string */
+       char *result = json_encode(root);
+       json_delete(root);
+       return result;
+}
+
 /** Trampoline function for module properties. */
 static int l_trampoline(lua_State *L)
 {
@@ -113,8 +152,14 @@ static int l_trampoline(lua_State *L)
         * if we expand the callables, we might need a callback_type.
         */
        const char *args = NULL;
+       auto_free char *cleanup_args = NULL;
        if (lua_gettop(L) > 0) {
-               args = lua_tostring(L, 1);
+               if (lua_istable(L, 1)) {
+                       cleanup_args = l_pack_json(L, 1);
+                       args = cleanup_args;
+               } else {
+                       args = lua_tostring(L, 1);
+               }
        }
        if (callback == module->config) {
                module->config(module, args);