diff options
Diffstat (limited to 'Sluift')
-rw-r--r-- | Sluift/client_test.lua | 32 | ||||
-rw-r--r-- | Sluift/linit.c | 40 | ||||
-rw-r--r-- | Sluift/sluift.cpp | 114 |
3 files changed, 146 insertions, 40 deletions
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} }; |