I'm trying to send encoding strings over the socket. The data that is received from a line edit. Then parsed then sent to the socket. When parsing the string, I'm checking to make sure that the information doesn't go over 510 bytes to the server. So I use QTextCodec::fromUnicode() on each character in the QString and check the length of that character and add it and if it goes over the limit, I split it until it's not possible to split anymore.
Now here is the issue. When I sent a short japanese text string (for testing), I test in Konversation and Quassel. It comes out perfectly. But if I send where it's alot it comes out with strange obfuscated text "€Âユーã‚ ¶Ã£Æ’Â¼Ã£Æ’Â»Ã£â€šÂµÃ£Æ ’Âã". Instead of what I'm sending. All the IRC clients including mine are using UTF-8.
Here is the code for the string parser.
void parsePrivmsg
(const QString &message
) {
if (msg.isEmpty()) {
window
->socket
()->rfcPrivmsg
(QString(), msg
);
return;
}
msg.remove(0, dest.length() + 1);
if (!msg.isEmpty()) {
if (dest.toLower() == window->name()) {
if (window->windowType() == Aki::BaseWindow::ChannelWindow) {
Aki::ChannelWindow *channel = qobject_cast<Aki::ChannelWindow*>(window);
foreach (Aki::Irc::User *user, channel->users()) {
if (user->nick() == channel->socket()->currentNick()) {
.arg(user->color().name(), user->nick());
QStringList messages
= checkMessageLength
("PRIVMSG", dest, msg, user
);
QStringListIterator iter(messages);
while (iter.hasNext()) {
channel->socket()->rfcPrivmsg(dest, tmp);
channel->view()->addPrivmsg(nickColour, Aki::Irc::Color::toHtml(tmp));
}
}
}
} else if (window->windowType() == Aki::BaseWindow::QueryWindow) {
}
}
}
}
const QString &message, Aki
::Irc::User *user
) {
const int nickLength = user->nick().length();
const int hostMaskLength = user->hostMask().length();
const int maxLength = 512 - 8 - (nickLength + hostMaskLength + type.length() +
destination.length());
int lastSplitLength;
int charLength;
int lastBreakPosition;
lastSplitLength = charLength = lastBreakPosition = 0;
int index = 0;
// Continue looping while the message still needs to be
// broken down
while (process.length() >= maxLength) {
// We need to check each character to get the proper size of character.
charLength = ch.length();
lastSplitLength += charLength;
if (process[index].isSpace() || process[index].isPunct()) {
lastBreakPosition = index;
}
if (charLength + lastSplitLength >= maxLength) {
if (lastBreakPosition != 0) {
split << process.left(lastBreakPosition);
process.remove(0, lastBreakPosition);
} else {
split << process.left(index);
process.remove(0, index);
}
}
++index;
lastBreakPosition = charLength = 0;
}
if (!process.isEmpty()) {
split << process;
}
return split;
}
void parsePrivmsg(const QString &message)
{
QString msg = message;
if (msg.isEmpty()) {
window->socket()->rfcPrivmsg(QString(), msg);
return;
}
QString dest = msg.left(msg.indexOf(QChar(' ')));
msg.remove(0, dest.length() + 1);
if (!msg.isEmpty()) {
if (dest.toLower() == window->name()) {
if (window->windowType() == Aki::BaseWindow::ChannelWindow) {
Aki::ChannelWindow *channel = qobject_cast<Aki::ChannelWindow*>(window);
foreach (Aki::Irc::User *user, channel->users()) {
if (user->nick() == channel->socket()->currentNick()) {
QString nickColour = QString("<font color='%1'>%2</font>")
.arg(user->color().name(), user->nick());
QStringList messages = checkMessageLength("PRIVMSG", dest, msg, user);
QStringListIterator iter(messages);
while (iter.hasNext()) {
QString tmp = iter.next();
channel->socket()->rfcPrivmsg(dest, tmp);
channel->view()->addPrivmsg(nickColour, Aki::Irc::Color::toHtml(tmp));
}
}
}
} else if (window->windowType() == Aki::BaseWindow::QueryWindow) {
}
}
}
}
QStringList checkMessageLength(const QString &type, const QString &destination,
const QString &message, Aki::Irc::User *user)
{
const int nickLength = user->nick().length();
const int hostMaskLength = user->hostMask().length();
const int maxLength = 512 - 8 - (nickLength + hostMaskLength + type.length() +
destination.length());
int lastSplitLength;
int charLength;
int lastBreakPosition;
lastSplitLength = charLength = lastBreakPosition = 0;
QString process = message;
QStringList split;
QTextCodec *codec = window->socket()->codec();
int index = 0;
// Continue looping while the message still needs to be
// broken down
while (process.length() >= maxLength) {
// We need to check each character to get the proper size of character.
QByteArray ch = codec->fromUnicode(QString(process[index]));
charLength = ch.length();
lastSplitLength += charLength;
if (process[index].isSpace() || process[index].isPunct()) {
lastBreakPosition = index;
}
if (charLength + lastSplitLength >= maxLength) {
if (lastBreakPosition != 0) {
split << process.left(lastBreakPosition);
process.remove(0, lastBreakPosition);
} else {
split << process.left(index);
process.remove(0, index);
}
}
++index;
lastBreakPosition = charLength = 0;
}
if (!process.isEmpty()) {
split << process;
}
return split;
}
To copy to clipboard, switch view to plain text mode
This is how it's done in the socket class
{
kDebug() << socket->write(data.toLatin1());
kDebug() << socket->write("\r\n");
}
void
Socket
::rfcPrivmsg(const QString &destination,
const QString &message
){
rfcRaw("PRIVMSG " + destination + " :" + codec()->fromUnicode(message));
}
void write(const QString &data)
{
kDebug() << socket->write(data.toLatin1());
kDebug() << socket->write("\r\n");
}
void
Socket::rfcPrivmsg(const QString &destination, const QString &message)
{
rfcRaw("PRIVMSG " + destination + " :" + codec()->fromUnicode(message));
}
To copy to clipboard, switch view to plain text mode
Heres how it looks from Konversation
[20:48] <comawhite> ィング株式会社スクウェア・エニックス・ホールディングス 株式会社スクウェア・エニックス・ホールディングス 株式会社スクウェア・エニックス・ホールディングス 株式会社スクウェア・エニックス・ホールディングス 株式会社スクウェア・エニックス・ホールディングス 株式会社スクウェア・エニックス・ホー
[20:48] <comawhite> ールデã⠚£ãƒ³ã‚°ã‚£ ングæ ªå¼Â会社ㆹクウェ Ã£â€šÂ¢Ã¯Â½Â¥Ã£â€šÂ¨Ã£Æ â€¹Ã£Æ’Æ’Ã£â€šÂ¯Ã£â€šÂ ¹Ã£Æ’Â»Ã£Æ’â€ºÃ£Æ’Â¼Ã£Æ ’«ãƒ‡ã‚£ãƒ ã‚°ã‚¹ æ ªå¼Â会社ㆹクウェ Ã£â€šÂ¢Ã¯Â½Â¥Ã£â€šÂ¨Ã£Æ â€¹Ã£Æ’Æ’Ã£â€šÂ¯Ã£â€šÂ ¹Ã£Æ’Â»Ã£Æ’â€ºÃ£Æ’Â¼Ã£Æ ’«ãƒ‡ã‚£ãƒ ã‚°ã‚¹ æ ªå¼Â会社ㆹクウェ Ã£â€šÂ¢Ã¯Â½Â¥Ã£â€šÂ¨Ã£Æ â€¹Ã£Æ’Æ’Ã£â€šÂ¯Ã£â€šÂ ¹Ã£Æ’Â»Ã£Æ’â€ºÃ£Æ’Â¼Ã£Æ ’«ãƒ‡ã‚£ãƒ ã‚°ã‚¹ æ ªå¼Â会社ㆹクウェ Ã£â€šÂ¢Ã¯Â½Â¥Ã£â€šÂ¨Ã£Æ â€¹Ã£Æ’Æ’Ã£â€šÂ¯Ã£â€šÂ ¹Ã£Æ’Â»Ã£Æ’â€ºÃ£Æ’Â¼Ã£Æ ’«ãƒ‡ã‚£ãƒ ã‚°ã‚¹ æ ªå¼Â会社ㆹクウェ Ã£â€šÂ¢Ã¯Â½Â¥Ã£â€šÂ¨Ã£Æ â€¹Ã£Æ’Æ’Ã£â€šÂ¯Ã£â€šÂ ¹Ã£Æ’Â»Ã£Æ’â€ºÃ£Æ’Â¼Ã£Æ ’«ãƒ‡ã‚£ãƒ ã‚°ã‚¹ æ ªå¼Â会社ㆹクウェ Ã£â€šÂ¢Ã¯Â½Â¥Ã£â€šÂ¨Ã£Æ â€¹Ã£Æ’Æ’Ã£â€šÂ¯Ã£â€šÂ ¹Ã£Æ’»ãƒ
[20:48] <comawhite> ルディング株式会社スクウェア・エニックス・ホールディングス 株式会社スクウェア・エニックス・ホールディングス 株式会社スクウェア・エニックス・ホールディングス 株式会社スクウェア・エニックス・ホールディングス 株式会社スクウェア・エニックス・ホールディングス 株式会社スクウェア・エニックス・ホ
Bookmarks