diff options
| author | Markus Mittendrein <git@maxmitti.tk> | 2015-09-09 19:00:56 +0200 |
|---|---|---|
| committer | Markus Mittendrein <git@maxmitti.tk> | 2015-09-09 19:02:23 +0200 |
| commit | 8a6d4b06f2291c363f3dea17837ed20893852453 (patch) | |
| tree | c091375499e35eaa1810586454e0834c06e6c9b2 /libcommuni/src/core | |
| parent | f554a27046f203e56a07baaf214d90834942e3f5 (diff) | |
| download | manager-8a6d4b06f2291c363f3dea17837ed20893852453.tar.gz manager-8a6d4b06f2291c363f3dea17837ed20893852453.zip | |
Cleanup repo with some directories
Diffstat (limited to 'libcommuni/src/core')
| -rw-r--r-- | libcommuni/src/core/core.pri | 65 | ||||
| -rw-r--r-- | libcommuni/src/core/core.pro | 8 | ||||
| -rw-r--r-- | libcommuni/src/core/irc.cpp | 172 | ||||
| -rw-r--r-- | libcommuni/src/core/irccommand.cpp | 851 | ||||
| -rw-r--r-- | libcommuni/src/core/ircconnection.cpp | 1508 | ||||
| -rw-r--r-- | libcommuni/src/core/irccore.cpp | 90 | ||||
| -rw-r--r-- | libcommuni/src/core/ircfilter.cpp | 248 | ||||
| -rw-r--r-- | libcommuni/src/core/ircmessage.cpp | 1604 | ||||
| -rw-r--r-- | libcommuni/src/core/ircmessage_p.cpp | 284 | ||||
| -rw-r--r-- | libcommuni/src/core/ircmessagebuilder.cpp | 121 | ||||
| -rw-r--r-- | libcommuni/src/core/ircmessagedecoder.cpp | 73 | ||||
| -rw-r--r-- | libcommuni/src/core/ircmessagedecoder_icu.cpp | 68 | ||||
| -rw-r--r-- | libcommuni/src/core/ircmessagedecoder_uchardet.cpp | 56 | ||||
| -rw-r--r-- | libcommuni/src/core/ircnetwork.cpp | 687 | ||||
| -rw-r--r-- | libcommuni/src/core/ircprotocol.cpp | 480 |
15 files changed, 0 insertions, 6315 deletions
diff --git a/libcommuni/src/core/core.pri b/libcommuni/src/core/core.pri deleted file mode 100644 index 3d4a0b1..0000000 --- a/libcommuni/src/core/core.pri +++ /dev/null @@ -1,65 +0,0 @@ -###################################################################### -# Communi -###################################################################### - -DEFINES += BUILD_IRC_CORE -QT += network - -INCDIR = $$PWD/../../include/IrcCore - -DEPENDPATH += $$PWD $$INCDIR -INCLUDEPATH += $$PWD $$INCDIR - -CONV_HEADERS = $$INCDIR/Irc -CONV_HEADERS += $$INCDIR/IrcCommand -CONV_HEADERS += $$INCDIR/IrcCommandFilter -CONV_HEADERS += $$INCDIR/IrcConnection -CONV_HEADERS += $$INCDIR/IrcCore -CONV_HEADERS += $$INCDIR/IrcGlobal -CONV_HEADERS += $$INCDIR/IrcMessage -CONV_HEADERS += $$INCDIR/IrcMessageFilter -CONV_HEADERS += $$INCDIR/IrcNetwork -CONV_HEADERS += $$INCDIR/IrcProtocol - -PUB_HEADERS = $$INCDIR/irc.h -PUB_HEADERS += $$INCDIR/irccommand.h -PUB_HEADERS += $$INCDIR/ircconnection.h -PUB_HEADERS += $$INCDIR/irccore.h -PUB_HEADERS += $$INCDIR/ircfilter.h -PUB_HEADERS += $$INCDIR/ircglobal.h -PUB_HEADERS += $$INCDIR/ircmessage.h -PUB_HEADERS += $$INCDIR/ircnetwork.h -PUB_HEADERS += $$INCDIR/ircprotocol.h - -PRIV_HEADERS = $$INCDIR/ircconnection_p.h -PRIV_HEADERS += $$INCDIR/ircmessage_p.h -PRIV_HEADERS += $$INCDIR/ircmessagebuilder_p.h -PRIV_HEADERS += $$INCDIR/ircmessagedecoder_p.h -PRIV_HEADERS += $$INCDIR/ircnetwork_p.h - -HEADERS += $$PUB_HEADERS -HEADERS += $$PRIV_HEADERS - -SOURCES += $$PWD/irc.cpp -SOURCES += $$PWD/irccommand.cpp -SOURCES += $$PWD/ircconnection.cpp -SOURCES += $$PWD/irccore.cpp -SOURCES += $$PWD/ircfilter.cpp -SOURCES += $$PWD/ircmessage.cpp -SOURCES += $$PWD/ircmessage_p.cpp -SOURCES += $$PWD/ircmessagebuilder.cpp -SOURCES += $$PWD/ircmessagedecoder.cpp -SOURCES += $$PWD/ircnetwork.cpp -SOURCES += $$PWD/ircprotocol.cpp - -include(../3rdparty/mozilla/mozilla.pri) - -CONFIG(icu, icu|no_icu) { - DEFINES += HAVE_ICU - SOURCES += $$PWD/ircmessagedecoder_icu.cpp - include(../3rdparty/icu/icu.pri) -} else { - DEFINES += HAVE_UCHARDET - SOURCES += $$PWD/ircmessagedecoder_uchardet.cpp - include(../3rdparty/uchardet-0.0.1/uchardet.pri) -} diff --git a/libcommuni/src/core/core.pro b/libcommuni/src/core/core.pro deleted file mode 100644 index a9a0c5a..0000000 --- a/libcommuni/src/core/core.pro +++ /dev/null @@ -1,8 +0,0 @@ -###################################################################### -# Communi -###################################################################### - -IRC_MODULE = IrcCore -include(core.pri) -include(../module_build.pri) -include(../module_install.pri) diff --git a/libcommuni/src/core/irc.cpp b/libcommuni/src/core/irc.cpp deleted file mode 100644 index 5a51645..0000000 --- a/libcommuni/src/core/irc.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "irc.h" -#include "irccore.h" -#include "irccommand.h" -#include "ircconnection.h" -#include "ircmessage_p.h" -#include <QMetaEnum> -#include <QDebug> - -IRC_BEGIN_NAMESPACE - -/*! - \file irc.h - \brief \#include <Irc> - */ - -/*! - \namespace Irc - \ingroup core - \brief Miscellaneous identifiers used throughout the library. - */ - -/*! - Returns the version number of Communi at run-time as a string (for example, "1.2.3"). - This may be a different version than the version the application was compiled against. - - \sa IRC_VERSION, IRC_VERSION_STR - */ -QString Irc::version() -{ - return QLatin1String(IRC_VERSION_STR); -} - -/*! - Returns the numeric \a code as a string or a null string if the code is unknown. - - \sa Irc::Code, IrcNumericMessage::code() - */ -QString Irc::codeToString(int code) -{ - const int index = Irc::staticMetaObject.indexOfEnumerator("Code"); - QMetaEnum enumerator = Irc::staticMetaObject.enumerator(index); - return QLatin1String(enumerator.valueToKey(code)); -} - -/*! - Returns the nick part of the specified \a prefix. - - Nick part of a prefix as specified in RFC 1459: - <pre> - <b><nick></b> [ '!' <ident> ] [ '@' <host> ] - </pre> - - \sa IrcMessage::prefix, IrcMessage::nick - */ -QString Irc::nickFromPrefix(const QString& prefix) -{ - QString nick; - IrcMessagePrivate::parsePrefix(prefix, &nick, 0, 0); - return nick; -} - -/*! - Returns the ident part of the specified \a prefix. - - Ident part of a prefix as specified in RFC 1459: - <pre> - <nick> [ '!' <b><ident></b> ] [ '@' <host> ] - </pre> - - \sa IrcMessage::prefix, IrcMessage::ident - */ -QString Irc::identFromPrefix(const QString& prefix) -{ - QString ident; - IrcMessagePrivate::parsePrefix(prefix, 0, &ident, 0); - return ident; -} - -/*! - Returns the host part of the specified \a prefix. - - Host part of a prefix as specified in RFC 1459: - <pre> - <nick> [ '!' <ident> ] [ '@' <b><host></b> ] - </pre> - - \sa IrcMessage::prefix, IrcMessage::host - */ -QString Irc::hostFromPrefix(const QString& prefix) -{ - QString host; - IrcMessagePrivate::parsePrefix(prefix, 0, 0, &host); - return host; -} - -/*! - \deprecated Use IrcCore::registerMetaTypes() instead. - */ -void Irc::registerMetaTypes() -{ - IrcCore::registerMetaTypes(); -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug debug, Irc::Code code) -{ - const int index = Irc::staticMetaObject.indexOfEnumerator("Code"); - QMetaEnum enumerator = Irc::staticMetaObject.enumerator(index); - const char* key = enumerator.valueToKey(code); - debug << (key ? key : "Unknown"); - return debug; -} - -QDebug operator<<(QDebug debug, Irc::DataRole role) -{ - const int index = Irc::staticMetaObject.indexOfEnumerator("DataRole"); - QMetaEnum enumerator = Irc::staticMetaObject.enumerator(index); - const char* key = enumerator.valueToKey(role); - debug << (key ? key : "Unknown"); - return debug; -} - -QDebug operator<<(QDebug debug, Irc::Color color) -{ - const int index = Irc::staticMetaObject.indexOfEnumerator("Color"); - QMetaEnum enumerator = Irc::staticMetaObject.enumerator(index); - const char* key = enumerator.valueToKey(color); - debug << (key ? key : "Unknown"); - return debug; -} - -QDebug operator<<(QDebug debug, Irc::SortMethod method) -{ - const int index = Irc::staticMetaObject.indexOfEnumerator("SortMethod"); - QMetaEnum enumerator = Irc::staticMetaObject.enumerator(index); - const char* key = enumerator.valueToKey(method); - debug << (key ? key : "Unknown"); - return debug; -} -#endif // QT_NO_DEBUG_STREAM - -#include "moc_irc.cpp" - -IRC_END_NAMESPACE diff --git a/libcommuni/src/core/irccommand.cpp b/libcommuni/src/core/irccommand.cpp deleted file mode 100644 index d7e9b30..0000000 --- a/libcommuni/src/core/irccommand.cpp +++ /dev/null @@ -1,851 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "irccommand.h" -#include "ircmessage.h" -#include <QTextCodec> -#include <QMetaEnum> -#include <QDebug> - -IRC_BEGIN_NAMESPACE - -/*! - \file irccommand.h - \brief \#include <IrcCommand> - */ - -/*! - \class IrcCommand irccommand.h <IrcCommand> - \ingroup core - \brief Provides the most common commands. - - The IrcCommand class supports the most common IRC commands out of the box, - and can be extended for custom commands as well. See IrcCommand::Type for - the list of built-in command types. IRC commands, as in IrcCommand instances, - are sent to the IRC server via IrcConnection::sendCommand(). - - \section creating-commands Creating commands - - It is recommended to create IrcCommand instances via static - IrcCommand::createXxx() methods. - - \warning IrcCommand instances must be allocated on the heap, since - IrcConnection::sendCommand() takes ownership of the command and deletes - it once it has been sent. - - \section custom-commands Custom commands - - A "custom command" here refers to command types not listed in IrcCommand::Type, - the list of built-in command types. There are two ways to send custom commands: - \li by passing the string representation of a command directly to - IrcConnection::sendRaw() or IrcConnection::sendData(), or - \li by subclassing IrcCommand and reimplementing - IrcCommand::toString(), which eventually creates the string representation - of the command. - - Example implementation of a custom command: - \code - class IrcServerCommand : public IrcCommand - { - Q_OBJECT - public: - explicit IrcServerCommand(QObject* parent = 0) : IrcCommand(parent) - { - } - - // provided for convenience, to ensure correct parameter order - static IrcCommand* create(const QString& serverName, int hopCount, const QString& info) - { - IrcCommand* command = new IrcServerCommand; - command->setParameters(QStringList() << serverName << QString::number(hopCount) << info); - return command; - } - - // reimplemented from IrcCommand::toString() - virtual toString() const - { - // SERVER <servername> <hopcount> <info> - return QString("SERVER %1 %2 %3").arg(params.value(0), params.value(1), params.value(2)); - } - }; - \endcode - - \sa IrcConnection::sendCommand(), IrcConnection::sendRaw(), IrcCommand::Type - */ - -/*! - \enum IrcCommand::Type - This enum describes the built-in command types. - */ - -/*! - \var IrcCommand::Admin - \brief An admin command (ADMIN) is used to query server admin info. - */ - -/*! - \var IrcCommand::Away - \brief An away command (AWAY) is used to set the away status. - */ - -/*! - \var IrcCommand::Capability - \brief A capability command (CAP) is used to manage connection capabilities. - */ - -/*! - \var IrcCommand::CtcpAction - \brief A CTCP action command is used to send an action message to channels and users. - */ - -/*! - \var IrcCommand::CtcpReply - \brief A CTCP reply command is used to send a reply to a request. - */ - -/*! - \var IrcCommand::CtcpRequest - \brief A CTCP request command is used to send a request. - */ - -/*! - \var IrcCommand::Custom - \brief A custom command - */ - -/*! - \var IrcCommand::Info - \brief An info command (INFO) is used to query server info. - */ - -/*! - \var IrcCommand::Invite - \brief An invite command (INVITE) is used to invite users to a channel. - */ - -/*! - \var IrcCommand::Join - \brief A join command (JOIN) is used to start listening a specific channel. - */ - -/*! - \var IrcCommand::Kick - \brief A kick command (KICK) is used to forcibly remove a user from a channel. - */ - -/*! - \var IrcCommand::Knock - \brief A knock command (KNOCK) is used to request channel invitation. - */ - -/*! - \var IrcCommand::List - \brief A list command (LIST) is used to list channels and their topics. - */ - -/*! - \var IrcCommand::Message - \brief A message command (PRIVMSG) is used to send private messages to channels and users. - */ - -/*! - \var IrcCommand::Mode - \brief A mode command (MODE) is used to change the mode of users and channels. - */ - -/*! - \var IrcCommand::Motd - \brief A message of the day command (MOTD) is used to query the message of the day. - */ - -/*! - \var IrcCommand::Names - \brief A names command (NAMES) is used to list all nicknames on a channel. - */ - -/*! - \var IrcCommand::Nick - \brief A nick command (NICK) is used to give user a nickname or change the previous one. - */ - -/*! - \var IrcCommand::Notice - \brief A notice command (NOTICE) is used to send notice messages to channels and users. - */ - -/*! - \var IrcCommand::Part - \brief A part command (PART) causes the client to be removed from the channel. - */ - -/*! - \var IrcCommand::Quit - \brief A quit command (QUIT) is used to end a client connection. - */ - -/*! - \var IrcCommand::Quote - \brief A quote command is used to send a raw message to the server. - */ - -/*! - \var IrcCommand::Stats - \brief A stats command (STATS) is used to query server statistics. - */ - -/*! - \var IrcCommand::Time - \brief A time command (TIME) is used to query local server time. - */ - -/*! - \var IrcCommand::Topic - \brief A topic command (TOPIC) is used to change or view the topic of a channel. - */ - -/*! - \var IrcCommand::Trace - \brief A trace command (TRACE) is used to trace the connection path to a target. - */ - -/*! - \var IrcCommand::Users - \brief A users command (USERS) is used to query server users. - */ - -/*! - \var IrcCommand::Version - \brief A version command (VERSION) is used to query user or server version. - */ - -/*! - \var IrcCommand::Who - \brief A who command (WHO) is used to generate a query which returns a list of matching users. - */ - -/*! - \var IrcCommand::Whois - \brief A whois command (WHOIS) is used to query information about a particular user. - */ - -/*! - \var IrcCommand::Whowas - \brief A whowas command (WHOWAS) is used to query information about a user that no longer exists. - */ - -#ifndef IRC_DOXYGEN -class IrcCommandPrivate -{ -public: - IrcCommandPrivate() : encoding("UTF-8") { } - - QString params(int index) const; - - IrcCommand::Type type; - QStringList parameters; - QByteArray encoding; - - static IrcCommand* createCommand(IrcCommand::Type type, const QStringList& parameters); -}; - -QString IrcCommandPrivate::params(int index) const -{ - return QStringList(parameters.mid(index)).join(QLatin1String(" ")); -} - -IrcCommand* IrcCommandPrivate::createCommand(IrcCommand::Type type, const QStringList& parameters) -{ - IrcCommand* command = new IrcCommand; - command->setType(type); - command->setParameters(parameters); - return command; -} -#endif // IRC_DOXYGEN - -/*! - Constructs a new IrcCommand with \a parent. - */ -IrcCommand::IrcCommand(QObject* parent) : QObject(parent), d_ptr(new IrcCommandPrivate) -{ - Q_D(IrcCommand); - d->type = Custom; -} - -/*! - Destructs the IRC command. - */ -IrcCommand::~IrcCommand() -{ -} - -/*! - This property holds the command type. - - \par Access functions: - \li IrcCommand::Type <b>type</b>() const - \li void <b>setType</b>(IrcCommand::Type type) - */ -IrcCommand::Type IrcCommand::type() const -{ - Q_D(const IrcCommand); - return d->type; -} - -void IrcCommand::setType(Type type) -{ - Q_D(IrcCommand); - d->type = type; -} - -/*! - This property holds the command parameters. - - \par Access functions: - \li QStringList <b>parameters</b>() const - \li void <b>setParameters</b>(const QStringList& parameters) - */ -QStringList IrcCommand::parameters() const -{ - Q_D(const IrcCommand); - return d->parameters; -} - -void IrcCommand::setParameters(const QStringList& parameters) -{ - Q_D(IrcCommand); - d->parameters = parameters; -} - -/*! - This property holds the encoding that is used when - sending the command via IrcConnection::sendCommand(). - - See QTextCodec::availableCodes() for the list of - supported encodings. The default value is \c "UTF-8". - - \par Access functions: - \li QByteArray <b>encoding</b>() const - \li void <b>setEncoding</b>(const QByteArray& encoding) - - \sa QTextCodec::availableCodecs() - */ -QByteArray IrcCommand::encoding() const -{ - Q_D(const IrcCommand); - return d->encoding; -} - -void IrcCommand::setEncoding(const QByteArray& encoding) -{ - Q_D(IrcCommand); - extern bool irc_is_supported_encoding(const QByteArray& encoding); // ircmessagedecoder.cpp - if (!irc_is_supported_encoding(encoding)) { - qWarning() << "IrcCommand::setEncoding(): unsupported encoding" << encoding; - return; - } - d->encoding = encoding; -} - -/*! - Returns the command as a string. - - Reimplement for custom commands. - \sa IrcCommand::Custom - */ -QString IrcCommand::toString() const -{ - Q_D(const IrcCommand); - const QString p0 = d->parameters.value(0); - const QString p1 = d->parameters.value(1); - const QString p2 = d->parameters.value(2); - - switch (d->type) { - case Admin: return QString("ADMIN %1").arg(p0); // server - case Away: return QString("AWAY :%1").arg(d->params(0)); // reason - case Capability: return QString("CAP %1 :%2").arg(p0, d->params(1)); // subcmd, caps - case CtcpAction: return QString("PRIVMSG %1 :\1ACTION %2\1").arg(p0, d->params(1)); // target, msg - case CtcpRequest: return QString("PRIVMSG %1 :\1%2\1").arg(p0, d->params(1)); // target, msg - case CtcpReply: return QString("NOTICE %1 :\1%2\1").arg(p0, d->params(1)); // target, msg - case Info: return QString("INFO %1").arg(p0); // server - case Invite: return QString("INVITE %1 %2").arg(p0, p1); // user, chan - case Join: return p1.isNull() ? QString("JOIN %1").arg(p0) : QString("JOIN %1 %2").arg(p0, p1); // chan, key - case Kick: return p2.isNull() ? QString("KICK %1 %2").arg(p0, p1) : QString("KICK %1 %2 :%3").arg(p0, p1, d->params(2)); // chan, user, reason - case Knock: return QString("KNOCK %1 %2").arg(p0, p1); // chan, msg - case List: return p1.isNull() ? QString("LIST %1").arg(p0) : QString("LIST %1 %2").arg(p0, p1); // chan, server - case Message: return QString("PRIVMSG %1 :%2").arg(p0, d->params(1)); // target, msg - case Mode: return QString("MODE ") + d->parameters.join(" "); // target, mode, arg - case Motd: return QString("MOTD %1").arg(p0); // server - case Names: return QString("NAMES %1").arg(p0); // chan - case Nick: return QString("NICK %1").arg(p0); // nick - case Notice: return QString("NOTICE %1 :%2").arg(p0, d->params(1)); // target, msg - case Part: return p1.isNull() ? QString("PART %1").arg(p0) : QString("PART %1 :%2").arg(p0, d->params(1)); // chan, reason - case Ping: return QString("PING %1").arg(p0); // argument - case Pong: return QString("PONG %1").arg(p0); // argument - case Quit: return QString("QUIT :%1").arg(d->params(0)); // reason - case Quote: return d->parameters.join(" "); - case Stats: return QString("STATS %1 %2").arg(p0, p1); // query, server - case Time: return QString("TIME %1").arg(p0); // server - case Topic: return p1.isNull() ? QString("TOPIC %1").arg(p0) : QString("TOPIC %1 :%2").arg(p0, d->params(1)); // chan, topic - case Trace: return QString("TRACE %1").arg(p0); // target - case Users: return QString("USERS %1").arg(p0); // server - case Version: return p0.isNull() ? QString("VERSION") : QString("PRIVMSG %1 :\1VERSION\1").arg(p0); // user - case Who: return QString("WHO %1").arg(p0); // user - case Whois: return QString("WHOIS %1 %1").arg(p0); // user - case Whowas: return QString("WHOWAS %1 %1").arg(p0); // user - - case Custom: qWarning("Reimplement IrcCommand::toString() for IrcCommand::Custom"); - default: return QString(); - } -} - -/*! - Creates a new message from this command for \a prefix and \a connection. - - Notice that IRC servers do not echo sent message commands back to the client. - This function is particularly useful for converting sent message commands as - messages for presentation purposes. - - \code - if (command->type() == IrcCommand::Message) { - IrcMessage* message = command->toMessage(connection->nickName(), connection); - receiveMessage(message); - message->deleteLater(); - } - \endcode - */ -IrcMessage* IrcCommand::toMessage(const QString& prefix, IrcConnection* connection) const -{ - return IrcMessage::fromData(":" + prefix.toUtf8() + " " + toString().toUtf8(), connection); -} - -/*! - Creates a new ADMIN command with type IrcCommand::Admin and optional parameter \a server. - - This command shows admin info for the specified \a server, - or the current server if not specified. - */ -IrcCommand* IrcCommand::createAdmin(const QString& server) -{ - return IrcCommandPrivate::createCommand(Admin, QStringList() << server); -} - -/*! - Creates a new AWAY command with type IrcCommand::Away and optional parameter \a reason. - - Provides the server with \a reason to automatically send in reply to a private - message directed at the user. If \a reason is omitted, the away status is removed. - */ -IrcCommand* IrcCommand::createAway(const QString& reason) -{ - return IrcCommandPrivate::createCommand(Away, QStringList() << reason); -} - -/*! - Creates a new capability command with type IrcCommand::Capability and parameters \a subCommand and a \a capability. - - Available subcommands are: LS, LIST, REQ, ACK, NAK, CLEAR and END. - */ -IrcCommand* IrcCommand::createCapability(const QString& subCommand, const QString& capability) -{ - return createCapability(subCommand, QStringList() << capability); -} - -/*! - Creates a new capability command with type IrcCommand::Capability and parameters \a subCommand and optional \a capabilities. - - Available subcommands are: LS, LIST, REQ, ACK, NAK, CLEAR and END. - */ -IrcCommand* IrcCommand::createCapability(const QString& subCommand, const QStringList& capabilities) -{ - return IrcCommandPrivate::createCommand(Capability, QStringList() << subCommand << capabilities.join(QLatin1String(" "))); -} - -/*! - Creates a new CTCP action command with type IrcCommand::CtcpAction and parameters \a target and \a action. - */ -IrcCommand* IrcCommand::createCtcpAction(const QString& target, const QString& action) -{ - return IrcCommandPrivate::createCommand(CtcpAction, QStringList() << target << action); -} - -/*! - Creates a new CTCP reply command with type IrcCommand::CtcpReply and parameters \a target and \a reply. - */ -IrcCommand* IrcCommand::createCtcpReply(const QString& target, const QString& reply) -{ - return IrcCommandPrivate::createCommand(CtcpReply, QStringList() << target << reply); -} - -/*! - Creates a new CTCP request command with type IrcCommand::CtcpRequest and parameters \a target and \a request. - */ -IrcCommand* IrcCommand::createCtcpRequest(const QString& target, const QString& request) -{ - return IrcCommandPrivate::createCommand(CtcpRequest, QStringList() << target << request); -} - -/*! - Creates a new INFO command with type IrcCommand::Info and optional parameter \a server. - - This command shows info for the specified \a server, - or the current server if not specified. - */ -IrcCommand* IrcCommand::createInfo(const QString& server) -{ - return IrcCommandPrivate::createCommand(Info, QStringList() << server); -} - -/*! - Creates a new INVITE command with type IrcCommand::Invite and parameters \a user and \a channel. - - This command invites \a user to the \a channel. The channel does not have to exist, but - if it does, only members of the channel are allowed to invite other clients. if the - channel mode +i (invite-only) is set, only channel operators may invite other clients. - */ -IrcCommand* IrcCommand::createInvite(const QString& user, const QString& channel) -{ - return IrcCommandPrivate::createCommand(Invite, QStringList() << user << channel); -} - -/*! - Creates a new JOIN command with type IrcCommand::Join and parameters \a channel and optional \a key. - - This command joins the \a channel using \a key if specified. - If the channel does not exist, it will be created. - */ -IrcCommand* IrcCommand::createJoin(const QString& channel, const QString& key) -{ - return IrcCommandPrivate::createCommand(Join, QStringList() << channel << key); -} - -/*! - This overload is provided for convenience. - */ -IrcCommand* IrcCommand::createJoin(const QStringList& channels, const QStringList& keys) -{ - return IrcCommandPrivate::createCommand(Join, QStringList() << channels.join(",") << keys.join(",")); -} - -/*! - Creates a new KICK command with type IrcCommand::Kick and parameters \a channel, \a user and optional \a reason. - - This command forcibly removes \a user from \a channel, - and may only be issued by channel operators. - */ -IrcCommand* IrcCommand::createKick(const QString& channel, const QString& user, const QString& reason) -{ - return IrcCommandPrivate::createCommand(Kick, QStringList() << channel << user << reason); -} - -/*! - Creates a new KNOCK command with type IrcCommand::Knock and parameters \a channel and optional \a message. - - This command sends an invitation request to a \a channel with an optional \a message. - - \note The command is not formally defined by an RFC, but is supported by most major IRC daemons. - Support is indicated in a RPL_ISUPPORT reply (numeric 005) with the KNOCK keyword. - */ -IrcCommand* IrcCommand::createKnock(const QString& channel, const QString& message) -{ - return IrcCommandPrivate::createCommand(Knock, QStringList() << channel << message); -} - -/*! - Creates a new LIST command with type IrcCommand::List and optional parameters \a channels and \a server. - - This command lists all channels on the server. If \a channels are given, it will list the channel topics. - If \a server is given, the command will be forwarded to \a server for evaluation. - */ -IrcCommand* IrcCommand::createList(const QStringList& channels, const QString& server) -{ - return IrcCommandPrivate::createCommand(List, QStringList() << channels.join(",") << server); -} - -/*! - Creates a new PRIVMSG command with type IrcCommand::Message and parameters \a target and \a message. - - This command sends \a message to \a target, which is usually a user or channel. - */ -IrcCommand* IrcCommand::createMessage(const QString& target, const QString& message) -{ - return IrcCommandPrivate::createCommand(Message, QStringList() << target << message); -} - -/*! - Creates a new MODE command with type IrcCommand::Mode and parameters \a target and optional \a mode and \a arg. - - This command is used to set both user and channel modes. - */ -IrcCommand* IrcCommand::createMode(const QString& target, const QString& mode, const QString& arg) -{ - return IrcCommandPrivate::createCommand(Mode, QStringList() << target << mode << arg); -} - -/*! - Creates a new MOTD command with type IrcCommand::Motd and optional parameter \a server. - - This command shows the message of the day on the specified \a server, - or the current server if not specified. - */ -IrcCommand* IrcCommand::createMotd(const QString& server) -{ - return IrcCommandPrivate::createCommand(Motd, QStringList() << server); -} - -/*! - Creates a new NAMES command with type IrcCommand::Names and parameter \a channel. - - This command lists all users on the \a channel, optionally limiting to the given \a server. - - If \a channel is omitted, all users are shown, grouped by channel name with - all users who are not on a channel being shown as part of channel "*". - If \a server is specified, the command is sent to \a server for evaluation. -*/ -IrcCommand* IrcCommand::createNames(const QString& channel, const QString& server) -{ - return IrcCommandPrivate::createCommand(Names, QStringList() << channel << server); -} - -/*! - This overload is provided for convenience. - */ -IrcCommand* IrcCommand::createNames(const QStringList& channels, const QString& server) -{ - return IrcCommandPrivate::createCommand(Names, QStringList() << channels.join(",") << server); -} - -/*! - Creates a new NICK command with type IrcCommand::Nick and parameter \a nick. - - This command allows a client to change their IRC nickname. - */ -IrcCommand* IrcCommand::createNick(const QString& nick) -{ - return IrcCommandPrivate::createCommand(Nick, QStringList() << nick); -} - -/*! - Creates a new NOTICE command with type IrcCommand::Notice and parameters \a target and \a message. - - This command sends \a notice to \a target, which is usually a user or channel. - - \note The command works similarly to PRIVMSG, except automatic replies must never be sent in reply to NOTICE messages. - */ -IrcCommand* IrcCommand::createNotice(const QString& target, const QString& message) -{ - return IrcCommandPrivate::createCommand(Notice, QStringList() << target << message); -} - -/*! - Creates a new PART command with type IrcCommand::Part and parameters \a channel and optional \a reason. - - This command causes the client to leave the specified channel. - */ -IrcCommand* IrcCommand::createPart(const QString& channel, const QString& reason) -{ - return IrcCommandPrivate::createCommand(Part, QStringList() << channel << reason); -} - -/*! - This overload is provided for convenience. - */ -IrcCommand* IrcCommand::createPart(const QStringList& channels, const QString& reason) -{ - return IrcCommandPrivate::createCommand(Part, QStringList() << channels.join(",") << reason); -} - -/*! - Creates a new PING command with type IrcCommand::Ping and \a argument. - */ -IrcCommand* IrcCommand::createPing(const QString& argument) -{ - return IrcCommandPrivate::createCommand(Ping, QStringList() << argument); -} - -/*! - Creates a new PONG command with type IrcCommand::Pong and \a argument. - */ -IrcCommand* IrcCommand::createPong(const QString& argument) -{ - return IrcCommandPrivate::createCommand(Pong, QStringList() << argument); -} - -/*! - Creates a new QUIT command with type IrcCommand::Quit and optional parameter \a reason. - */ -IrcCommand* IrcCommand::createQuit(const QString& reason) -{ - return IrcCommandPrivate::createCommand(Quit, QStringList() << reason); -} - -/*! - Creates a new QUOTE command with type IrcCommand::Quote and \a raw. - */ -IrcCommand* IrcCommand::createQuote(const QString& raw) -{ - return IrcCommandPrivate::createCommand(Quote, QStringList() << raw); -} - -/*! - Creates a new QUOTE command with type IrcCommand::Quote and \a parameters. - */ -IrcCommand* IrcCommand::createQuote(const QStringList& parameters) -{ - return IrcCommandPrivate::createCommand(Quote, parameters); -} - -/*! - Creates a new STATS command with type IrcCommand::Stats and parameters \a query and optional \a server. - - This command queries statistics about the specified \a server, - or the current server if not specified. - */ -IrcCommand* IrcCommand::createStats(const QString& query, const QString& server) -{ - return IrcCommandPrivate::createCommand(Stats, QStringList() << query << server); -} - -/*! - Creates a new TIME command with type IrcCommand::Time and optional parameter \a server. - - This command queries local time of the specified \a server, - or the current server if not specified. - */ -IrcCommand* IrcCommand::createTime(const QString& server) -{ - return IrcCommandPrivate::createCommand(Time, QStringList() << server); -} - -/*! - Creates a new TOPIC command with type IrcCommand::Topic and parameters \a channel and optional \a topic. - - This command allows the client to query or set the channel topic on \a channel. - If \a topic is given, it sets the channel topic to \a topic. - If channel mode +t is set, only a channel operator may set the topic. - */ -IrcCommand* IrcCommand::createTopic(const QString& channel, const QString& topic) -{ - return IrcCommandPrivate::createCommand(Topic, QStringList() << channel << topic); -} - -/*! - Creates a new TRACE command with type IrcCommand::Trace and optional parameter \a target. - - This command traces the connection path across the IRC network - to the current server or to a specific \a target (server or client) - in a similar method to traceroute. - */ -IrcCommand* IrcCommand::createTrace(const QString& target) -{ - return IrcCommandPrivate::createCommand(Trace, QStringList() << target); -} - -/*! - Creates a new USERS command with type IrcCommand::Users and optional parameter \a server. - - This command queries the users of the specified \a server, - or the current server if not specified. - */ -IrcCommand* IrcCommand::createUsers(const QString& server) -{ - return IrcCommandPrivate::createCommand(Users, QStringList() << server); -} - -/*! - Creates a new command with type IrcCommand::Version and optional parameter \a user. - - This command queries the version of the specified \a user's client (CTCP REQUEST VERSION), - or the current server (VERSION) if not specified. - */ -IrcCommand* IrcCommand::createVersion(const QString& user) -{ - return IrcCommandPrivate::createCommand(Version, QStringList() << user); -} - -/*! - Creates a new WHO command with type IrcCommand::Who and parameters \a mask and optional \a operators. - - This command returns a list of users who match \a mask, - optionally matching only IRC \a operators. - */ -IrcCommand* IrcCommand::createWho(const QString& mask, bool operators) -{ - return IrcCommandPrivate::createCommand(Who, QStringList() << mask << (operators ? "o" : "")); -} - -/*! - Creates a new WHOIS command with type IrcCommand::Whois and parameter \a user. - - This command returns information about \a user. - */ -IrcCommand* IrcCommand::createWhois(const QString& user) -{ - return IrcCommandPrivate::createCommand(Whois, QStringList() << user); -} - -/*! - Creates a new WHOWAS command with type IrcCommand::Whowas and parameters \a user and optional \a count. - - This command returns information about a \a user that is no longer online - (due to client disconnection, or nickname changes). If given, the server - will return information from the last \a count times the nickname has been used. - */ -IrcCommand* IrcCommand::createWhowas(const QString& user, int count) -{ - return IrcCommandPrivate::createCommand(Whowas, QStringList() << user << QString::number(count)); -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug debug, IrcCommand::Type type) -{ - const int index = IrcCommand::staticMetaObject.indexOfEnumerator("Type"); - QMetaEnum enumerator = IrcCommand::staticMetaObject.enumerator(index); - const char* key = enumerator.valueToKey(type); - debug << (key ? key : "Unknown"); - return debug; -} - -QDebug operator<<(QDebug debug, const IrcCommand* command) -{ - if (!command) - return debug << "IrcCommand(0x0) "; - debug.nospace() << command->metaObject()->className() << '(' << (void*) command; - if (!command->objectName().isEmpty()) - debug.nospace() << ", name=" << qPrintable(command->objectName()); - debug.nospace() << ", type=" << command->type(); - QString str = command->toString(); - if (!str.isEmpty()) - debug.nospace() << ", " << str.left(20); - debug.nospace() << ')'; - return debug.space(); -} -#endif // QT_NO_DEBUG_STREAM - -#include "moc_irccommand.cpp" - -IRC_END_NAMESPACE diff --git a/libcommuni/src/core/ircconnection.cpp b/libcommuni/src/core/ircconnection.cpp deleted file mode 100644 index 837aa16..0000000 --- a/libcommuni/src/core/ircconnection.cpp +++ /dev/null @@ -1,1508 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "ircconnection.h" -#include "ircconnection_p.h" -#include "ircnetwork_p.h" -#include "ircprotocol.h" -#include "ircnetwork.h" -#include "irccommand.h" -#include "ircmessage.h" -#include "ircfilter.h" -#include "irc.h" -#include <QLocale> -#include <QDateTime> -#include <QTcpSocket> -#include <QTextCodec> -#include <QStringList> -#include <QMetaObject> -#include <QMetaMethod> -#include <QMetaEnum> -#ifndef QT_NO_OPENSSL -#include <QSslSocket> -#include <QSslError> -#endif // QT_NO_OPENSSL -#include <QDataStream> -#include <QVariantMap> - -IRC_BEGIN_NAMESPACE - -/*! - \file ircconnection.h - \brief \#include <IrcConnection> - */ - -/*! - \class IrcConnection ircconnection.h IrcConnection - \ingroup core - \brief Provides means to establish a connection to an IRC server. - - \section connection-management Connection management - - Before \ref open() "opening" a connection, it must be first initialized - with \ref host, \ref userName, \ref nickName and \ref realName. - - The connection status may be queried at any time via status(). Also - \ref active "isActive()" and \ref connected "isConnected()" are provided - for convenience. In addition to the \ref status "statusChanged()" signal, - the most important statuses are informed via the following convenience - signals: - \li connecting() - - The connection is being established. - \li \ref connected "connected()" - - The IRC connection has been established, and the server is ready to receive commands. - \li disconnected() - - The connection has been lost. - - \section receiving-messages Receiving messages - - Whenever a message is received from the server, the messageReceived() - signal is emitted. Also message type specific signals are provided - for convenience. See messageReceived() and IrcMessage and its - subclasses for more details. - - \section sending-commands Sending commands - - Sending commands to a server is most conveniently done by creating - them via the various static \ref IrcCommand "IrcCommand::createXxx()" - methods and passing them to sendCommand(). Also sendData() is provided - for more low-level access. See IrcCommand for more details. - - \section example Example - - \code - IrcConnection* connection = new IrcConnection(this); - connect(connection, SIGNAL(messageReceived(IrcMessage*)), this, SLOT(onMessageReceived(IrcMessage*))); - connection->setHost("irc.server.com"); - connection->setUserName("me"); - connection->setNickName("myself"); - connection->setRealName("And I"); - connection->sendCommand(IrcCommand::createJoin("#mine")); - connection->open(); - \endcode - - \sa IrcNetwork, IrcMessage, IrcCommand - */ - -/*! - \enum IrcConnection::Status - This enum describes the connection status. - */ - -/*! - \var IrcConnection::Inactive - \brief The connection is inactive. - */ - -/*! - \var IrcConnection::Waiting - \brief The connection is waiting for a reconnect. - */ - -/*! - \var IrcConnection::Connecting - \brief The connection is being established. - */ - -/*! - \var IrcConnection::Connected - \brief The connection has been established. - */ - -/*! - \var IrcConnection::Closing - \brief The connection is being closed. - */ - -/*! - \var IrcConnection::Closed - \brief The connection has been closed. - */ - -/*! - \var IrcConnection::Error - \brief The connection has encountered an error. - */ - -/*! - \fn void IrcConnection::connecting() - - This signal is emitted when the connection is being established. - - The underlying \ref socket has connected, but the IRC handshake is - not yet finished and the server is not yet ready to receive commands. - */ - -/*! - \fn void IrcConnection::nickNameRequired(const QString& reserved, QString* alternate) - - This signal is emitted when the requested nick name is \a reserved - and an \a alternate nick name should be provided. - - An alternate nick name may be set via the provided argument, by changing - the \ref nickName property, or by sending a nick command directly. - - \sa IrcCommand::createNick(), Irc::ERR_NICKNAMEINUSE, Irc::ERR_NICKCOLLISION - */ - -/*! - \fn void IrcConnection::channelKeyRequired(const QString& channel, QString* key) - - This signal is emitted when joining a \a channel requires a \a key. - The key may be set via the provided argument, or by sending a new - join command directly. - - \sa IrcCommand::createJoin(), Irc::ERR_BADCHANNELKEY - */ - -/*! - \fn void IrcConnection::disconnected() - - This signal is emitted when the connection has been lost. - */ - -/*! - \fn void IrcConnection::socketError(QAbstractSocket::SocketError error) - - This signal is emitted when a \ref socket \a error occurs. - - \sa QAbstractSocket::error() - */ - -/*! - \fn void IrcConnection::socketStateChanged(QAbstractSocket::SocketState state) - - This signal is emitted when the \a state of the underlying \ref socket changes. - - \sa QAbstractSocket::stateChanged() - */ - -/*! - \since 3.2 - \fn void IrcConnection::secureError() - - This signal is emitted when SSL socket error occurs. - - Either QSslSocket::sslErrors() was emitted, or the remote host closed - the connection without QSslSocket::sslErrors() being emitted meaning - that the server is not SSL-enabled. - */ - -/*! - \fn void IrcConnection::messageReceived(IrcMessage* message) - - This signal is emitted when a \a message is received. - - In addition, message type specific signals are provided for convenience: - \li void <b>capabilityMessageReceived</b>(\ref IrcCapabilityMessage* message) - \li void <b>errorMessageReceived</b>(\ref IrcErrorMessage* message) - \li void <b>inviteMessageReceived</b>(\ref IrcInviteMessage* message) - \li void <b>joinMessageReceived</b>(\ref IrcJoinMessage* message) - \li void <b>kickMessageReceived</b>(\ref IrcKickMessage* message) - \li void <b>modeMessageReceived</b>(\ref IrcModeMessage* message) - \li void <b>namesMessageReceived</b>(\ref IrcNamesMessage* message) - \li void <b>nickMessageReceived</b>(\ref IrcNickMessage* message) - \li void <b>noticeMessageReceived</b>(\ref IrcNoticeMessage* message) - \li void <b>numericMessageReceived</b>(\ref IrcNumericMessage* message) - \li void <b>motdMessageReceived</b>(\ref IrcMotdMessage* message) - \li void <b>partMessageReceived</b>(\ref IrcPartMessage* message) - \li void <b>pingMessageReceived</b>(\ref IrcPingMessage* message) - \li void <b>pongMessageReceived</b>(\ref IrcPongMessage* message) - \li void <b>privateMessageReceived</b>(\ref IrcPrivateMessage* message) - \li void <b>quitMessageReceived</b>(\ref IrcQuitMessage* message) - \li void <b>topicMessageReceived</b>(\ref IrcTopicMessage* message) - */ - -#ifndef IRC_DOXYGEN -template<typename T> -static void irc_debug(IrcConnection* connection, const char* msg, const T& arg) -{ - static bool dbg = qgetenv("IRC_DEBUG").toInt(); - if (dbg) { - const QString desc = QString::fromLatin1("IrcConnection(%1)").arg(connection->displayName()); - qDebug() << qPrintable(desc) << msg << arg; - } -} - -IrcConnectionPrivate::IrcConnectionPrivate() : - q_ptr(0), - encoding("ISO-8859-15"), - network(0), - protocol(0), - socket(0), - host(), - port(6667), - userName(), - nickName(), - realName(), - enabled(true), - status(IrcConnection::Inactive), - sslErrors(false), - closed(false) -{ -} - -void IrcConnectionPrivate::init(IrcConnection* connection) -{ - q_ptr = connection; - network = IrcNetworkPrivate::create(connection); - connection->setSocket(new QTcpSocket(connection)); - connection->setProtocol(new IrcProtocol(connection)); - QObject::connect(&reconnecter, SIGNAL(timeout()), connection, SLOT(_irc_reconnect())); -} - -void IrcConnectionPrivate::_irc_connected() -{ - Q_Q(IrcConnection); - closed = false; - sslErrors = false; - emit q->connecting(); - if (q->isSecure()) - QMetaObject::invokeMethod(socket, "startClientEncryption"); - protocol->open(); -} - -void IrcConnectionPrivate::_irc_disconnected() -{ - Q_Q(IrcConnection); - protocol->close(); - emit q->disconnected(); - if (enabled && !sslErrors && (status != IrcConnection::Closed || !closed) && !reconnecter.isActive() && reconnecter.interval() > 0) { - reconnecter.start(); - setStatus(IrcConnection::Waiting); - } -} - -void IrcConnectionPrivate::_irc_error(QAbstractSocket::SocketError error) -{ - Q_Q(IrcConnection); - if (!closed && !sslErrors && error == QAbstractSocket::RemoteHostClosedError && q->isSecure()) { - irc_debug(q, "SSL error:", "no SSL available"); - setStatus(IrcConnection::Error); - sslErrors = true; - emit q->secureError(); - } else if (!closed || (error != QAbstractSocket::RemoteHostClosedError && error != QAbstractSocket::UnknownSocketError)) { - irc_debug(q, "socket error:", error); - emit q->socketError(error); - setStatus(IrcConnection::Error); - } -} - -void IrcConnectionPrivate::_irc_sslErrors() -{ - Q_Q(IrcConnection); - QStringList errors; -#ifndef QT_NO_OPENSSL - QSslSocket* ssl = qobject_cast<QSslSocket*>(socket); - if (ssl) { - foreach (const QSslError& error, ssl->sslErrors()) - errors += error.errorString(); - } -#endif - irc_debug(q, "SSL handshake errors:", errors); - sslErrors = true; - emit q->secureError(); -} - -void IrcConnectionPrivate::_irc_state(QAbstractSocket::SocketState state) -{ - Q_Q(IrcConnection); - switch (state) { - case QAbstractSocket::UnconnectedState: - if (closed) - setStatus(IrcConnection::Closed); - break; - case QAbstractSocket::ClosingState: - if (status != IrcConnection::Error) - setStatus(IrcConnection::Closing); - break; - case QAbstractSocket::HostLookupState: - case QAbstractSocket::ConnectingState: - case QAbstractSocket::ConnectedState: - default: - setStatus(IrcConnection::Connecting); - break; - } - emit q->socketStateChanged(state); -} - -void IrcConnectionPrivate::_irc_reconnect() -{ - Q_Q(IrcConnection); - if (!q->isActive()) { - reconnecter.stop(); - q->open(); - } -} - -void IrcConnectionPrivate::_irc_readData() -{ - protocol->read(); -} - -void IrcConnectionPrivate::_irc_filterDestroyed(QObject* filter) -{ - messageFilters.removeAll(filter); - commandFilters.removeAll(filter); -} - -void IrcConnectionPrivate::setNick(const QString& nick) -{ - Q_Q(IrcConnection); - if (nickName != nick) { - nickName = nick; - emit q->nickNameChanged(nick); - } -} - -void IrcConnectionPrivate::setStatus(IrcConnection::Status value) -{ - Q_Q(IrcConnection); - if (status != value) { - const bool wasConnected = q->isConnected(); - status = value; - emit q->statusChanged(value); - - if (!wasConnected && q->isConnected()) { - emit q->connected(); - foreach (IrcCommand* cmd, pendingCommands) - q->sendCommand(cmd); - pendingCommands.clear(); - } - irc_debug(q, "status:", status); - } -} - -void IrcConnectionPrivate::setInfo(const QHash<QString, QString>& info) -{ - Q_Q(IrcConnection); - const QString oldName = q->displayName(); - IrcNetworkPrivate* priv = IrcNetworkPrivate::get(network); - priv->setInfo(info); - const QString newName = q->displayName(); - if (oldName != newName) - emit q->displayNameChanged(newName); -} - -void IrcConnectionPrivate::receiveMessage(IrcMessage* msg) -{ - Q_Q(IrcConnection); - bool filtered = false; - for (int i = messageFilters.count() - 1; !filtered && i >= 0; --i) { - IrcMessageFilter* filter = qobject_cast<IrcMessageFilter*>(messageFilters.at(i)); - if (filter) - filtered |= filter->messageFilter(msg); - } - - if (!filtered) { - emit q->messageReceived(msg); - - switch (msg->type()) { - case IrcMessage::Nick: - emit q->nickMessageReceived(static_cast<IrcNickMessage*>(msg)); - break; - case IrcMessage::Quit: - emit q->quitMessageReceived(static_cast<IrcQuitMessage*>(msg)); - break; - case IrcMessage::Join: - emit q->joinMessageReceived(static_cast<IrcJoinMessage*>(msg)); - break; - case IrcMessage::Part: - emit q->partMessageReceived(static_cast<IrcPartMessage*>(msg)); - break; - case IrcMessage::Topic: - emit q->topicMessageReceived(static_cast<IrcTopicMessage*>(msg)); - break; - case IrcMessage::WhoReply: - emit q->whoReplyMessageReceived(static_cast<IrcWhoReplyMessage*>(msg)); - break; - case IrcMessage::Invite: - emit q->inviteMessageReceived(static_cast<IrcInviteMessage*>(msg)); - break; - case IrcMessage::Kick: - emit q->kickMessageReceived(static_cast<IrcKickMessage*>(msg)); - break; - case IrcMessage::Mode: - emit q->modeMessageReceived(static_cast<IrcModeMessage*>(msg)); - break; - case IrcMessage::Private: - emit q->privateMessageReceived(static_cast<IrcPrivateMessage*>(msg)); - break; - case IrcMessage::Notice: - emit q->noticeMessageReceived(static_cast<IrcNoticeMessage*>(msg)); - break; - case IrcMessage::Ping: - emit q->pingMessageReceived(static_cast<IrcPingMessage*>(msg)); - break; - case IrcMessage::Pong: - emit q->pongMessageReceived(static_cast<IrcPongMessage*>(msg)); - break; - case IrcMessage::Error: - emit q->errorMessageReceived(static_cast<IrcErrorMessage*>(msg)); - break; - case IrcMessage::Numeric: - emit q->numericMessageReceived(static_cast<IrcNumericMessage*>(msg)); - break; - case IrcMessage::Capability: - emit q->capabilityMessageReceived(static_cast<IrcCapabilityMessage*>(msg)); - break; - case IrcMessage::Motd: - emit q->motdMessageReceived(static_cast<IrcMotdMessage*>(msg)); - break; - case IrcMessage::Names: - emit q->namesMessageReceived(static_cast<IrcNamesMessage*>(msg)); - break; - case IrcMessage::Unknown: - default: - break; - } - } - msg->deleteLater(); -} - -IrcCommand* IrcConnectionPrivate::createCtcpReply(IrcPrivateMessage* request) -{ - Q_Q(IrcConnection); - IrcCommand* reply = 0; - const QMetaObject* metaObject = q->metaObject(); - int idx = metaObject->indexOfMethod("createCtcpReply(QVariant)"); - if (idx != -1) { - // QML: QVariant createCtcpReply(QVariant) - QVariant ret; - QMetaMethod method = metaObject->method(idx); - method.invoke(q, Q_RETURN_ARG(QVariant, ret), Q_ARG(QVariant, QVariant::fromValue(request))); - reply = ret.value<IrcCommand*>(); - } else { - // C++: IrcCommand* createCtcpReply(IrcPrivateMessage*) - idx = metaObject->indexOfMethod("createCtcpReply(IrcPrivateMessage*)"); - QMetaMethod method = metaObject->method(idx); - method.invoke(q, Q_RETURN_ARG(IrcCommand*, reply), Q_ARG(IrcPrivateMessage*, request)); - } - return reply; -} -#endif // IRC_DOXYGEN - -/*! - Constructs a new IRC connection with \a parent. - */ -IrcConnection::IrcConnection(QObject* parent) : QObject(parent), d_ptr(new IrcConnectionPrivate) -{ - Q_D(IrcConnection); - d->init(this); -} - -/*! - Constructs a new IRC connection with \a host and \a parent. - */ -IrcConnection::IrcConnection(const QString& host, QObject* parent) : QObject(parent), d_ptr(new IrcConnectionPrivate) -{ - Q_D(IrcConnection); - d->init(this); - setHost(host); -} - -/*! - Destructs the IRC connection. - */ -IrcConnection::~IrcConnection() -{ - close(); - emit destroyed(this); -} - -/*! - This property holds the FALLBACK encoding for received messages. - - The fallback encoding is used when the message is detected not - to be valid \c UTF-8 and the consequent auto-detection of message - encoding fails. See QTextCodec::availableCodecs() for the list of - supported encodings. - - The default value is \c ISO-8859-15. - - \par Access functions: - \li QByteArray <b>encoding</b>() const - \li void <b>setEncoding</b>(const QByteArray& encoding) - - \sa QTextCodec::availableCodecs(), QTextCodec::codecForLocale() - */ -QByteArray IrcConnection::encoding() const -{ - Q_D(const IrcConnection); - return d->encoding; -} - -void IrcConnection::setEncoding(const QByteArray& encoding) -{ - Q_D(IrcConnection); - extern bool irc_is_supported_encoding(const QByteArray& encoding); // ircmessagedecoder.cpp - if (!irc_is_supported_encoding(encoding)) { - qWarning() << "IrcConnection::setEncoding(): unsupported encoding" << encoding; - return; - } - d->encoding = encoding; -} - -/*! - This property holds the server host. - - \par Access functions: - \li QString <b>host</b>() const - \li void <b>setHost</b>(const QString& host) - - \par Notifier signal: - \li void <b>hostChanged</b>(const QString& host) - */ -QString IrcConnection::host() const -{ - Q_D(const IrcConnection); - return d->host; -} - -void IrcConnection::setHost(const QString& host) -{ - Q_D(IrcConnection); - if (d->host != host) { - if (isActive()) - qWarning("IrcConnection::setHost() has no effect until re-connect"); - const QString oldName = displayName(); - d->host = host; - emit hostChanged(host); - const QString newName = displayName(); - if (oldName != newName) - emit displayNameChanged(newName); - } -} - -/*! - This property holds the server port. - - The default value is \c 6667. - - \par Access functions: - \li int <b>port</b>() const - \li void <b>setPort</b>(int port) - - \par Notifier signal: - \li void <b>portChanged</b>(int port) - */ -int IrcConnection::port() const -{ - Q_D(const IrcConnection); - return d->port; -} - -void IrcConnection::setPort(int port) -{ - Q_D(IrcConnection); - if (d->port != port) { - if (isActive()) - qWarning("IrcConnection::setPort() has no effect until re-connect"); - d->port = port; - emit portChanged(port); - } -} - -/*! - This property holds the user name. - - \note Changing the user name has no effect until the connection is re-established. - - \par Access functions: - \li QString <b>userName</b>() const - \li void <b>setUserName</b>(const QString& name) - - \par Notifier signal: - \li void <b>userNameChanged</b>(const QString& name) - */ -QString IrcConnection::userName() const -{ - Q_D(const IrcConnection); - return d->userName; -} - -void IrcConnection::setUserName(const QString& name) -{ - Q_D(IrcConnection); - QString user = name.split(" ", QString::SkipEmptyParts).value(0).trimmed(); - if (d->userName != user) { - if (isActive()) - qWarning("IrcConnection::setUserName() has no effect until re-connect"); - d->userName = user; - emit userNameChanged(user); - } -} - -/*! - This property holds the nick name. - - \par Access functions: - \li QString <b>nickName</b>() const - \li void <b>setNickName</b>(const QString& name) - - \par Notifier signal: - \li void <b>nickNameChanged</b>(const QString& name) - */ -QString IrcConnection::nickName() const -{ - Q_D(const IrcConnection); - return d->nickName; -} - -void IrcConnection::setNickName(const QString& name) -{ - Q_D(IrcConnection); - QString nick = name.split(" ", QString::SkipEmptyParts).value(0).trimmed(); - if (d->nickName != nick) { - if (isActive()) - sendCommand(IrcCommand::createNick(nick)); - else - d->setNick(nick); - } -} - -/*! - This property holds the real name. - - \note Changing the real name has no effect until the connection is re-established. - - \par Access functions: - \li QString <b>realName</b>() const - \li void <b>setRealName</b>(const QString& name) - - \par Notifier signal: - \li void <b>realNameChanged</b>(const QString& name) - */ -QString IrcConnection::realName() const -{ - Q_D(const IrcConnection); - return d->realName; -} - -void IrcConnection::setRealName(const QString& name) -{ - Q_D(IrcConnection); - if (d->realName != name) { - if (isActive()) - qWarning("IrcConnection::setRealName() has no effect until re-connect"); - d->realName = name; - emit realNameChanged(name); - } -} - -/*! - This property holds the password. - - \par Access functions: - \li QString <b>password</b>() const - \li void <b>setPassword</b>(const QString& password) - - \par Notifier signal: - \li void <b>passwordChanged</b>(const QString& password) - */ -QString IrcConnection::password() const -{ - Q_D(const IrcConnection); - return d->password; -} - -void IrcConnection::setPassword(const QString& password) -{ - Q_D(IrcConnection); - if (d->password != password) { - if (isActive()) - qWarning("IrcConnection::setPassword() has no effect until re-connect"); - d->password = password; - emit passwordChanged(password); - } -} - -/*! - This property holds the display name. - - Unless explicitly set, display name resolves to IrcNetwork::name - or IrcConnection::host while the former is not known. - - \par Access functions: - \li QString <b>displayName</b>() const - \li void <b>setDisplayName</b>(const QString& name) - - \par Notifier signal: - \li void <b>displayNameChanged</b>(const QString& name) - */ -QString IrcConnection::displayName() const -{ - Q_D(const IrcConnection); - QString name = d->displayName; - if (name.isEmpty()) - name = d->network->name(); - if (name.isEmpty()) - name = d->host; - return name; -} - -void IrcConnection::setDisplayName(const QString& name) -{ - Q_D(IrcConnection); - if (d->displayName != name) { - d->displayName = name; - emit displayNameChanged(name); - } -} - -/*! - \since 3.1 - - This property holds arbitrary user data. - - \par Access functions: - \li QVariantMap <b>userData</b>() const - \li void <b>setUserData</b>(const QVariantMap& data) - - \par Notifier signal: - \li void <b>userDataChanged</b>(const QVariantMap& data) - */ -QVariantMap IrcConnection::userData() const -{ - Q_D(const IrcConnection); - return d->userData; -} - -void IrcConnection::setUserData(const QVariantMap& data) -{ - Q_D(IrcConnection); - if (d->userData != data) { - d->userData = data; - emit userDataChanged(data); - } -} - -/*! - \property Status IrcConnection::status - This property holds the connection status. - - \par Access function: - \li Status <b>status</b>() const - - \par Notifier signal: - \li void <b>statusChanged</b>(Status status) - */ -IrcConnection::Status IrcConnection::status() const -{ - Q_D(const IrcConnection); - return d->status; -} - -/*! - \property bool IrcConnection::active - This property holds whether the connection is active. - - The connection is considered active when its either connecting, connected or closing. - - \par Access function: - \li bool <b>isActive</b>() const - */ -bool IrcConnection::isActive() const -{ - Q_D(const IrcConnection); - return d->status == Connecting || d->status == Connected || d->status == Closing; -} - -/*! - \property bool IrcConnection::connected - This property holds whether the connection has been established. - - The connection has been established when the welcome message - has been received and the server is ready to receive commands. - - \sa Irc::RPL_WELCOME - - \par Access function: - \li bool <b>isConnected</b>() const - - \par Notifier signal: - \li void <b>connected</b>() - */ -bool IrcConnection::isConnected() const -{ - Q_D(const IrcConnection); - return d->status == Connected; -} - -/*! - \property bool IrcConnection::enabled - This property holds whether the connection is enabled. - - The default value is \c true. - - When set to \c false, a disabled connection does nothing when open() is called. - - \par Access functions: - \li bool <b>isEnabled</b>() const - \li void <b>setEnabled</b>(bool enabled) [slot] - \li void <b>setDisabled</b>(bool disabled) [slot] - - \par Notifier signal: - \li void <b>enabledChanged</b>(bool enabled) - */ -bool IrcConnection::isEnabled() const -{ - Q_D(const IrcConnection); - return d->enabled; -} - -void IrcConnection::setEnabled(bool enabled) -{ - Q_D(IrcConnection); - if (d->enabled != enabled) { - d->enabled = enabled; - emit enabledChanged(enabled); - } -} - -void IrcConnection::setDisabled(bool disabled) -{ - setEnabled(!disabled); -} - -/*! - \property int IrcConnection::reconnectDelay - This property holds the reconnect delay in seconds. - - A positive (greater than zero) value enables automatic reconnect. - When the connection is lost due to a socket error, IrcConnection - will automatically attempt to reconnect after the specified delay. - - The default value is \c 0 (automatic reconnect disabled). - - \par Access functions: - \li int <b>reconnectDelay</b>() const - \li void <b>setReconnectDelay</b>(int seconds) - - \par Notifier signal: - \li void <b>reconnectDelayChanged</b>(int seconds) - */ -int IrcConnection::reconnectDelay() const -{ - Q_D(const IrcConnection); - return d->reconnecter.interval() / 1000; -} - -void IrcConnection::setReconnectDelay(int seconds) -{ - Q_D(IrcConnection); - const int interval = qMax(0, seconds) * 1000; - if (d->reconnecter.interval() != interval) { - d->reconnecter.setInterval(interval); - emit reconnectDelayChanged(interval); - } -} - -/*! - This property holds the socket. The default value is an instance of QTcpSocket. - - The previously set socket is deleted if its parent is \c this. - - \note IrcConnection supports QSslSocket in the way that it automatically - calls QSslSocket::startClientEncryption() while connecting. - - \par Access functions: - \li \ref QAbstractSocket* <b>socket</b>() const - \li void <b>setSocket</b>(\ref QAbstractSocket* socket) - - \sa IrcConnection::secure - */ -QAbstractSocket* IrcConnection::socket() const -{ - Q_D(const IrcConnection); - return d->socket; -} - -void IrcConnection::setSocket(QAbstractSocket* socket) -{ - Q_D(IrcConnection); - if (d->socket != socket) { - if (d->socket) { - d->socket->disconnect(this); - if (d->socket->parent() == this) - d->socket->deleteLater(); - } - - d->socket = socket; - if (socket) { - connect(socket, SIGNAL(connected()), this, SLOT(_irc_connected())); - connect(socket, SIGNAL(disconnected()), this, SLOT(_irc_disconnected())); - connect(socket, SIGNAL(readyRead()), this, SLOT(_irc_readData())); - connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(_irc_error(QAbstractSocket::SocketError))); - connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(_irc_state(QAbstractSocket::SocketState))); - if (isSecure()) - connect(socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(_irc_sslErrors())); - } - } -} - -/*! - \property bool IrcConnection::secure - This property holds whether the socket is an SSL socket. - - This property is provided for convenience. Calling - \code - connection->setSecure(true); - \endcode - - is equivalent to: - - \code - QSslSocket* socket = new QSslSocket(socket); - socket->setPeerVerifyMode(QSslSocket::QueryPeer); - connection->setSocket(socket); - \endcode - - \note IrcConnection does not handle SSL errors, see - QSslSocket::sslErrors() for more details on the subject. - - \par Access functions: - \li bool <b>isSecure</b>() const - \li void <b>setSecure</b>(bool secure) - - \par Notifier signal: - \li void <b>secureChanged</b>(bool secure) - - \sa secureSupported, IrcConnection::socket - */ -bool IrcConnection::isSecure() const -{ -#ifdef QT_NO_OPENSSL - return false; -#else - return qobject_cast<QSslSocket*>(socket()); -#endif // QT_NO_OPENSSL -} - -void IrcConnection::setSecure(bool secure) -{ -#ifdef QT_NO_OPENSSL - if (secure) { - qWarning("IrcConnection::setSecure(): the Qt build does not support SSL"); - return; - } -#else - if (secure && !QSslSocket::supportsSsl()) { - qWarning("IrcConnection::setSecure(): the platform does not support SSL - try installing OpenSSL"); - return; - } - - QSslSocket* sslSocket = qobject_cast<QSslSocket*>(socket()); - if (secure && !sslSocket) { - sslSocket = new QSslSocket(this); - sslSocket->setPeerVerifyMode(QSslSocket::QueryPeer); - setSocket(sslSocket); - emit secureChanged(true); - } else if (!secure && sslSocket) { - setSocket(new QTcpSocket(this)); - emit secureChanged(false); - } -#endif // !QT_NO_OPENSSL -} - -/*! - \since 3.2 - \property bool IrcConnection::secureSupported - This property holds whether SSL is supported. - - The value may be \c false for the following reasons: - \li Qt was built without SSL support (\c QT_NO_SSL is defined), or - \li The platform does not support SSL (QSslSocket::supportsSsl() returns \c false). - - \par Access function: - \li static bool <b>isSecureSupported</b>() - - \sa secure, QSslSocket::supportsSsl() - */ - -bool IrcConnection::isSecureSupported() -{ -#ifdef QT_NO_OPENSSL - return false; -#else - return QSslSocket::supportsSsl(); -#endif -} - -/*! - This property holds the used SASL (Simple Authentication and Security Layer) mechanism. - - \par Access functions: - \li QString <b>saslMechanism</b>() const - \li void <b>setSaslMechanism</b>(const QString& mechanism) - - \par Notifier signal: - \li void <b>saslMechanismChanged</b>(const QString& mechanism) - - \sa supportedSaslMechanisms - */ -QString IrcConnection::saslMechanism() const -{ - Q_D(const IrcConnection); - return d->saslMechanism; -} - -void IrcConnection::setSaslMechanism(const QString& mechanism) -{ - Q_D(IrcConnection); - if (!mechanism.isEmpty() && !supportedSaslMechanisms().contains(mechanism.toUpper())) { - qWarning("IrcConnection::setSaslMechanism(): unsupported mechanism: '%s'", qPrintable(mechanism)); - return; - } - if (d->saslMechanism != mechanism) { - if (isActive()) - qWarning("IrcConnection::setSaslMechanism() has no effect until re-connect"); - d->saslMechanism = mechanism.toUpper(); - emit saslMechanismChanged(mechanism); - } -} - -/*! - This property holds the list of supported SASL (Simple Authentication and Security Layer) mechanisms. - - \par Access function: - \li static QStringList <b>supportedSaslMechanisms</b>() - - \sa saslMechanism - */ -QStringList IrcConnection::supportedSaslMechanisms() -{ - return QStringList() << QLatin1String("PLAIN"); -} - -/*! - This property holds the network information. - - \par Access function: - \li IrcNetwork* <b>network</b>() const - */ -IrcNetwork* IrcConnection::network() const -{ - Q_D(const IrcConnection); - return d->network; -} - -/*! - Opens a connection to the server. - - The function does nothing when the connection is already \ref active - or explicitly \ref enabled "disabled". - - \note The function merely outputs a warnings and returns immediately if - either \ref host, \ref userName, \ref nickName or \ref realName is empty. - */ -void IrcConnection::open() -{ - Q_D(IrcConnection); - if (d->host.isEmpty()) { - qWarning("IrcConnection::open(): host is empty!"); - return; - } - if (d->userName.isEmpty()) { - qWarning("IrcConnection::open(): userName is empty!"); - return; - } - if (d->nickName.isEmpty()) { - qWarning("IrcConnection::open(): nickName is empty!"); - return; - } - if (d->realName.isEmpty()) { - qWarning("IrcConnection::open(): realName is empty!"); - return; - } - if (d->enabled && d->socket && !isActive()) - d->socket->connectToHost(d->host, d->port); -} - -/*! - Immediately closes the connection to the server. - - Calling close() makes the connection close immediately and thus might lead to - "remote host closed the connection". In order to quit gracefully, call quit() - first. This function attempts to flush the underlying socket, but this does - not guarantee that the server ever receives the QUIT command if the connection - is closed immediately after sending the command. In order to ensure a graceful - quit, let the server handle closing the connection. - - C++ example: - \code - connection->quit(reason); - QTimer::singleShot(timeout, connection, SLOT(deleteLater())); - \endcode - - QML example: - \code - connection.quit(reason); - connection.destroy(timeout); - \endcode - - \sa quit() - */ -void IrcConnection::close() -{ - Q_D(IrcConnection); - if (d->socket) { - d->closed = true; - d->socket->flush(); - d->socket->abort(); - d->socket->disconnectFromHost(); - if (d->socket->state() == QAbstractSocket::UnconnectedState) - d->setStatus(Closed); - d->reconnecter.stop(); - } -} - -/*! - Sends a quit command with an optionally specified \a reason. - - This method is provided for convenience. It is equal to: - \code - IrcCommand* command = IrcCommand::createQuit(reason); - connection->sendCommand(command); - \endcode - - \sa IrcCommand::createQuit() - */ -void IrcConnection::quit(const QString& reason) -{ - sendCommand(IrcCommand::createQuit(reason)); -} - -/*! - Sends a \a command to the server. - - If the connection is not active, the \a command is queued and sent - later when the connection has been established. - - \note If the command has a valid parent, it is an indication that - the caller of this method is be responsible for freeing the command. - If the command does not have a valid parent (like the commands - created via various IrcCommand::createXxx() methods) the connection - will take ownership of the command and delete it once it has been - sent. Thus, the command must have been allocated on the heap and - it is not safe to access the command after it has been sent. - - \sa sendData() - */ -bool IrcConnection::sendCommand(IrcCommand* command) -{ - Q_D(IrcConnection); - bool res = false; - if (command) { - bool filtered = false; - for (int i = d->commandFilters.count() - 1; !filtered && i >= 0; --i) { - QObject* filter = d->commandFilters.at(i); - IrcCommandFilter* commandFilter = qobject_cast<IrcCommandFilter*>(filter); - if (commandFilter && !d->activeCommandFilters.contains(filter)) { - d->activeCommandFilters.push(filter); - filtered |= commandFilter->commandFilter(command); - d->activeCommandFilters.pop(); - } - } - if (filtered) - return false; - - if (isActive()) { - QTextCodec* codec = QTextCodec::codecForName(command->encoding()); - Q_ASSERT(codec); - res = sendData(codec->fromUnicode(command->toString())); - if (!command->parent()) - command->deleteLater(); - } else { - Q_D(IrcConnection); - d->pendingCommands += command; - } - } - return res; -} - -/*! - Sends raw \a data to the server. - - \sa sendCommand() - */ -bool IrcConnection::sendData(const QByteArray& data) -{ - Q_D(IrcConnection); - if (d->socket) { - static bool dbg = qgetenv("IRC_DEBUG").toInt(); - if (dbg) qDebug() << "->" << data; - if (!d->closed && data.length() >= 4) { - const QByteArray cmd = data.left(5).toUpper(); - if (cmd.startsWith("QUIT") && (data.length() == 4 || QChar(data.at(4)).isSpace())) - d->closed = true; - } - return d->protocol->write(data); - } - return false; -} - -/*! - Sends raw \a message to the server using UTF-8 encoding. - - \sa sendData(), sendCommand() - */ -bool IrcConnection::sendRaw(const QString& message) -{ - return sendData(message.toUtf8()); -} - -/*! - Installs a message \a filter on the connection. The \a filter must implement the IrcMessageFilter interface. - - A message filter receives all messages that are sent to the connection. The filter - receives messages via the \ref IrcMessageFilter::messageFilter() "messageFilter()" - function. The function must return \c true if the message should be filtered, - (i.e. stopped); otherwise it must return \c false. - - If multiple message filters are installed on the same connection, the filter - that was installed last is activated first. - - \sa removeMessageFilter() - */ -void IrcConnection::installMessageFilter(QObject* filter) -{ - Q_D(IrcConnection); - IrcMessageFilter* msgFilter = qobject_cast<IrcMessageFilter*>(filter); - if (msgFilter) { - d->messageFilters += filter; - connect(filter, SIGNAL(destroyed(QObject*)), this, SLOT(_irc_filterDestroyed(QObject*)), Qt::UniqueConnection); - } -} - -/*! - Removes a message \a filter from the connection. - - The request is ignored if such message filter has not been installed. - All message filters for a connection are automatically removed - when the connection is destroyed. - - \sa installMessageFilter() - */ -void IrcConnection::removeMessageFilter(QObject* filter) -{ - Q_D(IrcConnection); - IrcMessageFilter* msgFilter = qobject_cast<IrcMessageFilter*>(filter); - if (msgFilter) { - d->messageFilters.removeAll(filter); - disconnect(filter, SIGNAL(destroyed(QObject*)), this, SLOT(_irc_filterDestroyed(QObject*))); - } -} - -/*! - Installs a command \a filter on the connection. The \a filter must implement the IrcCommandFilter interface. - - A command filter receives all commands that are sent from the connection. The filter - receives commands via the \ref IrcCommandFilter::commandFilter() "commandFilter()" - function. The function must return \c true if the command should be filtered, - (i.e. stopped); otherwise it must return \c false. - - If multiple command filters are installed on the same connection, the filter - that was installed last is activated first. - - \sa removeCommandFilter() - */ -void IrcConnection::installCommandFilter(QObject* filter) -{ - Q_D(IrcConnection); - IrcCommandFilter* cmdFilter = qobject_cast<IrcCommandFilter*>(filter); - if (cmdFilter) { - d->commandFilters += filter; - connect(filter, SIGNAL(destroyed(QObject*)), this, SLOT(_irc_filterDestroyed(QObject*)), Qt::UniqueConnection); - } -} - -/*! - Removes a command \a filter from the connection. - - The request is ignored if such command filter has not been installed. - All command filters for a connection are automatically removed when - the connection is destroyed. - - \sa installCommandFilter() - */ -void IrcConnection::removeCommandFilter(QObject* filter) -{ - Q_D(IrcConnection); - IrcCommandFilter* cmdFilter = qobject_cast<IrcCommandFilter*>(filter); - if (cmdFilter) { - d->commandFilters.removeAll(filter); - disconnect(filter, SIGNAL(destroyed(QObject*)), this, SLOT(_irc_filterDestroyed(QObject*))); - } -} - -/*! - \since 3.1 - - Saves the state of the connection. The \a version number is stored as part of the state data. - - To restore the saved state, pass the return value and \a version number to restoreState(). - */ -QByteArray IrcConnection::saveState(int version) const -{ - QVariantMap args; - args.insert("version", version); - args.insert("host", host()); - args.insert("port", port()); - args.insert("userName", userName()); - args.insert("nickName", nickName()); - args.insert("realName", realName()); - args.insert("password", password()); - args.insert("displayName", displayName()); - args.insert("userData", userData()); - args.insert("encoding", encoding()); - args.insert("enabled", isEnabled()); - args.insert("reconnectDelay", reconnectDelay()); - args.insert("secure", isSecure()); - args.insert("saslMechanism", saslMechanism()); - - QByteArray state; - QDataStream out(&state, QIODevice::WriteOnly); - out << args; - return state; -} - -/*! - \since 3.1 - - Restores the \a state of the connection. The \a version number is compared with that stored in \a state. - If they do not match, the connection state is left unchanged, and this function returns \c false; otherwise, - the state is restored, and \c true is returned. - - \sa saveState() - */ -bool IrcConnection::restoreState(const QByteArray& state, int version) -{ - if (isActive()) - return false; - - QVariantMap args; - QDataStream in(state); - in >> args; - if (in.status() != QDataStream::Ok || args.value("version", -1).toInt() != version) - return false; - - setHost(args.value("host", host()).toString()); - setPort(args.value("port", port()).toInt()); - setUserName(args.value("userName", userName()).toString()); - setNickName(args.value("nickName", nickName()).toString()); - setRealName(args.value("realName", realName()).toString()); - setPassword(args.value("password", password()).toString()); - setDisplayName(args.value("displayName").toString()); - setUserData(args.value("userData", userData()).toMap()); - setEncoding(args.value("encoding", encoding()).toByteArray()); - setEnabled(args.value("enabled", isEnabled()).toBool()); - setReconnectDelay(args.value("reconnectDelay", reconnectDelay()).toInt()); - setSecure(args.value("secure", isSecure()).toBool()); - setSaslMechanism(args.value("saslMechanism", saslMechanism()).toString()); - return true; -} - -/*! - Creates a reply command for the CTCP \a request. - - The default implementation handles the following CTCP requests: CLIENTINFO, PING, SOURCE, TIME and VERSION. - - Reimplement this function in order to alter or omit the default replies. - */ -IrcCommand* IrcConnection::createCtcpReply(IrcPrivateMessage* request) const -{ - QString reply; - QString type = request->content().split(" ", QString::SkipEmptyParts).value(0).toUpper(); - if (type == "PING") - reply = request->content(); - else if (type == "TIME") - reply = QLatin1String("TIME ") + QLocale().toString(QDateTime::currentDateTime(), QLocale::ShortFormat); - else if (type == "VERSION") - reply = QLatin1String("VERSION Using libcommuni ") + Irc::version() + QLatin1String(" - http://communi.github.com"); - else if (type == "SOURCE") - reply = QLatin1String("SOURCE http://communi.github.com"); - else if (type == "CLIENTINFO") - reply = QLatin1String("CLIENTINFO PING SOURCE TIME VERSION"); - if (!reply.isEmpty()) - return IrcCommand::createCtcpReply(request->nick(), reply); - return 0; -} - -/*! - \since 3.2 - - This property holds the protocol. - - The previously set protocol is deleted if its parent is \c this. - - \par Access functions: - \li \ref IrcProtocol* <b>protocol</b>() const - \li void <b>setProtocol</b>(\ref IrcProtocol* protocol) - */ -IrcProtocol* IrcConnection::protocol() const -{ - Q_D(const IrcConnection); - return d->protocol; -} - -void IrcConnection::setProtocol(IrcProtocol* proto) -{ - Q_D(IrcConnection); - if (d->protocol != proto) { - if (d->protocol && d->protocol->parent() == this) - delete d->protocol; - d->protocol = proto; - } -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug debug, IrcConnection::Status status) -{ - const int index = IrcConnection::staticMetaObject.indexOfEnumerator("Status"); - QMetaEnum enumerator = IrcConnection::staticMetaObject.enumerator(index); - const char* key = enumerator.valueToKey(status); - debug << (key ? key : "Unknown"); - return debug; -} - -QDebug operator<<(QDebug debug, const IrcConnection* connection) -{ - if (!connection) - return debug << "IrcConnection(0x0) "; - debug.nospace() << connection->metaObject()->className() << '(' << (void*) connection; - if (!connection->displayName().isEmpty()) - debug.nospace() << ", " << qPrintable(connection->displayName()); - debug.nospace() << ')'; - return debug.space(); -} -#endif // QT_NO_DEBUG_STREAM - -#include "moc_ircconnection.cpp" - -IRC_END_NAMESPACE diff --git a/libcommuni/src/core/irccore.cpp b/libcommuni/src/core/irccore.cpp deleted file mode 100644 index f6453c8..0000000 --- a/libcommuni/src/core/irccore.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "irccore.h" - -IRC_BEGIN_NAMESPACE - -/*! - \file irccore.h - \brief \#include <IrcCore> - */ - -/*! - \namespace IrcCore - \ingroup core - \brief Module meta-type registration. - */ - -namespace IrcCore { - - /*! - Registers IrcCore types to the %Qt meta-system. - - \sa IrcModel::registerMetaTypes(), IrcUtil::registerMetaTypes(), qRegisterMetaType() - */ - void registerMetaTypes() - { - qRegisterMetaType<Irc::Color>("Irc::Color"); - qRegisterMetaType<Irc::DataRole>("Irc::DataRole"); - qRegisterMetaType<Irc::SortMethod>("Irc::SortMethod"); - qRegisterMetaType<Irc::Code>("Irc::Code"); - - qRegisterMetaType<IrcConnection*>("IrcConnection*"); - qRegisterMetaType<IrcConnection::Status>("IrcConnection::Status"); - - qRegisterMetaType<IrcNetwork*>("IrcNetwork*"); - - qRegisterMetaType<IrcCommand*>("IrcCommand*"); - qRegisterMetaType<IrcCommand::Type>("IrcCommand::Type"); - - qRegisterMetaType<IrcMessage*>("IrcMessage*"); - qRegisterMetaType<IrcMessage::Type>("IrcMessage::Type"); - - qRegisterMetaType<IrcCapabilityMessage*>("IrcCapabilityMessage*"); - qRegisterMetaType<IrcErrorMessage*>("IrcErrorMessage*"); - qRegisterMetaType<IrcInviteMessage*>("IrcInviteMessage*"); - qRegisterMetaType<IrcJoinMessage*>("IrcJoinMessage*"); - qRegisterMetaType<IrcKickMessage*>("IrcKickMessage*"); - qRegisterMetaType<IrcModeMessage*>("IrcModeMessage*"); - qRegisterMetaType<IrcNamesMessage*>("IrcNamesMessage*"); - qRegisterMetaType<IrcNickMessage*>("IrcNickMessage*"); - qRegisterMetaType<IrcNoticeMessage*>("IrcNoticeMessage*"); - qRegisterMetaType<IrcNumericMessage*>("IrcNumericMessage*"); - qRegisterMetaType<IrcMotdMessage*>("IrcMotdMessage*"); - qRegisterMetaType<IrcPartMessage*>("IrcPartMessage*"); - qRegisterMetaType<IrcPingMessage*>("IrcPingMessage*"); - qRegisterMetaType<IrcPongMessage*>("IrcPongMessage*"); - qRegisterMetaType<IrcPrivateMessage*>("IrcPrivateMessage*"); - qRegisterMetaType<IrcQuitMessage*>("IrcQuitMessage*"); - qRegisterMetaType<IrcTopicMessage*>("IrcTopicMessage*"); - qRegisterMetaType<IrcWhoReplyMessage*>("IrcWhoReplyMessage*"); - } -} - -IRC_END_NAMESPACE diff --git a/libcommuni/src/core/ircfilter.cpp b/libcommuni/src/core/ircfilter.cpp deleted file mode 100644 index 054badb..0000000 --- a/libcommuni/src/core/ircfilter.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "ircfilter.h" - -IRC_BEGIN_NAMESPACE - -/*! - \file ircfilter.h - \brief \#include <\ref ircfilter.h "IrcFilter"> - */ - -/*! - \file ircmessagefilter.h - \brief \#include <IrcMessageFilter> - */ - -/*! - \file irccommandfilter.h - \brief \#include <IrcCommandFilter> - */ - -/*! - \class IrcMessageFilter ircfilter.h <IrcMessageFilter> - \ingroup core - \brief Provides an interface for filtering messages - - IrcMessageFilter may be used to intercept messages before - IrcConnection::messageReceived() is emitted and the messages get delivered - further. In order to use IrcMessageFilter, it must be installed via - IrcConnection::installMessageFilter(). - - Message filtering is mostly useful for handling specific replies before - the rest of the application receives it. This way there is no need to - for example ignore and hide such replies later in the application code. - - The following example sends a PING command after each PRIVMSG command. - A consequent PONG reply from the server verifies that the PRIVMSG has - been also processed. - - \code - class CommandVerifier : public QObject, - public IrcCommandFilter, - public IrcMessageFilter - { - Q_OBJECT - Q_INTERFACES(IrcCommandFilter IrcMessageFilter) - - public: - CommandVerifier(IrcConnection* parent) : - QObject(parent), identifier(0), connection(parent) - { - connection->installMessageFilter(this); - connection->installCommandFilter(this); - } - - virtual bool commandFilter(IrcCommand* cmd) - { - if (cmd->type() == IrcCommand::Message) { - cmd->setParent(this); // take ownership - connection->sendCommand(cmd); - commands.insert(++identifier, cmd); - connection->sendData("PING communi/" + QByteArray::number(identifier)); - return true; - } - return false; - } - - virtual bool messageFilter(IrcMessage* msg) - { - if (msg->type() == IrcMessage::Pong) { - QString arg = static_cast<IrcPongMessage*>(msg)->argument(); - if (arg.startsWith("communi/")) { - bool ok = false; - quint64 id = arg.mid(8).toULongLong(&ok); - if (ok) { - IrcCommand* command = commands.take(id); - if (command) { - emit verified(command); - command->deleteLater(); - return true; - } - } - } - } - return false; - } - - signals: - void verified(IrcCommand* cmd); - - private: - quint64 identifier; - IrcConnection* connection; - QMap<quint64, IrcCommand*> commands; - }; - \endcode - - \sa IrcConnection::installMessageFilter(), IrcCommandFilter - */ - -/*! - \fn IrcMessageFilter::~IrcMessageFilter() - Destructs the message filter. - - The message filter is automatically removed from any connection(s) - it is installed on. - - \sa IrcConnection::removeMessageFilter() - */ - -/*! - \fn virtual bool IrcMessageFilter::messageFilter(IrcMessage* message) = 0 - - Reimplement this function to filter messages from installed connections. - - Return \c true to filter the message out, i.e. stop it being handled further; - otherwise return \c false. - - \sa IrcConnection::installMessageFilter() - */ - -/*! - \class IrcCommandFilter ircfilter.h <IrcCommandFilter> - \ingroup core - \brief Provides an interface for filtering commands - - IrcCommandFilter may be used to intercept commands before they - get sent further. In order to use IrcCommandFilter, it must be - installed via IrcConnection::installCommandFilter(). - - Command filtering can be useful doing extra tasks for specific - type of commands. The following example sends a PING command - after each PRIVMSG command. A consequent PONG reply from the - server verifies that the PRIVMSG has been also processed. - - \code - class CommandVerifier : public QObject, - public IrcCommandFilter, - public IrcMessageFilter - { - Q_OBJECT - Q_INTERFACES(IrcCommandFilter IrcMessageFilter) - - public: - CommandVerifier(IrcConnection* parent) : - QObject(parent), identifier(0), connection(parent) - { - connection->installMessageFilter(this); - connection->installCommandFilter(this); - } - - virtual bool commandFilter(IrcCommand* cmd) - { - if (cmd->type() == IrcCommand::Message) { - cmd->setParent(this); // take ownership - connection->sendCommand(cmd); - commands.insert(++identifier, cmd); - connection->sendData("PING communi/" + QByteArray::number(identifier)); - return true; - } - return false; - } - - virtual bool messageFilter(IrcMessage* msg) - { - if (msg->type() == IrcMessage::Pong) { - QString arg = static_cast<IrcPongMessage*>(msg)->argument(); - if (arg.startsWith("communi/")) { - bool ok = false; - quint64 id = arg.mid(8).toULongLong(&ok); - if (ok) { - IrcCommand* command = commands.take(id); - if (command) { - emit verified(command); - command->deleteLater(); - return true; - } - } - } - } - return false; - } - - signals: - void verified(IrcCommand* cmd); - - private: - quint64 identifier; - IrcConnection* connection; - QMap<quint64, IrcCommand*> commands; - }; - \endcode - - \note Notice that it is safe to call IrcConnection::sendCommand() - from IrcCommandFilter::commandFilter(). Such commands won't get - delivered back to the \b same filter to avoid recursion. - - \sa IrcConnection::installCommandFilter(), IrcMessageFilter - */ - -/*! - \fn IrcCommandFilter::~IrcCommandFilter() - Destructs the command filter. - - The command filter is automatically removed from any connection(s) - it is installed on. - - \sa IrcConnection::removeCommandFilter() - */ - -/*! - \fn virtual bool IrcCommandFilter::commandFilter(IrcCommand* command) = 0 - - Reimplement this function to filter commands to installed connections. - - Return \c true to filter the command out, i.e. stop it being handled further; - otherwise return \c false. - - \sa IrcConnection::installCommandFilter() - */ - -IRC_END_NAMESPACE diff --git a/libcommuni/src/core/ircmessage.cpp b/libcommuni/src/core/ircmessage.cpp deleted file mode 100644 index eaca6ab..0000000 --- a/libcommuni/src/core/ircmessage.cpp +++ /dev/null @@ -1,1604 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "ircmessage.h" -#include "ircmessage_p.h" -#include "ircconnection.h" -#include "ircconnection_p.h" -#include "ircnetwork.h" -#include "irccommand.h" -#include "irc.h" -#include <QMetaEnum> -#include <QVariant> -#include <QDebug> - -IRC_BEGIN_NAMESPACE - -/*! - \file ircmessage.h - \brief \#include <IrcMessage> - */ - -/*! - \class IrcMessage ircmessage.h <IrcMessage> - \ingroup core - \ingroup message - \brief The base class of all messages. - - IRC messages are received from an IRC server. IrcConnection translates received - messages into IrcMessage instances and emits the IrcConnection::messageReceived() - signal upon message received. - - Subclasses of IrcMessage contain specialized accessors for parameters that - are specific to the particular type of message. See IrcMessage::Type for - the list of supported message types. - - \sa IrcConnection::messageReceived(), IrcMessage::Type - */ - -/*! - \enum IrcMessage::Type - This enum describes the supported message types. - */ - -/*! - \var IrcMessage::Unknown - \brief An unknown message (IrcMessage). - */ - -/*! - \var IrcMessage::Capability - \brief A capability message (IrcCapabilityMessage). - */ - -/*! - \var IrcMessage::Error - \brief An error message (IrcErrorMessage). - */ - -/*! - \var IrcMessage::Invite - \brief An invite message (IrcInviteMessage). - */ - -/*! - \var IrcMessage::Join - \brief A join message (IrcJoinMessage). - */ - -/*! - \var IrcMessage::Kick - \brief A kick message (IrcKickMessage). - */ - -/*! - \var IrcMessage::Mode - \brief A mode message (IrcModeMessage). - */ - -/*! - \var IrcMessage::Motd - \brief A message of the day (IrcMotdMessage). - */ - -/*! - \var IrcMessage::Names - \brief A names message (IrcNamesMessage). - */ - -/*! - \var IrcMessage::Nick - \brief A nick message (IrcNickMessage). - */ - -/*! - \var IrcMessage::Notice - \brief A notice message (IrcNoticeMessage). - */ - -/*! - \var IrcMessage::Numeric - \brief A numeric message (IrcNumericMessage). - */ - -/*! - \var IrcMessage::Part - \brief A part message (IrcPartMessage). - */ - -/*! - \var IrcMessage::Ping - \brief A ping message (IrcPingMessage). - */ - -/*! - \var IrcMessage::Pong - \brief A pong message (IrcPongMessage). - */ - -/*! - \var IrcMessage::Private - \brief A private message (IrcPrivateMessage). - */ - -/*! - \var IrcMessage::Quit - \brief A quit message (IrcQuitMessage). - */ - -/*! - \var IrcMessage::Topic - \brief A topic message (IrcTopicMessage). - */ - -/*! - \enum IrcMessage::Flag - This enum describes the supported message flags. - */ - -/*! - \var IrcMessage::None - \brief The message has no flags. - */ - -/*! - \var IrcMessage::Own - \brief The message is user's own message. - */ - -/*! - \var IrcMessage::Identified - \brief The message is identified. - */ - -/*! - \var IrcMessage::Unidentified - \brief The message is unidentified. - */ - -/*! - \since 3.2 - \var IrcMessage::Playback - \brief The message is playback. - */ - -static const QMetaObject* irc_command_meta_object(const QString& command) -{ - static QHash<QString, const QMetaObject*> metaObjects; - if (metaObjects.isEmpty()) { - metaObjects.insert("CAP", &IrcCapabilityMessage::staticMetaObject); - metaObjects.insert("ERROR", &IrcErrorMessage::staticMetaObject); - metaObjects.insert("INVITE", &IrcInviteMessage::staticMetaObject); - metaObjects.insert("JOIN", &IrcJoinMessage::staticMetaObject); - metaObjects.insert("KICK", &IrcKickMessage::staticMetaObject); - metaObjects.insert("MODE", &IrcModeMessage::staticMetaObject); - metaObjects.insert("NICK", &IrcNickMessage::staticMetaObject); - metaObjects.insert("NOTICE", &IrcNoticeMessage::staticMetaObject); - metaObjects.insert("PART", &IrcPartMessage::staticMetaObject); - metaObjects.insert("PING", &IrcPingMessage::staticMetaObject); - metaObjects.insert("PONG", &IrcPongMessage::staticMetaObject); - metaObjects.insert("PRIVMSG", &IrcPrivateMessage::staticMetaObject); - metaObjects.insert("QUIT", &IrcQuitMessage::staticMetaObject); - metaObjects.insert("TOPIC", &IrcTopicMessage::staticMetaObject); - } - - const QMetaObject* metaObject = metaObjects.value(command.toUpper()); - if (!metaObject) { - bool ok = false; - command.toInt(&ok); - if (ok) - metaObject = &IrcNumericMessage::staticMetaObject; - } - if (!metaObject) - metaObject = &IrcMessage::staticMetaObject; - return metaObject; -} - -/*! - Constructs a new IrcMessage with \a connection. - */ -IrcMessage::IrcMessage(IrcConnection* connection) : QObject(connection), d_ptr(new IrcMessagePrivate) -{ - Q_D(IrcMessage); - d->connection = connection; -} - -/*! - Destructs the message. - */ -IrcMessage::~IrcMessage() -{ -} - -/*! - This property holds the message connection. - - \par Access function: - \li \ref IrcConnection* <b>connection</b>() const - */ -IrcConnection* IrcMessage::connection() const -{ - Q_D(const IrcMessage); - return d->connection; -} - -/*! - This property holds the message network. - - \par Access function: - \li \ref IrcNetwork* <b>network</b>() const - */ -IrcNetwork* IrcMessage::network() const -{ - Q_D(const IrcMessage); - return d->connection ? d->connection->network() : 0; -} - -/*! - This property holds the message type. - - \par Access function: - \li \ref IrcMessage::Type <b>type</b>() const - */ -IrcMessage::Type IrcMessage::type() const -{ - Q_D(const IrcMessage); - return d->type; -} - -/*! - \since 3.2 - \property bool IrcMessage::own - - This property holds whether the message is user's own. - - This property is provided for convenience. It is equivalent - of testing for the IrcMessage::Own flag. - - \par Access function: - \li bool <b>isOwn</b>() const - */ -bool IrcMessage::isOwn() const -{ - return flags() & Own; -} - -/*! - This property holds the message flags. - - \par Access function: - \li \ref IrcMessage::Flag "IrcMessage::Flags" <b>flags</b>() const - \li void <b>setFlags</b>(\ref IrcMessage::Flag "IrcMessage::Flags" flags) (\b Since 3.2) - */ -IrcMessage::Flags IrcMessage::flags() const -{ - Q_D(const IrcMessage); - if (d->flags == -1) { - d->flags = IrcMessage::None; - if (d->connection) { - if (!d->prefix().isEmpty() && d->nick() == d->connection->nickName()) - d->flags |= IrcMessage::Own; - - if ((d->type == IrcMessage::Private || d->type == IrcMessage::Notice) && - network()->activeCapabilities().contains("identify-msg")) { - QString msg = property("content").toString(); - if (msg.startsWith("+")) - d->flags |= IrcMessage::Identified; - else if (msg.startsWith("-")) - d->flags |= IrcMessage::Unidentified; - } - } - } - return IrcMessage::Flags(d->flags); -} - -void IrcMessage::setFlags(IrcMessage::Flags flags) -{ - Q_D(IrcMessage); - d->flags = flags; -} - -/*! - This property holds the message command. - - \par Access functions: - \li QString <b>command</b>() const - \li void <b>setCommand</b>(const QString& command) - */ -QString IrcMessage::command() const -{ - Q_D(const IrcMessage); - return d->command(); -} - -void IrcMessage::setCommand(const QString& command) -{ - Q_D(IrcMessage); - d->setCommand(command); -} - -/*! - This property holds the message sender prefix. - - The prefix consists of \ref nick, \ref ident and \ref host as specified in RFC 1459: - <pre> - <prefix> ::= <\ref nick> [ '!' <\ref ident> ] [ '@' <\ref host> ] - </pre> - - \par Access functions: - \li QString <b>prefix</b>() const - \li void <b>setPrefix</b>(const QString& prefix) - */ -QString IrcMessage::prefix() const -{ - Q_D(const IrcMessage); - return d->prefix(); -} - -void IrcMessage::setPrefix(const QString& prefix) -{ - Q_D(IrcMessage); - d->setPrefix(prefix); -} - -/*! - This property holds the message sender nick. - - Nick is part of the sender \ref prefix as specified in RFC 1459: - <pre> - <b><nick></b> [ '!' <\ref ident> ] [ '@' <\ref host> ] - </pre> - - \par Access function: - \li QString <b>nick</b>() const - */ -QString IrcMessage::nick() const -{ - Q_D(const IrcMessage); - return d->nick(); -} - -/*! - This property holds the message sender ident. - - Ident is part of the sender \ref prefix as specified in RFC 1459: - <pre> - <\ref nick> [ '!' <b><ident></b> ] [ '@' <\ref host> ] - </pre> - - \par Access function: - \li QString <b>ident</b>() const - */ -QString IrcMessage::ident() const -{ - Q_D(const IrcMessage); - return d->ident(); -} - -/*! - This property holds the message sender host. - - Host is part of the sender \ref prefix as specified in RFC 1459: - <pre> - <\ref nick> [ '!' <\ref ident> ] [ '@' <b><host></b> ] - </pre> - - \par Access function: - \li QString <b>host</b>() const - */ -QString IrcMessage::host() const -{ - Q_D(const IrcMessage); - return d->host(); -} - -/*! - This property holds the message parameters. - - \par Access functions: - \li QStringList <b>parameters</b>() const - \li void <b>setParameters</b>(const QStringList& parameters) - */ -QStringList IrcMessage::parameters() const -{ - Q_D(const IrcMessage); - return d->params(); -} - -void IrcMessage::setParameters(const QStringList& parameters) -{ - Q_D(IrcMessage); - d->setParams(parameters); -} - -/*! - This property holds the message time stamp. - - \par Access functions: - \li QDateTime <b>timeStamp</b>() const - \li void <b>setTimeStamp</b>(const QDateTime& timeStamp) - */ -QDateTime IrcMessage::timeStamp() const -{ - Q_D(const IrcMessage); - return d->timeStamp; -} - -void IrcMessage::setTimeStamp(const QDateTime& timeStamp) -{ - Q_D(IrcMessage); - d->timeStamp = timeStamp; -} - -/*! - This property holds the FALLBACK encoding for the message. - - The fallback encoding is used when the message is detected not - to be valid UTF-8 and the consequent auto-detection of message - encoding fails. See QTextCodec::availableCodes() for the list of - supported encodings. - - The default value is ISO-8859-15. - - \par Access functions: - \li QByteArray <b>encoding</b>() const - \li void <b>setEncoding</b>(const QByteArray& encoding) - - \sa QTextCodec::availableCodecs(), QTextCodec::codecForLocale() - */ -QByteArray IrcMessage::encoding() const -{ - Q_D(const IrcMessage); - return d->encoding; -} - -void IrcMessage::setEncoding(const QByteArray& encoding) -{ - Q_D(IrcMessage); - extern bool irc_is_supported_encoding(const QByteArray& encoding); // ircmessagedecoder.cpp - if (!irc_is_supported_encoding(encoding)) { - qWarning() << "IrcMessage::setEncoding(): unsupported encoding" << encoding; - return; - } - d->encoding = encoding; - d->invalidate(); -} - -/*! - \since 3.1 - - This property holds the message tags. - - \par Access functions: - \li QVariantMap <b>tags</b>() const - \li void <b>setTags</b>(const QVariantMap& tags) - - \sa <a href="http://ircv3.org/specification/message-tags-3.2">IRCv3.2 Message Tags</a> - */ -QVariantMap IrcMessage::tags() const -{ - Q_D(const IrcMessage); - return d->tags(); -} - -void IrcMessage::setTags(const QVariantMap& tags) -{ - Q_D(IrcMessage); - d->setTags(tags); -} - -/*! - Creates a new message from \a data and \a connection. - */ -IrcMessage* IrcMessage::fromData(const QByteArray& data, IrcConnection* connection) -{ - IrcMessage* message = 0; - IrcMessageData md = IrcMessageData::fromData(data); - const QMetaObject* metaObject = irc_command_meta_object(md.command); - if (metaObject) { - message = qobject_cast<IrcMessage*>(metaObject->newInstance(Q_ARG(IrcConnection*, connection))); - Q_ASSERT(message); - message->d_ptr->data = md; - } - return message; -} - -/*! - Creates a new message from \a prefix, \a command and \a parameters with \a connection. - */ -IrcMessage* IrcMessage::fromParameters(const QString& prefix, const QString& command, const QStringList& parameters, IrcConnection* connection) -{ - IrcMessage* message = 0; - const QMetaObject* metaObject = irc_command_meta_object(command); - if (metaObject) { - message = qobject_cast<IrcMessage*>(metaObject->newInstance(Q_ARG(IrcConnection*, connection))); - Q_ASSERT(message); - message->setPrefix(prefix); - message->setCommand(command); - message->setParameters(parameters); - } - return message; -} - -/*! - \property bool IrcMessage::valid - This property is \c true if the message is valid; otherwise \c false. - - A message is considered valid if the prefix is not empty - and the parameters match the message. - - \par Access function: - \li bool <b>isValid</b>() const - */ -bool IrcMessage::isValid() const -{ - Q_D(const IrcMessage); - return d->connection && !prefix().isNull(); -} - -/*! - Returns the message as received from an IRC server. - */ -QByteArray IrcMessage::toData() const -{ - Q_D(const IrcMessage); - return d->content(); -} - -/*! - \class IrcCapabilityMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a capability message. - */ - -/*! - Constructs a new IrcCapabilityMessage with \a connection. - */ -IrcCapabilityMessage::IrcCapabilityMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Capability; -} - -/*! - This property holds the subcommand. - - The following capability subcommands are defined: - LS, LIST, REQ, ACK, NAK, CLEAR, END - - \par Access function: - \li QString <b>subCommand</b>() const - */ -QString IrcCapabilityMessage::subCommand() const -{ - Q_D(const IrcMessage); - return d->param(1); -} - -/*! - This property holds the capabilities. - - A list of capabilities may exist for the following - subcommands: LS, LIST, REQ, ACK and NAK. - - \par Access function: - \li QStringList <b>capabilities</b>() const - */ -QStringList IrcCapabilityMessage::capabilities() const -{ - Q_D(const IrcMessage); - QStringList caps; - QStringList params = d->params(); - if (params.count() > 2) - caps = params.last().split(QLatin1Char(' '), QString::SkipEmptyParts); - return caps; -} - -bool IrcCapabilityMessage::isValid() const -{ - return IrcMessage::isValid(); -} - -/*! - \class IrcErrorMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents an error message. - */ - -/*! - Constructs a new IrcErrorMessage with \a connection. - */ -IrcErrorMessage::IrcErrorMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Error; -} - -/*! - This property holds the error. - - \par Access function: - \li QString <b>error</b>() const - */ -QString IrcErrorMessage::error() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -bool IrcErrorMessage::isValid() const -{ - return IrcMessage::isValid() && !error().isEmpty(); -} - -/*! - \class IrcInviteMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents an invite message. - */ - -/*! - Constructs a new IrcInviteMessage with \a connection. - */ -IrcInviteMessage::IrcInviteMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Invite; -} - -/*! - This property holds the user in question. - - \par Access function: - \li QString <b>user</b>() const - */ -QString IrcInviteMessage::user() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -/*! - This property holds the channel in question. - - \par Access function: - \li QString <b>channel</b>() const - */ -QString IrcInviteMessage::channel() const -{ - Q_D(const IrcMessage); - return d->param(1); -} - -bool IrcInviteMessage::isValid() const -{ - return IrcMessage::isValid() && !user().isEmpty() && !channel().isEmpty(); -} - -/*! - \class IrcJoinMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a join message. - */ - -/*! - Constructs a new IrcJoinMessage with \a connection. - */ -IrcJoinMessage::IrcJoinMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Join; -} - -/*! - This property holds the channel in question. - - \par Access function: - \li QString <b>channel</b>() const - */ -QString IrcJoinMessage::channel() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -bool IrcJoinMessage::isValid() const -{ - return IrcMessage::isValid() && !channel().isEmpty(); -} - -/*! - \class IrcKickMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a kick message. - */ - -/*! - Constructs a new IrcKickMessage with \a connection. - */ -IrcKickMessage::IrcKickMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Kick; -} - -/*! - This property holds the channel in question. - - \par Access function: - \li QString <b>channel</b>() const - */ -QString IrcKickMessage::channel() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -/*! - This property holds the user in question. - - \par Access function: - \li QString <b>user</b>() const - */ -QString IrcKickMessage::user() const -{ - Q_D(const IrcMessage); - return d->param(1); -} - -/*! - This property holds the optional kick reason. - - \par Access function: - \li QString <b>reason</b>() const - */ -QString IrcKickMessage::reason() const -{ - Q_D(const IrcMessage); - return d->param(2); -} - -bool IrcKickMessage::isValid() const -{ - return IrcMessage::isValid() && !channel().isEmpty() && !user().isEmpty(); -} - -/*! - \class IrcModeMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a mode message. - */ - -/*! - \enum IrcModeMessage::Kind - This enum describes the kind of modes. - */ - -/*! - \var IrcModeMessage::Channel - \brief Channel mode - */ - -/*! - \var IrcModeMessage::User - \brief User mode - */ - -/*! - Constructs a new IrcModeMessage with \a connection. - */ -IrcModeMessage::IrcModeMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Mode; -} - -/*! - This property holds the target channel or user in question. - - \par Access function: - \li QString <b>target</b>() const - */ -QString IrcModeMessage::target() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -/*! - This property holds the channel or user mode. - - \par Access function: - \li QString <b>mode</b>() const - */ -QString IrcModeMessage::mode() const -{ - Q_D(const IrcMessage); - return d->param(1); -} - -/*! - This property holds the first mode argument. - - \par Access function: - \li QString <b>argument</b>() const - */ -QString IrcModeMessage::argument() const -{ - Q_D(const IrcMessage); - return d->param(2); -} - -/*! - \since 3.1 - - This property holds the all mode arguments. - - \par Access function: - \li QStringList <b>arguments</b>() const - */ -QStringList IrcModeMessage::arguments() const -{ - Q_D(const IrcMessage); - return d->params().mid(2); -} - -/*! - This property holds whether the message is a reply. - - Mode messages are sent when a mode changes (\c false) - and when joining a channel (\c true). - - \par Access function: - \li bool <b>isReply</b>() const - - \sa Irc::RPL_CHANNELMODEIS - */ -bool IrcModeMessage::isReply() const -{ - Q_D(const IrcMessage); - int rpl = d->command().toInt(); - return rpl == Irc::RPL_CHANNELMODEIS; -} - -/*! - This property holds the kind of the mode. - - \par Access function: - \li Kind <b>kind</b>() const - */ -IrcModeMessage::Kind IrcModeMessage::kind() const -{ - Q_D(const IrcMessage); - const IrcNetwork* network = d->connection->network(); - const QStringList channelModes = network->channelModes(IrcNetwork::AllTypes); - const QString m = mode().remove(QLatin1Char('+')).remove(QLatin1Char('-')); - for (int i = 0; i < m.length(); ++i) { - if (!channelModes.contains(m.at(i))) - return User; - } - return Channel; -} - -bool IrcModeMessage::isValid() const -{ - return IrcMessage::isValid() && !target().isEmpty() && !mode().isEmpty(); -} - -/*! - \class IrcMotdMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a message of the day. - */ - -/*! - Constructs a new IrcMotdMessage with \a connection. - */ -IrcMotdMessage::IrcMotdMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Motd; - setCommand(QLatin1String("MOTD")); -} - -/*! - This property holds the message of the day lines. - - \par Access function: - \li QStringList <b>lines</b>() const - */ -QStringList IrcMotdMessage::lines() const -{ - Q_D(const IrcMessage); - return d->params().mid(1); -} - -bool IrcMotdMessage::isValid() const -{ - Q_D(const IrcMessage); - return IrcMessage::isValid() && !d->params().isEmpty(); -} - -/*! - \class IrcNamesMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a names list message. - */ - -/*! - Constructs a new IrcNamesMessage with \a connection. - */ -IrcNamesMessage::IrcNamesMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Names; - setCommand(QLatin1String("NAMES")); -} - -/*! - This property holds the channel. - - \par Access function: - \li QString <b>channel</b>() const - */ -QString IrcNamesMessage::channel() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -/*! - This property holds the list of names. - - \par Access function: - \li QStringList <b>names</b>() const - */ -QStringList IrcNamesMessage::names() const -{ - Q_D(const IrcMessage); - return d->params().mid(1); -} - -bool IrcNamesMessage::isValid() const -{ - Q_D(const IrcMessage); - return IrcMessage::isValid() && !d->params().isEmpty(); -} - -/*! - \class IrcNickMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a nick message. - */ - -/*! - Constructs a new IrcNickMessage with \a connection. - */ -IrcNickMessage::IrcNickMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Nick; -} - -/*! - This property holds the old nick. - - This property is provided for symmetry with \ref newNick - and is equal to \ref nick. - - \par Access function: - \li QString <b>oldNick</b>() const - */ -QString IrcNickMessage::oldNick() const -{ - Q_D(const IrcMessage); - return d->nick(); -} - -/*! - This property holds the new nick. - - \par Access function: - \li QString <b>newNick</b>() const - */ -QString IrcNickMessage::newNick() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -bool IrcNickMessage::isValid() const -{ - return IrcMessage::isValid() && !newNick().isEmpty(); -} - -/*! - \class IrcNoticeMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a notice message. - */ - -/*! - Constructs a new IrcNoticeMessage with \a connection. - */ -IrcNoticeMessage::IrcNoticeMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Notice; -} - -/*! - This property holds the target channel or user in question. - - \par Access function: - \li QString <b>target</b>() const - */ -QString IrcNoticeMessage::target() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -/*! - This property holds the message content. - - \par Access function: - \li QString <b>content</b>() const - */ -QString IrcNoticeMessage::content() const -{ - Q_D(const IrcMessage); - QString msg = d->param(1); - if (flags() & (Identified | Unidentified)) - msg.remove(0, 1); - if (isReply()) { - msg.remove(0, 1); - msg.chop(1); - } - return msg; -} - -/*! - \property bool IrcNoticeMessage::private - This property is \c true if the notice is private, - or \c false if it is a channel notice. - - \par Access function: - \li bool <b>isPrivate</b>() const - */ -bool IrcNoticeMessage::isPrivate() const -{ - Q_D(const IrcMessage); - if (d->connection) - return !target().compare(d->connection->nickName(), Qt::CaseInsensitive); - return false; -} - -/*! - \property bool IrcNoticeMessage::reply - This property is \c true if the message is a reply; otherwise \c false. - - \par Access function: - \li bool <b>isReply</b>() const - */ -bool IrcNoticeMessage::isReply() const -{ - Q_D(const IrcMessage); - QString msg = d->param(1); - return msg.startsWith('\1') && msg.endsWith('\1'); -} - -bool IrcNoticeMessage::isValid() const -{ - return IrcMessage::isValid() && !target().isEmpty() && !content().isEmpty(); -} - -/*! - \class IrcNumericMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a numeric message. - */ - -/*! - Constructs a new IrcNumericMessage with \a connection. - */ -IrcNumericMessage::IrcNumericMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Numeric; -} - -/*! - This property holds the numeric code. - - \par Access function: - \li int <b>code</b>() const - */ -int IrcNumericMessage::code() const -{ - Q_D(const IrcMessage); - bool ok = false; - int number = d->command().toInt(&ok); - return ok ? number : -1; -} - -bool IrcNumericMessage::isValid() const -{ - return IrcMessage::isValid() && code() != -1; -} - -/*! - \class IrcPartMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a part message. - */ - -/*! - Constructs a new IrcPartMessage with \a connection. - */ -IrcPartMessage::IrcPartMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Part; -} - -/*! - This property holds the channel in question. - - \par Access function: - \li QString <b>channel</b>() const - */ -QString IrcPartMessage::channel() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -/*! - This property holds the optional part reason. - - \par Access function: - \li QString <b>reason</b>() const - */ -QString IrcPartMessage::reason() const -{ - Q_D(const IrcMessage); - return d->param(1); -} - -bool IrcPartMessage::isValid() const -{ - return IrcMessage::isValid() && !channel().isEmpty(); -} - -/*! - \class IrcPingMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a ping message. - */ - -/*! - Constructs a new IrcPingMessage with \a connection. - */ -IrcPingMessage::IrcPingMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Ping; -} - -/*! - This property holds the optional message argument. - - \par Access function: - \li QString <b>argument</b>() const - */ -QString IrcPingMessage::argument() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -bool IrcPingMessage::isValid() const -{ - return IrcMessage::isValid(); -} - -/*! - \class IrcPongMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a pong message. - */ - -/*! - Constructs a new IrcPongMessage with \a connection. - */ -IrcPongMessage::IrcPongMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Pong; -} - -/*! - This property holds the optional message argument. - - \par Access function: - \li QString <b>argument</b>() const - */ -QString IrcPongMessage::argument() const -{ - Q_D(const IrcMessage); - return d->param(1); -} - -bool IrcPongMessage::isValid() const -{ - return IrcMessage::isValid(); -} - -/*! - \class IrcPrivateMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a private message. - */ - -/*! - Constructs a new IrcPrivateMessage with \a connection. - */ -IrcPrivateMessage::IrcPrivateMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Private; -} - -/*! - This property holds the target channel or user in question. - - \par Access function: - \li QString <b>target</b>() const - */ -QString IrcPrivateMessage::target() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -/*! - This property holds the message content. - - \par Access function: - \li QString <b>content</b>() const - */ -QString IrcPrivateMessage::content() const -{ - Q_D(const IrcMessage); - QString msg = d->param(1); - if (flags() & (Identified | Unidentified)) - msg.remove(0, 1); - const bool act = isAction(); - const bool req = isRequest(); - if (act) msg.remove(0, 8); - if (req) msg.remove(0, 1); - if (act || req) msg.chop(1); - return msg; -} - -/*! - \property bool IrcPrivateMessage::private - This property is \c true if the message is private, - or \c false if it is a channel message. - - \par Access function: - \li bool <b>isPrivate</b>() const - */ -bool IrcPrivateMessage::isPrivate() const -{ - Q_D(const IrcMessage); - if (d->connection) - return !target().compare(d->connection->nickName(), Qt::CaseInsensitive); - return false; -} - -/*! - \property bool IrcPrivateMessage::action - This property is \c true if the message is an action; otherwise \c false. - - \par Access function: - \li bool <b>isAction</b>() const - */ -bool IrcPrivateMessage::isAction() const -{ - Q_D(const IrcMessage); - QString msg = d->param(1); - if (flags() & (Identified | Unidentified)) - msg.remove(0, 1); - return msg.startsWith("\1ACTION ") && msg.endsWith('\1'); -} - -/*! - \property bool IrcPrivateMessage::request - This property is \c true if the message is a request; otherwise \c false. - - \par Access function: - \li bool <b>isRequest</b>() const - */ -bool IrcPrivateMessage::isRequest() const -{ - Q_D(const IrcMessage); - QString msg = d->param(1); - if (flags() & (Identified | Unidentified)) - msg.remove(0, 1); - return msg.startsWith('\1') && msg.endsWith('\1') && !isAction(); -} - -bool IrcPrivateMessage::isValid() const -{ - return IrcMessage::isValid() && !target().isEmpty() && !content().isEmpty(); -} - -/*! - \class IrcQuitMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a quit message. - */ - -/*! - Constructs a new IrcQuitMessage with \a connection. - */ -IrcQuitMessage::IrcQuitMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Quit; -} - -/*! - This property holds the optional quit reason. - - \par Access function: - \li QString <b>reason</b>() const - */ -QString IrcQuitMessage::reason() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -bool IrcQuitMessage::isValid() const -{ - return IrcMessage::isValid(); -} - -/*! - \class IrcTopicMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a topic message. - */ - -/*! - Constructs a new IrcTopicMessage with \a connection. - */ -IrcTopicMessage::IrcTopicMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = Topic; -} - -/*! - This property holds the channel in question. - - \par Access function: - \li QString <b>channel</b>() const - */ -QString IrcTopicMessage::channel() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -/*! - This property holds the new channel topic. - - \par Access function: - \li QString <b>topic</b>() const - */ -QString IrcTopicMessage::topic() const -{ - Q_D(const IrcMessage); - return d->param(1); -} - -/*! - This property holds whether the message is a reply. - - Topic messages are sent in three situations: - \li as a notification of a topic change (\c false), - \li as a reply when joining a channel (\c true), or - \li as a reply when explicitly querying the channel topic (\c true). - - \par Access function: - \li bool <b>isReply</b>() const - - \sa Irc::RPL_TOPIC, Irc::RPL_NOTOPIC, IrcTopicCommand - */ -bool IrcTopicMessage::isReply() const -{ - Q_D(const IrcMessage); - int rpl = d->command().toInt(); - return rpl == Irc::RPL_TOPIC || rpl == Irc::RPL_NOTOPIC; -} - -bool IrcTopicMessage::isValid() const -{ - return IrcMessage::isValid() && !channel().isEmpty(); -} - -/*! - \since 3.1 - \class IrcWhoReplyMessage ircmessage.h <IrcMessage> - \ingroup message - \brief Represents a reply message to a WHO command. - */ - -/*! - Constructs a new IrcWhoReplyMessage with \a connection. - */ -IrcWhoReplyMessage::IrcWhoReplyMessage(IrcConnection* connection) : IrcMessage(connection) -{ - Q_D(IrcMessage); - d->type = WhoReply; -} - -/*! - This property holds the mask. - - \par Access function: - \li QString <b>mask</b>() const - */ -QString IrcWhoReplyMessage::mask() const -{ - Q_D(const IrcMessage); - return d->param(0); -} - -/*! - This property holds the server of the user. - - \par Access function: - \li QString <b>server</b>() const - */ -QString IrcWhoReplyMessage::server() const -{ - Q_D(const IrcMessage); - return d->param(1); -} - -/*! - \property bool IrcWhoReplyMessage::away - This property holds whether the user is away. - - \par Access function: - \li QString <b>isAway</b>() const - */ -bool IrcWhoReplyMessage::isAway() const -{ - Q_D(const IrcMessage); - return d->param(2).contains("G"); -} - -/*! - \property bool IrcWhoReplyMessage::servOp - This property holds whether the user is a server operator. - - \par Access function: - \li QString <b>isServOp</b>() const - */ -bool IrcWhoReplyMessage::isServOp() const -{ - Q_D(const IrcMessage); - return d->param(2).contains("*"); -} - -/*! - This property holds the real name of the user. - - \par Access function: - \li QString <b>realName</b>() const - */ -QString IrcWhoReplyMessage::realName() const -{ - Q_D(const IrcMessage); - return d->param(3); -} - -bool IrcWhoReplyMessage::isValid() const -{ - return IrcMessage::isValid() && !mask().isEmpty() && !nick().isEmpty(); -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug debug, IrcMessage::Type type) -{ - const int index = IrcMessage::staticMetaObject.indexOfEnumerator("Type"); - QMetaEnum enumerator = IrcMessage::staticMetaObject.enumerator(index); - const char* key = enumerator.valueToKey(type); - debug << (key ? key : "Unknown"); - return debug; -} - -QDebug operator<<(QDebug debug, IrcMessage::Flag flag) -{ - const int index = IrcMessage::staticMetaObject.indexOfEnumerator("Flag"); - QMetaEnum enumerator = IrcMessage::staticMetaObject.enumerator(index); - const char* key = enumerator.valueToKey(flag); - debug << (key ? key : "None"); - return debug; -} - -QDebug operator<<(QDebug debug, IrcMessage::Flags flags) -{ - QStringList lst; - if (flags == IrcMessage::None) - lst << "None"; - if (flags & IrcMessage::Own) - lst << "Own"; - if (flags & IrcMessage::Identified) - lst << "Identified"; - if (flags & IrcMessage::Unidentified) - lst << "Unidentified"; - debug.nospace() << '(' << qPrintable(lst.join("|")) << ')'; - return debug; -} - -QDebug operator<<(QDebug debug, IrcModeMessage::Kind kind) -{ - const int index = IrcModeMessage::staticMetaObject.indexOfEnumerator("Kind"); - QMetaEnum enumerator = IrcModeMessage::staticMetaObject.enumerator(index); - const char* key = enumerator.valueToKey(kind); - debug << (key ? key : "Unknown"); - return debug; -} - -QDebug operator<<(QDebug debug, const IrcMessage* message) -{ - if (!message) - return debug << "IrcMessage(0x0) "; - debug.nospace() << message->metaObject()->className() << '(' << (void*) message; - if (!message->objectName().isEmpty()) - debug.nospace() << ", name=" << qPrintable(message->objectName()); - debug.nospace() << ", flags=" << message->flags(); - if (!message->prefix().isEmpty()) - debug.nospace() << ", prefix=" << qPrintable(message->prefix()); - if (!message->command().isEmpty()) - debug.nospace() << ", command=" << qPrintable(message->command()); - debug.nospace() << ')'; - return debug.space(); -} -#endif // QT_NO_DEBUG_STREAM - -#include "moc_ircmessage.cpp" - -IRC_END_NAMESPACE diff --git a/libcommuni/src/core/ircmessage_p.cpp b/libcommuni/src/core/ircmessage_p.cpp deleted file mode 100644 index e5fdd24..0000000 --- a/libcommuni/src/core/ircmessage_p.cpp +++ /dev/null @@ -1,284 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "ircmessage_p.h" -#include "ircmessagedecoder_p.h" - -IRC_BEGIN_NAMESPACE - -#ifndef IRC_DOXYGEN -IrcMessagePrivate::IrcMessagePrivate() : - connection(0), type(IrcMessage::Unknown), timeStamp(QDateTime::currentDateTime()), encoding("ISO-8859-15"), flags(-1) -{ -} - -QString IrcMessagePrivate::prefix() const -{ - if (!m_prefix.isExplicit() && m_prefix.isNull() && !data.prefix.isNull()) { - if (data.prefix.startsWith(':')) { - if (data.prefix.length() > 1) - m_prefix = decode(data.prefix.mid(1), encoding); - } else { - // empty (not null) - m_prefix = QString(""); - } - } - return m_prefix.value(); -} - -void IrcMessagePrivate::setPrefix(const QString& prefix) -{ - m_prefix.setValue(prefix); - m_nick.clear(); - m_ident.clear(); - m_host.clear(); -} - -QString IrcMessagePrivate::nick() const -{ - if (m_nick.isNull()) - parsePrefix(prefix(), &m_nick, &m_ident, &m_host); - return m_nick; -} - -QString IrcMessagePrivate::ident() const -{ - if (m_ident.isNull()) - parsePrefix(prefix(), &m_nick, &m_ident, &m_host); - return m_ident; -} - -QString IrcMessagePrivate::host() const -{ - if (m_host.isNull()) - parsePrefix(prefix(), &m_nick, &m_ident, &m_host); - return m_host; -} - -QString IrcMessagePrivate::command() const -{ - if (!m_command.isExplicit() && m_command.isNull() && !data.command.isNull()) - m_command = decode(data.command, encoding); - return m_command.value(); -} - -void IrcMessagePrivate::setCommand(const QString& command) -{ - m_command.setValue(command); -} - -QStringList IrcMessagePrivate::params() const -{ - if (!m_params.isExplicit() && m_params.isNull() && !data.params.isEmpty()) { - QStringList params; - foreach (const QByteArray& param, data.params) - params += decode(param, encoding); - m_params = params; - } - return m_params.value(); -} - -QString IrcMessagePrivate::param(int index) const -{ - return params().value(index); -} - -void IrcMessagePrivate::setParams(const QStringList& params) -{ - m_params.setValue(params); -} - -QVariantMap IrcMessagePrivate::tags() const -{ - if (!m_tags.isExplicit() && m_tags.isNull() && !data.tags.isEmpty()) { - QVariantMap tags; - QMap<QByteArray, QByteArray>::const_iterator it; - for (it = data.tags.constBegin(); it != data.tags.constEnd(); ++it) - tags.insert(decode(it.key(), encoding), decode(it.value(), encoding)); - m_tags = tags; - } - return m_tags.value(); -} - -void IrcMessagePrivate::setTags(const QVariantMap& tags) -{ - m_tags.setValue(tags); -} - -QByteArray IrcMessagePrivate::content() const -{ - if (m_prefix.isExplicit() || m_command.isExplicit() || m_params.isExplicit() || m_tags.isExplicit()) { - QByteArray data; - - // format <tags> - QStringList tt; - const QVariantMap t = tags(); - for (QVariantMap::const_iterator it = t.begin(); it != t.end(); ++it) - tt += it.key() + QLatin1Char('=') + it.value().toString(); - if (!tt.isEmpty()) - data += '@' + tt.join(QLatin1String(";")).toUtf8() + ' '; - - // format <prefix> - const QString p = prefix(); - if (!p.isEmpty()) - data += ':' + p.toUtf8() + ' '; - - // format <command> - data += command().toUtf8(); - - // format <params> - foreach (const QString& param, params()) { - data += ' '; - if (param.contains(QLatin1Char(' '))) - data += ':'; - data += param.toUtf8(); - } - return data; - } - - return data.content; -} - -void IrcMessagePrivate::invalidate() -{ - m_nick.clear(); - m_ident.clear(); - m_host.clear(); - - m_prefix.clear(); - m_command.clear(); - m_params.clear(); - m_tags.clear(); -} - -IrcMessageData IrcMessageData::fromData(const QByteArray& data) -{ - IrcMessageData message; - message.content = data; - - // From RFC 1459: - // <message> ::= [':' <prefix> <SPACE> ] <command> <params> <crlf> - // <prefix> ::= <servername> | <nick> [ '!' <user> ] [ '@' <host> ] - // <command> ::= <letter> { <letter> } | <number> <number> <number> - // <SPACE> ::= ' ' { ' ' } - // <params> ::= <SPACE> [ ':' <trailing> | <middle> <params> ] - // <middle> ::= <Any *non-empty* sequence of octets not including SPACE - // or NUL or CR or LF, the first of which may not be ':'> - // <trailing> ::= <Any, possibly *empty*, sequence of octets not including - // NUL or CR or LF> - - // IRCv3.2 Message Tags - // <message> ::= ['@' <tags> <SPACE>] [':' <prefix> <SPACE> ] <command> <params> <crlf> - // <tags> ::= <tag> [';' <tag>]* - // <tag> ::= <key> ['=' <value>] - // <key> ::= [ <vendor> '/' ] <sequence of letters, digits, hyphens (`-`)> - // <value> ::= <sequence of any characters except NUL, BELL, CR, LF, semicolon (`;`) and SPACE> - // <vendor> ::= <host> - - QByteArray process = data; - - // parse <tags> - if (process.startsWith('@')) { - process.remove(0, 1); - QByteArray tags = process.left(process.indexOf(' ')); - foreach (const QByteArray& tag, tags.split(';')) { - const int idx = tag.indexOf('='); - if (idx != -1) - message.tags.insert(tag.left(idx), tag.mid(idx + 1)); - else - message.tags.insert(tag, QByteArray()); - } - process.remove(0, tags.length() + 1); - } - - // parse <prefix> - if (process.startsWith(':')) { - message.prefix = process.left(process.indexOf(' ')); - process.remove(0, message.prefix.length() + 1); - } else { - // empty (not null) - message.prefix = QByteArray(""); - } - - // parse <command> - message.command = process.mid(0, process.indexOf(' ')); - process.remove(0, message.command.length() + 1); - - // parse <params> - while (!process.isEmpty()) { - if (process.startsWith(':')) { - process.remove(0, 1); - message.params += process; - process.clear(); - } else { - QByteArray param = process.mid(0, process.indexOf(' ')); - process.remove(0, param.length() + 1); - message.params += param; - } - } - - return message; -} - -QString IrcMessagePrivate::decode(const QByteArray& data, const QByteArray& encoding) -{ - // TODO: not thread safe - static IrcMessageDecoder decoder; - return decoder.decode(data, encoding); -} - -bool IrcMessagePrivate::parsePrefix(const QString& prefix, QString* nick, QString* ident, QString* host) -{ - const QString trimmed = prefix.trimmed(); - if (trimmed.contains(QLatin1Char(' '))) - return false; - - const int len = trimmed.length(); - const int ex = trimmed.indexOf(QLatin1Char('!')); - const int at = trimmed.indexOf(QLatin1Char('@')); - - if (ex == -1 && at == -1) { - if (nick) *nick = trimmed; - } else if (ex > 0 && at > 0 && ex + 1 < at && at < len - 1) { - if (nick) *nick = trimmed.mid(0, ex); - if (ident) *ident = trimmed.mid(ex + 1, at - ex - 1); - if (host) *host = trimmed.mid(at + 1); - } else if (ex > 0 && ex < len - 1 && at == -1) { - if (nick) *nick = trimmed.mid(0, ex); - if (ident) *ident = trimmed.mid(ex + 1); - } else if (at > 0 && at < len - 1 && ex == -1) { - if (nick) *nick = trimmed.mid(0, at); - if (host) *host = trimmed.mid(at + 1); - } else { - return false; - } - return true; -} -#endif // IRC_DOXYGEN - -IRC_END_NAMESPACE diff --git a/libcommuni/src/core/ircmessagebuilder.cpp b/libcommuni/src/core/ircmessagebuilder.cpp deleted file mode 100644 index 298ac79..0000000 --- a/libcommuni/src/core/ircmessagebuilder.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "ircmessagebuilder_p.h" -#include "ircmessage.h" -#include "irc.h" - -IRC_BEGIN_NAMESPACE - -#ifndef IRC_DOXYGEN -IrcMessageBuilder::IrcMessageBuilder(IrcConnection* connection) -{ - d.connection = connection; - d.message = 0; -} - -void IrcMessageBuilder::processMessage(IrcNumericMessage* message) -{ - switch (message->code()) { - case Irc::RPL_MOTDSTART: - d.message = new IrcMotdMessage(d.connection); - d.message->setPrefix(message->prefix()); - d.message->setParameters(QStringList(message->parameters().value(0))); - break; - case Irc::RPL_MOTD: - d.message->setParameters(d.message->parameters() << message->parameters().value(1)); - break; - case Irc::RPL_ENDOFMOTD: - d.message->setTimeStamp(message->timeStamp()); - emit messageReceived(d.message); - d.message = 0; - break; - - case Irc::RPL_NAMREPLY: { - if (!d.message) - d.message = new IrcNamesMessage(d.connection); - d.message->setPrefix(message->prefix()); - int count = message->parameters().count(); - QString channel = message->parameters().value(count - 2); - QStringList names = d.message->parameters().mid(1); - names += message->parameters().value(count - 1).split(QLatin1Char(' '), QString::SkipEmptyParts); - d.message->setParameters(QStringList() << channel << names); - break; - } - case Irc::RPL_ENDOFNAMES: - d.message->setTimeStamp(message->timeStamp()); - emit messageReceived(d.message); - d.message = 0; - break; - - case Irc::RPL_TOPIC: - case Irc::RPL_NOTOPIC: - d.message = new IrcTopicMessage(d.connection); - d.message->setPrefix(message->prefix()); - d.message->setTimeStamp(message->timeStamp()); - d.message->setCommand(QString::number(message->code())); - d.message->setParameters(QStringList() << message->parameters().value(1) << message->parameters().value(2)); - emit messageReceived(d.message); - d.message = 0; - break; - - case Irc::RPL_WHOREPLY: { - d.message = new IrcWhoReplyMessage(d.connection); - d.message->setPrefix(message->parameters().value(5) // nick - + QLatin1Char('!') + message->parameters().value(2) // ident - + QLatin1Char('@') + message->parameters().value(3)); // host - d.message->setTimeStamp(message->timeStamp()); - d.message->setCommand(QString::number(message->code())); - d.message->setParameters(QStringList() << message->parameters().value(1) // mask - << message->parameters().value(4) // server - << message->parameters().value(6)); // status - QString last = message->parameters().value(7); - int index = last.indexOf(QLatin1Char(' ')); // ignore hopcount - if (index != -1) - d.message->setParameters(d.message->parameters() << last.mid(index + 1)); // real name - emit messageReceived(d.message); - d.message = 0; - break; - } - - case Irc::RPL_CHANNELMODEIS: - d.message = new IrcModeMessage(d.connection); - d.message->setPrefix(message->prefix()); - d.message->setTimeStamp(message->timeStamp()); - d.message->setCommand(QString::number(message->code())); - d.message->setParameters(message->parameters().mid(1)); - emit messageReceived(d.message); - d.message = 0; - break; - } -} -#endif // IRC_DOXYGEN - -#include "moc_ircmessagebuilder_p.cpp" - -IRC_END_NAMESPACE diff --git a/libcommuni/src/core/ircmessagedecoder.cpp b/libcommuni/src/core/ircmessagedecoder.cpp deleted file mode 100644 index 1e2eb25..0000000 --- a/libcommuni/src/core/ircmessagedecoder.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "ircmessagedecoder_p.h" -#include <IrcGlobal> -#include <QSet> - -#ifndef IRC_DOXYGEN -extern "C" { - int IsUTF8Text(const char* utf8, int len); -} - -IRC_BEGIN_NAMESPACE - -IRC_CORE_EXPORT bool irc_is_supported_encoding(const QByteArray& encoding) -{ - static QSet<QByteArray> codecs = QTextCodec::availableCodecs().toSet(); - return codecs.contains(encoding); -} - -IrcMessageDecoder::IrcMessageDecoder() -{ - initialize(); -} - -IrcMessageDecoder::~IrcMessageDecoder() -{ - uninitialize(); -} - -QString IrcMessageDecoder::decode(const QByteArray& data, const QByteArray& encoding) const -{ - QTextCodec* codec = 0; - if (IsUTF8Text(data, data.length())) { - codec = QTextCodec::codecForName("UTF-8"); - } else { - QByteArray name = codecForData(data); - codec = QTextCodec::codecForName(name); - } - - if (!codec) - codec = QTextCodec::codecForName(encoding); - Q_ASSERT(codec); - return codec->toUnicode(data); -} -#endif // IRC_DOXYGEN - -IRC_END_NAMESPACE diff --git a/libcommuni/src/core/ircmessagedecoder_icu.cpp b/libcommuni/src/core/ircmessagedecoder_icu.cpp deleted file mode 100644 index 2c303fc..0000000 --- a/libcommuni/src/core/ircmessagedecoder_icu.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "ircmessagedecoder_p.h" -#include <unicode/ucsdet.h> - -IRC_BEGIN_NAMESPACE - -#ifndef IRC_DOXYGEN -#define UCSD(x) reinterpret_cast<UCharsetDetector*>(x) - -void IrcMessageDecoder::initialize() -{ - UErrorCode status = U_ZERO_ERROR; - d.detector = ucsdet_open(&status); - if (U_FAILURE(status)) - qWarning("IrcMessageDecoder: ICU initialization failed: %s", u_errorName(status)); -} - -void IrcMessageDecoder::uninitialize() -{ - ucsdet_close(UCSD(d.detector)); -} - -QByteArray IrcMessageDecoder::codecForData(const QByteArray &data) const -{ - QByteArray encoding; - UErrorCode status = U_ZERO_ERROR; - if (d.detector) { - ucsdet_setText(UCSD(d.detector), data.constData(), data.length(), &status); - if (!U_FAILURE(status)) { - const UCharsetMatch* match = ucsdet_detect(UCSD(d.detector), &status); - if (match && !U_FAILURE(status)) - encoding = ucsdet_getName(match, &status); - } - } - if (U_FAILURE(status)) - qWarning("IrcMessageDecoder::codecForData() failed: %s", u_errorName(status)); - return encoding; -} -#endif // IRC_DOXYGEN - -IRC_END_NAMESPACE diff --git a/libcommuni/src/core/ircmessagedecoder_uchardet.cpp b/libcommuni/src/core/ircmessagedecoder_uchardet.cpp deleted file mode 100644 index 8f0be8b..0000000 --- a/libcommuni/src/core/ircmessagedecoder_uchardet.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "ircmessagedecoder_p.h" -#include "uchardet.h" - -IRC_BEGIN_NAMESPACE - -#ifndef IRC_DOXYGEN -#define UCD(x) reinterpret_cast<uchardet_t>(x) - -void IrcMessageDecoder::initialize() -{ - d.detector = uchardet_new(); -} - -void IrcMessageDecoder::uninitialize() -{ - uchardet_delete(UCD(d.detector)); -} - -QByteArray IrcMessageDecoder::codecForData(const QByteArray &data) const -{ - uchardet_reset(UCD(d.detector)); - uchardet_handle_data(UCD(d.detector), data.constData(), data.length()); - uchardet_data_end(UCD(d.detector)); - return uchardet_get_charset(UCD(d.detector)); -} -#endif // IRC_DOXYGEN - -IRC_END_NAMESPACE diff --git a/libcommuni/src/core/ircnetwork.cpp b/libcommuni/src/core/ircnetwork.cpp deleted file mode 100644 index d73a9be..0000000 --- a/libcommuni/src/core/ircnetwork.cpp +++ /dev/null @@ -1,687 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "ircnetwork.h" -#include "ircnetwork_p.h" -#include "ircconnection_p.h" -#include "ircprotocol.h" -#include "ircconnection.h" -#include "irccommand.h" -#include <QMetaEnum> -#include <QPointer> - -IRC_BEGIN_NAMESPACE - -/*! - \file ircnetwork.h - \brief \#include <IrcNetwork> - */ - -/*! - \class IrcNetwork ircnetwork.h IrcNetwork - \ingroup core - \brief Provides network information and capability management. - - \section info Network information - - IrcNetwork provides various information about the IRC network of a - \ref IrcConnection::network "connection". This includes the \ref name - "network name", supported \ref channelTypes "channel types", channel - user \ref modes "mode characters" and \ref prefixes "prefix letters", - and various \ref numericLimit "numeric limitations", such as the maximum - nick, channel, topic and message lengths. - - Furthermore, IrcNetwork provides convenient methods for converting channel user - \ref modeToPrefix() "modes to prefixes" and \ref prefixToMode() "vice versa" and - testing whether a target name \ref isChannel() "is a channel". - - \note Most properties have empty values until the network - information has been \ref initialized. - - \section capabilities Capability management - - IrcNetwork also provides means for capability management. It maintais a - list of \ref availableCapabilities "available" and \ref activeCapabilities - "active" capabilities, automatically \ref requestedCapabilities "requests" - desired capabilities, and provides convenient methods for \ref requestCapability() - "manual capability requests". - - \sa IrcConnection::network - */ - -/*! - \fn void IrcNetwork::requestingCapabilities() - - This signal is emitted when capabilities are being requested. - - Normally it is enough to add the desired capabilities to the - list of \ref requestedCapabilities "requested capabilities". - Connect to this signal in order to implement more advanced - capability handling eg. based on which capabilities are \ref - availableCapabilities "available". - - \sa requestedCapabilities, availableCapabilities - */ - -/*! - \enum IrcNetwork::ModeType - This enum describes the channel mode types. - */ - -/*! - \var IrcNetwork::TypeA - \brief Type A modes - - Modes that add or remove an address to or from a list. - These modes always take a parameter when sent by the server to a - client; when sent by a client, they may be specified without a - parameter, which requests the server to display the current - contents of the corresponding list on the channel to the client. - */ - -/*! - \var IrcNetwork::TypeB - \brief Type B modes - - Modes that change a setting on the channel. These modes - always take a parameter. - */ - -/*! - \var IrcNetwork::TypeC - \brief Type C modes - - Modes that change a setting on the channel. These modes - take a parameter only when set; the parameter is absent when the - mode is removed both in the client's and server's MODE command. - */ - -/*! - \var IrcNetwork::TypeD - \brief Type D modes - - Modes that change a setting on the channel. These modes - never take a parameter. - */ - -/*! - \var IrcNetwork::AllTypes - \brief All type modes - */ - -/*! - \enum IrcNetwork::Limit - This enum describes the numeric limit types. - */ - -/*! - \var IrcNetwork::NickLength - \brief The maximum nick name length - */ - -/*! - \var IrcNetwork::ChannelLength - \brief The maximum channel name length - */ - -/*! - \var IrcNetwork::TopicLength - \brief The maximum channel topic length - */ - -/*! - \var IrcNetwork::MessageLength - \brief The maximum message length - */ - -/*! - \var IrcNetwork::KickReasonLength - \brief The maximum kick reason length - */ - -/*! - \var IrcNetwork::AwayReasonLength - \brief The maximum away reason length - */ - -/*! - \var IrcNetwork::ModeCount - \brief The maximum number of channel modes allowed per mode command - */ - -#ifndef IRC_DOXYGEN -IrcNetworkPrivate::IrcNetworkPrivate() : q_ptr(0), initialized(false) -{ -} - -static QHash<QString, int> numericValues(const QString& parameter) -{ - QHash<QString, int> values; - const QStringList keyValues = parameter.split(",", QString::SkipEmptyParts); - foreach (const QString& keyValue, keyValues) - values.insert(keyValue.section(":", 0, 0), keyValue.section(":", 1, 1).toInt()); - return values; -} - -void IrcNetworkPrivate::setInfo(const QHash<QString, QString>& info) -{ - Q_Q(IrcNetwork); - if (info.contains("NETWORK")) - setName(info.value("NETWORK")); - if (info.contains("PREFIX")) { - const QString pfx = info.value("PREFIX"); - setModes(pfx.mid(1, pfx.indexOf(')') - 1).split("", QString::SkipEmptyParts)); - setPrefixes(pfx.mid(pfx.indexOf(')') + 1).split("", QString::SkipEmptyParts)); - } - if (info.contains("CHANTYPES")) - setChannelTypes(info.value("CHANTYPES").split("", QString::SkipEmptyParts)); - - // TODO: - if (info.contains("NICKLEN")) - numericLimits.insert("NICKLEN", info.value("NICKLEN").toInt()); - if (info.contains("CHANNELLEN")) - numericLimits.insert("CHANNELLEN", info.value("CHANNELLEN").toInt()); - if (info.contains("TOPICLEN")) - numericLimits.insert("TOPICLEN", info.value("TOPICLEN").toInt()); - if (info.contains("KICKLEN")) - numericLimits.insert("KICKLEN", info.value("KICKLEN").toInt()); - if (info.contains("AWAYLEN")) - numericLimits.insert("AWAYLEN", info.value("AWAYLEN").toInt()); - if (info.contains("MODES")) - numericLimits.insert("MODES", info.value("MODES").toInt()); - if (info.contains("CHANMODES")) - channelModes = info.value("CHANMODES").split(",", QString::SkipEmptyParts); - if (info.contains("MAXLIST")) - modeLimits = numericValues(info.value("MAXLIST")); - if (info.contains("CHANLIMIT")) - channelLimits = numericValues(info.value("CHANLIMIT")); - if (info.contains("TARGMAX")) - targetLimits = numericValues(info.value("TARGMAX")); - - if (!initialized) { - initialized = true; - emit q->initialized(); - } -} - -void IrcNetworkPrivate::setAvailableCapabilities(const QSet<QString>& capabilities) -{ - Q_Q(IrcNetwork); - if (availableCaps != capabilities) { - availableCaps = capabilities; - emit q->availableCapabilitiesChanged(availableCaps.toList()); - } -} - -void IrcNetworkPrivate::setActiveCapabilities(const QSet<QString>& capabilities) -{ - Q_Q(IrcNetwork); - if (activeCaps != capabilities) { - activeCaps = capabilities; - emit q->activeCapabilitiesChanged(activeCaps.toList()); - } -} - -void IrcNetworkPrivate::setName(const QString& value) -{ - Q_Q(IrcNetwork); - if (name != value) { - name = value; - emit q->nameChanged(value); - } -} - -void IrcNetworkPrivate::setModes(const QStringList& value) -{ - Q_Q(IrcNetwork); - if (modes != value) { - modes = value; - emit q->modesChanged(value); - } -} - -void IrcNetworkPrivate::setPrefixes(const QStringList& value) -{ - Q_Q(IrcNetwork); - if (prefixes != value) { - prefixes = value; - emit q->prefixesChanged(value); - } -} - -void IrcNetworkPrivate::setChannelTypes(const QStringList& value) -{ - Q_Q(IrcNetwork); - if (channelTypes != value) { - channelTypes = value; - emit q->channelTypesChanged(value); - } -} -#endif // IRC_DOXYGEN - -/*! - \internal - Constructs a new network object for IRC \a connection. - */ -IrcNetwork::IrcNetwork(IrcConnection* connection) : QObject(connection), d_ptr(new IrcNetworkPrivate) -{ - Q_D(IrcNetwork); - d->q_ptr = this; - d->connection = connection; -} - -/*! - \internal - Destructs the IRC network. - */ -IrcNetwork::~IrcNetwork() -{ -} - -/*! - \property bool IrcNetwork::initialized - This property holds whether the network information has been initialized. - - Most properties have empty values until the server provides the - relevant network information during the client-server handshake. - - \par Access function: - \li bool <b>isInitialized</b>() const - - \par Notifier signal: - \li void <b>initialized</b>() - */ -bool IrcNetwork::isInitialized() -{ - Q_D(const IrcNetwork); - return d->initialized; -} - -/*! - This property holds the network name. - - \par Access function: - \li QString <b>name</b>() const - - \par Notifier signal: - \li void <b>nameChanged</b>(const QString& name) - */ -QString IrcNetwork::name() const -{ - Q_D(const IrcNetwork); - return d->name; -} - -/*! - This property holds the supported channel user mode letters. - - Examples of typical channel user modes: - Description | Mode | Prefix - -----------------|------------|------- - Channel operator | \b o | @ - Voiced user | \b v | + - - \par Access function: - \li QStringList <b>modes</b>() const - - \par Notifier signal: - \li void <b>modesChanged</b>(const QStringList& modes) - - \sa prefixes, modeToPrefix() - */ -QStringList IrcNetwork::modes() const -{ - Q_D(const IrcNetwork); - return d->modes; -} - -/*! - This property holds the supported channel user mode prefix characters. - - Examples of typical channel user modes: - Description | Mode | Prefix - -----------------|------------|------- - Channel operator | o | \b @ - Voiced user | v | \b + - - \par Access function: - \li QStringList <b>prefixes</b>() const - - \par Notifier signal: - \li void <b>prefixesChanged</b>(const QStringList& prefixes) - - \sa modes, prefixToMode() - */ -QStringList IrcNetwork::prefixes() const -{ - Q_D(const IrcNetwork); - return d->prefixes; -} - -/*! - Converts a channel user mode letter to a prefix character. - - \sa modes, prefixToMode() - */ -QString IrcNetwork::modeToPrefix(const QString& mode) const -{ - Q_D(const IrcNetwork); - return d->prefixes.value(d->modes.indexOf(mode)); -} - -/*! - Converts a channel mode prefix character to a mode letter. - - \sa prefixes, modeToPrefix() - */ -QString IrcNetwork::prefixToMode(const QString& prefix) const -{ - Q_D(const IrcNetwork); - return d->modes.value(d->prefixes.indexOf(prefix)); -} - -/*! - This property holds the supported channel type prefix characters. - - Examples of typical channel types: - Description | Type | Example - -----------------|------|--------- - Normal channel | \# | \#communi - Local channel | & | &foo - - \par Access function: - \li QStringList <b>channelTypes</b>() const - - \par Notifier signal: - \li void <b>channelTypesChanged</b>(const QStringList& types) - */ -QStringList IrcNetwork::channelTypes() const -{ - Q_D(const IrcNetwork); - return d->channelTypes; -} - -/*! - Returns \c true if the \a name is a channel. - - \code - QString name = ...; - if (connection->network()->isChannel(name)) - doSomeChannelAction(name); - \endcode - - \sa channelTypes - */ -bool IrcNetwork::isChannel(const QString& name) const -{ - Q_D(const IrcNetwork); - return !name.isEmpty() && d->channelTypes.contains(name.at(0)); -} - -/*! - Returns the supported channel modes for specified \a types. - - \sa ModeType - */ -QStringList IrcNetwork::channelModes(IrcNetwork::ModeTypes types) const -{ - Q_D(const IrcNetwork); - QStringList modes; - if (types & TypeA) - modes += d->channelModes.value(0).split("", QString::SkipEmptyParts); - if (types & TypeB) - modes += d->channelModes.value(1).split("", QString::SkipEmptyParts); - if (types & TypeC) - modes += d->channelModes.value(2).split("", QString::SkipEmptyParts); - if (types & TypeD) - modes += d->channelModes.value(3).split("", QString::SkipEmptyParts); - return modes; -} - -/*! - Returns a numeric type of \a limit, or \c -1 if the limitation is not known. - - \sa modeLimit(), channelLimit(), targetLimit() - */ -int IrcNetwork::numericLimit(Limit limit) const -{ - Q_D(const IrcNetwork); - QString key; - switch (limit) { - case NickLength: key = QLatin1String("NICKLEN"); break; - case ChannelLength: key = QLatin1String("CHANNELLEN"); break; - case TopicLength: key = QLatin1String("TOPICLEN"); break; - case MessageLength: return 512; // RFC 1459 - case KickReasonLength: key = QLatin1String("KICKLEN"); break; - case AwayReasonLength: key = QLatin1String("AWAYLEN"); break; - case ModeCount: key = QLatin1String("MODES"); break; - } - return d->numericLimits.value(key, -1); -} - -/*! - Returns the limit of entries in the list per \a mode, or \c -1 if the limitation is not known. - - \sa modes() - */ -int IrcNetwork::modeLimit(const QString& mode) const -{ - Q_D(const IrcNetwork); - return d->modeLimits.value(mode); -} - -/*! - Returns the limit for a \a type of channels, or \c -1 if the limitation is not known. - - \sa channelTypes() - */ -int IrcNetwork::channelLimit(const QString& type) const -{ - Q_D(const IrcNetwork); - return d->channelLimits.value(type); -} - -/*! - Returns the limit of targets for a \a command, or \c -1 if the limitation is not known. - */ -int IrcNetwork::targetLimit(const QString& command) const -{ - Q_D(const IrcNetwork); - return d->targetLimits.value(command); -} - -/*! - This property holds the available capabilities. - - \par Access function: - \li QStringList <b>availableCapabilities</b>() const - - \par Notifier signal: - \li void <b>availableCapabilitiesChanged</b>(const QStringList& capabilities) - - \sa requestedCapabilities, activeCapabilities - */ -QStringList IrcNetwork::availableCapabilities() const -{ - Q_D(const IrcNetwork); - return d->availableCaps.toList(); -} - -/*! - This property holds the active capabilities. - - \par Access function: - \li QStringList <b>activeCapabilities</b>() const - - \par Notifier signal: - \li void <b>activeCapabilitiesChanged</b>(const QStringList& capabilities) - - \sa requestedCapabilities, availableCapabilities - */ -QStringList IrcNetwork::activeCapabilities() const -{ - Q_D(const IrcNetwork); - return d->activeCaps.toList(); -} - -/*! - Returns \c true if the \a capability is \b available. - - \sa availableCapabilities - */ -bool IrcNetwork::hasCapability(const QString& capability) const -{ - Q_D(const IrcNetwork); - return d->availableCaps.contains(capability); -} - -/*! - Returns \c true if the \a capability is \b active. - - \sa activeCapabilities - */ -bool IrcNetwork::isCapable(const QString& capability) const -{ - Q_D(const IrcNetwork); - return d->activeCaps.contains(capability); -} - -/*! - Requests the specified \a capability. - - \note The \a capability is NOT added to the list of \ref requestedCapabilities - "requested capabilities" to avoid them "piling up". - */ -bool IrcNetwork::requestCapability(const QString& capability) -{ - Q_D(IrcNetwork); - if (d->connection) - return d->connection->sendCommand(IrcCommand::createCapability(QLatin1String("REQ"), capability)); - return false; -} - -/*! - Requests the specified \a capabilities. - - \note The \a capabilities are NOT added to the list of \ref requestedCapabilities - "requested capabilities" to avoid them "piling up". - */ -bool IrcNetwork::requestCapabilities(const QStringList& capabilities) -{ - Q_D(IrcNetwork); - if (d->connection && d->connection->isActive()) - return d->connection->sendCommand(IrcCommand::createCapability(QLatin1String("REQ"), capabilities)); - return false; -} - -/*! - This property holds the requested capabilities. - - These capabilities are automatically requested during the handshake, - right after requestingCapabilities() has been emitted. - - \par Access functions: - \li QStringList <b>requestedCapabilities</b>() const - \li void <b>setRequestedCapabilities</b>(const QStringList& capabilities) - - \par Notifier signal: - \li void <b>requestedCapabilitiesChanged</b>(const QStringList& capabilities) - - \sa availableCapabilities, activeCapabilities - */ -QStringList IrcNetwork::requestedCapabilities() const -{ - Q_D(const IrcNetwork); - return d->requestedCaps.toList(); -} - -void IrcNetwork::setRequestedCapabilities(const QStringList& capabilities) -{ - Q_D(IrcNetwork); - const QSet<QString> caps = capabilities.toSet(); - if (d->requestedCaps != caps) { - d->requestedCaps = caps; - emit requestedCapabilitiesChanged(caps.toList()); - } -} - -#ifndef QT_NO_DEBUG_STREAM -QDebug operator<<(QDebug debug, IrcNetwork::Limit limit) -{ - const int index = IrcNetwork::staticMetaObject.indexOfEnumerator("Limit"); - QMetaEnum enumerator = IrcNetwork::staticMetaObject.enumerator(index); - const char* key = enumerator.valueToKey(limit); - debug << (key ? key : "Unknown"); - return debug; -} - -QDebug operator<<(QDebug debug, IrcNetwork::ModeType type) -{ - const int index = IrcNetwork::staticMetaObject.indexOfEnumerator("ModeType"); - QMetaEnum enumerator = IrcNetwork::staticMetaObject.enumerator(index); - const char* key = enumerator.valueToKey(type); - debug << (key ? key : "Unknown"); - return debug; -} - -QDebug operator<<(QDebug debug, IrcNetwork::ModeTypes types) -{ - QStringList lst; - if (types == IrcNetwork::AllTypes) { - lst << "AllTypes"; - } else { - if (types & IrcNetwork::TypeA) - lst << "TypeA"; - if (types & IrcNetwork::TypeB) - lst << "TypeB"; - if (types & IrcNetwork::TypeC) - lst << "TypeC"; - if (types & IrcNetwork::TypeD) - lst << "TypeD"; - } - debug.nospace() << '(' << qPrintable(lst.join("|")) << ')'; - return debug; -} - -QDebug operator<<(QDebug debug, const IrcNetwork* network) -{ - if (!network) - return debug << "IrcNetwork(0x0) "; - debug.nospace() << network->metaObject()->className() << '(' << (void*) network; - if (!network->objectName().isEmpty()) - debug.nospace() << ", name=" << qPrintable(network->objectName()); - if (!network->name().isEmpty()) - debug.nospace() << ", network=" << qPrintable(network->name()); - debug.nospace() << ')'; - return debug.space(); -} -#endif // QT_NO_DEBUG_STREAM - -#include "moc_ircnetwork.cpp" - -IRC_END_NAMESPACE diff --git a/libcommuni/src/core/ircprotocol.cpp b/libcommuni/src/core/ircprotocol.cpp deleted file mode 100644 index 9d42126..0000000 --- a/libcommuni/src/core/ircprotocol.cpp +++ /dev/null @@ -1,480 +0,0 @@ -/* - Copyright (C) 2008-2014 The Communi Project - - You may use this file under the terms of BSD license as follows: - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "ircprotocol.h" -#include "ircconnection_p.h" -#include "ircmessagebuilder_p.h" -#include "ircnetwork_p.h" -#include "ircconnection.h" -#include "ircmessage.h" -#include "irccommand.h" -#include "irc.h" -#include <QDebug> - -IRC_BEGIN_NAMESPACE - -/*! - \file ircprotocol.h - \brief \#include <IrcProtocol> - */ - -/*! - \since 3.2 - \class IrcProtocol ircprotocol.h IrcProtocol - \ingroup core - \brief Implements the IRC protocol and provides means for implementing support for custom protocols. - - \sa IrcConnection::protocol - */ - -#ifndef IRC_DOXYGEN -class IrcProtocolPrivate -{ - Q_DECLARE_PUBLIC(IrcProtocol) - -public: - IrcProtocolPrivate(); - - void authenticate(bool secure); - - void readLines(const QByteArray& delimiter); - void processLine(const QByteArray& line); - - void handleNumericMessage(IrcNumericMessage* msg); - void handlePrivateMessage(IrcPrivateMessage* msg); - void handleCapabilityMessage(IrcCapabilityMessage* msg); - - void _irc_pauseHandshake(); - void _irc_resumeHandshake(); - - IrcProtocol* q_ptr; - IrcConnection* connection; - IrcMessageBuilder* builder; - QHash<QString, QString> info; - QByteArray buffer; - bool resumed; - bool authed; -}; - -IrcProtocolPrivate::IrcProtocolPrivate() : q_ptr(0), connection(0), builder(0), resumed(false), authed(false) -{ -} - -void IrcProtocolPrivate::authenticate(bool secure) -{ - const QString password = connection->password(); - if (!password.isEmpty()) { - if (secure) { - const QByteArray userName = connection->userName().toUtf8(); - const QByteArray data = userName + '\0' + userName + '\0' + password.toUtf8(); - authed = connection->sendData("AUTHENTICATE " + data.toBase64()); - } else { - authed = connection->sendRaw(QString("PASS %1").arg(password)); - } - } -} - -void IrcProtocolPrivate::readLines(const QByteArray& delimiter) -{ - int i = -1; - while ((i = buffer.indexOf(delimiter)) != -1) { - QByteArray line = buffer.left(i).trimmed(); - buffer = buffer.mid(i + delimiter.length()); - if (!line.isEmpty()) - processLine(line); - } -} - -void IrcProtocolPrivate::processLine(const QByteArray& line) -{ - Q_Q(IrcProtocol); - static bool dbg = qgetenv("IRC_DEBUG").toInt(); - if (dbg) qDebug() << line; - - if (line.startsWith("AUTHENTICATE") && !connection->saslMechanism().isEmpty()) { - const QList<QByteArray> args = line.split(' '); - if (args.count() == 2 && args.at(1) == "+") - authenticate(true); - if (!connection->isConnected()) - QMetaObject::invokeMethod(q, "_irc_resumeHandshake", Qt::QueuedConnection); - return; - } - - IrcMessage* msg = IrcMessage::fromData(line, connection); - if (msg) { - msg->setEncoding(connection->encoding()); - - switch (msg->type()) { - case IrcMessage::Capability: - handleCapabilityMessage(static_cast<IrcCapabilityMessage*>(msg)); - break; - case IrcMessage::Nick: - if (msg->flags() & IrcMessage::Own) - q->setNickName(static_cast<IrcNickMessage*>(msg)->newNick()); - break; - case IrcMessage::Numeric: - handleNumericMessage(static_cast<IrcNumericMessage*>(msg)); - break; - case IrcMessage::Ping: - connection->sendRaw("PONG " + static_cast<IrcPingMessage*>(msg)->argument()); - break; - case IrcMessage::Private: - handlePrivateMessage(static_cast<IrcPrivateMessage*>(msg)); - break; - default: - break; - } - q->receiveMessage(msg); - } -} - -void IrcProtocolPrivate::handleNumericMessage(IrcNumericMessage* msg) -{ - Q_Q(IrcProtocol); - switch (msg->code()) { - case Irc::RPL_WELCOME: - q->setNickName(msg->parameters().value(0)); - q->setStatus(IrcConnection::Connected); - break; - case Irc::RPL_ISUPPORT: { - foreach (const QString& param, msg->parameters().mid(1)) { - QStringList keyValue = param.split("=", QString::SkipEmptyParts); - info.insert(keyValue.value(0), keyValue.value(1)); - } - break; - } - case Irc::ERR_NOMOTD: - case Irc::RPL_MOTDSTART: - q->setInfo(info); - break; - case Irc::ERR_NICKNAMEINUSE: - case Irc::ERR_NICKCOLLISION: { - QString alternate = connection->nickName(); - emit connection->nickNameReserved(&alternate); - if (!alternate.isEmpty() && alternate != connection->nickName()) { - connection->setNickName(alternate); - } else { - emit connection->nickNameRequired(msg->parameters().value(1), &alternate); - if (!alternate.isEmpty() && alternate != connection->nickName()) - connection->setNickName(alternate); - } - break; - } - case Irc::ERR_BADCHANNELKEY: { - QString key; - QString channel = msg->parameters().value(1); - emit connection->channelKeyRequired(channel, &key); - if (!key.isEmpty()) - connection->sendCommand(IrcCommand::createJoin(channel, key)); - break; - } - default: - break; - } -} - -void IrcProtocolPrivate::handlePrivateMessage(IrcPrivateMessage* msg) -{ - if (msg->isRequest()) { - IrcCommand* reply = IrcConnectionPrivate::get(connection)->createCtcpReply(msg); - if (reply) - connection->sendCommand(reply); - } -} - -static void handleCapability(QSet<QString>* caps, const QString& cap) -{ - Q_ASSERT(caps); - // sticky modifier (once the cap is enabled, it cannot be disabled) - QLatin1Char stickyMod('='); - // ack modifier (the cap must be acked by the client to fully enable/disable) - QLatin1Char ackMod('~'); - // disable modifier (the cap should be disabled) - QLatin1Char disMod('-'); - - QString name = cap; - while (name.startsWith(stickyMod) || name.startsWith(ackMod)) - name.remove(0, 1); - - if (name.startsWith(disMod)) - caps->remove(name.mid(1)); - else - caps->insert(name); -} - -void IrcProtocolPrivate::handleCapabilityMessage(IrcCapabilityMessage* msg) -{ - Q_Q(IrcProtocol); - const bool connected = connection->isConnected(); - const QString subCommand = msg->subCommand(); - if (subCommand == "LS") { - QSet<QString> availableCaps = connection->network()->availableCapabilities().toSet(); - foreach (const QString& cap, msg->capabilities()) - handleCapability(&availableCaps, cap); - q->setAvailableCapabilities(availableCaps); - - if (!connected) { - QMetaObject::invokeMethod(connection->network(), "requestingCapabilities"); - QStringList requestedCaps = connection->network()->requestedCapabilities(); - const QStringList params = msg->parameters(); - if (params.value(params.count() - 1) != QLatin1String("*")) { - if (!connection->saslMechanism().isEmpty() && availableCaps.contains(QLatin1String("sasl"))) - requestedCaps += QLatin1String("sasl"); - } - if (!requestedCaps.isEmpty()) - connection->sendRaw("CAP REQ :" + requestedCaps.join(" ")); - else - QMetaObject::invokeMethod(q, "_irc_resumeHandshake", Qt::QueuedConnection); - } - } else if (subCommand == "ACK" || subCommand == "NAK") { - bool auth = false; - if (subCommand == "ACK") { - QSet<QString> activeCaps = connection->network()->activeCapabilities().toSet(); - foreach (const QString& cap, msg->capabilities()) { - handleCapability(&activeCaps, cap); - if (cap == "sasl" && !connection->saslMechanism().isEmpty() && !connection->password().isEmpty()) - auth = connection->sendRaw("AUTHENTICATE " + connection->saslMechanism()); - } - q->setActiveCapabilities(activeCaps); - } - - if (!connected && !auth) - QMetaObject::invokeMethod(q, "_irc_resumeHandshake", Qt::QueuedConnection); - } -} - -void IrcProtocolPrivate::_irc_pauseHandshake() -{ - // Send CAP LS first; if the server understands it this will - // temporarily pause the handshake until CAP END is sent, so we - // know whether the server supports the CAP extension. - connection->sendData("CAP LS"); - resumed = false; - authed = false; -} - -void IrcProtocolPrivate::_irc_resumeHandshake() -{ - if (!resumed && !connection->isConnected()) { - if (!authed && !connection->saslMechanism().isEmpty() && !connection->password().isEmpty()) - authenticate(false); - connection->sendData("CAP END"); - } - resumed = true; -} -#endif // IRC_DOXYGEN - -/*! - Constructs a new IRC protocol for \a connection. - */ -IrcProtocol::IrcProtocol(IrcConnection* connection) : QObject(connection), d_ptr(new IrcProtocolPrivate) -{ - Q_D(IrcProtocol); - d->q_ptr = this; - d->connection = connection; - d->builder = new IrcMessageBuilder(connection); - connect(d->builder, SIGNAL(messageReceived(IrcMessage*)), this, SLOT(receiveMessage(IrcMessage*))); -} - -/*! - Destructs the IRC protocol. - */ -IrcProtocol::~IrcProtocol() -{ - Q_D(IrcProtocol); - delete d->builder; -} - -/*! - This property holds the connection. - - \par Access function: - \li \ref IrcConnection* <b>connection</b>() const - */ -IrcConnection* IrcProtocol::connection() const -{ - Q_D(const IrcProtocol); - return d->connection; -} - -/*! - This property holds the socket. - - \par Access functions: - \li \ref QAbstractSocket* <b>socket</b>() const - */ -QAbstractSocket* IrcProtocol::socket() const -{ - Q_D(const IrcProtocol); - return d->connection->socket(); -} - -/*! - This method is called when the connection has been established. - - The default implementation sends the \c NICK, \c USER and \c PASSWORD commands as defined in - <a href="http://tools.ietf.org/html/rfc1459">RFC 1459</a>. - - Furthermore, it sends a <tt>CAP LS</tt> command as specified in - <a href="http://tools.ietf.org/html/draft-mitchell-irc-capabilities-01">IRC Client Capabilities Extension</a>. - */ -void IrcProtocol::open() -{ - Q_D(IrcProtocol); - d->_irc_pauseHandshake(); - - if (d->connection->saslMechanism().isEmpty() && !d->connection->password().isEmpty()) - d->authenticate(false); - - d->connection->sendRaw(QString("NICK %1").arg(d->connection->nickName())); - d->connection->sendRaw(QString("USER %1 hostname servername :%2").arg(d->connection->userName(), d->connection->realName())); -} - -/*! - This method is called when the connection has been lost. - */ -void IrcProtocol::close() -{ -} - -/*! - This method is called when the \ref socket has new data available for read. - - The default implementation reads lines as specified in - <a href="http://tools.ietf.org/html/rfc1459">RFC 1459</a>. - - \sa socket - */ -void IrcProtocol::read() -{ - Q_D(IrcProtocol); - d->buffer += socket()->readAll(); - // try reading RFC compliant message lines first - d->readLines("\r\n"); - // fall back to RFC incompliant lines... - d->readLines("\n"); -} - -/*! - This method is called when raw \a data should be written to the \ref socket. - - The default implementation writes the data and appends \c "\r\n" as specified in - <a href="http://tools.ietf.org/html/rfc1459">RFC 1459</a>. - - \sa socket - */ -bool IrcProtocol::write(const QByteArray& data) -{ - return socket()->write(data + QByteArray("\r\n")) != -1; -} - -/*! - This method should be called by the protocol implementation - to make the underlying IRC connection receive a \a message. - - \sa IrcConnection::messageReceived() - */ -void IrcProtocol::receiveMessage(IrcMessage* message) -{ - Q_D(IrcProtocol); - IrcConnectionPrivate* priv = IrcConnectionPrivate::get(d->connection); - priv->receiveMessage(message); - if (message->type() == IrcMessage::Numeric) - d->builder->processMessage(static_cast<IrcNumericMessage*>(message)); -} - -/*! - This method should be called by the protocol implementation to - notify the underlying IRC connection about a nick \a name change. - - \sa IrcConnection::nickName - */ -void IrcProtocol::setNickName(const QString& name) -{ - Q_D(IrcProtocol); - IrcConnectionPrivate* priv = IrcConnectionPrivate::get(d->connection); - priv->setNick(name); -} - -/*! - This method should be called by the protocol implementation - to notify the underlying IRC connection about a \a status change. - - \sa IrcConnection::status - */ -void IrcProtocol::setStatus(IrcConnection::Status status) -{ - Q_D(IrcProtocol); - IrcConnectionPrivate* priv = IrcConnectionPrivate::get(d->connection); - priv->setStatus(status); -} - -/*! - This method should be called by the protocol implementation - to initialize the underlying IRC network connection \a info. - - \sa IrcNetwork::initialized - */ -void IrcProtocol::setInfo(const QHash<QString, QString>& info) -{ - Q_D(IrcProtocol); - if (!info.isEmpty()) { - IrcConnectionPrivate* priv = IrcConnectionPrivate::get(d->connection); - priv->setInfo(info); - } -} - -/*! - This method should be called by the protocol implementation to notify - the underlying IRC network about a change in available \a capabilities. - - \sa IrcNetwork::availableCapabilities - */ -void IrcProtocol::setAvailableCapabilities(const QSet<QString>& capabilities) -{ - Q_D(IrcProtocol); - IrcNetworkPrivate* priv = IrcNetworkPrivate::get(d->connection->network()); - priv->setAvailableCapabilities(capabilities); -} - -/*! - This method should be called by the protocol implementation to notify - the underlying IRC network about a change in active \a capabilities. - - \sa IrcNetwork::activeCapabilities - */ -void IrcProtocol::setActiveCapabilities(const QSet<QString>& capabilities) -{ - Q_D(IrcProtocol); - IrcNetworkPrivate* priv = IrcNetworkPrivate::get(d->connection->network()); - priv->setActiveCapabilities(capabilities); -} - -#include "moc_ircprotocol.cpp" - -IRC_END_NAMESPACE |
