Rev 119 | Rev 125 | 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#endifCDirIO::CDirIO(){}CDirIO::~CDirIO(){}CDirIO::CDirIO(CyString dir){SetDir(dir);}CDirIO::CDirIO ( CFileIO *file ){SetDir(file->dir());}void CDirIO::SetDir(CyString dir){m_sCurrentDir = dir.ToString();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;}bool CDirIO::Exists(CyString dir){dir = ParseDir(dir);if (dir.Empty())return false;if (ACCESS(dir.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();}CyString CDirIO::ParseDir(CyString dir){dir = dir.FindReplace("\\", "/");if ( !m_sCurrentDir.empty() && !dir.IsIn(":") ){if ( dir.Empty() )dir = m_sCurrentDir;elsedir = CyString(m_sCurrentDir) + "/" + dir;}dir = dir.FindReplace("//", "/");return dir;}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::IsDir(CyString sDir){Utils::String dir = parseDir(sDir.ToString());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::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::IsFile(CyString sDir){Utils::String dir = parseDir(sDir.ToString());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(CyString sDir){Utils::String dir = sDir.ToString();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(CyString from, CyString to){from = ParseDir(from);to = ParseDir(to);if ( !Exists(to) ){if ( !Create(to) )return false;}if ( !rename(from.c_str(), to.c_str()) )return true;return false;}bool CDirIO::CheckEmptyDir(CyStringList *dirList){// no pointer, most likly emptyif ( !dirList )return true;// not found any files, most likly emptyif ( !dirList->Count() )return true;// check for any valid filesfor ( SStringList *str = dirList->Head(); str; str = str->next ){CyString d = str->str;if ( d == "." || d == ".." )continue;// found somethingreturn false;}return true;}bool CDirIO::RemoveDir(CyString dir, bool doFiles, bool recursive, CyStringList *errors){// check if the dir is emptyCyStringList *dirList = DirList(dir);if ( CheckEmptyDir(dirList) ){CyString 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 ( SStringList *str = dirList->Head(); str; str = str->next ){CyString d = str->str;if ( d == "." || d == ".." )continue;// if its a fileCyString fullFile = dir + "\\" + d;if ( doFiles && IsFile(fullFile) ){CyString remFile = ParseDir(fullFile);if ( remove(remFile.c_str()) == 0 ){if ( errors )errors->PushBack(remFile);}}else if ( recursive && IsDir(fullFile) )RemoveDir(fullFile, doFiles, recursive, errors);}}// now check if its emptydelete dirList;dirList = DirList(dir);if ( CheckEmptyDir(dirList) ){CyString 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;}Utils::CStringList CDirIO::dirList(Utils::String dir, Utils::String filePattern) const{Utils::CStringList files;dir = parseDir(dir);if ( dir.empty() )return files;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);}#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);}#endif//_WIN32return files;}CyStringList *CDirIO::DirList(CyString dir, CyString filepattern){dir = ParseDir(dir);if ( dir.Empty() )return 0;CyStringList *files = new CyStringList;#ifdef _WIN32dir = dir.FindReplace("/", "\\");if ( filepattern.Empty() )dir += "\\*";else{dir += "\\";dir += filepattern;}dir = 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){CyString checkFile(data.cFileName);if ( !checkFile.Compare(".") && !checkFile.Compare("..") )files->PushBack(checkFile);while ( FindNextFile(h, &data) ){CyString checkFile(data.cFileName);if ( checkFile != "." && checkFile != ".." )files->PushBack(checkFile);}FindClose(h);}#else#endif//_WIN32return files;}CyString CDirIO::File(CyString filename){if (m_sCurrentDir.empty())return filename;return CyString(m_sCurrentDir) + "/" + filename;}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;}CyString CDirIO::Dir(CyString dir){return parseDir(dir.ToString());}bool CDirIO::cd(CyString dir){Utils::String sDir = dir.ToString();if ( m_sCurrentDir.empty() )m_sCurrentDir = sDir;elsem_sCurrentDir = m_sCurrentDir + "/" + sDir;m_sCurrentDir = m_sCurrentDir.asFilename();return exists();}bool CDirIO::CreateAndChange(CyString 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);}CyString CDirIO::Back(){m_sCurrentDir = m_sCurrentDir.tokens("/", 1, -2);return m_sCurrentDir;}