casa
$Rev:20696$
|
00001 //# Path.h: Path name of a file 00002 //# Copyright (C) 1993,1994,1995,1996,1997,1998,1999,2000 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id: Path.h 21030 2011-03-16 13:44:34Z gervandiepen $ 00027 00028 00029 #ifndef CASA_PATH_H 00030 #define CASA_PATH_H 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 #include <casa/BasicSL/String.h> 00035 00036 00037 namespace casa { //# NAMESPACE CASA - BEGIN 00038 00039 // <summary> 00040 // Path name of a file 00041 // </summary> 00042 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos=""> 00043 // </reviewed> 00044 00045 // <prerequisite> 00046 // <li> Basic knowledge of the UNIX file system 00047 // </prerequisite> 00048 00049 // <etymology> 00050 // The term 'path' is the standard term for describing the location of a file 00051 // in a hierarchy of possibly nested directories. In order to find a 00052 // particular file you must travel a specific path strating from a known 00053 // point. We use the term in its standard sense in this class. 00054 // </etymology> 00055 00056 // <synopsis> 00057 // This class can be used to describe a pathname. One can also create, 00058 // validate, parse (get base or directory names or original, expanded or 00059 // absolute names), query and append strings. The client programmer can 00060 // give a string, at construction, which describes a path. This string can 00061 // be a relative or an absolute name. Environment variables and a tilde 00062 // (with or without user name) can also be used in the string and will 00063 // be expanded by the function expandedName. 00064 // <br> The function 00065 // Once a Path has been constructed, you can query the object for its 00066 // original name, expanded name, absolute name, the name of the directory 00067 // where it is found or the name of only the file. Expanding the path name 00068 // means that possible environment variables and tilde get expanded. 00069 // There are also functions to get the length or maximum length of a path. 00070 // Pathnames can also be checked on correctness and they can be checked 00071 // if they conform the POSIX standard. 00072 // </synopsis> 00073 00074 // <example> 00075 // In this example a few pathnames are created. 00076 // <srcblock> 00077 // Path test1("~/test/$TEST1/.."); // absolute path 00078 // Path test2("/$HOME/./analyse"); // absolute path 00079 // Path test3("myFile"); // relative path 00080 // 00081 // cout << test1.originalName() << endl; 00082 // 00083 // // Test1 is according the POSIX standard 00084 // if (test1.isStrictlyPosix()){ 00085 // cout << "test1 is strictly POSIX << endl; 00086 // } 00087 // 00088 // // Test1 is valid 00089 // if (test1.isValid()){ 00090 // cout << test1.isValid() << endl; 00091 // } 00092 // 00093 // // if "TEST1=$TEST2 and TEST2=$TEST1"(recursive environment variables) 00094 // // an exception will be thrown. ~ is replaced by the homedirectory 00095 // cout << test1.expandedName() << endl; 00096 // // $HOME is expanded 00097 // cout << test2.expandedName() << endl; 00098 // cout << test1.absoluteName() << endl; 00099 // cout << test2.absoluteName() << endl; 00100 // cout << test2.baseName() << endl; 00101 // cout << test1.dirName() << endl; 00102 // cout << test3.originalName() << endl; // myFile is returned 00103 // cout << test3.expandedName() << endl; // Nothing is changed 00104 // cout << test3.absoluteName() << endl; // The current working directory 00105 // is placed before 'myFile' 00106 // cout << test3.baseName() << endl; // The current working directory 00107 // // is returned 00108 // cout << test3.dirName() << endl; // myFile is returned 00109 // </srcblock> 00110 // </example> 00111 00112 // <motivation> 00113 // Programmer convenience and (eventually) OS independence. 00114 // </motivation> 00115 00116 // <todo asof=$DATE$> 00117 // <li> To make the class OS independent some functions should be rebuild. 00118 // These functions could be expandedName or absoluteName. 00119 // <li> The function expandedName or absoluteName could map the filename to 00120 // the native convention 00121 // <li> A (maybe static) function contractName(const String& pathName) 00122 // could be implemented to remove . and .. from the file name. 00123 // </todo> 00124 00125 00126 class Path 00127 { 00128 public: 00129 // Default constructor, the path is set to . (working directory). 00130 Path(); 00131 00132 // Construct a path with the given name. 00133 // When the name is empty, it is set to . (working directory). 00134 // It is not checked if the path name is valid. 00135 // Function isValid() can be used for that purpose. 00136 Path (const String& pathName); 00137 00138 // Copy constructor, copy semantics. 00139 Path (const Path& that); 00140 00141 // Destructor 00142 ~Path(); 00143 00144 // Assignment, copy semantics. 00145 Path& operator= (const Path& that); 00146 00147 // Append a string to the path name. 00148 // When the current path does not end with a / and the string to append 00149 // does not start with a /, an intermediate / is also added. 00150 void append (const String& string); 00151 00152 // Returns the string as given at construction. 00153 const String& originalName () const; 00154 00155 // Return a string giving the expanded pathname. 00156 // This means that the environment variables are expanded and the tilde 00157 // is replaced by the home directory. An expanded name can still 00158 // be a relative path. 00159 // An exception is thrown when converting a recursive environment 00160 // variable results in an endless loop (that is, more than 25 00161 // substitutions). 00162 const String& expandedName () const; 00163 00164 // Return the string which giving the absolute pathname. 00165 // It is generated from the expanded pathname by adding 00166 // the working directory when needed. 00167 const String& absoluteName () const; 00168 00169 // Return the realpath which is the absolute pathname with possible 00170 // symlinks resolved. It also resolves //, /./, /../ and trailing /. 00171 // <br>The path must be an existing file or directory. 00172 // It uses the system's realpath function. In case it fails, 00173 // an exception is thrown. 00174 String resolvedName() const; 00175 00176 // Check if pathname is valid. This function checks for: double slashes, 00177 // non-printable characters, pathname length and filename lenghts, this 00178 // function is more OS-specific. 00179 Bool isValid() const; 00180 00181 // Check if pathname is valid according the POSIX standard. 00182 // This function checks for 00183 // double slashes, non-printable characters,pathname length and filename 00184 // lenghts, all according to the POSIX-standard. 00185 Bool isStrictlyPosix() const; 00186 00187 // Return length of path name 00188 uInt length() const; 00189 00190 // Return the maximum length a path name can have. 00191 uInt maxLength() const; 00192 00193 // Return the basename of the path; this is only the name of the file. 00194 // It takes it from the expanded path name. 00195 String baseName() const; 00196 00197 // Return the dirname of the path; this is the directory where the 00198 // filename is found. It takes it from the expanded path name. 00199 // <br>To get the absolute dirname one could do: 00200 // <srcblock> 00201 // Path tmpPath (myPath.dirName()); 00202 // String absDir (tmpPath.absoluteName()); 00203 // </srcblock> 00204 // or 00205 // <srcblock> 00206 // Path tmpPath (myPath.absoluteName()); 00207 // String absDir (tmpPath.dirName()); 00208 // </srcblock> 00209 String dirName() const; 00210 00211 // Strip otherName from this name. If stripped, the result gets a 00212 // leading ././ 00213 // If not stripped, it is tried if name can be stripped from otherName. 00214 // If stripped, the result gets a trailing /. 00215 // If still not stripped, it is tried to strip the directory of otherName. 00216 // If that succeeds, the result gets a leading ./ 00217 // This is used by RefTable and TableKeyword to ensure that the 00218 // name of a subtable or referenced table is always relative to 00219 // the main table. 00220 static String stripDirectory (const String& name, const String& otherName); 00221 00222 // If the name starts with ././ add otherName to it. 00223 // If the name ends with /. strip name from otherName and return the 00224 // remainder. 00225 // If the name starts with ./ add the directory of otherName to it. 00226 // It is the opposite of stripDirectory. 00227 static String addDirectory (const String& name, const String& otherName); 00228 00229 00230 private: 00231 // Strings to describe the pathname in three different ways. 00232 String itsOriginalPathName; 00233 // These variables are pointer to strings because the functions which use 00234 // these variables are const functions. This means that they would not be 00235 // able to modify the string, now they can. 00236 mutable String itsAbsolutePathName; 00237 mutable String itsExpandedPathName; 00238 00239 // Define the maximum number of bytes in a pathname 00240 // This definition does not use Posix values. 00241 static uInt getMaxPathNameSize (); 00242 // Define the maximum number of bytes in a filename 00243 // This definition does not use Posix values. 00244 static uInt getMaxNameSize (); 00245 00246 00247 // This function is used by expandedName to replace the tilde and to 00248 // expand the environment variables 00249 String expandName (const String& inString) const; 00250 00251 // This function is used by absoluteName to make a name absolute, 00252 // this means that the name is described from the root 00253 String makeAbsoluteName (const String& inString) const; 00254 00255 // Remove . and .. from the path name. 00256 // Also multiple slashes are replaced by a single. 00257 String removeDots (const String& inString) const; 00258 00259 // This function is used by expandName and absoluteName. It sets the 00260 // integer "count" on the next slash or on the end of a string 00261 void getNextName (const String& inString, uInt& count) const; 00262 }; 00263 00264 00265 inline const String& Path::originalName() const 00266 { 00267 return itsOriginalPathName; 00268 } 00269 00270 00271 00272 } //# NAMESPACE CASA - END 00273 00274 #endif