# HG changeset patch # User Jacob Dawid # Date 1312446659 -7200 # Node ID b2ee41559bffe610f9b9e87db1dc54d374b4bf75 # Parent c0cb420d83b796bb30fc6d9452f419eb80896bfd Refactored IRC code. diff -r c0cb420d83b7 -r b2ee41559bff gui/src/qirc/IRCClientImpl.cpp --- a/gui/src/qirc/IRCClientImpl.cpp Wed Aug 03 19:05:15 2011 +0200 +++ b/gui/src/qirc/IRCClientImpl.cpp Thu Aug 04 10:30:59 2011 +0200 @@ -18,24 +18,22 @@ #include "IRCClientImpl.h" -IRCServerMessage::IRCServerMessage (const char *serverMessage) +IRCServerMessage::IRCServerMessage (const QString& serverMessage) { - char prefix[MAX_LINE_LEN]; + const char *message = serverMessage.toStdString().c_str(); + char prefix[512]; int index = 0; - n_nick = ""; + m_nick = ""; m_user = ""; m_host = ""; - for (int i = 0; i < 15; i++) - { - m_parameter[i] = ""; - } + m_parameters.reserve (16); - if (serverMessage[0] == CHR_COLON) + if (message[0] == CHR_COLON) { index++; strcpy (prefix, - getStringToken (serverMessage, index).toStdString ().c_str ()); + getStringToken (message, index).toStdString ().c_str ()); int etapa = 0; for (unsigned int i = 0; i < strlen (prefix); i++) @@ -52,7 +50,7 @@ switch (etapa) { case 0: - n_nick += prefix[i]; + m_nick += prefix[i]; break; case 1: m_user += prefix[i]; @@ -65,66 +63,54 @@ } } - m_command = getStringToken (serverMessage, index); + m_command = getStringToken (message, index); m_command = m_command.toUpper (); - m_parameterCount = 0; - while (serverMessage[index] != 0) + while (message[index] != 0) { - if ((serverMessage[index] == CHR_COLON) || (m_parameterCount == 14)) + if ((message[index] == CHR_COLON)) { - if (serverMessage[index] == CHR_COLON) + if (message[index] == CHR_COLON) { index++; } - m_parameter[m_parameterCount] = (const char *) (serverMessage + index); - index += strlen (serverMessage + index); + m_parameters.append ( (const char *) (message + index)); + index += strlen (message + index); } else { - m_parameter[m_parameterCount] = getStringToken (serverMessage, index); + m_parameters.append (getStringToken (message, index)); } - m_parameterCount++; } if (strlen (m_command.toStdString ().c_str ()) == strspn (m_command.toStdString ().c_str (), DIGITS)) { - n_numeric = true; + m_isNumeric = true; m_codeNumber = atoi (m_command.toStdString ().c_str ()); } else { - n_numeric = false; + m_isNumeric = false; } } int IRCServerMessage::numericValue () { - if (!n_numeric) - { - return -1; - } - else - { - return m_codeNumber; - } + if (m_isNumeric) + return m_codeNumber; + return -1; } QString IRCServerMessage::parameter (int index) { - if ((index < 0) || (index > 14)) - { - return QString (); - } - else - { - return m_parameter[index]; - } + if (index >= 0 && index < m_parameters.size ()) + return m_parameters.at (index); + return ""; } int @@ -195,13 +181,14 @@ void IRCClientImpl::disconnect () { - + m_tcpSocket.disconnect (); } void IRCClientImpl::reconnect () { - + disconnect (); + connectToHost (m_host, m_port, m_nickname); } bool @@ -233,7 +220,7 @@ void IRCClientImpl::sendJoinRequest (const QString& channel) { - sendCommand (1, IRCCommand::Join, channel.toStdString ().c_str ()); + sendIRCCommand (IRCCommand::Join, QStringList (channel)); } void @@ -252,22 +239,25 @@ void IRCClientImpl::sendNicknameChangeRequest (const QString &nickname) { - sendCommand (1, IRCCommand::Nick, nickname.toStdString ().c_str ()); + sendIRCCommand (IRCCommand::Nick, QStringList (nickname)); } void IRCClientImpl::sendPublicMessage (const QString& message) { - sendCommand (2, IRCCommand::PrivateMessage, m_focussedChannel.toStdString ().c_str (), - message.toStdString ().c_str ()); + QStringList arguments; + arguments << m_focussedChannel; + arguments << message; + sendIRCCommand (IRCCommand::PrivateMessage, arguments); } void IRCClientImpl::sendPrivateMessage (const QString &recipient, const QString &message) { - sendCommand (2, IRCCommand::PrivateMessage, - recipient.toStdString ().c_str (), - message.toStdString ().c_str ()); + QStringList arguments; + arguments << recipient; + arguments << message; + sendIRCCommand (IRCCommand::PrivateMessage, arguments); } const QString& @@ -280,7 +270,9 @@ IRCClientImpl::handleConnected () { m_connected = true; - sendCommand (4, IRCCommand::User, "na", "0", "0", "na"); + QStringList arguments; + arguments << "na" << "0" << "0" << "na"; + sendIRCCommand (IRCCommand::User, arguments); sendNicknameChangeRequest (m_nickname); emit connected (m_host.toString ()); } @@ -330,7 +322,7 @@ { if (m_connected && !line.isEmpty()) { - IRCServerMessage ircEvent(line.toStdString().c_str()); + IRCServerMessage ircEvent(line); if (ircEvent.isNumericValue () == true) { switch (ircEvent.numericValue ()) @@ -418,7 +410,7 @@ } else if (command == IRCCommand::Ping) { - sendCommand (1, IRCCommand::Pong, m_nickname.toStdString ().c_str ()); + sendIRCCommand (IRCCommand::Pong, QStringList (m_nickname)); } else if (command == IRCCommand::Error) { @@ -441,44 +433,21 @@ } void -IRCClientImpl::sendCommand (int numberOfCommands, const QString& command, ...) +IRCClientImpl::sendIRCCommand (const QString &command, const QStringList &arguments) { - // TODO: Change this. We are coding C++, not C ;) - char linea[513]; - char *parametro; - const char *cmd = command.toStdString().c_str(); - va_list lp; - - strncpy (linea, cmd, 512); - linea[512] = 0; - va_start (lp, cmd); - for (int i = 0; i < numberOfCommands; i++) + QString line = command; + for (int i = 0; i < arguments.size (); i++) { - if (i == 15) - break; - parametro = va_arg (lp, char *); - if (i == numberOfCommands - 1) - { - if (strlen (linea) + strlen (parametro) + 2 > 512) - break; - if (strchr (parametro, ' ') != NULL) - { - strcat (linea, " :"); - } - else - { - strcat (linea, " "); - } - strcat (linea, parametro); - } - else - { - if (strlen (linea) + strlen (parametro) + 1 > 512) - break; - strcat (linea, " "); - strcat (linea, parametro); - } + bool applyColon = false; + // Usually all parameters are separated by spaces. + // The last parameter of the message may contain spaces, it is usually used + // to transmit messages. In order to parse it correctly, if needs to be prefixed + // with a colon, so the server knows to ignore all forthcoming spaces and has to treat + // all remaining characters as a single parameter. If we detect any whitespace in the + // last argument, prefix it with a colon: + if ((i == arguments.size () - 1) && arguments.at (i).contains (QRegExp("\\s"))) + applyColon = true; + line += QString (" %1%2").arg (applyColon ? ":" : "").arg (arguments.at (i)); } - va_end (lp); - sendLine (linea); + sendLine (line); } diff -r c0cb420d83b7 -r b2ee41559bff gui/src/qirc/IRCClientImpl.h --- a/gui/src/qirc/IRCClientImpl.h Wed Aug 03 19:05:15 2011 +0200 +++ b/gui/src/qirc/IRCClientImpl.h Thu Aug 04 10:30:59 2011 +0200 @@ -228,29 +228,27 @@ class IRCServerMessage { - #define MAX_LINE_LEN 512 - #define PARAM_MAX_COUNT 15 #define CHR_COLON ':' #define CHR_SPACE ' ' #define CHR_ZERO '\0' #ifdef Q_OS_LINUX - #define CRLF "\n" + # define CRLF "\n" #else - #define CRLF "\r\n" + # define CRLF "\r\n" #endif #define DIGITS "0123456789" public: - IRCServerMessage (const char *serverMessage); + IRCServerMessage (const QString& serverMessage); bool isNumericValue () { - return n_numeric; + return m_isNumeric; } QString nick () { - return n_nick; + return m_nick; } QString command () @@ -267,12 +265,10 @@ QString getStringToken (QString linea, int &index); int m_codeNumber; - bool n_numeric; - - QString n_nick, m_user, m_host; + bool m_isNumeric; + QString m_nick, m_user, m_host; QString m_command; - int m_parameterCount; - QString m_parameter[PARAM_MAX_COUNT]; + QStringList m_parameters; }; class IRCChannelProxy : public IRCChannelProxyInterface @@ -326,7 +322,7 @@ void handleUserQuit (const QString& nick, const QString& reason); void handleIncomingLine (const QString& line); void sendLine (const QString& line); - void sendCommand (int numberOfCommands, const QString& command, ...); + void sendIRCCommand (const QString& command, const QStringList& arguments); QHostAddress m_host; int m_port;