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 <algorithm>
|
||||
#include "base/CCConsole.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
#include "mpg123.h"
|
||||
#include "vorbis/codec.h"
|
||||
#include "vorbis/vorbisfile.h"
|
||||
|
@ -96,8 +97,9 @@ void AudioCache::readDataTask()
|
|||
case FileFormat::OGG:
|
||||
{
|
||||
vf = new OggVorbis_File;
|
||||
if (ov_fopen(_fileFullPath.c_str(), vf)){
|
||||
log("Input does not appear to be an Ogg bitstream.\n");
|
||||
int openCode;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "AudioPlayer.h"
|
||||
#include "AudioCache.h"
|
||||
#include "base/CCConsole.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
#include "mpg123.h"
|
||||
#include "vorbis/codec.h"
|
||||
#include "vorbis/vorbisfile.h"
|
||||
|
@ -162,8 +163,9 @@ void AudioPlayer::rotateBufferThread(int offsetFrame)
|
|||
case AudioCache::FileFormat::OGG:
|
||||
{
|
||||
vorbisFile = new OggVorbis_File;
|
||||
if (ov_fopen(_audioCache->_fileFullPath.c_str(), vorbisFile)){
|
||||
log("Input does not appear to be an Ogg bitstream.\n");
|
||||
int openCode;
|
||||
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;
|
||||
}
|
||||
if (offsetFrame != 0) {
|
||||
|
|
|
@ -330,7 +330,6 @@ Console::Console()
|
|||
{
|
||||
_commands[commands[i].name] = commands[i];
|
||||
}
|
||||
_writablePath = FileUtils::getInstance()->getWritablePath();
|
||||
}
|
||||
|
||||
Console::~Console()
|
||||
|
@ -870,9 +869,10 @@ void Console::commandUpload(int fd)
|
|||
}
|
||||
*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)
|
||||
{
|
||||
const char err[] = "can't create file!\n";
|
||||
|
|
|
@ -140,8 +140,6 @@ protected:
|
|||
bool _running;
|
||||
bool _endThread;
|
||||
|
||||
std::string _writablePath;
|
||||
|
||||
std::map<std::string, Command> _commands;
|
||||
|
||||
// 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
|
||||
if (doc)
|
||||
{
|
||||
doc->SaveFile(UserDefault::getInstance()->getXMLFilePath().c_str());
|
||||
doc->SaveFile(FileUtils::getInstance()->getSuitableFOpen(UserDefault::getInstance()->getXMLFilePath()).c_str());
|
||||
delete doc;
|
||||
}
|
||||
}
|
||||
|
@ -484,7 +484,7 @@ bool UserDefault::createXMLFile()
|
|||
return false;
|
||||
}
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -403,7 +403,7 @@ bool FileUtils::writeToFile(ValueMap& dict, const std::string &fullPath)
|
|||
}
|
||||
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;
|
||||
return ret;
|
||||
|
@ -566,7 +566,7 @@ static Data getData(const std::string& filename, bool forString)
|
|||
{
|
||||
// Read the file from hardware
|
||||
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);
|
||||
fseek(fp,0,SEEK_END);
|
||||
size = ftell(fp);
|
||||
|
@ -629,7 +629,7 @@ unsigned char* FileUtils::getFileData(const std::string& filename, const char* m
|
|||
{
|
||||
// read the file from hardware
|
||||
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);
|
||||
|
||||
fseek(fp,0,SEEK_END);
|
||||
|
@ -1364,5 +1364,10 @@ bool FileUtils::isPopupNotify() const
|
|||
return s_popupNotify;
|
||||
}
|
||||
|
||||
std::string FileUtils::getSuitableFOpen(const std::string& filenameUtf8) const
|
||||
{
|
||||
return filenameUtf8;
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
||||
|
|
|
@ -330,6 +330,16 @@ public:
|
|||
// This method is used internally.
|
||||
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.
|
||||
// This method is used internally.
|
||||
virtual ValueVector getValueVectorFromFile(const std::string& filename);
|
||||
|
|
|
@ -2232,7 +2232,7 @@ bool Image::saveImageToPNG(const std::string& filePath, bool isToRGB)
|
|||
png_colorp palette;
|
||||
png_bytep *row_pointers;
|
||||
|
||||
fp = fopen(filePath.c_str(), "wb");
|
||||
fp = fopen(FileUtils::getInstance()->getSuitableFOpen(filePath).c_str(), "wb");
|
||||
CC_BREAK_IF(nullptr == fp);
|
||||
|
||||
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. */
|
||||
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);
|
||||
|
||||
|
|
|
@ -56,6 +56,81 @@ static inline std::string convertPathFormatToUnixStyle(const std::string& path)
|
|||
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()
|
||||
{
|
||||
if (0 == s_resourcePath.length())
|
||||
|
@ -334,6 +409,11 @@ string FileUtilsWin32::getWritablePath() const
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::string FileUtilsWin32::getSuitableFOpen(const std::string& filenameUtf8) const
|
||||
{
|
||||
return StringUtf8ToAnsi(filenameUtf8);
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
||||
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
|
||||
|
|
|
@ -54,6 +54,17 @@ public:
|
|||
protected:
|
||||
|
||||
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
|
||||
|
|
|
@ -359,7 +359,7 @@ bool AssetsManager::uncompress()
|
|||
{
|
||||
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)
|
||||
{
|
||||
|
@ -398,7 +398,7 @@ bool AssetsManager::uncompress()
|
|||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
CCLOG("can not open destination file %s", fullPath.c_str());
|
||||
|
@ -517,7 +517,7 @@ bool AssetsManager::downLoad()
|
|||
{
|
||||
// Create a file to save package.
|
||||
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)
|
||||
{
|
||||
Director::getInstance()->getScheduler()->performFunctionInCocosThread([&, this]{
|
||||
|
|
|
@ -355,7 +355,7 @@ bool AssetsManagerEx::decompress(const std::string &zip)
|
|||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
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;
|
||||
if (_supportResuming && resumeDownload && _fileUtils->isFileExist(outFileName))
|
||||
{
|
||||
fDesc->fp = fopen(outFileName.c_str(), "ab");
|
||||
fDesc->fp = fopen(FileUtils::getInstance()->getSuitableFOpen(outFileName).c_str(), "ab");
|
||||
}
|
||||
else
|
||||
{
|
||||
fDesc->fp = fopen(outFileName.c_str(), "wb");
|
||||
fDesc->fp = fopen(FileUtils::getInstance()->getSuitableFOpen(outFileName).c_str(), "wb");
|
||||
}
|
||||
if (!fDesc->fp)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue