Merge pull request #12778 from yangws/issue_9586

Fix bug: FileUtils::isDirectoryExist not correct on Android when using relative path in 'assets'
This commit is contained in:
pandamicro 2015-07-13 11:03:24 +08:00
commit 8ab1dce2a0
13 changed files with 110 additions and 39 deletions

View File

@ -584,7 +584,6 @@ bool FileUtils::writeStringToFile(std::string dataStr, const std::string& fullPa
bool FileUtils::writeDataToFile(Data retData, const std::string& fullPath)
{
unsigned char* buffer = nullptr;
size_t size = 0;
const char* mode = "wb";
@ -1038,36 +1037,6 @@ bool FileUtils::isAbsolutePath(const std::string& path) const
return (path[0] == '/');
}
bool FileUtils::isDirectoryExistInternal(const std::string& dirPath) const
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
WIN32_FILE_ATTRIBUTE_DATA wfad;
std::wstring wdirPath(dirPath.begin(), dirPath.end());
if (GetFileAttributesEx(wdirPath.c_str(), GetFileExInfoStandard, &wfad))
{
return true;
}
return false;
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
unsigned long fAttrib = GetFileAttributesA(dirPath.c_str());
if (fAttrib != INVALID_FILE_ATTRIBUTES &&
(fAttrib & FILE_ATTRIBUTE_DIRECTORY))
{
return true;
}
return false;
#else
struct stat st;
if (stat(dirPath.c_str(), &st) == 0)
{
return S_ISDIR(st.st_mode);
}
return false;
#endif
}
bool FileUtils::isDirectoryExist(const std::string& dirPath) const
{
CCASSERT(!dirPath.empty(), "Invalid path");
@ -1098,7 +1067,6 @@ bool FileUtils::isDirectoryExist(const std::string& dirPath) const
}
}
}
return false;
}

View File

@ -497,7 +497,7 @@ protected:
* @param dirPath The directory (with absolute path) to look up for
* @return Returns true if the directory found at the given absolute path, otherwise returns false
*/
virtual bool isDirectoryExistInternal(const std::string& dirPath) const;
virtual bool isDirectoryExistInternal(const std::string& dirPath) const = 0;
/**
* Gets full path for filename, resolution directory and search path.

View File

@ -33,6 +33,7 @@ THE SOFTWARE.
#include "android/asset_manager_jni.h"
#include "jni/CocosPlayClient.h"
#include <stdlib.h>
#include <sys/stat.h>
#define LOG_TAG "CCFileUtils-android.cpp"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
@ -187,6 +188,59 @@ bool FileUtilsAndroid::isFileExistInternal(const std::string& strFilePath) const
return bFound;
}
bool FileUtilsAndroid::isDirectoryExistInternal(const std::string& dirPath) const
{
if (dirPath.empty())
{
return false;
}
const char* s = dirPath.c_str();
bool startWithAssets = (dirPath.find("assets/") == 0);
int lenOfAssets = 7;
std::string tmpStr;
if (cocosplay::isEnabled() && !cocosplay::isDemo())
{
// redirect assets/*** path to cocosplay resource dir
tmpStr.append(_defaultResRootPath);
if ('/' != tmpStr[tmpStr.length() - 1])
{
tmpStr += '/';
}
tmpStr.append(s + lenOfAssets);
}
// find absolute path in flash memory
if (s[0] == '/')
{
CCLOG("find in flash memory dirPath(%s)", s);
struct stat st;
if (stat(s, &st) == 0)
{
return S_ISDIR(st.st_mode);
}
}
// find it in apk's assets dir
// Found "assets/" at the beginning of the path and we don't want it
CCLOG("find in apk dirPath(%s)", s);
if (startWithAssets)
{
s += lenOfAssets;
}
if (FileUtilsAndroid::assetmanager)
{
AAssetDir* aa = AAssetManager_openDir(FileUtilsAndroid::assetmanager, s);
if (aa && AAssetDir_getNextFileName(aa))
{
AAssetDir_close(aa);
return true;
}
}
return false;
}
bool FileUtilsAndroid::isAbsolutePath(const std::string& strPath) const
{
// On Android, there are two situations for full path.

View File

@ -81,7 +81,8 @@ public:
virtual bool isAbsolutePath(const std::string& strPath) const;
private:
virtual bool isFileExistInternal(const std::string& strFilePath) const;
virtual bool isFileExistInternal(const std::string& strFilePath) const override;
virtual bool isDirectoryExistInternal(const std::string& dirPath) const override;
Data getData(const std::string& filename, bool forString);
static AAssetManager* assetmanager;

View File

@ -213,7 +213,7 @@ public abstract class Cocos2dxActivity extends Activity implements Cocos2dxHelpe
// ===========================================================
// Constructors
// ===========================================================
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

View File

@ -57,6 +57,7 @@ public:
void setBundle(NSBundle* bundle);
private:
virtual bool isFileExistInternal(const std::string& filePath) const override;
virtual bool isDirectoryExistInternal(const std::string& dirPath) const override;
NSBundle* getBundle() const;
NSBundle* _bundle;
};

View File

@ -27,6 +27,8 @@ THE SOFTWARE.
#include "CCFileUtils-apple.h"
#include <ftw.h>
#include <string>
#include <stack>
@ -392,6 +394,16 @@ bool FileUtilsApple::isFileExistInternal(const std::string& filePath) const
return ret;
}
bool FileUtilsApple::isDirectoryExistInternal(const std::string& dirPath) const
{
struct stat st;
if (stat(dirPath.c_str(), &st) == 0)
{
return S_ISDIR(st.st_mode);
}
return false;
}
std::string FileUtilsApple::getFullPathForDirectoryAndFilename(const std::string& directory, const std::string& filename) const
{
if (directory[0] != '/')

View File

@ -35,6 +35,7 @@ THE SOFTWARE.
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#ifndef CC_RESOURCE_FOLDER_LINUX
#define CC_RESOURCE_FOLDER_LINUX ("/Resources/")
@ -121,6 +122,16 @@ bool FileUtilsLinux::isFileExistInternal(const std::string& strFilePath) const
return (stat(strPath.c_str(), &sts) != -1) ? true : false;
}
bool FileUtilsLinux::isDirectoryExistInternal(const std::string& dirPath) const
{
struct stat st;
if (stat(dirPath.c_str(), &st) == 0)
{
return S_ISDIR(st.st_mode);
}
return false;
}
NS_CC_END
#endif // CC_TARGET_PLATFORM == CC_PLATFORM_LINUX

View File

@ -52,7 +52,8 @@ public:
bool init();
virtual std::string getWritablePath() const;
private:
virtual bool isFileExistInternal(const std::string& strFilePath) const;
virtual bool isFileExistInternal(const std::string& strFilePath) const override;
virtual bool isDirectoryExistInternal(const std::string& dirPath) const override;
};
// end of platform group

View File

@ -121,6 +121,17 @@ bool FileUtilsWin32::isFileExistInternal(const std::string& strFilePath) const
return true;
}
bool FileUtilsWin32::isDirectoryExistInternal(const std::string& dirPath) const
{
unsigned long fAttrib = GetFileAttributesA(dirPath.c_str());
if (fAttrib != INVALID_FILE_ATTRIBUTES &&
(fAttrib & FILE_ATTRIBUTE_DIRECTORY))
{
return true;
}
return false;
}
bool FileUtilsWin32::isAbsolutePath(const std::string& strPath) const
{
if ( (strPath.length() > 2

View File

@ -53,8 +53,8 @@ public:
virtual bool isAbsolutePath(const std::string& strPath) const;
protected:
virtual bool isFileExistInternal(const std::string& strFilePath) const;
virtual bool isFileExistInternal(const std::string& strFilePath) const override;
virtual bool isDirectoryExistInternal(const std::string& dirPath) const override;
/**
* Gets resource file data
*

View File

@ -121,6 +121,17 @@ bool CCFileUtilsWinRT::isFileExistInternal(const std::string& strFilePath) const
return ret;
}
bool CCFileUtilsWinRT::isDirectoryExistInternal(const std::string& dirPath) const
{
WIN32_FILE_ATTRIBUTE_DATA wfad;
std::wstring wdirPath(dirPath.begin(), dirPath.end());
if (GetFileAttributesEx(wdirPath.c_str(), GetFileExInfoStandard, &wfad))
{
return true;
}
return false;
}
bool CCFileUtilsWinRT::isAbsolutePath(const std::string& strPath) const
{
if ( strPath.length() > 2

View File

@ -55,7 +55,8 @@ public:
static std::string getAppPath();
private:
virtual bool isFileExistInternal(const std::string& strFilePath) const;
virtual bool isFileExistInternal(const std::string& strFilePath) const override;
virtual bool isDirectoryExistInternal(const std::string& dirPath) const override;
};
// end of platform group