diff --git a/cocos2dx/platform/win32/CCFileUtilsWin32.cpp b/cocos2dx/platform/win32/CCFileUtilsWin32.cpp index 460e2400df..627747ecad 100644 --- a/cocos2dx/platform/win32/CCFileUtilsWin32.cpp +++ b/cocos2dx/platform/win32/CCFileUtilsWin32.cpp @@ -43,6 +43,36 @@ static void _checkPath() } } +// D:/aaa/bbb/ccc/ddd/abc.txt --> D:\aaa\bbb\ccc\ddd\abc.txt +static inline std::string convertPathFormatToWindowStyle(const std::string& path) +{ + std::string ret = path; + int len = ret.length(); + for (int i = 0; i < len; ++i) + { + if (ret[i] == '/') + { + ret[i] = '\\'; + } + } + return ret; +} + +// D:\aaa\bbb\ccc\ddd\abc.txt --> D:/aaa/bbb/ccc/ddd/abc.txt +static inline std::string convertPathFormatToUnixStyle(const std::string& path) +{ + std::string ret = path; + int len = ret.length(); + for (int i = 0; i < len; ++i) + { + if (ret[i] == '\\') + { + ret[i] = '/'; + } + } + return ret; +} + FileUtils* FileUtils::getInstance() { if (s_sharedFileUtils == NULL) @@ -81,7 +111,12 @@ bool FileUtilsWin32::isFileExist(const std::string& strFilePath) { // Not absolute path, add the default root path at the beginning. strPath.insert(0, _defaultResRootPath); } - return GetFileAttributesA(strPath.c_str()) != -1 ? true : false; + + convertPathFormatToWindowStyle(strPath); + WCHAR wszBuf[MAX_PATH] = {0}; + MultiByteToWideChar(CP_UTF8, 0, strPath.c_str(), -1, wszBuf, sizeof(wszBuf)); + + return GetFileAttributesW(wszBuf) != -1 ? true : false; } bool FileUtilsWin32::isAbsolutePath(const std::string& strPath) @@ -95,6 +130,68 @@ bool FileUtilsWin32::isAbsolutePath(const std::string& strPath) return false; } +unsigned char* FileUtilsWin32::getFileData(const char* filename, const char* mode, unsigned long* size) +{ + unsigned char * pBuffer = NULL; + CCASSERT(filename != NULL && size != NULL && mode != NULL, "Invalid parameters."); + *size = 0; + do + { + // read the file from hardware + std::string fullPath = fullPathForFilename(filename); + + WCHAR wszBuf[MAX_PATH] = {0}; + MultiByteToWideChar(CP_UTF8, 0, fullPath.c_str(), -1, wszBuf, sizeof(wszBuf)); + + + HANDLE fileHandle = ::CreateFileW(wszBuf, GENERIC_READ, 0, NULL, OPEN_EXISTING, NULL, NULL); + CC_BREAK_IF(fileHandle == INVALID_HANDLE_VALUE); + + *size = ::GetFileSize(fileHandle, NULL); + + pBuffer = new unsigned char[*size]; + DWORD sizeRead = 0; + BOOL successed = FALSE; + successed = ::ReadFile(fileHandle, pBuffer, *size, &sizeRead, NULL); + ::CloseHandle(fileHandle); + + if (!successed) + { + CC_SAFE_DELETE_ARRAY(pBuffer); + } + } while (0); + + if (! pBuffer) + { + std::string msg = "Get data from file("; + // Gets error code. + DWORD errorCode = ::GetLastError(); + char errorCodeBuffer[20] = {0}; + snprintf(errorCodeBuffer, sizeof(errorCodeBuffer), "%d", errorCode); + + msg = msg + filename + ") failed, error code is " + errorCodeBuffer; + CCLOG("%s", msg.c_str()); + } + return pBuffer; +} + +std::string FileUtilsWin32::getPathForFilename(const std::string& filename, const std::string& resolutionDirectory, const std::string& searchPath) +{ + std::string unixFileName = convertPathFormatToUnixStyle(filename); + std::string unixResolutionDirector = convertPathFormatToUnixStyle(resolutionDirectory); + std::string unixSearchPath = convertPathFormatToUnixStyle(searchPath); + + return FileUtils::getPathForFilename(unixFileName, unixResolutionDirector, unixSearchPath); +} + +std::string FileUtilsWin32::getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename) +{ + std::string dosDirectory = convertPathFormatToWindowStyle(strDirectory); + std::string dosFilename = convertPathFormatToWindowStyle(strFilename); + + return FileUtils::getFullPathForDirectoryAndFilename(dosDirectory, dosFilename); +} + string FileUtilsWin32::getWritablePath() { // Get full path of executable, e.g. c:\Program Files (x86)\My Game Folder\MyGame.exe diff --git a/cocos2dx/platform/win32/CCFileUtilsWin32.h b/cocos2dx/platform/win32/CCFileUtilsWin32.h index 3dc975a559..38656cf7f2 100644 --- a/cocos2dx/platform/win32/CCFileUtilsWin32.h +++ b/cocos2dx/platform/win32/CCFileUtilsWin32.h @@ -49,6 +49,39 @@ public: virtual std::string getWritablePath(); virtual bool isFileExist(const std::string& strFilePath); virtual bool isAbsolutePath(const std::string& strPath); +protected: + /** + * Gets resource file data + * + * @param[in] filename The resource file name which contains the path. + * @param[in] pszMode The read mode of the file. + * @param[out] pSize If the file read operation succeeds, it will be the data size, otherwise 0. + * @return Upon success, a pointer to the data is returned, otherwise NULL. + * @warning Recall: you are responsible for calling delete[] on any Non-NULL pointer returned. + */ + virtual unsigned char* getFileData(const char* filename, const char* mode, unsigned long * size) override; + + /** + * Gets full path for filename, resolution directory and search path. + * + * @param filename The file name. + * @param resolutionDirectory The resolution directory. + * @param searchPath The search path. + * @return The full path of the file. It will return an empty string if the full path of the file doesn't exist. + */ + virtual std::string getPathForFilename(const std::string& filename, const std::string& resolutionDirectory, const std::string& searchPath) override; + + /** + * Gets full path for the directory and the filename. + * + * @note Only iOS and Mac need to override this method since they are using + * `[[NSBundle mainBundle] pathForResource: ofType: inDirectory:]` to make a full path. + * Other platforms will use the default implementation of this method. + * @param strDirectory The directory contains the file we are looking for. + * @param strFilename The name of the file. + * @return The full path of the file, if the file can't be found, it will return an empty string. + */ + virtual std::string getFullPathForDirectoryAndFilename(const std::string& strDirectory, const std::string& strFilename) override; }; // end of platform group