Visual Servoing Platform  version 3.3.1 under development (2020-08-12)
vpIoTools.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Directory management.
33  *
34  * Authors:
35  * Fabien Spindler
36  *
37  *****************************************************************************/
38 
43 #include <algorithm>
44 #include <cctype>
45 #include <functional>
46 #include <cmath>
47 #include <errno.h>
48 #include <fcntl.h>
49 #include <fstream>
50 #include <limits>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <sys/stat.h>
55 #include <sys/types.h>
56 #include <visp3/core/vpDebug.h>
57 #include <visp3/core/vpEndian.h>
58 #include <visp3/core/vpIoException.h>
59 #include <visp3/core/vpIoTools.h>
60 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
61 #include <dirent.h>
62 #include <unistd.h>
63 #elif defined(_WIN32)
64 #include <direct.h>
65 #include <windows.h>
66 #endif
67 #if !defined(_WIN32)
68  #ifdef __ANDROID__
69  // Like IOS, wordexp.cpp is not defined for Android
70  #else
71  #include <wordexp.h>
72  #endif
73 #endif
74 
75 #if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
76 #include <TargetConditionals.h> // To detect OSX or IOS using TARGET_OS_IOS macro
77 #endif
78 
79 #ifndef PATH_MAX
80 # ifdef _MAX_PATH
81 # define PATH_MAX _MAX_PATH
82 # else
83 # define PATH_MAX 1024
84 # endif
85 #endif
86 
87 std::string vpIoTools::baseName = "";
88 std::string vpIoTools::baseDir = "";
89 std::string vpIoTools::configFile = "";
90 std::vector<std::string> vpIoTools::configVars = std::vector<std::string>();
91 std::vector<std::string> vpIoTools::configValues = std::vector<std::string>();
92 
93 namespace
94 {
95 // The following code is not working on iOS since wordexp() is not available
96 // The function is not used on Android
97 #if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
98 #if (TARGET_OS_IOS == 0) && !defined(__ANDROID__)
99 void replaceAll(std::string &str, const std::string &search, const std::string &replace)
100 {
101  size_t start_pos = 0;
102  while ((start_pos = str.find(search, start_pos)) != std::string::npos) {
103  str.replace(start_pos, search.length(), replace);
104  start_pos += replace.length(); // Handles case where 'replace' is a
105  // substring of 'search'
106  }
107 }
108 #endif
109 #endif
110 
111 std::string &ltrim(std::string &s)
112 {
113 #if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
114  s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) { return !std::isspace(c); }));
115 #else
116  s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
117 #endif
118  return s;
119 }
120 
121 std::string &rtrim(std::string &s)
122 {
123 #if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
124  s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) { return !std::isspace(c); }).base(), s.end());
125 #else
126  s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
127 #endif
128  return s;
129 }
130 }
131 
135 const std::string &vpIoTools::getBuildInformation()
136 {
137  static std::string build_info =
138 #include "version_string.inc"
139  ;
140  return build_info;
141 }
142 
148 void vpIoTools::setBaseName(const std::string &s) { baseName = s; }
154 void vpIoTools::setBaseDir(const std::string &dir) { baseDir = dir + "/"; }
160 std::string vpIoTools::getBaseName() { return baseName; }
166 std::string vpIoTools::getFullName() { return baseDir + baseName; }
167 
181 void vpIoTools::getUserName(std::string &username)
182 {
183 // With MinGW, UNIX and _WIN32 are defined
184 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
185  // Get the user name.
186  char *_username = ::getenv("LOGNAME");
187  if (!_username) {
188  username = "unknown";
189  }
190  else {
191  username = _username;
192  }
193 #elif defined(_WIN32)
194 #if (!defined(WINRT))
195  unsigned int info_buffer_size = 1024;
196  TCHAR *infoBuf = new TCHAR[info_buffer_size];
197  DWORD bufCharCount = (DWORD)info_buffer_size;
198  // Get the user name.
199  if (!GetUserName(infoBuf, &bufCharCount)) {
200  username = "unknown";
201  } else {
202  username = infoBuf;
203  }
204  delete[] infoBuf;
205 #else
206  // Universal platform
207  username = "unknown";
208 #endif
209 #else
210  username = "unknown";
211 #endif
212 }
213 
229 {
230  std::string username;
231  getUserName(username);
232  return username;
233 }
234 
265 std::string vpIoTools::getenv(const std::string &env)
266 {
267 #if defined(_WIN32) && defined(WINRT)
268  throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value: not "
269  "implemented on Universal Windows Platform"));
270 #else
271  std::string value;
272  // Get the environment variable value.
273  char *_value = ::getenv(env.c_str());
274  if (! _value) {
275  throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value"));
276  }
277  value = _value;
278 
279  return value;
280 #endif
281 }
282 
292 void vpIoTools::getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
293 {
294  if (version.size() == 0) {
295  major = 0;
296  minor = 0;
297  patch = 0;
298  } else {
299  size_t major_pos = version.find('.');
300  std::string major_str = version.substr(0, major_pos);
301  major = static_cast<unsigned>(atoi(major_str.c_str()));
302 
303  if (major_pos != std::string::npos) {
304  size_t minor_pos = version.find('.', major_pos + 1);
305  std::string minor_str = version.substr(major_pos + 1, (minor_pos - (major_pos + 1)));
306  minor = static_cast<unsigned>(atoi(minor_str.c_str()));
307 
308  if (minor_pos != std::string::npos) {
309  std::string patch_str = version.substr(minor_pos + 1);
310  patch = static_cast<unsigned>(atoi(patch_str.c_str()));
311  } else {
312  patch = 0;
313  }
314  } else {
315  minor = 0;
316  patch = 0;
317  }
318  }
319 }
320 
332 bool vpIoTools::checkDirectory(const std::string &dirname)
333 {
334 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
335  struct stat stbuf;
336 #elif defined(_WIN32) && defined(__MINGW32__)
337  struct stat stbuf;
338 #elif defined(_WIN32)
339  struct _stat stbuf;
340 #endif
341 
342  if (dirname.empty()) {
343  return false;
344  }
345 
346  std::string _dirname = path(dirname);
347 
348 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
349  if (stat(_dirname.c_str(), &stbuf) != 0)
350 #elif defined(_WIN32) && defined(__MINGW32__)
351  // Remove trailing separator character if any
352  // AppVeyor: Windows 6.3.9600 AMD64 ; C:/MinGW/bin/g++.exe (ver 5.3.0) ;
353  // GNU Make 3.82.90 Built for i686-pc-mingw32
354  if (_dirname.at(_dirname.size() - 1) == vpIoTools::separator)
355  _dirname = _dirname.substr(0, _dirname.size() - 1);
356  if (stat(_dirname.c_str(), &stbuf) != 0)
357 #elif defined(_WIN32)
358  if (_stat(_dirname.c_str(), &stbuf) != 0)
359 #endif
360  {
361  return false;
362  }
363 #if defined(_WIN32) || (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
364  if ((stbuf.st_mode & S_IFDIR) == 0)
365 #endif
366  {
367  return false;
368  }
369 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
370  if ((stbuf.st_mode & S_IWUSR) == 0)
371 #elif defined(_WIN32)
372  if ((stbuf.st_mode & S_IWRITE) == 0)
373 #endif
374  {
375  return false;
376  }
377  return true;
378 }
379 
392 bool vpIoTools::checkFifo(const std::string &fifofilename)
393 {
394 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
395  struct stat stbuf;
396 
397  std::string _filename = path(fifofilename);
398  if (stat(_filename.c_str(), &stbuf) != 0) {
399  return false;
400  }
401  if ((stbuf.st_mode & S_IFIFO) == 0) {
402  return false;
403  }
404  if ((stbuf.st_mode & S_IRUSR) == 0)
405 
406  {
407  return false;
408  }
409  return true;
410 #elif defined(_WIN32)
411  (void)fifofilename;
412  throw(vpIoException(vpIoException::notImplementedError, "Fifo files are not supported on Windows platforms."));
413 #endif
414 }
415 
416 #ifndef DOXYGEN_SHOULD_SKIP_THIS
417 // See:
418 // https://gist.github.com/JonathonReinhart/8c0d90191c38af2dcadb102c4e202950
419 int vpIoTools::mkdir_p(const char *path, int mode)
420 {
421  /* Adapted from http://stackoverflow.com/a/2336245/119527 */
422  const size_t len = strlen(path);
423  char _path[PATH_MAX];
424  const char sep = vpIoTools::separator;
425 
426  std::fill(_path, _path + PATH_MAX, 0);
427 
428  errno = 0;
429  if (len > sizeof(_path) - 1) {
430  errno = ENAMETOOLONG;
431  return -1;
432  }
433  /* Copy string so its mutable */
434  strcpy(_path, path);
435 
436  /* Iterate over the string */
437  for (char *p = _path + 1; *p; p++) { // path cannot be empty
438  if (*p == sep) {
439  /* Temporarily truncate */
440  *p = '\0';
441 
442 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
443  if (mkdir(_path, static_cast<mode_t>(mode)) != 0)
444 #elif defined(_WIN32)
445  (void)mode; // var not used
446  if (!checkDirectory(_path) && _mkdir(_path) != 0)
447 #endif
448  {
449  if (errno != EEXIST)
450  return -1;
451  }
452  *p = sep;
453  }
454  }
455 
456 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
457  if (mkdir(_path, static_cast<mode_t>(mode)) != 0)
458 #elif defined(_WIN32)
459  if (_mkdir(_path) != 0)
460 #endif
461  {
462  if (errno != EEXIST)
463  return -1;
464  }
465 
466  return 0;
467 }
468 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
469 
482 void vpIoTools::makeDirectory(const std::string &dirname)
483 {
484 #if ((!defined(__unix__) && !defined(__unix) && (!defined(__APPLE__) || !defined(__MACH__)))) && !defined(_WIN32)
485  std::cerr << "Unsupported platform for vpIoTools::makeDirectory()!" << std::endl;
486  return;
487 #endif
488 
489 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
490  struct stat stbuf;
491 #elif defined(_WIN32) && defined(__MINGW32__)
492  struct stat stbuf;
493 #elif defined(_WIN32)
494  struct _stat stbuf;
495 #endif
496 
497  if (dirname.empty()) {
498  throw(vpIoException(vpIoException::invalidDirectoryName, "invalid directory name"));
499  }
500 
501  std::string _dirname = path(dirname);
502 
503 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
504  if (stat(_dirname.c_str(), &stbuf) != 0)
505 #elif defined(_WIN32) && defined(__MINGW32__)
506  if (stat(_dirname.c_str(), &stbuf) != 0)
507 #elif defined(_WIN32)
508  if (_stat(_dirname.c_str(), &stbuf) != 0)
509 #endif
510  {
511  if (vpIoTools::mkdir_p(_dirname.c_str(), 0755) != 0) {
512  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'", dirname.c_str()));
513  }
514  }
515 
516  if (checkDirectory(dirname) == false) {
517  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'", dirname.c_str()));
518  }
519 }
520 
533 void vpIoTools::makeFifo(const std::string &fifoname)
534 {
535 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
536 
537  // If dirname is a directory, we throw an error
538  if (vpIoTools::checkDirectory(fifoname)) {
540  "Unable to create fifo file. '%s' is an existing directory.", fifoname.c_str()));
541  }
542 
543  // If dirname refers to an already existing file, we throw an error
544  else if (vpIoTools::checkFilename(fifoname)) {
545  throw(vpIoException(vpIoException::invalidDirectoryName, "Unable to create fifo file '%s'. File already exists.",
546  fifoname.c_str()));
547  // If dirname refers to an already existing fifo, we throw an error
548  } else if (vpIoTools::checkFifo(fifoname)) {
549  throw(vpIoException(vpIoException::invalidDirectoryName, "Unable to create fifo file '%s'. Fifo already exists.",
550  fifoname.c_str()));
551  }
552 
553  else if (mkfifo(fifoname.c_str(), 0666) < 0) {
554  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create fifo file '%s'.", fifoname.c_str()));
555  }
556 #elif defined(_WIN32)
557  (void)fifoname;
558  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create fifo on Windows platforms."));
559 #endif
560 }
561 
581 std::string vpIoTools::makeTempDirectory(const std::string &dirname)
582 {
583 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
584 
585  std::string dirname_cpy = std::string(dirname);
586 
587  std::string correctEnding = "XXXXXX";
588 
589  size_t endingLength = correctEnding.length();
590  size_t dirNameLength = dirname_cpy.length();
591 
592  // If dirname is an unexisting directory, it should end with XXXXXX in order to create a temp directory
593  if (!vpIoTools::checkDirectory(dirname_cpy)) {
594  if (endingLength > dirNameLength) {
596  "Unable to create temp directory '%s'. It should end with XXXXXX.", dirname_cpy.c_str()));
597  }
598 
599  if (dirname.compare(dirNameLength - endingLength, endingLength, correctEnding) != 0) {
601  "Unable to create temp directory '%s'. It should end with XXXXXX.", dirname_cpy.c_str()));
602  }
603 
604  // If dirname is an existing directory, we create a temp directory inside
605  } else {
606  if (dirname_cpy.at(dirname_cpy.length() - 1) != '/') {
607  dirname_cpy = dirname_cpy + "/";
608  }
609  dirname_cpy = dirname_cpy + "XXXXXX";
610  }
611  char *dirname_char = new char[dirname_cpy.length() + 1];
612  strcpy(dirname_char, dirname_cpy.c_str());
613 
614  char *computedDirname = mkdtemp(dirname_char);
615 
616  if (!computedDirname) {
617  delete[] dirname_char;
618  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'.", dirname_cpy.c_str()));
619  }
620 
621  std::string res(computedDirname);
622  delete[] dirname_char;
623  return res;
624 #elif defined(_WIN32)
625  (void)dirname;
626  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create temp directory. Not implemented yet."));
627 #endif
628 }
629 
640 bool vpIoTools::checkFilename(const std::string &filename)
641 {
642 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
643  struct stat stbuf;
644 #elif defined(_WIN32)
645  struct _stat stbuf;
646 #endif
647 
648  if (filename.empty()) {
649  return false;
650  }
651 
652  std::string _filename = path(filename);
653 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
654  if (stat(_filename.c_str(), &stbuf) != 0)
655 #elif defined(_WIN32)
656  if (_stat(_filename.c_str(), &stbuf) != 0)
657 #endif
658  {
659  return false;
660  }
661  if ((stbuf.st_mode & S_IFREG) == 0) {
662  return false;
663  }
664 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
665  if ((stbuf.st_mode & S_IRUSR) == 0)
666 #elif defined(_WIN32)
667  if ((stbuf.st_mode & S_IREAD) == 0)
668 #endif
669  {
670  return false;
671  }
672  return true;
673 }
674 
682 bool vpIoTools::copy(const std::string &src, const std::string &dst)
683 {
684  // Check if we have to consider a file or a directory
685  if (vpIoTools::checkFilename(src)) {
686 // std::cout << "copy file: " << src << " in " << dst << std::endl;
687 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
688 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
689  // wordexp() is not available
690  char cmd[FILENAME_MAX];
691  int ret;
692  sprintf(cmd, "cp -p %s %s", src.c_str(), dst.c_str());
693  ret = system(cmd);
694  if (ret) {
695  }; // to avoid a warning
696  // std::cout << cmd << " return value: " << ret << std::endl;
697  return true;
698 #else
699  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src.c_str(), dst.c_str()));
700 #endif
701 #elif defined(_WIN32)
702 #if (!defined(WINRT))
703  char cmd[FILENAME_MAX];
704  int ret;
705  std::string src_ = vpIoTools::path(src);
706  std::string dst_ = vpIoTools::path(dst);
707  sprintf(cmd, "copy %s %s", src_.c_str(), dst_.c_str());
708  ret = system(cmd);
709  if (ret) {
710  }; // to avoid a warning
711  // std::cout << cmd << " return value: " << ret << std::endl;
712  return true;
713 #else
714  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
715  src.c_str(), dst.c_str()));
716 #endif
717 #endif
718  } else if (vpIoTools::checkDirectory(src)) {
719 // std::cout << "copy directory: " << src << " in " << dst << std::endl;
720 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
721 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
722  // wordexp() is not available
723  char cmd[FILENAME_MAX];
724  int ret;
725  sprintf(cmd, "cp -p -r %s %s", src.c_str(), dst.c_str());
726  ret = system(cmd);
727  if (ret) {
728  }; // to avoid a warning
729  // std::cout << cmd << " return value: " << ret << std::endl;
730  return true;
731 #else
732  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src.c_str(), dst.c_str()));
733 #endif
734 #elif defined(_WIN32)
735 #if (!defined(WINRT))
736  char cmd[FILENAME_MAX];
737  int ret;
738  std::string src_ = vpIoTools::path(src);
739  std::string dst_ = vpIoTools::path(dst);
740  sprintf(cmd, "copy %s %s", src_.c_str(), dst_.c_str());
741  ret = system(cmd);
742  if (ret) {
743  }; // to avoid a warning
744  // std::cout << cmd << " return value: " << ret << std::endl;
745  return true;
746 #else
747  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
748  src.c_str(), dst.c_str()));
749 #endif
750 #endif
751  } else {
752  std::cout << "Cannot copy: " << src << " in " << dst << std::endl;
753  return false;
754  }
755 }
756 
765 bool vpIoTools::remove(const std::string &file_or_dir)
766 {
767  // Check if we have to consider a file or a directory
768  if (vpIoTools::checkFilename(file_or_dir)
769 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
770  || vpIoTools::checkFifo(std::string(file_or_dir))
771 #endif
772  ) {
773  // std::cout << "remove file: " << file_or_dir << std::endl;
774  if (::remove(file_or_dir.c_str()) != 0)
775  return false;
776  else
777  return true;
778  } else if (vpIoTools::checkDirectory(file_or_dir)) {
779 // std::cout << "remove directory: " << file_or_dir << std::endl;
780 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
781 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
782  // wordexp() is not available
783  char cmd[FILENAME_MAX];
784  sprintf(cmd, "rm -rf \"%s\"", file_or_dir.c_str());
785  int ret = system(cmd);
786  if (ret) {
787  }; // to avoid a warning
788  // std::cout << cmd << " return value: " << ret << std::endl;
789  return true;
790 #else
791  throw(vpIoException(vpException::fatalError, "Cannot remove %s: not implemented on iOS Platform", file_or_dir.c_str()));
792 #endif
793 #elif defined(_WIN32)
794 #if (!defined(WINRT))
795  char cmd[FILENAME_MAX];
796  std::string file_or_dir_ = vpIoTools::path(file_or_dir);
797  sprintf(cmd, "rmdir /S /Q %s", file_or_dir_.c_str());
798  int 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 remove %s: not implemented on Universal Windows Platform",
805  file_or_dir.c_str()));
806 #endif
807 #endif
808  } else {
809  std::cout << "Cannot remove: " << file_or_dir << std::endl;
810  return false;
811  }
812 }
813 
823 bool vpIoTools::rename(const std::string &oldfilename, const std::string &newfilename)
824 {
825  if (::rename(oldfilename.c_str(), newfilename.c_str()) != 0)
826  return false;
827  else
828  return true;
829 }
830 
841 std::string vpIoTools::path(const std::string &pathname)
842 {
843  std::string path(pathname);
844 
845 #if defined(_WIN32)
846  for (unsigned int i = 0; i < path.length(); i++)
847  if (path[i] == '/')
848  path[i] = '\\';
849 #elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
850  for (unsigned int i = 0; i < path.length(); i++)
851  if (path[i] == '\\')
852  path[i] = '/';
853 #if TARGET_OS_IOS == 0 // The following code is not working on iOS and android since
854  // wordexp() is not available
855  #ifdef __ANDROID__
856  // Do nothing
857  #else
858  wordexp_t exp_result;
859 
860  // escape quote character
861  replaceAll(path, "'", "'\\''");
862  // add quotes to handle special characters like parentheses and spaces
863  wordexp(std::string("'" + path + "'").c_str(), &exp_result, 0);
864  path = exp_result.we_wordc == 1 ? exp_result.we_wordv[0] : "";
865  wordfree(&exp_result);
866  #endif
867 #endif
868 #endif
869 
870  return path;
871 }
872 
881 bool vpIoTools::loadConfigFile(const std::string &confFile)
882 {
883  configFile = path(confFile);
884  configVars.clear();
885  configValues.clear();
886  std::ifstream confContent(configFile.c_str(), std::ios::in);
887 
888  if (confContent.is_open()) {
889  std::string line, var, val;
890  long unsigned int k;
891  int c;
892  std::string stop[3] = {" ", "\t", "#"};
893  while (std::getline(confContent, line)) {
894  if ((line.compare(0, 1, "#") != 0) && (line.size() > 2)) {
895  try {
896  // name of the variable
897  k = static_cast<unsigned long>(line.find(" "));
898  var = line.substr(0, k);
899  // look for the end of the actual value
900  c = 200;
901  for (unsigned i = 0; i < 3; ++i)
902  c = vpMath::minimum(c, static_cast<int>(line.find(stop[i], static_cast<size_t>(k) + static_cast<size_t>(1))));
903  if (c == -1)
904  c = static_cast<int>(line.size());
905  long unsigned int c_ = static_cast<long unsigned int>(c);
906  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));
907  configVars.push_back(var);
908  configValues.push_back(val);
909  } catch (...) {
910  }
911  }
912  }
913  confContent.close();
914  } else {
915  return false;
916  }
917  return true;
918 }
919 
928 bool vpIoTools::readConfigVar(const std::string &var, float &value)
929 {
930  bool found = false;
931  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
932  if (configVars[k] == var) {
933  if (configValues[k].compare("PI") == 0)
934  value = static_cast<float>(M_PI);
935  else if (configValues[k].compare("PI/2") == 0)
936  value = static_cast<float>(M_PI / 2.0);
937  else if (configValues[k].compare("-PI/2") == 0)
938  value = static_cast<float>(-M_PI / 2.0);
939  else
940  value = static_cast<float>(atof(configValues[k].c_str()));
941  found = true;
942  }
943  }
944  if (found == false)
945  std::cout << var << " not found in config file" << std::endl;
946  return found;
947 }
956 bool vpIoTools::readConfigVar(const std::string &var, double &value)
957 {
958  bool found = false;
959  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
960  if (configVars[k] == var) {
961  if (configValues[k].compare("PI") == 0)
962  value = M_PI;
963  else if (configValues[k].compare("PI/2") == 0)
964  value = M_PI / 2;
965  else if (configValues[k].compare("-PI/2") == 0)
966  value = -M_PI / 2;
967  else
968  value = atof(configValues[k].c_str());
969  found = true;
970  }
971  }
972  if (found == false)
973  std::cout << var << " not found in config file" << std::endl;
974  return found;
975 }
976 
985 bool vpIoTools::readConfigVar(const std::string &var, int &value)
986 {
987  bool found = false;
988  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
989  if (configVars[k] == var) {
990  value = atoi(configValues[k].c_str());
991  found = true;
992  }
993  }
994  if (found == false)
995  std::cout << var << " not found in config file" << std::endl;
996  return found;
997 }
998 
1007 bool vpIoTools::readConfigVar(const std::string &var, unsigned int &value)
1008 {
1009  int v = 0;
1010  bool found = readConfigVar(var, v);
1011  value = static_cast<unsigned int>(v);
1012  return found;
1013 }
1014 
1023 bool vpIoTools::readConfigVar(const std::string &var, bool &value)
1024 {
1025  int v = 0;
1026  bool found = readConfigVar(var, v);
1027  value = (v != 0);
1028  return found;
1029 }
1030 
1039 bool vpIoTools::readConfigVar(const std::string &var, vpColor &value)
1040 {
1041  unsigned int v = 0;
1042  bool found = readConfigVar(var, v);
1043  value = vpColor::getColor(v);
1044  return found;
1045 }
1046 
1055 bool vpIoTools::readConfigVar(const std::string &var, std::string &value)
1056 {
1057  bool found = false;
1058  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1059  if (configVars[k] == var) {
1060  value = configValues[k];
1061  found = true;
1062  }
1063  }
1064  if (found == false)
1065  std::cout << var << " not found in config file" << std::endl;
1066  return found;
1067 }
1068 
1082 bool vpIoTools::readConfigVar(const std::string &var, vpArray2D<double> &value, const unsigned int &nCols,
1083  const unsigned int &nRows)
1084 {
1085  bool found = false;
1086  std::string nb;
1087  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1088  if (configVars[k] == var) {
1089  found = true;
1090  // resize or not
1091  if (nCols != 0 && nRows != 0)
1092  value.resize(nRows, nCols);
1093  size_t ind = 0, ind2;
1094  for (unsigned int i = 0; i < value.getRows(); ++i)
1095  for (unsigned int j = 0; j < value.getCols(); ++j) {
1096  ind2 = configValues[k].find(",", ind);
1097  nb = configValues[k].substr(ind, ind2 - ind);
1098  if (nb.compare("PI") == 0)
1099  value[i][j] = M_PI;
1100  else if (nb.compare("PI/2") == 0)
1101  value[i][j] = M_PI / 2;
1102  else if (nb.compare("-PI/2") == 0)
1103  value[i][j] = -M_PI / 2;
1104  else
1105  value[i][j] = atof(nb.c_str());
1106  ind = ind2 + 1;
1107  }
1108  }
1109  }
1110  if (found == false)
1111  std::cout << var << " not found in config file" << std::endl;
1112  return found;
1113 }
1114 
1115 // construct experiment filename & path
1116 
1125 void vpIoTools::addNameElement(const std::string &strTrue, const bool &cond, const std::string &strFalse)
1126 {
1127  if (cond)
1128  baseName += "_" + strTrue;
1129  else if (strFalse != "")
1130  baseName += "_" + strFalse;
1131 }
1132 
1141 void vpIoTools::addNameElement(const std::string &strTrue, const double &val)
1142 {
1143  // if(val != 0.)
1144  if (std::fabs(val) < std::numeric_limits<double>::epsilon()) {
1145  char valC[256];
1146  sprintf(valC, "%.3f", val);
1147  std::string valS(valC);
1148  baseName += "_" + strTrue + valS;
1149  }
1150 }
1151 
1160 void vpIoTools::createBaseNamePath(const bool &empty)
1161 {
1162  if (vpIoTools::checkDirectory(baseDir + baseName) == false) {
1164  std::cout << "creating directory " + baseDir + baseName << std::endl;
1165  } else {
1166  if (empty) {
1167  std::cout << "emptying directory " + baseDir + baseName << std::endl;
1169  }
1170  }
1171 }
1172 
1179 void vpIoTools::saveConfigFile(const bool &actuallySave)
1180 {
1181  if (actuallySave) {
1182  std::string dest = baseDir + "/" + baseName + "_config.txt";
1183  // file copy
1184  vpIoTools::copy(configFile, dest);
1185  }
1186 }
1187 
1203 {
1204  std::string data_path;
1205  std::string file_to_test("mbt/cube.cao");
1206  std::string filename;
1207 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1208  // Test if visp-images-data package is u-installed (Ubuntu and Debian)
1209  data_path = "/usr/share/visp-images-data/ViSP-images";
1210  filename = data_path + "/" + file_to_test;
1211  if (vpIoTools::checkFilename(filename))
1212  return data_path;
1213  data_path = "/usr/share/visp-images-data/visp-images";
1214  filename = data_path + "/" + file_to_test;
1215  if (vpIoTools::checkFilename(filename))
1216  return data_path;
1217 #endif
1218  // Test if VISP_INPUT_IMAGE_PATH env var is set
1219  try {
1220  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH");
1221  filename = data_path + "/" + file_to_test;
1222  if (vpIoTools::checkFilename(filename))
1223  return data_path;
1224  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/ViSP-images";
1225  filename = data_path + "/" + file_to_test;
1226  if (vpIoTools::checkFilename(filename))
1227  return data_path;
1228  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/visp-images";
1229  filename = data_path + "/" + file_to_test;
1230  if (vpIoTools::checkFilename(filename))
1231  return data_path;
1232  } catch (...) {
1233  }
1234  data_path = "";
1235  return data_path;
1236 }
1237 
1267 std::string vpIoTools::getFileExtension(const std::string &pathname, bool checkFile)
1268 {
1269  if (checkFile && (vpIoTools::checkDirectory(pathname) || !vpIoTools::checkFilename(pathname))) {
1270  return "";
1271  }
1272 
1273 #if defined(_WIN32)
1274  std::string sep = "\\";
1275  std::string altsep = "/";
1276  std::string extsep = ".";
1277 #else
1278  // On Unix, or on the Mac
1279  std::string sep = "/";
1280  std::string altsep = "";
1281  std::string extsep = ".";
1282 #endif
1283 
1284  // Python 2.7.8 module.
1285  //# Split a path in root and extension.
1286  //# The extension is everything starting at the last dot in the last
1287  //# pathname component; the root is everything before that.
1288  //# It is always true that root + ext == p.
1289  //
1290  //# Generic implementation of splitext, to be parametrized with
1291  //# the separators
1292  // def _splitext(p, sep, altsep, extsep):
1293  // """Split the extension from a pathname.
1294  //
1295  // Extension is everything from the last dot to the end, ignoring
1296  // leading dots. Returns "(root, ext)"; ext may be empty."""
1297  //
1298  // sepIndex = p.rfind(sep)
1299  // if altsep:
1300  // altsepIndex = p.rfind(altsep)
1301  // sepIndex = max(sepIndex, altsepIndex)
1302  //
1303  // dotIndex = p.rfind(extsep)
1304  // if dotIndex > sepIndex:
1305  // # skip all leading dots
1306  // filenameIndex = sepIndex + 1
1307  // while filenameIndex < dotIndex:
1308  // if p[filenameIndex] != extsep:
1309  // return p[:dotIndex], p[dotIndex:]
1310  // filenameIndex += 1
1311  //
1312  // return p, ''
1313 
1314  int sepIndex = static_cast<int>(pathname.rfind(sep));
1315  if (!altsep.empty()) {
1316  int altsepIndex = static_cast<int>(pathname.rfind(altsep));
1317  sepIndex = ((std::max))(sepIndex, altsepIndex);
1318  }
1319 
1320  size_t dotIndex = pathname.rfind(extsep);
1321  if (dotIndex != std::string::npos) {
1322  // The extsep character exists
1323  size_t npos = std::string::npos;
1324  if ((sepIndex != static_cast<int>(npos) && static_cast<int>(dotIndex) > sepIndex) || sepIndex == static_cast<int>(npos)) {
1325  if (sepIndex == static_cast<int>(npos)) {
1326  sepIndex = 0;
1327  std::cout << "Debug sepIndex: " << sepIndex << std::endl;
1328  }
1329  size_t filenameIndex = static_cast<size_t>(sepIndex) + static_cast<size_t>(1);
1330 
1331  while (filenameIndex < dotIndex) {
1332  if (pathname.compare(filenameIndex, 1, extsep) != 0) {
1333  return pathname.substr(dotIndex);
1334  }
1335  filenameIndex++;
1336  }
1337  }
1338  }
1339 
1340  return "";
1341 }
1342 
1348 std::string vpIoTools::getName(const std::string &pathname)
1349 {
1350  if (pathname.size() > 0) {
1351  std::string convertedPathname = vpIoTools::path(pathname);
1352 
1353  size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1354  if (index != std::string::npos) {
1355  return convertedPathname.substr(index + 1);
1356  }
1357 
1358  return convertedPathname;
1359  }
1360 
1361  return "";
1362 }
1363 
1370 std::string vpIoTools::getNameWE(const std::string &pathname)
1371 {
1372  std::string name = vpIoTools::getName(pathname);
1373  size_t found = name.find_last_of(".");
1374  std::string name_we = name.substr(0, found);
1375  return name_we;
1376 }
1377 
1383 std::string vpIoTools::getParent(const std::string &pathname)
1384 {
1385  if (pathname.size() > 0) {
1386  std::string convertedPathname = vpIoTools::path(pathname);
1387 
1388  size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1389  if (index != std::string::npos) {
1390  return convertedPathname.substr(0, index);
1391  }
1392  }
1393 
1394  return "";
1395 }
1396 
1405 std::string vpIoTools::getAbsolutePathname(const std::string &pathname)
1406 {
1407 
1408 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1409  std::string real_path_str = pathname;
1410  char *real_path = realpath(pathname.c_str(), NULL);
1411 
1412  if (real_path) {
1413  real_path_str = real_path;
1414  free(real_path);
1415  }
1416  return real_path_str;
1417 #elif defined(_WIN32)
1418 #if (!defined(WINRT))
1419  std::string real_path_str = pathname;
1420  DWORD retval = 0;
1421  TCHAR buffer[4096] = TEXT("");
1422 
1423  retval = GetFullPathName(pathname.c_str(), 4096, buffer, 0);
1424  if (retval != 0) {
1425  real_path_str = buffer;
1426  }
1427  return real_path_str;
1428 #else
1430  "Cannot get absolute path of %s: not implemented on "
1431  "Universal Windows Platform",
1432  pathname.c_str()));
1433 #endif
1434 #endif
1435 }
1436 
1447 std::string vpIoTools::createFilePath(const std::string &parent, const std::string &child)
1448 {
1449  if (child.size() == 0 && parent.size() == 0) {
1450  return "";
1451  }
1452 
1453  if (child.size() == 0) {
1454  return vpIoTools::path(parent);
1455  }
1456 
1457  if (parent.size() == 0) {
1458  return vpIoTools::path(child);
1459  }
1460 
1461  std::string convertedParent = vpIoTools::path(parent);
1462  std::string convertedChild = vpIoTools::path(child);
1463 
1464  std::stringstream ss;
1465  ss << vpIoTools::separator;
1466  std::string stringSeparator;
1467  ss >> stringSeparator;
1468 
1469  std::string lastConvertedParentChar = convertedParent.substr(convertedParent.size() - 1);
1470  std::string firstConvertedChildChar = convertedChild.substr(0, 1);
1471 
1472  if (lastConvertedParentChar == stringSeparator) {
1473  convertedParent = convertedParent.substr(0, convertedParent.size() - 1);
1474  }
1475 
1476  if (firstConvertedChildChar == stringSeparator) {
1477  convertedChild = convertedChild.substr(1);
1478  }
1479 
1480  return std::string(convertedParent + vpIoTools::separator + convertedChild);
1481 }
1482 
1488 bool vpIoTools::isAbsolutePathname(const std::string &pathname)
1489 {
1490  //# Inspired by the Python 2.7.8 module.
1491  //# Return whether a path is absolute.
1492  //# Trivial in Posix, harder on the Mac or MS-DOS.
1493  //# For DOS it is absolute if it starts with a slash or backslash (current
1494  //# volume), or if a pathname after the volume letter and colon / UNC
1495  // resource # starts with a slash or backslash.
1496  //
1497  // def isabs(s):
1498  // """Test whether a path is absolute"""
1499  // s = splitdrive(s)[1]
1500  // return s != '' and s[:1] in '/\\'
1501  std::string path = splitDrive(pathname).second;
1502  return path.size() > 0 && (path.substr(0, 1) == "/" || path.substr(0, 1) == "\\");
1503 }
1504 
1512 bool vpIoTools::isSamePathname(const std::string &pathname1, const std::string &pathname2)
1513 {
1514  // Normalize path
1515  std::string path1_normalize = vpIoTools::path(pathname1);
1516  std::string path2_normalize = vpIoTools::path(pathname2);
1517 
1518  // Get absolute path
1519  path1_normalize = vpIoTools::getAbsolutePathname(path1_normalize);
1520  path2_normalize = vpIoTools::getAbsolutePathname(path2_normalize);
1521 
1522  return (path1_normalize == path2_normalize);
1523 }
1524 
1532 std::pair<std::string, std::string> vpIoTools::splitDrive(const std::string &pathname)
1533 {
1534 //# Split a path in a drive specification (a drive letter followed by a
1535 //# colon) and the path specification.
1536 //# It is always true that drivespec + pathspec == p
1537 // def splitdrive(p):
1538 // """Split a pathname into drive/UNC sharepoint and relative path
1539 // specifiers. Returns a 2-tuple (drive_or_unc, path); either part may be
1540 // empty.
1541 //
1542 // If you assign
1543 // result = splitdrive(p)
1544 // It is always true that:
1545 // result[0] + result[1] == p
1546 //
1547 // If the path contained a drive letter, drive_or_unc will contain
1548 // everything up to and including the colon. e.g. splitdrive("c:/dir")
1549 // returns ("c:", "/dir")
1550 //
1551 // If the path contained a UNC path, the drive_or_unc will contain the host
1552 // name and share up to but not including the fourth directory separator
1553 // character. e.g. splitdrive("//host/computer/dir") returns
1554 // ("//host/computer", "/dir")
1555 //
1556 // Paths cannot contain both a drive letter and a UNC path.
1557 //
1558 // """
1559 // if len(p) > 1:
1560 // normp = p.replace(altsep, sep)
1561 // if (normp[0:2] == sep*2) and (normp[2] != sep):
1562 // # is a UNC path:
1563 // # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
1564 // # \\machine\mountpoint\directory\etc\...
1565 // # directory ^^^^^^^^^^^^^^^
1566 // index = normp.find(sep, 2)
1567 // if index == -1:
1568 // return '', p
1569 // index2 = normp.find(sep, index + 1)
1570 // # a UNC path can't have two slashes in a row
1571 // # (after the initial two)
1572 // if index2 == index + 1:
1573 // return '', p
1574 // if index2 == -1:
1575 // index2 = len(p)
1576 // return p[:index2], p[index2:]
1577 // if normp[1] == ':':
1578 // return p[:2], p[2:]
1579 // return '', p
1580 
1581 // On Unix, the drive is always empty.
1582 // On the Mac, the drive is always empty (don't use the volume name -- it
1583 // doesn't have the same syntactic and semantic oddities as DOS drive
1584 // letters, such as there being a separate current directory per drive).
1585 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
1586  return std::pair<std::string, std::string>("", pathname);
1587 #else
1588  const std::string sep = "\\";
1589  const std::string sepsep = "\\\\";
1590  const std::string altsep = "/";
1591 
1592  if (pathname.size() > 1) {
1593  std::string normPathname = pathname;
1594  std::replace(normPathname.begin(), normPathname.end(), *altsep.c_str(), *sep.c_str());
1595 
1596  if (normPathname.substr(0, 2) == sepsep && normPathname.substr(2, 1) != sep) {
1597  // is a UNC path:
1598  // vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
1599  // \\machine\mountpoint\directory\etc\...
1600  // directory ^^^^^^^^^^^^^^^
1601  size_t index = normPathname.find(sep, 2);
1602  if (index == std::string::npos) {
1603  return std::pair<std::string, std::string>("", pathname);
1604  }
1605 
1606  size_t index2 = normPathname.find(sep, index + 1);
1607  //# a UNC path can't have two slashes in a row
1608  //# (after the initial two)
1609  if (index2 == index + 1) {
1610  return std::pair<std::string, std::string>("", pathname);
1611  }
1612 
1613  if (index2 == std::string::npos) {
1614  index2 = pathname.size();
1615  }
1616 
1617  return std::pair<std::string, std::string>(pathname.substr(0, index2), pathname.substr(index2));
1618  }
1619 
1620  if (normPathname[1] == ':') {
1621  return std::pair<std::string, std::string>(pathname.substr(0, 2), pathname.substr(2));
1622  }
1623  }
1624 
1625  return std::pair<std::string, std::string>("", pathname);
1626 #endif
1627 }
1628 
1677 std::vector<std::string> vpIoTools::splitChain(const std::string &chain, const std::string &sep)
1678 {
1679  size_t startIndex = 0;
1680 
1681  std::string chainToSplit = chain;
1682  std::vector<std::string> subChain;
1683  size_t sepIndex = chainToSplit.find(sep);
1684 
1685  while (sepIndex != std::string::npos) {
1686  std::string sub = chainToSplit.substr(startIndex, sepIndex);
1687  if (!sub.empty())
1688  subChain.push_back(sub);
1689  chainToSplit = chainToSplit.substr(sepIndex + 1, chain.size() - 1);
1690 
1691  sepIndex = chainToSplit.find(sep);
1692  }
1693  if (!chainToSplit.empty())
1694  subChain.push_back(chainToSplit);
1695 
1696  return subChain;
1697 }
1698 
1706 std::vector<std::string> vpIoTools::getDirFiles(const std::string &pathname)
1707 {
1708 
1709  if (!checkDirectory(pathname)) {
1710  throw(vpIoException(vpException::fatalError, "Directory %s doesn't exist'", pathname.c_str()));
1711  }
1712  std::string dirName = path(pathname);
1713 
1714 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1715 
1716  std::vector<std::string> files;
1717  struct dirent **list = NULL;
1718  int filesCount = scandir(dirName.c_str(), &list, NULL, NULL);
1719  if (filesCount == -1) {
1720  throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
1721  }
1722  for (int i = 0; i < filesCount; i++) {
1723  std::string fileName = list[i]->d_name;
1724  if (fileName != "." && fileName != "..") {
1725  files.push_back(fileName);
1726  }
1727  free(list[i]);
1728  }
1729  free(list);
1730  std::sort(files.begin(), files.end());
1731  return files;
1732 
1733 #elif defined(_WIN32)
1734 #if (!defined(WINRT))
1735 
1736  std::vector<std::string> files;
1737  std::string fileMask = dirName;
1738  fileMask.append("\\*");
1739  WIN32_FIND_DATA FindFileData;
1740  HANDLE hFind = FindFirstFile(fileMask.c_str(), &FindFileData);
1741  // Directory is empty
1742  if (HandleToLong(&hFind) == ERROR_FILE_NOT_FOUND) {
1743  return files;
1744  }
1745  if (hFind == INVALID_HANDLE_VALUE) {
1746  throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
1747  }
1748  do {
1749  std::string fileName = FindFileData.cFileName;
1750  if (fileName != "." && fileName != "..") {
1751  files.push_back(fileName);
1752  }
1753  } while (FindNextFile(hFind, &FindFileData));
1754  FindClose(hFind);
1755  std::sort(files.begin(), files.end());
1756  return files;
1757 
1758 #else
1760  "Cannot read files of directory %s: not implemented on "
1761  "Universal Windows Platform",
1762  dirName.c_str()));
1763 #endif
1764 #endif
1765 }
1766 
1770 void vpIoTools::readBinaryValueLE(std::ifstream &file, int16_t &short_value)
1771 {
1772  file.read((char *)(&short_value), sizeof(short_value));
1773 
1774 #ifdef VISP_BIG_ENDIAN
1775  // Swap bytes order from little endian to big endian
1776  short_value = vpEndian::swap16bits((uint16_t)short_value);
1777 #endif
1778 }
1779 
1783 void vpIoTools::readBinaryValueLE(std::ifstream &file, uint16_t &ushort_value)
1784 {
1785  file.read((char *)(&ushort_value), sizeof(ushort_value));
1786 
1787 #ifdef VISP_BIG_ENDIAN
1788  // Swap bytes order from little endian to big endian
1789  ushort_value = vpEndian::swap16bits(ushort_value);
1790 #endif
1791 }
1792 
1796 void vpIoTools::readBinaryValueLE(std::ifstream &file, int32_t &int_value)
1797 {
1798  file.read((char *)(&int_value), sizeof(int_value));
1799 
1800 #ifdef VISP_BIG_ENDIAN
1801  // Swap bytes order from little endian to big endian
1802  int_value = vpEndian::swap32bits((uint32_t)int_value);
1803 #endif
1804 }
1805 
1809 void vpIoTools::readBinaryValueLE(std::ifstream &file, uint32_t &uint_value)
1810 {
1811  file.read((char *)(&uint_value), sizeof(uint_value));
1812 
1813 #ifdef VISP_BIG_ENDIAN
1814  // Swap bytes order from little endian to big endian
1815  uint_value = vpEndian::swap32bits(uint_value);
1816 #endif
1817 }
1818 
1822 void vpIoTools::readBinaryValueLE(std::ifstream &file, float &float_value)
1823 {
1824  file.read((char *)(&float_value), sizeof(float_value));
1825 
1826 #ifdef VISP_BIG_ENDIAN
1827  // Swap bytes order from little endian to big endian
1828  float_value = vpEndian::swapFloat(float_value);
1829 #endif
1830 }
1831 
1835 void vpIoTools::readBinaryValueLE(std::ifstream &file, double &double_value)
1836 {
1837  file.read((char *)(&double_value), sizeof(double_value));
1838 
1839 #ifdef VISP_BIG_ENDIAN
1840  // Swap bytes order from little endian to big endian
1841  double_value = vpEndian::swapDouble(double_value);
1842 #endif
1843 }
1844 
1848 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
1849 {
1850 #ifdef VISP_BIG_ENDIAN
1851  // Swap bytes order to little endian
1852  uint16_t swap_short = vpEndian::swap16bits((uint16_t)short_value);
1853  file.write((char *)(&swap_short), sizeof(swap_short));
1854 #else
1855  file.write((char *)(&short_value), sizeof(short_value));
1856 #endif
1857 }
1858 
1862 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint16_t ushort_value)
1863 {
1864 #ifdef VISP_BIG_ENDIAN
1865  // Swap bytes order to little endian
1866  uint16_t swap_ushort = vpEndian::swap16bits(ushort_value);
1867  file.write((char *)(&swap_ushort), sizeof(swap_ushort));
1868 #else
1869  file.write((char *)(&ushort_value), sizeof(ushort_value));
1870 #endif
1871 }
1872 
1876 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int32_t int_value)
1877 {
1878 #ifdef VISP_BIG_ENDIAN
1879  // Swap bytes order to little endian
1880  uint32_t swap_int = vpEndian::swap32bits((uint32_t)int_value);
1881  file.write((char *)(&swap_int), sizeof(swap_int));
1882 #else
1883  file.write((char *)(&int_value), sizeof(int_value));
1884 #endif
1885 }
1886 
1890 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint32_t uint_value)
1891 {
1892 #ifdef VISP_BIG_ENDIAN
1893  // Swap bytes order to little endian
1894  uint32_t swap_int = vpEndian::swap32bits(uint_value);
1895  file.write((char *)(&swap_int), sizeof(swap_int));
1896 #else
1897  file.write((char *)(&uint_value), sizeof(uint_value));
1898 #endif
1899 }
1900 
1904 void vpIoTools::writeBinaryValueLE(std::ofstream &file, float float_value)
1905 {
1906 #ifdef VISP_BIG_ENDIAN
1907  // Swap bytes order to little endian
1908  float swap_float = vpEndian::swapFloat(float_value);
1909  file.write((char *)(&swap_float), sizeof(swap_float));
1910 #else
1911  file.write((char *)(&float_value), sizeof(float_value));
1912 #endif
1913 }
1914 
1918 void vpIoTools::writeBinaryValueLE(std::ofstream &file, double double_value)
1919 {
1920 #ifdef VISP_BIG_ENDIAN
1921  // Swap bytes order to little endian
1922  double swap_double = vpEndian::swapDouble(double_value);
1923  file.write((char *)(&swap_double), sizeof(swap_double));
1924 #else
1925  file.write((char *)(&double_value), sizeof(double_value));
1926 #endif
1927 }
1928 
1929 bool vpIoTools::parseBoolean(std::string input)
1930 {
1931  std::transform(input.begin(), input.end(), input.begin(), ::tolower);
1932  std::istringstream is(input);
1933  bool b;
1934  // Parse string to boolean either in the textual representation
1935  // (True/False) or in numeric representation (1/0)
1936  is >> (input.size() > 1 ? std::boolalpha : std::noboolalpha) >> b;
1937  return b;
1938 }
1939 
1943 std::string vpIoTools::trim(std::string s)
1944 {
1945  return ltrim(rtrim(s));
1946 }
static void makeDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:482
VISP_EXPORT float swapFloat(float f)
Definition: vpEndian.cpp:68
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:305
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1202
static bool isAbsolutePathname(const std::string &pathname)
Definition: vpIoTools.cpp:1488
static void getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
Definition: vpIoTools.cpp:292
static bool rename(const std::string &oldfilename, const std::string &newfilename)
Definition: vpIoTools.cpp:823
static void readBinaryValueLE(std::ifstream &file, int16_t &short_value)
Definition: vpIoTools.cpp:1770
Class to define RGB colors available for display functionnalities.
Definition: vpColor.h:157
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:682
static std::string getFileExtension(const std::string &pathname, bool checkFile=false)
Definition: vpIoTools.cpp:1267
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:1706
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:1383
static bool checkFifo(const std::string &filename)
Definition: vpIoTools.cpp:392
static std::string path(const std::string &pathname)
Definition: vpIoTools.cpp:841
static void createBaseNamePath(const bool &empty=false)
Definition: vpIoTools.cpp:1160
static const std::string & getBuildInformation()
Definition: vpIoTools.cpp:135
static bool checkDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:332
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:148
static bool parseBoolean(std::string input)
Definition: vpIoTools.cpp:1929
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:1447
static std::pair< std::string, std::string > splitDrive(const std::string &pathname)
Definition: vpIoTools.cpp:1532
static bool isSamePathname(const std::string &pathname1, const std::string &pathname2)
Definition: vpIoTools.cpp:1512
VISP_EXPORT uint16_t swap16bits(uint16_t val)
Definition: vpEndian.cpp:49
static void makeFifo(const std::string &dirname)
Definition: vpIoTools.cpp:533
VISP_EXPORT double swapDouble(double d)
Definition: vpEndian.cpp:87
static std::string getUserName()
Definition: vpIoTools.cpp:228
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:1677
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:153
static void saveConfigFile(const bool &actuallySave=true)
Definition: vpIoTools.cpp:1179
static std::vector< std::string > configVars
Definition: vpIoTools.h:254
static std::string getName(const std::string &pathname)
Definition: vpIoTools.cpp:1348
VISP_EXPORT uint32_t swap32bits(uint32_t val)
Definition: vpEndian.cpp:58
static void writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
Definition: vpIoTools.cpp:1848
static bool remove(const std::string &filename)
Definition: vpIoTools.cpp:765
static std::string makeTempDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:581
static std::string baseName
Definition: vpIoTools.h:251
static std::string getFullName()
Definition: vpIoTools.cpp:166
static std::string trim(std::string s)
Definition: vpIoTools.cpp:1943
static std::string configFile
Definition: vpIoTools.h:253
static void setBaseDir(const std::string &dir)
Definition: vpIoTools.cpp:154
static std::string getNameWE(const std::string &pathname)
Definition: vpIoTools.cpp:1370
static std::string getBaseName()
Definition: vpIoTools.cpp:160
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:640
static std::string getAbsolutePathname(const std::string &pathname)
Definition: vpIoTools.cpp:1405
static vpColor getColor(const unsigned int &i)
Definition: vpColor.h:310
static bool readConfigVar(const std::string &var, float &value)
Definition: vpIoTools.cpp:928
static std::vector< std::string > configValues
Definition: vpIoTools.h:255
static bool loadConfigFile(const std::string &confFile)
Definition: vpIoTools.cpp:881
static void addNameElement(const std::string &strTrue, const bool &cond=true, const std::string &strFalse="")
Definition: vpIoTools.cpp:1125
static std::string getenv(const std::string &env)
Definition: vpIoTools.cpp:265