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 self();
312 /// Returns the executable name with path.
313
314 static std::string temp();
315 /// Returns the temporary directory.
316
317 static std::string config();
318 /// Returns the systemwide config directory.
319 ///
320 /// On Unix systems, this is the '/etc/'.
321
322 static std::string null();
323 /// Returns the name of the null device.
324
325 static std::string expand(const std::string& path);
326 /// Expands all environment variables contained in the path.
327 ///
328 /// On Unix, a tilde as first character in the path is
329 /// replaced with the path to user's home directory.
330
331 static void listRoots(std::vector<std::string>& roots);
332 /// Fills the vector with all filesystem roots available on the
333 /// system. On Unix, there is exactly one root, "/".
334 /// On Windows, the roots are the drive letters.
335 /// On OpenVMS, the roots are the mounted disks.
336
337 static bool find(StringVec::const_iterator it, StringVec::const_iterator end, const std::string& name, Path& path);
338 /// Searches the file with the given name in the locations (paths) specified
339 /// by it and end. A relative path may be given in name.
340 ///
341 /// If the file is found in one of the locations, the complete
342 /// path of the file is stored in the path given as argument and true is returned.
343 /// Otherwise false is returned and the path argument remains unchanged.
344
345 static bool find(const std::string& pathList, const std::string& name, Path& path);
346 /// Searches the file with the given name in the locations (paths) specified
347 /// in pathList. The paths in pathList must be delimited by the platform's
348 /// path separator (see pathSeparator()). A relative path may be given in name.
349 ///
350 /// If the file is found in one of the locations, the complete
351 /// path of the file is stored in the path given as argument and true is returned.
352 /// Otherwise false is returned and the path argument remains unchanged.
353
354 static std::string transcode(const std::string& path);
355 /// On Windows, this function converts a string (usually containing a path)
356 /// encoded in UTF-8 into a string encoded in the current Windows code page.
357 ///
358 /// This function should be used for every string passed as a file name to
359 /// a string stream or fopen().
360 ///
361 /// On all other platforms, or if POCO has not been compiled with Windows UTF-8
362 /// support, this function returns the string unchanged.
363
364protected:
365 void parseUnix(const std::string& path);
366 void parseWindows(const std::string& path);
367 void parseVMS(const std::string& path);
368 void parseGuess(const std::string& path);
369 std::string buildUnix() const;
370 std::string buildWindows() const;
371 std::string buildVMS() const;
372
373private:
374 std::string _node;
375 std::string _device;
376 std::string _name;
377 std::string _version;
378 StringVec _dirs;
379 bool _absolute;
380};
381
382
383//
384// inlines
385//
386inline bool Path::isAbsolute() const
387{
388 return _absolute;
389}
390
391
392inline bool Path::isRelative() const
393{
394 return !_absolute;
395}
396
397
398inline bool Path::isDirectory() const
399{
400 return _name.empty();
401}
402
403
404inline bool Path::isFile() const
405{
406 return !_name.empty();
407}
408
409
410inline Path& Path::parse(const std::string& path)
411{
412 return assign(path);
413}
414
415
416inline Path& Path::parse(const std::string& path, Style style)
417{
418 return assign(path, style);
419}
420
421
422inline const std::string& Path::getNode() const
423{
424 return _node;
425}
426
427
428inline const std::string& Path::getDevice() const
429{
430 return _device;
431}
432
433
434inline const std::string& Path::getFileName() const
435{
436 return _name;
437}
438
439
440inline int Path::depth() const
441{
442 return int(_dirs.size());
443}
444
445
446inline const std::string& Path::version() const
447{
448 return _version;
449}
450
451
452inline Path Path::forDirectory(const std::string& path)
453{
454 Path p;
455 return p.parseDirectory(path);
456}
457
458
459inline Path Path::forDirectory(const std::string& path, Style style)
460{
461 Path p;
462 return p.parseDirectory(path, style);
463}
464
465
466inline char Path::separator()
467{
468#if defined(POCO_OS_FAMILY_VMS)
469 return '.';
470#elif defined(POCO_OS_FAMILY_WINDOWS)
471 return '\\';
472#else
473 return '/';
474#endif
475}
476
477
478inline char Path::pathSeparator()
479{
480#if defined(POCO_OS_FAMILY_VMS)
481 return ',';
482#elif defined(POCO_OS_FAMILY_WINDOWS)
483 return ';';
484#else
485 return ':';
486#endif
487}
488
489
490inline void swap(Path& p1, Path& p2)
491{
492 p1.swap(p2);
493}
494
495
496} // namespace Poco
497
498
499#endif // Foundation_Path_INCLUDED
500