From 93a0f41d4af17db3e3eedb61e786fec23dbd8db9 Mon Sep 17 00:00:00 2001
From: Roger Planas <roger.planas@isode.com>
Date: Wed, 28 Jun 2017 16:09:37 +0100
Subject: Sluift: Add extensions support to disco#info queries

Only identities and features were reported. Now extensions,
if any, will also be reported

Test-information:

Sent disco#info to a muc room, and got the following extensions  back
(along with identities and features, so no regression)

Change-Id: Ib4ab17114df4da5de51945df9e53c12bd42716d1

diff --git a/Sluift/ElementConvertors/DiscoInfoConvertor.cpp b/Sluift/ElementConvertors/DiscoInfoConvertor.cpp
index 2aa4a77..a528211 100644
--- a/Sluift/ElementConvertors/DiscoInfoConvertor.cpp
+++ b/Sluift/ElementConvertors/DiscoInfoConvertor.cpp
@@ -12,11 +12,15 @@
 
 #include <lua.hpp>
 
+#include <Swiften/Elements/Form.h>
+#include <Sluift/LuaElementConvertors.h>
 #include <Sluift/Lua/LuaUtils.h>
 
 using namespace Swift;
 
-DiscoInfoConvertor::DiscoInfoConvertor() : GenericLuaElementConvertor<DiscoInfo>("disco_info") {
+DiscoInfoConvertor::DiscoInfoConvertor(LuaElementConvertors* convertors) :
+        GenericLuaElementConvertor<DiscoInfo>("disco_info"),
+        convertors(convertors) {
 }
 
 DiscoInfoConvertor::~DiscoInfoConvertor() {
@@ -52,7 +56,17 @@ std::shared_ptr<DiscoInfo> DiscoInfoConvertor::doConvertFromLua(lua_State* L) {
     }
     lua_pop(L, 1);
 
-    // TODO: Extension
+    lua_getfield(L, -1, "extensions");
+    if (lua_istable(L, -1)) {
+        for (lua_pushnil(L); lua_next(L, -2); ) {
+            std::shared_ptr<Form> form = std::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"));
+            if (!!form) {
+                result->addExtension(form);
+            }
+            lua_pop(L, 1);
+        }
+    }
+    lua_pop(L, 1);
 
     return result;
 }
@@ -100,7 +114,16 @@ void DiscoInfoConvertor::doConvertToLua(lua_State* L, std::shared_ptr<DiscoInfo>
         lua_setfield(L, -2, "features");
     }
 
-    // TODO: Extension
+    const std::vector<Form::ref>& extensions = payload->getExtensions();
+    if (!extensions.empty()) {
+        lua_createtable(L, boost::numeric_cast<int>(extensions.size()), 0);
+        for (size_t i = 0; i < extensions.size(); ++i) {
+            if (convertors->convertToLuaUntyped(L, extensions[i]) > 0) {
+                lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+            }
+        }
+        lua_setfield(L, -2, "extensions");
+    }
 }
 
 boost::optional<LuaElementConvertor::Documentation> DiscoInfoConvertor::getDocumentation() const {
@@ -115,5 +138,7 @@ boost::optional<LuaElementConvertor::Documentation> DiscoInfoConvertor::getDocum
             "  - `type`: string\n"
             "  - `language`: string\n"
             "- `features`: array(string)\n"
+            "- `extensions`: array(table)\n"
+            "-   `form`: string @{Form} (Optional)\n"
     );
 }
diff --git a/Sluift/ElementConvertors/DiscoInfoConvertor.h b/Sluift/ElementConvertors/DiscoInfoConvertor.h
index 34f8237..c1b2910 100644
--- a/Sluift/ElementConvertors/DiscoInfoConvertor.h
+++ b/Sluift/ElementConvertors/DiscoInfoConvertor.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016 Isode Limited.
+ * Copyright (c) 2013-2017 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -12,13 +12,18 @@
 #include <Sluift/GenericLuaElementConvertor.h>
 
 namespace Swift {
+    class LuaElementConvertors;
+
     class DiscoInfoConvertor : public GenericLuaElementConvertor<DiscoInfo> {
         public:
-            DiscoInfoConvertor();
+            DiscoInfoConvertor(LuaElementConvertors* convertors);
             virtual ~DiscoInfoConvertor();
 
             virtual std::shared_ptr<DiscoInfo> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
             virtual void doConvertToLua(lua_State*, std::shared_ptr<DiscoInfo>) SWIFTEN_OVERRIDE;
             virtual boost::optional<Documentation> getDocumentation() const SWIFTEN_OVERRIDE;
+
+        private:
+            LuaElementConvertors* convertors;
     };
 }
diff --git a/Sluift/LuaElementConvertors.cpp b/Sluift/LuaElementConvertors.cpp
index aac4d93..db91761 100644
--- a/Sluift/LuaElementConvertors.cpp
+++ b/Sluift/LuaElementConvertors.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2016 Isode Limited.
+ * Copyright (c) 2013-2017 Isode Limited.
  * All rights reserved.
  * See the COPYING file for more information.
  */
@@ -53,7 +53,7 @@ LuaElementConvertors::LuaElementConvertors() {
     convertors.push_back(std::make_shared<VCardUpdateConvertor>());
     convertors.push_back(std::make_shared<FormConvertor>());
     convertors.push_back(std::make_shared<SoftwareVersionConvertor>());
-    convertors.push_back(std::make_shared<DiscoInfoConvertor>());
+    convertors.push_back(std::make_shared<DiscoInfoConvertor>(this));
     convertors.push_back(std::make_shared<DiscoItemsConvertor>());
     convertors.push_back(std::make_shared<IQConvertor>(this));
     convertors.push_back(std::make_shared<PresenceConvertor>(this));
-- 
cgit v0.10.2-6-g49f6