Evo C++ Library v0.5.1
dir.h
Go to the documentation of this file.
1 // Evo C++ Library
2 /* Copyright 2019 Justin Crowell
3 Distributed under the BSD 2-Clause License -- see included file LICENSE.txt for details.
4 */
6 
7 #pragma once
8 #ifndef INCL_evo_dir_h
9 #define INCL_evo_dir_h
10 
11 #include "impl/sysio_dir.h"
12 #include "filepath.h"
13 
14 #if defined(_WIN32)
15  #include "ustring.h"
16 #endif
17 
18 // Namespace: evo
19 namespace evo {
22 
24 
33 inline String& get_cwd(String& outpath) {
34 #if defined(_WIN32)
35  outpath.set();
36  DWORD sz = ::GetCurrentDirectory(0, NULL);
37  if (sz > 0 && (sz = ::GetCurrentDirectory(sz, outpath.advBuffer(sz))) > 0)
38  outpath.advSize(sz);
39  else
40  outpath = "C:\\"; // unknown so guess C drive root
41 #else
42  const size_t DEFAULT_BUF_SIZE = 512;
43  for (size_t sz = DEFAULT_BUF_SIZE;; sz *= 2) {
44  outpath.set().reserve(sz);
45  const char* p = ::getcwd(outpath.advBuffer(sz), sz);
46  if (p != NULL) {
47  assert( p == outpath.data() );
48  outpath.advSize(strlen(p));
49  break;
50  } else if (errno != ERANGE) {
51  outpath = "/"; // unknown so use root
52  break;
53  }
54  }
55 #endif
56  return outpath;
57 }
58 
69 inline Error set_cwd(const char* path, bool excep=EVO_EXCEPTIONS) {
70  Error err = ENone;
71 #if defined(_WIN32)
72  if (::SetCurrentDirectory(path) != 0)
73  return ENone;
74  err = EFail;
75 #else
76  if (::chdir(path) == 0)
77  return ENone;
78  const int code = errno;
79  switch (code) {
80  case EACCES: err = EAccess; break;
81  case EFAULT: err = EPtr; break;
82  case ELOOP: // fallthrough
83  case ENAMETOOLONG: err = ESize; break;
84  case ENOENT: err = ENotFound; break;
85  case ENOTDIR: err = ENotDir; break;
86  default: err = EFail; break;
87  }
88 #endif
89  EVO_THROW_ERR_CHECK(evo::Exception, "Error setting working directory", err, excep);
90  return err;
91 }
92 
106 inline String& get_abspath(String& outpath, SubString& path) {
107  if (path.null()) {
108  return outpath.set();
109  } else if (FilePath::abs(path, false)) {
110  outpath = path;
111  } else {
112  get_cwd(outpath);
113  FilePath::join(outpath, path);
114  }
115  return FilePath::normalize(outpath, outpath);
116 }
117 
119 
123 
125 
149 class Directory : public SafeBool<Directory> {
150 public:
154  Directory(bool excep=EVO_EXCEPTIONS) : excep_(excep) {
155  }
156 
163  Directory(const char* path, bool excep=EVO_EXCEPTIONS) : excep_(excep) {
164  open(path);
165  }
166 
173  bool operator!() const {
174  return (error_ != ENone);
175  }
176 
180  bool excep() const {
181  return excep_;
182  }
183 
187  void excep(bool val) {
188  excep_ = val;
189  }
190 
194  Error error() const {
195  return error_;
196  }
197 
201  bool isopen() const {
202  return (dir_.handle != NULL);
203  }
204 
212  bool open(const char* path) {
213  error_ = dir_.open(path);
214  EVO_THROW_ERR_CHECK(evo::ExceptionDirOpen, "Directory::open() failed", error_, (excep_ && error_ != ENone));
215  return error_ == ENone;
216  }
217 
219  void close() {
220  dir_.close();
221  error_ = ENone;
222  }
223 
227  void seek() {
228  dir_.seek();
229  }
230 
238  bool read(SubString& entry) {
239  return dir_.read(entry);
240  }
241 
242 #if !defined(_WIN32) || defined(DOXYGEN)
243 
246  bool chdir() {
247  return dir_.chdir();
248  }
249 #endif
250 
251 private:
252  // Disable copying
253  Directory(const Directory&) EVO_ONCPP11(= delete);
254  Directory& operator=(const Directory&) EVO_ONCPP11(= delete);
255 
256  SysDir dir_;
257  Error error_;
258  bool excep_;
259 };
260 
262 
263 }
264 #endif
bool chdir()
Change current working directory to currently open directory (Linux/Unix only).
Definition: dir.h:246
Error error() const
Get error code from last operation.
Definition: dir.h:194
Directory(const char *path, bool excep=1)
Constructor to open directory.
Definition: dir.h:163
Permission denied.
Definition: sys.h:1135
Invalid pointer used.
Definition: sys.h:1133
void advSize(Size size)
Advanced: Set new size after writing directly to buffer.
Definition: list.h:2754
static String & join(String &basepath, const SubString &addpath)
Join two paths together.
Definition: filepath.h:739
bool operator!() const
Negation operator checks whether an error was set by a previous operation.
Definition: dir.h:173
bool read(SubString &entry)
Read next directory entry.
Definition: dir.h:238
Directory reader.
Definition: dir.h:149
#define EVO_ONCPP11(EXPR)
Compile EXPR only if C++11 support is detected, otherwise this is a no-op.
Definition: sys.h:259
#define EVO_CREATE_EXCEPTION_IMPL(NAME, BASE)
Create an Evo exception implementation.
Definition: sys.h:1365
#define EVO_THROW_ERR_CHECK(TYPE, MSG, ERROR, COND)
Throw an Evo exception with error code if COND is true.
Definition: sys.h:1513
System directory reader (used internally).
Definition: sysio_dir.h:40
Error set_cwd(const char *path, bool excep=1)
Set current working directory.
Definition: dir.h:69
Resource not found.
Definition: sys.h:1137
Size limit exceeded.
Definition: sys.h:1139
No error.
Definition: sys.h:1115
#define EVO_EXCEPTIONS
Whether to throw exceptions on error by default.
Definition: evo_config.h:35
Error
General Evo error code stored in exceptions, or used directly when exceptions are disabled...
Definition: sys.h:1113
String & get_cwd(String &outpath)
Store current working directory in string.
Definition: dir.h:33
Evo system I/O implementation for directories.
const char * data() const
Get string pointer (const).
Definition: string.h:1533
bool excep() const
Get whether exceptions are enabled.
Definition: dir.h:180
static bool abs(const SubString &path, bool strict=true)
Check whether path is an absolute path.
Definition: filepath.h:113
String container.
Definition: string.h:674
void excep(bool val)
Set whether exceptions are enabled.
Definition: dir.h:187
Safe bool base class.
Definition: type.h:73
Directory(bool excep=1)
Constructor.
Definition: dir.h:154
void close()
Close currently open directory, if any.
Definition: dir.h:219
Evo base exception class.
Definition: sys.h:1214
Evo UnicodeString container.
Evo C++ Library namespace.
Definition: alg.h:11
Directory open exception for errors opening a directory for reading entries, see Exception.
Definition: dir.h:121
static String & normalize(String &outpath, const SubString &path)
Normalize path and remove redundant components.
Definition: filepath.h:267
Operation failed.
Definition: sys.h:1124
T * advBuffer(Size size)
Advanced: Resize and get buffer pointer (modifier).
Definition: list.h:2728
bool null() const
Get whether null.
bool open(const char *path)
Open directory for reading entries.
Definition: dir.h:212
String & set()
Set as null and empty.
Definition: string.h:995
Path component is not a directory.
Definition: sys.h:1138
String & get_abspath(String &outpath, SubString &path)
Get absolute path for given input path.
Definition: dir.h:106
Reference and access existing string data.
Definition: substring.h:229
void seek()
Seek to beginning of directory.
Definition: dir.h:227
Evo file path operations.
bool isopen() const
Get whether directory is open.
Definition: dir.h:201
String & reserve(Size size, bool prefer_realloc=false)
Reserve capacity for additional items (modifier).
Definition: string.h:5027