summaryrefslogtreecommitdiffstats
path: root/src/dir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dir.cpp')
-rw-r--r--src/dir.cpp303
1 files changed, 303 insertions, 0 deletions
diff --git a/src/dir.cpp b/src/dir.cpp
new file mode 100644
index 0000000..327bc72
--- /dev/null
+++ b/src/dir.cpp
@@ -0,0 +1,303 @@
+/******************************************************************************
+ *
+ * Copyright (C) 1997-2021 by Dimitri van Heesch.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include "filesystem.hpp"
+#include "dir.h"
+
+namespace fs = ghc::filesystem;
+
+//-----------------------------------------------------------------------------------------------
+
+struct DirEntry::Private
+{
+ fs::directory_entry entry;
+};
+
+DirEntry::DirEntry() : p(std::make_unique<Private>())
+{
+}
+
+DirEntry::~DirEntry()
+{
+}
+
+bool DirEntry::is_directory() const
+{
+ return p->entry.is_directory();
+}
+
+bool DirEntry::is_regular_file() const
+{
+ return p->entry.is_regular_file();
+}
+
+bool DirEntry::is_symlink() const
+{
+ return p->entry.is_symlink();
+}
+
+std::string DirEntry::path() const
+{
+ return p->entry.path().string();
+}
+
+//-----------------------------------------------------------------------------------------------
+
+struct DirIterator::Private
+{
+ Private() : it() {}
+ Private(const std::string &path) : it(path) {}
+ fs::directory_iterator it;
+ mutable DirEntry current;
+};
+
+DirIterator::DirIterator() : p(std::make_unique<Private>())
+{
+}
+
+DirIterator::DirIterator(const std::string &path) : p(std::make_unique<Private>(path))
+{
+}
+
+DirIterator::DirIterator(const DirIterator &it) : p(std::make_unique<Private>())
+{
+ p->it = it.p->it;
+}
+
+DirIterator::~DirIterator()
+{
+}
+
+DirIterator &DirIterator::operator=(const DirIterator &it)
+{
+ if (&it!=this)
+ {
+ p->it = it.p->it;
+ }
+ return *this;
+}
+
+DirIterator DirIterator::operator++()
+{
+ DirIterator result;
+ result.p->it = ++p->it;
+ return result;
+}
+
+const DirIterator::value_type &DirIterator::operator*() const
+{
+ p->current.p->entry = *p->it;
+ return p->current;
+}
+
+const DirIterator::value_type *DirIterator::operator->() const
+{
+ p->current.p->entry = *p->it;
+ return &p->current;
+}
+
+bool operator==(const DirIterator &it1,const DirIterator &it2)
+{
+ return it1.p->it!=it2.p->it;
+}
+
+bool operator!=(const DirIterator &it1,const DirIterator &it2)
+{
+ return it1.p->it!=it2.p->it;
+}
+
+DirIterator begin(DirIterator it) noexcept
+{
+ return it;
+}
+
+DirIterator end(const DirIterator &) noexcept
+{
+ return DirIterator();
+}
+
+
+//-----------------------------------------------------------------------------------------------
+
+
+struct Dir::Private
+{
+ fs::path path;
+};
+
+Dir::Dir() : p(std::make_unique<Private>())
+{
+ std::error_code ec;
+ p->path = fs::current_path(ec);
+}
+
+Dir::Dir(const Dir &d) : p(std::make_unique<Private>())
+{
+ p->path = d.p->path;
+}
+
+Dir &Dir::operator=(const Dir &d)
+{
+ if (&d!=this)
+ {
+ p->path = d.p->path;
+ }
+ return *this;
+}
+
+Dir::Dir(const std::string &path) : p(std::make_unique<Private>())
+{
+ setPath(path);
+}
+
+Dir::~Dir()
+{
+}
+
+void Dir::setPath(const std::string &path)
+{
+ p->path = path;
+}
+
+std::string Dir::path() const
+{
+ return p->path.string();
+}
+
+DirIterator Dir::iterator() const
+{
+ return DirIterator(p->path.string());
+}
+
+static void correctPath(std::string &s)
+{
+ std::replace( s.begin(), s.end(), '\\', '/' );
+}
+
+bool Dir::exists(const std::string &path,bool acceptsAbsPath) const
+{
+ std::string result = filePath(path,acceptsAbsPath);
+ std::error_code ec;
+ bool exist = fs::exists(fs::path(result),ec);
+ return !ec && exist;
+}
+
+bool Dir::exists() const
+{
+ FileInfo fi(p->path.string());
+ return fi.exists() && fi.isDir();
+}
+
+bool Dir::isRelative() const
+{
+ return isRelativePath(p->path.string());
+}
+
+bool Dir::isRelativePath(const std::string &path)
+{
+ return fs::path(path).is_relative();
+}
+
+std::string Dir::filePath(const std::string &path,bool acceptsAbsPath) const
+{
+ std::string result;
+ if (acceptsAbsPath && !isRelativePath(path))
+ {
+ result = path;
+ }
+ else
+ {
+ result = (p->path / path).string();
+ }
+ correctPath(result);
+ return result;
+}
+
+bool Dir::mkdir(const std::string &path,bool acceptsAbsPath) const
+{
+ std::error_code ec;
+ std::string result = filePath(path,acceptsAbsPath);
+ if (exists(path,acceptsAbsPath))
+ {
+ return true;
+ }
+ else
+ {
+ return fs::create_directory(result,ec);
+ }
+}
+
+bool Dir::rmdir(const std::string &path,bool acceptsAbsPath) const
+{
+ return remove(path,acceptsAbsPath);
+}
+
+bool Dir::remove(const std::string &path,bool acceptsAbsPath) const
+{
+ std::error_code ec;
+ std::string result = filePath(path,acceptsAbsPath);
+ return fs::remove(result,ec);
+}
+
+bool Dir::rename(const std::string &orgName,const std::string &newName,bool acceptsAbsPath) const
+{
+ std::error_code ec;
+ std::string fn1 = filePath(orgName,acceptsAbsPath);
+ std::string fn2 = filePath(newName,acceptsAbsPath);
+ fs::rename(fn1,fn2,ec);
+ return !ec;
+}
+
+bool Dir::copy(const std::string &srcName,const std::string &dstName,bool acceptsAbsPath) const
+{
+ const auto copyOptions = fs::copy_options::overwrite_existing;
+ std::error_code ec;
+ std::string sn = filePath(srcName,acceptsAbsPath);
+ std::string dn = filePath(dstName,acceptsAbsPath);
+ fs::copy(sn,dn,copyOptions,ec);
+ return !ec;
+}
+
+std::string Dir::currentDirPath()
+{
+ std::error_code ec;
+ std::string result = fs::current_path(ec).string();
+ correctPath(result);
+ return result;
+}
+
+bool Dir::setCurrent(const std::string &path)
+{
+ std::error_code ec;
+ fs::current_path(path,ec);
+ return !ec;
+}
+
+std::string Dir::cleanDirPath(const std::string &path)
+{
+ std::error_code ec;
+ std::string result = fs::path(path).lexically_normal().string();
+ correctPath(result);
+ return result;
+}
+
+std::string Dir::absPath() const
+{
+ std::error_code ec;
+ std::string result = fs::absolute(p->path,ec).string();
+ correctPath(result);
+ return result;
+}
+