diff options
author | Remko Tronçon <git@el-tramo.be> | 2011-03-01 20:57:03 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2011-03-01 21:25:56 (GMT) |
commit | 182dc1c6cbed6ac2bbe297f856650367e0f12ba7 (patch) | |
tree | f9f683e6688683eed559f37d2dfa2ed0966a89c1 /Sluift | |
parent | 48389cafdbf211d70fa56f453c6d3b652482a139 (diff) | |
download | swift-182dc1c6cbed6ac2bbe297f856650367e0f12ba7.zip swift-182dc1c6cbed6ac2bbe297f856650367e0f12ba7.tar.bz2 |
Introduce Lua::Value helper.
Diffstat (limited to 'Sluift')
-rw-r--r-- | Sluift/Lua/Value.cpp | 66 | ||||
-rw-r--r-- | Sluift/Lua/Value.h | 34 | ||||
-rw-r--r-- | Sluift/SConscript | 1 | ||||
-rw-r--r-- | Sluift/sluift.cpp | 75 |
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); |