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