simgear::Dir helpers

- remove all children of the dir
- check is the dir has children / is empty
This commit is contained in:
James Turner
2013-06-09 19:17:23 +01:00
parent 323d0d5ba0
commit 14decb7387
2 changed files with 85 additions and 15 deletions

View File

@@ -256,6 +256,55 @@ PathList Dir::children(int types, const std::string& nameFilter) const
return result;
}
bool Dir::isEmpty() const
{
bool empty= true;
#ifdef _WIN32
WIN32_FIND_DATA fData;
HANDLE find = FindFirstFile("\\*", &fData);
if (find == INVALID_HANDLE_VALUE) {
return true;
}
// since an empty dir will still have . and .. children, we need
// watch for those - anything else means the dir is really non-empty
bool done = false;
for (; !done; done = (FindNextFile(find, &fData) == 0)) {
if (fData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (!strcmp(fData.cFileName,".") || !strcmp(fData.cFileName,"..")) {
continue;
}
}
empty = false;
break;
}
FindClose(find);
#else
DIR* dp = opendir(_path.c_str());
if (!dp) {
return true;
}
while (true) {
struct dirent* entry = readdir(dp);
if (!entry) {
break; // done iteration
}
if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
continue;
}
empty = false;
break;
}
closedir(dp);
#endif
return empty;
}
bool Dir::exists() const
{
return _path.isDir();
@@ -299,28 +348,38 @@ bool Dir::create(mode_t mode)
return (err == 0);
}
bool Dir::removeChildren() const
{
bool ok;
PathList cs = children(NO_DOT_OR_DOTDOT | INCLUDE_HIDDEN | TYPE_FILE | TYPE_DIR);
BOOST_FOREACH(SGPath path, cs) {
if (path.isDir()) {
Dir childDir(path);
ok = childDir.remove(true);
} else {
ok = path.remove();
}
if (!ok) {
SG_LOG(SG_IO, SG_WARN, "failed to remove:" << path);
return false;
}
} // of child iteration
return true;
}
bool Dir::remove(bool recursive)
{
if (!exists()) {
SG_LOG(SG_IO, SG_WARN, "attempt to remove non-existant dir:" << _path.str());
SG_LOG(SG_IO, SG_WARN, "attempt to remove non-existant dir:" << _path);
return false;
}
if (recursive) {
bool ok;
PathList cs = children(NO_DOT_OR_DOTDOT | INCLUDE_HIDDEN | TYPE_FILE | TYPE_DIR);
BOOST_FOREACH(SGPath path, cs) {
if (path.isDir()) {
Dir childDir(path);
ok = childDir.remove(true);
} else {
ok = path.remove();
}
if (!ok) {
return false;
}
} // of child iteration
if (!removeChildren()) {
return false;
}
} // of recursive deletion
#ifdef _WIN32

View File

@@ -72,6 +72,11 @@ namespace simgear
PathList children(int types = 0, const std::string& nameGlob = "") const;
/**
* test if the directory contains no children (except '.' and '..')
*/
bool isEmpty() const;
SGPath file(const std::string& name) const;
SGPath path() const
@@ -90,6 +95,12 @@ namespace simgear
*/
bool remove(bool recursive = false);
/**
* remove our children but not us
*/
bool removeChildren() const;
/**
* Check that the directory at the path exists (and is a directory!)
*/