From c38103451c3088dbcbe0ec1bde549039391c49b2 Mon Sep 17 00:00:00 2001 From: HanzZ Date: Sat, 13 Aug 2011 01:48:13 +0200 Subject: [PATCH] InvisiblePayload + more mysql tweaks --- include/Swiften/Elements/InvisiblePayload.cpp | 17 ++++ include/Swiften/Elements/InvisiblePayload.h | 25 ++++++ .../Parser/PayloadParsers/InvisibleParser.cpp | 26 ++++++ .../Parser/PayloadParsers/InvisibleParser.h | 26 ++++++ .../InvisibleSerializer.cpp | 28 ++++++ .../PayloadSerializers/InvisibleSerializer.h | 21 +++++ include/transport/mysqlbackend.h | 9 +- src/mysqlbackend.cpp | 86 ++++++++++++++++--- src/transport.cpp | 4 + 9 files changed, 230 insertions(+), 12 deletions(-) create mode 100644 include/Swiften/Elements/InvisiblePayload.cpp create mode 100644 include/Swiften/Elements/InvisiblePayload.h create mode 100644 include/Swiften/Parser/PayloadParsers/InvisibleParser.cpp create mode 100644 include/Swiften/Parser/PayloadParsers/InvisibleParser.h create mode 100644 include/Swiften/Serializer/PayloadSerializers/InvisibleSerializer.cpp create mode 100644 include/Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h diff --git a/include/Swiften/Elements/InvisiblePayload.cpp b/include/Swiften/Elements/InvisiblePayload.cpp new file mode 100644 index 00000000..b507b035 --- /dev/null +++ b/include/Swiften/Elements/InvisiblePayload.cpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include + +namespace Swift { + +// This payload is NOT part of ANY XEP and it is only +// libtransport related extension. +InvisiblePayload::InvisiblePayload() { + +} + +} diff --git a/include/Swiften/Elements/InvisiblePayload.h b/include/Swiften/Elements/InvisiblePayload.h new file mode 100644 index 00000000..4966eddb --- /dev/null +++ b/include/Swiften/Elements/InvisiblePayload.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include +#include +#include + +#include + +// This payload is NOT part of ANY XEP and it is only +// libtransport related extension. +namespace Swift { + class InvisiblePayload : public Payload { + public: + typedef boost::shared_ptr ref; + + public: + InvisiblePayload(); + }; +} diff --git a/include/Swiften/Parser/PayloadParsers/InvisibleParser.cpp b/include/Swiften/Parser/PayloadParsers/InvisibleParser.cpp new file mode 100644 index 00000000..6a94de48 --- /dev/null +++ b/include/Swiften/Parser/PayloadParsers/InvisibleParser.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include + +namespace Swift { + +// This payload is NOT part of ANY XEP and it is only +// libtransport related extension. +InvisibleParser::InvisibleParser() /*: level_(0)*/ { +} + +void InvisibleParser::handleStartElement(const std::string& /*element*/, const std::string& /*ns*/, const AttributeMap& /*attributes*/) { +} + +void InvisibleParser::handleEndElement(const std::string&, const std::string&) { +} + +void InvisibleParser::handleCharacterData(const std::string&) { + +} + +} diff --git a/include/Swiften/Parser/PayloadParsers/InvisibleParser.h b/include/Swiften/Parser/PayloadParsers/InvisibleParser.h new file mode 100644 index 00000000..f45bc835 --- /dev/null +++ b/include/Swiften/Parser/PayloadParsers/InvisibleParser.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include +#include + +// This payload is NOT part of ANY XEP and it is only +// libtransport related extension. +namespace Swift { + class InvisibleParser : public GenericPayloadParser { + public: + InvisibleParser(); + + virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string&); + virtual void handleCharacterData(const std::string& data); + +// private: +// int level_; + }; +} diff --git a/include/Swiften/Serializer/PayloadSerializers/InvisibleSerializer.cpp b/include/Swiften/Serializer/PayloadSerializers/InvisibleSerializer.cpp new file mode 100644 index 00000000..0cf1b1b9 --- /dev/null +++ b/include/Swiften/Serializer/PayloadSerializers/InvisibleSerializer.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include + +#include + +#include +#include +#include + +namespace Swift { + +// This payload is NOT part of ANY XEP and it is only +// libtransport related extension. +InvisibleSerializer::InvisibleSerializer() : GenericPayloadSerializer() { +} + +std::string InvisibleSerializer::serializePayload(boost::shared_ptr attention) const { + XMLElement attentionElement("invisible", "urn:xmpp:invisible:0"); + + return attentionElement.serialize(); +} + +} diff --git a/include/Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h b/include/Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h new file mode 100644 index 00000000..034ab2e1 --- /dev/null +++ b/include/Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2011 Jan Kaluza + * Licensed under the Simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include +#include + +// This payload is NOT part of ANY XEP and it is only +// libtransport related extension. +namespace Swift { + class InvisibleSerializer : public GenericPayloadSerializer { + public: + InvisibleSerializer(); + + virtual std::string serializePayload(boost::shared_ptr) const; + }; +} diff --git a/include/transport/mysqlbackend.h b/include/transport/mysqlbackend.h index e411b3fc..63b90784 100644 --- a/include/transport/mysqlbackend.h +++ b/include/transport/mysqlbackend.h @@ -100,6 +100,8 @@ class MySQLBackend : public StorageBackend bool execute(); + bool fetch(); + // Pushes new data used as input for the statement. template Statement& operator << (const T& t); @@ -109,10 +111,13 @@ class MySQLBackend : public StorageBackend // Pulls fetched data by previous execute(); call. template Statement& operator >> (T& t); + + Statement& operator >> (std::string& t); private: MYSQL_STMT *m_stmt; MYSQL *m_conn; std::vector m_params; + std::vector m_results; int m_resultOffset; int m_offset; int m_error; @@ -125,8 +130,8 @@ class MySQLBackend : public StorageBackend // statements // MYSQL_STMT *m_setUser; - Statement * m_setUser; - MYSQL_STMT *m_getUser; + Statement *m_setUser; + Statement *m_getUser; MYSQL_STMT *m_getUserSetting; MYSQL_STMT *m_setUserSetting; MYSQL_STMT *m_updateUserSetting; diff --git a/src/mysqlbackend.cpp b/src/mysqlbackend.cpp index 388222b6..f45ec94e 100644 --- a/src/mysqlbackend.cpp +++ b/src/mysqlbackend.cpp @@ -87,7 +87,7 @@ MySQLBackend::Statement::Statement(MYSQL *conn, const std::string &format, const return; } - for (int i = 0; i < format.length(); i++) { + for (int i = 0; i < format.length() && m_resultOffset == -1; i++) { switch (format.at(i)) { case 's': m_params.resize(m_params.size() + 1); @@ -117,21 +117,57 @@ MySQLBackend::Statement::Statement(MYSQL *conn, const std::string &format, const m_params.back().is_null= 0; m_params.back().length= (unsigned long *) malloc(sizeof(unsigned long)); break; -// case 'b': -// m_params.push_back(NULL); -// break; case '|': m_resultOffset = i; break; } } - if (m_resultOffset < 0) - m_resultOffset = format.size(); + for (int i = m_resultOffset; i < format.length(); i++) { + switch (format.at(i)) { + case 's': + m_results.resize(m_results.size() + 1); + memset(&m_results.back(), 0, sizeof(MYSQL_BIND)); + + m_results.back().buffer_type= MYSQL_TYPE_STRING; + m_results.back().buffer= (char *) malloc(sizeof(char) * 4096); + m_results.back().buffer_length= 4096; + m_results.back().is_null= 0; + m_results.back().length= (unsigned long *) malloc(sizeof(unsigned long)); + break; + case 'i': + m_results.resize(m_results.size() + 1); + memset(&m_results.back(), 0, sizeof(MYSQL_BIND)); + + m_results.back().buffer_type= MYSQL_TYPE_LONG; + m_results.back().buffer= (unsigned long *) malloc(sizeof(unsigned long)); + m_results.back().is_null= 0; + m_results.back().length= (unsigned long *) malloc(sizeof(unsigned long)); + break; + case 'b': + m_results.resize(m_results.size() + 1); + memset(&m_results.back(), 0, sizeof(MYSQL_BIND)); + + m_results.back().buffer_type= MYSQL_TYPE_TINY; + m_results.back().buffer= (bool *) malloc(sizeof(bool)); + m_results.back().is_null= 0; + m_results.back().length= (unsigned long *) malloc(sizeof(unsigned long)); + break; + } + } if (mysql_stmt_bind_param(m_stmt, &m_params.front())) { LOG4CXX_ERROR(logger, statement << " " << mysql_error(conn)); } + + if (m_resultOffset < 0) + m_resultOffset = format.size(); + else { + if (mysql_stmt_bind_result(m_stmt, &m_results.front())) { + LOG4CXX_ERROR(logger, statement << " " << mysql_error(conn)); + } + } + m_resultOffset = 0; } MySQLBackend::Statement::~Statement() { @@ -156,6 +192,10 @@ bool MySQLBackend::Statement::execute() { return true; } +bool MySQLBackend::Statement::fetch() { + return mysql_stmt_fetch(m_stmt); +} + template MySQLBackend::Statement& MySQLBackend::Statement::operator << (const T& t) { if (m_offset >= m_resultOffset) @@ -183,7 +223,25 @@ MySQLBackend::Statement& MySQLBackend::Statement::operator >> (T& t) { if (m_offset < m_resultOffset) return *this; - std::swap(t, *(T *) m_params[m_offset]); + if (!m_params[m_offset].is_null) { + T *data = (T *) m_params[m_offset].buffer; + t = *data; + } + + if (++m_offset == m_params.size()) + m_offset = 0; + return *this; +} + +MySQLBackend::Statement& MySQLBackend::Statement::operator >> (std::string& t) { + std::cout << "getting " << m_offset << " " << m_resultOffset << "\n"; + if (m_offset < m_resultOffset) + return *this; + + if (!m_params[m_offset].is_null) { + t = (char *) m_params[m_offset].buffer; + } + if (++m_offset == m_params.size()) m_offset = 0; return *this; @@ -198,7 +256,7 @@ MySQLBackend::MySQLBackend(Config *config) { MySQLBackend::~MySQLBackend(){ // FINALIZE_STMT(m_setUser); delete m_setUser; - FINALIZE_STMT(m_getUser); + delete m_getUser; FINALIZE_STMT(m_removeUser); FINALIZE_STMT(m_removeUserBuddies); FINALIZE_STMT(m_removeUserSettings); @@ -232,7 +290,7 @@ bool MySQLBackend::connect() { createDatabase(); m_setUser = new Statement(&m_conn, "sssssb", "INSERT INTO " + m_prefix + "users (jid, uin, password, language, encoding, last_login, vip) VALUES (?, ?, ?, ?, ?, NOW(), ?)"); - PREP_STMT(m_getUser, "SELECT id, jid, uin, password, encoding, language, vip FROM " + m_prefix + "users WHERE jid=?"); + m_getUser = new Statement(&m_conn, "s|isssssb", "SELECT id, jid, uin, password, encoding, language, vip FROM " + m_prefix + "users WHERE jid=?"); PREP_STMT(m_removeUser, "DELETE FROM " + m_prefix + "users WHERE id=?"); PREP_STMT(m_removeUserBuddies, "DELETE FROM " + m_prefix + "buddies WHERE user_id=?"); @@ -324,7 +382,15 @@ void MySQLBackend::setUser(const UserInfo &user) { } bool MySQLBackend::getUser(const std::string &barejid, UserInfo &user) { - return false; + *m_getUser << barejid; + if (!m_getUser->execute()) + return false; + + m_getUser->fetch(); + + *m_getUser >> user.id >> user.jid >> user.uin >> user.password >> user.encoding >> user.language >> user.vip; + std::cout << user.id << " " << user.jid << " " << user.uin << " " << user.password << " " << user.encoding << " " << user.language << " " << user.vip << "\n"; + return true; } void MySQLBackend::setUserOnline(long id, bool online) { diff --git a/src/transport.cpp b/src/transport.cpp index b752b7bd..b928d10a 100644 --- a/src/transport.cpp +++ b/src/transport.cpp @@ -35,6 +35,8 @@ #include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h" #include "Swiften/Parser/PayloadParsers/BlockParser.h" #include "Swiften/Serializer/PayloadSerializers/BlockSerializer.h" +#include "Swiften/Parser/PayloadParsers/InvisibleParser.h" +#include "Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h" #include "log4cxx/logger.h" #include "log4cxx/consoleappender.h" #include "log4cxx/patternlayout.h" @@ -93,10 +95,12 @@ Component::Component(Swift::EventLoop *loop, Config *config, Factory *factory, T m_server->addPayloadParserFactory(new GenericPayloadParserFactory("attention", "urn:xmpp:attention:0")); m_server->addPayloadParserFactory(new GenericPayloadParserFactory("html", "http://jabber.org/protocol/xhtml-im")); m_server->addPayloadParserFactory(new GenericPayloadParserFactory("block", "urn:xmpp:block:0")); + m_server->addPayloadParserFactory(new GenericPayloadParserFactory("block", "urn:xmpp:invisible:0")); m_server->addPayloadSerializer(new Swift::AttentionSerializer()); m_server->addPayloadSerializer(new Swift::XHTMLIMSerializer()); m_server->addPayloadSerializer(new Swift::BlockSerializer()); + m_server->addPayloadSerializer(new Swift::InvisibleSerializer()); m_server->onDataRead.connect(bind(&Component::handleDataRead, this, _1)); m_server->onDataWritten.connect(bind(&Component::handleDataWritten, this, _1));