Merge v3 branch.

This commit is contained in:
Vincent Yang 2015-07-10 16:39:36 +08:00
commit 1711a70869
11 changed files with 888 additions and 383 deletions

View File

@ -59,7 +59,7 @@ THE SOFTWARE.
NS_CC_BEGIN
typedef enum
typedef enum
{
SAX_NONE = 0,
SAX_KEY,
@ -81,22 +81,22 @@ class DictMaker : public SAXDelegator
{
public:
SAXResult _resultType;
ValueMap _rootDict;
ValueVector _rootArray;
ValueMap _rootDict;
ValueVector _rootArray;
std::string _curKey; ///< parsed key
std::string _curValue; // parsed value
SAXState _state;
ValueMap* _curDict;
ValueMap* _curDict;
ValueVector* _curArray;
std::stack<ValueMap*> _dictStack;
std::stack<ValueMap*> _dictStack;
std::stack<ValueVector*> _arrayStack;
std::stack<SAXState> _stateStack;
public:
DictMaker()
DictMaker()
: _resultType(SAX_RESULT_NONE)
{
}
@ -114,20 +114,20 @@ public:
parser.setDelegator(this);
parser.parse(fileName);
return _rootDict;
return _rootDict;
}
ValueMap dictionaryWithDataOfFile(const char* filedata, int filesize)
{
_resultType = SAX_RESULT_DICT;
SAXParser parser;
ValueMap dictionaryWithDataOfFile(const char* filedata, int filesize)
{
_resultType = SAX_RESULT_DICT;
SAXParser parser;
CCASSERT(parser.init("UTF-8"), "The file format isn't UTF-8");
parser.setDelegator(this);
CCASSERT(parser.init("UTF-8"), "The file format isn't UTF-8");
parser.setDelegator(this);
parser.parse(filedata, filesize);
return _rootDict;
}
parser.parse(filedata, filesize);
return _rootDict;
}
ValueVector arrayWithContentsOfFile(const std::string& fileName)
{
@ -138,7 +138,7 @@ public:
parser.setDelegator(this);
parser.parse(fileName);
return _rootArray;
return _rootArray;
}
void startElement(void *ctx, const char *name, const char **atts)
@ -148,7 +148,7 @@ public:
const std::string sName(name);
if( sName == "dict" )
{
if(_resultType == SAX_RESULT_DICT && _rootDict.empty())
if(_resultType == SAX_RESULT_DICT && _rootDict.empty())
{
_curDict = &_rootDict;
}
@ -165,7 +165,7 @@ public:
{
// add a new dictionary into the array
_curArray->push_back(Value(ValueMap()));
_curDict = &(_curArray->rbegin())->asValueMap();
_curDict = &(_curArray->rbegin())->asValueMap();
}
else if (SAX_DICT == preState)
{
@ -173,7 +173,7 @@ public:
CCASSERT(! _dictStack.empty(), "The state is wrong!");
ValueMap* preDict = _dictStack.top();
(*preDict)[_curKey] = Value(ValueMap());
_curDict = &(*preDict)[_curKey].asValueMap();
_curDict = &(*preDict)[_curKey].asValueMap();
}
// record the dict state
@ -200,9 +200,9 @@ public:
{
_state = SAX_ARRAY;
if (_resultType == SAX_RESULT_ARRAY && _rootArray.empty())
if (_resultType == SAX_RESULT_ARRAY && _rootArray.empty())
{
_curArray = &_rootArray;
_curArray = &_rootArray;
}
SAXState preState = SAX_NONE;
if (! _stateStack.empty())
@ -213,14 +213,14 @@ public:
if (preState == SAX_DICT)
{
(*_curDict)[_curKey] = Value(ValueVector());
_curArray = &(*_curDict)[_curKey].asValueVector();
_curArray = &(*_curDict)[_curKey].asValueVector();
}
else if (preState == SAX_ARRAY)
{
CCASSERT(! _arrayStack.empty(), "The state is wrong!");
ValueVector* preArray = _arrayStack.top();
preArray->push_back(Value(ValueVector()));
_curArray = &(_curArray->rbegin())->asValueVector();
_curArray = &(_curArray->rbegin())->asValueVector();
}
// record the array state
_stateStack.push(_state);
@ -300,7 +300,7 @@ public:
_curValue.clear();
}
_state = SAX_NONE;
}
@ -328,7 +328,7 @@ public:
{
CCASSERT(!_curKey.empty(), "key not found : <integer/real>");
}
_curValue.append(text);
}
break;
@ -370,22 +370,26 @@ static tinyxml2::XMLElement* generateElementForDict(const ValueMap& dict, tinyxm
*/
bool FileUtils::writeToFile(ValueMap& dict, const std::string &fullPath)
{
//CCLOG("tinyxml2 Dictionary %d writeToFile %s", dict->_ID, fullPath.c_str());
tinyxml2::XMLDocument *doc = new tinyxml2::XMLDocument();
return writeValueMapToFile(dict, fullPath);
}
bool FileUtils::writeValueMapToFile(ValueMap& dict, const std::string& fullPath)
{
tinyxml2::XMLDocument *doc = new (std::nothrow)tinyxml2::XMLDocument();
if (nullptr == doc)
return false;
tinyxml2::XMLDeclaration *declaration = doc->NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\"");
if (nullptr == declaration)
{
delete doc;
return false;
}
doc->LinkEndChild(declaration);
tinyxml2::XMLElement *docType = doc->NewElement("!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"");
doc->LinkEndChild(docType);
tinyxml2::XMLElement *rootEle = doc->NewElement("plist");
rootEle->SetAttribute("version", "1.0");
if (nullptr == rootEle)
@ -394,17 +398,57 @@ bool FileUtils::writeToFile(ValueMap& dict, const std::string &fullPath)
return false;
}
doc->LinkEndChild(rootEle);
tinyxml2::XMLElement *innerDict = generateElementForDict(dict, doc);
if (nullptr == innerDict )
if (nullptr == innerDict)
{
delete doc;
return false;
}
rootEle->LinkEndChild(innerDict);
bool ret = tinyxml2::XML_SUCCESS == doc->SaveFile(getSuitableFOpen(fullPath).c_str());
delete doc;
return ret;
}
bool FileUtils::writeValueVectorToFile(ValueVector vecData, const std::string& fullPath)
{
tinyxml2::XMLDocument *doc = new (std::nothrow)tinyxml2::XMLDocument();
if (nullptr == doc)
return false;
tinyxml2::XMLDeclaration *declaration = doc->NewDeclaration("xml version=\"1.0\" encoding=\"UTF-8\"");
if (nullptr == declaration)
{
delete doc;
return false;
}
doc->LinkEndChild(declaration);
tinyxml2::XMLElement *docType = doc->NewElement("!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"");
doc->LinkEndChild(docType);
tinyxml2::XMLElement *rootEle = doc->NewElement("plist");
rootEle->SetAttribute("version", "1.0");
if (nullptr == rootEle)
{
delete doc;
return false;
}
doc->LinkEndChild(rootEle);
tinyxml2::XMLElement *innerDict = generateElementForArray(vecData, doc);
if (nullptr == innerDict)
{
delete doc;
return false;
}
rootEle->LinkEndChild(innerDict);
bool ret = tinyxml2::XML_SUCCESS == doc->SaveFile(getSuitableFOpen(fullPath).c_str());
delete doc;
return ret;
}
@ -422,7 +466,7 @@ static tinyxml2::XMLElement* generateElementForObject(const Value& value, tinyxm
node->LinkEndChild(content);
return node;
}
// object is integer
if (value.getType() == Value::Type::INTEGER)
{
@ -440,21 +484,21 @@ static tinyxml2::XMLElement* generateElementForObject(const Value& value, tinyxm
node->LinkEndChild(content);
return node;
}
//object is bool
if (value.getType() == Value::Type::BOOLEAN) {
tinyxml2::XMLElement* node = doc->NewElement(value.asString().c_str());
return node;
tinyxml2::XMLElement* node = doc->NewElement(value.asString().c_str());
return node;
}
// object is Array
if (value.getType() == Value::Type::VECTOR)
return generateElementForArray(value.asValueVector(), doc);
// object is Dictionary
if (value.getType() == Value::Type::MAP)
return generateElementForDict(value.asValueMap(), doc);
CCLOG("This type cannot appear in property list");
return nullptr;
}
@ -465,14 +509,14 @@ static tinyxml2::XMLElement* generateElementForObject(const Value& value, tinyxm
static tinyxml2::XMLElement* generateElementForDict(const ValueMap& dict, tinyxml2::XMLDocument *doc)
{
tinyxml2::XMLElement* rootNode = doc->NewElement("dict");
for (const auto &iter : dict)
{
tinyxml2::XMLElement* tmpNode = doc->NewElement("key");
rootNode->LinkEndChild(tmpNode);
tinyxml2::XMLText* content = doc->NewText(iter.first.c_str());
tmpNode->LinkEndChild(content);
tinyxml2::XMLElement *element = generateElementForObject(iter.second, doc);
if (element)
rootNode->LinkEndChild(element);
@ -517,7 +561,7 @@ void FileUtils::setDelegate(FileUtils *delegate)
{
if (s_sharedFileUtils)
delete s_sharedFileUtils;
s_sharedFileUtils = delegate;
}
@ -530,7 +574,39 @@ FileUtils::~FileUtils()
{
}
bool FileUtils::writeStringToFile(std::string dataStr, const std::string& fullPath)
{
Data retData;
retData.copy((unsigned char*)dataStr.c_str(), dataStr.size());
return writeDataToFile(retData, fullPath);
}
bool FileUtils::writeDataToFile(Data retData, const std::string& fullPath)
{
unsigned char* buffer = nullptr;
size_t size = 0;
const char* mode = "wb";
CCASSERT(!fullPath.empty() && retData.getSize() != 0, "Invalid parameters.");
auto fileutils = FileUtils::getInstance();
do
{
// Read the file from hardware
FILE *fp = fopen(fileutils->getSuitableFOpen(fullPath).c_str(), mode);
CC_BREAK_IF(!fp);
size = retData.getSize();
fwrite(retData.getBytes(), size, 1, fp);
fclose(fp);
return true;
} while (0);
return false;
}
bool FileUtils::init()
{
@ -550,13 +626,13 @@ static Data getData(const std::string& filename, bool forString)
{
return Data::Null;
}
Data ret;
unsigned char* buffer = nullptr;
size_t size = 0;
size_t readsize;
const char* mode = nullptr;
if (forString)
mode = "rt";
else
@ -572,7 +648,7 @@ static Data getData(const std::string& filename, bool forString)
fseek(fp,0,SEEK_END);
size = ftell(fp);
fseek(fp,0,SEEK_SET);
if (forString)
{
buffer = (unsigned char*)malloc(sizeof(unsigned char) * (size + 1));
@ -582,16 +658,16 @@ static Data getData(const std::string& filename, bool forString)
{
buffer = (unsigned char*)malloc(sizeof(unsigned char) * size);
}
readsize = fread(buffer, sizeof(unsigned char), size, fp);
fclose(fp);
if (forString && readsize < size)
{
buffer[readsize] = '\0';
}
} while (0);
if (nullptr == buffer || 0 == readsize)
{
CCLOG("Get data from file %s failed", filename.c_str());
@ -600,7 +676,7 @@ static Data getData(const std::string& filename, bool forString)
{
ret.fastSet(buffer, readsize);
}
return ret;
}
@ -608,8 +684,8 @@ std::string FileUtils::getStringFromFile(const std::string& filename)
{
Data data = getData(filename, true);
if (data.isNull())
return "";
return "";
std::string ret((const char*)data.getBytes());
return ret;
}
@ -630,7 +706,7 @@ unsigned char* FileUtils::getFileData(const std::string& filename, const char* m
const std::string fullPath = fullPathForFilename(filename);
FILE *fp = fopen(getSuitableFOpen(fullPath).c_str(), mode);
CC_BREAK_IF(!fp);
fseek(fp,0,SEEK_END);
*size = ftell(fp);
fseek(fp,0,SEEK_SET);
@ -638,12 +714,12 @@ unsigned char* FileUtils::getFileData(const std::string& filename, const char* m
*size = fread(buffer,sizeof(unsigned char), *size,fp);
fclose(fp);
} while (0);
if (!buffer)
{
std::string msg = "Get data from file(";
msg.append(filename).append(") failed!");
CCLOG("%s", msg.c_str());
}
return buffer;
@ -655,14 +731,14 @@ unsigned char* FileUtils::getFileDataFromZip(const std::string& zipFilePath, con
unzFile file = nullptr;
*size = 0;
do
do
{
CC_BREAK_IF(zipFilePath.empty());
file = unzOpen(zipFilePath.c_str());
CC_BREAK_IF(!file);
// FIXME: Other platforms should use upstream minizip like mingw-w64
// FIXME: Other platforms should use upstream minizip like mingw-w64
#ifdef MINIZIP_FROM_SYSTEM
int ret = unzLocateFile(file, filename.c_str(), NULL);
#else
@ -697,7 +773,7 @@ unsigned char* FileUtils::getFileDataFromZip(const std::string& zipFilePath, con
std::string FileUtils::getNewFilename(const std::string &filename) const
{
std::string newFileName;
// in Lookup Filename dictionary ?
auto iter = _filenameLookupDict.find(filename);
@ -722,14 +798,14 @@ std::string FileUtils::getPathForFilename(const std::string& filename, const std
file_path = filename.substr(0, pos+1);
file = filename.substr(pos+1);
}
// searchPath + file_path + resourceDirectory
std::string path = searchPath;
path += file_path;
path += resolutionDirectory;
path = getFullPathForDirectoryAndFilename(path, file);
//CCLOG("getPathForFilename, fullPath = %s", path.c_str());
return path;
}
@ -740,7 +816,7 @@ std::string FileUtils::fullPathForFilename(const std::string &filename) const
{
return "";
}
if (isAbsolutePath(filename))
{
return filename;
@ -752,28 +828,28 @@ std::string FileUtils::fullPathForFilename(const std::string &filename) const
{
return cacheIter->second;
}
// Get the new file name.
const std::string newFilename( getNewFilename(filename) );
std::string fullpath;
std::string fullpath;
for (const auto& searchIt : _searchPathArray)
{
for (const auto& resolutionIt : _searchResolutionsOrderArray)
{
fullpath = this->getPathForFilename(newFilename, resolutionIt, searchIt);
if (fullpath.length() > 0)
{
// Using the filename passed in as key.
_fullPathCache.insert(std::make_pair(filename, fullpath));
return fullpath;
}
}
}
if(isPopupNotify()){
CCLOG("cocos2d: fullPathForFilename: No file found at %s. Possible missing file.", filename.c_str());
}
@ -799,12 +875,12 @@ void FileUtils::setSearchResolutionsOrder(const std::vector<std::string>& search
{
existDefault = true;
}
if (resolutionDirectory.length() > 0 && resolutionDirectory[resolutionDirectory.length()-1] != '/')
{
resolutionDirectory += "/";
}
_searchResolutionsOrderArray.push_back(resolutionDirectory);
}
@ -819,7 +895,7 @@ void FileUtils::addSearchResolutionsOrder(const std::string &order,const bool fr
std::string resOrder = order;
if (!resOrder.empty() && resOrder[resOrder.length()-1] != '/')
resOrder.append("/");
if (front) {
_searchResolutionsOrderArray.insert(_searchResolutionsOrderArray.begin(), resOrder);
} else {
@ -850,14 +926,14 @@ void FileUtils::setDefaultResourceRootPath(const std::string& path)
void FileUtils::setSearchPaths(const std::vector<std::string>& searchPaths)
{
bool existDefaultRootPath = false;
_fullPathCache.clear();
_searchPathArray.clear();
for (const auto& iter : searchPaths)
{
std::string prefix;
std::string path;
if (!isAbsolutePath(iter))
{ // Not an absolute path
prefix = _defaultResRootPath;
@ -873,7 +949,7 @@ void FileUtils::setSearchPaths(const std::vector<std::string>& searchPaths)
}
_searchPathArray.push_back(path);
}
if (!existDefaultRootPath)
{
//CCLOG("Default root path doesn't exist, adding it.");
@ -901,7 +977,7 @@ void FileUtils::addSearchPath(const std::string &searchpath,const bool front)
void FileUtils::setFilenameLookupDictionary(const ValueMap& filenameLookupDict)
{
_fullPathCache.clear();
_fullPathCache.clear();
_filenameLookupDict = filenameLookupDict;
}
@ -927,13 +1003,13 @@ void FileUtils::loadFilenameLookupDictionaryFromFile(const std::string &filename
std::string FileUtils::getFullPathForDirectoryAndFilename(const std::string& directory, const std::string& filename) const
{
// get directory+filename, safely adding '/' as necessary
// get directory+filename, safely adding '/' as necessary
std::string ret = directory;
if (directory.size() && directory[directory.size()-1] != '/'){
ret += '/';
}
ret += filename;
// if the file doesn't exist, return an empty string
if (!isFileExistInternal(ret)) {
ret = "";
@ -965,20 +1041,20 @@ bool FileUtils::isAbsolutePath(const std::string& path) const
bool FileUtils::isDirectoryExist(const std::string& dirPath) const
{
CCASSERT(!dirPath.empty(), "Invalid path");
if (isAbsolutePath(dirPath))
{
return isDirectoryExistInternal(dirPath);
}
// Already Cached ?
auto cacheIter = _fullPathCache.find(dirPath);
if( cacheIter != _fullPathCache.end() )
{
return isDirectoryExistInternal(cacheIter->second);
}
std::string fullpath;
std::string fullpath;
for (const auto& searchIt : _searchPathArray)
{
for (const auto& resolutionIt : _searchResolutionsOrderArray)
@ -998,16 +1074,16 @@ bool FileUtils::isDirectoryExist(const std::string& dirPath) const
bool FileUtils::createDirectory(const std::string& path)
{
CCASSERT(!path.empty(), "Invalid path");
if (isDirectoryExist(path))
return true;
// Split the path
size_t start = 0;
size_t found = path.find_first_of("/\\", start);
std::string subpath;
std::vector<std::string> dirs;
if (found != std::string::npos)
{
while (true)
@ -1030,42 +1106,42 @@ bool FileUtils::createDirectory(const std::string& path)
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
WIN32_FILE_ATTRIBUTE_DATA wfad;
WIN32_FILE_ATTRIBUTE_DATA wfad;
std::wstring wpath(path.begin(), path.end());
if (!(GetFileAttributesEx(wpath.c_str(), GetFileExInfoStandard, &wfad)))
{
subpath = "";
for(unsigned int i = 0 ; i < dirs.size() ; ++i)
{
subpath += dirs[i];
if (i > 0 && !isDirectoryExist(subpath))
{
{
subpath = "";
for(unsigned int i = 0 ; i < dirs.size() ; ++i)
{
subpath += dirs[i];
if (i > 0 && !isDirectoryExist(subpath))
{
std::wstring wsubpath(subpath.begin(), subpath.end());
BOOL ret = CreateDirectory(wsubpath.c_str(), NULL);
if (!ret && ERROR_ALREADY_EXISTS != GetLastError())
{
return false;
}
}
}
}
return true;
if (!ret && ERROR_ALREADY_EXISTS != GetLastError())
{
return false;
}
}
}
}
return true;
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
if ((GetFileAttributesA(path.c_str())) == INVALID_FILE_ATTRIBUTES)
{
subpath = "";
for (unsigned int i = 0; i < dirs.size(); ++i)
{
subpath += dirs[i];
if (!isDirectoryExist(subpath))
{
BOOL ret = CreateDirectoryA(subpath.c_str(), NULL);
if (!ret && ERROR_ALREADY_EXISTS != GetLastError())
{
return false;
}
}
}
subpath = "";
for (unsigned int i = 0; i < dirs.size(); ++i)
{
subpath += dirs[i];
if (!isDirectoryExist(subpath))
{
BOOL ret = CreateDirectoryA(subpath.c_str(), NULL);
if (!ret && ERROR_ALREADY_EXISTS != GetLastError())
{
return false;
}
}
}
}
return true;
#else
@ -1077,11 +1153,11 @@ bool FileUtils::createDirectory(const std::string& path)
{
subpath += dirs[i];
dir = opendir(subpath.c_str());
if (!dir)
{
// directory doesn't exist, should create a new one
int ret = mkdir(subpath.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
if (ret != 0 && (errno != EEXIST))
{
@ -1108,7 +1184,7 @@ static int unlink_cb(const char *fpath, const struct stat *sb, int typeflag, str
{
log("Fail to remove: %s ",fpath);
}
return ret;
}
#endif
@ -1120,53 +1196,53 @@ bool FileUtils::removeDirectory(const std::string& path)
CCLOGERROR("Fail to remove directory, path must termniate with '/': %s", path.c_str());
return false;
}
// Remove downloaded files
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
std::wstring wpath = std::wstring(path.begin(), path.end());
std::wstring files = wpath + L"*.*";
WIN32_FIND_DATA wfd;
HANDLE search = FindFirstFileEx(files.c_str(), FindExInfoStandard, &wfd, FindExSearchNameMatch, NULL, 0);
bool ret=true;
if (search!=INVALID_HANDLE_VALUE)
{
BOOL find=true;
while (find)
{
//. ..
if(wfd.cFileName[0]!='.')
{
WIN32_FIND_DATA wfd;
HANDLE search = FindFirstFileEx(files.c_str(), FindExInfoStandard, &wfd, FindExSearchNameMatch, NULL, 0);
bool ret=true;
if (search!=INVALID_HANDLE_VALUE)
{
BOOL find=true;
while (find)
{
//. ..
if(wfd.cFileName[0]!='.')
{
std::wstring temp = wpath + wfd.cFileName;
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
temp += '/';
ret = ret && this->removeDirectory(std::string(temp.begin(), temp.end()));
}
else
{
}
else
{
SetFileAttributes(temp.c_str(), FILE_ATTRIBUTE_NORMAL);
ret = ret && DeleteFile(temp.c_str());
}
}
find = FindNextFile(search, &wfd);
}
FindClose(search);
}
}
}
find = FindNextFile(search, &wfd);
}
FindClose(search);
}
if (ret && RemoveDirectory(wpath.c_str()))
{
return true;
}
return false;
return false;
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
std::string command = "cmd /c rd /s /q ";
// Path may include space.
command += "\"" + path + "\"";
std::string command = "cmd /c rd /s /q ";
// Path may include space.
command += "\"" + path + "\"";
if (WinExec(command.c_str(), SW_HIDE) > 31)
return true;
else
return false;
if (WinExec(command.c_str(), SW_HIDE) > 31)
return true;
else
return false;
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
if (nftw(path.c_str(),unlink_cb, 64, FTW_DEPTH | FTW_PHYS))
return false;
@ -1190,27 +1266,27 @@ bool FileUtils::removeFile(const std::string &path)
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
std::wstring wpath(path.begin(), path.end());
if (DeleteFile(wpath.c_str()))
{
return true;
}
return false;
{
return true;
}
return false;
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
std::string command = "cmd /c del /q ";
std::string win32path = path;
int len = win32path.length();
for (int i = 0; i < len; ++i)
{
if (win32path[i] == '/')
{
win32path[i] = '\\';
}
}
command += win32path;
std::string command = "cmd /c del /q ";
std::string win32path = path;
int len = win32path.length();
for (int i = 0; i < len; ++i)
{
if (win32path[i] == '/')
{
win32path[i] = '\\';
}
}
command += win32path;
if (WinExec(command.c_str(), SW_HIDE) > 31)
return true;
else
return false;
if (WinExec(command.c_str(), SW_HIDE) > 31)
return true;
else
return false;
#else
if (remove(path.c_str())) {
return false;
@ -1225,20 +1301,20 @@ bool FileUtils::renameFile(const std::string &path, const std::string &oldname,
CCASSERT(!path.empty(), "Invalid path");
std::string oldPath = path + oldname;
std::string newPath = path + name;
// Rename a file
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
std::regex pat("\\/");
std::string _old = std::regex_replace(oldPath, pat, "\\");
std::string _new = std::regex_replace(newPath, pat, "\\");
if (MoveFileEx(std::wstring(_old.begin(), _old.end()).c_str(),
if (MoveFileEx(std::wstring(_old.begin(), _old.end()).c_str(),
std::wstring(_new.begin(), _new.end()).c_str(),
MOVEFILE_REPLACE_EXISTING & MOVEFILE_WRITE_THROUGH))
{
return true;
}
return false;
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
std::regex pat("\\/");
std::string _old = std::regex_replace(oldPath, pat, "\\");
std::string _new = std::regex_replace(newPath, pat, "\\");
@ -1275,7 +1351,7 @@ bool FileUtils::renameFile(const std::string &path, const std::string &oldname,
long FileUtils::getFileSize(const std::string &filepath)
{
CCASSERT(!filepath.empty(), "Invalid path");
std::string fullpath = filepath;
if (!isAbsolutePath(filepath))
{
@ -1283,11 +1359,11 @@ long FileUtils::getFileSize(const std::string &filepath)
if (fullpath.empty())
return 0;
}
struct stat info;
// Get data associated with "crt_stat.c":
int result = stat( fullpath.c_str(), &info );
// Check if statistics are valid:
if( result != 0 )
{
@ -1375,6 +1451,7 @@ std::string FileUtils::getSuitableFOpen(const std::string& filenameUtf8) const
{
return filenameUtf8;
}
#endif
NS_CC_END

View File

@ -54,11 +54,11 @@ public:
* Destroys the instance of FileUtils.
*/
static void destroyInstance();
/**
* You can inherit from platform dependent implementation of FileUtils, such as FileUtilsAndroid,
* and use this function to set delegate, then FileUtils will invoke delegate's implementation.
* Fox example, your resources are encrypted, so you need to decrypt it after reading data from
* Fox example, your resources are encrypted, so you need to decrypt it after reading data from
* resources, then you can implement all getXXX functions, and engine will invoke your own getXX
* functions when reading data of resources.
*
@ -82,23 +82,23 @@ public:
* @lua NA
*/
virtual ~FileUtils();
/**
* Purges full path caches.
*/
virtual void purgeCachedEntries();
/**
* Gets string from a file.
*/
virtual std::string getStringFromFile(const std::string& filename);
/**
* Creates binary data from a file.
* @return A data object.
*/
virtual Data getDataFromFile(const std::string& filename);
/**
* Gets resource file data
*
@ -120,59 +120,59 @@ public:
*/
virtual unsigned char* getFileDataFromZip(const std::string& zipFilePath, const std::string& filename, ssize_t *size);
/** Returns the fullpath for a given filename.
First it will try to get a new filename from the "filenameLookup" dictionary.
If a new filename can't be found on the dictionary, it will use the original filename.
Then it will try to obtain the full path of the filename using the FileUtils search rules: resolutions, and search paths.
The file search is based on the array element order of search paths and resolution directories.
For instance:
We set two elements("/mnt/sdcard/", "internal_dir/") to search paths vector by setSearchPaths,
and set three elements("resources-ipadhd/", "resources-ipad/", "resources-iphonehd")
to resolutions vector by setSearchResolutionsOrder. The "internal_dir" is relative to "Resources/".
We set two elements("/mnt/sdcard/", "internal_dir/") to search paths vector by setSearchPaths,
and set three elements("resources-ipadhd/", "resources-ipad/", "resources-iphonehd")
to resolutions vector by setSearchResolutionsOrder. The "internal_dir" is relative to "Resources/".
If we have a file named 'sprite.png', the mapping in fileLookup dictionary contains `key: sprite.png -> value: sprite.pvr.gz`.
Firstly, it will replace 'sprite.png' with 'sprite.pvr.gz', then searching the file sprite.pvr.gz as follows:
If we have a file named 'sprite.png', the mapping in fileLookup dictionary contains `key: sprite.png -> value: sprite.pvr.gz`.
Firstly, it will replace 'sprite.png' with 'sprite.pvr.gz', then searching the file sprite.pvr.gz as follows:
/mnt/sdcard/resources-ipadhd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/resources-ipad/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/resources-iphonehd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/sprite.pvr.gz (if not found, search next)
internal_dir/resources-ipadhd/sprite.pvr.gz (if not found, search next)
internal_dir/resources-ipad/sprite.pvr.gz (if not found, search next)
internal_dir/resources-iphonehd/sprite.pvr.gz (if not found, search next)
internal_dir/sprite.pvr.gz (if not found, return "sprite.png")
/mnt/sdcard/resources-ipadhd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/resources-ipad/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/resources-iphonehd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/sprite.pvr.gz (if not found, search next)
internal_dir/resources-ipadhd/sprite.pvr.gz (if not found, search next)
internal_dir/resources-ipad/sprite.pvr.gz (if not found, search next)
internal_dir/resources-iphonehd/sprite.pvr.gz (if not found, search next)
internal_dir/sprite.pvr.gz (if not found, return "sprite.png")
If the filename contains relative path like "gamescene/uilayer/sprite.png",
and the mapping in fileLookup dictionary contains `key: gamescene/uilayer/sprite.png -> value: gamescene/uilayer/sprite.pvr.gz`.
The file search order will be:
/mnt/sdcard/gamescene/uilayer/resources-ipadhd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/gamescene/uilayer/resources-ipad/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/gamescene/uilayer/resources-iphonehd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/gamescene/uilayer/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/resources-ipadhd/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/resources-ipad/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/resources-iphonehd/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/sprite.pvr.gz (if not found, return "gamescene/uilayer/sprite.png")
/mnt/sdcard/gamescene/uilayer/resources-ipadhd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/gamescene/uilayer/resources-ipad/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/gamescene/uilayer/resources-iphonehd/sprite.pvr.gz (if not found, search next)
/mnt/sdcard/gamescene/uilayer/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/resources-ipadhd/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/resources-ipad/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/resources-iphonehd/sprite.pvr.gz (if not found, search next)
internal_dir/gamescene/uilayer/sprite.pvr.gz (if not found, return "gamescene/uilayer/sprite.png")
If the new file can't be found on the file system, it will return the parameter filename directly.
This method was added to simplify multiplatform support. Whether you are using cocos2d-js or any cross-compilation toolchain like StellaSDK or Apportable,
you might need to load different resources for a given file in the different platforms.
@since v2.1
*/
virtual std::string fullPathForFilename(const std::string &filename) const;
/**
* Loads the filenameLookup dictionary from the contents of a filename.
*
*
* @note The plist file name should follow the format below:
*
*
* @code
* <?xml version="1.0" encoding="UTF-8"?>
* <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@ -202,15 +202,15 @@ public:
* @lua loadFilenameLookup
*/
virtual void loadFilenameLookupDictionaryFromFile(const std::string &filename);
/**
/**
* Sets the filenameLookup dictionary.
*
* @param pFilenameLookupDict The dictionary for replacing filename.
* @since v2.1
*/
virtual void setFilenameLookupDictionary(const ValueMap& filenameLookupDict);
/**
* Gets full path from a file name and the path of the relative file.
* @param filename The file name.
@ -222,7 +222,7 @@ public:
*/
virtual std::string fullPathFromRelativeFile(const std::string &filename, const std::string &relativeFile);
/**
/**
* Sets the array that contains the search order of the resources.
*
* @param searchResolutionsOrder The source array that contains the search order of the resources.
@ -240,7 +240,7 @@ public:
* @since v2.1
*/
virtual void addSearchResolutionsOrder(const std::string &order,const bool front=false);
/**
* Gets the array that contains the search order of the resources.
*
@ -249,19 +249,19 @@ public:
* @lua NA
*/
virtual const std::vector<std::string>& getSearchResolutionsOrder() const;
/**
/**
* Sets the array of search paths.
*
*
* You can use this array to modify the search path of the resources.
* If you want to use "themes" or search resources in the "cache", you can do it easily by adding new entries in this array.
*
* @note This method could access relative path and absolute path.
* If the relative path was passed to the vector, FileUtils will add the default resource directory before the relative path.
* For instance:
* On Android, the default resource root path is "assets/".
* If "/mnt/sdcard/" and "resources-large" were set to the search paths vector,
* "resources-large" will be converted to "assets/resources-large" since it was a relative path.
* On Android, the default resource root path is "assets/".
* If "/mnt/sdcard/" and "resources-large" were set to the search paths vector,
* "resources-large" will be converted to "assets/resources-large" since it was a relative path.
*
* @param searchPaths The array contains search paths.
* @see fullPathForFilename(const char*)
@ -270,7 +270,7 @@ public:
* @lua NA
*/
virtual void setSearchPaths(const std::vector<std::string>& searchPaths);
/**
* Set default resource root path.
*/
@ -282,10 +282,10 @@ public:
* @since v2.1
*/
void addSearchPath(const std::string & path, const bool front=false);
/**
* Gets the array of search paths.
*
*
* @return The array of search paths.
* @see fullPathForFilename(const char*).
* @lua NA
@ -297,7 +297,7 @@ public:
* @return The path that can be write/read a file in
*/
virtual std::string getWritablePath() const = 0;
/**
* Sets writable path.
*/
@ -307,8 +307,8 @@ public:
* Sets whether to pop-up a message box when failed to load an image.
*/
virtual void setPopupNotify(bool notify);
/** Checks whether to pop up a message box when failed to load an image.
/** Checks whether to pop up a message box when failed to load an image.
* @return True if pop up a message box when failed to load an image, false if not.
*/
virtual bool isPopupNotify() const;
@ -321,15 +321,58 @@ public:
*/
virtual ValueMap getValueMapFromFile(const std::string& filename);
// Converts the contents of a file to a ValueMap.
// This method is used internally.
virtual ValueMap getValueMapFromData(const char* filedata, int filesize);
// Write a ValueMap to a plist file.
// This method is used internally.
/** Converts the contents of a file to a ValueMap.
* This method is used internally.
*/
virtual ValueMap getValueMapFromData(const char* filedata, int filesize);
/**
* write a ValueMap into a plist file
*
*@param dict the ValueMap want to save
*@param fullPath The full path to the file you want to save a string
*@return bool
*/
virtual bool writeToFile(ValueMap& dict, const std::string& fullPath);
/**
* write a string into a file
*
* @param dataStr the string want to save
* @param fullPath The full path to the file you want to save a string
* @return bool True if write success
*/
virtual bool writeStringToFile(std::string dataStr, const std::string& fullPath);
/**
* write Data into a file
*
*@param retData the data want to save
*@param fullPath The full path to the file you want to save a string
*@return bool
*/
virtual bool writeDataToFile(Data retData, const std::string& fullPath);
/**
* write ValueMap into a plist file
*
*@param dict the ValueMap want to save
*@param fullPath The full path to the file you want to save a string
*@return bool
*/
virtual bool writeValueMapToFile(ValueMap& dict, const std::string& fullPath);
/**
* write ValueVector into a plist file
*
*@param vecData the ValueVector want to save
*@param fullPath The full path to the file you want to save a string
*@return bool
*/
virtual bool writeValueVectorToFile(ValueVector vecData, const std::string& fullPath);
/**
* Windows fopen can't support UTF-8 filename
* Need convert all parameters fopen and other 3rd-party libs
@ -338,11 +381,11 @@ public:
* @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);
/**
* Checks whether a file exists.
*
@ -351,7 +394,7 @@ public:
* @return True if the file exists, false if not.
*/
virtual bool isFileExist(const std::string& filename) const;
/**
* Checks whether the path is an absolute path.
*
@ -362,7 +405,7 @@ public:
* @return True if it's an absolute path, false if not.
*/
virtual bool isAbsolutePath(const std::string& path) const;
/**
* Checks whether the path is a directory.
*
@ -370,7 +413,7 @@ public:
* @return True if the directory exists, false if not.
*/
virtual bool isDirectoryExist(const std::string& dirPath) const;
/**
* Creates a directory.
*
@ -378,7 +421,7 @@ public:
* @return True if the directory have been created successfully, false if not.
*/
virtual bool createDirectory(const std::string& dirPath);
/**
* Removes a directory.
*
@ -386,7 +429,7 @@ public:
* @return True if the directory have been removed successfully, false if not.
*/
virtual bool removeDirectory(const std::string& dirPath);
/**
* Removes a file.
*
@ -394,7 +437,7 @@ public:
* @return True if the file have been removed successfully, false if not.
*/
virtual bool removeFile(const std::string &filepath);
/**
* Renames a file under the given directory.
*
@ -404,7 +447,7 @@ public:
* @return True if the file have been renamed successfully, false if not.
*/
virtual bool renameFile(const std::string &path, const std::string &oldname, const std::string &name);
/**
* Retrieve the file size.
*
@ -422,7 +465,7 @@ protected:
* The default constructor.
*/
FileUtils();
/**
* Initializes the instance of FileUtils. It will set _searchPathArray and _searchResolutionsOrderArray to default values.
*
@ -432,7 +475,7 @@ protected:
*
*/
virtual bool init();
/**
* Gets the new filename from the filename lookup dictionary.
* It is possible to have a override names.
@ -441,21 +484,21 @@ protected:
* If the original filename wasn't in the dictionary, it will return the original filename.
*/
virtual std::string getNewFilename(const std::string &filename) const;
/**
* Checks whether a file exists without considering search paths and resolution orders.
* @param filename The file (with absolute path) to look up for
* @return Returns true if the file found at the given absolute path, otherwise returns false
*/
virtual bool isFileExistInternal(const std::string& filename) const = 0;
/**
* Checks whether a directory exists without considering search paths and resolution orders.
* @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 = 0;
/**
* Gets full path for filename, resolution directory and search path.
*
@ -465,7 +508,7 @@ protected:
* @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) const;
/**
* Gets full path for the directory and the filename.
*
@ -477,7 +520,7 @@ protected:
* @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& directory, const std::string& filename) const;
/** Dictionary used to lookup filenames based on a key.
* It is used internally by the following methods:
*
@ -486,19 +529,19 @@ protected:
* @since v2.1
*/
ValueMap _filenameLookupDict;
/**
/**
* The vector contains resolution folders.
* The lower index of the element in this vector, the higher priority for this resolution directory.
*/
std::vector<std::string> _searchResolutionsOrderArray;
/**
* The vector contains search paths.
* The lower index of the element in this vector, the higher priority for this search path.
*/
std::vector<std::string> _searchPathArray;
/**
* The default root path of resources.
* If the default root path of resources needs to be changed, do it in the `init` method of FileUtils's subclass.
@ -507,13 +550,13 @@ protected:
* Similarly on Blackberry, we assign "app/native/Resources/" to this variable in FileUtilsBlackberry::init().
*/
std::string _defaultResRootPath;
/**
* The full path cache. When a file is found, it will be added into this cache.
* The full path cache. When a file is found, it will be added into this cache.
* This variable is used for improving the performance of file search.
*/
mutable std::unordered_map<std::string, std::string> _fullPathCache;
/**
* Writable path.
*/
@ -523,7 +566,7 @@ protected:
* The singleton pointer of FileUtils.
*/
static FileUtils* s_sharedFileUtils;
};
// end of support group

View File

@ -87,7 +87,7 @@ bool FileUtilsAndroid::init()
{
_defaultResRootPath = "assets/";
}
return FileUtils::init();
}
@ -131,7 +131,7 @@ std::string FileUtilsAndroid::getNewFilename(const std::string &filename) const
}
idx = pos + 1;
}
if (change)
{
newFileName.clear();
@ -156,7 +156,7 @@ bool FileUtilsAndroid::isFileExistInternal(const std::string& strFilePath) const
}
bool bFound = false;
// Check whether file exists in apk.
if (strFilePath[0] != '/')
{
@ -260,7 +260,7 @@ Data FileUtilsAndroid::getData(const std::string& filename, bool forString)
{
return Data::Null;
}
unsigned char* data = nullptr;
ssize_t size = 0;
string fullPath = fullPathForFilename(filename);
@ -325,7 +325,7 @@ Data FileUtilsAndroid::getData(const std::string& filename, bool forString)
FILE *fp = fopen(fullPath.c_str(), mode);
CC_BREAK_IF(!fp);
long fileSize;
fseek(fp,0,SEEK_END);
fileSize = ftell(fp);
@ -341,11 +341,11 @@ Data FileUtilsAndroid::getData(const std::string& filename, bool forString)
}
fileSize = fread(data,sizeof(unsigned char), fileSize,fp);
fclose(fp);
size = fileSize;
} while (0);
}
Data ret;
if (data == nullptr || size == 0)
{
@ -371,21 +371,21 @@ std::string FileUtilsAndroid::getStringFromFile(const std::string& filename)
std::string ret((const char*)data.getBytes());
return ret;
}
Data FileUtilsAndroid::getDataFromFile(const std::string& filename)
{
return getData(filename, false);
}
unsigned char* FileUtilsAndroid::getFileData(const std::string& filename, const char* mode, ssize_t * size)
{
{
unsigned char * data = 0;
if ( filename.empty() || (! mode) )
{
return 0;
}
string fullPath = fullPathForFilename(filename);
cocosplay::updateAssets(fullPath);
@ -437,7 +437,7 @@ unsigned char* FileUtilsAndroid::getFileData(const std::string& filename, const
//CCLOG("GETTING FILE ABSOLUTE DATA: %s", filename);
FILE *fp = fopen(fullPath.c_str(), mode);
CC_BREAK_IF(!fp);
long fileSize;
fseek(fp,0,SEEK_END);
fileSize = ftell(fp);
@ -445,14 +445,14 @@ unsigned char* FileUtilsAndroid::getFileData(const std::string& filename, const
data = (unsigned char*) malloc(fileSize);
fileSize = fread(data,sizeof(unsigned char), fileSize,fp);
fclose(fp);
if (size)
{
*size = fileSize;
}
} while (0);
}
if (! data)
{
std::string msg = "Get data from file(";

View File

@ -451,9 +451,9 @@ ValueMap FileUtilsApple::getValueMapFromData(const char* filedata, int filesize)
NSPropertyListFormat format;
NSError* error;
NSDictionary* dict = [NSPropertyListSerialization propertyListWithData:file options:NSPropertyListImmutable format:&format error:&error];
ValueMap ret;
if (dict != nil)
{
for (id key in [dict allKeys])
@ -467,21 +467,41 @@ ValueMap FileUtilsApple::getValueMapFromData(const char* filedata, int filesize)
bool FileUtilsApple::writeToFile(ValueMap& dict, const std::string &fullPath)
{
return writeValueMapToFile(dict, fullPath);
}
bool FileUtils::writeValueMapToFile(ValueMap& dict, const std::string& fullPath)
{
//CCLOG("iOS||Mac Dictionary %d write to file %s", dict->_ID, fullPath.c_str());
NSMutableDictionary *nsDict = [NSMutableDictionary dictionary];
for (auto iter = dict.begin(); iter != dict.end(); ++iter)
{
addObjectToNSDict(iter->first, iter->second, nsDict);
}
NSString *file = [NSString stringWithUTF8String:fullPath.c_str()];
// do it atomically
[nsDict writeToFile:file atomically:YES];
return true;
}
bool FileUtils::writeValueVectorToFile(ValueVector vecData, const std::string& fullPath)
{
NSString* path = [NSString stringWithUTF8String:fullPath.c_str()];
NSMutableArray* array = [NSMutableArray array];
for (const auto &e : vecData)
{
addObjectToNSArray(e, array);
}
[array writeToFile:path atomically:YES];
return true;
}
ValueVector FileUtilsApple::getValueVectorFromFile(const std::string& filename)
{
// NSString* pPath = [NSString stringWithUTF8String:pFileName];

View File

@ -117,7 +117,7 @@ bool FileUtilsLinux::isFileExistInternal(const std::string& strFilePath) const
{ // Not absolute path, add the default root path at the beginning.
strPath.insert(0, _defaultResRootPath);
}
struct stat sts;
return (stat(strPath.c_str(), &sts) != -1) ? true : false;
}

View File

@ -105,7 +105,7 @@ bool FileUtilsWin32::isFileExistInternal(const std::string& strFilePath) const
{
return false;
}
std::string strPath = strFilePath;
if (!isAbsolutePath(strPath))
{ // Not absolute path, add the default root path at the beginning.
@ -134,7 +134,7 @@ bool FileUtilsWin32::isDirectoryExistInternal(const std::string& dirPath) const
bool FileUtilsWin32::isAbsolutePath(const std::string& strPath) const
{
if ( (strPath.length() > 2
if ( (strPath.length() > 2
&& ( (strPath[0] >= 'a' && strPath[0] <= 'z') || (strPath[0] >= 'A' && strPath[0] <= 'Z') )
&& strPath[1] == ':') || (strPath[0] == '/' && strPath[1] == '/'))
{
@ -150,9 +150,9 @@ static bool checkFileName(const std::string& fullPath, const std::string& filena
size_t len = tmpPath.length();
size_t nl = filename.length();
std::string realName;
while (tmpPath.length() >= len - nl && tmpPath.length()>2)
{
{
//CCLOG("%s", tmpPath.c_str());
WIN32_FIND_DATAA data;
HANDLE h = FindFirstFileA(tmpPath.c_str(), &data);
@ -169,7 +169,7 @@ static bool checkFileName(const std::string& fullPath, const std::string& filena
{
std::string msg = "File path error: \"";
msg.append(filename).append("\" the real name is: ").append(realName);
CCLOG("%s", msg.c_str());
return false;
}
@ -185,7 +185,7 @@ static bool checkFileName(const std::string& fullPath, const std::string& filena
tmpPath = tmpPath.substr(0, tmpPath.rfind("/"));
} while (tmpPath.back() == '.');
}
return true;
return true;
}
static Data getData(const std::string& filename, bool forString)
@ -211,7 +211,7 @@ static Data getData(const std::string& filename, bool forString)
HANDLE fileHandle = ::CreateFileW(wszBuf, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, nullptr);
CC_BREAK_IF(fileHandle == INVALID_HANDLE_VALUE);
size = ::GetFileSize(fileHandle, nullptr);
if (forString)
@ -235,10 +235,10 @@ static Data getData(const std::string& filename, bool forString)
{
free(buffer);
buffer = nullptr;
}
}
}
} while (0);
Data ret;
if (buffer == nullptr || size == 0)
@ -265,15 +265,15 @@ static Data getData(const std::string& filename, bool forString)
std::string FileUtilsWin32::getStringFromFile(const std::string& filename)
{
Data data = getData(filename, true);
if (data.isNull())
{
return "";
}
if (data.isNull())
{
return "";
}
std::string ret((const char*)data.getBytes());
return ret;
}
Data FileUtilsWin32::getDataFromFile(const std::string& filename)
{
return getData(filename, false);
@ -296,7 +296,7 @@ unsigned char* FileUtilsWin32::getFileData(const std::string& filename, const ch
HANDLE fileHandle = ::CreateFileW(wszBuf, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, nullptr);
CC_BREAK_IF(fileHandle == INVALID_HANDLE_VALUE);
*size = ::GetFileSize(fileHandle, nullptr);
pBuffer = (unsigned char*) malloc(*size);
@ -311,7 +311,7 @@ unsigned char* FileUtilsWin32::getFileData(const std::string& filename, const ch
pBuffer = nullptr;
}
} while (0);
if (! pBuffer)
{
std::string msg = "Get data from file(";
@ -339,7 +339,7 @@ std::string FileUtilsWin32::getFullPathForDirectoryAndFilename(const std::string
{
std::string unixDirectory = convertPathFormatToUnixStyle(strDirectory);
std::string unixFilename = convertPathFormatToUnixStyle(strFilename);
return FileUtils::getFullPathForDirectoryAndFilename(unixDirectory, unixFilename);
}

View File

@ -52,8 +52,8 @@ static void _checkPath()
{
if (s_pszResourcePath.empty())
{
// TODO: needs to be tested
s_pszResourcePath = convertPathFormatToUnixStyle(CCFileUtilsWinRT::getAppPath() + '\\' + "Assets\\Resources" + '\\');
// TODO: needs to be tested
s_pszResourcePath = convertPathFormatToUnixStyle(CCFileUtilsWinRT::getAppPath() + '\\' + "Assets\\Resources" + '\\');
}
}
@ -134,7 +134,7 @@ bool CCFileUtilsWinRT::isDirectoryExistInternal(const std::string& dirPath) cons
bool CCFileUtilsWinRT::isAbsolutePath(const std::string& strPath) const
{
if ( strPath.length() > 2
if ( strPath.length() > 2
&& ( (strPath[0] >= 'a' && strPath[0] <= 'z') || (strPath[0] >= 'A' && strPath[0] <= 'Z') )
&& strPath[1] == ':')
{
@ -149,13 +149,13 @@ static Data getData(const std::string& filename, bool forString)
{
CCASSERT(!filename.empty(), "Invalid filename!");
}
Data ret;
unsigned char* buffer = nullptr;
ssize_t size = 0;
const char* mode = nullptr;
mode = "rb";
do
{
// Read the file from hardware
@ -165,7 +165,7 @@ static Data getData(const std::string& filename, bool forString)
fseek(fp,0,SEEK_END);
size = ftell(fp);
fseek(fp,0,SEEK_SET);
if (forString)
{
buffer = (unsigned char*)malloc(sizeof(unsigned char) * (size + 1));
@ -175,11 +175,11 @@ static Data getData(const std::string& filename, bool forString)
{
buffer = (unsigned char*)malloc(sizeof(unsigned char) * size);
}
size = fread(buffer, sizeof(unsigned char), size, fp);
fclose(fp);
} while (0);
if (nullptr == buffer || 0 == size)
{
std::string msg = "Get data from file(";
@ -190,31 +190,31 @@ static Data getData(const std::string& filename, bool forString)
{
ret.fastSet(buffer, size);
}
return ret;
}
std::string CCFileUtilsWinRT::getStringFromFile(const std::string& filename)
{
Data data = getData(filename, true);
if (data.isNull())
{
return "";
}
if (data.isNull())
{
return "";
}
std::string ret((const char*)data.getBytes());
return ret;
}
string CCFileUtilsWinRT::getWritablePath() const
{
auto localFolderPath = Windows::Storage::ApplicationData::Current->LocalFolder->Path;
return convertPathFormatToUnixStyle(std::string(PlatformStringToString(localFolderPath)) + '\\');
auto localFolderPath = Windows::Storage::ApplicationData::Current->LocalFolder->Path;
return convertPathFormatToUnixStyle(std::string(PlatformStringToString(localFolderPath)) + '\\');
}
string CCFileUtilsWinRT::getAppPath()
{
Windows::ApplicationModel::Package^ package = Windows::ApplicationModel::Package::Current;
return convertPathFormatToUnixStyle(std::string(PlatformStringToString(package->InstalledLocation->Path)));
Windows::ApplicationModel::Package^ package = Windows::ApplicationModel::Package::Current;
return convertPathFormatToUnixStyle(std::string(PlatformStringToString(package->InstalledLocation->Path)));
}
NS_CC_END

View File

@ -11,6 +11,10 @@ FileUtilsTests::FileUtilsTests()
ADD_TEST_CASE(TestFileFuncs);
ADD_TEST_CASE(TestDirectoryFuncs);
ADD_TEST_CASE(TextWritePlist);
ADD_TEST_CASE(TestWriteString);
ADD_TEST_CASE(TestWriteData);
ADD_TEST_CASE(TestWriteValueMap);
ADD_TEST_CASE(TestWriteValueVector);
}
// TestResolutionDirectories
@ -21,13 +25,13 @@ void TestResolutionDirectories::onEnter()
auto sharedFileUtils = FileUtils::getInstance();
std::string ret;
sharedFileUtils->purgeCachedEntries();
_defaultSearchPathArray = sharedFileUtils->getSearchPaths();
std::vector<std::string> searchPaths = _defaultSearchPathArray;
searchPaths.insert(searchPaths.begin(), "Misc");
sharedFileUtils->setSearchPaths(searchPaths);
_defaultResolutionsOrderArray = sharedFileUtils->getSearchResolutionsOrder();
std::vector<std::string> resolutionsOrder = _defaultResolutionsOrderArray;
@ -37,9 +41,9 @@ void TestResolutionDirectories::onEnter()
resolutionsOrder.insert(resolutionsOrder.begin()+3, "resources-wide");
resolutionsOrder.insert(resolutionsOrder.begin()+4, "resources-hd");
resolutionsOrder.insert(resolutionsOrder.begin()+5, "resources-iphone");
sharedFileUtils->setSearchResolutionsOrder(resolutionsOrder);
for( int i=1; i<7; i++) {
auto filename = String::createWithFormat("test%d.txt", i);
ret = sharedFileUtils->fullPathForFilename(filename->getCString());
@ -50,9 +54,9 @@ void TestResolutionDirectories::onEnter()
void TestResolutionDirectories::onExit()
{
auto sharedFileUtils = FileUtils::getInstance();
// reset search path
sharedFileUtils->setSearchPaths(_defaultSearchPathArray);
// reset search path
sharedFileUtils->setSearchPaths(_defaultSearchPathArray);
sharedFileUtils->setSearchResolutionsOrder(_defaultResolutionsOrderArray);
FileUtilsDemo::onExit();
}
@ -73,9 +77,9 @@ void TestSearchPath::onEnter()
{
FileUtilsDemo::onEnter();
auto sharedFileUtils = FileUtils::getInstance();
std::string ret;
sharedFileUtils->purgeCachedEntries();
_defaultSearchPathArray = sharedFileUtils->getSearchPaths();
std::vector<std::string> searchPaths = _defaultSearchPathArray;
@ -91,24 +95,24 @@ void TestSearchPath::onEnter()
if (ret != 0)
log("Writing file to writable path succeed.");
}
searchPaths.insert(searchPaths.begin(), writablePath);
searchPaths.insert(searchPaths.begin()+1, "Misc/searchpath1");
searchPaths.insert(searchPaths.begin()+2, "Misc/searchpath2");
sharedFileUtils->setSearchPaths(searchPaths);
_defaultResolutionsOrderArray = sharedFileUtils->getSearchResolutionsOrder();
std::vector<std::string> resolutionsOrder = _defaultResolutionsOrderArray;
resolutionsOrder.insert(resolutionsOrder.begin(), "resources-ipad");
sharedFileUtils->setSearchResolutionsOrder(resolutionsOrder);
for( int i=1; i<3; i++) {
auto filename = String::createWithFormat("file%d.txt", i);
ret = sharedFileUtils->fullPathForFilename(filename->getCString());
log("%s -> %s", filename->getCString(), ret.c_str());
}
// Gets external.txt from writable path
std::string fullPath = sharedFileUtils->fullPathForFilename("external.txt");
log("external file path = %s", fullPath.c_str());
@ -128,10 +132,10 @@ void TestSearchPath::onEnter()
void TestSearchPath::onExit()
{
FileUtils *sharedFileUtils = FileUtils::getInstance();
FileUtils *sharedFileUtils = FileUtils::getInstance();
// reset search path
sharedFileUtils->setSearchPaths(_defaultSearchPathArray);
// reset search path
sharedFileUtils->setSearchPaths(_defaultSearchPathArray);
sharedFileUtils->setSearchResolutionsOrder(_defaultResolutionsOrderArray);
FileUtilsDemo::onExit();
}
@ -151,31 +155,31 @@ std::string TestSearchPath::subtitle() const
void TestFilenameLookup::onEnter()
{
FileUtilsDemo::onEnter();
auto sharedFileUtils = FileUtils::getInstance();
ValueMap dict;
dict["grossini.bmp"] = Value("Images/grossini.png");
dict["grossini.xcf"] = Value("Images/grossini.png");
sharedFileUtils->setFilenameLookupDictionary(dict);
// Instead of loading carlitos.xcf, it will load grossini.png
auto sprite = Sprite::create("grossini.xcf");
this->addChild(sprite);
auto s = Director::getInstance()->getWinSize();
sprite->setPosition(s.width/2, s.height/2);
}
void TestFilenameLookup::onExit()
{
FileUtils *sharedFileUtils = FileUtils::getInstance();
// reset filename lookup
FileUtils *sharedFileUtils = FileUtils::getInstance();
// reset filename lookup
sharedFileUtils->setFilenameLookupDictionary(ValueMap());
FileUtilsDemo::onExit();
}
@ -191,16 +195,16 @@ void TestIsFileExist::onEnter()
FileUtilsDemo::onEnter();
auto s = Director::getInstance()->getWinSize();
auto sharedFileUtils = FileUtils::getInstance();
Label* label = nullptr;
bool isExist = false;
isExist = sharedFileUtils->isFileExist("Images/grossini.png");
label = Label::createWithSystemFont(isExist ? "Images/grossini.png exists" : "Images/grossini.png doesn't exist", "", 20);
label->setPosition(s.width/2, s.height/3);
this->addChild(label);
isExist = sharedFileUtils->isFileExist("Images/grossini.xcf");
label = Label::createWithSystemFont(isExist ? "Images/grossini.xcf exists" : "Images/grossini.xcf doesn't exist", "", 20);
label->setPosition(s.width/2, s.height/3*2);
@ -209,12 +213,12 @@ void TestIsFileExist::onEnter()
void TestIsFileExist::onExit()
{
FileUtils *sharedFileUtils = FileUtils::getInstance();
// reset filename lookup
FileUtils *sharedFileUtils = FileUtils::getInstance();
// reset filename lookup
sharedFileUtils->setFilenameLookupDictionary(ValueMap());
FileUtilsDemo::onExit();
}
@ -235,42 +239,42 @@ void TestFileFuncs::onEnter()
FileUtilsDemo::onEnter();
auto s = Director::getInstance()->getWinSize();
auto sharedFileUtils = FileUtils::getInstance();
int x = s.width/2,
y = s.height/5;
Label* label = nullptr;
std::string filename = "__test.test";
std::string filename2 = "__newtest.test";
std::string filepath = sharedFileUtils->getWritablePath() + filename;
std::string content = "Test string content to put into created file";
std::string msg;
FILE *out = fopen(filepath.c_str(), "w");
fputs(content.c_str(), out);
fclose(out);
// Check whether file can be created
if (sharedFileUtils->isFileExist(filepath))
{
label = Label::createWithSystemFont("Test file '__test.test' created", "", 20);
label->setPosition(x, y * 4);
this->addChild(label);
// getFileSize Test
long size = sharedFileUtils->getFileSize(filepath);
msg = StringUtils::format("getFileSize: Test file size equals %ld", size);
label = Label::createWithSystemFont(msg, "", 20);
label->setPosition(x, y * 3);
this->addChild(label);
// renameFile Test
if (sharedFileUtils->renameFile(sharedFileUtils->getWritablePath(), filename, filename2))
{
label = Label::createWithSystemFont("renameFile: Test file renamed to '__newtest.test'", "", 20);
label->setPosition(x, y * 2);
this->addChild(label);
// removeFile Test
filepath = sharedFileUtils->getWritablePath() + filename2;
if (sharedFileUtils->removeFile(filepath))
@ -318,16 +322,16 @@ void TestDirectoryFuncs::onEnter()
FileUtilsDemo::onEnter();
auto s = Director::getInstance()->getWinSize();
auto sharedFileUtils = FileUtils::getInstance();
int x = s.width/2,
y = s.height/4;
Label* label = nullptr;
std::string dir = sharedFileUtils->getWritablePath() + "__test/";
std::string subDir = "dir1/dir2";
std::string msg;
bool ok;
// Check whether dir can be created
ok = sharedFileUtils->createDirectory(dir);
if (ok && sharedFileUtils->isDirectoryExist(dir))
@ -336,7 +340,7 @@ void TestDirectoryFuncs::onEnter()
label = Label::createWithSystemFont(msg, "", 20);
label->setPosition(x, y * 3);
this->addChild(label);
// Create sub directories recursively
ok = sharedFileUtils->createDirectory(dir + subDir);
if (ok && sharedFileUtils->isDirectoryExist(dir + subDir))
@ -353,7 +357,7 @@ void TestDirectoryFuncs::onEnter()
label->setPosition(x, y * 2);
this->addChild(label);
}
// Remove directory
ok = sharedFileUtils->removeDirectory(dir);
if (ok && !sharedFileUtils->isDirectoryExist(dir))
@ -390,7 +394,7 @@ std::string TestDirectoryFuncs::subtitle() const
return "";
}
// TestWritePlist
// TextWritePlist
void TextWritePlist::onEnter()
{
@ -398,46 +402,46 @@ void TextWritePlist::onEnter()
auto root = Dictionary::create();
auto string = String::create("string element value");
root->setObject(string, "string element key");
auto array = Array::create();
auto dictInArray = Dictionary::create();
dictInArray->setObject(String::create("string in dictInArray value 0"), "string in dictInArray key 0");
dictInArray->setObject(String::create("string in dictInArray value 1"), "string in dictInArray key 1");
array->addObject(dictInArray);
array->addObject(String::create("string in array"));
auto arrayInArray = Array::create();
arrayInArray->addObject(String::create("string 0 in arrayInArray"));
arrayInArray->addObject(String::create("string 1 in arrayInArray"));
array->addObject(arrayInArray);
root->setObject(array, "array");
auto dictInDict = Dictionary::create();
dictInDict->setObject(String::create("string in dictInDict value"), "string in dictInDict key");
//add boolean to the plist
auto booleanObject = Bool::create(true);
dictInDict->setObject(booleanObject, "bool");
//add interger to the plist
auto intObject = Integer::create(1024);
dictInDict->setObject(intObject, "integer");
//add float to the plist
auto floatObject = Float::create(1024.1024f);
dictInDict->setObject(floatObject, "float");
//add double to the plist
auto doubleObject = Double::create(1024.123);
dictInDict->setObject(doubleObject, "double");
root->setObject(dictInDict, "dictInDict, Hello World");
// end with /
std::string writablePath = FileUtils::getInstance()->getWritablePath();
std::string fullPath = writablePath + "text.plist";
@ -445,12 +449,12 @@ void TextWritePlist::onEnter()
log("see the plist file at %s", fullPath.c_str());
else
log("write plist file failed");
auto label = Label::createWithTTF(fullPath.c_str(), "fonts/Thonburi.ttf", 6);
this->addChild(label);
auto winSize = Director::getInstance()->getWinSize();
label->setPosition(winSize.width/2, winSize.height/3);
auto loadDict = __Dictionary::createWithContentsOfFile(fullPath.c_str());
auto loadDictInDict = (__Dictionary*)loadDict->objectForKey("dictInDict, Hello World");
auto boolValue = (__String*)loadDictInDict->objectForKey("bool");
@ -479,3 +483,321 @@ std::string TextWritePlist::subtitle() const
std::string writablePath = FileUtils::getInstance()->getWritablePath().c_str();
return ("See plist file at your writablePath");
}
void TestWriteString::onEnter()
{
FileUtilsDemo::onEnter();
auto winSize = Director::getInstance()->getWinSize();
auto writeResult = Label::createWithTTF("show writeResult", "fonts/Thonburi.ttf", 18);
this->addChild(writeResult);
writeResult->setPosition(winSize.width / 2, winSize.height * 3 / 4);
auto readResult = Label::createWithTTF("show readResult", "fonts/Thonburi.ttf", 18);
this->addChild(readResult);
readResult->setPosition(winSize.width / 2, winSize.height / 3);
std::string writablePath = FileUtils::getInstance()->getWritablePath();
std::string fileName = "writeStringTest.txt";
// writeTest
std::string writeDataStr = "the string data will be write into a file";
std::string fullPath = writablePath + fileName;
if (FileUtils::getInstance()->writeStringToFile(writeDataStr, fullPath.c_str()))
{
log("see the plist file at %s", fullPath.c_str());
writeResult->setString("write success:" + writeDataStr);
}
else
{
log("write plist file failed");
writeResult->setString("write fail");
}
// readTest
std::string readDataStr = FileUtils::getInstance()->getStringFromFile(fullPath);
readResult->setString("read success:" + readDataStr);
}
void TestWriteString::onExit()
{
FileUtilsDemo::onExit();
}
std::string TestWriteString::title() const
{
return "FileUtils: TestWriteString to files";
}
std::string TestWriteString::subtitle() const
{
return "";
}
void TestWriteData::onEnter()
{
FileUtilsDemo::onEnter();
auto winSize = Director::getInstance()->getWinSize();
auto writeResult = Label::createWithTTF("show writeResult", "fonts/Thonburi.ttf", 18);
this->addChild(writeResult);
writeResult->setPosition(winSize.width / 2, winSize.height * 3 / 4);
auto readResult = Label::createWithTTF("show readResult", "fonts/Thonburi.ttf", 18);
this->addChild(readResult);
readResult->setPosition(winSize.width / 2, winSize.height / 3);
std::string writablePath = FileUtils::getInstance()->getWritablePath();
std::string fileName = "writeDataTest.txt";
// writeTest
std::string writeDataStr = "the binary data will be write into a file";
Data writeData;
writeData.copy((unsigned char *)writeDataStr.c_str(), writeDataStr.size());
std::string fullPath = writablePath + fileName;
if (FileUtils::getInstance()->writeDataToFile(writeData, fullPath.c_str()))
{
log("see the plist file at %s", fullPath.c_str());
writeResult->setString("write success:" + writeDataStr);
}
else
{
log("write plist file failed");
writeResult->setString("write fail");
}
// readTest
unsigned char* buffer = nullptr;
Data readData = FileUtils::getInstance()->getDataFromFile(fullPath);
buffer = (unsigned char*)malloc(sizeof(unsigned char) * (readData.getSize() + 1));
memcpy(buffer, readData.getBytes(), readData.getSize());
buffer[readData.getSize()] = '\0';
std::string readDataStr((const char*)buffer);
free(buffer);
readResult->setString("read success:" + readDataStr);
}
void TestWriteData::onExit()
{
FileUtilsDemo::onExit();
}
std::string TestWriteData::title() const
{
return "FileUtils: TestWriteData to files";
}
std::string TestWriteData::subtitle() const
{
return "";
}
void TestWriteValueMap::onEnter()
{
FileUtilsDemo::onEnter();
auto winSize = Director::getInstance()->getWinSize();
auto writeResult = Label::createWithTTF("show writeResult", "fonts/Thonburi.ttf", 18);
this->addChild(writeResult);
writeResult->setPosition(winSize.width / 2, winSize.height * 3 / 4);
auto readResult = Label::createWithTTF("show readResult", "fonts/Thonburi.ttf", 18);
this->addChild(readResult);
readResult->setPosition(winSize.width / 2, winSize.height / 3);
ValueMap valueMap;
ValueMap mapInValueMap;
mapInValueMap["string1"] = "string in dictInMap key 0";
mapInValueMap["string2"] = "string in dictInMap key 1";
valueMap["data0"] = Value(mapInValueMap);
valueMap["data1"] = Value("string in array");
ValueVector arrayInMap;
arrayInMap.push_back(Value("string 0 in arrayInMap"));
arrayInMap.push_back(Value("string 1 in arrayInMap"));
valueMap["data2"] = arrayInMap;
//add boolean to the plist
auto booleanObject = Value(true);
valueMap["data3"] = booleanObject;
//add interger to the plist
auto intObject = Value(1024);
valueMap["data4"] = intObject;
//add float to the plist
auto floatObject = Value(1024.1024f);
valueMap["data5"] = floatObject;
//add double to the plist
auto doubleObject = Value(1024.123);
valueMap["data6"] = doubleObject;
// end with /
std::string writablePath = FileUtils::getInstance()->getWritablePath();
std::string fullPath = writablePath + "testWriteValueMap.plist";
if (FileUtils::getInstance()->writeValueMapToFile(valueMap, fullPath.c_str()))
{
log("see the plist file at %s", fullPath.c_str());
writeResult->setString("write success");
}
else
{
log("write plist file failed");
writeResult->setString("write failed");
}
ValueMap readValueMap = FileUtils::getInstance()->getValueMapFromFile(fullPath.c_str());
std::string readDataStr = "read data:\n";
// read value map data
ValueMap readMapInMap = readValueMap["data0"].asValueMap();
readDataStr += " mapValue:[\"string1\"][" + readMapInMap["string1"].asString() + "]\n";
readDataStr += " mapValue:[\"string2\"][" + readMapInMap["string2"].asString() + "]\n";
// read string data
readDataStr += " stringValue:" + readValueMap["data1"].asString() + "\n";
// read value vector data
ValueVector readVectorInMap = readValueMap["data2"].asValueVector();
readDataStr += " vectorValue:[1]" + readVectorInMap.at(0).asString() + "\n";
readDataStr += " vectorValue:[2]" + readVectorInMap.at(1).asString() + "\n";
// read bool data
readDataStr += " boolValue:" + StringUtils::format("%d", readValueMap["data3"].asBool()) + "\n";
// read int data
readDataStr += " intValue:" + StringUtils::format("%d", readValueMap["data4"].asInt()) + "\n";
// read float data
readDataStr += " floatValue:" + StringUtils::format("%f", readValueMap["data5"].asFloat()) + "\n";
// read double data
readDataStr += " doubleValue:" + StringUtils::format("%f", readValueMap["data6"].asDouble()) + "\n";
readResult->setString(readDataStr);
}
void TestWriteValueMap::onExit()
{
FileUtilsDemo::onExit();
}
std::string TestWriteValueMap::title() const
{
return "FileUtils: TestWriteValueMap to files";
}
std::string TestWriteValueMap::subtitle() const
{
return "";
}
void TestWriteValueVector::onEnter()
{
FileUtilsDemo::onEnter();
auto winSize = Director::getInstance()->getWinSize();
auto writeResult = Label::createWithTTF("show writeResult", "fonts/Thonburi.ttf", 18);
this->addChild(writeResult);
writeResult->setPosition(winSize.width / 2, winSize.height * 3 / 4);
auto readResult = Label::createWithTTF("show readResult", "fonts/Thonburi.ttf", 18);
this->addChild(readResult);
readResult->setPosition(winSize.width / 2, winSize.height / 3);
ValueVector array;
ValueMap mapInArray;
mapInArray["string1"] = "string in dictInArray key 0";
mapInArray["string2"] = "string in dictInArray key 1";
array.push_back(Value(mapInArray));
array.push_back(Value("string in array"));
ValueVector arrayInArray;
arrayInArray.push_back(Value("string 0 in arrayInArray"));
arrayInArray.push_back(Value("string 1 in arrayInArray"));
array.push_back(Value(arrayInArray));
//add boolean to the plist
auto booleanObject = Value(true);
array.push_back(booleanObject);
//add interger to the plist
auto intObject = Value(1024);
array.push_back(intObject);
//add float to the plist
auto floatObject = Value(1024.1024f);
array.push_back(floatObject);
//add double to the plist
auto doubleObject = Value(1024.123);
array.push_back(doubleObject);
// end with /
std::string writablePath = FileUtils::getInstance()->getWritablePath();
std::string fullPath = writablePath + "testWriteValueVector.plist";
if (FileUtils::getInstance()->writeValueVectorToFile(array, fullPath.c_str()))
{
log("see the plist file at %s", fullPath.c_str());
writeResult->setString("write success");
}
else
{
log("write plist file failed");
writeResult->setString("write failed");
}
ValueVector readArray = FileUtils::getInstance()->getValueVectorFromFile(fullPath.c_str());
std::string readDataStr = "read data:\n";
// read value map data
ValueMap readMapInArray = readArray.at(0).asValueMap();
readDataStr += " mapValue:[\"string1\"][" + readMapInArray["string1"].asString() + "]\n";
readDataStr += " mapValue:[\"string2\"][" + readMapInArray["string2"].asString() + "]\n";
// read string data
readDataStr += " stringValue:" + readArray.at(1).asString() + "\n";
// read value vector data
ValueVector readVectorInArray = readArray.at(2).asValueVector();
readDataStr += " vectorValue:[1]" + readVectorInArray.at(0).asString() + "\n";
readDataStr += " vectorValue:[2]" + readVectorInArray.at(1).asString() + "\n";
// read bool data
readDataStr += " boolValue:" + StringUtils::format("%d", readArray.at(3).asBool()) + "\n";
// read int data
readDataStr += " intValue:" + StringUtils::format("%d", readArray.at(4).asInt()) + "\n";
// read float data
readDataStr += " floatValue:" + StringUtils::format("%f", readArray.at(5).asFloat()) + "\n";
// read double data
readDataStr += " doubleValue:" + StringUtils::format("%f", readArray.at(6).asDouble()) + "\n";
readResult->setString(readDataStr);
}
void TestWriteValueVector::onExit()
{
FileUtilsDemo::onExit();
}
std::string TestWriteValueVector::title() const
{
return "FileUtils: TestWriteValueVector to files";
}
std::string TestWriteValueVector::subtitle() const
{
return "";
}

View File

@ -64,7 +64,7 @@ class TestFileFuncs : public FileUtilsDemo
{
public:
CREATE_FUNC(TestFileFuncs);
virtual void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
@ -74,7 +74,7 @@ class TestDirectoryFuncs : public FileUtilsDemo
{
public:
CREATE_FUNC(TestDirectoryFuncs);
virtual void onEnter() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
@ -91,4 +91,47 @@ public:
virtual std::string subtitle() const override;
};
class TestWriteString : public FileUtilsDemo
{
public:
CREATE_FUNC(TestWriteString);
virtual void onEnter() override;
virtual void onExit() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TestWriteData : public FileUtilsDemo
{
public:
CREATE_FUNC(TestWriteData);
virtual void onEnter() override;
virtual void onExit() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TestWriteValueMap : public FileUtilsDemo
{
public:
CREATE_FUNC(TestWriteValueMap);
virtual void onEnter() override;
virtual void onExit() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
class TestWriteValueVector : public FileUtilsDemo
{
public:
CREATE_FUNC(TestWriteValueVector);
virtual void onEnter() override;
virtual void onExit() override;
virtual std::string title() const override;
virtual std::string subtitle() const override;
};
#endif /* __FILEUTILSTEST_H__ */

View File

@ -104,7 +104,7 @@ skip = Node::[^setPosition$ setGLServerState description getUserObject .*UserDat
Scheduler::[pause resume ^unschedule$ unscheduleUpdate unscheduleAllForTarget schedule isTargetPaused isScheduled],
TextureCache::[addPVRTCImage],
*::[copyWith.* onEnter.* onExit.* ^description$ getObjectType onTouch.* onAcc.* onKey.* onRegisterTouchListener operator.+],
FileUtils::[getFileData getDataFromFile setFilenameLookupDictionary destroyInstance getFullPathCache],
FileUtils::[getFileData getDataFromFile writeDataToFile setFilenameLookupDictionary destroyInstance getFullPathCache],
Application::[^application.* ^run$ getCurrentLanguageCode setAnimationInterval],
Camera::[getEyeXYZ getCenterXYZ getUpXYZ],
ccFontDefinition::[*],

View File

@ -8,18 +8,18 @@ prefix = cocos2dx
target_namespace = cc
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/include
android_flags = -D_SIZE_T_DEFINED_
android_flags = -D_SIZE_T_DEFINED_
clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__
cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/platform/android -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/external
cocos_flags = -DANDROID
cxxgenerator_headers =
cxxgenerator_headers =
# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s
# what headers to parse
headers = %(cocosdir)s/cocos/cocos2d.h %(cocosdir)s/cocos/2d/CCProtectedNode.h %(cocosdir)s/cocos/base/CCAsyncTaskPool.h
@ -99,7 +99,7 @@ skip = Node::[setGLServerState description getUserObject .*UserData getGLServerS
TextureCache::[addPVRTCImage addImageAsync],
Timer::[getSelector createWithScriptHandler],
*::[copyWith.* onEnter.* onExit.* ^description$ getObjectType (g|s)etDelegate onTouch.* onAcc.* onKey.* onRegisterTouchListener],
FileUtils::[getFileData getDataFromFile getFullPathCache],
FileUtils::[getFileData getDataFromFile writeDataToFile getFullPathCache],
Application::[^application.* ^run$],
Camera::[getEyeXYZ getCenterXYZ getUpXYZ],
ccFontDefinition::[*],
@ -158,7 +158,7 @@ rename_functions = SpriteFrameCache::[addSpriteFramesWithFile=addSpriteFrames ge
rename_classes = ParticleSystemQuad::ParticleSystem
# for all class names, should we remove something when registering in the target VM?
remove_prefix =
remove_prefix =
# classes for which there will be no "parent" lookup
classes_have_no_parents = Director FileUtils TMXMapInfo Application