1 // 2 // CDDL HEADER START 3 // 4 // The contents of this file are subject to the terms of the Common Development 5 // and Distribution License Version 1.0 (the "License"). 6 // 7 // You can obtain a copy of the license at 8 // http://www.opensource.org/licenses/CDDL-1.0. See the License for the 9 // specific language governing permissions and limitations under the License. 10 // 11 // When distributing Covered Code, include this CDDL HEADER in each file and 12 // include the License file in a prominent location with the name LICENSE.CDDL. 13 // If applicable, add the following below this CDDL HEADER, with the fields 14 // enclosed by brackets "[]" replaced with your own identifying information: 15 // 16 // Portions Copyright (c) [yyyy] [name of copyright owner]. All rights reserved. 17 // 18 // CDDL HEADER END 19 // 20 21 // 22 // Copyright (c) 2016--2020, Regents of the University of Minnesota. 23 // All rights reserved. 24 // 25 // Contributors: 26 // Ryan S. Elliott 27 // Alexander Stukowski 28 // 29 30 // 31 // Release: This file is part of the kim-api-2.2.1 package. 32 // 33 34 35 #ifndef KIM_FILESYSTEM_PATH_HPP_ 36 #define KIM_FILESYSTEM_PATH_HPP_ 37 38 #include <cstdlib> 39 #include <iostream> 40 #include <vector> 41 42 // If available, use the std::filesystem::path class 43 // for cross-platform file path handling introduced with C++17. 44 // Older versions of the GCC compiler support C++17 but do not include an 45 // implementation of the std::filesystem library. Then fall back to the GHC 46 // drop-in replacement library. In all other cases, in particular in C++98 mode, 47 // fall back to a minimal implementation based on std::string. 48 #if defined(__cplusplus) && __cplusplus >= 201703L && defined(__has_include) 49 // C++17 mode: 50 #if __has_include(<filesystem>) 51 // Have std::filesystem implementation: 52 #include <filesystem> 53 #else 54 // Fall back to drop-in library: 55 #define GHC_WIN_WSTRING_STRING_TYPE 56 #include "ghc-filesystem/filesystem.hpp" 57 // We need the alias from ghc::filesystem to std::filesystem 58 namespace std 59 { 60 namespace filesystem = ghc::filesystem; 61 } 62 #endif 63 #define KIM_API_USE_FILESYSTEM_LIBRARY 1 64 #endif 65 66 #ifdef KIM_API_USE_FILESYSTEM_LIBRARY 67 namespace 68 { 69 typedef std::filesystem::path KIM_Path; 70 } 71 #else 72 #include <string> 73 namespace 74 { 75 typedef std::string KIM_Path; 76 } 77 #endif 78 79 namespace KIM 80 { 81 namespace FILESYSTEM 82 { 83 class Path 84 { 85 public: 86 // Platform-dependent character for separating path entries. 87 static const std::string::value_type preferred_separator; 88 Path()89 Path() {} Path(const char * str)90 Path(const char * str) 91 { 92 if (str != NULL) path_ = str; 93 } Path(const std::string & str)94 Path(const std::string & str) : path_(str) {} 95 #ifdef KIM_API_USE_FILESYSTEM_LIBRARY Path(const std::filesystem::path & p)96 Path(const std::filesystem::path & p) : path_(p) {} Path(std::filesystem::path && p)97 Path(std::filesystem::path && p) : path_(std::move(p)) {} 98 #endif 99 operator =(const std::string & other)100 Path & operator=(const std::string & other) 101 { 102 path_ = other; 103 return *this; 104 } 105 operator =(const char * other)106 Path & operator=(const char * other) 107 { 108 path_ = other; 109 return *this; 110 } 111 112 Path & operator+=(char const * const s); 113 Path & operator/=(const Path & p); 114 Path operator/(const Path & p) const; operator <(const Path & lhs,const Path & rhs)115 friend bool operator<(const Path & lhs, const Path & rhs) 116 { 117 return lhs.path_ < rhs.path_; 118 } operator ==(const Path & lhs,const Path & rhs)119 friend bool operator==(const Path & lhs, const Path & rhs) 120 { 121 return lhs.path_ == rhs.path_; 122 } 123 124 // Concatenates the current path and the argument. 125 Path & concat(const std::string & p); 126 127 // Turns the path object into a conventional string, which can be passed to 128 // I/O functions. 129 std::string string() const; 130 131 // Returns the native string representation of the path, using native syntax, 132 // native character type, and native character encoding. This string is 133 // suitable for use with OS APIs. c_str() const134 const KIM_Path::value_type * c_str() const { return path_.c_str(); } 135 136 // Resets the path to an empty string. clear()137 void clear() { path_.clear(); } 138 139 // Returns whether this path is the empty string. empty() const140 bool empty() const { return path_.empty(); } 141 142 // Returns the path of the parent path 143 Path parent_path() const; 144 145 // Returns the last component of the path. 146 Path filename() const; 147 148 // Removes a single filename component from the path. 149 Path & remove_filename(); 150 151 // Converts all directory separators to the preferred directory separator of 152 // the current platform. 153 Path & make_preferred(); 154 155 // Creates a new directory, including parent directories if necessary. 156 // It's not an error if the directory to be created already exists. 157 // Returns true on error. 158 bool MakeDirectory() const; 159 160 // Deletes the contents of this path (if it is a directory) and the contents 161 // of all its subdirectories, recursively, then deletes the file path itself. 162 // Returns true on error. 163 bool RemoveDirectoryRecursive() const; 164 165 // Returns the list of subdirectories of this directory. 166 std::vector<Path> Subdirectories() const; 167 168 // Checks whether the file or directory exists. 169 bool exists() const; 170 171 // Checks whether the path is relative. 172 bool is_relative() const; 173 174 // Returns the current working directory. 175 static Path current_path(); 176 177 // Returns the user's home directory. 178 static Path HomePath(); 179 180 // Creates a new empty directory that can be used to write temporary files 181 // into. Returns an empty path on failure. 182 static Path CreateTemporaryDirectory(char const * const namePrefix); 183 184 // Performs stream output on the path (operator <<). 185 template<class CharT, class Traits> 186 friend std::basic_ostream<CharT, Traits> & operator <<(std::basic_ostream<CharT,Traits> & os,const Path & p)187 operator<<(std::basic_ostream<CharT, Traits> & os, const Path & p) 188 { 189 return os << p.path_; 190 } 191 192 private: 193 // The internal path storage: 194 KIM_Path path_; 195 }; 196 197 class PathList : public std::vector<Path> 198 { 199 public: 200 // Platform-dependent character for separating paths in the lists. 201 static const std::string::value_type PreferredSeparator; 202 203 // Platform-dependent character for home directory. 204 static const std::string::value_type HomeDirectoryShortcut; 205 206 // Creates all directories in the path list, including parent directories if 207 // necessary. It's not an error if a directory to be created already exists. 208 // Returns true on error. 209 bool MakeDirectories() const; 210 211 // Converts the path list into a colon- or semicolon-separated string list. 212 std::string ToString() const; 213 214 // Parses a list of filesystem paths separated by colons (or semi-colons on 215 // Windows). 216 // '~' at the beginning of a path is replaced with the user's home directory. 217 size_t Parse(std::string::value_type const * const paths); 218 219 // Performs stream output on the path (operator <<). 220 template<class CharT, class Traits> 221 friend std::basic_ostream<CharT, Traits> & operator <<(std::basic_ostream<CharT,Traits> & os,const PathList & p)222 operator<<(std::basic_ostream<CharT, Traits> & os, const PathList & p) 223 { 224 return os << p.ToString(); 225 } 226 }; 227 228 } // namespace FILESYSTEM 229 } // namespace KIM 230 231 #endif // KIM_FILESYSTEM_PATH_HPP_ 232