Rev 211 | 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 _waccess
#else
#include <dirent.h>
#define ACCESS waccess
#endif
#pragma warning(disable:4244)
std::string TOSTRING(const std::wstring& s) { return std::string(s.begin(), s.end()); }
#pragma warning(default:4244)
/////////////////////////////////////////
// STATIC FUNCTIONS
bool CDirIO::Exists(const Utils::WString &dir)
{
return CDirIO(dir).exists();
}
bool CDirIO::IsEmptyDir(const Utils::WStringList& dirList)
{
// not found any files, most likly empty
if (dirList.empty())
return true;
// check for any valid files
for (auto itr = dirList.begin(); itr != dirList.end(); itr++)
{
Utils::WString d = (*itr)->str;
if (d == L"." || d == L"..")
continue;
// found something
return false;
}
return true;
}
////////////////////////////////////////
// Ctor/Dtor
CDirIO::CDirIO()
{
}
CDirIO::~CDirIO()
{
}
CDirIO::CDirIO(const Utils::WString &dir)
{
setDir(dir);
}
CDirIO::CDirIO(CFileIO *file)
{
setDir(file->dir());
}
/////////////////////////////////////////////////////////
//
void CDirIO::setDir(const Utils::WString& dir)
{
m_sCurrentDir = dir;
m_sCurrentDir.toFilename();
}
bool CDirIO::exists() const
{
Utils::WString dir = m_sCurrentDir;
if (dir.empty())
return false;
//std::wifstream f(dir.c_str());
//if (f.good())
//return true;
if (ACCESS(dir.c_str(), 0) == 0)
return true;
return false;
}
bool CDirIO::exists(const Utils::WString &dir) const
{
Utils::WString d = _parseDir(dir);
if (d.empty())
return false;
//std::wifstream f(d.c_str());
//if (f.good())
//return true;
if (ACCESS(d.c_str(), 0) == 0)
return true;
return false;
}
Utils::WString CDirIO::_parseDir(const Utils::WString &dir) const
{
Utils::WString sDir = dir.asFilename();
if ( !m_sCurrentDir.empty() && !sDir.contains(L":") )
{
if ( sDir.empty() )
sDir = m_sCurrentDir;
else
sDir = m_sCurrentDir + L"/" + sDir;
}
return sDir.asFilename();
}
bool CDirIO::isDir(const Utils::WString &sDir) const
{
Utils::WString dir = _parseDir(sDir);
if (ACCESS(dir.c_str(), 0) != -1)
{
#ifdef _WIN32
struct _stat64i32 status;
_wstat(dir.c_str(), &status);
if (status.st_mode & S_IFDIR)
return true;
#else
struct stat status;
stat(TOSTRING(dir).c_str(), &status);
if (status.st_mode & S_IFDIR)
return true;
#endif
}
else {
return !dir.token(L"/", -1).contains(L".");
}
return false;
}
bool CDirIO::isDir() const
{
return isDir(m_sCurrentDir);
}
bool CDirIO::isFile() const
{
return isFile(m_sCurrentDir);
}
bool CDirIO::isFile(const Utils::WString &sDir) const
{
Utils::WString dir = _parseDir(sDir);
if (ACCESS(dir.c_str(), 0) != -1)
{
#ifdef _WIN32
struct _stat64i32 status;
_wstat(dir.c_str(), &status);
if (status.st_mode & S_IFDIR)
return false;
#else
struct stat status;
stat(TOSTRING(dir).c_str(), &status);
if (status.st_mode & S_IFDIR)
return false;
#endif
return true;
}
else {
return dir.token(L"/", -1).contains(L".");
}
return false;
}
bool CDirIO::create() const
{
return create(Utils::WString::Null());
}
bool CDirIO::create(const Utils::WString &sDir) const
{
Utils::WString dir = sDir;
if ( dir.empty() )
dir = m_sCurrentDir;
dir = _parseDir(dir);
// split up directorys
std::vector<Utils::WString> dirs;
if(dir.findReplace(L"/", L"\\").findReplace(L"\\\\", L"\\").tokenise(L"\\", dirs))
{
// check if full dir, or relative
size_t start = 1;
Utils::WString curDir = dirs.front();
if (!curDir.contains(L":"))
{
curDir = m_sCurrentDir;
start = 0;
}
// process each dir
for (size_t i = start; i < dirs.size(); i++)
{
if (!curDir.empty())
curDir += L"/";
curDir += dirs.at(i);
// check if the directory exists
if (!exists(curDir))
{
#ifdef _WIN32
std::string str = TOSTRING(curDir);
if (_wmkdir(curDir.c_str()))
#else
if (mkdir(TOSTRING(curDir).c_str(), 0755))
#endif
return false;
}
}
}
return true;
}
bool CDirIO::move(const Utils::WString &sTo)
{
Utils::WString to = _parseDir(sTo);
if (exists(to))
return false;
if (!CFileIO::Rename(m_sCurrentDir, to))
{
m_sCurrentDir = to;
return true;
}
return false;
}
bool CDirIO::move(const Utils::WString &sFrom, const Utils::WString &sTo)
{
Utils::WString from = _parseDir(sFrom);
Utils::WString to = _parseDir(sTo);
if ( !exists(to) )
{
if ( !create(to) )
return false;
}
if(CFileIO::Rename(from, to))
return true;
return false;
}
bool CDirIO::checkEmptyDir(const Utils::WStringList &dirList) const
{
// not found any files, most likly empty
if (dirList.empty())
return true;
// check for any valid files
for(auto itr = dirList.begin(); itr != dirList.end(); itr++)
{
Utils::WString d = (*itr)->str;
if (d == L"." || d == L"..")
continue;
// found something
return false;
}
return true;
}
bool CDirIO::removeDir(const Utils::WString& dir, bool doFiles, bool recursive, Utils::WStringList* errors)
{
// check if the dir is empty
Utils::WStringList list;
if (dirList(list, dir))
{
if (CDirIO::IsEmptyDir(list))
{
Utils::WString remDir = _parseDir(dir);
#ifdef _WIN32
if (_wrmdir(remDir.c_str()) == 0)
#else
if (rmdir(TOSTRING(remDir).c_str()) == 0)
#endif
{
if (errors)
errors->pushBack(remDir);
}
return true;
}
// not empty
if (doFiles || recursive)
{
for (auto itr = list.begin(); itr != list.end(); itr++)
{
Utils::WString d = (*itr)->str;
if (d == L"." || d == L"..")
continue;
// if its a file
Utils::WString fullFile = dir + "\\" + d;
if (doFiles && isFile(fullFile))
{
Utils::WString remFile = _parseDir(fullFile);
if (!CFileIO::Remove(remFile))
{
if (errors)
errors->pushBack(remFile);
}
}
else if (recursive && isDir(fullFile))
removeDir(fullFile, doFiles, recursive, errors);
}
}
}
list.clear();
// now check if its empty
if(dirList(list, dir))
{
if (CDirIO::IsEmptyDir(list))
{
Utils::WString remDir = _parseDir(dir);
#ifdef _WIN32
if (_wrmdir(remDir.c_str()) == 0)
#else
if (rmdir(TOSTRING(remDir).c_str()) == 0)
#endif
{
if (errors)
errors->pushBack(remDir);
}
return true;
}
}
return false;
}
bool CDirIO::dirList(Utils::WStringList& files, const Utils::WString &sDir, const Utils::WString &filePattern) const
{
Utils::WString dir = _parseDir(sDir);
if (dir.empty())
return false;
dir = dir.findReplace(L"\\", L"/");
if (filePattern.empty())
dir += L"/*";
else
{
dir += L"/";
dir += filePattern;
}
dir = dir.findReplace(L"//", L"/");
#ifdef _WIN32
dir = dir.findReplace(L"/", L"\\");
WIN32_FIND_DATA data;
HANDLE h = FindFirstFile(dir.c_str(), &data);
if (h != INVALID_HANDLE_VALUE)
{
Utils::WString checkFile(data.cFileName);
if (!checkFile.Compare(L".") && !checkFile.Compare(L".."))
files.pushBack(checkFile);
while (FindNextFile(h, &data))
{
Utils::WString checkFile(data.cFileName);
if (checkFile != L"." && checkFile != L"..")
files.pushBack(checkFile);
}
FindClose(h);
return true;
}
return false;
#else
DIR* dir;
struct dirent* ent;
if ((dir = opendir(dir.c_str())) != NULL) {
while ((ent = readdir(dir)) != NULL) {
Utils::WString checkFile(ent->d_name);
if (checkFile != L"." && checkFile != L"..")
files.pushBack(checkFile);
}
closedir(dir);
}
return true;
#endif//_WIN32
}
Utils::WString CDirIO::file(const Utils::WString &filename) const
{
if (m_sCurrentDir.empty())
return filename;
return m_sCurrentDir + L"/" + filename;
}
Utils::WString CDirIO::dir(const Utils::WString &sDir) const
{
return _parseDir(sDir);
}
const Utils::WString &CDirIO::dir() const
{
return m_sCurrentDir;
}
bool CDirIO::cd(const Utils::WString &sDir)
{
if ( m_sCurrentDir.empty() )
m_sCurrentDir = sDir;
else
m_sCurrentDir = m_sCurrentDir + L"/" + sDir;
m_sCurrentDir = m_sCurrentDir.asFilename();
return exists();
}
bool CDirIO::createAndChange(const Utils::WString &dir)
{
if ( create(dir) )
return cd(dir);
return false;
}
Utils::WString CDirIO::topDir() const
{
if ( m_sCurrentDir.empty() )
return Utils::WString(L"");
return m_sCurrentDir.token(L"/", -1);
}
const Utils::WString &CDirIO::moveBack()
{
m_sCurrentDir = m_sCurrentDir.tokens(L"/", 1, -2);
return m_sCurrentDir;
}
Utils::WString CDirIO::back() const
{
return m_sCurrentDir.tokens(L"/", 1, -2);
}