Coverage Report

Created: 2025-09-05 06:24

/src/poco/Foundation/include/Poco/Path.h
Line
Count
Source (jump to first uncovered line)
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
  using StringVec = std::vector<std::string>;
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) noexcept;
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 addDirectorySeparator(const std::string& path);
294
    /// Adds a separator to the end of a string to create the correct syntax for a path.
295
    /// If the source path already has a trailing separator, no separator will be added.
296
    ///
297
    /// On Unix systems, this is the slash '/'. On Windows systems,
298
    /// this is the backslash '\'. On OpenVMS systems, this is the
299
    /// period '.'.
300
301
  static std::string addDirectorySeparator(const std::string& path, Style style);
302
    /// Adds a separator to the end of a string to create the correct syntax for a path.
303
    /// If the source path already has a trailing separator, no separator will be added.
304
    ///
305
    /// On Unix systems, this is the slash '/'. On Windows systems,
306
    /// this is the backslash '\'. On OpenVMS systems, this is the
307
    /// period '.'.
308
309
  static std::string self();
310
    /// Return path to the executable file, empty string if failed.
311
    /// The path is absolute one.
312
313
  static std::string current();
314
    /// Returns the current working directory.
315
316
  static std::string home();
317
    /// Returns the user's home directory.
318
319
  static std::string configHome();
320
    /// Returns the user's config directory.
321
    ///
322
    /// On Unix systems, this is the '~/.config/'. On Windows systems,
323
    /// this is '%APPDATA%' (typically C:\Users\user\AppData\Roaming).
324
325
  static std::string dataHome();
326
    /// Returns the user's data directory.
327
    ///
328
    /// On Unix systems, this is the '~/.local/share/'. On Windows systems,
329
    /// this is '%LOCALAPPDATA%' (typically C:\Users\user\AppData\Local).
330
331
  static std::string tempHome();
332
    /// Returns the user's temp directory.
333
    ///
334
    /// On Unix systems, this is the '~/.local/temp/'.
335
336
  static std::string cacheHome();
337
    /// Returns the user's cache directory.
338
    ///
339
    /// On Unix systems, this is the '~/.cache/'. On Windows systems,
340
    /// this is the same as tempHome().
341
342
  static std::string temp();
343
    /// Returns the temporary directory.
344
345
  static std::string config();
346
    /// Returns the systemwide config directory.
347
    ///
348
    /// On Unix systems, this is the '/etc/'.
349
350
  static std::string null();
351
    /// Returns the name of the null device.
352
353
  static std::string expand(const std::string& path);
354
    /// Expands all environment variables contained in the path.
355
    ///
356
    /// On Unix, a tilde as first character in the path is
357
    /// replaced with the path to user's home directory.
358
359
  static void listRoots(std::vector<std::string>& roots);
360
    /// Fills the vector with all filesystem roots available on the
361
    /// system. On Unix, there is exactly one root, "/".
362
    /// On Windows, the roots are the drive letters.
363
    /// On OpenVMS, the roots are the mounted disks.
364
365
  static bool find(StringVec::const_iterator it, StringVec::const_iterator end, const std::string& name, Path& path);
366
    /// Searches the file with the given name in the locations (paths) specified
367
    /// by it and end. A relative path may be given in name.
368
    ///
369
    /// If the file is found in one of the locations, the complete
370
    /// path of the file is stored in the path given as argument and true is returned.
371
    /// Otherwise false is returned and the path argument remains unchanged.
372
373
  static bool find(const std::string& pathList, const std::string& name, Path& path);
374
    /// Searches the file with the given name in the locations (paths) specified
375
    /// in pathList. The paths in pathList must be delimited by the platform's
376
    /// path separator (see pathSeparator()). A relative path may be given in name.
377
    ///
378
    /// If the file is found in one of the locations, the complete
379
    /// path of the file is stored in the path given as argument and true is returned.
380
    /// Otherwise false is returned and the path argument remains unchanged.
381
382
  static std::string transcode(const std::string& path);
383
    /// On Windows, this function converts a string (usually containing a path)
384
    /// encoded in UTF-8 into a string encoded in the current Windows code page.
385
    ///
386
    /// This function should be used for every string passed as a file name to
387
    /// a string stream or fopen().
388
    ///
389
    /// On all other platforms, or if POCO has not been compiled with Windows UTF-8
390
    /// support, this function returns the string unchanged.
391
392
protected:
393
  void parseUnix(const std::string& path);
394
  void parseWindows(const std::string& path);
395
  void parseVMS(const std::string& path);
396
  void parseGuess(const std::string& path);
397
  std::string buildUnix() const;
398
  std::string buildWindows() const;
399
  std::string buildVMS() const;
400
401
private:
402
  std::string _node;
403
  std::string _device;
404
  std::string _name;
405
  std::string _version;
406
  StringVec   _dirs;
407
  bool        _absolute;
408
};
409
410
411
//
412
// inlines
413
//
414
inline bool Path::isAbsolute() const
415
2.83k
{
416
2.83k
  return _absolute;
417
2.83k
}
418
419
420
inline bool Path::isRelative() const
421
0
{
422
0
  return !_absolute;
423
0
}
424
425
426
inline bool Path::isDirectory() const
427
0
{
428
0
  return _name.empty();
429
0
}
430
431
432
inline bool Path::isFile() const
433
0
{
434
0
  return !_name.empty();
435
0
}
436
437
438
inline Path& Path::parse(const std::string& path)
439
2.83k
{
440
2.83k
  return assign(path);
441
2.83k
}
442
443
444
inline Path& Path::parse(const std::string& path, Style style)
445
50.4k
{
446
50.4k
  return assign(path, style);
447
50.4k
}
448
449
450
inline const std::string& Path::getNode() const
451
0
{
452
0
  return _node;
453
0
}
454
455
456
inline const std::string& Path::getDevice() const
457
0
{
458
0
  return _device;
459
0
}
460
461
462
inline const std::string& Path::getFileName() const
463
0
{
464
0
  return _name;
465
0
}
466
467
468
inline int Path::depth() const
469
1.05M
{
470
1.05M
  return int(_dirs.size());
471
1.05M
}
472
473
474
inline const std::string& Path::version() const
475
0
{
476
0
  return _version;
477
0
}
478
479
480
inline Path Path::forDirectory(const std::string& path)
481
0
{
482
0
  Path p;
483
0
  return p.parseDirectory(path);
484
0
}
485
486
487
inline Path Path::forDirectory(const std::string& path, Style style)
488
0
{
489
0
  Path p;
490
0
  return p.parseDirectory(path, style);
491
0
}
492
493
494
inline char Path::separator()
495
0
{
496
#if defined(POCO_OS_FAMILY_VMS)
497
  return '.';
498
#elif defined(POCO_OS_FAMILY_WINDOWS)
499
  return '\\';
500
#else
501
0
  return '/';
502
0
#endif
503
0
}
504
505
506
inline char Path::pathSeparator()
507
0
{
508
#if defined(POCO_OS_FAMILY_VMS)
509
  return ',';
510
#elif defined(POCO_OS_FAMILY_WINDOWS)
511
  return ';';
512
#else
513
0
  return ':';
514
0
#endif
515
0
}
516
517
518
inline void swap(Path& p1, Path& p2) noexcept
519
0
{
520
0
  p1.swap(p2);
521
0
}
522
523
524
} // namespace Poco
525
526
527
#endif // Foundation_Path_INCLUDED