VideoTools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gpath.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2017 Graeme Walker
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 // ===
17 ///
18 /// \file gpath.h
19 ///
20 
21 #ifndef G_PATH_H
22 #define G_PATH_H
23 
24 #include "gdef.h"
25 #include "gstrings.h"
26 #include <string>
27 #include <iostream>
28 
29 namespace G
30 {
31  class Path ;
32  class PathImp ;
33 }
34 
35 /// \class G::Path
36 /// A Path object represents a file system path. The class is concerned with
37 /// path syntax, not file system i/o.
38 ///
39 /// A full path is made up of a root, a set of directories, and a filename. The
40 /// posix root is just a forward slash, but on Windows the root can be complex,
41 /// possibly including non-splitting separator characters. The filename may have
42 /// an extension part, which is to the right of the right-most dot.
43 ///
44 /// The path separator is used between directories and filename, but only
45 /// between the root and the first directory if the root does not itself end in
46 /// a separator character.
47 ///
48 /// A windows drive-letter root may end with a separator character or not; if
49 /// there is no separator character at the end of the drive-letter root then
50 /// the path is relative to the drive's current working directory.
51 ///
52 /// Path components of "." are ignored by simple(), basename(), and dirname().
53 /// Path components of ".." are retained but can be eliminated if they are
54 /// collapsed(). Path components of "." are eliminated by split(), except
55 /// in the degenerate case.
56 ///
57 /// This class is agnostic on the choice of utf8 or eight-bit characters since
58 /// the delimiters are all seven-bit ascii. On Windows it might make sense to
59 /// obtain paths from the win32 api as multi-byte and convert immediately to
60 /// utf8 before wrapping in G::Path.
61 ///
62 /// Both posix and windows behaviours are available at run-time; the default
63 /// behaviour is the native behaviour, but this can be overridden, typically
64 /// for testing purposes.
65 ///
66 /// The posix path separator character is the forward-slash; on Windows it is a
67 /// back-slash, but with all forward-slashes converted to back-slashes
68 /// immediately on input.
69 ///
70 /// \see G::File, G::Directory
71 ///
72 class G::Path
73 {
74 public:
75  Path() ;
76  ///< Default constructor for a zero-length path.
77  ///< Postcondition: str().empty()
78 
79  Path( const std::string & path ) ;
80  ///< Implicit constructor from a string.
81 
82  Path( const char * path ) ;
83  ///< Implicit constructor from a c-style string.
84 
85  Path( const Path & path , const std::string & tail ) ;
86  ///< Constructor with an implicit pathAppend().
87 
88  Path( const Path & path , const std::string & tail_1 , const std::string & tail_2 ) ;
89  ///< Constructor with two implicit pathAppend()s.
90 
91  Path( const Path & other ) ;
92  ///< Copy constructor.
93 
94  ~Path() ;
95  ///< Destructor.
96 
97  std::string str() const ;
98  ///< Returns the path string.
99 
100  bool simple() const ;
101  ///< Returns true if the path has a single component (ignoring "." parts),
102  ///< ie. the dirname() is empty.
103 
104  std::string basename() const ;
105  ///< Returns the rightmost part of the path, ignoring "." parts.
106  ///< For a directory path this may be "..", but see also collapsed().
107 
108  Path dirname() const ;
109  ///< Returns the path without the rightmost part, ignoring "." parts.
110  ///< For simple() paths the empty path is returned.
111 
112  std::string extension() const ;
113  ///< Returns the path's basename extension, ie. anything
114  ///< after the rightmost dot. Returns the zero-length
115  ///< string if there is none.
116 
117  Path withExtension( const std::string & ext ) const ;
118  ///< Returns the path with the new basename extension.
119  ///< Any previous extension is replaced. The extension
120  ///< should not normally have a leading dot and it
121  ///< should not be the empty string.
122 
123  Path withoutExtension() const ;
124  ///< Returns a path without the basename extension, if any.
125  ///< As a special case, a basename() that starts with a dot
126  ///< is replaced by a single dot. Prefer withExtension()
127  ///< where appropriate to avoid this.
128 
129  bool isAbsolute() const ;
130  ///< Returns !isRelative().
131 
132  bool isRelative() const ;
133  ///< Returns true if the path is a relative path.
134 
135  void pathAppend( const std::string & tail ) ;
136  ///< Appends a filename or a relative path to this path.
137 
138  StringArray split() const ;
139  ///< Spits the path into a list of component parts (ignoring "." parts
140  ///< unless the whole path is ".").
141 
142  static Path join( const StringArray & parts ) ;
143  ///< Builds a path from a set of parts. Note that part boundaries
144  ///< are not necessarily preserved once they have been join()ed
145  ///< into a path.
146 
147  static Path join( const Path & p1 , const Path & p2 ) ;
148  ///< Joins two paths together. The second should be a relative path.
149 
150  static Path difference( const Path & p1 , const Path & p2 ) ;
151  ///< Returns the relative path from p1 to p2. Returns the empty
152  ///< path if p2 is not under p1. Returns "." if p1 and p2 are the
153  ///< same. Input paths are collapsed(). Empty input paths are
154  ///< treated as ".".
155 
156  Path collapsed() const ;
157  ///< Returns the path with "foo/.." and "." parts removed, so far
158  ///< as is possible without changing the meaning of the path.
159  ///< Parts like "../foo" at the beginning of the path, or immediately
160  ///< following the root, are not removed.
161 
162  static Path nullDevice() ;
163  ///< Returns the path of the "/dev/null" special file, or equivalent.
164 
165  void swap( Path & other ) ;
166  ///< Swaps this with other.
167 
168  Path & operator=( const Path & other ) ;
169  ///< Assignment operator.
170 
171  bool operator==( const Path & path ) const ;
172  ///< Comparison operator.
173 
174  bool operator!=( const Path & path ) const ;
175  ///< Comparison operator.
176 
177  static void setPosixStyle() ;
178  ///< Sets posix mode for testing purposes.
179 
180  static void setWindowsStyle() ;
181  ///< Sets windows mode for testing purposes.
182 
183  static bool less( const Path & a , const Path & b ) ;
184  ///< Compares two paths, with simple eight-bit lexicographical
185  ///< comparisons of each path component. This is slightly different
186  ///< from a lexicographical comparison of the compete strings
187  ///< (eg. "a/b" compared to "a./b"), and it is not suitable for
188  ///< utf8 paths.
189 
190 private:
191  friend class G::PathImp ;
192  std::string m_str ;
193 } ;
194 
195 namespace G
196 {
197  inline
198  std::ostream & operator<<( std::ostream & stream , const Path & path )
199  {
200  return stream << path.str() ;
201  }
202 
203  inline
204  Path & operator+=( Path & p , const std::string & str )
205  {
206  p.pathAppend( str ) ;
207  return p ;
208  }
209 
210  inline
211  Path operator+( const Path & p , const std::string & str )
212  {
213  return Path( p , str ) ;
214  }
215 
216  inline
217  void swap( Path & p1 , Path & p2 )
218  {
219  p1.swap( p2 ) ;
220  }
221 }
222 
223 #endif
std::string str() const
Returns the path string.
Definition: gpath.cpp:290
Path & operator=(const Path &other)
Assignment operator.
Definition: gpath.cpp:461
void swap(Path &other)
Swaps this with other.
Definition: gpath.cpp:455
A private implementation class used by G::Path providing a set of static methods. ...
Definition: gpath.cpp:35
Path()
Default constructor for a zero-length path.
Definition: gpath.cpp:245
Path withoutExtension() const
Returns a path without the basename extension, if any.
Definition: gpath.cpp:328
std::string basename() const
Returns the rightmost part of the path, ignoring "." parts.
Definition: gpath.cpp:310
bool operator!=(const Path &path) const
Comparison operator.
Definition: gpath.cpp:450
std::vector< std::string > StringArray
A std::vector of std::strings.
Definition: gstrings.h:33
std::string extension() const
Returns the path's basename extension, ie.
Definition: gpath.cpp:373
bool simple() const
Returns true if the path has a single component (ignoring "." parts), ie.
Definition: gpath.cpp:295
bool isRelative() const
Returns true if the path is a relative path.
Definition: gpath.cpp:305
static Path difference(const Path &p1, const Path &p2)
Returns the relative path from p1 to p2.
Definition: gpath.cpp:483
static bool less(const Path &a, const Path &b)
Compares two paths, with simple eight-bit lexicographical comparisons of each path component...
Definition: gpath.cpp:473
bool isAbsolute() const
Returns !isRelative().
Definition: gpath.cpp:300
bool operator==(const Path &path) const
Comparison operator.
Definition: gpath.cpp:445
Path dirname() const
Returns the path without the rightmost part, ignoring "." parts.
Definition: gpath.cpp:318
StringArray split() const
Spits the path into a list of component parts (ignoring "." parts unless the whole path is "...
Definition: gpath.cpp:382
Path collapsed() const
Returns the path with "foo/.." and "." parts removed, so far as is possible without changing the mean...
Definition: gpath.cpp:415
void pathAppend(const std::string &tail)
Appends a filename or a relative path to this path.
Definition: gpath.cpp:357
static void setWindowsStyle()
Sets windows mode for testing purposes.
Definition: gpath.cpp:240
static void setPosixStyle()
Sets posix mode for testing purposes.
Definition: gpath.cpp:235
A Path object represents a file system path.
Definition: gpath.h:72
static Path join(const StringArray &parts)
Builds a path from a set of parts.
Definition: gpath.cpp:390
~Path()
Destructor.
Definition: gpath.cpp:249
static Path nullDevice()
Returns the path of the "/dev/null" special file, or equivalent.
Definition: gpath.cpp:285
Path withExtension(const std::string &ext) const
Returns the path with the new basename extension.
Definition: gpath.cpp:346