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