Rev 129 | Rev 185 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include "DirIO.h"#include <sys/types.h> // For stat().#include <sys/stat.h> // For stat().#include <fcntl.h>#include "File.h"#include "File_IO.h"#ifdef _WIN32#include <windows.h>#include <io.h>#include <direct.h>#define ACCESS _access#else#include <dirent.h>#define ACCESS access#endif/////////////////////////////////////////// STATIC FUNCTIONSbool CDirIO::Exists(const Utils::String &dir){return CDirIO(dir).exists();}////////////////////////////////////////// Ctor/DtorCDirIO::CDirIO(){}CDirIO::~CDirIO(){}CDirIO::CDirIO(CyString dir){setDir(dir.ToString());}CDirIO::CDirIO ( CFileIO *file ){setDir(file->dir());}///////////////////////////////////////////////////////////void CDirIO::setDir(const Utils::String& dir){m_sCurrentDir = dir;m_sCurrentDir.toFilename();}bool CDirIO::exists() const{Utils::String dir = m_sCurrentDir;if (dir.empty())return false;if (ACCESS(dir.c_str(), 0) == 0)return true;return false;}bool CDirIO::exists(const Utils::String &dir) const{Utils::String d = _parseDir(dir);if (d.empty())return false;if (ACCESS(d.c_str(), 0) == 0)return true;return false;}Utils::String CDirIO::_parseDir(const Utils::String &dir) const{Utils::String sDir = dir.asFilename();if ( !m_sCurrentDir.empty() && !sDir.isin(":") ){if ( sDir.empty() )sDir = m_sCurrentDir;elsesDir = m_sCurrentDir + "/" + sDir;}return sDir.asFilename();}bool CDirIO::isDir(const Utils::String &sDir) const{Utils::String dir = _parseDir(sDir);if (ACCESS(dir.c_str(), 0) != -1){struct stat status;stat(dir.c_str(), &status);if (status.st_mode & S_IFDIR)return true;}else {return !dir.token("/", -1).isin(".");}return false;}bool CDirIO::isDir() const{return isDir(m_sCurrentDir);}bool CDirIO::isFile() const{return isFile(m_sCurrentDir);}bool CDirIO::isFile(const Utils::String &sDir) const{Utils::String dir = _parseDir(sDir);if (ACCESS(dir.c_str(), 0) != -1){struct stat status;stat(dir.c_str(), &status);if (status.st_mode & S_IFDIR)return false;elsereturn true;}else {return dir.token("/", -1).isin(".");}return false;}bool CDirIO::create() const{return create(Utils::String::Null());}bool CDirIO::create(const Utils::String &sDir) const{Utils::String dir = sDir;if ( dir.empty() )dir = m_sCurrentDir;dir = _parseDir(dir);// split up directorysint max = 0;Utils::String *dirs = dir.findReplace( "/", "\\" ).findReplace( "\\\\", "\\" ).tokenise("\\", &max );// check if full dir, or relativeint start = 1;Utils::String curDir;if ( dirs && max )curDir = dirs[0];if ( !curDir.isin(":") ){curDir = m_sCurrentDir;start = 0;}// process each dirfor ( int i = start; i < max; i++ ){if ( !curDir.empty() )curDir += "/";curDir += dirs[i];// check if the directory existsif ( !exists(curDir) ){#ifdef _WIN32if ( _mkdir(curDir.c_str()) )#elseif ( mkdir(curDir.c_str(), 0755) )#endif{CLEANSPLIT(dirs, max);return false;}}}CLEANSPLIT(dirs, max);return true;}bool CDirIO::move(const Utils::String &sTo){Utils::String to = _parseDir(sTo);if (exists(to))return false;if (!rename(m_sCurrentDir.c_str(), to.c_str())){m_sCurrentDir = to;return true;}return false;}bool CDirIO::move(const Utils::String &sFrom, const Utils::String &sTo){Utils::String from = _parseDir(sFrom);Utils::String to = _parseDir(sTo);if ( !exists(to) ){if ( !create(to) )return false;}if ( !rename(from.c_str(), to.c_str()) )return true;return false;}bool CDirIO::checkEmptyDir(const Utils::CStringList &dirList) const{// not found any files, most likly emptyif (dirList.empty())return true;// check for any valid filesfor(auto itr = dirList.begin(); itr != dirList.end(); itr++){Utils::String d = (*itr)->str;if (d == "." || d == "..")continue;// found somethingreturn false;}return true;}bool CDirIO::removeDir(const Utils::String& dir, bool doFiles, bool recursive, Utils::CStringList* errors){// check if the dir is emptyUtils::CStringList list;if (dirList(list, dir)){if (checkEmptyDir(list)){Utils::String remDir = _parseDir(dir);#ifdef _WIN32if (_rmdir(remDir.c_str()) == 0)#elseif (rmdir(remDir.c_str()) == 0)#endif{if (errors)errors->pushBack(remDir);}return true;}// not emptyif (doFiles || recursive){for (auto itr = list.begin(); itr != list.end(); itr++){Utils::String d = (*itr)->str;if (d == "." || d == "..")continue;// if its a fileUtils::String fullFile = dir + "\\" + d;if (doFiles && isFile(fullFile)){Utils::String remFile = _parseDir(fullFile);if (remove(remFile.c_str()) == 0){if (errors)errors->pushBack(remFile);}}else if (recursive && isDir(fullFile))removeDir(fullFile, doFiles, recursive, errors);}}}list.clear();// now check if its emptyif(dirList(list, dir)){if (checkEmptyDir(list)){Utils::String remDir = _parseDir(dir);#ifdef _WIN32if (_rmdir(remDir.c_str()) == 0)#elseif (rmdir(remDir.c_str()) == 0)#endif{if (errors)errors->pushBack(remDir);}return true;}}return false;}bool CDirIO::RemoveDir(CyString dir, bool doFiles, bool recursive, CyStringList* errors){// check if the dir is emptyUtils::CStringList list;if (dirList(list, dir.ToString())){if (checkEmptyDir(list)){Utils::String remDir = _parseDir(dir.ToString());#ifdef _WIN32if (_rmdir(remDir.c_str()) == 0)#elseif (rmdir(remDir.c_str()) == 0)#endif{if (errors)errors->PushBack(CyString(remDir));}return true;}// not emptyif (doFiles || recursive){for (auto itr = list.begin(); itr != list.end(); itr++){Utils::String d = (*itr)->str;if (d == "." || d == "..")continue;// if its a fileUtils::String fullFile = dir.ToString() + "\\" + d;if (doFiles && isFile(fullFile)){Utils::String remFile = _parseDir(fullFile);if (remove(remFile.c_str()) == 0){if (errors)errors->PushBack(CyString(remFile));}}else if (recursive && isDir(fullFile))RemoveDir(fullFile, doFiles, recursive, errors);}}}list.clear();if (dirList(list, dir.ToString())){if (checkEmptyDir(list)){Utils::String remDir = _parseDir(dir.ToString());#ifdef _WIN32if (_rmdir(remDir.c_str()) == 0)#elseif (rmdir(remDir.c_str()) == 0)#endif{if (errors)errors->PushBack(CyString(remDir));}return true;}}return false;}bool CDirIO::dirList(Utils::CStringList &files, Utils::String dir, Utils::String filePattern) const{dir = _parseDir(dir);if ( dir.empty() )return false;dir = dir.findReplace("\\", "/");if (filePattern.empty())dir += "/*";else{dir += "/";dir += filePattern;}dir = dir.findReplace("//", "/");#ifdef _WIN32dir = dir.findReplace("/", "\\");WIN32_FIND_DATA data;TCHAR buf[5000];wsprintf(buf, L"%hs", dir.c_str());HANDLE h = FindFirstFile(buf, &data);if ( h != INVALID_HANDLE_VALUE){std::wstring ws(data.cFileName);std::string s(ws.begin(), ws.end());Utils::String checkFile(s);if ( !checkFile.Compare(".") && !checkFile.Compare("..") )files.pushBack(checkFile);while ( FindNextFile(h, &data) ){std::wstring ws(data.cFileName);std::string s(ws.begin(), ws.end());Utils::String checkFile(s);if ( checkFile != "." && checkFile != ".." )files.pushBack(checkFile);}FindClose(h);return true;}return false;#elseDIR *dir;struct dirent *ent;if ((dir = opendir(dir.c_str())) != NULL) {while ((ent = readdir(dir)) != NULL) {Utils::String checkFile(ent->d_name);if (checkFile != "." && checkFile != "..")files.pushBack(checkFile);}closedir(dir);}return true;#endif//_WIN32}Utils::String CDirIO::file(const Utils::String &filename) const{if (m_sCurrentDir.empty())return filename;return m_sCurrentDir + "/" + filename;}Utils::String CDirIO::dir(const Utils::String &sDir) const{return _parseDir(sDir);}const Utils::String &CDirIO::dir() const{return m_sCurrentDir;}bool CDirIO::cd(const Utils::String &sDir){if ( m_sCurrentDir.empty() )m_sCurrentDir = sDir;elsem_sCurrentDir = m_sCurrentDir + "/" + sDir;m_sCurrentDir = m_sCurrentDir.asFilename();return exists();}bool CDirIO::createAndChange(const Utils::String &dir){if ( create(dir) )return cd(dir);return false;}Utils::String CDirIO::topDir() const{if ( m_sCurrentDir.empty() )return Utils::String("");return m_sCurrentDir.token("/", -1);}const Utils::String &CDirIO::moveBack(){m_sCurrentDir = m_sCurrentDir.tokens("/", 1, -2);return m_sCurrentDir;}Utils::String CDirIO::back() const{return m_sCurrentDir.tokens("/", 1, -2);}