Visual Servoing Platform  version 3.2.1 under development (2019-05-26)
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/vpIoException.h>
58 #include <visp3/core/vpIoTools.h>
59 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
60 #include <dirent.h>
61 #include <unistd.h>
62 #elif defined(_WIN32)
63 #include <direct.h>
64 #include <windows.h>
65 #endif
66 #if !defined(_WIN32)
67  #ifdef __ANDROID__
68  // Like IOS, wordexp.cpp is not defined for Android
69  #else
70  #include <wordexp.h>
71  #endif
72 #endif
73 
74 #if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
75 #include <TargetConditionals.h> // To detect OSX or IOS using TARGET_OS_IOS macro
76 #endif
77 
78 #ifndef PATH_MAX
79 # ifdef _MAX_PATH
80 # define PATH_MAX _MAX_PATH
81 # else
82 # define PATH_MAX 1024
83 # endif
84 #endif
85 
86 // Detect endianness of the host machine
87 // Reference: http://www.boost.org/doc/libs/1_36_0/boost/detail/endian.hpp
88 #if defined(__GLIBC__)
89 #include <endian.h>
90 #if (__BYTE_ORDER == __LITTLE_ENDIAN)
91 #define VISP_LITTLE_ENDIAN
92 #elif (__BYTE_ORDER == __BIG_ENDIAN)
93 #define VISP_BIG_ENDIAN
94 #elif (__BYTE_ORDER == __PDP_ENDIAN)
95 // Currently not supported when reading / writing binary file
96 #define VISP_PDP_ENDIAN
97 //#error PDP endian is not supported. //Uncomment if needed/happens
98 #else
99 #error Unknown machine endianness detected.
100 #endif
101 #elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) || defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
102 #define VISP_BIG_ENDIAN
103 #elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) || defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
104 #define VISP_LITTLE_ENDIAN
105 #elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || defined(__powerpc__) || defined(__ppc__) || \
106  defined(__hpux) || defined(_MIPSEB) || defined(_POWER) || defined(__s390__)
107 
108 #define VISP_BIG_ENDIAN
109 #elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || defined(__ia64__) || defined(_M_IX86) || \
110  defined(_M_IA64) || defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) || \
111  defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || defined(__ANDROID__)
112  // It appears that all Android systems are little endian.
113  // Refer https://stackoverflow.com/questions/6212951/endianness-of-android-ndk
114 #define VISP_LITTLE_ENDIAN
115 #elif defined(WINRT) // For UWP
116 // Refer https://social.msdn.microsoft.com/Forums/en-US/04c92ef9-e38e-415f-8958-ec9f7c196fd3/arm-endianess-under-windows-mobile?forum=windowsmobiledev
117 #define VISP_LITTLE_ENDIAN
118 #else
119 #error Cannot detect host machine endianness.
120 #endif
121 
122 std::string vpIoTools::baseName = "";
123 std::string vpIoTools::baseDir = "";
124 std::string vpIoTools::configFile = "";
125 std::vector<std::string> vpIoTools::configVars = std::vector<std::string>();
126 std::vector<std::string> vpIoTools::configValues = std::vector<std::string>();
127 
128 namespace
129 {
130 // The following code is not working on iOS since wordexp() is not available
131 // The function is not used on Android
132 #if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
133 #if (TARGET_OS_IOS == 0) && !defined(__ANDROID__)
134 void replaceAll(std::string &str, const std::string &search, const std::string &replace)
135 {
136  size_t start_pos = 0;
137  while ((start_pos = str.find(search, start_pos)) != std::string::npos) {
138  str.replace(start_pos, search.length(), replace);
139  start_pos += replace.length(); // Handles case where 'replace' is a
140  // substring of 'search'
141  }
142 }
143 #endif
144 #endif
145 
146 #ifdef VISP_BIG_ENDIAN
147 // Swap 16 bits by shifting to the right the first byte and by shifting to the
148 // left the second byte
149 uint16_t swap16bits(const uint16_t val)
150 {
151  return (((val >> 8) & 0x00FF) | ((val << 8) & 0xFF00));
152 }
153 
154 // Swap 32 bits by shifting to the right the first 2 bytes and by shifting to
155 // the left the last 2 bytes
156 uint32_t swap32bits(const uint32_t val)
157 {
158  return (((val >> 24) & 0x000000FF) | ((val >> 8) & 0x0000FF00) | ((val << 8) & 0x00FF0000) |
159  ((val << 24) & 0xFF000000));
160 }
161 
162 // Swap a float, the union is necessary because of the representation of a
163 // float in memory in IEEE 754.
164 float swapFloat(const float f)
165 {
166  union {
167  float f;
168  unsigned char b[4];
169  } dat1, dat2;
170 
171  dat1.f = f;
172  dat2.b[0] = dat1.b[3];
173  dat2.b[1] = dat1.b[2];
174  dat2.b[2] = dat1.b[1];
175  dat2.b[3] = dat1.b[0];
176  return dat2.f;
177 }
178 
179 // Swap a double, the union is necessary because of the representation of a
180 // double in memory in IEEE 754.
181 double swapDouble(const double d)
182 {
183  union {
184  double d;
185  unsigned char b[8];
186  } dat1, dat2;
187 
188  dat1.d = d;
189  dat2.b[0] = dat1.b[7];
190  dat2.b[1] = dat1.b[6];
191  dat2.b[2] = dat1.b[5];
192  dat2.b[3] = dat1.b[4];
193  dat2.b[4] = dat1.b[3];
194  dat2.b[5] = dat1.b[2];
195  dat2.b[6] = dat1.b[1];
196  dat2.b[7] = dat1.b[0];
197  return dat2.d;
198 }
199 #endif
200 
201 std::string &ltrim(std::string &s)
202 {
203  s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
204  return s;
205 }
206 
207 std::string &rtrim(std::string &s)
208 {
209  s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
210  return s;
211 }
212 }
213 
217 const std::string &vpIoTools::getBuildInformation()
218 {
219  static std::string build_info =
220 #include "version_string.inc"
221  ;
222  return build_info;
223 }
224 
230 void vpIoTools::setBaseName(const std::string &s) { baseName = s; }
236 void vpIoTools::setBaseDir(const std::string &dir) { baseDir = dir + "/"; }
242 std::string vpIoTools::getBaseName() { return baseName; }
248 std::string vpIoTools::getFullName() { return baseDir + baseName; }
249 
265 void vpIoTools::getUserName(std::string &username)
266 {
267 // With MinGW, UNIX and _WIN32 are defined
268 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
269  // Get the user name.
270  char *_username = NULL;
271  _username = ::getenv("LOGNAME");
272  if (_username == NULL) {
273  username = "unknown";
274  }
275  else {
276  username = _username;
277  }
278 #elif defined(_WIN32)
279 #if (!defined(WINRT))
280  unsigned int info_buffer_size = 1024;
281  TCHAR *infoBuf = new TCHAR[info_buffer_size];
282  DWORD bufCharCount = (DWORD)info_buffer_size;
283  // Get the user name.
284  if (!GetUserName(infoBuf, &bufCharCount)) {
285  delete[] infoBuf;
286  throw(vpIoException(vpIoException::cantGetUserName, "Cannot get the username"));
287  }
288  username = infoBuf;
289  delete[] infoBuf;
290 #else
291  // Universal platform
292  username = "unknown";
293 #endif
294 #else
295  username = "unknown";
296 #endif
297 }
316 {
317  std::string username;
318 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
319  // Get the user name.
320  char *_username = NULL;
321  _username = ::getenv("LOGNAME");
322  if (_username == NULL) {
323  vpERROR_TRACE("Cannot get the username. Check your LOGNAME environment variable");
324  throw(vpIoException(vpIoException::cantGetUserName, "Cannot get the username"));
325  }
326  username = _username;
327 #elif defined(_WIN32)
328 #if (!defined(WINRT))
329  unsigned int info_buffer_size = 1024;
330  TCHAR *infoBuf = new TCHAR[info_buffer_size];
331  DWORD bufCharCount = (DWORD)info_buffer_size;
332  // Get the user name.
333  if (!GetUserName(infoBuf, &bufCharCount)) {
334  delete[] infoBuf;
335  vpERROR_TRACE("Cannot get the username");
336  throw(vpIoException(vpIoException::cantGetUserName, "Cannot get the username"));
337  }
338  username = infoBuf;
339  delete[] infoBuf;
340 #else
341  throw(vpIoException(vpIoException::cantGetUserName, "Cannot get the username: not implemented on Universal "
342  "Windows Platform"));
343 #endif
344 #endif
345  return username;
346 }
347 
379 std::string vpIoTools::getenv(const char *env)
380 {
381 #if defined(_WIN32) && defined(WINRT)
382  throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value: not "
383  "implemented on Universal Windows Platform"));
384 #else
385  std::string value;
386  // Get the environment variable value.
387  char *_value = NULL;
388  _value = ::getenv(env);
389  if (_value == NULL) {
390  throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value"));
391  }
392  value = _value;
393 
394  return value;
395 #endif
396 }
397 
430 std::string vpIoTools::getenv(const std::string &env) { return (vpIoTools::getenv(env.c_str())); }
431 
441 void vpIoTools::getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
442 {
443  if (version.size() == 0) {
444  major = 0;
445  minor = 0;
446  patch = 0;
447  } else {
448  size_t major_pos = version.find('.');
449  std::string major_str = version.substr(0, major_pos);
450  major = (unsigned)atoi(major_str.c_str());
451 
452  if (major_pos != std::string::npos) {
453  size_t minor_pos = version.find('.', major_pos + 1);
454  std::string minor_str = version.substr(major_pos + 1, (minor_pos - (major_pos + 1)));
455  minor = (unsigned)atoi(minor_str.c_str());
456 
457  if (minor_pos != std::string::npos) {
458  std::string patch_str = version.substr(minor_pos + 1);
459  patch = (unsigned)atoi(patch_str.c_str());
460  } else {
461  patch = 0;
462  }
463  } else {
464  minor = 0;
465  patch = 0;
466  }
467  }
468 }
469 
484 bool vpIoTools::checkDirectory(const char *dirname)
485 {
486 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
487  struct stat stbuf;
488 #elif defined(_WIN32) && defined(__MINGW32__)
489  struct stat stbuf;
490 #elif defined(_WIN32)
491  struct _stat stbuf;
492 #endif
493 
494  if (dirname == NULL || dirname[0] == '\0') {
495  return false;
496  }
497 
498  std::string _dirname = path(dirname);
499 
500 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
501  if (stat(_dirname.c_str(), &stbuf) != 0)
502 #elif defined(_WIN32) && defined(__MINGW32__)
503  // Remove trailing separator character if any
504  // AppVeyor: Windows 6.3.9600 AMD64 ; C:/MinGW/bin/g++.exe (ver 5.3.0) ;
505  // GNU Make 3.82.90 Built for i686-pc-mingw32
506  if (!_dirname.empty() && _dirname.at(_dirname.size() - 1) == vpIoTools::separator)
507  _dirname = _dirname.substr(0, _dirname.size() - 1);
508  if (stat(_dirname.c_str(), &stbuf) != 0)
509 #elif defined(_WIN32)
510  if (_stat(_dirname.c_str(), &stbuf) != 0)
511 #endif
512  {
513  return false;
514  }
515 #if defined(_WIN32) || (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
516  if ((stbuf.st_mode & S_IFDIR) == 0)
517 #endif
518  {
519  return false;
520  }
521 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
522  if ((stbuf.st_mode & S_IWUSR) == 0)
523 #elif defined(_WIN32)
524  if ((stbuf.st_mode & S_IWRITE) == 0)
525 #endif
526  {
527  return false;
528  }
529  return true;
530 }
531 
545 bool vpIoTools::checkDirectory(const std::string &dirname) { return vpIoTools::checkDirectory(dirname.c_str()); }
546 
547 // See:
548 // https://gist.github.com/JonathonReinhart/8c0d90191c38af2dcadb102c4e202950
549 int vpIoTools::mkdir_p(const char *path, const int mode)
550 {
551  /* Adapted from http://stackoverflow.com/a/2336245/119527 */
552  const size_t len = strlen(path);
553  char _path[PATH_MAX];
554  char *p = NULL;
555  const char sep = vpIoTools::separator;
556 
557  std::fill(_path, _path + PATH_MAX, 0);
558 
559  errno = 0;
560  if (len > sizeof(_path) - 1) {
561  errno = ENAMETOOLONG;
562  return -1;
563  }
564  /* Copy string so its mutable */
565  strcpy(_path, path);
566 
567  /* Iterate over the string */
568  for (p = _path + 1; *p; p++) { // path cannot be empty
569  if (*p == sep) {
570  /* Temporarily truncate */
571  *p = '\0';
572 
573 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
574  if (mkdir(_path, (mode_t)mode) != 0)
575 #elif defined(_WIN32)
576  (void)mode; // var not used
577  if (!checkDirectory(_path) && _mkdir(_path) != 0)
578 #endif
579  {
580  if (errno != EEXIST)
581  return -1;
582  }
583  *p = sep;
584  }
585  }
586 
587 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
588  if (mkdir(_path, (mode_t)mode) != 0)
589 #elif defined(_WIN32)
590  if (_mkdir(_path) != 0)
591 #endif
592  {
593  if (errno != EEXIST)
594  return -1;
595  }
596 
597  return 0;
598 }
599 
614 void vpIoTools::makeDirectory(const char *dirname)
615 {
616 #if ((!defined(__unix__) && !defined(__unix) && (!defined(__APPLE__) || !defined(__MACH__)))) && !defined(_WIN32)
617  std::cerr << "Unsupported platform for vpIoTools::makeDirectory()!" << std::endl;
618  return;
619 #endif
620 
621 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
622  struct stat stbuf;
623 #elif defined(_WIN32) && defined(__MINGW32__)
624  struct stat stbuf;
625 #elif defined(_WIN32)
626  struct _stat stbuf;
627 #endif
628 
629  if (dirname == NULL || dirname[0] == '\0') {
630  vpERROR_TRACE("invalid directory name\n");
631  throw(vpIoException(vpIoException::invalidDirectoryName, "invalid directory name"));
632  }
633 
634  std::string _dirname = path(dirname);
635 
636 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
637  if (stat(_dirname.c_str(), &stbuf) != 0)
638 #elif defined(_WIN32) && defined(__MINGW32__)
639  if (stat(_dirname.c_str(), &stbuf) != 0)
640 #elif defined(_WIN32)
641  if (_stat(_dirname.c_str(), &stbuf) != 0)
642 #endif
643  {
644  if (vpIoTools::mkdir_p(_dirname.c_str(), 0755) != 0) {
645  vpERROR_TRACE("unable to create directory '%s'\n", dirname);
646  throw(vpIoException(vpIoException::cantCreateDirectory, "unable to create directory"));
647  }
648 
649  vpDEBUG_TRACE(2, "has created directory '%s'\n", dirname);
650  }
651 
652  if (checkDirectory(dirname) == false) {
653  vpERROR_TRACE("unable to create directory '%s'\n", dirname);
654  throw(vpIoException(vpIoException::cantCreateDirectory, "unable to create directory"));
655  }
656 }
657 
670 void vpIoTools::makeDirectory(const std::string &dirname)
671 {
672  try {
673  vpIoTools::makeDirectory(dirname.c_str());
674  } catch (...) {
675  vpERROR_TRACE("unable to create directory '%s'\n", dirname.c_str());
676  throw(vpIoException(vpIoException::cantCreateDirectory, "unable to create directory"));
677  }
678 }
679 
692 bool vpIoTools::checkFilename(const char *filename)
693 {
694 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
695  struct stat stbuf;
696 #elif defined(_WIN32)
697  struct _stat stbuf;
698 #endif
699 
700  if (filename == NULL || filename[0] == '\0') {
701  return false;
702  }
703 
704  std::string _filename = path(filename);
705 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
706  if (stat(_filename.c_str(), &stbuf) != 0)
707 #elif defined(_WIN32)
708  if (_stat(_filename.c_str(), &stbuf) != 0)
709 #endif
710  {
711  return false;
712  }
713  if ((stbuf.st_mode & S_IFREG) == 0) {
714  return false;
715  }
716 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
717  if ((stbuf.st_mode & S_IRUSR) == 0)
718 #elif defined(_WIN32)
719  if ((stbuf.st_mode & S_IREAD) == 0)
720 #endif
721  {
722  return false;
723  }
724  return true;
725 }
726 
739 bool vpIoTools::checkFilename(const std::string &filename) { return vpIoTools::checkFilename(filename.c_str()); }
740 
753 bool vpIoTools::copy(const char *src, const char *dst)
754 {
755  // Check if we have to consider a file or a directory
756  if (vpIoTools::checkFilename(src)) {
757 // std::cout << "copy file: " << src << " in " << dst << std::endl;
758 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
759 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
760  // wordexp() is not available
761  char cmd[FILENAME_MAX];
762  int ret;
763  sprintf(cmd, "cp -p %s %s", src, dst);
764  ret = system(cmd);
765  if (ret) {
766  }; // to avoid a warning
767  // std::cout << cmd << " return value: " << ret << std::endl;
768  return true;
769 #else
770  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src, dst));
771 #endif
772 #elif defined(_WIN32)
773 #if (!defined(WINRT))
774  char cmd[FILENAME_MAX];
775  int ret;
776  std::string src_ = vpIoTools::path(src);
777  std::string dst_ = vpIoTools::path(dst);
778  sprintf(cmd, "copy %s %s", src_.c_str(), dst_.c_str());
779  ret = system(cmd);
780  if (ret) {
781  }; // to avoid a warning
782  // std::cout << cmd << " return value: " << ret << std::endl;
783  return true;
784 #else
785  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
786  src, dst));
787 #endif
788 #endif
789  } else if (vpIoTools::checkDirectory(src)) {
790 // std::cout << "copy directory: " << src << " in " << dst << std::endl;
791 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
792 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
793  // wordexp() is not available
794  char cmd[FILENAME_MAX];
795  int ret;
796  sprintf(cmd, "cp -p -r %s %s", src, dst);
797  ret = system(cmd);
798  if (ret) {
799  }; // to avoid a warning
800  // std::cout << cmd << " return value: " << ret << std::endl;
801  return true;
802 #else
803  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src, dst));
804 #endif
805 #elif defined(_WIN32)
806 #if (!defined(WINRT))
807  char cmd[FILENAME_MAX];
808  int ret;
809  std::string src_ = vpIoTools::path(src);
810  std::string dst_ = vpIoTools::path(dst);
811  sprintf(cmd, "copy %s %s", src_.c_str(), dst_.c_str());
812  ret = system(cmd);
813  if (ret) {
814  }; // to avoid a warning
815  // std::cout << cmd << " return value: " << ret << std::endl;
816  return true;
817 #else
818  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
819  src, dst));
820 #endif
821 #endif
822  } else {
823  std::cout << "Cannot copy: " << src << " in " << dst << std::endl;
824  return false;
825  }
826 }
839 bool vpIoTools::copy(const std::string &src, const std::string &dst)
840 {
841  return vpIoTools::copy(src.c_str(), dst.c_str());
842 }
843 
854 bool vpIoTools::remove(const char *file_or_dir)
855 {
856  // Check if we have to consider a file or a directory
857  if (vpIoTools::checkFilename(file_or_dir)) {
858  // std::cout << "remove file: " << file_or_dir << std::endl;
859  if (::remove(file_or_dir) != 0)
860  return false;
861  else
862  return true;
863  } else if (vpIoTools::checkDirectory(file_or_dir)) {
864 // std::cout << "remove directory: " << file_or_dir << std::endl;
865 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
866 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
867  // wordexp() is not available
868  char cmd[FILENAME_MAX];
869  sprintf(cmd, "rm -rf \"%s\"", file_or_dir);
870  int 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 remove %s: not implemented on iOS Platform", file_or_dir));
877 #endif
878 #elif defined(_WIN32)
879 #if (!defined(WINRT))
880  char cmd[FILENAME_MAX];
881  std::string file_or_dir_ = vpIoTools::path(file_or_dir);
882  sprintf(cmd, "rmdir /S /Q %s", file_or_dir_.c_str());
883  int ret = system(cmd);
884  if (ret) {
885  }; // to avoid a warning
886  // std::cout << cmd << " return value: " << ret << std::endl;
887  return true;
888 #else
889  throw(vpIoException(vpException::fatalError, "Cannot remove %s: not implemented on Universal Windows Platform",
890  file_or_dir));
891 #endif
892 #endif
893  } else {
894  std::cout << "Cannot remove: " << file_or_dir << std::endl;
895  return false;
896  }
897 }
909 bool vpIoTools::remove(const std::string &file_or_dir) { return vpIoTools::remove(file_or_dir.c_str()); }
910 
922 bool vpIoTools::rename(const char *oldfilename, const char *newfilename)
923 {
924  if (::rename(oldfilename, newfilename) != 0)
925  return false;
926  else
927  return true;
928 }
929 
941 bool vpIoTools::rename(const std::string &oldfilename, const std::string &newfilename)
942 {
943  return vpIoTools::rename(oldfilename.c_str(), newfilename.c_str());
944 }
945 
958 std::string vpIoTools::path(const char *pathname)
959 {
960  std::string path(pathname);
961 
962 #if defined(_WIN32)
963  for (unsigned int i = 0; i < path.length(); i++)
964  if (path[i] == '/')
965  path[i] = '\\';
966 #elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
967  for (unsigned int i = 0; i < path.length(); i++)
968  if (path[i] == '\\')
969  path[i] = '/';
970 #if TARGET_OS_IOS == 0 // The following code is not working on iOS and android since
971  // wordexp() is not available
972  #ifdef __ANDROID__
973  // Do nothing
974  #else
975  wordexp_t exp_result;
976 
977  // escape quote character
978  replaceAll(path, "'", "'\\''");
979  // add quotes to handle special characters like parentheses and spaces
980  wordexp(std::string("'" + path + "'").c_str(), &exp_result, 0);
981  path = exp_result.we_wordc == 1 ? exp_result.we_wordv[0] : "";
982  wordfree(&exp_result);
983  #endif
984 #endif
985 #endif
986 
987  return path;
988 }
989 
1002 std::string vpIoTools::path(const std::string &pathname) { return path(pathname.c_str()); }
1003 
1012 bool vpIoTools::loadConfigFile(const std::string &confFile)
1013 {
1014  configFile = path(confFile);
1015  configVars.clear();
1016  configValues.clear();
1017  std::ifstream confContent(configFile.c_str(), std::ios::in);
1018 
1019  if (confContent.is_open()) {
1020  std::string line, var, val;
1021  long unsigned int k;
1022  int c;
1023  std::string stop[3] = {" ", "\t", "#"};
1024  while (std::getline(confContent, line)) {
1025  if ((line.compare(0, 1, "#") != 0) && (line.size() > 2)) {
1026  try {
1027  // name of the variable
1028  k = (unsigned long)line.find(" ");
1029  var = line.substr(0, k);
1030  // look for the end of the actual value
1031  c = 200;
1032  for (unsigned i = 0; i < 3; ++i)
1033  c = vpMath::minimum(c, (int)line.find(stop[i], (size_t)k + (size_t)1));
1034  if (c == -1)
1035  c = (int)line.size();
1036  long unsigned int c_ = (long unsigned int)c;
1037  val = line.substr((size_t)(k) + (size_t)(1), (size_t)c_ - (size_t)k - (size_t)1);
1038  configVars.push_back(var);
1039  configValues.push_back(val);
1040  } catch (...) {
1041  }
1042  }
1043  }
1044  confContent.close();
1045  } else {
1046  return false;
1047  }
1048  return true;
1049 }
1050 
1059 bool vpIoTools::readConfigVar(const std::string &var, float &value)
1060 {
1061  bool found = false;
1062  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1063  if (configVars[k] == var) {
1064  if (configValues[k].compare("PI") == 0)
1065  value = (float)M_PI;
1066  else if (configValues[k].compare("PI/2") == 0)
1067  value = (float)(M_PI / 2.0);
1068  else if (configValues[k].compare("-PI/2") == 0)
1069  value = (float)(-M_PI / 2.0);
1070  else
1071  value = (float)atof(configValues[k].c_str());
1072  found = true;
1073  }
1074  }
1075  if (found == false)
1076  std::cout << var << " not found in config file" << std::endl;
1077  return found;
1078 }
1087 bool vpIoTools::readConfigVar(const std::string &var, double &value)
1088 {
1089  bool found = false;
1090  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1091  if (configVars[k] == var) {
1092  if (configValues[k].compare("PI") == 0)
1093  value = M_PI;
1094  else if (configValues[k].compare("PI/2") == 0)
1095  value = M_PI / 2;
1096  else if (configValues[k].compare("-PI/2") == 0)
1097  value = -M_PI / 2;
1098  else
1099  value = atof(configValues[k].c_str());
1100  found = true;
1101  }
1102  }
1103  if (found == false)
1104  std::cout << var << " not found in config file" << std::endl;
1105  return found;
1106 }
1107 
1116 bool vpIoTools::readConfigVar(const std::string &var, int &value)
1117 {
1118  bool found = false;
1119  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1120  if (configVars[k] == var) {
1121  value = atoi(configValues[k].c_str());
1122  found = true;
1123  }
1124  }
1125  if (found == false)
1126  std::cout << var << " not found in config file" << std::endl;
1127  return found;
1128 }
1129 
1138 bool vpIoTools::readConfigVar(const std::string &var, unsigned int &value)
1139 {
1140  int v = 0;
1141  bool found = readConfigVar(var, v);
1142  value = (unsigned int)v;
1143  return found;
1144 }
1145 
1154 bool vpIoTools::readConfigVar(const std::string &var, bool &value)
1155 {
1156  int v = 0;
1157  bool found = readConfigVar(var, v);
1158  value = (v != 0);
1159  return found;
1160 }
1161 
1170 bool vpIoTools::readConfigVar(const std::string &var, vpColor &value)
1171 {
1172  unsigned int v = 0;
1173  bool found = readConfigVar(var, v);
1174  value = vpColor::getColor(v);
1175  return found;
1176 }
1177 
1186 bool vpIoTools::readConfigVar(const std::string &var, std::string &value)
1187 {
1188  bool found = false;
1189  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1190  if (configVars[k] == var) {
1191  value = configValues[k];
1192  found = true;
1193  }
1194  }
1195  if (found == false)
1196  std::cout << var << " not found in config file" << std::endl;
1197  return found;
1198 }
1199 
1213 bool vpIoTools::readConfigVar(const std::string &var, vpArray2D<double> &value, const unsigned int &nCols,
1214  const unsigned int &nRows)
1215 {
1216  bool found = false;
1217  std::string nb;
1218  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1219  if (configVars[k] == var) {
1220  found = true;
1221  // resize or not
1222  if (nCols != 0 && nRows != 0)
1223  value.resize(nRows, nCols);
1224  size_t ind = 0, ind2;
1225  for (unsigned int i = 0; i < value.getRows(); ++i)
1226  for (unsigned int j = 0; j < value.getCols(); ++j) {
1227  ind2 = configValues[k].find(",", ind);
1228  nb = configValues[k].substr(ind, ind2 - ind);
1229  if (nb.compare("PI") == 0)
1230  value[i][j] = M_PI;
1231  else if (nb.compare("PI/2") == 0)
1232  value[i][j] = M_PI / 2;
1233  else if (nb.compare("-PI/2") == 0)
1234  value[i][j] = -M_PI / 2;
1235  else
1236  value[i][j] = atof(nb.c_str());
1237  ind = ind2 + 1;
1238  }
1239  }
1240  }
1241  if (found == false)
1242  std::cout << var << " not found in config file" << std::endl;
1243  return found;
1244 }
1245 
1246 // construct experiment filename & path
1247 
1256 void vpIoTools::addNameElement(const std::string &strTrue, const bool &cond, const std::string &strFalse)
1257 {
1258  if (cond)
1259  baseName += "_" + strTrue;
1260  else if (strFalse != "")
1261  baseName += "_" + strFalse;
1262 }
1263 
1272 void vpIoTools::addNameElement(const std::string &strTrue, const double &val)
1273 {
1274  // if(val != 0.)
1275  if (std::fabs(val) < std::numeric_limits<double>::epsilon()) {
1276  char valC[256];
1277  sprintf(valC, "%.3f", val);
1278  std::string valS(valC);
1279  baseName += "_" + strTrue + valS;
1280  }
1281 }
1282 
1291 void vpIoTools::createBaseNamePath(const bool &empty)
1292 {
1293  if (vpIoTools::checkDirectory(baseDir + baseName) == false) {
1295  std::cout << "creating directory " + baseDir + baseName << std::endl;
1296  } else {
1297  if (empty) {
1298  std::cout << "emptying directory " + baseDir + baseName << std::endl;
1300  }
1301  }
1302 }
1303 
1310 void vpIoTools::saveConfigFile(const bool &actuallySave)
1311 {
1312  if (actuallySave) {
1313  std::string dest = baseDir + "/" + baseName + "_config.txt";
1314  // file copy
1315  vpIoTools::copy(configFile, dest);
1316  }
1317 }
1318 
1334 {
1335  std::string data_path;
1336  std::string file_to_test("mbt/cube.cao");
1337  std::string filename;
1338 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1339  // Test if visp-images-data package is u-installed (Ubuntu and Debian)
1340  data_path = "/usr/share/visp-images-data/ViSP-images";
1341  filename = data_path + "/" + file_to_test;
1342  if (vpIoTools::checkFilename(filename))
1343  return data_path;
1344  data_path = "/usr/share/visp-images-data/visp-images";
1345  filename = data_path + "/" + file_to_test;
1346  if (vpIoTools::checkFilename(filename))
1347  return data_path;
1348 #endif
1349  // Test if VISP_INPUT_IMAGE_PATH env var is set
1350  try {
1351  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH");
1352  filename = data_path + "/" + file_to_test;
1353  if (vpIoTools::checkFilename(filename))
1354  return data_path;
1355  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/ViSP-images";
1356  filename = data_path + "/" + file_to_test;
1357  if (vpIoTools::checkFilename(filename))
1358  return data_path;
1359  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/visp-images";
1360  filename = data_path + "/" + file_to_test;
1361  if (vpIoTools::checkFilename(filename))
1362  return data_path;
1363  } catch (...) {
1364  }
1365  data_path = "";
1366  return data_path;
1367 }
1368 
1398 std::string vpIoTools::getFileExtension(const std::string &pathname, const bool checkFile)
1399 {
1400  if (checkFile && (vpIoTools::checkDirectory(pathname) || !vpIoTools::checkFilename(pathname))) {
1401  return "";
1402  }
1403 
1404 #if defined(_WIN32)
1405  std::string sep = "\\";
1406  std::string altsep = "/";
1407  std::string extsep = ".";
1408 #else
1409  // On Unix, or on the Mac
1410  std::string sep = "/";
1411  std::string altsep = "";
1412  std::string extsep = ".";
1413 #endif
1414 
1415  // Python 2.7.8 module.
1416  //# Split a path in root and extension.
1417  //# The extension is everything starting at the last dot in the last
1418  //# pathname component; the root is everything before that.
1419  //# It is always true that root + ext == p.
1420  //
1421  //# Generic implementation of splitext, to be parametrized with
1422  //# the separators
1423  // def _splitext(p, sep, altsep, extsep):
1424  // """Split the extension from a pathname.
1425  //
1426  // Extension is everything from the last dot to the end, ignoring
1427  // leading dots. Returns "(root, ext)"; ext may be empty."""
1428  //
1429  // sepIndex = p.rfind(sep)
1430  // if altsep:
1431  // altsepIndex = p.rfind(altsep)
1432  // sepIndex = max(sepIndex, altsepIndex)
1433  //
1434  // dotIndex = p.rfind(extsep)
1435  // if dotIndex > sepIndex:
1436  // # skip all leading dots
1437  // filenameIndex = sepIndex + 1
1438  // while filenameIndex < dotIndex:
1439  // if p[filenameIndex] != extsep:
1440  // return p[:dotIndex], p[dotIndex:]
1441  // filenameIndex += 1
1442  //
1443  // return p, ''
1444 
1445  int sepIndex = (int)pathname.rfind(sep);
1446  if (!altsep.empty()) {
1447  int altsepIndex = (int)pathname.rfind(altsep);
1448  sepIndex = ((std::max))(sepIndex, altsepIndex);
1449  }
1450 
1451  size_t dotIndex = pathname.rfind(extsep);
1452  if (dotIndex != std::string::npos) {
1453  // The extsep character exists
1454  if ((sepIndex != (int)std::string::npos && (int)dotIndex > sepIndex) || sepIndex == (int)std::string::npos) {
1455  if (sepIndex == (int)std::string::npos) {
1456  sepIndex = -1;
1457  }
1458  size_t filenameIndex = (size_t)(sepIndex) + (size_t)(1);
1459 
1460  while (filenameIndex < dotIndex) {
1461  if (pathname.compare(filenameIndex, 1, extsep) != 0) {
1462  return pathname.substr(dotIndex);
1463  }
1464  filenameIndex++;
1465  }
1466  }
1467  }
1468 
1469  return "";
1470 }
1471 
1477 std::string vpIoTools::getName(const std::string &pathname)
1478 {
1479  if (pathname.size() > 0) {
1480  std::string convertedPathname = vpIoTools::path(pathname);
1481 
1482  size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1483  if (index != std::string::npos) {
1484  return convertedPathname.substr(index + 1);
1485  }
1486 
1487  return convertedPathname;
1488  }
1489 
1490  return "";
1491 }
1492 
1499 std::string vpIoTools::getNameWE(const std::string &pathname)
1500 {
1501  std::string name = vpIoTools::getName(pathname);
1502  size_t found = name.find_last_of(".");
1503  std::string name_we = name.substr(0, found);
1504  return name_we;
1505 }
1506 
1512 std::string vpIoTools::getParent(const std::string &pathname)
1513 {
1514  if (pathname.size() > 0) {
1515  std::string convertedPathname = vpIoTools::path(pathname);
1516 
1517  size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1518  if (index != std::string::npos) {
1519  return convertedPathname.substr(0, index);
1520  }
1521  }
1522 
1523  return "";
1524 }
1525 
1534 std::string vpIoTools::getAbsolutePathname(const std::string &pathname)
1535 {
1536 
1537 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1538  std::string real_path_str = pathname;
1539  char *real_path = realpath(pathname.c_str(), NULL);
1540 
1541  if (real_path != NULL) {
1542  real_path_str = real_path;
1543  free(real_path);
1544  }
1545  return real_path_str;
1546 #elif defined(_WIN32)
1547 #if (!defined(WINRT))
1548  std::string real_path_str = pathname;
1549  DWORD retval = 0;
1550  TCHAR buffer[4096] = TEXT("");
1551 
1552  retval = GetFullPathName(pathname.c_str(), 4096, buffer, 0);
1553  if (retval != 0) {
1554  real_path_str = buffer;
1555  }
1556  return real_path_str;
1557 #else
1559  "Cannot get absolute path of %s: not implemented on "
1560  "Universal Windows Platform",
1561  pathname.c_str()));
1562 #endif
1563 #endif
1564 }
1565 
1576 std::string vpIoTools::createFilePath(const std::string &parent, const std::string &child)
1577 {
1578  if (child.size() == 0 && parent.size() == 0) {
1579  return "";
1580  }
1581 
1582  if (child.size() == 0) {
1583  return vpIoTools::path(parent);
1584  }
1585 
1586  if (parent.size() == 0) {
1587  return vpIoTools::path(child);
1588  }
1589 
1590  std::string convertedParent = vpIoTools::path(parent);
1591  std::string convertedChild = vpIoTools::path(child);
1592 
1593  std::stringstream ss;
1594  ss << vpIoTools::separator;
1595  std::string stringSeparator;
1596  ss >> stringSeparator;
1597 
1598  std::string lastConvertedParentChar = convertedParent.substr(convertedParent.size() - 1);
1599  std::string firstConvertedChildChar = convertedChild.substr(0, 1);
1600 
1601  if (lastConvertedParentChar == stringSeparator) {
1602  convertedParent = convertedParent.substr(0, convertedParent.size() - 1);
1603  }
1604 
1605  if (firstConvertedChildChar == stringSeparator) {
1606  convertedChild = convertedChild.substr(1);
1607  }
1608 
1609  return std::string(convertedParent + vpIoTools::separator + convertedChild);
1610 }
1611 
1617 bool vpIoTools::isAbsolutePathname(const std::string &pathname)
1618 {
1619  //# Inspired by the Python 2.7.8 module.
1620  //# Return whether a path is absolute.
1621  //# Trivial in Posix, harder on the Mac or MS-DOS.
1622  //# For DOS it is absolute if it starts with a slash or backslash (current
1623  //# volume), or if a pathname after the volume letter and colon / UNC
1624  // resource # starts with a slash or backslash.
1625  //
1626  // def isabs(s):
1627  // """Test whether a path is absolute"""
1628  // s = splitdrive(s)[1]
1629  // return s != '' and s[:1] in '/\\'
1630  std::string path = splitDrive(pathname).second;
1631  return path.size() > 0 && (path.substr(0, 1) == "/" || path.substr(0, 1) == "\\");
1632 }
1633 
1641 bool vpIoTools::isSamePathname(const std::string &pathname1, const std::string &pathname2)
1642 {
1643  // Normalize path
1644  std::string path1_normalize = vpIoTools::path(pathname1);
1645  std::string path2_normalize = vpIoTools::path(pathname2);
1646 
1647  // Get absolute path
1648  path1_normalize = vpIoTools::getAbsolutePathname(path1_normalize);
1649  path2_normalize = vpIoTools::getAbsolutePathname(path2_normalize);
1650 
1651  return (path1_normalize == path2_normalize);
1652 }
1653 
1661 std::pair<std::string, std::string> vpIoTools::splitDrive(const std::string &pathname)
1662 {
1663 //# Split a path in a drive specification (a drive letter followed by a
1664 //# colon) and the path specification.
1665 //# It is always true that drivespec + pathspec == p
1666 // def splitdrive(p):
1667 // """Split a pathname into drive/UNC sharepoint and relative path
1668 // specifiers. Returns a 2-tuple (drive_or_unc, path); either part may be
1669 // empty.
1670 //
1671 // If you assign
1672 // result = splitdrive(p)
1673 // It is always true that:
1674 // result[0] + result[1] == p
1675 //
1676 // If the path contained a drive letter, drive_or_unc will contain
1677 // everything up to and including the colon. e.g. splitdrive("c:/dir")
1678 // returns ("c:", "/dir")
1679 //
1680 // If the path contained a UNC path, the drive_or_unc will contain the host
1681 // name and share up to but not including the fourth directory separator
1682 // character. e.g. splitdrive("//host/computer/dir") returns
1683 // ("//host/computer", "/dir")
1684 //
1685 // Paths cannot contain both a drive letter and a UNC path.
1686 //
1687 // """
1688 // if len(p) > 1:
1689 // normp = p.replace(altsep, sep)
1690 // if (normp[0:2] == sep*2) and (normp[2] != sep):
1691 // # is a UNC path:
1692 // # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
1693 // # \\machine\mountpoint\directory\etc\...
1694 // # directory ^^^^^^^^^^^^^^^
1695 // index = normp.find(sep, 2)
1696 // if index == -1:
1697 // return '', p
1698 // index2 = normp.find(sep, index + 1)
1699 // # a UNC path can't have two slashes in a row
1700 // # (after the initial two)
1701 // if index2 == index + 1:
1702 // return '', p
1703 // if index2 == -1:
1704 // index2 = len(p)
1705 // return p[:index2], p[index2:]
1706 // if normp[1] == ':':
1707 // return p[:2], p[2:]
1708 // return '', p
1709 
1710 // On Unix, the drive is always empty.
1711 // On the Mac, the drive is always empty (don't use the volume name -- it
1712 // doesn't have the same syntactic and semantic oddities as DOS drive
1713 // letters, such as there being a separate current directory per drive).
1714 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
1715  return std::pair<std::string, std::string>("", pathname);
1716 #else
1717  const std::string sep = "\\";
1718  const std::string sepsep = "\\\\";
1719  const std::string altsep = "/";
1720 
1721  if (pathname.size() > 1) {
1722  std::string normPathname = pathname;
1723  std::replace(normPathname.begin(), normPathname.end(), *altsep.c_str(), *sep.c_str());
1724 
1725  if (normPathname.substr(0, 2) == sepsep && normPathname.substr(2, 1) != sep) {
1726  // is a UNC path:
1727  // vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
1728  // \\machine\mountpoint\directory\etc\...
1729  // directory ^^^^^^^^^^^^^^^
1730  size_t index = normPathname.find(sep, 2);
1731  if (index == std::string::npos) {
1732  return std::pair<std::string, std::string>("", pathname);
1733  }
1734 
1735  size_t index2 = normPathname.find(sep, index + 1);
1736  //# a UNC path can't have two slashes in a row
1737  //# (after the initial two)
1738  if (index2 == index + 1) {
1739  return std::pair<std::string, std::string>("", pathname);
1740  }
1741 
1742  if (index2 == std::string::npos) {
1743  index2 = pathname.size();
1744  }
1745 
1746  return std::pair<std::string, std::string>(pathname.substr(0, index2), pathname.substr(index2));
1747  }
1748 
1749  if (normPathname[1] == ':') {
1750  return std::pair<std::string, std::string>(pathname.substr(0, 2), pathname.substr(2));
1751  }
1752  }
1753 
1754  return std::pair<std::string, std::string>("", pathname);
1755 #endif
1756 }
1757 
1806 std::vector<std::string> vpIoTools::splitChain(const std::string &chain, const std::string &sep)
1807 {
1808  size_t startIndex = 0;
1809 
1810  std::string chainToSplit = chain;
1811  std::vector<std::string> subChain;
1812  size_t sepIndex = chainToSplit.find(sep);
1813 
1814  while (sepIndex != std::string::npos) {
1815  std::string sub = chainToSplit.substr(startIndex, sepIndex);
1816  if (!sub.empty())
1817  subChain.push_back(sub);
1818  chainToSplit = chainToSplit.substr(sepIndex + 1, chain.size() - 1);
1819 
1820  sepIndex = chainToSplit.find(sep);
1821  }
1822  if (!chainToSplit.empty())
1823  subChain.push_back(chainToSplit);
1824 
1825  return subChain;
1826 }
1827 
1835 std::vector<std::string> vpIoTools::getDirFiles(const std::string &pathname)
1836 {
1837 
1838  if (!checkDirectory(pathname)) {
1839  throw(vpIoException(vpException::fatalError, "Directory %s doesn't exist'", pathname.c_str()));
1840  }
1841  std::string dirName = path(pathname);
1842 
1843 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1844 
1845  std::vector<std::string> files;
1846  struct dirent **list = NULL;
1847  int filesCount = scandir(dirName.c_str(), &list, NULL, NULL);
1848  if (filesCount == -1) {
1849  throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
1850  }
1851  for (int i = 0; i < filesCount; i++) {
1852  std::string fileName = list[i]->d_name;
1853  if (fileName != "." && fileName != "..") {
1854  files.push_back(fileName);
1855  }
1856  free(list[i]);
1857  }
1858  free(list);
1859  std::sort(files.begin(), files.end());
1860  return files;
1861 
1862 #elif defined(_WIN32)
1863 #if (!defined(WINRT))
1864 
1865  std::vector<std::string> files;
1866  std::string fileMask = dirName;
1867  fileMask.append("\\*");
1868  WIN32_FIND_DATA FindFileData;
1869  HANDLE hFind = FindFirstFile(fileMask.c_str(), &FindFileData);
1870  // Directory is empty
1871  if (HandleToLong(&hFind) == ERROR_FILE_NOT_FOUND) {
1872  return files;
1873  }
1874  if (hFind == INVALID_HANDLE_VALUE) {
1875  throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
1876  }
1877  do {
1878  std::string fileName = FindFileData.cFileName;
1879  if (fileName != "." && fileName != "..") {
1880  files.push_back(fileName);
1881  }
1882  } while (FindNextFile(hFind, &FindFileData));
1883  FindClose(hFind);
1884  std::sort(files.begin(), files.end());
1885  return files;
1886 
1887 #else
1889  "Cannot read files of directory %s: not implemented on "
1890  "Universal Windows Platform",
1891  dirName.c_str()));
1892 #endif
1893 #endif
1894 }
1895 
1899 void vpIoTools::readBinaryValueLE(std::ifstream &file, int16_t &short_value)
1900 {
1901  file.read((char *)(&short_value), sizeof(short_value));
1902 
1903 #ifdef VISP_BIG_ENDIAN
1904  // Swap bytes order from little endian to big endian
1905  short_value = swap16bits((uint16_t)short_value);
1906 #endif
1907 }
1908 
1912 void vpIoTools::readBinaryValueLE(std::ifstream &file, uint16_t &ushort_value)
1913 {
1914  file.read((char *)(&ushort_value), sizeof(ushort_value));
1915 
1916 #ifdef VISP_BIG_ENDIAN
1917  // Swap bytes order from little endian to big endian
1918  ushort_value = swap16bits(ushort_value);
1919 #endif
1920 }
1921 
1925 void vpIoTools::readBinaryValueLE(std::ifstream &file, int32_t &int_value)
1926 {
1927  file.read((char *)(&int_value), sizeof(int_value));
1928 
1929 #ifdef VISP_BIG_ENDIAN
1930  // Swap bytes order from little endian to big endian
1931  int_value = swap32bits((uint32_t)int_value);
1932 #endif
1933 }
1934 
1938 void vpIoTools::readBinaryValueLE(std::ifstream &file, uint32_t &uint_value)
1939 {
1940  file.read((char *)(&uint_value), sizeof(uint_value));
1941 
1942 #ifdef VISP_BIG_ENDIAN
1943  // Swap bytes order from little endian to big endian
1944  uint_value = swap32bits(uint_value);
1945 #endif
1946 }
1947 
1951 void vpIoTools::readBinaryValueLE(std::ifstream &file, float &float_value)
1952 {
1953  file.read((char *)(&float_value), sizeof(float_value));
1954 
1955 #ifdef VISP_BIG_ENDIAN
1956  // Swap bytes order from little endian to big endian
1957  float_value = swapFloat(float_value);
1958 #endif
1959 }
1960 
1964 void vpIoTools::readBinaryValueLE(std::ifstream &file, double &double_value)
1965 {
1966  file.read((char *)(&double_value), sizeof(double_value));
1967 
1968 #ifdef VISP_BIG_ENDIAN
1969  // Swap bytes order from little endian to big endian
1970  double_value = swapDouble(double_value);
1971 #endif
1972 }
1973 
1977 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
1978 {
1979 #ifdef VISP_BIG_ENDIAN
1980  // Swap bytes order to little endian
1981  uint16_t swap_short = swap16bits((uint16_t)short_value);
1982  file.write((char *)(&swap_short), sizeof(swap_short));
1983 #else
1984  file.write((char *)(&short_value), sizeof(short_value));
1985 #endif
1986 }
1987 
1991 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint16_t ushort_value)
1992 {
1993 #ifdef VISP_BIG_ENDIAN
1994  // Swap bytes order to little endian
1995  uint16_t swap_ushort = swap16bits(ushort_value);
1996  file.write((char *)(&swap_ushort), sizeof(swap_ushort));
1997 #else
1998  file.write((char *)(&ushort_value), sizeof(ushort_value));
1999 #endif
2000 }
2001 
2005 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int32_t int_value)
2006 {
2007 #ifdef VISP_BIG_ENDIAN
2008  // Swap bytes order to little endian
2009  uint32_t swap_int = swap32bits((uint32_t)int_value);
2010  file.write((char *)(&swap_int), sizeof(swap_int));
2011 #else
2012  file.write((char *)(&int_value), sizeof(int_value));
2013 #endif
2014 }
2015 
2019 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint32_t uint_value)
2020 {
2021 #ifdef VISP_BIG_ENDIAN
2022  // Swap bytes order to little endian
2023  uint32_t swap_int = swap32bits(uint_value);
2024  file.write((char *)(&swap_int), sizeof(swap_int));
2025 #else
2026  file.write((char *)(&uint_value), sizeof(uint_value));
2027 #endif
2028 }
2029 
2033 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const float float_value)
2034 {
2035 #ifdef VISP_BIG_ENDIAN
2036  // Swap bytes order to little endian
2037  float swap_float = swapFloat(float_value);
2038  file.write((char *)(&swap_float), sizeof(swap_float));
2039 #else
2040  file.write((char *)(&float_value), sizeof(float_value));
2041 #endif
2042 }
2043 
2047 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const double double_value)
2048 {
2049 #ifdef VISP_BIG_ENDIAN
2050  // Swap bytes order to little endian
2051  double swap_double = swapDouble(double_value);
2052  file.write((char *)(&swap_double), sizeof(swap_double));
2053 #else
2054  file.write((char *)(&double_value), sizeof(double_value));
2055 #endif
2056 }
2057 
2058 bool vpIoTools::parseBoolean(std::string input)
2059 {
2060  std::transform(input.begin(), input.end(), input.begin(), ::tolower);
2061  std::istringstream is(input);
2062  bool b;
2063  // Parse string to boolean either in the textual representation
2064  // (True/False) or in numeric representation (1/0)
2065  is >> (input.size() > 1 ? std::boolalpha : std::noboolalpha) >> b;
2066  return b;
2067 }
2068 
2072 std::string vpIoTools::trim(std::string s)
2073 {
2074  return ltrim(rtrim(s));
2075 }
static bool remove(const char *filename)
Definition: vpIoTools.cpp:854
static bool checkDirectory(const char *dirname)
Definition: vpIoTools.cpp:484
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1333
static bool isAbsolutePathname(const std::string &pathname)
Definition: vpIoTools.cpp:1617
static void getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
Definition: vpIoTools.cpp:441
static std::string getFileExtension(const std::string &pathname, const bool checkFile=false)
Definition: vpIoTools.cpp:1398
static void readBinaryValueLE(std::ifstream &file, int16_t &short_value)
Definition: vpIoTools.cpp:1899
#define vpERROR_TRACE
Definition: vpDebug.h:393
void resize(const unsigned int nrows, const unsigned int ncols, const bool flagNullify=true, const bool recopy_=true)
Definition: vpArray2D.h:305
Class to define colors available for display functionnalities.
Definition: vpColor.h:120
static const char separator
Definition: vpIoTools.h:187
static std::string getenv(const char *env)
Definition: vpIoTools.cpp:379
static bool rename(const char *oldfilename, const char *newfilename)
Definition: vpIoTools.cpp:922
static std::string path(const char *pathname)
Definition: vpIoTools.cpp:958
Error that can be emited by the vpIoTools class and its derivates.
Definition: vpIoException.h:72
unsigned int getCols() const
Definition: vpArray2D.h:279
static std::vector< std::string > getDirFiles(const std::string &dirname)
Definition: vpIoTools.cpp:1835
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:1512
static void createBaseNamePath(const bool &empty=false)
Definition: vpIoTools.cpp:1291
static const std::string & getBuildInformation()
Definition: vpIoTools.cpp:217
static std::string baseDir
Definition: vpIoTools.h:254
static void makeDirectory(const char *dirname)
Definition: vpIoTools.cpp:614
static bool checkFilename(const char *filename)
Definition: vpIoTools.cpp:692
static void setBaseName(const std::string &s)
Definition: vpIoTools.cpp:230
static bool parseBoolean(std::string input)
Definition: vpIoTools.cpp:2058
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1576
static int mkdir_p(const char *path, const int mode)
Definition: vpIoTools.cpp:549
static bool copy(const char *src, const char *dst)
Definition: vpIoTools.cpp:753
static std::pair< std::string, std::string > splitDrive(const std::string &pathname)
Definition: vpIoTools.cpp:1661
static bool isSamePathname(const std::string &pathname1, const std::string &pathname2)
Definition: vpIoTools.cpp:1641
static std::string getUserName()
Definition: vpIoTools.cpp:315
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1806
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:151
unsigned int getRows() const
Definition: vpArray2D.h:289
static void saveConfigFile(const bool &actuallySave=true)
Definition: vpIoTools.cpp:1310
static std::vector< std::string > configVars
Definition: vpIoTools.h:256
static std::string getName(const std::string &pathname)
Definition: vpIoTools.cpp:1477
static void writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
Definition: vpIoTools.cpp:1977
static std::string baseName
Definition: vpIoTools.h:253
static std::string getFullName()
Definition: vpIoTools.cpp:248
static std::string trim(std::string s)
Definition: vpIoTools.cpp:2072
static std::string configFile
Definition: vpIoTools.h:255
static void setBaseDir(const std::string &dir)
Definition: vpIoTools.cpp:236
static std::string getNameWE(const std::string &pathname)
Definition: vpIoTools.cpp:1499
static std::string getBaseName()
Definition: vpIoTools.cpp:242
#define vpDEBUG_TRACE
Definition: vpDebug.h:487
static std::string getAbsolutePathname(const std::string &pathname)
Definition: vpIoTools.cpp:1534
static vpColor getColor(const unsigned int &i)
Definition: vpColor.h:249
static bool readConfigVar(const std::string &var, float &value)
Definition: vpIoTools.cpp:1059
static std::vector< std::string > configValues
Definition: vpIoTools.h:257
static bool loadConfigFile(const std::string &confFile)
Definition: vpIoTools.cpp:1012
static void addNameElement(const std::string &strTrue, const bool &cond=true, const std::string &strFalse="")
Definition: vpIoTools.cpp:1256