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