Doxygen
Loading...
Searching...
No Matches
dir.cpp
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2021 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15
16#define NOMINMAX
17#define WIN32_LEAN_AND_MEAN
18
19// own header
20#include "dir.h"
21
22// standard includes
23#include <utility>
24
25// other includes
26#include "fileinfo.h"
27#include "filesystem.hpp"
28
29namespace fs = ghc::filesystem;
30
31
32//-----------------------------------------------------------------------------------------------
33
35{
36 fs::directory_entry entry;
37};
38
39DirEntry::DirEntry() : p(std::make_unique<Private>())
40{
41}
42
43DirEntry::DirEntry(const DirEntry &de) : p(std::make_unique<Private>())
44{
45 p->entry = de.p->entry;
46}
47
49{
50 if (this!=&de)
51 {
52 p = std::make_unique<Private>();
53 p->entry = de.p->entry;
54 }
55 return *this;
56}
57
58DirEntry::DirEntry(DirEntry &&de) : p(std::make_unique<Private>())
59{
60 p = std::move(de.p);
61}
62
64{
65 p = std::move(de.p);
66 return *this;
67}
68
69DirEntry::~DirEntry() = default;
70
72{
73 return p->entry.is_directory();
74}
75
77{
78 return p->entry.is_regular_file();
79}
80
82{
83 return p->entry.is_symlink();
84}
85
86std::string DirEntry::path() const
87{
88 return p->entry.path().string();
89}
90
91//-----------------------------------------------------------------------------------------------
92
94{
95 Private() : it() {}
96 Private(const std::string &path) : it(path,ec) {}
97 fs::directory_iterator it;
98 std::error_code ec;
100};
101
103{
104}
105
106DirIterator::DirIterator(const std::string &path) : p(std::make_unique<Private>(path))
107{
108}
109
110DirIterator::DirIterator(const DirIterator &it) : p(std::make_unique<Private>())
111{
112 p->it = it.p->it;
113 p->ec = it.p->ec;
114 p->current = it.p->current;
115}
116
118{
119 if (&it!=this)
120 {
121 p->it = it.p->it;
122 p->ec = it.p->ec;
123 p->current = it.p->current;
124 }
125 return *this;
126}
127
129{
130 std::exchange(p->it,it.p->it);
131 std::exchange(p->ec,it.p->ec);
132 std::exchange(p->current,it.p->current);
133}
134
136{
137 std::exchange(p->it,it.p->it);
138 std::exchange(p->ec,it.p->ec);
139 std::exchange(p->current,it.p->current);
140 return *this;
141}
142
146
148{
149 DirIterator result;
150 result.p->it = ++p->it;
151 return result;
152}
153
155{
156 p->current.p->entry = *p->it;
157 return p->current;
158}
159
161{
162 p->current.p->entry = *p->it;
163 return &p->current;
164}
165
166bool operator==(const DirIterator &it1,const DirIterator &it2)
167{
168 return it1.p->it == it2.p->it;
169}
170
171bool operator!=(const DirIterator &it1,const DirIterator &it2)
172{
173 return it1.p->it!=it2.p->it;
174}
175
177{
178 return it;
179}
180
181DirIterator end(const DirIterator &) noexcept
182{
183 return DirIterator();
184}
185
186
187//-----------------------------------------------------------------------------------------------
188
189
191{
192 fs::path path;
193};
194
195Dir::Dir() : p(std::make_unique<Private>())
196{
197 std::error_code ec;
198 p->path = fs::current_path(ec);
199}
200
201Dir::Dir(const Dir &d) : p(std::make_unique<Private>())
202{
203 p->path = d.p->path;
204}
205
207{
208 if (&d!=this)
209 {
210 p->path = d.p->path;
211 }
212 return *this;
213}
214
215Dir::Dir(Dir &&d) : p(std::make_unique<Private>())
216{
217 std::exchange(p->path,d.p->path);
218}
219
221{
222 std::exchange(p->path,d.p->path);
223 return *this;
224}
225
226Dir::Dir(const std::string &path) : p(std::make_unique<Private>())
227{
228 setPath(path);
229}
230
232{
233}
234
235void Dir::setPath(const std::string &path)
236{
237 p->path = path;
238}
239
240std::string Dir::path() const
241{
242 return p->path.string();
243}
244
246{
247 return DirIterator(p->path.string());
248}
249
250static void correctPath(std::string &s)
251{
252 std::replace( s.begin(), s.end(), '\\', '/' );
253}
254
255bool Dir::exists(const std::string &path,bool acceptsAbsPath) const
256{
257 std::string result = filePath(path,acceptsAbsPath);
258 std::error_code ec;
259 bool exist = fs::exists(fs::path(result),ec);
260 return !ec && exist;
261}
262
263bool Dir::exists() const
264{
265 FileInfo fi(p->path.string());
266 return fi.exists() && fi.isDir();
267}
268
269bool Dir::empty(const std::string &subdir) const
270{
271 fs::path pth = path();
272 pth /= subdir;
273 return fs::is_empty(pth);
274}
275
276bool Dir::isRelative() const
277{
278 return isRelativePath(p->path.string());
279}
280
281bool Dir::isRelativePath(const std::string &path)
282{
283 return fs::path(path).is_relative();
284}
285
286std::string Dir::filePath(const std::string &path,bool acceptsAbsPath) const
287{
288 std::string result;
289 if (acceptsAbsPath && !isRelativePath(path))
290 {
291 result = path;
292 }
293 else
294 {
295 result = (p->path / path).string();
296 }
297 correctPath(result);
298 return result;
299}
300
301bool Dir::mkdir(const std::string &path,bool acceptsAbsPath) const
302{
303 std::error_code ec;
304 std::string result = filePath(path,acceptsAbsPath);
305 if (exists(path,acceptsAbsPath))
306 {
307 return true;
308 }
309 else
310 {
311 return fs::create_directory(result,ec);
312 }
313}
314
315bool Dir::rmdir(const std::string &path,bool acceptsAbsPath) const
316{
317 return remove(path,acceptsAbsPath);
318}
319
320bool Dir::remove(const std::string &path,bool acceptsAbsPath) const
321{
322 std::error_code ec;
323 std::string result = filePath(path,acceptsAbsPath);
324 return fs::remove(result,ec);
325}
326
327bool Dir::rename(const std::string &orgName,const std::string &newName,bool acceptsAbsPath) const
328{
329 std::error_code ec;
330 std::string fn1 = filePath(orgName,acceptsAbsPath);
331 std::string fn2 = filePath(newName,acceptsAbsPath);
332 fs::rename(fn1,fn2,ec);
333 return !ec;
334}
335
336bool Dir::copy(const std::string &srcName,const std::string &dstName,bool acceptsAbsPath) const
337{
338 const auto &copyOptions = fs::copy_options::overwrite_existing;
339 std::error_code ec, ec_perm;
340 std::string sn = filePath(srcName,acceptsAbsPath);
341 std::string dn = filePath(dstName,acceptsAbsPath);
342 fs::copy(sn,dn,copyOptions,ec);
343 // make sure the destination is writable for the owner (see issue #11600)
344 fs::permissions(dn, fs::perms::owner_write, fs::perm_options::add, ec_perm);
345 return !ec;
346}
347
349{
350 std::error_code ec;
351 std::string result = fs::current_path(ec).string();
352 correctPath(result);
353 return result;
354}
355
356bool Dir::setCurrent(const std::string &path)
357{
358 std::error_code ec;
359 fs::current_path(path,ec);
360 return !ec;
361}
362
363std::string Dir::cleanDirPath(const std::string &path)
364{
365 std::string result = fs::path(path).lexically_normal().string();
366 correctPath(result);
367 return result;
368}
369
370std::string Dir::absPath() const
371{
372 std::error_code ec;
373 std::string result = fs::absolute(p->path,ec).string();
374 correctPath(result);
375 return result;
376}
377
Definition dir.h:23
~DirEntry()
DirEntry(const DirEntry &)
Definition dir.cpp:43
bool is_directory() const
Definition dir.cpp:71
bool is_regular_file() const
Definition dir.cpp:76
std::string path() const
Definition dir.cpp:86
std::unique_ptr< Private > p
Definition dir.h:38
DirEntry & operator=(const DirEntry &)
Definition dir.cpp:48
bool is_symlink() const
Definition dir.cpp:81
DirEntry()
Definition dir.cpp:39
static std::string currentDirPath()
Definition dir.cpp:348
Dir()
Definition dir.cpp:195
Dir & operator=(const Dir &d)
Definition dir.cpp:206
std::string absPath() const
Definition dir.cpp:370
bool mkdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:301
void setPath(const std::string &path)
Definition dir.cpp:235
static bool isRelativePath(const std::string &path)
Definition dir.cpp:281
~Dir()
Definition dir.cpp:231
bool isRelative() const
Definition dir.cpp:276
bool remove(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:320
bool empty(const std::string &subdir) const
Definition dir.cpp:269
bool copy(const std::string &src, const std::string &dest, bool acceptsAbsPath=true) const
Definition dir.cpp:336
std::string filePath(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:286
DirIterator iterator() const
Definition dir.cpp:245
bool rmdir(const std::string &path, bool acceptsAbsPath=true) const
Definition dir.cpp:315
bool rename(const std::string &orgName, const std::string &newName, bool acceptsAbsPath=true) const
Definition dir.cpp:327
static std::string cleanDirPath(const std::string &path)
Definition dir.cpp:363
static bool setCurrent(const std::string &path)
Definition dir.cpp:356
std::string path() const
Definition dir.cpp:240
bool exists() const
Definition dir.cpp:263
std::unique_ptr< Private > p
Definition dir.h:108
DirIterator()
Definition dir.cpp:102
DirEntry value_type
Definition dir.h:44
DirIterator(const DirIterator &it)
Definition dir.cpp:110
DirIterator operator++()
Definition dir.cpp:147
~DirIterator()
Definition dir.cpp:143
const value_type & operator*() const
Definition dir.cpp:154
const value_type * operator->() const
Definition dir.cpp:160
std::unique_ptr< Private > p
Definition dir.h:68
DirIterator & operator=(const DirIterator &it)
Definition dir.cpp:117
Minimal replacement for QFileInfo.
Definition fileinfo.h:26
bool exists() const
Definition fileinfo.cpp:34
bool isDir() const
Definition fileinfo.cpp:74
static void correctPath(std::string &s)
Definition dir.cpp:250
bool operator==(const DirIterator &it1, const DirIterator &it2)
Definition dir.cpp:166
DirIterator begin(DirIterator it) noexcept
Definition dir.cpp:176
bool operator!=(const DirIterator &it1, const DirIterator &it2)
Definition dir.cpp:171
DirIterator end(const DirIterator &) noexcept
Definition dir.cpp:181
Definition dstring.h:913
fs::path path
Definition dir.cpp:192
Definition dir.cpp:35
fs::directory_entry entry
Definition dir.cpp:36
Private(const std::string &path)
Definition dir.cpp:96
std::error_code ec
Definition dir.cpp:98
fs::directory_iterator it
Definition dir.cpp:97
DirEntry current
Definition dir.cpp:99