summaryrefslogtreecommitdiff
path: root/libs/pbd/pbd/filesystem.h
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-06-02 21:41:35 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-06-02 21:41:35 +0000
commit449aab3c465bbbf66d221fac3d7ea559f1720357 (patch)
tree6843cc40c88250a132acac701271f1504cd2df04 /libs/pbd/pbd/filesystem.h
parent9c0d7d72d70082a54f823cd44c0ccda5da64bb6f (diff)
rollback to 3428, before the mysterious removal of libs/* at 3431/3432
git-svn-id: svn://localhost/ardour2/branches/3.0@3435 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/pbd/pbd/filesystem.h')
-rw-r--r--libs/pbd/pbd/filesystem.h202
1 files changed, 202 insertions, 0 deletions
diff --git a/libs/pbd/pbd/filesystem.h b/libs/pbd/pbd/filesystem.h
new file mode 100644
index 0000000000..2d21a3fafc
--- /dev/null
+++ b/libs/pbd/pbd/filesystem.h
@@ -0,0 +1,202 @@
+/*
+ Copyright (C) 2007 Tim Mayberry
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/**
+ * @namespace PBD::sys
+ *
+ * The API in this file is intended to be as close as possible to the
+ * boost::filesystem API but implementing only the subset of it that is required
+ * by ardour using the glib/glibmm file utility functions in the implementation.
+ *
+ * More information about boost::filesystem and the TR2 proposal at
+ *
+ * http://www.boost.org/libs/filesystem/doc/tr2_proposal.html
+ *
+ * Hopefully the boost::filesystem API will pass TR2 review etc and become part
+ * of the C++ standard and this code can be removed, or we just end up using
+ * the boost filesystem library when it matures a bit more.
+ *
+ * My reasons for writing this thin wrapper instead of using glib directly or
+ * using boost::filesystem immediately are:
+ *
+ * - Using sys::path instead of strings and Glib::build_filename is more
+ * convenient, terse and forces correct platform agnostic path building.
+ *
+ * - Using boost::filesystem on windows would mean converting between any UTF-8
+ * encoded strings(such as when selecting a file/directory in the gtk file
+ * chooser) and the native file encoding (UTF-16). It would take some time
+ * and testing to find out when this is required and the glib functions already
+ * do this if necessary.
+ *
+ * - Using exceptions to indicate errors is more likely to uncover situations
+ * where error conditions are being silently ignored(I've already encounted
+ * a few examples of this in the ardour code).
+ *
+ * - Many of the glib file utility functions are not wrapped by glibmm so this
+ * also provides what I think is a better API.
+ *
+ * - Using boost::filesystem directly means another library dependence and would
+ * require more testing on windows because of the character encoding issue.
+ *
+ * - The boost::filesystem API changes a bit as part of the TR2 review process etc.
+ */
+
+#ifndef __filesystem_h__
+#define __filesystem_h__
+
+#include <stdexcept>
+#include <string>
+
+namespace PBD {
+
+namespace sys {
+
+using std::string;
+
+class path
+{
+public:
+ path() : m_path("") { }
+ path(const path & p) : m_path(p.m_path) { }
+ path(const string & s) : m_path(s) { }
+ path(const char* s) : m_path(s) { }
+
+ path& operator=(const path& p) { m_path = p.m_path; return *this;}
+ path& operator=(const string& s) { m_path = s; return *this; }
+ path& operator=(const char* s) { m_path = s; return *this; }
+
+ path& operator/=(const path& rhs);
+ path& operator/=(const string& s);
+ path& operator/=(const char* s);
+
+ const string to_string() const { return m_path; }
+
+ /**
+ * @return the last component of the path, if the path refers to
+ * a file then it will be the entire filename including any extension.
+ */
+ string leaf() const;
+
+ /**
+ * @returns the directory component of a path without any trailing
+ * path separator or an empty string if the path has no directory
+ * component(branch path).
+ */
+ path branch_path () const;
+
+private:
+
+ string m_path;
+};
+
+class filesystem_error : public std::runtime_error
+{
+ const int m_error_code;
+
+public:
+ explicit filesystem_error(const std::string & what, int error_code=0)
+ : std::runtime_error(what), m_error_code(error_code) { }
+
+ int system_error() const { return m_error_code; }
+};
+
+inline path operator/ (const path& lhs, const path& rhs)
+{ return path(lhs) /= rhs; }
+
+/// @return true if path at p exists
+bool exists(const path & p);
+
+/// @return true if path at p is a directory.
+bool is_directory(const path & p);
+
+/**
+ * Attempt to create a directory at p as if by the glib function g_mkdir
+ * with a second argument of S_IRWXU|S_IRWXG|S_IRWXO
+ *
+ * @throw filesystem_error if mkdir fails for any other reason other than
+ * the directory already exists.
+ *
+ * @return true If the directory p was created, otherwise false
+ *
+ * @post is_directory(p)
+ */
+bool create_directory(const path & p);
+
+/**
+ * Attempt to create a directory at p as if by the glib function
+ * g_mkdir_with_parents with a second argument of S_IRWXU|S_IRWXG|S_IRWXO
+ *
+ * @throw filesystem_error if g_mkdir_with_parents fails for any other
+ * reason other than the directory already exists.
+ *
+ * @return true If the directory at p was created, otherwise false
+ *
+ * @post is_directory(p)
+ */
+bool create_directories(const path & p);
+
+/**
+ * Attempt to delete the file at path p as if by the glib function
+ * g_unlink.
+ *
+ * @return true if file existed prior to removing it, false if file
+ * at p did not exist.
+ *
+ * @throw filesystem_error if removing the file failed for any other
+ * reason other than the file did not exist.
+ */
+bool remove(const path & p);
+
+/**
+ * Renames from_path to to_path as if by the glib function g_rename.
+ */
+void rename (const path& from_path, const path& to_path);
+
+/**
+ * Attempt to copy the contents of the file from_path to a new file
+ * at path to_path.
+ *
+ * @throw filesystem_error if from_path.empty() || to_path.empty() ||
+ * !exists(from_path) || !is_regular(from_path) || exists(to_path)
+ */
+void copy_file(const path & from_path, const path & to_path);
+
+/**
+ * @return The substring of the filename component of the path, starting
+ * at the beginning of the filename up to but not including the last dot.
+ *
+ * boost::filesystem::path::basename differs from g_path_get_basename and
+ * ::basename and most other forms of basename in that it removes the
+ * extension from the filename if the filename has one.
+ */
+string basename (const path& p);
+
+/**
+ * @return If the filename contains a dot, return a substring of the
+ * filename starting the rightmost dot to the end of the string, otherwise
+ * an empty string.
+ *
+ * @param p a file path.
+ */
+string extension (const path& p);
+
+} // namespace sys
+
+} // namespace PBD
+
+#endif