Biorbd
Path.cpp
1 #define BIORBD_API_EXPORTS
2 #include "Utils/Path.h"
3 
4 #include <fstream>
5 #include <regex>
6 
7 #include "Utils/String.h"
8 #include "Utils/Error.h"
9 
10 #ifdef _WIN32
11  #include <direct.h>
12  #include <Windows.h>
13  #undef max
14 #else
15  #include <sys/stat.h>
16  #include <unistd.h>
17 #endif
18 
20  m_originalPath(std::make_shared<biorbd::utils::String>()),
21  m_folder(std::make_shared<biorbd::utils::String>()),
22  m_isFolderAbsolute(std::make_shared<bool>()),
23  m_filename(std::make_shared<biorbd::utils::String>()),
24  m_extension(std::make_shared<biorbd::utils::String>())
25 {
26 
27 }
28 
30  const char *path) :
31  m_originalPath(std::make_shared<biorbd::utils::String>(path)),
32  m_folder(std::make_shared<biorbd::utils::String>()),
33  m_isFolderAbsolute(std::make_shared<bool>()),
34  m_filename(std::make_shared<biorbd::utils::String>()),
35  m_extension(std::make_shared<biorbd::utils::String>())
36 {
39 }
40 
42  const biorbd::utils::String &path) :
43  m_originalPath(std::make_shared<biorbd::utils::String>(path)),
44  m_folder(std::make_shared<biorbd::utils::String>()),
45  m_isFolderAbsolute(std::make_shared<bool>()),
46  m_filename(std::make_shared<biorbd::utils::String>()),
47  m_extension(std::make_shared<biorbd::utils::String>())
48 {
51 }
52 
54  const std::basic_string<char> &path) :
55  m_originalPath(std::make_shared<biorbd::utils::String>(path)),
56  m_folder(std::make_shared<biorbd::utils::String>()),
57  m_isFolderAbsolute(std::make_shared<bool>()),
58  m_filename(std::make_shared<biorbd::utils::String>()),
59  m_extension(std::make_shared<biorbd::utils::String>())
60 {
63 }
64 
66 {
68  copy.DeepCopy(*this);
69  return copy;
70 }
71 
73  const Path &other)
74 {
75  *m_originalPath = *other.m_originalPath;
76  *m_folder = *other.m_folder;
77  *m_isFolderAbsolute = *other.m_isFolderAbsolute;
78  *m_filename = *other.m_filename;
79  *m_extension = *other.m_extension;
80 }
81 
83 {
84  return isFileExist(absolutePath());
85 }
87  const Path& path)
88 {
89  return isFileExist(path.absolutePath());
90 }
92  const biorbd::utils::String& path)
93 {
94  if (FILE *file = fopen(
95  #ifdef _WIN32
96  toWindowsFormat(path).c_str(),
97  #else
98  path.c_str(),
99  #endif
100  "r")) {
101  fclose(file);
102  return true;
103  } else {
104  return false;
105  }
106 }
107 
109 {
110  std::ifstream fichier(
111  #ifdef _WIN32
112  toWindowsFormat(absolutePath()).c_str()
113  #else
114  absolutePath().c_str()
115  #endif
116  );
117  bool isOpen(fichier.is_open());
118  fichier.close();
119  return isOpen;
120 }
121 
123 {
124  return isFolderExist(*this);
125 }
126 
128  const Path &path)
129 {
130  return isFolderExist(path.folder());
131 }
132 
134  const biorbd::utils::String & path)
135 {
136 #ifdef _WIN32
137  if (GetFileAttributesA(toWindowsFormat(path).c_str())
138  == INVALID_FILE_ATTRIBUTES)
139  return false; // Le path est invalide
140  else
141  // Si on est ici, c'est que quelque chose existe,
142  // s'assurer que ça ne soit pas un fichier
143  if (isFileExist(path))
144  return false;
145  else
146  return true;
147 #else
148  struct stat statbuf;
149  if (stat(path.c_str(), &statbuf) != -1) {
150  return true;
151  } else {
152  return false;
153  }
154 #endif
155 
156 }
157 
159  const biorbd::utils::String &path,
160  biorbd::utils::String &folder,
161  biorbd::utils::String &filename,
162  biorbd::utils::String &extension)
163 {
164  biorbd::utils::String pathSep(toUnixFormat(path));
165 
166  size_t sepPos(pathSep.rfind("/"));
167 
168  // Stocker le folder
169  if (sepPos == std::string::npos)
170  // If no separator is found, then there is no separator
171  // and therefore the path is ./
172  folder = "";
173  else
174  folder = pathSep.substr(0, sepPos) + "/";
175 
176  if (folder.find("./") == 0) // Remove the leading ./ if necessary
177  folder = folder.substr(2);
178 
179  // Stocker l'extension
180  size_t ext(pathSep.rfind("."));
181  if (ext != SIZE_MAX)
182  extension = pathSep.substr(ext+1);
183  else
184  extension = "";
185 
186  // Stocker le nom de fichier
187  filename = pathSep.substr(sepPos+1, ext- sepPos-1);
188 }
189 
191  return relativePath(*this, currentDir());
192 }
193 
195  const biorbd::utils::String& relativeTo) const
196 {
197  return relativePath(*this, relativeTo);
198 }
199 
201  const biorbd::utils::Path &path,
202  const biorbd::utils::String &relativeTo)
203 {
205  biorbd::utils::String currentDir(relativeTo);
206 
207  biorbd::utils::String meFirstPart("");
208  biorbd::utils::String currentDirFirstPart("");
209 
210  // Set the separator to the 0 position
211  size_t sepMe = std::string::npos;
212  size_t sepCurrentDir = std::string::npos;
213  do {
214  // cut according to previous separator
215  me = me.substr(sepMe+1);
216  currentDir = currentDir.substr(sepCurrentDir+1);
217 
218  // Find the next separator
219  sepMe = me.find("/"); // UNIX formalism
220  sepCurrentDir = currentDir.find("/");
221 
222  // Separate first and last part
223  meFirstPart = me.substr(0, sepMe);
224  currentDirFirstPart = currentDir.substr(0, sepCurrentDir);
225 
226  // While the first part are equal,
227  // we still can advance to find de closest relative part
228  } while(!meFirstPart.compare(currentDirFirstPart));
229 
230  biorbd::utils::String outPath;
231  while (currentDir.compare("")) {
232  // Tant que currentDir n'est pas vide, reculer
233  // Trouver le prochain séparateur
234  sepCurrentDir = currentDir.find("/");
235 
236  // Séparer la première et la dernière partie
237  if (sepCurrentDir != std::string::npos){
238  // -1 Si on est au dernier dossier
239  // et que celui-ci ne se termine pas par "/"
240  currentDirFirstPart = currentDir.substr(0, sepCurrentDir);
241  currentDir = currentDir.substr(sepCurrentDir+1);
242  }
243  else
244  currentDir = "";
245 
246  outPath += "../";
247  // Tant que les premières parties sont égales,
248  // continuer à avancer dans le path
249  };
250  if (!outPath.compare("") && me.find("../") != 0)
251  outPath += "./";
252 
253  outPath += me;
254 
255  return outPath;
256 }
257 
259  const biorbd::utils::Path &path)
260 {
261  if (*path.m_isFolderAbsolute) {
262  return path.folder();
263  }
264 
266 #ifdef _WIN32
267  biorbd::utils::String current(currentDir());
268  std::smatch matches;
269 
270  if (std::regex_search(current, matches, std::regex("^([A-Z]):[\\/].*$"))) {
271  base = matches[1].str() + ":/";
272  }
273  else {
274  biorbd::utils::Error::raise("I could not find the current drive to estimate the path");
275  }
276 #else
277  base = "/";
278 #endif
279  return base + relativePath(path, base);
280 }
281 
283 {
284  if (*m_isFolderAbsolute)
285  return *m_folder;
286  else
287  return currentDir() + *m_folder;
288 }
289 
291 {
292  if (m_filename->compare("")){
293  if (m_extension->compare(""))
294  return absoluteFolder() + *m_filename + "." + *m_extension;
295  else
296  return absoluteFolder() + *m_filename;
297  } else
298  return absoluteFolder();
299 }
300 
302  const biorbd::utils::String& path)
303 {
304  biorbd::utils::String pathOut(path);
305 
306  // Depending on the string origin, "\\" is either the character "\"
307  // escaped or the character "\" written twice. Test for both
308  size_t pos(pathOut.rfind("\\\\"));
309  while (pos != std::string::npos) {
310  pathOut.replace(pos, 2, "/");
311  pos = pathOut.rfind("\\\\");
312  }
313 
314  // However, this next hunk can create false positive each time a
315  // legitimate escape character is used (should not happen in a path?)
316  pos = pathOut.rfind("\\");
317  while (pos != std::string::npos) {
318  pathOut.replace(pos, 1, "/");
319  pos = pathOut.rfind("\\");
320  }
321  return pathOut;
322 }
323 
325  const biorbd::utils::String &path)
326 {
327  biorbd::utils::String pathOut(path);
328  size_t pos(pathOut.rfind("/"));
329  while (pos != std::string::npos) {
330  pathOut.replace(pos, 1, "\\\\");
331  pos = pathOut.rfind("/");
332  }
333  return pathOut;
334 }
335 
337 {
338  return *m_originalPath;
339 }
340 
342 {
343  return *m_folder;
344 }
345 
347  const biorbd::utils::String& name)
348 {
349  *m_filename = name;
350 }
351 
353 {
354  return *m_filename;
355 }
356 
358  const biorbd::utils::String &ext)
359 {
360  *m_extension = ext;
361 }
362 
364 {
365  return *m_extension;
366 }
367 
369 {
371 #ifdef _WIN32
372  biorbd::utils::String current(*m_folder);
373  std::smatch matches;
374 
375  if (std::regex_search(current, matches, std::regex("^([A-Z]):[\\/].*$"))) {
376  *m_isFolderAbsolute = true;
377  }
378  else {
379  *m_isFolderAbsolute = false;
380  }
381 #else
382  base = "/";
383  size_t pos(m_folder->find(base.c_str()));
384  if (pos == 0)
385  *m_isFolderAbsolute = true;
386  else
387  *m_isFolderAbsolute = false;
388 #endif
389 }
390 
392 {
393  char buff[FILENAME_MAX];
394 #ifdef _WIN32
395  biorbd::utils::Error::check(_getcwd(buff, FILENAME_MAX),
396  "Could not find the current directory");
397 #else
398  biorbd::utils::Error::check(getcwd(buff, FILENAME_MAX),
399  "Could not find the current directory");
400 #endif
401  return toUnixFormat(buff) + "/";
402 }
403 
405 {
406  const biorbd::utils::String& tp(folder());
407  biorbd::utils::String tp2(tp);
408 
409  size_t sep = std::string::npos;
410  size_t sepTrack = 0;
411  do {
412  // Découper en fonction de la position précédente du séparateur
413  tp2 = tp2.substr(sep+1);
414 
415  // Trouver le prochain séparateur
416  sep = tp2.find("/"); // Path are stored in UNIX formalism
417  if (sep != std::string::npos){
418  sepTrack += sep + 1 ;
419 
420  // Séparer la première et la dernière partie
421  if (!isFolderExist(
422  static_cast<biorbd::utils::String>(
423  tp.substr(0, sepTrack)))) {
424 #ifdef _WIN32
425  _mkdir(toWindowsFormat(tp.substr(0, sepTrack)).c_str());
426 #else
427  mkdir(tp.substr(0, sepTrack).c_str(), 0777);
428 #endif
429  }
430  }
431  } while (sep != std::string::npos);
432 }
biorbd::utils::Path::m_extension
std::shared_ptr< biorbd::utils::String > m_extension
The extension.
Definition: Path.h:251
biorbd::utils::Path::toWindowsFormat
static biorbd::utils::String toWindowsFormat(const biorbd::utils::String &path)
Return the path to Windows format.
Definition: Path.cpp:324
biorbd::utils::Path::absoluteFolder
biorbd::utils::String absoluteFolder() const
Return the absolute folder relative to root.
Definition: Path.cpp:282
biorbd::utils::Path::absolutePath
biorbd::utils::String absolutePath() const
Return the absolute path relative to root.
Definition: Path.cpp:290
biorbd::utils::Path::setFilename
void setFilename(const biorbd::utils::String &name)
Set the filename.
Definition: Path.cpp:346
biorbd::utils::Path::Path
Path()
Construct path.
Definition: Path.cpp:19
biorbd::utils::Path::folder
const biorbd::utils::String & folder() const
Return the folder of the file.
Definition: Path.cpp:341
biorbd::utils::Path::setExtension
void setExtension(const biorbd::utils::String &ext)
Set the extension.
Definition: Path.cpp:357
biorbd::utils::Path::currentDir
static biorbd::utils::String currentDir()
Definition: Path.cpp:391
biorbd::utils::Path::setIsFolderAbsolute
void setIsFolderAbsolute()
Set if folder is absolute.
Definition: Path.cpp:368
biorbd::utils::Path::relativePath
biorbd::utils::String relativePath() const
Return relative path to current working directory.
Definition: Path.cpp:190
biorbd::utils::Error::raise
static void raise(const biorbd::utils::String &message)
Throw an error message.
Definition: Error.cpp:4
biorbd::utils::Path::m_folder
std::shared_ptr< biorbd::utils::String > m_folder
The folder.
Definition: Path.h:248
biorbd::utils::Path::isFolderExist
bool isFolderExist() const
Test if folder exists on the computer.
Definition: Path.cpp:122
biorbd::utils::Path::toUnixFormat
static biorbd::utils::String toUnixFormat(const biorbd::utils::String &path)
Return the path to Unix format.
Definition: Path.cpp:301
biorbd::utils::Path::DeepCopy
biorbd::utils::Path DeepCopy() const
Deep copy of path.
Definition: Path.cpp:65
biorbd::utils::Path::parseFileName
static void parseFileName(const biorbd::utils::String &path, biorbd::utils::String &folder, biorbd::utils::String &filename, biorbd::utils::String &ext)
Parse a path in folder, filename and extension.
Definition: Path.cpp:158
biorbd::utils::Path::filename
const biorbd::utils::String & filename() const
Return the filename.
Definition: Path.cpp:352
biorbd::utils::Path::extension
const biorbd::utils::String & extension() const
Return the extension of the file.
Definition: Path.cpp:363
biorbd::utils::Path::originalPath
const biorbd::utils::String & originalPath() const
Return original path as it was at constructor time.
Definition: Path.cpp:336
biorbd::utils::Path::m_originalPath
std::shared_ptr< biorbd::utils::String > m_originalPath
The original path at construction time.
Definition: Path.h:247
biorbd::utils::Path::isFileExist
bool isFileExist() const
Test if file exist on the computer.
Definition: Path.cpp:82
biorbd::utils::String
Wrapper around the std::string class with augmented functionality.
Definition: String.h:17
biorbd::utils::Path::createFolder
void createFolder() const
To create folder on the computer.
Definition: Path.cpp:404
biorbd::utils::Path::isFileReadable
bool isFileReadable() const
Test if file exist on the computer and is accessible.
Definition: Path.cpp:108
biorbd::utils::Path
Collection of methods to manipulate path.
Definition: Path.h:17
biorbd::utils::Path::m_isFolderAbsolute
std::shared_ptr< bool > m_isFolderAbsolute
If folder is absolute.
Definition: Path.h:249
biorbd::utils::Error::check
static void check(bool cond, const biorbd::utils::String &message)
Assert that raises the error message if false.
Definition: Error.cpp:10
biorbd::utils::Path::m_filename
std::shared_ptr< biorbd::utils::String > m_filename
The filename.
Definition: Path.h:250