TLA Line data Source code
1 : // Copyright (c) 2014-2022 Thomas Fussell
2 : // Copyright (c) 2024-2025 xlnt-community
3 : //
4 : // Permission is hereby granted, free of charge, to any person obtaining a copy
5 : // of this software and associated documentation files (the "Software"), to deal
6 : // in the Software without restriction, including without limitation the rights
7 : // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 : // copies of the Software, and to permit persons to whom the Software is
9 : // furnished to do so, subject to the following conditions:
10 : //
11 : // The above copyright notice and this permission notice shall be included in
12 : // all copies or substantial portions of the Software.
13 : //
14 : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 : // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 : // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 : // THE SOFTWARE
21 : //
22 : // @license: http://www.opensource.org/licenses/mit-license.php
23 : // @author: see AUTHORS file
24 :
25 : #pragma once
26 :
27 : #include <string>
28 : #include <utility>
29 : #include <vector>
30 :
31 : #include <xlnt/xlnt_config.hpp>
32 : #include <xlnt/internal/features.hpp>
33 :
34 : #if XLNT_HAS_INCLUDE(<string_view>) && XLNT_HAS_FEATURE(U8_STRING_VIEW)
35 : #include <string_view>
36 : #endif
37 :
38 : namespace xlnt {
39 :
40 : /// <summary>
41 : /// Encapsulates a path that points to location in a filesystem.
42 : /// </summary>
43 : class XLNT_API path
44 : {
45 : public:
46 : /// <summary>
47 : /// The system-specific path separator character (e.g. '/' or '\').
48 : /// </summary>
49 : static char system_separator();
50 :
51 : /// <summary>
52 : /// Construct an empty path.
53 : /// </summary>
54 : path();
55 :
56 : /// <summary>
57 : /// Counstruct a path from a string representing the path.
58 : /// </summary>
59 : explicit path(const std::string &path_string);
60 :
61 : /// <summary>
62 : /// Construct a path from a string with an explicit directory seprator.
63 : /// </summary>
64 : path(const std::string &path_string, char sep);
65 :
66 : #if XLNT_HAS_FEATURE(U8_STRING_VIEW)
67 : /// <summary>
68 : /// Counstruct a path from a string representing the path.
69 : /// </summary>
70 : explicit path(std::u8string_view path_string);
71 :
72 : /// <summary>
73 : /// Construct a path from a string with an explicit directory seprator.
74 : /// </summary>
75 : path(std::u8string_view path_string, char sep);
76 : #endif
77 :
78 : // general attributes
79 :
80 : /// <summary>
81 : /// Return true iff this path doesn't begin with / (or a drive letter on Windows).
82 : /// </summary>
83 : bool is_relative() const;
84 :
85 : /// <summary>
86 : /// Return true iff path::is_relative() is false.
87 : /// </summary>
88 : bool is_absolute() const;
89 :
90 : /// <summary>
91 : /// Return true iff this path is the root directory.
92 : /// </summary>
93 : bool is_root() const;
94 :
95 : /// <summary>
96 : /// Return a new path that points to the directory containing the current path
97 : /// Return the path unchanged if this path is the absolute or relative root.
98 : /// </summary>
99 : path parent() const;
100 :
101 : /// <summary>
102 : /// Return the last component of this path.
103 : /// </summary>
104 : std::string filename() const;
105 :
106 : /// <summary>
107 : /// Return the part of the path following the last dot in the filename.
108 : /// </summary>
109 : std::string extension() const;
110 :
111 : /// <summary>
112 : /// Return a pair of strings resulting from splitting the filename on the last dot.
113 : /// </summary>
114 : std::pair<std::string, std::string> split_extension() const;
115 :
116 : // conversion
117 :
118 : /// <summary>
119 : /// Create a string representing this path separated by the provided
120 : /// separator or the system-default separator if not provided.
121 : /// </summary>
122 : std::vector<std::string> split() const;
123 :
124 : /// <summary>
125 : /// Create a string representing this path separated by the provided
126 : /// separator or the system-default separator if not provided.
127 : /// </summary>
128 : const std::string &string() const;
129 :
130 : #ifdef _MSC_VER
131 : /// <summary>
132 : /// Create a wstring representing this path separated by the provided
133 : /// separator or the system-default separator if not provided.
134 : /// </summary>
135 : std::wstring wstring() const;
136 : #endif
137 :
138 : /// <summary>
139 : /// If this path is relative, append each component of this path
140 : /// to base_path and return the resulting absolute path. Otherwise,
141 : /// the the current path will be returned and base_path will be ignored.
142 : /// </summary>
143 : path resolve(const path &base_path) const;
144 :
145 : /// <summary>
146 : /// The inverse of path::resolve. Creates a relative path from an absolute
147 : /// path by removing the common root between base_path and this path.
148 : /// If the current path is already relative, return it unchanged.
149 : /// </summary>
150 : path relative_to(const path &base_path) const;
151 :
152 : // filesystem attributes
153 :
154 : /// <summary>
155 : /// Return true iff the file or directory pointed to by this path
156 : /// exists on the filesystem.
157 : /// </summary>
158 : bool exists() const;
159 :
160 : /// <summary>
161 : /// Return true if the file or directory pointed to by this path
162 : /// is a directory.
163 : /// </summary>
164 : bool is_directory() const;
165 :
166 : /// <summary>
167 : /// Return true if the file or directory pointed to by this path
168 : /// is a regular file.
169 : /// </summary>
170 : bool is_file() const;
171 :
172 : // filesystem
173 :
174 : /// <summary>
175 : /// Open the file pointed to by this path and return a string containing
176 : /// the files contents.
177 : /// </summary>
178 : std::string read_contents() const;
179 :
180 : // mutators
181 :
182 : /// <summary>
183 : /// Append the provided part to this path and return the result.
184 : /// </summary>
185 : path append(const std::string &to_append) const;
186 :
187 : #if XLNT_HAS_FEATURE(U8_STRING_VIEW)
188 : /// <summary>
189 : /// Append the provided part to this path and return the result.
190 : /// </summary>
191 : path append(std::u8string_view to_append) const;
192 : #endif
193 :
194 : /// <summary>
195 : /// Append the provided part to this path and return the result.
196 : /// </summary>
197 : path append(const path &to_append) const;
198 :
199 : /// <summary>
200 : /// Returns true if left path is equal to right path.
201 : /// </summary>
202 : bool operator==(const path &other) const;
203 :
204 : /// <summary>
205 : /// Returns true if left path is equal to right path.
206 : /// </summary>
207 : bool operator!=(const path &other) const;
208 :
209 : private:
210 : /// <summary>
211 : /// Returns the character that separates directories in the path.
212 : /// On POSIX style filesystems, this is always '/'.
213 : /// On Windows, this is the character that separates the drive letter from
214 : /// the rest of the path for absolute paths with a drive letter, '/' if the path
215 : /// is absolute and starts with '/', and '/' or '\' for relative paths
216 : /// depending on which splits the path into more directory components.
217 : /// </summary>
218 : char guess_separator() const;
219 :
220 : /// <summary>
221 : /// A string that represents this path.
222 : /// </summary>
223 : std::string internal_;
224 : };
225 :
226 : } // namespace xlnt
227 :
228 : namespace std {
229 :
230 : /// <summary>
231 : /// Template specialization to allow xlnt:path to be used as a key in a std container.
232 : /// </summary>
233 : template <>
234 : struct hash<xlnt::path>
235 : {
236 : /// <summary>
237 : /// Returns a hashed represenation of the given path.
238 : /// </summary>
239 CBC 27156 : size_t operator()(const xlnt::path &p) const
240 : {
241 : static hash<string> hasher;
242 27156 : return hasher(p.string());
243 : }
244 : };
245 :
246 : } // namespace std
|