summaryrefslogtreecommitdiffstats
path: root/Sluift
diff options
context:
space:
mode:
Diffstat (limited to 'Sluift')
-rw-r--r--Sluift/.gitignore4
-rw-r--r--Sluift/ClientHelpers.cpp50
-rw-r--r--Sluift/ClientHelpers.h18
-rw-r--r--Sluift/Completer.cpp12
-rw-r--r--Sluift/Completer.h19
-rw-r--r--Sluift/Console.cpp283
-rw-r--r--Sluift/Console.h42
-rw-r--r--Sluift/EditlineTerminal.cpp101
-rw-r--r--Sluift/EditlineTerminal.h24
-rw-r--r--Sluift/ElementConvertors/BodyConvertor.cpp32
-rw-r--r--Sluift/ElementConvertors/BodyConvertor.h23
-rw-r--r--Sluift/ElementConvertors/CarbonsReceivedConvertor.cpp53
-rw-r--r--Sluift/ElementConvertors/CarbonsReceivedConvertor.h29
-rw-r--r--Sluift/ElementConvertors/CarbonsSentConvertor.cpp52
-rw-r--r--Sluift/ElementConvertors/CarbonsSentConvertor.h29
-rw-r--r--Sluift/ElementConvertors/CommandConvertor.cpp334
-rw-r--r--Sluift/ElementConvertors/CommandConvertor.h27
-rw-r--r--Sluift/ElementConvertors/DOMElementConvertor.cpp337
-rw-r--r--Sluift/ElementConvertors/DOMElementConvertor.h29
-rw-r--r--Sluift/ElementConvertors/DefaultElementConvertor.cpp23
-rw-r--r--Sluift/ElementConvertors/DefaultElementConvertor.h20
-rw-r--r--Sluift/ElementConvertors/DelayConvertor.cpp51
-rw-r--r--Sluift/ElementConvertors/DelayConvertor.h22
-rw-r--r--Sluift/ElementConvertors/DiscoInfoConvertor.cpp207
-rw-r--r--Sluift/ElementConvertors/DiscoInfoConvertor.h27
-rw-r--r--Sluift/ElementConvertors/DiscoItemsConvertor.cpp99
-rw-r--r--Sluift/ElementConvertors/DiscoItemsConvertor.h21
-rw-r--r--Sluift/ElementConvertors/ElementConvertors.ipp134
-rw-r--r--Sluift/ElementConvertors/FormConvertor.cpp670
-rw-r--r--Sluift/ElementConvertors/FormConvertor.h21
-rw-r--r--Sluift/ElementConvertors/ForwardedConvertor.cpp74
-rw-r--r--Sluift/ElementConvertors/ForwardedConvertor.h29
-rw-r--r--Sluift/ElementConvertors/IQConvertor.cpp75
-rw-r--r--Sluift/ElementConvertors/IQConvertor.h33
-rw-r--r--Sluift/ElementConvertors/IsodeIQDelegationConvertor.cpp50
-rw-r--r--Sluift/ElementConvertors/IsodeIQDelegationConvertor.h28
-rw-r--r--Sluift/ElementConvertors/MAMFinConvertor.cpp81
-rw-r--r--Sluift/ElementConvertors/MAMFinConvertor.h29
-rw-r--r--Sluift/ElementConvertors/MAMQueryConvertor.cpp88
-rw-r--r--Sluift/ElementConvertors/MAMQueryConvertor.h29
-rw-r--r--Sluift/ElementConvertors/MAMResultConvertor.cpp73
-rw-r--r--Sluift/ElementConvertors/MAMResultConvertor.h29
-rw-r--r--Sluift/ElementConvertors/MessageConvertor.cpp85
-rw-r--r--Sluift/ElementConvertors/MessageConvertor.h33
-rw-r--r--Sluift/ElementConvertors/PresenceConvertor.cpp97
-rw-r--r--Sluift/ElementConvertors/PresenceConvertor.h33
-rw-r--r--Sluift/ElementConvertors/PubSubAffiliationConvertor.cpp116
-rw-r--r--Sluift/ElementConvertors/PubSubAffiliationConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubAffiliationsConvertor.cpp106
-rw-r--r--Sluift/ElementConvertors/PubSubAffiliationsConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubConfigureConvertor.cpp54
-rw-r--r--Sluift/ElementConvertors/PubSubConfigureConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubCreateConvertor.cpp69
-rw-r--r--Sluift/ElementConvertors/PubSubCreateConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubDefaultConvertor.cpp93
-rw-r--r--Sluift/ElementConvertors/PubSubDefaultConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubEventAssociateConvertor.cpp49
-rw-r--r--Sluift/ElementConvertors/PubSubEventAssociateConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubEventCollectionConvertor.cpp94
-rw-r--r--Sluift/ElementConvertors/PubSubEventCollectionConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubEventConfigurationConvertor.cpp69
-rw-r--r--Sluift/ElementConvertors/PubSubEventConfigurationConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubEventConvertor.cpp32
-rw-r--r--Sluift/ElementConvertors/PubSubEventConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubEventDeleteConvertor.cpp69
-rw-r--r--Sluift/ElementConvertors/PubSubEventDeleteConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubEventDisassociateConvertor.cpp49
-rw-r--r--Sluift/ElementConvertors/PubSubEventDisassociateConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubEventItemConvertor.cpp152
-rw-r--r--Sluift/ElementConvertors/PubSubEventItemConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubEventItemsConvertor.cpp169
-rw-r--r--Sluift/ElementConvertors/PubSubEventItemsConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubEventPurgeConvertor.cpp49
-rw-r--r--Sluift/ElementConvertors/PubSubEventPurgeConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubEventRedirectConvertor.cpp49
-rw-r--r--Sluift/ElementConvertors/PubSubEventRedirectConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubEventRetractConvertor.cpp49
-rw-r--r--Sluift/ElementConvertors/PubSubEventRetractConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.cpp145
-rw-r--r--Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubItemConvertor.cpp110
-rw-r--r--Sluift/ElementConvertors/PubSubItemConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubItemsConvertor.cpp140
-rw-r--r--Sluift/ElementConvertors/PubSubItemsConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubOptionsConvertor.cpp103
-rw-r--r--Sluift/ElementConvertors/PubSubOptionsConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerAffiliationConvertor.cpp116
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerAffiliationConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.cpp102
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.cpp73
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerDefaultConvertor.cpp54
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerDefaultConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.cpp69
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.cpp49
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.cpp49
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.cpp98
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.cpp102
-rw-r--r--Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubPublishConvertor.cpp110
-rw-r--r--Sluift/ElementConvertors/PubSubPublishConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubRetractConvertor.cpp127
-rw-r--r--Sluift/ElementConvertors/PubSubRetractConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubSubscribeConvertor.cpp88
-rw-r--r--Sluift/ElementConvertors/PubSubSubscribeConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.cpp49
-rw-r--r--Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.h27
-rw-r--r--Sluift/ElementConvertors/PubSubSubscriptionConvertor.cpp156
-rw-r--r--Sluift/ElementConvertors/PubSubSubscriptionConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubSubscriptionsConvertor.cpp106
-rw-r--r--Sluift/ElementConvertors/PubSubSubscriptionsConvertor.h28
-rw-r--r--Sluift/ElementConvertors/PubSubUnsubscribeConvertor.cpp87
-rw-r--r--Sluift/ElementConvertors/PubSubUnsubscribeConvertor.h27
-rw-r--r--Sluift/ElementConvertors/RawXMLElementConvertor.cpp33
-rw-r--r--Sluift/ElementConvertors/RawXMLElementConvertor.h25
-rw-r--r--Sluift/ElementConvertors/ResultSetConvertor.cpp116
-rw-r--r--Sluift/ElementConvertors/ResultSetConvertor.h26
-rw-r--r--Sluift/ElementConvertors/SConscript86
-rw-r--r--Sluift/ElementConvertors/SecurityLabelConvertor.cpp98
-rw-r--r--Sluift/ElementConvertors/SecurityLabelConvertor.h25
-rw-r--r--Sluift/ElementConvertors/SoftwareVersionConvertor.cpp63
-rw-r--r--Sluift/ElementConvertors/SoftwareVersionConvertor.h21
-rw-r--r--Sluift/ElementConvertors/StanzaConvertor.h88
-rw-r--r--Sluift/ElementConvertors/StatusConvertor.cpp39
-rw-r--r--Sluift/ElementConvertors/StatusConvertor.h22
-rw-r--r--Sluift/ElementConvertors/StatusShowConvertor.cpp77
-rw-r--r--Sluift/ElementConvertors/StatusShowConvertor.h25
-rw-r--r--Sluift/ElementConvertors/SubjectConvertor.cpp37
-rw-r--r--Sluift/ElementConvertors/SubjectConvertor.h24
-rw-r--r--Sluift/ElementConvertors/UserLocationConvertor.cpp450
-rw-r--r--Sluift/ElementConvertors/UserLocationConvertor.h27
-rw-r--r--Sluift/ElementConvertors/UserTuneConvertor.cpp108
-rw-r--r--Sluift/ElementConvertors/UserTuneConvertor.h25
-rw-r--r--Sluift/ElementConvertors/VCardConvertor.cpp639
-rw-r--r--Sluift/ElementConvertors/VCardConvertor.h21
-rw-r--r--Sluift/ElementConvertors/VCardUpdateConvertor.cpp35
-rw-r--r--Sluift/ElementConvertors/VCardUpdateConvertor.h21
-rw-r--r--Sluift/Examples/AdHocCommands.lua6
-rw-r--r--Sluift/Examples/CollectVersions.lua6
-rw-r--r--Sluift/Examples/Component.lua55
-rw-r--r--Sluift/Examples/ContactsMap.lua6
-rw-r--r--Sluift/Examples/EchoBot.lua6
-rw-r--r--Sluift/Examples/EchoBot_With.lua32
-rw-r--r--Sluift/Examples/Login.lua8
-rw-r--r--Sluift/Examples/MAMRSM.lua23
-rw-r--r--Sluift/Examples/MAMRSMPage.lua36
-rw-r--r--Sluift/Examples/MAMSimple.lua19
-rw-r--r--Sluift/Examples/MAMSupportedFields.lua18
-rw-r--r--Sluift/Examples/MAMUser.lua25
-rw-r--r--Sluift/Examples/PEPListener.lua6
-rw-r--r--Sluift/Examples/RemoveUnreachableContacts.lua6
-rw-r--r--Sluift/Examples/SendReference.lua74
-rw-r--r--Sluift/Examples/Tunes.lua68
-rwxr-xr-xSluift/Examples/Wonderland.lua6
-rw-r--r--Sluift/GenerateDocumentation.lua90
-rw-r--r--Sluift/GenericLuaElementConvertor.h82
-rw-r--r--Sluift/Helpers.cpp65
-rw-r--r--Sluift/Helpers.h19
-rw-r--r--Sluift/ITunesInterface.h40
-rw-r--r--Sluift/ITunesInterface.mm58
-rw-r--r--Sluift/Lua/Check.cpp74
-rw-r--r--Sluift/Lua/Check.h27
-rw-r--r--Sluift/Lua/Debug.h37
-rw-r--r--Sluift/Lua/Exception.cpp6
-rw-r--r--Sluift/Lua/Exception.h23
-rw-r--r--Sluift/Lua/FunctionRegistration.cpp8
-rw-r--r--Sluift/Lua/FunctionRegistration.h57
-rw-r--r--Sluift/Lua/FunctionRegistry.cpp62
-rw-r--r--Sluift/Lua/FunctionRegistry.h71
-rw-r--r--Sluift/Lua/LuaUtils.cpp221
-rw-r--r--Sluift/Lua/LuaUtils.h66
-rw-r--r--Sluift/Lua/Value.cpp80
-rw-r--r--Sluift/Lua/Value.h92
-rw-r--r--Sluift/LuaElementConvertor.cpp4
-rw-r--r--Sluift/LuaElementConvertor.h35
-rw-r--r--Sluift/LuaElementConvertors.cpp177
-rw-r--r--Sluift/LuaElementConvertors.h71
-rw-r--r--Sluift/Response.cpp113
-rw-r--r--Sluift/Response.h46
-rw-r--r--Sluift/SConscript151
-rw-r--r--Sluift/SConscript.variant47
-rw-r--r--Sluift/SluiftClient.cpp292
-rw-r--r--Sluift/SluiftClient.h241
-rw-r--r--Sluift/SluiftComponent.cpp149
-rw-r--r--Sluift/SluiftComponent.h109
-rw-r--r--Sluift/SluiftGlobals.h35
-rw-r--r--Sluift/StandardTerminal.cpp39
-rw-r--r--Sluift/StandardTerminal.h21
-rw-r--r--Sluift/Terminal.cpp15
-rw-r--r--Sluift/Terminal.h36
-rw-r--r--Sluift/Tests/FormTest.lua43
-rw-r--r--Sluift/UnitTest/TokenizeTest.cpp64
-rw-r--r--Sluift/Watchdog.cpp50
-rw-r--r--Sluift/Watchdog.h52
-rw-r--r--Sluift/boot.lua436
-rw-r--r--Sluift/client.cpp1337
-rw-r--r--Sluift/component.cpp465
-rw-r--r--Sluift/core.lua1244
-rw-r--r--Sluift/globals.h10
-rw-r--r--Sluift/linit.c27
-rw-r--r--Sluift/main.cpp192
-rw-r--r--Sluift/sluift.cpp615
-rw-r--r--Sluift/sluift.h6
-rw-r--r--Sluift/tokenize.cpp87
-rw-r--r--Sluift/tokenize.h16
210 files changed, 12261 insertions, 5526 deletions
diff --git a/Sluift/.gitignore b/Sluift/.gitignore
index e5fd1e5..4e4c2a4 100644
--- a/Sluift/.gitignore
+++ b/Sluift/.gitignore
@@ -1,7 +1,9 @@
lua.c
+Version.h
sluift_dll.cpp
sluift
dll.c
-boot.c
+core.c
+iTunes.h
dll/
exe/
diff --git a/Sluift/ClientHelpers.cpp b/Sluift/ClientHelpers.cpp
deleted file mode 100644
index 8e07112..0000000
--- a/Sluift/ClientHelpers.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
- * See the COPYING file for more information.
- */
-
-#include <Sluift/ClientHelpers.h>
-
-#include <Swiften/Client/ClientError.h>
-
-using namespace Swift;
-
-std::string Swift::getClientErrorString(const ClientError& error) {
- std::string reason = "Disconnected: ";
- switch(error.getType()) {
- case ClientError::UnknownError: reason += "Unknown Error"; break;
- case ClientError::DomainNameResolveError: reason += "Unable to find server"; break;
- case ClientError::ConnectionError: reason += "Error connecting to server"; break;
- case ClientError::ConnectionReadError: reason += "Error while receiving server data"; break;
- case ClientError::ConnectionWriteError: reason += "Error while sending data to the server"; break;
- case ClientError::XMLError: reason += "Error parsing server data"; break;
- case ClientError::AuthenticationFailedError: reason += "Login/password invalid"; break;
- case ClientError::CompressionFailedError: reason += "Error while compressing stream"; break;
- case ClientError::ServerVerificationFailedError: reason += "Server verification failed"; break;
- case ClientError::NoSupportedAuthMechanismsError: reason += "Authentication mechanisms not supported"; break;
- case ClientError::UnexpectedElementError: reason += "Unexpected response"; break;
- case ClientError::ResourceBindError: reason += "Error binding resource"; break;
- case ClientError::RevokedError: reason += "Certificate got revoked"; break;
- case ClientError::RevocationCheckFailedError: reason += "Failed to do revokation check"; break;
- case ClientError::SessionStartError: reason += "Error starting session"; break;
- case ClientError::StreamError: reason += "Stream error"; break;
- case ClientError::TLSError: reason += "Encryption error"; break;
- case ClientError::ClientCertificateLoadError: reason += "Error loading certificate (Invalid password?)"; break;
- case ClientError::ClientCertificateError: reason += "Certificate not authorized"; break;
- case ClientError::UnknownCertificateError: reason += "Unknown certificate"; break;
- case ClientError::CertificateCardRemoved: reason += "Certificate card removed"; break;
- case ClientError::CertificateExpiredError: reason += "Certificate has expired"; break;
- case ClientError::CertificateNotYetValidError: reason += "Certificate is not yet valid"; break;
- case ClientError::CertificateSelfSignedError: reason += "Certificate is self-signed"; break;
- case ClientError::CertificateRejectedError: reason += "Certificate has been rejected"; break;
- case ClientError::CertificateUntrustedError: reason += "Certificate is not trusted"; break;
- case ClientError::InvalidCertificatePurposeError: reason += "Certificate cannot be used for encrypting your connection"; break;
- case ClientError::CertificatePathLengthExceededError: reason += "Certificate path length constraint exceeded"; break;
- case ClientError::InvalidCertificateSignatureError: reason += "Invalid certificate signature"; break;
- case ClientError::InvalidCAError: reason += "Invalid Certificate Authority"; break;
- case ClientError::InvalidServerIdentityError: reason += "Certificate does not match the host identity"; break;
- }
- return reason;
-}
-
diff --git a/Sluift/ClientHelpers.h b/Sluift/ClientHelpers.h
deleted file mode 100644
index eb78ba6..0000000
--- a/Sluift/ClientHelpers.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
- * See the COPYING file for more information.
- */
-
-#pragma once
-
-#include <Swiften/Base/Override.h>
-#include <Swiften/Base/API.h>
-
-#include <string>
-
-namespace Swift {
- class ClientError;
-
- std::string getClientErrorString(const ClientError& error);
-}
diff --git a/Sluift/Completer.cpp b/Sluift/Completer.cpp
new file mode 100644
index 0000000..2ef491e
--- /dev/null
+++ b/Sluift/Completer.cpp
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/Completer.h>
+
+using namespace Swift;
+
+Completer::~Completer() {
+}
diff --git a/Sluift/Completer.h b/Sluift/Completer.h
new file mode 100644
index 0000000..564c647
--- /dev/null
+++ b/Sluift/Completer.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+namespace Swift {
+ class Completer {
+ public:
+ virtual ~Completer();
+
+ virtual std::vector<std::string> getCompletions(const std::string& buffer, int start, int end) = 0;
+ };
+}
diff --git a/Sluift/Console.cpp b/Sluift/Console.cpp
new file mode 100644
index 0000000..ef0b1a4
--- /dev/null
+++ b/Sluift/Console.cpp
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/Console.h>
+
+#include <cctype>
+#include <iostream>
+#include <stdexcept>
+
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/optional.hpp>
+
+#include <lua.hpp>
+
+#include <Sluift/Lua/LuaUtils.h>
+#include <Sluift/Terminal.h>
+#include <Sluift/tokenize.h>
+
+using namespace Swift;
+
+/**
+ * This function is called by pcall() when an error happens.
+ * Adds the backtrace to the error message.
+ */
+static int traceback(lua_State* L) {
+ if (!lua_isstring(L, 1)) {
+ return 1;
+ }
+ lua_getglobal(L, "debug");
+ if (!lua_istable(L, -1)) {
+ lua_pop(L, 1);
+ return 1;
+ }
+ lua_getfield(L, -1, "traceback");
+ if (!lua_isfunction(L, -1)) {
+ lua_pop(L, 2);
+ return 1;
+ }
+ lua_pushvalue(L, 1);
+ lua_pushinteger(L, 2);
+ lua_call(L, 2, 1);
+ return 1;
+}
+
+
+Console::Console(lua_State* L, Terminal* terminal) : L(L), terminal(terminal), previousNumberOfReturnArguments(0) {
+ terminal->setCompleter(this);
+}
+
+Console::~Console() {
+}
+
+void Console::run() {
+ while (true) {
+ lua_settop(L, 0);
+ try {
+ if (!readCommand()) {
+ return;
+ }
+ int result = call(L, 0, true);
+ if (result != 0) {
+ throw std::runtime_error(getErrorMessage());
+ }
+
+ // Clear the previous results
+ for (int i = 0; i < previousNumberOfReturnArguments; ++i) {
+ lua_pushnil(L);
+ lua_setglobal(L, ("_" + boost::lexical_cast<std::string>(i+1)).c_str());
+ }
+
+ // Store the results
+ for (int i = 0; i < lua_gettop(L); ++i) {
+ lua_pushvalue(L, i+1);
+ lua_setglobal(L, ("_" + boost::lexical_cast<std::string>(i+1)).c_str());
+ }
+ previousNumberOfReturnArguments = lua_gettop(L);
+
+ // Print results
+ if (lua_gettop(L) > 0) {
+ lua_getglobal(L, "print");
+ lua_insert(L, 1);
+ if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) {
+ throw std::runtime_error("Error calling 'print': " + getErrorMessage());
+ }
+ }
+ }
+ catch (const std::exception& e) {
+ terminal->printError(e.what());
+ }
+ }
+
+}
+
+int Console::tryLoadCommand(const std::string& originalCommand) {
+ std::string command = originalCommand;
+
+ // Replace '=' by 'return' (for compatibility with Lua console)
+ if (boost::algorithm::starts_with(command, "=")) {
+ command = "return " + command.substr(1);
+ }
+
+ std::string commandAsExpression = "return " + command;
+
+ // Try to load the command as an expression
+ if (luaL_loadbuffer(L, commandAsExpression.c_str(), commandAsExpression.size(), "=stdin") == 0) {
+ return 0;
+ }
+ lua_pop(L, 1);
+
+ // Try to load the command as a regular command
+ return luaL_loadbuffer(L, command.c_str(), command.size(), "=stdin");
+}
+
+bool Console::readCommand() {
+ boost::optional<std::string> line = terminal->readLine(getPrompt(true));
+ if (!line) {
+ return false;
+ }
+ std::string command = *line;
+ while (true) {
+ int result = tryLoadCommand(command);
+
+ // Check if we need to read more
+ if (result == LUA_ERRSYNTAX) {
+ std::string errorMessage(lua_tostring(L, -1));
+ if (boost::algorithm::ends_with(errorMessage, "'<eof>'")) {
+ lua_pop(L, 1);
+
+ // Read another line
+ boost::optional<std::string> line = terminal->readLine(getPrompt(false));
+ if (!line) {
+ return false;
+ }
+ command = command + "\n" + *line;
+ continue;
+ }
+ }
+ if (!command.empty()) {
+ terminal->addToHistory(command);
+ }
+ if (result != 0) {
+ throw std::runtime_error(getErrorMessage());
+ }
+ return true;
+ }
+}
+
+std::string Console::getErrorMessage() const {
+ if (lua_isnil(L, -1)) {
+ return "<null error>";
+ }
+ const char* errorMessage = lua_tostring(L, -1);
+ return errorMessage ? errorMessage : "<error is not a string>";
+}
+
+int Console::call(lua_State* L, int numberOfArguments, bool keepResult) {
+ // Put traceback function on stack below call
+ int tracebackIndex = lua_gettop(L) - numberOfArguments;
+ lua_pushcfunction(L, traceback);
+ lua_insert(L, tracebackIndex);
+
+ int result = lua_pcall(L, numberOfArguments, keepResult ? LUA_MULTRET : 0, tracebackIndex);
+
+ // Remove traceback
+ lua_remove(L, tracebackIndex);
+
+ return result;
+}
+
+std::string Console::getPrompt(bool firstLine) const {
+ lua_getglobal(L,firstLine ? "_PROMPT" : "_PROMPT2");
+ const char* rawPrompt = lua_tostring(L, -1);
+ std::string prompt;
+ if (rawPrompt) {
+ prompt = std::string(rawPrompt);
+ }
+ else {
+ prompt = firstLine ? "> " : ">> ";
+ }
+ lua_pop(L, 1);
+ return prompt;
+}
+
+static void addMatchingTableKeys(lua_State* L, const std::string& match, std::vector<std::string>& result) {
+ for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
+ const char* rawKey = lua_tostring(L, -2);
+ if (rawKey) {
+ std::string key(rawKey);
+ if (boost::starts_with(key, match) && !(match == "" && boost::starts_with(key, "_"))) {
+ result.push_back(key);
+ }
+ }
+ }
+}
+
+static void addMatchingTableValues(lua_State* L, const std::string& match, std::vector<std::string>& result) {
+ for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
+ const char* rawValue = lua_tostring(L, -1);
+ if (rawValue) {
+ std::string key(rawValue);
+ if (boost::starts_with(key, match) && !(match == "" && boost::starts_with(key, "_"))) {
+ result.push_back(key);
+ }
+ }
+ }
+}
+
+std::vector<std::string> Console::getCompletions(const std::string& input, int start, int end) {
+ std::string prefix = input.substr(boost::numeric_cast<size_t>(start), boost::numeric_cast<size_t>(end - start));
+
+ std::vector<std::string> tokens;
+ if (end) {
+ tokens = Lua::tokenize(input.substr(0, boost::numeric_cast<size_t>(end)));
+ }
+
+ // Don't autocomplete strings
+ if (!tokens.empty() && ((*tokens.rbegin())[0] == '\'' || (*tokens.rbegin())[0] == '"')) {
+ return std::vector<std::string>();
+ }
+
+ std::vector<std::string> context;
+ for (std::vector<std::string>::reverse_iterator i = tokens.rbegin(); i != tokens.rend(); ++i) {
+ if (std::isalpha((*i)[0]) || (*i)[0] == '_') {
+ if (i != tokens.rbegin()) {
+ context.push_back(*i);
+ }
+ }
+ else if (*i != "." && *i != ":") {
+ break;
+ }
+ }
+
+ // Drill into context
+ int top = lua_gettop(L);
+ lua_pushglobaltable(L);
+ for (std::vector<std::string>::reverse_iterator i = context.rbegin(); i != context.rend(); ++i) {
+ if (lua_istable(L, -1) || lua_isuserdata(L, -1)) {
+ lua_getfield(L, -1, i->c_str());
+ if (!lua_isnil(L, 1)) {
+ continue;
+ }
+ }
+ lua_settop(L, top);
+ return std::vector<std::string>();
+ }
+
+ // Collect all keys from the table
+ std::vector<std::string> result;
+ if (lua_istable(L, -1)) {
+ addMatchingTableKeys(L, prefix, result);
+ }
+
+ // Collect all keys from the metatable
+ if (lua_getmetatable(L, -1)) {
+ lua_getfield(L, -1, "__index");
+ if (lua_istable(L, -1)) {
+ addMatchingTableKeys(L, prefix, result);
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "_completions");
+ if (lua_isfunction(L, -1)) {
+ lua_pushvalue(L, -3);
+ if (lua_pcall(L, 1, 1, 0) != 0) {
+ throw std::runtime_error("Error calling '_completions': " + getErrorMessage());
+ }
+ }
+ if (lua_istable(L, -1)) {
+ addMatchingTableValues(L, prefix, result);
+ }
+ lua_pop(L, 2);
+ }
+
+ lua_settop(L, top);
+
+ return result;
+}
+
diff --git a/Sluift/Console.h b/Sluift/Console.h
new file mode 100644
index 0000000..0d5ceb0
--- /dev/null
+++ b/Sluift/Console.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <boost/optional/optional.hpp>
+
+#include <Sluift/Completer.h>
+
+struct lua_State;
+
+namespace Swift {
+ class Terminal;
+
+ class Console : public Completer {
+ public:
+ Console(lua_State* L, Terminal* terminal);
+ virtual ~Console() override;
+
+ void run();
+
+ static int call(lua_State* L, int numberOfArguments, bool keepResult);
+
+ private:
+ std::string getPrompt(bool firstLine) const;
+ std::string getErrorMessage() const;
+ bool readCommand();
+ int tryLoadCommand(const std::string& command);
+
+ virtual std::vector<std::string> getCompletions(const std::string&, int start, int end) override;
+
+ private:
+ lua_State* L;
+ Terminal* terminal;
+ int previousNumberOfReturnArguments;
+ };
+}
diff --git a/Sluift/EditlineTerminal.cpp b/Sluift/EditlineTerminal.cpp
new file mode 100644
index 0000000..206ced6
--- /dev/null
+++ b/Sluift/EditlineTerminal.cpp
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/EditlineTerminal.h>
+
+#include <cassert>
+#include <cstring>
+#include <iostream>
+#include <vector>
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/optional.hpp>
+
+#include <editline/readline.h>
+
+#include <Swiften/Base/Platform.h>
+
+#include <Sluift/Completer.h>
+
+using namespace Swift;
+
+static EditlineTerminal* globalInstance = nullptr;
+
+static int completionStart = -1;
+static int completionEnd = -1;
+
+#if defined(SWIFTEN_PLATFORM_WINDOWS)
+static char* getEmptyCompletions(const char*, int) {
+#else
+static int getEmptyCompletions(const char*, int) {
+#endif
+ return 0;
+}
+
+static char* getCompletions(const char*, int state) {
+ rl_completion_append_character = 0;
+#if RL_READLINE_VERSION >= 0x0600
+ rl_completion_suppress_append = 1;
+#endif
+
+ static std::vector<std::string> completions;
+ if (state == 0) {
+ assert(globalInstance);
+ completions.clear();
+ if (globalInstance->getCompleter()) {
+ completions = globalInstance->getCompleter()->getCompletions(rl_line_buffer, completionStart, completionEnd);
+ }
+ }
+ if (boost::numeric_cast<size_t>(state) >= completions.size()) {
+ return nullptr;
+ }
+ return strdup(completions[boost::numeric_cast<size_t>(state)].c_str());
+}
+
+static char** getAttemptedCompletions(const char* text, int start, int end) {
+ completionStart = start;
+ completionEnd = end;
+ return rl_completion_matches(text, getCompletions);
+}
+
+EditlineTerminal& EditlineTerminal::getInstance() {
+ static EditlineTerminal instance;
+ globalInstance = &instance;
+ return instance;
+}
+
+EditlineTerminal::EditlineTerminal() {
+ rl_attempted_completion_function = getAttemptedCompletions;
+ rl_completion_entry_function = getEmptyCompletions; // Fallback. Do nothing.
+#if defined(SWIFTEN_PLATFORM_WINDOWS)
+ // rl_basic_word_break is a cons char[] in MinGWEditLine.
+ // This one seems to work, although it doesn't on OS X for some reason.
+ rl_completer_word_break_characters = strdup(" \t\n.:+-*/><=;|&()[]{}");
+#else
+ rl_basic_word_break_characters = strdup(" \t\n.:+-*/><=;|&()[]{}");
+#endif
+}
+
+EditlineTerminal::~EditlineTerminal() {
+}
+
+void EditlineTerminal::printError(const std::string& message) {
+ std::cout << message << std::endl;
+}
+
+boost::optional<std::string> EditlineTerminal::readLine(const std::string& prompt) {
+ const char* line = readline(prompt.c_str());
+ return line ? std::string(line) : boost::optional<std::string>();
+}
+
+void EditlineTerminal::addToHistory(const std::string& line) {
+#if defined(SWIFTEN_PLATFORM_WINDOWS)
+ // MinGWEditLine copies the string, so this is safe
+ add_history(const_cast<char*>(line.c_str()));
+#else
+ add_history(line.c_str());
+#endif
+}
diff --git a/Sluift/EditlineTerminal.h b/Sluift/EditlineTerminal.h
new file mode 100644
index 0000000..8f4624b
--- /dev/null
+++ b/Sluift/EditlineTerminal.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Sluift/Terminal.h>
+
+namespace Swift {
+ class EditlineTerminal : public Terminal {
+ public:
+ static EditlineTerminal& getInstance();
+
+ private:
+ EditlineTerminal();
+ virtual ~EditlineTerminal() override;
+
+ virtual boost::optional<std::string> readLine(const std::string& prompt) override;
+ virtual void printError(const std::string& message) override;
+ virtual void addToHistory(const std::string& command) override;
+ };
+}
diff --git a/Sluift/ElementConvertors/BodyConvertor.cpp b/Sluift/ElementConvertors/BodyConvertor.cpp
index a7abc1e..f6797b0 100644
--- a/Sluift/ElementConvertors/BodyConvertor.cpp
+++ b/Sluift/ElementConvertors/BodyConvertor.cpp
@@ -1,13 +1,15 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/BodyConvertor.h>
+#include <memory>
+
#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+
#include <Sluift/Lua/LuaUtils.h>
using namespace Swift;
@@ -18,18 +20,18 @@ BodyConvertor::BodyConvertor() : GenericLuaElementConvertor<Body>("body") {
BodyConvertor::~BodyConvertor() {
}
-boost::shared_ptr<Body> BodyConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<Body> result = boost::make_shared<Body>();
- if (boost::optional<std::string> value = Lua::getStringField(L, -1, "text")) {
- result->setText(*value);
- }
- return result;
+std::shared_ptr<Body> BodyConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<Body> result = std::make_shared<Body>();
+ if (boost::optional<std::string> value = Lua::getStringField(L, -1, "text")) {
+ result->setText(*value);
+ }
+ return result;
}
-void BodyConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<Body> payload) {
- lua_createtable(L, 0, 0);
- if (!payload->getText().empty()) {
- lua_pushstring(L, payload->getText().c_str());
- lua_setfield(L, -2, "text");
- }
+void BodyConvertor::doConvertToLua(lua_State* L, std::shared_ptr<Body> payload) {
+ lua_createtable(L, 0, 0);
+ if (!payload->getText().empty()) {
+ lua_pushstring(L, payload->getText().c_str());
+ lua_setfield(L, -2, "text");
+ }
}
diff --git a/Sluift/ElementConvertors/BodyConvertor.h b/Sluift/ElementConvertors/BodyConvertor.h
index b1cd494..574fca9 100644
--- a/Sluift/ElementConvertors/BodyConvertor.h
+++ b/Sluift/ElementConvertors/BodyConvertor.h
@@ -1,25 +1,24 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/Body.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/Body.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class BodyConvertor : public GenericLuaElementConvertor<Body> {
- public:
- BodyConvertor();
- virtual ~BodyConvertor();
+ class BodyConvertor : public GenericLuaElementConvertor<Body> {
+ public:
+ BodyConvertor();
+ virtual ~BodyConvertor() override;
- virtual boost::shared_ptr<Body> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<Body>) SWIFTEN_OVERRIDE;
- };
+ virtual std::shared_ptr<Body> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<Body>) override;
+ };
}
diff --git a/Sluift/ElementConvertors/CarbonsReceivedConvertor.cpp b/Sluift/ElementConvertors/CarbonsReceivedConvertor.cpp
new file mode 100644
index 0000000..cfd55f3
--- /dev/null
+++ b/Sluift/ElementConvertors/CarbonsReceivedConvertor.cpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/CarbonsReceivedConvertor.h>
+
+#include <memory>
+#include <lua.hpp>
+
+#include <Swiften/Elements/Forwarded.h>
+
+#include <Sluift/LuaElementConvertors.h>
+
+using namespace Swift;
+
+CarbonsReceivedConvertor::CarbonsReceivedConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<CarbonsReceived>("carbons_received"),
+ convertors(convertors) {
+}
+
+CarbonsReceivedConvertor::~CarbonsReceivedConvertor() {
+}
+
+std::shared_ptr<CarbonsReceived> CarbonsReceivedConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<CarbonsReceived> result = std::make_shared<CarbonsReceived>();
+ lua_getfield(L, -1, "payload");
+ if (!lua_isnil(L, -1)) {
+ std::shared_ptr<Forwarded> payload = std::dynamic_pointer_cast<Forwarded>(convertors->convertFromLuaUntyped(L, -1, "payload"));
+ if (!!payload) {
+ result->setForwarded(payload);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void CarbonsReceivedConvertor::doConvertToLua(lua_State* L, std::shared_ptr<CarbonsReceived> payload) {
+ lua_createtable(L, 0, 0);
+ if (convertors->convertToLuaUntyped(L, payload->getForwarded()) > 0) {
+ lua_setfield(L, -2, "payload");
+
+ }
+}
+
+boost::optional<LuaElementConvertor::Documentation> CarbonsReceivedConvertor::getDocumentation() const {
+ return Documentation(
+ "CarbonsReceived",
+ "This table has the following fields:\n\n"
+ "- `payload`: @{Forwarded}\n"
+ );
+}
diff --git a/Sluift/ElementConvertors/CarbonsReceivedConvertor.h b/Sluift/ElementConvertors/CarbonsReceivedConvertor.h
new file mode 100644
index 0000000..cc4e6dc
--- /dev/null
+++ b/Sluift/ElementConvertors/CarbonsReceivedConvertor.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/CarbonsReceived.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class CarbonsReceivedConvertor : public GenericLuaElementConvertor<CarbonsReceived> {
+ public:
+ CarbonsReceivedConvertor(LuaElementConvertors* convertors);
+ virtual ~CarbonsReceivedConvertor() override;
+
+ virtual std::shared_ptr<CarbonsReceived> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<CarbonsReceived>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+
+ private:
+ LuaElementConvertors* convertors;
+ };
+}
+
diff --git a/Sluift/ElementConvertors/CarbonsSentConvertor.cpp b/Sluift/ElementConvertors/CarbonsSentConvertor.cpp
new file mode 100644
index 0000000..45851d2
--- /dev/null
+++ b/Sluift/ElementConvertors/CarbonsSentConvertor.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/CarbonsSentConvertor.h>
+
+#include <memory>
+#include <lua.hpp>
+
+#include <Swiften/Elements/Forwarded.h>
+
+#include <Sluift/LuaElementConvertors.h>
+
+using namespace Swift;
+
+CarbonsSentConvertor::CarbonsSentConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<CarbonsSent>("carbons_sent"),
+ convertors(convertors) {
+}
+
+CarbonsSentConvertor::~CarbonsSentConvertor() {
+}
+
+std::shared_ptr<CarbonsSent> CarbonsSentConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<CarbonsSent> result = std::make_shared<CarbonsSent>();
+ lua_getfield(L, -1, "payload");
+ if (!lua_isnil(L, -1)) {
+ std::shared_ptr<Forwarded> payload = std::dynamic_pointer_cast<Forwarded>(convertors->convertFromLuaUntyped(L, -1, "payload"));
+ if (!!payload) {
+ result->setForwarded(payload);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void CarbonsSentConvertor::doConvertToLua(lua_State* L, std::shared_ptr<CarbonsSent> payload) {
+ lua_createtable(L, 0, 0);
+ if (convertors->convertToLuaUntyped(L, payload->getForwarded()) > 0) {
+ lua_setfield(L, -2, "payload");
+ }
+}
+
+boost::optional<LuaElementConvertor::Documentation> CarbonsSentConvertor::getDocumentation() const {
+ return Documentation(
+ "CarbonsSent",
+ "This table has the following fields:\n\n"
+ "- `payload`: @{Forwarded}\n"
+ );
+}
diff --git a/Sluift/ElementConvertors/CarbonsSentConvertor.h b/Sluift/ElementConvertors/CarbonsSentConvertor.h
new file mode 100644
index 0000000..794e0ed
--- /dev/null
+++ b/Sluift/ElementConvertors/CarbonsSentConvertor.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/CarbonsSent.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class CarbonsSentConvertor : public GenericLuaElementConvertor<CarbonsSent> {
+ public:
+ CarbonsSentConvertor(LuaElementConvertors* convertors);
+ virtual ~CarbonsSentConvertor() override;
+
+ virtual std::shared_ptr<CarbonsSent> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<CarbonsSent>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+
+ private:
+ LuaElementConvertors* convertors;
+ };
+}
+
diff --git a/Sluift/ElementConvertors/CommandConvertor.cpp b/Sluift/ElementConvertors/CommandConvertor.cpp
index 7fb7b22..de7a439 100644
--- a/Sluift/ElementConvertors/CommandConvertor.cpp
+++ b/Sluift/ElementConvertors/CommandConvertor.cpp
@@ -1,16 +1,17 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/CommandConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
-#include <Swiften/Base/foreach.h>
+#include <lua.hpp>
+
#include <Sluift/Lua/Check.h>
#include <Sluift/Lua/Value.h>
#include <Sluift/LuaElementConvertors.h>
@@ -18,178 +19,177 @@
using namespace Swift;
static Command::Action convertActionFromString(const std::string& action) {
- if (action == "cancel") { return Command::Cancel; }
- else if (action == "execute") { return Command::Execute; }
- else if (action == "complete") { return Command::Complete; }
- else if (action == "prev") { return Command::Prev; }
- else if (action == "next") { return Command::Next; }
- return Command::NoAction;
+ if (action == "cancel") { return Command::Cancel; }
+ else if (action == "execute") { return Command::Execute; }
+ else if (action == "complete") { return Command::Complete; }
+ else if (action == "prev") { return Command::Prev; }
+ else if (action == "next") { return Command::Next; }
+ return Command::NoAction;
}
static std::string convertActionToString(Command::Action action) {
- switch (action) {
- case Command::Cancel: return "cancel";
- case Command::Execute: return "execute";
- case Command::Complete: return "complete";
- case Command::Prev: return "prev";
- case Command::Next: return "next";
- case Command::NoAction: assert(false); return "";
- }
- assert(false);
- return "";
+ switch (action) {
+ case Command::Cancel: return "cancel";
+ case Command::Execute: return "execute";
+ case Command::Complete: return "complete";
+ case Command::Prev: return "prev";
+ case Command::Next: return "next";
+ case Command::NoAction: assert(false); return "";
+ }
+ assert(false);
+ return "";
}
-CommandConvertor::CommandConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<Command>("command"),
- convertors(convertors) {
+CommandConvertor::CommandConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<Command>("command"),
+ convertors(convertors) {
}
CommandConvertor::~CommandConvertor() {
}
-boost::shared_ptr<Command> CommandConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<Command> result = boost::make_shared<Command>();
-
- lua_getfield(L, -1, "node");
- if (!lua_isnil(L, -1)) {
- result->setNode(std::string(Lua::checkString(L, -1)));
- }
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "session_id");
- if (!lua_isnil(L, -1)) {
- result->setSessionID(std::string(Lua::checkString(L, -1)));
- }
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "status");
- if (!lua_isnil(L, -1)) {
- std::string statusText = Lua::checkString(L, -1);
- Command::Status status = Command::NoStatus;
- if (statusText == "executing") { status = Command::Executing; }
- else if (statusText == "completed") { status = Command::Completed; }
- else if (statusText == "canceled") { status = Command::Canceled; }
- result->setStatus(status);
- }
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "action");
- if (!lua_isnil(L, -1)) {
- result->setAction(convertActionFromString(Lua::checkString(L, -1)));
- }
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "execute_action");
- if (!lua_isnil(L, -1)) {
- result->setExecuteAction(convertActionFromString(Lua::checkString(L, -1)));
- }
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "available_actions");
- if (!lua_isnil(L, -1)) {
- Lua::checkType(L, -1, LUA_TTABLE);
- lua_pushnil(L);
- for (lua_pushnil(L); lua_next(L, -2) != 0; ) {
- result->addAvailableAction(convertActionFromString(Lua::checkString(L, -1)));
- lua_pop(L, 1);
- }
- }
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "notes");
- if (!lua_isnil(L, -1)) {
- Lua::checkType(L, -1, LUA_TTABLE);
- lua_pushnil(L);
- for (lua_pushnil(L); lua_next(L, -2) != 0; ) {
- Lua::checkType(L, -1, LUA_TTABLE);
- std::string note;
- lua_getfield(L, -1, "note");
- if (!lua_isnil(L, -1)) {
- note = Lua::checkString(L, -1);
- }
- lua_pop(L, 1);
-
- Command::Note::Type noteType = Command::Note::Info;
- lua_getfield(L, -1, "type");
- if (!lua_isnil(L, -1)) {
- std::string type = Lua::checkString(L, -1);
- if (type == "info") { noteType = Command::Note::Info; }
- else if (type == "warn") { noteType = Command::Note::Warn; }
- else if (type == "error") { noteType = Command::Note::Error; }
- }
- lua_pop(L, 1);
-
- result->addNote(Command::Note(note, noteType));
- lua_pop(L, 1);
- }
- }
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "form");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<Form> form = boost::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) {
- result->setForm(form);
- }
- }
- lua_pop(L, 1);
-
- return result;
+std::shared_ptr<Command> CommandConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<Command> result = std::make_shared<Command>();
+
+ lua_getfield(L, -1, "node");
+ if (!lua_isnil(L, -1)) {
+ result->setNode(std::string(Lua::checkString(L, -1)));
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "session_id");
+ if (!lua_isnil(L, -1)) {
+ result->setSessionID(std::string(Lua::checkString(L, -1)));
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "status");
+ if (!lua_isnil(L, -1)) {
+ std::string statusText = Lua::checkString(L, -1);
+ Command::Status status = Command::NoStatus;
+ if (statusText == "executing") { status = Command::Executing; }
+ else if (statusText == "completed") { status = Command::Completed; }
+ else if (statusText == "canceled") { status = Command::Canceled; }
+ result->setStatus(status);
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "action");
+ if (!lua_isnil(L, -1)) {
+ result->setAction(convertActionFromString(Lua::checkString(L, -1)));
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "execute_action");
+ if (!lua_isnil(L, -1)) {
+ result->setExecuteAction(convertActionFromString(Lua::checkString(L, -1)));
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "available_actions");
+ if (!lua_isnil(L, -1)) {
+ Lua::checkType(L, -1, LUA_TTABLE);
+ for (lua_pushnil(L); lua_next(L, -2) != 0; ) {
+ result->addAvailableAction(convertActionFromString(Lua::checkString(L, -1)));
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "notes");
+ if (!lua_isnil(L, -1)) {
+ Lua::checkType(L, -1, LUA_TTABLE);
+ for (lua_pushnil(L); lua_next(L, -2) != 0; ) {
+ Lua::checkType(L, -1, LUA_TTABLE);
+ std::string note;
+ lua_getfield(L, -1, "note");
+ if (!lua_isnil(L, -1)) {
+ note = Lua::checkString(L, -1);
+ }
+ lua_pop(L, 1);
+
+ Command::Note::Type noteType = Command::Note::Info;
+ lua_getfield(L, -1, "type");
+ if (!lua_isnil(L, -1)) {
+ std::string type = Lua::checkString(L, -1);
+ if (type == "info") { noteType = Command::Note::Info; }
+ else if (type == "warn") { noteType = Command::Note::Warn; }
+ else if (type == "error") { noteType = Command::Note::Error; }
+ }
+ lua_pop(L, 1);
+
+ result->addNote(Command::Note(note, noteType));
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "form");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<Form> form = std::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) {
+ result->setForm(form);
+ }
+ }
+ lua_pop(L, 1);
+
+ return result;
}
-void CommandConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<Command> payload) {
- Lua::Table result;
- if (!payload->getNode().empty()) {
- result["node"] = Lua::valueRef(payload->getNode());
- }
- if (!payload->getSessionID().empty()) {
- result["session_id"] = Lua::valueRef(payload->getSessionID());
- }
- switch (payload->getStatus()) {
- case Command::Executing: result["status"] = Lua::valueRef("executing"); break;
- case Command::Completed: result["status"] = Lua::valueRef("completed"); break;
- case Command::Canceled: result["status"] = Lua::valueRef("canceled"); break;
- case Command::NoStatus: break;
- }
-
- if (!payload->getNotes().empty()) {
- std::vector<Lua::Value> notes;
- foreach (const Command::Note& note, payload->getNotes()) {
- Lua::Table noteTable;
- if (!note.note.empty()) {
- noteTable["note"] = Lua::valueRef(note.note);
- }
- switch (note.type) {
- case Command::Note::Info: noteTable["type"] = Lua::valueRef("info"); break;
- case Command::Note::Warn: noteTable["type"] = Lua::valueRef("warn"); break;
- case Command::Note::Error: noteTable["type"] = Lua::valueRef("error"); break;
- }
- notes.push_back(noteTable);
- }
- result["notes"] = Lua::valueRef(notes);
- }
-
- if (payload->getAction() != Command::NoAction) {
- result["action"] = Lua::valueRef(convertActionToString(payload->getAction()));
- }
-
- if (payload->getExecuteAction() != Command::NoAction) {
- result["execute_action"] = Lua::valueRef(convertActionToString(payload->getAction()));
- }
-
- if (!payload->getAvailableActions().empty()) {
- std::vector<Lua::Value> availableActions;
- foreach (const Command::Action& action, payload->getAvailableActions()) {
- if (action != Command::NoAction) {
- availableActions.push_back(convertActionToString(action));
- }
- }
- result["available_actions"] = Lua::valueRef(availableActions);
- }
-
- Lua::pushValue(L, result);
-
- if (payload->getForm()) {
- convertors->convertToLuaUntyped(L, payload->getForm());
- lua_setfield(L, -2, "form");
- }
+void CommandConvertor::doConvertToLua(lua_State* L, std::shared_ptr<Command> payload) {
+ Lua::Table result;
+ if (!payload->getNode().empty()) {
+ result["node"] = Lua::valueRef(payload->getNode());
+ }
+ if (!payload->getSessionID().empty()) {
+ result["session_id"] = Lua::valueRef(payload->getSessionID());
+ }
+ switch (payload->getStatus()) {
+ case Command::Executing: result["status"] = Lua::valueRef("executing"); break;
+ case Command::Completed: result["status"] = Lua::valueRef("completed"); break;
+ case Command::Canceled: result["status"] = Lua::valueRef("canceled"); break;
+ case Command::NoStatus: break;
+ }
+
+ if (!payload->getNotes().empty()) {
+ std::vector<Lua::Value> notes;
+ for (const auto& note : payload->getNotes()) {
+ Lua::Table noteTable;
+ if (!note.note.empty()) {
+ noteTable["note"] = Lua::valueRef(note.note);
+ }
+ switch (note.type) {
+ case Command::Note::Info: noteTable["type"] = Lua::valueRef("info"); break;
+ case Command::Note::Warn: noteTable["type"] = Lua::valueRef("warn"); break;
+ case Command::Note::Error: noteTable["type"] = Lua::valueRef("error"); break;
+ }
+ notes.push_back(noteTable);
+ }
+ result["notes"] = Lua::valueRef(notes);
+ }
+
+ if (payload->getAction() != Command::NoAction) {
+ result["action"] = Lua::valueRef(convertActionToString(payload->getAction()));
+ }
+
+ if (payload->getExecuteAction() != Command::NoAction) {
+ result["execute_action"] = Lua::valueRef(convertActionToString(payload->getAction()));
+ }
+
+ if (!payload->getAvailableActions().empty()) {
+ std::vector<Lua::Value> availableActions;
+ for (const auto& action : payload->getAvailableActions()) {
+ if (action != Command::NoAction) {
+ availableActions.push_back(convertActionToString(action));
+ }
+ }
+ result["available_actions"] = Lua::valueRef(availableActions);
+ }
+
+ Lua::pushValue(L, result);
+
+ if (payload->getForm()) {
+ bool result = convertors->convertToLuaUntyped(L, payload->getForm());
+ assert(result);
+ lua_setfield(L, -2, "form");
+ }
}
diff --git a/Sluift/ElementConvertors/CommandConvertor.h b/Sluift/ElementConvertors/CommandConvertor.h
index 7008b50..274eaa6 100644
--- a/Sluift/ElementConvertors/CommandConvertor.h
+++ b/Sluift/ElementConvertors/CommandConvertor.h
@@ -1,28 +1,27 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/Command.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/Command.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class CommandConvertor : public GenericLuaElementConvertor<Command> {
- public:
- CommandConvertor(LuaElementConvertors* convertors);
- virtual ~CommandConvertor();
+ class CommandConvertor : public GenericLuaElementConvertor<Command> {
+ public:
+ CommandConvertor(LuaElementConvertors* convertors);
+ virtual ~CommandConvertor() override;
- virtual boost::shared_ptr<Command> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<Command>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<Command> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<Command>) override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/DOMElementConvertor.cpp b/Sluift/ElementConvertors/DOMElementConvertor.cpp
index bb4256d..5e72cc8 100644
--- a/Sluift/ElementConvertors/DOMElementConvertor.cpp
+++ b/Sluift/ElementConvertors/DOMElementConvertor.cpp
@@ -1,157 +1,159 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/DOMElementConvertor.h>
-#include <iostream>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <lua.hpp>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Elements/RawXMLPayload.h>
-#include <Swiften/Serializer/PayloadSerializer.h>
-#include <Sluift/Lua/Check.h>
-#include <Sluift/Lua/LuaUtils.h>
-#include <Swiften/Parser/XMLParserClient.h>
-#include <Swiften/Parser/XMLParser.h>
-#include <Swiften/Parser/AttributeMap.h>
#include <Swiften/Parser/Attribute.h>
+#include <Swiften/Parser/AttributeMap.h>
+#include <Swiften/Parser/XMLParser.h>
+#include <Swiften/Parser/XMLParserClient.h>
+#include <Swiften/Serializer/PayloadSerializer.h>
#include <Swiften/Serializer/XML/XMLElement.h>
-#include <Swiften/Serializer/XML/XMLTextNode.h>
#include <Swiften/Serializer/XML/XMLRawTextNode.h>
+#include <Swiften/Serializer/XML/XMLTextNode.h>
+
+#include <Sluift/Lua/Check.h>
#include <Sluift/Lua/Debug.h>
+#include <Sluift/Lua/LuaUtils.h>
using namespace Swift;
namespace {
- class ParserClient : public XMLParserClient {
- public:
- ParserClient(lua_State* L) : L(L), currentIndex(1) {
- }
-
- virtual void handleStartElement(
- const std::string& element, const std::string& ns,
- const AttributeMap& attributes) SWIFTEN_OVERRIDE {
- lua_pushnumber(L, currentIndex);
- lua_newtable(L);
- lua_pushstring(L, element.c_str());
- lua_setfield(L, -2, "tag");
- if (!ns.empty()) {
- lua_pushstring(L, ns.c_str());
- lua_setfield(L, -2, "ns");
- }
- if (!attributes.getEntries().empty()) {
- lua_newtable(L);
- int i = 1;
- foreach(const AttributeMap::Entry& entry, attributes.getEntries()) {
- lua_pushnumber(L, i);
- lua_newtable(L);
- lua_pushstring(L, entry.getAttribute().getName().c_str());
- lua_setfield(L, -2, "name");
- if (!entry.getAttribute().getNamespace().empty()) {
- lua_pushstring(L, entry.getAttribute().getNamespace().c_str());
- lua_setfield(L, -2, "ns");
- }
- lua_pushstring(L, entry.getValue().c_str());
- lua_setfield(L, -2, "value");
- lua_settable(L, -3);
- ++i;
- }
- lua_setfield(L, -2, "attributes");
- }
-
- indexStack.push_back(currentIndex);
- currentIndex = 1;
- lua_newtable(L);
- }
-
- virtual void handleEndElement(
- const std::string&, const std::string&) SWIFTEN_OVERRIDE {
- lua_setfield(L, -2, "children");
- lua_settable(L, -3);
- currentIndex = indexStack.back();
- indexStack.pop_back();
- currentIndex++;
- }
-
- virtual void handleCharacterData(const std::string& data) SWIFTEN_OVERRIDE {
- lua_pushnumber(L, currentIndex);
- lua_pushstring(L, data.c_str());
- lua_settable(L, -3);
- currentIndex++;
- }
-
- private:
- lua_State* L;
- std::vector<int> indexStack;
- int currentIndex;
- };
-
- std::string serializeElement(lua_State* L) {
- std::string tag;
- lua_getfield(L, -1, "tag");
- if (lua_isstring(L, -1)) {
- tag = lua_tostring(L, -1);
- }
- lua_pop(L, 1);
-
- std::string ns;
- lua_getfield(L, -1, "ns");
- if (lua_isstring(L, -1)) {
- ns = lua_tostring(L, -1);
- }
- lua_pop(L, 1);
-
- XMLElement element(tag, ns);
-
- lua_getfield(L, -1, "attributes");
- if (lua_istable(L, -1)) {
- int index = Lua::absoluteOffset(L, -1);
- for (lua_pushnil(L); lua_next(L, index) != 0; ) {
- if (lua_istable(L, -1)) {
- std::string attributeName;
- lua_getfield(L, -1, "name");
- if (lua_isstring(L, -1)) {
- attributeName = lua_tostring(L, -1);
- }
- lua_pop(L, 1);
-
- std::string attributeValue;
- lua_getfield(L, -1, "value");
- if (lua_isstring(L, -1)) {
- attributeValue = lua_tostring(L, -1);
- }
- lua_pop(L, 1);
-
- if (!attributeName.empty()) {
- element.setAttribute(attributeName, attributeValue);
- }
- }
- lua_pop(L, 1); // value
- }
- }
- lua_pop(L, 1); // children
-
- lua_getfield(L, -1, "children");
- if (lua_istable(L, -1)) {
- int index = Lua::absoluteOffset(L, -1);
- for (lua_pushnil(L); lua_next(L, index) != 0; ) {
- if (lua_isstring(L, -1)) {
- element.addNode(boost::make_shared<XMLTextNode>(lua_tostring(L, -1)));
- }
- else if (lua_istable(L, -1)) {
- element.addNode(boost::make_shared<XMLRawTextNode>(serializeElement(L)));
- }
- lua_pop(L, 1); // value
- }
- }
- lua_pop(L, 1); // children
-
- return element.serialize();
- }
+ class ParserClient : public XMLParserClient {
+ public:
+ ParserClient(lua_State* L) : L(L), currentIndex(1) {
+ }
+
+ virtual void handleStartElement(
+ const std::string& element, const std::string& ns,
+ const AttributeMap& attributes) override {
+ lua_checkstack(L, 6);
+ lua_pushnumber(L, currentIndex);
+ lua_newtable(L);
+ lua_pushstring(L, element.c_str());
+ lua_setfield(L, -2, "tag");
+ if (!ns.empty()) {
+ lua_pushstring(L, ns.c_str());
+ lua_setfield(L, -2, "ns");
+ }
+ if (!attributes.getEntries().empty()) {
+ lua_newtable(L);
+ int i = 1;
+ for (const auto& entry : attributes.getEntries()) {
+ lua_pushnumber(L, i);
+ lua_newtable(L);
+ lua_pushstring(L, entry.getAttribute().getName().c_str());
+ lua_setfield(L, -2, "name");
+ if (!entry.getAttribute().getNamespace().empty()) {
+ lua_pushstring(L, entry.getAttribute().getNamespace().c_str());
+ lua_setfield(L, -2, "ns");
+ }
+ lua_pushstring(L, entry.getValue().c_str());
+ lua_setfield(L, -2, "value");
+ lua_settable(L, -3);
+ ++i;
+ }
+ lua_setfield(L, -2, "attributes");
+ }
+
+ indexStack.push_back(currentIndex);
+ currentIndex = 1;
+ lua_newtable(L);
+ }
+
+ virtual void handleEndElement(
+ const std::string&, const std::string&) override {
+ lua_setfield(L, -2, "children");
+ lua_settable(L, -3);
+ currentIndex = indexStack.back();
+ indexStack.pop_back();
+ currentIndex++;
+ }
+
+ virtual void handleCharacterData(const std::string& data) override {
+ lua_checkstack(L, 2);
+ lua_pushnumber(L, currentIndex);
+ lua_pushstring(L, data.c_str());
+ lua_settable(L, -3);
+ currentIndex++;
+ }
+
+ private:
+ lua_State* L;
+ std::vector<int> indexStack;
+ int currentIndex;
+ };
+
+ std::string serializeElement(lua_State* L) {
+ std::string tag;
+ lua_getfield(L, -1, "tag");
+ if (lua_isstring(L, -1)) {
+ tag = lua_tostring(L, -1);
+ }
+ lua_pop(L, 1);
+
+ std::string ns;
+ lua_getfield(L, -1, "ns");
+ if (lua_isstring(L, -1)) {
+ ns = lua_tostring(L, -1);
+ }
+ lua_pop(L, 1);
+
+ XMLElement element(tag, ns);
+
+ lua_getfield(L, -1, "attributes");
+ if (lua_istable(L, -1)) {
+ int index = Lua::absoluteOffset(L, -1);
+ for (lua_pushnil(L); lua_next(L, index) != 0; ) {
+ if (lua_istable(L, -1)) {
+ std::string attributeName;
+ lua_getfield(L, -1, "name");
+ if (lua_isstring(L, -1)) {
+ attributeName = lua_tostring(L, -1);
+ }
+ lua_pop(L, 1);
+
+ std::string attributeValue;
+ lua_getfield(L, -1, "value");
+ if (lua_isstring(L, -1)) {
+ attributeValue = lua_tostring(L, -1);
+ }
+ lua_pop(L, 1);
+
+ if (!attributeName.empty()) {
+ element.setAttribute(attributeName, attributeValue);
+ }
+ }
+ lua_pop(L, 1); // value
+ }
+ }
+ lua_pop(L, 1); // children
+
+ lua_getfield(L, -1, "children");
+ if (lua_istable(L, -1)) {
+ int index = Lua::absoluteOffset(L, -1);
+ for (lua_pushnil(L); lua_next(L, index) != 0; ) {
+ if (lua_isstring(L, -1)) {
+ element.addNode(std::make_shared<XMLTextNode>(lua_tostring(L, -1)));
+ }
+ else if (lua_istable(L, -1)) {
+ element.addNode(std::make_shared<XMLRawTextNode>(serializeElement(L)));
+ }
+ lua_pop(L, 1); // value
+ }
+ }
+ lua_pop(L, 1); // children
+
+ return element.serialize();
+ }
}
DOMElementConvertor::DOMElementConvertor() {
@@ -160,35 +162,40 @@ DOMElementConvertor::DOMElementConvertor() {
DOMElementConvertor::~DOMElementConvertor() {
}
-boost::shared_ptr<Payload> DOMElementConvertor::convertFromLua(lua_State* L, int index, const std::string& type) {
- if (!lua_istable(L, index) || type != "dom") {
- return boost::shared_ptr<Payload>();
- }
- return boost::make_shared<RawXMLPayload>(serializeElement(L).c_str());
+std::shared_ptr<Element> DOMElementConvertor::convertFromLua(lua_State* L, int index, const std::string& type) {
+ if (!lua_istable(L, index) || type != "dom") {
+ return std::shared_ptr<Payload>();
+ }
+ return std::make_shared<RawXMLPayload>(serializeElement(L).c_str());
}
boost::optional<std::string> DOMElementConvertor::convertToLua(
- lua_State* L, boost::shared_ptr<Payload> payload) {
- // Serialize payload to XML
- PayloadSerializer* serializer = serializers.getPayloadSerializer(payload);
- assert(serializer);
- std::string serializedPayload = serializer->serialize(payload);
-
- lua_newtable(L);
-
- // Parse the payload again
- ParserClient parserClient(L);
- boost::shared_ptr<XMLParser> parser(parsers.createXMLParser(&parserClient));
- bool result = parser->parse(serializedPayload);
- assert(result);
-
- // There can only be one element, so stripping the list
- lua_pushnil(L);
- lua_next(L, -2);
- Lua::registerTableToString(L, -1);
-
- lua_replace(L, -3);
- lua_settop(L, -2);
-
- return std::string("dom");
+ lua_State* L, std::shared_ptr<Element> element) {
+ // Serialize payload to XML
+ std::shared_ptr<Payload> payload = std::dynamic_pointer_cast<Payload>(element);
+ if (!payload) {
+ return boost::optional<std::string>();
+ }
+
+ PayloadSerializer* serializer = serializers.getPayloadSerializer(payload);
+ assert(serializer);
+ std::string serializedPayload = serializer->serialize(payload);
+
+ lua_newtable(L);
+
+ // Parse the payload again
+ ParserClient parserClient(L);
+ std::shared_ptr<XMLParser> parser(parsers.createXMLParser(&parserClient, false));
+ bool result = parser->parse(serializedPayload);
+ assert(result);
+
+ // There can only be one element, so stripping the list
+ lua_pushnil(L);
+ lua_next(L, -2);
+ Lua::registerTableToString(L, -1);
+
+ lua_replace(L, -3);
+ lua_settop(L, -2);
+
+ return std::string("dom");
}
diff --git a/Sluift/ElementConvertors/DOMElementConvertor.h b/Sluift/ElementConvertors/DOMElementConvertor.h
index 94d0669..dd8d79b 100644
--- a/Sluift/ElementConvertors/DOMElementConvertor.h
+++ b/Sluift/ElementConvertors/DOMElementConvertor.h
@@ -1,28 +1,27 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Parser/PlatformXMLParserFactory.h>
+#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h>
#include <Sluift/LuaElementConvertor.h>
-#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h>
-#include <Swiften/Parser/PlatformXMLParserFactory.h>
namespace Swift {
- class DOMElementConvertor : public LuaElementConvertor {
- public:
- DOMElementConvertor();
- virtual ~DOMElementConvertor();
+ class DOMElementConvertor : public LuaElementConvertor {
+ public:
+ DOMElementConvertor();
+ virtual ~DOMElementConvertor() override;
- virtual boost::shared_ptr<Payload> convertFromLua(lua_State*, int index, const std::string& type) SWIFTEN_OVERRIDE;
- virtual boost::optional<std::string> convertToLua(lua_State*, boost::shared_ptr<Payload>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<Element> convertFromLua(lua_State*, int index, const std::string& type) override;
+ virtual boost::optional<std::string> convertToLua(lua_State*, std::shared_ptr<Element>) override;
- private:
- PlatformXMLParserFactory parsers;
- FullPayloadSerializerCollection serializers;
- };
+ private:
+ PlatformXMLParserFactory parsers;
+ FullPayloadSerializerCollection serializers;
+ };
}
diff --git a/Sluift/ElementConvertors/DefaultElementConvertor.cpp b/Sluift/ElementConvertors/DefaultElementConvertor.cpp
index 62c799b..d3d60ff 100644
--- a/Sluift/ElementConvertors/DefaultElementConvertor.cpp
+++ b/Sluift/ElementConvertors/DefaultElementConvertor.cpp
@@ -1,14 +1,15 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2019 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/DefaultElementConvertor.h>
-#include <iostream>
-#include <typeinfo>
#include <string>
+#include <typeinfo>
+
+#include <Swiften/Base/Log.h>
using namespace Swift;
@@ -18,13 +19,13 @@ DefaultElementConvertor::DefaultElementConvertor() {
DefaultElementConvertor::~DefaultElementConvertor() {
}
-boost::shared_ptr<Payload> DefaultElementConvertor::convertFromLua(lua_State*, int, const std::string& type) {
- std::cerr << "Warning: Unable to convert type '" << type << "'" << std::endl;
- return boost::shared_ptr<Payload>();
+std::shared_ptr<Element> DefaultElementConvertor::convertFromLua(lua_State*, int, const std::string& type) {
+ SWIFT_LOG(warning) << "Unable to convert type '" << type << "'";
+ return std::shared_ptr<Element>();
}
-boost::optional<std::string> DefaultElementConvertor::convertToLua(lua_State*, boost::shared_ptr<Payload>) {
- // Should have been handled by the raw XML convertor
- assert(false);
- return NO_RESULT;
+boost::optional<std::string> DefaultElementConvertor::convertToLua(lua_State*, std::shared_ptr<Element>) {
+ // Should have been handled by the raw XML convertor
+ assert(false);
+ return NO_RESULT;
}
diff --git a/Sluift/ElementConvertors/DefaultElementConvertor.h b/Sluift/ElementConvertors/DefaultElementConvertor.h
index ad8fe75..dfef3e8 100644
--- a/Sluift/ElementConvertors/DefaultElementConvertor.h
+++ b/Sluift/ElementConvertors/DefaultElementConvertor.h
@@ -1,22 +1,20 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
-
#include <Sluift/LuaElementConvertor.h>
namespace Swift {
- class DefaultElementConvertor : public LuaElementConvertor {
- public:
- DefaultElementConvertor();
- virtual ~DefaultElementConvertor();
+ class DefaultElementConvertor : public LuaElementConvertor {
+ public:
+ DefaultElementConvertor();
+ virtual ~DefaultElementConvertor() override;
- virtual boost::shared_ptr<Payload> convertFromLua(lua_State*, int index, const std::string& type) SWIFTEN_OVERRIDE;
- virtual boost::optional<std::string> convertToLua(lua_State*, boost::shared_ptr<Payload>) SWIFTEN_OVERRIDE;
- };
+ virtual std::shared_ptr<Element> convertFromLua(lua_State*, int index, const std::string& type) override;
+ virtual boost::optional<std::string> convertToLua(lua_State*, std::shared_ptr<Element>) override;
+ };
}
diff --git a/Sluift/ElementConvertors/DelayConvertor.cpp b/Sluift/ElementConvertors/DelayConvertor.cpp
new file mode 100644
index 0000000..f23e137
--- /dev/null
+++ b/Sluift/ElementConvertors/DelayConvertor.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/DelayConvertor.h>
+
+#include <memory>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
+#include <Swiften/Base/DateTime.h>
+
+#include <Sluift/Lua/Check.h>
+
+using namespace Swift;
+
+DelayConvertor::DelayConvertor() : GenericLuaElementConvertor<Delay>("delay") {
+}
+
+DelayConvertor::~DelayConvertor() {
+}
+
+std::shared_ptr<Delay> DelayConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<Delay> result = std::make_shared<Delay>();
+ lua_getfield(L, -1, "stamp");
+ if (lua_isstring(L, -1)) {
+ result->setStamp(stringToDateTime(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "from");
+ if (lua_isstring(L, -1)) {
+ result->setFrom(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void DelayConvertor::doConvertToLua(lua_State* L, std::shared_ptr<Delay> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getFrom()) {
+ lua_pushstring(L, (*payload->getFrom()).toString().c_str());
+ lua_setfield(L, -2, "from");
+ }
+ lua_pushstring(L, dateTimeToString(payload->getStamp()).c_str());
+ lua_setfield(L, -2, "stamp");
+}
diff --git a/Sluift/ElementConvertors/DelayConvertor.h b/Sluift/ElementConvertors/DelayConvertor.h
new file mode 100644
index 0000000..ad340da
--- /dev/null
+++ b/Sluift/ElementConvertors/DelayConvertor.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/Delay.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class DelayConvertor : public GenericLuaElementConvertor<Delay> {
+ public:
+ DelayConvertor();
+ virtual ~DelayConvertor() override;
+
+ virtual std::shared_ptr<Delay> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<Delay>) override;
+ };
+}
diff --git a/Sluift/ElementConvertors/DiscoInfoConvertor.cpp b/Sluift/ElementConvertors/DiscoInfoConvertor.cpp
index ac0cf2e..a528211 100644
--- a/Sluift/ElementConvertors/DiscoInfoConvertor.cpp
+++ b/Sluift/ElementConvertors/DiscoInfoConvertor.cpp
@@ -1,101 +1,144 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/DiscoInfoConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
+
+#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() {
}
-boost::shared_ptr<DiscoInfo> DiscoInfoConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<DiscoInfo> result = boost::make_shared<DiscoInfo>();
- if (boost::optional<std::string> value = Lua::getStringField(L, -1, "node")) {
- result->setNode(*value);
- }
-
- lua_getfield(L, -1, "identities");
- if (lua_istable(L, -1)) {
- for (lua_pushnil(L); lua_next(L, -2); ) {
- result->addIdentity(DiscoInfo::Identity(
- Lua::getStringField(L, -1, "name").get_value_or(""),
- Lua::getStringField(L, -1, "category").get_value_or("client"),
- Lua::getStringField(L, -1, "type").get_value_or("pc"),
- Lua::getStringField(L, -1, "language").get_value_or("")));
- lua_pop(L, 1);
- }
- }
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "features");
- if (lua_istable(L, -1)) {
- for (lua_pushnil(L); lua_next(L, -2); ) {
- if (lua_isstring(L, -1)) {
- result->addFeature(lua_tostring(L, -1));
- }
- lua_pop(L, 1);
- }
- }
- lua_pop(L, 1);
-
- // TODO: Extension
-
- return result;
+std::shared_ptr<DiscoInfo> DiscoInfoConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<DiscoInfo> result = std::make_shared<DiscoInfo>();
+ if (boost::optional<std::string> value = Lua::getStringField(L, -1, "node")) {
+ result->setNode(*value);
+ }
+
+ lua_getfield(L, -1, "identities");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ result->addIdentity(DiscoInfo::Identity(
+ Lua::getStringField(L, -1, "name").get_value_or(""),
+ Lua::getStringField(L, -1, "category").get_value_or("client"),
+ Lua::getStringField(L, -1, "type").get_value_or("pc"),
+ Lua::getStringField(L, -1, "language").get_value_or("")));
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "features");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ if (lua_isstring(L, -1)) {
+ result->addFeature(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+
+ 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;
+}
+
+void DiscoInfoConvertor::doConvertToLua(lua_State* L, std::shared_ptr<DiscoInfo> payload) {
+ lua_newtable(L);
+ if (!payload->getNode().empty()) {
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ }
+
+ const std::vector<DiscoInfo::Identity>& identities = payload->getIdentities();
+ if (!identities.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(identities.size()), 0);
+ for (size_t i = 0; i < identities.size(); ++i) {
+ lua_createtable(L, 0, 0);
+ if (!identities[i].getName().empty()) {
+ lua_pushstring(L, identities[i].getName().c_str());
+ lua_setfield(L, -2, "name");
+ }
+ if (!identities[i].getCategory().empty()) {
+ lua_pushstring(L, identities[i].getCategory().c_str());
+ lua_setfield(L, -2, "category");
+ }
+ if (!identities[i].getType().empty()) {
+ lua_pushstring(L, identities[i].getType().c_str());
+ lua_setfield(L, -2, "type");
+ }
+ if (!identities[i].getLanguage().empty()) {
+ lua_pushstring(L, identities[i].getLanguage().c_str());
+ lua_setfield(L, -2, "language");
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setfield(L, -2, "identities");
+ }
+
+ const std::vector<std::string>& features = payload->getFeatures();
+ if (!features.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(features.size()), 0);
+ for (size_t i = 0; i < features.size(); ++i) {
+ lua_pushstring(L, features[i].c_str());
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setfield(L, -2, "features");
+ }
+
+ 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");
+ }
}
-void DiscoInfoConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<DiscoInfo> payload) {
- lua_newtable(L);
- if (!payload->getNode().empty()) {
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- }
-
- const std::vector<DiscoInfo::Identity>& identities = payload->getIdentities();
- if (!identities.empty()) {
- lua_createtable(L, boost::numeric_cast<int>(identities.size()), 0);
- for (size_t i = 0; i < identities.size(); ++i) {
- lua_createtable(L, 0, 0);
- if (!identities[i].getName().empty()) {
- lua_pushstring(L, identities[i].getName().c_str());
- lua_setfield(L, -2, "name");
- }
- if (!identities[i].getCategory().empty()) {
- lua_pushstring(L, identities[i].getCategory().c_str());
- lua_setfield(L, -2, "category");
- }
- if (!identities[i].getType().empty()) {
- lua_pushstring(L, identities[i].getType().c_str());
- lua_setfield(L, -2, "type");
- }
- if (!identities[i].getLanguage().empty()) {
- lua_pushstring(L, identities[i].getLanguage().c_str());
- lua_setfield(L, -2, "language");
- }
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- }
- lua_setfield(L, -2, "identities");
- }
-
- const std::vector<std::string>& features = payload->getFeatures();
- if (!features.empty()) {
- lua_createtable(L, boost::numeric_cast<int>(features.size()), 0);
- for (size_t i = 0; i < features.size(); ++i) {
- lua_pushstring(L, features[i].c_str());
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- }
- lua_setfield(L, -2, "features");
- }
-
- // TODO: Extension
+boost::optional<LuaElementConvertor::Documentation> DiscoInfoConvertor::getDocumentation() const {
+ return Documentation(
+ "DiscoInfo",
+ "Represents `disco#info` service discovery data.\n\n"
+ "This table has the following structure:\n\n"
+ "- `node`: string\n"
+ "- `identities`: array(table)\n"
+ " - `name`: string\n"
+ " - `category`: string\n"
+ " - `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 7a2270e..b0e0849 100644
--- a/Sluift/ElementConvertors/DiscoInfoConvertor.h
+++ b/Sluift/ElementConvertors/DiscoInfoConvertor.h
@@ -1,23 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/DiscoInfo.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/DiscoInfo.h>
namespace Swift {
- class DiscoInfoConvertor : public GenericLuaElementConvertor<DiscoInfo> {
- public:
- DiscoInfoConvertor();
- virtual ~DiscoInfoConvertor();
+ class LuaElementConvertors;
+
+ class DiscoInfoConvertor : public GenericLuaElementConvertor<DiscoInfo> {
+ public:
+ DiscoInfoConvertor(LuaElementConvertors* convertors);
+ virtual ~DiscoInfoConvertor() override;
+
+ virtual std::shared_ptr<DiscoInfo> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<DiscoInfo>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- virtual boost::shared_ptr<DiscoInfo> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<DiscoInfo>) SWIFTEN_OVERRIDE;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/DiscoItemsConvertor.cpp b/Sluift/ElementConvertors/DiscoItemsConvertor.cpp
index 9049912..c15a0f8 100644
--- a/Sluift/ElementConvertors/DiscoItemsConvertor.cpp
+++ b/Sluift/ElementConvertors/DiscoItemsConvertor.cpp
@@ -1,14 +1,17 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/DiscoItemsConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
#include <Sluift/Lua/LuaUtils.h>
using namespace Swift;
@@ -19,50 +22,50 @@ DiscoItemsConvertor::DiscoItemsConvertor() : GenericLuaElementConvertor<DiscoIte
DiscoItemsConvertor::~DiscoItemsConvertor() {
}
-boost::shared_ptr<DiscoItems> DiscoItemsConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<DiscoItems> result = boost::make_shared<DiscoItems>();
- if (boost::optional<std::string> value = Lua::getStringField(L, -1, "node")) {
- result->setNode(*value);
- }
- lua_getfield(L, -1, "items");
- if (lua_istable(L, -1)) {
- for (lua_pushnil(L); lua_next(L, -2); ) {
- result->addItem(DiscoItems::Item(
- Lua::getStringField(L, -1, "name").get_value_or(""),
- JID(Lua::getStringField(L, -1, "jid").get_value_or("")),
- Lua::getStringField(L, -1, "node").get_value_or("")));
- lua_pop(L, 1);
- }
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<DiscoItems> DiscoItemsConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<DiscoItems> result = std::make_shared<DiscoItems>();
+ if (boost::optional<std::string> value = Lua::getStringField(L, -1, "node")) {
+ result->setNode(*value);
+ }
+ lua_getfield(L, -1, "items");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ result->addItem(DiscoItems::Item(
+ Lua::getStringField(L, -1, "name").get_value_or(""),
+ JID(Lua::getStringField(L, -1, "jid").get_value_or("")),
+ Lua::getStringField(L, -1, "node").get_value_or("")));
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
}
-void DiscoItemsConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<DiscoItems> payload) {
- lua_newtable(L);
- if (!payload->getNode().empty()) {
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- }
- const std::vector<DiscoItems::Item>& items = payload->getItems();
- if (!items.empty()) {
- lua_createtable(L, boost::numeric_cast<int>(items.size()), 0);
- for (size_t i = 0; i < items.size(); ++i) {
- lua_createtable(L, 0, 0);
- if (!items[i].getName().empty()) {
- lua_pushstring(L, items[i].getName().c_str());
- lua_setfield(L, -2, "name");
- }
- if (!items[i].getNode().empty()) {
- lua_pushstring(L, items[i].getNode().c_str());
- lua_setfield(L, -2, "node");
- }
- if (items[i].getJID().isValid()) {
- lua_pushstring(L, items[i].getJID().toString().c_str());
- lua_setfield(L, -2, "jid");
- }
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- }
- lua_setfield(L, -2, "items");
- }
+void DiscoItemsConvertor::doConvertToLua(lua_State* L, std::shared_ptr<DiscoItems> payload) {
+ lua_newtable(L);
+ if (!payload->getNode().empty()) {
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ }
+ const std::vector<DiscoItems::Item>& items = payload->getItems();
+ if (!items.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(items.size()), 0);
+ for (size_t i = 0; i < items.size(); ++i) {
+ lua_createtable(L, 0, 0);
+ if (!items[i].getName().empty()) {
+ lua_pushstring(L, items[i].getName().c_str());
+ lua_setfield(L, -2, "name");
+ }
+ if (!items[i].getNode().empty()) {
+ lua_pushstring(L, items[i].getNode().c_str());
+ lua_setfield(L, -2, "node");
+ }
+ if (items[i].getJID().isValid()) {
+ lua_pushstring(L, items[i].getJID().toString().c_str());
+ lua_setfield(L, -2, "jid");
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setfield(L, -2, "items");
+ }
}
diff --git a/Sluift/ElementConvertors/DiscoItemsConvertor.h b/Sluift/ElementConvertors/DiscoItemsConvertor.h
index 8972a84..98dcb5c 100644
--- a/Sluift/ElementConvertors/DiscoItemsConvertor.h
+++ b/Sluift/ElementConvertors/DiscoItemsConvertor.h
@@ -1,23 +1,22 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/DiscoItems.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/DiscoItems.h>
namespace Swift {
- class DiscoItemsConvertor : public GenericLuaElementConvertor<DiscoItems> {
- public:
- DiscoItemsConvertor();
- virtual ~DiscoItemsConvertor();
+ class DiscoItemsConvertor : public GenericLuaElementConvertor<DiscoItems> {
+ public:
+ DiscoItemsConvertor();
+ virtual ~DiscoItemsConvertor() override;
- virtual boost::shared_ptr<DiscoItems> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<DiscoItems>) SWIFTEN_OVERRIDE;
- };
+ virtual std::shared_ptr<DiscoItems> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<DiscoItems>) override;
+ };
}
diff --git a/Sluift/ElementConvertors/ElementConvertors.ipp b/Sluift/ElementConvertors/ElementConvertors.ipp
index b7b9166..a81c9cf 100644
--- a/Sluift/ElementConvertors/ElementConvertors.ipp
+++ b/Sluift/ElementConvertors/ElementConvertors.ipp
@@ -1,81 +1,87 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
-#include <Sluift/ElementConvertors/PubSubRetractConvertor.h>
+#include <Sluift/ElementConvertors/IsodeIQDelegationConvertor.h>
+#include <Sluift/ElementConvertors/PubSubAffiliationConvertor.h>
#include <Sluift/ElementConvertors/PubSubAffiliationsConvertor.h>
-#include <Sluift/ElementConvertors/PubSubPublishConvertor.h>
-#include <Sluift/ElementConvertors/PubSubItemsConvertor.h>
-#include <Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.h>
-#include <Sluift/ElementConvertors/PubSubEventRedirectConvertor.h>
#include <Sluift/ElementConvertors/PubSubConfigureConvertor.h>
-#include <Sluift/ElementConvertors/PubSubEventDisassociateConvertor.h>
-#include <Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.h>
-#include <Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.h>
-#include <Sluift/ElementConvertors/UserLocationConvertor.h>
-#include <Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.h>
-#include <Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.h>
+#include <Sluift/ElementConvertors/PubSubCreateConvertor.h>
#include <Sluift/ElementConvertors/PubSubDefaultConvertor.h>
+#include <Sluift/ElementConvertors/PubSubEventAssociateConvertor.h>
#include <Sluift/ElementConvertors/PubSubEventCollectionConvertor.h>
-#include <Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.h>
-#include <Sluift/ElementConvertors/PubSubEventRetractConvertor.h>
-#include <Sluift/ElementConvertors/PubSubItemConvertor.h>
-#include <Sluift/ElementConvertors/PubSubUnsubscribeConvertor.h>
+#include <Sluift/ElementConvertors/PubSubEventConfigurationConvertor.h>
#include <Sluift/ElementConvertors/PubSubEventDeleteConvertor.h>
-#include <Sluift/ElementConvertors/PubSubCreateConvertor.h>
-#include <Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.h>
+#include <Sluift/ElementConvertors/PubSubEventDisassociateConvertor.h>
+#include <Sluift/ElementConvertors/PubSubEventItemConvertor.h>
#include <Sluift/ElementConvertors/PubSubEventItemsConvertor.h>
+#include <Sluift/ElementConvertors/PubSubEventPurgeConvertor.h>
+#include <Sluift/ElementConvertors/PubSubEventRedirectConvertor.h>
+#include <Sluift/ElementConvertors/PubSubEventRetractConvertor.h>
+#include <Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.h>
+#include <Sluift/ElementConvertors/PubSubItemConvertor.h>
+#include <Sluift/ElementConvertors/PubSubItemsConvertor.h>
#include <Sluift/ElementConvertors/PubSubOptionsConvertor.h>
-#include <Sluift/ElementConvertors/PubSubEventItemConvertor.h>
-#include <Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.h>
#include <Sluift/ElementConvertors/PubSubOwnerAffiliationConvertor.h>
-#include <Sluift/ElementConvertors/PubSubEventPurgeConvertor.h>
-#include <Sluift/ElementConvertors/PubSubAffiliationConvertor.h>
-#include <Sluift/ElementConvertors/PubSubSubscribeConvertor.h>
-#include <Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.h>
+#include <Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.h>
+#include <Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.h>
#include <Sluift/ElementConvertors/PubSubOwnerDefaultConvertor.h>
-#include <Sluift/ElementConvertors/PubSubSubscriptionsConvertor.h>
-#include <Sluift/ElementConvertors/PubSubEventAssociateConvertor.h>
+#include <Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.h>
+#include <Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.h>
+#include <Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.h>
+#include <Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.h>
+#include <Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.h>
+#include <Sluift/ElementConvertors/PubSubPublishConvertor.h>
+#include <Sluift/ElementConvertors/PubSubRetractConvertor.h>
+#include <Sluift/ElementConvertors/PubSubSubscribeConvertor.h>
+#include <Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.h>
#include <Sluift/ElementConvertors/PubSubSubscriptionConvertor.h>
-#include <Sluift/ElementConvertors/PubSubEventConfigurationConvertor.h>
+#include <Sluift/ElementConvertors/PubSubSubscriptionsConvertor.h>
+#include <Sluift/ElementConvertors/PubSubUnsubscribeConvertor.h>
+#include <Sluift/ElementConvertors/SecurityLabelConvertor.h>
+#include <Sluift/ElementConvertors/UserLocationConvertor.h>
+#include <Sluift/ElementConvertors/UserTuneConvertor.h>
void LuaElementConvertors::registerConvertors() {
- convertors.push_back(boost::make_shared<PubSubRetractConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubAffiliationsConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubPublishConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubItemsConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubOwnerRedirectConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubEventRedirectConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubConfigureConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubEventDisassociateConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubOwnerAffiliationsConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubOwnerConfigureConvertor>(this));
- convertors.push_back(boost::make_shared<UserLocationConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubSubscribeOptionsConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubOwnerSubscriptionsConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubDefaultConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubEventCollectionConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubEventSubscriptionConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubEventRetractConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubItemConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubUnsubscribeConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubEventDeleteConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubCreateConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubOwnerPurgeConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubEventItemsConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubOptionsConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubEventItemConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubOwnerSubscriptionConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubOwnerAffiliationConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubEventPurgeConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubAffiliationConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubSubscribeConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubOwnerDeleteConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubOwnerDefaultConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubSubscriptionsConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubEventAssociateConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubSubscriptionConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubEventConfigurationConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubRetractConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubAffiliationsConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubPublishConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubItemsConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubOwnerRedirectConvertor>());
+ convertors.push_back(std::make_shared<PubSubEventRedirectConvertor>());
+ convertors.push_back(std::make_shared<UserTuneConvertor>());
+ convertors.push_back(std::make_shared<PubSubConfigureConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubEventDisassociateConvertor>());
+ convertors.push_back(std::make_shared<PubSubOwnerAffiliationsConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubOwnerConfigureConvertor>(this));
+ convertors.push_back(std::make_shared<UserLocationConvertor>());
+ convertors.push_back(std::make_shared<PubSubSubscribeOptionsConvertor>());
+ convertors.push_back(std::make_shared<PubSubOwnerSubscriptionsConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubDefaultConvertor>());
+ convertors.push_back(std::make_shared<PubSubEventCollectionConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubEventSubscriptionConvertor>());
+ convertors.push_back(std::make_shared<PubSubEventRetractConvertor>());
+ convertors.push_back(std::make_shared<PubSubItemConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubUnsubscribeConvertor>());
+ convertors.push_back(std::make_shared<PubSubEventDeleteConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubCreateConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubOwnerPurgeConvertor>());
+ convertors.push_back(std::make_shared<PubSubEventItemsConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubOptionsConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubEventItemConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubOwnerSubscriptionConvertor>());
+ convertors.push_back(std::make_shared<IsodeIQDelegationConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubOwnerAffiliationConvertor>());
+ convertors.push_back(std::make_shared<PubSubEventPurgeConvertor>());
+ convertors.push_back(std::make_shared<PubSubAffiliationConvertor>());
+ convertors.push_back(std::make_shared<PubSubSubscribeConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubOwnerDeleteConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubOwnerDefaultConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubSubscriptionsConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubEventAssociateConvertor>());
+ convertors.push_back(std::make_shared<PubSubSubscriptionConvertor>(this));
+ convertors.push_back(std::make_shared<SecurityLabelConvertor>());
+ convertors.push_back(std::make_shared<PubSubEventConfigurationConvertor>(this));
}
diff --git a/Sluift/ElementConvertors/FormConvertor.cpp b/Sluift/ElementConvertors/FormConvertor.cpp
index e44ca3e..245e0f9 100644
--- a/Sluift/ElementConvertors/FormConvertor.cpp
+++ b/Sluift/ElementConvertors/FormConvertor.cpp
@@ -1,345 +1,343 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/FormConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <sstream>
+
+#include <boost/assign/list_of.hpp>
#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
#include <Sluift/Lua/Check.h>
#include <Sluift/Lua/Value.h>
-#include <Swiften/Base/foreach.h>
-#include <boost/assign/list_of.hpp>
-#include <sstream>
using namespace Swift;
namespace {
- int formIndex(lua_State* L) {
- lua_getfield(L, 1, "fields");
- if (lua_type(L, -1) != LUA_TTABLE) {
- return 0;
- }
- int index = Lua::absoluteOffset(L, -1);
- lua_pushnil(L);
- for (lua_pushnil(L); lua_next(L, index) != 0; ) {
- lua_getfield(L, -1, "name");
- if (lua_equal(L, -1, 2)) {
- lua_pop(L, 1);
- return 1;
- }
- lua_pop(L, 2);
- }
- return 0;
- }
-
- int formNewIndex(lua_State* L) {
- lua_getfield(L, 1, "fields");
- bool foundField = false;
- if (lua_type(L, -1) == LUA_TTABLE) {
- for (lua_pushnil(L); lua_next(L, -2) != 0; ) {
- lua_getfield(L, -1, "name");
- if (lua_equal(L, -1, 2)) {
- lua_pushvalue(L, 3);
- lua_setfield(L, -3, "value");
- foundField = true;
- lua_pop(L, 3);
- break;
- }
- lua_pop(L, 2);
- }
- }
- lua_pop(L, 1);
-
- if (!foundField) {
- lua_pushvalue(L, 2);
- lua_pushvalue(L, 3);
- lua_rawset(L, 1);
- }
- return 0;
- }
-
- Lua::Table convertFieldToLua(boost::shared_ptr<FormField> field) {
- Lua::Table luaField = boost::assign::map_list_of("name", Lua::valueRef(field->getName()));
- std::string type;
- switch (field->getType()) {
- case FormField::UnknownType: type = ""; break;
- case FormField::BooleanType: type = "boolean"; break;
- case FormField::FixedType: type = "fixed"; break;
- case FormField::HiddenType: type = "hidden"; break;
- case FormField::ListSingleType: type = "list-single"; break;
- case FormField::TextMultiType: type = "text-multi"; break;
- case FormField::TextPrivateType: type = "text-private"; break;
- case FormField::TextSingleType: type = "text-single"; break;
- case FormField::JIDSingleType: type = "jid-single"; break;
- case FormField::JIDMultiType: type = "jid-multi"; break;
- case FormField::ListMultiType: type = "list-multi"; break;
- }
- if (!type.empty()) {
- luaField["type"] = Lua::valueRef(type);
- }
- if (!field->getLabel().empty()) {
- luaField["label"] = Lua::valueRef(field->getLabel());
- }
- if (field->getRequired()) {
- luaField["required"] = Lua::boolRef(field->getRequired());
- }
- if (!field->getDescription().empty()) {
- luaField["description"] = Lua::valueRef(field->getDescription());
- }
-
- if (field->getType() == FormField::ListMultiType || field->getType() == FormField::JIDMultiType || field->getType() == FormField::TextMultiType) {
- luaField["values"] = Lua::valueRef(Lua::Array(field->getValues().begin(), field->getValues().end()));
- }
- else if (field->getType() == FormField::BooleanType) {
- luaField["value"] = Lua::boolRef(field->getBoolValue());
- }
- else if (!field->getValues().empty()) {
- luaField["value"] = Lua::valueRef(field->getValues()[0]);
- }
-
- if (!field->getOptions().empty()) {
- Lua::Array options;
- foreach(const FormField::Option& option, field->getOptions()) {
- Lua::Table luaOption = boost::assign::map_list_of
- ("label", Lua::valueRef(option.label))
- ("value", Lua::valueRef(option.value));
- options.push_back(luaOption);
- }
- luaField["options"] = valueRef(options);
- }
- return luaField;
- }
-
- Lua::Array convertFieldListToLua(const std::vector< boost::shared_ptr<FormField> >& fieldList) {
- Lua::Array fields;
- foreach(boost::shared_ptr<FormField> field, fieldList) {
- fields.push_back(convertFieldToLua(field));
- }
- return fields;
- }
-
-
- boost::shared_ptr<FormField> convertFieldFromLua(lua_State* L) {
- boost::shared_ptr<FormField> result = boost::make_shared<FormField>();
- FormField::Type fieldType = FormField::UnknownType;
- boost::optional<std::string> type = Lua::getStringField(L, -1, "type");
- if (type) {
- if (*type == "boolean") {
- fieldType = FormField::BooleanType;
- }
- if (*type == "fixed") {
- fieldType = FormField::FixedType;
- }
- if (*type == "hidden") {
- fieldType = FormField::HiddenType;
- }
- if (*type == "list-single") {
- fieldType = FormField::ListSingleType;
- }
- if (*type == "text-multi") {
- fieldType = FormField::TextMultiType;
- }
- if (*type == "text-private") {
- fieldType = FormField::TextPrivateType;
- }
- if (*type == "text-single") {
- fieldType = FormField::TextSingleType;
- }
- if (*type == "jid-single") {
- fieldType = FormField::JIDSingleType;
- }
- if (*type == "jid-multi") {
- fieldType = FormField::JIDMultiType;
- }
- if (*type == "list-multi") {
- fieldType = FormField::ListMultiType;
- }
- }
- result->setType(fieldType);
- if (boost::optional<std::string> name = Lua::getStringField(L, -1, "name")) {
- result->setName(*name);
- }
- if (boost::optional<std::string> description = Lua::getStringField(L, -1, "description")) {
- result->setDescription(*description);
- }
- if (boost::optional<std::string> label = Lua::getStringField(L, -1, "label")) {
- result->setLabel(*label);
- }
- if (boost::optional<bool> required = Lua::getBooleanField(L, -1, "required")) {
- result->setRequired(*required);
- }
- if (boost::optional<std::string> value = Lua::getStringField(L, -1, "value")) {
- result->addValue(*value);
- }
- else if (boost::optional<bool> value = Lua::getBooleanField(L, -1, "value")) {
- result->setBoolValue(*value);
- }
- else {
- lua_getfield(L, -1, "values");
- if (lua_istable(L, -1)) {
- for (lua_pushnil(L); lua_next(L, -2); ) {
- if (lua_isstring(L, -1)) {
- result->addValue(lua_tostring(L, -1));
- }
- lua_pop(L, 1);
- }
- }
- lua_pop(L, 1);
- }
- lua_getfield(L, -1, "options");
- if (lua_istable(L, -1)) {
- for (lua_pushnil(L); lua_next(L, -2); ) {
- if (lua_istable(L, -1)) {
- FormField::Option option("", "");
- if (boost::optional<std::string> value = Lua::getStringField(L, -1, "value")) {
- option.value = *value;
- }
- if (boost::optional<std::string> label = Lua::getStringField(L, -1, "label")) {
- option.label = *label;
- }
- result->addOption(option);
- }
- lua_pop(L, 1);
- }
- }
- lua_pop(L, 1);
- return result;
- }
-
- std::vector< boost::shared_ptr<FormField> > convertFieldListFromLua(lua_State* L) {
- std::vector< boost::shared_ptr<FormField> > result;
- for (lua_pushnil(L); lua_next(L, -2);) {
- result.push_back(convertFieldFromLua(L));
- lua_pop(L, 1);
- }
- return result;
- }
-
- boost::shared_ptr<Form> convertFormFromLua(lua_State* L) {
- boost::shared_ptr<Form> result = boost::make_shared<Form>();
- if (boost::optional<std::string> title = Lua::getStringField(L, -1, "title")) {
- result->setTitle(*title);
- }
- if (boost::optional<std::string> instructions = Lua::getStringField(L, -1, "instructions")) {
- result->setInstructions(*instructions);
- }
- if (boost::optional<std::string> type = Lua::getStringField(L, -1, "type")) {
- Form::Type formType = Form::FormType;
- if (*type == "submit") {
- formType = Form::SubmitType;
- }
- else if (*type == "cancel") {
- formType = Form::CancelType;
- }
- else if (*type == "result") {
- formType = Form::ResultType;
- }
- result->setType(formType);
- }
-
- lua_getfield(L, -1, "fields");
- if (lua_istable(L, -1)) {
- foreach (boost::shared_ptr<FormField> formField, convertFieldListFromLua(L)) {
- result->addField(formField);
- }
- }
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "reported_fields");
- if (lua_istable(L, -1)) {
- foreach (boost::shared_ptr<FormField> formField, convertFieldListFromLua(L)) {
- result->addReportedField(formField);
- }
- }
- lua_pop(L, 1);
-
- lua_getfield(L, -1, "items");
- if (lua_istable(L, -1)) {
- for (lua_pushnil(L); lua_next(L, -2);) {
- result->addItem(convertFieldListFromLua(L));
- lua_pop(L, 1);
- }
- }
- lua_pop(L, 1);
-
- return result;
- }
-
- void convertFormToLua(lua_State* L, boost::shared_ptr<Form> payload) {
- std::string type;
- switch (payload->getType()) {
- case Form::FormType: type = "form"; break;
- case Form::SubmitType: type = "submit"; break;
- case Form::CancelType: type = "cancel"; break;
- case Form::ResultType: type = "result"; break;
- }
-
- Lua::Table result = boost::assign::map_list_of("type", Lua::valueRef(type));
- if (!payload->getTitle().empty()) {
- result["title"] = Lua::valueRef(payload->getTitle());
- }
- if (!payload->getInstructions().empty()) {
- result["instructions"] = Lua::valueRef(payload->getInstructions());
- }
- if (!payload->getFields().empty()) {
- result["fields"] = valueRef(convertFieldListToLua(payload->getFields()));
- }
- if (!payload->getReportedFields().empty()) {
- result["reported_fields"] = valueRef(convertFieldListToLua(payload->getReportedFields()));
- }
-
- if (!payload->getItems().empty()) {
- Lua::Array luaItems;
- foreach(const Form::FormItem& item, payload->getItems()) {
- if (!item.empty()) {
- luaItems.push_back(convertFieldListToLua(item));
- }
- }
- result["items"] = valueRef(luaItems);
- }
-
- Lua::pushValue(L, result);
-
- lua_newtable(L);
- lua_pushcfunction(L, formIndex);
- lua_setfield(L, -2, "__index");
- lua_pushcfunction(L, formNewIndex);
- lua_setfield(L, -2, "__newindex");
- lua_setmetatable(L, -2);
- }
-
- int createSubmission(lua_State* L) {
- boost::shared_ptr<Form> form = convertFormFromLua(L);
-
- // Remove all redundant elements
- form->setInstructions("");
- form->setTitle("");
- form->clearItems();
- form->clearReportedFields();
- std::vector< boost::shared_ptr<FormField> > fields(form->getFields());
- form->clearFields();
- foreach (boost::shared_ptr<FormField> field, fields) {
- if (field->getType() == FormField::FixedType) {
- continue;
- }
- field->clearOptions();
- field->setLabel("");
- field->setType(FormField::UnknownType);
- field->setDescription("");
- form->addField(field);
- }
- form->setType(Form::SubmitType);
-
- // Convert back
- convertFormToLua(L, form);
- Lua::registerTableToString(L, -1);
-
- return 1;
- }
+ int formIndex(lua_State* L) {
+ lua_getfield(L, 1, "fields");
+ if (lua_type(L, -1) != LUA_TTABLE) {
+ return 0;
+ }
+ int index = Lua::absoluteOffset(L, -1);
+ lua_pushnil(L);
+ for (lua_pushnil(L); lua_next(L, index) != 0; ) {
+ lua_getfield(L, -1, "name");
+ if (lua_compare(L, -1, 2, LUA_OPEQ)) {
+ lua_pop(L, 1);
+ return 1;
+ }
+ lua_pop(L, 2);
+ }
+ return 0;
+ }
+
+ int formNewIndex(lua_State* L) {
+ lua_getfield(L, 1, "fields");
+ bool foundField = false;
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ for (lua_pushnil(L); lua_next(L, -2) != 0; ) {
+ lua_getfield(L, -1, "name");
+ if (lua_compare(L, -1, 2, LUA_OPEQ)) {
+ lua_pushvalue(L, 3);
+ lua_setfield(L, -3, "value");
+ foundField = true;
+ lua_pop(L, 3);
+ break;
+ }
+ lua_pop(L, 2);
+ }
+ }
+ lua_pop(L, 1);
+
+ if (!foundField) {
+ lua_pushvalue(L, 2);
+ lua_pushvalue(L, 3);
+ lua_rawset(L, 1);
+ }
+ return 0;
+ }
+
+ Lua::Table convertFieldToLua(std::shared_ptr<FormField> field) {
+ Lua::Table luaField = boost::assign::map_list_of("name", Lua::valueRef(field->getName()));
+ std::string type;
+ switch (field->getType()) {
+ case FormField::UnknownType: type = ""; break;
+ case FormField::BooleanType: type = "boolean"; break;
+ case FormField::FixedType: type = "fixed"; break;
+ case FormField::HiddenType: type = "hidden"; break;
+ case FormField::ListSingleType: type = "list-single"; break;
+ case FormField::TextMultiType: type = "text-multi"; break;
+ case FormField::TextPrivateType: type = "text-private"; break;
+ case FormField::TextSingleType: type = "text-single"; break;
+ case FormField::JIDSingleType: type = "jid-single"; break;
+ case FormField::JIDMultiType: type = "jid-multi"; break;
+ case FormField::ListMultiType: type = "list-multi"; break;
+ }
+ if (!type.empty()) {
+ luaField["type"] = Lua::valueRef(type);
+ }
+ if (!field->getLabel().empty()) {
+ luaField["label"] = Lua::valueRef(field->getLabel());
+ }
+ if (field->getRequired()) {
+ luaField["required"] = Lua::boolRef(field->getRequired());
+ }
+ if (!field->getDescription().empty()) {
+ luaField["description"] = Lua::valueRef(field->getDescription());
+ }
+ if (field->getType() == FormField::BooleanType) {
+ luaField["value"] = Lua::boolRef(field->getBoolValue());
+ }
+ else if (field->getValues().size() > 1) {
+ luaField["value"] = Lua::valueRef(Lua::Array(field->getValues().begin(), field->getValues().end()));
+ }
+ else if (field->getValues().size() == 1) {
+ luaField["value"] = Lua::valueRef(field->getValues()[0]);
+ }
+ if (!field->getOptions().empty()) {
+ Lua::Array options;
+ for (const auto& option : field->getOptions()) {
+ Lua::Table luaOption = boost::assign::map_list_of
+ ("label", Lua::valueRef(option.label))
+ ("value", Lua::valueRef(option.value));
+ options.push_back(luaOption);
+ }
+ luaField["options"] = valueRef(options);
+ }
+ return luaField;
+ }
+
+ Lua::Array convertFieldListToLua(const std::vector< std::shared_ptr<FormField> >& fieldList) {
+ Lua::Array fields;
+ for (auto&& field : fieldList) {
+ fields.push_back(convertFieldToLua(field));
+ }
+ return fields;
+ }
+
+
+ std::shared_ptr<FormField> convertFieldFromLua(lua_State* L) {
+ std::shared_ptr<FormField> result = std::make_shared<FormField>();
+ FormField::Type fieldType = FormField::UnknownType;
+ boost::optional<std::string> type = Lua::getStringField(L, -1, "type");
+ if (type) {
+ if (*type == "boolean") {
+ fieldType = FormField::BooleanType;
+ }
+ if (*type == "fixed") {
+ fieldType = FormField::FixedType;
+ }
+ if (*type == "hidden") {
+ fieldType = FormField::HiddenType;
+ }
+ if (*type == "list-single") {
+ fieldType = FormField::ListSingleType;
+ }
+ if (*type == "text-multi") {
+ fieldType = FormField::TextMultiType;
+ }
+ if (*type == "text-private") {
+ fieldType = FormField::TextPrivateType;
+ }
+ if (*type == "text-single") {
+ fieldType = FormField::TextSingleType;
+ }
+ if (*type == "jid-single") {
+ fieldType = FormField::JIDSingleType;
+ }
+ if (*type == "jid-multi") {
+ fieldType = FormField::JIDMultiType;
+ }
+ if (*type == "list-multi") {
+ fieldType = FormField::ListMultiType;
+ }
+ }
+ result->setType(fieldType);
+ if (boost::optional<std::string> name = Lua::getStringField(L, -1, "name")) {
+ result->setName(*name);
+ }
+ if (boost::optional<std::string> description = Lua::getStringField(L, -1, "description")) {
+ result->setDescription(*description);
+ }
+ if (boost::optional<std::string> label = Lua::getStringField(L, -1, "label")) {
+ result->setLabel(*label);
+ }
+ if (boost::optional<bool> required = Lua::getBooleanField(L, -1, "required")) {
+ result->setRequired(*required);
+ }
+ if (boost::optional<std::string> value = Lua::getStringField(L, -1, "value")) {
+ result->addValue(*value);
+ }
+ else if (boost::optional<bool> value = Lua::getBooleanField(L, -1, "value")) {
+ result->setBoolValue(*value);
+ }
+ else {
+ lua_getfield(L, -1, "value");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ if (lua_isstring(L, -1)) {
+ result->addValue(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ }
+ lua_getfield(L, -1, "options");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ if (lua_istable(L, -1)) {
+ FormField::Option option("", "");
+ if (boost::optional<std::string> value = Lua::getStringField(L, -1, "value")) {
+ option.value = *value;
+ }
+ if (boost::optional<std::string> label = Lua::getStringField(L, -1, "label")) {
+ option.label = *label;
+ }
+ result->addOption(option);
+ }
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+ }
+
+ std::vector< std::shared_ptr<FormField> > convertFieldListFromLua(lua_State* L) {
+ std::vector< std::shared_ptr<FormField> > result;
+ for (lua_pushnil(L); lua_next(L, -2);) {
+ result.push_back(convertFieldFromLua(L));
+ lua_pop(L, 1);
+ }
+ return result;
+ }
+
+ std::shared_ptr<Form> convertFormFromLua(lua_State* L) {
+ std::shared_ptr<Form> result = std::make_shared<Form>();
+ if (boost::optional<std::string> title = Lua::getStringField(L, -1, "title")) {
+ result->setTitle(*title);
+ }
+ if (boost::optional<std::string> instructions = Lua::getStringField(L, -1, "instructions")) {
+ result->setInstructions(*instructions);
+ }
+ if (boost::optional<std::string> type = Lua::getStringField(L, -1, "type")) {
+ Form::Type formType = Form::FormType;
+ if (*type == "submit") {
+ formType = Form::SubmitType;
+ }
+ else if (*type == "cancel") {
+ formType = Form::CancelType;
+ }
+ else if (*type == "result") {
+ formType = Form::ResultType;
+ }
+ result->setType(formType);
+ }
+
+ lua_getfield(L, -1, "fields");
+ if (lua_istable(L, -1)) {
+ for (auto&& formField : convertFieldListFromLua(L)) {
+ result->addField(formField);
+ }
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "reported_fields");
+ if (lua_istable(L, -1)) {
+ for (auto&& formField : convertFieldListFromLua(L)) {
+ result->addReportedField(formField);
+ }
+ }
+ lua_pop(L, 1);
+
+ lua_getfield(L, -1, "items");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2);) {
+ result->addItem(convertFieldListFromLua(L));
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+
+ return result;
+ }
+
+ void convertFormToLua(lua_State* L, std::shared_ptr<Form> payload) {
+ std::string type;
+ switch (payload->getType()) {
+ case Form::FormType: type = "form"; break;
+ case Form::SubmitType: type = "submit"; break;
+ case Form::CancelType: type = "cancel"; break;
+ case Form::ResultType: type = "result"; break;
+ }
+
+ Lua::Table result = boost::assign::map_list_of("type", Lua::valueRef(type));
+ if (!payload->getTitle().empty()) {
+ result["title"] = Lua::valueRef(payload->getTitle());
+ }
+ if (!payload->getInstructions().empty()) {
+ result["instructions"] = Lua::valueRef(payload->getInstructions());
+ }
+ result["fields"] = valueRef(convertFieldListToLua(payload->getFields()));
+ if (!payload->getReportedFields().empty()) {
+ result["reported_fields"] = valueRef(convertFieldListToLua(payload->getReportedFields()));
+ }
+
+ if (!payload->getItems().empty()) {
+ Lua::Array luaItems;
+ for (const auto& item : payload->getItems()) {
+ if (!item.empty()) {
+ luaItems.push_back(convertFieldListToLua(item));
+ }
+ }
+ result["items"] = valueRef(luaItems);
+ }
+
+ Lua::pushValue(L, result);
+
+ lua_newtable(L);
+ lua_pushcfunction(L, formIndex);
+ lua_setfield(L, -2, "__index");
+ lua_pushcfunction(L, formNewIndex);
+ lua_setfield(L, -2, "__newindex");
+ lua_setmetatable(L, -2);
+ }
+
+ int createSubmission(lua_State* L) {
+ std::shared_ptr<Form> form = convertFormFromLua(L);
+
+ // Remove all redundant elements
+ form->setInstructions("");
+ form->setTitle("");
+ form->clearItems();
+ form->clearReportedFields();
+ std::vector< std::shared_ptr<FormField> > fields(form->getFields());
+ form->clearFields();
+ for (auto&& field : fields) {
+ if (field->getType() == FormField::FixedType) {
+ continue;
+ }
+ field->clearOptions();
+ field->setLabel("");
+ field->setType(FormField::UnknownType);
+ field->setDescription("");
+ form->addField(field);
+ }
+ form->setType(Form::SubmitType);
+
+ // Convert back
+ convertFormToLua(L, form);
+ Lua::registerTableToString(L, -1);
+
+ return 1;
+ }
}
FormConvertor::FormConvertor() : GenericLuaElementConvertor<Form>("form") {
@@ -348,14 +346,14 @@ FormConvertor::FormConvertor() : GenericLuaElementConvertor<Form>("form") {
FormConvertor::~FormConvertor() {
}
-boost::shared_ptr<Form> FormConvertor::doConvertFromLua(lua_State* L) {
- return convertFormFromLua(L);
+std::shared_ptr<Form> FormConvertor::doConvertFromLua(lua_State* L) {
+ return convertFormFromLua(L);
}
-void FormConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<Form> payload) {
- convertFormToLua(L, payload);
+void FormConvertor::doConvertToLua(lua_State* L, std::shared_ptr<Form> payload) {
+ convertFormToLua(L, payload);
- lua_pushstring(L, "create_submission");
- lua_pushcfunction(L, createSubmission);
- lua_rawset(L, -3);
+ lua_pushstring(L, "create_submission");
+ lua_pushcfunction(L, createSubmission);
+ lua_rawset(L, -3);
}
diff --git a/Sluift/ElementConvertors/FormConvertor.h b/Sluift/ElementConvertors/FormConvertor.h
index eaccf74..8ca20cc 100644
--- a/Sluift/ElementConvertors/FormConvertor.h
+++ b/Sluift/ElementConvertors/FormConvertor.h
@@ -1,23 +1,22 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/Form.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/Form.h>
namespace Swift {
- class FormConvertor : public GenericLuaElementConvertor<Form> {
- public:
- FormConvertor();
- virtual ~FormConvertor();
+ class FormConvertor : public GenericLuaElementConvertor<Form> {
+ public:
+ FormConvertor();
+ virtual ~FormConvertor() override;
- virtual boost::shared_ptr<Form> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<Form>) SWIFTEN_OVERRIDE;
- };
+ virtual std::shared_ptr<Form> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<Form>) override;
+ };
}
diff --git a/Sluift/ElementConvertors/ForwardedConvertor.cpp b/Sluift/ElementConvertors/ForwardedConvertor.cpp
new file mode 100644
index 0000000..b353eea
--- /dev/null
+++ b/Sluift/ElementConvertors/ForwardedConvertor.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/ForwardedConvertor.h>
+
+#include <memory>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
+#include <Swiften/Elements/Delay.h>
+#include <Swiften/Elements/IQ.h>
+#include <Swiften/Elements/Message.h>
+#include <Swiften/Elements/Presence.h>
+
+#include <Sluift/LuaElementConvertors.h>
+
+using namespace Swift;
+
+ForwardedConvertor::ForwardedConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<Forwarded>("forwarded"),
+ convertors(convertors) {
+}
+
+ForwardedConvertor::~ForwardedConvertor() {
+}
+
+std::shared_ptr<Forwarded> ForwardedConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<Forwarded> result = std::make_shared<Forwarded>();
+ lua_getfield(L, -1, "delay");
+ if (!lua_isnil(L, -1)) {
+ std::shared_ptr<Delay> delay = std::dynamic_pointer_cast<Delay>(convertors->convertFromLuaUntyped(L, -1, "delay"));
+ if (!!delay) {
+ result->setDelay(delay);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "stanza");
+ if (!lua_isnil(L, -1)) {
+ std::shared_ptr<Stanza> stanza = std::dynamic_pointer_cast<Stanza>(convertors->convertFromLua(L, -1));
+ if (!!stanza) {
+ result->setStanza(stanza);
+ }
+ lua_pop(L, 1);
+ return result;
+ }
+ return result;
+}
+
+void ForwardedConvertor::doConvertToLua(lua_State* L, std::shared_ptr<Forwarded> payload) {
+ lua_createtable(L, 0, 0);
+ if (convertors->convertToLuaUntyped(L, payload->getDelay()) > 0) {
+ lua_setfield(L, -2, "delay");
+ }
+ std::shared_ptr<Stanza> stanza = payload->getStanza();
+ if (!!stanza) {
+ if (convertors->convertToLua(L, stanza) > 0) {
+ lua_setfield(L, -2, "stanza");
+ }
+ }
+}
+
+boost::optional<LuaElementConvertor::Documentation> ForwardedConvertor::getDocumentation() const {
+ return Documentation(
+ "Forwarded",
+ "This table has the following fields:\n\n"
+ "- `delay`: @{Delay} (Optional)\n"
+ "- `stanza`: @{Stanza} (Optional)\n"
+ );
+}
diff --git a/Sluift/ElementConvertors/ForwardedConvertor.h b/Sluift/ElementConvertors/ForwardedConvertor.h
new file mode 100644
index 0000000..32d29e6
--- /dev/null
+++ b/Sluift/ElementConvertors/ForwardedConvertor.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/Forwarded.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class ForwardedConvertor : public GenericLuaElementConvertor<Forwarded> {
+ public:
+ ForwardedConvertor(LuaElementConvertors* convertors);
+ virtual ~ForwardedConvertor() override;
+
+ virtual std::shared_ptr<Forwarded> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<Forwarded>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+
+ private:
+ LuaElementConvertors* convertors;
+ };
+}
+
diff --git a/Sluift/ElementConvertors/IQConvertor.cpp b/Sluift/ElementConvertors/IQConvertor.cpp
new file mode 100644
index 0000000..67a4a2a
--- /dev/null
+++ b/Sluift/ElementConvertors/IQConvertor.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/IQConvertor.h>
+
+#include <memory>
+
+#include <lua.hpp>
+
+#include <Sluift/LuaElementConvertors.h>
+
+using namespace Swift;
+
+IQConvertor::IQConvertor(LuaElementConvertors* convertors) :
+ StanzaConvertor<IQ>("iq"),
+ convertors(convertors) {
+}
+
+IQConvertor::~IQConvertor() {
+}
+
+std::shared_ptr<IQ> IQConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<IQ> result = getStanza(L, convertors);
+ lua_getfield(L, -1, "type");
+ if (lua_isstring(L, -1)) {
+ result->setType(IQConvertor::convertIQTypeFromString(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void IQConvertor::doConvertToLua(lua_State* L, std::shared_ptr<IQ> stanza) {
+ pushStanza(L, stanza, convertors);
+ const std::string type = IQConvertor::convertIQTypeToString(stanza->getType());
+ lua_pushstring(L, type.c_str());
+ lua_setfield(L, -2, "type");
+}
+
+boost::optional<LuaElementConvertor::Documentation> IQConvertor::getDocumentation() const {
+ return Documentation(
+ "IQ",
+ "This table has the following fields:\n\n"
+ "- `type`: string\n"
+ "- `id`: string\n"
+ "- `from`: string\n"
+ "- `to`: string\n"
+ "- `payloads`: array<@{Payload}>\n"
+ );
+}
+
+std::string IQConvertor::convertIQTypeToString(IQ::Type type) {
+ switch (type) {
+ case IQ::Get: return "get";
+ case IQ::Set: return "set";
+ case IQ::Result: return "result";
+ case IQ::Error: return "error";
+ }
+ assert(false);
+ return "";
+}
+
+IQ::Type IQConvertor::convertIQTypeFromString(const std::string& type) {
+ if (type == "get") {
+ return IQ::Get;
+ }
+ else if (type == "set") {
+ return IQ::Set;
+ }
+ else {
+ throw Lua::Exception("Illegal query type: '" + type + "'");
+ }
+}
diff --git a/Sluift/ElementConvertors/IQConvertor.h b/Sluift/ElementConvertors/IQConvertor.h
new file mode 100644
index 0000000..6ccaa46
--- /dev/null
+++ b/Sluift/ElementConvertors/IQConvertor.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/IQ.h>
+
+#include <Sluift/ElementConvertors/StanzaConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class IQConvertor : public StanzaConvertor<IQ> {
+ public:
+ IQConvertor(LuaElementConvertors* convertors);
+ virtual ~IQConvertor() override;
+
+ virtual std::shared_ptr<IQ> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<IQ>) override;
+
+ virtual boost::optional<Documentation> getDocumentation() const override;
+
+ static std::string convertIQTypeToString(IQ::Type type);
+ static IQ::Type convertIQTypeFromString(const std::string& type);
+
+ private:
+ LuaElementConvertors* convertors;
+ };
+}
+
diff --git a/Sluift/ElementConvertors/IsodeIQDelegationConvertor.cpp b/Sluift/ElementConvertors/IsodeIQDelegationConvertor.cpp
new file mode 100644
index 0000000..56b4a80
--- /dev/null
+++ b/Sluift/ElementConvertors/IsodeIQDelegationConvertor.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/IsodeIQDelegationConvertor.h>
+
+#include <memory>
+
+#include <lua.hpp>
+
+#include <Sluift/LuaElementConvertors.h>
+
+using namespace Swift;
+
+IsodeIQDelegationConvertor::IsodeIQDelegationConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<IsodeIQDelegation>("isode_iq_delegation"),
+ convertors(convertors) {
+}
+
+IsodeIQDelegationConvertor::~IsodeIQDelegationConvertor() {
+}
+
+std::shared_ptr<IsodeIQDelegation> IsodeIQDelegationConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<IsodeIQDelegation> result = std::make_shared<IsodeIQDelegation>();
+ lua_getfield(L, -1, "forward");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<Forwarded> payload = std::dynamic_pointer_cast<Forwarded>(convertors->convertFromLuaUntyped(L, -1, "forwarded"))) {
+ result->setForward(payload);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void IsodeIQDelegationConvertor::doConvertToLua(lua_State* L, std::shared_ptr<IsodeIQDelegation> payload) {
+ lua_createtable(L, 0, 0);
+ if (convertors->convertToLuaUntyped(L, payload->getForward()) > 0) {
+ lua_setfield(L, -2, "forward");
+ }
+}
+
+boost::optional<LuaElementConvertor::Documentation> IsodeIQDelegationConvertor::getDocumentation() const {
+ return Documentation(
+ "IsodeIQDelegation",
+ "This table has the following fields:\n\n"
+ "- `forward`: @{Forwarded}\n"
+ );
+}
diff --git a/Sluift/ElementConvertors/IsodeIQDelegationConvertor.h b/Sluift/ElementConvertors/IsodeIQDelegationConvertor.h
new file mode 100644
index 0000000..f573b13
--- /dev/null
+++ b/Sluift/ElementConvertors/IsodeIQDelegationConvertor.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/IsodeIQDelegation.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class IsodeIQDelegationConvertor : public GenericLuaElementConvertor<IsodeIQDelegation> {
+ public:
+ IsodeIQDelegationConvertor(LuaElementConvertors* convertors);
+ virtual ~IsodeIQDelegationConvertor() override;
+
+ virtual std::shared_ptr<IsodeIQDelegation> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<IsodeIQDelegation>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+
+ private:
+ LuaElementConvertors* convertors;
+ };
+}
diff --git a/Sluift/ElementConvertors/MAMFinConvertor.cpp b/Sluift/ElementConvertors/MAMFinConvertor.cpp
new file mode 100644
index 0000000..4fb8201
--- /dev/null
+++ b/Sluift/ElementConvertors/MAMFinConvertor.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/MAMFinConvertor.h>
+
+#include <memory>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
+#include <Swiften/Elements/ResultSet.h>
+
+#include <Sluift/LuaElementConvertors.h>
+
+using namespace Swift;
+
+MAMFinConvertor::MAMFinConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<MAMFin>("mam_fin"),
+ convertors(convertors) {
+}
+
+MAMFinConvertor::~MAMFinConvertor() {
+}
+
+std::shared_ptr<MAMFin> MAMFinConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<MAMFin> result = std::make_shared<MAMFin>();
+ lua_getfield(L, -1, "query_id");
+ if (lua_isstring(L, -1)) {
+ result->setQueryID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "complete");
+ if (lua_isboolean(L, -1)) {
+ result->setComplete(lua_toboolean(L, -1) != 0);
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "stable");
+ if (!lua_isnil(L, -1)) {
+ result->setStable(lua_toboolean(L, -1) != 0);
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "result_set");
+ if (!lua_isnil(L, -1)) {
+ std::shared_ptr<ResultSet> resultSet = std::dynamic_pointer_cast<ResultSet>(convertors->convertFromLuaUntyped(L, -1, "result_set"));
+ if (!!resultSet) {
+ result->setResultSet(resultSet);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void MAMFinConvertor::doConvertToLua(lua_State* L, std::shared_ptr<MAMFin> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getQueryID()) {
+ lua_pushstring(L, (*payload->getQueryID()).c_str());
+ lua_setfield(L, -2, "query_id");
+ }
+ lua_pushboolean(L, payload->isComplete());
+ lua_setfield(L, -2, "complete");
+ lua_pushboolean(L, payload->isStable());
+ lua_setfield(L, -2, "stable");
+ if (convertors->convertToLuaUntyped(L, payload->getResultSet()) > 0) {
+ lua_setfield(L, -2, "result_set");
+ }
+}
+
+boost::optional<LuaElementConvertor::Documentation> MAMFinConvertor::getDocumentation() const {
+ return Documentation(
+ "MAMFin",
+ "This table has the following fields:\n\n"
+ "- `query_id`: string (Optional)\n"
+ "- `complete`: boolean (Optional)\n"
+ "- `stable`: boolean (Optional)\n"
+ "- `result_set`: @{ResultSet} (Optional)\n"
+ );
+}
diff --git a/Sluift/ElementConvertors/MAMFinConvertor.h b/Sluift/ElementConvertors/MAMFinConvertor.h
new file mode 100644
index 0000000..6e5d58c
--- /dev/null
+++ b/Sluift/ElementConvertors/MAMFinConvertor.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/MAMFin.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class MAMFinConvertor : public GenericLuaElementConvertor<MAMFin> {
+ public:
+ MAMFinConvertor(LuaElementConvertors* convertors);
+ virtual ~MAMFinConvertor() override;
+
+ virtual std::shared_ptr<MAMFin> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<MAMFin>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+
+ private:
+ LuaElementConvertors* convertors;
+ };
+}
+
diff --git a/Sluift/ElementConvertors/MAMQueryConvertor.cpp b/Sluift/ElementConvertors/MAMQueryConvertor.cpp
new file mode 100644
index 0000000..52337ce
--- /dev/null
+++ b/Sluift/ElementConvertors/MAMQueryConvertor.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/MAMQueryConvertor.h>
+
+#include <memory>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
+#include <Swiften/Elements/Form.h>
+#include <Swiften/Elements/ResultSet.h>
+
+#include <Sluift/LuaElementConvertors.h>
+
+using namespace Swift;
+
+MAMQueryConvertor::MAMQueryConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<MAMQuery>("mam"),
+ convertors(convertors) {
+}
+
+MAMQueryConvertor::~MAMQueryConvertor() {
+}
+
+std::shared_ptr<MAMQuery> MAMQueryConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<MAMQuery> result = std::make_shared<MAMQuery>();
+ lua_getfield(L, -1, "query_id");
+ if (lua_isstring(L, -1)) {
+ result->setQueryID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "form");
+ if (!lua_isnil(L, -1)) {
+ std::shared_ptr<Form> form = std::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"));
+ if (!!form) {
+ result->setForm(form);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "result_set");
+ if (!lua_isnil(L, -1)) {
+ std::shared_ptr<ResultSet> resultSet = std::dynamic_pointer_cast<ResultSet>(convertors->convertFromLuaUntyped(L, -1, "result_set"));
+ if (!!resultSet) {
+ result->setResultSet(resultSet);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void MAMQueryConvertor::doConvertToLua(lua_State* L, std::shared_ptr<MAMQuery> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getQueryID()) {
+ lua_pushstring(L, (*payload->getQueryID()).c_str());
+ lua_setfield(L, -2, "query_id");
+ }
+ if (payload->getNode()) {
+ lua_pushstring(L, (*payload->getNode()).c_str());
+ lua_setfield(L, -2, "node");
+ }
+ if (convertors->convertToLuaUntyped(L, payload->getForm()) > 0) {
+ lua_setfield(L, -2, "form");
+ }
+ if (convertors->convertToLuaUntyped(L, payload->getResultSet()) > 0) {
+ lua_setfield(L, -2, "result_set");
+ }
+}
+
+boost::optional<LuaElementConvertor::Documentation> MAMQueryConvertor::getDocumentation() const {
+ return Documentation(
+ "MAMQuery",
+ "This table has the following fields:\n\n"
+ "- `query_id`: string (Optional)\n"
+ "- `node`: string (Optional)\n"
+ "- `form`: string @{Form} (Optional)\n"
+ "- `result_set`: @{ResultSet} (Optional)\n"
+ );
+}
diff --git a/Sluift/ElementConvertors/MAMQueryConvertor.h b/Sluift/ElementConvertors/MAMQueryConvertor.h
new file mode 100644
index 0000000..3e9d387
--- /dev/null
+++ b/Sluift/ElementConvertors/MAMQueryConvertor.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/MAMQuery.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class MAMQueryConvertor : public GenericLuaElementConvertor<MAMQuery> {
+ public:
+ MAMQueryConvertor(LuaElementConvertors* convertors);
+ virtual ~MAMQueryConvertor() override;
+
+ virtual std::shared_ptr<MAMQuery> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<MAMQuery>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+
+ private:
+ LuaElementConvertors* convertors;
+ };
+}
+
diff --git a/Sluift/ElementConvertors/MAMResultConvertor.cpp b/Sluift/ElementConvertors/MAMResultConvertor.cpp
new file mode 100644
index 0000000..25b4c39
--- /dev/null
+++ b/Sluift/ElementConvertors/MAMResultConvertor.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/MAMResultConvertor.h>
+
+#include <memory>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
+#include <Swiften/Elements/Forwarded.h>
+
+#include <Sluift/LuaElementConvertors.h>
+
+using namespace Swift;
+
+MAMResultConvertor::MAMResultConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<MAMResult>("mam_result"),
+ convertors(convertors) {
+}
+
+MAMResultConvertor::~MAMResultConvertor() {
+}
+
+std::shared_ptr<MAMResult> MAMResultConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<MAMResult> result = std::make_shared<MAMResult>();
+ lua_getfield(L, -1, "payload");
+ if (!lua_isnil(L, -1)) {
+ std::shared_ptr<Forwarded> payload = std::dynamic_pointer_cast<Forwarded>(convertors->convertFromLuaUntyped(L, -1, "payload"));
+ if (!!payload) {
+ result->setPayload(payload);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "id");
+ if (lua_isstring(L, -1)) {
+ result->setID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "query_id");
+ if (lua_isstring(L, -1)) {
+ result->setQueryID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void MAMResultConvertor::doConvertToLua(lua_State* L, std::shared_ptr<MAMResult> payload) {
+ lua_createtable(L, 0, 0);
+ if (convertors->convertToLuaUntyped(L, payload->getPayload()) > 0) {
+ lua_setfield(L, -2, "payload");
+ }
+ lua_pushstring(L, payload->getID().c_str());
+ lua_setfield(L, -2, "id");
+ if (payload->getQueryID()) {
+ lua_pushstring(L, (*payload->getQueryID()).c_str());
+ lua_setfield(L, -2, "query_id");
+ }
+}
+
+boost::optional<LuaElementConvertor::Documentation> MAMResultConvertor::getDocumentation() const {
+ return Documentation(
+ "MAMResult",
+ "This table has the following fields:\n\n"
+ "- `payload`: @{Forwarded}\n"
+ "- `id`: string\n"
+ "- `query_id`: string (Optional)\n"
+ );
+}
diff --git a/Sluift/ElementConvertors/MAMResultConvertor.h b/Sluift/ElementConvertors/MAMResultConvertor.h
new file mode 100644
index 0000000..cd1d27d
--- /dev/null
+++ b/Sluift/ElementConvertors/MAMResultConvertor.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/MAMResult.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class MAMResultConvertor : public GenericLuaElementConvertor<MAMResult> {
+ public:
+ MAMResultConvertor(LuaElementConvertors* convertors);
+ virtual ~MAMResultConvertor() override;
+
+ virtual std::shared_ptr<MAMResult> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<MAMResult>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+
+ private:
+ LuaElementConvertors* convertors;
+ };
+}
+
diff --git a/Sluift/ElementConvertors/MessageConvertor.cpp b/Sluift/ElementConvertors/MessageConvertor.cpp
new file mode 100644
index 0000000..b7bf286
--- /dev/null
+++ b/Sluift/ElementConvertors/MessageConvertor.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/MessageConvertor.h>
+
+#include <memory>
+
+#include <lua.hpp>
+
+#include <Sluift/LuaElementConvertors.h>
+
+using namespace Swift;
+
+MessageConvertor::MessageConvertor(LuaElementConvertors* convertors) :
+ StanzaConvertor<Message>("message"),
+ convertors(convertors) {
+}
+
+MessageConvertor::~MessageConvertor() {
+}
+
+std::shared_ptr<Message> MessageConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<Message> result = getStanza(L, convertors);
+ lua_getfield(L, -1, "type");
+ if (lua_isstring(L, -1)) {
+ result->setType(convertMessageTypeFromString(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void MessageConvertor::doConvertToLua(lua_State* L, std::shared_ptr<Message> stanza) {
+ pushStanza(L, stanza, convertors);
+ const std::string type = convertMessageTypeToString(stanza->getType());
+ lua_pushstring(L, type.c_str());
+ lua_setfield(L, -2, "type");
+}
+
+boost::optional<LuaElementConvertor::Documentation> MessageConvertor::getDocumentation() const {
+ return Documentation(
+ "Message",
+ "This table has the following fields:\n\n"
+ "- `type`: string\n"
+ "- `id`: string\n"
+ "- `from`: string\n"
+ "- `to`: string\n"
+ "- `payloads`: array<@{Payload}>\n"
+ );
+}
+
+std::string MessageConvertor::convertMessageTypeToString(Message::Type type) {
+ switch (type) {
+ case Message::Normal: return "normal";
+ case Message::Chat: return "chat";
+ case Message::Error: return "error";
+ case Message::Groupchat: return "groupchat";
+ case Message::Headline: return "headline";
+ }
+ assert(false);
+ return "";
+}
+
+Message::Type MessageConvertor::convertMessageTypeFromString(const std::string& type) {
+ if (type == "normal") {
+ return Message::Normal;
+ }
+ else if (type == "chat") {
+ return Message::Chat;
+ }
+ else if (type == "error") {
+ return Message::Error;
+ }
+ else if (type == "groupchat") {
+ return Message::Groupchat;
+ }
+ else if (type == "headline") {
+ return Message::Headline;
+ }
+ else {
+ throw Lua::Exception("Illegal message type: '" + type + "'");
+ }
+}
diff --git a/Sluift/ElementConvertors/MessageConvertor.h b/Sluift/ElementConvertors/MessageConvertor.h
new file mode 100644
index 0000000..723e1b1
--- /dev/null
+++ b/Sluift/ElementConvertors/MessageConvertor.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/Message.h>
+
+#include <Sluift/ElementConvertors/StanzaConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class MessageConvertor : public StanzaConvertor<Message> {
+ public:
+ MessageConvertor(LuaElementConvertors* convertors);
+ virtual ~MessageConvertor() override;
+
+ virtual std::shared_ptr<Message> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<Message>) override;
+
+ virtual boost::optional<Documentation> getDocumentation() const override;
+
+ static std::string convertMessageTypeToString(Message::Type type);
+ static Message::Type convertMessageTypeFromString(const std::string& type);
+
+ private:
+ LuaElementConvertors* convertors;
+ };
+}
+
diff --git a/Sluift/ElementConvertors/PresenceConvertor.cpp b/Sluift/ElementConvertors/PresenceConvertor.cpp
new file mode 100644
index 0000000..abfac77
--- /dev/null
+++ b/Sluift/ElementConvertors/PresenceConvertor.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/PresenceConvertor.h>
+
+#include <memory>
+
+#include <lua.hpp>
+
+#include <Sluift/LuaElementConvertors.h>
+
+using namespace Swift;
+
+PresenceConvertor::PresenceConvertor(LuaElementConvertors* convertors) :
+ StanzaConvertor<Presence>("presence"),
+ convertors(convertors) {
+}
+
+PresenceConvertor::~PresenceConvertor() {
+}
+
+std::shared_ptr<Presence> PresenceConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<Presence> result = getStanza(L, convertors);
+ lua_getfield(L, -1, "type");
+ if (lua_isstring(L, -1)) {
+ result->setType(convertPresenceTypeFromString(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PresenceConvertor::doConvertToLua(lua_State* L, std::shared_ptr<Presence> stanza) {
+ pushStanza(L, stanza, convertors);
+ const std::string type = convertPresenceTypeToString(stanza->getType());
+ lua_pushstring(L, type.c_str());
+ lua_setfield(L, -2, "type");
+}
+
+boost::optional<LuaElementConvertor::Documentation> PresenceConvertor::getDocumentation() const {
+ return Documentation(
+ "Presence",
+ "This table has the following fields:\n\n"
+ "- `type`: string\n"
+ "- `id`: string\n"
+ "- `from`: string\n"
+ "- `to`: string\n"
+ "- `payloads`: array<@{Payload}>\n"
+ );
+}
+
+std::string PresenceConvertor::convertPresenceTypeToString(Presence::Type type) {
+ switch (type) {
+ case Presence::Available: return "available";
+ case Presence::Error: return "error";
+ case Presence::Probe: return "probe";
+ case Presence::Subscribe: return "subscribe";
+ case Presence::Subscribed: return "subscribed";
+ case Presence::Unavailable: return "unavailable";
+ case Presence::Unsubscribe: return "unsubscribe";
+ case Presence::Unsubscribed: return "unsubscribed";
+ }
+ assert(false);
+ return "";
+}
+
+Presence::Type PresenceConvertor::convertPresenceTypeFromString(const std::string& type) {
+ if (type == "available") {
+ return Presence::Available;
+ }
+ else if (type == "error") {
+ return Presence::Error;
+ }
+ else if (type == "probe") {
+ return Presence::Probe;
+ }
+ else if (type == "subscribe") {
+ return Presence::Subscribe;
+ }
+ else if (type == "subscribed") {
+ return Presence::Subscribed;
+ }
+ else if (type == "unavailable") {
+ return Presence::Unavailable;
+ }
+ else if (type == "unsubscribe") {
+ return Presence::Unsubscribe;
+ }
+ else if (type == "unsubscribed") {
+ return Presence::Unsubscribed;
+ }
+ else {
+ throw Lua::Exception("Illegal presence type: '" + type + "'");
+ }
+}
diff --git a/Sluift/ElementConvertors/PresenceConvertor.h b/Sluift/ElementConvertors/PresenceConvertor.h
new file mode 100644
index 0000000..b13398d
--- /dev/null
+++ b/Sluift/ElementConvertors/PresenceConvertor.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/Presence.h>
+
+#include <Sluift/ElementConvertors/StanzaConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class PresenceConvertor : public StanzaConvertor<Presence> {
+ public:
+ PresenceConvertor(LuaElementConvertors* convertors);
+ virtual ~PresenceConvertor() override;
+
+ virtual std::shared_ptr<Presence> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<Presence>) override;
+
+ virtual boost::optional<Documentation> getDocumentation() const override;
+
+ static std::string convertPresenceTypeToString(Presence::Type type);
+ static Presence::Type convertPresenceTypeFromString(const std::string& type);
+
+ private:
+ LuaElementConvertors* convertors;
+ };
+}
+
diff --git a/Sluift/ElementConvertors/PubSubAffiliationConvertor.cpp b/Sluift/ElementConvertors/PubSubAffiliationConvertor.cpp
index 3d40be9..62a2b60 100644
--- a/Sluift/ElementConvertors/PubSubAffiliationConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubAffiliationConvertor.cpp
@@ -1,64 +1,88 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubAffiliationConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubAffiliationConvertor::PubSubAffiliationConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubAffiliation>("pubsub_affiliation"),
- convertors(convertors) {
+PubSubAffiliationConvertor::PubSubAffiliationConvertor() :
+ GenericLuaElementConvertor<PubSubAffiliation>("pubsub_affiliation") {
}
PubSubAffiliationConvertor::~PubSubAffiliationConvertor() {
}
-boost::shared_ptr<PubSubAffiliation> PubSubAffiliationConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubAffiliation> result = boost::make_shared<PubSubAffiliation>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "type");
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubAffiliation> PubSubAffiliationConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubAffiliation> result = std::make_shared<PubSubAffiliation>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "type");
+ if (lua_isstring(L, -1)) {
+ if (std::string(lua_tostring(L, -1)) == "none") {
+ result->setType(PubSubAffiliation::None);
+ }
+ if (std::string(lua_tostring(L, -1)) == "member") {
+ result->setType(PubSubAffiliation::Member);
+ }
+ if (std::string(lua_tostring(L, -1)) == "outcast") {
+ result->setType(PubSubAffiliation::Outcast);
+ }
+ if (std::string(lua_tostring(L, -1)) == "owner") {
+ result->setType(PubSubAffiliation::Owner);
+ }
+ if (std::string(lua_tostring(L, -1)) == "publisher") {
+ result->setType(PubSubAffiliation::Publisher);
+ }
+ if (std::string(lua_tostring(L, -1)) == "publish_only") {
+ result->setType(PubSubAffiliation::PublishOnly);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubAffiliationConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubAffiliation> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ switch (payload->getType()) {
+ case PubSubAffiliation::None:
+ lua_pushstring(L, "none");
+ break;
+ case PubSubAffiliation::Member:
+ lua_pushstring(L, "member");
+ break;
+ case PubSubAffiliation::Outcast:
+ lua_pushstring(L, "outcast");
+ break;
+ case PubSubAffiliation::Owner:
+ lua_pushstring(L, "owner");
+ break;
+ case PubSubAffiliation::Publisher:
+ lua_pushstring(L, "publisher");
+ break;
+ case PubSubAffiliation::PublishOnly:
+ lua_pushstring(L, "publish_only");
+ break;
+ }
+ lua_setfield(L, -2, "type");
}
-void PubSubAffiliationConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubAffiliation> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- switch (payload->getType()) {
- case PubSubAffiliation::None:
- lua_pushstring(L, "none");
- break;
- case PubSubAffiliation::Member:
- lua_pushstring(L, "member");
- break;
- case PubSubAffiliation::Outcast:
- lua_pushstring(L, "outcast");
- break;
- case PubSubAffiliation::Owner:
- lua_pushstring(L, "owner");
- break;
- case PubSubAffiliation::Publisher:
- lua_pushstring(L, "publisher");
- break;
- case PubSubAffiliation::PublishOnly:
- lua_pushstring(L, "publish_only");
- break;
- }
- lua_setfield(L, -2, "type");
+boost::optional<LuaElementConvertor::Documentation> PubSubAffiliationConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubAffiliation",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `type`: `\"none\"`, `\"member\"`, `\"outcast\"`, `\"owner\"`, `\"publisher\"`, or `\"publish_only\"`\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubAffiliationConvertor.h b/Sluift/ElementConvertors/PubSubAffiliationConvertor.h
index 632a8d7..1b5cd60 100644
--- a/Sluift/ElementConvertors/PubSubAffiliationConvertor.h
+++ b/Sluift/ElementConvertors/PubSubAffiliationConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubAffiliation.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubAffiliation.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubAffiliationConvertor : public GenericLuaElementConvertor<PubSubAffiliation> {
- public:
- PubSubAffiliationConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubAffiliationConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubAffiliation> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubAffiliation>) SWIFTEN_OVERRIDE;
+ class PubSubAffiliationConvertor : public GenericLuaElementConvertor<PubSubAffiliation> {
+ public:
+ PubSubAffiliationConvertor();
+ virtual ~PubSubAffiliationConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubAffiliation> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubAffiliation>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubAffiliationsConvertor.cpp b/Sluift/ElementConvertors/PubSubAffiliationsConvertor.cpp
index 9f34235..8f8a660 100644
--- a/Sluift/ElementConvertors/PubSubAffiliationsConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubAffiliationsConvertor.cpp
@@ -1,70 +1,78 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubAffiliationsConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
-#include <Sluift/LuaElementConvertors.h>
-#include <Swiften/Base/foreach.h>
+#include <lua.hpp>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <Sluift/LuaElementConvertors.h>
using namespace Swift;
-PubSubAffiliationsConvertor::PubSubAffiliationsConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubAffiliations>("pubsub_affiliations"),
- convertors(convertors) {
+PubSubAffiliationsConvertor::PubSubAffiliationsConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubAffiliations>("pubsub_affiliations"),
+ convertors(convertors) {
}
PubSubAffiliationsConvertor::~PubSubAffiliationsConvertor() {
}
-boost::shared_ptr<PubSubAffiliations> PubSubAffiliationsConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubAffiliations> result = boost::make_shared<PubSubAffiliations>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- if (lua_type(L, -1) == LUA_TTABLE) {
- std::vector< boost::shared_ptr<PubSubAffiliation> > items;
- for(size_t i = 0; i < lua_objlen(L, -1); ++i) {
- lua_pushnumber(L, i + 1);
- lua_gettable(L, -2);
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubAffiliation> payload = boost::dynamic_pointer_cast<PubSubAffiliation>(convertors->convertFromLuaUntyped(L, -1, "pubsub_affiliation"))) {
- items.push_back(payload);
- }
- }
- lua_pop(L, 1);
- }
+std::shared_ptr<PubSubAffiliations> PubSubAffiliationsConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubAffiliations> result = std::make_shared<PubSubAffiliations>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ std::vector< std::shared_ptr<PubSubAffiliation> > items;
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubAffiliation> payload = std::dynamic_pointer_cast<PubSubAffiliation>(convertors->convertFromLuaUntyped(L, -1, "pubsub_affiliation"))) {
+ items.push_back(payload);
+ }
+ }
+ lua_pop(L, 1);
+ }
+
+ result->setAffiliations(items);
+ }
+ return result;
+}
- result->setAffiliations(items);
- }
- return result;
+void PubSubAffiliationsConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubAffiliations> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getNode()) {
+ lua_pushstring(L, (*payload->getNode()).c_str());
+ lua_setfield(L, -2, "node");
+ }
+ if (!payload->getAffiliations().empty()) {
+ {
+ int i = 0;
+ for (auto&& item : payload->getAffiliations()) {
+ if (convertors->convertToLuaUntyped(L, item) > 0) {
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ }
+ }
}
-void PubSubAffiliationsConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubAffiliations> payload) {
- lua_createtable(L, 0, 0);
- if (payload->getNode()) {
- lua_pushstring(L, (*payload->getNode()).c_str());
- lua_setfield(L, -2, "node");
- }
- if (!payload->getAffiliations().empty()) {
- {
- int i = 0;
- foreach(boost::shared_ptr<PubSubAffiliation> item, payload->getAffiliations()) {
- if (convertors->convertToLuaUntyped(L, item) > 0) {
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- ++i;
- }
- }
- }
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubAffiliationsConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubAffiliations",
+ "This table has the following fields:\n\n"
+ "- `node`: string (Optional)\n"
+ "- `affiliations`: array<@{PubSubAffiliation}>\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubAffiliationsConvertor.h b/Sluift/ElementConvertors/PubSubAffiliationsConvertor.h
index fb0279a..eda218b 100644
--- a/Sluift/ElementConvertors/PubSubAffiliationsConvertor.h
+++ b/Sluift/ElementConvertors/PubSubAffiliationsConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubAffiliations.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubAffiliations.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubAffiliationsConvertor : public GenericLuaElementConvertor<PubSubAffiliations> {
- public:
- PubSubAffiliationsConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubAffiliationsConvertor();
+ class PubSubAffiliationsConvertor : public GenericLuaElementConvertor<PubSubAffiliations> {
+ public:
+ PubSubAffiliationsConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubAffiliationsConvertor() override;
- virtual boost::shared_ptr<PubSubAffiliations> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubAffiliations>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubAffiliations> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubAffiliations>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubConfigureConvertor.cpp b/Sluift/ElementConvertors/PubSubConfigureConvertor.cpp
index 893bc27..d8bf05d 100644
--- a/Sluift/ElementConvertors/PubSubConfigureConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubConfigureConvertor.cpp
@@ -1,44 +1,50 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubConfigureConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Sluift/LuaElementConvertors.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubConfigureConvertor::PubSubConfigureConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubConfigure>("pubsub_configure"),
- convertors(convertors) {
+PubSubConfigureConvertor::PubSubConfigureConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubConfigure>("pubsub_configure"),
+ convertors(convertors) {
}
PubSubConfigureConvertor::~PubSubConfigureConvertor() {
}
-boost::shared_ptr<PubSubConfigure> PubSubConfigureConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubConfigure> result = boost::make_shared<PubSubConfigure>();
- lua_getfield(L, -1, "data");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<Form> payload = boost::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) {
- result->setData(payload);
- }
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubConfigure> PubSubConfigureConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubConfigure> result = std::make_shared<PubSubConfigure>();
+ lua_getfield(L, -1, "data");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<Form> payload = std::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) {
+ result->setData(payload);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubConfigureConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubConfigure> payload) {
+ lua_createtable(L, 0, 0);
+ if (convertors->convertToLuaUntyped(L, payload->getData()) > 0) {
+ lua_setfield(L, -2, "data");
+ }
}
-void PubSubConfigureConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubConfigure> payload) {
- lua_createtable(L, 0, 0);
- if (convertors->convertToLuaUntyped(L, payload->getData()) > 0) {
- lua_setfield(L, -2, "data");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubConfigureConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubConfigure",
+ "This table has the following fields:\n\n"
+ "- `data`: @{Form}\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubConfigureConvertor.h b/Sluift/ElementConvertors/PubSubConfigureConvertor.h
index 0dd9094..f1848c2 100644
--- a/Sluift/ElementConvertors/PubSubConfigureConvertor.h
+++ b/Sluift/ElementConvertors/PubSubConfigureConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubConfigure.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubConfigure.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubConfigureConvertor : public GenericLuaElementConvertor<PubSubConfigure> {
- public:
- PubSubConfigureConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubConfigureConvertor();
+ class PubSubConfigureConvertor : public GenericLuaElementConvertor<PubSubConfigure> {
+ public:
+ PubSubConfigureConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubConfigureConvertor() override;
- virtual boost::shared_ptr<PubSubConfigure> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubConfigure>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubConfigure> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubConfigure>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubCreateConvertor.cpp b/Sluift/ElementConvertors/PubSubCreateConvertor.cpp
index 64e2ee3..80553d5 100644
--- a/Sluift/ElementConvertors/PubSubCreateConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubCreateConvertor.cpp
@@ -1,51 +1,58 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubCreateConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Sluift/LuaElementConvertors.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubCreateConvertor::PubSubCreateConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubCreate>("pubsub_create"),
- convertors(convertors) {
+PubSubCreateConvertor::PubSubCreateConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubCreate>("pubsub_create"),
+ convertors(convertors) {
}
PubSubCreateConvertor::~PubSubCreateConvertor() {
}
-boost::shared_ptr<PubSubCreate> PubSubCreateConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubCreate> result = boost::make_shared<PubSubCreate>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "configure");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubConfigure> payload = boost::dynamic_pointer_cast<PubSubConfigure>(convertors->convertFromLuaUntyped(L, -1, "pubsub_configure"))) {
- result->setConfigure(payload);
- }
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubCreate> PubSubCreateConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubCreate> result = std::make_shared<PubSubCreate>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "configure");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubConfigure> payload = std::dynamic_pointer_cast<PubSubConfigure>(convertors->convertFromLuaUntyped(L, -1, "pubsub_configure"))) {
+ result->setConfigure(payload);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubCreateConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubCreate> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ if (convertors->convertToLuaUntyped(L, payload->getConfigure()) > 0) {
+ lua_setfield(L, -2, "configure");
+ }
}
-void PubSubCreateConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubCreate> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- if (convertors->convertToLuaUntyped(L, payload->getConfigure()) > 0) {
- lua_setfield(L, -2, "configure");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubCreateConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubCreate",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `configure`: @{PubSubConfigure}\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubCreateConvertor.h b/Sluift/ElementConvertors/PubSubCreateConvertor.h
index 2cb1ea6..f3b11bd 100644
--- a/Sluift/ElementConvertors/PubSubCreateConvertor.h
+++ b/Sluift/ElementConvertors/PubSubCreateConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubCreate.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubCreate.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubCreateConvertor : public GenericLuaElementConvertor<PubSubCreate> {
- public:
- PubSubCreateConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubCreateConvertor();
+ class PubSubCreateConvertor : public GenericLuaElementConvertor<PubSubCreate> {
+ public:
+ PubSubCreateConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubCreateConvertor() override;
- virtual boost::shared_ptr<PubSubCreate> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubCreate>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubCreate> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubCreate>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubDefaultConvertor.cpp b/Sluift/ElementConvertors/PubSubDefaultConvertor.cpp
index 89609ed..8406913 100644
--- a/Sluift/ElementConvertors/PubSubDefaultConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubDefaultConvertor.cpp
@@ -1,57 +1,72 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubDefaultConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubDefaultConvertor::PubSubDefaultConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubDefault>("pubsub_default"),
- convertors(convertors) {
+PubSubDefaultConvertor::PubSubDefaultConvertor() :
+ GenericLuaElementConvertor<PubSubDefault>("pubsub_default") {
}
PubSubDefaultConvertor::~PubSubDefaultConvertor() {
}
-boost::shared_ptr<PubSubDefault> PubSubDefaultConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubDefault> result = boost::make_shared<PubSubDefault>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "type");
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubDefault> PubSubDefaultConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubDefault> result = std::make_shared<PubSubDefault>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "type");
+ if (lua_isstring(L, -1)) {
+ if (std::string(lua_tostring(L, -1)) == "none") {
+ result->setType(PubSubDefault::None);
+ }
+ if (std::string(lua_tostring(L, -1)) == "collection") {
+ result->setType(PubSubDefault::Collection);
+ }
+ if (std::string(lua_tostring(L, -1)) == "leaf") {
+ result->setType(PubSubDefault::Leaf);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubDefaultConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubDefault> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getNode()) {
+ lua_pushstring(L, (*payload->getNode()).c_str());
+ lua_setfield(L, -2, "node");
+ }
+ switch (payload->getType()) {
+ case PubSubDefault::None:
+ lua_pushstring(L, "none");
+ break;
+ case PubSubDefault::Collection:
+ lua_pushstring(L, "collection");
+ break;
+ case PubSubDefault::Leaf:
+ lua_pushstring(L, "leaf");
+ break;
+ }
+ lua_setfield(L, -2, "type");
}
-void PubSubDefaultConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubDefault> payload) {
- lua_createtable(L, 0, 0);
- if (payload->getNode()) {
- lua_pushstring(L, (*payload->getNode()).c_str());
- lua_setfield(L, -2, "node");
- }
- switch (payload->getType()) {
- case PubSubDefault::None:
- lua_pushstring(L, "none");
- break;
- case PubSubDefault::Collection:
- lua_pushstring(L, "collection");
- break;
- case PubSubDefault::Leaf:
- lua_pushstring(L, "leaf");
- break;
- }
- lua_setfield(L, -2, "type");
+boost::optional<LuaElementConvertor::Documentation> PubSubDefaultConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubDefault",
+ "This table has the following fields:\n\n"
+ "- `node`: string (Optional)\n"
+ "- `type`: `\"none\"`, `\"collection\"`, or `\"leaf\"`\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubDefaultConvertor.h b/Sluift/ElementConvertors/PubSubDefaultConvertor.h
index 89dd9be..1049cd4 100644
--- a/Sluift/ElementConvertors/PubSubDefaultConvertor.h
+++ b/Sluift/ElementConvertors/PubSubDefaultConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubDefault.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubDefault.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubDefaultConvertor : public GenericLuaElementConvertor<PubSubDefault> {
- public:
- PubSubDefaultConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubDefaultConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubDefault> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubDefault>) SWIFTEN_OVERRIDE;
+ class PubSubDefaultConvertor : public GenericLuaElementConvertor<PubSubDefault> {
+ public:
+ PubSubDefaultConvertor();
+ virtual ~PubSubDefaultConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubDefault> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubDefault>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubEventAssociateConvertor.cpp b/Sluift/ElementConvertors/PubSubEventAssociateConvertor.cpp
index 2b004c8..eb025a5 100644
--- a/Sluift/ElementConvertors/PubSubEventAssociateConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubEventAssociateConvertor.cpp
@@ -1,41 +1,44 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubEventAssociateConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubEventAssociateConvertor::PubSubEventAssociateConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubEventAssociate>("pubsub_event_associate"),
- convertors(convertors) {
+PubSubEventAssociateConvertor::PubSubEventAssociateConvertor() :
+ GenericLuaElementConvertor<PubSubEventAssociate>("pubsub_event_associate") {
}
PubSubEventAssociateConvertor::~PubSubEventAssociateConvertor() {
}
-boost::shared_ptr<PubSubEventAssociate> PubSubEventAssociateConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubEventAssociate> result = boost::make_shared<PubSubEventAssociate>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubEventAssociate> PubSubEventAssociateConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubEventAssociate> result = std::make_shared<PubSubEventAssociate>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubEventAssociateConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubEventAssociate> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
}
-void PubSubEventAssociateConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubEventAssociate> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
+boost::optional<LuaElementConvertor::Documentation> PubSubEventAssociateConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubEventAssociate",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubEventAssociateConvertor.h b/Sluift/ElementConvertors/PubSubEventAssociateConvertor.h
index 60c9d28..e84460f 100644
--- a/Sluift/ElementConvertors/PubSubEventAssociateConvertor.h
+++ b/Sluift/ElementConvertors/PubSubEventAssociateConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubEventAssociate.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubEventAssociate.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubEventAssociateConvertor : public GenericLuaElementConvertor<PubSubEventAssociate> {
- public:
- PubSubEventAssociateConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubEventAssociateConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubEventAssociate> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubEventAssociate>) SWIFTEN_OVERRIDE;
+ class PubSubEventAssociateConvertor : public GenericLuaElementConvertor<PubSubEventAssociate> {
+ public:
+ PubSubEventAssociateConvertor();
+ virtual ~PubSubEventAssociateConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubEventAssociate> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubEventAssociate>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubEventCollectionConvertor.cpp b/Sluift/ElementConvertors/PubSubEventCollectionConvertor.cpp
index d05b479..721b1b4 100644
--- a/Sluift/ElementConvertors/PubSubEventCollectionConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubEventCollectionConvertor.cpp
@@ -1,63 +1,71 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubEventCollectionConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Sluift/LuaElementConvertors.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubEventCollectionConvertor::PubSubEventCollectionConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubEventCollection>("pubsub_event_collection"),
- convertors(convertors) {
+PubSubEventCollectionConvertor::PubSubEventCollectionConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubEventCollection>("pubsub_event_collection"),
+ convertors(convertors) {
}
PubSubEventCollectionConvertor::~PubSubEventCollectionConvertor() {
}
-boost::shared_ptr<PubSubEventCollection> PubSubEventCollectionConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubEventCollection> result = boost::make_shared<PubSubEventCollection>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "disassociate");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubEventDisassociate> payload = boost::dynamic_pointer_cast<PubSubEventDisassociate>(convertors->convertFromLuaUntyped(L, -1, "pubsub_event_disassociate"))) {
- result->setDisassociate(payload);
- }
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "associate");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubEventAssociate> payload = boost::dynamic_pointer_cast<PubSubEventAssociate>(convertors->convertFromLuaUntyped(L, -1, "pubsub_event_associate"))) {
- result->setAssociate(payload);
- }
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubEventCollection> PubSubEventCollectionConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubEventCollection> result = std::make_shared<PubSubEventCollection>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "disassociate");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubEventDisassociate> payload = std::dynamic_pointer_cast<PubSubEventDisassociate>(convertors->convertFromLuaUntyped(L, -1, "pubsub_event_disassociate"))) {
+ result->setDisassociate(payload);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "associate");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubEventAssociate> payload = std::dynamic_pointer_cast<PubSubEventAssociate>(convertors->convertFromLuaUntyped(L, -1, "pubsub_event_associate"))) {
+ result->setAssociate(payload);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubEventCollectionConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubEventCollection> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getNode()) {
+ lua_pushstring(L, (*payload->getNode()).c_str());
+ lua_setfield(L, -2, "node");
+ }
+ if (convertors->convertToLuaUntyped(L, payload->getDisassociate()) > 0) {
+ lua_setfield(L, -2, "disassociate");
+ }
+ if (convertors->convertToLuaUntyped(L, payload->getAssociate()) > 0) {
+ lua_setfield(L, -2, "associate");
+ }
}
-void PubSubEventCollectionConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubEventCollection> payload) {
- lua_createtable(L, 0, 0);
- if (payload->getNode()) {
- lua_pushstring(L, (*payload->getNode()).c_str());
- lua_setfield(L, -2, "node");
- }
- if (convertors->convertToLuaUntyped(L, payload->getDisassociate()) > 0) {
- lua_setfield(L, -2, "disassociate");
- }
- if (convertors->convertToLuaUntyped(L, payload->getAssociate()) > 0) {
- lua_setfield(L, -2, "associate");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubEventCollectionConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubEventCollection",
+ "This table has the following fields:\n\n"
+ "- `node`: string (Optional)\n"
+ "- `disassociate`: @{PubSubEventDisassociate}\n"
+ "- `associate`: @{PubSubEventAssociate}\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubEventCollectionConvertor.h b/Sluift/ElementConvertors/PubSubEventCollectionConvertor.h
index eed2541..cab3b97 100644
--- a/Sluift/ElementConvertors/PubSubEventCollectionConvertor.h
+++ b/Sluift/ElementConvertors/PubSubEventCollectionConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubEventCollection.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubEventCollection.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubEventCollectionConvertor : public GenericLuaElementConvertor<PubSubEventCollection> {
- public:
- PubSubEventCollectionConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubEventCollectionConvertor();
+ class PubSubEventCollectionConvertor : public GenericLuaElementConvertor<PubSubEventCollection> {
+ public:
+ PubSubEventCollectionConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubEventCollectionConvertor() override;
- virtual boost::shared_ptr<PubSubEventCollection> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubEventCollection>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubEventCollection> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubEventCollection>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubEventConfigurationConvertor.cpp b/Sluift/ElementConvertors/PubSubEventConfigurationConvertor.cpp
index ecdf145..828a010 100644
--- a/Sluift/ElementConvertors/PubSubEventConfigurationConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubEventConfigurationConvertor.cpp
@@ -1,51 +1,58 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubEventConfigurationConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Sluift/LuaElementConvertors.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubEventConfigurationConvertor::PubSubEventConfigurationConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubEventConfiguration>("pubsub_event_configuration"),
- convertors(convertors) {
+PubSubEventConfigurationConvertor::PubSubEventConfigurationConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubEventConfiguration>("pubsub_event_configuration"),
+ convertors(convertors) {
}
PubSubEventConfigurationConvertor::~PubSubEventConfigurationConvertor() {
}
-boost::shared_ptr<PubSubEventConfiguration> PubSubEventConfigurationConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubEventConfiguration> result = boost::make_shared<PubSubEventConfiguration>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "data");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<Form> payload = boost::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) {
- result->setData(payload);
- }
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubEventConfiguration> PubSubEventConfigurationConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubEventConfiguration> result = std::make_shared<PubSubEventConfiguration>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "data");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<Form> payload = std::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) {
+ result->setData(payload);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubEventConfigurationConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubEventConfiguration> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ if (convertors->convertToLuaUntyped(L, payload->getData()) > 0) {
+ lua_setfield(L, -2, "data");
+ }
}
-void PubSubEventConfigurationConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubEventConfiguration> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- if (convertors->convertToLuaUntyped(L, payload->getData()) > 0) {
- lua_setfield(L, -2, "data");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubEventConfigurationConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubEventConfiguration",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `data`: @{Form}\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubEventConfigurationConvertor.h b/Sluift/ElementConvertors/PubSubEventConfigurationConvertor.h
index 4347ebc..c2d82a5 100644
--- a/Sluift/ElementConvertors/PubSubEventConfigurationConvertor.h
+++ b/Sluift/ElementConvertors/PubSubEventConfigurationConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubEventConfiguration.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubEventConfiguration.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubEventConfigurationConvertor : public GenericLuaElementConvertor<PubSubEventConfiguration> {
- public:
- PubSubEventConfigurationConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubEventConfigurationConvertor();
+ class PubSubEventConfigurationConvertor : public GenericLuaElementConvertor<PubSubEventConfiguration> {
+ public:
+ PubSubEventConfigurationConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubEventConfigurationConvertor() override;
- virtual boost::shared_ptr<PubSubEventConfiguration> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubEventConfiguration>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubEventConfiguration> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubEventConfiguration>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubEventConvertor.cpp b/Sluift/ElementConvertors/PubSubEventConvertor.cpp
index 46d870a..da7c849 100644
--- a/Sluift/ElementConvertors/PubSubEventConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubEventConvertor.cpp
@@ -1,37 +1,35 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubEventConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Sluift/LuaElementConvertors.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubEventConvertor::PubSubEventConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubEvent>("pubsub_event"),
- convertors(convertors) {
+PubSubEventConvertor::PubSubEventConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubEvent>("pubsub_event"),
+ convertors(convertors) {
}
PubSubEventConvertor::~PubSubEventConvertor() {
}
-boost::shared_ptr<PubSubEvent> PubSubEventConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubEvent> result = boost::make_shared<PubSubEvent>();
- if (boost::shared_ptr<PubSubEventPayload> payload = boost::dynamic_pointer_cast<PubSubEventPayload>(convertors->convertFromLua(L, -1))) {
- result->setPayload(payload);
- }
- return result;
+std::shared_ptr<PubSubEvent> PubSubEventConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubEvent> result = std::make_shared<PubSubEvent>();
+ if (std::shared_ptr<PubSubEventPayload> payload = std::dynamic_pointer_cast<PubSubEventPayload>(convertors->convertFromLua(L, -1))) {
+ result->setPayload(payload);
+ }
+ return result;
}
-void PubSubEventConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubEvent> event) {
- convertors->convertToLua(L, event->getPayload());
+void PubSubEventConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubEvent> event) {
+ convertors->convertToLua(L, event->getPayload());
}
diff --git a/Sluift/ElementConvertors/PubSubEventConvertor.h b/Sluift/ElementConvertors/PubSubEventConvertor.h
index 8250fc4..b116c68 100644
--- a/Sluift/ElementConvertors/PubSubEventConvertor.h
+++ b/Sluift/ElementConvertors/PubSubEventConvertor.h
@@ -1,28 +1,27 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubEvent.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubEvent.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubEventConvertor : public GenericLuaElementConvertor<PubSubEvent> {
- public:
- PubSubEventConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubEventConvertor();
+ class PubSubEventConvertor : public GenericLuaElementConvertor<PubSubEvent> {
+ public:
+ PubSubEventConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubEventConvertor() override;
- virtual boost::shared_ptr<PubSubEvent> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubEvent>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubEvent> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubEvent>) override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubEventDeleteConvertor.cpp b/Sluift/ElementConvertors/PubSubEventDeleteConvertor.cpp
index b03f22a..06fb3a2 100644
--- a/Sluift/ElementConvertors/PubSubEventDeleteConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubEventDeleteConvertor.cpp
@@ -1,51 +1,58 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubEventDeleteConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Sluift/LuaElementConvertors.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubEventDeleteConvertor::PubSubEventDeleteConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubEventDelete>("pubsub_event_delete"),
- convertors(convertors) {
+PubSubEventDeleteConvertor::PubSubEventDeleteConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubEventDelete>("pubsub_event_delete"),
+ convertors(convertors) {
}
PubSubEventDeleteConvertor::~PubSubEventDeleteConvertor() {
}
-boost::shared_ptr<PubSubEventDelete> PubSubEventDeleteConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubEventDelete> result = boost::make_shared<PubSubEventDelete>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "redirects");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubEventRedirect> payload = boost::dynamic_pointer_cast<PubSubEventRedirect>(convertors->convertFromLuaUntyped(L, -1, "pubsub_event_redirect"))) {
- result->setRedirects(payload);
- }
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubEventDelete> PubSubEventDeleteConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubEventDelete> result = std::make_shared<PubSubEventDelete>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "redirects");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubEventRedirect> payload = std::dynamic_pointer_cast<PubSubEventRedirect>(convertors->convertFromLuaUntyped(L, -1, "pubsub_event_redirect"))) {
+ result->setRedirects(payload);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubEventDeleteConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubEventDelete> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ if (convertors->convertToLuaUntyped(L, payload->getRedirects()) > 0) {
+ lua_setfield(L, -2, "redirects");
+ }
}
-void PubSubEventDeleteConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubEventDelete> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- if (convertors->convertToLuaUntyped(L, payload->getRedirects()) > 0) {
- lua_setfield(L, -2, "redirects");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubEventDeleteConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubEventDelete",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `redirects`: @{PubSubEventRedirect}\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubEventDeleteConvertor.h b/Sluift/ElementConvertors/PubSubEventDeleteConvertor.h
index a0cfd3d..66c706f 100644
--- a/Sluift/ElementConvertors/PubSubEventDeleteConvertor.h
+++ b/Sluift/ElementConvertors/PubSubEventDeleteConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubEventDelete.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubEventDelete.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubEventDeleteConvertor : public GenericLuaElementConvertor<PubSubEventDelete> {
- public:
- PubSubEventDeleteConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubEventDeleteConvertor();
+ class PubSubEventDeleteConvertor : public GenericLuaElementConvertor<PubSubEventDelete> {
+ public:
+ PubSubEventDeleteConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubEventDeleteConvertor() override;
- virtual boost::shared_ptr<PubSubEventDelete> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubEventDelete>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubEventDelete> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubEventDelete>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubEventDisassociateConvertor.cpp b/Sluift/ElementConvertors/PubSubEventDisassociateConvertor.cpp
index ccd8c6e..0ada5ce 100644
--- a/Sluift/ElementConvertors/PubSubEventDisassociateConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubEventDisassociateConvertor.cpp
@@ -1,41 +1,44 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubEventDisassociateConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubEventDisassociateConvertor::PubSubEventDisassociateConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubEventDisassociate>("pubsub_event_disassociate"),
- convertors(convertors) {
+PubSubEventDisassociateConvertor::PubSubEventDisassociateConvertor() :
+ GenericLuaElementConvertor<PubSubEventDisassociate>("pubsub_event_disassociate") {
}
PubSubEventDisassociateConvertor::~PubSubEventDisassociateConvertor() {
}
-boost::shared_ptr<PubSubEventDisassociate> PubSubEventDisassociateConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubEventDisassociate> result = boost::make_shared<PubSubEventDisassociate>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubEventDisassociate> PubSubEventDisassociateConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubEventDisassociate> result = std::make_shared<PubSubEventDisassociate>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubEventDisassociateConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubEventDisassociate> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
}
-void PubSubEventDisassociateConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubEventDisassociate> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
+boost::optional<LuaElementConvertor::Documentation> PubSubEventDisassociateConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubEventDisassociate",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubEventDisassociateConvertor.h b/Sluift/ElementConvertors/PubSubEventDisassociateConvertor.h
index 90c8232..17f9ae9 100644
--- a/Sluift/ElementConvertors/PubSubEventDisassociateConvertor.h
+++ b/Sluift/ElementConvertors/PubSubEventDisassociateConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubEventDisassociate.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubEventDisassociate.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubEventDisassociateConvertor : public GenericLuaElementConvertor<PubSubEventDisassociate> {
- public:
- PubSubEventDisassociateConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubEventDisassociateConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubEventDisassociate> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubEventDisassociate>) SWIFTEN_OVERRIDE;
+ class PubSubEventDisassociateConvertor : public GenericLuaElementConvertor<PubSubEventDisassociate> {
+ public:
+ PubSubEventDisassociateConvertor();
+ virtual ~PubSubEventDisassociateConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubEventDisassociate> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubEventDisassociate>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubEventItemConvertor.cpp b/Sluift/ElementConvertors/PubSubEventItemConvertor.cpp
index fab4bff..19ab09a 100644
--- a/Sluift/ElementConvertors/PubSubEventItemConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubEventItemConvertor.cpp
@@ -1,92 +1,102 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubEventItemConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
-#include <Sluift/LuaElementConvertors.h>
-#include <Swiften/Base/foreach.h>
+#include <lua.hpp>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <Sluift/LuaElementConvertors.h>
using namespace Swift;
-PubSubEventItemConvertor::PubSubEventItemConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubEventItem>("pubsub_event_item"),
- convertors(convertors) {
+PubSubEventItemConvertor::PubSubEventItemConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubEventItem>("pubsub_event_item"),
+ convertors(convertors) {
}
PubSubEventItemConvertor::~PubSubEventItemConvertor() {
}
-boost::shared_ptr<PubSubEventItem> PubSubEventItemConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubEventItem> result = boost::make_shared<PubSubEventItem>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "publisher");
- if (lua_isstring(L, -1)) {
- result->setPublisher(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "data");
- if (lua_type(L, -1) == LUA_TTABLE) {
- std::vector< boost::shared_ptr<Payload> > items;
- for(size_t i = 0; i < lua_objlen(L, -1); ++i) {
- lua_pushnumber(L, i + 1);
- lua_gettable(L, -2);
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<Payload> payload = convertors->convertFromLua(L, -1)) {
- items.push_back(payload);
- }
- }
- lua_pop(L, 1);
- }
+std::shared_ptr<PubSubEventItem> PubSubEventItemConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubEventItem> result = std::make_shared<PubSubEventItem>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "publisher");
+ if (lua_isstring(L, -1)) {
+ result->setPublisher(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "data");
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ std::vector< std::shared_ptr<Payload> > items;
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<Payload> payload = std::dynamic_pointer_cast<Payload>(convertors->convertFromLua(L, -1))) {
+ items.push_back(payload);
+ }
+ }
+ lua_pop(L, 1);
+ }
+
+ result->setData(items);
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "id");
+ if (lua_isstring(L, -1)) {
+ result->setID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
- result->setData(items);
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "id");
- if (lua_isstring(L, -1)) {
- result->setID(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+void PubSubEventItemConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubEventItem> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getNode()) {
+ lua_pushstring(L, (*payload->getNode()).c_str());
+ lua_setfield(L, -2, "node");
+ }
+ if (payload->getPublisher()) {
+ lua_pushstring(L, (*payload->getPublisher()).c_str());
+ lua_setfield(L, -2, "publisher");
+ }
+ if (!payload->getData().empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(payload->getData().size()), 0);
+ {
+ int i = 0;
+ for (auto&& item : payload->getData()) {
+ if (convertors->convertToLua(L, item) > 0) {
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ }
+ lua_setfield(L, -2, "data");
+ }
+ if (payload->getID()) {
+ lua_pushstring(L, (*payload->getID()).c_str());
+ lua_setfield(L, -2, "id");
+ }
}
-void PubSubEventItemConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubEventItem> payload) {
- lua_createtable(L, 0, 0);
- if (payload->getNode()) {
- lua_pushstring(L, (*payload->getNode()).c_str());
- lua_setfield(L, -2, "node");
- }
- if (payload->getPublisher()) {
- lua_pushstring(L, (*payload->getPublisher()).c_str());
- lua_setfield(L, -2, "publisher");
- }
- if (!payload->getData().empty()) {
- lua_createtable(L, boost::numeric_cast<int>(payload->getData().size()), 0);
- {
- int i = 0;
- foreach(boost::shared_ptr<Payload> item, payload->getData()) {
- if (convertors->convertToLua(L, item) > 0) {
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- ++i;
- }
- }
- }
- lua_setfield(L, -2, "data");
- }
- if (payload->getID()) {
- lua_pushstring(L, (*payload->getID()).c_str());
- lua_setfield(L, -2, "id");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubEventItemConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubEventItem",
+ "This table has the following fields:\n\n"
+ "- `node`: string (Optional)\n"
+ "- `publisher`: string (Optional)\n"
+ "- `data`: array<element (table)>\n"
+ "- `id`: string (Optional)\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubEventItemConvertor.h b/Sluift/ElementConvertors/PubSubEventItemConvertor.h
index 340602a..9e29ce8 100644
--- a/Sluift/ElementConvertors/PubSubEventItemConvertor.h
+++ b/Sluift/ElementConvertors/PubSubEventItemConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubEventItem.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubEventItem.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubEventItemConvertor : public GenericLuaElementConvertor<PubSubEventItem> {
- public:
- PubSubEventItemConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubEventItemConvertor();
+ class PubSubEventItemConvertor : public GenericLuaElementConvertor<PubSubEventItem> {
+ public:
+ PubSubEventItemConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubEventItemConvertor() override;
- virtual boost::shared_ptr<PubSubEventItem> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubEventItem>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubEventItem> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubEventItem>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubEventItemsConvertor.cpp b/Sluift/ElementConvertors/PubSubEventItemsConvertor.cpp
index 9996cc6..66f798e 100644
--- a/Sluift/ElementConvertors/PubSubEventItemsConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubEventItemsConvertor.cpp
@@ -1,102 +1,111 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubEventItemsConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
-#include <Sluift/LuaElementConvertors.h>
-#include <Swiften/Base/foreach.h>
+#include <lua.hpp>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <Sluift/LuaElementConvertors.h>
using namespace Swift;
-PubSubEventItemsConvertor::PubSubEventItemsConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubEventItems>("pubsub_event_items"),
- convertors(convertors) {
+PubSubEventItemsConvertor::PubSubEventItemsConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubEventItems>("pubsub_event_items"),
+ convertors(convertors) {
}
PubSubEventItemsConvertor::~PubSubEventItemsConvertor() {
}
-boost::shared_ptr<PubSubEventItems> PubSubEventItemsConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubEventItems> result = boost::make_shared<PubSubEventItems>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "items");
- if (lua_type(L, -1) == LUA_TTABLE) {
- std::vector< boost::shared_ptr<PubSubEventItem> > items;
- for(size_t i = 0; i < lua_objlen(L, -1); ++i) {
- lua_pushnumber(L, i + 1);
- lua_gettable(L, -2);
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubEventItem> payload = boost::dynamic_pointer_cast<PubSubEventItem>(convertors->convertFromLuaUntyped(L, -1, "pubsub_event_item"))) {
- items.push_back(payload);
- }
- }
- lua_pop(L, 1);
- }
+std::shared_ptr<PubSubEventItems> PubSubEventItemsConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubEventItems> result = std::make_shared<PubSubEventItems>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "items");
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ std::vector< std::shared_ptr<PubSubEventItem> > items;
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubEventItem> payload = std::dynamic_pointer_cast<PubSubEventItem>(convertors->convertFromLuaUntyped(L, -1, "pubsub_event_item"))) {
+ items.push_back(payload);
+ }
+ }
+ lua_pop(L, 1);
+ }
+
+ result->setItems(items);
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "retracts");
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ std::vector< std::shared_ptr<PubSubEventRetract> > items;
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubEventRetract> payload = std::dynamic_pointer_cast<PubSubEventRetract>(convertors->convertFromLuaUntyped(L, -1, "pubsub_event_retract"))) {
+ items.push_back(payload);
+ }
+ }
+ lua_pop(L, 1);
+ }
- result->setItems(items);
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "retracts");
- if (lua_type(L, -1) == LUA_TTABLE) {
- std::vector< boost::shared_ptr<PubSubEventRetract> > items;
- for(size_t i = 0; i < lua_objlen(L, -1); ++i) {
- lua_pushnumber(L, i + 1);
- lua_gettable(L, -2);
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubEventRetract> payload = boost::dynamic_pointer_cast<PubSubEventRetract>(convertors->convertFromLuaUntyped(L, -1, "pubsub_event_retract"))) {
- items.push_back(payload);
- }
- }
- lua_pop(L, 1);
- }
+ result->setRetracts(items);
+ }
+ lua_pop(L, 1);
+ return result;
+}
- result->setRetracts(items);
- }
- lua_pop(L, 1);
- return result;
+void PubSubEventItemsConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubEventItems> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ if (!payload->getItems().empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(payload->getItems().size()), 0);
+ {
+ int i = 0;
+ for (auto&& item : payload->getItems()) {
+ if (convertors->convertToLuaUntyped(L, item) > 0) {
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ }
+ lua_setfield(L, -2, "items");
+ }
+ if (!payload->getRetracts().empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(payload->getRetracts().size()), 0);
+ {
+ int i = 0;
+ for (auto&& item : payload->getRetracts()) {
+ if (convertors->convertToLuaUntyped(L, item) > 0) {
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ }
+ lua_setfield(L, -2, "retracts");
+ }
}
-void PubSubEventItemsConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubEventItems> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- if (!payload->getItems().empty()) {
- lua_createtable(L, boost::numeric_cast<int>(payload->getItems().size()), 0);
- {
- int i = 0;
- foreach(boost::shared_ptr<PubSubEventItem> item, payload->getItems()) {
- if (convertors->convertToLuaUntyped(L, item) > 0) {
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- ++i;
- }
- }
- }
- lua_setfield(L, -2, "items");
- }
- if (!payload->getRetracts().empty()) {
- lua_createtable(L, boost::numeric_cast<int>(payload->getRetracts().size()), 0);
- {
- int i = 0;
- foreach(boost::shared_ptr<PubSubEventRetract> item, payload->getRetracts()) {
- if (convertors->convertToLuaUntyped(L, item) > 0) {
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- ++i;
- }
- }
- }
- lua_setfield(L, -2, "retracts");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubEventItemsConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubEventItems",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `items`: array<@{PubSubEventItem}>\n"
+ "- `retracts`: array<@{PubSubEventRetract}>\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubEventItemsConvertor.h b/Sluift/ElementConvertors/PubSubEventItemsConvertor.h
index 9adbf15..8f7e3fe 100644
--- a/Sluift/ElementConvertors/PubSubEventItemsConvertor.h
+++ b/Sluift/ElementConvertors/PubSubEventItemsConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubEventItems.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubEventItems.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubEventItemsConvertor : public GenericLuaElementConvertor<PubSubEventItems> {
- public:
- PubSubEventItemsConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubEventItemsConvertor();
+ class PubSubEventItemsConvertor : public GenericLuaElementConvertor<PubSubEventItems> {
+ public:
+ PubSubEventItemsConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubEventItemsConvertor() override;
- virtual boost::shared_ptr<PubSubEventItems> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubEventItems>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubEventItems> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubEventItems>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubEventPurgeConvertor.cpp b/Sluift/ElementConvertors/PubSubEventPurgeConvertor.cpp
index e389fcf..223eedd 100644
--- a/Sluift/ElementConvertors/PubSubEventPurgeConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubEventPurgeConvertor.cpp
@@ -1,41 +1,44 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubEventPurgeConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubEventPurgeConvertor::PubSubEventPurgeConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubEventPurge>("pubsub_event_purge"),
- convertors(convertors) {
+PubSubEventPurgeConvertor::PubSubEventPurgeConvertor() :
+ GenericLuaElementConvertor<PubSubEventPurge>("pubsub_event_purge") {
}
PubSubEventPurgeConvertor::~PubSubEventPurgeConvertor() {
}
-boost::shared_ptr<PubSubEventPurge> PubSubEventPurgeConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubEventPurge> result = boost::make_shared<PubSubEventPurge>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubEventPurge> PubSubEventPurgeConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubEventPurge> result = std::make_shared<PubSubEventPurge>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubEventPurgeConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubEventPurge> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
}
-void PubSubEventPurgeConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubEventPurge> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
+boost::optional<LuaElementConvertor::Documentation> PubSubEventPurgeConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubEventPurge",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubEventPurgeConvertor.h b/Sluift/ElementConvertors/PubSubEventPurgeConvertor.h
index d94aa36..1c2cdbb 100644
--- a/Sluift/ElementConvertors/PubSubEventPurgeConvertor.h
+++ b/Sluift/ElementConvertors/PubSubEventPurgeConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubEventPurge.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubEventPurge.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubEventPurgeConvertor : public GenericLuaElementConvertor<PubSubEventPurge> {
- public:
- PubSubEventPurgeConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubEventPurgeConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubEventPurge> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubEventPurge>) SWIFTEN_OVERRIDE;
+ class PubSubEventPurgeConvertor : public GenericLuaElementConvertor<PubSubEventPurge> {
+ public:
+ PubSubEventPurgeConvertor();
+ virtual ~PubSubEventPurgeConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubEventPurge> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubEventPurge>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubEventRedirectConvertor.cpp b/Sluift/ElementConvertors/PubSubEventRedirectConvertor.cpp
index 6e128da..673b320 100644
--- a/Sluift/ElementConvertors/PubSubEventRedirectConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubEventRedirectConvertor.cpp
@@ -1,41 +1,44 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubEventRedirectConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubEventRedirectConvertor::PubSubEventRedirectConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubEventRedirect>("pubsub_event_redirect"),
- convertors(convertors) {
+PubSubEventRedirectConvertor::PubSubEventRedirectConvertor() :
+ GenericLuaElementConvertor<PubSubEventRedirect>("pubsub_event_redirect") {
}
PubSubEventRedirectConvertor::~PubSubEventRedirectConvertor() {
}
-boost::shared_ptr<PubSubEventRedirect> PubSubEventRedirectConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubEventRedirect> result = boost::make_shared<PubSubEventRedirect>();
- lua_getfield(L, -1, "uri");
- if (lua_isstring(L, -1)) {
- result->setURI(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubEventRedirect> PubSubEventRedirectConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubEventRedirect> result = std::make_shared<PubSubEventRedirect>();
+ lua_getfield(L, -1, "uri");
+ if (lua_isstring(L, -1)) {
+ result->setURI(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubEventRedirectConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubEventRedirect> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getURI().c_str());
+ lua_setfield(L, -2, "uri");
}
-void PubSubEventRedirectConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubEventRedirect> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getURI().c_str());
- lua_setfield(L, -2, "uri");
+boost::optional<LuaElementConvertor::Documentation> PubSubEventRedirectConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubEventRedirect",
+ "This table has the following fields:\n\n"
+ "- `uri`: string\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubEventRedirectConvertor.h b/Sluift/ElementConvertors/PubSubEventRedirectConvertor.h
index 4904102..a61cb79 100644
--- a/Sluift/ElementConvertors/PubSubEventRedirectConvertor.h
+++ b/Sluift/ElementConvertors/PubSubEventRedirectConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubEventRedirect.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubEventRedirect.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubEventRedirectConvertor : public GenericLuaElementConvertor<PubSubEventRedirect> {
- public:
- PubSubEventRedirectConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubEventRedirectConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubEventRedirect> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubEventRedirect>) SWIFTEN_OVERRIDE;
+ class PubSubEventRedirectConvertor : public GenericLuaElementConvertor<PubSubEventRedirect> {
+ public:
+ PubSubEventRedirectConvertor();
+ virtual ~PubSubEventRedirectConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubEventRedirect> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubEventRedirect>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubEventRetractConvertor.cpp b/Sluift/ElementConvertors/PubSubEventRetractConvertor.cpp
index aed29a0..5981922 100644
--- a/Sluift/ElementConvertors/PubSubEventRetractConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubEventRetractConvertor.cpp
@@ -1,41 +1,44 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubEventRetractConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubEventRetractConvertor::PubSubEventRetractConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubEventRetract>("pubsub_event_retract"),
- convertors(convertors) {
+PubSubEventRetractConvertor::PubSubEventRetractConvertor() :
+ GenericLuaElementConvertor<PubSubEventRetract>("pubsub_event_retract") {
}
PubSubEventRetractConvertor::~PubSubEventRetractConvertor() {
}
-boost::shared_ptr<PubSubEventRetract> PubSubEventRetractConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubEventRetract> result = boost::make_shared<PubSubEventRetract>();
- lua_getfield(L, -1, "id");
- if (lua_isstring(L, -1)) {
- result->setID(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubEventRetract> PubSubEventRetractConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubEventRetract> result = std::make_shared<PubSubEventRetract>();
+ lua_getfield(L, -1, "id");
+ if (lua_isstring(L, -1)) {
+ result->setID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubEventRetractConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubEventRetract> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getID().c_str());
+ lua_setfield(L, -2, "id");
}
-void PubSubEventRetractConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubEventRetract> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getID().c_str());
- lua_setfield(L, -2, "id");
+boost::optional<LuaElementConvertor::Documentation> PubSubEventRetractConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubEventRetract",
+ "This table has the following fields:\n\n"
+ "- `id`: string\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubEventRetractConvertor.h b/Sluift/ElementConvertors/PubSubEventRetractConvertor.h
index 7a7c0f9..f437ad5 100644
--- a/Sluift/ElementConvertors/PubSubEventRetractConvertor.h
+++ b/Sluift/ElementConvertors/PubSubEventRetractConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubEventRetract.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubEventRetract.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubEventRetractConvertor : public GenericLuaElementConvertor<PubSubEventRetract> {
- public:
- PubSubEventRetractConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubEventRetractConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubEventRetract> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubEventRetract>) SWIFTEN_OVERRIDE;
+ class PubSubEventRetractConvertor : public GenericLuaElementConvertor<PubSubEventRetract> {
+ public:
+ PubSubEventRetractConvertor();
+ virtual ~PubSubEventRetractConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubEventRetract> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubEventRetract>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.cpp b/Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.cpp
index 68cb34a..cab78d4 100644
--- a/Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.cpp
@@ -1,81 +1,104 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Swiften/Base/DateTime.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubEventSubscriptionConvertor::PubSubEventSubscriptionConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubEventSubscription>("pubsub_event_subscription"),
- convertors(convertors) {
+PubSubEventSubscriptionConvertor::PubSubEventSubscriptionConvertor() :
+ GenericLuaElementConvertor<PubSubEventSubscription>("pubsub_event_subscription") {
}
PubSubEventSubscriptionConvertor::~PubSubEventSubscriptionConvertor() {
}
-boost::shared_ptr<PubSubEventSubscription> PubSubEventSubscriptionConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubEventSubscription> result = boost::make_shared<PubSubEventSubscription>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "jid");
- if (lua_isstring(L, -1)) {
- result->setJID(JID(std::string(lua_tostring(L, -1))));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "subscription");
- lua_pop(L, 1);
- lua_getfield(L, -1, "subscriptionid");
- if (lua_isstring(L, -1)) {
- result->setSubscriptionID(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "expiry");
- if (lua_isstring(L, -1)) {
- result->setExpiry(stringToDateTime(std::string(lua_tostring(L, -1))));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubEventSubscription> PubSubEventSubscriptionConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubEventSubscription> result = std::make_shared<PubSubEventSubscription>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "jid");
+ if (lua_isstring(L, -1)) {
+ result->setJID(JID(std::string(lua_tostring(L, -1))));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "subscription");
+ if (lua_isstring(L, -1)) {
+ if (std::string(lua_tostring(L, -1)) == "none") {
+ result->setSubscription(PubSubEventSubscription::None);
+ }
+ if (std::string(lua_tostring(L, -1)) == "pending") {
+ result->setSubscription(PubSubEventSubscription::Pending);
+ }
+ if (std::string(lua_tostring(L, -1)) == "subscribed") {
+ result->setSubscription(PubSubEventSubscription::Subscribed);
+ }
+ if (std::string(lua_tostring(L, -1)) == "unconfigured") {
+ result->setSubscription(PubSubEventSubscription::Unconfigured);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "subscription_id");
+ if (lua_isstring(L, -1)) {
+ result->setSubscriptionID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "expiry");
+ if (lua_isstring(L, -1)) {
+ result->setExpiry(stringToDateTime(std::string(lua_tostring(L, -1))));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubEventSubscriptionConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubEventSubscription> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ lua_pushstring(L, payload->getJID().toString().c_str());
+ lua_setfield(L, -2, "jid");
+ switch (payload->getSubscription()) {
+ case PubSubEventSubscription::None:
+ lua_pushstring(L, "none");
+ break;
+ case PubSubEventSubscription::Pending:
+ lua_pushstring(L, "pending");
+ break;
+ case PubSubEventSubscription::Subscribed:
+ lua_pushstring(L, "subscribed");
+ break;
+ case PubSubEventSubscription::Unconfigured:
+ lua_pushstring(L, "unconfigured");
+ break;
+ }
+ lua_setfield(L, -2, "subscription");
+ if (payload->getSubscriptionID()) {
+ lua_pushstring(L, (*payload->getSubscriptionID()).c_str());
+ lua_setfield(L, -2, "subscription_id");
+ }
+ lua_pushstring(L, dateTimeToString(payload->getExpiry()).c_str());
+ lua_setfield(L, -2, "expiry");
}
-void PubSubEventSubscriptionConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubEventSubscription> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- lua_pushstring(L, payload->getJID().toString().c_str());
- lua_setfield(L, -2, "jid");
- switch (payload->getSubscription()) {
- case PubSubEventSubscription::None:
- lua_pushstring(L, "none");
- break;
- case PubSubEventSubscription::Pending:
- lua_pushstring(L, "pending");
- break;
- case PubSubEventSubscription::Subscribed:
- lua_pushstring(L, "subscribed");
- break;
- case PubSubEventSubscription::Unconfigured:
- lua_pushstring(L, "unconfigured");
- break;
- }
- lua_setfield(L, -2, "subscription");
- if (payload->getSubscriptionID()) {
- lua_pushstring(L, (*payload->getSubscriptionID()).c_str());
- lua_setfield(L, -2, "subscriptionid");
- }
- lua_pushstring(L, dateTimeToString(payload->getExpiry()).c_str());
- lua_setfield(L, -2, "expiry");
+boost::optional<LuaElementConvertor::Documentation> PubSubEventSubscriptionConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubEventSubscription",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `jid`: jid (string)\n"
+ "- `subscription`: `\"none\"`, `\"pending\"`, `\"subscribed\"`, or `\"unconfigured\"`\n"
+ "- `subscription_id`: string (Optional)\n"
+ "- `expiry`: datetime (string)\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.h b/Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.h
index fa04fb7..61d1f21 100644
--- a/Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.h
+++ b/Sluift/ElementConvertors/PubSubEventSubscriptionConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubEventSubscription.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubEventSubscription.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubEventSubscriptionConvertor : public GenericLuaElementConvertor<PubSubEventSubscription> {
- public:
- PubSubEventSubscriptionConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubEventSubscriptionConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubEventSubscription> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubEventSubscription>) SWIFTEN_OVERRIDE;
+ class PubSubEventSubscriptionConvertor : public GenericLuaElementConvertor<PubSubEventSubscription> {
+ public:
+ PubSubEventSubscriptionConvertor();
+ virtual ~PubSubEventSubscriptionConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubEventSubscription> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubEventSubscription>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubItemConvertor.cpp b/Sluift/ElementConvertors/PubSubItemConvertor.cpp
index e06065b..b46419a 100644
--- a/Sluift/ElementConvertors/PubSubItemConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubItemConvertor.cpp
@@ -1,72 +1,80 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubItemConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
-#include <Sluift/LuaElementConvertors.h>
-#include <Swiften/Base/foreach.h>
+#include <lua.hpp>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <Sluift/LuaElementConvertors.h>
using namespace Swift;
-PubSubItemConvertor::PubSubItemConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubItem>("pubsub_item"),
- convertors(convertors) {
+PubSubItemConvertor::PubSubItemConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubItem>("pubsub_item"),
+ convertors(convertors) {
}
PubSubItemConvertor::~PubSubItemConvertor() {
}
-boost::shared_ptr<PubSubItem> PubSubItemConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubItem> result = boost::make_shared<PubSubItem>();
- lua_getfield(L, -1, "data");
- if (lua_type(L, -1) == LUA_TTABLE) {
- std::vector< boost::shared_ptr<Payload> > items;
- for(size_t i = 0; i < lua_objlen(L, -1); ++i) {
- lua_pushnumber(L, i + 1);
- lua_gettable(L, -2);
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<Payload> payload = convertors->convertFromLua(L, -1)) {
- items.push_back(payload);
- }
- }
- lua_pop(L, 1);
- }
+std::shared_ptr<PubSubItem> PubSubItemConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubItem> result = std::make_shared<PubSubItem>();
+ lua_getfield(L, -1, "data");
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ std::vector< std::shared_ptr<Payload> > items;
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<Payload> payload = std::dynamic_pointer_cast<Payload>(convertors->convertFromLua(L, -1))) {
+ items.push_back(payload);
+ }
+ }
+ lua_pop(L, 1);
+ }
+
+ result->setData(items);
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "id");
+ if (lua_isstring(L, -1)) {
+ result->setID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
- result->setData(items);
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "id");
- if (lua_isstring(L, -1)) {
- result->setID(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+void PubSubItemConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubItem> payload) {
+ lua_createtable(L, 0, 0);
+ if (!payload->getData().empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(payload->getData().size()), 0);
+ {
+ int i = 0;
+ for (auto&& item : payload->getData()) {
+ if (convertors->convertToLua(L, item) > 0) {
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ }
+ lua_setfield(L, -2, "data");
+ }
+ lua_pushstring(L, payload->getID().c_str());
+ lua_setfield(L, -2, "id");
}
-void PubSubItemConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubItem> payload) {
- lua_createtable(L, 0, 0);
- if (!payload->getData().empty()) {
- lua_createtable(L, boost::numeric_cast<int>(payload->getData().size()), 0);
- {
- int i = 0;
- foreach(boost::shared_ptr<Payload> item, payload->getData()) {
- if (convertors->convertToLua(L, item) > 0) {
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- ++i;
- }
- }
- }
- lua_setfield(L, -2, "data");
- }
- lua_pushstring(L, payload->getID().c_str());
- lua_setfield(L, -2, "id");
+boost::optional<LuaElementConvertor::Documentation> PubSubItemConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubItem",
+ "This table has the following fields:\n\n"
+ "- `data`: array<element (table)>\n"
+ "- `id`: string\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubItemConvertor.h b/Sluift/ElementConvertors/PubSubItemConvertor.h
index 176e1c4..87c3809 100644
--- a/Sluift/ElementConvertors/PubSubItemConvertor.h
+++ b/Sluift/ElementConvertors/PubSubItemConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubItem.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubItem.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubItemConvertor : public GenericLuaElementConvertor<PubSubItem> {
- public:
- PubSubItemConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubItemConvertor();
+ class PubSubItemConvertor : public GenericLuaElementConvertor<PubSubItem> {
+ public:
+ PubSubItemConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubItemConvertor() override;
- virtual boost::shared_ptr<PubSubItem> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubItem>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubItem> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubItem>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubItemsConvertor.cpp b/Sluift/ElementConvertors/PubSubItemsConvertor.cpp
index 5ecb72e..0bb8eb9 100644
--- a/Sluift/ElementConvertors/PubSubItemsConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubItemsConvertor.cpp
@@ -1,86 +1,96 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubItemsConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
-#include <Sluift/LuaElementConvertors.h>
-#include <Swiften/Base/foreach.h>
+#include <lua.hpp>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <Sluift/LuaElementConvertors.h>
using namespace Swift;
-PubSubItemsConvertor::PubSubItemsConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubItems>("pubsub_items"),
- convertors(convertors) {
+PubSubItemsConvertor::PubSubItemsConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubItems>("pubsub_items"),
+ convertors(convertors) {
}
PubSubItemsConvertor::~PubSubItemsConvertor() {
}
-boost::shared_ptr<PubSubItems> PubSubItemsConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubItems> result = boost::make_shared<PubSubItems>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- if (lua_type(L, -1) == LUA_TTABLE) {
- std::vector< boost::shared_ptr<PubSubItem> > items;
- for(size_t i = 0; i < lua_objlen(L, -1); ++i) {
- lua_pushnumber(L, i + 1);
- lua_gettable(L, -2);
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubItem> payload = boost::dynamic_pointer_cast<PubSubItem>(convertors->convertFromLuaUntyped(L, -1, "pubsub_item"))) {
- items.push_back(payload);
- }
- }
- lua_pop(L, 1);
- }
+std::shared_ptr<PubSubItems> PubSubItemsConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubItems> result = std::make_shared<PubSubItems>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ std::vector< std::shared_ptr<PubSubItem> > items;
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubItem> payload = std::dynamic_pointer_cast<PubSubItem>(convertors->convertFromLuaUntyped(L, -1, "pubsub_item"))) {
+ items.push_back(payload);
+ }
+ }
+ lua_pop(L, 1);
+ }
+
+ result->setItems(items);
+ }
+ lua_getfield(L, -1, "maximum_items");
+ if (lua_isnumber(L, -1)) {
+ result->setMaximumItems(boost::numeric_cast<unsigned int>(lua_tonumber(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "subscription_id");
+ if (lua_isstring(L, -1)) {
+ result->setSubscriptionID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
- result->setItems(items);
- }
- lua_getfield(L, -1, "maximum_items");
- if (lua_isnumber(L, -1)) {
- result->setMaximumItems(boost::numeric_cast<unsigned int>(lua_tonumber(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "subscriptionid");
- if (lua_isstring(L, -1)) {
- result->setSubscriptionID(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+void PubSubItemsConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubItems> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ if (!payload->getItems().empty()) {
+ {
+ int i = 0;
+ for (auto&& item : payload->getItems()) {
+ if (convertors->convertToLuaUntyped(L, item) > 0) {
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ }
+ }
+ if (payload->getMaximumItems()) {
+ lua_pushnumber(L, (*payload->getMaximumItems()));
+ lua_setfield(L, -2, "maximum_items");
+ }
+ if (payload->getSubscriptionID()) {
+ lua_pushstring(L, (*payload->getSubscriptionID()).c_str());
+ lua_setfield(L, -2, "subscription_id");
+ }
}
-void PubSubItemsConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubItems> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- if (!payload->getItems().empty()) {
- {
- int i = 0;
- foreach(boost::shared_ptr<PubSubItem> item, payload->getItems()) {
- if (convertors->convertToLuaUntyped(L, item) > 0) {
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- ++i;
- }
- }
- }
- }
- if (payload->getMaximumItems()) {
- lua_pushnumber(L, (*payload->getMaximumItems()));
- lua_setfield(L, -2, "maximum_items");
- }
- if (payload->getSubscriptionID()) {
- lua_pushstring(L, (*payload->getSubscriptionID()).c_str());
- lua_setfield(L, -2, "subscriptionid");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubItemsConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubItems",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `items`: array<@{PubSubItem}>\n"
+ "- `maximum_items`: number (Optional)\n"
+ "- `subscription_id`: string (Optional)\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubItemsConvertor.h b/Sluift/ElementConvertors/PubSubItemsConvertor.h
index 9978806..9e0f73a 100644
--- a/Sluift/ElementConvertors/PubSubItemsConvertor.h
+++ b/Sluift/ElementConvertors/PubSubItemsConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubItems.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubItems.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubItemsConvertor : public GenericLuaElementConvertor<PubSubItems> {
- public:
- PubSubItemsConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubItemsConvertor();
+ class PubSubItemsConvertor : public GenericLuaElementConvertor<PubSubItems> {
+ public:
+ PubSubItemsConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubItemsConvertor() override;
- virtual boost::shared_ptr<PubSubItems> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubItems>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubItems> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubItems>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubOptionsConvertor.cpp b/Sluift/ElementConvertors/PubSubOptionsConvertor.cpp
index cc27973..3582c63 100644
--- a/Sluift/ElementConvertors/PubSubOptionsConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubOptionsConvertor.cpp
@@ -1,67 +1,76 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubOptionsConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Sluift/LuaElementConvertors.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubOptionsConvertor::PubSubOptionsConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubOptions>("pubsub_options"),
- convertors(convertors) {
+PubSubOptionsConvertor::PubSubOptionsConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubOptions>("pubsub_options"),
+ convertors(convertors) {
}
PubSubOptionsConvertor::~PubSubOptionsConvertor() {
}
-boost::shared_ptr<PubSubOptions> PubSubOptionsConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubOptions> result = boost::make_shared<PubSubOptions>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "jid");
- if (lua_isstring(L, -1)) {
- result->setJID(JID(std::string(lua_tostring(L, -1))));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "data");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<Form> payload = boost::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) {
- result->setData(payload);
- }
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "subscriptionid");
- if (lua_isstring(L, -1)) {
- result->setSubscriptionID(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubOptions> PubSubOptionsConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubOptions> result = std::make_shared<PubSubOptions>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "jid");
+ if (lua_isstring(L, -1)) {
+ result->setJID(JID(std::string(lua_tostring(L, -1))));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "data");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<Form> payload = std::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) {
+ result->setData(payload);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "subscription_id");
+ if (lua_isstring(L, -1)) {
+ result->setSubscriptionID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubOptionsConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubOptions> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ lua_pushstring(L, payload->getJID().toString().c_str());
+ lua_setfield(L, -2, "jid");
+ if (convertors->convertToLuaUntyped(L, payload->getData()) > 0) {
+ lua_setfield(L, -2, "data");
+ }
+ if (payload->getSubscriptionID()) {
+ lua_pushstring(L, (*payload->getSubscriptionID()).c_str());
+ lua_setfield(L, -2, "subscription_id");
+ }
}
-void PubSubOptionsConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubOptions> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- lua_pushstring(L, payload->getJID().toString().c_str());
- lua_setfield(L, -2, "jid");
- if (convertors->convertToLuaUntyped(L, payload->getData()) > 0) {
- lua_setfield(L, -2, "data");
- }
- if (payload->getSubscriptionID()) {
- lua_pushstring(L, (*payload->getSubscriptionID()).c_str());
- lua_setfield(L, -2, "subscriptionid");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubOptionsConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubOptions",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `jid`: jid (string)\n"
+ "- `data`: @{Form}\n"
+ "- `subscription_id`: string (Optional)\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubOptionsConvertor.h b/Sluift/ElementConvertors/PubSubOptionsConvertor.h
index 95a1dc8..add661a 100644
--- a/Sluift/ElementConvertors/PubSubOptionsConvertor.h
+++ b/Sluift/ElementConvertors/PubSubOptionsConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubOptions.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubOptions.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubOptionsConvertor : public GenericLuaElementConvertor<PubSubOptions> {
- public:
- PubSubOptionsConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubOptionsConvertor();
+ class PubSubOptionsConvertor : public GenericLuaElementConvertor<PubSubOptions> {
+ public:
+ PubSubOptionsConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubOptionsConvertor() override;
- virtual boost::shared_ptr<PubSubOptions> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubOptions>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubOptions> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubOptions>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerAffiliationConvertor.cpp b/Sluift/ElementConvertors/PubSubOwnerAffiliationConvertor.cpp
index d7edaf4..15a800b 100644
--- a/Sluift/ElementConvertors/PubSubOwnerAffiliationConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubOwnerAffiliationConvertor.cpp
@@ -1,64 +1,88 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubOwnerAffiliationConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubOwnerAffiliationConvertor::PubSubOwnerAffiliationConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubOwnerAffiliation>("pubsub_owner_affiliation"),
- convertors(convertors) {
+PubSubOwnerAffiliationConvertor::PubSubOwnerAffiliationConvertor() :
+ GenericLuaElementConvertor<PubSubOwnerAffiliation>("pubsub_owner_affiliation") {
}
PubSubOwnerAffiliationConvertor::~PubSubOwnerAffiliationConvertor() {
}
-boost::shared_ptr<PubSubOwnerAffiliation> PubSubOwnerAffiliationConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubOwnerAffiliation> result = boost::make_shared<PubSubOwnerAffiliation>();
- lua_getfield(L, -1, "jid");
- if (lua_isstring(L, -1)) {
- result->setJID(JID(std::string(lua_tostring(L, -1))));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "type");
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubOwnerAffiliation> PubSubOwnerAffiliationConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubOwnerAffiliation> result = std::make_shared<PubSubOwnerAffiliation>();
+ lua_getfield(L, -1, "jid");
+ if (lua_isstring(L, -1)) {
+ result->setJID(JID(std::string(lua_tostring(L, -1))));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "type");
+ if (lua_isstring(L, -1)) {
+ if (std::string(lua_tostring(L, -1)) == "none") {
+ result->setType(PubSubOwnerAffiliation::None);
+ }
+ if (std::string(lua_tostring(L, -1)) == "member") {
+ result->setType(PubSubOwnerAffiliation::Member);
+ }
+ if (std::string(lua_tostring(L, -1)) == "outcast") {
+ result->setType(PubSubOwnerAffiliation::Outcast);
+ }
+ if (std::string(lua_tostring(L, -1)) == "owner") {
+ result->setType(PubSubOwnerAffiliation::Owner);
+ }
+ if (std::string(lua_tostring(L, -1)) == "publisher") {
+ result->setType(PubSubOwnerAffiliation::Publisher);
+ }
+ if (std::string(lua_tostring(L, -1)) == "publish_only") {
+ result->setType(PubSubOwnerAffiliation::PublishOnly);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubOwnerAffiliationConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubOwnerAffiliation> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getJID().toString().c_str());
+ lua_setfield(L, -2, "jid");
+ switch (payload->getType()) {
+ case PubSubOwnerAffiliation::None:
+ lua_pushstring(L, "none");
+ break;
+ case PubSubOwnerAffiliation::Member:
+ lua_pushstring(L, "member");
+ break;
+ case PubSubOwnerAffiliation::Outcast:
+ lua_pushstring(L, "outcast");
+ break;
+ case PubSubOwnerAffiliation::Owner:
+ lua_pushstring(L, "owner");
+ break;
+ case PubSubOwnerAffiliation::Publisher:
+ lua_pushstring(L, "publisher");
+ break;
+ case PubSubOwnerAffiliation::PublishOnly:
+ lua_pushstring(L, "publish_only");
+ break;
+ }
+ lua_setfield(L, -2, "type");
}
-void PubSubOwnerAffiliationConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubOwnerAffiliation> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getJID().toString().c_str());
- lua_setfield(L, -2, "jid");
- switch (payload->getType()) {
- case PubSubOwnerAffiliation::None:
- lua_pushstring(L, "none");
- break;
- case PubSubOwnerAffiliation::Member:
- lua_pushstring(L, "member");
- break;
- case PubSubOwnerAffiliation::Outcast:
- lua_pushstring(L, "outcast");
- break;
- case PubSubOwnerAffiliation::Owner:
- lua_pushstring(L, "owner");
- break;
- case PubSubOwnerAffiliation::Publisher:
- lua_pushstring(L, "publisher");
- break;
- case PubSubOwnerAffiliation::PublishOnly:
- lua_pushstring(L, "publish_only");
- break;
- }
- lua_setfield(L, -2, "type");
+boost::optional<LuaElementConvertor::Documentation> PubSubOwnerAffiliationConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubOwnerAffiliation",
+ "This table has the following fields:\n\n"
+ "- `jid`: jid (string)\n"
+ "- `type`: `\"none\"`, `\"member\"`, `\"outcast\"`, `\"owner\"`, `\"publisher\"`, or `\"publish_only\"`\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerAffiliationConvertor.h b/Sluift/ElementConvertors/PubSubOwnerAffiliationConvertor.h
index 72bfaa1..92b001b 100644
--- a/Sluift/ElementConvertors/PubSubOwnerAffiliationConvertor.h
+++ b/Sluift/ElementConvertors/PubSubOwnerAffiliationConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubOwnerAffiliation.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubOwnerAffiliation.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubOwnerAffiliationConvertor : public GenericLuaElementConvertor<PubSubOwnerAffiliation> {
- public:
- PubSubOwnerAffiliationConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubOwnerAffiliationConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubOwnerAffiliation> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubOwnerAffiliation>) SWIFTEN_OVERRIDE;
+ class PubSubOwnerAffiliationConvertor : public GenericLuaElementConvertor<PubSubOwnerAffiliation> {
+ public:
+ PubSubOwnerAffiliationConvertor();
+ virtual ~PubSubOwnerAffiliationConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubOwnerAffiliation> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubOwnerAffiliation>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.cpp b/Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.cpp
index bee8539..9ca76fc 100644
--- a/Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.cpp
@@ -1,68 +1,76 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
-#include <Sluift/LuaElementConvertors.h>
-#include <Swiften/Base/foreach.h>
+#include <lua.hpp>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <Sluift/LuaElementConvertors.h>
using namespace Swift;
-PubSubOwnerAffiliationsConvertor::PubSubOwnerAffiliationsConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubOwnerAffiliations>("pubsub_owner_affiliations"),
- convertors(convertors) {
+PubSubOwnerAffiliationsConvertor::PubSubOwnerAffiliationsConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubOwnerAffiliations>("pubsub_owner_affiliations"),
+ convertors(convertors) {
}
PubSubOwnerAffiliationsConvertor::~PubSubOwnerAffiliationsConvertor() {
}
-boost::shared_ptr<PubSubOwnerAffiliations> PubSubOwnerAffiliationsConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubOwnerAffiliations> result = boost::make_shared<PubSubOwnerAffiliations>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- if (lua_type(L, -1) == LUA_TTABLE) {
- std::vector< boost::shared_ptr<PubSubOwnerAffiliation> > items;
- for(size_t i = 0; i < lua_objlen(L, -1); ++i) {
- lua_pushnumber(L, i + 1);
- lua_gettable(L, -2);
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubOwnerAffiliation> payload = boost::dynamic_pointer_cast<PubSubOwnerAffiliation>(convertors->convertFromLuaUntyped(L, -1, "pubsub_owner_affiliation"))) {
- items.push_back(payload);
- }
- }
- lua_pop(L, 1);
- }
+std::shared_ptr<PubSubOwnerAffiliations> PubSubOwnerAffiliationsConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubOwnerAffiliations> result = std::make_shared<PubSubOwnerAffiliations>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ std::vector< std::shared_ptr<PubSubOwnerAffiliation> > items;
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubOwnerAffiliation> payload = std::dynamic_pointer_cast<PubSubOwnerAffiliation>(convertors->convertFromLuaUntyped(L, -1, "pubsub_owner_affiliation"))) {
+ items.push_back(payload);
+ }
+ }
+ lua_pop(L, 1);
+ }
+
+ result->setAffiliations(items);
+ }
+ return result;
+}
- result->setAffiliations(items);
- }
- return result;
+void PubSubOwnerAffiliationsConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubOwnerAffiliations> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ if (!payload->getAffiliations().empty()) {
+ {
+ int i = 0;
+ for (auto&& item : payload->getAffiliations()) {
+ if (convertors->convertToLuaUntyped(L, item) > 0) {
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ }
+ }
}
-void PubSubOwnerAffiliationsConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubOwnerAffiliations> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- if (!payload->getAffiliations().empty()) {
- {
- int i = 0;
- foreach(boost::shared_ptr<PubSubOwnerAffiliation> item, payload->getAffiliations()) {
- if (convertors->convertToLuaUntyped(L, item) > 0) {
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- ++i;
- }
- }
- }
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubOwnerAffiliationsConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubOwnerAffiliations",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `affiliations`: array<@{PubSubOwnerAffiliation}>\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.h b/Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.h
index 377e108..f0c45a3 100644
--- a/Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.h
+++ b/Sluift/ElementConvertors/PubSubOwnerAffiliationsConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubOwnerAffiliations.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubOwnerAffiliations.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubOwnerAffiliationsConvertor : public GenericLuaElementConvertor<PubSubOwnerAffiliations> {
- public:
- PubSubOwnerAffiliationsConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubOwnerAffiliationsConvertor();
+ class PubSubOwnerAffiliationsConvertor : public GenericLuaElementConvertor<PubSubOwnerAffiliations> {
+ public:
+ PubSubOwnerAffiliationsConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubOwnerAffiliationsConvertor() override;
- virtual boost::shared_ptr<PubSubOwnerAffiliations> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubOwnerAffiliations>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubOwnerAffiliations> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubOwnerAffiliations>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.cpp b/Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.cpp
index 87505e1..d179152 100644
--- a/Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.cpp
@@ -1,53 +1,60 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Sluift/LuaElementConvertors.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubOwnerConfigureConvertor::PubSubOwnerConfigureConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubOwnerConfigure>("pubsub_owner_configure"),
- convertors(convertors) {
+PubSubOwnerConfigureConvertor::PubSubOwnerConfigureConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubOwnerConfigure>("pubsub_owner_configure"),
+ convertors(convertors) {
}
PubSubOwnerConfigureConvertor::~PubSubOwnerConfigureConvertor() {
}
-boost::shared_ptr<PubSubOwnerConfigure> PubSubOwnerConfigureConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubOwnerConfigure> result = boost::make_shared<PubSubOwnerConfigure>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "data");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<Form> payload = boost::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) {
- result->setData(payload);
- }
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubOwnerConfigure> PubSubOwnerConfigureConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubOwnerConfigure> result = std::make_shared<PubSubOwnerConfigure>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "data");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<Form> payload = std::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) {
+ result->setData(payload);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubOwnerConfigureConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubOwnerConfigure> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getNode()) {
+ lua_pushstring(L, (*payload->getNode()).c_str());
+ lua_setfield(L, -2, "node");
+ }
+ if (convertors->convertToLuaUntyped(L, payload->getData()) > 0) {
+ lua_setfield(L, -2, "data");
+ }
}
-void PubSubOwnerConfigureConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubOwnerConfigure> payload) {
- lua_createtable(L, 0, 0);
- if (payload->getNode()) {
- lua_pushstring(L, (*payload->getNode()).c_str());
- lua_setfield(L, -2, "node");
- }
- if (convertors->convertToLuaUntyped(L, payload->getData()) > 0) {
- lua_setfield(L, -2, "data");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubOwnerConfigureConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubOwnerConfigure",
+ "This table has the following fields:\n\n"
+ "- `node`: string (Optional)\n"
+ "- `data`: @{Form}\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.h b/Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.h
index 83b1153..9f0ed9f 100644
--- a/Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.h
+++ b/Sluift/ElementConvertors/PubSubOwnerConfigureConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubOwnerConfigure.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubOwnerConfigure.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubOwnerConfigureConvertor : public GenericLuaElementConvertor<PubSubOwnerConfigure> {
- public:
- PubSubOwnerConfigureConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubOwnerConfigureConvertor();
+ class PubSubOwnerConfigureConvertor : public GenericLuaElementConvertor<PubSubOwnerConfigure> {
+ public:
+ PubSubOwnerConfigureConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubOwnerConfigureConvertor() override;
- virtual boost::shared_ptr<PubSubOwnerConfigure> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubOwnerConfigure>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubOwnerConfigure> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubOwnerConfigure>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerDefaultConvertor.cpp b/Sluift/ElementConvertors/PubSubOwnerDefaultConvertor.cpp
index 17612cc..b2ff3de 100644
--- a/Sluift/ElementConvertors/PubSubOwnerDefaultConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubOwnerDefaultConvertor.cpp
@@ -1,44 +1,50 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubOwnerDefaultConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Sluift/LuaElementConvertors.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubOwnerDefaultConvertor::PubSubOwnerDefaultConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubOwnerDefault>("pubsub_owner_default"),
- convertors(convertors) {
+PubSubOwnerDefaultConvertor::PubSubOwnerDefaultConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubOwnerDefault>("pubsub_owner_default"),
+ convertors(convertors) {
}
PubSubOwnerDefaultConvertor::~PubSubOwnerDefaultConvertor() {
}
-boost::shared_ptr<PubSubOwnerDefault> PubSubOwnerDefaultConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubOwnerDefault> result = boost::make_shared<PubSubOwnerDefault>();
- lua_getfield(L, -1, "data");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<Form> payload = boost::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) {
- result->setData(payload);
- }
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubOwnerDefault> PubSubOwnerDefaultConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubOwnerDefault> result = std::make_shared<PubSubOwnerDefault>();
+ lua_getfield(L, -1, "data");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<Form> payload = std::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"))) {
+ result->setData(payload);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubOwnerDefaultConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubOwnerDefault> payload) {
+ lua_createtable(L, 0, 0);
+ if (convertors->convertToLuaUntyped(L, payload->getData()) > 0) {
+ lua_setfield(L, -2, "data");
+ }
}
-void PubSubOwnerDefaultConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubOwnerDefault> payload) {
- lua_createtable(L, 0, 0);
- if (convertors->convertToLuaUntyped(L, payload->getData()) > 0) {
- lua_setfield(L, -2, "data");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubOwnerDefaultConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubOwnerDefault",
+ "This table has the following fields:\n\n"
+ "- `data`: @{Form}\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerDefaultConvertor.h b/Sluift/ElementConvertors/PubSubOwnerDefaultConvertor.h
index 3a0f8ee..ab4a25b 100644
--- a/Sluift/ElementConvertors/PubSubOwnerDefaultConvertor.h
+++ b/Sluift/ElementConvertors/PubSubOwnerDefaultConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubOwnerDefault.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubOwnerDefault.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubOwnerDefaultConvertor : public GenericLuaElementConvertor<PubSubOwnerDefault> {
- public:
- PubSubOwnerDefaultConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubOwnerDefaultConvertor();
+ class PubSubOwnerDefaultConvertor : public GenericLuaElementConvertor<PubSubOwnerDefault> {
+ public:
+ PubSubOwnerDefaultConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubOwnerDefaultConvertor() override;
- virtual boost::shared_ptr<PubSubOwnerDefault> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubOwnerDefault>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubOwnerDefault> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubOwnerDefault>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.cpp b/Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.cpp
index f67ed1e..3733d74 100644
--- a/Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.cpp
@@ -1,51 +1,58 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Sluift/LuaElementConvertors.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubOwnerDeleteConvertor::PubSubOwnerDeleteConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubOwnerDelete>("pubsub_owner_delete"),
- convertors(convertors) {
+PubSubOwnerDeleteConvertor::PubSubOwnerDeleteConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubOwnerDelete>("pubsub_owner_delete"),
+ convertors(convertors) {
}
PubSubOwnerDeleteConvertor::~PubSubOwnerDeleteConvertor() {
}
-boost::shared_ptr<PubSubOwnerDelete> PubSubOwnerDeleteConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubOwnerDelete> result = boost::make_shared<PubSubOwnerDelete>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "redirect");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubOwnerRedirect> payload = boost::dynamic_pointer_cast<PubSubOwnerRedirect>(convertors->convertFromLuaUntyped(L, -1, "pubsub_owner_redirect"))) {
- result->setRedirect(payload);
- }
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubOwnerDelete> PubSubOwnerDeleteConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubOwnerDelete> result = std::make_shared<PubSubOwnerDelete>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "redirect");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubOwnerRedirect> payload = std::dynamic_pointer_cast<PubSubOwnerRedirect>(convertors->convertFromLuaUntyped(L, -1, "pubsub_owner_redirect"))) {
+ result->setRedirect(payload);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubOwnerDeleteConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubOwnerDelete> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ if (convertors->convertToLuaUntyped(L, payload->getRedirect()) > 0) {
+ lua_setfield(L, -2, "redirect");
+ }
}
-void PubSubOwnerDeleteConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubOwnerDelete> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- if (convertors->convertToLuaUntyped(L, payload->getRedirect()) > 0) {
- lua_setfield(L, -2, "redirect");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubOwnerDeleteConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubOwnerDelete",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `redirect`: @{PubSubOwnerRedirect}\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.h b/Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.h
index 7475e9c..8c44b5c 100644
--- a/Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.h
+++ b/Sluift/ElementConvertors/PubSubOwnerDeleteConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubOwnerDelete.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubOwnerDelete.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubOwnerDeleteConvertor : public GenericLuaElementConvertor<PubSubOwnerDelete> {
- public:
- PubSubOwnerDeleteConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubOwnerDeleteConvertor();
+ class PubSubOwnerDeleteConvertor : public GenericLuaElementConvertor<PubSubOwnerDelete> {
+ public:
+ PubSubOwnerDeleteConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubOwnerDeleteConvertor() override;
- virtual boost::shared_ptr<PubSubOwnerDelete> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubOwnerDelete>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubOwnerDelete> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubOwnerDelete>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.cpp b/Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.cpp
index a060db9..98c6355 100644
--- a/Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.cpp
@@ -1,41 +1,44 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubOwnerPurgeConvertor::PubSubOwnerPurgeConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubOwnerPurge>("pubsub_owner_purge"),
- convertors(convertors) {
+PubSubOwnerPurgeConvertor::PubSubOwnerPurgeConvertor() :
+ GenericLuaElementConvertor<PubSubOwnerPurge>("pubsub_owner_purge") {
}
PubSubOwnerPurgeConvertor::~PubSubOwnerPurgeConvertor() {
}
-boost::shared_ptr<PubSubOwnerPurge> PubSubOwnerPurgeConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubOwnerPurge> result = boost::make_shared<PubSubOwnerPurge>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubOwnerPurge> PubSubOwnerPurgeConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubOwnerPurge> result = std::make_shared<PubSubOwnerPurge>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubOwnerPurgeConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubOwnerPurge> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
}
-void PubSubOwnerPurgeConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubOwnerPurge> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
+boost::optional<LuaElementConvertor::Documentation> PubSubOwnerPurgeConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubOwnerPurge",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.h b/Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.h
index 34c979b..b2cb565 100644
--- a/Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.h
+++ b/Sluift/ElementConvertors/PubSubOwnerPurgeConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubOwnerPurge.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubOwnerPurge.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubOwnerPurgeConvertor : public GenericLuaElementConvertor<PubSubOwnerPurge> {
- public:
- PubSubOwnerPurgeConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubOwnerPurgeConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubOwnerPurge> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubOwnerPurge>) SWIFTEN_OVERRIDE;
+ class PubSubOwnerPurgeConvertor : public GenericLuaElementConvertor<PubSubOwnerPurge> {
+ public:
+ PubSubOwnerPurgeConvertor();
+ virtual ~PubSubOwnerPurgeConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubOwnerPurge> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubOwnerPurge>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.cpp b/Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.cpp
index d11df72..8fc20d2 100644
--- a/Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.cpp
@@ -1,41 +1,44 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubOwnerRedirectConvertor::PubSubOwnerRedirectConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubOwnerRedirect>("pubsub_owner_redirect"),
- convertors(convertors) {
+PubSubOwnerRedirectConvertor::PubSubOwnerRedirectConvertor() :
+ GenericLuaElementConvertor<PubSubOwnerRedirect>("pubsub_owner_redirect") {
}
PubSubOwnerRedirectConvertor::~PubSubOwnerRedirectConvertor() {
}
-boost::shared_ptr<PubSubOwnerRedirect> PubSubOwnerRedirectConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubOwnerRedirect> result = boost::make_shared<PubSubOwnerRedirect>();
- lua_getfield(L, -1, "uri");
- if (lua_isstring(L, -1)) {
- result->setURI(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubOwnerRedirect> PubSubOwnerRedirectConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubOwnerRedirect> result = std::make_shared<PubSubOwnerRedirect>();
+ lua_getfield(L, -1, "uri");
+ if (lua_isstring(L, -1)) {
+ result->setURI(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubOwnerRedirectConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubOwnerRedirect> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getURI().c_str());
+ lua_setfield(L, -2, "uri");
}
-void PubSubOwnerRedirectConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubOwnerRedirect> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getURI().c_str());
- lua_setfield(L, -2, "uri");
+boost::optional<LuaElementConvertor::Documentation> PubSubOwnerRedirectConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubOwnerRedirect",
+ "This table has the following fields:\n\n"
+ "- `uri`: string\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.h b/Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.h
index fc1ddce..433303f 100644
--- a/Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.h
+++ b/Sluift/ElementConvertors/PubSubOwnerRedirectConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubOwnerRedirect.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubOwnerRedirect.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubOwnerRedirectConvertor : public GenericLuaElementConvertor<PubSubOwnerRedirect> {
- public:
- PubSubOwnerRedirectConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubOwnerRedirectConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubOwnerRedirect> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubOwnerRedirect>) SWIFTEN_OVERRIDE;
+ class PubSubOwnerRedirectConvertor : public GenericLuaElementConvertor<PubSubOwnerRedirect> {
+ public:
+ PubSubOwnerRedirectConvertor();
+ virtual ~PubSubOwnerRedirectConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubOwnerRedirect> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubOwnerRedirect>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.cpp b/Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.cpp
index 0216874..e0b3687 100644
--- a/Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.cpp
@@ -1,58 +1,76 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubOwnerSubscriptionConvertor::PubSubOwnerSubscriptionConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubOwnerSubscription>("pubsub_owner_subscription"),
- convertors(convertors) {
+PubSubOwnerSubscriptionConvertor::PubSubOwnerSubscriptionConvertor() :
+ GenericLuaElementConvertor<PubSubOwnerSubscription>("pubsub_owner_subscription") {
}
PubSubOwnerSubscriptionConvertor::~PubSubOwnerSubscriptionConvertor() {
}
-boost::shared_ptr<PubSubOwnerSubscription> PubSubOwnerSubscriptionConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubOwnerSubscription> result = boost::make_shared<PubSubOwnerSubscription>();
- lua_getfield(L, -1, "jid");
- if (lua_isstring(L, -1)) {
- result->setJID(JID(std::string(lua_tostring(L, -1))));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "subscription");
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubOwnerSubscription> PubSubOwnerSubscriptionConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubOwnerSubscription> result = std::make_shared<PubSubOwnerSubscription>();
+ lua_getfield(L, -1, "jid");
+ if (lua_isstring(L, -1)) {
+ result->setJID(JID(std::string(lua_tostring(L, -1))));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "subscription");
+ if (lua_isstring(L, -1)) {
+ if (std::string(lua_tostring(L, -1)) == "none") {
+ result->setSubscription(PubSubOwnerSubscription::None);
+ }
+ if (std::string(lua_tostring(L, -1)) == "pending") {
+ result->setSubscription(PubSubOwnerSubscription::Pending);
+ }
+ if (std::string(lua_tostring(L, -1)) == "subscribed") {
+ result->setSubscription(PubSubOwnerSubscription::Subscribed);
+ }
+ if (std::string(lua_tostring(L, -1)) == "unconfigured") {
+ result->setSubscription(PubSubOwnerSubscription::Unconfigured);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubOwnerSubscriptionConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubOwnerSubscription> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getJID().toString().c_str());
+ lua_setfield(L, -2, "jid");
+ switch (payload->getSubscription()) {
+ case PubSubOwnerSubscription::None:
+ lua_pushstring(L, "none");
+ break;
+ case PubSubOwnerSubscription::Pending:
+ lua_pushstring(L, "pending");
+ break;
+ case PubSubOwnerSubscription::Subscribed:
+ lua_pushstring(L, "subscribed");
+ break;
+ case PubSubOwnerSubscription::Unconfigured:
+ lua_pushstring(L, "unconfigured");
+ break;
+ }
+ lua_setfield(L, -2, "subscription");
}
-void PubSubOwnerSubscriptionConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubOwnerSubscription> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getJID().toString().c_str());
- lua_setfield(L, -2, "jid");
- switch (payload->getSubscription()) {
- case PubSubOwnerSubscription::None:
- lua_pushstring(L, "none");
- break;
- case PubSubOwnerSubscription::Pending:
- lua_pushstring(L, "pending");
- break;
- case PubSubOwnerSubscription::Subscribed:
- lua_pushstring(L, "subscribed");
- break;
- case PubSubOwnerSubscription::Unconfigured:
- lua_pushstring(L, "unconfigured");
- break;
- }
- lua_setfield(L, -2, "subscription");
+boost::optional<LuaElementConvertor::Documentation> PubSubOwnerSubscriptionConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubOwnerSubscription",
+ "This table has the following fields:\n\n"
+ "- `jid`: jid (string)\n"
+ "- `subscription`: `\"none\"`, `\"pending\"`, `\"subscribed\"`, or `\"unconfigured\"`\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.h b/Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.h
index ca80c82..bf054b3 100644
--- a/Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.h
+++ b/Sluift/ElementConvertors/PubSubOwnerSubscriptionConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubOwnerSubscription.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubOwnerSubscription.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubOwnerSubscriptionConvertor : public GenericLuaElementConvertor<PubSubOwnerSubscription> {
- public:
- PubSubOwnerSubscriptionConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubOwnerSubscriptionConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubOwnerSubscription> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubOwnerSubscription>) SWIFTEN_OVERRIDE;
+ class PubSubOwnerSubscriptionConvertor : public GenericLuaElementConvertor<PubSubOwnerSubscription> {
+ public:
+ PubSubOwnerSubscriptionConvertor();
+ virtual ~PubSubOwnerSubscriptionConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubOwnerSubscription> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubOwnerSubscription>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.cpp b/Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.cpp
index 045cf12..3530efe 100644
--- a/Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.cpp
@@ -1,68 +1,76 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
-#include <Sluift/LuaElementConvertors.h>
-#include <Swiften/Base/foreach.h>
+#include <lua.hpp>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <Sluift/LuaElementConvertors.h>
using namespace Swift;
-PubSubOwnerSubscriptionsConvertor::PubSubOwnerSubscriptionsConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubOwnerSubscriptions>("pubsub_owner_subscriptions"),
- convertors(convertors) {
+PubSubOwnerSubscriptionsConvertor::PubSubOwnerSubscriptionsConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubOwnerSubscriptions>("pubsub_owner_subscriptions"),
+ convertors(convertors) {
}
PubSubOwnerSubscriptionsConvertor::~PubSubOwnerSubscriptionsConvertor() {
}
-boost::shared_ptr<PubSubOwnerSubscriptions> PubSubOwnerSubscriptionsConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubOwnerSubscriptions> result = boost::make_shared<PubSubOwnerSubscriptions>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- if (lua_type(L, -1) == LUA_TTABLE) {
- std::vector< boost::shared_ptr<PubSubOwnerSubscription> > items;
- for(size_t i = 0; i < lua_objlen(L, -1); ++i) {
- lua_pushnumber(L, i + 1);
- lua_gettable(L, -2);
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubOwnerSubscription> payload = boost::dynamic_pointer_cast<PubSubOwnerSubscription>(convertors->convertFromLuaUntyped(L, -1, "pubsub_owner_subscription"))) {
- items.push_back(payload);
- }
- }
- lua_pop(L, 1);
- }
+std::shared_ptr<PubSubOwnerSubscriptions> PubSubOwnerSubscriptionsConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubOwnerSubscriptions> result = std::make_shared<PubSubOwnerSubscriptions>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ std::vector< std::shared_ptr<PubSubOwnerSubscription> > items;
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubOwnerSubscription> payload = std::dynamic_pointer_cast<PubSubOwnerSubscription>(convertors->convertFromLuaUntyped(L, -1, "pubsub_owner_subscription"))) {
+ items.push_back(payload);
+ }
+ }
+ lua_pop(L, 1);
+ }
+
+ result->setSubscriptions(items);
+ }
+ return result;
+}
- result->setSubscriptions(items);
- }
- return result;
+void PubSubOwnerSubscriptionsConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubOwnerSubscriptions> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ if (!payload->getSubscriptions().empty()) {
+ {
+ int i = 0;
+ for (auto&& item : payload->getSubscriptions()) {
+ if (convertors->convertToLuaUntyped(L, item) > 0) {
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ }
+ }
}
-void PubSubOwnerSubscriptionsConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubOwnerSubscriptions> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- if (!payload->getSubscriptions().empty()) {
- {
- int i = 0;
- foreach(boost::shared_ptr<PubSubOwnerSubscription> item, payload->getSubscriptions()) {
- if (convertors->convertToLuaUntyped(L, item) > 0) {
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- ++i;
- }
- }
- }
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubOwnerSubscriptionsConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubOwnerSubscriptions",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `subscriptions`: array<@{PubSubOwnerSubscription}>\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.h b/Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.h
index 2e12c93..2e3f9be 100644
--- a/Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.h
+++ b/Sluift/ElementConvertors/PubSubOwnerSubscriptionsConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubOwnerSubscriptions.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubOwnerSubscriptions.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubOwnerSubscriptionsConvertor : public GenericLuaElementConvertor<PubSubOwnerSubscriptions> {
- public:
- PubSubOwnerSubscriptionsConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubOwnerSubscriptionsConvertor();
+ class PubSubOwnerSubscriptionsConvertor : public GenericLuaElementConvertor<PubSubOwnerSubscriptions> {
+ public:
+ PubSubOwnerSubscriptionsConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubOwnerSubscriptionsConvertor() override;
- virtual boost::shared_ptr<PubSubOwnerSubscriptions> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubOwnerSubscriptions>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubOwnerSubscriptions> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubOwnerSubscriptions>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubPublishConvertor.cpp b/Sluift/ElementConvertors/PubSubPublishConvertor.cpp
index 880d9fc..d8a2742 100644
--- a/Sluift/ElementConvertors/PubSubPublishConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubPublishConvertor.cpp
@@ -1,72 +1,80 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubPublishConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
-#include <Sluift/LuaElementConvertors.h>
-#include <Swiften/Base/foreach.h>
+#include <lua.hpp>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <Sluift/LuaElementConvertors.h>
using namespace Swift;
-PubSubPublishConvertor::PubSubPublishConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubPublish>("pubsub_publish"),
- convertors(convertors) {
+PubSubPublishConvertor::PubSubPublishConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubPublish>("pubsub_publish"),
+ convertors(convertors) {
}
PubSubPublishConvertor::~PubSubPublishConvertor() {
}
-boost::shared_ptr<PubSubPublish> PubSubPublishConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubPublish> result = boost::make_shared<PubSubPublish>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "items");
- if (lua_type(L, -1) == LUA_TTABLE) {
- std::vector< boost::shared_ptr<PubSubItem> > items;
- for(size_t i = 0; i < lua_objlen(L, -1); ++i) {
- lua_pushnumber(L, i + 1);
- lua_gettable(L, -2);
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubItem> payload = boost::dynamic_pointer_cast<PubSubItem>(convertors->convertFromLuaUntyped(L, -1, "pubsub_item"))) {
- items.push_back(payload);
- }
- }
- lua_pop(L, 1);
- }
+std::shared_ptr<PubSubPublish> PubSubPublishConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubPublish> result = std::make_shared<PubSubPublish>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "items");
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ std::vector< std::shared_ptr<PubSubItem> > items;
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubItem> payload = std::dynamic_pointer_cast<PubSubItem>(convertors->convertFromLuaUntyped(L, -1, "pubsub_item"))) {
+ items.push_back(payload);
+ }
+ }
+ lua_pop(L, 1);
+ }
+
+ result->setItems(items);
+ }
+ lua_pop(L, 1);
+ return result;
+}
- result->setItems(items);
- }
- lua_pop(L, 1);
- return result;
+void PubSubPublishConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubPublish> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ if (!payload->getItems().empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(payload->getItems().size()), 0);
+ {
+ int i = 0;
+ for (auto&& item : payload->getItems()) {
+ if (convertors->convertToLuaUntyped(L, item) > 0) {
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ }
+ lua_setfield(L, -2, "items");
+ }
}
-void PubSubPublishConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubPublish> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- if (!payload->getItems().empty()) {
- lua_createtable(L, boost::numeric_cast<int>(payload->getItems().size()), 0);
- {
- int i = 0;
- foreach(boost::shared_ptr<PubSubItem> item, payload->getItems()) {
- if (convertors->convertToLuaUntyped(L, item) > 0) {
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- ++i;
- }
- }
- }
- lua_setfield(L, -2, "items");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubPublishConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubPublish",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `items`: array<@{PubSubItem}>\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubPublishConvertor.h b/Sluift/ElementConvertors/PubSubPublishConvertor.h
index 4415566..ae28f14 100644
--- a/Sluift/ElementConvertors/PubSubPublishConvertor.h
+++ b/Sluift/ElementConvertors/PubSubPublishConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubPublish.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubPublish.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubPublishConvertor : public GenericLuaElementConvertor<PubSubPublish> {
- public:
- PubSubPublishConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubPublishConvertor();
+ class PubSubPublishConvertor : public GenericLuaElementConvertor<PubSubPublish> {
+ public:
+ PubSubPublishConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubPublishConvertor() override;
- virtual boost::shared_ptr<PubSubPublish> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubPublish>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubPublish> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubPublish>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubRetractConvertor.cpp b/Sluift/ElementConvertors/PubSubRetractConvertor.cpp
index 61ca3df..c27ad7d 100644
--- a/Sluift/ElementConvertors/PubSubRetractConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubRetractConvertor.cpp
@@ -1,79 +1,90 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubRetractConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
-#include <Sluift/LuaElementConvertors.h>
-#include <Swiften/Base/foreach.h>
+#include <lua.hpp>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <Sluift/LuaElementConvertors.h>
using namespace Swift;
-PubSubRetractConvertor::PubSubRetractConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubRetract>("pubsub_retract"),
- convertors(convertors) {
+PubSubRetractConvertor::PubSubRetractConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubRetract>("pubsub_retract"),
+ convertors(convertors) {
}
PubSubRetractConvertor::~PubSubRetractConvertor() {
}
-boost::shared_ptr<PubSubRetract> PubSubRetractConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubRetract> result = boost::make_shared<PubSubRetract>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "items");
- if (lua_type(L, -1) == LUA_TTABLE) {
- std::vector< boost::shared_ptr<PubSubItem> > items;
- for(size_t i = 0; i < lua_objlen(L, -1); ++i) {
- lua_pushnumber(L, i + 1);
- lua_gettable(L, -2);
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubItem> payload = boost::dynamic_pointer_cast<PubSubItem>(convertors->convertFromLuaUntyped(L, -1, "pubsub_item"))) {
- items.push_back(payload);
- }
- }
- lua_pop(L, 1);
- }
+std::shared_ptr<PubSubRetract> PubSubRetractConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubRetract> result = std::make_shared<PubSubRetract>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "items");
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ std::vector< std::shared_ptr<PubSubItem> > items;
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubItem> payload = std::dynamic_pointer_cast<PubSubItem>(convertors->convertFromLuaUntyped(L, -1, "pubsub_item"))) {
+ items.push_back(payload);
+ }
+ }
+ lua_pop(L, 1);
+ }
+
+ result->setItems(items);
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "notify");
+ if (lua_isboolean(L, -1)) {
+ result->setNotify(lua_toboolean(L, -1));
+ }
+ lua_pop(L, 1);
+ return result;
+}
- result->setItems(items);
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "notify");
- if (lua_isboolean(L, -1)) {
- result->setNotify(lua_toboolean(L, -1));
- }
- lua_pop(L, 1);
- return result;
+void PubSubRetractConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubRetract> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getNode().c_str());
+ lua_setfield(L, -2, "node");
+ if (!payload->getItems().empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(payload->getItems().size()), 0);
+ {
+ int i = 0;
+ for (auto&& item : payload->getItems()) {
+ if (convertors->convertToLuaUntyped(L, item) > 0) {
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ }
+ lua_setfield(L, -2, "items");
+ }
+ if (payload->isNotify().is_initialized()) {
+ lua_pushboolean(L, payload->isNotify().get_value_or(false));
+ lua_setfield(L, -2, "notify");
+ }
}
-void PubSubRetractConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubRetract> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getNode().c_str());
- lua_setfield(L, -2, "node");
- if (!payload->getItems().empty()) {
- lua_createtable(L, boost::numeric_cast<int>(payload->getItems().size()), 0);
- {
- int i = 0;
- foreach(boost::shared_ptr<PubSubItem> item, payload->getItems()) {
- if (convertors->convertToLuaUntyped(L, item) > 0) {
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- ++i;
- }
- }
- }
- lua_setfield(L, -2, "items");
- }
- lua_pushboolean(L, payload->isNotify());
- lua_setfield(L, -2, "notify");
+boost::optional<LuaElementConvertor::Documentation> PubSubRetractConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubRetract",
+ "This table has the following fields:\n\n"
+ "- `node`: string\n"
+ "- `items`: array<@{PubSubItem}>\n"
+ "- `notify`: boolean\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubRetractConvertor.h b/Sluift/ElementConvertors/PubSubRetractConvertor.h
index 80d888b..ca15ca7 100644
--- a/Sluift/ElementConvertors/PubSubRetractConvertor.h
+++ b/Sluift/ElementConvertors/PubSubRetractConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubRetract.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubRetract.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubRetractConvertor : public GenericLuaElementConvertor<PubSubRetract> {
- public:
- PubSubRetractConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubRetractConvertor();
+ class PubSubRetractConvertor : public GenericLuaElementConvertor<PubSubRetract> {
+ public:
+ PubSubRetractConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubRetractConvertor() override;
- virtual boost::shared_ptr<PubSubRetract> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubRetract>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubRetract> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubRetract>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubSubscribeConvertor.cpp b/Sluift/ElementConvertors/PubSubSubscribeConvertor.cpp
index 06d6447..bb5eb61 100644
--- a/Sluift/ElementConvertors/PubSubSubscribeConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubSubscribeConvertor.cpp
@@ -1,60 +1,68 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubSubscribeConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Sluift/LuaElementConvertors.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubSubscribeConvertor::PubSubSubscribeConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubSubscribe>("pubsub_subscribe"),
- convertors(convertors) {
+PubSubSubscribeConvertor::PubSubSubscribeConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubSubscribe>("pubsub_subscribe"),
+ convertors(convertors) {
}
PubSubSubscribeConvertor::~PubSubSubscribeConvertor() {
}
-boost::shared_ptr<PubSubSubscribe> PubSubSubscribeConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubSubscribe> result = boost::make_shared<PubSubSubscribe>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "jid");
- if (lua_isstring(L, -1)) {
- result->setJID(JID(std::string(lua_tostring(L, -1))));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "options");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubOptions> payload = boost::dynamic_pointer_cast<PubSubOptions>(convertors->convertFromLuaUntyped(L, -1, "pubsub_options"))) {
- result->setOptions(payload);
- }
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubSubscribe> PubSubSubscribeConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubSubscribe> result = std::make_shared<PubSubSubscribe>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "jid");
+ if (lua_isstring(L, -1)) {
+ result->setJID(JID(std::string(lua_tostring(L, -1))));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "options");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubOptions> payload = std::dynamic_pointer_cast<PubSubOptions>(convertors->convertFromLuaUntyped(L, -1, "pubsub_options"))) {
+ result->setOptions(payload);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubSubscribeConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubSubscribe> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getNode()) {
+ lua_pushstring(L, (*payload->getNode()).c_str());
+ lua_setfield(L, -2, "node");
+ }
+ lua_pushstring(L, payload->getJID().toString().c_str());
+ lua_setfield(L, -2, "jid");
+ if (convertors->convertToLuaUntyped(L, payload->getOptions()) > 0) {
+ lua_setfield(L, -2, "options");
+ }
}
-void PubSubSubscribeConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubSubscribe> payload) {
- lua_createtable(L, 0, 0);
- if (payload->getNode()) {
- lua_pushstring(L, (*payload->getNode()).c_str());
- lua_setfield(L, -2, "node");
- }
- lua_pushstring(L, payload->getJID().toString().c_str());
- lua_setfield(L, -2, "jid");
- if (convertors->convertToLuaUntyped(L, payload->getOptions()) > 0) {
- lua_setfield(L, -2, "options");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubSubscribeConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubSubscribe",
+ "This table has the following fields:\n\n"
+ "- `node`: string (Optional)\n"
+ "- `jid`: jid (string)\n"
+ "- `options`: @{PubSubOptions}\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubSubscribeConvertor.h b/Sluift/ElementConvertors/PubSubSubscribeConvertor.h
index 2073c09..5f9d224 100644
--- a/Sluift/ElementConvertors/PubSubSubscribeConvertor.h
+++ b/Sluift/ElementConvertors/PubSubSubscribeConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubSubscribe.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubSubscribe.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubSubscribeConvertor : public GenericLuaElementConvertor<PubSubSubscribe> {
- public:
- PubSubSubscribeConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubSubscribeConvertor();
+ class PubSubSubscribeConvertor : public GenericLuaElementConvertor<PubSubSubscribe> {
+ public:
+ PubSubSubscribeConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubSubscribeConvertor() override;
- virtual boost::shared_ptr<PubSubSubscribe> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubSubscribe>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubSubscribe> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubSubscribe>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.cpp b/Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.cpp
index e8053fb..01da15f 100644
--- a/Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.cpp
@@ -1,41 +1,44 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubSubscribeOptionsConvertor::PubSubSubscribeOptionsConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubSubscribeOptions>("pubsub_subscribe_options"),
- convertors(convertors) {
+PubSubSubscribeOptionsConvertor::PubSubSubscribeOptionsConvertor() :
+ GenericLuaElementConvertor<PubSubSubscribeOptions>("pubsub_subscribe_options") {
}
PubSubSubscribeOptionsConvertor::~PubSubSubscribeOptionsConvertor() {
}
-boost::shared_ptr<PubSubSubscribeOptions> PubSubSubscribeOptionsConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubSubscribeOptions> result = boost::make_shared<PubSubSubscribeOptions>();
- lua_getfield(L, -1, "required");
- if (lua_isboolean(L, -1)) {
- result->setRequired(lua_toboolean(L, -1));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubSubscribeOptions> PubSubSubscribeOptionsConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubSubscribeOptions> result = std::make_shared<PubSubSubscribeOptions>();
+ lua_getfield(L, -1, "required");
+ if (lua_isboolean(L, -1)) {
+ result->setRequired(lua_toboolean(L, -1));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubSubscribeOptionsConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubSubscribeOptions> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushboolean(L, payload->isRequired());
+ lua_setfield(L, -2, "required");
}
-void PubSubSubscribeOptionsConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubSubscribeOptions> payload) {
- lua_createtable(L, 0, 0);
- lua_pushboolean(L, payload->isRequired());
- lua_setfield(L, -2, "required");
+boost::optional<LuaElementConvertor::Documentation> PubSubSubscribeOptionsConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubSubscribeOptions",
+ "This table has the following fields:\n\n"
+ "- `required`: boolean\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.h b/Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.h
index 71e1baf..d853989 100644
--- a/Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.h
+++ b/Sluift/ElementConvertors/PubSubSubscribeOptionsConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubSubscribeOptions.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubSubscribeOptions.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubSubscribeOptionsConvertor : public GenericLuaElementConvertor<PubSubSubscribeOptions> {
- public:
- PubSubSubscribeOptionsConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubSubscribeOptionsConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubSubscribeOptions> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubSubscribeOptions>) SWIFTEN_OVERRIDE;
+ class PubSubSubscribeOptionsConvertor : public GenericLuaElementConvertor<PubSubSubscribeOptions> {
+ public:
+ PubSubSubscribeOptionsConvertor();
+ virtual ~PubSubSubscribeOptionsConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubSubscribeOptions> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubSubscribeOptions>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubSubscriptionConvertor.cpp b/Sluift/ElementConvertors/PubSubSubscriptionConvertor.cpp
index 9ec9fec..65c6474 100644
--- a/Sluift/ElementConvertors/PubSubSubscriptionConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubSubscriptionConvertor.cpp
@@ -1,86 +1,110 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubSubscriptionConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+#include <lua.hpp>
#include <Sluift/LuaElementConvertors.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-PubSubSubscriptionConvertor::PubSubSubscriptionConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubSubscription>("pubsub_subscription"),
- convertors(convertors) {
+PubSubSubscriptionConvertor::PubSubSubscriptionConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubSubscription>("pubsub_subscription"),
+ convertors(convertors) {
}
PubSubSubscriptionConvertor::~PubSubSubscriptionConvertor() {
}
-boost::shared_ptr<PubSubSubscription> PubSubSubscriptionConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubSubscription> result = boost::make_shared<PubSubSubscription>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "subscriptionid");
- if (lua_isstring(L, -1)) {
- result->setSubscriptionID(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "jid");
- if (lua_isstring(L, -1)) {
- result->setJID(JID(std::string(lua_tostring(L, -1))));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "options");
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubSubscribeOptions> payload = boost::dynamic_pointer_cast<PubSubSubscribeOptions>(convertors->convertFromLuaUntyped(L, -1, "pubsub_subscribe_options"))) {
- result->setOptions(payload);
- }
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "subscription");
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubSubscription> PubSubSubscriptionConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubSubscription> result = std::make_shared<PubSubSubscription>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "subscription_id");
+ if (lua_isstring(L, -1)) {
+ result->setSubscriptionID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "jid");
+ if (lua_isstring(L, -1)) {
+ result->setJID(JID(std::string(lua_tostring(L, -1))));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "options");
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubSubscribeOptions> payload = std::dynamic_pointer_cast<PubSubSubscribeOptions>(convertors->convertFromLuaUntyped(L, -1, "pubsub_subscribe_options"))) {
+ result->setOptions(payload);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "subscription");
+ if (lua_isstring(L, -1)) {
+ if (std::string(lua_tostring(L, -1)) == "none") {
+ result->setSubscription(PubSubSubscription::None);
+ }
+ if (std::string(lua_tostring(L, -1)) == "pending") {
+ result->setSubscription(PubSubSubscription::Pending);
+ }
+ if (std::string(lua_tostring(L, -1)) == "subscribed") {
+ result->setSubscription(PubSubSubscription::Subscribed);
+ }
+ if (std::string(lua_tostring(L, -1)) == "unconfigured") {
+ result->setSubscription(PubSubSubscription::Unconfigured);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubSubscriptionConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubSubscription> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getNode()) {
+ lua_pushstring(L, (*payload->getNode()).c_str());
+ lua_setfield(L, -2, "node");
+ }
+ if (payload->getSubscriptionID()) {
+ lua_pushstring(L, (*payload->getSubscriptionID()).c_str());
+ lua_setfield(L, -2, "subscription_id");
+ }
+ lua_pushstring(L, payload->getJID().toString().c_str());
+ lua_setfield(L, -2, "jid");
+ if (convertors->convertToLuaUntyped(L, payload->getOptions()) > 0) {
+ lua_setfield(L, -2, "options");
+ }
+ switch (payload->getSubscription()) {
+ case PubSubSubscription::None:
+ lua_pushstring(L, "none");
+ break;
+ case PubSubSubscription::Pending:
+ lua_pushstring(L, "pending");
+ break;
+ case PubSubSubscription::Subscribed:
+ lua_pushstring(L, "subscribed");
+ break;
+ case PubSubSubscription::Unconfigured:
+ lua_pushstring(L, "unconfigured");
+ break;
+ }
+ lua_setfield(L, -2, "subscription");
}
-void PubSubSubscriptionConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubSubscription> payload) {
- lua_createtable(L, 0, 0);
- if (payload->getNode()) {
- lua_pushstring(L, (*payload->getNode()).c_str());
- lua_setfield(L, -2, "node");
- }
- if (payload->getSubscriptionID()) {
- lua_pushstring(L, (*payload->getSubscriptionID()).c_str());
- lua_setfield(L, -2, "subscriptionid");
- }
- lua_pushstring(L, payload->getJID().toString().c_str());
- lua_setfield(L, -2, "jid");
- if (convertors->convertToLuaUntyped(L, payload->getOptions()) > 0) {
- lua_setfield(L, -2, "options");
- }
- switch (payload->getSubscription()) {
- case PubSubSubscription::None:
- lua_pushstring(L, "none");
- break;
- case PubSubSubscription::Pending:
- lua_pushstring(L, "pending");
- break;
- case PubSubSubscription::Subscribed:
- lua_pushstring(L, "subscribed");
- break;
- case PubSubSubscription::Unconfigured:
- lua_pushstring(L, "unconfigured");
- break;
- }
- lua_setfield(L, -2, "subscription");
+boost::optional<LuaElementConvertor::Documentation> PubSubSubscriptionConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubSubscription",
+ "This table has the following fields:\n\n"
+ "- `node`: string (Optional)\n"
+ "- `subscription_id`: string (Optional)\n"
+ "- `jid`: jid (string)\n"
+ "- `options`: @{PubSubSubscribeOptions}\n"
+ "- `subscription`: `\"none\"`, `\"pending\"`, `\"subscribed\"`, or `\"unconfigured\"`\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubSubscriptionConvertor.h b/Sluift/ElementConvertors/PubSubSubscriptionConvertor.h
index 2da4930..9cad963 100644
--- a/Sluift/ElementConvertors/PubSubSubscriptionConvertor.h
+++ b/Sluift/ElementConvertors/PubSubSubscriptionConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubSubscription.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubSubscription.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubSubscriptionConvertor : public GenericLuaElementConvertor<PubSubSubscription> {
- public:
- PubSubSubscriptionConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubSubscriptionConvertor();
+ class PubSubSubscriptionConvertor : public GenericLuaElementConvertor<PubSubSubscription> {
+ public:
+ PubSubSubscriptionConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubSubscriptionConvertor() override;
- virtual boost::shared_ptr<PubSubSubscription> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubSubscription>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubSubscription> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubSubscription>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubSubscriptionsConvertor.cpp b/Sluift/ElementConvertors/PubSubSubscriptionsConvertor.cpp
index 04f8da8..2325181 100644
--- a/Sluift/ElementConvertors/PubSubSubscriptionsConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubSubscriptionsConvertor.cpp
@@ -1,70 +1,78 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubSubscriptionsConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
-#include <Sluift/LuaElementConvertors.h>
-#include <Swiften/Base/foreach.h>
+#include <lua.hpp>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <Sluift/LuaElementConvertors.h>
using namespace Swift;
-PubSubSubscriptionsConvertor::PubSubSubscriptionsConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubSubscriptions>("pubsub_subscriptions"),
- convertors(convertors) {
+PubSubSubscriptionsConvertor::PubSubSubscriptionsConvertor(LuaElementConvertors* convertors) :
+ GenericLuaElementConvertor<PubSubSubscriptions>("pubsub_subscriptions"),
+ convertors(convertors) {
}
PubSubSubscriptionsConvertor::~PubSubSubscriptionsConvertor() {
}
-boost::shared_ptr<PubSubSubscriptions> PubSubSubscriptionsConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubSubscriptions> result = boost::make_shared<PubSubSubscriptions>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- if (lua_type(L, -1) == LUA_TTABLE) {
- std::vector< boost::shared_ptr<PubSubSubscription> > items;
- for(size_t i = 0; i < lua_objlen(L, -1); ++i) {
- lua_pushnumber(L, i + 1);
- lua_gettable(L, -2);
- if (!lua_isnil(L, -1)) {
- if (boost::shared_ptr<PubSubSubscription> payload = boost::dynamic_pointer_cast<PubSubSubscription>(convertors->convertFromLuaUntyped(L, -1, "pubsub_subscription"))) {
- items.push_back(payload);
- }
- }
- lua_pop(L, 1);
- }
+std::shared_ptr<PubSubSubscriptions> PubSubSubscriptionsConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubSubscriptions> result = std::make_shared<PubSubSubscriptions>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ std::vector< std::shared_ptr<PubSubSubscription> > items;
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (!lua_isnil(L, -1)) {
+ if (std::shared_ptr<PubSubSubscription> payload = std::dynamic_pointer_cast<PubSubSubscription>(convertors->convertFromLuaUntyped(L, -1, "pubsub_subscription"))) {
+ items.push_back(payload);
+ }
+ }
+ lua_pop(L, 1);
+ }
+
+ result->setSubscriptions(items);
+ }
+ return result;
+}
- result->setSubscriptions(items);
- }
- return result;
+void PubSubSubscriptionsConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubSubscriptions> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getNode()) {
+ lua_pushstring(L, (*payload->getNode()).c_str());
+ lua_setfield(L, -2, "node");
+ }
+ if (!payload->getSubscriptions().empty()) {
+ {
+ int i = 0;
+ for (auto&& item : payload->getSubscriptions()) {
+ if (convertors->convertToLuaUntyped(L, item) > 0) {
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ }
+ }
}
-void PubSubSubscriptionsConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubSubscriptions> payload) {
- lua_createtable(L, 0, 0);
- if (payload->getNode()) {
- lua_pushstring(L, (*payload->getNode()).c_str());
- lua_setfield(L, -2, "node");
- }
- if (!payload->getSubscriptions().empty()) {
- {
- int i = 0;
- foreach(boost::shared_ptr<PubSubSubscription> item, payload->getSubscriptions()) {
- if (convertors->convertToLuaUntyped(L, item) > 0) {
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- ++i;
- }
- }
- }
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubSubscriptionsConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubSubscriptions",
+ "This table has the following fields:\n\n"
+ "- `node`: string (Optional)\n"
+ "- `subscriptions`: array<@{PubSubSubscription}>\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubSubscriptionsConvertor.h b/Sluift/ElementConvertors/PubSubSubscriptionsConvertor.h
index 7f18f64..94b4533 100644
--- a/Sluift/ElementConvertors/PubSubSubscriptionsConvertor.h
+++ b/Sluift/ElementConvertors/PubSubSubscriptionsConvertor.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubSubscriptions.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubSubscriptions.h>
namespace Swift {
- class LuaElementConvertors;
+ class LuaElementConvertors;
- class PubSubSubscriptionsConvertor : public GenericLuaElementConvertor<PubSubSubscriptions> {
- public:
- PubSubSubscriptionsConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubSubscriptionsConvertor();
+ class PubSubSubscriptionsConvertor : public GenericLuaElementConvertor<PubSubSubscriptions> {
+ public:
+ PubSubSubscriptionsConvertor(LuaElementConvertors* convertors);
+ virtual ~PubSubSubscriptionsConvertor() override;
- virtual boost::shared_ptr<PubSubSubscriptions> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubSubscriptions>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<PubSubSubscriptions> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubSubscriptions>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
- private:
- LuaElementConvertors* convertors;
- };
+ private:
+ LuaElementConvertors* convertors;
+ };
}
diff --git a/Sluift/ElementConvertors/PubSubUnsubscribeConvertor.cpp b/Sluift/ElementConvertors/PubSubUnsubscribeConvertor.cpp
index 323cb29..056c84c 100644
--- a/Sluift/ElementConvertors/PubSubUnsubscribeConvertor.cpp
+++ b/Sluift/ElementConvertors/PubSubUnsubscribeConvertor.cpp
@@ -1,59 +1,64 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/PubSubUnsubscribeConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-
-
-
+#include <memory>
-#pragma clang diagnostic ignored "-Wunused-private-field"
+#include <lua.hpp>
using namespace Swift;
-PubSubUnsubscribeConvertor::PubSubUnsubscribeConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<PubSubUnsubscribe>("pubsub_unsubscribe"),
- convertors(convertors) {
+PubSubUnsubscribeConvertor::PubSubUnsubscribeConvertor() :
+ GenericLuaElementConvertor<PubSubUnsubscribe>("pubsub_unsubscribe") {
}
PubSubUnsubscribeConvertor::~PubSubUnsubscribeConvertor() {
}
-boost::shared_ptr<PubSubUnsubscribe> PubSubUnsubscribeConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<PubSubUnsubscribe> result = boost::make_shared<PubSubUnsubscribe>();
- lua_getfield(L, -1, "node");
- if (lua_isstring(L, -1)) {
- result->setNode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "jid");
- if (lua_isstring(L, -1)) {
- result->setJID(JID(std::string(lua_tostring(L, -1))));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "subscriptionid");
- if (lua_isstring(L, -1)) {
- result->setSubscriptionID(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<PubSubUnsubscribe> PubSubUnsubscribeConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<PubSubUnsubscribe> result = std::make_shared<PubSubUnsubscribe>();
+ lua_getfield(L, -1, "node");
+ if (lua_isstring(L, -1)) {
+ result->setNode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "jid");
+ if (lua_isstring(L, -1)) {
+ result->setJID(JID(std::string(lua_tostring(L, -1))));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "subscription_id");
+ if (lua_isstring(L, -1)) {
+ result->setSubscriptionID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void PubSubUnsubscribeConvertor::doConvertToLua(lua_State* L, std::shared_ptr<PubSubUnsubscribe> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getNode()) {
+ lua_pushstring(L, (*payload->getNode()).c_str());
+ lua_setfield(L, -2, "node");
+ }
+ lua_pushstring(L, payload->getJID().toString().c_str());
+ lua_setfield(L, -2, "jid");
+ if (payload->getSubscriptionID()) {
+ lua_pushstring(L, (*payload->getSubscriptionID()).c_str());
+ lua_setfield(L, -2, "subscription_id");
+ }
}
-void PubSubUnsubscribeConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<PubSubUnsubscribe> payload) {
- lua_createtable(L, 0, 0);
- if (payload->getNode()) {
- lua_pushstring(L, (*payload->getNode()).c_str());
- lua_setfield(L, -2, "node");
- }
- lua_pushstring(L, payload->getJID().toString().c_str());
- lua_setfield(L, -2, "jid");
- if (payload->getSubscriptionID()) {
- lua_pushstring(L, (*payload->getSubscriptionID()).c_str());
- lua_setfield(L, -2, "subscriptionid");
- }
+boost::optional<LuaElementConvertor::Documentation> PubSubUnsubscribeConvertor::getDocumentation() const {
+ return Documentation(
+ "PubSubUnsubscribe",
+ "This table has the following fields:\n\n"
+ "- `node`: string (Optional)\n"
+ "- `jid`: jid (string)\n"
+ "- `subscription_id`: string (Optional)\n"
+ );
}
diff --git a/Sluift/ElementConvertors/PubSubUnsubscribeConvertor.h b/Sluift/ElementConvertors/PubSubUnsubscribeConvertor.h
index 16d279f..f76f2b1 100644
--- a/Sluift/ElementConvertors/PubSubUnsubscribeConvertor.h
+++ b/Sluift/ElementConvertors/PubSubUnsubscribeConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/PubSubUnsubscribe.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/PubSubUnsubscribe.h>
namespace Swift {
- class LuaElementConvertors;
-
- class PubSubUnsubscribeConvertor : public GenericLuaElementConvertor<PubSubUnsubscribe> {
- public:
- PubSubUnsubscribeConvertor(LuaElementConvertors* convertors);
- virtual ~PubSubUnsubscribeConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<PubSubUnsubscribe> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<PubSubUnsubscribe>) SWIFTEN_OVERRIDE;
+ class PubSubUnsubscribeConvertor : public GenericLuaElementConvertor<PubSubUnsubscribe> {
+ public:
+ PubSubUnsubscribeConvertor();
+ virtual ~PubSubUnsubscribeConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<PubSubUnsubscribe> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<PubSubUnsubscribe>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/RawXMLElementConvertor.cpp b/Sluift/ElementConvertors/RawXMLElementConvertor.cpp
index 35a53ca..9688677 100644
--- a/Sluift/ElementConvertors/RawXMLElementConvertor.cpp
+++ b/Sluift/ElementConvertors/RawXMLElementConvertor.cpp
@@ -1,17 +1,18 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/RawXMLElementConvertor.h>
-#include <iostream>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <lua.hpp>
#include <Swiften/Elements/RawXMLPayload.h>
#include <Swiften/Serializer/PayloadSerializer.h>
+
#include <Sluift/Lua/Check.h>
using namespace Swift;
@@ -22,16 +23,20 @@ RawXMLElementConvertor::RawXMLElementConvertor() {
RawXMLElementConvertor::~RawXMLElementConvertor() {
}
-boost::shared_ptr<Payload> RawXMLElementConvertor::convertFromLua(lua_State* L, int index, const std::string& type) {
- if (type == "xml") {
- return boost::make_shared<RawXMLPayload>(std::string(Lua::checkString(L, index)));
- }
- return boost::shared_ptr<Payload>();
+std::shared_ptr<Element> RawXMLElementConvertor::convertFromLua(lua_State* L, int index, const std::string& type) {
+ if (type == "xml") {
+ return std::make_shared<RawXMLPayload>(std::string(Lua::checkString(L, index)));
+ }
+ return std::shared_ptr<Payload>();
}
-boost::optional<std::string> RawXMLElementConvertor::convertToLua(lua_State* L, boost::shared_ptr<Payload> payload) {
- PayloadSerializer* serializer = serializers.getPayloadSerializer(payload);
- assert(serializer);
- lua_pushstring(L, serializer->serialize(payload).c_str());
- return std::string("xml");
+boost::optional<std::string> RawXMLElementConvertor::convertToLua(lua_State* L, std::shared_ptr<Element> element) {
+ std::shared_ptr<Payload> payload = std::dynamic_pointer_cast<Payload>(element);
+ if (!payload) {
+ return boost::optional<std::string>();
+ }
+ PayloadSerializer* serializer = serializers.getPayloadSerializer(payload);
+ assert(serializer);
+ lua_pushstring(L, serializer->serialize(payload).c_str());
+ return std::string("xml");
}
diff --git a/Sluift/ElementConvertors/RawXMLElementConvertor.h b/Sluift/ElementConvertors/RawXMLElementConvertor.h
index 6087ba0..af3625b 100644
--- a/Sluift/ElementConvertors/RawXMLElementConvertor.h
+++ b/Sluift/ElementConvertors/RawXMLElementConvertor.h
@@ -1,26 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h>
#include <Sluift/LuaElementConvertor.h>
-#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h>
namespace Swift {
- class RawXMLElementConvertor : public LuaElementConvertor {
- public:
- RawXMLElementConvertor();
- virtual ~RawXMLElementConvertor();
+ class RawXMLElementConvertor : public LuaElementConvertor {
+ public:
+ RawXMLElementConvertor();
+ virtual ~RawXMLElementConvertor() override;
- virtual boost::shared_ptr<Payload> convertFromLua(lua_State*, int index, const std::string& type) SWIFTEN_OVERRIDE;
- virtual boost::optional<std::string> convertToLua(lua_State*, boost::shared_ptr<Payload>) SWIFTEN_OVERRIDE;
+ virtual std::shared_ptr<Element> convertFromLua(lua_State*, int index, const std::string& type) override;
+ virtual boost::optional<std::string> convertToLua(lua_State*, std::shared_ptr<Element>) override;
- private:
- FullPayloadSerializerCollection serializers;
- };
+ private:
+ FullPayloadSerializerCollection serializers;
+ };
}
diff --git a/Sluift/ElementConvertors/ResultSetConvertor.cpp b/Sluift/ElementConvertors/ResultSetConvertor.cpp
new file mode 100644
index 0000000..7762a79
--- /dev/null
+++ b/Sluift/ElementConvertors/ResultSetConvertor.cpp
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/ResultSetConvertor.h>
+
+#include <memory>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
+using namespace Swift;
+
+ResultSetConvertor::ResultSetConvertor() :
+ GenericLuaElementConvertor<ResultSet>("result_set") {
+}
+
+ResultSetConvertor::~ResultSetConvertor() {
+}
+
+std::shared_ptr<ResultSet> ResultSetConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<ResultSet> result = std::make_shared<ResultSet>();
+ lua_getfield(L, -1, "max_items");
+ if (lua_isstring(L, -1)) {
+ result->setMaxItems(boost::numeric_cast<int>(lua_tonumber(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "count");
+ if (lua_isnumber(L, -1)) {
+ result->setCount(boost::numeric_cast<int>(lua_tonumber(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "index");
+ if (lua_isnumber(L, -1)) {
+ result->setIndex(boost::numeric_cast<int>(lua_tonumber(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "first_id_index");
+ if (lua_isstring(L, -1)) {
+ result->setFirstIDIndex(boost::numeric_cast<int>(lua_tonumber(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "first_id");
+ if (lua_isstring(L, -1)) {
+ result->setFirstID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "last_id");
+ if (lua_isstring(L, -1)) {
+ result->setLastID(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "after");
+ if (lua_isstring(L, -1)) {
+ result->setAfter(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "before");
+ if (lua_isstring(L, -1)) {
+ result->setBefore(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void ResultSetConvertor::doConvertToLua(lua_State* L, std::shared_ptr<ResultSet> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getMaxItems()) {
+ lua_pushnumber(L, *payload->getMaxItems());
+ lua_setfield(L, -2, "max_items");
+ }
+ if (payload->getCount()) {
+ lua_pushnumber(L, *payload->getCount());
+ lua_setfield(L, -2, "count");
+ }
+ if (payload->getIndex()) {
+ lua_pushnumber(L, *payload->getIndex());
+ lua_setfield(L, -2, "index");
+ }
+ if (payload->getFirstIDIndex()) {
+ lua_pushnumber(L, *payload->getFirstIDIndex());
+ lua_setfield(L, -2, "first_id_index");
+ }
+ if (payload->getFirstID()) {
+ lua_pushstring(L, (*payload->getFirstID()).c_str());
+ lua_setfield(L, -2, "first_id");
+ }
+ if (payload->getLastID()) {
+ lua_pushstring(L, (*payload->getLastID()).c_str());
+ lua_setfield(L, -2, "last_id");
+ }
+ if (payload->getAfter()) {
+ lua_pushstring(L, (*payload->getAfter()).c_str());
+ lua_setfield(L, -2, "after");
+ }
+ if (payload->getBefore()) {
+ lua_pushstring(L, (*payload->getBefore()).c_str());
+ lua_setfield(L, -2, "before");
+ }
+}
+
+boost::optional<LuaElementConvertor::Documentation> ResultSetConvertor::getDocumentation() const {
+ return Documentation(
+ "ResultSet",
+ "This table has the following fields:\n\n"
+ "- `max_items`: number (Optional)\n"
+ "- `count`: number (Optional)\n"
+ "- `first_id_index`: number (Optional)\n"
+ "- `first_id`: string (Optional)\n"
+ "- `last_id`: string (Optional)\n"
+ "- `after`: string (Optional)\n"
+ );
+}
diff --git a/Sluift/ElementConvertors/ResultSetConvertor.h b/Sluift/ElementConvertors/ResultSetConvertor.h
new file mode 100644
index 0000000..e098605
--- /dev/null
+++ b/Sluift/ElementConvertors/ResultSetConvertor.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/ResultSet.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class ResultSetConvertor : public GenericLuaElementConvertor<ResultSet> {
+ public:
+ ResultSetConvertor();
+ virtual ~ResultSetConvertor() override;
+
+ virtual std::shared_ptr<ResultSet> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<ResultSet>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
+}
+
diff --git a/Sluift/ElementConvertors/SConscript b/Sluift/ElementConvertors/SConscript
index e98f7c4..0bf8022 100644
--- a/Sluift/ElementConvertors/SConscript
+++ b/Sluift/ElementConvertors/SConscript
@@ -2,41 +2,55 @@
Import('env')
convertors = [
- env.File("PubSubRetractConvertor.cpp"),
- env.File("PubSubAffiliationsConvertor.cpp"),
- env.File("PubSubPublishConvertor.cpp"),
- env.File("PubSubItemsConvertor.cpp"),
- env.File("PubSubOwnerRedirectConvertor.cpp"),
- env.File("PubSubEventRedirectConvertor.cpp"),
- env.File("PubSubConfigureConvertor.cpp"),
- env.File("PubSubEventDisassociateConvertor.cpp"),
- env.File("PubSubOwnerAffiliationsConvertor.cpp"),
- env.File("PubSubOwnerConfigureConvertor.cpp"),
- env.File("UserLocationConvertor.cpp"),
- env.File("PubSubSubscribeOptionsConvertor.cpp"),
- env.File("PubSubOwnerSubscriptionsConvertor.cpp"),
- env.File("PubSubDefaultConvertor.cpp"),
- env.File("PubSubEventCollectionConvertor.cpp"),
- env.File("PubSubEventSubscriptionConvertor.cpp"),
- env.File("PubSubEventRetractConvertor.cpp"),
- env.File("PubSubItemConvertor.cpp"),
- env.File("PubSubUnsubscribeConvertor.cpp"),
- env.File("PubSubEventDeleteConvertor.cpp"),
- env.File("PubSubCreateConvertor.cpp"),
- env.File("PubSubOwnerPurgeConvertor.cpp"),
- env.File("PubSubEventItemsConvertor.cpp"),
- env.File("PubSubOptionsConvertor.cpp"),
- env.File("PubSubEventItemConvertor.cpp"),
- env.File("PubSubOwnerSubscriptionConvertor.cpp"),
- env.File("PubSubOwnerAffiliationConvertor.cpp"),
- env.File("PubSubEventPurgeConvertor.cpp"),
- env.File("PubSubAffiliationConvertor.cpp"),
- env.File("PubSubSubscribeConvertor.cpp"),
- env.File("PubSubOwnerDeleteConvertor.cpp"),
- env.File("PubSubOwnerDefaultConvertor.cpp"),
- env.File("PubSubSubscriptionsConvertor.cpp"),
- env.File("PubSubEventAssociateConvertor.cpp"),
- env.File("PubSubSubscriptionConvertor.cpp"),
- env.File("PubSubEventConfigurationConvertor.cpp")
+ env.File("PubSubRetractConvertor.cpp"),
+ env.File("PubSubAffiliationsConvertor.cpp"),
+ env.File("PubSubPublishConvertor.cpp"),
+ env.File("PubSubItemsConvertor.cpp"),
+ env.File("PubSubOwnerRedirectConvertor.cpp"),
+ env.File("PubSubEventRedirectConvertor.cpp"),
+ env.File("UserTuneConvertor.cpp"),
+ env.File("PubSubConfigureConvertor.cpp"),
+ env.File("PubSubEventDisassociateConvertor.cpp"),
+ env.File("PubSubOwnerAffiliationsConvertor.cpp"),
+ env.File("PubSubOwnerConfigureConvertor.cpp"),
+ env.File("UserLocationConvertor.cpp"),
+ env.File("PubSubSubscribeOptionsConvertor.cpp"),
+ env.File("PubSubOwnerSubscriptionsConvertor.cpp"),
+ env.File("PubSubDefaultConvertor.cpp"),
+ env.File("PubSubEventCollectionConvertor.cpp"),
+ env.File("PubSubEventSubscriptionConvertor.cpp"),
+ env.File("PubSubEventRetractConvertor.cpp"),
+ env.File("PubSubItemConvertor.cpp"),
+ env.File("PubSubUnsubscribeConvertor.cpp"),
+ env.File("PubSubEventDeleteConvertor.cpp"),
+ env.File("PubSubCreateConvertor.cpp"),
+ env.File("PubSubOwnerPurgeConvertor.cpp"),
+ env.File("PubSubEventItemsConvertor.cpp"),
+ env.File("PubSubOptionsConvertor.cpp"),
+ env.File("PubSubEventItemConvertor.cpp"),
+ env.File("PubSubOwnerSubscriptionConvertor.cpp"),
+ env.File("PubSubOwnerAffiliationConvertor.cpp"),
+ env.File("PubSubEventPurgeConvertor.cpp"),
+ env.File("PubSubAffiliationConvertor.cpp"),
+ env.File("PubSubSubscribeConvertor.cpp"),
+ env.File("PubSubOwnerDeleteConvertor.cpp"),
+ env.File("PubSubOwnerDefaultConvertor.cpp"),
+ env.File("PubSubSubscriptionsConvertor.cpp"),
+ env.File("PubSubEventAssociateConvertor.cpp"),
+ env.File("PubSubSubscriptionConvertor.cpp"),
+ env.File("SecurityLabelConvertor.cpp"),
+ env.File("PubSubEventConfigurationConvertor.cpp"),
+ env.File("IQConvertor.cpp"),
+ env.File("PresenceConvertor.cpp"),
+ env.File("MessageConvertor.cpp"),
+ env.File("ResultSetConvertor.cpp"),
+ env.File("ForwardedConvertor.cpp"),
+ env.File("MAMResultConvertor.cpp"),
+ env.File("MAMQueryConvertor.cpp"),
+ env.File("MAMFinConvertor.cpp"),
+ env.File("CarbonsReceivedConvertor.cpp"),
+ env.File("CarbonsSentConvertor.cpp"),
+ env.File("SubjectConvertor.cpp"),
+ env.File("IsodeIQDelegationConvertor.cpp")
]
Return('convertors')
diff --git a/Sluift/ElementConvertors/SecurityLabelConvertor.cpp b/Sluift/ElementConvertors/SecurityLabelConvertor.cpp
new file mode 100644
index 0000000..8bc323a
--- /dev/null
+++ b/Sluift/ElementConvertors/SecurityLabelConvertor.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/SecurityLabelConvertor.h>
+
+#include <memory>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
+using namespace Swift;
+
+SecurityLabelConvertor::SecurityLabelConvertor() :
+ GenericLuaElementConvertor<SecurityLabel>("security_label") {
+}
+
+SecurityLabelConvertor::~SecurityLabelConvertor() {
+}
+
+std::shared_ptr<SecurityLabel> SecurityLabelConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<SecurityLabel> result = std::make_shared<SecurityLabel>();
+ lua_getfield(L, -1, "equivalent_labels");
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ std::vector< std::string > items;
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (lua_isstring(L, -1)) {
+ items.push_back(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ }
+
+ result->setEquivalentLabels(items);
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "foreground_color");
+ if (lua_isstring(L, -1)) {
+ result->setForegroundColor(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "display_marking");
+ if (lua_isstring(L, -1)) {
+ result->setDisplayMarking(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "background_color");
+ if (lua_isstring(L, -1)) {
+ result->setBackgroundColor(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "label");
+ if (lua_isstring(L, -1)) {
+ result->setLabel(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void SecurityLabelConvertor::doConvertToLua(lua_State* L, std::shared_ptr<SecurityLabel> payload) {
+ lua_createtable(L, 0, 0);
+ if (!payload->getEquivalentLabels().empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(payload->getEquivalentLabels().size()), 0);
+ {
+ int i = 0;
+ for (const auto& item : payload->getEquivalentLabels()) {
+ lua_pushstring(L, item.c_str());
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ lua_setfield(L, -2, "equivalent_labels");
+ }
+ lua_pushstring(L, payload->getForegroundColor().c_str());
+ lua_setfield(L, -2, "foreground_color");
+ lua_pushstring(L, payload->getDisplayMarking().c_str());
+ lua_setfield(L, -2, "display_marking");
+ lua_pushstring(L, payload->getBackgroundColor().c_str());
+ lua_setfield(L, -2, "background_color");
+ lua_pushstring(L, payload->getLabel().c_str());
+ lua_setfield(L, -2, "label");
+}
+
+boost::optional<LuaElementConvertor::Documentation> SecurityLabelConvertor::getDocumentation() const {
+ return Documentation(
+ "SecurityLabel",
+ "This table has the following fields:\n\n"
+ "- `equivalent_labels`: array<string>\n"
+ "- `foreground_color`: string\n"
+ "- `display_marking`: string\n"
+ "- `background_color`: string\n"
+ "- `label`: string\n"
+ );
+}
diff --git a/Sluift/ElementConvertors/SecurityLabelConvertor.h b/Sluift/ElementConvertors/SecurityLabelConvertor.h
new file mode 100644
index 0000000..22d11ca
--- /dev/null
+++ b/Sluift/ElementConvertors/SecurityLabelConvertor.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2010-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/SecurityLabel.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class SecurityLabelConvertor : public GenericLuaElementConvertor<SecurityLabel> {
+ public:
+ SecurityLabelConvertor();
+ virtual ~SecurityLabelConvertor() override;
+
+ virtual std::shared_ptr<SecurityLabel> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<SecurityLabel>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
+}
diff --git a/Sluift/ElementConvertors/SoftwareVersionConvertor.cpp b/Sluift/ElementConvertors/SoftwareVersionConvertor.cpp
index 5799614..f997a45 100644
--- a/Sluift/ElementConvertors/SoftwareVersionConvertor.cpp
+++ b/Sluift/ElementConvertors/SoftwareVersionConvertor.cpp
@@ -1,14 +1,17 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/SoftwareVersionConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
#include <Sluift/Lua/Check.h>
using namespace Swift;
@@ -19,32 +22,32 @@ SoftwareVersionConvertor::SoftwareVersionConvertor() : GenericLuaElementConverto
SoftwareVersionConvertor::~SoftwareVersionConvertor() {
}
-boost::shared_ptr<SoftwareVersion> SoftwareVersionConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<SoftwareVersion> result = boost::make_shared<SoftwareVersion>();
- lua_getfield(L, -1, "name");
- if (!lua_isnil(L, -1)) {
- result->setName(std::string(Lua::checkString(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "version");
- if (!lua_isnil(L, -1)) {
- result->setVersion(std::string(Lua::checkString(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "os");
- if (!lua_isnil(L, -1)) {
- result->setOS(std::string(Lua::checkString(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<SoftwareVersion> SoftwareVersionConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<SoftwareVersion> result = std::make_shared<SoftwareVersion>();
+ lua_getfield(L, -1, "name");
+ if (!lua_isnil(L, -1)) {
+ result->setName(std::string(Lua::checkString(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "version");
+ if (!lua_isnil(L, -1)) {
+ result->setVersion(std::string(Lua::checkString(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "os");
+ if (!lua_isnil(L, -1)) {
+ result->setOS(std::string(Lua::checkString(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
}
-void SoftwareVersionConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<SoftwareVersion> payload) {
- lua_createtable(L, 0, 0);
- lua_pushstring(L, payload->getName().c_str());
- lua_setfield(L, -2, "name");
- lua_pushstring(L, payload->getVersion().c_str());
- lua_setfield(L, -2, "version");
- lua_pushstring(L, payload->getOS().c_str());
- lua_setfield(L, -2, "os");
+void SoftwareVersionConvertor::doConvertToLua(lua_State* L, std::shared_ptr<SoftwareVersion> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getName().c_str());
+ lua_setfield(L, -2, "name");
+ lua_pushstring(L, payload->getVersion().c_str());
+ lua_setfield(L, -2, "version");
+ lua_pushstring(L, payload->getOS().c_str());
+ lua_setfield(L, -2, "os");
}
diff --git a/Sluift/ElementConvertors/SoftwareVersionConvertor.h b/Sluift/ElementConvertors/SoftwareVersionConvertor.h
index 5fa3cc3..791aede 100644
--- a/Sluift/ElementConvertors/SoftwareVersionConvertor.h
+++ b/Sluift/ElementConvertors/SoftwareVersionConvertor.h
@@ -1,23 +1,22 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/SoftwareVersion.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/SoftwareVersion.h>
namespace Swift {
- class SoftwareVersionConvertor : public GenericLuaElementConvertor<SoftwareVersion> {
- public:
- SoftwareVersionConvertor();
- virtual ~SoftwareVersionConvertor();
+ class SoftwareVersionConvertor : public GenericLuaElementConvertor<SoftwareVersion> {
+ public:
+ SoftwareVersionConvertor();
+ virtual ~SoftwareVersionConvertor() override;
- virtual boost::shared_ptr<SoftwareVersion> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<SoftwareVersion>) SWIFTEN_OVERRIDE;
- };
+ virtual std::shared_ptr<SoftwareVersion> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<SoftwareVersion>) override;
+ };
}
diff --git a/Sluift/ElementConvertors/StanzaConvertor.h b/Sluift/ElementConvertors/StanzaConvertor.h
new file mode 100644
index 0000000..a7b4e4e
--- /dev/null
+++ b/Sluift/ElementConvertors/StanzaConvertor.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <Swiften/Elements/IQ.h>
+#include <Swiften/Elements/Message.h>
+#include <Swiften/Elements/Payload.h>
+#include <Swiften/Elements/Presence.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+#include <Sluift/Lua/Exception.h>
+#include <Sluift/LuaElementConvertors.h>
+
+namespace Swift {
+ template <typename T> class StanzaConvertor : public GenericLuaElementConvertor<T> {
+ public:
+ StanzaConvertor(const std::string& tag)
+ : GenericLuaElementConvertor<T>(tag) {
+ }
+
+ virtual ~StanzaConvertor() {
+ }
+
+ std::shared_ptr<T> getStanza(lua_State* L, LuaElementConvertors* convertors) {
+ std::shared_ptr<T> result = std::make_shared<T>();
+ lua_getfield(L, -1, "id");
+ if (lua_isstring(L, -1)) {
+ result->setID(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "from");
+ if (lua_isstring(L, -1)) {
+ result->setFrom(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "to");
+ if (lua_isstring(L, -1)) {
+ result->setTo(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "payloads");
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ for(size_t i = 0; i < lua_rawlen(L, -1); ++i) {
+ lua_pushnumber(L, i + 1);
+ lua_gettable(L, -2);
+ if (!lua_isnil(L, -1)) {
+ std::shared_ptr<Payload> payload = std::dynamic_pointer_cast<Payload>(convertors->convertFromLua(L, -1));
+ if (!!payload) {
+ result->addPayload(payload);
+ }
+ }
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+ }
+
+ void pushStanza(lua_State* L, const std::shared_ptr<T> stanza, LuaElementConvertors* convertors) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, stanza->getID().c_str());
+ lua_setfield(L, -2, "id");
+ lua_pushstring(L, stanza->getFrom().toString().c_str());
+ lua_setfield(L, -2, "from");
+ lua_pushstring(L, stanza->getTo().toString().c_str());
+ lua_setfield(L, -2, "to");
+ if (!stanza->getPayloads().empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(stanza->getPayloads().size()), 0);
+ {
+ int i = 0;
+ for (const auto& item : stanza->getPayloads()) {
+ if (convertors->convertToLua(L, item) > 0) {
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ ++i;
+ }
+ }
+ }
+ lua_setfield(L, -2, "payloads");
+ }
+ }
+ };
+}
diff --git a/Sluift/ElementConvertors/StatusConvertor.cpp b/Sluift/ElementConvertors/StatusConvertor.cpp
new file mode 100644
index 0000000..eed4044
--- /dev/null
+++ b/Sluift/ElementConvertors/StatusConvertor.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/StatusConvertor.h>
+
+#include <memory>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
+#include <Sluift/Lua/Check.h>
+
+using namespace Swift;
+
+StatusConvertor::StatusConvertor() : GenericLuaElementConvertor<Status>("status") {
+}
+
+StatusConvertor::~StatusConvertor() {
+}
+
+std::shared_ptr<Status> StatusConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<Status> result = std::make_shared<Status>();
+ lua_getfield(L, -1, "text");
+ if (lua_isstring(L, -1)) {
+ result->setText(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void StatusConvertor::doConvertToLua(lua_State* L, std::shared_ptr<Status> payload) {
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, payload->getText().c_str());
+ lua_setfield(L, -2, "text");
+}
diff --git a/Sluift/ElementConvertors/StatusConvertor.h b/Sluift/ElementConvertors/StatusConvertor.h
new file mode 100644
index 0000000..994cee5
--- /dev/null
+++ b/Sluift/ElementConvertors/StatusConvertor.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/Status.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class StatusConvertor : public GenericLuaElementConvertor<Status> {
+ public:
+ StatusConvertor();
+ virtual ~StatusConvertor() override;
+
+ virtual std::shared_ptr<Status> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<Status>) override;
+ };
+}
diff --git a/Sluift/ElementConvertors/StatusShowConvertor.cpp b/Sluift/ElementConvertors/StatusShowConvertor.cpp
new file mode 100644
index 0000000..6d0a067
--- /dev/null
+++ b/Sluift/ElementConvertors/StatusShowConvertor.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/StatusShowConvertor.h>
+
+#include <memory>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
+#include <Sluift/Lua/Check.h>
+#include <Sluift/Lua/Exception.h>
+
+using namespace Swift;
+
+StatusShowConvertor::StatusShowConvertor() : GenericLuaElementConvertor<StatusShow>("show") {
+}
+
+StatusShowConvertor::~StatusShowConvertor() {
+}
+
+std::shared_ptr<StatusShow> StatusShowConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<StatusShow> result = std::make_shared<StatusShow>();
+ lua_getfield(L, -1, "type");
+ if (lua_isstring(L, -1)) {
+ result->setType(convertStatusShowTypeFromString(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void StatusShowConvertor::doConvertToLua(lua_State* L, std::shared_ptr<StatusShow> payload) {
+ lua_createtable(L, 0, 0);
+ const std::string show = convertStatusShowTypeToString(payload->getType());
+ if (!show.empty()) {
+ lua_pushstring(L, show.c_str());
+ lua_setfield(L, -2, "type");
+ }
+}
+
+std::string StatusShowConvertor::convertStatusShowTypeToString(const StatusShow::Type &show) {
+ switch (show) {
+ case StatusShow::Online: return "online";
+ case StatusShow::FFC: return "ffc";
+ case StatusShow::Away: return "away";
+ case StatusShow::XA: return "xa";
+ case StatusShow::DND: return "dnd";
+ case StatusShow::None: return "";
+ }
+ assert(false);
+ return "";
+}
+
+StatusShow::Type StatusShowConvertor::convertStatusShowTypeFromString(const std::string& show) {
+ if (show == "online") {
+ return StatusShow::Online;
+ }
+ else if (show == "ffc") {
+ return StatusShow::FFC;
+ }
+ else if (show == "away") {
+ return StatusShow::Away;
+ }
+ else if (show == "xa") {
+ return StatusShow::XA;
+ }
+ else if (show == "dnd") {
+ return StatusShow::DND;
+ }
+ else {
+ throw Lua::Exception("Illegal status show: '" + show + "'");
+ }
+}
diff --git a/Sluift/ElementConvertors/StatusShowConvertor.h b/Sluift/ElementConvertors/StatusShowConvertor.h
new file mode 100644
index 0000000..41be6b3
--- /dev/null
+++ b/Sluift/ElementConvertors/StatusShowConvertor.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/StatusShow.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class StatusShowConvertor : public GenericLuaElementConvertor<StatusShow> {
+ public:
+ StatusShowConvertor();
+ virtual ~StatusShowConvertor() override;
+
+ virtual std::shared_ptr<StatusShow> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<StatusShow>) override;
+
+ static std::string convertStatusShowTypeToString(const StatusShow::Type &show);
+ static StatusShow::Type convertStatusShowTypeFromString(const std::string& show);
+ };
+}
diff --git a/Sluift/ElementConvertors/SubjectConvertor.cpp b/Sluift/ElementConvertors/SubjectConvertor.cpp
new file mode 100644
index 0000000..ae03564
--- /dev/null
+++ b/Sluift/ElementConvertors/SubjectConvertor.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/SubjectConvertor.h>
+
+#include <memory>
+
+#include <lua.hpp>
+
+#include <Sluift/Lua/LuaUtils.h>
+
+using namespace Swift;
+
+SubjectConvertor::SubjectConvertor() : GenericLuaElementConvertor<Subject>("subject") {
+}
+
+SubjectConvertor::~SubjectConvertor() {
+}
+
+std::shared_ptr<Subject> SubjectConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<Subject> result = std::make_shared<Subject>();
+ if (boost::optional<std::string> value = Lua::getStringField(L, -1, "text")) {
+ result->setText(*value);
+ }
+ return result;
+}
+
+void SubjectConvertor::doConvertToLua(lua_State* L, std::shared_ptr<Subject> payload) {
+ lua_createtable(L, 0, 0);
+ if (!payload->getText().empty()) {
+ lua_pushstring(L, payload->getText().c_str());
+ lua_setfield(L, -2, "text");
+ }
+}
diff --git a/Sluift/ElementConvertors/SubjectConvertor.h b/Sluift/ElementConvertors/SubjectConvertor.h
new file mode 100644
index 0000000..f8eb152
--- /dev/null
+++ b/Sluift/ElementConvertors/SubjectConvertor.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/Subject.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class SubjectConvertor : public GenericLuaElementConvertor<Subject> {
+ public:
+ SubjectConvertor();
+ virtual ~SubjectConvertor() override;
+
+ virtual std::shared_ptr<Subject> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<Subject>) override;
+ };
+}
diff --git a/Sluift/ElementConvertors/UserLocationConvertor.cpp b/Sluift/ElementConvertors/UserLocationConvertor.cpp
index 97cb288..253ca36 100644
--- a/Sluift/ElementConvertors/UserLocationConvertor.cpp
+++ b/Sluift/ElementConvertors/UserLocationConvertor.cpp
@@ -1,232 +1,258 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/UserLocationConvertor.h>
+#include <memory>
+
#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-#include <boost/numeric/conversion/cast.hpp>
#include <Swiften/Base/DateTime.h>
-#pragma clang diagnostic ignored "-Wunused-private-field"
-
using namespace Swift;
-UserLocationConvertor::UserLocationConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<UserLocation>("user_location"),
- convertors(convertors) {
+UserLocationConvertor::UserLocationConvertor() :
+ GenericLuaElementConvertor<UserLocation>("user_location") {
}
UserLocationConvertor::~UserLocationConvertor() {
}
-boost::shared_ptr<UserLocation> UserLocationConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<UserLocation> result = boost::make_shared<UserLocation>();
- lua_getfield(L, -1, "area");
- if (lua_isstring(L, -1)) {
- result->setArea(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "altitude");
- if (lua_isnumber(L, -1)) {
- result->setAltitude(boost::numeric_cast<float>(lua_tonumber(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "locality");
- if (lua_isstring(L, -1)) {
- result->setLocality(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "latitude");
- if (lua_isnumber(L, -1)) {
- result->setLatitude(boost::numeric_cast<float>(lua_tonumber(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "accuracy");
- if (lua_isnumber(L, -1)) {
- result->setAccuracy(boost::numeric_cast<float>(lua_tonumber(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "description");
- if (lua_isstring(L, -1)) {
- result->setDescription(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "country_code");
- if (lua_isstring(L, -1)) {
- result->setCountryCode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "timestamp");
- if (lua_isstring(L, -1)) {
- result->setTimestamp(stringToDateTime(std::string(lua_tostring(L, -1))));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "floor");
- if (lua_isstring(L, -1)) {
- result->setFloor(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "building");
- if (lua_isstring(L, -1)) {
- result->setBuilding(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "room");
- if (lua_isstring(L, -1)) {
- result->setRoom(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "country");
- if (lua_isstring(L, -1)) {
- result->setCountry(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "region");
- if (lua_isstring(L, -1)) {
- result->setRegion(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "uri");
- if (lua_isstring(L, -1)) {
- result->setURI(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "longitude");
- if (lua_isnumber(L, -1)) {
- result->setLongitude(boost::numeric_cast<float>(lua_tonumber(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "error");
- if (lua_isnumber(L, -1)) {
- result->setError(boost::numeric_cast<float>(lua_tonumber(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "postal_code");
- if (lua_isstring(L, -1)) {
- result->setPostalCode(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "bearing");
- if (lua_isnumber(L, -1)) {
- result->setBearing(boost::numeric_cast<float>(lua_tonumber(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "text");
- if (lua_isstring(L, -1)) {
- result->setText(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "datum");
- if (lua_isstring(L, -1)) {
- result->setDatum(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "street");
- if (lua_isstring(L, -1)) {
- result->setStreet(std::string(lua_tostring(L, -1)));
- }
- lua_pop(L, 1);
- lua_getfield(L, -1, "speed");
- if (lua_isnumber(L, -1)) {
- result->setSpeed(boost::numeric_cast<float>(lua_tonumber(L, -1)));
- }
- lua_pop(L, 1);
- return result;
+std::shared_ptr<UserLocation> UserLocationConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<UserLocation> result = std::make_shared<UserLocation>();
+ lua_getfield(L, -1, "area");
+ if (lua_isstring(L, -1)) {
+ result->setArea(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "altitude");
+ if (lua_isnumber(L, -1)) {
+ result->setAltitude(lua_tonumber(L, -1));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "locality");
+ if (lua_isstring(L, -1)) {
+ result->setLocality(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "latitude");
+ if (lua_isnumber(L, -1)) {
+ result->setLatitude(lua_tonumber(L, -1));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "accuracy");
+ if (lua_isnumber(L, -1)) {
+ result->setAccuracy(lua_tonumber(L, -1));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "description");
+ if (lua_isstring(L, -1)) {
+ result->setDescription(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "country_code");
+ if (lua_isstring(L, -1)) {
+ result->setCountryCode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "timestamp");
+ if (lua_isstring(L, -1)) {
+ result->setTimestamp(stringToDateTime(std::string(lua_tostring(L, -1))));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "floor");
+ if (lua_isstring(L, -1)) {
+ result->setFloor(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "building");
+ if (lua_isstring(L, -1)) {
+ result->setBuilding(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "room");
+ if (lua_isstring(L, -1)) {
+ result->setRoom(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "country");
+ if (lua_isstring(L, -1)) {
+ result->setCountry(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "region");
+ if (lua_isstring(L, -1)) {
+ result->setRegion(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "uri");
+ if (lua_isstring(L, -1)) {
+ result->setURI(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "longitude");
+ if (lua_isnumber(L, -1)) {
+ result->setLongitude(lua_tonumber(L, -1));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "error");
+ if (lua_isnumber(L, -1)) {
+ result->setError(lua_tonumber(L, -1));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "postal_code");
+ if (lua_isstring(L, -1)) {
+ result->setPostalCode(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "bearing");
+ if (lua_isnumber(L, -1)) {
+ result->setBearing(lua_tonumber(L, -1));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "text");
+ if (lua_isstring(L, -1)) {
+ result->setText(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "datum");
+ if (lua_isstring(L, -1)) {
+ result->setDatum(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "street");
+ if (lua_isstring(L, -1)) {
+ result->setStreet(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "speed");
+ if (lua_isnumber(L, -1)) {
+ result->setSpeed(lua_tonumber(L, -1));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void UserLocationConvertor::doConvertToLua(lua_State* L, std::shared_ptr<UserLocation> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getArea()) {
+ lua_pushstring(L, (*payload->getArea()).c_str());
+ lua_setfield(L, -2, "area");
+ }
+ if (payload->getAltitude()) {
+ lua_pushnumber(L, (*payload->getAltitude()));
+ lua_setfield(L, -2, "altitude");
+ }
+ if (payload->getLocality()) {
+ lua_pushstring(L, (*payload->getLocality()).c_str());
+ lua_setfield(L, -2, "locality");
+ }
+ if (payload->getLatitude()) {
+ lua_pushnumber(L, (*payload->getLatitude()));
+ lua_setfield(L, -2, "latitude");
+ }
+ if (payload->getAccuracy()) {
+ lua_pushnumber(L, (*payload->getAccuracy()));
+ lua_setfield(L, -2, "accuracy");
+ }
+ if (payload->getDescription()) {
+ lua_pushstring(L, (*payload->getDescription()).c_str());
+ lua_setfield(L, -2, "description");
+ }
+ if (payload->getCountryCode()) {
+ lua_pushstring(L, (*payload->getCountryCode()).c_str());
+ lua_setfield(L, -2, "country_code");
+ }
+ if (payload->getTimestamp()) {
+ lua_pushstring(L, dateTimeToString((*payload->getTimestamp())).c_str());
+ lua_setfield(L, -2, "timestamp");
+ }
+ if (payload->getFloor()) {
+ lua_pushstring(L, (*payload->getFloor()).c_str());
+ lua_setfield(L, -2, "floor");
+ }
+ if (payload->getBuilding()) {
+ lua_pushstring(L, (*payload->getBuilding()).c_str());
+ lua_setfield(L, -2, "building");
+ }
+ if (payload->getRoom()) {
+ lua_pushstring(L, (*payload->getRoom()).c_str());
+ lua_setfield(L, -2, "room");
+ }
+ if (payload->getCountry()) {
+ lua_pushstring(L, (*payload->getCountry()).c_str());
+ lua_setfield(L, -2, "country");
+ }
+ if (payload->getRegion()) {
+ lua_pushstring(L, (*payload->getRegion()).c_str());
+ lua_setfield(L, -2, "region");
+ }
+ if (payload->getURI()) {
+ lua_pushstring(L, (*payload->getURI()).c_str());
+ lua_setfield(L, -2, "uri");
+ }
+ if (payload->getLongitude()) {
+ lua_pushnumber(L, (*payload->getLongitude()));
+ lua_setfield(L, -2, "longitude");
+ }
+ if (payload->getError()) {
+ lua_pushnumber(L, (*payload->getError()));
+ lua_setfield(L, -2, "error");
+ }
+ if (payload->getPostalCode()) {
+ lua_pushstring(L, (*payload->getPostalCode()).c_str());
+ lua_setfield(L, -2, "postal_code");
+ }
+ if (payload->getBearing()) {
+ lua_pushnumber(L, (*payload->getBearing()));
+ lua_setfield(L, -2, "bearing");
+ }
+ if (payload->getText()) {
+ lua_pushstring(L, (*payload->getText()).c_str());
+ lua_setfield(L, -2, "text");
+ }
+ if (payload->getDatum()) {
+ lua_pushstring(L, (*payload->getDatum()).c_str());
+ lua_setfield(L, -2, "datum");
+ }
+ if (payload->getStreet()) {
+ lua_pushstring(L, (*payload->getStreet()).c_str());
+ lua_setfield(L, -2, "street");
+ }
+ if (payload->getSpeed()) {
+ lua_pushnumber(L, (*payload->getSpeed()));
+ lua_setfield(L, -2, "speed");
+ }
}
-void UserLocationConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<UserLocation> payload) {
- lua_createtable(L, 0, 0);
- if (payload->getArea()) {
- lua_pushstring(L, (*payload->getArea()).c_str());
- lua_setfield(L, -2, "area");
- }
- if (payload->getAltitude()) {
- lua_pushnumber(L, (*payload->getAltitude()));
- lua_setfield(L, -2, "altitude");
- }
- if (payload->getLocality()) {
- lua_pushstring(L, (*payload->getLocality()).c_str());
- lua_setfield(L, -2, "locality");
- }
- if (payload->getLatitude()) {
- lua_pushnumber(L, (*payload->getLatitude()));
- lua_setfield(L, -2, "latitude");
- }
- if (payload->getAccuracy()) {
- lua_pushnumber(L, (*payload->getAccuracy()));
- lua_setfield(L, -2, "accuracy");
- }
- if (payload->getDescription()) {
- lua_pushstring(L, (*payload->getDescription()).c_str());
- lua_setfield(L, -2, "description");
- }
- if (payload->getCountryCode()) {
- lua_pushstring(L, (*payload->getCountryCode()).c_str());
- lua_setfield(L, -2, "country_code");
- }
- if (payload->getTimestamp()) {
- lua_pushstring(L, dateTimeToString((*payload->getTimestamp())).c_str());
- lua_setfield(L, -2, "timestamp");
- }
- if (payload->getFloor()) {
- lua_pushstring(L, (*payload->getFloor()).c_str());
- lua_setfield(L, -2, "floor");
- }
- if (payload->getBuilding()) {
- lua_pushstring(L, (*payload->getBuilding()).c_str());
- lua_setfield(L, -2, "building");
- }
- if (payload->getRoom()) {
- lua_pushstring(L, (*payload->getRoom()).c_str());
- lua_setfield(L, -2, "room");
- }
- if (payload->getCountry()) {
- lua_pushstring(L, (*payload->getCountry()).c_str());
- lua_setfield(L, -2, "country");
- }
- if (payload->getRegion()) {
- lua_pushstring(L, (*payload->getRegion()).c_str());
- lua_setfield(L, -2, "region");
- }
- if (payload->getURI()) {
- lua_pushstring(L, (*payload->getURI()).c_str());
- lua_setfield(L, -2, "uri");
- }
- if (payload->getLongitude()) {
- lua_pushnumber(L, (*payload->getLongitude()));
- lua_setfield(L, -2, "longitude");
- }
- if (payload->getError()) {
- lua_pushnumber(L, (*payload->getError()));
- lua_setfield(L, -2, "error");
- }
- if (payload->getPostalCode()) {
- lua_pushstring(L, (*payload->getPostalCode()).c_str());
- lua_setfield(L, -2, "postal_code");
- }
- if (payload->getBearing()) {
- lua_pushnumber(L, (*payload->getBearing()));
- lua_setfield(L, -2, "bearing");
- }
- if (payload->getText()) {
- lua_pushstring(L, (*payload->getText()).c_str());
- lua_setfield(L, -2, "text");
- }
- if (payload->getDatum()) {
- lua_pushstring(L, (*payload->getDatum()).c_str());
- lua_setfield(L, -2, "datum");
- }
- if (payload->getStreet()) {
- lua_pushstring(L, (*payload->getStreet()).c_str());
- lua_setfield(L, -2, "street");
- }
- if (payload->getSpeed()) {
- lua_pushnumber(L, (*payload->getSpeed()));
- lua_setfield(L, -2, "speed");
- }
+boost::optional<LuaElementConvertor::Documentation> UserLocationConvertor::getDocumentation() const {
+ return Documentation(
+ "UserLocation",
+ "This table has the following fields:\n\n"
+ "- `area`: string (Optional)\n"
+ "- `altitude`: @{float} (Optional)\n"
+ "- `locality`: string (Optional)\n"
+ "- `latitude`: @{float} (Optional)\n"
+ "- `accuracy`: @{float} (Optional)\n"
+ "- `description`: string (Optional)\n"
+ "- `country_code`: string (Optional)\n"
+ "- `timestamp`: datetime (string) (Optional)\n"
+ "- `floor`: string (Optional)\n"
+ "- `building`: string (Optional)\n"
+ "- `room`: string (Optional)\n"
+ "- `country`: string (Optional)\n"
+ "- `region`: string (Optional)\n"
+ "- `uri`: string (Optional)\n"
+ "- `longitude`: @{float} (Optional)\n"
+ "- `error`: @{float} (Optional)\n"
+ "- `postal_code`: string (Optional)\n"
+ "- `bearing`: @{float} (Optional)\n"
+ "- `text`: string (Optional)\n"
+ "- `datum`: string (Optional)\n"
+ "- `street`: string (Optional)\n"
+ "- `speed`: @{float} (Optional)\n"
+ );
}
diff --git a/Sluift/ElementConvertors/UserLocationConvertor.h b/Sluift/ElementConvertors/UserLocationConvertor.h
index a5eb153..b667d2a 100644
--- a/Sluift/ElementConvertors/UserLocationConvertor.h
+++ b/Sluift/ElementConvertors/UserLocationConvertor.h
@@ -1,28 +1,25 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/UserLocation.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/UserLocation.h>
namespace Swift {
- class LuaElementConvertors;
-
- class UserLocationConvertor : public GenericLuaElementConvertor<UserLocation> {
- public:
- UserLocationConvertor(LuaElementConvertors* convertors);
- virtual ~UserLocationConvertor();
+ class LuaElementConvertors;
- virtual boost::shared_ptr<UserLocation> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<UserLocation>) SWIFTEN_OVERRIDE;
+ class UserLocationConvertor : public GenericLuaElementConvertor<UserLocation> {
+ public:
+ UserLocationConvertor();
+ virtual ~UserLocationConvertor() override;
- private:
- LuaElementConvertors* convertors;
- };
+ virtual std::shared_ptr<UserLocation> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<UserLocation>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
}
diff --git a/Sluift/ElementConvertors/UserTuneConvertor.cpp b/Sluift/ElementConvertors/UserTuneConvertor.cpp
new file mode 100644
index 0000000..a9e1bee
--- /dev/null
+++ b/Sluift/ElementConvertors/UserTuneConvertor.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ElementConvertors/UserTuneConvertor.h>
+
+#include <memory>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
+using namespace Swift;
+
+UserTuneConvertor::UserTuneConvertor() :
+ GenericLuaElementConvertor<UserTune>("user_tune") {
+}
+
+UserTuneConvertor::~UserTuneConvertor() {
+}
+
+std::shared_ptr<UserTune> UserTuneConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<UserTune> result = std::make_shared<UserTune>();
+ lua_getfield(L, -1, "rating");
+ if (lua_isnumber(L, -1)) {
+ result->setRating(boost::numeric_cast<unsigned int>(lua_tonumber(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "title");
+ if (lua_isstring(L, -1)) {
+ result->setTitle(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "track");
+ if (lua_isstring(L, -1)) {
+ result->setTrack(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "artist");
+ if (lua_isstring(L, -1)) {
+ result->setArtist(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "uri");
+ if (lua_isstring(L, -1)) {
+ result->setURI(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "source");
+ if (lua_isstring(L, -1)) {
+ result->setSource(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "length");
+ if (lua_isnumber(L, -1)) {
+ result->setLength(boost::numeric_cast<unsigned int>(lua_tonumber(L, -1)));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void UserTuneConvertor::doConvertToLua(lua_State* L, std::shared_ptr<UserTune> payload) {
+ lua_createtable(L, 0, 0);
+ if (payload->getRating()) {
+ lua_pushnumber(L, (*payload->getRating()));
+ lua_setfield(L, -2, "rating");
+ }
+ if (payload->getTitle()) {
+ lua_pushstring(L, (*payload->getTitle()).c_str());
+ lua_setfield(L, -2, "title");
+ }
+ if (payload->getTrack()) {
+ lua_pushstring(L, (*payload->getTrack()).c_str());
+ lua_setfield(L, -2, "track");
+ }
+ if (payload->getArtist()) {
+ lua_pushstring(L, (*payload->getArtist()).c_str());
+ lua_setfield(L, -2, "artist");
+ }
+ if (payload->getURI()) {
+ lua_pushstring(L, (*payload->getURI()).c_str());
+ lua_setfield(L, -2, "uri");
+ }
+ if (payload->getSource()) {
+ lua_pushstring(L, (*payload->getSource()).c_str());
+ lua_setfield(L, -2, "source");
+ }
+ if (payload->getLength()) {
+ lua_pushnumber(L, (*payload->getLength()));
+ lua_setfield(L, -2, "length");
+ }
+}
+
+boost::optional<LuaElementConvertor::Documentation> UserTuneConvertor::getDocumentation() const {
+ return Documentation(
+ "UserTune",
+ "This table has the following fields:\n\n"
+ "- `rating`: number (Optional)\n"
+ "- `title`: string (Optional)\n"
+ "- `track`: string (Optional)\n"
+ "- `artist`: string (Optional)\n"
+ "- `uri`: string (Optional)\n"
+ "- `source`: string (Optional)\n"
+ "- `length`: number (Optional)\n"
+ );
+}
diff --git a/Sluift/ElementConvertors/UserTuneConvertor.h b/Sluift/ElementConvertors/UserTuneConvertor.h
new file mode 100644
index 0000000..90bda41
--- /dev/null
+++ b/Sluift/ElementConvertors/UserTuneConvertor.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Elements/UserTune.h>
+
+#include <Sluift/GenericLuaElementConvertor.h>
+
+namespace Swift {
+ class LuaElementConvertors;
+
+ class UserTuneConvertor : public GenericLuaElementConvertor<UserTune> {
+ public:
+ UserTuneConvertor();
+ virtual ~UserTuneConvertor() override;
+
+ virtual std::shared_ptr<UserTune> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<UserTune>) override;
+ virtual boost::optional<Documentation> getDocumentation() const override;
+ };
+}
diff --git a/Sluift/ElementConvertors/VCardConvertor.cpp b/Sluift/ElementConvertors/VCardConvertor.cpp
index a1c57be..ad521b3 100644
--- a/Sluift/ElementConvertors/VCardConvertor.cpp
+++ b/Sluift/ElementConvertors/VCardConvertor.cpp
@@ -1,16 +1,21 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/VCardConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
-#include <Sluift/Lua/LuaUtils.h>
+
+#include <lua.hpp>
+
#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Base/DateTime.h>
+
+#include <Sluift/Lua/LuaUtils.h>
using namespace Swift;
@@ -20,27 +25,609 @@ VCardConvertor::VCardConvertor() : GenericLuaElementConvertor<VCard>("vcard") {
VCardConvertor::~VCardConvertor() {
}
-boost::shared_ptr<VCard> VCardConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<VCard> result = boost::make_shared<VCard>();
- lua_getfield(L, -1, "photo");
- if (lua_isstring(L, -1)) {
- size_t len;
- const char* data = lua_tolstring(L, -1, &len);
- result->setPhoto(createByteArray(data, len));
- }
- lua_pop(L, 1);
-
- // TODO
-
- return result;
+std::shared_ptr<VCard> VCardConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<VCard> result = std::make_shared<VCard>();
+ lua_getfield(L, -1, "fullname");
+ if (lua_isstring(L, -1)) {
+ result->setFullName(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "familyname");
+ if (lua_isstring(L, -1)) {
+ result->setFamilyName(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "givenname");
+ if (lua_isstring(L, -1)) {
+ result->setGivenName(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "middlename");
+ if (lua_isstring(L, -1)) {
+ result->setMiddleName(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "prefix");
+ if (lua_isstring(L, -1)) {
+ result->setPrefix(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "suffix");
+ if (lua_isstring(L, -1)) {
+ result->setSuffix(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "nick");
+ if (lua_isstring(L, -1)) {
+ result->setNickname(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "description");
+ if (lua_isstring(L, -1)) {
+ result->setDescription(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "photo");
+ if (lua_isstring(L, -1)) {
+ size_t len;
+ const char* data = lua_tolstring(L, -1, &len);
+ result->setPhoto(createByteArray(data, len));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "phototype");
+ if (lua_isstring(L, -1)) {
+ result->setPhotoType(std::string(lua_tostring(L, -1)));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "birthday");
+ if (lua_isstring(L, -1)) {
+ result->setBirthday(stringToDateTime(std::string(lua_tostring(L, -1))));
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "email");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ VCard::EMailAddress emailAddress;
+ emailAddress.address = Lua::getStringField(L, -1, "address").get_value_or("");
+ if (boost::optional<bool> home = Lua::getBooleanField(L, -1, "home")) {
+ emailAddress.isHome = *home;
+ }
+ if (boost::optional<bool> work = Lua::getBooleanField(L, -1, "work")) {
+ emailAddress.isWork = *work;
+ }
+ if (boost::optional<bool> internet = Lua::getBooleanField(L, -1, "internet")) {
+ emailAddress.isInternet = *internet;
+ }
+ if (boost::optional<bool> preferred = Lua::getBooleanField(L, -1, "preferred")) {
+ emailAddress.isPreferred = *preferred;
+ }
+ if (boost::optional<bool> x400 = Lua::getBooleanField(L, -1, "x400")) {
+ emailAddress.isX400 = *x400;
+ }
+ result->addEMailAddress(emailAddress);
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "telephone");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ VCard::Telephone telephone;
+ telephone.number = Lua::getStringField(L, -1, "number").get_value_or("");
+ if (boost::optional<bool> home = Lua::getBooleanField(L, -1, "home")) {
+ telephone.isHome = *home;
+ }
+ if (boost::optional<bool> work = Lua::getBooleanField(L, -1, "work")) {
+ telephone.isWork = *work;
+ }
+ if (boost::optional<bool> voice = Lua::getBooleanField(L, -1, "voice")) {
+ telephone.isVoice = *voice;
+ }
+ if (boost::optional<bool> fax = Lua::getBooleanField(L, -1, "fax")) {
+ telephone.isFax = *fax;
+ }
+ if (boost::optional<bool> pager = Lua::getBooleanField(L, -1, "pager")) {
+ telephone.isPager = *pager;
+ }
+ if (boost::optional<bool> msg = Lua::getBooleanField(L, -1, "msg")) {
+ telephone.isMSG = *msg;
+ }
+ if (boost::optional<bool> cell = Lua::getBooleanField(L, -1, "cell")) {
+ telephone.isCell = *cell;
+ }
+ if (boost::optional<bool> video = Lua::getBooleanField(L, -1, "video")) {
+ telephone.isVideo = *video;
+ }
+ if (boost::optional<bool> bbs = Lua::getBooleanField(L, -1, "bbs")) {
+ telephone.isBBS = *bbs;
+ }
+ if (boost::optional<bool> modem = Lua::getBooleanField(L, -1, "modem")) {
+ telephone.isModem = *modem;
+ }
+ if (boost::optional<bool> isdn = Lua::getBooleanField(L, -1, "isdn")) {
+ telephone.isISDN = *isdn;
+ }
+ if (boost::optional<bool> pcs = Lua::getBooleanField(L, -1, "pcs")) {
+ telephone.isPCS = *pcs;
+ }
+ if (boost::optional<bool> preferred = Lua::getBooleanField(L, -1, "preferred")) {
+ telephone.isPreferred = *preferred;
+ }
+ result->addTelephone(telephone);
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "address");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ VCard::Address address;
+ address.poBox = Lua::getStringField(L, -1, "pobox").get_value_or("");
+ address.addressExtension = Lua::getStringField(L, -1, "extension").get_value_or("");
+ address.street = Lua::getStringField(L, -1, "street").get_value_or("");
+ address.locality = Lua::getStringField(L, -1, "locality").get_value_or("");
+ address.region = Lua::getStringField(L, -1, "region").get_value_or("");
+ address.postalCode = Lua::getStringField(L, -1, "postalcode").get_value_or("");
+ address.country = Lua::getStringField(L, -1, "country").get_value_or("");
+ if (boost::optional<bool> home = Lua::getBooleanField(L, -1, "home")) {
+ address.isHome = *home;
+ }
+ if (boost::optional<bool> work = Lua::getBooleanField(L, -1, "work")) {
+ address.isWork = *work;
+ }
+ if (boost::optional<bool> postal = Lua::getBooleanField(L, -1, "postal")) {
+ address.isPostal = *postal;
+ }
+ if (boost::optional<bool> parcel = Lua::getBooleanField(L, -1, "parcel")) {
+ address.isParcel = *parcel;
+ }
+ if (boost::optional<bool> preferred = Lua::getBooleanField(L, -1, "preferred")) {
+ address.isPreferred = *preferred;
+ }
+ if (boost::optional<bool> domestic = Lua::getBooleanField(L, -1, "domestic")) {
+ if (*domestic) {
+ address.deliveryType = VCard::DomesticDelivery;
+ }
+ }
+ if (boost::optional<bool> international = Lua::getBooleanField(L, -1, "international")) {
+ if (*international) {
+ address.deliveryType = VCard::InternationalDelivery;
+ }
+ }
+ result->addAddress(address);
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "addresslabel");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ VCard::AddressLabel addresslabel;
+ lua_getfield(L, -1, "lines");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ if (lua_isstring(L, -1)) {
+ addresslabel.lines.push_back(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ if (boost::optional<bool> home = Lua::getBooleanField(L, -1, "home")) {
+ addresslabel.isHome = *home;
+ }
+ if (boost::optional<bool> work = Lua::getBooleanField(L, -1, "work")) {
+ addresslabel.isWork = *work;
+ }
+ if (boost::optional<bool> postal = Lua::getBooleanField(L, -1, "postal")) {
+ addresslabel.isPostal = *postal;
+ }
+ if (boost::optional<bool> parcel = Lua::getBooleanField(L, -1, "parcel")) {
+ addresslabel.isParcel = *parcel;
+ }
+ if (boost::optional<bool> preferred = Lua::getBooleanField(L, -1, "preferred")) {
+ addresslabel.isPreferred = *preferred;
+ }
+ if (boost::optional<bool> domestic = Lua::getBooleanField(L, -1, "domestic")) {
+ if (*domestic) {
+ addresslabel.deliveryType = VCard::DomesticDelivery;
+ }
+ }
+ if (boost::optional<bool> international = Lua::getBooleanField(L, -1, "international")) {
+ if (*international) {
+ addresslabel.deliveryType = VCard::InternationalDelivery;
+ }
+ }
+ result->addAddressLabel(addresslabel);
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "organization");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ VCard::Organization organization;
+ organization.name = Lua::getStringField(L, -1, "name").get_value_or("");
+ lua_getfield(L, -1, "units");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ if (lua_isstring(L, -1)) {
+ organization.units.push_back(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ result->addOrganization(organization);
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "jid");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ if (lua_isstring(L, -1)) {
+ result->addJID(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "title");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ if (lua_isstring(L, -1)) {
+ result->addTitle(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "role");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ if (lua_isstring(L, -1)) {
+ result->addRole(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1); }
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "url");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); ) {
+ if (lua_isstring(L, -1)) {
+ result->addURL(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ return result;
}
-void VCardConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<VCard> payload) {
- lua_newtable(L);
- if (!payload->getPhoto().empty()) {
- lua_pushlstring(L,
- reinterpret_cast<const char*>(vecptr(payload->getPhoto())),
- payload->getPhoto().size());
- lua_setfield(L, -2, "photo");
- }
+void VCardConvertor::doConvertToLua(lua_State* L, std::shared_ptr<VCard> payload) {
+ lua_newtable(L);
+ if (!payload->getFullName().empty()) {
+ lua_pushstring(L, payload->getFullName().c_str());
+ lua_setfield(L, -2, "fullname");
+ }
+ if (!payload->getFamilyName().empty()) {
+ lua_pushstring(L, payload->getFamilyName().c_str());
+ lua_setfield(L, -2, "familyname");
+ }
+ if (!payload->getGivenName().empty()) {
+ lua_pushstring(L, payload->getGivenName().c_str());
+ lua_setfield(L, -2, "givenname");
+ }
+ if (!payload->getMiddleName().empty()) {
+ lua_pushstring(L, payload->getMiddleName().c_str());
+ lua_setfield(L, -2, "middlename");
+ }
+ if (!payload->getPrefix().empty()) {
+ lua_pushstring(L, payload->getPrefix().c_str());
+ lua_setfield(L, -2, "prefix");
+ }
+ if (!payload->getSuffix().empty()) {
+ lua_pushstring(L, payload->getSuffix().c_str());
+ lua_setfield(L, -2, "suffix");
+ }
+ if (!payload->getNickname().empty()) {
+ lua_pushstring(L, payload->getNickname().c_str());
+ lua_setfield(L, -2, "nick");
+ }
+ if (!payload->getDescription().empty()) {
+ lua_pushstring(L, payload->getDescription().c_str());
+ lua_setfield(L, -2, "description");
+ }
+ if (!payload->getPhoto().empty()) {
+ lua_pushlstring(L, reinterpret_cast<const char*>(vecptr(payload->getPhoto())), payload->getPhoto().size());
+ lua_setfield(L, -2, "photo");
+ }
+ if (!payload->getPhotoType().empty()) {
+ lua_pushstring(L, payload->getPhotoType().c_str());
+ lua_setfield(L, -2, "phototype");
+ }
+ if (!payload->getBirthday().is_not_a_date_time()) {
+ lua_pushstring(L, dateTimeToString(payload->getBirthday()).c_str());
+ lua_setfield(L, -2, "birthday");
+ }
+ const std::vector<VCard::EMailAddress>& emails = payload->getEMailAddresses();
+ if (!emails.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(emails.size()), 0);
+ for (size_t i = 0; i < emails.size(); ++i) {
+ lua_createtable(L, 0, 0);
+ if (!emails[i].address.empty()) {
+ lua_pushstring(L, emails[i].address.c_str());
+ lua_setfield(L, -2, "address");
+ }
+ if (emails[i].isHome) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "home");
+ }
+ if (emails[i].isWork) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "work");
+ }
+ if (emails[i].isInternet) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "internet");
+ }
+ if (emails[i].isPreferred) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "preferred");
+ }
+ if (emails[i].isX400) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "x400");
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setfield(L, -2, "email");
+ }
+ const std::vector<VCard::Telephone>& telephones = payload->getTelephones();
+ if (!telephones.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(telephones.size()), 0);
+ for (size_t i = 0; i < telephones.size(); ++i) {
+ lua_createtable(L, 0, 0);
+ if (!telephones[i].number.empty()) {
+ lua_pushstring(L, telephones[i].number.c_str());
+ lua_setfield(L, -2, "number");
+ }
+ if (telephones[i].isHome) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "home");
+ }
+ if (telephones[i].isWork) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "work");
+ }
+ if (telephones[i].isVoice) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "voice");
+ }
+ if (telephones[i].isFax) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "fax");
+ }
+ if (telephones[i].isPager) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "pager");
+ }
+ if (telephones[i].isMSG) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "msg");
+ }
+ if (telephones[i].isCell) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "cell");
+ }
+ if (telephones[i].isVideo) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "video");
+ }
+ if (telephones[i].isBBS) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "bbs");
+ }
+ if (telephones[i].isModem) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "modem");
+ }
+ if (telephones[i].isISDN) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "isdn");
+ }
+ if (telephones[i].isPCS) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "pcs");
+ }
+ if (telephones[i].isPreferred) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "preferred");
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setfield(L, -2, "telephone");
+ }
+ const std::vector<VCard::Address>& addresses = payload->getAddresses();
+ if (!addresses.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(addresses.size()), 0);
+ for (size_t i = 0; i < addresses.size(); ++i) {
+ lua_createtable(L, 0, 0);
+ if (!addresses[i].poBox.empty()) {
+ lua_pushstring(L, addresses[i].poBox.c_str());
+ lua_setfield(L, -2, "pobox");
+ }
+ if (!addresses[i].addressExtension.empty()) {
+ lua_pushstring(L, addresses[i].addressExtension.c_str());
+ lua_setfield(L, -2, "extension");
+ }
+ if (!addresses[i].street.empty()) {
+ lua_pushstring(L, addresses[i].street.c_str());
+ lua_setfield(L, -2, "street");
+ }
+ if (!addresses[i].locality.empty()) {
+ lua_pushstring(L, addresses[i].locality.c_str());
+ lua_setfield(L, -2, "locality");
+ }
+ if (!addresses[i].region.empty()) {
+ lua_pushstring(L, addresses[i].region.c_str());
+ lua_setfield(L, -2, "region");
+ }
+ if (!addresses[i].postalCode.empty()) {
+ lua_pushstring(L, addresses[i].postalCode.c_str());
+ lua_setfield(L, -2, "postalcode");
+ }
+ if (!addresses[i].country.empty()) {
+ lua_pushstring(L, addresses[i].country.c_str());
+ lua_setfield(L, -2, "country");
+ }
+ if (addresses[i].isHome) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "home");
+ }
+ if (addresses[i].isWork) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "work");
+ }
+ if (addresses[i].isPostal) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "postal");
+ }
+ if (addresses[i].isParcel) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "parcel");
+ }
+ if (addresses[i].isPreferred) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "preferred");
+ }
+ if (addresses[i].deliveryType == VCard::DomesticDelivery) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "domestic");
+ }
+ if (addresses[i].deliveryType == VCard::InternationalDelivery) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "international");
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setfield(L, -2, "address");
+ }
+ const std::vector<VCard::AddressLabel>& addresslabels = payload->getAddressLabels();
+ if (!addresslabels.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(addresslabels.size()), 0);
+ for (size_t i = 0; i < addresslabels.size(); ++i) {
+ lua_createtable(L, 0, 0);
+ const std::vector<std::string>& lines = addresslabels[i].lines;
+ if (!lines.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(addresslabels[i].lines.size()), 0);
+ for (size_t j = 0; j < lines.size(); ++j) {
+ if (!lines[j].empty()) {
+ lua_pushstring(L, lines[j].c_str());
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(j+1));
+ }
+ lua_setfield(L, -2, "lines");
+ }
+ if (addresslabels[i].isHome) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "home");
+ }
+ if (addresslabels[i].isWork) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "work");
+ }
+ if (addresslabels[i].isPostal) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "postal");
+ }
+ if (addresslabels[i].isParcel) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "parcel");
+ }
+ if (addresslabels[i].isPreferred) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "preferred");
+ }
+ if (addresslabels[i].deliveryType == VCard::DomesticDelivery) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "domestic");
+ }
+ if (addresslabels[i].deliveryType == VCard::InternationalDelivery) {
+ lua_pushboolean(L, true);
+ lua_setfield(L, -2, "international");
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setfield(L, -2, "addresslabel");
+ }
+ const std::vector<VCard::Organization>& organizations = payload->getOrganizations();
+ if (!organizations.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(organizations.size()), 0);
+ for (size_t i = 0; i < organizations.size(); ++i) {
+ lua_createtable(L, 0, 0);
+ if (!organizations[i].name.empty()) {
+ lua_pushstring(L, organizations[i].name.c_str());
+ lua_setfield(L, -2, "name");
+ }
+ const std::vector<std::string>& units = organizations[i].units;
+ if (!units.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(organizations[i].units.size()), 0);
+ for (size_t j = 0; j < units.size(); ++j) {
+ if (!units[j].empty()) {
+ lua_pushstring(L, units[j].c_str());
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(j+1));
+ }
+ lua_setfield(L, -2, "units");
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setfield(L, -2, "organization");
+ }
+ const std::vector<JID>& jids = payload->getJIDs();
+ if (!jids.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(jids.size()), 0);
+ for (size_t i = 0; i < jids.size(); ++i) {
+ if (!jids[i].toString().empty()) {
+ lua_pushstring(L, jids[i].toString().c_str());
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setfield(L, -2, "jid");
+ }
+ const std::vector<std::string>& titles = payload->getTitles();
+ if (!titles.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(titles.size()), 0);
+ for (size_t i = 0; i < titles.size(); ++i) {
+ if (!titles[i].empty()) {
+ lua_pushstring(L, titles[i].c_str());
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setfield(L, -2, "title");
+ }
+ const std::vector<std::string>& roles = payload->getRoles();
+ if (!roles.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(roles.size()), 0);
+ for (size_t i = 0; i < roles.size(); ++i) {
+ if (!roles[i].empty()) {
+ lua_pushstring(L, roles[i].c_str());
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setfield(L, -2, "role");
+ }
+ const std::vector<std::string>& urls = payload->getURLs();
+ if (!urls.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(urls.size()), 0);
+ for (size_t i = 0; i < urls.size(); ++i) {
+ if (!urls[i].empty()) {
+ lua_pushstring(L, urls[i].c_str());
+ }
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setfield(L, -2, "url");
+ }
}
diff --git a/Sluift/ElementConvertors/VCardConvertor.h b/Sluift/ElementConvertors/VCardConvertor.h
index 1cf4e9f..1d59c69 100644
--- a/Sluift/ElementConvertors/VCardConvertor.h
+++ b/Sluift/ElementConvertors/VCardConvertor.h
@@ -1,23 +1,22 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/VCard.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/VCard.h>
namespace Swift {
- class VCardConvertor : public GenericLuaElementConvertor<VCard> {
- public:
- VCardConvertor();
- virtual ~VCardConvertor();
+ class VCardConvertor : public GenericLuaElementConvertor<VCard> {
+ public:
+ VCardConvertor();
+ virtual ~VCardConvertor() override;
- virtual boost::shared_ptr<VCard> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<VCard>) SWIFTEN_OVERRIDE;
- };
+ virtual std::shared_ptr<VCard> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<VCard>) override;
+ };
}
diff --git a/Sluift/ElementConvertors/VCardUpdateConvertor.cpp b/Sluift/ElementConvertors/VCardUpdateConvertor.cpp
index 0010ca5..21c3d68 100644
--- a/Sluift/ElementConvertors/VCardUpdateConvertor.cpp
+++ b/Sluift/ElementConvertors/VCardUpdateConvertor.cpp
@@ -1,14 +1,17 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/ElementConvertors/VCardUpdateConvertor.h>
-#include <lua.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/numeric/conversion/cast.hpp>
+
+#include <lua.hpp>
+
#include <Sluift/Lua/LuaUtils.h>
using namespace Swift;
@@ -19,18 +22,18 @@ VCardUpdateConvertor::VCardUpdateConvertor() : GenericLuaElementConvertor<VCardU
VCardUpdateConvertor::~VCardUpdateConvertor() {
}
-boost::shared_ptr<VCardUpdate> VCardUpdateConvertor::doConvertFromLua(lua_State* L) {
- boost::shared_ptr<VCardUpdate> result = boost::make_shared<VCardUpdate>();
- if (boost::optional<std::string> value = Lua::getStringField(L, -1, "photo_hash")) {
- result->setPhotoHash(*value);
- }
- return result;
+std::shared_ptr<VCardUpdate> VCardUpdateConvertor::doConvertFromLua(lua_State* L) {
+ std::shared_ptr<VCardUpdate> result = std::make_shared<VCardUpdate>();
+ if (boost::optional<std::string> value = Lua::getStringField(L, -1, "photo_hash")) {
+ result->setPhotoHash(*value);
+ }
+ return result;
}
-void VCardUpdateConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<VCardUpdate> payload) {
- lua_newtable(L);
- if (!payload->getPhotoHash().empty()) {
- lua_pushstring(L, payload->getPhotoHash().c_str());
- lua_setfield(L, -2, "photo_hash");
- }
+void VCardUpdateConvertor::doConvertToLua(lua_State* L, std::shared_ptr<VCardUpdate> payload) {
+ lua_newtable(L);
+ if (!payload->getPhotoHash().empty()) {
+ lua_pushstring(L, payload->getPhotoHash().c_str());
+ lua_setfield(L, -2, "photo_hash");
+ }
}
diff --git a/Sluift/ElementConvertors/VCardUpdateConvertor.h b/Sluift/ElementConvertors/VCardUpdateConvertor.h
index e9bcd0f..19e42c6 100644
--- a/Sluift/ElementConvertors/VCardUpdateConvertor.h
+++ b/Sluift/ElementConvertors/VCardUpdateConvertor.h
@@ -1,23 +1,22 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <Swiften/Elements/VCardUpdate.h>
#include <Sluift/GenericLuaElementConvertor.h>
-#include <Swiften/Elements/VCardUpdate.h>
namespace Swift {
- class VCardUpdateConvertor : public GenericLuaElementConvertor<VCardUpdate> {
- public:
- VCardUpdateConvertor();
- virtual ~VCardUpdateConvertor();
+ class VCardUpdateConvertor : public GenericLuaElementConvertor<VCardUpdate> {
+ public:
+ VCardUpdateConvertor();
+ virtual ~VCardUpdateConvertor() override;
- virtual boost::shared_ptr<VCardUpdate> doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<VCardUpdate>) SWIFTEN_OVERRIDE;
- };
+ virtual std::shared_ptr<VCardUpdate> doConvertFromLua(lua_State*) override;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<VCardUpdate>) override;
+ };
}
diff --git a/Sluift/Examples/AdHocCommands.lua b/Sluift/Examples/AdHocCommands.lua
index 9e83f0c..f2f9cb4 100644
--- a/Sluift/Examples/AdHocCommands.lua
+++ b/Sluift/Examples/AdHocCommands.lua
@@ -1,7 +1,7 @@
--[[
- Copyright (c) 2013 Remko Tronçon
- Licensed under the GNU General Public License v3.
- See Documentation/Licenses/GPLv3.txt for more information.
+ Copyright (c) 2013 Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
--]]
--[[
diff --git a/Sluift/Examples/CollectVersions.lua b/Sluift/Examples/CollectVersions.lua
index 38bf6ac..42bcf86 100644
--- a/Sluift/Examples/CollectVersions.lua
+++ b/Sluift/Examples/CollectVersions.lua
@@ -1,8 +1,8 @@
--[[
- Copyright (c) 2010-2013 Remko Tronçon
- Licensed under the GNU General Public License v3.
- See Documentation/Licenses/GPLv3.txt for more information.
+ Copyright (c) 2010-2013 Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
This script logs into an XMPP server, and collects statistics about
the server software of all contacts in your roster
diff --git a/Sluift/Examples/Component.lua b/Sluift/Examples/Component.lua
new file mode 100644
index 0000000..b8a71f5
--- /dev/null
+++ b/Sluift/Examples/Component.lua
@@ -0,0 +1,55 @@
+--[[
+ Copyright (c) 2014 Edwin Mons and Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
+--]]
+
+--[[
+
+ Component example.
+
+ This script connects to an XMPP server as a component, and listens to
+ messages received.
+
+ The following environment variables are used:
+ * SLUIFT_COMP_DOMAIN: Component domain name
+ * SLUIFT_COMP_SECRET: Component secret
+ * SLUIFT_COMP_HOST: XMPP server host name
+ * SLUIFT_COMP_PORT: XMPP server component port
+ * SLUIFT_JID: Recipient of presence and initial message
+ * SLUIFT_DEBUG: Sets whether debugging should be turned on
+
+--]]
+
+require "sluift"
+
+sluift.debug = os.getenv("SLUIFT_DEBUG") or false
+
+config = {
+ domain = os.getenv('SLUIFT_COMP_DOMAIN'),
+ secret = os.getenv('SLUIFT_COMP_SECRET'),
+ host = os.getenv('SLUIFT_COMP_HOST'),
+ port = os.getenv('SLUIFT_COMP_PORT'),
+ jid = os.getenv('SLUIFT_JID')
+}
+
+-- Create the component, and connect
+comp = sluift.new_component(config.domain, config.secret);
+comp:connect(config)
+
+-- Send initial presence and message
+-- Assumes the remote client already has this component user on his roster
+comp:send_presence{from='root@' .. config.domain, to=config.jid}
+comp:send_message{from='root@' .. config.domain, to=config.jid, body='Component active'}
+
+-- Listen for messages, and reply if one is received
+for message in comp:messages() do
+ print("Received a message from " .. message.from)
+ comp:send_message{to=message.from, from=message.to, body='I received: ' .. message['body']}
+
+ -- Send out a ping to demonstrate we can do more than just send messages
+ comp:get{to=message.from, query='<ping xmlns="urn:xmpp:ping"/>'}
+end
+
+comp:disconnect()
+
diff --git a/Sluift/Examples/ContactsMap.lua b/Sluift/Examples/ContactsMap.lua
index d248dc7..573eb9f 100644
--- a/Sluift/Examples/ContactsMap.lua
+++ b/Sluift/Examples/ContactsMap.lua
@@ -1,7 +1,7 @@
--[[
- Copyright (c) 2013 Remko Tronçon
- Licensed under the GNU General Public License v3.
- See Documentation/Licenses/GPLv3.txt for more information.
+ Copyright (c) 2013 Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
--]]
--[[
diff --git a/Sluift/Examples/EchoBot.lua b/Sluift/Examples/EchoBot.lua
index fc495c4..81c2fa3 100644
--- a/Sluift/Examples/EchoBot.lua
+++ b/Sluift/Examples/EchoBot.lua
@@ -1,7 +1,7 @@
--[[
- Copyright (c) 2010-2013 Remko Tronçon
- Licensed under the GNU General Public License v3.
- See Documentation/Licenses/GPLv3.txt for more information.
+ Copyright (c) 2010-2013 Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
--]]
--[[
diff --git a/Sluift/Examples/EchoBot_With.lua b/Sluift/Examples/EchoBot_With.lua
new file mode 100644
index 0000000..2260deb
--- /dev/null
+++ b/Sluift/Examples/EchoBot_With.lua
@@ -0,0 +1,32 @@
+--[[
+ Copyright (c) 2010-2013 Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
+--]]
+
+--[[
+
+ Alternative version of EchoBot that uses with()
+
+ This script logs into an XMPP server, sends initial presence,
+ and then waits for incoming messages, and echoes them back.
+
+ The following environment variables are used:
+ * SLUIFT_JID, SWIFT_PASS: JID and password to log in with
+ * SLUIFT_DEBUG: Sets whether debugging should be turned on
+
+--]]
+
+require "sluift"
+
+sluift.debug = os.getenv("SLUIFT_DEBUG") or false
+
+client = sluift.new_client(os.getenv("SLUIFT_JID"), os.getenv("SLUIFT_PASS"))
+sluift.with(client, function ()
+ connect()
+ set_version{name = "EchoBot", version = "0.1"}
+ send_presence("Send me a message")
+ for message in messages() do
+ send_message{to = message["from"], body = message["body"]}
+ end
+end)
diff --git a/Sluift/Examples/Login.lua b/Sluift/Examples/Login.lua
index c43b72a..1d70954 100644
--- a/Sluift/Examples/Login.lua
+++ b/Sluift/Examples/Login.lua
@@ -1,7 +1,7 @@
--[[
- Copyright (c) 2010-2013 Remko Tronçon
- Licensed under the GNU General Public License v3.
- See Documentation/Licenses/GPLv3.txt for more information.
+ Copyright (c) 2010-2014 Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
--]]
--[[
@@ -21,7 +21,7 @@ sluift.debug = os.getenv("SLUIFT_DEBUG") or false
print("Connecting " .. os.getenv("SLUIFT_JID") .. " ...")
c = sluift.new_client(os.getenv("SLUIFT_JID"), os.getenv("SLUIFT_PASS"))
-c:set_options({compress = false, tls = false})
+c:set_options{compress = false, tls = false}
c:connect()
c:send_presence("")
diff --git a/Sluift/Examples/MAMRSM.lua b/Sluift/Examples/MAMRSM.lua
new file mode 100644
index 0000000..c8a1e85
--- /dev/null
+++ b/Sluift/Examples/MAMRSM.lua
@@ -0,0 +1,23 @@
+-- A query using Result Set Management
+-- Usage: ./sluift MAMRSM.lua <jid> <password> <query_dest> <max_results>
+
+sluift.debug = true
+
+c = sluift.new_client(arg[1], arg[2])
+
+c:connect();
+
+query = {
+ result_set={max_items=arg[4]}
+}
+
+c:set_mam{mam=query, to=arg[3]}
+
+c:for_each_message(function(e)
+ if e.payloads[1].tag == 'fin' then return true end
+ if e.payloads[1]._type == 'mam_result' then
+ print(e.payloads[1].payload.stanza.payloads[1].text)
+ end
+end)
+
+c:disconnect()
diff --git a/Sluift/Examples/MAMRSMPage.lua b/Sluift/Examples/MAMRSMPage.lua
new file mode 100644
index 0000000..cb3307c
--- /dev/null
+++ b/Sluift/Examples/MAMRSMPage.lua
@@ -0,0 +1,36 @@
+-- A page query using Result Set Management
+-- Usage: ./sluift MAMRSMPage.lua <jid> <password> <query_dest> <pages>
+
+sluift.debug = true
+
+c = sluift.new_client(arg[1], arg[2])
+
+c:set_options{compress = false, tls = false}
+
+c:connect();
+
+query = {
+ result_set={max_items=5}
+}
+
+done = false
+page = 0
+while not done and page < tonumber(arg[4]) do
+ page = page + 1
+ c:set_mam{mam=query, to=arg[3]}
+ c:for_each_message(function(e)
+ if e.payloads[1].tag == 'fin' then
+ if e.payloads[2].last_id then
+ query.result_set.after = e.payloads[2].last_id
+ else
+ done = true
+ end
+ return true
+ end
+ if e.payloads[1]._type == 'mam_result' then
+ print(e.payloads[1].payload.stanza.payloads[1].text)
+ end
+ end)
+end
+
+c:disconnect()
diff --git a/Sluift/Examples/MAMSimple.lua b/Sluift/Examples/MAMSimple.lua
new file mode 100644
index 0000000..13ab1a0
--- /dev/null
+++ b/Sluift/Examples/MAMSimple.lua
@@ -0,0 +1,19 @@
+-- Querying the archive for messages
+-- Usage: ./sluift MAMSimple.lua <jid> <password> <query_dest>
+
+sluift.debug = true
+
+c = sluift.new_client(arg[1], arg[2])
+
+c:connect();
+
+c:set_mam{mam={}, to=arg[3]}
+
+c:for_each_message(function(e)
+ if e.payloads[1].tag == 'fin' then return true end
+ if e.payloads[1]._type == 'mam_result' then
+ print(e.payloads[1].payload.stanza.payloads[1].text)
+ end
+end)
+
+c:disconnect()
diff --git a/Sluift/Examples/MAMSupportedFields.lua b/Sluift/Examples/MAMSupportedFields.lua
new file mode 100644
index 0000000..0417924
--- /dev/null
+++ b/Sluift/Examples/MAMSupportedFields.lua
@@ -0,0 +1,18 @@
+-- Retrieving form fields
+-- Usage: ./sluift MAMSupportedFields.lua <jid> <password>
+
+sluift.debug = true
+
+c = sluift.new_client(arg[1], arg[2])
+
+c:connect();
+
+mam_result = c:get_mam{}
+
+for i=1,#mam_result.form.fields do
+ if mam_result.form.fields[i].type ~= "hidden" then
+ print("Server supports: " .. mam_result.form.fields[i].name)
+ end
+end
+
+c:disconnect()
diff --git a/Sluift/Examples/MAMUser.lua b/Sluift/Examples/MAMUser.lua
new file mode 100644
index 0000000..e4a7c28
--- /dev/null
+++ b/Sluift/Examples/MAMUser.lua
@@ -0,0 +1,25 @@
+-- Querying for all messages to/from a particular JID
+-- Usage: ./sluift MAMUser.lua <jid> <password> <query_dest> <query_jid>
+
+sluift.debug = true
+
+c = sluift.new_client(arg[1], arg[2])
+
+c:connect();
+
+fields = {
+ with = arg[4]
+}
+
+query_form = sluift.create_form{fields, form_type="urn:xmpp:mam:0"}
+
+c:set_mam{mam={form=query_form}, to=arg[3]}
+
+c:for_each_message(function(e)
+ if e.payloads[1].tag == 'fin' then return true end
+ if e.payloads[1]._type == 'mam_result' then
+ print(e.payloads[1].payload.stanza.payloads[1].text)
+ end
+end)
+
+c:disconnect()
diff --git a/Sluift/Examples/PEPListener.lua b/Sluift/Examples/PEPListener.lua
index f196f84..416ae52 100644
--- a/Sluift/Examples/PEPListener.lua
+++ b/Sluift/Examples/PEPListener.lua
@@ -1,7 +1,7 @@
--[[
- Copyright (c) 2010-2013 Remko Tronçon
- Licensed under the GNU General Public License v3.
- See Documentation/Licenses/GPLv3.txt for more information.
+ Copyright (c) 2010-2013 Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
--]]
--[[
diff --git a/Sluift/Examples/RemoveUnreachableContacts.lua b/Sluift/Examples/RemoveUnreachableContacts.lua
index a202e62..65d64b9 100644
--- a/Sluift/Examples/RemoveUnreachableContacts.lua
+++ b/Sluift/Examples/RemoveUnreachableContacts.lua
@@ -1,7 +1,7 @@
--[[
- Copyright (c) 2010-2013 Remko Tronçon
- Licensed under the GNU General Public License v3.
- See Documentation/Licenses/GPLv3.txt for more information.
+ Copyright (c) 2010-2013 Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
--]]
--[[
diff --git a/Sluift/Examples/SendReference.lua b/Sluift/Examples/SendReference.lua
new file mode 100644
index 0000000..2e60182
--- /dev/null
+++ b/Sluift/Examples/SendReference.lua
@@ -0,0 +1,74 @@
+#!/usr/bin/env sluift --
+
+-- This is an example of sending a custom payload, a XEP-0372 reference in this
+-- case.
+--
+-- Running this requires a sluift binary somewhere in the PATH. Alternatively,
+-- you can feed this to sluift, or to a Lua that has sluift.so in its library
+-- path.
+
+require("sluift")
+
+DEFAULT_URI = "http://example.com/kitten.jpg"
+
+function usage(err)
+ print("Usage: SendReference.lua jid [tojid] [datauri]")
+ print()
+ print("This tool will log in as jid, and send a reference to tojid. If no tojid")
+ print("is provided, a message to itself is sent. The datauri defaults to")
+ print(DEFAULT_URI .. ", but can be overridden.")
+
+ if err then
+ print("")
+ print("Error: " .. err)
+ end
+ os.exit(1)
+end
+
+function get_password(prompt)
+ if prompt then
+ io.write(prompt)
+ end
+ local stty_ret = os.execute("stty -echo 2>/dev/null")
+ if stty_ret then
+ io.write("\027[8m")
+ end
+ local ok, pass = pcall(io.read, "*l")
+ if stty_ret then
+ io.write("\027[m")
+ else
+ os.execute("stty echo")
+ end
+ io.write("\n");
+ if ok then
+ return pass
+ end
+end
+
+if #arg < 1 then
+ usage("no jid specified")
+end
+jid = arg[1]
+password = os.getenv("XMPP_PASSWORD") or get_password("Password: ")
+tojid = #arg > 1 and arg[2] or jid
+datauri = #arg > 2 and arg[3] or DEFAULT_URI
+
+sluift.debug = 1
+sluift.with(sluift.new_client(jid, password), function()
+ options = { host=os.getenv("XMPP_HOST"), port=os.getenv("XMPP_PORT") }
+ connect(options)
+ reference = {
+ ['_type'] = 'dom',
+ ['tag'] = 'reference',
+ ['ns'] = 'urn:xmpp:reference:0',
+ ['attributes'] = {
+ { ['name'] = 'type', ['value'] = 'data' },
+ { ['name'] = 'uri', ['value'] = datauri },
+ { ['name'] = 'mimeType', ['value'] = arg[4] },
+ { ['name'] = 'begin', ['value'] = arg[5] },
+ { ['name'] = 'end', ['value'] = arg[6] }
+ },
+ }
+ send_message{to=tojid, body="Check out this data!", payloads={reference}}
+ disconnect()
+end)
diff --git a/Sluift/Examples/Tunes.lua b/Sluift/Examples/Tunes.lua
new file mode 100644
index 0000000..c645583
--- /dev/null
+++ b/Sluift/Examples/Tunes.lua
@@ -0,0 +1,68 @@
+--[[
+ Copyright (c) 2014 Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
+--]]
+
+--[[
+
+ Tune Publisher/Listener
+
+ Publishes the currently playing tune in iTunes, and prints
+ the playing tunes of contacts
+
+ The following environment variables are used:
+ - SLUIFT_JID, SWIFT_PASS: JID and password to log in with
+ - SLUIFT_DEBUG: Sets whether debugging should be turned on
+
+--]]
+
+require 'sluift'
+
+sluift.debug = os.getenv('SLUIFT_DEBUG') or false
+
+client = sluift.new_client(os.getenv('SLUIFT_JID'), os.getenv('SLUIFT_PASS'))
+client:connect(function (c)
+ -- Send initial presence (with service discovery information)
+ c:set_caps_node('http://swift.im/Tunes')
+ c:set_disco_info{
+ identities = {{name = 'Tunes'}},
+ features = {
+ sluift.disco.features.DISCO_INFO,
+ sluift.disco.features.USER_TUNE .. '+notify'
+ }}
+ c:send_presence{priority = -1}
+
+ local pubsub = c:pubsub(sluift.jid.to_bare(c:jid()))
+ local tunes_node = pubsub:node(sluift.disco.features.USER_TUNE)
+ local current_track = nil
+ while true do
+ -- Publish currently playing tune
+ if sluift.itunes then
+ local track = sluift.itunes.get_current_track()
+ if track ~= current_track then
+ tunes_node:publish{item = {
+ _type = 'user_tune',
+ title = track.name,
+ artist = track.artist,
+ track = track.track_number,
+ source = track.album,
+ length = track.length,
+ rating = track.rating and track.rating / 10 or nil
+ }}
+ current_track = track
+ end
+ end
+
+ -- Print incoming events for a while
+ for event in c:pubsub_events{timeout = 1000} do
+ if event._type == 'pubsub_event_items'
+ and event.node == sluift.disco.features.USER_TUNE
+ and event.item.title then
+ print(event.from .. ' is playing "'
+ .. (event.item.artist or '<Unknown Artist>') .. ' - '
+ .. event.item.title .. '"')
+ end
+ end
+ end
+end)
diff --git a/Sluift/Examples/Wonderland.lua b/Sluift/Examples/Wonderland.lua
index 426ec07..5104830 100755
--- a/Sluift/Examples/Wonderland.lua
+++ b/Sluift/Examples/Wonderland.lua
@@ -1,7 +1,7 @@
--
--- Copyright (c) 2011 Remko Tronçon
--- Licensed under the GNU General Public License v3.
--- See Documentation/Licenses/GPLv3.txt for more information.
+-- Copyright (c) 2011 Isode Limited.
+-- All rights reserved.
+-- See the COPYING file for more information.
--
-- This script creates the wonderland world example.
diff --git a/Sluift/GenerateDocumentation.lua b/Sluift/GenerateDocumentation.lua
new file mode 100644
index 0000000..ce9c9a9
--- /dev/null
+++ b/Sluift/GenerateDocumentation.lua
@@ -0,0 +1,90 @@
+--[[
+ Copyright (c) 2013 Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
+--]]
+
+require "sluift"
+
+local function get_anchor(...)
+ return table.concat({...}, "-")
+end
+
+local function convert_links(text)
+ result = text:gsub("(@{(%w*)})", "[`%2`](#%2)")
+ return result
+end
+
+local function add_help(help, document, class, level)
+ -- Collect help of children
+ local methods = {}
+ for _, method in pairs(help.methods or {}) do
+ local description
+ local method_help = sluift.get_help(method.ref)
+ if method_help and method_help.description then
+ description = method_help.synopsis
+ end
+ methods[#methods+1] = { name = method.name, description = description, ref = method.ref }
+ end
+ local fields = sluift.copy(help.fields or {})
+
+ table.sort(methods, function (a, b) return (a.name or "") < (b.name or "") end)
+ table.sort(fields, function (a, b) return (a.name or "") < (b.name or "") end)
+
+ local classes = {}
+ for _, class in pairs(help.classes or {}) do
+ classes[#classes+1] = { name = class, description = sluift.get_help(class).synopsis }
+ end
+
+ table.insert(document, convert_links(help.description or ""))
+ for _, p in ipairs({
+ {"Parameters", help.parameters}, {"Options", help.options}, {"Fields", fields}, {"Methods", methods}}) do
+ if p[2] and next(p[2]) ~= nil then
+ table.insert(document, "\n\n" .. level .. " " .. p[1] .. "\n")
+ for _, parameter in ipairs(p[2]) do
+ parameter_name = "`" .. parameter.name .. "`"
+ if p[1] == "Methods" then
+ parameter_name = "[" .. parameter_name .. "](#" .. get_anchor(class, parameter.name) .. ")"
+ end
+ if parameter.description then
+ table.insert(document, "- " .. parameter_name .. ": " .. convert_links(parameter.description))
+ else
+ table.insert(document, "- " .. parameter_name)
+ end
+ end
+ if p[1] == "Methods" then
+ for _, method in ipairs(p[2]) do
+ table.insert(document, "\n#### <a name=\"" .. get_anchor(class, method.name) .. "\"></a> `" .. method.name .. "`\n")
+ if method.ref then
+ add_help(sluift.get_help(method.ref) or {}, document, class, level .. "#")
+ end
+ end
+ end
+ end
+ end
+end
+
+local document = {}
+
+table.insert(document, [[
+# Sluift
+
+This document describes the API of the `sluift` module.
+
+The entry points of Sluift are in the `sluift` module, described below.
+
+## `sluift` module
+]])
+
+help = sluift.get_help(sluift)
+add_help(help, document, "sluift", "###")
+for _, class in pairs(help.classes) do
+ class_help = sluift.get_help(class)
+ if class_help then
+ table.insert(document, "\n## <a name=\"" .. class .. "\"></a> `" .. class .. "` class\n")
+ add_help(class_help, document, class, "###")
+ end
+end
+
+document = table.concat(document, "\n") .. "\n"
+print(document)
diff --git a/Sluift/GenericLuaElementConvertor.h b/Sluift/GenericLuaElementConvertor.h
index afad481..4e52d9e 100644
--- a/Sluift/GenericLuaElementConvertor.h
+++ b/Sluift/GenericLuaElementConvertor.h
@@ -1,54 +1,54 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <lua.hpp>
#include <string>
-#include <Swiften/Base/Override.h>
-#include <Sluift/LuaElementConvertor.h>
+#include <lua.hpp>
+
#include <Sluift/Lua/Check.h>
#include <Sluift/Lua/LuaUtils.h>
+#include <Sluift/LuaElementConvertor.h>
namespace Swift {
- template<typename T>
- class GenericLuaElementConvertor : public LuaElementConvertor {
- public:
- GenericLuaElementConvertor(const std::string& type) : type(type) {
- }
-
- virtual ~GenericLuaElementConvertor() {}
-
- virtual boost::shared_ptr<Payload> convertFromLua(lua_State* L, int index, const std::string& payloadType) SWIFTEN_OVERRIDE {
- if (payloadType == type) {
- Lua::checkType(L, index, LUA_TTABLE);
- lua_pushvalue(L, index);
- boost::shared_ptr<Payload> result = doConvertFromLua(L);
- lua_pop(L, 1);
- return result;
- }
- return boost::shared_ptr<Payload>();
- }
-
- virtual boost::optional<std::string> convertToLua(
- lua_State* L, boost::shared_ptr<Payload> payload) SWIFTEN_OVERRIDE {
- if (boost::shared_ptr<T> actualPayload = boost::dynamic_pointer_cast<T>(payload)) {
- doConvertToLua(L, actualPayload);
- assert(lua_type(L, -1) == LUA_TTABLE);
- return type;
- }
- return NO_RESULT;
- }
-
- protected:
- virtual boost::shared_ptr<T> doConvertFromLua(lua_State*) = 0;
- virtual void doConvertToLua(lua_State*, boost::shared_ptr<T>) = 0;
-
- private:
- std::string type;
- };
+ template<typename T>
+ class GenericLuaElementConvertor : public LuaElementConvertor {
+ public:
+ GenericLuaElementConvertor(const std::string& type) : type(type) {
+ }
+
+ virtual ~GenericLuaElementConvertor() override {}
+
+ virtual std::shared_ptr<Element> convertFromLua(lua_State* L, int index, const std::string& payloadType) override {
+ if (payloadType == type) {
+ Lua::checkType(L, index, LUA_TTABLE);
+ lua_pushvalue(L, index);
+ std::shared_ptr<Element> result = doConvertFromLua(L);
+ lua_pop(L, 1);
+ return result;
+ }
+ return std::shared_ptr<Element>();
+ }
+
+ virtual boost::optional<std::string> convertToLua(
+ lua_State* L, std::shared_ptr<Element> payload) override {
+ if (std::shared_ptr<T> actualPayload = std::dynamic_pointer_cast<T>(payload)) {
+ doConvertToLua(L, actualPayload);
+ assert(lua_type(L, -1) == LUA_TTABLE);
+ return type;
+ }
+ return NO_RESULT;
+ }
+
+ protected:
+ virtual std::shared_ptr<T> doConvertFromLua(lua_State*) = 0;
+ virtual void doConvertToLua(lua_State*, std::shared_ptr<T>) = 0;
+
+ private:
+ std::string type;
+ };
}
diff --git a/Sluift/Helpers.cpp b/Sluift/Helpers.cpp
new file mode 100644
index 0000000..97d14ad
--- /dev/null
+++ b/Sluift/Helpers.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2013-2015 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/Helpers.h>
+
+#include <Swiften/Client/ClientError.h>
+#include <Swiften/Component/ComponentError.h>
+
+using namespace Swift;
+
+std::string Swift::getErrorString(const ClientError& error) {
+ std::string reason = "Disconnected: ";
+ switch(error.getType()) {
+ case ClientError::UnknownError: reason += "Unknown Error"; break;
+ case ClientError::ConnectionError: reason += "Error connecting to server"; break;
+ case ClientError::ConnectionReadError: reason += "Error while receiving server data"; break;
+ case ClientError::ConnectionWriteError: reason += "Error while sending data to the server"; break;
+ case ClientError::XMLError: reason += "Error parsing server data"; break;
+ case ClientError::AuthenticationFailedError: reason += "Login/password invalid"; break;
+ case ClientError::UnexpectedElementError: reason += "Unexpected response"; break;
+ case ClientError::DomainNameResolveError: reason += "Unable to find server"; break;
+ case ClientError::CompressionFailedError: reason += "Error while compressing stream"; break;
+ case ClientError::ServerVerificationFailedError: reason += "Server verification failed"; break;
+ case ClientError::NoSupportedAuthMechanismsError: reason += "Authentication mechanisms not supported"; break;
+ case ClientError::ResourceBindError: reason += "Error binding resource"; break;
+ case ClientError::RevokedError: reason += "Certificate got revoked"; break;
+ case ClientError::RevocationCheckFailedError: reason += "Failed to do revokation check"; break;
+ case ClientError::SessionStartError: reason += "Error starting session"; break;
+ case ClientError::StreamError: reason += "Stream error"; break;
+ case ClientError::TLSError: reason += "Encryption error"; break;
+ case ClientError::ClientCertificateLoadError: reason += "Error loading certificate (Invalid file or password?)"; break;
+ case ClientError::ClientCertificateError: reason += "Certificate not authorized"; break;
+ case ClientError::UnknownCertificateError: reason += "Unknown certificate"; break;
+ case ClientError::CertificateCardRemoved: reason += "Certificate card removed"; break;
+ case ClientError::CertificateExpiredError: reason += "Certificate has expired"; break;
+ case ClientError::CertificateNotYetValidError: reason += "Certificate is not yet valid"; break;
+ case ClientError::CertificateSelfSignedError: reason += "Certificate is self-signed"; break;
+ case ClientError::CertificateRejectedError: reason += "Certificate has been rejected"; break;
+ case ClientError::CertificateUntrustedError: reason += "Certificate is not trusted"; break;
+ case ClientError::InvalidCertificatePurposeError: reason += "Certificate cannot be used for encrypting your connection"; break;
+ case ClientError::CertificatePathLengthExceededError: reason += "Certificate path length constraint exceeded"; break;
+ case ClientError::InvalidCertificateSignatureError: reason += "Invalid certificate signature"; break;
+ case ClientError::InvalidCAError: reason += "Invalid Certificate Authority"; break;
+ case ClientError::InvalidServerIdentityError: reason += "Certificate does not match the host identity"; break;
+ }
+ return reason;
+}
+
+std::string Swift::getErrorString(const ComponentError& error) {
+ std::string reason = "Disconnected: ";
+ switch(error.getType()) {
+ case ComponentError::UnknownError: reason += "Unknown Error"; break;
+ case ComponentError::ConnectionError: reason += "Error connecting to server"; break;
+ case ComponentError::ConnectionReadError: reason += "Error while receiving server data"; break;
+ case ComponentError::ConnectionWriteError: reason += "Error while sending data to the server"; break;
+ case ComponentError::XMLError: reason += "Error parsing server data"; break;
+ case ComponentError::AuthenticationFailedError: reason += "Login/password invalid"; break;
+ case ComponentError::UnexpectedElementError: reason += "Unexpected response"; break;
+ }
+ return reason;
+}
+
diff --git a/Sluift/Helpers.h b/Sluift/Helpers.h
new file mode 100644
index 0000000..41bfc97
--- /dev/null
+++ b/Sluift/Helpers.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <Swiften/Base/API.h>
+
+namespace Swift {
+ class ClientError;
+ class ComponentError;
+
+ std::string getErrorString(const ClientError& error);
+ std::string getErrorString(const ComponentError& error);
+}
diff --git a/Sluift/ITunesInterface.h b/Sluift/ITunesInterface.h
new file mode 100644
index 0000000..d44dcb1
--- /dev/null
+++ b/Sluift/ITunesInterface.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include <boost/optional/optional.hpp>
+
+#include <Swiften/Base/API.h>
+
+namespace Swift {
+ class SWIFTEN_API ITunesInterface {
+ public:
+ struct Track {
+ std::string name;
+ std::string artist;
+ std::string album;
+ long trackNumber;
+ double duration;
+ long rating;
+ };
+
+ ITunesInterface();
+ virtual ~ITunesInterface();
+
+ boost::optional<Track> getCurrentTrack() const;
+
+ private:
+ bool haveApplication() const;
+
+ private:
+ struct Private;
+ const std::unique_ptr<Private> p;
+ };
+}
diff --git a/Sluift/ITunesInterface.mm b/Sluift/ITunesInterface.mm
new file mode 100644
index 0000000..33cf1ca
--- /dev/null
+++ b/Sluift/ITunesInterface.mm
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2014-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/ITunesInterface.h>
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wfour-char-constants"
+#import <Sluift/iTunes.h>
+#pragma clang diagnostic pop
+#include <ScriptingBridge/ScriptingBridge.h>
+
+#include <memory>
+#include <boost/optional.hpp>
+#include <SwifTools/Cocoa/CocoaUtil.h>
+
+using namespace Swift;
+
+struct ITunesInterface::Private {
+ Private() : iTunes(nil) {
+ }
+
+ iTunesApplication* iTunes;
+};
+
+ITunesInterface::ITunesInterface() : p(new Private()) {
+}
+
+ITunesInterface::~ITunesInterface() {
+}
+
+boost::optional<ITunesInterface::Track> ITunesInterface::getCurrentTrack() const {
+ if (!haveApplication()) {
+ return boost::optional<ITunesInterface::Track>();
+ }
+ iTunesTrack* currentTrack = p->iTunes.currentTrack;
+ if (!currentTrack) {
+ return boost::optional<ITunesInterface::Track>();
+ }
+ ITunesInterface::Track result;
+ result.name = ns2StdString(currentTrack.name);
+ result.artist = ns2StdString(currentTrack.artist);
+ result.album = ns2StdString(currentTrack.album);
+ result.trackNumber = currentTrack.trackNumber;
+ result.duration = currentTrack.duration;
+ result.rating = currentTrack.rating;
+ return result;
+}
+
+
+bool ITunesInterface::haveApplication() const {
+ if (!p->iTunes) {
+ p->iTunes = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];
+ }
+ return p->iTunes != nil && [p->iTunes isRunning];
+}
diff --git a/Sluift/Lua/Check.cpp b/Sluift/Lua/Check.cpp
index cfb726a..b956623 100644
--- a/Sluift/Lua/Check.cpp
+++ b/Sluift/Lua/Check.cpp
@@ -1,60 +1,68 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/Lua/Check.h>
-#include <boost/numeric/conversion/cast.hpp>
-#include <iostream>
#include <sstream>
+
+#include <boost/numeric/conversion/cast.hpp>
+
#include <lua.hpp>
+#include <Swiften/Base/ByteArray.h>
+
#include <Sluift/Lua/Exception.h>
using namespace Swift;
static std::string getArgTypeError(lua_State* L, int arg, int tag) {
- std::ostringstream s;
- s << "Arg " << arg << ": expected " << lua_typename(L, tag) << ", got " << luaL_typename(L, arg);
- return s.str();
+ std::ostringstream s;
+ s << "Arg " << arg << ": expected " << lua_typename(L, tag) << ", got " << luaL_typename(L, arg);
+ return s.str();
}
void Lua::checkType(lua_State* L, int arg, int type) {
- if (lua_type(L, arg) != type) {
- throw Lua::Exception(getArgTypeError(L, arg, type));
- }
+ if (lua_type(L, arg) != type) {
+ throw Lua::Exception(getArgTypeError(L, arg, type));
+ }
}
int Lua::checkIntNumber(lua_State* L, int arg) {
- if (!lua_isnumber(L, arg)) {
- throw Lua::Exception(getArgTypeError(L, arg, LUA_TNUMBER));
- }
- return boost::numeric_cast<int>(lua_tonumber(L, arg));
+ if (!lua_isnumber(L, arg)) {
+ throw Lua::Exception(getArgTypeError(L, arg, LUA_TNUMBER));
+ }
+ return boost::numeric_cast<int>(lua_tonumber(L, arg));
}
std::string Lua::checkString(lua_State* L, int arg) {
- const char *s = lua_tolstring(L, arg, NULL);
- if (!s) {
- throw Lua::Exception(getArgTypeError(L, arg, LUA_TSTRING));
- }
- return std::string(s);
+ const char *s = lua_tolstring(L, arg, nullptr);
+ if (!s) {
+ throw Lua::Exception(getArgTypeError(L, arg, LUA_TSTRING));
+ }
+ return std::string(s);
+}
+
+ByteArray Lua::checkByteArray(lua_State* L, int arg) {
+ size_t len;
+ const char *s = lua_tolstring(L, arg, &len);
+ if (!s) {
+ throw Lua::Exception(getArgTypeError(L, arg, LUA_TSTRING));
+ }
+ return createByteArray(s, len);
}
-void* Lua::checkUserDataRaw(lua_State* L, int arg, const char* tableName) {
- void* userData = lua_touserdata(L, arg);
- if (!userData) {
- throw Lua::Exception(getArgTypeError(L, arg, LUA_TUSERDATA));
- }
- if (!lua_getmetatable(L, arg)) {
- throw Lua::Exception(getArgTypeError(L, arg, LUA_TUSERDATA));
- }
- lua_getfield(L, LUA_REGISTRYINDEX, tableName);
- if (!lua_rawequal(L, -1, -2)) {
- throw Lua::Exception(getArgTypeError(L, arg, LUA_TUSERDATA));
- }
- lua_pop(L, 2);
- return userData;
+void* Lua::checkUserDataRaw(lua_State* L, int arg) {
+ void* userData = lua_touserdata(L, arg);
+ if (!userData) {
+ throw Lua::Exception(getArgTypeError(L, arg, LUA_TUSERDATA));
+ }
+ if (!lua_getmetatable(L, arg)) {
+ throw Lua::Exception(getArgTypeError(L, arg, LUA_TUSERDATA));
+ }
+ lua_pop(L, 1);
+ return userData;
}
diff --git a/Sluift/Lua/Check.h b/Sluift/Lua/Check.h
index a569826..61658a6 100644
--- a/Sluift/Lua/Check.h
+++ b/Sluift/Lua/Check.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2014 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,19 +8,22 @@
#include <string>
+#include <Swiften/Base/ByteArray.h>
+
struct lua_State;
namespace Swift {
- namespace Lua {
- void checkType(lua_State* L, int arg, int type);
- int checkIntNumber(lua_State* L, int arg);
- std::string checkString(lua_State* L, int arg);
+ namespace Lua {
+ void checkType(lua_State* L, int arg, int type);
+ int checkIntNumber(lua_State* L, int arg);
+ std::string checkString(lua_State* L, int arg);
+ ByteArray checkByteArray(lua_State* L, int arg);
- void* checkUserDataRaw(lua_State* L, int arg, const char* tableName);
+ void* checkUserDataRaw(lua_State* L, int arg);
- template<typename T>
- T** checkUserData(lua_State* L, int arg, const char* tableName) {
- return reinterpret_cast<T**>(checkUserDataRaw(L, arg, tableName));
- }
- }
+ template<typename T>
+ T** checkUserData(lua_State* L, int arg) {
+ return reinterpret_cast<T**>(checkUserDataRaw(L, arg));
+ }
+ }
}
diff --git a/Sluift/Lua/Debug.h b/Sluift/Lua/Debug.h
index 8e86b89..5f141e1 100644
--- a/Sluift/Lua/Debug.h
+++ b/Sluift/Lua/Debug.h
@@ -1,28 +1,29 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <lua.hpp>
#include <iostream>
+#include <lua.hpp>
+
namespace Swift {
- namespace Lua {
- inline void dumpStack(lua_State *L) {
- for (int i = 1; i <= lua_gettop(L); i++) {
- int type = lua_type(L, i);
- std::cout << i << ": [" << lua_typename(L, type) << "] ";
- switch (type) {
- case LUA_TSTRING: std::cout << lua_tostring(L, i); break;
- case LUA_TNUMBER: std::cout << lua_tonumber(L, i); break;
- case LUA_TBOOLEAN: std::cout << lua_toboolean(L, i); break;
- default: break;
- }
- std::cout << std::endl;
- }
- }
- }
+ namespace Lua {
+ inline void dumpStack(lua_State *L) {
+ for (int i = 1; i <= lua_gettop(L); i++) {
+ int type = lua_type(L, i);
+ std::cout << i << ": [" << lua_typename(L, type) << "] ";
+ switch (type) {
+ case LUA_TSTRING: std::cout << lua_tostring(L, i); break;
+ case LUA_TNUMBER: std::cout << lua_tonumber(L, i); break;
+ case LUA_TBOOLEAN: std::cout << lua_toboolean(L, i); break;
+ default: break;
+ }
+ std::cout << std::endl;
+ }
+ }
+ }
}
diff --git a/Sluift/Lua/Exception.cpp b/Sluift/Lua/Exception.cpp
index d80b9fb..a51ad10 100644
--- a/Sluift/Lua/Exception.cpp
+++ b/Sluift/Lua/Exception.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
@@ -11,5 +11,5 @@ using namespace Swift::Lua;
Exception::Exception(const std::string& what) : std::runtime_error(what) {
}
-Exception::~Exception() throw() {
+Exception::~Exception() SWIFTEN_NOEXCEPT {
}
diff --git a/Sluift/Lua/Exception.h b/Sluift/Lua/Exception.h
index 6d00d01..a8ecc5f 100644
--- a/Sluift/Lua/Exception.h
+++ b/Sluift/Lua/Exception.h
@@ -1,20 +1,23 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
#include <stdexcept>
+#include <Swiften/Base/API.h>
+
namespace Swift {
- namespace Lua {
- class Exception : public std::runtime_error {
- public:
- Exception(const std::string& what);
- virtual ~Exception() throw();
- };
- }
+ namespace Lua {
+ class Exception : public std::runtime_error {
+ public:
+ Exception(const std::string& what);
+ SWIFTEN_DEFAULT_COPY_CONSTRUCTOR(Exception)
+ virtual ~Exception() SWIFTEN_NOEXCEPT;
+ };
+ }
}
diff --git a/Sluift/Lua/FunctionRegistration.cpp b/Sluift/Lua/FunctionRegistration.cpp
index b773952..5a6d43e 100644
--- a/Sluift/Lua/FunctionRegistration.cpp
+++ b/Sluift/Lua/FunctionRegistration.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,8 +8,8 @@
using namespace Swift::Lua;
-FunctionRegistration::FunctionRegistration(const std::string& name, lua_CFunction function, const std::string& type) {
- FunctionRegistry::getInstance().addFunction(name, function, type);
+FunctionRegistration::FunctionRegistration(const std::string& name, lua_CFunction function, const std::string& type, const std::string& helpDescription, const std::string& helpParameters, const std::string& helpOptions) {
+ FunctionRegistry::getInstance().addFunction(name, function, type, helpDescription, helpParameters, helpOptions);
}
FunctionRegistration::~FunctionRegistration() {
diff --git a/Sluift/Lua/FunctionRegistration.h b/Sluift/Lua/FunctionRegistration.h
index 0df1da1..285c3d0 100644
--- a/Sluift/Lua/FunctionRegistration.h
+++ b/Sluift/Lua/FunctionRegistration.h
@@ -1,36 +1,45 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <string>
+
+#include <lua.hpp>
+
#include <Swiften/Base/API.h>
+
#include <Sluift/Lua/FunctionRegistry.h>
-#include <lua.hpp>
-#include <string>
namespace Swift {
- namespace Lua {
- class FunctionRegistration {
- public:
- FunctionRegistration(const std::string& name, lua_CFunction function, const std::string& type);
- ~FunctionRegistration();
- };
- }
+ namespace Lua {
+ class FunctionRegistration {
+ public:
+ FunctionRegistration(
+ const std::string& name, lua_CFunction function, const std::string& type,
+ const std::string& helpDescription, const std::string& helpParameters, const std::string& helpOptions);
+ ~FunctionRegistration();
+ };
+ }
}
+
+
+#define SLUIFT_LUA_FUNCTION_WITH_HELP(TYPE, NAME, HELP_DESCRIPTION, HELP_PARAMETERS, HELP_OPTIONS) \
+ static int TYPE##_##NAME(lua_State* L); \
+ static int TYPE##_##NAME##_wrapper(lua_State* L); \
+ static ::Swift::Lua::FunctionRegistration TYPE##_##NAME##_registration( #NAME , TYPE##_##NAME##_wrapper, #TYPE, HELP_DESCRIPTION, HELP_PARAMETERS, HELP_OPTIONS); \
+ static int TYPE##_##NAME##_wrapper(lua_State* L) { \
+ try { \
+ return TYPE ## _ ## NAME (L); \
+ } \
+ catch (const std::exception& e) { \
+ return luaL_error(L, e.what()); \
+ } \
+ } \
+ static int TYPE ## _ ## NAME (lua_State* L)
+
#define SLUIFT_LUA_FUNCTION(TYPE, NAME) \
- static int TYPE##_##NAME(lua_State* L); \
- static int TYPE##_##NAME##_wrapper(lua_State* L); \
- static ::Swift::Lua::FunctionRegistration TYPE##_##NAME##_registration( #NAME , TYPE##_##NAME##_wrapper, #TYPE); \
- static int TYPE##_##NAME##_wrapper(lua_State* L) { \
- try { \
- return TYPE ## _ ## NAME (L); \
- } \
- catch (const std::exception& e) { \
- return luaL_error(L, e.what()); \
- } \
- } \
- static int TYPE ## _ ## NAME (lua_State* L)
+ SLUIFT_LUA_FUNCTION_WITH_HELP(TYPE, NAME, "", "", "")
diff --git a/Sluift/Lua/FunctionRegistry.cpp b/Sluift/Lua/FunctionRegistry.cpp
index 99ea096..46c6d18 100644
--- a/Sluift/Lua/FunctionRegistry.cpp
+++ b/Sluift/Lua/FunctionRegistry.cpp
@@ -1,12 +1,14 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/Lua/FunctionRegistry.h>
-#include <Swiften/Base/foreach.h>
+#include <Sluift/Lua/Exception.h>
+#include <Sluift/Lua/LuaUtils.h>
+#include <Sluift/globals.h>
using namespace Swift::Lua;
@@ -17,39 +19,39 @@ FunctionRegistry::~FunctionRegistry() {
}
FunctionRegistry& FunctionRegistry::getInstance() {
- static FunctionRegistry instance;
- return instance;
+ static FunctionRegistry instance;
+ return instance;
}
-void FunctionRegistry::addFunction(const std::string& name, lua_CFunction function, const std::string& type) {
- Registration registration;
- registration.name = name;
- registration.function = function;
- registration.type = type;
- registrations.push_back(registration);
-}
-
-std::string FunctionRegistry::getMetaTableNameForType(const std::string& type) {
- return "Sluift_" + type;
-}
-
-void FunctionRegistry::registerTypeMetaTable(lua_State* L, const std::string& type) {
- luaL_newmetatable(L, getMetaTableNameForType(type).c_str());
- lua_pushvalue(L, -1);
- lua_setfield(L, -2, "__index");
- addFunctionsToTable(L, type);
+void FunctionRegistry::addFunction(
+ const std::string& name, lua_CFunction function, const std::string& type,
+ const std::string& helpDescription, const std::string& helpParameters, const std::string& helpOptions) {
+ Registration registration;
+ registration.name = name;
+ registration.function = function;
+ registration.type = type;
+ registration.helpDescription = helpDescription;
+ registration.helpParameters = helpParameters;
+ registration.helpOptions = helpOptions;
+ registrations.push_back(registration);
}
void FunctionRegistry::createFunctionTable(lua_State* L, const std::string& type) {
- lua_newtable(L);
- addFunctionsToTable(L, type);
+ lua_newtable(L);
+ addFunctionsToTable(L, type);
}
void FunctionRegistry::addFunctionsToTable(lua_State* L, const std::string& type) {
- foreach(const Registration& registration, registrations) {
- if (registration.type == type) {
- lua_pushcclosure(L, registration.function, 0);
- lua_setfield(L, -2, registration.name.c_str());
- }
- }
+ for (const auto& registration : registrations) {
+ if (registration.type == type) {
+ lua_pushcclosure(L, registration.function, 0);
+ if (!registration.helpDescription.empty()) {
+ Lua::registerHelp(L, -1, registration.helpDescription, registration.helpParameters, registration.helpOptions);
+ }
+ else {
+ Lua::registerExtraHelp(L, -1, registration.type + "." + registration.name);
+ }
+ lua_setfield(L, -2, registration.name.c_str());
+ }
+ }
}
diff --git a/Sluift/Lua/FunctionRegistry.h b/Sluift/Lua/FunctionRegistry.h
index e3ad620..88e15d5 100644
--- a/Sluift/Lua/FunctionRegistry.h
+++ b/Sluift/Lua/FunctionRegistry.h
@@ -1,46 +1,47 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
-#include <lua.hpp>
#include <string>
#include <vector>
-namespace Swift {
- namespace Lua {
- class FunctionRegistry {
- public:
- ~FunctionRegistry();
- static FunctionRegistry& getInstance();
-
- void addFunction(const std::string& name, lua_CFunction function, const std::string& type);
-
- static std::string getMetaTableNameForType(const std::string& type);
- void registerTypeMetaTable(lua_State* L, const std::string& type);
-
- void createFunctionTable(lua_State* L, const std::string& type);
-
- /**
- * Adds the functions to the table on the top of the stack.
- */
- void addFunctionsToTable(lua_State* L, const std::string& type);
-
- private:
- FunctionRegistry();
-
+#include <lua.hpp>
- private:
- struct Registration {
- std::string name;
- lua_CFunction function;
- std::string type;
- };
- std::vector<Registration> registrations;
- };
- }
+namespace Swift {
+ namespace Lua {
+ class FunctionRegistry {
+ public:
+ ~FunctionRegistry();
+ static FunctionRegistry& getInstance();
+
+ void addFunction(const std::string& name, lua_CFunction function, const std::string& type,
+ const std::string& helpDescription, const std::string& helpParameters, const std::string& helpOptions);
+
+ void createFunctionTable(lua_State* L, const std::string& type);
+
+ /**
+ * Adds the functions to the table on the top of the stack.
+ */
+ void addFunctionsToTable(lua_State* L, const std::string& type);
+
+ private:
+ FunctionRegistry();
+
+
+ private:
+ struct Registration {
+ std::string name;
+ lua_CFunction function;
+ std::string type;
+ std::string helpDescription;
+ std::string helpParameters;
+ std::string helpOptions;
+ };
+ std::vector<Registration> registrations;
+ };
+ }
}
diff --git a/Sluift/Lua/LuaUtils.cpp b/Sluift/Lua/LuaUtils.cpp
index 7052abe..c677381 100644
--- a/Sluift/Lua/LuaUtils.cpp
+++ b/Sluift/Lua/LuaUtils.cpp
@@ -1,19 +1,21 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/Lua/LuaUtils.h>
-#include <lua.hpp>
-
-#include <boost/scope_exit.hpp>
-#include <Sluift/Lua/Exception.h>
-#include <iostream>
#include <cassert>
#include <sstream>
+
+#include <boost/algorithm/string/trim.hpp>
#include <boost/numeric/conversion/cast.hpp>
+#include <boost/scope_exit.hpp>
+
+#include <lua.hpp>
+
+#include <Sluift/Lua/Exception.h>
#include <Sluift/globals.h>
using namespace Swift::Lua;
@@ -21,59 +23,178 @@ using namespace Swift::Lua;
static const std::string INDENT = " ";
void Swift::Lua::registerTableToString(lua_State* L, int index) {
- index = Lua::absoluteOffset(L, index);
- lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.bootIndex);
- lua_getfield(L, -1, "register_table_tostring");
- lua_pushvalue(L, index);
- if (lua_pcall(L, 1, 0, 0) != 0) {
- throw Lua::Exception(lua_tostring(L, -1));
- }
- lua_pop(L, 1);
+ index = Lua::absoluteOffset(L, index);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ lua_getfield(L, -1, "register_table_tostring");
+ lua_pushvalue(L, index);
+ if (lua_pcall(L, 1, 0, 0) != 0) {
+ throw Lua::Exception(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+}
+
+void Swift::Lua::registerTableEquals(lua_State* L, int index) {
+ index = Lua::absoluteOffset(L, index);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ lua_getfield(L, -1, "register_table_equals");
+ lua_pushvalue(L, index);
+ if (lua_pcall(L, 1, 0, 0) != 0) {
+ throw Lua::Exception(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
}
void Swift::Lua::registerGetByTypeIndex(lua_State* L, int index) {
- index = Lua::absoluteOffset(L, index);
- lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.bootIndex);
- lua_getfield(L, -1, "register_get_by_type_index");
- lua_pushvalue(L, index);
- if (lua_pcall(L, 1, 0, 0) != 0) {
- throw Lua::Exception(lua_tostring(L, -1));
- }
- lua_pop(L, 1);
+ index = Lua::absoluteOffset(L, index);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ lua_getfield(L, -1, "register_get_by_type_index");
+ lua_pushvalue(L, index);
+ if (lua_pcall(L, 1, 0, 0) != 0) {
+ throw Lua::Exception(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
}
boost::optional<std::string> Swift::Lua::getStringField(lua_State* L, int index, const std::string& field) {
- lua_getfield(L, index, field.c_str());
- // Seems to generate warnings with some versions of CLang that i can't turn off.
- // Leaving the more elegant code here, hoping we can re-enable it later (newer boost? c++11?).
- // The same applies to the other get*Field functions.
- //BOOST_SCOPE_EXIT(&L) { lua_pop(L,1); } BOOST_SCOPE_EXIT_END
- //return lua_isstring(L, -1) ? std::string(lua_tostring(L, -1)) : boost::optional<std::string>();
-
- boost::optional<std::string> result;
- if (lua_isstring(L, -1)) {
- result = std::string(lua_tostring(L, -1));
- }
- lua_pop(L, 1);
- return result;
+ lua_getfield(L, index, field.c_str());
+ // Seems to generate warnings with some versions of CLang that i can't turn off.
+ // Leaving the more elegant code here, hoping we can re-enable it later (newer boost? c++11?).
+ // The same applies to the other get*Field functions.
+ //BOOST_SCOPE_EXIT(&L) { lua_pop(L,1); } BOOST_SCOPE_EXIT_END
+ //return lua_isstring(L, -1) ? std::string(lua_tostring(L, -1)) : boost::optional<std::string>();
+
+ boost::optional<std::string> result;
+ if (lua_isstring(L, -1)) {
+ result = std::string(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+ return result;
}
boost::optional<bool> Swift::Lua::getBooleanField(lua_State* L, int index, const std::string& field) {
- lua_getfield(L, index, field.c_str());
- boost::optional<bool> result;
- if (lua_isboolean(L, -1)) {
- result = lua_toboolean(L, -1);
- }
- lua_pop(L, 1);
- return result;
+ lua_getfield(L, index, field.c_str());
+ boost::optional<bool> result;
+ if (lua_isboolean(L, -1)) {
+ result = lua_toboolean(L, -1);
+ }
+ lua_pop(L, 1);
+ return result;
}
boost::optional<int> Swift::Lua::getIntField(lua_State* L, int index, const std::string& field) {
- lua_getfield(L, index, field.c_str());
- boost::optional<int> result;
- if (lua_isnumber(L, -1)) {
- result = boost::numeric_cast<int>(lua_tonumber(L, -1));
- }
- lua_pop(L, 1);
- return result;
+ lua_getfield(L, index, field.c_str());
+ boost::optional<int> result;
+ if (lua_isnumber(L, -1)) {
+ result = boost::numeric_cast<int>(lua_tonumber(L, -1));
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+void Swift::Lua::registerHelp(lua_State* L, int index, const std::string& description, const std::string& parameters, const std::string& options) {
+ index = Lua::absoluteOffset(L, index);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ lua_getfield(L, -1, "register_help");
+ lua_pushvalue(L, index);
+
+ lua_newtable(L);
+ lua_pushstring(L, description.c_str());
+ lua_rawseti(L, -2, 1);
+
+ if (!parameters.empty()) {
+ std::istringstream s(parameters);
+ lua_newtable(L);
+ int i = 1;
+ for (std::string line; std::getline(s, line); ) {
+ std::string trimmedLine = boost::trim_copy(line);
+ if (trimmedLine.empty()) {
+ continue;
+ }
+ size_t splitIndex = trimmedLine.find_first_of(" \t");
+ std::string key;
+ std::string value;
+ if (splitIndex == std::string::npos) {
+ key = trimmedLine;
+ }
+ else {
+ key = trimmedLine.substr(0, splitIndex);
+ value = boost::trim_copy(trimmedLine.substr(splitIndex+1));
+ }
+ lua_createtable(L, 2, 0);
+ lua_pushstring(L, key.c_str());
+ lua_rawseti(L, -2, 1);
+ lua_pushstring(L, value.c_str());
+ lua_rawseti(L, -2, 2);
+
+ lua_rawseti(L, -2, i++);
+ }
+ lua_setfield(L, -2, "parameters");
+ }
+ if (!options.empty()) {
+ std::istringstream s(options);
+ lua_newtable(L);
+ for (std::string line; std::getline(s, line); ) {
+ std::string trimmedLine = boost::trim_copy(line);
+ if (trimmedLine.empty()) {
+ continue;
+ }
+ size_t splitIndex = trimmedLine.find_first_of(" \t");
+ std::string key;
+ std::string value;
+ if (splitIndex == std::string::npos) {
+ key = trimmedLine;
+ }
+ else {
+ key = trimmedLine.substr(0, splitIndex);
+ value = boost::trim_copy(trimmedLine.substr(splitIndex+1));
+ }
+ lua_pushstring(L, value.c_str());
+ lua_setfield(L, -2, key.c_str());
+ }
+ lua_setfield(L, -2, "options");
+ }
+
+ if (lua_pcall(L, 2, 0, 0) != 0) {
+ throw Lua::Exception(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+}
+
+void Swift::Lua::registerClassHelp(lua_State* L, const std::string& name, const std::string& description) {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ lua_getfield(L, -1, "register_class_help");
+ lua_pushstring(L, name.c_str());
+
+ lua_newtable(L);
+ lua_pushstring(L, description.c_str());
+ lua_rawseti(L, -2, 1);
+
+ if (lua_pcall(L, 2, 0, 0) != 0) {
+ throw Lua::Exception(lua_tostring(L, -1));
+ }
+ lua_pop(L, 1);
+}
+
+void Swift::Lua::registerExtraHelp(lua_State* L, int index, const std::string& name) {
+ index = Lua::absoluteOffset(L, index);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ lua_getfield(L, -1, "extra_help");
+ lua_getfield(L, -1, name.c_str());
+ if (!lua_isnil(L, -1)) {
+ lua_getfield(L, -3, "register_help");
+ lua_pushvalue(L, index);
+ lua_pushvalue(L, -3);
+ if (lua_pcall(L, 2, 0, 0) != 0) {
+ throw Lua::Exception(lua_tostring(L, -1));
+ }
+ }
+ lua_pop(L, 3);
+}
+
+void Swift::Lua::pushStringArray(lua_State* L, const std::vector<std::string>& strings) {
+ lua_createtable(L, boost::numeric_cast<int>(strings.size()), 0);
+ for (size_t i = 0; i < strings.size(); ++i) {
+ lua_pushstring(L, strings[i].c_str());
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
}
diff --git a/Sluift/Lua/LuaUtils.h b/Sluift/Lua/LuaUtils.h
index bad307c..b9f5bff 100644
--- a/Sluift/Lua/LuaUtils.h
+++ b/Sluift/Lua/LuaUtils.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,25 +8,51 @@
#include <lua.hpp>
#include <boost/optional.hpp>
+#include <string>
+#include <vector>
-struct lua_State;
+#if LUA_VERSION_NUM < 502
+#define lua_pushglobaltable(L) lua_pushvalue(L, LUA_GLOBALSINDEX)
+#define lua_compare(L,idx1,idx2,LUA_OPEQ) lua_equal(L,(idx1),(idx2))
+#define lua_rawlen(L, i) lua_objlen(L,(i))
+#endif
+#if LUA_VERSION_NUM >= 503
+#undef luaL_register
+#define luaL_register(L, n, l) \
+ lua_getglobal( L, n ); \
+ if( lua_isnil( L, -1 ) ) \
+ { \
+ lua_pop( L, 1 ); \
+ lua_newtable( L ); \
+ } \
+ luaL_setfuncs( L, (l), 0 ); \
+ lua_pushvalue( L, -1 ); \
+ lua_setglobal( L, n );
+#endif
namespace Swift {
- namespace Lua {
- /**
- * Can be used as __tostring metamethod on a table.
- */
- int convertTableToString(lua_State* L);
-
- void registerTableToString(lua_State* L, int index);
- void registerGetByTypeIndex(lua_State* L, int index);
-
- inline int absoluteOffset(lua_State* L, int index) {
- return index > 0 ? index : lua_gettop(L) + index + 1;
- }
-
- boost::optional<std::string> getStringField(lua_State* L, int index, const std::string&);
- boost::optional<bool> getBooleanField(lua_State* L, int index, const std::string&);
- boost::optional<int> getIntField(lua_State* L, int index, const std::string&);
- }
+ namespace Lua {
+ /**
+ * Can be used as __tostring metamethod on a table.
+ */
+ int convertTableToString(lua_State* L);
+
+ void registerTableToString(lua_State* L, int index);
+ void registerTableEquals(lua_State* L, int index);
+ void registerGetByTypeIndex(lua_State* L, int index);
+ void registerHelp(lua_State* L, int index,
+ const std::string& description, const std::string& parameters, const std::string& options);
+ void registerClassHelp(lua_State* L, const std::string& name, const std::string& description);
+ void registerExtraHelp(lua_State* L, int index, const std::string& name);
+
+ inline int absoluteOffset(lua_State* L, int index) {
+ return index > 0 ? index : lua_gettop(L) + index + 1;
+ }
+
+ boost::optional<std::string> getStringField(lua_State* L, int index, const std::string&);
+ boost::optional<bool> getBooleanField(lua_State* L, int index, const std::string&);
+ boost::optional<int> getIntField(lua_State* L, int index, const std::string&);
+
+ void pushStringArray(lua_State* L, const std::vector<std::string>& strings);
+ }
}
diff --git a/Sluift/Lua/Value.cpp b/Sluift/Lua/Value.cpp
index 4f8078e..96d954c 100644
--- a/Sluift/Lua/Value.cpp
+++ b/Sluift/Lua/Value.cpp
@@ -1,66 +1,66 @@
/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
-#include "Value.h"
+#include <Sluift/Lua/Value.h>
+
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/variant/apply_visitor.hpp>
extern "C" {
- #include <lualib.h>
+ #include <lualib.h>
}
-#include <boost/variant/apply_visitor.hpp>
-#include <boost/numeric/conversion/cast.hpp>
-#include <Swiften/Base/foreach.h>
using namespace Swift;
using namespace Swift::Lua;
namespace {
- struct PushVisitor : public boost::static_visitor<> {
- PushVisitor(lua_State* state) : state(state) {
- }
+ struct PushVisitor : public boost::static_visitor<> {
+ PushVisitor(lua_State* state) : state(state) {
+ }
- void operator()(const Nil&) const {
- lua_pushnil(state);
- }
+ void operator()(const Nil&) const {
+ lua_pushnil(state);
+ }
- void operator()(const bool& b) const {
- lua_pushboolean(state, b);
- }
+ void operator()(const bool& b) const {
+ lua_pushboolean(state, b);
+ }
- void operator()(const int& i) const {
- lua_pushnumber(state, i);
- }
+ void operator()(const int& i) const {
+ lua_pushnumber(state, i);
+ }
- void operator()(const std::string& s) const {
- lua_pushstring(state, s.c_str());
- }
+ void operator()(const std::string& s) const {
+ lua_pushstring(state, s.c_str());
+ }
- void operator()(const std::vector<Value>& values) const {
- lua_createtable(state, boost::numeric_cast<int>(values.size()), 0);
- for(size_t i = 0; i < values.size(); ++i) {
- boost::apply_visitor(PushVisitor(state), values[i]);
- lua_rawseti(state, -2, boost::numeric_cast<int>(i + 1));
- }
- }
+ void operator()(const std::vector<Value>& values) const {
+ lua_createtable(state, boost::numeric_cast<int>(values.size()), 0);
+ for(size_t i = 0; i < values.size(); ++i) {
+ boost::apply_visitor(PushVisitor(state), values[i]);
+ lua_rawseti(state, -2, boost::numeric_cast<int>(i + 1));
+ }
+ }
- void operator()(const std::map<std::string, boost::shared_ptr<Value> >& table) const {
- lua_createtable(state, 0, boost::numeric_cast<int>(table.size()));
- for(std::map<std::string, boost::shared_ptr<Value> >::const_iterator i = table.begin(); i != table.end(); ++i) {
- boost::apply_visitor(PushVisitor(state), *i->second);
- lua_setfield(state, -2, i->first.c_str());
- }
- }
+ void operator()(const std::map<std::string, std::shared_ptr<Value> >& table) const {
+ lua_createtable(state, 0, boost::numeric_cast<int>(table.size()));
+ for (const auto& i : table) {
+ boost::apply_visitor(PushVisitor(state), *i.second);
+ lua_setfield(state, -2, i.first.c_str());
+ }
+ }
- lua_State* state;
- };
+ lua_State* state;
+ };
}
namespace Swift { namespace Lua {
void pushValue(lua_State* state, const Value& value) {
- boost::apply_visitor(PushVisitor(state), value);
+ boost::apply_visitor(PushVisitor(state), value);
}
}}
diff --git a/Sluift/Lua/Value.h b/Sluift/Lua/Value.h
index 55aa347..13c4a0c 100644
--- a/Sluift/Lua/Value.h
+++ b/Sluift/Lua/Value.h
@@ -1,60 +1,60 @@
/*
- * Copyright (c) 2010-2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
#include <map>
+#include <memory>
#include <string>
#include <vector>
+
#include <boost/variant.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
struct lua_State;
namespace Swift {
- namespace Lua {
- struct Nil {};
-
- typedef boost::make_recursive_variant<
- Nil,
- bool,
- int,
- std::string,
- std::vector< boost::recursive_variant_ >,
- std::map<std::string, boost::shared_ptr<boost::recursive_variant_> >
- >::type Value;
-
- typedef std::map<std::string, boost::shared_ptr<Value> > Table;
- typedef std::vector<Value> Array;
-
- inline boost::shared_ptr<Value> nilRef() {
- return boost::make_shared<Value>(Nil());
- }
-
- inline boost::shared_ptr<Value> valueRef(const std::string& value) {
- return boost::make_shared<Value>(value);
- }
-
- inline boost::shared_ptr<Value> intRef(int value) {
- return boost::make_shared<Value>(value);
- }
-
- inline boost::shared_ptr<Value> boolRef(bool value) {
- return boost::make_shared<Value>(value);
- }
-
- inline boost::shared_ptr<Value> valueRef(const Table& table) {
- return boost::make_shared<Value>(table);
- }
-
- inline boost::shared_ptr<Value> valueRef(const Array& array) {
- return boost::make_shared<Value>(array);
- }
-
- void pushValue(lua_State* state, const Value& value);
- }
+ namespace Lua {
+ struct Nil {};
+
+ typedef boost::make_recursive_variant<
+ Nil,
+ bool,
+ int,
+ std::string,
+ std::vector< boost::recursive_variant_ >,
+ std::map<std::string, std::shared_ptr<boost::recursive_variant_> >
+ >::type Value;
+
+ typedef std::map<std::string, std::shared_ptr<Value> > Table;
+ typedef std::vector<Value> Array;
+
+ inline std::shared_ptr<Value> nilRef() {
+ return std::make_shared<Value>(Nil());
+ }
+
+ inline std::shared_ptr<Value> valueRef(const std::string& value) {
+ return std::make_shared<Value>(value);
+ }
+
+ inline std::shared_ptr<Value> intRef(int value) {
+ return std::make_shared<Value>(value);
+ }
+
+ inline std::shared_ptr<Value> boolRef(bool value) {
+ return std::make_shared<Value>(value);
+ }
+
+ inline std::shared_ptr<Value> valueRef(const Table& table) {
+ return std::make_shared<Value>(table);
+ }
+
+ inline std::shared_ptr<Value> valueRef(const Array& array) {
+ return std::make_shared<Value>(array);
+ }
+
+ void pushValue(lua_State* state, const Value& value);
+ }
}
diff --git a/Sluift/LuaElementConvertor.cpp b/Sluift/LuaElementConvertor.cpp
index c1d0720..176ed1f 100644
--- a/Sluift/LuaElementConvertor.cpp
+++ b/Sluift/LuaElementConvertor.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
diff --git a/Sluift/LuaElementConvertor.h b/Sluift/LuaElementConvertor.h
index 187ccf1..eb3a24f 100644
--- a/Sluift/LuaElementConvertor.h
+++ b/Sluift/LuaElementConvertor.h
@@ -1,28 +1,39 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
+#include <memory>
+#include <string>
-#include <boost/shared_ptr.hpp>
#include <boost/optional.hpp>
struct lua_State;
namespace Swift {
- class Payload;
+ class Element;
- class LuaElementConvertor {
- public:
- static boost::optional<std::string> NO_RESULT;
+ class LuaElementConvertor {
+ public:
+ static boost::optional<std::string> NO_RESULT;
- virtual ~LuaElementConvertor();
+ struct Documentation {
+ Documentation(const std::string& className, const std::string& description) :
+ className(className), description(description) {}
+ std::string className;
+ std::string description;
+ };
- virtual boost::shared_ptr<Payload> convertFromLua(lua_State*, int index, const std::string& type) = 0;
- virtual boost::optional<std::string> convertToLua(lua_State*, boost::shared_ptr<Payload>) = 0;
- };
+ virtual ~LuaElementConvertor();
+
+ virtual std::shared_ptr<Element> convertFromLua(lua_State*, int index, const std::string& type) = 0;
+ virtual boost::optional<std::string> convertToLua(lua_State*, std::shared_ptr<Element>) = 0;
+
+ virtual boost::optional<Documentation> getDocumentation() const {
+ return boost::optional<Documentation>();
+ }
+ };
}
diff --git a/Sluift/LuaElementConvertors.cpp b/Sluift/LuaElementConvertors.cpp
index 71957c1..db91761 100644
--- a/Sluift/LuaElementConvertors.cpp
+++ b/Sluift/LuaElementConvertors.cpp
@@ -1,46 +1,73 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/LuaElementConvertors.h>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
-#include <Swiften/Base/foreach.h>
-#include <Sluift/LuaElementConvertor.h>
-#include <Sluift/ElementConvertors/RawXMLElementConvertor.h>
-#include <Sluift/ElementConvertors/PubSubEventConvertor.h>
+#include <Sluift/ElementConvertors/BodyConvertor.h>
+#include <Sluift/ElementConvertors/CarbonsReceivedConvertor.h>
+#include <Sluift/ElementConvertors/CarbonsSentConvertor.h>
+#include <Sluift/ElementConvertors/CommandConvertor.h>
#include <Sluift/ElementConvertors/DOMElementConvertor.h>
#include <Sluift/ElementConvertors/DefaultElementConvertor.h>
-#include <Sluift/ElementConvertors/DiscoItemsConvertor.h>
+#include <Sluift/ElementConvertors/DelayConvertor.h>
#include <Sluift/ElementConvertors/DiscoInfoConvertor.h>
+#include <Sluift/ElementConvertors/DiscoItemsConvertor.h>
#include <Sluift/ElementConvertors/FormConvertor.h>
+#include <Sluift/ElementConvertors/ForwardedConvertor.h>
+#include <Sluift/ElementConvertors/IQConvertor.h>
+#include <Sluift/ElementConvertors/MAMFinConvertor.h>
+#include <Sluift/ElementConvertors/MAMQueryConvertor.h>
+#include <Sluift/ElementConvertors/MAMResultConvertor.h>
+#include <Sluift/ElementConvertors/MessageConvertor.h>
+#include <Sluift/ElementConvertors/PresenceConvertor.h>
+#include <Sluift/ElementConvertors/PubSubEventConvertor.h>
+#include <Sluift/ElementConvertors/RawXMLElementConvertor.h>
+#include <Sluift/ElementConvertors/ResultSetConvertor.h>
#include <Sluift/ElementConvertors/SoftwareVersionConvertor.h>
-#include <Sluift/ElementConvertors/VCardUpdateConvertor.h>
+#include <Sluift/ElementConvertors/StatusConvertor.h>
+#include <Sluift/ElementConvertors/StatusShowConvertor.h>
+#include <Sluift/ElementConvertors/SubjectConvertor.h>
#include <Sluift/ElementConvertors/VCardConvertor.h>
-#include <Sluift/ElementConvertors/BodyConvertor.h>
-#include <Sluift/ElementConvertors/CommandConvertor.h>
-#include <Sluift/Lua/LuaUtils.h>
+#include <Sluift/ElementConvertors/VCardUpdateConvertor.h>
#include <Sluift/Lua/Exception.h>
+#include <Sluift/Lua/LuaUtils.h>
+#include <Sluift/LuaElementConvertor.h>
using namespace Swift;
LuaElementConvertors::LuaElementConvertors() {
- registerConvertors();
- convertors.push_back(boost::make_shared<CommandConvertor>(this));
- convertors.push_back(boost::make_shared<PubSubEventConvertor>(this));
- convertors.push_back(boost::make_shared<BodyConvertor>());
- convertors.push_back(boost::make_shared<VCardConvertor>());
- convertors.push_back(boost::make_shared<VCardUpdateConvertor>());
- convertors.push_back(boost::make_shared<FormConvertor>());
- convertors.push_back(boost::make_shared<SoftwareVersionConvertor>());
- convertors.push_back(boost::make_shared<DiscoInfoConvertor>());
- convertors.push_back(boost::make_shared<DiscoItemsConvertor>());
- convertors.push_back(boost::make_shared<DOMElementConvertor>());
- convertors.push_back(boost::make_shared<RawXMLElementConvertor>());
- convertors.push_back(boost::make_shared<DefaultElementConvertor>());
+ registerConvertors();
+ convertors.push_back(std::make_shared<StatusConvertor>());
+ convertors.push_back(std::make_shared<StatusShowConvertor>());
+ convertors.push_back(std::make_shared<DelayConvertor>());
+ convertors.push_back(std::make_shared<CommandConvertor>(this));
+ convertors.push_back(std::make_shared<PubSubEventConvertor>(this));
+ convertors.push_back(std::make_shared<BodyConvertor>());
+ convertors.push_back(std::make_shared<SubjectConvertor>());
+ convertors.push_back(std::make_shared<VCardConvertor>());
+ 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>(this));
+ convertors.push_back(std::make_shared<DiscoItemsConvertor>());
+ convertors.push_back(std::make_shared<IQConvertor>(this));
+ convertors.push_back(std::make_shared<PresenceConvertor>(this));
+ convertors.push_back(std::make_shared<MessageConvertor>(this));
+ convertors.push_back(std::make_shared<ResultSetConvertor>());
+ convertors.push_back(std::make_shared<ForwardedConvertor>(this));
+ convertors.push_back(std::make_shared<MAMResultConvertor>(this));
+ convertors.push_back(std::make_shared<MAMQueryConvertor>(this));
+ convertors.push_back(std::make_shared<MAMFinConvertor>(this));
+ convertors.push_back(std::make_shared<CarbonsReceivedConvertor>(this));
+ convertors.push_back(std::make_shared<CarbonsSentConvertor>(this));
+ convertors.push_back(std::make_shared<DOMElementConvertor>());
+ convertors.push_back(std::make_shared<RawXMLElementConvertor>());
+ convertors.push_back(std::make_shared<DefaultElementConvertor>());
}
LuaElementConvertors::~LuaElementConvertors() {
@@ -48,65 +75,65 @@ LuaElementConvertors::~LuaElementConvertors() {
#include <Sluift/ElementConvertors/ElementConvertors.ipp>
-boost::shared_ptr<Payload> LuaElementConvertors::convertFromLua(lua_State* L, int index) {
- if (lua_isstring(L, index)) {
- return convertFromLuaUntyped(L, index, "xml");
- }
- else if (lua_istable(L, index)) {
- lua_getfield(L, index, "_type");
- if (lua_isstring(L, -1)) {
- std::string type = lua_tostring(L, -1);
- lua_pop(L, 1);
- return convertFromLuaUntyped(L, index, type);
- }
- lua_pop(L, 1);
- }
- throw Lua::Exception("Unable to determine type");
+std::shared_ptr<Element> LuaElementConvertors::convertFromLua(lua_State* L, int index) {
+ if (lua_isstring(L, index)) {
+ return convertFromLuaUntyped(L, index, "xml");
+ }
+ else if (lua_istable(L, index)) {
+ lua_getfield(L, index, "_type");
+ if (lua_isstring(L, -1)) {
+ std::string type = lua_tostring(L, -1);
+ lua_pop(L, 1);
+ return convertFromLuaUntyped(L, index, type);
+ }
+ lua_pop(L, 1);
+ }
+ throw Lua::Exception("Unable to determine type");
}
-boost::shared_ptr<Payload> LuaElementConvertors::convertFromLuaUntyped(lua_State* L, int index, const std::string& type) {
- index = Lua::absoluteOffset(L, index);
- foreach (boost::shared_ptr<LuaElementConvertor> convertor, convertors) {
- if (boost::shared_ptr<Payload> result = convertor->convertFromLua(L, index, type)) {
- return result;
- }
- }
- return boost::shared_ptr<Payload>();
+std::shared_ptr<Element> LuaElementConvertors::convertFromLuaUntyped(lua_State* L, int index, const std::string& type) {
+ index = Lua::absoluteOffset(L, index);
+ for (auto&& convertor : convertors) {
+ if (std::shared_ptr<Element> result = convertor->convertFromLua(L, index, type)) {
+ return result;
+ }
+ }
+ return std::shared_ptr<Element>();
}
-int LuaElementConvertors::convertToLua(lua_State* L, boost::shared_ptr<Payload> payload) {
- if (boost::optional<std::string> type = doConvertToLuaUntyped(L, payload)) {
- if (lua_istable(L, -1)) {
- lua_pushstring(L, type->c_str());
- lua_setfield(L, -2, "_type");
- Lua::registerTableToString(L, -1);
- }
- else {
- assert(*type == "xml");
- }
- return 1;
- }
- return 0;
+int LuaElementConvertors::convertToLua(lua_State* L, std::shared_ptr<Element> payload) {
+ if (boost::optional<std::string> type = doConvertToLuaUntyped(L, payload)) {
+ if (lua_istable(L, -1)) {
+ lua_pushstring(L, type->c_str());
+ lua_setfield(L, -2, "_type");
+ Lua::registerTableToString(L, -1);
+ }
+ else {
+ assert(*type == "xml");
+ }
+ return 1;
+ }
+ return 0;
}
-int LuaElementConvertors::convertToLuaUntyped(lua_State* L, boost::shared_ptr<Payload> payload) {
- if (doConvertToLuaUntyped(L, payload)) {
- return 1;
- }
- return 0;
+int LuaElementConvertors::convertToLuaUntyped(lua_State* L, std::shared_ptr<Element> payload) {
+ if (doConvertToLuaUntyped(L, payload)) {
+ return 1;
+ }
+ return 0;
}
boost::optional<std::string> LuaElementConvertors::doConvertToLuaUntyped(
- lua_State* L, boost::shared_ptr<Payload> payload) {
- if (!payload) {
- return LuaElementConvertor::NO_RESULT;
- }
- foreach (boost::shared_ptr<LuaElementConvertor> convertor, convertors) {
- if (boost::optional<std::string> type = convertor->convertToLua(L, payload)) {
- return *type;
- }
- }
- return LuaElementConvertor::NO_RESULT;
+ lua_State* L, std::shared_ptr<Element> payload) {
+ if (!payload) {
+ return LuaElementConvertor::NO_RESULT;
+ }
+ for (auto&& convertor : convertors) {
+ if (boost::optional<std::string> type = convertor->convertToLua(L, payload)) {
+ return *type;
+ }
+ }
+ return LuaElementConvertor::NO_RESULT;
}
diff --git a/Sluift/LuaElementConvertors.h b/Sluift/LuaElementConvertors.h
index 36da15a..bfcffdd 100644
--- a/Sluift/LuaElementConvertors.h
+++ b/Sluift/LuaElementConvertors.h
@@ -1,47 +1,50 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/Override.h>
-
+#include <memory>
#include <vector>
-#include <boost/shared_ptr.hpp>
+
#include <boost/optional.hpp>
struct lua_State;
namespace Swift {
- class LuaElementConvertor;
- class Payload;
-
- class LuaElementConvertors {
- public:
- LuaElementConvertors();
- virtual ~LuaElementConvertors();
-
- boost::shared_ptr<Payload> convertFromLua(lua_State*, int index);
- int convertToLua(lua_State*, boost::shared_ptr<Payload>);
-
- /**
- * Adds a toplevel type+data table with the given type.
- */
- boost::shared_ptr<Payload> convertFromLuaUntyped(lua_State*, int index, const std::string& type);
-
- /**
- * Strips the toplevel type+data table, and only return the
- * data.
- */
- int convertToLuaUntyped(lua_State*, boost::shared_ptr<Payload>);
-
- private:
- boost::optional<std::string> doConvertToLuaUntyped(lua_State*, boost::shared_ptr<Payload>);
- void registerConvertors();
-
- private:
- std::vector< boost::shared_ptr<LuaElementConvertor> > convertors;
- };
+ class LuaElementConvertor;
+ class Element;
+
+ class LuaElementConvertors {
+ public:
+ LuaElementConvertors();
+ virtual ~LuaElementConvertors();
+
+ std::shared_ptr<Element> convertFromLua(lua_State*, int index);
+ int convertToLua(lua_State*, std::shared_ptr<Element>);
+
+ /**
+ * Adds a toplevel type+data table with the given type.
+ */
+ std::shared_ptr<Element> convertFromLuaUntyped(lua_State*, int index, const std::string& type);
+
+ /**
+ * Strips the toplevel type+data table, and only return the
+ * data.
+ */
+ int convertToLuaUntyped(lua_State*, std::shared_ptr<Element>);
+
+ const std::vector< std::shared_ptr<LuaElementConvertor> >& getConvertors() const {
+ return convertors;
+ }
+
+ private:
+ boost::optional<std::string> doConvertToLuaUntyped(lua_State*, std::shared_ptr<Element>);
+ void registerConvertors();
+
+ private:
+ std::vector< std::shared_ptr<LuaElementConvertor> > convertors;
+ };
}
diff --git a/Sluift/Response.cpp b/Sluift/Response.cpp
index 519379c..dd98a25 100644
--- a/Sluift/Response.cpp
+++ b/Sluift/Response.cpp
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,71 +8,74 @@
#include <lua.hpp>
-#include <Sluift/globals.h>
#include <Swiften/Elements/ErrorPayload.h>
+
#include <Sluift/Lua/LuaUtils.h>
+#include <Sluift/globals.h>
using namespace Swift;
using namespace Swift::Sluift;
-static std::string getErrorString(boost::shared_ptr<ErrorPayload> error) {
- // Copied from ChatControllerBase.
- // TODO: Share this code;
- std::string defaultMessage = "Error sending message";
- if (!error->getText().empty()) {
- return error->getText();
- }
- else {
- switch (error->getCondition()) {
- case ErrorPayload::BadRequest: return "Bad request";
- case ErrorPayload::Conflict: return "Conflict";
- case ErrorPayload::FeatureNotImplemented: return "This feature is not implemented";
- case ErrorPayload::Forbidden: return "Forbidden";
- case ErrorPayload::Gone: return "Recipient can no longer be contacted";
- case ErrorPayload::InternalServerError: return "Internal server error";
- case ErrorPayload::ItemNotFound: return "Item not found";
- case ErrorPayload::JIDMalformed: return "JID Malformed";
- case ErrorPayload::NotAcceptable: return "Message was rejected";
- case ErrorPayload::NotAllowed: return "Not allowed";
- case ErrorPayload::NotAuthorized: return "Not authorized";
- case ErrorPayload::PaymentRequired: return "Payment is required";
- case ErrorPayload::RecipientUnavailable: return "Recipient is unavailable";
- case ErrorPayload::Redirect: return "Redirect";
- case ErrorPayload::RegistrationRequired: return "Registration required";
- case ErrorPayload::RemoteServerNotFound: return "Recipient's server not found";
- case ErrorPayload::RemoteServerTimeout: return "Remote server timeout";
- case ErrorPayload::ResourceConstraint: return "The server is low on resources";
- case ErrorPayload::ServiceUnavailable: return "The service is unavailable";
- case ErrorPayload::SubscriptionRequired: return "A subscription is required";
- case ErrorPayload::UndefinedCondition: return "Undefined condition";
- case ErrorPayload::UnexpectedRequest: return "Unexpected request";
- }
- }
- assert(false);
- return defaultMessage;
+static std::string getErrorString(std::shared_ptr<ErrorPayload> error) {
+ // Copied from ChatControllerBase.
+ // TODO: Share this code;
+ std::string defaultMessage = "Error sending message";
+ if (!error->getText().empty()) {
+ return error->getText();
+ }
+ else {
+ switch (error->getCondition()) {
+ case ErrorPayload::BadRequest: return "Bad request";
+ case ErrorPayload::Conflict: return "Conflict";
+ case ErrorPayload::FeatureNotImplemented: return "This feature is not implemented";
+ case ErrorPayload::Forbidden: return "Forbidden";
+ case ErrorPayload::Gone: return "Recipient can no longer be contacted";
+ case ErrorPayload::InternalServerError: return "Internal server error";
+ case ErrorPayload::ItemNotFound: return "Item not found";
+ case ErrorPayload::JIDMalformed: return "JID Malformed";
+ case ErrorPayload::NotAcceptable: return "Message was rejected";
+ case ErrorPayload::NotAllowed: return "Not allowed";
+ case ErrorPayload::NotAuthorized: return "Not authorized";
+ case ErrorPayload::PaymentRequired: return "Payment is required";
+ case ErrorPayload::RecipientUnavailable: return "Recipient is unavailable";
+ case ErrorPayload::Redirect: return "Redirect";
+ case ErrorPayload::RegistrationRequired: return "Registration required";
+ case ErrorPayload::RemoteServerNotFound: return "Recipient's server not found";
+ case ErrorPayload::RemoteServerTimeout: return "Remote server timeout";
+ case ErrorPayload::ResourceConstraint: return "The server is low on resources";
+ case ErrorPayload::ServiceUnavailable: return "The service is unavailable";
+ case ErrorPayload::SubscriptionRequired: return "A subscription is required";
+ case ErrorPayload::UndefinedCondition: return "Undefined condition";
+ case ErrorPayload::UnexpectedRequest: return "Unexpected request";
+ }
+ }
+ assert(false);
+ return defaultMessage;
}
Response::~Response() {
}
int Response::convertToLuaResult(lua_State* L) {
- if (error) {
- lua_pushnil(L);
- lua_pushstring(L, getErrorString(error).c_str());
- Sluift::globals.elementConvertor.convertToLuaUntyped(L, error);
- Lua::registerTableToString(L, -1);
- return 3;
- }
- else {
- if (result) {
- Sluift::globals.elementConvertor.convertToLuaUntyped(L, result);
- Lua::registerTableToString(L, -1);
- }
- else {
- lua_pushboolean(L, 1);
- }
- return 1;
- }
+ if (error) {
+ lua_pushnil(L);
+ lua_pushstring(L, getErrorString(error).c_str());
+ bool converted = Sluift::globals.elementConvertor.convertToLuaUntyped(L, error);
+ assert(converted);
+ Lua::registerTableToString(L, -1);
+ return 3;
+ }
+ else {
+ if (result) {
+ bool converted = Sluift::globals.elementConvertor.convertToLuaUntyped(L, result);
+ assert(converted);
+ Lua::registerTableToString(L, -1);
+ }
+ else {
+ lua_pushboolean(L, 1);
+ }
+ return 1;
+ }
}
diff --git a/Sluift/Response.h b/Sluift/Response.h
index 1cd059a..dc35289 100644
--- a/Sluift/Response.h
+++ b/Sluift/Response.h
@@ -1,34 +1,36 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Elements/Payload.h>
+#include <Swiften/Base/API.h>
#include <Swiften/Elements/ErrorPayload.h>
+#include <Swiften/Elements/Payload.h>
struct lua_State;
namespace Swift {
- namespace Sluift {
- struct Response {
- Response(boost::shared_ptr<Payload> result, boost::shared_ptr<ErrorPayload> error) : result(result), error(error) {}
- ~Response();
-
- static Response withResult(boost::shared_ptr<Payload> response) {
- return Response(response, boost::shared_ptr<ErrorPayload>());
- }
-
- static Response withError(boost::shared_ptr<ErrorPayload> error) {
- return Response(boost::shared_ptr<Payload>(), error);
- }
-
- int convertToLuaResult(lua_State* L);
-
- boost::shared_ptr<Payload> result;
- boost::shared_ptr<ErrorPayload> error;
- };
- }
+ namespace Sluift {
+ struct Response {
+ Response(std::shared_ptr<Payload> result, std::shared_ptr<ErrorPayload> error) : result(result), error(error) {}
+ SWIFTEN_DEFAULT_COPY_CONSTRUCTOR(Response)
+ ~Response();
+
+ static Response withResult(std::shared_ptr<Payload> response) {
+ return Response(response, std::shared_ptr<ErrorPayload>());
+ }
+
+ static Response withError(std::shared_ptr<ErrorPayload> error) {
+ return Response(std::shared_ptr<Payload>(), error);
+ }
+
+ int convertToLuaResult(lua_State* L);
+
+ std::shared_ptr<Payload> result;
+ std::shared_ptr<ErrorPayload> error;
+ };
+ }
}
diff --git a/Sluift/SConscript b/Sluift/SConscript
index 1a29e43..af54ece 100644
--- a/Sluift/SConscript
+++ b/Sluift/SConscript
@@ -1,85 +1,88 @@
import Version, os.path
-Import(["env", "conf_env"])
+Import(["env"])
if env["SCONS_STAGE"] == "build" and not GetOption("help") and not env.get("HAVE_LUA", 0) :
- print "Warning: Lua was not found. Sluift will not be built."
- if "Sluift" in env["PROJECTS"] :
- env["PROJECTS"].remove("Sluift")
-
+ print("Warning: Lua was not found. Sluift will not be built.")
+ if "Sluift" in env["PROJECTS"] :
+ env["PROJECTS"].remove("Sluift")
+
elif env["SCONS_STAGE"] == "build" :
- sluift_sources = [
- "Lua/Value.cpp",
- "Lua/Exception.cpp",
- "Lua/Check.cpp",
- "Lua/FunctionRegistration.cpp",
- "Lua/FunctionRegistry.cpp",
- "Lua/LuaUtils.cpp",
- "LuaElementConvertors.cpp",
- "LuaElementConvertor.cpp",
- "Response.cpp",
- "ElementConvertors/BodyConvertor.cpp",
- "ElementConvertors/VCardUpdateConvertor.cpp",
- "ElementConvertors/PubSubEventConvertor.cpp",
- "ElementConvertors/RawXMLElementConvertor.cpp",
- "ElementConvertors/DOMElementConvertor.cpp",
- "ElementConvertors/DefaultElementConvertor.cpp",
- "ElementConvertors/DiscoInfoConvertor.cpp",
- "ElementConvertors/DiscoItemsConvertor.cpp",
- "ElementConvertors/FormConvertor.cpp",
- "ElementConvertors/SoftwareVersionConvertor.cpp",
- "ElementConvertors/VCardConvertor.cpp",
- "ElementConvertors/CommandConvertor.cpp",
- "ClientHelpers.cpp",
- "SluiftClient.cpp",
- "boot.c",
- "client.cpp",
- "sluift.cpp"
- ]
- sluift_sources += env.SConscript("ElementConvertors/SConscript")
+ sluift_sources = [
+ "Lua/Value.cpp",
+ "Lua/Exception.cpp",
+ "Lua/Check.cpp",
+ "Lua/FunctionRegistration.cpp",
+ "Lua/FunctionRegistry.cpp",
+ "Lua/LuaUtils.cpp",
+ "LuaElementConvertors.cpp",
+ "LuaElementConvertor.cpp",
+ "Response.cpp",
+ "ElementConvertors/BodyConvertor.cpp",
+ "ElementConvertors/VCardUpdateConvertor.cpp",
+ "ElementConvertors/PubSubEventConvertor.cpp",
+ "ElementConvertors/RawXMLElementConvertor.cpp",
+ "ElementConvertors/DOMElementConvertor.cpp",
+ "ElementConvertors/DefaultElementConvertor.cpp",
+ "ElementConvertors/DiscoInfoConvertor.cpp",
+ "ElementConvertors/DiscoItemsConvertor.cpp",
+ "ElementConvertors/FormConvertor.cpp",
+ "ElementConvertors/SoftwareVersionConvertor.cpp",
+ "ElementConvertors/VCardConvertor.cpp",
+ "ElementConvertors/CommandConvertor.cpp",
+ "ElementConvertors/StatusConvertor.cpp",
+ "ElementConvertors/StatusShowConvertor.cpp",
+ "ElementConvertors/DelayConvertor.cpp",
+ "Helpers.cpp",
+ "SluiftClient.cpp",
+ "SluiftComponent.cpp",
+ "Watchdog.cpp",
+ "core.c",
+ "client.cpp",
+ "component.cpp",
+ "sluift.cpp"
+ ]
+ sluift_sources += env.SConscript("ElementConvertors/SConscript")
+
+
- sluift_env = env.Clone()
- sluift_env.UseFlags(env.get("LUA_FLAGS", {}))
- sluift_env.UseFlags(env["SWIFTEN_FLAGS"])
- sluift_env.UseFlags(env["SWIFTEN_DEP_FLAGS"])
- if sluift_env["PLATFORM"] == "win32" :
- sluift_env.Append(CPPDEFINES = ["SLUIFT_BUILD_DLL"])
+ sluift_env = env.Clone()
+ sluift_env.UseFlags(env.get("LUA_FLAGS", {}))
+ sluift_env.UseFlags(env["SWIFTEN_FLAGS"])
+ sluift_env.UseFlags(env["SWIFTEN_DEP_FLAGS"])
+ # Support compilation on both Lua 5.1 and Lua 5.2
+ sluift_env.Append(CPPDEFINES = ["LUA_COMPAT_ALL"])
+ if sluift_env["PLATFORM"] == "win32" :
+ sluift_env.Append(CPPDEFINES = ["SLUIFT_BUILD_DLL"])
- # Generate a customized lua.c
- sluift_env["SLUIFT_VERSION"] = Version.getBuildVersion(env.Dir("#").abspath, "sluift")
- def patchLua(env, target, source) :
- f = open(source[0].abspath, "r")
- contents = f.read()
- f.close()
- if env["PLATFORM"] == "win32" :
- key = "Z"
- else :
- key = "D"
- contents = contents.replace("LUA_RELEASE", "\"== Sluift XMPP Console (%(version)s) == \\nPress Ctrl-%(key)s to exit\"" % {"version": source[1].get_contents(), "key" : key})
- contents = contents.replace("LUA_COPYRIGHT", "")
- f = open(target[0].abspath, "w")
- f.write(contents)
- f.close()
- sluift_env.Command("lua.c", ["#/3rdParty/Lua/src/lua.c", sluift_env.Value(sluift_env["SLUIFT_VERSION"])], env.Action(patchLua, cmdstr = "$GENCOMSTR"))
+ if sluift_env["PLATFORM"] == "darwin" and os.path.isdir("/Applications/iTunes.app") :
+ sluift_env.Append(FRAMEWORKS = ["ScriptingBridge"])
+ sluift_env.Command("iTunes.h", "/Applications/iTunes.app",
+ "sdef ${SOURCE} | sdp -fh --basename iTunes -V 10.10 -o ${TARGET.dir}")
+ sluift_env.Append(CPPDEFINES = ["HAVE_ITUNES"])
+ sluift_sources += ["ITunesInterface.mm"]
- # Generate boot.cpp
- def generate_embedded_lua(env, target, source) :
- f = open(source[0].abspath, "r")
- data = f.read()
- f.close()
- f = open(target[0].abspath, "w")
- f.write('const char ' + source[0].name.replace(".", "_") + "[] = \"" + data.replace("\\", "\\\\").replace("\n", "\\n").replace('"', '\\"') + "\";")
- f.close()
- sluift_env.Command("boot.c", ["boot.lua"], env.Action(generate_embedded_lua, cmdstr="$GENCOMSTR"))
+ # Generate Version.h
+ version_header = "#pragma once\n\n"
+ version_header += "#define SLUIFT_VERSION_STRING \"" + Version.getBuildVersion(env.Dir("#").abspath, "sluift") + "\"\n"
+ sluift_env.WriteVal("Version.h", sluift_env.Value(version_header))
- if sluift_env.get("HAVE_READLINE", False) :
- sluift_env.Append(CPPDEFINES = ["LUA_USE_READLINE"])
- sluift_env.MergeFlags(sluift_env["READLINE_FLAGS"])
+ # Generate core.c
+ def generate_embedded_lua(env, target, source) :
+ f = open(source[0].abspath, "r")
+ data = f.read()
+ f.close()
+ f = open(target[0].abspath, "w")
+ f.write('#include <stddef.h>\n')
+ f.write('const size_t ' + source[0].name.replace(".", "_") + "_size = " + str(len(data)) + ";\n")
+ f.write('const char ' + source[0].name.replace(".", "_") + "[] = {" + ", ".join([str(ord(c)) for c in data]) + "};\n")
+ f.close()
+ sluift_env.Command("core.c", ["core.lua"], env.Action(generate_embedded_lua, cmdstr="$GENCOMSTR"))
- sluift_env.WriteVal("dll.c", sluift_env.Value(""))
+ sluift_env.WriteVal("dll.c", sluift_env.Value(""))
- sluift_sources = [env.File(x) for x in sluift_sources]
- for sluift_variant in ['dll', 'exe'] :
- SConscript(["SConscript.variant"], variant_dir = sluift_variant,
- duplicate = 0,
- exports = ['sluift_sources', 'sluift_variant', 'sluift_env'])
+ sluift_sources = [env.File(x) for x in sluift_sources]
+ for sluift_variant in ['dll', 'exe'] :
+ SConscript(["SConscript.variant"], variant_dir = sluift_variant,
+ duplicate = 0,
+ exports = ['sluift_sources', 'sluift_variant', 'sluift_env'])
diff --git a/Sluift/SConscript.variant b/Sluift/SConscript.variant
index 92ee493..9f56c91 100644
--- a/Sluift/SConscript.variant
+++ b/Sluift/SConscript.variant
@@ -6,20 +6,37 @@ Import('sluift_variant')
Import('sluift_sources')
if sluift_variant == 'exe' :
- env["SLUIFT"] = sluift_env.Program("sluift", sluift_sources + [
- "#/Sluift/lua.c",
- "#/Sluift/linit.c",
- ])
- if sluift_env.get("SLUIFT_INSTALLDIR", "") :
- sluift_env.Install(os.path.join(sluift_env["SLUIFT_INSTALLDIR"], "bin"), env["SLUIFT"])
+ common_objects = sluift_env.StaticObject(sluift_sources)
+
+ sluift_exe_env = sluift_env.Clone()
+ tokenize = sluift_exe_env.StaticObject("#/Sluift/tokenize.cpp")
+ exe_sources = tokenize + [
+ "#/Sluift/Console.cpp",
+ "#/Sluift/Terminal.cpp",
+ "#/Sluift/StandardTerminal.cpp",
+ "#/Sluift/Completer.cpp",
+ "#/Sluift/main.cpp",
+ ]
+
+ if sluift_exe_env.get("HAVE_EDITLINE", False) :
+ sluift_exe_env.Append(CPPDEFINES = ["HAVE_EDITLINE"])
+ sluift_exe_env.MergeFlags(sluift_exe_env["EDITLINE_FLAGS"])
+ exe_sources += ["#/Sluift/EditlineTerminal.cpp"]
+
+ env["SLUIFT"] = sluift_exe_env.Program("sluift", common_objects + exe_sources)
+ if sluift_exe_env.get("SLUIFT_INSTALLDIR", "") :
+ sluift_exe_env.Install(os.path.join(sluift_exe_env["SLUIFT_INSTALLDIR"], "bin"), env["SLUIFT"])
+
+ # Unit tests
+ env.Append(UNITTEST_OBJECTS = tokenize + ["#/Sluift/UnitTest/TokenizeTest.cpp"])
else :
- sluift_env["SLUIFT_DLL_SUFFIX"] = "${SHLIBSUFFIX}"
- if sluift_env["PLATFORM"] == "darwin" :
- sluift_env["SLUIFT_DLL_SUFFIX"] = ".so"
- sluift_dll = sluift_env.SharedLibrary(sluift_env.File("sluift${SLUIFT_DLL_SUFFIX}"),
- sluift_sources + ["#/Sluift/dll.c"])
- if sluift_env.get("SLUIFT_INSTALLDIR", False) and sluift_env.get("LUA_VERSION", False) :
- sluift_env.Install(
- os.path.join(sluift_env["SLUIFT_INSTALLDIR"], "lib", "lua", sluift_env["LUA_VERSION"]),
- sluift_dll)
+ sluift_env["SLUIFT_DLL_SUFFIX"] = "${SHLIBSUFFIX}"
+ if sluift_env["PLATFORM"] == "darwin" :
+ sluift_env["SLUIFT_DLL_SUFFIX"] = ".so"
+ sluift_dll = sluift_env.SharedLibrary(sluift_env.File("sluift${SLUIFT_DLL_SUFFIX}"),
+ sluift_sources + ["#/Sluift/dll.c"])
+ if sluift_env.get("SLUIFT_INSTALLDIR", False) and sluift_env.get("LUA_VERSION", False) :
+ sluift_env.Install(
+ os.path.join(sluift_env["SLUIFT_INSTALLDIR"], "lib", "lua", sluift_env["LUA_VERSION"]),
+ sluift_dll)
diff --git a/Sluift/SluiftClient.cpp b/Sluift/SluiftClient.cpp
index 8a8d772..99892a9 100644
--- a/Sluift/SluiftClient.cpp
+++ b/Sluift/SluiftClient.cpp
@@ -1,168 +1,232 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2018 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#include <Sluift/SluiftClient.h>
-#include <Swiften/Client/ClientXMLTracer.h>
+#include <boost/numeric/conversion/cast.hpp>
+
#include <Swiften/Client/Client.h>
-#include <Swiften/Roster/XMPPRoster.h>
-#include <Sluift/SluiftGlobals.h>
-#include <Sluift/Lua/Exception.h>
+#include <Swiften/Client/ClientBlockListManager.h>
+#include <Swiften/Client/ClientXMLTracer.h>
#include <Swiften/Elements/Message.h>
+#include <Swiften/Elements/Presence.h>
#include <Swiften/Elements/PubSubEvent.h>
#include <Swiften/Queries/RawRequest.h>
-#include <Sluift/ClientHelpers.h>
-#include <Swiften/Elements/Presence.h>
+#include <Swiften/Roster/XMPPRoster.h>
+
+#include <Sluift/Helpers.h>
+#include <Sluift/Lua/Exception.h>
+#include <Sluift/SluiftGlobals.h>
using namespace Swift;
SluiftClient::SluiftClient(
- const JID& jid,
- const std::string& password,
- NetworkFactories* networkFactories,
- SimpleEventLoop* eventLoop,
- SluiftGlobals* globals) :
- networkFactories(networkFactories),
- eventLoop(eventLoop),
- globals(globals),
- tracer(NULL) {
- client = new Client(jid, password, networkFactories);
- client->setAlwaysTrustCertificates();
- client->onDisconnected.connect(boost::bind(&SluiftClient::handleDisconnected, this, _1));
- client->onMessageReceived.connect(boost::bind(&SluiftClient::handleIncomingMessage, this, _1));
- client->onPresenceReceived.connect(boost::bind(&SluiftClient::handleIncomingPresence, this, _1));
- client->getPubSubManager()->onEvent.connect(boost::bind(&SluiftClient::handleIncomingPubSubEvent, this, _1, _2));
- client->getRoster()->onInitialRosterPopulated.connect(boost::bind(&SluiftClient::handleInitialRosterPopulated, this));
- if (globals->debug) {
- tracer = new ClientXMLTracer(client);
- }
+ const JID& jid,
+ const std::string& password,
+ NetworkFactories* networkFactories,
+ SimpleEventLoop* eventLoop) :
+ networkFactories(networkFactories),
+ eventLoop(eventLoop),
+ tracer(nullptr) {
+ client = new Client(jid, password, networkFactories);
+ client->setAlwaysTrustCertificates();
+ client->onDisconnected.connect(boost::bind(&SluiftClient::handleDisconnected, this, _1));
+ client->onMessageReceived.connect(boost::bind(&SluiftClient::handleIncomingMessage, this, _1));
+ client->onPresenceReceived.connect(boost::bind(&SluiftClient::handleIncomingPresence, this, _1));
+ client->getPubSubManager()->onEvent.connect(boost::bind(&SluiftClient::handleIncomingPubSubEvent, this, _1, _2));
+ client->getRoster()->onInitialRosterPopulated.connect(boost::bind(&SluiftClient::handleInitialRosterPopulated, this));
+ client->getRoster()->onJIDAdded.connect(boost::bind(&SluiftClient::handleIncomingRosterAdd, this, _1));
+ client->getRoster()->onJIDRemoved.connect(boost::bind(&SluiftClient::handleIncomingRosterRemove, this, _1));
+ client->getRoster()->onJIDUpdated.connect(boost::bind(&SluiftClient::handleIncomingRosterUpdate, this, _1));
+ client->getClientBlockListManager()->getBlockList()->onItemAdded.connect(boost::bind(&SluiftClient::handleIncomingBlockEvent, this, _1));
+ client->getClientBlockListManager()->getBlockList()->onItemRemoved.connect(boost::bind(&SluiftClient::handleIncomingUnblockEvent, this, _1));
}
SluiftClient::~SluiftClient() {
- delete tracer;
- delete client;
+ delete tracer;
+ delete client;
}
void SluiftClient::connect() {
- rosterReceived = false;
- disconnectedError = boost::optional<ClientError>();
- client->connect(options);
-}
-
-void SluiftClient::connect(const std::string& host) {
- rosterReceived = false;
- options.manualHostname = host;
- client->connect(options);
-}
-
-void SluiftClient::waitConnected() {
- Watchdog watchdog(globals->timeout, networkFactories->getTimerFactory());
- while (!watchdog.getTimedOut() && client->isActive() && !client->isAvailable()) {
- eventLoop->runUntilEvents();
- }
- if (watchdog.getTimedOut()) {
- client->disconnect();
- throw Lua::Exception("Timeout while connecting");
- }
- if (disconnectedError) {
- throw Lua::Exception(getClientErrorString(*disconnectedError));
- }
+ if (client->isActive()) {
+ throw Lua::Exception("Client is already connecting or connected");
+ }
+ rosterReceived = false;
+ blockListReceived = false;
+ disconnectedError = boost::optional<ClientError>();
+ client->connect(options);
+}
+
+void SluiftClient::setTraceEnabled(bool b) {
+ if (b && !tracer) {
+ tracer = new ClientXMLTracer(client, options.boshURL.isEmpty()? false: true);
+ }
+ else if (!b && tracer) {
+ delete tracer;
+ tracer = nullptr;
+ }
+}
+
+void SluiftClient::waitConnected(int timeout) {
+ Watchdog watchdog(timeout, networkFactories->getTimerFactory());
+ while (!watchdog.getTimedOut() && client->isActive() && !client->isAvailable()) {
+ eventLoop->runUntilEvents();
+ }
+ if (watchdog.getTimedOut()) {
+ client->disconnect();
+ throw Lua::Exception("Timeout while connecting");
+ }
+ if (disconnectedError) {
+ throw Lua::Exception(getErrorString(*disconnectedError));
+ }
}
bool SluiftClient::isConnected() const {
- return client->isAvailable();
+ return client->isAvailable();
}
void SluiftClient::disconnect() {
- client->disconnect();
- while (client->isActive()) {
- eventLoop->runUntilEvents();
- }
+ client->disconnect();
+ while (client->isActive()) {
+ eventLoop->runUntilEvents();
+ }
}
void SluiftClient::setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os) {
- client->setSoftwareVersion(name, version, os);
+ client->setSoftwareVersion(name, version, os);
}
boost::optional<SluiftClient::Event> SluiftClient::getNextEvent(
- int timeout, boost::function<bool (const Event&)> condition) {
- Watchdog watchdog(timeout, networkFactories->getTimerFactory());
- while (true) {
- // Look for pending events in the queue
- while (!pendingEvents.empty()) {
- Event event = pendingEvents.front();
- pendingEvents.pop_front();
- if (!condition || condition(event)) {
- return event;
- }
- }
+ int timeout, boost::function<bool (const Event&)> condition) {
+ Watchdog watchdog(timeout, networkFactories->getTimerFactory());
+ size_t currentIndex = 0;
+ while (true) {
+ // Look for pending events in the queue
+ while (currentIndex < pendingEvents.size()) {
+ Event event = pendingEvents[currentIndex];
+ if (!condition || condition(event)) {
+ pendingEvents.erase(
+ pendingEvents.begin()
+ + boost::numeric_cast<int>(currentIndex));
+ return event;
+ }
+ ++currentIndex;
+ }
- // Wait for new events
- while (!watchdog.getTimedOut() && pendingEvents.empty() && client->isActive()) {
- eventLoop->runUntilEvents();
- }
+ // Wait for new events
+ while (!watchdog.getTimedOut() && currentIndex >= pendingEvents.size() && client->isActive()) {
+ eventLoop->runUntilEvents();
+ }
- // Finish if we're disconnected or timed out
- if (watchdog.getTimedOut() || !client->isActive()) {
- return boost::optional<Event>();
- }
- }
+ // Finish if we're disconnected or timed out
+ if (watchdog.getTimedOut() || !client->isActive()) {
+ return boost::optional<Event>();
+ }
+ }
}
-std::vector<XMPPRosterItem> SluiftClient::getRoster() {
- if (!rosterReceived) {
- // If we haven't requested it yet, request it for the first time
- client->requestRoster();
- }
- while (!rosterReceived) {
- eventLoop->runUntilEvents();
- }
- return client->getRoster()->getItems();
+std::vector<JID> SluiftClient::getBlockList(int timeout) {
+ Watchdog watchdog(timeout, networkFactories->getTimerFactory());
+ if (!blockListReceived) {
+ // If we haven't requested it yet, request it for the first time
+ client->getClientBlockListManager()->requestBlockList();
+
+ // Wait for new events
+ while (!watchdog.getTimedOut() && client->getClientBlockListManager()->getBlockList()->getState() != BlockList::Available) {
+ eventLoop->runUntilEvents();
+ }
+
+ // Throw an error if we're timed out
+ if (watchdog.getTimedOut()) {
+ throw Lua::Exception("Timeout while requesting blocklist");
+ }
+ }
+ blockListReceived = true;
+ return client->getClientBlockListManager()->getBlockList()->getItems();
+}
+
+std::vector<XMPPRosterItem> SluiftClient::getRoster(int timeout) {
+ Watchdog watchdog(timeout, networkFactories->getTimerFactory());
+ if (!rosterReceived) {
+ // If we haven't requested it yet, request it for the first time
+ client->requestRoster();
+
+ // Wait for new events
+ while (!watchdog.getTimedOut() && !rosterReceived) {
+ eventLoop->runUntilEvents();
+ }
+
+ // Throw an error if we're timed out
+ if (watchdog.getTimedOut()) {
+ throw Lua::Exception("Timeout while requesting roster");
+ }
+ }
+ return client->getRoster()->getItems();
+}
+
+void SluiftClient::handleIncomingMessage(std::shared_ptr<Message> stanza) {
+ if (stanza->getPayload<PubSubEvent>()) {
+ // Already handled by pubsub manager
+ return;
+ }
+ pendingEvents.push_back(Event(stanza));
}
-void SluiftClient::handleIncomingMessage(boost::shared_ptr<Message> stanza) {
- if (stanza->getPayload<PubSubEvent>()) {
- // Already handled by pubsub manager
- return;
- }
- pendingEvents.push_back(Event(stanza));
+void SluiftClient::handleIncomingPresence(std::shared_ptr<Presence> stanza) {
+ pendingEvents.push_back(Event(stanza));
}
-void SluiftClient::handleIncomingPresence(boost::shared_ptr<Presence> stanza) {
- pendingEvents.push_back(Event(stanza));
+void SluiftClient::handleIncomingPubSubEvent(const JID& from, std::shared_ptr<PubSubEventPayload> event) {
+ pendingEvents.push_back(Event(from, event));
}
-void SluiftClient::handleIncomingPubSubEvent(const JID& from, boost::shared_ptr<PubSubEventPayload> event) {
- pendingEvents.push_back(Event(from, event));
+void SluiftClient::handleIncomingBlockEvent(const JID& item) {
+ pendingEvents.push_back(Event(item, Event::BlockEventType));
+}
+
+void SluiftClient::handleIncomingUnblockEvent(const JID& item) {
+ pendingEvents.push_back(Event(item, Event::UnblockEventType));
}
void SluiftClient::handleInitialRosterPopulated() {
- rosterReceived = true;
+ rosterReceived = true;
+}
+
+void SluiftClient::handleIncomingRosterAdd(const JID& item) {
+ pendingEvents.push_back(Event(item, Event::RosterAddType));
+}
+
+void SluiftClient::handleIncomingRosterRemove(const JID& item) {
+ pendingEvents.push_back(Event(item, Event::RosterRemoveType));
+}
+
+void SluiftClient::handleIncomingRosterUpdate(const JID& item) {
+ pendingEvents.push_back(Event(item, Event::RosterUpdateType));
}
-void SluiftClient::handleRequestResponse(boost::shared_ptr<Payload> response, boost::shared_ptr<ErrorPayload> error) {
- requestResponse = response;
- requestError = error;
- requestResponseReceived = true;
+void SluiftClient::handleRequestResponse(std::shared_ptr<Payload> response, std::shared_ptr<ErrorPayload> error) {
+ requestResponse = response;
+ requestError = error;
+ requestResponseReceived = true;
}
void SluiftClient::handleDisconnected(const boost::optional<ClientError>& error) {
- disconnectedError = error;
+ disconnectedError = error;
}
-Sluift::Response SluiftClient::doSendRequest(boost::shared_ptr<Request> request, int timeout) {
- requestResponse.reset();
- requestError.reset();
- requestResponseReceived = false;
- request->send();
+Sluift::Response SluiftClient::doSendRequest(std::shared_ptr<Request> request, int timeout) {
+ requestResponse.reset();
+ requestError.reset();
+ requestResponseReceived = false;
+ request->send();
- Watchdog watchdog(timeout, networkFactories->getTimerFactory());
- while (!watchdog.getTimedOut() && !requestResponseReceived) {
- eventLoop->runUntilEvents();
- }
- return Sluift::Response(requestResponse, watchdog.getTimedOut() ?
- boost::make_shared<ErrorPayload>(ErrorPayload::RemoteServerTimeout) : requestError);
+ Watchdog watchdog(timeout, networkFactories->getTimerFactory());
+ while (!watchdog.getTimedOut() && !requestResponseReceived) {
+ eventLoop->runUntilEvents();
+ }
+ return Sluift::Response(requestResponse, watchdog.getTimedOut() ?
+ std::make_shared<ErrorPayload>(ErrorPayload::RemoteServerTimeout) : requestError);
}
diff --git a/Sluift/SluiftClient.h b/Sluift/SluiftClient.h
index bedd6ba..ac4c582 100644
--- a/Sluift/SluiftClient.h
+++ b/Sluift/SluiftClient.h
@@ -1,133 +1,148 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2018 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
#include <deque>
-#include <boost/optional.hpp>
+
#include <boost/bind.hpp>
#include <boost/function.hpp>
+#include <boost/optional.hpp>
+#include <Swiften/Client/Client.h>
+#include <Swiften/Client/ClientBlockListManager.h>
+#include <Swiften/Client/ClientError.h>
#include <Swiften/Client/ClientOptions.h>
-#include <Sluift/globals.h>
#include <Swiften/Elements/IQ.h>
#include <Swiften/Elements/Message.h>
#include <Swiften/Elements/Presence.h>
-#include <Swiften/Queries/GenericRequest.h>
-#include <Swiften/Roster/XMPPRosterItem.h>
-#include <Swiften/Client/ClientError.h>
-#include <Swiften/Network/NetworkFactories.h>
-#include <Swiften/Client/Client.h>
#include <Swiften/EventLoop/SimpleEventLoop.h>
-#include <Sluift/Watchdog.h>
+#include <Swiften/Network/NetworkFactories.h>
#include <Swiften/PubSub/PubSubManager.h>
+#include <Swiften/Queries/GenericRequest.h>
+#include <Swiften/Roster/XMPPRosterItem.h>
+
#include <Sluift/Response.h>
+#include <Sluift/Watchdog.h>
namespace Swift {
- struct SluiftGlobals;
- class ClientXMLTracer;
- class Client;
- class Stanza;
- class Payload;
- class ErrorPayload;
- class JID;
-
- class SluiftClient {
- public:
- struct Event {
- enum Type {
- MessageType,
- PresenceType,
- PubSubEventType
- };
-
- Event(boost::shared_ptr<Message> stanza) : type(MessageType), stanza(stanza) {}
- Event(boost::shared_ptr<Presence> stanza) : type(PresenceType), stanza(stanza) {}
- Event(const JID& from, boost::shared_ptr<PubSubEventPayload> payload) : type(PubSubEventType), from(from), pubsubEvent(payload) {}
-
- Type type;
-
- // Message & Presence
- boost::shared_ptr<Stanza> stanza;
-
- // PubSubEvent
- JID from;
- boost::shared_ptr<PubSubEventPayload> pubsubEvent;
- };
-
- SluiftClient(
- const JID& jid,
- const std::string& password,
- NetworkFactories* networkFactories,
- SimpleEventLoop* eventLoop,
- SluiftGlobals* globals);
- ~SluiftClient();
-
- Client* getClient() {
- return client;
- }
-
- ClientOptions& getOptions() {
- return options;
- }
-
- void connect();
- void connect(const std::string& host);
- void waitConnected();
- bool isConnected() const;
-
- template<typename T>
- Sluift::Response sendPubSubRequest(
- IQ::Type type, const JID& jid, boost::shared_ptr<T> payload, int timeout) {
- return sendRequest(client->getPubSubManager()->createRequest(
- type, jid, payload), timeout);
- }
-
- template<typename REQUEST_TYPE>
- Sluift::Response sendRequest(REQUEST_TYPE request, int timeout) {
- boost::signals::scoped_connection c = request->onResponse.connect(
- boost::bind(&SluiftClient::handleRequestResponse, this, _1, _2));
- return doSendRequest(request, timeout);
- }
-
- template<typename REQUEST_TYPE>
- Sluift::Response sendVoidRequest(REQUEST_TYPE request, int timeout) {
- boost::signals::scoped_connection c = request->onResponse.connect(
- boost::bind(&SluiftClient::handleRequestResponse, this, boost::shared_ptr<Payload>(), _1));
- return doSendRequest(request, timeout);
- }
-
- void disconnect();
- void setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os);
- boost::optional<SluiftClient::Event> getNextEvent(int timeout,
- boost::function<bool (const Event&)> condition = 0);
- std::vector<XMPPRosterItem> getRoster();
-
- private:
- Sluift::Response doSendRequest(boost::shared_ptr<Request> request, int timeout);
-
- void handleIncomingMessage(boost::shared_ptr<Message> stanza);
- void handleIncomingPresence(boost::shared_ptr<Presence> stanza);
- void handleIncomingPubSubEvent(const JID& from, boost::shared_ptr<PubSubEventPayload> event);
- void handleInitialRosterPopulated();
- void handleRequestResponse(boost::shared_ptr<Payload> response, boost::shared_ptr<ErrorPayload> error);
- void handleDisconnected(const boost::optional<ClientError>& error);
-
- private:
- NetworkFactories* networkFactories;
- SimpleEventLoop* eventLoop;
- SluiftGlobals* globals;
- Client* client;
- ClientOptions options;
- ClientXMLTracer* tracer;
- bool rosterReceived;
- std::deque<Event> pendingEvents;
- boost::optional<ClientError> disconnectedError;
- bool requestResponseReceived;
- boost::shared_ptr<Payload> requestResponse;
- boost::shared_ptr<ErrorPayload> requestError;
- };
+ struct SluiftGlobals;
+ class ClientXMLTracer;
+ class Client;
+ class Stanza;
+ class Payload;
+ class ErrorPayload;
+ class JID;
+
+ class SluiftClient {
+ public:
+ struct Event {
+ enum Type {
+ MessageType,
+ PresenceType,
+ PubSubEventType,
+ BlockEventType,
+ UnblockEventType,
+ RosterAddType,
+ RosterRemoveType,
+ RosterUpdateType
+ };
+
+ Event(std::shared_ptr<Message> stanza) : type(MessageType), stanza(stanza) {}
+ Event(std::shared_ptr<Presence> stanza) : type(PresenceType), stanza(stanza) {}
+ Event(const JID& from, std::shared_ptr<PubSubEventPayload> payload) : type(PubSubEventType), from(from), pubsubEvent(payload) {}
+ Event(const JID& item, Type type) : type(type), item(item) {}
+ Type type;
+
+ // Message & Presence
+ std::shared_ptr<Stanza> stanza;
+
+ // PubSubEvent
+ JID from;
+ std::shared_ptr<PubSubEventPayload> pubsubEvent;
+
+ // Blocklist & Roster Push
+ JID item;
+ };
+
+ SluiftClient(
+ const JID& jid,
+ const std::string& password,
+ NetworkFactories* networkFactories,
+ SimpleEventLoop* eventLoop);
+ ~SluiftClient();
+
+ Client* getClient() {
+ return client;
+ }
+
+ ClientOptions& getOptions() {
+ return options;
+ }
+
+ void connect();
+ void waitConnected(int timeout);
+ bool isConnected() const;
+ void setTraceEnabled(bool b);
+
+ template<typename T>
+ Sluift::Response sendPubSubRequest(
+ IQ::Type type, const JID& jid, std::shared_ptr<T> payload, int timeout) {
+ return sendRequest(client->getPubSubManager()->createRequest(
+ type, jid, payload), timeout);
+ }
+
+ template<typename REQUEST_TYPE>
+ Sluift::Response sendRequest(REQUEST_TYPE request, int timeout) {
+ boost::signals2::scoped_connection c(request->onResponse.connect(
+ boost::bind(&SluiftClient::handleRequestResponse, this, _1, _2)));
+ return doSendRequest(request, timeout);
+ }
+
+ template<typename REQUEST_TYPE>
+ Sluift::Response sendVoidRequest(REQUEST_TYPE request, int timeout) {
+ boost::signals2::scoped_connection c(request->onResponse.connect(
+ boost::bind(&SluiftClient::handleRequestResponse, this, std::shared_ptr<Payload>(), _1)));
+ return doSendRequest(request, timeout);
+ }
+
+ void disconnect();
+ void setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os);
+ boost::optional<SluiftClient::Event> getNextEvent(int timeout,
+ boost::function<bool (const Event&)> condition = boost::function<bool (const Event&)>());
+ std::vector<XMPPRosterItem> getRoster(int timeout);
+ std::vector<JID> getBlockList(int timeout);
+
+ private:
+ Sluift::Response doSendRequest(std::shared_ptr<Request> request, int timeout);
+
+ void handleIncomingMessage(std::shared_ptr<Message> stanza);
+ void handleIncomingPresence(std::shared_ptr<Presence> stanza);
+ void handleIncomingPubSubEvent(const JID& from, std::shared_ptr<PubSubEventPayload> event);
+ void handleIncomingBlockEvent(const JID& item);
+ void handleIncomingUnblockEvent(const JID& item);
+ void handleInitialRosterPopulated();
+ void handleIncomingRosterAdd(const JID& item);
+ void handleIncomingRosterRemove(const JID& item);
+ void handleIncomingRosterUpdate(const JID& item);
+ void handleRequestResponse(std::shared_ptr<Payload> response, std::shared_ptr<ErrorPayload> error);
+ void handleDisconnected(const boost::optional<ClientError>& error);
+
+ private:
+ NetworkFactories* networkFactories;
+ SimpleEventLoop* eventLoop;
+ Client* client;
+ ClientOptions options;
+ ClientXMLTracer* tracer;
+ bool rosterReceived = false;
+ bool blockListReceived = false;
+ std::deque<Event> pendingEvents;
+ boost::optional<ClientError> disconnectedError;
+ bool requestResponseReceived = false;
+ std::shared_ptr<Payload> requestResponse;
+ std::shared_ptr<ErrorPayload> requestError;
+ };
}
diff --git a/Sluift/SluiftComponent.cpp b/Sluift/SluiftComponent.cpp
new file mode 100644
index 0000000..74728ee
--- /dev/null
+++ b/Sluift/SluiftComponent.cpp
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2014-2018 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/SluiftComponent.h>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <Swiften/Component/Component.h>
+#include <Swiften/Component/ComponentXMLTracer.h>
+#include <Swiften/Elements/Message.h>
+#include <Swiften/Elements/Presence.h>
+#include <Swiften/Queries/RawRequest.h>
+#include <Swiften/Roster/XMPPRoster.h>
+
+#include <Sluift/Helpers.h>
+#include <Sluift/Lua/Exception.h>
+#include <Sluift/SluiftGlobals.h>
+
+using namespace Swift;
+
+SluiftComponent::SluiftComponent(
+ const JID& jid,
+ const std::string& password,
+ NetworkFactories* networkFactories,
+ SimpleEventLoop* eventLoop):
+ networkFactories(networkFactories),
+ eventLoop(eventLoop),
+ tracer(nullptr) {
+ component = new Component(jid, password, networkFactories);
+ component->onError.connect(boost::bind(&SluiftComponent::handleError, this, _1));
+ component->onMessageReceived.connect(boost::bind(&SluiftComponent::handleIncomingMessage, this, _1));
+ component->onPresenceReceived.connect(boost::bind(&SluiftComponent::handleIncomingPresence, this, _1));
+}
+
+SluiftComponent::~SluiftComponent() {
+ delete tracer;
+ delete component;
+}
+
+void SluiftComponent::connect(const std::string& host, unsigned short port) {
+ if (component->isActive()) {
+ throw Lua::Exception("Component is already connecting or connected");
+ }
+ disconnectedError = boost::optional<ComponentError>();
+ component->connect(host, port);
+}
+
+void SluiftComponent::setTraceEnabled(bool b) {
+ if (b && !tracer) {
+ tracer = new ComponentXMLTracer(component);
+ }
+ else if (!b && tracer) {
+ delete tracer;
+ tracer = nullptr;
+ }
+}
+
+void SluiftComponent::waitConnected(int timeout) {
+ Watchdog watchdog(timeout, networkFactories->getTimerFactory());
+ while (!watchdog.getTimedOut() && !disconnectedError && !component->isAvailable()) {
+ eventLoop->runUntilEvents();
+ }
+ if (watchdog.getTimedOut()) {
+ component->disconnect();
+ throw Lua::Exception("Timeout while connecting");
+ }
+ if (disconnectedError) {
+ throw Lua::Exception(getErrorString(*disconnectedError));
+ }
+}
+
+bool SluiftComponent::isConnected() const {
+ return component->isAvailable();
+}
+
+void SluiftComponent::disconnect() {
+ component->disconnect();
+ while (component->isActive()) {
+ eventLoop->runUntilEvents();
+ }
+}
+
+void SluiftComponent::setSoftwareVersion(const std::string& name, const std::string& version, const std::string& /* os */) {
+ component->setSoftwareVersion(name, version);
+}
+
+boost::optional<SluiftComponent::Event> SluiftComponent::getNextEvent(
+ int timeout, boost::function<bool (const Event&)> condition) {
+ Watchdog watchdog(timeout, networkFactories->getTimerFactory());
+ size_t currentIndex = 0;
+ while (true) {
+ // Look for pending events in the queue
+ while (currentIndex < pendingEvents.size()) {
+ Event event = pendingEvents[currentIndex];
+ if (!condition || condition(event)) {
+ pendingEvents.erase(
+ pendingEvents.begin()
+ + boost::numeric_cast<int>(currentIndex));
+ return event;
+ }
+ ++currentIndex;
+ }
+
+ // Wait for new events
+ while (!watchdog.getTimedOut() && currentIndex >= pendingEvents.size() && component->isActive()) {
+ eventLoop->runUntilEvents();
+ }
+
+ // Finish if we're disconnected or timed out
+ if (watchdog.getTimedOut() || !component->isActive()) {
+ return boost::optional<Event>();
+ }
+ }
+}
+
+void SluiftComponent::handleIncomingMessage(std::shared_ptr<Message> stanza) {
+ pendingEvents.push_back(Event(stanza));
+}
+
+void SluiftComponent::handleIncomingPresence(std::shared_ptr<Presence> stanza) {
+ pendingEvents.push_back(Event(stanza));
+}
+
+void SluiftComponent::handleRequestResponse(std::shared_ptr<Payload> response, std::shared_ptr<ErrorPayload> error) {
+ requestResponse = response;
+ requestError = error;
+ requestResponseReceived = true;
+}
+
+void SluiftComponent::handleError(const boost::optional<ComponentError>& error) {
+ disconnectedError = error;
+}
+
+Sluift::Response SluiftComponent::doSendRequest(std::shared_ptr<Request> request, int timeout) {
+ requestResponse.reset();
+ requestError.reset();
+ requestResponseReceived = false;
+ request->send();
+
+ Watchdog watchdog(timeout, networkFactories->getTimerFactory());
+ while (!watchdog.getTimedOut() && !requestResponseReceived) {
+ eventLoop->runUntilEvents();
+ }
+ return Sluift::Response(requestResponse, watchdog.getTimedOut() ?
+ std::make_shared<ErrorPayload>(ErrorPayload::RemoteServerTimeout) : requestError);
+}
diff --git a/Sluift/SluiftComponent.h b/Sluift/SluiftComponent.h
new file mode 100644
index 0000000..586a94e
--- /dev/null
+++ b/Sluift/SluiftComponent.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2014-2018 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <deque>
+
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
+#include <boost/optional.hpp>
+
+#include <Swiften/Client/ClientOptions.h>
+#include <Swiften/Component/Component.h>
+#include <Swiften/Component/ComponentError.h>
+#include <Swiften/Elements/IQ.h>
+#include <Swiften/Elements/Message.h>
+#include <Swiften/Elements/Presence.h>
+#include <Swiften/EventLoop/SimpleEventLoop.h>
+#include <Swiften/Network/NetworkFactories.h>
+#include <Swiften/Queries/GenericRequest.h>
+#include <Swiften/Roster/XMPPRosterItem.h>
+
+#include <Sluift/Response.h>
+#include <Sluift/Watchdog.h>
+
+namespace Swift {
+ struct SluiftGlobals;
+ class ComponentXMLTracer;
+ class Component;
+ class Stanza;
+ class Payload;
+ class ErrorPayload;
+ class JID;
+
+ class SluiftComponent {
+ public:
+ struct Event {
+ enum Type {
+ MessageType,
+ PresenceType
+ };
+
+ Event(std::shared_ptr<Message> stanza) : type(MessageType), stanza(stanza) {}
+ Event(std::shared_ptr<Presence> stanza) : type(PresenceType), stanza(stanza) {}
+
+ Type type;
+
+ // Message & Presence
+ std::shared_ptr<Stanza> stanza;
+ };
+
+ SluiftComponent(
+ const JID& jid,
+ const std::string& password,
+ NetworkFactories* networkFactories,
+ SimpleEventLoop* eventLoop);
+ ~SluiftComponent();
+
+ Component* getComponent() {
+ return component;
+ }
+
+ void connect(const std::string& host, unsigned short port);
+ void waitConnected(int timeout);
+ bool isConnected() const;
+ void setTraceEnabled(bool b);
+
+ template<typename REQUEST_TYPE>
+ Sluift::Response sendRequest(REQUEST_TYPE request, int timeout) {
+ boost::signals2::scoped_connection c(request->onResponse.connect(
+ boost::bind(&SluiftComponent::handleRequestResponse, this, _1, _2)));
+ return doSendRequest(request, timeout);
+ }
+
+ template<typename REQUEST_TYPE>
+ Sluift::Response sendVoidRequest(REQUEST_TYPE request, int timeout) {
+ boost::signals2::scoped_connection c(request->onResponse.connect(
+ boost::bind(&SluiftComponent::handleRequestResponse, this, std::shared_ptr<Payload>(), _1)));
+ return doSendRequest(request, timeout);
+ }
+
+ void disconnect();
+ void setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os);
+ boost::optional<SluiftComponent::Event> getNextEvent(int timeout,
+ boost::function<bool (const Event&)> condition = boost::function<bool (const Event&)>());
+
+ private:
+ Sluift::Response doSendRequest(std::shared_ptr<Request> request, int timeout);
+
+ void handleIncomingMessage(std::shared_ptr<Message> stanza);
+ void handleIncomingPresence(std::shared_ptr<Presence> stanza);
+ void handleRequestResponse(std::shared_ptr<Payload> response, std::shared_ptr<ErrorPayload> error);
+ void handleError(const boost::optional<ComponentError>& error);
+
+ private:
+ NetworkFactories* networkFactories;
+ SimpleEventLoop* eventLoop;
+ Component* component;
+ ComponentXMLTracer* tracer;
+ std::deque<Event> pendingEvents;
+ boost::optional<ComponentError> disconnectedError;
+ bool requestResponseReceived = false;
+ std::shared_ptr<Payload> requestResponse;
+ std::shared_ptr<ErrorPayload> requestError;
+ };
+}
diff --git a/Sluift/SluiftGlobals.h b/Sluift/SluiftGlobals.h
index 03c1c1a..14ed6f3 100644
--- a/Sluift/SluiftGlobals.h
+++ b/Sluift/SluiftGlobals.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2014 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,16 +9,29 @@
#include <Sluift/LuaElementConvertors.h>
#include <Swiften/EventLoop/SimpleEventLoop.h>
#include <Swiften/Network/BoostNetworkFactories.h>
+#include <Swiften/TLS/PlatformTLSFactories.h>
+#ifdef HAVE_ITUNES
+#include <Sluift/ITunesInterface.h>
+#endif
+#include <signal.h>
namespace Swift {
- struct SluiftGlobals {
- SluiftGlobals() : networkFactories(&eventLoop) {}
+ struct SluiftGlobals {
+ SluiftGlobals() :
+ networkFactories(&eventLoop),
+ coreLibIndex(-1),
+ moduleLibIndex(-1),
+ interruptRequested(0) {}
- int timeout;
- bool debug;
- LuaElementConvertors elementConvertor;
- SimpleEventLoop eventLoop;
- BoostNetworkFactories networkFactories;
- int bootIndex;
- };
+ LuaElementConvertors elementConvertor;
+ SimpleEventLoop eventLoop;
+ BoostNetworkFactories networkFactories;
+ PlatformTLSFactories tlsFactories;
+ int coreLibIndex;
+ int moduleLibIndex;
+ sig_atomic_t interruptRequested;
+#ifdef HAVE_ITUNES
+ ITunesInterface iTunes;
+#endif
+ };
}
diff --git a/Sluift/StandardTerminal.cpp b/Sluift/StandardTerminal.cpp
new file mode 100644
index 0000000..1378346
--- /dev/null
+++ b/Sluift/StandardTerminal.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/StandardTerminal.h>
+
+#include <iostream>
+#include <stdexcept>
+
+#include <boost/optional.hpp>
+
+using namespace Swift;
+
+StandardTerminal::StandardTerminal() {
+}
+
+StandardTerminal::~StandardTerminal() {
+}
+
+void StandardTerminal::printError(const std::string& message) {
+ std::cout << message << std::endl;
+}
+
+boost::optional<std::string> StandardTerminal::readLine(const std::string& prompt) {
+ std::cout << prompt << std::flush;
+ std::string input;
+ if (!std::getline(std::cin, input)) {
+ if (std::cin.eof()) {
+ return boost::optional<std::string>();
+ }
+ throw std::runtime_error("Input error");
+ }
+ return input;
+}
+
+void StandardTerminal::addToHistory(const std::string&) {
+}
diff --git a/Sluift/StandardTerminal.h b/Sluift/StandardTerminal.h
new file mode 100644
index 0000000..f32bd1c
--- /dev/null
+++ b/Sluift/StandardTerminal.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2013-2017 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Sluift/Terminal.h>
+
+namespace Swift {
+ class StandardTerminal : public Terminal {
+ public:
+ StandardTerminal();
+ virtual ~StandardTerminal() override;
+
+ virtual boost::optional<std::string> readLine(const std::string& prompt) override;
+ virtual void printError(const std::string& message) override;
+ virtual void addToHistory(const std::string& command) override;
+ };
+}
diff --git a/Sluift/Terminal.cpp b/Sluift/Terminal.cpp
new file mode 100644
index 0000000..4b54a87
--- /dev/null
+++ b/Sluift/Terminal.cpp
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/Terminal.h>
+
+using namespace Swift;
+
+Terminal::Terminal() : completer(nullptr) {
+}
+
+Terminal::~Terminal() {
+}
diff --git a/Sluift/Terminal.h b/Sluift/Terminal.h
new file mode 100644
index 0000000..3443d16
--- /dev/null
+++ b/Sluift/Terminal.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <boost/optional/optional.hpp>
+
+namespace Swift {
+ class Completer;
+
+ class Terminal {
+ public:
+ Terminal();
+ virtual ~Terminal();
+
+ Completer* getCompleter() const {
+ return completer;
+ }
+
+ void setCompleter(Completer* completer) {
+ this->completer = completer;
+ }
+
+ virtual boost::optional<std::string> readLine(const std::string& prompt) = 0;
+ virtual void addToHistory(const std::string& command) = 0;
+ virtual void printError(const std::string& message) = 0;
+
+ private:
+ Completer* completer;
+ };
+}
diff --git a/Sluift/Tests/FormTest.lua b/Sluift/Tests/FormTest.lua
index 7b6b4af..d584646 100644
--- a/Sluift/Tests/FormTest.lua
+++ b/Sluift/Tests/FormTest.lua
@@ -1,7 +1,7 @@
--[[
- Copyright (c) 2013 Remko Tronçon
- Licensed under the GNU General Public License v3.
- See Documentation/Licenses/GPLv3.txt for more information.
+ Copyright (c) 2013-2016 Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
--]]
example_form = [[
@@ -13,7 +13,10 @@ example_form = [[
</field>
<field type='fixed'><value>Section 1: Bot Info</value></field>
<field type='text-single' label='The name of your bot' var='botname'/>
- <field type='text-multi' label='Helpful description of your bot' var='description'/>
+ <field type='text-multi' label='Helpful description of your bot' var='description'>
+ <value>This is</value>
+ <value>my bot</value>
+ </field>
<field type='boolean' label='Public bot?' var='public'>
<required/>
</field>
@@ -59,10 +62,10 @@ assert(public_field['required'] == true)
-- Test multi field
features_field = form['fields'][8]
assert(features_field['name'] == 'features')
-assert(type(features_field['values']) == 'table')
-assert(#features_field['values'] == 2)
-assert(features_field['values'][1] == 'news')
-assert(features_field['values'][2] == 'search')
+assert(type(features_field['value']) == 'table')
+assert(#features_field['value'] == 2)
+assert(features_field['value'][1] == 'news')
+assert(features_field['value'][2] == 'search')
-- Test shortcut index
assert(form['features']['name'] == 'features')
@@ -71,9 +74,31 @@ assert(form['FORM_TYPE']['value'] == 'jabber:bot')
-- Test response form
submission = form:create_submission()
assert(#(submission.fields) == 8)
+description_submit_value = submission['description']['value']
+assert(type(description_submit_value) == 'table')
+assert(description_submit_value[1] == 'This is')
+assert(description_submit_value[2] == 'my bot')
+
submission['description'] = 'my description'
assert(submission['description']['value'] == 'my description')
submission['type'] = 'cancel'
-assert(#(submission.fields) == 8)
+
+-- Test text-multi field
+text_multi_field = form['fields'][4]
+assert(text_multi_field['name'] == 'description')
+assert(type(text_multi_field['value']) == 'table')
+
--print(sluift.to_xml({type = 'form', data = form}))
+
+-- test parsing an empty form -- this had issues as reported in SWIFT-174
+empty_form = [[<x xmlns='jabber:x:data' type='form'/>]]
+form = sluift.from_xml(empty_form)
+-- and check if we can access all fields without problems
+assert(type(form._type))
+assert(type(form.title))
+assert(type(form.instructions))
+assert(type(form.type))
+assert(type(form.fields))
+assert(type(form.items))
+assert(type(form.reported_items))
diff --git a/Sluift/UnitTest/TokenizeTest.cpp b/Sluift/UnitTest/TokenizeTest.cpp
new file mode 100644
index 0000000..cd617b5
--- /dev/null
+++ b/Sluift/UnitTest/TokenizeTest.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include <Sluift/tokenize.h>
+
+using namespace Swift;
+
+class TokenizeTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(TokenizeTest);
+ CPPUNIT_TEST(testTokenize);
+ CPPUNIT_TEST(testTokenize);
+ CPPUNIT_TEST(testTokenize_String);
+ CPPUNIT_TEST(testTokenize_IncompleteString);
+ CPPUNIT_TEST(testTokenize_Identifier);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void testTokenize() {
+ std::vector<std::string> tokens = Lua::tokenize("foo.bar + 1.23 - bam");
+
+ CPPUNIT_ASSERT_EQUAL(7, static_cast<int>(tokens.size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("foo"), tokens[0]);
+ CPPUNIT_ASSERT_EQUAL(std::string("."), tokens[1]);
+ CPPUNIT_ASSERT_EQUAL(std::string("bar"), tokens[2]);
+ CPPUNIT_ASSERT_EQUAL(std::string("+"), tokens[3]);
+ CPPUNIT_ASSERT_EQUAL(std::string("1.23"), tokens[4]);
+ CPPUNIT_ASSERT_EQUAL(std::string("-"), tokens[5]);
+ CPPUNIT_ASSERT_EQUAL(std::string("bam"), tokens[6]);
+ }
+
+ void testTokenize_String() {
+ std::vector<std::string> tokens = Lua::tokenize(" foo .. \"1234\\\"bla blo\"");
+
+ CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(tokens.size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("foo"), tokens[0]);
+ CPPUNIT_ASSERT_EQUAL(std::string(".."), tokens[1]);
+ CPPUNIT_ASSERT_EQUAL(std::string("\"1234\\\"bla blo\""), tokens[2]);
+ }
+
+ void testTokenize_IncompleteString() {
+ std::vector<std::string> tokens = Lua::tokenize("\"1234");
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(tokens.size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("\"1234"), tokens[0]);
+ }
+
+ void testTokenize_Identifier() {
+ std::vector<std::string> tokens = Lua::tokenize("foo.bar_baz");
+
+ CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(tokens.size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("foo"), tokens[0]);
+ CPPUNIT_ASSERT_EQUAL(std::string("."), tokens[1]);
+ CPPUNIT_ASSERT_EQUAL(std::string("bar_baz"), tokens[2]);
+ }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(TokenizeTest);
diff --git a/Sluift/Watchdog.cpp b/Sluift/Watchdog.cpp
new file mode 100644
index 0000000..a99d63a
--- /dev/null
+++ b/Sluift/Watchdog.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/Watchdog.h>
+
+#include <Sluift/globals.h>
+
+static const int INTERVAL_MS = 500;
+
+
+using namespace Swift;
+
+Watchdog::Watchdog(int timeout, TimerFactory* timerFactory) :
+ remainingTime(timeout),
+ timerFactory(timerFactory),
+ timedOut(false) {
+ Sluift::globals.interruptRequested = 0;
+
+ int nextTimeout = remainingTime >= 0 ? std::min(remainingTime, INTERVAL_MS) : INTERVAL_MS;
+
+ timer = timerFactory->createTimer(nextTimeout);
+ timer->onTick.connect(boost::bind(&Watchdog::handleTimerTick, this));
+ remainingTime -= nextTimeout;
+ timer->start();
+}
+
+Watchdog::~Watchdog() {
+ if (timer) {
+ timer->stop();
+ }
+}
+
+void Watchdog::handleTimerTick() {
+ if (Sluift::globals.interruptRequested || remainingTime == 0) {
+ timedOut = true;
+ }
+ else {
+ int nextTimeout = remainingTime >= 0 ? std::min(remainingTime, INTERVAL_MS) : INTERVAL_MS;
+ if (nextTimeout != INTERVAL_MS) {
+ timer->onTick.disconnect(boost::bind(&Watchdog::handleTimerTick, this));
+ timer = timerFactory->createTimer(nextTimeout);
+ timer->onTick.connect(boost::bind(&Watchdog::handleTimerTick, this));
+ }
+ remainingTime -= nextTimeout;
+ timer->start();
+ }
+}
diff --git a/Sluift/Watchdog.h b/Sluift/Watchdog.h
index 95b6971..271c610 100644
--- a/Sluift/Watchdog.h
+++ b/Sluift/Watchdog.h
@@ -1,44 +1,32 @@
/*
- * Copyright (c) 2011 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2014 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
+#include <algorithm>
+
#include <Swiften/Network/TimerFactory.h>
namespace Swift {
- class Watchdog {
- public:
- Watchdog(int timeout, TimerFactory* timerFactory) : timedOut(false) {
- if (timeout > 0) {
- timer = timerFactory->createTimer(timeout);
- timer->start();
- timer->onTick.connect(boost::bind(&Watchdog::handleTimerTick, this));
- }
- else if (timeout == 0) {
- timedOut = true;
- }
- }
-
- ~Watchdog() {
- if (timer) {
- timer->stop();
- }
- }
+ class Watchdog {
+ public:
+ Watchdog(int timeout, TimerFactory* timerFactory);
+ ~Watchdog();
- bool getTimedOut() const {
- return timedOut;
- }
+ bool getTimedOut() const {
+ return timedOut;
+ }
- private:
- void handleTimerTick() {
- timedOut = true;
- }
+ private:
+ void handleTimerTick();
- private:
- Timer::ref timer;
- bool timedOut;
- };
+ private:
+ Timer::ref timer;
+ int remainingTime;
+ TimerFactory* timerFactory;
+ bool timedOut;
+ };
}
diff --git a/Sluift/boot.lua b/Sluift/boot.lua
deleted file mode 100644
index 2505736..0000000
--- a/Sluift/boot.lua
+++ /dev/null
@@ -1,436 +0,0 @@
---[[
- Copyright (c) 2013 Remko Tronçon
- Licensed under the GNU General Public License.
- See the COPYING file for more information.
---]]
-
-local Client = {}
-local PubSub = {}
-local PubSubNode = {}
-
---------------------------------------------------------------------------------
--- Utility methods
---------------------------------------------------------------------------------
-
-local function merge_tables(...)
- local result = {}
- for _, table in ipairs({...}) do
- for k, v in pairs(table) do
- result[k] = v
- end
- end
- return result
-end
-
-local function clone_table(table)
- return merge_tables(table)
-end
-
-local function parse_options(unnamed_parameters, arg1, arg2)
- local options = {}
- if type(arg1) == 'table' then
- options = arg1
- f = arg2
- elseif type(arg1) == 'function' then
- f = arg1
- end
- options.f = f or options.f
- return clone_table(options)
-end
-
-
-local function table_value_tostring(value)
- local result = tostring(value)
- if type(value) == 'number' then return result
- elseif type(value) == 'boolean' then return result
- elseif type(value) == 'string' then return "'" .. result .. "'"
- else return '<' .. result .. '>'
- end
-end
-
-local function table_tostring(table, indent, accumulator)
- local INDENT = ' '
- local accumulator = accumulator or ''
- local indent = indent or ''
- accumulator = accumulator .. '{'
- local is_first = true
- for key, value in pairs(table) do
- if type(value) ~= 'function' then
- if not is_first then
- accumulator = accumulator .. ','
- end
- is_first = false
- accumulator = accumulator .. '\n' .. indent .. INDENT .. '[' .. table_value_tostring(key) .. '] = '
- if type(value) == 'table' then
- accumulator = table_tostring(value, indent .. INDENT, accumulator)
- else
- accumulator = accumulator .. table_value_tostring(value)
- end
- end
- end
- if not is_first then
- accumulator = accumulator .. '\n' .. indent
- end
- accumulator = accumulator .. '}'
- return accumulator
-end
-
-local function tprint(table)
- print(table_tostring(table))
-end
-
-local function register_table_tostring(table)
- if type(table) == 'table' then
- local metatable = getmetatable(table)
- if not metatable then
- metatable = {}
- setmetatable(table, metatable)
- end
- metatable.__tostring = table_tostring
- end
- return table
-end
-
-local function get_by_type(table, typ)
- for _, v in ipairs(table) do
- if v['_type'] == typ then
- return v
- end
- end
-end
-
-local function register_get_by_type_index(table)
- if type(table) == 'table' then
- local metatable = getmetatable(table)
- if not metatable then
- metatable = {}
- setmetatable(table, metatable)
- end
- metatable.__index = get_by_type
- end
- return table
-end
-
---------------------------------------------------------------------------------
--- Client
---------------------------------------------------------------------------------
-
-function Client.connect (client, ...)
- local options = parse_options({}, ...)
- local f = options.f
- client:async_connect(options)
- client:wait_connected()
- if f then
- local result = { xpcall(function() return f(client) end, debug.traceback) }
- client:disconnect()
- if result[1] then
- table.remove(result, 1)
- return unpack(result)
- else
- error(result[2])
- end
- end
- return true
-end
-
-function Client.events (client, options)
- local function client_events_iterator(s)
- return s['client']:get_next_event(s['options'])
- end
- return client_events_iterator, {client = client, options = options}
-end
-
-function Client.for_each_event (client, ...)
- local options = parse_options({}, ...)
- if not type(options.f) == 'function' then error('Expected function') end
- for event in client:events(options) do
- local result = options.f(event)
- if result then
- return result
- end
- end
-end
-
-for method, event_type in pairs({message = 'message', presence = 'presence', pubsub_event = 'pubsub'}) do
- Client['for_each_' .. method] = function (client, ...)
- local options = parse_options({}, ...)
- options['type'] = event_type
- return client:for_each_event (options)
- end
-
- Client['get_next_' .. method] = function (client, ...)
- local options = parse_options({}, ...)
- options['type'] = event_type
- return client:get_next_event(options)
- end
-end
-
-for method, event_type in pairs({messages = 'message', pubsub_events = 'pubsub'}) do
- Client[method] = function (client, ...)
- local options = parse_options({}, ...)
- options['type'] = event_type
- return client:events (options)
- end
-end
-
---
--- Register get_* and set_* convenience methods for some type of queries
---
--- Example usages:
--- client:get_software_version{to = 'alice@wonderland.lit'}
--- client:set_command{to = 'alice@wonderland.lit', command = { type = 'execute', node = 'uptime' }}
---
-local get_set_shortcuts = {
- get = {'software_version', 'disco_items', 'xml', 'dom', 'vcard'},
- set = {'command'}
-}
-for query_action, query_types in pairs(get_set_shortcuts) do
- for _, query_type in ipairs(query_types) do
- Client[query_action .. '_' .. query_type] = function (client, options)
- options = options or {}
- if type(options) ~= 'table' then error('Invalid options: ' .. options) end
- options['query'] = merge_tables({_type = query_type}, options[query_type] or {})
- return client[query_action](client, options)
- end
- end
-end
-
-function Client.pubsub (client, jid)
- local result = { client = client, jid = jid }
- setmetatable(result, PubSub)
- return result
-end
-
---------------------------------------------------------------------------------
--- PubSub
---------------------------------------------------------------------------------
-
-PubSub.__index = PubSub
-
-local function process_pubsub_event (event)
- if event._type == 'pubsub_event_items' then
- -- Add 'item' shortcut to payload of first item
- event.item = event.items and event.items[1] and
- event.items[1].data and event.items[1].data[1]
- end
-end
-
-function PubSub.list_nodes (service, options)
- return service.client:get_disco_items(merge_tables({to = service.jid}, options))
-end
-
-function PubSub.node (service, node)
- local result = { client = service.client, jid = service.jid, node = node }
- setmetatable(result, PubSubNode)
- return result
-end
-
-local simple_pubsub_queries = {
- get_default_configuration = 'pubsub_owner_default',
- get_subscriptions = 'pubsub_subscriptions',
- get_affiliations = 'pubsub_affiliations',
- get_default_subscription_options = 'pubsub_default',
-}
-for method, query_type in pairs(simple_pubsub_queries) do
- PubSub[method] = function (service, options)
- options = options or {}
- return service.client:query_pubsub(merge_tables(
- { type = 'get', to = service.jid, query = { _type = query_type } },
- options))
- end
-end
-
-for _, method in ipairs({'events', 'get_next_event', 'for_each_event'}) do
- PubSub[method] = function (node, ...)
- local options = parse_options({}, ...)
- options['if'] = function (event)
- return event.type == 'pubsub' and event.from == node.jid and event.node == node
- end
- return node.client[method](node.client, options)
- end
-end
-
---------------------------------------------------------------------------------
--- PubSubNode
---------------------------------------------------------------------------------
-
-PubSubNode.__index = PubSubNode
-
-local function pubsub_node_configuration_to_form(configuration)
- if not configuration then
- return
- end
- local fields = { {name = 'form_type', value = 'http://jabber.org/protocol/pubsub#node_config'} }
- for var, value in pairs(configuration) do
- fields[#fields+1] = { name = var, value = value }
- end
- return { type = "submit", fields = fields }
-end
-
-function PubSubNode.list_items (node, options)
- return node.client:get_disco_items(merge_tables({to = node.jid, query = { node = node.node }}, options))
-end
-
-local simple_pubsub_node_queries = {
- get_configuration = 'pubsub_owner_configure',
- get_subscriptions = 'pubsub_subscriptions',
- get_affiliations = 'pubsub_affiliations',
- get_default_subscription_options = 'pubsub_default',
-}
-for method, query_type in pairs(simple_pubsub_node_queries) do
- PubSubNode[method] = function (node, options)
- return node.client:query_pubsub(merge_tables({
- type = 'get', to = node.jid, query = {
- _type = query_type, node = node.node
- }}, options))
- end
-end
-
-function PubSubNode.get_items (node, ...)
- local options = parse_options({}, ...)
- local items = options.items or {}
- if options.maximum_items then
- items = merge_tables({maximum_items = options.maximum_items}, items)
- end
- items = merge_tables({_type = 'pubsub_items', node = node.node}, items)
- return node.client:query_pubsub(merge_tables({
- type = 'get', to = node.jid, query = items}, options))
-end
-
-function PubSubNode.get_item (node, ...)
- local options = parse_options({}, ...)
- if not type(options.id) == 'string' then error('Expected ID') end
- return PubSubNode.get_items(node, {items = {{id = options.id}}})
-end
-
-function PubSubNode.create (node, options)
- options = options or {}
- local configure
- if options['configuration'] then
- configure = { data = pubsub_node_configuration_to_form(options['configuration']) }
- end
- return node.client:query_pubsub(merge_tables(
- { type = 'set', to = node.jid, query = {
- _type = 'pubsub_create', node = node.node, configure = configure }
- }, options))
-end
-
-function PubSubNode.delete (node, options)
- options = options or {}
- local redirect
- if options['redirect'] then
- redirect = {uri = options['redirect']}
- end
- return node.client:query_pubsub(merge_tables({ type = 'set', to = node.jid, query = {
- _type = 'pubsub_owner_delete', node = node.node, redirect = redirect
- }}, options))
-end
-
-function PubSubNode.set_configuration(node, options)
- options = options or {}
- local configuration = pubsub_node_configuration_to_form(options['configuration'])
- return node.client:query_pubsub(merge_tables(
- { type = 'set', to = node.jid, query = {
- _type = 'pubsub_owner_configure', node = node.node, data = configuration }
- }, options))
-end
-
-function PubSubNode.subscribe(node, ...)
- local options = parse_options(...)
- local jid = options.jid or sluift.jid.to_bare(node.client:jid())
- return node.client:query_pubsub(merge_tables(
- { type = 'set', to = node.jid, query = {
- _type = 'pubsub_subscribe', node = node.node, jid = jid }
- }, options))
-end
-
-function PubSubNode.unsubscribe(node, options)
- options = options or {}
- return node.client:query_pubsub(merge_tables(
- { type = 'set', to = node.jid, query = {
- _type = 'pubsub_unsubscribe', node = node.node, jid = options['jid'] }
- }, options))
-end
-
-function PubSubNode.get_subscription_options (node, options)
- return node.client:query_pubsub(merge_tables(
- { type = 'get', to = node.jid, query = {
- _type = 'pubsub_options', node = node.node, jid = options['jid'] }
- }, options))
-end
-
-function PubSubNode.publish(node, ...)
- local options = parse_options({}, ...)
- local items = options.items or {}
- if options.item then
- if type(options.item) == 'string' or options.item._type then
- items = {{id = options.id, data = { options.item } }}
- options.id = nil
- else
- items = { options.item }
- end
- options.item = nil
- end
- return node.client:query_pubsub(merge_tables(
- { type = 'set', to = node.jid, query = {
- _type = 'pubsub_publish', node = node.node, items = items }
- }, options))
-end
-
-function PubSubNode.retract(node, ...)
- local options = parse_options({}, ...)
- local items = options.items
- if options.id then
- items = {{id = options.id}}
- end
- return node.client:query_pubsub(merge_tables(
- { type = 'set', to = node.jid, query = {
- _type = 'pubsub_retract', node = node.node, items = items, notify = options['notify']
- }}, options))
-end
-
-function PubSubNode.purge(node, ...)
- local options = parse_options({}, ...)
- return node.client:query_pubsub(merge_tables(
- { type = 'set', to = node.jid, query = {
- _type = 'pubsub_owner_purge', node = node.node
- }}, options))
-end
-
--- Iterators over events
-for _, method in ipairs({'events', 'get_next_event', 'for_each_event'}) do
- PubSubNode[method] = function (node, ...)
- local options = parse_options({}, ...)
- options['if'] = function (event)
- return event.type == 'pubsub' and event.from == node.jid and event.node == node.node
- end
- return node.client[method](node.client, options)
- end
-end
-
---------------------------------------------------------------------------------
--- Service discovery
---------------------------------------------------------------------------------
-
-local disco = {
- features = {
- DISCO_INFO = 'http://jabber.org/protocol/disco#info',
- COMMANDS = 'http://jabber.org/protocol/commands',
- USER_LOCATION = 'http://jabber.org/protocol/geoloc',
- USER_TUNE = 'http://jabber.org/protocol/tune',
- USER_AVATAR_METADATA = 'urn:xmpp:avatar:metadata',
- USER_ACTIVITY = 'http://jabber.org/protocol/activity',
- USER_PROFILE = 'urn:xmpp:tmp:profile'
- }
-}
-
---------------------------------------------------------------------------------
-
-return {
- Client = Client,
- register_table_tostring = register_table_tostring,
- register_get_by_type_index = register_get_by_type_index,
- process_pubsub_event = process_pubsub_event,
- tprint = tprint,
- disco = disco,
-}
diff --git a/Sluift/client.cpp b/Sluift/client.cpp
index df43075..814ad45 100644
--- a/Sluift/client.cpp
+++ b/Sluift/client.cpp
@@ -1,564 +1,899 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013-2018 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
-#include <boost/lambda/lambda.hpp>
-#include <boost/lambda/bind.hpp>
#include <boost/assign/list_of.hpp>
-#include <iostream>
-#include <Sluift/SluiftClient.h>
-#include <Swiften/JID/JID.h>
-#include <Swiften/Elements/SoftwareVersion.h>
+#include <Swiften/Base/IDGenerator.h>
+#include <Swiften/Disco/ClientDiscoManager.h>
+#include <Swiften/Elements/DiscoInfo.h>
#include <Swiften/Elements/Message.h>
#include <Swiften/Elements/Presence.h>
#include <Swiften/Elements/RawXMLPayload.h>
#include <Swiften/Elements/RosterItemPayload.h>
#include <Swiften/Elements/RosterPayload.h>
-#include <Swiften/Elements/DiscoInfo.h>
-#include <Swiften/Disco/ClientDiscoManager.h>
-#include <Swiften/Queries/GenericRequest.h>
+#include <Swiften/Elements/SoftwareVersion.h>
+#include <Swiften/JID/JID.h>
#include <Swiften/Presence/PresenceSender.h>
-#include <Swiften/Roster/XMPPRoster.h>
-#include <Swiften/Roster/SetRosterRequest.h>
#include <Swiften/Presence/SubscriptionManager.h>
-#include <Swiften/Roster/XMPPRosterItem.h>
-#include <Sluift/Watchdog.h>
+#include <Swiften/Queries/GenericRequest.h>
+#include <Swiften/Queries/IQRouter.h>
#include <Swiften/Queries/Requests/GetSoftwareVersionRequest.h>
-#include <Sluift/Lua/FunctionRegistration.h>
-#include <Swiften/Base/foreach.h>
+#include <Swiften/Roster/SetRosterRequest.h>
+#include <Swiften/Roster/XMPPRoster.h>
+#include <Swiften/Roster/XMPPRosterItem.h>
+#include <Swiften/TLS/PKCS12Certificate.h>
+
+#include <Sluift/ElementConvertors/IQConvertor.h>
+#include <Sluift/ElementConvertors/MessageConvertor.h>
+#include <Sluift/ElementConvertors/PresenceConvertor.h>
+#include <Sluift/ElementConvertors/StanzaConvertor.h>
+#include <Sluift/ElementConvertors/StatusShowConvertor.h>
#include <Sluift/Lua/Check.h>
-#include <Sluift/Lua/Value.h>
#include <Sluift/Lua/Exception.h>
+#include <Sluift/Lua/FunctionRegistration.h>
#include <Sluift/Lua/LuaUtils.h>
+#include <Sluift/Lua/Value.h>
+#include <Sluift/SluiftClient.h>
#include <Sluift/globals.h>
using namespace Swift;
-namespace lambda = boost::lambda;
-
-static const std::string SLUIFT_CLIENT = Lua::FunctionRegistry::getMetaTableNameForType("Client");
static inline SluiftClient* getClient(lua_State* L) {
- return *Lua::checkUserData<SluiftClient>(L, 1, SLUIFT_CLIENT.c_str());
+ return *Lua::checkUserData<SluiftClient>(L, 1);
+}
+
+static inline int getGlobalTimeout(lua_State* L) {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.moduleLibIndex);
+ lua_getfield(L, -1, "timeout");
+ int result = boost::numeric_cast<int>(lua_tointeger(L, -1));
+ lua_pop(L, 2);
+ return result;
+}
+
+static void addPayloadsToTable(lua_State* L, const std::vector<std::shared_ptr<Payload> >& payloads) {
+ if (!payloads.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(payloads.size()), 0);
+ for (size_t i = 0; i < payloads.size(); ++i) {
+ Sluift::globals.elementConvertor.convertToLua(L, payloads[i]);
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ Lua::registerGetByTypeIndex(L, -1);
+ lua_setfield(L, -2, "payloads");
+ }
+}
+
+static std::shared_ptr<Payload> getPayload(lua_State* L, int index) {
+ if (lua_type(L, index) == LUA_TTABLE) {
+ return std::dynamic_pointer_cast<Payload>(Sluift::globals.elementConvertor.convertFromLua(L, index));
+ }
+ else if (lua_type(L, index) == LUA_TSTRING) {
+ return std::make_shared<RawXMLPayload>(Lua::checkString(L, index));
+ }
+ else {
+ return std::shared_ptr<Payload>();
+ }
+}
+
+static std::vector< std::shared_ptr<Payload> > getPayloadsFromTable(lua_State* L, int index) {
+ index = Lua::absoluteOffset(L, index);
+ std::vector< std::shared_ptr<Payload> > result;
+ lua_getfield(L, index, "payloads");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
+ std::shared_ptr<Payload> payload = getPayload(L, -1);
+ if (payload) {
+ result.push_back(payload);
+ }
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+static void setOptions(lua_State* L, SluiftClient* client) {
+ Lua::checkType(L, 2, LUA_TTABLE);
+ lua_getfield(L, 2, "host");
+ if (!lua_isnil(L, -1)) {
+ client->getOptions().manualHostname = lua_tostring(L, -1);
+ }
+ lua_getfield(L, 2, "port");
+ if (!lua_isnil(L, -1)) {
+ client->getOptions().manualPort = boost::numeric_cast<int>(lua_tointeger(L, -1));
+ }
+ lua_getfield(L, 2, "ack");
+ if (!lua_isnil(L, -1)) {
+ client->getOptions().useAcks = lua_toboolean(L, -1);
+ }
+ lua_getfield(L, 2, "compress");
+ if (!lua_isnil(L, -1)) {
+ client->getOptions().useStreamCompression = lua_toboolean(L, -1);
+ }
+ lua_getfield(L, 2, "tls");
+ if (!lua_isnil(L, -1)) {
+ bool useTLS = lua_toboolean(L, -1);
+ client->getOptions().useTLS = (useTLS ? ClientOptions::UseTLSWhenAvailable : ClientOptions::NeverUseTLS);
+ }
+ lua_getfield(L, 2, "bosh_url");
+ if (!lua_isnil(L, -1)) {
+ client->getOptions().boshURL = URL::fromString(lua_tostring(L, -1));
+ }
+ lua_getfield(L, 2, "allow_plain_without_tls");
+ if (!lua_isnil(L, -1)) {
+ client->getOptions().allowPLAINWithoutTLS = lua_toboolean(L, -1);
+ }
+ lua_pushvalue(L, 1);
}
+
SLUIFT_LUA_FUNCTION(Client, async_connect) {
- SluiftClient* client = getClient(L);
-
- std::string host;
- if (lua_istable(L, 2)) {
- if (boost::optional<std::string> hostString = Lua::getStringField(L, 2, "host")) {
- host = *hostString;
- }
- }
- if (host.empty()) {
- client->connect();
- }
- else {
- client->connect(host);
- }
- return 0;
-}
-
-SLUIFT_LUA_FUNCTION(Client, wait_connected) {
- getClient(L)->waitConnected();
- return 0;
-}
-
-SLUIFT_LUA_FUNCTION(Client, is_connected) {
- lua_pushboolean(L, getClient(L)->isConnected());
- return 1;
-}
-
-SLUIFT_LUA_FUNCTION(Client, disconnect) {
- getClient(L)->disconnect();
- return 0;
-}
-
-SLUIFT_LUA_FUNCTION(Client, set_version) {
- Sluift::globals.eventLoop.runOnce();
- SluiftClient* client = getClient(L);
- if (boost::shared_ptr<SoftwareVersion> version = boost::dynamic_pointer_cast<SoftwareVersion>(Sluift::globals.elementConvertor.convertFromLuaUntyped(L, 2, "software_version"))) {
- client->setSoftwareVersion(version->getName(), version->getVersion(), version->getOS());
- }
- return 0;
-}
-
-SLUIFT_LUA_FUNCTION(Client, get_contacts) {
- Sluift::globals.eventLoop.runOnce();
-
- SluiftClient* client = getClient(L);
- Lua::Table contactsTable;
- foreach(const XMPPRosterItem& item, client->getRoster()) {
- std::string subscription;
- switch(item.getSubscription()) {
- case RosterItemPayload::None: subscription = "none"; break;
- case RosterItemPayload::To: subscription = "to"; break;
- case RosterItemPayload::From: subscription = "from"; break;
- case RosterItemPayload::Both: subscription = "both"; break;
- case RosterItemPayload::Remove: subscription = "remove"; break;
- }
- Lua::Table itemTable = boost::assign::map_list_of
- ("jid", boost::make_shared<Lua::Value>(item.getJID().toString()))
- ("name", boost::make_shared<Lua::Value>(item.getName()))
- ("subscription", boost::make_shared<Lua::Value>(subscription))
- ("groups", boost::make_shared<Lua::Value>(std::vector<Lua::Value>(item.getGroups().begin(), item.getGroups().end())));
- contactsTable[item.getJID().toString()] = boost::make_shared<Lua::Value>(itemTable);
- }
- pushValue(L, contactsTable);
- Lua::registerTableToString(L, -1);
- return 1;
-}
-
-SLUIFT_LUA_FUNCTION(Client, send_message) {
- Sluift::globals.eventLoop.runOnce();
- JID to;
- std::string body;
- int index = 2;
- Message::Type type = Message::Chat;
- if (lua_isstring(L, index)) {
- to = std::string(lua_tostring(L, index));
- ++index;
- if (!lua_isstring(L, index)) {
- std::string body = lua_tostring(L, index);
- ++index;
- }
- }
- if (lua_istable(L, index)) {
- if (boost::optional<std::string> value = Lua::getStringField(L, index, "to")) {
- to = *value;
- }
-
- if (boost::optional<std::string> value = Lua::getStringField(L, index, "body")) {
- body = *value;
- }
-
- if (boost::optional<std::string> value = Lua::getStringField(L, index, "type")) {
- if (*value == "normal") {
- type = Message::Normal;
- }
- else if (*value == "chat") {
- type = Message::Chat;
- }
- else if (*value == "error") {
- type = Message::Error;
- }
- else if (*value == "groupchat") {
- type = Message::Groupchat;
- }
- else if (*value == "headline") {
- type = Message::Headline;
- }
- }
- }
-
- if (!to.isValid()) {
- throw Lua::Exception("Missing 'to'");
- }
- if (body.empty()) {
- throw Lua::Exception("Missing 'body'");
- }
-
- Message::ref message = boost::make_shared<Message>();
- message->setTo(to);
- message->setBody(body);
- message->setType(type);
- getClient(L)->getClient()->sendMessage(message);
- return 0;
-}
-
-SLUIFT_LUA_FUNCTION(Client, send_presence) {
- Sluift::globals.eventLoop.runOnce();
- boost::shared_ptr<Presence> presence = boost::make_shared<Presence>();
-
- int index = 2;
- if (lua_isstring(L, index)) {
- presence->setStatus(lua_tostring(L, index));
- ++index;
- }
- if (lua_istable(L, index)) {
- if (boost::optional<std::string> value = Lua::getStringField(L, index, "to")) {
- presence->setTo(*value);
- }
- if (boost::optional<std::string> value = Lua::getStringField(L, index, "status")) {
- presence->setStatus(*value);
- }
- if (boost::optional<int> value = Lua::getIntField(L, index, "priority")) {
- presence->setPriority(*value);
- }
- if (boost::optional<std::string> value = Lua::getStringField(L, index, "type")) {
- if (*value == "available") {
- presence->setType(Presence::Available);
- }
- else if (*value == "error") {
- presence->setType(Presence::Error);
- }
- else if (*value == "probe") {
- presence->setType(Presence::Probe);
- }
- else if (*value == "subscribe") {
- presence->setType(Presence::Subscribe);
- }
- else if (*value == "subscribed") {
- presence->setType(Presence::Subscribed);
- }
- else if (*value == "unavailable") {
- presence->setType(Presence::Unavailable);
- }
- else if (*value == "unsubscribe") {
- presence->setType(Presence::Unsubscribe);
- }
- else if (*value == "unsubscribed") {
- presence->setType(Presence::Unsubscribed);
- }
- }
- }
-
- getClient(L)->getClient()->getPresenceSender()->sendPresence(presence);
- lua_pushvalue(L, 1);
- return 0;
+ SluiftClient* client = getClient(L);
+ setOptions(L, client);
+ client->connect();
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, set_trace_enabled,
+ "Enable/disable tracing of the data sent/received.\n\n.",
+ "self\n"
+ "enable a boolean specifying whether to enable/disable tracing",
+ ""
+) {
+ getClient(L)->setTraceEnabled(lua_toboolean(L, 1));
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, wait_connected,
+ "Block until the client is connected.\n\nThis is useful after an `async_connect`.",
+ "self",
+ ""
+) {
+ getClient(L)->waitConnected(getGlobalTimeout(L));
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, is_connected,
+ "Checks whether this client is still connected.\n\nReturns a boolean.",
+ "self\n",
+ ""
+) {
+ lua_pushboolean(L, getClient(L)->isConnected());
+ return 1;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, disconnect,
+ "Disconnect from the server",
+ "self\n",
+ ""
+) {
+ Sluift::globals.eventLoop.runOnce();
+ getClient(L)->disconnect();
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, set_version,
+
+ "Sets the published version of this client.",
+
+ "self",
+
+ "name the name of the client software\n"
+ "version the version identifier of this client\n"
+ "os the OS this client is running on\n"
+) {
+ Sluift::globals.eventLoop.runOnce();
+ SluiftClient* client = getClient(L);
+ if (std::shared_ptr<SoftwareVersion> version = std::dynamic_pointer_cast<SoftwareVersion>(Sluift::globals.elementConvertor.convertFromLuaUntyped(L, 2, "software_version"))) {
+ client->setSoftwareVersion(version->getName(), version->getVersion(), version->getOS());
+ }
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, get_contacts,
+ "Returns a table of all the contacts in the contact list.",
+ "self\n",
+ ""
+) {
+ Sluift::globals.eventLoop.runOnce();
+
+ SluiftClient* client = getClient(L);
+ Lua::Table contactsTable;
+ for (const auto& item : client->getRoster(getGlobalTimeout(L))) {
+ std::string subscription;
+ switch(item.getSubscription()) {
+ case RosterItemPayload::None: subscription = "none"; break;
+ case RosterItemPayload::To: subscription = "to"; break;
+ case RosterItemPayload::From: subscription = "from"; break;
+ case RosterItemPayload::Both: subscription = "both"; break;
+ case RosterItemPayload::Remove: subscription = "remove"; break;
+ }
+ Lua::Table itemTable = boost::assign::map_list_of
+ ("jid", std::make_shared<Lua::Value>(item.getJID().toString()))
+ ("name", std::make_shared<Lua::Value>(item.getName()))
+ ("subscription", std::make_shared<Lua::Value>(subscription))
+ ("groups", std::make_shared<Lua::Value>(std::vector<Lua::Value>(item.getGroups().begin(), item.getGroups().end())));
+ contactsTable[item.getJID().toString()] = std::make_shared<Lua::Value>(itemTable);
+ }
+ pushValue(L, contactsTable);
+ Lua::registerTableToString(L, -1);
+ return 1;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, get_block_list,
+ "Returns a table of all the items in the blocking list.",
+ "self\n",
+ ""
+) {
+ Sluift::globals.eventLoop.runOnce();
+ SluiftClient* client = getClient(L);
+ lua_newtable(L);
+ int i = 0;
+ for (const auto& item : client->getBlockList(getGlobalTimeout(L))) {
+ lua_pushstring(L, item.toString().c_str());
+ lua_rawseti(L, -2, boost::numeric_cast<int>(++i));
+ }
+ Lua::registerTableToString(L, -1);
+ return 1;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, add_block,
+ "Adds a user or domain to the blocking list.",
+ "self\n",
+ "jid the JID of the user or domain to add to the blocking list\n"
+
+) {
+ SluiftClient* client = getClient(L);
+ JID jid(Lua::checkString(L, 2));
+ int timeout = getGlobalTimeout(L);
+
+ std::shared_ptr<BlockPayload> payload = std::make_shared<BlockPayload>(std::vector<JID>(1, jid));
+ return client->sendRequest(
+ std::make_shared< GenericRequest<BlockPayload> >(IQ::Set, JID(), payload, client->getClient()->getIQRouter()), timeout).convertToLuaResult(L);
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, remove_block,
+ "Removes a user or domain from the blocking list.",
+ "self\n",
+ "jid the JID of the user or domain to remove from the blocking list\n"
+
+) {
+ SluiftClient* client = getClient(L);
+ JID jid(Lua::checkString(L, 2));
+ int timeout = getGlobalTimeout(L);
+
+ std::shared_ptr<UnblockPayload> payload = std::make_shared<UnblockPayload>(std::vector<JID>(1, jid));
+ return client->sendRequest(
+ std::make_shared< GenericRequest<UnblockPayload> >(IQ::Set, JID(), payload, client->getClient()->getIQRouter()), timeout).convertToLuaResult(L);
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, remove_all_block,
+ "Removes all users and domains from the blocking list.",
+ "self\n",
+ ""
+) {
+ SluiftClient* client = getClient(L);
+ int timeout = getGlobalTimeout(L);
+
+ std::shared_ptr<UnblockPayload> payload = std::make_shared<UnblockPayload>(std::vector<JID>());
+ return client->sendRequest(
+ std::make_shared< GenericRequest<UnblockPayload> >(IQ::Set, JID(), payload, client->getClient()->getIQRouter()), timeout).convertToLuaResult(L);
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, send_message,
+ "Send a message.",
+ "self\n"
+ "to the JID to send the message to\n"
+ "body the body of the message. Can alternatively be specified using the `body` option\n",
+
+ "to the JID to send the message to\n"
+ "id the id to set on the stanza\n"
+ "body the body of the message\n"
+ "subject the subject of the MUC room to set\n"
+ "type the type of message to send (`normal`, `chat`, `error`, `groupchat`, `headline`)\n"
+ "payloads payloads to add to the message\n"
+) {
+ Sluift::globals.eventLoop.runOnce();
+ JID to;
+ boost::optional<std::string> body;
+ boost::optional<std::string> id;
+ boost::optional<std::string> subject;
+ std::vector<std::shared_ptr<Payload> > payloads;
+ int index = 2;
+ Message::Type type = Message::Chat;
+ if (lua_isstring(L, index)) {
+ to = std::string(lua_tostring(L, index));
+ ++index;
+ if (lua_isstring(L, index)) {
+ body = lua_tostring(L, index);
+ ++index;
+ }
+ }
+ if (lua_istable(L, index)) {
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "to")) {
+ to = *value;
+ }
+
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "id")) {
+ id = value;
+ }
+
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "body")) {
+ body = value;
+ }
+
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "type")) {
+ type = MessageConvertor::convertMessageTypeFromString(*value);
+ }
+
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "subject")) {
+ subject = value;
+ }
+
+ payloads = getPayloadsFromTable(L, index);
+ }
+
+ if (!to.isValid()) {
+ throw Lua::Exception("Missing 'to'");
+ }
+ if ((!body || body->empty()) && !subject && payloads.empty()) {
+ throw Lua::Exception("Missing any of 'body', 'subject' or 'payloads'");
+ }
+ Message::ref message = std::make_shared<Message>();
+ message->setTo(to);
+ if (body && !body->empty()) {
+ message->setBody(*body);
+ }
+ if (id) {
+ message->setID(*id);
+ }
+ if (subject) {
+ message->setSubject(*subject);
+ }
+ message->addPayloads(payloads.begin(), payloads.end());
+ message->setType(type);
+ if (!getClient(L)->getClient()->isAvailable()) {
+ throw Lua::Exception("Trying to send message while client is offline.");
+ }
+ getClient(L)->getClient()->sendMessage(message);
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, send_presence,
+ "Send presence.",
+
+ "self\n"
+ "body the text of the presence. Can alternatively be specified using the `status` option\n",
+
+ "to the JID to send the presence to\n"
+ "id the id to set on the stanza\n"
+ "status the text of the presence\n"
+ "show the availability of the presence (`online`, `ffc`, `away`, `xa`, `dnd`)\n"
+ "priority the priority of the presence\n"
+ "type the type of message to send (`available`, `error`, `probe`, `subscribe`, `subscribed`, `unavailable`, `unsubscribe`, `unsubscribed`)\n"
+ "payloads payloads to add to the presence\n"
+) {
+ Sluift::globals.eventLoop.runOnce();
+ std::shared_ptr<Presence> presence = std::make_shared<Presence>();
+
+ int index = 2;
+ if (lua_isstring(L, index)) {
+ presence->setStatus(lua_tostring(L, index));
+ ++index;
+ }
+ if (lua_istable(L, index)) {
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "to")) {
+ presence->setTo(*value);
+ }
+ if (boost::optional<std::string> id = Lua::getStringField(L, index, "id")) {
+ presence->setID(*id);
+ }
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "status")) {
+ presence->setStatus(*value);
+ }
+ if (boost::optional<int> value = Lua::getIntField(L, index, "priority")) {
+ presence->setPriority(*value);
+ }
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "type")) {
+ presence->setType(PresenceConvertor::convertPresenceTypeFromString(*value));
+ }
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "show")) {
+ presence->setShow(StatusShowConvertor::convertStatusShowTypeFromString(*value));
+ }
+ std::vector< std::shared_ptr<Payload> > payloads = getPayloadsFromTable(L, index);
+ presence->addPayloads(payloads.begin(), payloads.end());
+ }
+ if (!getClient(L)->getClient()->getPresenceSender()->isAvailable()) {
+ throw Lua::Exception("Trying to send presence while client is offline.");
+ }
+ getClient(L)->getClient()->getPresenceSender()->sendPresence(presence);
+ lua_pushvalue(L, 1);
+ return 0;
}
static int sendQuery(lua_State* L, IQ::Type type) {
- SluiftClient* client = getClient(L);
+ SluiftClient* client = getClient(L);
- JID to;
- if (boost::optional<std::string> toString = Lua::getStringField(L, 2, "to")) {
- to = JID(*toString);
- }
+ JID to;
+ if (boost::optional<std::string> toString = Lua::getStringField(L, 2, "to")) {
+ to = JID(*toString);
+ }
- int timeout = Sluift::globals.timeout;
- if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) {
- timeout = *timeoutInt;
- }
+ int timeout = getGlobalTimeout(L);
+ if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) {
+ timeout = *timeoutInt;
+ }
- boost::shared_ptr<Payload> payload;
- lua_getfield(L, 2, "query");
- if (lua_type(L, -1) == LUA_TTABLE) {
- payload = Sluift::globals.elementConvertor.convertFromLua(L, -1);
- }
- else if (lua_type(L, -1) == LUA_TSTRING) {
- payload = boost::make_shared<RawXMLPayload>(Lua::checkString(L, -1));
- }
- lua_pop(L, 1);
+ std::shared_ptr<Payload> payload;
+ lua_getfield(L, 2, "query");
+ payload = getPayload(L, -1);
+ lua_pop(L, 1);
- return client->sendRequest(
- boost::make_shared< GenericRequest<Payload> >(type, to, payload, client->getClient()->getIQRouter()), timeout).convertToLuaResult(L);
+ return client->sendRequest(
+ std::make_shared< GenericRequest<Payload> >(type, to, payload, client->getClient()->getIQRouter()), timeout).convertToLuaResult(L);
}
#define DISPATCH_PUBSUB_PAYLOAD(payloadType, container, response) \
- else if (boost::shared_ptr<payloadType> p = boost::dynamic_pointer_cast<payloadType>(payload)) { \
- return client->sendPubSubRequest(type, to, p, timeout).convertToLuaResult(L); \
- }
+ else if (std::shared_ptr<payloadType> p = std::dynamic_pointer_cast<payloadType>(payload)) { \
+ return client->sendPubSubRequest(type, to, p, timeout).convertToLuaResult(L); \
+ }
SLUIFT_LUA_FUNCTION(Client, query_pubsub) {
- SluiftClient* client = getClient(L);
-
- JID to;
- if (boost::optional<std::string> toString = Lua::getStringField(L, 2, "to")) {
- to = JID(*toString);
- }
-
- int timeout = Sluift::globals.timeout;
- if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) {
- timeout = *timeoutInt;
- }
-
- IQ::Type type;
- if (boost::optional<std::string> queryType = Lua::getStringField(L, 2, "type")) {
- if (*queryType == "get") {
- type = IQ::Get;
- }
- else if (*queryType == "set") {
- type = IQ::Set;
- }
- else {
- throw Lua::Exception("Illegal query type: '" + *queryType + "'");
- }
- }
- else {
- throw Lua::Exception("Missing query type");
- }
-
- lua_getfield(L, 2, "query");
- if (!lua_istable(L, -1)) {
- throw Lua::Exception("Missing/incorrect query");
- }
- boost::shared_ptr<Payload> payload = Sluift::globals.elementConvertor.convertFromLua(L, -1);
-
- if (false) { }
- SWIFTEN_PUBSUB_FOREACH_PUBSUB_PAYLOAD_TYPE(DISPATCH_PUBSUB_PAYLOAD)
- else {
- throw Lua::Exception("Incorrect PubSub payload");
- }
+ SluiftClient* client = getClient(L);
+
+ JID to;
+ if (boost::optional<std::string> toString = Lua::getStringField(L, 2, "to")) {
+ to = JID(*toString);
+ }
+
+ int timeout = getGlobalTimeout(L);
+ if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) {
+ timeout = *timeoutInt;
+ }
+
+ IQ::Type type;
+ if (boost::optional<std::string> queryType = Lua::getStringField(L, 2, "type")) {
+ type = IQConvertor::convertIQTypeFromString(*queryType);
+ }
+ else {
+ throw Lua::Exception("Missing query type");
+ }
+
+ lua_getfield(L, 2, "query");
+ if (!lua_istable(L, -1)) {
+ throw Lua::Exception("Missing/incorrect query");
+ }
+ std::shared_ptr<Payload> payload = getPayload(L, -1);
+
+ if (false) { }
+ SWIFTEN_PUBSUB_FOREACH_PUBSUB_PAYLOAD_TYPE(DISPATCH_PUBSUB_PAYLOAD)
+ else {
+ throw Lua::Exception("Incorrect PubSub payload");
+ }
}
SLUIFT_LUA_FUNCTION(Client, get) {
- return sendQuery(L, IQ::Get);
+ return sendQuery(L, IQ::Get);
}
SLUIFT_LUA_FUNCTION(Client, set) {
- return sendQuery(L, IQ::Set);
+ return sendQuery(L, IQ::Set);
}
-SLUIFT_LUA_FUNCTION(Client, send) {
- Sluift::globals.eventLoop.runOnce();
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, send,
+ "Sends a raw string",
+
+ "self\n"
+ "data the string to send\n",
+
+ ""
+) {
+ Sluift::globals.eventLoop.runOnce();
+ if (!getClient(L)->getClient()->isAvailable()) {
+ throw Lua::Exception("Trying to send data while client is offline.");
+ }
+ getClient(L)->getClient()->sendData(std::string(Lua::checkString(L, 2)));
+ lua_pushvalue(L, 1);
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, set_options,
+
+ "Sets the connection options of this client.",
- getClient(L)->getClient()->sendData(std::string(Lua::checkString(L, 2)));
- lua_pushvalue(L, 1);
- return 0;
+ "self",
+
+ "host The host to connect to. When omitted, is determined from resolving the JID domain.\n"
+ "port The port to connect to. When omitted, is determined from resolving the JID domain.\n"
+ "ack Request acknowledgements\n"
+ "compress Use stream compression when available\n"
+ "tls Use TLS when available\n"
+ "bosh_url Connect using the specified BOSH URL\n"
+ "allow_plain_without_tls Allow PLAIN authentication without a TLS encrypted connection\n"
+) {
+ SluiftClient* client = getClient(L);
+ setOptions(L, client);
+ return 0;
}
-SLUIFT_LUA_FUNCTION(Client, set_options) {
- SluiftClient* client = getClient(L);
- Lua::checkType(L, 2, LUA_TTABLE);
- lua_getfield(L, 2, "ack");
- if (!lua_isnil(L, -1)) {
- client->getOptions().useAcks = lua_toboolean(L, -1);
- }
- lua_getfield(L, 2, "compress");
- if (!lua_isnil(L, -1)) {
- client->getOptions().useStreamCompression = lua_toboolean(L, -1);
- }
- lua_getfield(L, 2, "tls");
- if (!lua_isnil(L, -1)) {
- bool useTLS = lua_toboolean(L, -1);
- client->getOptions().useTLS = (useTLS ? ClientOptions::UseTLSWhenAvailable : ClientOptions::NeverUseTLS);
- }
- lua_pushvalue(L, 1);
- return 0;
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, get_options,
+ "Returns a table with all the connection options of this client.",
+ "self\n",
+ ""
+) {
+ Sluift::globals.eventLoop.runOnce();
+
+ SluiftClient* client = getClient(L);
+ Lua::Table optionsTable = boost::assign::map_list_of
+ ("host", std::make_shared<Lua::Value>(client->getOptions().manualHostname))
+ ("port", std::make_shared<Lua::Value>(client->getOptions().manualPort))
+ ("ack", std::make_shared<Lua::Value>(client->getOptions().useAcks))
+ ("compress", std::make_shared<Lua::Value>(client->getOptions().useStreamCompression))
+ ("tls", std::make_shared<Lua::Value>(client->getOptions().useTLS == ClientOptions::NeverUseTLS ? false : true))
+ ("bosh_url", std::make_shared<Lua::Value>(client->getOptions().boshURL.toString()))
+ ("allow_plain_without_tls", std::make_shared<Lua::Value>(client->getOptions().allowPLAINWithoutTLS));
+ pushValue(L, optionsTable);
+ Lua::registerTableToString(L, -1);
+ return 1;
}
static void pushEvent(lua_State* L, const SluiftClient::Event& event) {
- switch (event.type) {
- case SluiftClient::Event::MessageType: {
- Message::ref message = boost::dynamic_pointer_cast<Message>(event.stanza);
- Lua::Table result = boost::assign::map_list_of
- ("type", boost::make_shared<Lua::Value>(std::string("message")))
- ("from", boost::make_shared<Lua::Value>(message->getFrom().toString()))
- ("body", boost::make_shared<Lua::Value>(message->getBody()));
- Lua::pushValue(L, result);
- Lua::registerTableToString(L, -1);
- break;
- }
- case SluiftClient::Event::PresenceType: {
- Presence::ref presence = boost::dynamic_pointer_cast<Presence>(event.stanza);
- Lua::Table result = boost::assign::map_list_of
- ("type", boost::make_shared<Lua::Value>(std::string("presence")))
- ("from", boost::make_shared<Lua::Value>(presence->getFrom().toString()))
- ("status", boost::make_shared<Lua::Value>(presence->getStatus()));
- Lua::pushValue(L, result);
- if (!presence->getPayloads().empty()) {
- const std::vector<boost::shared_ptr<Payload> > payloads = presence->getPayloads();
- lua_createtable(L, boost::numeric_cast<int>(payloads.size()), 0);
- for (size_t i = 0; i < payloads.size(); ++i) {
- Sluift::globals.elementConvertor.convertToLua(L, payloads[i]);
- lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
- }
- Lua::registerGetByTypeIndex(L, -1);
- lua_setfield(L, -2, "payloads");
- }
- Lua::registerTableToString(L, -1);
- break;
- }
- case SluiftClient::Event::PubSubEventType: {
- Sluift::globals.elementConvertor.convertToLua(L, event.pubsubEvent);
- lua_pushstring(L, "pubsub");
- lua_setfield(L, -2, "type");
- lua_pushstring(L, event.from.toString().c_str());
- lua_setfield(L, -2, "from");
-
- lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.bootIndex);
- lua_getfield(L, -1, "process_pubsub_event");
- lua_pushvalue(L, -3);
- lua_call(L, 1, 0);
- lua_pop(L, 1);
- }
- }
+ switch (event.type) {
+ case SluiftClient::Event::MessageType: {
+ Message::ref message = std::dynamic_pointer_cast<Message>(event.stanza);
+ Lua::Table result = boost::assign::map_list_of
+ ("type", std::make_shared<Lua::Value>(std::string("message")))
+ ("from", std::make_shared<Lua::Value>(message->getFrom().toString()))
+ ("to", std::make_shared<Lua::Value>(message->getTo().toString()))
+ ("body", std::make_shared<Lua::Value>(message->getBody().get_value_or("")))
+ ("message_type", std::make_shared<Lua::Value>(MessageConvertor::convertMessageTypeToString(message->getType())));
+ Lua::pushValue(L, result);
+ addPayloadsToTable(L, message->getPayloads());
+ Lua::registerTableToString(L, -1);
+ break;
+ }
+ case SluiftClient::Event::PresenceType: {
+ Presence::ref presence = std::dynamic_pointer_cast<Presence>(event.stanza);
+ Lua::Table result = boost::assign::map_list_of
+ ("type", std::make_shared<Lua::Value>(std::string("presence")))
+ ("from", std::make_shared<Lua::Value>(presence->getFrom().toString()))
+ ("to", std::make_shared<Lua::Value>(presence->getTo().toString()))
+ ("status", std::make_shared<Lua::Value>(presence->getStatus()))
+ ("presence_type", std::make_shared<Lua::Value>(PresenceConvertor::convertPresenceTypeToString(presence->getType())));
+ Lua::pushValue(L, result);
+ addPayloadsToTable(L, presence->getPayloads());
+ Lua::registerTableToString(L, -1);
+ break;
+ }
+ case SluiftClient::Event::PubSubEventType: {
+ Sluift::globals.elementConvertor.convertToLua(L, event.pubsubEvent);
+ lua_pushstring(L, "pubsub");
+ lua_setfield(L, -2, "type");
+ lua_pushstring(L, event.from.toString().c_str());
+ lua_setfield(L, -2, "from");
+
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ lua_getfield(L, -1, "process_pubsub_event");
+ lua_pushvalue(L, -3);
+ lua_call(L, 1, 0);
+ lua_pop(L, 1);
+ break;
+ }
+ case SluiftClient::Event::BlockEventType: {
+ Lua::Table result = boost::assign::map_list_of
+ ("type", std::make_shared<Lua::Value>(std::string("block")))
+ ("jid", std::make_shared<Lua::Value>(event.item.toString()));
+ Lua::pushValue(L, result);
+ Lua::registerTableToString(L, -1);
+ break;
+ }
+ case SluiftClient::Event::UnblockEventType: {
+ Lua::Table result = boost::assign::map_list_of
+ ("type", std::make_shared<Lua::Value>(std::string("unblock")))
+ ("jid", std::make_shared<Lua::Value>(event.item.toString()));
+ Lua::pushValue(L, result);
+ Lua::registerTableToString(L, -1);
+ break;
+ }
+ case SluiftClient::Event::RosterAddType: {
+ Lua::Table result = boost::assign::map_list_of
+ ("type", std::make_shared<Lua::Value>(std::string("rosterpush")))
+ ("jid", std::make_shared<Lua::Value>(event.item.toString()))
+ ("action", std::make_shared<Lua::Value>(std::string("added")));
+ Lua::pushValue(L, result);
+ Lua::registerTableToString(L, -1);
+ break;
+ }
+ case SluiftClient::Event::RosterRemoveType: {
+ Lua::Table result = boost::assign::map_list_of
+ ("type", std::make_shared<Lua::Value>(std::string("rosterpush")))
+ ("jid", std::make_shared<Lua::Value>(event.item.toString()))
+ ("action", std::make_shared<Lua::Value>(std::string("removed")));
+ Lua::pushValue(L, result);
+ Lua::registerTableToString(L, -1);
+ break;
+ }
+ case SluiftClient::Event::RosterUpdateType: {
+ Lua::Table result = boost::assign::map_list_of
+ ("type", std::make_shared<Lua::Value>(std::string("rosterpush")))
+ ("jid", std::make_shared<Lua::Value>(event.item.toString()))
+ ("action", std::make_shared<Lua::Value>(std::string("updated")));
+ Lua::pushValue(L, result);
+ Lua::registerTableToString(L, -1);
+ break;
+ }
+ }
}
struct CallUnaryLuaPredicateOnEvent {
- CallUnaryLuaPredicateOnEvent(lua_State* L, int index) : L(L), index(index) {
- }
-
- bool operator()(const SluiftClient::Event& event) {
- lua_pushvalue(L, index);
- pushEvent(L, event);
- if (lua_pcall(L, 1, 1, 0) != 0) {
- throw Lua::Exception(lua_tostring(L, -1));
- }
- bool result = lua_toboolean(L, -1);
- lua_pop(L, 1);
- return result;
- }
-
- lua_State* L;
- int index;
+ CallUnaryLuaPredicateOnEvent(lua_State* L, int index) : L(L), index(index) {
+ }
+
+ bool operator()(const SluiftClient::Event& event) {
+ lua_pushvalue(L, index);
+ pushEvent(L, event);
+ if (lua_pcall(L, 1, 1, 0) != 0) {
+ throw Lua::Exception(lua_tostring(L, -1));
+ }
+ bool result = lua_toboolean(L, -1);
+ lua_pop(L, 1);
+ return result;
+ }
+
+ lua_State* L;
+ int index;
};
SLUIFT_LUA_FUNCTION(Client, get_next_event) {
- Sluift::globals.eventLoop.runOnce();
- SluiftClient* client = getClient(L);
-
- int timeout = Sluift::globals.timeout;
- boost::optional<SluiftClient::Event::Type> type;
- int condition = 0;
- if (lua_istable(L, 2)) {
- if (boost::optional<std::string> typeString = Lua::getStringField(L, 2, "type")) {
- if (*typeString == "message") {
- type = SluiftClient::Event::MessageType;
- }
- else if (*typeString == "presence") {
- type = SluiftClient::Event::PresenceType;
- }
- else if (*typeString == "pubsub") {
- type = SluiftClient::Event::PubSubEventType;
- }
- }
- if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) {
- timeout = *timeoutInt;
- }
- lua_getfield(L, 2, "if");
- if (lua_isfunction(L, -1)) {
- condition = Lua::absoluteOffset(L, -1);
- }
- }
-
- boost::optional<SluiftClient::Event> event;
- if (condition) {
- event = client->getNextEvent(timeout, CallUnaryLuaPredicateOnEvent(L, condition));
- }
- else if (type) {
- event = client->getNextEvent(
- timeout, lambda::bind(&SluiftClient::Event::type, lambda::_1) == *type);
- }
- else {
- event = client->getNextEvent(timeout);
- }
-
- if (event) {
- pushEvent(L, *event);
- }
- else {
- lua_pushnil(L);
- }
- return 1;
-}
-
-
-SLUIFT_LUA_FUNCTION(Client, add_contact) {
- Sluift::globals.eventLoop.runOnce();
- SluiftClient* client = getClient(L);
- RosterItemPayload item;
- if (lua_type(L, 2) == LUA_TTABLE) {
- lua_getfield(L, 2, "jid");
- const char* rawJID = lua_tostring(L, -1);
- if (rawJID) {
- item.setJID(std::string(rawJID));
- }
- lua_getfield(L, 2, "name");
- const char* rawName = lua_tostring(L, -1);
- if (rawName) {
- item.setName(rawName);
- }
- lua_getfield(L, 2, "groups");
- if (!lua_isnil(L, -1)) {
- if (lua_type(L, -1) == LUA_TTABLE) {
- for (size_t i = 1; i <= lua_objlen(L, -1); ++i) {
- lua_rawgeti(L, -1, boost::numeric_cast<int>(i));
- const char* rawGroup = lua_tostring(L, -1);
- if (rawGroup) {
- item.addGroup(rawGroup);
- }
- lua_pop(L, 1);
- }
- }
- else {
- throw Lua::Exception("Groups should be a table");
- }
- }
- }
- else {
- item.setJID(Lua::checkString(L, 2));
- }
-
- client->getRoster();
- if (!client->getClient()->getRoster()->containsJID(item.getJID())) {
- RosterPayload::ref roster = boost::make_shared<RosterPayload>();
- roster->addItem(item);
-
- Sluift::Response response = client->sendVoidRequest(
- SetRosterRequest::create(roster, client->getClient()->getIQRouter()), -1);
- if (response.error) {
- return response.convertToLuaResult(L);
- }
- }
- client->getClient()->getSubscriptionManager()->requestSubscription(item.getJID());
- lua_pushboolean(L, true);
- return 1;
-}
-
-SLUIFT_LUA_FUNCTION(Client, remove_contact) {
- Sluift::globals.eventLoop.runOnce();
- SluiftClient* client = getClient(L);
- JID jid(Lua::checkString(L, 2));
-
- RosterPayload::ref roster = boost::make_shared<RosterPayload>();
- roster->addItem(RosterItemPayload(JID(Lua::checkString(L, 2)), "", RosterItemPayload::Remove));
-
- return client->sendVoidRequest(
- SetRosterRequest::create(roster, client->getClient()->getIQRouter()), -1).convertToLuaResult(L);
-}
-
-SLUIFT_LUA_FUNCTION(Client, confirm_subscription) {
- Sluift::globals.eventLoop.runOnce();
- SluiftClient* client = getClient(L);
- JID jid(Lua::checkString(L, 2));
- client->getClient()->getSubscriptionManager()->confirmSubscription(jid);
- return 0;
-}
-
-SLUIFT_LUA_FUNCTION(Client, cancel_subscription) {
- Sluift::globals.eventLoop.runOnce();
- SluiftClient* client = getClient(L);
- JID jid(Lua::checkString(L, 2));
- client->getClient()->getSubscriptionManager()->cancelSubscription(jid);
- return 0;
-}
-
-SLUIFT_LUA_FUNCTION(Client, set_disco_info) {
- SluiftClient* client = getClient(L);
- if (!lua_istable(L, 2)) {
- throw Lua::Exception("Missing disco info");
- }
- if (boost::shared_ptr<DiscoInfo> discoInfo = boost::dynamic_pointer_cast<DiscoInfo>(Sluift::globals.elementConvertor.convertFromLuaUntyped(L, 2, "disco_info"))) {
- client->getClient()->getDiscoManager()->setDiscoInfo(*discoInfo);
- }
- else {
- throw Lua::Exception("Illegal disco info");
- }
- return 0;
-}
-
-SLUIFT_LUA_FUNCTION(Client, set_caps_node) {
- SluiftClient* client = getClient(L);
- std::string node(Lua::checkString(L, 2));
- client->getClient()->getDiscoManager()->setCapsNode(Lua::checkString(L, 2));
- return 0;
-}
-
-SLUIFT_LUA_FUNCTION(Client, jid) {
- SluiftClient* client = getClient(L);
- lua_pushstring(L, client->getClient()->getJID().toString().c_str());
- return 1;
+ Sluift::globals.eventLoop.runOnce();
+ SluiftClient* client = getClient(L);
+
+ int timeout = getGlobalTimeout(L);
+ boost::optional<SluiftClient::Event::Type> type;
+ int condition = 0;
+ if (lua_istable(L, 2)) {
+ if (boost::optional<std::string> typeString = Lua::getStringField(L, 2, "type")) {
+ if (*typeString == "message") {
+ type = SluiftClient::Event::MessageType;
+ }
+ else if (*typeString == "presence") {
+ type = SluiftClient::Event::PresenceType;
+ }
+ else if (*typeString == "pubsub") {
+ type = SluiftClient::Event::PubSubEventType;
+ }
+ }
+ if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) {
+ timeout = *timeoutInt;
+ }
+ lua_getfield(L, 2, "if");
+ if (lua_isfunction(L, -1)) {
+ condition = Lua::absoluteOffset(L, -1);
+ }
+ }
+
+ boost::optional<SluiftClient::Event> event;
+ if (condition) {
+ event = client->getNextEvent(timeout, CallUnaryLuaPredicateOnEvent(L, condition));
+ }
+ else if (type) {
+ event = client->getNextEvent(
+ timeout, [&](const SluiftClient::Event& event) {
+ return event.type == *type;
+ });
+ }
+ else {
+ event = client->getNextEvent(timeout);
+ }
+
+ if (event) {
+ pushEvent(L, *event);
+ }
+ else {
+ lua_pushnil(L);
+ }
+ return 1;
+}
+
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, add_contact,
+ "Add a contact to the contact list.",
+ "self\n",
+ "jid The JID of the contact to add\n"
+ "name The name to use in the contact list\n"
+ "groups An array of group names to add the contact to\n") {
+ Sluift::globals.eventLoop.runOnce();
+ SluiftClient* client = getClient(L);
+ RosterItemPayload item;
+ int timeout = getGlobalTimeout(L);
+
+ if (lua_type(L, 2) == LUA_TTABLE) {
+ lua_getfield(L, 2, "jid");
+ const char* rawJID = lua_tostring(L, -1);
+ if (rawJID) {
+ item.setJID(std::string(rawJID));
+ }
+ lua_getfield(L, 2, "name");
+ const char* rawName = lua_tostring(L, -1);
+ if (rawName) {
+ item.setName(rawName);
+ }
+ lua_getfield(L, 2, "groups");
+ if (!lua_isnil(L, -1)) {
+ if (lua_type(L, -1) == LUA_TTABLE) {
+ for (size_t i = 1; i <= lua_rawlen(L, -1); ++i) {
+ lua_rawgeti(L, -1, boost::numeric_cast<int>(i));
+ const char* rawGroup = lua_tostring(L, -1);
+ if (rawGroup) {
+ item.addGroup(rawGroup);
+ }
+ lua_pop(L, 1);
+ }
+ }
+ else {
+ throw Lua::Exception("Groups should be a table");
+ }
+ }
+ }
+ else {
+ item.setJID(Lua::checkString(L, 2));
+ }
+
+ client->getRoster(timeout);
+ if (!client->getClient()->getRoster()->containsJID(item.getJID())) {
+ RosterPayload::ref roster = std::make_shared<RosterPayload>();
+ roster->addItem(item);
+
+ Sluift::Response response = client->sendVoidRequest(
+ SetRosterRequest::create(roster, client->getClient()->getIQRouter()), timeout);
+ if (response.error) {
+ return response.convertToLuaResult(L);
+ }
+ }
+ client->getClient()->getSubscriptionManager()->requestSubscription(item.getJID());
+ lua_pushboolean(L, true);
+ return 1;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, remove_contact,
+ "Remove a contact from the contact list.",
+ "self\n"
+ "jid the JID of the contact to remove\n",
+ ""
+) {
+ Sluift::globals.eventLoop.runOnce();
+ SluiftClient* client = getClient(L);
+ JID jid(Lua::checkString(L, 2));
+ int timeout = getGlobalTimeout(L);
+
+ RosterPayload::ref roster = std::make_shared<RosterPayload>();
+ roster->addItem(RosterItemPayload(JID(Lua::checkString(L, 2)), "", RosterItemPayload::Remove));
+
+ return client->sendVoidRequest(
+ SetRosterRequest::create(roster, client->getClient()->getIQRouter()), timeout).convertToLuaResult(L);
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, confirm_subscription,
+ "Confirm subscription of a contact.",
+ "self\n"
+ "jid the JID of the contact to confirm the subscription of\n",
+ ""
+) {
+ Sluift::globals.eventLoop.runOnce();
+ SluiftClient* client = getClient(L);
+ JID jid(Lua::checkString(L, 2));
+ client->getClient()->getSubscriptionManager()->confirmSubscription(jid);
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, cancel_subscription,
+ "Cancel the subscription of a contact.",
+ "self\n"
+ "jid the JID of the contact to cancel the subscription of\n",
+ ""
+) {
+ Sluift::globals.eventLoop.runOnce();
+ SluiftClient* client = getClient(L);
+ JID jid(Lua::checkString(L, 2));
+ client->getClient()->getSubscriptionManager()->cancelSubscription(jid);
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, set_disco_info,
+ "Sets the service discovery information for this client",
+ "self\n"
+ "disco_info A structured representation of the service discovery information\n",
+ ""
+) {
+ SluiftClient* client = getClient(L);
+ if (!lua_istable(L, 2)) {
+ throw Lua::Exception("Missing disco info");
+ }
+ if (std::shared_ptr<DiscoInfo> discoInfo = std::dynamic_pointer_cast<DiscoInfo>(Sluift::globals.elementConvertor.convertFromLuaUntyped(L, 2, "disco_info"))) {
+ client->getClient()->getDiscoManager()->setDiscoInfo(*discoInfo);
+ }
+ else {
+ throw Lua::Exception("Illegal disco info");
+ }
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, set_caps_node,
+ "Sets the caps node of this client",
+ "self\n"
+ "node The caps node (e.g. 'http://swift.im/sluift')\n",
+ ""
+) {
+ SluiftClient* client = getClient(L);
+ std::string node(Lua::checkString(L, 2));
+ client->getClient()->getDiscoManager()->setCapsNode(Lua::checkString(L, 2));
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, set_certificate,
+ "Sets a client certificate to use for strong authentication with the server.",
+ "self\n"
+ "file PKCS #12 file\n"
+ "pwd passphrase for the certificate private key\n",
+ ""
+) {
+ std::string file;
+ std::string pwd;
+ int index = 2;
+ if (!lua_isnoneornil(L, index)) {
+ file = Lua::checkString(L, index);
+ ++index;
+ if (!lua_isnoneornil(L, index)) {
+ pwd = Lua::checkString(L, index);
+ ++index;
+ }
+ }
+ if (file.empty()) {
+ getClient(L)->getClient()->setCertificate(CertificateWithKey::ref());
+ } else {
+ getClient(L)->getClient()->setCertificate(std::make_shared<PKCS12Certificate>(file, createSafeByteArray(pwd)));
+ }
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Client, jid,
+ "Returns the JID of this client",
+ "self\n",
+ ""
+) {
+ SluiftClient* client = getClient(L);
+ lua_pushstring(L, client->getClient()->getJID().toString().c_str());
+ return 1;
}
SLUIFT_LUA_FUNCTION(Client, __gc) {
- SluiftClient* client = getClient(L);
- delete client;
- return 0;
+ SluiftClient* client = getClient(L);
+ delete client;
+ return 0;
}
diff --git a/Sluift/component.cpp b/Sluift/component.cpp
new file mode 100644
index 0000000..c1b1da4
--- /dev/null
+++ b/Sluift/component.cpp
@@ -0,0 +1,465 @@
+/*
+ * Copyright (c) 2014-2018 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <boost/assign/list_of.hpp>
+
+#include <Swiften/Base/IDGenerator.h>
+#include <Swiften/Elements/DiscoInfo.h>
+#include <Swiften/Elements/MAMQuery.h>
+#include <Swiften/Elements/Message.h>
+#include <Swiften/Elements/Presence.h>
+#include <Swiften/Elements/RawXMLPayload.h>
+#include <Swiften/Elements/RosterItemPayload.h>
+#include <Swiften/Elements/RosterPayload.h>
+#include <Swiften/Elements/SoftwareVersion.h>
+#include <Swiften/JID/JID.h>
+#include <Swiften/Presence/PresenceSender.h>
+#include <Swiften/Presence/SubscriptionManager.h>
+#include <Swiften/Queries/GenericRequest.h>
+#include <Swiften/Queries/IQRouter.h>
+#include <Swiften/Queries/Requests/GetSoftwareVersionRequest.h>
+#include <Swiften/Roster/SetRosterRequest.h>
+#include <Swiften/Roster/XMPPRoster.h>
+#include <Swiften/Roster/XMPPRosterItem.h>
+
+#include <Sluift/ElementConvertors/IQConvertor.h>
+#include <Sluift/ElementConvertors/MessageConvertor.h>
+#include <Sluift/ElementConvertors/PresenceConvertor.h>
+#include <Sluift/ElementConvertors/StanzaConvertor.h>
+#include <Sluift/ElementConvertors/StatusShowConvertor.h>
+#include <Sluift/Lua/Check.h>
+#include <Sluift/Lua/Exception.h>
+#include <Sluift/Lua/FunctionRegistration.h>
+#include <Sluift/Lua/LuaUtils.h>
+#include <Sluift/Lua/Value.h>
+#include <Sluift/SluiftComponent.h>
+#include <Sluift/globals.h>
+
+using namespace Swift;
+
+static inline SluiftComponent* getComponent(lua_State* L) {
+ return *Lua::checkUserData<SluiftComponent>(L, 1);
+}
+
+static inline int getGlobalTimeout(lua_State* L) {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.moduleLibIndex);
+ lua_getfield(L, -1, "timeout");
+ int result = boost::numeric_cast<int>(lua_tointeger(L, -1));
+ lua_pop(L, 2);
+ return result;
+}
+
+static void addPayloadsToTable(lua_State* L, const std::vector<std::shared_ptr<Payload> >& payloads) {
+ if (!payloads.empty()) {
+ lua_createtable(L, boost::numeric_cast<int>(payloads.size()), 0);
+ for (size_t i = 0; i < payloads.size(); ++i) {
+ Sluift::globals.elementConvertor.convertToLua(L, payloads[i]);
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ Lua::registerGetByTypeIndex(L, -1);
+ lua_setfield(L, -2, "payloads");
+ }
+}
+
+static std::shared_ptr<Payload> getPayload(lua_State* L, int index) {
+ if (lua_type(L, index) == LUA_TTABLE) {
+ return std::dynamic_pointer_cast<Payload>(Sluift::globals.elementConvertor.convertFromLua(L, index));
+ }
+ else if (lua_type(L, index) == LUA_TSTRING) {
+ return std::make_shared<RawXMLPayload>(Lua::checkString(L, index));
+ }
+ else {
+ return std::shared_ptr<Payload>();
+ }
+}
+
+static std::vector< std::shared_ptr<Payload> > getPayloadsFromTable(lua_State* L, int index) {
+ index = Lua::absoluteOffset(L, index);
+ std::vector< std::shared_ptr<Payload> > result;
+ lua_getfield(L, index, "payloads");
+ if (lua_istable(L, -1)) {
+ for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
+ std::shared_ptr<Payload> payload = getPayload(L, -1);
+ if (payload) {
+ result.push_back(payload);
+ }
+ }
+ }
+ lua_pop(L, 1);
+ return result;
+}
+
+SLUIFT_LUA_FUNCTION(Component, async_connect) {
+ SluiftComponent* component = getComponent(L);
+
+ std::string host;
+ unsigned short port = 0;
+ if (lua_istable(L, 2)) {
+ if (boost::optional<std::string> hostString = Lua::getStringField(L, 2, "host")) {
+ host = *hostString;
+ }
+ if (boost::optional<int> portInt = Lua::getIntField(L, 2, "port")) {
+ port = boost::numeric_cast<unsigned short>(*portInt);
+ }
+ }
+ component->connect(host, port);
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Component, set_trace_enabled,
+ "Enable/disable tracing of the data sent/received.\n\n.",
+ "self\n"
+ "enable a boolean specifying whether to enable/disable tracing",
+ ""
+) {
+ getComponent(L)->setTraceEnabled(lua_toboolean(L, 1));
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Component, wait_connected,
+ "Block until the component is connected.\n\nThis is useful after an `async_connect`.",
+ "self",
+ ""
+) {
+ getComponent(L)->waitConnected(getGlobalTimeout(L));
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Component, is_connected,
+ "Checks whether this component is still connected.\n\nReturns a boolean.",
+ "self\n",
+ ""
+) {
+ lua_pushboolean(L, getComponent(L)->isConnected());
+ return 1;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Component, disconnect,
+ "Disconnect from the server",
+ "self\n",
+ ""
+) {
+ Sluift::globals.eventLoop.runOnce();
+ getComponent(L)->disconnect();
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Component, set_version,
+
+ "Sets the published version of this component.",
+
+ "self",
+
+ "name the name of the component software\n"
+ "version the version identifier of this component\n"
+ "os the OS this component is running on\n"
+) {
+ Sluift::globals.eventLoop.runOnce();
+ SluiftComponent* component = getComponent(L);
+ if (std::shared_ptr<SoftwareVersion> version = std::dynamic_pointer_cast<SoftwareVersion>(Sluift::globals.elementConvertor.convertFromLuaUntyped(L, 2, "software_version"))) {
+ component->setSoftwareVersion(version->getName(), version->getVersion(), version->getOS());
+ }
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Component, send_message,
+ "Send a message.",
+ "self\n"
+ "to the JID to send the message to\n"
+ "body the body of the message. Can alternatively be specified using the `body` option\n",
+
+ "to the JID to send the message to\n"
+ "body the body of the message\n"
+ "subject the subject of the MUC room to set\n"
+ "type the type of message to send (`normal`, `chat`, `error`, `groupchat`, `headline`)\n"
+ "payloads payloads to add to the message\n"
+) {
+ Sluift::globals.eventLoop.runOnce();
+ JID to;
+ boost::optional<std::string> from;
+ boost::optional<std::string> body;
+ boost::optional<std::string> subject;
+ std::vector<std::shared_ptr<Payload> > payloads;
+ int index = 2;
+ Message::Type type = Message::Chat;
+ if (lua_isstring(L, index)) {
+ to = std::string(lua_tostring(L, index));
+ ++index;
+ if (lua_isstring(L, index)) {
+ body = lua_tostring(L, index);
+ ++index;
+ }
+ }
+ if (lua_istable(L, index)) {
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "to")) {
+ to = *value;
+ }
+
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "from")) {
+ from = value;
+ }
+
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "body")) {
+ body = value;
+ }
+
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "type")) {
+ type = MessageConvertor::convertMessageTypeFromString(*value);
+ }
+
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "subject")) {
+ subject = value;
+ }
+
+ payloads = getPayloadsFromTable(L, index);
+ }
+
+ if (!to.isValid()) {
+ throw Lua::Exception("Missing 'to'");
+ }
+ if ((!body || body->empty()) && !subject && payloads.empty()) {
+ throw Lua::Exception("Missing any of 'body', 'subject' or 'payloads'");
+ }
+ Message::ref message = std::make_shared<Message>();
+ message->setTo(to);
+ if (from && !from->empty()) {
+ message->setFrom(*from);
+ }
+ if (body && !body->empty()) {
+ message->setBody(*body);
+ }
+ if (subject) {
+ message->setSubject(*subject);
+ }
+ message->addPayloads(payloads.begin(), payloads.end());
+ message->setType(type);
+ getComponent(L)->getComponent()->sendMessage(message);
+ return 0;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Component, send_presence,
+ "Send presence.",
+
+ "self\n"
+ "body the text of the presence. Can alternatively be specified using the `status` option\n",
+
+ "to the JID to send the message to\n"
+ "from the JID to send the message from\n"
+ "status the text of the presence\n"
+ "show the availability of the presence (`online`, `ffc`, `away`, `xa`, `dnd`)\n"
+ "priority the priority of the presence\n"
+ "type the type of message to send (`available`, `error`, `probe`, `subscribe`, `subscribed`, `unavailable`, `unsubscribe`, `unsubscribed`)\n"
+ "payloads payloads to add to the presence\n"
+) {
+ Sluift::globals.eventLoop.runOnce();
+ std::shared_ptr<Presence> presence = std::make_shared<Presence>();
+
+ int index = 2;
+ if (lua_isstring(L, index)) {
+ presence->setStatus(lua_tostring(L, index));
+ ++index;
+ }
+ if (lua_istable(L, index)) {
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "to")) {
+ presence->setTo(*value);
+ }
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "from")) {
+ presence->setFrom(*value);
+ }
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "status")) {
+ presence->setStatus(*value);
+ }
+ if (boost::optional<int> value = Lua::getIntField(L, index, "priority")) {
+ presence->setPriority(*value);
+ }
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "type")) {
+ presence->setType(PresenceConvertor::convertPresenceTypeFromString(*value));
+ }
+ if (boost::optional<std::string> value = Lua::getStringField(L, index, "show")) {
+ presence->setShow(StatusShowConvertor::convertStatusShowTypeFromString(*value));
+ }
+ std::vector< std::shared_ptr<Payload> > payloads = getPayloadsFromTable(L, index);
+ presence->addPayloads(payloads.begin(), payloads.end());
+ }
+
+ getComponent(L)->getComponent()->sendPresence(presence);
+ lua_pushvalue(L, 1);
+ return 0;
+}
+
+static int sendQuery(lua_State* L, IQ::Type type) {
+ SluiftComponent* component = getComponent(L);
+
+ JID to;
+ if (boost::optional<std::string> toString = Lua::getStringField(L, 2, "to")) {
+ to = JID(*toString);
+ }
+
+ JID from;
+ if (boost::optional<std::string> fromString = Lua::getStringField(L, 2, "from")) {
+ from = JID(*fromString);
+ }
+
+ int timeout = getGlobalTimeout(L);
+ if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) {
+ timeout = *timeoutInt;
+ }
+
+ std::shared_ptr<Payload> payload;
+ lua_getfield(L, 2, "query");
+ payload = getPayload(L, -1);
+ lua_pop(L, 1);
+
+ return component->sendRequest(
+ std::make_shared< GenericRequest<Payload> >(type, from, to, payload, component->getComponent()->getIQRouter()), timeout).convertToLuaResult(L);
+}
+
+SLUIFT_LUA_FUNCTION(Component, get) {
+ return sendQuery(L, IQ::Get);
+}
+
+SLUIFT_LUA_FUNCTION(Component, set) {
+ return sendQuery(L, IQ::Set);
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Component, send,
+ "Sends a raw string",
+
+ "self\n"
+ "data the string to send\n",
+
+ ""
+) {
+ Sluift::globals.eventLoop.runOnce();
+
+ getComponent(L)->getComponent()->sendData(std::string(Lua::checkString(L, 2)));
+ lua_pushvalue(L, 1);
+ return 0;
+}
+
+static void pushEvent(lua_State* L, const SluiftComponent::Event& event) {
+ switch (event.type) {
+ case SluiftComponent::Event::MessageType: {
+ Message::ref message = std::dynamic_pointer_cast<Message>(event.stanza);
+ Lua::Table result = boost::assign::map_list_of
+ ("type", std::make_shared<Lua::Value>(std::string("message")))
+ ("from", std::make_shared<Lua::Value>(message->getFrom().toString()))
+ ("to", std::make_shared<Lua::Value>(message->getTo().toString()))
+ ("body", std::make_shared<Lua::Value>(message->getBody().get_value_or("")))
+ ("message_type", std::make_shared<Lua::Value>(MessageConvertor::convertMessageTypeToString(message->getType())));
+ Lua::pushValue(L, result);
+ addPayloadsToTable(L, message->getPayloads());
+ Lua::registerTableToString(L, -1);
+ break;
+ }
+ case SluiftComponent::Event::PresenceType: {
+ Presence::ref presence = std::dynamic_pointer_cast<Presence>(event.stanza);
+ Lua::Table result = boost::assign::map_list_of
+ ("type", std::make_shared<Lua::Value>(std::string("presence")))
+ ("from", std::make_shared<Lua::Value>(presence->getFrom().toString()))
+ ("to", std::make_shared<Lua::Value>(presence->getTo().toString()))
+ ("status", std::make_shared<Lua::Value>(presence->getStatus()))
+ ("presence_type", std::make_shared<Lua::Value>(PresenceConvertor::convertPresenceTypeToString(presence->getType())));
+ Lua::pushValue(L, result);
+ addPayloadsToTable(L, presence->getPayloads());
+ Lua::registerTableToString(L, -1);
+ break;
+ }
+ }
+}
+
+struct CallUnaryLuaPredicateOnEvent {
+ CallUnaryLuaPredicateOnEvent(lua_State* L, int index) : L(L), index(index) {
+ }
+
+ bool operator()(const SluiftComponent::Event& event) {
+ lua_pushvalue(L, index);
+ pushEvent(L, event);
+ if (lua_pcall(L, 1, 1, 0) != 0) {
+ throw Lua::Exception(lua_tostring(L, -1));
+ }
+ bool result = lua_toboolean(L, -1);
+ lua_pop(L, 1);
+ return result;
+ }
+
+ lua_State* L;
+ int index;
+};
+
+
+SLUIFT_LUA_FUNCTION(Component, get_next_event) {
+ Sluift::globals.eventLoop.runOnce();
+ SluiftComponent* component = getComponent(L);
+
+ int timeout = getGlobalTimeout(L);
+ boost::optional<SluiftComponent::Event::Type> type;
+ int condition = 0;
+ if (lua_istable(L, 2)) {
+ if (boost::optional<std::string> typeString = Lua::getStringField(L, 2, "type")) {
+ if (*typeString == "message") {
+ type = SluiftComponent::Event::MessageType;
+ }
+ else if (*typeString == "presence") {
+ type = SluiftComponent::Event::PresenceType;
+ }
+ }
+ if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) {
+ timeout = *timeoutInt;
+ }
+ lua_getfield(L, 2, "if");
+ if (lua_isfunction(L, -1)) {
+ condition = Lua::absoluteOffset(L, -1);
+ }
+ }
+
+ boost::optional<SluiftComponent::Event> event;
+ if (condition) {
+ event = component->getNextEvent(timeout, CallUnaryLuaPredicateOnEvent(L, condition));
+ }
+ else if (type) {
+ event = component->getNextEvent(
+ timeout, [&](const SluiftComponent::Event& event) {
+ return event.type == *type;
+ });
+ }
+ else {
+ event = component->getNextEvent(timeout);
+ }
+
+ if (event) {
+ pushEvent(L, *event);
+ }
+ else {
+ lua_pushnil(L);
+ }
+ return 1;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Component, jid,
+ "Returns the JID of this component",
+ "self\n",
+ ""
+) {
+ SluiftComponent* component = getComponent(L);
+ lua_pushstring(L, component->getComponent()->getJID().toString().c_str());
+ return 1;
+}
+
+SLUIFT_LUA_FUNCTION(Component, __gc) {
+ SluiftComponent* component = getComponent(L);
+ delete component;
+ return 0;
+}
diff --git a/Sluift/core.lua b/Sluift/core.lua
new file mode 100644
index 0000000..f35a603
--- /dev/null
+++ b/Sluift/core.lua
@@ -0,0 +1,1244 @@
+--[[
+ Copyright (c) 2013-2017 Isode Limited.
+ All rights reserved.
+ See the COPYING file for more information.
+--]]
+
+local sluift = select(1, ...)
+local _G = _G
+local pairs, ipairs, print, tostring, type, error, assert, next, rawset, xpcall, io = pairs, ipairs, print, tostring, type, error, assert, next, rawset, xpcall, io
+local unpack = table.unpack or unpack
+local setmetatable, getmetatable = setmetatable, getmetatable
+local string = require "string"
+local table = require "table"
+local debug = require "debug"
+_ENV = nil
+
+--------------------------------------------------------------------------------
+-- Table utility methods
+--------------------------------------------------------------------------------
+
+local function table_value_tostring(value)
+ local result = tostring(value)
+ if type(value) == 'number' then return result
+ elseif type(value) == 'boolean' then return result
+ elseif type(value) == 'string' then return "'" .. result .. "'"
+ else return '<' .. result .. '>'
+ end
+end
+
+local function table_tostring(table, print_functions, indent, accumulator, history)
+ local INDENT = ' '
+ local accumulator = accumulator or ''
+ local history = history or {}
+ local indent = indent or ''
+ accumulator = accumulator .. '{'
+ history[table] = true
+ local is_first = true
+ for key, value in pairs(table) do
+ if print_functions or type(value) ~= 'function' then
+ if not is_first then
+ accumulator = accumulator .. ','
+ end
+ is_first = false
+ accumulator = accumulator .. '\n' .. indent .. INDENT .. '[' .. table_value_tostring(key) .. '] = '
+ if type(value) == 'table' then
+ if history[value] then
+ accumulator = accumulator .. "..."
+ else
+ accumulator = table_tostring(value, print_functions, indent .. INDENT, accumulator, history)
+ end
+ else
+ accumulator = accumulator .. table_value_tostring(value)
+ end
+ end
+ end
+ history[table] = false
+ if not is_first then
+ accumulator = accumulator .. '\n' .. indent
+ end
+ accumulator = accumulator .. '}'
+ return accumulator
+end
+
+local function register_table_tostring(table, print_functions)
+ if type(table) == 'table' then
+ local metatable = getmetatable(table)
+ if not metatable then
+ metatable = {}
+ setmetatable(table, metatable)
+ end
+ if print_functions then
+ metatable.__tostring = function(table) return table_tostring(table, true) end
+ else
+ metatable.__tostring = table_tostring
+ end
+ end
+end
+
+-- FIXME: Not really a good or efficiant equals, but does the trick for now
+local function table_equals(t1, t2)
+ return tostring(t1) == tostring(t2)
+end
+
+local function register_table_equals(table)
+ if type(table) == 'table' then
+ local metatable = getmetatable(table)
+ if not metatable then
+ metatable = {}
+ setmetatable(table, metatable)
+ end
+ metatable.__eq = table_equals
+ end
+end
+
+local function merge_tables(...)
+ local result = {}
+ for _, table in ipairs({...}) do
+ for k, v in pairs(table) do
+ result[k] = v
+ end
+ end
+ return result
+end
+
+local function copy(object)
+ if type(object) == 'table' then
+ local copy = {}
+ for key, value in pairs(object) do
+ copy[key] = value
+ end
+ return copy
+ else
+ return object
+ end
+end
+
+local function clear(table)
+ setmetatable(table, nil)
+ for key, value in pairs(table) do
+ rawset(table, key, nil)
+ end
+end
+
+local function trim(string)
+ return string:gsub("^%s*(.-)%s*$", "%1")
+end
+
+local function keys(table)
+ local result = {}
+ for key in pairs(table) do
+ result[#result+1] = key
+ end
+ return result
+end
+
+local function insert_all(table, values)
+ for _, value in pairs(values) do
+ table[#table+1] = value
+ end
+end
+
+--------------------------------------------------------------------------------
+-- Help
+--------------------------------------------------------------------------------
+
+-- Contains help for native methods that we want access to from here
+local extra_help = {}
+local component_extra_help = {}
+local help_data = {}
+local help_classes = {}
+local help_class_metatables = {}
+
+local _H
+
+local function get_synopsis(description)
+ return description:gsub("[\n\r].*", "")
+end
+
+local function format_description(text)
+ local result = {}
+ local trim_whitespace
+ for line in (text .. "\n"):gmatch"(.-)\n" do
+ if not trim_whitespace and line:find('[^%s]') then
+ trim_whitespace = line:match("^(%s*)")
+ end
+ if trim_whitespace then
+ line = line:gsub("^" .. trim_whitespace, "")
+ end
+ table.insert(result, line)
+ end
+ return trim(table.concat(result, "\n"))
+end
+
+local function strip_links(text)
+ return text:gsub("(@{(%w*)})", "`%2`")
+end
+
+local function register_help(target, help)
+ assert(target)
+ if not help then
+ help = _H
+ end
+ assert(help)
+
+ -- Transform description into canonical representation
+ local parameters = {}
+ for _, parameter in pairs(help.parameters or {}) do
+ local parameter_description = parameter[2]
+ if parameter_description and #parameter_description == 0 then
+ parameter_description = nil
+ end
+ if type(parameter) == "table" then
+ parameters[#parameters+1] = { name = parameter[1], description = parameter_description }
+ else
+ parameters[#parameters+1] = { name = parameter }
+ end
+ end
+ local options = {}
+ for option_name, option_description in pairs(help.options or {}) do
+ if type(option_description) == "table" then
+ options[#options+1] = { name = option_description.name, description = option_description.description }
+ else
+ options[#options+1] = { name = option_name, description = option_description }
+ end
+ end
+ local description = format_description(help[1] or help.description or "")
+ local synopsis = get_synopsis(description)
+ if #description == 0 then
+ synopsis = nil
+ description = nil
+ end
+ local data = {
+ description = description,
+ synopsis = synopsis,
+ parameters = parameters,
+ options = options,
+ classes = help.classes
+ }
+ register_table_tostring(data, true)
+ help_data[target] = data
+end
+
+local function register_class_help(class, help)
+ help_classes[#help_classes+1] = class
+ register_help(class, help)
+end
+
+local function register_class_table_help(target, class, help)
+ register_help(target, help)
+ help_class_metatables[class] = target
+ register_class_help(class, help)
+end
+
+_H = {
+ [[
+ Retrieves the help information from `target`.
+
+ Returns a table with the following fields:
+
+ - `description`: the description of `target`
+ - `parameters`: an array of parameters of `target` represented as tables with `name` and `description` fields.
+ - `options`: an array of options (named parameters) of `target` represented as tables with `name` and
+ `description` fields.
+ - `methods`: an array of methods
+ - `fields`: an array of fields
+ ]],
+ parameters = { {"target", "The target to retrieve help of"} }
+}
+local function get_help(target)
+ if not target then error("Nil argument or argument missing") end
+ local help = help_data[target] or help_data[getmetatable(target)] or {}
+
+ -- Collect child methods and fields
+ local children = {}
+ if type(target) == "table" then children = target end
+ local mt
+ if type(target) == "string" then
+ mt = help_class_metatables[target]
+ else
+ mt = getmetatable(target)
+ end
+ if mt and type(mt.__index) == "table" then
+ children = merge_tables(children, mt.__index)
+ end
+
+ local methods = {}
+ local fields = {}
+ for name, value in pairs(children) do
+ if name:sub(1, 1) ~= "_" then
+ if type(value) == "function" then
+ methods[#methods+1] = { name = name, ref = value }
+ else
+ fields[#fields+1] = { name = name, description = nil }
+ end
+ end
+ end
+ if next(methods) ~= nil then
+ help.methods = methods
+ end
+ if next(fields) ~= nil then
+ help.fields = fields
+ end
+ if next(help) then
+ return help
+ else
+ return nil
+ end
+end
+register_help(get_help)
+
+_H = {
+ [[
+ Prints the help of `target`.
+
+ `target` can be any object. When `target` is a string, prints the help of the class with
+ the given name.
+ ]],
+ parameters = { {"target", "The target to retrieve help of"} }
+}
+local function help(target)
+ print()
+ if not target then
+ print("Call `help(target)` to get the help of a specific `target`.")
+ print("`target` can be any object. When `target` is a string, prints")
+ print("the help of the class with the given name.")
+ print()
+ print("For general information about sluift, type:")
+ print(" help(sluift)")
+ print()
+ return
+ end
+ local data = get_help(target)
+ if not data then
+ print("No help available\n")
+ return
+ end
+
+ -- Collect help of children
+ local methods = {}
+ for _, method in pairs(data.methods or {}) do
+ local description
+ local method_help = get_help(method.ref)
+ if method_help and method_help.description then
+ description = method_help.synopsis
+ end
+ methods[#methods+1] = { name = method.name, description = description }
+ end
+ local fields = copy(data.fields or {})
+
+ table.sort(methods, function (a, b) return (a.name or "") < (b.name or "") end)
+ table.sort(fields, function (a, b) return (a.name or "") < (b.name or "") end)
+
+ local classes = {}
+ for _, class in pairs(data.classes or {}) do
+ classes[#classes+1] = { name = class, description = get_help(class).synopsis }
+ end
+
+ print(strip_links(data.description) or "(No description available)")
+ for _, p in ipairs({
+ {"Parameters", data.parameters}, {"Options", data.options}, {"Methods", methods}, {"Fields", fields}, {"Classes", classes}}) do
+ if p[2] and next(p[2]) ~= nil then
+ print()
+ print(p[1] .. ":")
+ for _, parameter in ipairs(p[2]) do
+ if parameter.description then
+ print(" " .. parameter.name .. ": " .. strip_links(parameter.description))
+ else
+ print(" " .. parameter.name)
+ end
+ end
+ end
+ end
+
+ print()
+end
+register_help(help)
+
+--------------------------------------------------------------------------------
+-- Utility methods
+--------------------------------------------------------------------------------
+
+_H = {
+ [[ Perform a shallow copy of `object`. ]],
+ parameters = {{"object", "the object to copy"}}
+}
+register_help(copy)
+
+_H = {
+ [[ Pretty-print a table ]],
+ parameters = {{"table", "the table to print"}}
+}
+local function tprint(table)
+ print(table_tostring(table, true))
+end
+register_help(tprint)
+
+local function remove_help_parameters(elements, table)
+ if type(elements) ~= "table" then
+ elements = {elements}
+ end
+ local result = copy(table)
+ for k, v in ipairs(table) do
+ for _, element in ipairs(elements) do
+ if v.name == element then
+ result[k] = nil
+ end
+ end
+ end
+ return result
+end
+
+local function parse_options(unnamed_parameters, arg1, arg2)
+ local options = {}
+ local f
+ if type(arg1) == 'table' then
+ options = arg1
+ f = arg2
+ elseif type(arg1) == 'function' then
+ f = arg1
+ end
+ options.f = f or options.f
+ return copy(options)
+end
+
+
+local function get_by_type(table, typ)
+ for _, v in ipairs(table) do
+ if v['_type'] == typ then
+ return v
+ end
+ end
+end
+
+local function register_get_by_type_index(table)
+ if type(table) == 'table' then
+ local metatable = getmetatable(table)
+ if not metatable then
+ metatable = {}
+ setmetatable(table, metatable)
+ end
+ metatable.__index = get_by_type
+ end
+ return table
+end
+
+local function call(options)
+ local f = options[1]
+ local result = { xpcall(f, debug.traceback) }
+ if options.finally then
+ options.finally()
+ end
+ if result[1] then
+ table.remove(result, 1)
+ return unpack(result)
+ else
+ error(result[2])
+ end
+end
+
+local function read_file(file)
+ local f = io.open(file, 'rb')
+ local result = f:read('*all')
+ f:close()
+ return result
+end
+
+_H = {
+ [[ Generate a form table, suitable for PubSubConfiguration and MAMQuery ]],
+ parameters = { {"fields", "The fields that will be converted into a form table"},
+ {"form_type", "If specified, add a form_type field with this value"},
+ {"type", "Form type, e.g. 'submit'"} }
+}
+local function create_form(...)
+ local options = parse_options({}, ...)
+ local result = { fields = {} }
+ -- FIXME: make nicer when parse_options binds positional arguments to names
+ if options.fields then
+ for var, value in pairs(options.fields) do
+ result.fields[#result.fields+1] = { name = var, value = value }
+ end
+ elseif options[1] then
+ for var, value in pairs(options[1]) do
+ result.fields[#result.fields+1] = { name = var, value = value }
+ end
+ end
+ if options.form_type then
+ result.fields[#result.fields+1] = { name = 'FORM_TYPE', value = options.form_type }
+ end
+ result['type'] = options.type
+ return result
+end
+
+--------------------------------------------------------------------------------
+-- Metatables
+--------------------------------------------------------------------------------
+
+_H = {
+ [[ Client interface ]]
+}
+local Client = {
+ _with_prompt = function(client) return client:jid() end
+}
+Client.__index = Client
+register_class_table_help(Client, "Client")
+
+_H = {
+ [[ Component interface ]]
+}
+local Component = {
+ _with_prompt = function(component) return component:jid() end
+}
+Component.__index = Component
+register_class_table_help(Component, "Component")
+
+
+_H = {
+ [[ Interface to communicate with a PubSub service ]]
+}
+local PubSub = {}
+PubSub.__index = PubSub
+register_class_table_help(PubSub, "PubSub")
+
+_H = {
+ [[ Interface to communicate with a PubSub node on a service ]]
+}
+local PubSubNode = {}
+PubSubNode.__index = PubSubNode
+register_class_table_help(PubSubNode, "PubSubNode")
+
+
+--------------------------------------------------------------------------------
+-- with
+--------------------------------------------------------------------------------
+
+local original_G
+
+local function with (target, f)
+ -- Dynamic scope
+ if f then
+ with(target)
+ return call{f, finally = function() with() end}
+ end
+
+ -- No scope
+ if target then
+ if not original_G then
+ original_G = copy(_G)
+ setmetatable(original_G, getmetatable(_G))
+ clear(_G)
+ end
+
+ setmetatable(_G, {
+ __index = function(_, key)
+ local value = target[key]
+ if value then
+ if type(value) == 'function' then
+ -- Add 'self' argument to all functions
+ return function(...) return value(target, ...) end
+ else
+ return value
+ end
+ else
+ return original_G[key]
+ end
+ end,
+ __newindex = original_G,
+ _completions = function ()
+ local result = {}
+ if type(target) == "table" then
+ insert_all(result, keys(target))
+ end
+ local mt = getmetatable(target)
+ if mt and type(mt.__index) == 'table' then
+ insert_all(result, keys(mt.__index))
+ end
+ insert_all(result, keys(original_G))
+ return result
+ end
+ })
+
+ -- Set prompt
+ local prompt = nil
+
+ -- Try '_with_prompt' in metatable
+ local target_metatable = getmetatable(target)
+ if target_metatable then
+ if type(target_metatable._with_prompt) == "function" then
+ prompt = target_metatable._with_prompt(target)
+ else
+ prompt = target_metatable._with_prompt
+ end
+ end
+
+ if not prompt then
+ -- Use tostring()
+ local target_string = tostring(target)
+ if string.len(target_string) > 25 then
+ prompt = string.sub(target_string, 0, 22) .. "..."
+ else
+ prompt = target_string
+ end
+ end
+ rawset(_G, "_PROMPT", prompt .. '> ')
+ else
+ -- Reset _G
+ clear(_G)
+ for key, value in pairs(original_G) do
+ _G[key] = value
+ end
+ setmetatable(_G, original_G)
+ end
+end
+
+--------------------------------------------------------------------------------
+-- Client
+--------------------------------------------------------------------------------
+
+extra_help = {
+ ["Client.get_next_event"] = {
+ [[ Returns the next event. ]],
+ parameters = { "self" },
+ options = {
+ type = "The type of event to return (`message`, `presence`, `pubsub`). When omitted, all event types are returned.",
+ timeout = "The amount of time to wait for events.",
+ ["if"] = "A function to filter events. When this function, called with the event as a parameter, returns true, the event will be returned"
+ }
+ },
+ ["Client.get"] = {
+ [[ Sends a `get` query. ]],
+ parameters = { "self" },
+ options = {
+ to = "The JID of the target to send the query to",
+ query = "The query to send",
+ timeout = "The amount of time to wait for the query to finish",
+ }
+ },
+ ["Client.set"] = {
+ [[ Sends a `set` query. ]],
+ parameters = { "self" },
+ options = {
+ to = "The JID of the target to send the query to",
+ query = "The query to send.",
+ timeout = "The amount of time to wait for the query to finish.",
+ }
+ },
+ ["Client.async_connect"] = {
+ [[
+ Connect to the server asynchronously.
+
+ This method immediately returns.
+ ]],
+ parameters = { "self" },
+ options = {
+ host = "The host to connect to. When omitted, is determined by resolving the client JID.",
+ port = "The port to connect to. When omitted, is determined by resolving the client JID."
+ }
+ }
+}
+
+_H = {
+ [[
+ Connect to the server.
+
+ This method blocks until the connection has been established.
+ ]],
+ parameters = { "self" },
+ options = extra_help["Client.async_connect"].options
+}
+function Client:connect (...)
+ local options = parse_options({}, ...)
+ local f = options.f
+ self:async_connect(options)
+ self:wait_connected()
+ if f then
+ return call {function() return f(self) end, finally = function() self:disconnect() end}
+ end
+ return true
+end
+register_help(Client.connect)
+
+
+_H = {
+ [[
+ Returns an iterator over all events.
+
+ This function blocks until `timeout` is reached (or blocks forever if it is omitted).
+ ]],
+ parameters = { "self" },
+ options = extra_help["Client.get_next_event"].options
+}
+function Client:events (options)
+ local function client_events_iterator(s)
+ return s['client']:get_next_event(s['options'])
+ end
+ return client_events_iterator, {client = self, options = options}
+end
+register_help(Client.events)
+
+
+_H = {
+ [[
+ Calls `f` for each event.
+ ]],
+ parameters = { "self" },
+ options = merge_tables(get_help(Client.events).options, {
+ f = "The functor to call with each event. Required."
+ })
+}
+function Client:for_each_event (...)
+ local options = parse_options({}, ...)
+ if not type(options.f) == 'function' then error('Expected function') end
+ for event in self:events(options) do
+ local result = options.f(event)
+ if result then
+ return result
+ end
+ end
+end
+register_help(Client.for_each_event)
+
+for method, event_type in pairs({message = 'message', presence = 'presence', pubsub_event = 'pubsub'}) do
+ _H = {
+ "Call `f` for all events of type `" .. event_type .. "`.",
+ parameters = { "self" },
+ options = remove_help_parameters("type", get_help(Client.for_each_event).options)
+ }
+ Client['for_each_' .. method] = function (client, ...)
+ local options = parse_options({}, ...)
+ options['type'] = event_type
+ return client:for_each_event (options)
+ end
+ register_help(Client['for_each_' .. method])
+
+ _H = {
+ "Get the next event of type `" .. event_type .. "`.",
+ parameters = { "self" },
+ options = remove_help_parameters("type", extra_help["Client.get_next_event"].options)
+ }
+ Client['get_next_' .. method] = function (client, ...)
+ local options = parse_options({}, ...)
+ options['type'] = event_type
+ return client:get_next_event(options)
+ end
+ register_help(Client['get_next_' .. method])
+end
+
+for method, event_type in pairs({messages = 'message', pubsub_events = 'pubsub'}) do
+ _H = {
+ "Returns an iterator over all events of type `" .. event_type .. "`.",
+ parameters = { "self" },
+ options = remove_help_parameters("type", get_help(Client.for_each_event).options)
+ }
+ Client[method] = function (client, ...)
+ local options = parse_options({}, ...)
+ options['type'] = event_type
+ return client:events (options)
+ end
+ register_help(Client[method])
+end
+
+_H = {
+ [[
+ Process all pending events
+ ]],
+ parameters = { "self" }
+}
+function Client:process_events ()
+ for event in self:events{timeout=0} do end
+end
+register_help(Client.process_events)
+
+
+--
+-- Register get_* and set_* convenience methods for some type of queries
+--
+-- Example usages:
+-- client:get_software_version{to = 'alice@wonderland.lit'}
+-- client:set_command{to = 'alice@wonderland.lit', command = { type = 'execute', node = 'uptime' }}
+--
+local get_set_shortcuts = {
+ get = {'software_version', 'disco_items', 'disco_info', 'xml', 'dom', 'vcard', 'mam'},
+ set = {'command', 'vcard', 'mam'}
+}
+for query_action, query_types in pairs(get_set_shortcuts) do
+ for _, query_type in ipairs(query_types) do
+ _H = {
+ "Sends a `" .. query_action .. "` query of type `" .. query_type .. "`.\n" ..
+ "Apart from the options below, all top level elements of `" .. query_type .. "` can be passed.",
+ parameters = { "self" },
+ options = remove_help_parameters({"query", "type"}, extra_help["Client.get"].options),
+ }
+ local method = query_action .. '_' .. query_type
+ Client[method] = function (client, options)
+ options = options or {}
+ if type(options) ~= 'table' then error('Invalid options: ' .. options) end
+ options['query'] = merge_tables({_type = query_type}, options[query_type] or {})
+ return client[query_action](client, options)
+ end
+ register_help(Client[method])
+ end
+end
+
+_H = {
+ [[ Returns a @{PubSub} object for communicating with the PubSub service at `jid`. ]],
+ parameters = {
+ "self",
+ {"jid", "The JID of the PubSub service"}
+ }
+}
+function Client:pubsub (jid)
+ local result = { client = self, jid = jid }
+ setmetatable(result, PubSub)
+ return result
+end
+register_help(Client.pubsub)
+
+
+--------------------------------------------------------------------------------
+-- Component
+--------------------------------------------------------------------------------
+
+component_extra_help = {
+ ["Component.get_next_event"] = {
+ [[ Returns the next event. ]],
+ parameters = { "self" },
+ options = {
+ type = "The type of event to return (`message`, `presence`). When omitted, all event types are returned.",
+ timeout = "The amount of time to wait for events.",
+ ["if"] = "A function to filter events. When this function, called with the event as a parameter, returns true, the event will be returned"
+ }
+ },
+ ["Component.get"] = {
+ [[ Sends a `get` query. ]],
+ parameters = { "self" },
+ options = {
+ to = "The JID of the target to send the query to",
+ query = "The query to send",
+ timeout = "The amount of time to wait for the query to finish",
+ }
+ },
+ ["Component.set"] = {
+ [[ Sends a `set` query. ]],
+ parameters = { "self" },
+ options = {
+ to = "The JID of the target to send the query to",
+ query = "The query to send.",
+ timeout = "The amount of time to wait for the query to finish.",
+ }
+ },
+ ["Component.async_connect"] = {
+ [[
+ Connect to the server asynchronously.
+
+ This method immediately returns.
+ ]],
+ parameters = { "self" },
+ options = {
+ host = "The host to connect to.",
+ port = "The port to connect to."
+ }
+ }
+}
+
+_H = {
+ [[
+ Connect to the server.
+
+ This method blocks until the connection has been established.
+ ]],
+ parameters = { "self" },
+ options = component_extra_help["Component.async_connect"].options
+}
+function Component:connect (...)
+ local options = parse_options({}, ...)
+ local f = options.f
+ self:async_connect(options)
+ self:wait_connected()
+ if f then
+ return call {function() return f(self) end, finally = function() self:disconnect() end}
+ end
+ return true
+end
+register_help(Component.connect)
+
+
+_H = {
+ [[
+ Returns an iterator over all events.
+
+ This function blocks until `timeout` is reached (or blocks forever if it is omitted).
+ ]],
+ parameters = { "self" },
+ options = component_extra_help["Component.get_next_event"].options
+}
+function Component:events (options)
+ local function component_events_iterator(s)
+ return s['component']:get_next_event(s['options'])
+ end
+ return component_events_iterator, {component = self, options = options}
+end
+register_help(Component.events)
+
+
+_H = {
+ [[
+ Calls `f` for each event.
+ ]],
+ parameters = { "self" },
+ options = merge_tables(get_help(Component.events).options, {
+ f = "The functor to call with each event. Required."
+ })
+}
+function Component:for_each_event (...)
+ local options = parse_options({}, ...)
+ if not type(options.f) == 'function' then error('Expected function') end
+ for event in self:events(options) do
+ local result = options.f(event)
+ if result then
+ return result
+ end
+ end
+end
+register_help(Component.for_each_event)
+
+for method, event_type in pairs({message = 'message', presence = 'presence'}) do
+ _H = {
+ "Call `f` for all events of type `" .. event_type .. "`.",
+ parameters = { "self" },
+ options = remove_help_parameters("type", get_help(Component.for_each_event).options)
+ }
+ Component['for_each_' .. method] = function (component, ...)
+ local options = parse_options({}, ...)
+ options['type'] = event_type
+ return component:for_each_event (options)
+ end
+ register_help(Component['for_each_' .. method])
+
+ _H = {
+ "Get the next event of type `" .. event_type .. "`.",
+ parameters = { "self" },
+ options = remove_help_parameters("type", component_extra_help["Component.get_next_event"].options)
+ }
+ Component['get_next_' .. method] = function (component, ...)
+ local options = parse_options({}, ...)
+ options['type'] = event_type
+ return component:get_next_event(options)
+ end
+ register_help(Component['get_next_' .. method])
+end
+
+for method, event_type in pairs({messages = 'message'}) do
+ _H = {
+ "Returns an iterator over all events of type `" .. event_type .. "`.",
+ parameters = { "self" },
+ options = remove_help_parameters("type", get_help(Component.for_each_event).options)
+ }
+ Component[method] = function (component, ...)
+ local options = parse_options({}, ...)
+ options['type'] = event_type
+ return component:events (options)
+ end
+ register_help(Component[method])
+end
+
+_H = {
+ [[
+ Process all pending events
+ ]],
+ parameters = { "self" }
+}
+function Component:process_events ()
+ for event in self:events{timeout=0} do end
+end
+register_help(Component.process_events)
+
+
+--
+-- Register get_* and set_* convenience methods for some type of queries
+--
+-- Example usages:
+-- component:get_software_version{to = 'alice@wonderland.lit'}
+-- component:set_command{to = 'alice@wonderland.lit', command = { type = 'execute', node = 'uptime' }}
+--
+local get_set_shortcuts = {
+ get = {'software_version', 'disco_items', 'disco_info', 'xml', 'dom', 'vcard'},
+ set = {'command', 'vcard'}
+}
+for query_action, query_types in pairs(get_set_shortcuts) do
+ for _, query_type in ipairs(query_types) do
+ _H = {
+ "Sends a `" .. query_action .. "` query of type `" .. query_type .. "`.\n" ..
+ "Apart from the options below, all top level elements of `" .. query_type .. "` can be passed.",
+ parameters = { "self" },
+ options = remove_help_parameters({"query", "type"}, component_extra_help["Component.get"].options),
+ }
+ local method = query_action .. '_' .. query_type
+ Component[method] = function (component, options)
+ options = options or {}
+ if type(options) ~= 'table' then error('Invalid options: ' .. options) end
+ options['query'] = merge_tables({_type = query_type}, options[query_type] or {})
+ return component[query_action](component, options)
+ end
+ register_help(Component[method])
+ end
+end
+
+--------------------------------------------------------------------------------
+-- PubSub
+--------------------------------------------------------------------------------
+
+local function process_pubsub_event (event)
+ if event._type == 'pubsub_event_items' then
+ -- Add 'item' shortcut to payload of first item
+ event.item = event.items and event.items[1] and
+ event.items[1].data and event.items[1].data[1]
+ end
+end
+
+function PubSub:list_nodes (options)
+ return self.client:get_disco_items(merge_tables({to = self.jid}, options))
+end
+
+function PubSub:node (node)
+ local result = { client = self.client, jid = self.jid, node = node }
+ setmetatable(result, PubSubNode)
+ return result
+end
+
+local simple_pubsub_queries = {
+ get_default_configuration = 'pubsub_owner_default',
+ get_subscriptions = 'pubsub_subscriptions',
+ get_affiliations = 'pubsub_affiliations',
+ get_default_subscription_options = 'pubsub_default',
+}
+for method, query_type in pairs(simple_pubsub_queries) do
+ PubSub[method] = function (service, options)
+ options = options or {}
+ return service.client:query_pubsub(merge_tables(
+ { type = 'get', to = service.jid, query = { _type = query_type } },
+ options))
+ end
+end
+
+for _, method in ipairs({'events', 'get_next_event', 'for_each_event'}) do
+ PubSub[method] = function (node, ...)
+ local options = parse_options({}, ...)
+ options['if'] = function (event)
+ return event.type == 'pubsub' and event.from == node.jid and event.node == node
+ end
+ return node.client[method](node.client, options)
+ end
+end
+
+--------------------------------------------------------------------------------
+-- PubSubNode
+--------------------------------------------------------------------------------
+
+local function pubsub_node_configuration_to_form(configuration)
+ return create_form{configuration, form_type="http://jabber.org/protocol/pubsub#node_config", type="submit"}
+end
+
+function PubSubNode:list_items (options)
+ return self.client:get_disco_items(merge_tables({to = self.jid, disco_items = { node = self.node }}, options))
+end
+
+local simple_pubsub_node_queries = {
+ get_configuration = 'pubsub_owner_configure',
+ get_subscriptions = 'pubsub_subscriptions',
+ get_affiliations = 'pubsub_affiliations',
+ get_owner_subscriptions = 'pubsub_owner_subscriptions',
+ get_owner_affiliations = 'pubsub_owner_affiliations',
+ get_default_subscription_options = 'pubsub_default',
+}
+for method, query_type in pairs(simple_pubsub_node_queries) do
+ PubSubNode[method] = function (node, options)
+ return node.client:query_pubsub(merge_tables({
+ type = 'get', to = node.jid, query = {
+ _type = query_type, node = node.node
+ }}, options))
+ end
+end
+
+function PubSubNode:get_items (...)
+ local options = parse_options({}, ...)
+ local items = options.items or {}
+ if options.maximum_items then
+ items = merge_tables({maximum_items = options.maximum_items}, items)
+ end
+ items = merge_tables({_type = 'pubsub_items', node = self.node}, items)
+ return self.client:query_pubsub(merge_tables({
+ type = 'get', to = self.jid, query = items}, options))
+end
+
+function PubSubNode:get_item (...)
+ local options = parse_options({}, ...)
+ if not type(options.id) == 'string' then error('Expected ID') end
+ return self:get_items{items = {{id = options.id}}}
+end
+
+function PubSubNode:create (options)
+ options = options or {}
+ local configure
+ if options['configuration'] then
+ configure = { data = pubsub_node_configuration_to_form(options['configuration']) }
+ end
+ return self.client:query_pubsub(merge_tables(
+ { type = 'set', to = self.jid, query = {
+ _type = 'pubsub_create', node = self.node, configure = configure }
+ }, options))
+end
+
+function PubSubNode:delete (options)
+ options = options or {}
+ local redirect
+ if options['redirect'] then
+ redirect = {uri = options['redirect']}
+ end
+ return self.client:query_pubsub(merge_tables({ type = 'set', to = self.jid, query = {
+ _type = 'pubsub_owner_delete', node = self.node, redirect = redirect
+ }}, options))
+end
+
+function PubSubNode:set_configuration(options)
+ options = options or {}
+ local configuration = pubsub_node_configuration_to_form(options['configuration'])
+ return self.client:query_pubsub(merge_tables(
+ { type = 'set', to = self.jid, query = {
+ _type = 'pubsub_owner_configure', node = self.node, data = configuration }
+ }, options))
+end
+
+function PubSubNode:set_owner_affiliations(...)
+ local options = parse_options({}, ...)
+ return self.client:query_pubsub(merge_tables({
+ type = 'set', to = self.jid, query = merge_tables({
+ _type = 'pubsub_owner_affiliations', node = self.node,
+ }, options.affiliations)}, options))
+end
+
+
+function PubSubNode:subscribe(...)
+ local options = parse_options({}, ...)
+ local jid = options.jid or sluift.jid.to_bare(self.client:jid())
+ return self.client:query_pubsub(merge_tables(
+ { type = 'set', to = self.jid, query = {
+ _type = 'pubsub_subscribe', node = self.node, jid = jid }
+ }, options))
+end
+
+function PubSubNode:unsubscribe(options)
+ options = options or {}
+ return self.client:query_pubsub(merge_tables(
+ { type = 'set', to = self.jid, query = {
+ _type = 'pubsub_unsubscribe', node = self.node, jid = options['jid'],
+ subscription_id = 'subscription_id'}
+ }, options))
+end
+
+function PubSubNode:get_subscription_options (options)
+ return self.client:query_pubsub(merge_tables(
+ { type = 'get', to = self.jid, query = {
+ _type = 'pubsub_options', node = self.node, jid = options['jid'] }
+ }, options))
+end
+
+function PubSubNode:publish(...)
+ local options = parse_options({}, ...)
+ local items = options.items or {}
+ if options.item then
+ if type(options.item) == 'string' or options.item._type then
+ items = {{id = options.id, data = { options.item } }}
+ options.id = nil
+ else
+ items = { options.item }
+ end
+ options.item = nil
+ end
+ return self.client:query_pubsub(merge_tables(
+ { type = 'set', to = self.jid, query = {
+ _type = 'pubsub_publish', node = self.node, items = items }
+ }, options))
+end
+
+function PubSubNode:retract(...)
+ local options = parse_options({}, ...)
+ local items = options.items
+ if options.id then
+ items = {{id = options.id}}
+ end
+ return self.client:query_pubsub(merge_tables(
+ { type = 'set', to = self.jid, query = {
+ _type = 'pubsub_retract', node = self.node, items = items, notify = options['notify']
+ }}, options))
+end
+
+function PubSubNode:purge(...)
+ local options = parse_options({}, ...)
+ return self.client:query_pubsub(merge_tables(
+ { type = 'set', to = self.jid, query = {
+ _type = 'pubsub_owner_purge', node = self.node
+ }}, options))
+end
+
+-- Iterators over events
+for _, method in ipairs({'events', 'get_next_event', 'for_each_event'}) do
+ PubSubNode[method] = function (node, ...)
+ local options = parse_options({}, ...)
+ options['if'] = function (event)
+ return event.type == 'pubsub' and event.from == node.jid and event.node == node.node
+ end
+ return node.client[method](node.client, options)
+ end
+end
+
+--------------------------------------------------------------------------------
+-- Service discovery
+--------------------------------------------------------------------------------
+
+local disco = {
+ features = {
+ DISCO_INFO = 'http://jabber.org/protocol/disco#info',
+ COMMANDS = 'http://jabber.org/protocol/commands',
+ USER_LOCATION = 'http://jabber.org/protocol/geoloc',
+ USER_TUNE = 'http://jabber.org/protocol/tune',
+ USER_AVATAR_METADATA = 'urn:xmpp:avatar:metadata',
+ USER_ACTIVITY = 'http://jabber.org/protocol/activity',
+ USER_PROFILE = 'urn:xmpp:tmp:profile'
+ }
+}
+
+--------------------------------------------------------------------------------
+
+_H = nil
+
+extra_help['sluift'] = {
+ [[
+ This module provides methods for XMPP communication.
+
+ The main entry point of this module is the `new_client` method, which creates a
+ new client for communicating with an XMPP server.
+ ]],
+ classes = help_classes
+}
+
+return {
+ Client = Client,
+ Component = Component,
+ register_help = register_help,
+ register_class_help = register_class_help,
+ register_table_tostring = register_table_tostring,
+ register_table_equals = register_table_equals,
+ register_get_by_type_index = register_get_by_type_index,
+ process_pubsub_event = process_pubsub_event,
+ tprint = tprint,
+ read_file = read_file,
+ disco = disco,
+ get_help = get_help,
+ help = help,
+ extra_help = extra_help,
+ component_extra_help = component_extra_help,
+ copy = copy,
+ with = with,
+ create_form = create_form
+}
diff --git a/Sluift/globals.h b/Sluift/globals.h
index 3e7e1c9..f92beeb 100644
--- a/Sluift/globals.h
+++ b/Sluift/globals.h
@@ -1,6 +1,6 @@
/*
- * Copyright (c) 2013 Remko Tronçon
- * Licensed under the GNU General Public License.
+ * Copyright (c) 2013 Isode Limited.
+ * All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,7 +9,7 @@
#include <Sluift/SluiftGlobals.h>
namespace Swift {
- namespace Sluift {
- extern SluiftGlobals globals;
- }
+ namespace Sluift {
+ extern SluiftGlobals globals;
+ }
}
diff --git a/Sluift/linit.c b/Sluift/linit.c
deleted file mode 100644
index 8507609..0000000
--- a/Sluift/linit.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <lua.h>
-#include <lualib.h>
-#include <lauxlib.h>
-#include "sluift.h"
-
-static const luaL_Reg lualibs[] = {
- {"", luaopen_base},
- {LUA_LOADLIBNAME, luaopen_package},
- {LUA_TABLIBNAME, luaopen_table},
- {LUA_IOLIBNAME, luaopen_io},
- {LUA_OSLIBNAME, luaopen_os},
- {LUA_STRLIBNAME, luaopen_string},
- {LUA_MATHLIBNAME, luaopen_math},
- {LUA_DBLIBNAME, luaopen_debug},
- {"sluift", luaopen_sluift},
- {NULL, NULL}
-};
-
-
-LUALIB_API void luaL_openlibs (lua_State *L) {
- const luaL_Reg *lib = lualibs;
- for (; lib->func; lib++) {
- lua_pushcfunction(L, lib->func);
- lua_pushstring(L, lib->name);
- lua_call(L, 1, 0);
- }
-}
diff --git a/Sluift/main.cpp b/Sluift/main.cpp
new file mode 100644
index 0000000..65d6d60
--- /dev/null
+++ b/Sluift/main.cpp
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <boost/assign/list_of.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+#include <boost/program_options.hpp>
+#include <boost/program_options/options_description.hpp>
+#include <boost/program_options/variables_map.hpp>
+#include <boost/version.hpp>
+
+#include <lua.hpp>
+
+#include <Swiften/Base/Platform.h>
+
+#include <Sluift/globals.h>
+#include <Sluift/Console.h>
+#include <Sluift/StandardTerminal.h>
+#include <Sluift/sluift.h>
+#include <Sluift/Lua/LuaUtils.h>
+#ifdef HAVE_EDITLINE
+#include <Sluift/EditlineTerminal.h>
+#endif
+#include <Sluift/Version.h>
+
+using namespace Swift;
+
+#ifdef SWIFTEN_PLATFORM_WINDOWS
+#define EXIT_KEY "Z"
+#else
+#define EXIT_KEY "D"
+#endif
+
+static const std::string SLUIFT_WELCOME_STRING(
+ "== Sluift XMPP Console (" SLUIFT_VERSION_STRING ")\nPress Ctrl-" EXIT_KEY " to exit. Type help() for help.");
+
+static const luaL_Reg defaultLibraries[] = {
+ {"", luaopen_base},
+ {LUA_LOADLIBNAME, luaopen_package},
+ {LUA_TABLIBNAME, luaopen_table},
+ {LUA_IOLIBNAME, luaopen_io},
+ {LUA_OSLIBNAME, luaopen_os},
+ {LUA_STRLIBNAME, luaopen_string},
+ {LUA_MATHLIBNAME, luaopen_math},
+ {LUA_DBLIBNAME, luaopen_debug},
+ {"sluift", luaopen_sluift},
+ {nullptr, nullptr}
+};
+
+static void handleInterruptSignal(int) {
+ Sluift::globals.interruptRequested = 1;
+}
+
+static void checkResult(lua_State* L, int result) {
+ if (result && !lua_isnil(L, -1)) {
+ const char* errorMessage = lua_tostring(L, -1);
+ throw std::runtime_error(errorMessage ? errorMessage : "Unknown error");
+ }
+}
+
+static void initialize(lua_State* L) {
+ lua_gc(L, LUA_GCSTOP, 0);
+ for (const luaL_Reg* lib = defaultLibraries; lib->func; lib++) {
+#if LUA_VERSION_NUM >= 502
+ luaL_requiref(L, lib->name, lib->func, 1);
+ lua_pop(L, 1);
+#else
+ lua_pushcfunction(L, lib->func);
+ lua_pushstring(L, lib->name);
+ lua_call(L, 1, 0);
+#endif
+ }
+ lua_gc(L, LUA_GCRESTART, 0);
+}
+
+static void runScript(lua_State* L, const std::string& script, const std::vector<std::string>& scriptArguments) {
+ // Create arguments table
+ lua_createtable(L, boost::numeric_cast<int>(scriptArguments.size()), 0);
+ for (size_t i = 0; i < scriptArguments.size(); ++i) {
+ lua_pushstring(L, scriptArguments[i].c_str());
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ lua_setglobal(L, "arg");
+
+ // Load file
+ checkResult(L, luaL_loadfile(L, script.c_str()));
+ for (const auto& scriptArgument : scriptArguments) {
+ lua_pushstring(L, scriptArgument.c_str());
+ }
+ checkResult(L, Console::call(L, boost::numeric_cast<int>(scriptArguments.size()), false));
+}
+
+int main(int argc, char* argv[]) {
+ // Parse program options
+ boost::program_options::options_description visibleOptions("Options");
+ visibleOptions.add_options()
+ ("help,h", "Display this help message")
+ ("version,v", "Display version information")
+ ("interactive,i", "Enter interactive mode after executing script")
+ ;
+ boost::program_options::options_description hiddenOptions("Hidden Options");
+ hiddenOptions.add_options()
+ ("script", boost::program_options::value< std::string >(), "Script to be executed")
+ ("script-arguments", boost::program_options::value< std::vector<std::string> >(), "Script arguments")
+ ;
+ boost::program_options::options_description options("All Options");
+ options.add(visibleOptions).add(hiddenOptions);
+
+ boost::program_options::positional_options_description positional_options;
+ positional_options.add("script", 1).add("script-arguments", -1);
+
+ boost::program_options::variables_map arguments;
+ try {
+ boost::program_options::store(
+ boost::program_options::command_line_parser(argc, argv)
+ .options(options)
+ .positional(positional_options).run(), arguments);
+ }
+ catch (const boost::program_options::unknown_option& option) {
+#if BOOST_VERSION >= 104200
+ std::cout << "Ignoring unknown option " << option.get_option_name() << " but continuing." << std::endl;
+#else
+ std::cout << "Error: " << option.what() << " (continuing)" << std::endl;
+#endif
+ }
+ catch (const std::exception& e) {
+ std::cout << "Error: " << e.what() << std::endl;
+ return -1;
+ }
+ boost::program_options::notify(arguments);
+
+ // Help & version
+ if (arguments.count("help")) {
+ std::cout << visibleOptions << "\n";
+ return 0;
+ }
+ else if (arguments.count("version")) {
+ std::cout << SLUIFT_VERSION_STRING;
+ return 0;
+ }
+
+ lua_State* L = luaL_newstate();
+ initialize(L);
+ try {
+ // Run script
+ if (arguments.count("script")) {
+ std::vector<std::string> scriptArguments;
+ if (arguments.count("script-arguments")) {
+ scriptArguments = arguments["script-arguments"].as< std::vector<std::string> >();
+ }
+ runScript(L, arguments["script"].as<std::string>(), scriptArguments);
+ }
+
+ // Run console
+ if (arguments.count("interactive") || arguments.count("script") == 0) {
+ // Set up signal handler
+ signal(SIGINT, handleInterruptSignal);
+
+ // Import some useful functions into the global namespace
+ lua_getglobal(L, "sluift");
+ std::vector<std::string> globalImports = boost::assign::list_of
+ ("help")("with");
+ for (const auto& globalImport : globalImports) {
+ lua_getfield(L, -1, globalImport.c_str());
+ lua_setglobal(L, globalImport.c_str());
+ }
+ lua_pop(L, 1);
+
+ std::cout << SLUIFT_WELCOME_STRING << std::endl;
+#ifdef HAVE_EDITLINE
+ EditlineTerminal& terminal = EditlineTerminal::getInstance();
+#else
+ StandardTerminal terminal;
+#endif
+ Console console(L, &terminal);
+ console.run();
+ }
+ }
+ catch (const std::exception& e) {
+ std::cerr << e.what() << std::endl;
+ lua_close(L);
+ return -1;
+ }
+ lua_close(L);
+ return 0;
+}
diff --git a/Sluift/sluift.cpp b/Sluift/sluift.cpp
index e6096a0..561f404 100644
--- a/Sluift/sluift.cpp
+++ b/Sluift/sluift.cpp
@@ -1,159 +1,287 @@
/*
- * Copyright (c) 2011-2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#include <Sluift/sluift.h>
-#include <lua.hpp>
-
#include <string>
+
+#include <boost/assign/list_of.hpp>
#include <boost/bind.hpp>
+#include <boost/filesystem.hpp>
#include <boost/numeric/conversion/cast.hpp>
-#include <boost/assign/list_of.hpp>
-#include "Watchdog.h"
-#include <Sluift/Lua/Check.h>
-#include <Sluift/SluiftClient.h>
-#include <Sluift/globals.h>
-#include <Sluift/Lua/Exception.h>
-#include <Sluift/Lua/FunctionRegistration.h>
+#include <lua.hpp>
+
+#include <Swiften/Base/IDGenerator.h>
#include <Swiften/Base/sleep.h>
-#include <Swiften/Base/foreach.h>
+#include <Swiften/Crypto/CryptoProvider.h>
+#include <Swiften/Crypto/PlatformCryptoProvider.h>
+#include <Swiften/IDN/IDNConverter.h>
#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h>
-#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h>
#include <Swiften/Serializer/PayloadSerializer.h>
-#include <Sluift/Lua/Debug.h>
+#include <Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h>
#include <Swiften/StringCodecs/Base64.h>
#include <Swiften/StringCodecs/Hexify.h>
-#include <Swiften/Crypto/CryptoProvider.h>
-#include <Swiften/Crypto/PlatformCryptoProvider.h>
+#include <Swiften/TLS/Certificate.h>
+#include <Swiften/TLS/CertificateFactory.h>
+
+#include <Sluift/ITunesInterface.h>
+#include <Sluift/Lua/Check.h>
+#include <Sluift/Lua/Debug.h>
+#include <Sluift/Lua/Exception.h>
+#include <Sluift/Lua/FunctionRegistration.h>
+#include <Sluift/Lua/LuaUtils.h>
+#include <Sluift/LuaElementConvertor.h>
+#include <Sluift/SluiftClient.h>
+#include <Sluift/SluiftComponent.h>
+#include <Sluift/Watchdog.h>
+#include <Sluift/globals.h>
using namespace Swift;
namespace Swift {
- namespace Sluift {
- SluiftGlobals globals;
- }
+ namespace Sluift {
+ SluiftGlobals globals;
+ }
+}
+
+extern "C" const char core_lua[];
+extern "C" size_t core_lua_size;
+
+static inline bool getGlobalDebug(lua_State* L) {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.moduleLibIndex);
+ lua_getfield(L, -1, "debug");
+ int result = lua_toboolean(L, -1);
+ lua_pop(L, 2);
+ return result;
}
-extern "C" const char boot_lua[];
/*******************************************************************************
* Module functions
******************************************************************************/
-SLUIFT_LUA_FUNCTION(Sluift, new_client) {
- Lua::checkString(L, 1);
- JID jid(std::string(Lua::checkString(L, 1)));
- std::string password(Lua::checkString(L, 2));
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Sluift, new_client,
+
+ "Creates a new client.\n\nReturns a @{Client} object.\n",
+
+ "jid The JID to connect as\n"
+ "passphrase The passphrase to use\n",
- SluiftClient** client = reinterpret_cast<SluiftClient**>(lua_newuserdata(L, sizeof(SluiftClient*)));
- luaL_getmetatable(L, Lua::FunctionRegistry::getMetaTableNameForType("Client").c_str());
- lua_setmetatable(L, -2);
+ ""
+) {
+ Lua::checkString(L, 1);
+ JID jid(std::string(Lua::checkString(L, 1)));
+ std::string password(Lua::checkString(L, 2));
- *client = new SluiftClient(jid, password, &Sluift::globals.networkFactories, &Sluift::globals.eventLoop, &Sluift::globals);
- return 1;
+ SluiftClient** client = reinterpret_cast<SluiftClient**>(lua_newuserdata(L, sizeof(SluiftClient*)));
+
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ lua_getfield(L, -1, "Client");
+ lua_setmetatable(L, -3);
+ lua_pop(L, 1);
+
+ *client = new SluiftClient(jid, password, &Sluift::globals.networkFactories, &Sluift::globals.eventLoop);
+ (*client)->setTraceEnabled(getGlobalDebug(L));
+ return 1;
}
-SLUIFT_LUA_FUNCTION(Sluift, sha1) {
- static boost::shared_ptr<CryptoProvider> crypto(PlatformCryptoProvider::create());
- if (!lua_isstring(L, 1)) {
- throw Lua::Exception("Expected string");
- }
- size_t len;
- const char* data = lua_tolstring(L, 1, &len);
- ByteArray result = crypto->getSHA1Hash(createByteArray(data, len));
- lua_pushlstring(L, reinterpret_cast<char*>(vecptr(result)), result.size());
- return 1;
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Sluift, new_component,
+
+ "Creates a new component.\n\nReturns a @{Component} object.\n",
+
+ "jid The JID to connect as\n"
+ "passphrase The passphrase to use\n",
+
+ ""
+) {
+ Lua::checkString(L, 1);
+ JID jid(std::string(Lua::checkString(L, 1)));
+ std::string password(Lua::checkString(L, 2));
+
+ SluiftComponent** component = reinterpret_cast<SluiftComponent**>(lua_newuserdata(L, sizeof(SluiftComponent*)));
+
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ lua_getfield(L, -1, "Component");
+ lua_setmetatable(L, -3);
+ lua_pop(L, 1);
+
+ *component = new SluiftComponent(jid, password, &Sluift::globals.networkFactories, &Sluift::globals.eventLoop);
+ (*component)->setTraceEnabled(getGlobalDebug(L));
+ return 1;
}
-SLUIFT_LUA_FUNCTION(Sluift, sleep) {
- Sluift::globals.eventLoop.runOnce();
- int timeout = Lua::checkIntNumber(L, 1);
- Watchdog watchdog(timeout, Sluift::globals.networkFactories.getTimerFactory());
- while (!watchdog.getTimedOut()) {
- Swift::sleep(boost::numeric_cast<unsigned int>(std::min(100, timeout)));
- Sluift::globals.eventLoop.runOnce();
- }
- return 0;
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Sluift, sha1,
+ "Compute the SHA-1 hash of given data",
+ "data the data to hash",
+ ""
+) {
+ static std::shared_ptr<CryptoProvider> crypto(PlatformCryptoProvider::create());
+ if (!lua_isstring(L, 1)) {
+ throw Lua::Exception("Expected string");
+ }
+ size_t len;
+ const char* data = lua_tolstring(L, 1, &len);
+ ByteArray result = crypto->getSHA1Hash(createByteArray(data, len));
+ lua_pushlstring(L, reinterpret_cast<char*>(vecptr(result)), result.size());
+ return 1;
}
-static int sluift_index(lua_State* L) {
- try {
- std::string key(Lua::checkString(L, 2));
- if (key == "debug") {
- lua_pushboolean(L, Sluift::globals.debug);
- return 1;
- }
- else if (key == "timeout") {
- lua_pushnumber(L, Sluift::globals.timeout);
- return 1;
- }
- throw Lua::Exception("Unknown property");
- }
- catch (const std::exception& e) {
- return luaL_error(L, e.what());
- }
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Sluift, sleep,
+ "Sleeps for the given time.",
+ "milliseconds the amount of milliseconds to sleep",
+ ""
+) {
+ Sluift::globals.eventLoop.runOnce();
+ int timeout = Lua::checkIntNumber(L, 1);
+ Watchdog watchdog(timeout, Sluift::globals.networkFactories.getTimerFactory());
+ while (!watchdog.getTimedOut()) {
+ Swift::sleep(boost::numeric_cast<unsigned int>(std::min(100, timeout)));
+ Sluift::globals.eventLoop.runOnce();
+ }
+ return 0;
}
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Sluift, new_uuid,
+ "Generates a new UUID", "", ""
+) {
+ lua_pushstring(L, IDGenerator().generateID().c_str());
+ return 1;
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Sluift, from_xml,
+ "Convert a raw XML string into a structured representation.",
+ "string the string to convert",
+ ""
+) {
+ PayloadsParserTester parser;
+ if (!parser.parse(Lua::checkString(L, 1))) {
+ throw Lua::Exception("Error in XML");
+ }
+ return Sluift::globals.elementConvertor.convertToLua(L, parser.getPayload());
+}
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Sluift, to_xml,
+ "Convert a structured element into XML.",
+ "element the element to convert",
+ ""
+) {
+ static FullPayloadSerializerCollection serializers;
+ std::shared_ptr<Payload> payload = std::dynamic_pointer_cast<Payload>(Sluift::globals.elementConvertor.convertFromLua(L, 1));
+ if (!payload) {
+ throw Lua::Exception("Unrecognized XML");
+ }
+ PayloadSerializer* serializer = serializers.getPayloadSerializer(payload);
+ if (!payload) {
+ throw Lua::Exception("Unrecognized XML");
+ }
+ lua_pushstring(L, serializer->serialize(payload).c_str());
+ return 1;
+}
-static int sluift_newindex(lua_State* L) {
- try {
- std::string key(Lua::checkString(L, 2));
- if (key == "debug") {
- Sluift::globals.debug = lua_toboolean(L, 3);
- }
- else if (key == "timeout") {
- Sluift::globals.timeout = Lua::checkIntNumber(L, 3);
- }
- return 0;
- }
- catch (const std::exception& e) {
- return luaL_error(L, e.what());
- }
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Sluift, hexify,
+ "Convert binary data into hexadecimal format.",
+ "data the data to convert",
+ ""
+) {
+ if (!lua_isstring(L, 1)) {
+ throw Lua::Exception("Expected string");
+ }
+ size_t len;
+ const char* data = lua_tolstring(L, 1, &len);
+ lua_pushstring(L, Hexify::hexify(createByteArray(data, len)).c_str());
+ return 1;
}
-SLUIFT_LUA_FUNCTION(Sluift, from_xml) {
- PayloadsParserTester parser;
- if (!parser.parse(Lua::checkString(L, 1))) {
- throw Lua::Exception("Error in XML");
- }
- return Sluift::globals.elementConvertor.convertToLua(L, parser.getPayload());
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Sluift, unhexify,
+ "Convert hexadecimal data into binary data.",
+ "data the data in hexadecimal format",
+ ""
+) {
+ if (!lua_isstring(L, 1)) {
+ throw Lua::Exception("Expected string");
+ }
+ ByteArray result = Hexify::unhexify(lua_tostring(L, 1));
+ lua_pushlstring(L, reinterpret_cast<char*>(vecptr(result)), result.size());
+ return 1;
}
-SLUIFT_LUA_FUNCTION(Sluift, to_xml) {
- static FullPayloadSerializerCollection serializers;
- boost::shared_ptr<Payload> payload = Sluift::globals.elementConvertor.convertFromLua(L, 1);
- if (!payload) {
- throw Lua::Exception("Unrecognized XML");
- }
- PayloadSerializer* serializer = serializers.getPayloadSerializer(payload);
- if (!payload) {
- throw Lua::Exception("Unrecognized XML");
- }
- lua_pushstring(L, serializer->serialize(payload).c_str());
- return 1;
+/*******************************************************************************
+ * Crypto functions
+ ******************************************************************************/
+
+SLUIFT_LUA_FUNCTION_WITH_HELP(
+ Crypto, new_certificate,
+ "Creates a new X.509 certificate from DER data.\n",
+
+ "der the DER-encoded certificate data",
+
+ "") {
+ ByteArray certData(Lua::checkByteArray(L, 1));
+ Certificate::ref cert(Sluift::globals.tlsFactories.getCertificateFactory()->createCertificateFromDER(certData));
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, cert->getSubjectName().c_str());
+ lua_setfield(L, -2, "subject_name");
+ lua_pushstring(L, Certificate::getSHA1Fingerprint(cert, Sluift::globals.networkFactories.getCryptoProvider()).c_str());
+ lua_setfield(L, -2, "sha1_fingerprint");
+
+ Lua::pushStringArray(L, cert->getCommonNames());
+ lua_setfield(L, -2, "common_names");
+
+ Lua::pushStringArray(L, cert->getSRVNames());
+ lua_setfield(L, -2, "srv_names");
+
+ Lua::pushStringArray(L, cert->getDNSNames());
+ lua_setfield(L, -2, "dns_names");
+
+ Lua::pushStringArray(L, cert->getXMPPAddresses());
+ lua_setfield(L, -2, "xmpp_addresses");
+
+ Lua::registerTableToString(L, -1);
+ return 1;
}
-SLUIFT_LUA_FUNCTION(Sluift, hexify) {
- if (!lua_isstring(L, 1)) {
- throw Lua::Exception("Expected string");
- }
- size_t len;
- const char* data = lua_tolstring(L, 1, &len);
- lua_pushstring(L, Hexify::hexify(createByteArray(data, len)).c_str());
- return 1;
+/*******************************************************************************
+ * Filesystem Functions
+ ******************************************************************************/
+
+SLUIFT_LUA_FUNCTION(FS, list) {
+ boost::filesystem::path dir(std::string(Lua::checkString(L, 1)));
+ if (!boost::filesystem::exists(dir) || !boost::filesystem::is_directory(dir)) {
+ lua_pushnil(L);
+ lua_pushstring(L, "Argument is not an existing directory");
+ return 2;
+ }
+
+ boost::filesystem::directory_iterator i(dir);
+ std::vector<boost::filesystem::path> items(
+ i, boost::filesystem::directory_iterator());
+
+ lua_createtable(L, boost::numeric_cast<int>(items.size()), 0);
+ for (size_t i = 0; i < items.size(); ++i) {
+ lua_pushstring(L, items[i].string().c_str());
+ lua_rawseti(L, -2, boost::numeric_cast<int>(i+1));
+ }
+ Lua::registerTableToString(L, -1);
+ return 1;
}
-SLUIFT_LUA_FUNCTION(Sluift, unhexify) {
- if (!lua_isstring(L, 1)) {
- throw Lua::Exception("Expected string");
- }
- ByteArray result = Hexify::unhexify(lua_tostring(L, 1));
- lua_pushlstring(L, reinterpret_cast<char*>(vecptr(result)), result.size());
- return 1;
+SLUIFT_LUA_FUNCTION(FS, is_file) {
+ boost::filesystem::path file(std::string(Lua::checkString(L, 1)));
+ lua_pushboolean(L, boost::filesystem::is_regular_file(file));
+ return 1;
}
@@ -162,32 +290,32 @@ SLUIFT_LUA_FUNCTION(Sluift, unhexify) {
******************************************************************************/
SLUIFT_LUA_FUNCTION(JID, to_bare) {
- JID jid(std::string(Lua::checkString(L, 1)));
- lua_pushstring(L, jid.toBare().toString().c_str());
- return 1;
+ JID jid(std::string(Lua::checkString(L, 1)));
+ lua_pushstring(L, jid.toBare().toString().c_str());
+ return 1;
}
SLUIFT_LUA_FUNCTION(JID, node) {
- JID jid(std::string(Lua::checkString(L, 1)));
- lua_pushstring(L, jid.getNode().c_str());
- return 1;
+ JID jid(std::string(Lua::checkString(L, 1)));
+ lua_pushstring(L, jid.getNode().c_str());
+ return 1;
}
SLUIFT_LUA_FUNCTION(JID, domain) {
- JID jid(std::string(Lua::checkString(L, 1)));
- lua_pushstring(L, jid.getDomain().c_str());
- return 1;
+ JID jid(std::string(Lua::checkString(L, 1)));
+ lua_pushstring(L, jid.getDomain().c_str());
+ return 1;
}
SLUIFT_LUA_FUNCTION(JID, resource) {
- JID jid(std::string(Lua::checkString(L, 1)));
- lua_pushstring(L, jid.getResource().c_str());
- return 1;
+ JID jid(std::string(Lua::checkString(L, 1)));
+ lua_pushstring(L, jid.getResource().c_str());
+ return 1;
}
SLUIFT_LUA_FUNCTION(JID, escape_node) {
- lua_pushstring(L, JID::getEscapedNode(Lua::checkString(L, 1)).c_str());
- return 1;
+ lua_pushstring(L, JID::getEscapedNode(Lua::checkString(L, 1)).c_str());
+ return 1;
}
/*******************************************************************************
@@ -195,86 +323,179 @@ SLUIFT_LUA_FUNCTION(JID, escape_node) {
******************************************************************************/
SLUIFT_LUA_FUNCTION(Base64, encode) {
- if (!lua_isstring(L, 1)) {
- throw Lua::Exception("Expected string");
- }
- size_t len;
- const char* data = lua_tolstring(L, 1, &len);
- lua_pushstring(L, Base64::encode(createByteArray(data, len)).c_str());
- return 1;
+ if (!lua_isstring(L, 1)) {
+ throw Lua::Exception("Expected string");
+ }
+ size_t len;
+ const char* data = lua_tolstring(L, 1, &len);
+ lua_pushstring(L, Base64::encode(createByteArray(data, len)).c_str());
+ return 1;
}
SLUIFT_LUA_FUNCTION(Base64, decode) {
- if (!lua_isstring(L, 1)) {
- throw Lua::Exception("Expected string");
- }
- ByteArray result = Base64::decode(lua_tostring(L, 1));
- lua_pushlstring(L, reinterpret_cast<char*>(vecptr(result)), result.size());
- return 1;
+ if (!lua_isstring(L, 1)) {
+ throw Lua::Exception("Expected string");
+ }
+ ByteArray result = Base64::decode(lua_tostring(L, 1));
+ lua_pushlstring(L, reinterpret_cast<char*>(vecptr(result)), result.size());
+ return 1;
+}
+
+/*******************************************************************************
+ * IDN Functions
+ ******************************************************************************/
+
+SLUIFT_LUA_FUNCTION(IDN, encode) {
+ IDNConverter* converter = Sluift::globals.networkFactories.getIDNConverter();
+ boost::optional<std::string> encoded = converter->getIDNAEncoded(Lua::checkString(L, 1));
+ if (!encoded) {
+ lua_pushnil(L);
+ lua_pushstring(L, "Error encoding domain name");
+ return 2;
+ }
+ lua_pushstring(L, encoded->c_str());
+ return 1;
+}
+
+SLUIFT_LUA_FUNCTION(IDN, stringprep) {
+ IDNConverter* converter = Sluift::globals.networkFactories.getIDNConverter();
+ IDNConverter::StringPrepProfile profile;
+ std::string profileString = Lua::checkString(L, 2);
+ if (profileString == "nameprep") {
+ profile = IDNConverter::NamePrep;
+ }
+ else if (profileString == "xmpp_nodeprep") {
+ profile = IDNConverter::XMPPNodePrep;
+ }
+ else if (profileString == "xmpp_resourceprep") {
+ profile = IDNConverter::XMPPResourcePrep;
+ }
+ else if (profileString == "saslprep") {
+ profile = IDNConverter::SASLPrep;
+ }
+ else {
+ throw Lua::Exception("Invalid profile");
+ }
+ try {
+ lua_pushstring(L, converter->getStringPrepared(Lua::checkString(L, 1), profile).c_str());
+ }
+ catch (const std::exception&) {
+ throw Lua::Exception("Error");
+ }
+ return 1;
+}
+
+/*******************************************************************************
+ * iTunes Functions
+ ******************************************************************************/
+
+#ifdef HAVE_ITUNES
+SLUIFT_LUA_FUNCTION(iTunes, get_current_track) {
+ boost::optional<ITunesInterface::Track> track = Sluift::globals.iTunes.getCurrentTrack();
+ if (!track) {
+ return 0;
+ }
+ lua_createtable(L, 0, 0);
+ lua_pushstring(L, track->artist.c_str());
+ lua_setfield(L, -2, "artist");
+ lua_pushstring(L, track->name.c_str());
+ lua_setfield(L, -2, "name");
+ lua_pushstring(L, track->album.c_str());
+ lua_setfield(L, -2, "album");
+ lua_pushinteger(L, track->trackNumber);
+ lua_setfield(L, -2, "track_number");
+ lua_pushnumber(L, track->duration);
+ lua_setfield(L, -2, "duration");
+ lua_pushinteger(L, track->rating);
+ lua_setfield(L, -2, "rating");
+ Lua::registerTableToString(L, -1);
+ Lua::registerTableEquals(L, -1);
+ return 1;
}
+#endif
/*******************************************************************************
* Module registration
******************************************************************************/
-static const luaL_reg sluift_functions[] = { {NULL, NULL} };
+static const luaL_Reg sluift_functions[] = { {nullptr, nullptr} };
SLUIFT_API int luaopen_sluift(lua_State* L) {
- // Initialize globals
- Sluift::globals.debug = false;
- Sluift::globals.timeout = -1;
-
- luaL_register(L, "sluift", sluift_functions);
-
- // Load bootstrap code
- if (luaL_loadbuffer(L, boot_lua, strlen(boot_lua), "boot.lua") != 0) {
- lua_error(L);
- }
- lua_call(L, 0, 1);
- Sluift::globals.bootIndex = luaL_ref(L, LUA_REGISTRYINDEX);
-
- // Register functions
- Lua::FunctionRegistry::getInstance().addFunctionsToTable(L, "Sluift");
- Lua::FunctionRegistry::getInstance().createFunctionTable(L, "JID");
- lua_setfield(L, -2, "jid");
- Lua::FunctionRegistry::getInstance().createFunctionTable(L, "Base64");
- lua_setfield(L, -2, "base64");
-
- // Register convenience functions
- lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.bootIndex);
- lua_getfield(L, -1, "tprint");
- lua_setfield(L, -3, "tprint");
- lua_pop(L, 1);
-
- lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.bootIndex);
- lua_getfield(L, -1, "disco");
- lua_setfield(L, -3, "disco");
- lua_pop(L, 1);
-
- // Set read only
- lua_createtable(L, 0, 0);
- lua_pushcclosure(L, sluift_index, 0);
- lua_setfield(L, -2, "__index");
- lua_pushcclosure(L, sluift_newindex, 0);
- lua_setfield(L, -2, "__newindex");
- lua_setmetatable(L, -2);
-
- // Load client metatable
- std::vector<std::string> tables = boost::assign::list_of("Client");
- foreach (const std::string& table, tables) {
- Lua::FunctionRegistry::getInstance().registerTypeMetaTable(L, table);
- luaL_getmetatable(L, Lua::FunctionRegistry::getMetaTableNameForType(table).c_str());
- lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.bootIndex);
- lua_getfield(L, -1, table.c_str());
- if (!lua_isnil(L, -1)) {
- for (lua_pushnil(L); lua_next(L, -2); ) {
- lua_pushvalue(L, -2);
- lua_pushvalue(L, -2);
- lua_settable(L, -7);
- lua_pop(L, 1);
- }
- }
- lua_pop(L, 2);
- }
- return 1;
+ // Initialize & store the module table
+ luaL_register(L, lua_tostring(L, 1), sluift_functions);
+ lua_pushinteger(L, -1);
+ lua_setfield(L, -2, "timeout");
+ lua_pushboolean(L, 0);
+ lua_setfield(L, -2, "debug");
+
+ lua_pushvalue(L, -1);
+ Sluift::globals.moduleLibIndex = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ // Load core lib code
+ if (luaL_loadbuffer(L, core_lua, core_lua_size, "core.lua") != 0) {
+ lua_error(L);
+ }
+ lua_pushvalue(L, -2);
+ lua_call(L, 1, 1);
+ Sluift::globals.coreLibIndex = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ // Register functions
+ Lua::FunctionRegistry::getInstance().addFunctionsToTable(L, "Sluift");
+ Lua::FunctionRegistry::getInstance().createFunctionTable(L, "JID");
+ lua_setfield(L, -2, "jid");
+ Lua::FunctionRegistry::getInstance().createFunctionTable(L, "Base64");
+ lua_setfield(L, -2, "base64");
+ Lua::FunctionRegistry::getInstance().createFunctionTable(L, "IDN");
+ lua_setfield(L, -2, "idn");
+ Lua::FunctionRegistry::getInstance().createFunctionTable(L, "Crypto");
+ lua_setfield(L, -2, "crypto");
+ Lua::FunctionRegistry::getInstance().createFunctionTable(L, "FS");
+ lua_setfield(L, -2, "fs");
+#ifdef HAVE_ITUNES
+ Lua::FunctionRegistry::getInstance().createFunctionTable(L, "iTunes");
+ lua_setfield(L, -2, "itunes");
+#endif
+
+ // Register convenience functions
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ std::vector<std::string> coreLibExports = boost::assign::list_of
+ ("tprint")("disco")("help")("get_help")("copy")("with")("read_file")("create_form");
+ for (const auto& coreLibExport : coreLibExports) {
+ lua_getfield(L, -1, coreLibExport.c_str());
+ lua_setfield(L, -3, coreLibExport.c_str());
+ }
+ lua_pop(L, 1);
+
+ // Load client metatable
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ std::vector<std::string> tables = boost::assign::list_of("Client");
+ for (const auto& table : tables) {
+ lua_getfield(L, -1, table.c_str());
+ Lua::FunctionRegistry::getInstance().addFunctionsToTable(L, table);
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1);
+
+ // Load component metatable
+ lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
+ std::vector<std::string> comp_tables = boost::assign::list_of("Component");
+ for (const auto& table : comp_tables) {
+ lua_getfield(L, -1, table.c_str());
+ Lua::FunctionRegistry::getInstance().addFunctionsToTable(L, table);
+ lua_pop(L, 1);
+ }
+ lua_pop(L, 1);
+
+ // Register documentation for all elements
+ for (auto&& convertor : Sluift::globals.elementConvertor.getConvertors()) {
+ boost::optional<LuaElementConvertor::Documentation> documentation = convertor->getDocumentation();
+ if (documentation) {
+ Lua::registerClassHelp(L, documentation->className, documentation->description);
+ }
+ }
+
+ // Register global documentation
+ Lua::registerExtraHelp(L, -1, "sluift");
+
+ return 1;
}
diff --git a/Sluift/sluift.h b/Sluift/sluift.h
index b82e1c4..4ffe3bf 100644
--- a/Sluift/sluift.h
+++ b/Sluift/sluift.h
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2011-2013 Remko Tronçon
- * Licensed under the GNU General Public License v3.
- * See Documentation/Licenses/GPLv3.txt for more information.
+ * Copyright (c) 2011-2013 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
*/
#pragma once
diff --git a/Sluift/tokenize.cpp b/Sluift/tokenize.cpp
new file mode 100644
index 0000000..ff162d6
--- /dev/null
+++ b/Sluift/tokenize.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/tokenize.h>
+
+#include <cctype>
+
+#include <boost/tokenizer.hpp>
+
+using namespace Swift;
+
+namespace {
+ struct LuaTokenizeFunctor {
+ void reset() {
+ }
+
+ template<typename InputIterator, typename Token>
+ bool operator()(InputIterator& next, InputIterator& end, Token& result) {
+ while (next != end && std::isspace(*next)) {
+ ++next;
+ }
+ if (next == end) {
+ return false;
+ }
+
+ std::vector<char> token;
+ char c = *next++;
+ token.push_back(c);
+
+ // String literal
+ if (c == '\'' || c == '"') {
+ char quote = c;
+ bool inEscape = false;
+ for (; next != end; ++next) {
+ c = *next;
+ token.push_back(c);
+ if (inEscape) {
+ inEscape = false;
+ }
+ else if (c == '\\') {
+ inEscape = true;
+ }
+ else if (c == quote) {
+ break;
+ }
+ }
+ if (next != end) {
+ ++next;
+ }
+ }
+ // Identifier
+ else if (std::isalpha(c) || c == '_') {
+ while (next != end && (std::isalpha(*next) || *next == '_' || std::isdigit(*next))) {
+ token.push_back(*next);
+ ++next;
+ }
+ }
+ // Digit
+ else if (std::isdigit(c)) {
+ while (next != end && !std::isspace(*next)) {
+ token.push_back(*next);
+ ++next;
+ }
+ }
+ // Dots
+ else if (c == '.') {
+ while (next != end && *next == '.') {
+ token.push_back(*next);
+ ++next;
+ }
+ }
+
+ result = Token(&token[0], token.size());
+ return true;
+ }
+ };
+}
+
+
+std::vector<std::string> Lua::tokenize(const std::string& input) {
+ boost::tokenizer<LuaTokenizeFunctor> tokenizer(input);
+ return std::vector<std::string>(tokenizer.begin(), tokenizer.end());
+}
+
diff --git a/Sluift/tokenize.h b/Sluift/tokenize.h
new file mode 100644
index 0000000..33ea435
--- /dev/null
+++ b/Sluift/tokenize.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2013-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+namespace Swift {
+ namespace Lua {
+ std::vector<std::string> tokenize(const std::string&);
+ }
+}