Correct use and convert unicode from utf8

Move StringUtf8ToWideChar and StringWideCharToUtf8 to CCWinRTUtils(
Replace CCUtf8ToUnicode)
Use StringUtf8ToWideChar for convert utf8 to unicode
Use StringWideCharToUtf8 for convert unicode to utf8
This commit is contained in:
Vladimir Perminov 2015-08-16 12:51:41 +03:00
parent 487c99e632
commit d70a21aa25
10 changed files with 92 additions and 223 deletions

View File

@ -472,53 +472,6 @@ bool Audio::IsSoundEffectStarted(unsigned int sound)
return m_soundEffects[sound].m_soundEffectStarted; return m_soundEffects[sound].m_soundEffectStarted;
} }
std::wstring CCUtf8ToUnicode(const char * pszUtf8Str)
{
std::wstring ret;
do
{
if (! pszUtf8Str) break;
size_t len = strlen(pszUtf8Str);
if (len <= 0) break;
++len;
wchar_t * pwszStr = new wchar_t[len];
if (! pwszStr) break;
pwszStr[len - 1] = 0;
MultiByteToWideChar(CP_UTF8, 0, pszUtf8Str, len, pwszStr, len);
ret = pwszStr;
if(pwszStr) {
delete[] (pwszStr);
(pwszStr) = 0;
}
} while (0);
return ret;
}
std::string CCUnicodeToUtf8(const wchar_t* pwszStr)
{
std::string ret;
do
{
if(! pwszStr) break;
size_t len = wcslen(pwszStr);
if (len <= 0) break;
char * pszUtf8Str = new char[len*3 + 1];
WideCharToMultiByte(CP_UTF8, 0, pwszStr, len+1, pszUtf8Str, len*3 + 1, 0, 0);
ret = pszUtf8Str;
if(pszUtf8Str) {
delete[] (pszUtf8Str);
(pszUtf8Str) = 0;
}
}while(0);
return ret;
}
void Audio::PreloadSoundEffect(const char* pszFilePath, bool isMusic) void Audio::PreloadSoundEffect(const char* pszFilePath, bool isMusic)
{ {
if (m_engineExperiencedCriticalError) { if (m_engineExperiencedCriticalError) {

View File

@ -64,8 +64,6 @@ void AudioCache::readDataTask()
return; return;
} }
std::wstring path(_fileFullPath.begin(), _fileFullPath.end());
if (nullptr != _srcReader) { if (nullptr != _srcReader) {
delete _srcReader; delete _srcReader;
_srcReader = nullptr; _srcReader = nullptr;

View File

@ -97,7 +97,8 @@ bool WAVReader::initialize(const std::string& filePath)
flushChunks(); flushChunks();
_streamer = ref new MediaStreamer; _streamer = ref new MediaStreamer;
_streamer->Initialize(std::wstring(_filePath.begin(), _filePath.end()).c_str(), true);
_streamer->Initialize(StringUtf8ToWideChar(_filePath).c_str(), true);
_wfx = _streamer->GetOutputWaveFormatEx(); _wfx = _streamer->GetOutputWaveFormatEx();
UINT32 dataSize = _streamer->GetMaxStreamLengthInBytes(); UINT32 dataSize = _streamer->GetMaxStreamLengthInBytes();
@ -204,7 +205,7 @@ bool MP3Reader::initialize(const std::string& filePath)
ComPtr<IMFSourceReader> pReader; ComPtr<IMFSourceReader> pReader;
ComPtr<IMFMediaType> ppDecomprsdAudioType; ComPtr<IMFMediaType> ppDecomprsdAudioType;
if (FAILED(hr = MFCreateSourceReaderFromURL(std::wstring(_filePath.begin(), _filePath.end()).c_str(), NULL, &pReader))) { if (FAILED(hr = MFCreateSourceReaderFromURL(StringUtf8ToWideChar(_filePath).c_str(), NULL, &pReader))) {
break; break;
} }
@ -483,7 +484,7 @@ void MP3Reader::readFromMappedWavFile(BYTE *data, size_t offset, int size, UINT
} while (false); } while (false);
} }
Wrappers::FileHandle MP3Reader::openFile(const std::string& path, bool append) Wrappers::FileHandle MP3Reader::openFile(const std::string& filePath, bool append)
{ {
CREATEFILE2_EXTENDED_PARAMETERS extParams = { 0 }; CREATEFILE2_EXTENDED_PARAMETERS extParams = { 0 };
extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
@ -495,7 +496,7 @@ Wrappers::FileHandle MP3Reader::openFile(const std::string& path, bool append)
DWORD access = append ? GENERIC_WRITE : GENERIC_READ; DWORD access = append ? GENERIC_WRITE : GENERIC_READ;
DWORD creation = append ? OPEN_ALWAYS : OPEN_EXISTING; DWORD creation = append ? OPEN_ALWAYS : OPEN_EXISTING;
return Microsoft::WRL::Wrappers::FileHandle(CreateFile2(std::wstring(path.begin(), path.end()).c_str(), access, FILE_SHARE_READ, creation, &extParams)); return Microsoft::WRL::Wrappers::FileHandle(CreateFile2(StringUtf8ToWideChar(filePath).c_str(), access, FILE_SHARE_READ, creation, &extParams));
} }

View File

@ -116,7 +116,7 @@ const char * Application::getCurrentLanguageCode()
result = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numLanguages, pwszLanguagesBuffer, &cchLanguagesBuffer); result = GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &numLanguages, pwszLanguagesBuffer, &cchLanguagesBuffer);
if (result) { if (result) {
code = CCUnicodeToUtf8(pwszLanguagesBuffer); code = StringWideCharToUtf8(pwszLanguagesBuffer);
} }
if (pwszLanguagesBuffer) if (pwszLanguagesBuffer)

View File

@ -35,10 +35,10 @@ NS_CC_BEGIN
void MessageBox(const char * pszMsg, const char * pszTitle) void MessageBox(const char * pszMsg, const char * pszTitle)
{ {
// Create the message dialog and set its content
Platform::String^ message = ref new Platform::String(CCUtf8ToUnicode(pszMsg, -1).c_str());
Platform::String^ title = ref new Platform::String(CCUtf8ToUnicode(pszTitle, -1).c_str());
#ifndef WP8_SHADER_COMPILER #ifndef WP8_SHADER_COMPILER
// Create the message dialog and set its content
Platform::String^ message = PlatformStringFromString(pszMsg);
Platform::String^ title = PlatformStringFromString(pszTitle);
GLViewImpl::sharedOpenGLView()->ShowMessageBox(title, message); GLViewImpl::sharedOpenGLView()->ShowMessageBox(title, message);
#endif #endif
} }

View File

@ -47,55 +47,6 @@ static inline std::string convertPathFormatToUnixStyle(const std::string& path)
return ret; return ret;
} }
static std::wstring StringUtf8ToWideChar(const std::string& strUtf8)
{
std::wstring ret;
if (!strUtf8.empty())
{
int nNum = MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), -1, nullptr, 0);
if (nNum)
{
WCHAR* wideCharString = new WCHAR[nNum + 1];
wideCharString[0] = 0;
nNum = MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), -1, wideCharString, nNum + 1);
ret = wideCharString;
delete[] wideCharString;
}
else
{
CCLOG("Wrong convert to WideChar code:0x%x", GetLastError());
}
}
return ret;
}
static std::string StringWideCharToUtf8(const std::wstring& strWideChar)
{
std::string ret;
if (!strWideChar.empty())
{
int nNum = WideCharToMultiByte(CP_UTF8, 0, strWideChar.c_str(), -1, nullptr, 0, nullptr, FALSE);
if (nNum)
{
char* utf8String = new char[nNum + 1];
utf8String[0] = 0;
nNum = WideCharToMultiByte(CP_UTF8, 0, strWideChar.c_str(), -1, utf8String, nNum + 1, nullptr, FALSE);
ret = utf8String;
delete[] utf8String;
}
else
{
CCLOG("Wrong convert to Utf8 code:0x%x", GetLastError());
}
}
return ret;
}
static std::string UTF8StringToMultiByte(const std::string& strUtf8) static std::string UTF8StringToMultiByte(const std::string& strUtf8)
{ {
std::string ret; std::string ret;
@ -244,8 +195,8 @@ bool CCFileUtilsWinRT::createDirectory(const std::string& path)
} }
WIN32_FILE_ATTRIBUTE_DATA wfad; WIN32_FILE_ATTRIBUTE_DATA wfad;
std::wstring wpath(path.begin(), path.end());
if (!(GetFileAttributesEx(wpath.c_str(), GetFileExInfoStandard, &wfad))) if (!(GetFileAttributesEx(StringUtf8ToWideChar(path).c_str(), GetFileExInfoStandard, &wfad)))
{ {
subpath = ""; subpath = "";
for (unsigned int i = 0; i < dirs.size(); ++i) for (unsigned int i = 0; i < dirs.size(); ++i)
@ -253,8 +204,7 @@ bool CCFileUtilsWinRT::createDirectory(const std::string& path)
subpath += dirs[i]; subpath += dirs[i];
if (i > 0 && !isDirectoryExist(subpath)) if (i > 0 && !isDirectoryExist(subpath))
{ {
std::wstring wsubpath(subpath.begin(), subpath.end()); BOOL ret = CreateDirectory(StringUtf8ToWideChar(subpath).c_str(), NULL);
BOOL ret = CreateDirectory(wsubpath.c_str(), NULL);
if (!ret && ERROR_ALREADY_EXISTS != GetLastError()) if (!ret && ERROR_ALREADY_EXISTS != GetLastError())
{ {
return false; return false;
@ -267,7 +217,7 @@ bool CCFileUtilsWinRT::createDirectory(const std::string& path)
bool CCFileUtilsWinRT::removeDirectory(const std::string& path) bool CCFileUtilsWinRT::removeDirectory(const std::string& path)
{ {
std::wstring wpath = std::wstring(path.begin(), path.end()); std::wstring wpath = StringUtf8ToWideChar(path);
std::wstring files = wpath + L"*.*"; std::wstring files = wpath + L"*.*";
WIN32_FIND_DATA wfd; WIN32_FIND_DATA wfd;
HANDLE search = FindFirstFileEx(files.c_str(), FindExInfoStandard, &wfd, FindExSearchNameMatch, NULL, 0); HANDLE search = FindFirstFileEx(files.c_str(), FindExInfoStandard, &wfd, FindExSearchNameMatch, NULL, 0);
@ -316,12 +266,16 @@ bool CCFileUtilsWinRT::isAbsolutePath(const std::string& strPath) const
bool CCFileUtilsWinRT::removeFile(const std::string &path) bool CCFileUtilsWinRT::removeFile(const std::string &path)
{ {
std::wstring wpath(path.begin(), path.end()); std::wstring wpath = StringUtf8ToWideChar(path);
if (DeleteFile(wpath.c_str())) if (DeleteFile(wpath.c_str()))
{ {
return true; return true;
} }
else
{
CCLOG("Remove file failed with error: %d", GetLastError());
return false; return false;
}
} }
bool CCFileUtilsWinRT::renameFile(const std::string &oldfullpath, const std::string& newfullpath) bool CCFileUtilsWinRT::renameFile(const std::string &oldfullpath, const std::string& newfullpath)
@ -329,16 +283,30 @@ bool CCFileUtilsWinRT::renameFile(const std::string &oldfullpath, const std::str
CCASSERT(!oldfullpath.empty(), "Invalid path"); CCASSERT(!oldfullpath.empty(), "Invalid path");
CCASSERT(!newfullpath.empty(), "Invalid path"); CCASSERT(!newfullpath.empty(), "Invalid path");
std::wstring oldfile(oldfullpath.begin(), oldfullpath.end()); std::regex pat("\\/");
std::wstring newfile(newfullpath.begin(), newfullpath.end()); std::string _oldfullpath = std::regex_replace(oldfullpath, pat, "\\");
std::string _newfullpath = std::regex_replace(newfullpath, pat, "\\");
if (MoveFileEx(oldfile.c_str(), newfile.c_str(), std::wstring _wNewfullpath = StringUtf8ToWideChar(_newfullpath);
MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH))
if (FileUtils::getInstance()->isFileExist(_newfullpath))
{
if (!DeleteFile(_wNewfullpath.c_str()))
{
CCLOGERROR("Fail to delete file %s !Error code is 0x%x", newfullpath.c_str(), GetLastError());
}
}
if (MoveFileEx(StringUtf8ToWideChar(_oldfullpath).c_str(), _wNewfullpath.c_str(),
MOVEFILE_REPLACE_EXISTING & MOVEFILE_WRITE_THROUGH))
{ {
return true; return true;
} }
CCLOG("Rename failed with error: %d", GetLastError()); else
{
CCLOGERROR("Fail to rename file %s to %s !Error code is 0x%x", oldfullpath.c_str(), newfullpath.c_str(), GetLastError());
return false; return false;
}
} }
bool CCFileUtilsWinRT::renameFile(const std::string &path, const std::string &oldname, const std::string &name) bool CCFileUtilsWinRT::renameFile(const std::string &path, const std::string &oldname, const std::string &name)
@ -347,71 +315,17 @@ bool CCFileUtilsWinRT::renameFile(const std::string &path, const std::string &ol
std::string oldPath = path + oldname; std::string oldPath = path + oldname;
std::string newPath = path + name; std::string newPath = path + name;
std::regex pat("\\/"); return renameFile(oldPath, newPath);
std::string _old = std::regex_replace(oldPath, pat, "\\");
std::string _new = std::regex_replace(newPath, pat, "\\");
return renameFile(_old, _new);
}
static Data getData(const std::string& filename, bool forString)
{
if (filename.empty())
{
CCASSERT(!filename.empty(), "Invalid filename!");
}
Data ret;
unsigned char* buffer = nullptr;
ssize_t size = 0;
const char* mode = nullptr;
mode = "rb";
do
{
// Read the file from hardware
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename);
FILE *fp = fopen(fullPath.c_str(), mode);
CC_BREAK_IF(!fp);
fseek(fp,0,SEEK_END);
size = ftell(fp);
fseek(fp,0,SEEK_SET);
if (forString)
{
buffer = (unsigned char*)malloc(sizeof(unsigned char) * (size + 1));
buffer[size] = '\0';
}
else
{
buffer = (unsigned char*)malloc(sizeof(unsigned char) * size);
}
size = fread(buffer, sizeof(unsigned char), size, fp);
fclose(fp);
} while (0);
if (nullptr == buffer || 0 == size)
{
std::string msg = "Get data from file(";
msg.append(filename).append(") failed!");
CCLOG("%s", msg.c_str());
}
else
{
ret.fastSet(buffer, size);
}
return ret;
} }
std::string CCFileUtilsWinRT::getStringFromFile(const std::string& filename) std::string CCFileUtilsWinRT::getStringFromFile(const std::string& filename)
{ {
Data data = getData(filename, true); Data data = getDataFromFile(filename);
if (data.isNull()) if (data.isNull())
{ {
return ""; return "";
} }
std::string ret((const char*)data.getBytes()); std::string ret((const char*)data.getBytes(), data.getSize());
return ret; return ret;
} }

View File

@ -210,7 +210,7 @@ void CCPrecompiledShaders::savePrecompiledPrograms(Windows::Storage::StorageFold
for (auto iter = m_programs.begin(); iter != m_programs.end(); ++iter) for (auto iter = m_programs.begin(); iter != m_programs.end(); ++iter)
{ {
CompiledProgram* p = (CompiledProgram*)iter->second; CompiledProgram* p = (CompiledProgram*)iter->second;
Platform::String^ keyName = ref new Platform::String(CCUtf8ToUnicode(p->key.c_str()).c_str()); Platform::String^ keyName = PlatformStringFromString(p->key);
Platform::String^ programName = SHADER_NAME_PREFIX + keyName; Platform::String^ programName = SHADER_NAME_PREFIX + keyName;
dataWriter->WriteString("const unsigned char "); dataWriter->WriteString("const unsigned char ");
@ -225,12 +225,12 @@ void CCPrecompiledShaders::savePrecompiledPrograms(Windows::Storage::StorageFold
if(i % 8 == 0) if(i % 8 == 0)
dataWriter->WriteString("\n"); dataWriter->WriteString("\n");
sprintf_s(temp, "%3i, ", buffer[i]); sprintf_s(temp, "%3i, ", buffer[i]);
dataWriter->WriteString(ref new Platform::String(CCUtf8ToUnicode(temp).c_str())); dataWriter->WriteString(PlatformStringFromString(temp));
} }
if((p->length - 1) % 8 == 0) if((p->length - 1) % 8 == 0)
dataWriter->WriteString("\n"); dataWriter->WriteString("\n");
sprintf_s(temp, "%3i, ", buffer[p->length - 1]); sprintf_s(temp, "%3i, ", buffer[p->length - 1]);
dataWriter->WriteString(ref new Platform::String(CCUtf8ToUnicode(temp).c_str())); dataWriter->WriteString(PlatformStringFromString(temp));
dataWriter->WriteString("\n};\n\n"); dataWriter->WriteString("\n};\n\n");
if(numPrograms != 0) if(numPrograms != 0)

View File

@ -47,61 +47,62 @@ using namespace Windows::Storage::Pickers;
using namespace Windows::Storage::Streams; using namespace Windows::Storage::Streams;
using namespace Windows::Networking::Connectivity; using namespace Windows::Networking::Connectivity;
std::wstring CCUtf8ToUnicode(const char * pszUtf8Str, unsigned len/* = -1*/) std::wstring StringUtf8ToWideChar(const std::string& strUtf8)
{ {
std::wstring ret; std::wstring ret;
do if (!strUtf8.empty())
{ {
if (! pszUtf8Str) break; int nNum = MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), -1, nullptr, 0);
// get UTF8 string length if (nNum)
if (-1 == len)
{ {
len = strlen(pszUtf8Str); WCHAR* wideCharString = new WCHAR[nNum + 1];
wideCharString[0] = 0;
nNum = MultiByteToWideChar(CP_UTF8, 0, strUtf8.c_str(), -1, wideCharString, nNum + 1);
ret = wideCharString;
delete[] wideCharString;
}
else
{
CCLOG("Wrong convert to WideChar code:0x%x", GetLastError());
}
} }
if (len <= 0) break;
// get UTF16 string length
int wLen = MultiByteToWideChar(CP_UTF8, 0, pszUtf8Str, len, 0, 0);
if (0 == wLen || 0xFFFD == wLen) break;
// convert string
wchar_t * pwszStr = new wchar_t[wLen + 1];
if (! pwszStr) break;
pwszStr[wLen] = 0;
MultiByteToWideChar(CP_UTF8, 0, pszUtf8Str, len, pwszStr, wLen + 1);
ret = pwszStr;
CC_SAFE_DELETE_ARRAY(pwszStr);
} while (0);
return ret; return ret;
} }
std::string CCUnicodeToUtf8(const wchar_t* pwszStr) std::string StringWideCharToUtf8(const std::wstring& strWideChar)
{ {
std::string ret; std::string ret;
do if (!strWideChar.empty())
{ {
if(! pwszStr) break; int nNum = WideCharToMultiByte(CP_UTF8, 0, strWideChar.c_str(), -1, nullptr, 0, nullptr, FALSE);
size_t len = wcslen(pwszStr); if (nNum)
if (len <= 0) break; {
char* utf8String = new char[nNum + 1];
utf8String[0] = 0;
size_t convertedChars = 0; nNum = WideCharToMultiByte(CP_UTF8, 0, strWideChar.c_str(), -1, utf8String, nNum + 1, nullptr, FALSE);
char * pszUtf8Str = new char[len*3 + 1];
WideCharToMultiByte(CP_UTF8, 0, pwszStr, len+1, pszUtf8Str, len*3 + 1, 0, 0); ret = utf8String;
ret = pszUtf8Str; delete[] utf8String;
CC_SAFE_DELETE_ARRAY(pszUtf8Str); }
}while(0); else
{
CCLOG("Wrong convert to Utf8 code:0x%x", GetLastError());
}
}
return ret; return ret;
} }
std::string PlatformStringToString(Platform::String^ s) { std::string PlatformStringToString(Platform::String^ s) {
std::wstring t = std::wstring(s->Data()); return StringWideCharToUtf8(std::wstring(s->Data()));
return std::string(t.begin(),t.end());
} }
Platform::String^ PlatformStringFromString(const std::string& s) Platform::String^ PlatformStringFromString(const std::string& s)
{ {
std::wstring ws(CCUtf8ToUnicode(s.c_str())); std::wstring ws = StringUtf8ToWideChar(s);
return ref new Platform::String(ws.data(), ws.length()); return ref new Platform::String(ws.data(), ws.length());
} }

View File

@ -38,8 +38,11 @@ NS_CC_BEGIN
std::wstring CC_DLL CCUtf8ToUnicode(const char * pszUtf8Str, unsigned len = -1);
std::string CC_DLL CCUnicodeToUtf8(const wchar_t* pwszStr);
std::wstring CC_DLL StringUtf8ToWideChar(const std::string& strUtf8);
std::string CC_DLL StringWideCharToUtf8(const std::wstring& strWideChar);
Platform::Object^ findXamlElement(Platform::Object^ parent, Platform::String^ name); Platform::Object^ findXamlElement(Platform::Object^ parent, Platform::String^ name);
bool removeXamlElement(Platform::Object^ parent, Platform::Object^ element); bool removeXamlElement(Platform::Object^ parent, Platform::Object^ element);
bool replaceXamlElement(Platform::Object^ parent, Platform::Object^ add, Platform::Object^ remove); bool replaceXamlElement(Platform::Object^ parent, Platform::Object^ add, Platform::Object^ remove);

View File

@ -25,6 +25,7 @@ Based upon code from the DirectX Tool Kit by Microsoft Corporation,
obtained from https://directxtk.codeplex.com obtained from https://directxtk.codeplex.com
****************************************************************************/ ****************************************************************************/
#include "WICImageLoader-winrt.h" #include "WICImageLoader-winrt.h"
#include "CCWinRTUtils.h"
NS_CC_BEGIN NS_CC_BEGIN
@ -321,9 +322,7 @@ bool WICImageLoader::encodeImageData(std::string path, const unsigned char* data
} }
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
std::wstring wpath; hr = pStream->InitializeFromFilename(StringUtf8ToWideChar(path).c_str(), GENERIC_WRITE);
wpath.assign(path.begin(), path.end());
hr = pStream->InitializeFromFilename(wpath.c_str(), GENERIC_WRITE);
} }
IWICBitmapEncoder* pEnc = NULL; IWICBitmapEncoder* pEnc = NULL;