Rev 95 | 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
#define ACCESS access
#endif
CDirIO::CDirIO()
{
}
CDirIO::~CDirIO()
{
}
CDirIO::CDirIO(CyString dir)
{
SetDir(dir);
}
CDirIO::CDirIO ( CFileIO *file )
{
SetDir(file->GetDir());
}
void CDirIO::SetDir(CyString dir)
{
m_sCurrentDir = dir;
m_sCurrentDir = m_sCurrentDir.FindReplace("\\", "/");
}
bool CDirIO::Exists(CyString dir)
{
dir = ParseDir(dir);
if ( dir.Empty() )
return false;
if ( ACCESS( dir.c_str(), 0 ) == 0 )
return true;
return false;
}
CyString CDirIO::ParseDir(CyString dir)
{
dir = dir.FindReplace("\\", "/");
if ( !m_sCurrentDir.Empty() && !dir.IsIn(":") )
{
if ( dir.Empty() )
dir = m_sCurrentDir;
else
dir = m_sCurrentDir + "/" + dir;
}
dir = dir.FindReplace("//", "/");
return dir;
}
bool CDirIO::IsDir(CyString dir)
{
dir = ParseDir(dir);
if ( ACCESS( dir.c_str(), 0 ) == 0 )
{
struct stat status;
stat( dir.c_str(), &status );
if ( status.st_mode & S_IFDIR )
return true;
}
return false;
}
bool CDirIO::IsFile(CyString dir)
{
dir = ParseDir(dir);
if ( ACCESS( dir.c_str(), 0 ) == 0 )
{
struct stat status;
stat( dir.c_str(), &status );
if ( status.st_mode & S_IFDIR )
return false;
else
return true;
}
return false;
}
bool CDirIO::Create(CyString dir)
{
if ( dir.Empty() )
dir = m_sCurrentDir;
dir = ParseDir(dir);
// split up directorys
int max = 0;
CyString *dirs = dir.FindReplace ( "/", "\\" ).FindReplace ( "\\\\", "\\" ).SplitToken ( '\\', &max );
// check if full dir, or relative
int start = 1;
CyString curDir;
if ( dirs && max )
curDir = dirs[0];
if ( !curDir.IsIn(":") )
{
curDir = m_sCurrentDir;
start = 0;
}
// process each dir
for ( int i = start; i < max; i++ )
{
if ( !curDir.Empty() )
curDir += "/";
curDir += dirs[i];
// check if the directory exists
if ( !Exists(curDir) )
{
#ifdef _WIN32
if ( _mkdir(curDir.c_str()) )
#else
if ( 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 empty
if ( !dirList )
return true;
// not found any files, most likly empty
if ( !dirList->Count() )
return true;
// check for any valid files
for ( SStringList *str = dirList->Head(); str; str = str->next )
{
CyString d = str->str;
if ( d == "." || d == ".." )
continue;
// found something
return false;
}
return true;
}
bool CDirIO::RemoveDir(CyString dir, bool doFiles, bool recursive, CyStringList *errors)
{
// check if the dir is empty
CyStringList *dirList = DirList(dir);
if ( CheckEmptyDir(dirList) )
{
CyString remDir = ParseDir(dir);
#ifdef _WIN32
if ( _rmdir(remDir.c_str()) == 0 )
#else
if ( rmdir(remDir.c_str()) == 0 )
#endif
{
if ( errors )
errors->PushBack(remDir);
}
return true;
}
// not empty
if ( doFiles || recursive )
{
for ( SStringList *str = dirList->Head(); str; str = str->next )
{
CyString d = str->str;
if ( d == "." || d == ".." )
continue;
// if its a file
CyString 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 empty
delete dirList;
dirList = DirList(dir);
if ( CheckEmptyDir(dirList) )
{
CyString remDir = ParseDir(dir);
#ifdef _WIN32
if ( _rmdir(remDir.c_str()) == 0 )
#else
if ( rmdir(remDir.c_str()) == 0 )
#endif
{
if ( errors )
errors->PushBack(remDir);
}
return true;
}
return false;
}
CyStringList *CDirIO::DirList(CyString dir, CyString filepattern)
{
dir = ParseDir(dir);
if ( dir.Empty() )
return 0;
CyStringList *files = new CyStringList;
#ifdef _WIN32
dir = 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//_WIN32
return files;
}
CyString CDirIO::File(CyString filename)
{
if ( m_sCurrentDir.Empty() )
return filename;
return m_sCurrentDir + "/" + filename;
}
CyString CDirIO::Dir(CyString dir)
{
return ParseDir(dir);
}
bool CDirIO::cd(CyString dir)
{
if ( m_sCurrentDir.Empty() )
m_sCurrentDir = dir;
else
m_sCurrentDir = m_sCurrentDir + "/" + dir;
m_sCurrentDir.FindReplace("\\", "/");
m_sCurrentDir.FindReplace("//", "/");
return Exists();
}
bool CDirIO::CreateAndChange(CyString dir)
{
if ( Create(dir) )
return cd(dir);
return false;
}
CyString CDirIO::TopDir()
{
if ( m_sCurrentDir.Empty() )
return NullString;
return m_sCurrentDir.GetTokenRev("/", -1);
}
CyString CDirIO::Back()
{
m_sCurrentDir = m_sCurrentDir.GetToken("/", 0, -1);
return m_sCurrentDir;
}