Visual Servoing Platform  version 3.5.0 under development (2022-02-15)
vpIoTools.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Directory management.
33  *
34  * Authors:
35  * Fabien Spindler
36  *
37  *****************************************************************************/
38 
43 #include <algorithm>
44 #include <cctype>
45 #include <functional>
46 #include <cmath>
47 #include <errno.h>
48 #include <fcntl.h>
49 #include <fstream>
50 #include <limits>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <sys/stat.h>
55 #include <sys/types.h>
56 #include <visp3/core/vpDebug.h>
57 #include <visp3/core/vpEndian.h>
58 #include <visp3/core/vpIoException.h>
59 #include <visp3/core/vpIoTools.h>
60 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
61 #include <dirent.h>
62 #include <unistd.h>
63 #elif defined(_WIN32)
64 #include <direct.h>
65 #include <windows.h>
66 #endif
67 #if !defined(_WIN32)
68  #ifdef __ANDROID__
69  // Like IOS, wordexp.cpp is not defined for Android
70  #else
71  #include <wordexp.h>
72  #endif
73 #endif
74 
75 #if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
76 #include <TargetConditionals.h> // To detect OSX or IOS using TARGET_OS_IOS macro
77 #endif
78 
79 #ifndef PATH_MAX
80 # ifdef _MAX_PATH
81 # define PATH_MAX _MAX_PATH
82 # else
83 # define PATH_MAX 1024
84 # endif
85 #endif
86 
87 std::string vpIoTools::baseName = "";
88 std::string vpIoTools::baseDir = "";
89 std::string vpIoTools::configFile = "";
90 std::vector<std::string> vpIoTools::configVars = std::vector<std::string>();
91 std::vector<std::string> vpIoTools::configValues = std::vector<std::string>();
92 
93 namespace
94 {
95 // The following code is not working on iOS since wordexp() is not available
96 // The function is not used on Android
97 #if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
98 #if (TARGET_OS_IOS == 0) && !defined(__ANDROID__)
99 void replaceAll(std::string &str, const std::string &search, const std::string &replace)
100 {
101  size_t start_pos = 0;
102  while ((start_pos = str.find(search, start_pos)) != std::string::npos) {
103  str.replace(start_pos, search.length(), replace);
104  start_pos += replace.length(); // Handles case where 'replace' is a
105  // substring of 'search'
106  }
107 }
108 #endif
109 #endif
110 
111 std::string &ltrim(std::string &s)
112 {
113 #if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
114  s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) { return !std::isspace(c); }));
115 #else
116  s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
117 #endif
118  return s;
119 }
120 
121 std::string &rtrim(std::string &s)
122 {
123 #if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
124  s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) { return !std::isspace(c); }).base(), s.end());
125 #else
126  s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
127 #endif
128  return s;
129 }
130 }
131 
135 const std::string &vpIoTools::getBuildInformation()
136 {
137  static std::string build_info =
138 #include "version_string.inc"
139  ;
140  return build_info;
141 }
142 
195 {
196 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
197  std::string username;
198  vpIoTools::getUserName(username);
199  return "/tmp/" + username;
200 #elif defined(_WIN32) && !defined(WINRT)
201  // https://docs.microsoft.com/en-us/windows/win32/fileio/creating-and-using-a-temporary-file
202  // Gets the temp path env string (no guarantee it's a valid path).
203  TCHAR lpTempPathBuffer[MAX_PATH];
204  DWORD dwRetVal = GetTempPath(MAX_PATH /* length of the buffer */, lpTempPathBuffer /* buffer for path */);
205  if (dwRetVal > MAX_PATH || (dwRetVal == 0)) {
206  throw vpIoException(vpIoException::cantGetenv, "Error with GetTempPath() call!");
207  }
208  std::string temp_path(lpTempPathBuffer);
209  if (!temp_path.empty()) {
210  if (temp_path.back() == '\\') {
211  temp_path.resize(temp_path.size() - 1);
212  }
213  }
214  else {
215  temp_path = "C:\temp";
216  try {
217  vpIoTools::makeDirectory(temp_path);
218  } catch (...) {
219  throw(vpException(vpException::fatalError, "Cannot set temp path to %s", temp_path.c_str()));
220  }
221  }
222  return temp_path;
223 #else
224  throw vpIoException(vpException::fatalError, "Not implemented on this platform!");
225 #endif
226 }
227 
233 void vpIoTools::setBaseName(const std::string &s) { baseName = s; }
234 
240 void vpIoTools::setBaseDir(const std::string &dir) { baseDir = dir + "/"; }
241 
247 std::string vpIoTools::getBaseName() { return baseName; }
248 
254 std::string vpIoTools::getFullName() { return baseDir + baseName; }
255 
269 void vpIoTools::getUserName(std::string &username)
270 {
271 // With MinGW, UNIX and _WIN32 are defined
272 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
273  // Get the user name.
274  char *_username = ::getenv("LOGNAME");
275  if (!_username) {
276  username = "unknown";
277  }
278  else {
279  username = _username;
280  }
281 #elif defined(_WIN32)
282 #if (!defined(WINRT))
283  unsigned int info_buffer_size = 1024;
284  TCHAR *infoBuf = new TCHAR[info_buffer_size];
285  DWORD bufCharCount = (DWORD)info_buffer_size;
286  // Get the user name.
287  if (!GetUserName(infoBuf, &bufCharCount)) {
288  username = "unknown";
289  } else {
290  username = infoBuf;
291  }
292  delete[] infoBuf;
293 #else
294  // Universal platform
295  username = "unknown";
296 #endif
297 #else
298  username = "unknown";
299 #endif
300 }
301 
317 {
318  std::string username;
319  getUserName(username);
320  return username;
321 }
322 
353 std::string vpIoTools::getenv(const std::string &env)
354 {
355 #if defined(_WIN32) && defined(WINRT)
356  throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value: not "
357  "implemented on Universal Windows Platform"));
358 #else
359  std::string value;
360  // Get the environment variable value.
361  char *_value = ::getenv(env.c_str());
362  if (! _value) {
363  throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value"));
364  }
365  value = _value;
366 
367  return value;
368 #endif
369 }
370 
380 void vpIoTools::getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
381 {
382  if (version.size() == 0) {
383  major = 0;
384  minor = 0;
385  patch = 0;
386  } else {
387  size_t major_pos = version.find('.');
388  std::string major_str = version.substr(0, major_pos);
389  major = static_cast<unsigned>(atoi(major_str.c_str()));
390 
391  if (major_pos != std::string::npos) {
392  size_t minor_pos = version.find('.', major_pos + 1);
393  std::string minor_str = version.substr(major_pos + 1, (minor_pos - (major_pos + 1)));
394  minor = static_cast<unsigned>(atoi(minor_str.c_str()));
395 
396  if (minor_pos != std::string::npos) {
397  std::string patch_str = version.substr(minor_pos + 1);
398  patch = static_cast<unsigned>(atoi(patch_str.c_str()));
399  } else {
400  patch = 0;
401  }
402  } else {
403  minor = 0;
404  patch = 0;
405  }
406  }
407 }
408 
420 bool vpIoTools::checkDirectory(const std::string &dirname)
421 {
422 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
423  struct stat stbuf;
424 #elif defined(_WIN32) && defined(__MINGW32__)
425  struct stat stbuf;
426 #elif defined(_WIN32)
427  struct _stat stbuf;
428 #endif
429 
430  if (dirname.empty()) {
431  return false;
432  }
433 
434  std::string _dirname = path(dirname);
435 
436 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
437  if (stat(_dirname.c_str(), &stbuf) != 0)
438 #elif defined(_WIN32) && defined(__MINGW32__)
439  // Remove trailing separator character if any
440  // AppVeyor: Windows 6.3.9600 AMD64 ; C:/MinGW/bin/g++.exe (ver 5.3.0) ;
441  // GNU Make 3.82.90 Built for i686-pc-mingw32
442  if (_dirname.at(_dirname.size() - 1) == vpIoTools::separator)
443  _dirname = _dirname.substr(0, _dirname.size() - 1);
444  if (stat(_dirname.c_str(), &stbuf) != 0)
445 #elif defined(_WIN32)
446  if (_stat(_dirname.c_str(), &stbuf) != 0)
447 #endif
448  {
449  return false;
450  }
451 #if defined(_WIN32) || (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
452  if ((stbuf.st_mode & S_IFDIR) == 0)
453 #endif
454  {
455  return false;
456  }
457 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
458  if ((stbuf.st_mode & S_IWUSR) == 0)
459 #elif defined(_WIN32)
460  if ((stbuf.st_mode & S_IWRITE) == 0)
461 #endif
462  {
463  return false;
464  }
465  return true;
466 }
467 
480 bool vpIoTools::checkFifo(const std::string &fifofilename)
481 {
482 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
483  struct stat stbuf;
484 
485  std::string _filename = path(fifofilename);
486  if (stat(_filename.c_str(), &stbuf) != 0) {
487  return false;
488  }
489  if ((stbuf.st_mode & S_IFIFO) == 0) {
490  return false;
491  }
492  if ((stbuf.st_mode & S_IRUSR) == 0)
493 
494  {
495  return false;
496  }
497  return true;
498 #elif defined(_WIN32)
499  (void)fifofilename;
500  throw(vpIoException(vpIoException::notImplementedError, "Fifo files are not supported on Windows platforms."));
501 #endif
502 }
503 
504 #ifndef DOXYGEN_SHOULD_SKIP_THIS
505 // See:
506 // https://gist.github.com/JonathonReinhart/8c0d90191c38af2dcadb102c4e202950
507 int vpIoTools::mkdir_p(const char *path, int mode)
508 {
509  /* Adapted from http://stackoverflow.com/a/2336245/119527 */
510  const size_t len = strlen(path);
511  char _path[PATH_MAX];
512  const char sep = vpIoTools::separator;
513 
514  std::fill(_path, _path + PATH_MAX, 0);
515 
516  errno = 0;
517  if (len > sizeof(_path) - 1) {
518  errno = ENAMETOOLONG;
519  return -1;
520  }
521  /* Copy string so its mutable */
522  strcpy(_path, path);
523 
524  /* Iterate over the string */
525  for (char *p = _path + 1; *p; p++) { // path cannot be empty
526  if (*p == sep) {
527  /* Temporarily truncate */
528  *p = '\0';
529 
530 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
531  if (mkdir(_path, static_cast<mode_t>(mode)) != 0)
532 #elif defined(_WIN32)
533  (void)mode; // var not used
534  if (!checkDirectory(_path) && _mkdir(_path) != 0)
535 #endif
536  {
537  if (errno != EEXIST)
538  return -1;
539  }
540  *p = sep;
541  }
542  }
543 
544 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
545  if (mkdir(_path, static_cast<mode_t>(mode)) != 0)
546 #elif defined(_WIN32)
547  if (_mkdir(_path) != 0)
548 #endif
549  {
550  if (errno != EEXIST)
551  return -1;
552  }
553 
554  return 0;
555 }
556 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
557 
570 void vpIoTools::makeDirectory(const std::string &dirname)
571 {
572 #if ((!defined(__unix__) && !defined(__unix) && (!defined(__APPLE__) || !defined(__MACH__)))) && !defined(_WIN32)
573  std::cerr << "Unsupported platform for vpIoTools::makeDirectory()!" << std::endl;
574  return;
575 #endif
576 
577 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
578  struct stat stbuf;
579 #elif defined(_WIN32) && defined(__MINGW32__)
580  struct stat stbuf;
581 #elif defined(_WIN32)
582  struct _stat stbuf;
583 #endif
584 
585  if (dirname.empty()) {
586  throw(vpIoException(vpIoException::invalidDirectoryName, "invalid directory name"));
587  }
588 
589  std::string _dirname = path(dirname);
590 
591 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
592  if (stat(_dirname.c_str(), &stbuf) != 0)
593 #elif defined(_WIN32) && defined(__MINGW32__)
594  if (stat(_dirname.c_str(), &stbuf) != 0)
595 #elif defined(_WIN32)
596  if (_stat(_dirname.c_str(), &stbuf) != 0)
597 #endif
598  {
599  if (vpIoTools::mkdir_p(_dirname.c_str(), 0755) != 0) {
600  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'", dirname.c_str()));
601  }
602  }
603 
604  if (checkDirectory(dirname) == false) {
605  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'", dirname.c_str()));
606  }
607 }
608 
621 void vpIoTools::makeFifo(const std::string &fifoname)
622 {
623 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
624 
625  // If dirname is a directory, we throw an error
626  if (vpIoTools::checkDirectory(fifoname)) {
628  "Unable to create fifo file. '%s' is an existing directory.", fifoname.c_str()));
629  }
630 
631  // If dirname refers to an already existing file, we throw an error
632  else if (vpIoTools::checkFilename(fifoname)) {
633  throw(vpIoException(vpIoException::invalidDirectoryName, "Unable to create fifo file '%s'. File already exists.",
634  fifoname.c_str()));
635  // If dirname refers to an already existing fifo, we throw an error
636  } else if (vpIoTools::checkFifo(fifoname)) {
637  throw(vpIoException(vpIoException::invalidDirectoryName, "Unable to create fifo file '%s'. Fifo already exists.",
638  fifoname.c_str()));
639  }
640 
641  else if (mkfifo(fifoname.c_str(), 0666) < 0) {
642  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create fifo file '%s'.", fifoname.c_str()));
643  }
644 #elif defined(_WIN32)
645  (void)fifoname;
646  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create fifo on Windows platforms."));
647 #endif
648 }
649 
650 #if defined(_WIN32) && !defined(WINRT)
651 std::string getUuid()
652 {
653  UUID uuid;
654  if (UuidCreate(&uuid) != RPC_S_OK) {
655  throw(vpIoException(vpIoException::fatalError, "UuidCreate() failed!"));
656  }
657 
658  RPC_CSTR stringUuid;
659  if (UuidToString(&uuid, &stringUuid) != RPC_S_OK) {
660  throw(vpIoException(vpIoException::fatalError, "UuidToString() failed!"));
661  }
662 
663  return reinterpret_cast<char *>(stringUuid);
664 }
665 #endif
666 
728 std::string vpIoTools::makeTempDirectory(const std::string &dirname)
729 {
730 #if defined(WINRT) || !defined(_WIN32) && \
731  !(defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // not UNIX and not Windows
732  throw(vpIoException(vpIoException::cantCreateDirectory, "makeTempDirectory() is not supported on this platform!"));
733 #endif
734 
735  std::string dirname_cpy = std::string(dirname);
736  std::string correctEnding = "XXXXXX";
737 
738  size_t endingLength = correctEnding.length();
739  size_t dirNameLength = dirname_cpy.length();
740 
741  // If dirname is an unexisting directory, it should end with XXXXXX in order to create a temp directory
742  if (!vpIoTools::checkDirectory(dirname_cpy)) {
743  if (endingLength > dirNameLength) {
745  "Unable to create temp directory '%s'. It should end with XXXXXX.", dirname_cpy.c_str()));
746  }
747 
748  if (dirname.compare(dirNameLength - endingLength, endingLength, correctEnding) != 0) {
750  "Unable to create temp directory '%s'. It should end with XXXXXX.", dirname_cpy.c_str()));
751  }
752 
753 #if defined(_WIN32) && !defined(WINRT)
754  // Remove XXXXXX
755  dirname_cpy = dirname_cpy.substr(0, dirname_cpy.rfind(correctEnding));
756  // Append UUID
757  dirname_cpy = dirname_cpy + getUuid();
758 #endif
759 
760  } else {
761  // If dirname is an existing directory, we create a temp directory inside
762 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
763  if (dirname_cpy.at(dirname_cpy.length() - 1) != '/') {
764  dirname_cpy = dirname_cpy + "/";
765  }
766  dirname_cpy = dirname_cpy + "XXXXXX";
767 #elif defined(_WIN32) && !defined(WINRT)
768  dirname_cpy = createFilePath(dirname_cpy, getUuid());
769 #endif
770  }
771 
772 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
773  char *dirname_char = new char[dirname_cpy.length() + 1];
774  strcpy(dirname_char, dirname_cpy.c_str());
775 
776  char *computedDirname = mkdtemp(dirname_char);
777 
778  if (!computedDirname) {
779  delete[] dirname_char;
780  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'.", dirname_cpy.c_str()));
781  }
782 
783  std::string res(computedDirname);
784  delete[] dirname_char;
785  return res;
786 #elif defined(_WIN32) && !defined(WINRT)
787  makeDirectory(dirname_cpy);
788  return dirname_cpy;
789 #endif
790 }
791 
802 bool vpIoTools::checkFilename(const std::string &filename)
803 {
804 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
805  struct stat stbuf;
806 #elif defined(_WIN32)
807  struct _stat stbuf;
808 #endif
809 
810  if (filename.empty()) {
811  return false;
812  }
813 
814  std::string _filename = path(filename);
815 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
816  if (stat(_filename.c_str(), &stbuf) != 0)
817 #elif defined(_WIN32)
818  if (_stat(_filename.c_str(), &stbuf) != 0)
819 #endif
820  {
821  return false;
822  }
823  if ((stbuf.st_mode & S_IFREG) == 0) {
824  return false;
825  }
826 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
827  if ((stbuf.st_mode & S_IRUSR) == 0)
828 #elif defined(_WIN32)
829  if ((stbuf.st_mode & S_IREAD) == 0)
830 #endif
831  {
832  return false;
833  }
834  return true;
835 }
836 
844 bool vpIoTools::copy(const std::string &src, const std::string &dst)
845 {
846  // Check if we have to consider a file or a directory
847  if (vpIoTools::checkFilename(src)) {
848 // std::cout << "copy file: " << src << " in " << dst << std::endl;
849 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
850 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
851  // wordexp() is not available
852  char cmd[FILENAME_MAX];
853  int ret;
854  sprintf(cmd, "cp -p %s %s", src.c_str(), dst.c_str());
855  ret = system(cmd);
856  if (ret) {
857  }; // to avoid a warning
858  // std::cout << cmd << " return value: " << ret << std::endl;
859  return true;
860 #else
861  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src.c_str(), dst.c_str()));
862 #endif
863 #elif defined(_WIN32)
864 #if (!defined(WINRT))
865  char cmd[FILENAME_MAX];
866  int ret;
867  std::string src_ = vpIoTools::path(src);
868  std::string dst_ = vpIoTools::path(dst);
869  sprintf(cmd, "copy %s %s", src_.c_str(), dst_.c_str());
870  ret = system(cmd);
871  if (ret) {
872  }; // to avoid a warning
873  // std::cout << cmd << " return value: " << ret << std::endl;
874  return true;
875 #else
876  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
877  src.c_str(), dst.c_str()));
878 #endif
879 #endif
880  } else if (vpIoTools::checkDirectory(src)) {
881 // std::cout << "copy directory: " << src << " in " << dst << std::endl;
882 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
883 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
884  // wordexp() is not available
885  char cmd[FILENAME_MAX];
886  int ret;
887  sprintf(cmd, "cp -p -r %s %s", src.c_str(), dst.c_str());
888  ret = system(cmd);
889  if (ret) {
890  }; // to avoid a warning
891  // std::cout << cmd << " return value: " << ret << std::endl;
892  return true;
893 #else
894  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src.c_str(), dst.c_str()));
895 #endif
896 #elif defined(_WIN32)
897 #if (!defined(WINRT))
898  char cmd[FILENAME_MAX];
899  int ret;
900  std::string src_ = vpIoTools::path(src);
901  std::string dst_ = vpIoTools::path(dst);
902  sprintf(cmd, "copy %s %s", src_.c_str(), dst_.c_str());
903  ret = system(cmd);
904  if (ret) {
905  }; // to avoid a warning
906  // std::cout << cmd << " return value: " << ret << std::endl;
907  return true;
908 #else
909  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
910  src.c_str(), dst.c_str()));
911 #endif
912 #endif
913  } else {
914  std::cout << "Cannot copy: " << src << " in " << dst << std::endl;
915  return false;
916  }
917 }
918 
929 bool vpIoTools::remove(const std::string &file_or_dir)
930 {
931  // Check if we have to consider a file or a directory
932  if (vpIoTools::checkFilename(file_or_dir)
933 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
934  || vpIoTools::checkFifo(std::string(file_or_dir))
935 #endif
936  ) {
937  // std::cout << "remove file: " << file_or_dir << std::endl;
938  if (::remove(file_or_dir.c_str()) != 0)
939  return false;
940  else
941  return true;
942  } else if (vpIoTools::checkDirectory(file_or_dir)) {
943 // std::cout << "remove directory: " << file_or_dir << std::endl;
944 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
945 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
946  // wordexp() is not available
947  char cmd[FILENAME_MAX];
948  sprintf(cmd, "rm -rf \"%s\"", file_or_dir.c_str());
949  int ret = system(cmd);
950  if (ret) {
951  }; // to avoid a warning
952  // std::cout << cmd << " return value: " << ret << std::endl;
953  return true;
954 #else
955  throw(vpIoException(vpException::fatalError, "Cannot remove %s: not implemented on iOS Platform", file_or_dir.c_str()));
956 #endif
957 #elif defined(_WIN32)
958 #if (!defined(WINRT))
959  char cmd[FILENAME_MAX];
960  std::string file_or_dir_ = vpIoTools::path(file_or_dir);
961  sprintf(cmd, "rmdir /S /Q %s", file_or_dir_.c_str());
962  int ret = system(cmd);
963  if (ret) {
964  }; // to avoid a warning
965  // std::cout << cmd << " return value: " << ret << std::endl;
966  return true;
967 #else
968  throw(vpIoException(vpException::fatalError, "Cannot remove %s: not implemented on Universal Windows Platform",
969  file_or_dir.c_str()));
970 #endif
971 #endif
972  } else {
973  std::cout << "Cannot remove: " << file_or_dir << std::endl;
974  return false;
975  }
976 }
977 
987 bool vpIoTools::rename(const std::string &oldfilename, const std::string &newfilename)
988 {
989  if (::rename(oldfilename.c_str(), newfilename.c_str()) != 0)
990  return false;
991  else
992  return true;
993 }
994 
1005 std::string vpIoTools::path(const std::string &pathname)
1006 {
1007  std::string path(pathname);
1008 
1009 #if defined(_WIN32)
1010  for (unsigned int i = 0; i < path.length(); i++)
1011  if (path[i] == '/')
1012  path[i] = '\\';
1013 #elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
1014  for (unsigned int i = 0; i < path.length(); i++)
1015  if (path[i] == '\\')
1016  path[i] = '/';
1017 #if TARGET_OS_IOS == 0 // The following code is not working on iOS and android since
1018  // wordexp() is not available
1019  #ifdef __ANDROID__
1020  // Do nothing
1021  #else
1022  wordexp_t exp_result;
1023 
1024  // escape quote character
1025  replaceAll(path, "'", "'\\''");
1026  // add quotes to handle special characters like parentheses and spaces
1027  wordexp(std::string("'" + path + "'").c_str(), &exp_result, 0);
1028  path = exp_result.we_wordc == 1 ? exp_result.we_wordv[0] : "";
1029  wordfree(&exp_result);
1030  #endif
1031 #endif
1032 #endif
1033 
1034  return path;
1035 }
1036 
1045 bool vpIoTools::loadConfigFile(const std::string &confFile)
1046 {
1047  configFile = path(confFile);
1048  configVars.clear();
1049  configValues.clear();
1050  std::ifstream confContent(configFile.c_str(), std::ios::in);
1051 
1052  if (confContent.is_open()) {
1053  std::string line, var, val;
1054  long unsigned int k;
1055  int c;
1056  std::string stop[3] = {" ", "\t", "#"};
1057  while (std::getline(confContent, line)) {
1058  if ((line.compare(0, 1, "#") != 0) && (line.size() > 2)) {
1059  try {
1060  // name of the variable
1061  k = static_cast<unsigned long>(line.find(" "));
1062  var = line.substr(0, k);
1063  // look for the end of the actual value
1064  c = 200;
1065  for (unsigned i = 0; i < 3; ++i)
1066  c = vpMath::minimum(c, static_cast<int>(line.find(stop[i], static_cast<size_t>(k) + static_cast<size_t>(1))));
1067  if (c == -1)
1068  c = static_cast<int>(line.size());
1069  long unsigned int c_ = static_cast<long unsigned int>(c);
1070  val = line.substr(static_cast<size_t>(k) + static_cast<size_t>(1), static_cast<size_t>(c_) - static_cast<size_t>(k) - static_cast<size_t>(1));
1071  configVars.push_back(var);
1072  configValues.push_back(val);
1073  } catch (...) {
1074  }
1075  }
1076  }
1077  confContent.close();
1078  } else {
1079  return false;
1080  }
1081  return true;
1082 }
1083 
1092 bool vpIoTools::readConfigVar(const std::string &var, float &value)
1093 {
1094  bool found = false;
1095  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1096  if (configVars[k] == var) {
1097  if (configValues[k].compare("PI") == 0)
1098  value = static_cast<float>(M_PI);
1099  else if (configValues[k].compare("PI/2") == 0)
1100  value = static_cast<float>(M_PI / 2.0);
1101  else if (configValues[k].compare("-PI/2") == 0)
1102  value = static_cast<float>(-M_PI / 2.0);
1103  else
1104  value = static_cast<float>(atof(configValues[k].c_str()));
1105  found = true;
1106  }
1107  }
1108  if (found == false)
1109  std::cout << var << " not found in config file" << std::endl;
1110  return found;
1111 }
1120 bool vpIoTools::readConfigVar(const std::string &var, double &value)
1121 {
1122  bool found = false;
1123  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1124  if (configVars[k] == var) {
1125  if (configValues[k].compare("PI") == 0)
1126  value = M_PI;
1127  else if (configValues[k].compare("PI/2") == 0)
1128  value = M_PI / 2;
1129  else if (configValues[k].compare("-PI/2") == 0)
1130  value = -M_PI / 2;
1131  else
1132  value = atof(configValues[k].c_str());
1133  found = true;
1134  }
1135  }
1136  if (found == false)
1137  std::cout << var << " not found in config file" << std::endl;
1138  return found;
1139 }
1140 
1149 bool vpIoTools::readConfigVar(const std::string &var, int &value)
1150 {
1151  bool found = false;
1152  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1153  if (configVars[k] == var) {
1154  value = atoi(configValues[k].c_str());
1155  found = true;
1156  }
1157  }
1158  if (found == false)
1159  std::cout << var << " not found in config file" << std::endl;
1160  return found;
1161 }
1162 
1171 bool vpIoTools::readConfigVar(const std::string &var, unsigned int &value)
1172 {
1173  int v = 0;
1174  bool found = readConfigVar(var, v);
1175  value = static_cast<unsigned int>(v);
1176  return found;
1177 }
1178 
1187 bool vpIoTools::readConfigVar(const std::string &var, bool &value)
1188 {
1189  int v = 0;
1190  bool found = readConfigVar(var, v);
1191  value = (v != 0);
1192  return found;
1193 }
1194 
1203 bool vpIoTools::readConfigVar(const std::string &var, vpColor &value)
1204 {
1205  unsigned int v = 0;
1206  bool found = readConfigVar(var, v);
1207  value = vpColor::getColor(v);
1208  return found;
1209 }
1210 
1219 bool vpIoTools::readConfigVar(const std::string &var, std::string &value)
1220 {
1221  bool found = false;
1222  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1223  if (configVars[k] == var) {
1224  value = configValues[k];
1225  found = true;
1226  }
1227  }
1228  if (found == false)
1229  std::cout << var << " not found in config file" << std::endl;
1230  return found;
1231 }
1232 
1246 bool vpIoTools::readConfigVar(const std::string &var, vpArray2D<double> &value, const unsigned int &nCols,
1247  const unsigned int &nRows)
1248 {
1249  bool found = false;
1250  std::string nb;
1251  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1252  if (configVars[k] == var) {
1253  found = true;
1254  // resize or not
1255  if (nCols != 0 && nRows != 0)
1256  value.resize(nRows, nCols);
1257  size_t ind = 0, ind2;
1258  for (unsigned int i = 0; i < value.getRows(); ++i)
1259  for (unsigned int j = 0; j < value.getCols(); ++j) {
1260  ind2 = configValues[k].find(",", ind);
1261  nb = configValues[k].substr(ind, ind2 - ind);
1262  if (nb.compare("PI") == 0)
1263  value[i][j] = M_PI;
1264  else if (nb.compare("PI/2") == 0)
1265  value[i][j] = M_PI / 2;
1266  else if (nb.compare("-PI/2") == 0)
1267  value[i][j] = -M_PI / 2;
1268  else
1269  value[i][j] = atof(nb.c_str());
1270  ind = ind2 + 1;
1271  }
1272  }
1273  }
1274  if (found == false)
1275  std::cout << var << " not found in config file" << std::endl;
1276  return found;
1277 }
1278 
1279 // construct experiment filename & path
1280 
1289 void vpIoTools::addNameElement(const std::string &strTrue, const bool &cond, const std::string &strFalse)
1290 {
1291  if (cond)
1292  baseName += "_" + strTrue;
1293  else if (strFalse != "")
1294  baseName += "_" + strFalse;
1295 }
1296 
1305 void vpIoTools::addNameElement(const std::string &strTrue, const double &val)
1306 {
1307  // if(val != 0.)
1308  if (std::fabs(val) < std::numeric_limits<double>::epsilon()) {
1309  char valC[256];
1310  sprintf(valC, "%.3f", val);
1311  std::string valS(valC);
1312  baseName += "_" + strTrue + valS;
1313  }
1314 }
1315 
1324 void vpIoTools::createBaseNamePath(const bool &empty)
1325 {
1326  if (vpIoTools::checkDirectory(baseDir + baseName) == false) {
1328  std::cout << "creating directory " + baseDir + baseName << std::endl;
1329  } else {
1330  if (empty) {
1331  std::cout << "emptying directory " + baseDir + baseName << std::endl;
1333  }
1334  }
1335 }
1336 
1343 void vpIoTools::saveConfigFile(const bool &actuallySave)
1344 {
1345  if (actuallySave) {
1346  std::string dest = baseDir + "/" + baseName + "_config.txt";
1347  // file copy
1348  vpIoTools::copy(configFile, dest);
1349  }
1350 }
1351 
1366 {
1367  std::string data_path;
1368  std::string file_to_test("mbt/cube.cao");
1369  std::string filename;
1370  // Test if VISP_INPUT_IMAGE_PATH env var is set
1371  try {
1372  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH");
1373  filename = data_path + "/" + file_to_test;
1374  if (vpIoTools::checkFilename(filename))
1375  return data_path;
1376  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/ViSP-images";
1377  filename = data_path + "/" + file_to_test;
1378  if (vpIoTools::checkFilename(filename))
1379  return data_path;
1380  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/visp-images";
1381  filename = data_path + "/" + file_to_test;
1382  if (vpIoTools::checkFilename(filename))
1383  return data_path;
1384  } catch (...) {
1385  }
1386 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1387  // Test if visp-images-data package is installed (Ubuntu and Debian)
1388  data_path = "/usr/share/visp-images-data/ViSP-images";
1389  filename = data_path + "/" + file_to_test;
1390  if (vpIoTools::checkFilename(filename))
1391  return data_path;
1392  data_path = "/usr/share/visp-images-data/visp-images";
1393  filename = data_path + "/" + file_to_test;
1394  if (vpIoTools::checkFilename(filename))
1395  return data_path;
1396 #endif
1397  data_path = "";
1398  return data_path;
1399 }
1400 
1430 std::string vpIoTools::getFileExtension(const std::string &pathname, bool checkFile)
1431 {
1432  if (checkFile && (vpIoTools::checkDirectory(pathname) || !vpIoTools::checkFilename(pathname))) {
1433  return "";
1434  }
1435 
1436 #if defined(_WIN32)
1437  std::string sep = "\\";
1438  std::string altsep = "/";
1439  std::string extsep = ".";
1440 #else
1441  // On Unix, or on the Mac
1442  std::string sep = "/";
1443  std::string altsep = "";
1444  std::string extsep = ".";
1445 #endif
1446 
1447  // Python 2.7.8 module.
1448  //# Split a path in root and extension.
1449  //# The extension is everything starting at the last dot in the last
1450  //# pathname component; the root is everything before that.
1451  //# It is always true that root + ext == p.
1452  //
1453  //# Generic implementation of splitext, to be parametrized with
1454  //# the separators
1455  // def _splitext(p, sep, altsep, extsep):
1456  // """Split the extension from a pathname.
1457  //
1458  // Extension is everything from the last dot to the end, ignoring
1459  // leading dots. Returns "(root, ext)"; ext may be empty."""
1460  //
1461  // sepIndex = p.rfind(sep)
1462  // if altsep:
1463  // altsepIndex = p.rfind(altsep)
1464  // sepIndex = max(sepIndex, altsepIndex)
1465  //
1466  // dotIndex = p.rfind(extsep)
1467  // if dotIndex > sepIndex:
1468  // # skip all leading dots
1469  // filenameIndex = sepIndex + 1
1470  // while filenameIndex < dotIndex:
1471  // if p[filenameIndex] != extsep:
1472  // return p[:dotIndex], p[dotIndex:]
1473  // filenameIndex += 1
1474  //
1475  // return p, ''
1476 
1477  int sepIndex = static_cast<int>(pathname.rfind(sep));
1478  if (!altsep.empty()) {
1479  int altsepIndex = static_cast<int>(pathname.rfind(altsep));
1480  sepIndex = ((std::max))(sepIndex, altsepIndex);
1481  }
1482 
1483  size_t dotIndex = pathname.rfind(extsep);
1484  if (dotIndex != std::string::npos) {
1485  // The extsep character exists
1486  size_t npos = std::string::npos;
1487  if ((sepIndex != static_cast<int>(npos) && static_cast<int>(dotIndex) > sepIndex) || sepIndex == static_cast<int>(npos)) {
1488  if (sepIndex == static_cast<int>(npos)) {
1489  sepIndex = 0;
1490  }
1491  size_t filenameIndex = static_cast<size_t>(sepIndex) + static_cast<size_t>(1);
1492 
1493  while (filenameIndex < dotIndex) {
1494  if (pathname.compare(filenameIndex, 1, extsep) != 0) {
1495  return pathname.substr(dotIndex);
1496  }
1497  filenameIndex++;
1498  }
1499  }
1500  }
1501 
1502  return "";
1503 }
1504 
1510 std::string vpIoTools::getName(const std::string &pathname)
1511 {
1512  if (pathname.size() > 0) {
1513  std::string convertedPathname = vpIoTools::path(pathname);
1514 
1515  size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1516  if (index != std::string::npos) {
1517  return convertedPathname.substr(index + 1);
1518  }
1519 
1520  return convertedPathname;
1521  }
1522 
1523  return "";
1524 }
1525 
1532 std::string vpIoTools::getNameWE(const std::string &pathname)
1533 {
1534  std::string name = vpIoTools::getName(pathname);
1535  size_t found = name.find_last_of(".");
1536  std::string name_we = name.substr(0, found);
1537  return name_we;
1538 }
1539 
1573 long vpIoTools::getIndex(const std::string &filename, const std::string &format)
1574 {
1575  size_t indexBegin = format.find_last_of('%');
1576  size_t indexEnd = format.find_first_of('d', indexBegin);
1577  size_t suffixLength = format.length() - indexEnd - 1;
1578 
1579  // Extracting index
1580  if (filename.length() <= suffixLength + indexBegin) {
1581  return -1;
1582  }
1583  size_t indexLength = filename.length() - suffixLength - indexBegin;
1584  std::string indexSubstr = filename.substr(indexBegin, indexLength);
1585  std::istringstream ss(indexSubstr);
1586  long index = 0;
1587  ss >> index;
1588  if (ss.fail() || index < 0 || !ss.eof()) {
1589  return -1;
1590  }
1591 
1592  // Checking that format with inserted index equals filename
1593  char nameByFormat[FILENAME_MAX];
1594  sprintf(nameByFormat, format.c_str(), index);
1595  if (std::string(nameByFormat) != filename) {
1596  return -1;
1597  }
1598  return index;
1599 }
1600 
1606 std::string vpIoTools::getParent(const std::string &pathname)
1607 {
1608  if (pathname.size() > 0) {
1609  std::string convertedPathname = vpIoTools::path(pathname);
1610 
1611  size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1612  if (index != std::string::npos) {
1613  return convertedPathname.substr(0, index);
1614  }
1615  }
1616 
1617  return "";
1618 }
1619 
1628 std::string vpIoTools::getAbsolutePathname(const std::string &pathname)
1629 {
1630 
1631 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1632  std::string real_path_str = pathname;
1633  char *real_path = realpath(pathname.c_str(), NULL);
1634 
1635  if (real_path) {
1636  real_path_str = real_path;
1637  free(real_path);
1638  }
1639  return real_path_str;
1640 #elif defined(_WIN32)
1641 #if (!defined(WINRT))
1642  std::string real_path_str = pathname;
1643  DWORD retval = 0;
1644  TCHAR buffer[4096] = TEXT("");
1645 
1646  retval = GetFullPathName(pathname.c_str(), 4096, buffer, 0);
1647  if (retval != 0) {
1648  real_path_str = buffer;
1649  }
1650  return real_path_str;
1651 #else
1653  "Cannot get absolute path of %s: not implemented on "
1654  "Universal Windows Platform",
1655  pathname.c_str()));
1656 #endif
1657 #endif
1658 }
1659 
1670 std::string vpIoTools::createFilePath(const std::string &parent, const std::string &child)
1671 {
1672  if (child.size() == 0 && parent.size() == 0) {
1673  return "";
1674  }
1675 
1676  if (child.size() == 0) {
1677  return vpIoTools::path(parent);
1678  }
1679 
1680  if (parent.size() == 0) {
1681  return vpIoTools::path(child);
1682  }
1683 
1684  std::string convertedParent = vpIoTools::path(parent);
1685  std::string convertedChild = vpIoTools::path(child);
1686 
1687  std::stringstream ss;
1688  ss << vpIoTools::separator;
1689  std::string stringSeparator;
1690  ss >> stringSeparator;
1691 
1692  std::string lastConvertedParentChar = convertedParent.substr(convertedParent.size() - 1);
1693  std::string firstConvertedChildChar = convertedChild.substr(0, 1);
1694 
1695  if (lastConvertedParentChar == stringSeparator) {
1696  convertedParent = convertedParent.substr(0, convertedParent.size() - 1);
1697  }
1698 
1699  if (firstConvertedChildChar == stringSeparator) {
1700  convertedChild = convertedChild.substr(1);
1701  }
1702 
1703  return std::string(convertedParent + vpIoTools::separator + convertedChild);
1704 }
1705 
1711 bool vpIoTools::isAbsolutePathname(const std::string &pathname)
1712 {
1713  //# Inspired by the Python 2.7.8 module.
1714  //# Return whether a path is absolute.
1715  //# Trivial in Posix, harder on the Mac or MS-DOS.
1716  //# For DOS it is absolute if it starts with a slash or backslash (current
1717  //# volume), or if a pathname after the volume letter and colon / UNC
1718  // resource # starts with a slash or backslash.
1719  //
1720  // def isabs(s):
1721  // """Test whether a path is absolute"""
1722  // s = splitdrive(s)[1]
1723  // return s != '' and s[:1] in '/\\'
1724  std::string path = splitDrive(pathname).second;
1725  return path.size() > 0 && (path.substr(0, 1) == "/" || path.substr(0, 1) == "\\");
1726 }
1727 
1735 bool vpIoTools::isSamePathname(const std::string &pathname1, const std::string &pathname2)
1736 {
1737  // Normalize path
1738  std::string path1_normalize = vpIoTools::path(pathname1);
1739  std::string path2_normalize = vpIoTools::path(pathname2);
1740 
1741  // Get absolute path
1742  path1_normalize = vpIoTools::getAbsolutePathname(path1_normalize);
1743  path2_normalize = vpIoTools::getAbsolutePathname(path2_normalize);
1744 
1745  return (path1_normalize == path2_normalize);
1746 }
1747 
1755 std::pair<std::string, std::string> vpIoTools::splitDrive(const std::string &pathname)
1756 {
1757 //# Split a path in a drive specification (a drive letter followed by a
1758 //# colon) and the path specification.
1759 //# It is always true that drivespec + pathspec == p
1760 // def splitdrive(p):
1761 // """Split a pathname into drive/UNC sharepoint and relative path
1762 // specifiers. Returns a 2-tuple (drive_or_unc, path); either part may be
1763 // empty.
1764 //
1765 // If you assign
1766 // result = splitdrive(p)
1767 // It is always true that:
1768 // result[0] + result[1] == p
1769 //
1770 // If the path contained a drive letter, drive_or_unc will contain
1771 // everything up to and including the colon. e.g. splitdrive("c:/dir")
1772 // returns ("c:", "/dir")
1773 //
1774 // If the path contained a UNC path, the drive_or_unc will contain the host
1775 // name and share up to but not including the fourth directory separator
1776 // character. e.g. splitdrive("//host/computer/dir") returns
1777 // ("//host/computer", "/dir")
1778 //
1779 // Paths cannot contain both a drive letter and a UNC path.
1780 //
1781 // """
1782 // if len(p) > 1:
1783 // normp = p.replace(altsep, sep)
1784 // if (normp[0:2] == sep*2) and (normp[2] != sep):
1785 // # is a UNC path:
1786 // # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
1787 // # \\machine\mountpoint\directory\etc\...
1788 // # directory ^^^^^^^^^^^^^^^
1789 // index = normp.find(sep, 2)
1790 // if index == -1:
1791 // return '', p
1792 // index2 = normp.find(sep, index + 1)
1793 // # a UNC path can't have two slashes in a row
1794 // # (after the initial two)
1795 // if index2 == index + 1:
1796 // return '', p
1797 // if index2 == -1:
1798 // index2 = len(p)
1799 // return p[:index2], p[index2:]
1800 // if normp[1] == ':':
1801 // return p[:2], p[2:]
1802 // return '', p
1803 
1804 // On Unix, the drive is always empty.
1805 // On the Mac, the drive is always empty (don't use the volume name -- it
1806 // doesn't have the same syntactic and semantic oddities as DOS drive
1807 // letters, such as there being a separate current directory per drive).
1808 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
1809  return std::pair<std::string, std::string>("", pathname);
1810 #else
1811  const std::string sep = "\\";
1812  const std::string sepsep = "\\\\";
1813  const std::string altsep = "/";
1814 
1815  if (pathname.size() > 1) {
1816  std::string normPathname = pathname;
1817  std::replace(normPathname.begin(), normPathname.end(), *altsep.c_str(), *sep.c_str());
1818 
1819  if (normPathname.substr(0, 2) == sepsep && normPathname.substr(2, 1) != sep) {
1820  // is a UNC path:
1821  // vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
1822  // \\machine\mountpoint\directory\etc\...
1823  // directory ^^^^^^^^^^^^^^^
1824  size_t index = normPathname.find(sep, 2);
1825  if (index == std::string::npos) {
1826  return std::pair<std::string, std::string>("", pathname);
1827  }
1828 
1829  size_t index2 = normPathname.find(sep, index + 1);
1830  //# a UNC path can't have two slashes in a row
1831  //# (after the initial two)
1832  if (index2 == index + 1) {
1833  return std::pair<std::string, std::string>("", pathname);
1834  }
1835 
1836  if (index2 == std::string::npos) {
1837  index2 = pathname.size();
1838  }
1839 
1840  return std::pair<std::string, std::string>(pathname.substr(0, index2), pathname.substr(index2));
1841  }
1842 
1843  if (normPathname[1] == ':') {
1844  return std::pair<std::string, std::string>(pathname.substr(0, 2), pathname.substr(2));
1845  }
1846  }
1847 
1848  return std::pair<std::string, std::string>("", pathname);
1849 #endif
1850 }
1851 
1900 std::vector<std::string> vpIoTools::splitChain(const std::string &chain, const std::string &sep)
1901 {
1902  size_t startIndex = 0;
1903 
1904  std::string chainToSplit = chain;
1905  std::vector<std::string> subChain;
1906  size_t sepIndex = chainToSplit.find(sep);
1907 
1908  while (sepIndex != std::string::npos) {
1909  std::string sub = chainToSplit.substr(startIndex, sepIndex);
1910  if (!sub.empty())
1911  subChain.push_back(sub);
1912  chainToSplit = chainToSplit.substr(sepIndex + 1, chain.size() - 1);
1913 
1914  sepIndex = chainToSplit.find(sep);
1915  }
1916  if (!chainToSplit.empty())
1917  subChain.push_back(chainToSplit);
1918 
1919  return subChain;
1920 }
1921 
1929 std::vector<std::string> vpIoTools::getDirFiles(const std::string &pathname)
1930 {
1931 
1932  if (!checkDirectory(pathname)) {
1933  throw(vpIoException(vpException::fatalError, "Directory %s doesn't exist'", pathname.c_str()));
1934  }
1935  std::string dirName = path(pathname);
1936 
1937 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1938 
1939  std::vector<std::string> files;
1940  struct dirent **list = NULL;
1941  int filesCount = scandir(dirName.c_str(), &list, NULL, NULL);
1942  if (filesCount == -1) {
1943  throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
1944  }
1945  for (int i = 0; i < filesCount; i++) {
1946  std::string fileName = list[i]->d_name;
1947  if (fileName != "." && fileName != "..") {
1948  files.push_back(fileName);
1949  }
1950  free(list[i]);
1951  }
1952  free(list);
1953  std::sort(files.begin(), files.end());
1954  return files;
1955 
1956 #elif defined(_WIN32)
1957 #if (!defined(WINRT))
1958 
1959  std::vector<std::string> files;
1960  std::string fileMask = dirName;
1961  fileMask.append("\\*");
1962  WIN32_FIND_DATA FindFileData;
1963  HANDLE hFind = FindFirstFile(fileMask.c_str(), &FindFileData);
1964  // Directory is empty
1965  if (HandleToLong(&hFind) == ERROR_FILE_NOT_FOUND) {
1966  return files;
1967  }
1968  if (hFind == INVALID_HANDLE_VALUE) {
1969  throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
1970  }
1971  do {
1972  std::string fileName = FindFileData.cFileName;
1973  if (fileName != "." && fileName != "..") {
1974  files.push_back(fileName);
1975  }
1976  } while (FindNextFile(hFind, &FindFileData));
1977  FindClose(hFind);
1978  std::sort(files.begin(), files.end());
1979  return files;
1980 
1981 #else
1983  "Cannot read files of directory %s: not implemented on "
1984  "Universal Windows Platform",
1985  dirName.c_str()));
1986 #endif
1987 #endif
1988 }
1989 
1993 void vpIoTools::readBinaryValueLE(std::ifstream &file, int16_t &short_value)
1994 {
1995  file.read((char *)(&short_value), sizeof(short_value));
1996 
1997 #ifdef VISP_BIG_ENDIAN
1998  // Swap bytes order from little endian to big endian
1999  short_value = vpEndian::swap16bits((uint16_t)short_value);
2000 #endif
2001 }
2002 
2006 void vpIoTools::readBinaryValueLE(std::ifstream &file, uint16_t &ushort_value)
2007 {
2008  file.read((char *)(&ushort_value), sizeof(ushort_value));
2009 
2010 #ifdef VISP_BIG_ENDIAN
2011  // Swap bytes order from little endian to big endian
2012  ushort_value = vpEndian::swap16bits(ushort_value);
2013 #endif
2014 }
2015 
2019 void vpIoTools::readBinaryValueLE(std::ifstream &file, int32_t &int_value)
2020 {
2021  file.read((char *)(&int_value), sizeof(int_value));
2022 
2023 #ifdef VISP_BIG_ENDIAN
2024  // Swap bytes order from little endian to big endian
2025  int_value = vpEndian::swap32bits((uint32_t)int_value);
2026 #endif
2027 }
2028 
2032 void vpIoTools::readBinaryValueLE(std::ifstream &file, uint32_t &uint_value)
2033 {
2034  file.read((char *)(&uint_value), sizeof(uint_value));
2035 
2036 #ifdef VISP_BIG_ENDIAN
2037  // Swap bytes order from little endian to big endian
2038  uint_value = vpEndian::swap32bits(uint_value);
2039 #endif
2040 }
2041 
2045 void vpIoTools::readBinaryValueLE(std::ifstream &file, float &float_value)
2046 {
2047  file.read((char *)(&float_value), sizeof(float_value));
2048 
2049 #ifdef VISP_BIG_ENDIAN
2050  // Swap bytes order from little endian to big endian
2051  float_value = vpEndian::swapFloat(float_value);
2052 #endif
2053 }
2054 
2058 void vpIoTools::readBinaryValueLE(std::ifstream &file, double &double_value)
2059 {
2060  file.read((char *)(&double_value), sizeof(double_value));
2061 
2062 #ifdef VISP_BIG_ENDIAN
2063  // Swap bytes order from little endian to big endian
2064  double_value = vpEndian::swapDouble(double_value);
2065 #endif
2066 }
2067 
2071 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
2072 {
2073 #ifdef VISP_BIG_ENDIAN
2074  // Swap bytes order to little endian
2075  uint16_t swap_short = vpEndian::swap16bits((uint16_t)short_value);
2076  file.write((char *)(&swap_short), sizeof(swap_short));
2077 #else
2078  file.write((char *)(&short_value), sizeof(short_value));
2079 #endif
2080 }
2081 
2085 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint16_t ushort_value)
2086 {
2087 #ifdef VISP_BIG_ENDIAN
2088  // Swap bytes order to little endian
2089  uint16_t swap_ushort = vpEndian::swap16bits(ushort_value);
2090  file.write((char *)(&swap_ushort), sizeof(swap_ushort));
2091 #else
2092  file.write((char *)(&ushort_value), sizeof(ushort_value));
2093 #endif
2094 }
2095 
2099 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int32_t int_value)
2100 {
2101 #ifdef VISP_BIG_ENDIAN
2102  // Swap bytes order to little endian
2103  uint32_t swap_int = vpEndian::swap32bits((uint32_t)int_value);
2104  file.write((char *)(&swap_int), sizeof(swap_int));
2105 #else
2106  file.write((char *)(&int_value), sizeof(int_value));
2107 #endif
2108 }
2109 
2113 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint32_t uint_value)
2114 {
2115 #ifdef VISP_BIG_ENDIAN
2116  // Swap bytes order to little endian
2117  uint32_t swap_int = vpEndian::swap32bits(uint_value);
2118  file.write((char *)(&swap_int), sizeof(swap_int));
2119 #else
2120  file.write((char *)(&uint_value), sizeof(uint_value));
2121 #endif
2122 }
2123 
2127 void vpIoTools::writeBinaryValueLE(std::ofstream &file, float float_value)
2128 {
2129 #ifdef VISP_BIG_ENDIAN
2130  // Swap bytes order to little endian
2131  float swap_float = vpEndian::swapFloat(float_value);
2132  file.write((char *)(&swap_float), sizeof(swap_float));
2133 #else
2134  file.write((char *)(&float_value), sizeof(float_value));
2135 #endif
2136 }
2137 
2141 void vpIoTools::writeBinaryValueLE(std::ofstream &file, double double_value)
2142 {
2143 #ifdef VISP_BIG_ENDIAN
2144  // Swap bytes order to little endian
2145  double swap_double = vpEndian::swapDouble(double_value);
2146  file.write((char *)(&swap_double), sizeof(swap_double));
2147 #else
2148  file.write((char *)(&double_value), sizeof(double_value));
2149 #endif
2150 }
2151 
2152 bool vpIoTools::parseBoolean(std::string input)
2153 {
2154  std::transform(input.begin(), input.end(), input.begin(), ::tolower);
2155  std::istringstream is(input);
2156  bool b;
2157  // Parse string to boolean either in the textual representation
2158  // (True/False) or in numeric representation (1/0)
2159  is >> (input.size() > 1 ? std::boolalpha : std::noboolalpha) >> b;
2160  return b;
2161 }
2162 
2166 std::string vpIoTools::trim(std::string s)
2167 {
2168  return ltrim(rtrim(s));
2169 }
static void makeDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:570
VISP_EXPORT float swapFloat(float f)
Definition: vpEndian.cpp:68
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:304
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1365
static bool isAbsolutePathname(const std::string &pathname)
Definition: vpIoTools.cpp:1711
static void getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
Definition: vpIoTools.cpp:380
static bool rename(const std::string &oldfilename, const std::string &newfilename)
Definition: vpIoTools.cpp:987
static void readBinaryValueLE(std::ifstream &file, int16_t &short_value)
Definition: vpIoTools.cpp:1993
Class to define RGB colors available for display functionnalities.
Definition: vpColor.h:157
static const char separator
Definition: vpIoTools.h:186
error that can be emited by ViSP classes.
Definition: vpException.h:71
unsigned int getRows() const
Definition: vpArray2D.h:289
static bool copy(const std::string &src, const std::string &dst)
Definition: vpIoTools.cpp:844
static std::string getFileExtension(const std::string &pathname, bool checkFile=false)
Definition: vpIoTools.cpp:1430
Error that can be emited by the vpIoTools class and its derivates.
Definition: vpIoException.h:72
static std::vector< std::string > getDirFiles(const std::string &dirname)
Definition: vpIoTools.cpp:1929
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:1606
static bool checkFifo(const std::string &filename)
Definition: vpIoTools.cpp:480
static std::string path(const std::string &pathname)
Definition: vpIoTools.cpp:1005
static void createBaseNamePath(const bool &empty=false)
Definition: vpIoTools.cpp:1324
static const std::string & getBuildInformation()
Definition: vpIoTools.cpp:135
static bool checkDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:420
static std::string baseDir
Definition: vpIoTools.h:254
unsigned int getCols() const
Definition: vpArray2D.h:279
static void setBaseName(const std::string &s)
Definition: vpIoTools.cpp:233
static bool parseBoolean(std::string input)
Definition: vpIoTools.cpp:2152
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1670
static std::pair< std::string, std::string > splitDrive(const std::string &pathname)
Definition: vpIoTools.cpp:1755
static bool isSamePathname(const std::string &pathname1, const std::string &pathname2)
Definition: vpIoTools.cpp:1735
VISP_EXPORT uint16_t swap16bits(uint16_t val)
Definition: vpEndian.cpp:49
static void makeFifo(const std::string &dirname)
Definition: vpIoTools.cpp:621
VISP_EXPORT double swapDouble(double d)
Definition: vpEndian.cpp:87
static std::string getUserName()
Definition: vpIoTools.cpp:316
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1900
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:153
static void saveConfigFile(const bool &actuallySave=true)
Definition: vpIoTools.cpp:1343
static std::vector< std::string > configVars
Definition: vpIoTools.h:256
static std::string getTempPath()
Definition: vpIoTools.cpp:194
static std::string getName(const std::string &pathname)
Definition: vpIoTools.cpp:1510
VISP_EXPORT uint32_t swap32bits(uint32_t val)
Definition: vpEndian.cpp:58
static void writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
Definition: vpIoTools.cpp:2071
static bool remove(const std::string &filename)
Definition: vpIoTools.cpp:929
static std::string makeTempDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:728
static std::string baseName
Definition: vpIoTools.h:253
static std::string getFullName()
Definition: vpIoTools.cpp:254
static std::string trim(std::string s)
Definition: vpIoTools.cpp:2166
static long getIndex(const std::string &filename, const std::string &format)
Definition: vpIoTools.cpp:1573
static std::string configFile
Definition: vpIoTools.h:255
static void setBaseDir(const std::string &dir)
Definition: vpIoTools.cpp:240
static std::string getNameWE(const std::string &pathname)
Definition: vpIoTools.cpp:1532
static std::string getBaseName()
Definition: vpIoTools.cpp:247
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:802
static std::string getAbsolutePathname(const std::string &pathname)
Definition: vpIoTools.cpp:1628
static vpColor getColor(const unsigned int &i)
Definition: vpColor.h:310
static bool readConfigVar(const std::string &var, float &value)
Definition: vpIoTools.cpp:1092
static std::vector< std::string > configValues
Definition: vpIoTools.h:257
static bool loadConfigFile(const std::string &confFile)
Definition: vpIoTools.cpp:1045
static void addNameElement(const std::string &strTrue, const bool &cond=true, const std::string &strFalse="")
Definition: vpIoTools.cpp:1289
static std::string getenv(const std::string &env)
Definition: vpIoTools.cpp:353