Fixed utf8 issue in history manager.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4626 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2011-10-01 13:12:28 +00:00
parent c650265704
commit 363af69254
11 changed files with 248 additions and 73 deletions

View File

@ -22,7 +22,7 @@
*/
#ifdef WINDOWS_SYS
#include "util/rswin.h"
#include "util/rsstring.h"
#endif
#include "dbase/fimonitor.h"

View File

@ -36,7 +36,7 @@
*/
#ifdef WINDOWS_SYS
#include "util/rswin.h"
#include "util/rsstring.h"
#endif
#include "util/rsdiscspace.h"

View File

@ -455,6 +455,7 @@ HEADERS += util/folderiterator.h \
util/extaddrfinder.h \
util/dnsresolver.h \
util/rsprint.h \
util/rsstring.h \
util/rsthreads.h \
util/rsversion.h \
util/rswin.h \
@ -587,6 +588,7 @@ SOURCES += util/folderiterator.cc \
util/extaddrfinder.cc \
util/dnsresolver.cc \
util/rsprint.cc \
util/rsstring.cc \
util/rsthreads.cc \
util/rsversion.cc \
util/rswin.cc \

View File

@ -29,6 +29,7 @@
#include "retroshare/rsiface.h"
#include "retroshare/rspeers.h"
#include "serialiser/rsmsgitems.h"
#include "util/rsstring.h"
RsHistory *rsHistory = NULL;
@ -71,7 +72,8 @@ void p3HistoryMgr::addMessage(bool incoming, const std::string &chatPeerId, cons
item->peerName = rsPeers->getPeerName(item->peerId);
item->sendTime = chatItem->sendTime;
item->recvTime = chatItem->recvTime;
item->message.assign(chatItem->message.begin(), chatItem->message.end());
librs::util::ConvertUtf16ToUtf8(chatItem->message, item->message);
std::map<std::string, std::map<uint32_t, RsHistoryMsgItem*> >::iterator mit = mMessages.find(item->chatPeerId);
if (mit != mMessages.end()) {

View File

@ -37,6 +37,7 @@
#include "util/rsdir.h"
#include "util/rsrandom.h"
#include "util/folderiterator.h"
#include "util/rsstring.h"
#include "retroshare/rsinit.h"
#include "plugins/pluginmanager.h"
#include "rsserver/rsloginhandler.h"

View File

@ -1,5 +1,5 @@
#include "folderiterator.h"
#include "rswin.h"
#include "rsstring.h"
namespace librs { namespace util {

View File

@ -45,7 +45,7 @@
#include <fstream>
#if defined(WIN32) || defined(__CYGWIN__)
#include "util/rswin.h"
#include "util/rsstring.h"
#include "wtypes.h"
#include <winioctl.h>
#else

View File

@ -0,0 +1,203 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2010, Thomas Kister
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#include "rsstring.h"
#ifdef WINDOWS_SYS
#include <windows.h>
#else
#include <vector>
#endif
namespace librs { namespace util {
bool ConvertUtf8ToUtf16(const std::string& source, std::wstring& dest)
{
if (source.empty()) {
dest.clear();
return true;
}
#ifdef WINDOWS_SYS
int nbChars = MultiByteToWideChar(CP_UTF8, 0, source.c_str(), -1, 0, 0);
if(nbChars == 0) {
return false;
}
wchar_t* utf16Name = new wchar_t[nbChars];
if( MultiByteToWideChar(CP_UTF8, 0, source.c_str(), -1, utf16Name, nbChars) == 0) {
delete[] utf16Name;
return false;
}
dest = utf16Name;
delete[] utf16Name;
#else
std::vector<wchar_t> res;
std::string::size_type len = source.length();
unsigned int i = 0;
unsigned long temp;
while (i < len) {
char src = source[i];
if ((src & 0x80) == 0) { // ASCII : 0000 0000-0000 007F 0xxxxxxx
temp = src;
++i;
} else if ((src & 0xE0) == 0xC0) { // 0000 0080-0000 07FF 110xxxxx 10xxxxxx
temp = (src & 0x1F);
temp <<= 6;
temp += (source[i + 1] & 0x3F);
i += 2;
} else if ((src & 0xF0) == 0xE0) { // 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
temp = (src & 0x0F);
temp <<= 6;
temp += (source[i + 1] & 0x3F);
temp <<= 6;
temp += (source[i + 2] & 0x3F);
i += 3;
} else if ((src & 0xF8) == 0xF0) { // 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
temp = (src & 0x07);
temp <<= 6;
temp += (source[i + 1] & 0x3F);
temp <<= 6;
temp += (source[i + 2] & 0x3F);
temp <<= 6;
temp += (source[i + 3] & 0x3F);
i += 4;
} else if ((src & 0xFC) == 0xF8) { // 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
temp = (src & 0x03);
temp <<= 6;
temp += (source[i + 1] & 0x3F);
temp <<= 6;
temp += (source[i + 2] & 0x3F);
temp <<= 6;
temp += (source[i + 3] & 0x3F);
temp <<= 6;
temp += (source[i + 4] & 0x3F);
i += 5;
} else if ((src & 0xFE) == 0xFC) { // 0400 0000-7FFF FFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
temp = (src & 0x01);
temp <<= 6;
temp += (source[i + 1] & 0x3F);
temp <<= 6;
temp += (source[i + 2] & 0x3F);
temp <<= 6;
temp += (source[i + 3] & 0x3F);
temp <<= 6;
temp += (source[i + 4] & 0x3F);
temp <<= 6;
temp += (source[i + 5] & 0x3F);
i += 6;
} else {
temp = '?';
}
// Need to transform to UTF-16 > handle surrogates
if (temp > 0xFFFF) {
// First high surrogate
res.push_back(0xD800 + wchar_t(temp >> 10));
// Now low surrogate
res.push_back(0xDC00 + wchar_t(temp & 0x3FF));
} else {
res.push_back(wchar_t(temp));
}
}
// Check whether first wchar_t is the BOM 0xFEFF
if (res[0] == 0xFEFF) {
dest.append(&res[1], res.size() - 1);
} else {
dest.append(&res[0], res.size());
}
#endif
return true;
}
bool ConvertUtf16ToUtf8(const std::wstring& source, std::string& dest)
{
#ifdef WINDOWS_SYS
int nbChars = WideCharToMultiByte(CP_UTF8, 0, source.c_str(), -1, 0, 0, 0, 0);
if(nbChars == 0) {
return false;
}
char* utf8Name = new char[nbChars];
if( WideCharToMultiByte(CP_UTF8, 0, source.c_str(), -1, utf8Name, nbChars, 0, 0) == 0) {
delete[] utf8Name;
return false;
}
dest = utf8Name;
delete[] utf8Name;
#else
std::vector<char> res;
std::wstring::size_type len = source.length();
unsigned int i = 0;
unsigned long temp;
while (i < len) {
if ((source[i] & 0xD800) == 0xD800) { // surrogate
temp = (source[i] - 0xD800);
temp <<= 10;
temp += (source[i + 1] - 0xDC00);
i += 2;
} else {
temp = source[i];
++i;
}
if (temp < 0x00000080) { // ASCII : 0000 0000-0000 007F 0xxxxxxx
res.push_back(char(temp));
} else if (temp < 0x00000800) { // 0000 0080-0000 07FF 110xxxxx 10xxxxxx
res.push_back(char(0xC0 | (temp >> 6)));
res.push_back(char(0x80 | (temp & 0x3F)));
} else if (temp < 0x00010000) { // 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
res.push_back(char(0xE0 | (temp >> 12)));
res.push_back(char(0x80 | ((temp >> 6) & 0x3F)));
res.push_back(char(0x80 | (temp & 0x3F)));
} else if (temp < 0x00200000) { // 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
res.push_back(char(0xF0 | (temp >> 18)));
res.push_back(char(0x80 | ((temp >> 12) & 0x3F)));
res.push_back(char(0x80 | ((temp >> 6) & 0x3F)));
res.push_back(char(0x80 | (temp & 0x3F)));
} else if (temp < 0x04000000) { // 0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
res.push_back(char(0xF8 | (temp >> 24)));
res.push_back(char(0x80 | ((temp >> 18) & 0x3F)));
res.push_back(char(0x80 | ((temp >> 12) & 0x3F)));
res.push_back(char(0x80 | ((temp >> 6) & 0x3F)));
res.push_back(char(0x80 | (temp & 0x3F)));
} else if (temp < 0x80000000) { // 0400 0000-7FFF FFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
res.push_back(char(0xFC | (temp >> 30)));
res.push_back(char(0x80 | ((temp >> 24) & 0x3F)));
res.push_back(char(0x80 | ((temp >> 18) & 0x3F)));
res.push_back(char(0x80 | ((temp >> 12) & 0x3F)));
res.push_back(char(0x80 | ((temp >> 6) & 0x3F)));
res.push_back(char(0x80 | (temp & 0x3F)));
}
}
dest.append(&res[0], res.size());
#endif
return true;
}
} } // librs::util

View File

@ -0,0 +1,34 @@
/****************************************************************
* This file is distributed under the following license:
*
* Copyright (c) 2010, Thomas Kister
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
#ifndef RSSTRING_H_
#define RSSTRING_H_
#include <string>
namespace librs { namespace util {
bool ConvertUtf8ToUtf16(const std::string& source, std::wstring& dest);
bool ConvertUtf16ToUtf8(const std::wstring& source, std::string& dest);
} } // librs::util
#endif // RSSTRING_H_

View File

@ -1,55 +1 @@
#include "util/rswin.h"
#ifdef WINDOWS_SYS
namespace librs { namespace util {
bool ConvertUtf8ToUtf16(const std::string& source, std::wstring& dest) {
int nbChars = MultiByteToWideChar(CP_UTF8, 0,
source.c_str(), -1,
0, 0);
if(nbChars == 0)
return false;
wchar_t* utf16Name = new wchar_t[nbChars];
if( MultiByteToWideChar(CP_UTF8, 0,
source.c_str(), -1,
utf16Name, nbChars) == 0) {
return false;
}
dest = utf16Name;
delete[] utf16Name;
return true;
}
bool ConvertUtf16ToUtf8(const std::wstring& source, std::string& dest) {
int nbChars = WideCharToMultiByte(CP_UTF8, 0,
source.c_str(), -1,
0, 0,
0, 0);
if(nbChars == 0)
return false;
char* utf8Name = new char[nbChars];
if( WideCharToMultiByte(CP_UTF8, 0,
source.c_str(), -1,
utf8Name, nbChars,
0, 0) == 0) {
return false;
}
dest = utf8Name;
delete[] utf8Name;
return true;
}
} } // librs::util
#endif // WINDOWS_SYS

View File

@ -43,21 +43,8 @@
#include <string>
// For win32 systems (tested on MingW+Ubuntu)
#define stat64 _stati64
namespace librs { namespace util {
bool ConvertUtf8ToUtf16(const std::string& source, std::wstring& dest);
bool ConvertUtf16ToUtf8(const std::wstring& source, std::string& dest);
} } // librs::util
#define stat64 _stati64
#endif // WINDOWS_SYS
#endif // RSWIN_H_