mirror of https://github.com/axmolengine/axmol.git
Add FileUtils::getSuitableFOpen
win32 fopen only ansi encoding. if filePath contains utf8 characters fopen fail. AudioCache FileFormat::OGG bag, can't open file, if filePath contains utf8. Need make all filename for fopen correct encoding. Only Win32 FileUtils::getSuitableFOpen return StringUtf8ToAnsi(filename), other platform return filename all fopen use FileUtils::getSuitableFOpen
This commit is contained in:
parent
425b2b62e1
commit
694b9adc1e
|
@ -29,6 +29,7 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "base/CCConsole.h"
|
#include "base/CCConsole.h"
|
||||||
|
#include "platform/CCFileUtils.h"
|
||||||
#include "mpg123.h"
|
#include "mpg123.h"
|
||||||
#include "vorbis/codec.h"
|
#include "vorbis/codec.h"
|
||||||
#include "vorbis/vorbisfile.h"
|
#include "vorbis/vorbisfile.h"
|
||||||
|
@ -96,8 +97,9 @@ void AudioCache::readDataTask()
|
||||||
case FileFormat::OGG:
|
case FileFormat::OGG:
|
||||||
{
|
{
|
||||||
vf = new OggVorbis_File;
|
vf = new OggVorbis_File;
|
||||||
if (ov_fopen(_fileFullPath.c_str(), vf)){
|
int openCode;
|
||||||
log("Input does not appear to be an Ogg bitstream.\n");
|
if (openCode = ov_fopen(FileUtils::getInstance()->getSuitableFOpen(_fileFullPath).c_str(), vf)){
|
||||||
|
log("Input does not appear to be an Ogg bitstream: %s. Code: 0x%x\n", _fileFullPath.c_str(), openCode);
|
||||||
goto ExitThread;
|
goto ExitThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "AudioPlayer.h"
|
#include "AudioPlayer.h"
|
||||||
#include "AudioCache.h"
|
#include "AudioCache.h"
|
||||||
#include "base/CCConsole.h"
|
#include "base/CCConsole.h"
|
||||||
|
#include "platform/CCFileUtils.h"
|
||||||
#include "mpg123.h"
|
#include "mpg123.h"
|
||||||
#include "vorbis/codec.h"
|
#include "vorbis/codec.h"
|
||||||
#include "vorbis/vorbisfile.h"
|
#include "vorbis/vorbisfile.h"
|
||||||
|
@ -162,8 +163,9 @@ void AudioPlayer::rotateBufferThread(int offsetFrame)
|
||||||
case AudioCache::FileFormat::OGG:
|
case AudioCache::FileFormat::OGG:
|
||||||
{
|
{
|
||||||
vorbisFile = new OggVorbis_File;
|
vorbisFile = new OggVorbis_File;
|
||||||
if (ov_fopen(_audioCache->_fileFullPath.c_str(), vorbisFile)){
|
int openCode;
|
||||||
log("Input does not appear to be an Ogg bitstream.\n");
|
if (openCode = ov_fopen(FileUtils::getInstance()->getSuitableFOpen(_audioCache->_fileFullPath).c_str(), vorbisFile)){
|
||||||
|
log("Input does not appear to be an Ogg bitstream: %s. Code: 0x%x\n", _audioCache->_fileFullPath.c_str(), openCode);
|
||||||
goto ExitBufferThread;
|
goto ExitBufferThread;
|
||||||
}
|
}
|
||||||
if (offsetFrame != 0) {
|
if (offsetFrame != 0) {
|
||||||
|
|
|
@ -330,7 +330,6 @@ Console::Console()
|
||||||
{
|
{
|
||||||
_commands[commands[i].name] = commands[i];
|
_commands[commands[i].name] = commands[i];
|
||||||
}
|
}
|
||||||
_writablePath = FileUtils::getInstance()->getWritablePath();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Console::~Console()
|
Console::~Console()
|
||||||
|
@ -870,9 +869,10 @@ void Console::commandUpload(int fd)
|
||||||
}
|
}
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
|
|
||||||
std::string filepath = _writablePath + std::string(buf);
|
static std::string writablePath = FileUtils::getInstance()->getWritablePath();
|
||||||
|
std::string filepath = writablePath + std::string(buf);
|
||||||
|
|
||||||
FILE* fp = fopen(filepath.c_str(), "wb");
|
FILE* fp = fopen(FileUtils::getInstance()->getSuitableFOpen(filepath).c_str(), "wb");
|
||||||
if(!fp)
|
if(!fp)
|
||||||
{
|
{
|
||||||
const char err[] = "can't create file!\n";
|
const char err[] = "can't create file!\n";
|
||||||
|
|
|
@ -140,8 +140,6 @@ protected:
|
||||||
bool _running;
|
bool _running;
|
||||||
bool _endThread;
|
bool _endThread;
|
||||||
|
|
||||||
std::string _writablePath;
|
|
||||||
|
|
||||||
std::map<std::string, Command> _commands;
|
std::map<std::string, Command> _commands;
|
||||||
|
|
||||||
// strings generated by cocos2d sent to the remote console
|
// strings generated by cocos2d sent to the remote console
|
||||||
|
|
|
@ -132,7 +132,7 @@ static void setValueForKey(const char* pKey, const char* pValue)
|
||||||
// save file and free doc
|
// save file and free doc
|
||||||
if (doc)
|
if (doc)
|
||||||
{
|
{
|
||||||
doc->SaveFile(UserDefault::getInstance()->getXMLFilePath().c_str());
|
doc->SaveFile(FileUtils::getInstance()->getSuitableFOpen(UserDefault::getInstance()->getXMLFilePath()).c_str());
|
||||||
delete doc;
|
delete doc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -484,7 +484,7 @@ bool UserDefault::createXMLFile()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pDoc->LinkEndChild(pRootEle);
|
pDoc->LinkEndChild(pRootEle);
|
||||||
bRet = tinyxml2::XML_SUCCESS == pDoc->SaveFile(_filePath.c_str());
|
bRet = tinyxml2::XML_SUCCESS == pDoc->SaveFile(FileUtils::getInstance()->getSuitableFOpen(_filePath).c_str());
|
||||||
|
|
||||||
if(pDoc)
|
if(pDoc)
|
||||||
{
|
{
|
||||||
|
|
|
@ -403,7 +403,7 @@ bool FileUtils::writeToFile(ValueMap& dict, const std::string &fullPath)
|
||||||
}
|
}
|
||||||
rootEle->LinkEndChild(innerDict);
|
rootEle->LinkEndChild(innerDict);
|
||||||
|
|
||||||
bool ret = tinyxml2::XML_SUCCESS == doc->SaveFile(fullPath.c_str());
|
bool ret = tinyxml2::XML_SUCCESS == doc->SaveFile(getSuitableFOpen(fullPath).c_str());
|
||||||
|
|
||||||
delete doc;
|
delete doc;
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -566,7 +566,7 @@ static Data getData(const std::string& filename, bool forString)
|
||||||
{
|
{
|
||||||
// Read the file from hardware
|
// Read the file from hardware
|
||||||
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename);
|
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename);
|
||||||
FILE *fp = fopen(fullPath.c_str(), mode);
|
FILE *fp = fopen(FileUtils::getInstance()->getSuitableFOpen(fullPath).c_str(), mode);
|
||||||
CC_BREAK_IF(!fp);
|
CC_BREAK_IF(!fp);
|
||||||
fseek(fp,0,SEEK_END);
|
fseek(fp,0,SEEK_END);
|
||||||
size = ftell(fp);
|
size = ftell(fp);
|
||||||
|
@ -629,7 +629,7 @@ unsigned char* FileUtils::getFileData(const std::string& filename, const char* m
|
||||||
{
|
{
|
||||||
// read the file from hardware
|
// read the file from hardware
|
||||||
const std::string fullPath = fullPathForFilename(filename);
|
const std::string fullPath = fullPathForFilename(filename);
|
||||||
FILE *fp = fopen(fullPath.c_str(), mode);
|
FILE *fp = fopen(getSuitableFOpen(fullPath).c_str(), mode);
|
||||||
CC_BREAK_IF(!fp);
|
CC_BREAK_IF(!fp);
|
||||||
|
|
||||||
fseek(fp,0,SEEK_END);
|
fseek(fp,0,SEEK_END);
|
||||||
|
@ -1364,5 +1364,10 @@ bool FileUtils::isPopupNotify() const
|
||||||
return s_popupNotify;
|
return s_popupNotify;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string FileUtils::getSuitableFOpen(const std::string& filenameUtf8) const
|
||||||
|
{
|
||||||
|
return filenameUtf8;
|
||||||
|
}
|
||||||
|
|
||||||
NS_CC_END
|
NS_CC_END
|
||||||
|
|
||||||
|
|
|
@ -330,6 +330,16 @@ public:
|
||||||
// This method is used internally.
|
// This method is used internally.
|
||||||
virtual bool writeToFile(ValueMap& dict, const std::string& fullPath);
|
virtual bool writeToFile(ValueMap& dict, const std::string& fullPath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Windows fopen can't support UTF-8 filename
|
||||||
|
* Need convert all parameters fopen and other 3rd-party libs
|
||||||
|
* CC_PLATFORM_WP8 and CC_PLATFORM_WINRT the same needs?
|
||||||
|
*
|
||||||
|
* @param filename std::string name file for convertation from utf-8
|
||||||
|
* @return std::string ansi filename in current locale
|
||||||
|
*/
|
||||||
|
virtual std::string getSuitableFOpen(const std::string& filenameUtf8) const;
|
||||||
|
|
||||||
// Converts the contents of a file to a ValueVector.
|
// Converts the contents of a file to a ValueVector.
|
||||||
// This method is used internally.
|
// This method is used internally.
|
||||||
virtual ValueVector getValueVectorFromFile(const std::string& filename);
|
virtual ValueVector getValueVectorFromFile(const std::string& filename);
|
||||||
|
|
|
@ -2232,7 +2232,7 @@ bool Image::saveImageToPNG(const std::string& filePath, bool isToRGB)
|
||||||
png_colorp palette;
|
png_colorp palette;
|
||||||
png_bytep *row_pointers;
|
png_bytep *row_pointers;
|
||||||
|
|
||||||
fp = fopen(filePath.c_str(), "wb");
|
fp = fopen(FileUtils::getInstance()->getSuitableFOpen(filePath).c_str(), "wb");
|
||||||
CC_BREAK_IF(nullptr == fp);
|
CC_BREAK_IF(nullptr == fp);
|
||||||
|
|
||||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||||
|
@ -2388,7 +2388,7 @@ bool Image::saveImageToJPG(const std::string& filePath)
|
||||||
/* Now we can initialize the JPEG compression object. */
|
/* Now we can initialize the JPEG compression object. */
|
||||||
jpeg_create_compress(&cinfo);
|
jpeg_create_compress(&cinfo);
|
||||||
|
|
||||||
CC_BREAK_IF((outfile = fopen(filePath.c_str(), "wb")) == nullptr);
|
CC_BREAK_IF((outfile = fopen(FileUtils::getInstance()->getSuitableFOpen(filePath).c_str(), "wb")) == nullptr);
|
||||||
|
|
||||||
jpeg_stdio_dest(&cinfo, outfile);
|
jpeg_stdio_dest(&cinfo, outfile);
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,81 @@ 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 StringUtf8ToAnsi(const std::string& strUtf8)
|
||||||
|
{
|
||||||
|
std::string ret;
|
||||||
|
if (!strUtf8.empty())
|
||||||
|
{
|
||||||
|
std::wstring strWideChar = NS_CC::StringUtf8ToWideChar(strUtf8);
|
||||||
|
int nNum = WideCharToMultiByte(CP_ACP, 0, strWideChar.c_str(), -1, nullptr, 0, nullptr, FALSE);
|
||||||
|
if (nNum)
|
||||||
|
{
|
||||||
|
char* ansiString = new char[nNum + 1];
|
||||||
|
ansiString[0] = 0;
|
||||||
|
|
||||||
|
nNum = WideCharToMultiByte(CP_ACP, 0, strWideChar.c_str(), -1, ansiString, nNum + 1, nullptr, FALSE);
|
||||||
|
|
||||||
|
ret = ansiString;
|
||||||
|
delete[] ansiString;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCLOG("Wrong convert to Ansi code:0x%x", GetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void _checkPath()
|
static void _checkPath()
|
||||||
{
|
{
|
||||||
if (0 == s_resourcePath.length())
|
if (0 == s_resourcePath.length())
|
||||||
|
@ -334,6 +409,11 @@ string FileUtilsWin32::getWritablePath() const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string FileUtilsWin32::getSuitableFOpen(const std::string& filenameUtf8) const
|
||||||
|
{
|
||||||
|
return StringUtf8ToAnsi(filenameUtf8);
|
||||||
|
}
|
||||||
|
|
||||||
NS_CC_END
|
NS_CC_END
|
||||||
|
|
||||||
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
||||||
|
|
|
@ -55,6 +55,17 @@ protected:
|
||||||
|
|
||||||
virtual bool isFileExistInternal(const std::string& strFilePath) const;
|
virtual bool isFileExistInternal(const std::string& strFilePath) const;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Windows fopen can't support UTF-8 filename
|
||||||
|
* Need convert all parameters fopen and other 3rd-party libs
|
||||||
|
* CC_PLATFORM_WP8 and CC_PLATFORM_WINRT the same needs?
|
||||||
|
*
|
||||||
|
* @param filename std::string name file for convertation from utf-8
|
||||||
|
* @return std::string ansi filename in current locale
|
||||||
|
*/
|
||||||
|
virtual std::string getSuitableFOpen(const std::string& filenameUtf8) const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets resource file data
|
* Gets resource file data
|
||||||
*
|
*
|
||||||
|
|
|
@ -359,7 +359,7 @@ bool AssetsManager::uncompress()
|
||||||
{
|
{
|
||||||
const string dir=_storagePath+fileNameStr.substr(0,index);
|
const string dir=_storagePath+fileNameStr.substr(0,index);
|
||||||
|
|
||||||
FILE *out = fopen(dir.c_str(), "r");
|
FILE *out = fopen(FileUtils::getInstance()->getSuitableFOpen(dir).c_str(), "r");
|
||||||
|
|
||||||
if(!out)
|
if(!out)
|
||||||
{
|
{
|
||||||
|
@ -398,7 +398,7 @@ bool AssetsManager::uncompress()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a file to store current file.
|
// Create a file to store current file.
|
||||||
FILE *out = fopen(fullPath.c_str(), "wb");
|
FILE *out = fopen(FileUtils::getInstance()->getSuitableFOpen(fullPath).c_str(), "wb");
|
||||||
if (! out)
|
if (! out)
|
||||||
{
|
{
|
||||||
CCLOG("can not open destination file %s", fullPath.c_str());
|
CCLOG("can not open destination file %s", fullPath.c_str());
|
||||||
|
@ -517,7 +517,7 @@ bool AssetsManager::downLoad()
|
||||||
{
|
{
|
||||||
// Create a file to save package.
|
// Create a file to save package.
|
||||||
const string outFileName = _storagePath + TEMP_PACKAGE_FILE_NAME;
|
const string outFileName = _storagePath + TEMP_PACKAGE_FILE_NAME;
|
||||||
FILE *fp = fopen(outFileName.c_str(), "wb");
|
FILE *fp = fopen(FileUtils::getInstance()->getSuitableFOpen(outFileName).c_str(), "wb");
|
||||||
if (! fp)
|
if (! fp)
|
||||||
{
|
{
|
||||||
Director::getInstance()->getScheduler()->performFunctionInCocosThread([&, this]{
|
Director::getInstance()->getScheduler()->performFunctionInCocosThread([&, this]{
|
||||||
|
|
|
@ -355,7 +355,7 @@ bool AssetsManagerEx::decompress(const std::string &zip)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a file to store current file.
|
// Create a file to store current file.
|
||||||
FILE *out = fopen(fullPath.c_str(), "wb");
|
FILE *out = fopen(FileUtils::getInstance()->getSuitableFOpen(fullPath).c_str(), "wb");
|
||||||
if (!out)
|
if (!out)
|
||||||
{
|
{
|
||||||
CCLOG("AssetsManagerEx : can not create decompress destination file %s\n", fullPath.c_str());
|
CCLOG("AssetsManagerEx : can not create decompress destination file %s\n", fullPath.c_str());
|
||||||
|
|
|
@ -259,11 +259,11 @@ void Downloader::prepareDownload(const std::string &srcUrl, const std::string &s
|
||||||
const std::string outFileName = storagePath + TEMP_EXT;
|
const std::string outFileName = storagePath + TEMP_EXT;
|
||||||
if (_supportResuming && resumeDownload && _fileUtils->isFileExist(outFileName))
|
if (_supportResuming && resumeDownload && _fileUtils->isFileExist(outFileName))
|
||||||
{
|
{
|
||||||
fDesc->fp = fopen(outFileName.c_str(), "ab");
|
fDesc->fp = fopen(FileUtils::getInstance()->getSuitableFOpen(outFileName).c_str(), "ab");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fDesc->fp = fopen(outFileName.c_str(), "wb");
|
fDesc->fp = fopen(FileUtils::getInstance()->getSuitableFOpen(outFileName).c_str(), "wb");
|
||||||
}
|
}
|
||||||
if (!fDesc->fp)
|
if (!fDesc->fp)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue