From 4f1274bcdd2af1a38b7de0b3ef4c18d6cd83c4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Sun, 1 Sep 2013 08:12:18 +0200 Subject: Sluift: More PubSub convenience methods & use cases. - Convenience iterators to PubSub and PubSubNode. - Retrieving X most recent items - Retrieving a single item - Fixed GeoLocation serializer Change-Id: Ib4ecde225fb274b21163fcc9b52e19b0d3431860 diff --git a/.gitignore b/.gitignore index c89f9bf..b67b8e0 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ *.moc *.patch *.dSYM +*.ld_* .gdb_history .clang_complete *~ diff --git a/Sluift/ElementConvertors/BodyConvertor.cpp b/Sluift/ElementConvertors/BodyConvertor.cpp new file mode 100644 index 0000000..a7abc1e --- /dev/null +++ b/Sluift/ElementConvertors/BodyConvertor.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +#include + +#include +#include +#include + +using namespace Swift; + +BodyConvertor::BodyConvertor() : GenericLuaElementConvertor("body") { +} + +BodyConvertor::~BodyConvertor() { +} + +boost::shared_ptr BodyConvertor::doConvertFromLua(lua_State* L) { + boost::shared_ptr result = boost::make_shared(); + if (boost::optional value = Lua::getStringField(L, -1, "text")) { + result->setText(*value); + } + return result; +} + +void BodyConvertor::doConvertToLua(lua_State* L, boost::shared_ptr 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 new file mode 100644 index 0000000..b1cd494 --- /dev/null +++ b/Sluift/ElementConvertors/BodyConvertor.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2013 Remko Tronçon + * Licensed under the GNU General Public License. + * See the COPYING file for more information. + */ + +#pragma once + +#include + +#include +#include + +namespace Swift { + class LuaElementConvertors; + + class BodyConvertor : public GenericLuaElementConvertor { + public: + BodyConvertor(); + virtual ~BodyConvertor(); + + virtual boost::shared_ptr doConvertFromLua(lua_State*) SWIFTEN_OVERRIDE; + virtual void doConvertToLua(lua_State*, boost::shared_ptr) SWIFTEN_OVERRIDE; + }; +} diff --git a/Sluift/ElementConvertors/DiscoItemsConvertor.cpp b/Sluift/ElementConvertors/DiscoItemsConvertor.cpp index 6c39aea..a38e766 100644 --- a/Sluift/ElementConvertors/DiscoItemsConvertor.cpp +++ b/Sluift/ElementConvertors/DiscoItemsConvertor.cpp @@ -49,12 +49,18 @@ void DiscoItemsConvertor::doConvertToLua(lua_State* L, boost::shared_ptr(items.size()), 0); for (size_t i = 0; i < items.size(); ++i) { lua_createtable(L, 0, 0); - lua_pushstring(L, items[i].getName().c_str()); - lua_setfield(L, -2, "name"); - lua_pushstring(L, items[i].getNode().c_str()); - lua_setfield(L, -2, "node"); - lua_pushstring(L, items[i].getJID().toString().c_str()); - lua_setfield(L, -2, "jid"); + 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(i+1)); } lua_setfield(L, -2, "items"); diff --git a/Sluift/Examples/Wonderland.lua b/Sluift/Examples/Wonderland.lua index 235d8d0..426ec07 100755 --- a/Sluift/Examples/Wonderland.lua +++ b/Sluift/Examples/Wonderland.lua @@ -8,45 +8,97 @@ -- require "sluift" ---sluift.debug = true +sluift.debug = true characters = { - {jid = "alice@wonderland.lit", name = "Alice", groups = {}, presence = ""}, - {jid = "hatter@wonderland.lit", name = "Mad Hatter", groups = {}, presence = "awayAt the Tea Party"}, - {jid ="queen@wonderland.lit", name = "Queen of Hearts", groups = {}, presence = "dndExecuting"}, - {jid = "rabbit@wonderland.lit", name = "White Rabbit", groups = {"Animals"}, presence = "Oh dear!"}, - {jid = "turtle@wonderland.lit", name = "Mock Turtle", groups = {"Animals"}, presence = ""}, + ["Alice"] = { + jid = "alice@wonderland.lit", groups = {}, presence = "" + }, + ["Mad Hatter"] = { + jid = "hatter@wonderland.lit", groups = {}, + presence = "awayAt the Tea Party" + }, + ["Queen of Hearts"] = { + jid ="queen@wonderland.lit", groups = {}, + presence = "dndExecuting" + }, + ["White Rabbit"] = { + jid = "rabbit@wonderland.lit", groups = {"Animals"}, + presence = "Oh dear!"}, + ["Mock Turtle"] = { + jid = "turtle@wonderland.lit", groups = {"Animals"}, + presence = "" + }, } -clients = {} -for _, character in ipairs(characters) do - print("Connecting " .. character["name"] .. "...") - client = sluift.new_client(character["jid"], os.getenv("SLUIFT_PASS")) +for name, character in pairs(characters) do + print("Connecting " .. name .. "...") + local client = sluift.new_client(character.jid, os.getenv("SLUIFT_PASS")) client:set_options({compress = false, tls = false}) client:connect() client:get_contacts() - client:send(character["presence"]) - table.insert(clients, client) - for _, contact in ipairs(characters) do - if contact["jid"] ~= character["jid"] then + client:send(character.presence) + for contact_name, contact in pairs(characters) do + if contact.jid ~= character.jid then client:add_contact(contact) end end + character.client = client end print("Confirming subscriptions") -for _, client in ipairs(clients) do - for _, contact in ipairs(characters) do - client:confirm_subscription(contact["jid"]) +for _, character in pairs(characters) do + for _, contact in pairs(characters) do + character.client:confirm_subscription(contact.jid) end end +print("Setting up PubSub nodes") +local hatters_riddles = characters["Mad Hatter"].client:pubsub("pubsub.wonderland.lit"):node("hatters_riddles") +hatters_riddles:delete() +assert(hatters_riddles:create()) + +local queen_quotes = characters["Queen of Hearts"].client:pubsub("pubsub.wonderland.lit"):node("queen_quotes") +queen_quotes:delete() +assert(queen_quotes:create()) +queen_quotes:publish{id = 'quote1', item = {_type = 'body', text = 'Off with his head!'}} +queen_quotes:publish{id = 'quote2', item = {_type = 'body', text = 'Off with her head!'}} +queen_quotes:publish{id = 'quote3', item = {_type = 'body', text = 'Off with their heads!'}} + +characters['Mad Hatter'].client:pubsub():node('http://jabber.org/protocol/geoloc'):publish{ + item = {_type = 'user_location', latitude = 50.376739, longitude = -4.200709}} +characters['Queen of Hearts'].client:pubsub():node('http://jabber.org/protocol/geoloc'):publish{ + item = {_type = 'user_location', latitude = 50.551123, longitude = -4.141654}} +characters['Mock Turtle'].client:pubsub():node('http://jabber.org/protocol/geoloc'):publish{ + item = {_type = 'user_location', latitude = 50.366630, longitude = -4.134518}} +characters['White Rabbit'].client:pubsub():node('http://jabber.org/protocol/geoloc'):publish{ + item = {_type = 'user_location', latitude = 50.332907, longitude = -4.759194}} + + + +print("Disconnecting alice") +characters['Alice'].client:disconnect() + print("Done. Waiting ...") while true do - for _, client in ipairs(clients) do - for message in client:messages {timeout = 1000} do - client:send_message{to = e["from"], body = "Off with their heads!"} + for name, character in pairs(characters) do + if name == 'Queen of Hearts' then + for message in character.client:messages{timeout = 1000} do + if message.body == 'publish' then + queen_quotes:publish{item = {_type = 'body', text = 'Off with her head!'}} + queen_quotes:publish{item = {_type = 'body', text = 'Off with his head!'}} + else + character.client:send_message{to = e["from"], body = "Off with their heads!"} + end + end + elseif name == "Mad Hatter" then + for message in character.client:messages{timeout = 1000} do + if message.body == 'publish' then + hatters_riddles:publish{item = {_type = 'body', text = 'Why is a raven like a writing desk?'}} + end + end + else + for message in character.client:messages{timeout = 100} do end end end - sluift.sleep(1000) end diff --git a/Sluift/LuaElementConvertors.cpp b/Sluift/LuaElementConvertors.cpp index 5913858..cadfbc4 100644 --- a/Sluift/LuaElementConvertors.cpp +++ b/Sluift/LuaElementConvertors.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,7 @@ using namespace Swift; LuaElementConvertors::LuaElementConvertors() { registerConvertors(); convertors.push_back(boost::make_shared(this)); + convertors.push_back(boost::make_shared()); convertors.push_back(boost::make_shared()); convertors.push_back(boost::make_shared()); convertors.push_back(boost::make_shared()); diff --git a/Sluift/SConscript b/Sluift/SConscript index fcc39fc..c4d3b28 100644 --- a/Sluift/SConscript +++ b/Sluift/SConscript @@ -18,6 +18,7 @@ elif env["SCONS_STAGE"] == "build" : "LuaElementConvertors.cpp", "LuaElementConvertor.cpp", "Response.cpp", + "ElementConvertors/BodyConvertor.cpp", "ElementConvertors/VCardUpdateConvertor.cpp", "ElementConvertors/PubSubEventConvertor.cpp", "ElementConvertors/RawXMLElementConvertor.cpp", diff --git a/Sluift/SluiftClient.cpp b/Sluift/SluiftClient.cpp index 726a683..8a8d772 100644 --- a/Sluift/SluiftClient.cpp +++ b/Sluift/SluiftClient.cpp @@ -87,14 +87,15 @@ void SluiftClient::setSoftwareVersion(const std::string& name, const std::string client->setSoftwareVersion(name, version, os); } -boost::optional SluiftClient::getNextEvent(boost::optional type, int timeout) { +boost::optional SluiftClient::getNextEvent( + int timeout, boost::function 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 (!type || *type == event.type) { + if (!condition || condition(event)) { return event; } } diff --git a/Sluift/SluiftClient.h b/Sluift/SluiftClient.h index 6515b7d..bedd6ba 100644 --- a/Sluift/SluiftClient.h +++ b/Sluift/SluiftClient.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -101,7 +102,8 @@ namespace Swift { void disconnect(); void setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os); - boost::optional getNextEvent(boost::optional type, int timeout); + boost::optional getNextEvent(int timeout, + boost::function condition = 0); std::vector getRoster(); private: diff --git a/Sluift/boot.lua b/Sluift/boot.lua index ae8cc41..e81257a 100644 --- a/Sluift/boot.lua +++ b/Sluift/boot.lua @@ -157,6 +157,12 @@ for method, event_type in pairs({message = 'message', presence = 'presence', pub 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 @@ -222,6 +228,16 @@ for method, query_type in pairs(simple_pubsub_queries) do 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 -------------------------------------------------------------------------------- @@ -247,7 +263,6 @@ local simple_pubsub_node_queries = { get_configuration = 'pubsub_owner_configure', get_subscriptions = 'pubsub_subscriptions', get_affiliations = 'pubsub_affiliations', - get_items = 'pubsub_items', get_default_subscription_options = 'pubsub_default', } for method, query_type in pairs(simple_pubsub_node_queries) do @@ -259,6 +274,23 @@ for method, query_type in pairs(simple_pubsub_node_queries) do 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 @@ -291,11 +323,12 @@ function PubSubNode.set_configuration(node, options) }, options)) end -function PubSubNode.subscribe(node, options) - options = options or {} +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 = options['jid'] } + _type = 'pubsub_subscribe', node = node.node, jid = jid } }, options)) end @@ -332,13 +365,11 @@ function PubSubNode.publish(node, ...) }, options)) end -function PubSubNode.retract(node, options) - options = options or {} - local item_ids = options['items'] - item_ids = item_ids or { options['item'] } - local items = {} - for _, item_id in ipairs(item_ids) do - items[#items+1] = { id = item_id } +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 = { @@ -346,14 +377,25 @@ function PubSubNode.retract(node, options) }}, options)) end -function PubSubNode.purge(node, options) - options = options or {} +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 -------------------------------------------------------------------------------- diff --git a/Sluift/client.cpp b/Sluift/client.cpp index 6d8bee8..df43075 100644 --- a/Sluift/client.cpp +++ b/Sluift/client.cpp @@ -4,6 +4,11 @@ * See the COPYING file for more information. */ +#include +#include +#include +#include + #include #include #include @@ -20,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -30,9 +34,9 @@ #include #include #include -#include using namespace Swift; +namespace lambda = boost::lambda; static const std::string SLUIFT_CLIENT = Lua::FunctionRegistry::getMetaTableNameForType("Client"); @@ -376,12 +380,33 @@ static void pushEvent(lua_State* L, const SluiftClient::Event& event) { } } +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; +}; + + SLUIFT_LUA_FUNCTION(Client, get_next_event) { Sluift::globals.eventLoop.runOnce(); SluiftClient* client = getClient(L); int timeout = Sluift::globals.timeout; boost::optional type; + int condition = 0; if (lua_istable(L, 2)) { if (boost::optional typeString = Lua::getStringField(L, 2, "type")) { if (*typeString == "message") { @@ -397,9 +422,25 @@ SLUIFT_LUA_FUNCTION(Client, get_next_event) { if (boost::optional timeoutInt = Lua::getIntField(L, 2, "timeout")) { timeout = *timeoutInt; } + lua_getfield(L, 2, "if"); + if (lua_isfunction(L, -1)) { + condition = Lua::absoluteOffset(L, -1); + } } - if (boost::optional event = client->getNextEvent(type, timeout)) { + boost::optional 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 { @@ -510,6 +551,12 @@ SLUIFT_LUA_FUNCTION(Client, set_caps_node) { return 0; } +SLUIFT_LUA_FUNCTION(Client, jid) { + 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; diff --git a/Swiften/QA/ScriptedTests/PubSub.lua b/Swiften/QA/ScriptedTests/PubSub.lua index a9c0fe8..cb4679a 100644 --- a/Swiften/QA/ScriptedTests/PubSub.lua +++ b/Swiften/QA/ScriptedTests/PubSub.lua @@ -22,6 +22,7 @@ local subscriber_node local publish_item = {id = 'item_id', data = {{ _type = 'software_version', name = 'MyTest', os = 'Lua' }} } local publish_item2 = {id = 'item_id2', data = {{ _type = 'software_version', name = 'MyTest2', os = 'Lua' }} } +local publish_item3 = {id = 'item_id3', data = {{ _type = 'software_version', name = 'MyTest3', os = 'Lua' }} } -------------------------------------------------------------------------------- -- Helper methods @@ -109,11 +110,40 @@ function test_subscriber_use_cases() -- 6.5 Retrieve items of a node assert(node:create()) - assert(node:publish {item = publish_item}) + assert(node:set_configuration{configuration = {['pubsub#max_items'] = '10'}}) + assert(node:publish{item = publish_item}) + assert(node:publish{item = publish_item2}) local items = assert(subscriber_node:get_items()) - assert(#items == 1) + assert(#items == 2) assert(items[1].id == 'item_id') assert(items[1].data[1].name == 'MyTest') + assert(items[2].id == 'item_id2') + assert(items[2].data[1].name == 'MyTest2') + assert(node:delete()) + + -- 6.5.7 Requesting most recent items + assert(node:create()) + assert(node:set_configuration{configuration = {['pubsub#max_items'] = '10'}}) + assert(node:publish{item = publish_item}) + assert(node:publish{item = publish_item2}) + assert(node:publish{item = publish_item3}) + local items = assert(subscriber_node:get_items{maximum_items = 2}) + assert(#items == 2) + assert(items[1].id == 'item_id2') + assert(items[1].data[1].name == 'MyTest2') + assert(items[2].id == 'item_id3') + assert(items[2].data[1].name == 'MyTest3') + assert(node:delete()) + + -- 6.5.8 requesting specific item + assert(node:create()) + assert(node:set_configuration{configuration = {['pubsub#max_items'] = '10'}}) + assert(node:publish{item = publish_item}) + assert(node:publish{item = publish_item2}) + local items = assert(subscriber_node:get_item{id = 'item_id2'}) + assert(#items == 1) + assert(items[1].id == 'item_id2') + assert(items[1].data[1].name == 'MyTest2') assert(node:delete()) end @@ -141,7 +171,7 @@ function test_publisher_use_cases() assert(node:create()) assert(subscriber_node:subscribe({ jid = subscriber_jid })) assert(node:publish {items = {publish_item}}) - assert(node:retract { item = 'item_id', notify = true }) + assert(node:retract { id = 'item_id', notify = true }) assert(node:delete()) -- 7.2.2.1 Delete and notify @@ -149,7 +179,7 @@ function test_publisher_use_cases() assert(subscriber_node:subscribe({ jid = subscriber_jid })) assert(node:publish {items = {publish_item}}) purge_pubsub_events(subscriber) - assert(node:retract { item = 'item_id', notify = true }) + assert(node:retract { id = 'item_id', notify = true }) local event = assert(subscriber:get_next_event { type = 'pubsub' }) assert(event._type == 'pubsub_event_items') assert(event.retracts[1].id == 'item_id') diff --git a/Swiften/Serializer/PayloadSerializers/UserLocationSerializer.cpp b/Swiften/Serializer/PayloadSerializers/UserLocationSerializer.cpp index 373276b..e257654 100644 --- a/Swiften/Serializer/PayloadSerializers/UserLocationSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/UserLocationSerializer.cpp @@ -25,67 +25,67 @@ std::string UserLocationSerializer::serializePayload( if (boost::optional value = payload->getArea()) { result.addNode(boost::make_shared("area", "", *value)); } - else if (boost::optional value = payload->getAltitude()) { + if (boost::optional value = payload->getAltitude()) { result.addNode(boost::make_shared("alt", "", boost::lexical_cast(*value))); } - else if (boost::optional value = payload->getLocality()) { + if (boost::optional value = payload->getLocality()) { result.addNode(boost::make_shared("locality", "", *value)); } - else if (boost::optional value = payload->getLatitude()) { + if (boost::optional value = payload->getLatitude()) { result.addNode(boost::make_shared("lat", "", boost::lexical_cast(*value))); } - else if (boost::optional value = payload->getAccuracy()) { - result.addNode(boost::make_shared("lon", "", boost::lexical_cast(*value))); + if (boost::optional value = payload->getAccuracy()) { + result.addNode(boost::make_shared("accuracy", "", boost::lexical_cast(*value))); } - else if (boost::optional value = payload->getDescription()) { + if (boost::optional value = payload->getDescription()) { result.addNode(boost::make_shared("description", "", *value)); } - else if (boost::optional value = payload->getCountryCode()) { + if (boost::optional value = payload->getCountryCode()) { result.addNode(boost::make_shared("countrycode", "", *value)); } - else if (boost::optional value = payload->getTimestamp()) { + if (boost::optional value = payload->getTimestamp()) { result.addNode(boost::make_shared("timestamp", "", dateTimeToString(*value))); } - else if (boost::optional value = payload->getFloor()) { + if (boost::optional value = payload->getFloor()) { result.addNode(boost::make_shared("floor", "", *value)); } - else if (boost::optional value = payload->getBuilding()) { + if (boost::optional value = payload->getBuilding()) { result.addNode(boost::make_shared("building", "", *value)); } - else if (boost::optional value = payload->getRoom()) { + if (boost::optional value = payload->getRoom()) { result.addNode(boost::make_shared("room", "", *value)); } - else if (boost::optional value = payload->getCountry()) { + if (boost::optional value = payload->getCountry()) { result.addNode(boost::make_shared("country", "", *value)); } - else if (boost::optional value = payload->getRegion()) { + if (boost::optional value = payload->getRegion()) { result.addNode(boost::make_shared("region", "", *value)); } - else if (boost::optional value = payload->getURI()) { + if (boost::optional value = payload->getURI()) { result.addNode(boost::make_shared("uri", "", *value)); } - else if (boost::optional value = payload->getLongitude()) { + if (boost::optional value = payload->getLongitude()) { result.addNode(boost::make_shared("lon", "", boost::lexical_cast(*value))); } - else if (boost::optional value = payload->getError()) { + if (boost::optional value = payload->getError()) { result.addNode(boost::make_shared("error", "", boost::lexical_cast(*value))); } - else if (boost::optional value = payload->getPostalCode()) { + if (boost::optional value = payload->getPostalCode()) { result.addNode(boost::make_shared("postalcode", "", *value)); } - else if (boost::optional value = payload->getBearing()) { + if (boost::optional value = payload->getBearing()) { result.addNode(boost::make_shared("bearing", "", boost::lexical_cast(*value))); } - else if (boost::optional value = payload->getText()) { + if (boost::optional value = payload->getText()) { result.addNode(boost::make_shared("text", "", *value)); } - else if (boost::optional value = payload->getDatum()) { + if (boost::optional value = payload->getDatum()) { result.addNode(boost::make_shared("datum", "", *value)); } - else if (boost::optional value = payload->getStreet()) { + if (boost::optional value = payload->getStreet()) { result.addNode(boost::make_shared("street", "", *value)); } - else if (boost::optional value = payload->getSpeed()) { + if (boost::optional value = payload->getSpeed()) { result.addNode(boost::make_shared("speed", "", boost::lexical_cast(*value))); } return result.serialize(); -- cgit v0.10.2-6-g49f6