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(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 | |
364 | protected: |
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 | |
373 | private: |
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 | // |
386 | inline bool Path::isAbsolute() const |
387 | { |
388 | return _absolute; |
389 | } |
390 | |
391 | |
392 | inline bool Path::isRelative() const |
393 | { |
394 | return !_absolute; |
395 | } |
396 | |
397 | |
398 | inline bool Path::isDirectory() const |
399 | { |
400 | return _name.empty(); |
401 | } |
402 | |
403 | |
404 | inline bool Path::isFile() const |
405 | { |
406 | return !_name.empty(); |
407 | } |
408 | |
409 | |
410 | inline Path& Path::parse(const std::string& path) |
411 | { |
412 | return assign(path); |
413 | } |
414 | |
415 | |
416 | inline Path& Path::parse(const std::string& path, Style style) |
417 | { |
418 | return assign(path, style); |
419 | } |
420 | |
421 | |
422 | inline const std::string& Path::getNode() const |
423 | { |
424 | return _node; |
425 | } |
426 | |
427 | |
428 | inline const std::string& Path::getDevice() const |
429 | { |
430 | return _device; |
431 | } |
432 | |
433 | |
434 | inline const std::string& Path::getFileName() const |
435 | { |
436 | return _name; |
437 | } |
438 | |
439 | |
440 | inline int Path::depth() const |
441 | { |
442 | return int(_dirs.size()); |
443 | } |
444 | |
445 | |
446 | inline const std::string& Path::version() const |
447 | { |
448 | return _version; |
449 | } |
450 | |
451 | |
452 | inline Path Path::forDirectory(const std::string& path) |
453 | { |
454 | Path p; |
455 | return p.parseDirectory(path); |
456 | } |
457 | |
458 | |
459 | inline Path Path::forDirectory(const std::string& path, Style style) |
460 | { |
461 | Path p; |
462 | return p.parseDirectory(path, style); |
463 | } |
464 | |
465 | |
466 | inline 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 | |
478 | inline 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 | |
490 | inline 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 | |