Path.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. //
  2. // Path.h
  3. //
  4. // $Id: //poco/1.4/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. // SPDX-License-Identifier: BSL-1.0
  16. //
  17. #ifndef Foundation_Path_INCLUDED
  18. #define Foundation_Path_INCLUDED
  19. #include "Poco/Foundation.h"
  20. #include <vector>
  21. namespace Poco {
  22. class Foundation_API Path
  23. /// This class represents filesystem paths in a
  24. /// platform-independent manner.
  25. /// Unix, Windows and OpenVMS all use a different
  26. /// syntax for filesystem paths.
  27. /// This class can work with all three formats.
  28. /// A path is made up of an optional node name
  29. /// (only Windows and OpenVMS), an optional
  30. /// device name (also only Windows and OpenVMS),
  31. /// a list of directory names and an optional
  32. /// filename.
  33. {
  34. public:
  35. enum Style
  36. {
  37. PATH_UNIX, /// Unix-style path
  38. PATH_WINDOWS, /// Windows-style path
  39. PATH_VMS, /// VMS-style path
  40. PATH_NATIVE, /// The current platform's native style
  41. PATH_GUESS /// Guess the style by examining the path
  42. };
  43. typedef std::vector<std::string> StringVec;
  44. Path();
  45. /// Creates an empty relative path.
  46. Path(bool absolute);
  47. /// Creates an empty absolute or relative path.
  48. Path(const char* path);
  49. /// Creates a path from a string.
  50. Path(const char* path, Style style);
  51. /// Creates a path from a string.
  52. Path(const std::string& path);
  53. /// Creates a path from a string.
  54. Path(const std::string& path, Style style);
  55. /// Creates a path from a string.
  56. Path(const Path& path);
  57. /// Copy constructor
  58. Path(const Path& parent, const std::string& fileName);
  59. /// Creates a path from a parent path and a filename.
  60. /// The parent path is expected to reference a directory.
  61. Path(const Path& parent, const char* fileName);
  62. /// Creates a path from a parent path and a filename.
  63. /// The parent path is expected to reference a directory.
  64. Path(const Path& parent, const Path& relative);
  65. /// Creates a path from a parent path and a relative path.
  66. /// The parent path is expected to reference a directory.
  67. /// The relative path is appended to the parent path.
  68. ~Path();
  69. /// Destroys the Path.
  70. Path& operator = (const Path& path);
  71. /// Assignment operator.
  72. Path& operator = (const std::string& path);
  73. /// Assigns a string containing a path in native format.
  74. Path& operator = (const char* path);
  75. /// Assigns a string containing a path in native format.
  76. void swap(Path& path);
  77. /// Swaps the path with another one.
  78. Path& assign(const std::string& path);
  79. /// Assigns a string containing a path in native format.
  80. Path& assign(const std::string& path, Style style);
  81. /// Assigns a string containing a path.
  82. Path& assign(const Path& path);
  83. /// Assigns the given path.
  84. Path& assign(const char* path);
  85. /// Assigns a string containing a path.
  86. std::string toString() const;
  87. /// Returns a string containing the path in native format.
  88. std::string toString(Style style) const;
  89. /// Returns a string containing the path in the given format.
  90. Path& parse(const std::string& path);
  91. /// Same as assign().
  92. Path& parse(const std::string& path, Style style);
  93. /// Assigns a string containing a path.
  94. bool tryParse(const std::string& path);
  95. /// Tries to interpret the given string as a path
  96. /// in native format.
  97. /// If the path is syntactically valid, assigns the
  98. /// path and returns true. Otherwise leaves the
  99. /// object unchanged and returns false.
  100. bool tryParse(const std::string& path, Style style);
  101. /// Tries to interpret the given string as a path,
  102. /// according to the given style.
  103. /// If the path is syntactically valid, assigns the
  104. /// path and returns true. Otherwise leaves the
  105. /// object unchanged and returns false.
  106. Path& parseDirectory(const std::string& path);
  107. /// The resulting path always refers to a directory and
  108. /// the filename part is empty.
  109. Path& parseDirectory(const std::string& path, Style style);
  110. /// The resulting path always refers to a directory and
  111. /// the filename part is empty.
  112. Path& makeDirectory();
  113. /// If the path contains a filename, the filename is appended
  114. /// to the directory list and cleared. Thus the resulting path
  115. /// always refers to a directory.
  116. Path& makeFile();
  117. /// If the path contains no filename, the last directory
  118. /// becomes the filename.
  119. Path& makeParent();
  120. /// Makes the path refer to its parent.
  121. Path& makeAbsolute();
  122. /// Makes the path absolute if it is relative.
  123. /// The current working directory is taken as base directory.
  124. Path& makeAbsolute(const Path& base);
  125. /// Makes the path absolute if it is relative.
  126. /// The given path is taken as base.
  127. Path& append(const Path& path);
  128. /// Appends the given path.
  129. Path& resolve(const Path& path);
  130. /// Resolves the given path agains the current one.
  131. ///
  132. /// If the given path is absolute, it replaces the current one.
  133. /// Otherwise, the relative path is appended to the current path.
  134. bool isAbsolute() const;
  135. /// Returns true iff the path is absolute.
  136. bool isRelative() const;
  137. /// Returns true iff the path is relative.
  138. bool isDirectory() const;
  139. /// Returns true iff the path references a directory
  140. /// (the filename part is empty).
  141. bool isFile() const;
  142. /// Returns true iff the path references a file
  143. /// (the filename part is not empty).
  144. Path& setNode(const std::string& node);
  145. /// Sets the node name.
  146. /// Setting a non-empty node automatically makes
  147. /// the path an absolute one.
  148. const std::string& getNode() const;
  149. /// Returns the node name.
  150. Path& setDevice(const std::string& device);
  151. /// Sets the device name.
  152. /// Setting a non-empty device automatically makes
  153. /// the path an absolute one.
  154. const std::string& getDevice() const;
  155. /// Returns the device name.
  156. int depth() const;
  157. /// Returns the number of directories in the directory list.
  158. const std::string& directory(int n) const;
  159. /// Returns the n'th directory in the directory list.
  160. /// If n == depth(), returns the filename.
  161. const std::string& operator [] (int n) const;
  162. /// Returns the n'th directory in the directory list.
  163. /// If n == depth(), returns the filename.
  164. Path& pushDirectory(const std::string& dir);
  165. /// Adds a directory to the directory list.
  166. Path& popDirectory();
  167. /// Removes the last directory from the directory list.
  168. Path& popFrontDirectory();
  169. /// Removes the first directory from the directory list.
  170. Path& setFileName(const std::string& name);
  171. /// Sets the filename.
  172. const std::string& getFileName() const;
  173. /// Returns the filename.
  174. Path& setBaseName(const std::string& name);
  175. /// Sets the basename part of the filename and
  176. /// does not change the extension.
  177. std::string getBaseName() const;
  178. /// Returns the basename (the filename sans
  179. /// extension) of the path.
  180. Path& setExtension(const std::string& extension);
  181. /// Sets the filename extension.
  182. std::string getExtension() const;
  183. /// Returns the filename extension.
  184. const std::string& version() const;
  185. /// Returns the file version. VMS only.
  186. Path& clear();
  187. /// Clears all components.
  188. Path parent() const;
  189. /// Returns a path referring to the path's
  190. /// directory.
  191. Path absolute() const;
  192. /// Returns an absolute variant of the path,
  193. /// taking the current working directory as base.
  194. Path absolute(const Path& base) const;
  195. /// Returns an absolute variant of the path,
  196. /// taking the given path as base.
  197. static Path forDirectory(const std::string& path);
  198. /// Creates a path referring to a directory.
  199. static Path forDirectory(const std::string& path, Style style);
  200. /// Creates a path referring to a directory.
  201. static char separator();
  202. /// Returns the platform's path name separator, which separates
  203. /// the components (names) in a path.
  204. ///
  205. /// On Unix systems, this is the slash '/'. On Windows systems,
  206. /// this is the backslash '\'. On OpenVMS systems, this is the
  207. /// period '.'.
  208. static char pathSeparator();
  209. /// Returns the platform's path separator, which separates
  210. /// single paths in a list of paths.
  211. ///
  212. /// On Unix systems, this is the colon ':'. On Windows systems,
  213. /// this is the semicolon ';'. On OpenVMS systems, this is the
  214. /// comma ','.
  215. static std::string current();
  216. /// Returns the current working directory.
  217. static std::string home();
  218. /// Returns the user's home directory.
  219. static std::string temp();
  220. /// Returns the temporary directory.
  221. static std::string null();
  222. /// Returns the name of the null device.
  223. static std::string expand(const std::string& path);
  224. /// Expands all environment variables contained in the path.
  225. ///
  226. /// On Unix, a tilde as first character in the path is
  227. /// replaced with the path to user's home directory.
  228. static void listRoots(std::vector<std::string>& roots);
  229. /// Fills the vector with all filesystem roots available on the
  230. /// system. On Unix, there is exactly one root, "/".
  231. /// On Windows, the roots are the drive letters.
  232. /// On OpenVMS, the roots are the mounted disks.
  233. static bool find(StringVec::const_iterator it, StringVec::const_iterator end, const std::string& name, Path& path);
  234. /// Searches the file with the given name in the locations (paths) specified
  235. /// by it and end. A relative path may be given in name.
  236. ///
  237. /// If the file is found in one of the locations, the complete
  238. /// path of the file is stored in the path given as argument and true is returned.
  239. /// Otherwise false is returned and the path argument remains unchanged.
  240. static bool find(const std::string& pathList, const std::string& name, Path& path);
  241. /// Searches the file with the given name in the locations (paths) specified
  242. /// in pathList. The paths in pathList must be delimited by the platform's
  243. /// path separator (see pathSeparator()). A relative path may be given in name.
  244. ///
  245. /// If the file is found in one of the locations, the complete
  246. /// path of the file is stored in the path given as argument and true is returned.
  247. /// Otherwise false is returned and the path argument remains unchanged.
  248. static std::string transcode(const std::string& path);
  249. /// On Windows, if POCO has been compiled with Windows UTF-8 support
  250. /// (POCO_WIN32_UTF8), this function converts a string (usually containing a path)
  251. /// encoded in UTF-8 into a string encoded in the current Windows code page.
  252. ///
  253. /// This function should be used for every string passed as a file name to
  254. /// a string stream or fopen().
  255. ///
  256. /// On all other platforms, or if POCO has not been compiled with Windows UTF-8
  257. /// support, this function returns the string unchanged.
  258. protected:
  259. void parseUnix(const std::string& path);
  260. void parseWindows(const std::string& path);
  261. void parseVMS(const std::string& path);
  262. void parseGuess(const std::string& path);
  263. std::string buildUnix() const;
  264. std::string buildWindows() const;
  265. std::string buildVMS() const;
  266. private:
  267. std::string _node;
  268. std::string _device;
  269. std::string _name;
  270. std::string _version;
  271. StringVec _dirs;
  272. bool _absolute;
  273. };
  274. //
  275. // inlines
  276. //
  277. inline bool Path::isAbsolute() const
  278. {
  279. return _absolute;
  280. }
  281. inline bool Path::isRelative() const
  282. {
  283. return !_absolute;
  284. }
  285. inline bool Path::isDirectory() const
  286. {
  287. return _name.empty();
  288. }
  289. inline bool Path::isFile() const
  290. {
  291. return !_name.empty();
  292. }
  293. inline Path& Path::parse(const std::string& path)
  294. {
  295. return assign(path);
  296. }
  297. inline Path& Path::parse(const std::string& path, Style style)
  298. {
  299. return assign(path, style);
  300. }
  301. inline const std::string& Path::getNode() const
  302. {
  303. return _node;
  304. }
  305. inline const std::string& Path::getDevice() const
  306. {
  307. return _device;
  308. }
  309. inline const std::string& Path::getFileName() const
  310. {
  311. return _name;
  312. }
  313. inline int Path::depth() const
  314. {
  315. return int(_dirs.size());
  316. }
  317. inline const std::string& Path::version() const
  318. {
  319. return _version;
  320. }
  321. inline Path Path::forDirectory(const std::string& path)
  322. {
  323. Path p;
  324. return p.parseDirectory(path);
  325. }
  326. inline Path Path::forDirectory(const std::string& path, Style style)
  327. {
  328. Path p;
  329. return p.parseDirectory(path, style);
  330. }
  331. inline char Path::separator()
  332. {
  333. #if defined(POCO_OS_FAMILY_VMS)
  334. return '.';
  335. #elif defined(POCO_OS_FAMILY_WINDOWS)
  336. return '\\';
  337. #else
  338. return '/';
  339. #endif
  340. }
  341. inline char Path::pathSeparator()
  342. {
  343. #if defined(POCO_OS_FAMILY_VMS)
  344. return ',';
  345. #elif defined(POCO_OS_FAMILY_WINDOWS)
  346. return ';';
  347. #else
  348. return ':';
  349. #endif
  350. }
  351. inline void swap(Path& p1, Path& p2)
  352. {
  353. p1.swap(p2);
  354. }
  355. } // namespace Poco
  356. #endif // Foundation_Path_INCLUDED