Visual Servoing Platform  version 3.2.1 under development (2019-12-07)
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 
263 void vpIoTools::getUserName(std::string &username)
264 {
265 // With MinGW, UNIX and _WIN32 are defined
266 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
267  // Get the user name.
268  char *_username = ::getenv("LOGNAME");
269  if (!_username) {
270  username = "unknown";
271  }
272  else {
273  username = _username;
274  }
275 #elif defined(_WIN32)
276 #if (!defined(WINRT))
277  unsigned int info_buffer_size = 1024;
278  TCHAR *infoBuf = new TCHAR[info_buffer_size];
279  DWORD bufCharCount = (DWORD)info_buffer_size;
280  // Get the user name.
281  if (!GetUserName(infoBuf, &bufCharCount)) {
282  username = "unknown";
283  } else {
284  username = infoBuf;
285  }
286  delete[] infoBuf;
287 #else
288  // Universal platform
289  username = "unknown";
290 #endif
291 #else
292  username = "unknown";
293 #endif
294 }
295 
311 {
312  std::string username;
313  getUserName(username);
314  return username;
315 }
316 
347 std::string vpIoTools::getenv(const std::string &env)
348 {
349 #if defined(_WIN32) && defined(WINRT)
350  throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value: not "
351  "implemented on Universal Windows Platform"));
352 #else
353  std::string value;
354  // Get the environment variable value.
355  char *_value = ::getenv(env.c_str());
356  if (! _value) {
357  throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value"));
358  }
359  value = _value;
360 
361  return value;
362 #endif
363 }
364 
374 void vpIoTools::getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
375 {
376  if (version.size() == 0) {
377  major = 0;
378  minor = 0;
379  patch = 0;
380  } else {
381  size_t major_pos = version.find('.');
382  std::string major_str = version.substr(0, major_pos);
383  major = static_cast<unsigned>(atoi(major_str.c_str()));
384 
385  if (major_pos != std::string::npos) {
386  size_t minor_pos = version.find('.', major_pos + 1);
387  std::string minor_str = version.substr(major_pos + 1, (minor_pos - (major_pos + 1)));
388  minor = static_cast<unsigned>(atoi(minor_str.c_str()));
389 
390  if (minor_pos != std::string::npos) {
391  std::string patch_str = version.substr(minor_pos + 1);
392  patch = static_cast<unsigned>(atoi(patch_str.c_str()));
393  } else {
394  patch = 0;
395  }
396  } else {
397  minor = 0;
398  patch = 0;
399  }
400  }
401 }
402 
414 bool vpIoTools::checkDirectory(const std::string &dirname)
415 {
416 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
417  struct stat stbuf;
418 #elif defined(_WIN32) && defined(__MINGW32__)
419  struct stat stbuf;
420 #elif defined(_WIN32)
421  struct _stat stbuf;
422 #endif
423 
424  if (dirname.empty()) {
425  return false;
426  }
427 
428  std::string _dirname = path(dirname);
429 
430 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
431  if (stat(_dirname.c_str(), &stbuf) != 0)
432 #elif defined(_WIN32) && defined(__MINGW32__)
433  // Remove trailing separator character if any
434  // AppVeyor: Windows 6.3.9600 AMD64 ; C:/MinGW/bin/g++.exe (ver 5.3.0) ;
435  // GNU Make 3.82.90 Built for i686-pc-mingw32
436  if (_dirname.at(_dirname.size() - 1) == vpIoTools::separator)
437  _dirname = _dirname.substr(0, _dirname.size() - 1);
438  if (stat(_dirname.c_str(), &stbuf) != 0)
439 #elif defined(_WIN32)
440  if (_stat(_dirname.c_str(), &stbuf) != 0)
441 #endif
442  {
443  return false;
444  }
445 #if defined(_WIN32) || (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
446  if ((stbuf.st_mode & S_IFDIR) == 0)
447 #endif
448  {
449  return false;
450  }
451 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
452  if ((stbuf.st_mode & S_IWUSR) == 0)
453 #elif defined(_WIN32)
454  if ((stbuf.st_mode & S_IWRITE) == 0)
455 #endif
456  {
457  return false;
458  }
459  return true;
460 }
461 
474 bool vpIoTools::checkFifo(const std::string &fifofilename)
475 {
476 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
477  struct stat stbuf;
478 
479  std::string _filename = path(fifofilename);
480  if (stat(_filename.c_str(), &stbuf) != 0) {
481  return false;
482  }
483  if ((stbuf.st_mode & S_IFIFO) == 0) {
484  return false;
485  }
486  if ((stbuf.st_mode & S_IRUSR) == 0)
487 
488  {
489  return false;
490  }
491  return true;
492 #elif defined(_WIN32)
493  (void)fifofilename;
494  throw(vpIoException(vpIoException::notImplementedError, "Fifo files are not supported on Windows platforms."));
495 #endif
496 }
497 
498 #ifndef DOXYGEN_SHOULD_SKIP_THIS
499 // See:
500 // https://gist.github.com/JonathonReinhart/8c0d90191c38af2dcadb102c4e202950
501 int vpIoTools::mkdir_p(const char *path, const int mode)
502 {
503  /* Adapted from http://stackoverflow.com/a/2336245/119527 */
504  const size_t len = strlen(path);
505  char _path[PATH_MAX];
506  const char sep = vpIoTools::separator;
507 
508  std::fill(_path, _path + PATH_MAX, 0);
509 
510  errno = 0;
511  if (len > sizeof(_path) - 1) {
512  errno = ENAMETOOLONG;
513  return -1;
514  }
515  /* Copy string so its mutable */
516  strcpy(_path, path);
517 
518  /* Iterate over the string */
519  for (char *p = _path + 1; *p; p++) { // path cannot be empty
520  if (*p == sep) {
521  /* Temporarily truncate */
522  *p = '\0';
523 
524 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
525  if (mkdir(_path, static_cast<mode_t>(mode)) != 0)
526 #elif defined(_WIN32)
527  (void)mode; // var not used
528  if (!checkDirectory(_path) && _mkdir(_path) != 0)
529 #endif
530  {
531  if (errno != EEXIST)
532  return -1;
533  }
534  *p = sep;
535  }
536  }
537 
538 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
539  if (mkdir(_path, static_cast<mode_t>(mode)) != 0)
540 #elif defined(_WIN32)
541  if (_mkdir(_path) != 0)
542 #endif
543  {
544  if (errno != EEXIST)
545  return -1;
546  }
547 
548  return 0;
549 }
550 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
551 
564 void vpIoTools::makeDirectory(const std::string &dirname)
565 {
566 #if ((!defined(__unix__) && !defined(__unix) && (!defined(__APPLE__) || !defined(__MACH__)))) && !defined(_WIN32)
567  std::cerr << "Unsupported platform for vpIoTools::makeDirectory()!" << std::endl;
568  return;
569 #endif
570 
571 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
572  struct stat stbuf;
573 #elif defined(_WIN32) && defined(__MINGW32__)
574  struct stat stbuf;
575 #elif defined(_WIN32)
576  struct _stat stbuf;
577 #endif
578 
579  if (dirname.empty()) {
580  throw(vpIoException(vpIoException::invalidDirectoryName, "invalid directory name"));
581  }
582 
583  std::string _dirname = path(dirname);
584 
585 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
586  if (stat(_dirname.c_str(), &stbuf) != 0)
587 #elif defined(_WIN32) && defined(__MINGW32__)
588  if (stat(_dirname.c_str(), &stbuf) != 0)
589 #elif defined(_WIN32)
590  if (_stat(_dirname.c_str(), &stbuf) != 0)
591 #endif
592  {
593  if (vpIoTools::mkdir_p(_dirname.c_str(), 0755) != 0) {
594  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'", dirname.c_str()));
595  }
596  }
597 
598  if (checkDirectory(dirname) == false) {
599  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'", dirname.c_str()));
600  }
601 }
602 
615 void vpIoTools::makeFifo(const std::string &fifoname)
616 {
617 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
618 
619  // If dirname is a directory, we throw an error
620  if (vpIoTools::checkDirectory(fifoname)) {
622  "Unable to create fifo file. '%s' is an existing directory.", fifoname.c_str()));
623  }
624 
625  // If dirname refers to an already existing file, we throw an error
626  else if (vpIoTools::checkFilename(fifoname)) {
627  throw(vpIoException(vpIoException::invalidDirectoryName, "Unable to create fifo file '%s'. File already exists.",
628  fifoname.c_str()));
629  // If dirname refers to an already existing fifo, we throw an error
630  } else if (vpIoTools::checkFifo(fifoname)) {
631  throw(vpIoException(vpIoException::invalidDirectoryName, "Unable to create fifo file '%s'. Fifo already exists.",
632  fifoname.c_str()));
633  }
634 
635  else if (mkfifo(fifoname.c_str(), 0666) < 0) {
636  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create fifo file '%s'.", fifoname.c_str()));
637  }
638 #elif defined(_WIN32)
639  (void)fifoname;
640  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create fifo on Windows platforms."));
641 #endif
642 }
643 
663 std::string vpIoTools::makeTempDirectory(const std::string &dirname)
664 {
665 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
666 
667  std::string dirname_cpy = std::string(dirname);
668 
669  std::string correctEnding = "XXXXXX";
670 
671  size_t endingLength = correctEnding.length();
672  size_t dirNameLength = dirname_cpy.length();
673 
674  // If dirname is an unexisting directory, it should end with XXXXXX in order to create a temp directory
675  if (!vpIoTools::checkDirectory(dirname_cpy)) {
676  if (endingLength > dirNameLength) {
678  "Unable to create temp directory '%s'. It should end with XXXXXX.", dirname_cpy.c_str()));
679  }
680 
681  if (dirname.compare(dirNameLength - endingLength, endingLength, correctEnding) != 0) {
683  "Unable to create temp directory '%s'. It should end with XXXXXX.", dirname_cpy.c_str()));
684  }
685 
686  // If dirname is an existing directory, we create a temp directory inside
687  } else {
688  if (dirname_cpy.at(dirname_cpy.length() - 1) != '/') {
689  dirname_cpy = dirname_cpy + "/";
690  }
691  dirname_cpy = dirname_cpy + "XXXXXX";
692  }
693  char *dirname_char = new char[dirname_cpy.length() + 1];
694  strcpy(dirname_char, dirname_cpy.c_str());
695 
696  char *computedDirname = mkdtemp(dirname_char);
697 
698  if (!computedDirname) {
699  delete[] dirname_char;
700  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'.", dirname_cpy.c_str()));
701  }
702 
703  std::string res(computedDirname);
704  delete[] dirname_char;
705  return res;
706 #elif defined(_WIN32)
707  (void)dirname;
708  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create temp directory. Not implemented yet."));
709 #endif
710 }
711 
722 bool vpIoTools::checkFilename(const std::string &filename)
723 {
724 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
725  struct stat stbuf;
726 #elif defined(_WIN32)
727  struct _stat stbuf;
728 #endif
729 
730  if (filename.empty()) {
731  return false;
732  }
733 
734  std::string _filename = path(filename);
735 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
736  if (stat(_filename.c_str(), &stbuf) != 0)
737 #elif defined(_WIN32)
738  if (_stat(_filename.c_str(), &stbuf) != 0)
739 #endif
740  {
741  return false;
742  }
743  if ((stbuf.st_mode & S_IFREG) == 0) {
744  return false;
745  }
746 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
747  if ((stbuf.st_mode & S_IRUSR) == 0)
748 #elif defined(_WIN32)
749  if ((stbuf.st_mode & S_IREAD) == 0)
750 #endif
751  {
752  return false;
753  }
754  return true;
755 }
756 
764 bool vpIoTools::copy(const std::string &src, const std::string &dst)
765 {
766  // Check if we have to consider a file or a directory
767  if (vpIoTools::checkFilename(src)) {
768 // std::cout << "copy file: " << src << " in " << dst << std::endl;
769 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
770 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
771  // wordexp() is not available
772  char cmd[FILENAME_MAX];
773  int ret;
774  sprintf(cmd, "cp -p %s %s", src.c_str(), dst.c_str());
775  ret = system(cmd);
776  if (ret) {
777  }; // to avoid a warning
778  // std::cout << cmd << " return value: " << ret << std::endl;
779  return true;
780 #else
781  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src.c_str(), dst.c_str()));
782 #endif
783 #elif defined(_WIN32)
784 #if (!defined(WINRT))
785  char cmd[FILENAME_MAX];
786  int ret;
787  std::string src_ = vpIoTools::path(src);
788  std::string dst_ = vpIoTools::path(dst);
789  sprintf(cmd, "copy %s %s", src_.c_str(), dst_.c_str());
790  ret = system(cmd);
791  if (ret) {
792  }; // to avoid a warning
793  // std::cout << cmd << " return value: " << ret << std::endl;
794  return true;
795 #else
796  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
797  src.c_str(), dst.c_str()));
798 #endif
799 #endif
800  } else if (vpIoTools::checkDirectory(src)) {
801 // std::cout << "copy directory: " << src << " in " << dst << std::endl;
802 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
803 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
804  // wordexp() is not available
805  char cmd[FILENAME_MAX];
806  int ret;
807  sprintf(cmd, "cp -p -r %s %s", src.c_str(), dst.c_str());
808  ret = system(cmd);
809  if (ret) {
810  }; // to avoid a warning
811  // std::cout << cmd << " return value: " << ret << std::endl;
812  return true;
813 #else
814  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src.c_str(), dst.c_str()));
815 #endif
816 #elif defined(_WIN32)
817 #if (!defined(WINRT))
818  char cmd[FILENAME_MAX];
819  int ret;
820  std::string src_ = vpIoTools::path(src);
821  std::string dst_ = vpIoTools::path(dst);
822  sprintf(cmd, "copy %s %s", src_.c_str(), dst_.c_str());
823  ret = system(cmd);
824  if (ret) {
825  }; // to avoid a warning
826  // std::cout << cmd << " return value: " << ret << std::endl;
827  return true;
828 #else
829  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
830  src.c_str(), dst.c_str()));
831 #endif
832 #endif
833  } else {
834  std::cout << "Cannot copy: " << src << " in " << dst << std::endl;
835  return false;
836  }
837 }
838 
847 bool vpIoTools::remove(const std::string &file_or_dir)
848 {
849  // Check if we have to consider a file or a directory
850  if (vpIoTools::checkFilename(file_or_dir)
851 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
852  || vpIoTools::checkFifo(std::string(file_or_dir))
853 #endif
854  ) {
855  // std::cout << "remove file: " << file_or_dir << std::endl;
856  if (::remove(file_or_dir.c_str()) != 0)
857  return false;
858  else
859  return true;
860  } else if (vpIoTools::checkDirectory(file_or_dir)) {
861 // std::cout << "remove directory: " << file_or_dir << std::endl;
862 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
863 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
864  // wordexp() is not available
865  char cmd[FILENAME_MAX];
866  sprintf(cmd, "rm -rf \"%s\"", file_or_dir.c_str());
867  int ret = system(cmd);
868  if (ret) {
869  }; // to avoid a warning
870  // std::cout << cmd << " return value: " << ret << std::endl;
871  return true;
872 #else
873  throw(vpIoException(vpException::fatalError, "Cannot remove %s: not implemented on iOS Platform", file_or_dir.c_str()));
874 #endif
875 #elif defined(_WIN32)
876 #if (!defined(WINRT))
877  char cmd[FILENAME_MAX];
878  std::string file_or_dir_ = vpIoTools::path(file_or_dir);
879  sprintf(cmd, "rmdir /S /Q %s", file_or_dir_.c_str());
880  int ret = system(cmd);
881  if (ret) {
882  }; // to avoid a warning
883  // std::cout << cmd << " return value: " << ret << std::endl;
884  return true;
885 #else
886  throw(vpIoException(vpException::fatalError, "Cannot remove %s: not implemented on Universal Windows Platform",
887  file_or_dir.c_str()));
888 #endif
889 #endif
890  } else {
891  std::cout << "Cannot remove: " << file_or_dir << std::endl;
892  return false;
893  }
894 }
895 
905 bool vpIoTools::rename(const std::string &oldfilename, const std::string &newfilename)
906 {
907  if (::rename(oldfilename.c_str(), newfilename.c_str()) != 0)
908  return false;
909  else
910  return true;
911 }
912 
923 std::string vpIoTools::path(const std::string &pathname)
924 {
925  std::string path(pathname);
926 
927 #if defined(_WIN32)
928  for (unsigned int i = 0; i < path.length(); i++)
929  if (path[i] == '/')
930  path[i] = '\\';
931 #elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
932  for (unsigned int i = 0; i < path.length(); i++)
933  if (path[i] == '\\')
934  path[i] = '/';
935 #if TARGET_OS_IOS == 0 // The following code is not working on iOS and android since
936  // wordexp() is not available
937  #ifdef __ANDROID__
938  // Do nothing
939  #else
940  wordexp_t exp_result;
941 
942  // escape quote character
943  replaceAll(path, "'", "'\\''");
944  // add quotes to handle special characters like parentheses and spaces
945  wordexp(std::string("'" + path + "'").c_str(), &exp_result, 0);
946  path = exp_result.we_wordc == 1 ? exp_result.we_wordv[0] : "";
947  wordfree(&exp_result);
948  #endif
949 #endif
950 #endif
951 
952  return path;
953 }
954 
963 bool vpIoTools::loadConfigFile(const std::string &confFile)
964 {
965  configFile = path(confFile);
966  configVars.clear();
967  configValues.clear();
968  std::ifstream confContent(configFile.c_str(), std::ios::in);
969 
970  if (confContent.is_open()) {
971  std::string line, var, val;
972  long unsigned int k;
973  int c;
974  std::string stop[3] = {" ", "\t", "#"};
975  while (std::getline(confContent, line)) {
976  if ((line.compare(0, 1, "#") != 0) && (line.size() > 2)) {
977  try {
978  // name of the variable
979  k = static_cast<unsigned long>(line.find(" "));
980  var = line.substr(0, k);
981  // look for the end of the actual value
982  c = 200;
983  for (unsigned i = 0; i < 3; ++i)
984  c = vpMath::minimum(c, static_cast<int>(line.find(stop[i], static_cast<size_t>(k) + static_cast<size_t>(1))));
985  if (c == -1)
986  c = static_cast<int>(line.size());
987  long unsigned int c_ = static_cast<long unsigned int>(c);
988  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));
989  configVars.push_back(var);
990  configValues.push_back(val);
991  } catch (...) {
992  }
993  }
994  }
995  confContent.close();
996  } else {
997  return false;
998  }
999  return true;
1000 }
1001 
1010 bool vpIoTools::readConfigVar(const std::string &var, float &value)
1011 {
1012  bool found = false;
1013  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1014  if (configVars[k] == var) {
1015  if (configValues[k].compare("PI") == 0)
1016  value = static_cast<float>(M_PI);
1017  else if (configValues[k].compare("PI/2") == 0)
1018  value = static_cast<float>(M_PI / 2.0);
1019  else if (configValues[k].compare("-PI/2") == 0)
1020  value = static_cast<float>(-M_PI / 2.0);
1021  else
1022  value = static_cast<float>(atof(configValues[k].c_str()));
1023  found = true;
1024  }
1025  }
1026  if (found == false)
1027  std::cout << var << " not found in config file" << std::endl;
1028  return found;
1029 }
1038 bool vpIoTools::readConfigVar(const std::string &var, double &value)
1039 {
1040  bool found = false;
1041  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1042  if (configVars[k] == var) {
1043  if (configValues[k].compare("PI") == 0)
1044  value = M_PI;
1045  else if (configValues[k].compare("PI/2") == 0)
1046  value = M_PI / 2;
1047  else if (configValues[k].compare("-PI/2") == 0)
1048  value = -M_PI / 2;
1049  else
1050  value = atof(configValues[k].c_str());
1051  found = true;
1052  }
1053  }
1054  if (found == false)
1055  std::cout << var << " not found in config file" << std::endl;
1056  return found;
1057 }
1058 
1067 bool vpIoTools::readConfigVar(const std::string &var, int &value)
1068 {
1069  bool found = false;
1070  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1071  if (configVars[k] == var) {
1072  value = atoi(configValues[k].c_str());
1073  found = true;
1074  }
1075  }
1076  if (found == false)
1077  std::cout << var << " not found in config file" << std::endl;
1078  return found;
1079 }
1080 
1089 bool vpIoTools::readConfigVar(const std::string &var, unsigned int &value)
1090 {
1091  int v = 0;
1092  bool found = readConfigVar(var, v);
1093  value = static_cast<unsigned int>(v);
1094  return found;
1095 }
1096 
1105 bool vpIoTools::readConfigVar(const std::string &var, bool &value)
1106 {
1107  int v = 0;
1108  bool found = readConfigVar(var, v);
1109  value = (v != 0);
1110  return found;
1111 }
1112 
1121 bool vpIoTools::readConfigVar(const std::string &var, vpColor &value)
1122 {
1123  unsigned int v = 0;
1124  bool found = readConfigVar(var, v);
1125  value = vpColor::getColor(v);
1126  return found;
1127 }
1128 
1137 bool vpIoTools::readConfigVar(const std::string &var, std::string &value)
1138 {
1139  bool found = false;
1140  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1141  if (configVars[k] == var) {
1142  value = configValues[k];
1143  found = true;
1144  }
1145  }
1146  if (found == false)
1147  std::cout << var << " not found in config file" << std::endl;
1148  return found;
1149 }
1150 
1164 bool vpIoTools::readConfigVar(const std::string &var, vpArray2D<double> &value, const unsigned int &nCols,
1165  const unsigned int &nRows)
1166 {
1167  bool found = false;
1168  std::string nb;
1169  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1170  if (configVars[k] == var) {
1171  found = true;
1172  // resize or not
1173  if (nCols != 0 && nRows != 0)
1174  value.resize(nRows, nCols);
1175  size_t ind = 0, ind2;
1176  for (unsigned int i = 0; i < value.getRows(); ++i)
1177  for (unsigned int j = 0; j < value.getCols(); ++j) {
1178  ind2 = configValues[k].find(",", ind);
1179  nb = configValues[k].substr(ind, ind2 - ind);
1180  if (nb.compare("PI") == 0)
1181  value[i][j] = M_PI;
1182  else if (nb.compare("PI/2") == 0)
1183  value[i][j] = M_PI / 2;
1184  else if (nb.compare("-PI/2") == 0)
1185  value[i][j] = -M_PI / 2;
1186  else
1187  value[i][j] = atof(nb.c_str());
1188  ind = ind2 + 1;
1189  }
1190  }
1191  }
1192  if (found == false)
1193  std::cout << var << " not found in config file" << std::endl;
1194  return found;
1195 }
1196 
1197 // construct experiment filename & path
1198 
1207 void vpIoTools::addNameElement(const std::string &strTrue, const bool &cond, const std::string &strFalse)
1208 {
1209  if (cond)
1210  baseName += "_" + strTrue;
1211  else if (strFalse != "")
1212  baseName += "_" + strFalse;
1213 }
1214 
1223 void vpIoTools::addNameElement(const std::string &strTrue, const double &val)
1224 {
1225  // if(val != 0.)
1226  if (std::fabs(val) < std::numeric_limits<double>::epsilon()) {
1227  char valC[256];
1228  sprintf(valC, "%.3f", val);
1229  std::string valS(valC);
1230  baseName += "_" + strTrue + valS;
1231  }
1232 }
1233 
1242 void vpIoTools::createBaseNamePath(const bool &empty)
1243 {
1244  if (vpIoTools::checkDirectory(baseDir + baseName) == false) {
1246  std::cout << "creating directory " + baseDir + baseName << std::endl;
1247  } else {
1248  if (empty) {
1249  std::cout << "emptying directory " + baseDir + baseName << std::endl;
1251  }
1252  }
1253 }
1254 
1261 void vpIoTools::saveConfigFile(const bool &actuallySave)
1262 {
1263  if (actuallySave) {
1264  std::string dest = baseDir + "/" + baseName + "_config.txt";
1265  // file copy
1266  vpIoTools::copy(configFile, dest);
1267  }
1268 }
1269 
1285 {
1286  std::string data_path;
1287  std::string file_to_test("mbt/cube.cao");
1288  std::string filename;
1289 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1290  // Test if visp-images-data package is u-installed (Ubuntu and Debian)
1291  data_path = "/usr/share/visp-images-data/ViSP-images";
1292  filename = data_path + "/" + file_to_test;
1293  if (vpIoTools::checkFilename(filename))
1294  return data_path;
1295  data_path = "/usr/share/visp-images-data/visp-images";
1296  filename = data_path + "/" + file_to_test;
1297  if (vpIoTools::checkFilename(filename))
1298  return data_path;
1299 #endif
1300  // Test if VISP_INPUT_IMAGE_PATH env var is set
1301  try {
1302  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH");
1303  filename = data_path + "/" + file_to_test;
1304  if (vpIoTools::checkFilename(filename))
1305  return data_path;
1306  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/ViSP-images";
1307  filename = data_path + "/" + file_to_test;
1308  if (vpIoTools::checkFilename(filename))
1309  return data_path;
1310  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/visp-images";
1311  filename = data_path + "/" + file_to_test;
1312  if (vpIoTools::checkFilename(filename))
1313  return data_path;
1314  } catch (...) {
1315  }
1316  data_path = "";
1317  return data_path;
1318 }
1319 
1349 std::string vpIoTools::getFileExtension(const std::string &pathname, const bool checkFile)
1350 {
1351  if (checkFile && (vpIoTools::checkDirectory(pathname) || !vpIoTools::checkFilename(pathname))) {
1352  return "";
1353  }
1354 
1355 #if defined(_WIN32)
1356  std::string sep = "\\";
1357  std::string altsep = "/";
1358  std::string extsep = ".";
1359 #else
1360  // On Unix, or on the Mac
1361  std::string sep = "/";
1362  std::string altsep = "";
1363  std::string extsep = ".";
1364 #endif
1365 
1366  // Python 2.7.8 module.
1367  //# Split a path in root and extension.
1368  //# The extension is everything starting at the last dot in the last
1369  //# pathname component; the root is everything before that.
1370  //# It is always true that root + ext == p.
1371  //
1372  //# Generic implementation of splitext, to be parametrized with
1373  //# the separators
1374  // def _splitext(p, sep, altsep, extsep):
1375  // """Split the extension from a pathname.
1376  //
1377  // Extension is everything from the last dot to the end, ignoring
1378  // leading dots. Returns "(root, ext)"; ext may be empty."""
1379  //
1380  // sepIndex = p.rfind(sep)
1381  // if altsep:
1382  // altsepIndex = p.rfind(altsep)
1383  // sepIndex = max(sepIndex, altsepIndex)
1384  //
1385  // dotIndex = p.rfind(extsep)
1386  // if dotIndex > sepIndex:
1387  // # skip all leading dots
1388  // filenameIndex = sepIndex + 1
1389  // while filenameIndex < dotIndex:
1390  // if p[filenameIndex] != extsep:
1391  // return p[:dotIndex], p[dotIndex:]
1392  // filenameIndex += 1
1393  //
1394  // return p, ''
1395 
1396  int sepIndex = static_cast<int>(pathname.rfind(sep));
1397  if (!altsep.empty()) {
1398  int altsepIndex = static_cast<int>(pathname.rfind(altsep));
1399  sepIndex = ((std::max))(sepIndex, altsepIndex);
1400  }
1401 
1402  size_t dotIndex = pathname.rfind(extsep);
1403  if (dotIndex != std::string::npos) {
1404  // The extsep character exists
1405  size_t npos = std::string::npos;
1406  if ((sepIndex != static_cast<int>(npos) && static_cast<int>(dotIndex) > sepIndex) || sepIndex == static_cast<int>(npos)) {
1407  if (sepIndex == static_cast<int>(npos)) {
1408  sepIndex = 0;
1409  std::cout << "Debug sepIndex: " << sepIndex << std::endl;
1410  }
1411  size_t filenameIndex = static_cast<size_t>(sepIndex) + static_cast<size_t>(1);
1412 
1413  while (filenameIndex < dotIndex) {
1414  if (pathname.compare(filenameIndex, 1, extsep) != 0) {
1415  return pathname.substr(dotIndex);
1416  }
1417  filenameIndex++;
1418  }
1419  }
1420  }
1421 
1422  return "";
1423 }
1424 
1430 std::string vpIoTools::getName(const std::string &pathname)
1431 {
1432  if (pathname.size() > 0) {
1433  std::string convertedPathname = vpIoTools::path(pathname);
1434 
1435  size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1436  if (index != std::string::npos) {
1437  return convertedPathname.substr(index + 1);
1438  }
1439 
1440  return convertedPathname;
1441  }
1442 
1443  return "";
1444 }
1445 
1452 std::string vpIoTools::getNameWE(const std::string &pathname)
1453 {
1454  std::string name = vpIoTools::getName(pathname);
1455  size_t found = name.find_last_of(".");
1456  std::string name_we = name.substr(0, found);
1457  return name_we;
1458 }
1459 
1465 std::string vpIoTools::getParent(const std::string &pathname)
1466 {
1467  if (pathname.size() > 0) {
1468  std::string convertedPathname = vpIoTools::path(pathname);
1469 
1470  size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1471  if (index != std::string::npos) {
1472  return convertedPathname.substr(0, index);
1473  }
1474  }
1475 
1476  return "";
1477 }
1478 
1487 std::string vpIoTools::getAbsolutePathname(const std::string &pathname)
1488 {
1489 
1490 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1491  std::string real_path_str = pathname;
1492  char *real_path = realpath(pathname.c_str(), NULL);
1493 
1494  if (real_path) {
1495  real_path_str = real_path;
1496  free(real_path);
1497  }
1498  return real_path_str;
1499 #elif defined(_WIN32)
1500 #if (!defined(WINRT))
1501  std::string real_path_str = pathname;
1502  DWORD retval = 0;
1503  TCHAR buffer[4096] = TEXT("");
1504 
1505  retval = GetFullPathName(pathname.c_str(), 4096, buffer, 0);
1506  if (retval != 0) {
1507  real_path_str = buffer;
1508  }
1509  return real_path_str;
1510 #else
1512  "Cannot get absolute path of %s: not implemented on "
1513  "Universal Windows Platform",
1514  pathname.c_str()));
1515 #endif
1516 #endif
1517 }
1518 
1529 std::string vpIoTools::createFilePath(const std::string &parent, const std::string &child)
1530 {
1531  if (child.size() == 0 && parent.size() == 0) {
1532  return "";
1533  }
1534 
1535  if (child.size() == 0) {
1536  return vpIoTools::path(parent);
1537  }
1538 
1539  if (parent.size() == 0) {
1540  return vpIoTools::path(child);
1541  }
1542 
1543  std::string convertedParent = vpIoTools::path(parent);
1544  std::string convertedChild = vpIoTools::path(child);
1545 
1546  std::stringstream ss;
1547  ss << vpIoTools::separator;
1548  std::string stringSeparator;
1549  ss >> stringSeparator;
1550 
1551  std::string lastConvertedParentChar = convertedParent.substr(convertedParent.size() - 1);
1552  std::string firstConvertedChildChar = convertedChild.substr(0, 1);
1553 
1554  if (lastConvertedParentChar == stringSeparator) {
1555  convertedParent = convertedParent.substr(0, convertedParent.size() - 1);
1556  }
1557 
1558  if (firstConvertedChildChar == stringSeparator) {
1559  convertedChild = convertedChild.substr(1);
1560  }
1561 
1562  return std::string(convertedParent + vpIoTools::separator + convertedChild);
1563 }
1564 
1570 bool vpIoTools::isAbsolutePathname(const std::string &pathname)
1571 {
1572  //# Inspired by the Python 2.7.8 module.
1573  //# Return whether a path is absolute.
1574  //# Trivial in Posix, harder on the Mac or MS-DOS.
1575  //# For DOS it is absolute if it starts with a slash or backslash (current
1576  //# volume), or if a pathname after the volume letter and colon / UNC
1577  // resource # starts with a slash or backslash.
1578  //
1579  // def isabs(s):
1580  // """Test whether a path is absolute"""
1581  // s = splitdrive(s)[1]
1582  // return s != '' and s[:1] in '/\\'
1583  std::string path = splitDrive(pathname).second;
1584  return path.size() > 0 && (path.substr(0, 1) == "/" || path.substr(0, 1) == "\\");
1585 }
1586 
1594 bool vpIoTools::isSamePathname(const std::string &pathname1, const std::string &pathname2)
1595 {
1596  // Normalize path
1597  std::string path1_normalize = vpIoTools::path(pathname1);
1598  std::string path2_normalize = vpIoTools::path(pathname2);
1599 
1600  // Get absolute path
1601  path1_normalize = vpIoTools::getAbsolutePathname(path1_normalize);
1602  path2_normalize = vpIoTools::getAbsolutePathname(path2_normalize);
1603 
1604  return (path1_normalize == path2_normalize);
1605 }
1606 
1614 std::pair<std::string, std::string> vpIoTools::splitDrive(const std::string &pathname)
1615 {
1616 //# Split a path in a drive specification (a drive letter followed by a
1617 //# colon) and the path specification.
1618 //# It is always true that drivespec + pathspec == p
1619 // def splitdrive(p):
1620 // """Split a pathname into drive/UNC sharepoint and relative path
1621 // specifiers. Returns a 2-tuple (drive_or_unc, path); either part may be
1622 // empty.
1623 //
1624 // If you assign
1625 // result = splitdrive(p)
1626 // It is always true that:
1627 // result[0] + result[1] == p
1628 //
1629 // If the path contained a drive letter, drive_or_unc will contain
1630 // everything up to and including the colon. e.g. splitdrive("c:/dir")
1631 // returns ("c:", "/dir")
1632 //
1633 // If the path contained a UNC path, the drive_or_unc will contain the host
1634 // name and share up to but not including the fourth directory separator
1635 // character. e.g. splitdrive("//host/computer/dir") returns
1636 // ("//host/computer", "/dir")
1637 //
1638 // Paths cannot contain both a drive letter and a UNC path.
1639 //
1640 // """
1641 // if len(p) > 1:
1642 // normp = p.replace(altsep, sep)
1643 // if (normp[0:2] == sep*2) and (normp[2] != sep):
1644 // # is a UNC path:
1645 // # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
1646 // # \\machine\mountpoint\directory\etc\...
1647 // # directory ^^^^^^^^^^^^^^^
1648 // index = normp.find(sep, 2)
1649 // if index == -1:
1650 // return '', p
1651 // index2 = normp.find(sep, index + 1)
1652 // # a UNC path can't have two slashes in a row
1653 // # (after the initial two)
1654 // if index2 == index + 1:
1655 // return '', p
1656 // if index2 == -1:
1657 // index2 = len(p)
1658 // return p[:index2], p[index2:]
1659 // if normp[1] == ':':
1660 // return p[:2], p[2:]
1661 // return '', p
1662 
1663 // On Unix, the drive is always empty.
1664 // On the Mac, the drive is always empty (don't use the volume name -- it
1665 // doesn't have the same syntactic and semantic oddities as DOS drive
1666 // letters, such as there being a separate current directory per drive).
1667 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
1668  return std::pair<std::string, std::string>("", pathname);
1669 #else
1670  const std::string sep = "\\";
1671  const std::string sepsep = "\\\\";
1672  const std::string altsep = "/";
1673 
1674  if (pathname.size() > 1) {
1675  std::string normPathname = pathname;
1676  std::replace(normPathname.begin(), normPathname.end(), *altsep.c_str(), *sep.c_str());
1677 
1678  if (normPathname.substr(0, 2) == sepsep && normPathname.substr(2, 1) != sep) {
1679  // is a UNC path:
1680  // vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
1681  // \\machine\mountpoint\directory\etc\...
1682  // directory ^^^^^^^^^^^^^^^
1683  size_t index = normPathname.find(sep, 2);
1684  if (index == std::string::npos) {
1685  return std::pair<std::string, std::string>("", pathname);
1686  }
1687 
1688  size_t index2 = normPathname.find(sep, index + 1);
1689  //# a UNC path can't have two slashes in a row
1690  //# (after the initial two)
1691  if (index2 == index + 1) {
1692  return std::pair<std::string, std::string>("", pathname);
1693  }
1694 
1695  if (index2 == std::string::npos) {
1696  index2 = pathname.size();
1697  }
1698 
1699  return std::pair<std::string, std::string>(pathname.substr(0, index2), pathname.substr(index2));
1700  }
1701 
1702  if (normPathname[1] == ':') {
1703  return std::pair<std::string, std::string>(pathname.substr(0, 2), pathname.substr(2));
1704  }
1705  }
1706 
1707  return std::pair<std::string, std::string>("", pathname);
1708 #endif
1709 }
1710 
1759 std::vector<std::string> vpIoTools::splitChain(const std::string &chain, const std::string &sep)
1760 {
1761  size_t startIndex = 0;
1762 
1763  std::string chainToSplit = chain;
1764  std::vector<std::string> subChain;
1765  size_t sepIndex = chainToSplit.find(sep);
1766 
1767  while (sepIndex != std::string::npos) {
1768  std::string sub = chainToSplit.substr(startIndex, sepIndex);
1769  if (!sub.empty())
1770  subChain.push_back(sub);
1771  chainToSplit = chainToSplit.substr(sepIndex + 1, chain.size() - 1);
1772 
1773  sepIndex = chainToSplit.find(sep);
1774  }
1775  if (!chainToSplit.empty())
1776  subChain.push_back(chainToSplit);
1777 
1778  return subChain;
1779 }
1780 
1788 std::vector<std::string> vpIoTools::getDirFiles(const std::string &pathname)
1789 {
1790 
1791  if (!checkDirectory(pathname)) {
1792  throw(vpIoException(vpException::fatalError, "Directory %s doesn't exist'", pathname.c_str()));
1793  }
1794  std::string dirName = path(pathname);
1795 
1796 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1797 
1798  std::vector<std::string> files;
1799  struct dirent **list = NULL;
1800  int filesCount = scandir(dirName.c_str(), &list, NULL, NULL);
1801  if (filesCount == -1) {
1802  throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
1803  }
1804  for (int i = 0; i < filesCount; i++) {
1805  std::string fileName = list[i]->d_name;
1806  if (fileName != "." && fileName != "..") {
1807  files.push_back(fileName);
1808  }
1809  free(list[i]);
1810  }
1811  free(list);
1812  std::sort(files.begin(), files.end());
1813  return files;
1814 
1815 #elif defined(_WIN32)
1816 #if (!defined(WINRT))
1817 
1818  std::vector<std::string> files;
1819  std::string fileMask = dirName;
1820  fileMask.append("\\*");
1821  WIN32_FIND_DATA FindFileData;
1822  HANDLE hFind = FindFirstFile(fileMask.c_str(), &FindFileData);
1823  // Directory is empty
1824  if (HandleToLong(&hFind) == ERROR_FILE_NOT_FOUND) {
1825  return files;
1826  }
1827  if (hFind == INVALID_HANDLE_VALUE) {
1828  throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
1829  }
1830  do {
1831  std::string fileName = FindFileData.cFileName;
1832  if (fileName != "." && fileName != "..") {
1833  files.push_back(fileName);
1834  }
1835  } while (FindNextFile(hFind, &FindFileData));
1836  FindClose(hFind);
1837  std::sort(files.begin(), files.end());
1838  return files;
1839 
1840 #else
1842  "Cannot read files of directory %s: not implemented on "
1843  "Universal Windows Platform",
1844  dirName.c_str()));
1845 #endif
1846 #endif
1847 }
1848 
1852 void vpIoTools::readBinaryValueLE(std::ifstream &file, int16_t &short_value)
1853 {
1854  file.read((char *)(&short_value), sizeof(short_value));
1855 
1856 #ifdef VISP_BIG_ENDIAN
1857  // Swap bytes order from little endian to big endian
1858  short_value = swap16bits((uint16_t)short_value);
1859 #endif
1860 }
1861 
1865 void vpIoTools::readBinaryValueLE(std::ifstream &file, uint16_t &ushort_value)
1866 {
1867  file.read((char *)(&ushort_value), sizeof(ushort_value));
1868 
1869 #ifdef VISP_BIG_ENDIAN
1870  // Swap bytes order from little endian to big endian
1871  ushort_value = swap16bits(ushort_value);
1872 #endif
1873 }
1874 
1878 void vpIoTools::readBinaryValueLE(std::ifstream &file, int32_t &int_value)
1879 {
1880  file.read((char *)(&int_value), sizeof(int_value));
1881 
1882 #ifdef VISP_BIG_ENDIAN
1883  // Swap bytes order from little endian to big endian
1884  int_value = swap32bits((uint32_t)int_value);
1885 #endif
1886 }
1887 
1891 void vpIoTools::readBinaryValueLE(std::ifstream &file, uint32_t &uint_value)
1892 {
1893  file.read((char *)(&uint_value), sizeof(uint_value));
1894 
1895 #ifdef VISP_BIG_ENDIAN
1896  // Swap bytes order from little endian to big endian
1897  uint_value = swap32bits(uint_value);
1898 #endif
1899 }
1900 
1904 void vpIoTools::readBinaryValueLE(std::ifstream &file, float &float_value)
1905 {
1906  file.read((char *)(&float_value), sizeof(float_value));
1907 
1908 #ifdef VISP_BIG_ENDIAN
1909  // Swap bytes order from little endian to big endian
1910  float_value = swapFloat(float_value);
1911 #endif
1912 }
1913 
1917 void vpIoTools::readBinaryValueLE(std::ifstream &file, double &double_value)
1918 {
1919  file.read((char *)(&double_value), sizeof(double_value));
1920 
1921 #ifdef VISP_BIG_ENDIAN
1922  // Swap bytes order from little endian to big endian
1923  double_value = swapDouble(double_value);
1924 #endif
1925 }
1926 
1930 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
1931 {
1932 #ifdef VISP_BIG_ENDIAN
1933  // Swap bytes order to little endian
1934  uint16_t swap_short = swap16bits((uint16_t)short_value);
1935  file.write((char *)(&swap_short), sizeof(swap_short));
1936 #else
1937  file.write((char *)(&short_value), sizeof(short_value));
1938 #endif
1939 }
1940 
1944 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint16_t ushort_value)
1945 {
1946 #ifdef VISP_BIG_ENDIAN
1947  // Swap bytes order to little endian
1948  uint16_t swap_ushort = swap16bits(ushort_value);
1949  file.write((char *)(&swap_ushort), sizeof(swap_ushort));
1950 #else
1951  file.write((char *)(&ushort_value), sizeof(ushort_value));
1952 #endif
1953 }
1954 
1958 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int32_t int_value)
1959 {
1960 #ifdef VISP_BIG_ENDIAN
1961  // Swap bytes order to little endian
1962  uint32_t swap_int = swap32bits((uint32_t)int_value);
1963  file.write((char *)(&swap_int), sizeof(swap_int));
1964 #else
1965  file.write((char *)(&int_value), sizeof(int_value));
1966 #endif
1967 }
1968 
1972 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint32_t uint_value)
1973 {
1974 #ifdef VISP_BIG_ENDIAN
1975  // Swap bytes order to little endian
1976  uint32_t swap_int = swap32bits(uint_value);
1977  file.write((char *)(&swap_int), sizeof(swap_int));
1978 #else
1979  file.write((char *)(&uint_value), sizeof(uint_value));
1980 #endif
1981 }
1982 
1986 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const float float_value)
1987 {
1988 #ifdef VISP_BIG_ENDIAN
1989  // Swap bytes order to little endian
1990  float swap_float = swapFloat(float_value);
1991  file.write((char *)(&swap_float), sizeof(swap_float));
1992 #else
1993  file.write((char *)(&float_value), sizeof(float_value));
1994 #endif
1995 }
1996 
2000 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const double double_value)
2001 {
2002 #ifdef VISP_BIG_ENDIAN
2003  // Swap bytes order to little endian
2004  double swap_double = swapDouble(double_value);
2005  file.write((char *)(&swap_double), sizeof(swap_double));
2006 #else
2007  file.write((char *)(&double_value), sizeof(double_value));
2008 #endif
2009 }
2010 
2011 bool vpIoTools::parseBoolean(std::string input)
2012 {
2013  std::transform(input.begin(), input.end(), input.begin(), ::tolower);
2014  std::istringstream is(input);
2015  bool b;
2016  // Parse string to boolean either in the textual representation
2017  // (True/False) or in numeric representation (1/0)
2018  is >> (input.size() > 1 ? std::boolalpha : std::noboolalpha) >> b;
2019  return b;
2020 }
2021 
2025 std::string vpIoTools::trim(std::string s)
2026 {
2027  return ltrim(rtrim(s));
2028 }
static void makeDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:564
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1284
static bool isAbsolutePathname(const std::string &pathname)
Definition: vpIoTools.cpp:1570
static void getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
Definition: vpIoTools.cpp:374
static bool rename(const std::string &oldfilename, const std::string &newfilename)
Definition: vpIoTools.cpp:905
static std::string getFileExtension(const std::string &pathname, const bool checkFile=false)
Definition: vpIoTools.cpp:1349
static void readBinaryValueLE(std::ifstream &file, int16_t &short_value)
Definition: vpIoTools.cpp:1852
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:183
unsigned int getRows() const
Definition: vpArray2D.h:289
static bool copy(const std::string &src, const std::string &dst)
Definition: vpIoTools.cpp:764
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:1788
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:1465
static bool checkFifo(const std::string &filename)
Definition: vpIoTools.cpp:474
static std::string path(const std::string &pathname)
Definition: vpIoTools.cpp:923
static void createBaseNamePath(const bool &empty=false)
Definition: vpIoTools.cpp:1242
static const std::string & getBuildInformation()
Definition: vpIoTools.cpp:217
static bool checkDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:414
static std::string baseDir
Definition: vpIoTools.h:250
unsigned int getCols() const
Definition: vpArray2D.h:279
static void setBaseName(const std::string &s)
Definition: vpIoTools.cpp:230
static bool parseBoolean(std::string input)
Definition: vpIoTools.cpp:2011
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1529
static std::pair< std::string, std::string > splitDrive(const std::string &pathname)
Definition: vpIoTools.cpp:1614
static bool isSamePathname(const std::string &pathname1, const std::string &pathname2)
Definition: vpIoTools.cpp:1594
static void makeFifo(const std::string &dirname)
Definition: vpIoTools.cpp:615
static std::string getUserName()
Definition: vpIoTools.cpp:310
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1759
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:151
static void saveConfigFile(const bool &actuallySave=true)
Definition: vpIoTools.cpp:1261
static std::vector< std::string > configVars
Definition: vpIoTools.h:252
static std::string getName(const std::string &pathname)
Definition: vpIoTools.cpp:1430
static void writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
Definition: vpIoTools.cpp:1930
static bool remove(const std::string &filename)
Definition: vpIoTools.cpp:847
static std::string makeTempDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:663
static std::string baseName
Definition: vpIoTools.h:249
static std::string getFullName()
Definition: vpIoTools.cpp:248
static std::string trim(std::string s)
Definition: vpIoTools.cpp:2025
static std::string configFile
Definition: vpIoTools.h:251
static void setBaseDir(const std::string &dir)
Definition: vpIoTools.cpp:236
static std::string getNameWE(const std::string &pathname)
Definition: vpIoTools.cpp:1452
static std::string getBaseName()
Definition: vpIoTools.cpp:242
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:722
static std::string getAbsolutePathname(const std::string &pathname)
Definition: vpIoTools.cpp:1487
static vpColor getColor(const unsigned int &i)
Definition: vpColor.h:249
static bool readConfigVar(const std::string &var, float &value)
Definition: vpIoTools.cpp:1010
static std::vector< std::string > configValues
Definition: vpIoTools.h:253
static bool loadConfigFile(const std::string &confFile)
Definition: vpIoTools.cpp:963
static void addNameElement(const std::string &strTrue, const bool &cond=true, const std::string &strFalse="")
Definition: vpIoTools.cpp:1207
static std::string getenv(const std::string &env)
Definition: vpIoTools.cpp:347