| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 | 
							- /****************************************************************************
 
- Copyright (c) 2010-2012 cocos2d-x.org
 
- Copyright (c) 2013-2017 Chukong Technologies Inc.
 
- http://www.cocos2d-x.org
 
- Permission is hereby granted, free of charge, to any person obtaining a copy
 
- of this software and associated documentation files (the "Software"), to deal
 
- in the Software without restriction, including without limitation the rights
 
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
- copies of the Software, and to permit persons to whom the Software is
 
- furnished to do so, subject to the following conditions:
 
- The above copyright notice and this permission notice shall be included in
 
- all copies or substantial portions of the Software.
 
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
- THE SOFTWARE.
 
- ****************************************************************************/
 
- #include "platform/CCPlatformConfig.h"
 
- #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
 
- #include "platform/android/CCFileUtils-android.h"
 
- #include "platform/CCCommon.h"
 
- #include "platform/android/jni/JniHelper.h"
 
- #include "platform/android/jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h"
 
- #include "android/asset_manager.h"
 
- #include "android/asset_manager_jni.h"
 
- #include "base/ZipUtils.h"
 
- #include "base/CCDirector.h"
 
- #include "base/CCEventDispatcher.h"
 
- #include "base/CCEventType.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__)
 
- #define  ASSETS_FOLDER_NAME          "assets/"
 
- #define  ASSETS_FOLDER_NAME_LENGTH   7
 
- using namespace std;
 
- NS_CC_BEGIN
 
- AAssetManager* FileUtilsAndroid::assetmanager = nullptr;
 
- ZipFile* FileUtilsAndroid::obbfile = nullptr;
 
- void FileUtilsAndroid::setassetmanager(AAssetManager* a) {
 
-     if (nullptr == a) {
 
-         LOGD("setassetmanager : received unexpected nullptr parameter");
 
-         return;
 
-     }
 
-     cocos2d::FileUtilsAndroid::assetmanager = a;
 
- }
 
- FileUtils* FileUtils::getInstance()
 
- {
 
-     if (s_sharedFileUtils == nullptr)
 
-     {
 
-         s_sharedFileUtils = new FileUtilsAndroid();
 
-         if (!s_sharedFileUtils->init())
 
-         {
 
-           delete s_sharedFileUtils;
 
-           s_sharedFileUtils = nullptr;
 
-           CCLOG("ERROR: Could not init CCFileUtilsAndroid");
 
-         }
 
-     }
 
-     return s_sharedFileUtils;
 
- }
 
- FileUtilsAndroid::FileUtilsAndroid()
 
- {
 
- }
 
- FileUtilsAndroid::~FileUtilsAndroid()
 
- {
 
-     if (obbfile)
 
-     {
 
-         delete obbfile;
 
-         obbfile = nullptr;
 
-     }
 
- }
 
- bool FileUtilsAndroid::init()
 
- {
 
-     _defaultResRootPath = ASSETS_FOLDER_NAME;
 
-     
 
-     std::string assetsPath(getApkPath());
 
-     if (assetsPath.find("/obb/") != std::string::npos)
 
-     {
 
-         obbfile = new ZipFile(assetsPath);
 
-     }
 
-     return FileUtils::init();
 
- }
 
- std::string FileUtilsAndroid::getNewFilename(const std::string &filename) const
 
- {
 
-     std::string newFileName = FileUtils::getNewFilename(filename);
 
-     // ../xxx do not fix this path
 
-     auto pos = newFileName.find("../");
 
-     if (pos == std::string::npos || pos == 0)
 
-     {
 
-         return newFileName;
 
-     }
 
-     std::vector<std::string> v(3);
 
-     v.resize(0);
 
-     auto change = false;
 
-     size_t size = newFileName.size();
 
-     size_t idx = 0;
 
-     bool noexit = true;
 
-     while (noexit)
 
-     {
 
-         pos = newFileName.find('/', idx);
 
-         std::string tmp;
 
-         if (pos == std::string::npos)
 
-         {
 
-             tmp = newFileName.substr(idx, size - idx);
 
-             noexit = false;
 
-         }else
 
-         {
 
-             tmp = newFileName.substr(idx, pos - idx + 1);
 
-         }
 
-         auto t = v.size();
 
-         if (t > 0 && v[t-1].compare("../") != 0 &&
 
-              (tmp.compare("../") == 0 || tmp.compare("..") == 0))
 
-         {
 
-             v.pop_back();
 
-             change = true;
 
-         }else
 
-         {
 
-             v.push_back(tmp);
 
-         }
 
-         idx = pos + 1;
 
-     }
 
-     if (change)
 
-     {
 
-         newFileName.clear();
 
-         for (auto &s : v)
 
-         {
 
-             newFileName.append(s);
 
-         }
 
-     }
 
-     return newFileName;
 
- }
 
- bool FileUtilsAndroid::isFileExistInternal(const std::string& strFilePath) const
 
- {
 
-     if (strFilePath.empty())
 
-     {
 
-         return false;
 
-     }
 
-     bool bFound = false;
 
-     // Check whether file exists in apk.
 
-     if (strFilePath[0] != '/')
 
-     {
 
-         const char* s = strFilePath.c_str();
 
-         // Found "assets/" at the beginning of the path and we don't want it
 
-         if (strFilePath.find(_defaultResRootPath) == 0) s += _defaultResRootPath.length();
 
-         
 
-         if (obbfile && obbfile->fileExists(s))
 
-         {
 
-             bFound = true;
 
-         }
 
-         else if (FileUtilsAndroid::assetmanager)
 
-         {
 
-             AAsset* aa = AAssetManager_open(FileUtilsAndroid::assetmanager, s, AASSET_MODE_UNKNOWN);
 
-             if (aa)
 
-             {
 
-                 bFound = true;
 
-                 AAsset_close(aa);
 
-             } else {
 
-                 // CCLOG("[AssetManager] ... in APK %s, found = false!", strFilePath.c_str());
 
-             }
 
-         }
 
-     }
 
-     else
 
-     {
 
-         FILE *fp = fopen(strFilePath.c_str(), "r");
 
-         if (fp)
 
-         {
 
-             bFound = true;
 
-             fclose(fp);
 
-         }
 
-     }
 
-     return bFound;
 
- }
 
- bool FileUtilsAndroid::isDirectoryExistInternal(const std::string& dirPath) const
 
- {
 
-     if (dirPath.empty())
 
-     {
 
-         return false;
 
-     }
 
-     const char* s = dirPath.c_str();
 
-     
 
-     // 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);
 
-         }
 
-     }
 
-     else
 
-     {
 
-         // 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 (dirPath.find(ASSETS_FOLDER_NAME) == 0)
 
-         {
 
-             s += ASSETS_FOLDER_NAME_LENGTH;
 
-         }
 
-         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.
 
-     // 1) Files in APK, e.g. assets/path/path/file.png
 
-     // 2) Files not in APK, e.g. /data/data/org.cocos2dx.hellocpp/cache/path/path/file.png, or /sdcard/path/path/file.png.
 
-     // So these two situations need to be checked on Android.
 
-     if (strPath[0] == '/' || strPath.find(_defaultResRootPath) == 0)
 
-     {
 
-         return true;
 
-     }
 
-     return false;
 
- }
 
- FileUtils::Status FileUtilsAndroid::getContents(const std::string& filename, ResizableBuffer* buffer)
 
- {
 
-     Director::getInstance()->getEventDispatcher()->dispatchCustomEvent(EVENT_BEFORE_READ_FILE);
 
-     static const std::string apkprefix("assets/");
 
-     if (filename.empty())
 
-         return FileUtils::Status::NotExists;
 
-     string fullPath = fullPathForFilename(filename);
 
-     if (fullPath[0] == '/')
 
-         return FileUtils::getContents(fullPath, buffer);
 
-     string relativePath = string();
 
-     size_t position = fullPath.find(apkprefix);
 
-     if (0 == position) {
 
-         // "assets/" is at the beginning of the path and we don't want it
 
-         relativePath += fullPath.substr(apkprefix.size());
 
-     } else {
 
-         relativePath = fullPath;
 
-     }
 
-     
 
-     if (obbfile)
 
-     {
 
-         if (obbfile->getFileData(relativePath, buffer))
 
-             return FileUtils::Status::OK;
 
-     }
 
-     if (nullptr == assetmanager) {
 
-         LOGD("... FileUtilsAndroid::assetmanager is nullptr");
 
-         return FileUtils::Status::NotInitialized;
 
-     }
 
-     AAsset* asset = AAssetManager_open(assetmanager, relativePath.data(), AASSET_MODE_UNKNOWN);
 
-     if (nullptr == asset) {
 
-         LOGD("asset is nullptr");
 
-         return FileUtils::Status::OpenFailed;
 
-     }
 
-     auto size = AAsset_getLength(asset);
 
-     buffer->resize(size);
 
-     int readsize = AAsset_read(asset, buffer->buffer(), size);
 
-     AAsset_close(asset);
 
-     if (readsize < size) {
 
-         if (readsize >= 0)
 
-             buffer->resize(readsize);
 
-         return FileUtils::Status::ReadFailed;
 
-     }
 
-     return FileUtils::Status::OK;
 
- }
 
- string FileUtilsAndroid::getWritablePath() const
 
- {
 
-     // Fix for Nexus 10 (Android 4.2 multi-user environment)
 
-     // the path is retrieved through Java Context.getCacheDir() method
 
-     string dir("");
 
-     string tmp = JniHelper::callStaticStringMethod("org/cocos2dx/lib/Cocos2dxHelper", "getCocos2dxWritablePath");
 
-     if (tmp.length() > 0)
 
-     {
 
-         dir.append(tmp).append("/");
 
-         return dir;
 
-     }
 
-     else
 
-     {
 
-         return "";
 
-     }
 
- }
 
- NS_CC_END
 
- #endif // CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
 
 
  |