Visual Servoing Platform  version 3.3.0 under development (2020-02-17)
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__) || (defined(__GNUC__) && !defined(__llvm__) && !defined(__MINGW32__) && defined(__BYTE_ORDER__))
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(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(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 #if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
204  s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) { return !std::isspace(c); }));
205 #else
206  s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
207 #endif
208  return s;
209 }
210 
211 std::string &rtrim(std::string &s)
212 {
213 #if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
214  s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) { return !std::isspace(c); }).base(), s.end());
215 #else
216  s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
217 #endif
218  return s;
219 }
220 }
221 
225 const std::string &vpIoTools::getBuildInformation()
226 {
227  static std::string build_info =
228 #include "version_string.inc"
229  ;
230  return build_info;
231 }
232 
238 void vpIoTools::setBaseName(const std::string &s) { baseName = s; }
244 void vpIoTools::setBaseDir(const std::string &dir) { baseDir = dir + "/"; }
250 std::string vpIoTools::getBaseName() { return baseName; }
256 std::string vpIoTools::getFullName() { return baseDir + baseName; }
257 
271 void vpIoTools::getUserName(std::string &username)
272 {
273 // With MinGW, UNIX and _WIN32 are defined
274 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
275  // Get the user name.
276  char *_username = ::getenv("LOGNAME");
277  if (!_username) {
278  username = "unknown";
279  }
280  else {
281  username = _username;
282  }
283 #elif defined(_WIN32)
284 #if (!defined(WINRT))
285  unsigned int info_buffer_size = 1024;
286  TCHAR *infoBuf = new TCHAR[info_buffer_size];
287  DWORD bufCharCount = (DWORD)info_buffer_size;
288  // Get the user name.
289  if (!GetUserName(infoBuf, &bufCharCount)) {
290  username = "unknown";
291  } else {
292  username = infoBuf;
293  }
294  delete[] infoBuf;
295 #else
296  // Universal platform
297  username = "unknown";
298 #endif
299 #else
300  username = "unknown";
301 #endif
302 }
303 
319 {
320  std::string username;
321  getUserName(username);
322  return username;
323 }
324 
355 std::string vpIoTools::getenv(const std::string &env)
356 {
357 #if defined(_WIN32) && defined(WINRT)
358  throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value: not "
359  "implemented on Universal Windows Platform"));
360 #else
361  std::string value;
362  // Get the environment variable value.
363  char *_value = ::getenv(env.c_str());
364  if (! _value) {
365  throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value"));
366  }
367  value = _value;
368 
369  return value;
370 #endif
371 }
372 
382 void vpIoTools::getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
383 {
384  if (version.size() == 0) {
385  major = 0;
386  minor = 0;
387  patch = 0;
388  } else {
389  size_t major_pos = version.find('.');
390  std::string major_str = version.substr(0, major_pos);
391  major = static_cast<unsigned>(atoi(major_str.c_str()));
392 
393  if (major_pos != std::string::npos) {
394  size_t minor_pos = version.find('.', major_pos + 1);
395  std::string minor_str = version.substr(major_pos + 1, (minor_pos - (major_pos + 1)));
396  minor = static_cast<unsigned>(atoi(minor_str.c_str()));
397 
398  if (minor_pos != std::string::npos) {
399  std::string patch_str = version.substr(minor_pos + 1);
400  patch = static_cast<unsigned>(atoi(patch_str.c_str()));
401  } else {
402  patch = 0;
403  }
404  } else {
405  minor = 0;
406  patch = 0;
407  }
408  }
409 }
410 
422 bool vpIoTools::checkDirectory(const std::string &dirname)
423 {
424 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
425  struct stat stbuf;
426 #elif defined(_WIN32) && defined(__MINGW32__)
427  struct stat stbuf;
428 #elif defined(_WIN32)
429  struct _stat stbuf;
430 #endif
431 
432  if (dirname.empty()) {
433  return false;
434  }
435 
436  std::string _dirname = path(dirname);
437 
438 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
439  if (stat(_dirname.c_str(), &stbuf) != 0)
440 #elif defined(_WIN32) && defined(__MINGW32__)
441  // Remove trailing separator character if any
442  // AppVeyor: Windows 6.3.9600 AMD64 ; C:/MinGW/bin/g++.exe (ver 5.3.0) ;
443  // GNU Make 3.82.90 Built for i686-pc-mingw32
444  if (_dirname.at(_dirname.size() - 1) == vpIoTools::separator)
445  _dirname = _dirname.substr(0, _dirname.size() - 1);
446  if (stat(_dirname.c_str(), &stbuf) != 0)
447 #elif defined(_WIN32)
448  if (_stat(_dirname.c_str(), &stbuf) != 0)
449 #endif
450  {
451  return false;
452  }
453 #if defined(_WIN32) || (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
454  if ((stbuf.st_mode & S_IFDIR) == 0)
455 #endif
456  {
457  return false;
458  }
459 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
460  if ((stbuf.st_mode & S_IWUSR) == 0)
461 #elif defined(_WIN32)
462  if ((stbuf.st_mode & S_IWRITE) == 0)
463 #endif
464  {
465  return false;
466  }
467  return true;
468 }
469 
482 bool vpIoTools::checkFifo(const std::string &fifofilename)
483 {
484 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
485  struct stat stbuf;
486 
487  std::string _filename = path(fifofilename);
488  if (stat(_filename.c_str(), &stbuf) != 0) {
489  return false;
490  }
491  if ((stbuf.st_mode & S_IFIFO) == 0) {
492  return false;
493  }
494  if ((stbuf.st_mode & S_IRUSR) == 0)
495 
496  {
497  return false;
498  }
499  return true;
500 #elif defined(_WIN32)
501  (void)fifofilename;
502  throw(vpIoException(vpIoException::notImplementedError, "Fifo files are not supported on Windows platforms."));
503 #endif
504 }
505 
506 #ifndef DOXYGEN_SHOULD_SKIP_THIS
507 // See:
508 // https://gist.github.com/JonathonReinhart/8c0d90191c38af2dcadb102c4e202950
509 int vpIoTools::mkdir_p(const char *path, int mode)
510 {
511  /* Adapted from http://stackoverflow.com/a/2336245/119527 */
512  const size_t len = strlen(path);
513  char _path[PATH_MAX];
514  const char sep = vpIoTools::separator;
515 
516  std::fill(_path, _path + PATH_MAX, 0);
517 
518  errno = 0;
519  if (len > sizeof(_path) - 1) {
520  errno = ENAMETOOLONG;
521  return -1;
522  }
523  /* Copy string so its mutable */
524  strcpy(_path, path);
525 
526  /* Iterate over the string */
527  for (char *p = _path + 1; *p; p++) { // path cannot be empty
528  if (*p == sep) {
529  /* Temporarily truncate */
530  *p = '\0';
531 
532 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
533  if (mkdir(_path, static_cast<mode_t>(mode)) != 0)
534 #elif defined(_WIN32)
535  (void)mode; // var not used
536  if (!checkDirectory(_path) && _mkdir(_path) != 0)
537 #endif
538  {
539  if (errno != EEXIST)
540  return -1;
541  }
542  *p = sep;
543  }
544  }
545 
546 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
547  if (mkdir(_path, static_cast<mode_t>(mode)) != 0)
548 #elif defined(_WIN32)
549  if (_mkdir(_path) != 0)
550 #endif
551  {
552  if (errno != EEXIST)
553  return -1;
554  }
555 
556  return 0;
557 }
558 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
559 
572 void vpIoTools::makeDirectory(const std::string &dirname)
573 {
574 #if ((!defined(__unix__) && !defined(__unix) && (!defined(__APPLE__) || !defined(__MACH__)))) && !defined(_WIN32)
575  std::cerr << "Unsupported platform for vpIoTools::makeDirectory()!" << std::endl;
576  return;
577 #endif
578 
579 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
580  struct stat stbuf;
581 #elif defined(_WIN32) && defined(__MINGW32__)
582  struct stat stbuf;
583 #elif defined(_WIN32)
584  struct _stat stbuf;
585 #endif
586 
587  if (dirname.empty()) {
588  throw(vpIoException(vpIoException::invalidDirectoryName, "invalid directory name"));
589  }
590 
591  std::string _dirname = path(dirname);
592 
593 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
594  if (stat(_dirname.c_str(), &stbuf) != 0)
595 #elif defined(_WIN32) && defined(__MINGW32__)
596  if (stat(_dirname.c_str(), &stbuf) != 0)
597 #elif defined(_WIN32)
598  if (_stat(_dirname.c_str(), &stbuf) != 0)
599 #endif
600  {
601  if (vpIoTools::mkdir_p(_dirname.c_str(), 0755) != 0) {
602  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'", dirname.c_str()));
603  }
604  }
605 
606  if (checkDirectory(dirname) == false) {
607  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'", dirname.c_str()));
608  }
609 }
610 
623 void vpIoTools::makeFifo(const std::string &fifoname)
624 {
625 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
626 
627  // If dirname is a directory, we throw an error
628  if (vpIoTools::checkDirectory(fifoname)) {
630  "Unable to create fifo file. '%s' is an existing directory.", fifoname.c_str()));
631  }
632 
633  // If dirname refers to an already existing file, we throw an error
634  else if (vpIoTools::checkFilename(fifoname)) {
635  throw(vpIoException(vpIoException::invalidDirectoryName, "Unable to create fifo file '%s'. File already exists.",
636  fifoname.c_str()));
637  // If dirname refers to an already existing fifo, we throw an error
638  } else if (vpIoTools::checkFifo(fifoname)) {
639  throw(vpIoException(vpIoException::invalidDirectoryName, "Unable to create fifo file '%s'. Fifo already exists.",
640  fifoname.c_str()));
641  }
642 
643  else if (mkfifo(fifoname.c_str(), 0666) < 0) {
644  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create fifo file '%s'.", fifoname.c_str()));
645  }
646 #elif defined(_WIN32)
647  (void)fifoname;
648  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create fifo on Windows platforms."));
649 #endif
650 }
651 
671 std::string vpIoTools::makeTempDirectory(const std::string &dirname)
672 {
673 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
674 
675  std::string dirname_cpy = std::string(dirname);
676 
677  std::string correctEnding = "XXXXXX";
678 
679  size_t endingLength = correctEnding.length();
680  size_t dirNameLength = dirname_cpy.length();
681 
682  // If dirname is an unexisting directory, it should end with XXXXXX in order to create a temp directory
683  if (!vpIoTools::checkDirectory(dirname_cpy)) {
684  if (endingLength > dirNameLength) {
686  "Unable to create temp directory '%s'. It should end with XXXXXX.", dirname_cpy.c_str()));
687  }
688 
689  if (dirname.compare(dirNameLength - endingLength, endingLength, correctEnding) != 0) {
691  "Unable to create temp directory '%s'. It should end with XXXXXX.", dirname_cpy.c_str()));
692  }
693 
694  // If dirname is an existing directory, we create a temp directory inside
695  } else {
696  if (dirname_cpy.at(dirname_cpy.length() - 1) != '/') {
697  dirname_cpy = dirname_cpy + "/";
698  }
699  dirname_cpy = dirname_cpy + "XXXXXX";
700  }
701  char *dirname_char = new char[dirname_cpy.length() + 1];
702  strcpy(dirname_char, dirname_cpy.c_str());
703 
704  char *computedDirname = mkdtemp(dirname_char);
705 
706  if (!computedDirname) {
707  delete[] dirname_char;
708  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'.", dirname_cpy.c_str()));
709  }
710 
711  std::string res(computedDirname);
712  delete[] dirname_char;
713  return res;
714 #elif defined(_WIN32)
715  (void)dirname;
716  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create temp directory. Not implemented yet."));
717 #endif
718 }
719 
730 bool vpIoTools::checkFilename(const std::string &filename)
731 {
732 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
733  struct stat stbuf;
734 #elif defined(_WIN32)
735  struct _stat stbuf;
736 #endif
737 
738  if (filename.empty()) {
739  return false;
740  }
741 
742  std::string _filename = path(filename);
743 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
744  if (stat(_filename.c_str(), &stbuf) != 0)
745 #elif defined(_WIN32)
746  if (_stat(_filename.c_str(), &stbuf) != 0)
747 #endif
748  {
749  return false;
750  }
751  if ((stbuf.st_mode & S_IFREG) == 0) {
752  return false;
753  }
754 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
755  if ((stbuf.st_mode & S_IRUSR) == 0)
756 #elif defined(_WIN32)
757  if ((stbuf.st_mode & S_IREAD) == 0)
758 #endif
759  {
760  return false;
761  }
762  return true;
763 }
764 
772 bool vpIoTools::copy(const std::string &src, const std::string &dst)
773 {
774  // Check if we have to consider a file or a directory
775  if (vpIoTools::checkFilename(src)) {
776 // std::cout << "copy file: " << src << " in " << dst << std::endl;
777 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
778 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
779  // wordexp() is not available
780  char cmd[FILENAME_MAX];
781  int ret;
782  sprintf(cmd, "cp -p %s %s", src.c_str(), dst.c_str());
783  ret = system(cmd);
784  if (ret) {
785  }; // to avoid a warning
786  // std::cout << cmd << " return value: " << ret << std::endl;
787  return true;
788 #else
789  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src.c_str(), dst.c_str()));
790 #endif
791 #elif defined(_WIN32)
792 #if (!defined(WINRT))
793  char cmd[FILENAME_MAX];
794  int ret;
795  std::string src_ = vpIoTools::path(src);
796  std::string dst_ = vpIoTools::path(dst);
797  sprintf(cmd, "copy %s %s", src_.c_str(), dst_.c_str());
798  ret = system(cmd);
799  if (ret) {
800  }; // to avoid a warning
801  // std::cout << cmd << " return value: " << ret << std::endl;
802  return true;
803 #else
804  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
805  src.c_str(), dst.c_str()));
806 #endif
807 #endif
808  } else if (vpIoTools::checkDirectory(src)) {
809 // std::cout << "copy directory: " << src << " in " << dst << std::endl;
810 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
811 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
812  // wordexp() is not available
813  char cmd[FILENAME_MAX];
814  int ret;
815  sprintf(cmd, "cp -p -r %s %s", src.c_str(), dst.c_str());
816  ret = system(cmd);
817  if (ret) {
818  }; // to avoid a warning
819  // std::cout << cmd << " return value: " << ret << std::endl;
820  return true;
821 #else
822  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src.c_str(), dst.c_str()));
823 #endif
824 #elif defined(_WIN32)
825 #if (!defined(WINRT))
826  char cmd[FILENAME_MAX];
827  int ret;
828  std::string src_ = vpIoTools::path(src);
829  std::string dst_ = vpIoTools::path(dst);
830  sprintf(cmd, "copy %s %s", src_.c_str(), dst_.c_str());
831  ret = system(cmd);
832  if (ret) {
833  }; // to avoid a warning
834  // std::cout << cmd << " return value: " << ret << std::endl;
835  return true;
836 #else
837  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
838  src.c_str(), dst.c_str()));
839 #endif
840 #endif
841  } else {
842  std::cout << "Cannot copy: " << src << " in " << dst << std::endl;
843  return false;
844  }
845 }
846 
855 bool vpIoTools::remove(const std::string &file_or_dir)
856 {
857  // Check if we have to consider a file or a directory
858  if (vpIoTools::checkFilename(file_or_dir)
859 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
860  || vpIoTools::checkFifo(std::string(file_or_dir))
861 #endif
862  ) {
863  // std::cout << "remove file: " << file_or_dir << std::endl;
864  if (::remove(file_or_dir.c_str()) != 0)
865  return false;
866  else
867  return true;
868  } else if (vpIoTools::checkDirectory(file_or_dir)) {
869 // std::cout << "remove directory: " << file_or_dir << std::endl;
870 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
871 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
872  // wordexp() is not available
873  char cmd[FILENAME_MAX];
874  sprintf(cmd, "rm -rf \"%s\"", file_or_dir.c_str());
875  int ret = system(cmd);
876  if (ret) {
877  }; // to avoid a warning
878  // std::cout << cmd << " return value: " << ret << std::endl;
879  return true;
880 #else
881  throw(vpIoException(vpException::fatalError, "Cannot remove %s: not implemented on iOS Platform", file_or_dir.c_str()));
882 #endif
883 #elif defined(_WIN32)
884 #if (!defined(WINRT))
885  char cmd[FILENAME_MAX];
886  std::string file_or_dir_ = vpIoTools::path(file_or_dir);
887  sprintf(cmd, "rmdir /S /Q %s", file_or_dir_.c_str());
888  int 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 remove %s: not implemented on Universal Windows Platform",
895  file_or_dir.c_str()));
896 #endif
897 #endif
898  } else {
899  std::cout << "Cannot remove: " << file_or_dir << std::endl;
900  return false;
901  }
902 }
903 
913 bool vpIoTools::rename(const std::string &oldfilename, const std::string &newfilename)
914 {
915  if (::rename(oldfilename.c_str(), newfilename.c_str()) != 0)
916  return false;
917  else
918  return true;
919 }
920 
931 std::string vpIoTools::path(const std::string &pathname)
932 {
933  std::string path(pathname);
934 
935 #if defined(_WIN32)
936  for (unsigned int i = 0; i < path.length(); i++)
937  if (path[i] == '/')
938  path[i] = '\\';
939 #elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
940  for (unsigned int i = 0; i < path.length(); i++)
941  if (path[i] == '\\')
942  path[i] = '/';
943 #if TARGET_OS_IOS == 0 // The following code is not working on iOS and android since
944  // wordexp() is not available
945  #ifdef __ANDROID__
946  // Do nothing
947  #else
948  wordexp_t exp_result;
949 
950  // escape quote character
951  replaceAll(path, "'", "'\\''");
952  // add quotes to handle special characters like parentheses and spaces
953  wordexp(std::string("'" + path + "'").c_str(), &exp_result, 0);
954  path = exp_result.we_wordc == 1 ? exp_result.we_wordv[0] : "";
955  wordfree(&exp_result);
956  #endif
957 #endif
958 #endif
959 
960  return path;
961 }
962 
971 bool vpIoTools::loadConfigFile(const std::string &confFile)
972 {
973  configFile = path(confFile);
974  configVars.clear();
975  configValues.clear();
976  std::ifstream confContent(configFile.c_str(), std::ios::in);
977 
978  if (confContent.is_open()) {
979  std::string line, var, val;
980  long unsigned int k;
981  int c;
982  std::string stop[3] = {" ", "\t", "#"};
983  while (std::getline(confContent, line)) {
984  if ((line.compare(0, 1, "#") != 0) && (line.size() > 2)) {
985  try {
986  // name of the variable
987  k = static_cast<unsigned long>(line.find(" "));
988  var = line.substr(0, k);
989  // look for the end of the actual value
990  c = 200;
991  for (unsigned i = 0; i < 3; ++i)
992  c = vpMath::minimum(c, static_cast<int>(line.find(stop[i], static_cast<size_t>(k) + static_cast<size_t>(1))));
993  if (c == -1)
994  c = static_cast<int>(line.size());
995  long unsigned int c_ = static_cast<long unsigned int>(c);
996  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));
997  configVars.push_back(var);
998  configValues.push_back(val);
999  } catch (...) {
1000  }
1001  }
1002  }
1003  confContent.close();
1004  } else {
1005  return false;
1006  }
1007  return true;
1008 }
1009 
1018 bool vpIoTools::readConfigVar(const std::string &var, float &value)
1019 {
1020  bool found = false;
1021  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1022  if (configVars[k] == var) {
1023  if (configValues[k].compare("PI") == 0)
1024  value = static_cast<float>(M_PI);
1025  else if (configValues[k].compare("PI/2") == 0)
1026  value = static_cast<float>(M_PI / 2.0);
1027  else if (configValues[k].compare("-PI/2") == 0)
1028  value = static_cast<float>(-M_PI / 2.0);
1029  else
1030  value = static_cast<float>(atof(configValues[k].c_str()));
1031  found = true;
1032  }
1033  }
1034  if (found == false)
1035  std::cout << var << " not found in config file" << std::endl;
1036  return found;
1037 }
1046 bool vpIoTools::readConfigVar(const std::string &var, double &value)
1047 {
1048  bool found = false;
1049  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1050  if (configVars[k] == var) {
1051  if (configValues[k].compare("PI") == 0)
1052  value = M_PI;
1053  else if (configValues[k].compare("PI/2") == 0)
1054  value = M_PI / 2;
1055  else if (configValues[k].compare("-PI/2") == 0)
1056  value = -M_PI / 2;
1057  else
1058  value = atof(configValues[k].c_str());
1059  found = true;
1060  }
1061  }
1062  if (found == false)
1063  std::cout << var << " not found in config file" << std::endl;
1064  return found;
1065 }
1066 
1075 bool vpIoTools::readConfigVar(const std::string &var, int &value)
1076 {
1077  bool found = false;
1078  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1079  if (configVars[k] == var) {
1080  value = atoi(configValues[k].c_str());
1081  found = true;
1082  }
1083  }
1084  if (found == false)
1085  std::cout << var << " not found in config file" << std::endl;
1086  return found;
1087 }
1088 
1097 bool vpIoTools::readConfigVar(const std::string &var, unsigned int &value)
1098 {
1099  int v = 0;
1100  bool found = readConfigVar(var, v);
1101  value = static_cast<unsigned int>(v);
1102  return found;
1103 }
1104 
1113 bool vpIoTools::readConfigVar(const std::string &var, bool &value)
1114 {
1115  int v = 0;
1116  bool found = readConfigVar(var, v);
1117  value = (v != 0);
1118  return found;
1119 }
1120 
1129 bool vpIoTools::readConfigVar(const std::string &var, vpColor &value)
1130 {
1131  unsigned int v = 0;
1132  bool found = readConfigVar(var, v);
1133  value = vpColor::getColor(v);
1134  return found;
1135 }
1136 
1145 bool vpIoTools::readConfigVar(const std::string &var, std::string &value)
1146 {
1147  bool found = false;
1148  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1149  if (configVars[k] == var) {
1150  value = configValues[k];
1151  found = true;
1152  }
1153  }
1154  if (found == false)
1155  std::cout << var << " not found in config file" << std::endl;
1156  return found;
1157 }
1158 
1172 bool vpIoTools::readConfigVar(const std::string &var, vpArray2D<double> &value, const unsigned int &nCols,
1173  const unsigned int &nRows)
1174 {
1175  bool found = false;
1176  std::string nb;
1177  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1178  if (configVars[k] == var) {
1179  found = true;
1180  // resize or not
1181  if (nCols != 0 && nRows != 0)
1182  value.resize(nRows, nCols);
1183  size_t ind = 0, ind2;
1184  for (unsigned int i = 0; i < value.getRows(); ++i)
1185  for (unsigned int j = 0; j < value.getCols(); ++j) {
1186  ind2 = configValues[k].find(",", ind);
1187  nb = configValues[k].substr(ind, ind2 - ind);
1188  if (nb.compare("PI") == 0)
1189  value[i][j] = M_PI;
1190  else if (nb.compare("PI/2") == 0)
1191  value[i][j] = M_PI / 2;
1192  else if (nb.compare("-PI/2") == 0)
1193  value[i][j] = -M_PI / 2;
1194  else
1195  value[i][j] = atof(nb.c_str());
1196  ind = ind2 + 1;
1197  }
1198  }
1199  }
1200  if (found == false)
1201  std::cout << var << " not found in config file" << std::endl;
1202  return found;
1203 }
1204 
1205 // construct experiment filename & path
1206 
1215 void vpIoTools::addNameElement(const std::string &strTrue, const bool &cond, const std::string &strFalse)
1216 {
1217  if (cond)
1218  baseName += "_" + strTrue;
1219  else if (strFalse != "")
1220  baseName += "_" + strFalse;
1221 }
1222 
1231 void vpIoTools::addNameElement(const std::string &strTrue, const double &val)
1232 {
1233  // if(val != 0.)
1234  if (std::fabs(val) < std::numeric_limits<double>::epsilon()) {
1235  char valC[256];
1236  sprintf(valC, "%.3f", val);
1237  std::string valS(valC);
1238  baseName += "_" + strTrue + valS;
1239  }
1240 }
1241 
1250 void vpIoTools::createBaseNamePath(const bool &empty)
1251 {
1252  if (vpIoTools::checkDirectory(baseDir + baseName) == false) {
1254  std::cout << "creating directory " + baseDir + baseName << std::endl;
1255  } else {
1256  if (empty) {
1257  std::cout << "emptying directory " + baseDir + baseName << std::endl;
1259  }
1260  }
1261 }
1262 
1269 void vpIoTools::saveConfigFile(const bool &actuallySave)
1270 {
1271  if (actuallySave) {
1272  std::string dest = baseDir + "/" + baseName + "_config.txt";
1273  // file copy
1274  vpIoTools::copy(configFile, dest);
1275  }
1276 }
1277 
1293 {
1294  std::string data_path;
1295  std::string file_to_test("mbt/cube.cao");
1296  std::string filename;
1297 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1298  // Test if visp-images-data package is u-installed (Ubuntu and Debian)
1299  data_path = "/usr/share/visp-images-data/ViSP-images";
1300  filename = data_path + "/" + file_to_test;
1301  if (vpIoTools::checkFilename(filename))
1302  return data_path;
1303  data_path = "/usr/share/visp-images-data/visp-images";
1304  filename = data_path + "/" + file_to_test;
1305  if (vpIoTools::checkFilename(filename))
1306  return data_path;
1307 #endif
1308  // Test if VISP_INPUT_IMAGE_PATH env var is set
1309  try {
1310  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH");
1311  filename = data_path + "/" + file_to_test;
1312  if (vpIoTools::checkFilename(filename))
1313  return data_path;
1314  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/ViSP-images";
1315  filename = data_path + "/" + file_to_test;
1316  if (vpIoTools::checkFilename(filename))
1317  return data_path;
1318  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/visp-images";
1319  filename = data_path + "/" + file_to_test;
1320  if (vpIoTools::checkFilename(filename))
1321  return data_path;
1322  } catch (...) {
1323  }
1324  data_path = "";
1325  return data_path;
1326 }
1327 
1357 std::string vpIoTools::getFileExtension(const std::string &pathname, bool checkFile)
1358 {
1359  if (checkFile && (vpIoTools::checkDirectory(pathname) || !vpIoTools::checkFilename(pathname))) {
1360  return "";
1361  }
1362 
1363 #if defined(_WIN32)
1364  std::string sep = "\\";
1365  std::string altsep = "/";
1366  std::string extsep = ".";
1367 #else
1368  // On Unix, or on the Mac
1369  std::string sep = "/";
1370  std::string altsep = "";
1371  std::string extsep = ".";
1372 #endif
1373 
1374  // Python 2.7.8 module.
1375  //# Split a path in root and extension.
1376  //# The extension is everything starting at the last dot in the last
1377  //# pathname component; the root is everything before that.
1378  //# It is always true that root + ext == p.
1379  //
1380  //# Generic implementation of splitext, to be parametrized with
1381  //# the separators
1382  // def _splitext(p, sep, altsep, extsep):
1383  // """Split the extension from a pathname.
1384  //
1385  // Extension is everything from the last dot to the end, ignoring
1386  // leading dots. Returns "(root, ext)"; ext may be empty."""
1387  //
1388  // sepIndex = p.rfind(sep)
1389  // if altsep:
1390  // altsepIndex = p.rfind(altsep)
1391  // sepIndex = max(sepIndex, altsepIndex)
1392  //
1393  // dotIndex = p.rfind(extsep)
1394  // if dotIndex > sepIndex:
1395  // # skip all leading dots
1396  // filenameIndex = sepIndex + 1
1397  // while filenameIndex < dotIndex:
1398  // if p[filenameIndex] != extsep:
1399  // return p[:dotIndex], p[dotIndex:]
1400  // filenameIndex += 1
1401  //
1402  // return p, ''
1403 
1404  int sepIndex = static_cast<int>(pathname.rfind(sep));
1405  if (!altsep.empty()) {
1406  int altsepIndex = static_cast<int>(pathname.rfind(altsep));
1407  sepIndex = ((std::max))(sepIndex, altsepIndex);
1408  }
1409 
1410  size_t dotIndex = pathname.rfind(extsep);
1411  if (dotIndex != std::string::npos) {
1412  // The extsep character exists
1413  size_t npos = std::string::npos;
1414  if ((sepIndex != static_cast<int>(npos) && static_cast<int>(dotIndex) > sepIndex) || sepIndex == static_cast<int>(npos)) {
1415  if (sepIndex == static_cast<int>(npos)) {
1416  sepIndex = 0;
1417  std::cout << "Debug sepIndex: " << sepIndex << std::endl;
1418  }
1419  size_t filenameIndex = static_cast<size_t>(sepIndex) + static_cast<size_t>(1);
1420 
1421  while (filenameIndex < dotIndex) {
1422  if (pathname.compare(filenameIndex, 1, extsep) != 0) {
1423  return pathname.substr(dotIndex);
1424  }
1425  filenameIndex++;
1426  }
1427  }
1428  }
1429 
1430  return "";
1431 }
1432 
1438 std::string vpIoTools::getName(const std::string &pathname)
1439 {
1440  if (pathname.size() > 0) {
1441  std::string convertedPathname = vpIoTools::path(pathname);
1442 
1443  size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1444  if (index != std::string::npos) {
1445  return convertedPathname.substr(index + 1);
1446  }
1447 
1448  return convertedPathname;
1449  }
1450 
1451  return "";
1452 }
1453 
1460 std::string vpIoTools::getNameWE(const std::string &pathname)
1461 {
1462  std::string name = vpIoTools::getName(pathname);
1463  size_t found = name.find_last_of(".");
1464  std::string name_we = name.substr(0, found);
1465  return name_we;
1466 }
1467 
1473 std::string vpIoTools::getParent(const std::string &pathname)
1474 {
1475  if (pathname.size() > 0) {
1476  std::string convertedPathname = vpIoTools::path(pathname);
1477 
1478  size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1479  if (index != std::string::npos) {
1480  return convertedPathname.substr(0, index);
1481  }
1482  }
1483 
1484  return "";
1485 }
1486 
1495 std::string vpIoTools::getAbsolutePathname(const std::string &pathname)
1496 {
1497 
1498 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1499  std::string real_path_str = pathname;
1500  char *real_path = realpath(pathname.c_str(), NULL);
1501 
1502  if (real_path) {
1503  real_path_str = real_path;
1504  free(real_path);
1505  }
1506  return real_path_str;
1507 #elif defined(_WIN32)
1508 #if (!defined(WINRT))
1509  std::string real_path_str = pathname;
1510  DWORD retval = 0;
1511  TCHAR buffer[4096] = TEXT("");
1512 
1513  retval = GetFullPathName(pathname.c_str(), 4096, buffer, 0);
1514  if (retval != 0) {
1515  real_path_str = buffer;
1516  }
1517  return real_path_str;
1518 #else
1520  "Cannot get absolute path of %s: not implemented on "
1521  "Universal Windows Platform",
1522  pathname.c_str()));
1523 #endif
1524 #endif
1525 }
1526 
1537 std::string vpIoTools::createFilePath(const std::string &parent, const std::string &child)
1538 {
1539  if (child.size() == 0 && parent.size() == 0) {
1540  return "";
1541  }
1542 
1543  if (child.size() == 0) {
1544  return vpIoTools::path(parent);
1545  }
1546 
1547  if (parent.size() == 0) {
1548  return vpIoTools::path(child);
1549  }
1550 
1551  std::string convertedParent = vpIoTools::path(parent);
1552  std::string convertedChild = vpIoTools::path(child);
1553 
1554  std::stringstream ss;
1555  ss << vpIoTools::separator;
1556  std::string stringSeparator;
1557  ss >> stringSeparator;
1558 
1559  std::string lastConvertedParentChar = convertedParent.substr(convertedParent.size() - 1);
1560  std::string firstConvertedChildChar = convertedChild.substr(0, 1);
1561 
1562  if (lastConvertedParentChar == stringSeparator) {
1563  convertedParent = convertedParent.substr(0, convertedParent.size() - 1);
1564  }
1565 
1566  if (firstConvertedChildChar == stringSeparator) {
1567  convertedChild = convertedChild.substr(1);
1568  }
1569 
1570  return std::string(convertedParent + vpIoTools::separator + convertedChild);
1571 }
1572 
1578 bool vpIoTools::isAbsolutePathname(const std::string &pathname)
1579 {
1580  //# Inspired by the Python 2.7.8 module.
1581  //# Return whether a path is absolute.
1582  //# Trivial in Posix, harder on the Mac or MS-DOS.
1583  //# For DOS it is absolute if it starts with a slash or backslash (current
1584  //# volume), or if a pathname after the volume letter and colon / UNC
1585  // resource # starts with a slash or backslash.
1586  //
1587  // def isabs(s):
1588  // """Test whether a path is absolute"""
1589  // s = splitdrive(s)[1]
1590  // return s != '' and s[:1] in '/\\'
1591  std::string path = splitDrive(pathname).second;
1592  return path.size() > 0 && (path.substr(0, 1) == "/" || path.substr(0, 1) == "\\");
1593 }
1594 
1602 bool vpIoTools::isSamePathname(const std::string &pathname1, const std::string &pathname2)
1603 {
1604  // Normalize path
1605  std::string path1_normalize = vpIoTools::path(pathname1);
1606  std::string path2_normalize = vpIoTools::path(pathname2);
1607 
1608  // Get absolute path
1609  path1_normalize = vpIoTools::getAbsolutePathname(path1_normalize);
1610  path2_normalize = vpIoTools::getAbsolutePathname(path2_normalize);
1611 
1612  return (path1_normalize == path2_normalize);
1613 }
1614 
1622 std::pair<std::string, std::string> vpIoTools::splitDrive(const std::string &pathname)
1623 {
1624 //# Split a path in a drive specification (a drive letter followed by a
1625 //# colon) and the path specification.
1626 //# It is always true that drivespec + pathspec == p
1627 // def splitdrive(p):
1628 // """Split a pathname into drive/UNC sharepoint and relative path
1629 // specifiers. Returns a 2-tuple (drive_or_unc, path); either part may be
1630 // empty.
1631 //
1632 // If you assign
1633 // result = splitdrive(p)
1634 // It is always true that:
1635 // result[0] + result[1] == p
1636 //
1637 // If the path contained a drive letter, drive_or_unc will contain
1638 // everything up to and including the colon. e.g. splitdrive("c:/dir")
1639 // returns ("c:", "/dir")
1640 //
1641 // If the path contained a UNC path, the drive_or_unc will contain the host
1642 // name and share up to but not including the fourth directory separator
1643 // character. e.g. splitdrive("//host/computer/dir") returns
1644 // ("//host/computer", "/dir")
1645 //
1646 // Paths cannot contain both a drive letter and a UNC path.
1647 //
1648 // """
1649 // if len(p) > 1:
1650 // normp = p.replace(altsep, sep)
1651 // if (normp[0:2] == sep*2) and (normp[2] != sep):
1652 // # is a UNC path:
1653 // # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
1654 // # \\machine\mountpoint\directory\etc\...
1655 // # directory ^^^^^^^^^^^^^^^
1656 // index = normp.find(sep, 2)
1657 // if index == -1:
1658 // return '', p
1659 // index2 = normp.find(sep, index + 1)
1660 // # a UNC path can't have two slashes in a row
1661 // # (after the initial two)
1662 // if index2 == index + 1:
1663 // return '', p
1664 // if index2 == -1:
1665 // index2 = len(p)
1666 // return p[:index2], p[index2:]
1667 // if normp[1] == ':':
1668 // return p[:2], p[2:]
1669 // return '', p
1670 
1671 // On Unix, the drive is always empty.
1672 // On the Mac, the drive is always empty (don't use the volume name -- it
1673 // doesn't have the same syntactic and semantic oddities as DOS drive
1674 // letters, such as there being a separate current directory per drive).
1675 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
1676  return std::pair<std::string, std::string>("", pathname);
1677 #else
1678  const std::string sep = "\\";
1679  const std::string sepsep = "\\\\";
1680  const std::string altsep = "/";
1681 
1682  if (pathname.size() > 1) {
1683  std::string normPathname = pathname;
1684  std::replace(normPathname.begin(), normPathname.end(), *altsep.c_str(), *sep.c_str());
1685 
1686  if (normPathname.substr(0, 2) == sepsep && normPathname.substr(2, 1) != sep) {
1687  // is a UNC path:
1688  // vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
1689  // \\machine\mountpoint\directory\etc\...
1690  // directory ^^^^^^^^^^^^^^^
1691  size_t index = normPathname.find(sep, 2);
1692  if (index == std::string::npos) {
1693  return std::pair<std::string, std::string>("", pathname);
1694  }
1695 
1696  size_t index2 = normPathname.find(sep, index + 1);
1697  //# a UNC path can't have two slashes in a row
1698  //# (after the initial two)
1699  if (index2 == index + 1) {
1700  return std::pair<std::string, std::string>("", pathname);
1701  }
1702 
1703  if (index2 == std::string::npos) {
1704  index2 = pathname.size();
1705  }
1706 
1707  return std::pair<std::string, std::string>(pathname.substr(0, index2), pathname.substr(index2));
1708  }
1709 
1710  if (normPathname[1] == ':') {
1711  return std::pair<std::string, std::string>(pathname.substr(0, 2), pathname.substr(2));
1712  }
1713  }
1714 
1715  return std::pair<std::string, std::string>("", pathname);
1716 #endif
1717 }
1718 
1767 std::vector<std::string> vpIoTools::splitChain(const std::string &chain, const std::string &sep)
1768 {
1769  size_t startIndex = 0;
1770 
1771  std::string chainToSplit = chain;
1772  std::vector<std::string> subChain;
1773  size_t sepIndex = chainToSplit.find(sep);
1774 
1775  while (sepIndex != std::string::npos) {
1776  std::string sub = chainToSplit.substr(startIndex, sepIndex);
1777  if (!sub.empty())
1778  subChain.push_back(sub);
1779  chainToSplit = chainToSplit.substr(sepIndex + 1, chain.size() - 1);
1780 
1781  sepIndex = chainToSplit.find(sep);
1782  }
1783  if (!chainToSplit.empty())
1784  subChain.push_back(chainToSplit);
1785 
1786  return subChain;
1787 }
1788 
1796 std::vector<std::string> vpIoTools::getDirFiles(const std::string &pathname)
1797 {
1798 
1799  if (!checkDirectory(pathname)) {
1800  throw(vpIoException(vpException::fatalError, "Directory %s doesn't exist'", pathname.c_str()));
1801  }
1802  std::string dirName = path(pathname);
1803 
1804 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1805 
1806  std::vector<std::string> files;
1807  struct dirent **list = NULL;
1808  int filesCount = scandir(dirName.c_str(), &list, NULL, NULL);
1809  if (filesCount == -1) {
1810  throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
1811  }
1812  for (int i = 0; i < filesCount; i++) {
1813  std::string fileName = list[i]->d_name;
1814  if (fileName != "." && fileName != "..") {
1815  files.push_back(fileName);
1816  }
1817  free(list[i]);
1818  }
1819  free(list);
1820  std::sort(files.begin(), files.end());
1821  return files;
1822 
1823 #elif defined(_WIN32)
1824 #if (!defined(WINRT))
1825 
1826  std::vector<std::string> files;
1827  std::string fileMask = dirName;
1828  fileMask.append("\\*");
1829  WIN32_FIND_DATA FindFileData;
1830  HANDLE hFind = FindFirstFile(fileMask.c_str(), &FindFileData);
1831  // Directory is empty
1832  if (HandleToLong(&hFind) == ERROR_FILE_NOT_FOUND) {
1833  return files;
1834  }
1835  if (hFind == INVALID_HANDLE_VALUE) {
1836  throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
1837  }
1838  do {
1839  std::string fileName = FindFileData.cFileName;
1840  if (fileName != "." && fileName != "..") {
1841  files.push_back(fileName);
1842  }
1843  } while (FindNextFile(hFind, &FindFileData));
1844  FindClose(hFind);
1845  std::sort(files.begin(), files.end());
1846  return files;
1847 
1848 #else
1850  "Cannot read files of directory %s: not implemented on "
1851  "Universal Windows Platform",
1852  dirName.c_str()));
1853 #endif
1854 #endif
1855 }
1856 
1860 void vpIoTools::readBinaryValueLE(std::ifstream &file, int16_t &short_value)
1861 {
1862  file.read((char *)(&short_value), sizeof(short_value));
1863 
1864 #ifdef VISP_BIG_ENDIAN
1865  // Swap bytes order from little endian to big endian
1866  short_value = swap16bits((uint16_t)short_value);
1867 #endif
1868 }
1869 
1873 void vpIoTools::readBinaryValueLE(std::ifstream &file, uint16_t &ushort_value)
1874 {
1875  file.read((char *)(&ushort_value), sizeof(ushort_value));
1876 
1877 #ifdef VISP_BIG_ENDIAN
1878  // Swap bytes order from little endian to big endian
1879  ushort_value = swap16bits(ushort_value);
1880 #endif
1881 }
1882 
1886 void vpIoTools::readBinaryValueLE(std::ifstream &file, int32_t &int_value)
1887 {
1888  file.read((char *)(&int_value), sizeof(int_value));
1889 
1890 #ifdef VISP_BIG_ENDIAN
1891  // Swap bytes order from little endian to big endian
1892  int_value = swap32bits((uint32_t)int_value);
1893 #endif
1894 }
1895 
1899 void vpIoTools::readBinaryValueLE(std::ifstream &file, uint32_t &uint_value)
1900 {
1901  file.read((char *)(&uint_value), sizeof(uint_value));
1902 
1903 #ifdef VISP_BIG_ENDIAN
1904  // Swap bytes order from little endian to big endian
1905  uint_value = swap32bits(uint_value);
1906 #endif
1907 }
1908 
1912 void vpIoTools::readBinaryValueLE(std::ifstream &file, float &float_value)
1913 {
1914  file.read((char *)(&float_value), sizeof(float_value));
1915 
1916 #ifdef VISP_BIG_ENDIAN
1917  // Swap bytes order from little endian to big endian
1918  float_value = swapFloat(float_value);
1919 #endif
1920 }
1921 
1925 void vpIoTools::readBinaryValueLE(std::ifstream &file, double &double_value)
1926 {
1927  file.read((char *)(&double_value), sizeof(double_value));
1928 
1929 #ifdef VISP_BIG_ENDIAN
1930  // Swap bytes order from little endian to big endian
1931  double_value = swapDouble(double_value);
1932 #endif
1933 }
1934 
1938 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
1939 {
1940 #ifdef VISP_BIG_ENDIAN
1941  // Swap bytes order to little endian
1942  uint16_t swap_short = swap16bits((uint16_t)short_value);
1943  file.write((char *)(&swap_short), sizeof(swap_short));
1944 #else
1945  file.write((char *)(&short_value), sizeof(short_value));
1946 #endif
1947 }
1948 
1952 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint16_t ushort_value)
1953 {
1954 #ifdef VISP_BIG_ENDIAN
1955  // Swap bytes order to little endian
1956  uint16_t swap_ushort = swap16bits(ushort_value);
1957  file.write((char *)(&swap_ushort), sizeof(swap_ushort));
1958 #else
1959  file.write((char *)(&ushort_value), sizeof(ushort_value));
1960 #endif
1961 }
1962 
1966 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int32_t int_value)
1967 {
1968 #ifdef VISP_BIG_ENDIAN
1969  // Swap bytes order to little endian
1970  uint32_t swap_int = swap32bits((uint32_t)int_value);
1971  file.write((char *)(&swap_int), sizeof(swap_int));
1972 #else
1973  file.write((char *)(&int_value), sizeof(int_value));
1974 #endif
1975 }
1976 
1980 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint32_t uint_value)
1981 {
1982 #ifdef VISP_BIG_ENDIAN
1983  // Swap bytes order to little endian
1984  uint32_t swap_int = swap32bits(uint_value);
1985  file.write((char *)(&swap_int), sizeof(swap_int));
1986 #else
1987  file.write((char *)(&uint_value), sizeof(uint_value));
1988 #endif
1989 }
1990 
1994 void vpIoTools::writeBinaryValueLE(std::ofstream &file, float float_value)
1995 {
1996 #ifdef VISP_BIG_ENDIAN
1997  // Swap bytes order to little endian
1998  float swap_float = swapFloat(float_value);
1999  file.write((char *)(&swap_float), sizeof(swap_float));
2000 #else
2001  file.write((char *)(&float_value), sizeof(float_value));
2002 #endif
2003 }
2004 
2008 void vpIoTools::writeBinaryValueLE(std::ofstream &file, double double_value)
2009 {
2010 #ifdef VISP_BIG_ENDIAN
2011  // Swap bytes order to little endian
2012  double swap_double = swapDouble(double_value);
2013  file.write((char *)(&swap_double), sizeof(swap_double));
2014 #else
2015  file.write((char *)(&double_value), sizeof(double_value));
2016 #endif
2017 }
2018 
2019 bool vpIoTools::parseBoolean(std::string input)
2020 {
2021  std::transform(input.begin(), input.end(), input.begin(), ::tolower);
2022  std::istringstream is(input);
2023  bool b;
2024  // Parse string to boolean either in the textual representation
2025  // (True/False) or in numeric representation (1/0)
2026  is >> (input.size() > 1 ? std::boolalpha : std::noboolalpha) >> b;
2027  return b;
2028 }
2029 
2033 std::string vpIoTools::trim(std::string s)
2034 {
2035  return ltrim(rtrim(s));
2036 }
static void makeDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:572
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:305
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1292
static bool isAbsolutePathname(const std::string &pathname)
Definition: vpIoTools.cpp:1578
static void getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
Definition: vpIoTools.cpp:382
static bool rename(const std::string &oldfilename, const std::string &newfilename)
Definition: vpIoTools.cpp:913
static void readBinaryValueLE(std::ifstream &file, int16_t &short_value)
Definition: vpIoTools.cpp:1860
Class to define colors available for display functionnalities.
Definition: vpColor.h:119
static const char separator
Definition: vpIoTools.h:185
unsigned int getRows() const
Definition: vpArray2D.h:289
static bool copy(const std::string &src, const std::string &dst)
Definition: vpIoTools.cpp:772
static std::string getFileExtension(const std::string &pathname, bool checkFile=false)
Definition: vpIoTools.cpp:1357
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:1796
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:1473
static bool checkFifo(const std::string &filename)
Definition: vpIoTools.cpp:482
static std::string path(const std::string &pathname)
Definition: vpIoTools.cpp:931
static void createBaseNamePath(const bool &empty=false)
Definition: vpIoTools.cpp:1250
static const std::string & getBuildInformation()
Definition: vpIoTools.cpp:225
static bool checkDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:422
static std::string baseDir
Definition: vpIoTools.h:252
unsigned int getCols() const
Definition: vpArray2D.h:279
static void setBaseName(const std::string &s)
Definition: vpIoTools.cpp:238
static bool parseBoolean(std::string input)
Definition: vpIoTools.cpp:2019
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1537
static std::pair< std::string, std::string > splitDrive(const std::string &pathname)
Definition: vpIoTools.cpp:1622
static bool isSamePathname(const std::string &pathname1, const std::string &pathname2)
Definition: vpIoTools.cpp:1602
static void makeFifo(const std::string &dirname)
Definition: vpIoTools.cpp:623
static std::string getUserName()
Definition: vpIoTools.cpp:318
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1767
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:151
static void saveConfigFile(const bool &actuallySave=true)
Definition: vpIoTools.cpp:1269
static std::vector< std::string > configVars
Definition: vpIoTools.h:254
static std::string getName(const std::string &pathname)
Definition: vpIoTools.cpp:1438
static void writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
Definition: vpIoTools.cpp:1938
static bool remove(const std::string &filename)
Definition: vpIoTools.cpp:855
static std::string makeTempDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:671
static std::string baseName
Definition: vpIoTools.h:251
static std::string getFullName()
Definition: vpIoTools.cpp:256
static std::string trim(std::string s)
Definition: vpIoTools.cpp:2033
static std::string configFile
Definition: vpIoTools.h:253
static void setBaseDir(const std::string &dir)
Definition: vpIoTools.cpp:244
static std::string getNameWE(const std::string &pathname)
Definition: vpIoTools.cpp:1460
static std::string getBaseName()
Definition: vpIoTools.cpp:250
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:730
static std::string getAbsolutePathname(const std::string &pathname)
Definition: vpIoTools.cpp:1495
static vpColor getColor(const unsigned int &i)
Definition: vpColor.h:248
static bool readConfigVar(const std::string &var, float &value)
Definition: vpIoTools.cpp:1018
static std::vector< std::string > configValues
Definition: vpIoTools.h:255
static bool loadConfigFile(const std::string &confFile)
Definition: vpIoTools.cpp:971
static void addNameElement(const std::string &strTrue, const bool &cond=true, const std::string &strFalse="")
Definition: vpIoTools.cpp:1215
static std::string getenv(const std::string &env)
Definition: vpIoTools.cpp:355