1//
2// Path.h
3//
4// Library: Foundation
5// Package: Filesystem
6// Module: Path
7//
8// Definition of the Path class.
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Foundation_Path_INCLUDED
18#define Foundation_Path_INCLUDED
19
20
21#include "Poco/Foundation.h"
22#include <vector>
23
24
25namespace Poco {
26
27
28class Foundation_API Path
29 /// This class represents filesystem paths in a
30 /// platform-independent manner.
31 /// Unix, Windows and OpenVMS all use a different
32 /// syntax for filesystem paths.
33 /// This class can work with all three formats.
34 /// A path is made up of an optional node name
35 /// (only Windows and OpenVMS), an optional
36 /// device name (also only Windows and OpenVMS),
37 /// a list of directory names and an optional
38 /// filename.
39{
40public:
41 enum Style
42 {
43 PATH_UNIX, /// Unix-style path
44 PATH_URI = PATH_UNIX, /// URI-style path, same as Unix-style
45 PATH_WINDOWS, /// Windows-style path
46 PATH_VMS, /// VMS-style path
47 PATH_NATIVE, /// The current platform's native style
48 PATH_GUESS /// Guess the style by examining the path
49 };
50
51 typedef std::vector<std::string> StringVec;
52
53 Path();
54 /// Creates an empty relative path.
55
56 Path(bool absolute);
57 /// Creates an empty absolute or relative path.
58
59 Path(const char* path);
60 /// Creates a path from a string.
61
62 Path(const char* path, Style style);
63 /// Creates a path from a string.
64
65 Path(const std::string& path);
66 /// Creates a path from a string.
67
68 Path(const std::string& path, Style style);
69 /// Creates a path from a string.
70
71 Path(const Path& path);
72 /// Copy constructor
73
74 Path(const Path& parent, const std::string& fileName);
75 /// Creates a path from a parent path and a filename.
76 /// The parent path is expected to reference a directory.
77
78 Path(const Path& parent, const char* fileName);
79 /// Creates a path from a parent path and a filename.
80 /// The parent path is expected to reference a directory.
81
82 Path(const Path& parent, const Path& relative);
83 /// Creates a path from a parent path and a relative path.
84 /// The parent path is expected to reference a directory.
85 /// The relative path is appended to the parent path.
86
87 ~Path();
88 /// Destroys the Path.
89
90 Path& operator = (const Path& path);
91 /// Assignment operator.
92
93 Path& operator = (const std::string& path);
94 /// Assigns a string containing a path in native format.
95
96 Path& operator = (const char* path);
97 /// Assigns a string containing a path in native format.
98
99 void swap(Path& path);
100 /// Swaps the path with another one.
101
102 Path& assign(const std::string& path);
103 /// Assigns a string containing a path in native format.
104
105 Path& assign(const std::string& path, Style style);
106 /// Assigns a string containing a path.
107
108 Path& assign(const Path& path);
109 /// Assigns the given path.
110
111 Path& assign(const char* path);
112 /// Assigns a string containing a path.
113
114 std::string toString() const;
115 /// Returns a string containing the path in native format.
116
117 std::string toString(Style style) const;
118 /// Returns a string containing the path in the given format.
119
120 Path& parse(const std::string& path);
121 /// Same as assign().
122
123 Path& parse(const std::string& path, Style style);
124 /// Assigns a string containing a path.
125
126 bool tryParse(const std::string& path);
127 /// Tries to interpret the given string as a path
128 /// in native format.
129 /// If the path is syntactically valid, assigns the
130 /// path and returns true. Otherwise leaves the
131 /// object unchanged and returns false.
132
133 bool tryParse(const std::string& path, Style style);
134 /// Tries to interpret the given string as a path,
135 /// according to the given style.
136 /// If the path is syntactically valid, assigns the
137 /// path and returns true. Otherwise leaves the
138 /// object unchanged and returns false.
139
140 Path& parseDirectory(const std::string& path);
141 /// The resulting path always refers to a directory and
142 /// the filename part is empty.
143
144 Path& parseDirectory(const std::string& path, Style style);
145 /// The resulting path always refers to a directory and
146 /// the filename part is empty.
147
148 Path& makeDirectory();
149 /// If the path contains a filename, the filename is appended
150 /// to the directory list and cleared. Thus the resulting path
151 /// always refers to a directory.
152
153 Path& makeFile();
154 /// If the path contains no filename, the last directory
155 /// becomes the filename.
156
157 Path& makeParent();
158 /// Makes the path refer to its parent.
159
160 Path& makeAbsolute();
161 /// Makes the path absolute if it is relative.
162 /// The current working directory is taken as base directory.
163
164 Path& makeAbsolute(const Path& base);
165 /// Makes the path absolute if it is relative.
166 /// The given path is taken as base.
167
168 Path& append(const Path& path);
169 /// Appends the given path.
170
171 Path& resolve(const Path& path);
172 /// Resolves the given path against the current one.
173 ///
174 /// If the given path is absolute, it replaces the current one.
175 /// Otherwise, the relative path is appended to the current path.
176
177 bool isAbsolute() const;
178 /// Returns true iff the path is absolute.
179
180 bool isRelative() const;
181 /// Returns true iff the path is relative.
182
183 bool isDirectory() const;
184 /// Returns true iff the path references a directory
185 /// (the filename part is empty).
186
187 bool isFile() const;
188 /// Returns true iff the path references a file
189 /// (the filename part is not empty).
190
191 Path& setNode(const std::string& node);
192 /// Sets the node name.
193 /// Setting a non-empty node automatically makes
194 /// the path an absolute one.
195
196 const std::string& getNode() const;
197 /// Returns the node name.
198
199 Path& setDevice(const std::string& device);
200 /// Sets the device name.
201 /// Setting a non-empty device automatically makes
202 /// the path an absolute one.
203
204 const std::string& getDevice() const;
205 /// Returns the device name.
206
207 int depth() const;
208 /// Returns the number of directories in the directory list.
209
210 const std::string& directory(int n) const;
211 /// Returns the n'th directory in the directory list.
212 /// If n == depth(), returns the filename.
213
214 const std::string& operator [] (int n) const;
215 /// Returns the n'th directory in the directory list.
216 /// If n == depth(), returns the filename.
217
218 Path& pushDirectory(const std::string& dir);
219 /// Adds a directory to the directory list.
220
221 Path& popDirectory();
222 /// Removes the last directory from the directory list.
223
224 Path& popFrontDirectory();
225 /// Removes the first directory from the directory list.
226
227 Path& setFileName(const std::string& name);
228 /// Sets the filename.
229
230 const std::string& getFileName() const;
231 /// Returns the filename.
232
233 Path& setBaseName(const std::string& name);
234 /// Sets the basename part of the filename and
235 /// does not change the extension.
236
237 std::string getBaseName() const;
238 /// Returns the basename (the filename sans
239 /// extension) of the path.
240
241 Path& setExtension(const std::string& extension);
242 /// Sets the filename extension.
243
244 std::string getExtension() const;
245 /// Returns the filename extension.
246
247 const std::string& version() const;
248 /// Returns the file version. VMS only.
249
250 Path& clear();
251 /// Clears all components.
252
253 Path parent() const;
254 /// Returns a path referring to the path's
255 /// directory.
256
257 Path absolute() const;
258 /// Returns an absolute variant of the path,
259 /// taking the current working directory as base.
260
261 Path absolute(const Path& base) const;
262 /// Returns an absolute variant of the path,
263 /// taking the given path as base.
264
265 static Path forDirectory(const std::string& path);
266 /// Creates a path referring to a directory.
267
268 static Path forDirectory(const std::string& path, Style style);
269 /// Creates a path referring to a directory.
270
271 static char separator();
272 /// Returns the platform's path name separator, which separates
273 /// the components (names) in a path.
274 ///
275 /// On Unix systems, this is the slash '/'. On Windows systems,
276 /// this is the backslash '\'. On OpenVMS systems, this is the
277 /// period '.'.
278
279 static char pathSeparator();
280 /// Returns the platform's path separator, which separates
281 /// single paths in a list of paths.
282 ///
283 /// On Unix systems, this is the colon ':'. On Windows systems,
284 /// this is the semicolon ';'. On OpenVMS systems, this is the
285 /// comma ','.
286
287 static std::string current();
288 /// Returns the current working directory.
289
290 static std::string home();
291 /// Returns the user's home directory.
292
293 static std::string configHome();
294 /// Returns the user's config directory.
295 ///
296 /// On Unix systems, this is the '~/.config/'. On Windows systems,
297 /// this is '%APPDATA%'.
298
299 static std::string dataHome();
300 /// Returns the user's data directory.
301 ///
302 /// On Unix systems, this is the '~/.local/share/'. On Windows systems,
303 /// this is '%APPDATA%'.
304
305 static std::string cacheHome();
306 /// Returns the user's cache directory.
307 ///
308 /// On Unix systems, this is the '~/.cache/'. On Windows systems,
309 /// this is '%APPDATA%'.
310
311 static std::string temp();
312 /// Returns the temporary directory.
313
314 static std::string config();
315 /// Returns the systemwide config directory.
316 ///
317 /// On Unix systems, this is the '/etc/'.
318
319 static std::string null();
320 /// Returns the name of the null device.
321
322 static std::string expand(const std::string& path);
323 /// Expands all environment variables contained in the path.
324 ///
325 /// On Unix, a tilde as first character in the path is
326 /// replaced with the path to user's home directory.
327
328 static void listRoots(std::vector<std::string>& roots);
329 /// Fills the vector with all filesystem roots available on the
330 /// system. On Unix, there is exactly one root, "/".
331 /// On Windows, the roots are the drive letters.
332 /// On OpenVMS, the roots are the mounted disks.
333
334 static bool find(StringVec::const_iterator it, StringVec::const_iterator end, const std::string& name, Path& path);
335 /// Searches the file with the given name in the locations (paths) specified
336 /// by it and end. A relative path may be given in name.
337 ///
338 /// If the file is found in one of the locations, the complete
339 /// path of the file is stored in the path given as argument and true is returned.
340 /// Otherwise false is returned and the path argument remains unchanged.
341
342 static bool find(const std::string& pathList, const std::string& name, Path& path);
343 /// Searches the file with the given name in the locations (paths) specified
344 /// in pathList. The paths in pathList must be delimited by the platform's
345 /// path separator (see pathSeparator()). A relative path may be given in name.
346 ///
347 /// If the file is found in one of the locations, the complete
348 /// path of the file is stored in the path given as argument and true is returned.
349 /// Otherwise false is returned and the path argument remains unchanged.
350
351 static std::string transcode(const std::string& path);
352 /// On Windows, this function converts a string (usually containing a path)
353 /// encoded in UTF-8 into a string encoded in the current Windows code page.
354 ///
355 /// This function should be used for every string passed as a file name to
356 /// a string stream or fopen().
357 ///
358 /// On all other platforms, or if POCO has not been compiled with Windows UTF-8
359 /// support, this function returns the string unchanged.
360
361protected:
362 void parseUnix(const std::string& path);
363 void parseWindows(const std::string& path);
364 void parseVMS(const std::string& path);
365 void parseGuess(const std::string& path);
366 std::string buildUnix() const;
367 std::string buildWindows() const;
368 std::string buildVMS() const;
369
370private:
371 std::string _node;
372 std::string _device;
373 std::string _name;
374 std::string _version;
375 StringVec _dirs;
376 bool _absolute;
377};
378
379
380//
381// inlines
382//
383inline bool Path::isAbsolute() const
384{
385 return _absolute;
386}
387
388
389inline bool Path::isRelative() const
390{
391 return !_absolute;
392}
393
394
395inline bool Path::isDirectory() const
396{
397 return _name.empty();
398}
399
400
401inline bool Path::isFile() const
402{
403 return !_name.empty();
404}
405
406
407inline Path& Path::parse(const std::string& path)
408{
409 return assign(path);
410}
411
412
413inline Path& Path::parse(const std::string& path, Style style)
414{
415 return assign(path, style);
416}
417
418
419inline const std::string& Path::getNode() const
420{
421 return _node;
422}
423
424
425inline const std::string& Path::getDevice() const
426{
427 return _device;
428}
429
430
431inline const std::string& Path::getFileName() const
432{
433 return _name;
434}
435
436
437inline int Path::depth() const
438{
439 return int(_dirs.size());
440}
441
442
443inline const std::string& Path::version() const
444{
445 return _version;
446}
447
448
449inline Path Path::forDirectory(const std::string& path)
450{
451 Path p;
452 return p.parseDirectory(path);
453}
454
455
456inline Path Path::forDirectory(const std::string& path, Style style)
457{
458 Path p;
459 return p.parseDirectory(path, style);
460}
461
462
463inline char Path::separator()
464{
465#if defined(POCO_OS_FAMILY_VMS)
466 return '.';
467#elif defined(POCO_OS_FAMILY_WINDOWS)
468 return '\\';
469#else
470 return '/';
471#endif
472}
473
474
475inline char Path::pathSeparator()
476{
477#if defined(POCO_OS_FAMILY_VMS)
478 return ',';
479#elif defined(POCO_OS_FAMILY_WINDOWS)
480 return ';';
481#else
482 return ':';
483#endif
484}
485
486
487inline void swap(Path& p1, Path& p2)
488{
489 p1.swap(p2);
490}
491
492
493} // namespace Poco
494
495
496#endif // Foundation_Path_INCLUDED
497