summaryrefslogtreecommitdiffstats
path: root/Sluift
diff options
context:
space:
mode:
Diffstat (limited to 'Sluift')
-rw-r--r--Sluift/Lua/Value.cpp66
-rw-r--r--Sluift/Lua/Value.h34
-rw-r--r--Sluift/SConscript1
-rw-r--r--Sluift/sluift.cpp75
4 files changed, 130 insertions, 46 deletions
diff --git a/Sluift/Lua/Value.cpp b/Sluift/Lua/Value.cpp
new file mode 100644
index 0000000..b612bd9
--- /dev/null
+++ b/Sluift/Lua/Value.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include "Value.h"
+
+extern "C" {
+ #include <lualib.h>
+}
+#include <boost/variant/apply_visitor.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) {
+ }
+
+ void operator()(const Nil&) const {
+ lua_pushnil(state);
+ }
+
+ void operator()(const bool& b) const {
+ lua_pushboolean(state, b);
+ }
+
+ 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::vector<Value>& list) const {
+ lua_newtable(state);
+ int i = 0;
+ foreach(const Value& value, list) {
+ boost::apply_visitor(PushVisitor(state), value);
+ lua_rawseti(state, -2, i + 1);
+ }
+ }
+
+ void operator()(const std::map<std::string, boost::shared_ptr<Value> >& table) const {
+ lua_createtable(state, 0, 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());
+ }
+ }
+
+ lua_State* state;
+ };
+}
+
+namespace Swift { namespace Lua {
+
+void pushValue(lua_State* state, const Value& value) {
+ boost::apply_visitor(PushVisitor(state), value);
+}
+
+}}
diff --git a/Sluift/Lua/Value.h b/Sluift/Lua/Value.h
new file mode 100644
index 0000000..9b6da34
--- /dev/null
+++ b/Sluift/Lua/Value.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <map>
+#include <string>
+#include <vector>
+#include <boost/variant.hpp>
+#include <boost/shared_ptr.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;
+
+ void pushValue(lua_State* state, const Value& value);
+ }
+}
diff --git a/Sluift/SConscript b/Sluift/SConscript
index eeb2f24..ec9f690 100644
--- a/Sluift/SConscript
+++ b/Sluift/SConscript
@@ -6,6 +6,7 @@ if env["SCONS_STAGE"] == "build" :
lib_env.UseFlags(env["SWIFTEN_FLAGS"])
lib_env.UseFlags(env["SWIFTEN_DEP_FLAGS"])
sluift_lib = lib_env.StaticLibrary("SluiftCore", [
+ "Lua/Value.cpp",
"sluift.cpp"
]);
diff --git a/Sluift/sluift.cpp b/Sluift/sluift.cpp
index da2c93b..d4692a3 100644
--- a/Sluift/sluift.cpp
+++ b/Sluift/sluift.cpp
@@ -12,6 +12,7 @@ extern "C" {
#include <iostream>
#include <string>
#include <deque>
+#include <boost/assign/list_of.hpp>
#include <Swiften/Client/Client.h>
#include <Swiften/Client/ClientXMLTracer.h>
@@ -28,6 +29,7 @@ extern "C" {
#include "Watchdog.h"
#include "SluiftException.h"
#include "ResponseSink.h"
+#include "Lua/Value.h"
using namespace Swift;
@@ -118,7 +120,7 @@ class SluiftClient {
client->setSoftwareVersion(name, version, os);
}
- boost::optional<SoftwareVersion> getSoftwareVersion(const JID& jid) {
+ SoftwareVersion::ref getSoftwareVersion(const JID& jid) {
ResponseSink<SoftwareVersion> sink;
GetSoftwareVersionRequest::ref request = GetSoftwareVersionRequest::create(jid, client->getIQRouter());
request->onResponse.connect(boost::ref(sink));
@@ -126,7 +128,7 @@ class SluiftClient {
while (!sink.hasResponse()) {
eventLoop.runUntilEvents();
}
- return sink.getResponsePayload() ? *sink.getResponsePayload() : boost::optional<SoftwareVersion>();
+ return sink.getResponsePayload();
}
Stanza::ref getNextEvent(int timeout) {
@@ -256,15 +258,8 @@ static int sluift_client_set_version(lua_State *L) {
static int sluift_client_get_roster(lua_State *L) {
try {
SluiftClient* client = getClient(L);
- std::vector<XMPPRosterItem> items = client->getRoster();
-
- lua_createtable(L, 0, items.size());
- foreach(const XMPPRosterItem& item, items) {
- lua_createtable(L, 0, 3);
-
- lua_pushstring(L, item.getName().c_str());
- lua_setfield(L, -2, "name");
-
+ Lua::Table rosterTable;
+ foreach(const XMPPRosterItem& item, client->getRoster()) {
std::string subscription;
switch(item.getSubscription()) {
case RosterItemPayload::None: subscription = "none"; break;
@@ -273,19 +268,14 @@ static int sluift_client_get_roster(lua_State *L) {
case RosterItemPayload::Both: subscription = "both"; break;
case RosterItemPayload::Remove: subscription = "remove"; break;
}
- lua_pushstring(L, subscription.c_str());
- lua_setfield(L, -2, "subscription");
-
- std::vector<std::string> groups = item.getGroups();
- lua_createtable(L, groups.size(), 0);
- for (size_t i = 0; i < groups.size(); ++i) {
- lua_pushstring(L, groups[i].c_str());
- lua_rawseti(L, -2, i + 1);
- }
- lua_setfield(L, -2, "groups");
-
- lua_setfield(L, -2, item.getJID().toString().c_str());
+ Lua::Value groups(std::vector<Lua::Value>(item.getGroups().begin(), item.getGroups().end()));
+ Lua::Table itemTable = boost::assign::map_list_of
+ ("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())));
+ rosterTable[item.getJID().toString()] = boost::make_shared<Lua::Value>(itemTable);
}
+ pushValue(L, rosterTable);
return 1;
}
catch (const SluiftException& e) {
@@ -297,16 +287,13 @@ static int sluift_client_get_version(lua_State *L) {
try {
SluiftClient* client = getClient(L);
JID jid(std::string(luaL_checkstring(L, 2)));
-
- boost::optional<SoftwareVersion> version = client->getSoftwareVersion(jid);
+ SoftwareVersion::ref version = client->getSoftwareVersion(jid);
if (version) {
- lua_createtable(L, 0, 3);
- lua_pushstring(L, version->getName().c_str());
- lua_setfield(L, -2, "name");
- lua_pushstring(L, version->getVersion().c_str());
- lua_setfield(L, -2, "version");
- lua_pushstring(L, version->getOS().c_str());
- lua_setfield(L, -2, "os");
+ Lua::Table result = boost::assign::map_list_of
+ ("name", boost::make_shared<Lua::Value>(version->getName()))
+ ("version", boost::make_shared<Lua::Value>(version->getVersion()))
+ ("os", boost::make_shared<Lua::Value>(version->getOS()));
+ Lua::pushValue(L, result);
}
else {
lua_pushnil(L);
@@ -382,22 +369,18 @@ static int sluift_client_set_options(lua_State* L) {
static void pushEvent(lua_State* L, Stanza::ref event) {
if (Message::ref message = boost::dynamic_pointer_cast<Message>(event)) {
- lua_createtable(L, 0, 3);
- lua_pushliteral(L, "message");
- lua_setfield(L, -2, "type");
- lua_pushstring(L, message->getFrom().toString().c_str());
- lua_setfield(L, -2, "from");
- lua_pushstring(L, message->getBody().c_str());
- lua_setfield(L, -2, "body");
+ Lua::Table result = boost::assign::map_list_of
+ ("type", boost::make_shared<Lua::Value>("message"))
+ ("from", boost::make_shared<Lua::Value>(message->getFrom().toString()))
+ ("body", boost::make_shared<Lua::Value>(message->getBody()));
+ Lua::pushValue(L, result);
}
else if (Presence::ref presence = boost::dynamic_pointer_cast<Presence>(event)) {
- lua_createtable(L, 0, 3);
- lua_pushliteral(L, "presence");
- lua_setfield(L, -2, "type");
- lua_pushstring(L, presence->getFrom().toString().c_str());
- lua_setfield(L, -2, "from");
- lua_pushstring(L, presence->getStatus().c_str());
- lua_setfield(L, -2, "status");
+ Lua::Table result = boost::assign::map_list_of
+ ("type", boost::make_shared<Lua::Value>("presence"))
+ ("from", boost::make_shared<Lua::Value>(presence->getFrom().toString()))
+ ("status", boost::make_shared<Lua::Value>(presence->getStatus()));
+ Lua::pushValue(L, result);
}
else {
lua_pushnil(L);