diff options
-rw-r--r-- | 3rdParty/Lua/SConscript | 6 | ||||
-rw-r--r-- | Sluift/client_test.lua | 32 | ||||
-rw-r--r-- | Sluift/linit.c | 40 | ||||
-rw-r--r-- | Sluift/sluift.cpp | 114 | ||||
-rw-r--r-- | Swiften/Client/Client.cpp | 4 | ||||
-rw-r--r-- | Swiften/Client/Client.h | 2 | ||||
-rw-r--r-- | Swiften/Queries/Responders/SoftwareVersionResponder.cpp | 5 | ||||
-rw-r--r-- | Swiften/Queries/Responders/SoftwareVersionResponder.h | 3 |
8 files changed, 158 insertions, 48 deletions
diff --git a/3rdParty/Lua/SConscript b/3rdParty/Lua/SConscript index 9d0315e..f69c3cd 100644 --- a/3rdParty/Lua/SConscript +++ b/3rdParty/Lua/SConscript @@ -8,12 +8,14 @@ if env.get("LUA_BUNDLED", False) : if env["SCONS_STAGE"] == "flags" : cppdefines = [] + if not env["optimize"] : + cppdefines.append("LUA_USE_APICHECK") if env["PLATFORM"] == "win32" : pass elif env["PLATFORM"] == "darwin" : - cppdefines = ["LUA_USE_POSIX", "LUA_USE_DLOPEN"] + cppdefines += ["LUA_USE_POSIX", "LUA_USE_DLOPEN"] else : - cppdefines = ["LUA_USE_POSIX", "LUA_USE_DLOPEN"] + cppdefines += ["LUA_USE_POSIX", "LUA_USE_DLOPEN"] env["LUA_FLAGS"] = { "CPPDEFINES": cppdefines, diff --git a/Sluift/client_test.lua b/Sluift/client_test.lua new file mode 100644 index 0000000..afb8147 --- /dev/null +++ b/Sluift/client_test.lua @@ -0,0 +1,32 @@ +require "sluift" + +--sluift.debug = true +client1_jid = os.getenv("SWIFT_CLIENTTEST_JID") .. "/Client1" +client2_jid = os.getenv("SWIFT_CLIENTTEST_JID") .. "/Client2" +password = os.getenv("SWIFT_CLIENTTEST_PASS") + +print "Connecting client 1" +client1 = sluift.connect(client1_jid, password) +client1:send_presence("I'm here") + +print "Connecting client 2" +client2 = sluift.connect(client2_jid, password) +client2:send_presence("I'm here") + +print "Checking version of client 2 from client 1" +client2:set_version({name = "Sluift Test", version = "1.0"}) +client2_version = client1:get_version(client2_jid) +assert(client2_version["name"] == "Sluift Test") +assert(client2_version["version"] == "1.0") + +print "Sending message from client 1 to client 2" +client1:send_message(client2_jid, "Hello") +received_message = client2:for_event(function(event) + if event["type"] == "message" and event["from"] == client1_jid then + return event["body"] + end + end) +assert(received_message == "Hello") + +client1:disconnect() +client2:disconnect() diff --git a/Sluift/linit.c b/Sluift/linit.c deleted file mode 100644 index 4cb4c26..0000000 --- a/Sluift/linit.c +++ /dev/null @@ -1,40 +0,0 @@ -/* -** $Id: linit.c,v 1.14.1.1 2007/12/27 13:02:25 roberto Exp $ -** Initialization of libraries for lua.c -** See Copyright Notice in lua.h -*/ - - -#define linit_c -#define LUA_LIB - -#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/sluift.cpp b/Sluift/sluift.cpp index 5a9fbd5..895d90d 100644 --- a/Sluift/sluift.cpp +++ b/Sluift/sluift.cpp @@ -11,6 +11,7 @@ extern "C" { #include <iostream> #include <string> +#include <deque> #include <Swiften/Client/Client.h> #include <Swiften/Client/ClientXMLTracer.h> @@ -51,6 +52,8 @@ class SluiftClient { SluiftClient(const JID& jid, const std::string& password, bool debug = false) : tracer(NULL) { client = new Client(jid, password, &networkFactories); client->setAlwaysTrustCertificates(); + client->onMessageReceived.connect(boost::bind(&SluiftClient::handleIncomingEvent, this, _1)); + client->onPresenceReceived.connect(boost::bind(&SluiftClient::handleIncomingEvent, this, _1)); if (debug) { tracer = new ClientXMLTracer(client); } @@ -79,6 +82,10 @@ class SluiftClient { client->sendMessage(message); } + void sendPresence(const std::string& status) { + client->sendPresence(boost::make_shared<Presence>(status)); + } + void disconnect() { client->disconnect(); while (client->isActive()) { @@ -86,6 +93,10 @@ class SluiftClient { } } + void setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os) { + client->setSoftwareVersion(name, version, os); + } + boost::optional<SoftwareVersion> getSoftwareVersion(const JID& jid) { GetSoftwareVersionRequest::ref request = GetSoftwareVersionRequest::create(jid, client->getIQRouter()); request->onResponse.connect(boost::bind(&SluiftClient::handleSoftwareVersionResponse, this, _1, _2)); @@ -98,7 +109,31 @@ class SluiftClient { return softwareVersion; } + Stanza::ref getNextEvent() { + if (client->isActive() && !pendingEvents.empty()) { + Stanza::ref event = pendingEvents.front(); + pendingEvents.pop_front(); + return event; + } + while (client->isActive() && pendingEvents.empty()) { + processEvents(); + } + if (client->isActive()) { + assert(!pendingEvents.empty()); + Stanza::ref event = pendingEvents.front(); + pendingEvents.pop_front(); + return event; + } + else { + return Stanza::ref(); + } + } + private: + void handleIncomingEvent(Stanza::ref stanza) { + pendingEvents.push_back(stanza); + } + void processEvents() { eventLoop.runUntilEvents(); } @@ -120,6 +155,7 @@ class SluiftClient { ClientXMLTracer* tracer; boost::optional<SoftwareVersion> softwareVersion; ErrorPayload::ref error; + std::deque<Stanza::ref> pendingEvents; }; @@ -141,6 +177,19 @@ static int sluift_client_disconnect(lua_State *L) { return 0; } +static int sluift_client_set_version(lua_State *L) { + SluiftClient* client = getClient(L); + luaL_checktype(L, 2, LUA_TTABLE); + lua_getfield(L, 2, "name"); + const char* rawName = lua_tostring(L, -1); + lua_getfield(L, 2, "version"); + const char* rawVersion = lua_tostring(L, -1); + lua_getfield(L, 2, "os"); + const char* rawOS = lua_tostring(L, -1); + client->setSoftwareVersion(rawName ? rawName : "", rawVersion ? rawVersion : "", rawOS ? rawOS : ""); + lua_pop(L, 3); + return 0; +} static int sluift_client_get_version(lua_State *L) { SluiftClient* client = getClient(L); @@ -167,6 +216,68 @@ static int sluift_client_send_message(lua_State *L) { return 0; } +static int sluift_client_send_presence(lua_State *L) { + getClient(L)->sendPresence(std::string(luaL_checkstring(L, 2))); + return 0; +} + +static int sluift_client_for_event (lua_State *L) { + SluiftClient* client = getClient(L); + luaL_checktype(L, 2, LUA_TFUNCTION); + while (true) { + Stanza::ref event = client->getNextEvent(); + if (!event) { + // We got disconnected + lua_pushnil(L); + lua_pushliteral(L, "disconnected"); + return 2; + } + else { + // Push the function on the stack + lua_pushvalue(L, 2); + + bool emitEvent = false; + 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"); + emitEvent = true; + } + 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"); + emitEvent = true; + } + else { + assert(false); + } + if (emitEvent) { + int oldTop = lua_gettop(L) - 2; + lua_call(L, 1, LUA_MULTRET); + int returnValues = lua_gettop(L) - oldTop; + if (returnValues > 0) { + lua_remove(L, -1 - returnValues); + return returnValues; + } + } + else { + // Remove the function from the stack again, since + // we're not calling the function + lua_pop(L, 1); + } + } + } +} + static int sluift_client_gc (lua_State *L) { SluiftClient* client = getClient(L); delete client; @@ -178,7 +289,10 @@ static const luaL_reg sluift_client_functions[] = { {"is_connected", sluift_client_is_connected}, {"disconnect", sluift_client_disconnect}, {"send_message", sluift_client_send_message}, + {"send_presence", sluift_client_send_presence}, + {"set_version", sluift_client_set_version}, {"get_version", sluift_client_get_version}, + {"for_event", sluift_client_for_event}, {"__gc", sluift_client_gc}, {NULL, NULL} }; diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp index 904f722..7918c46 100644 --- a/Swiften/Client/Client.cpp +++ b/Swiften/Client/Client.cpp @@ -93,8 +93,8 @@ XMPPRoster* Client::getRoster() const { return roster; } -void Client::setSoftwareVersion(const std::string& name, const std::string& version) { - softwareVersionResponder->setVersion(name, version); +void Client::setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os) { + softwareVersionResponder->setVersion(name, version, os); } void Client::requestRoster() { diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h index 868c9c4..d5db1ac 100644 --- a/Swiften/Client/Client.h +++ b/Swiften/Client/Client.h @@ -56,7 +56,7 @@ namespace Swift { * * This will be used to respond to version queries from other entities. */ - void setSoftwareVersion(const std::string& name, const std::string& version); + void setSoftwareVersion(const std::string& name, const std::string& version, const std::string& os); /** * Returns a representation of the roster. diff --git a/Swiften/Queries/Responders/SoftwareVersionResponder.cpp b/Swiften/Queries/Responders/SoftwareVersionResponder.cpp index 0b8362c..445dcc7 100644 --- a/Swiften/Queries/Responders/SoftwareVersionResponder.cpp +++ b/Swiften/Queries/Responders/SoftwareVersionResponder.cpp @@ -12,13 +12,14 @@ namespace Swift { SoftwareVersionResponder::SoftwareVersionResponder(IQRouter* router) : GetResponder<SoftwareVersion>(router) { } -void SoftwareVersionResponder::setVersion(const std::string& client, const std::string& version) { +void SoftwareVersionResponder::setVersion(const std::string& client, const std::string& version, const std::string& os) { this->client = client; this->version = version; + this->os = os; } bool SoftwareVersionResponder::handleGetRequest(const JID& from, const JID&, const std::string& id, boost::shared_ptr<SoftwareVersion>) { - sendResponse(from, id, boost::shared_ptr<SoftwareVersion>(new SoftwareVersion(client, version))); + sendResponse(from, id, boost::shared_ptr<SoftwareVersion>(new SoftwareVersion(client, version, os))); return true; } diff --git a/Swiften/Queries/Responders/SoftwareVersionResponder.h b/Swiften/Queries/Responders/SoftwareVersionResponder.h index f6a3d52..cbda54c 100644 --- a/Swiften/Queries/Responders/SoftwareVersionResponder.h +++ b/Swiften/Queries/Responders/SoftwareVersionResponder.h @@ -16,7 +16,7 @@ namespace Swift { public: SoftwareVersionResponder(IQRouter* router); - void setVersion(const std::string& client, const std::string& version); + void setVersion(const std::string& client, const std::string& version, const std::string& os = ""); private: virtual bool handleGetRequest(const JID& from, const JID& to, const std::string& id, boost::shared_ptr<SoftwareVersion> payload); @@ -24,5 +24,6 @@ namespace Swift { private: std::string client; std::string version; + std::string os; }; } |