Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
vpIoTools.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2023 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 https://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*****************************************************************************/
35
41// At this point, to make scandir() working as expected on armv7 virtualized on a x86-64bit architecture
42// (see github/workflow/other-arch-isolated.yml) we need to define _FILE_OFFSET_BITS=64. Otherwise
43// testVideo.cpp will fail.
44// Since adding here something like:
45// #include <visp3/core/vpConfig.h>
46// #ifdef VISP_DEFINE_FILE_OFFSET_BITS
47// # define _FILE_OFFSET_BITS 64
48// #endif
49// where VISP_DEFINE_FILE_OFFSET_BITS is defined in vpConfig.h doesn't work (my explanation is that the define
50// should be done before any other includes; in vpConfig.h there is cstdlib that is included), the other way
51// that was retained is to add to vpIoTools.cpp COMPILE_DEFINTIONS _FILE_OFFSET_BITS=64 (see CMakeLists.txt)
52
53#include <algorithm>
54#include <cctype>
55#include <cmath>
56#include <errno.h>
57#include <fcntl.h>
58#include <fstream>
59#include <functional>
60#include <limits>
61#include <stdio.h>
62#include <stdlib.h>
63#include <string.h>
64#include <sys/stat.h>
65#include <sys/types.h>
66#include <visp3/core/vpDebug.h>
67#include <visp3/core/vpEndian.h>
68#include <visp3/core/vpIoException.h>
69#include <visp3/core/vpIoTools.h>
70#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
71#include <dirent.h>
72#include <unistd.h>
73#elif defined(_WIN32)
74#include <direct.h>
75#include <windows.h>
76#endif
77#if !defined(_WIN32)
78#ifdef __ANDROID__
79// Like IOS, wordexp.cpp is not defined for Android
80#else
81#include <wordexp.h>
82#endif
83#endif
84
85#if defined(__APPLE__) && defined(__MACH__) // Apple OSX and iOS (Darwin)
86#include <TargetConditionals.h> // To detect OSX or IOS using TARGET_OS_IOS macro
87#endif
88
89#ifndef PATH_MAX
90#ifdef _MAX_PATH
91#define PATH_MAX _MAX_PATH
92#else
93#define PATH_MAX 1024
94#endif
95#endif
96
97#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
98#define VP_STAT stat
99#elif defined(_WIN32) && defined(__MINGW32__)
100#define VP_STAT stat
101#elif defined(_WIN32)
102#define VP_STAT _stat
103#else
104#define VP_STAT stat
105#endif
106
107std::string vpIoTools::baseName = "";
108std::string vpIoTools::baseDir = "";
109std::string vpIoTools::configFile = "";
110std::vector<std::string> vpIoTools::configVars = std::vector<std::string>();
111std::vector<std::string> vpIoTools::configValues = std::vector<std::string>();
112
113namespace
114{
115// The following code is not working on iOS since wordexp() is not available
116// The function is not used on Android
117#if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
118#if (TARGET_OS_IOS == 0) && !defined(__ANDROID__)
119void replaceAll(std::string &str, const std::string &search, const std::string &replace)
120{
121 size_t start_pos = 0;
122 while ((start_pos = str.find(search, start_pos)) != std::string::npos) {
123 str.replace(start_pos, search.length(), replace);
124 start_pos += replace.length(); // Handles case where 'replace' is a
125 // substring of 'search'
126 }
127}
128#endif
129#endif
130
131std::string &ltrim(std::string &s)
132{
133#if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
134 s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) {
135 return !std::isspace(c);
136 }));
137#else
138 s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
139#endif
140 return s;
141}
142
143std::string &rtrim(std::string &s)
144{
145#if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
146 s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) {
147 return !std::isspace(c);
148 }).base(), s.end());
149#else
150 s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
151#endif
152 return s;
153}
154} // namespace
155
160{
161 static std::string build_info =
162#include "version_string.inc"
163 ;
164 return build_info;
165}
166
219{
220#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
221 std::string username;
222 vpIoTools::getUserName(username);
223 return "/tmp/" + username;
224#elif defined(_WIN32) && !defined(WINRT)
225 // https://docs.microsoft.com/en-us/windows/win32/fileio/creating-and-using-a-temporary-file
226 // Gets the temp path env string (no guarantee it's a valid path).
227 TCHAR lpTempPathBuffer[MAX_PATH];
228 DWORD dwRetVal = GetTempPath(MAX_PATH /* length of the buffer */, lpTempPathBuffer /* buffer for path */);
229 if (dwRetVal > MAX_PATH || (dwRetVal == 0)) {
230 throw vpIoException(vpIoException::cantGetenv, "Error with GetTempPath() call!");
231 }
232 std::string temp_path(lpTempPathBuffer);
233 if (!temp_path.empty()) {
234 if (temp_path.back() == '\\') {
235 temp_path.resize(temp_path.size() - 1);
236 }
237 }
238 else {
239 temp_path = "C:\temp";
240 try {
241 vpIoTools::makeDirectory(temp_path);
242 }
243 catch (...) {
244 throw(vpException(vpException::fatalError, "Cannot set temp path to %s", temp_path.c_str()));
245 }
246 }
247 return temp_path;
248#else
249 throw vpIoException(vpException::fatalError, "Not implemented on this platform!");
250#endif
251}
252
258void vpIoTools::setBaseName(const std::string &s) { baseName = s; }
259
265void vpIoTools::setBaseDir(const std::string &dir) { baseDir = dir + "/"; }
266
272std::string vpIoTools::getBaseName() { return baseName; }
273
279std::string vpIoTools::getFullName() { return baseDir + baseName; }
280
294void vpIoTools::getUserName(std::string &username)
295{
296 // With MinGW, UNIX and _WIN32 are defined
297#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
298 // Get the user name.
299 char *_username = ::getenv("LOGNAME");
300 if (!_username) {
301 username = "unknown";
302 }
303 else {
304 username = _username;
305 }
306#elif defined(_WIN32)
307#if (!defined(WINRT))
308 unsigned int info_buffer_size = 1024;
309 TCHAR *infoBuf = new TCHAR[info_buffer_size];
310 DWORD bufCharCount = (DWORD)info_buffer_size;
311 // Get the user name.
312 if (!GetUserName(infoBuf, &bufCharCount)) {
313 username = "unknown";
314 }
315 else {
316 username = infoBuf;
317 }
318 delete[] infoBuf;
319#else
320 // Universal platform
321 username = "unknown";
322#endif
323#else
324 username = "unknown";
325#endif
326}
327
343{
344 std::string username;
345 getUserName(username);
346 return username;
347}
348
379std::string vpIoTools::getenv(const std::string &env)
380{
381#if defined(_WIN32) && defined(WINRT)
382 throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value: not "
383 "implemented on Universal Windows Platform"));
384#else
385 std::string value;
386 // Get the environment variable value.
387 char *_value = ::getenv(env.c_str());
388 if (!_value) {
389 throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value"));
390 }
391 value = _value;
392
393 return value;
394#endif
395}
396
406void vpIoTools::getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
407{
408 if (version.size() == 0) {
409 major = 0;
410 minor = 0;
411 patch = 0;
412 }
413 else {
414 size_t major_pos = version.find('.');
415 std::string major_str = version.substr(0, major_pos);
416 major = static_cast<unsigned>(atoi(major_str.c_str()));
417
418 if (major_pos != std::string::npos) {
419 size_t minor_pos = version.find('.', major_pos + 1);
420 std::string minor_str = version.substr(major_pos + 1, (minor_pos - (major_pos + 1)));
421 minor = static_cast<unsigned>(atoi(minor_str.c_str()));
422
423 if (minor_pos != std::string::npos) {
424 std::string patch_str = version.substr(minor_pos + 1);
425 patch = static_cast<unsigned>(atoi(patch_str.c_str()));
426 }
427 else {
428 patch = 0;
429 }
430 }
431 else {
432 minor = 0;
433 patch = 0;
434 }
435 }
436}
437
449bool vpIoTools::checkDirectory(const std::string &dirname)
450{
451#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
452 struct stat stbuf;
453#elif defined(_WIN32) && defined(__MINGW32__)
454 struct stat stbuf;
455#elif defined(_WIN32)
456 struct _stat stbuf;
457#endif
458
459 if (dirname.empty()) {
460 return false;
461 }
462
463 std::string _dirname = path(dirname);
464
465 if (VP_STAT(_dirname.c_str(), &stbuf) != 0) {
466 std::cout << "DEBUG 1 _dirname: " << _dirname << " is not a dir" << std::endl;
467 // Test adding the separator if not already present
468 if (_dirname.at(_dirname.size() - 1) != separator) {
469 std::cout << "DEBUG 2 test if _dirname + separator: " << _dirname + separator << " is a dir ?" << std::endl;
470 if (VP_STAT((_dirname + separator).c_str(), &stbuf) != 0) {
471 std::cout << "DEBUG 2 _dirname + separator: " << _dirname + separator << " is not a dir" << std::endl;
472 return false;
473 }
474 }
475 // Test removing the separator if already present
476 if (_dirname.at(_dirname.size() - 1) == separator) {
477 std::cout << "DEBUG 2 test if _dirname - separator: " << _dirname.substr(0, _dirname.size() - 1) << " is a dir ?" << std::endl;
478 if (VP_STAT((_dirname.substr(0, _dirname.size() - 1)).c_str(), &stbuf) != 0) {
479 std::cout << "DEBUG 3 _dirname - separator: " << _dirname.substr(0, _dirname.size() - 1) << " is not a dir" << std::endl;
480 return false;
481 }
482 }
483 }
484
485#if defined(_WIN32) || (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
486 if ((stbuf.st_mode & S_IFDIR) == 0)
487#endif
488 {
489 return false;
490 }
491#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
492 if ((stbuf.st_mode & S_IWUSR) == 0)
493#elif defined(_WIN32)
494 if ((stbuf.st_mode & S_IWRITE) == 0)
495#endif
496 {
497 return false;
498 }
499 return true;
500}
501
514bool vpIoTools::checkFifo(const std::string &fifofilename)
515{
516#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
517 struct stat stbuf;
518
519 std::string _filename = path(fifofilename);
520 if (stat(_filename.c_str(), &stbuf) != 0) {
521 return false;
522 }
523 if ((stbuf.st_mode & S_IFIFO) == 0) {
524 return false;
525 }
526 if ((stbuf.st_mode & S_IRUSR) == 0)
527
528 {
529 return false;
530 }
531 return true;
532#elif defined(_WIN32)
533 (void)fifofilename;
534 throw(vpIoException(vpIoException::notImplementedError, "Fifo files are not supported on Windows platforms."));
535#endif
536}
537
538#ifndef DOXYGEN_SHOULD_SKIP_THIS
539int vpIoTools::mkdir_p(const std::string &path, int mode)
540{
541 errno = 0;
542 if (path.size() > PATH_MAX) {
543 errno = ENAMETOOLONG;
544 return -1;
545 }
546
547 // Iterate over the string
548 std::string _path = path;
549 std::string _sub_path;
550 for (size_t pos = 0; (pos = _path.find(vpIoTools::separator)) != std::string::npos;) {
551 _sub_path += _path.substr(0, pos + 1);
552 // Continue if sub_path = separator
553 if (pos == 0) {
554 _path.erase(0, pos + 1);
555 continue;
556 }
557#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
558 if (mkdir(_sub_path.c_str(), static_cast<mode_t>(mode)) != 0)
559#elif defined(_WIN32)
560 (void)mode; // var not used
561 if (!checkDirectory(_sub_path) && _mkdir(_sub_path.c_str()) != 0)
562#endif
563 {
564 if (errno != EEXIST) {
565 return -1;
566 }
567 }
568 _path.erase(0, pos + 1);
569 }
570
571 if (!_path.empty()) {
572 _sub_path += _path;
573#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
574 if (mkdir(_sub_path.c_str(), static_cast<mode_t>(mode)) != 0)
575#elif defined(_WIN32)
576
577 if (_mkdir(_sub_path.c_str()) != 0)
578#endif
579 {
580 if (errno != EEXIST) {
581 return -1;
582 }
583 }
584 }
585
586 return 0;
587}
588
589#endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
590
603void vpIoTools::makeDirectory(const std::string &dirname)
604{
605#if ((!defined(__unix__) && !defined(__unix) && (!defined(__APPLE__) || !defined(__MACH__)))) && !defined(_WIN32)
606 std::cerr << "Unsupported platform for vpIoTools::makeDirectory()!" << std::endl;
607 return;
608#endif
609
610#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
611 struct stat stbuf;
612#elif defined(_WIN32) && defined(__MINGW32__)
613 struct stat stbuf;
614#elif defined(_WIN32)
615 struct _stat stbuf;
616#endif
617
618 if (dirname.empty()) {
619 throw(vpIoException(vpIoException::invalidDirectoryName, "invalid directory name"));
620 }
621
622 std::string _dirname = path(dirname);
623
624#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
625 if (stat(_dirname.c_str(), &stbuf) != 0)
626#elif defined(_WIN32) && defined(__MINGW32__)
627 if (stat(_dirname.c_str(), &stbuf) != 0)
628#elif defined(_WIN32)
629 if (_stat(_dirname.c_str(), &stbuf) != 0)
630#endif
631 {
632 if (vpIoTools::mkdir_p(_dirname, 0755) != 0) {
633 throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'", dirname.c_str()));
634 }
635 }
636
637 if (checkDirectory(dirname) == false) {
638 throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'", dirname.c_str()));
639 }
640}
641
654void vpIoTools::makeFifo(const std::string &fifoname)
655{
656#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
657
658 // If dirname is a directory, we throw an error
659 if (vpIoTools::checkDirectory(fifoname)) {
661 "Unable to create fifo file. '%s' is an existing directory.", fifoname.c_str()));
662 }
663
664 // If dirname refers to an already existing file, we throw an error
665 else if (vpIoTools::checkFilename(fifoname)) {
666 throw(vpIoException(vpIoException::invalidDirectoryName, "Unable to create fifo file '%s'. File already exists.",
667 fifoname.c_str()));
668 // If dirname refers to an already existing fifo, we throw an error
669 }
670 else if (vpIoTools::checkFifo(fifoname)) {
671 throw(vpIoException(vpIoException::invalidDirectoryName, "Unable to create fifo file '%s'. Fifo already exists.",
672 fifoname.c_str()));
673 }
674
675 else if (mkfifo(fifoname.c_str(), 0666) < 0) {
676 throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create fifo file '%s'.", fifoname.c_str()));
677 }
678#elif defined(_WIN32)
679 (void)fifoname;
680 throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create fifo on Windows platforms."));
681#endif
682}
683
684#if defined(_WIN32) && !defined(WINRT)
685std::string getUuid()
686{
687 UUID uuid;
688 if (UuidCreate(&uuid) != RPC_S_OK) {
689 throw(vpIoException(vpIoException::fatalError, "UuidCreate() failed!"));
690 }
691
692 RPC_CSTR stringUuid;
693 if (UuidToString(&uuid, &stringUuid) != RPC_S_OK) {
694 throw(vpIoException(vpIoException::fatalError, "UuidToString() failed!"));
695 }
696
697 return reinterpret_cast<char *>(stringUuid);
698}
699#endif
700
757std::string vpIoTools::makeTempDirectory(const std::string &dirname)
758{
759#if defined(WINRT) || !defined(_WIN32) && !(defined(__unix__) || defined(__unix) || \
760 (defined(__APPLE__) && defined(__MACH__))) // not UNIX and not Windows
761 throw(vpIoException(vpIoException::cantCreateDirectory, "makeTempDirectory() is not supported on this platform!"));
762#endif
763
764 std::string dirname_cpy = std::string(dirname);
765 std::string correctEnding = "XXXXXX";
766
767 // If dirname is an unexisting directory, it should end with XXXXXX in order to create a temp directory
768 if (!vpIoTools::checkDirectory(dirname_cpy)) {
769#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
770 // Check if dirname ends with XXXXXX
771 if (dirname_cpy.rfind(correctEnding) == std::string::npos) {
772 if (dirname_cpy.at(dirname_cpy.length() - 1) != '/') {
773 dirname_cpy = dirname_cpy + "/";
774 }
775 try {
776 vpIoTools::makeDirectory(dirname_cpy);
777 }
778 catch (const vpException &e) {
779 throw e;
780 }
781
782 dirname_cpy = dirname_cpy + "XXXXXX";
783 }
784
785#elif defined(_WIN32) && !defined(WINRT)
786 // Remove XXXXXX
787 dirname_cpy = dirname_cpy.substr(0, dirname_cpy.rfind(correctEnding));
788 // Append UUID
789 dirname_cpy = dirname_cpy + getUuid();
790#endif
791
792 }
793 else {
794 // If dirname is an existing directory, we create a temp directory inside
795#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
796 if (dirname_cpy.at(dirname_cpy.length() - 1) != '/') {
797 dirname_cpy = dirname_cpy + "/";
798 }
799 dirname_cpy = dirname_cpy + "XXXXXX";
800#elif defined(_WIN32) && !defined(WINRT)
801 dirname_cpy = createFilePath(dirname_cpy, getUuid());
802#endif
803 }
804
805#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
806 char *dirname_char = new char[dirname_cpy.length() + 1];
807 strcpy(dirname_char, dirname_cpy.c_str());
808
809 char *computedDirname = mkdtemp(dirname_char);
810
811 if (!computedDirname) {
812 delete[] dirname_char;
813 throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'.", dirname_cpy.c_str()));
814 }
815
816 std::string res(computedDirname);
817 delete[] dirname_char;
818 return res;
819#elif defined(_WIN32) && !defined(WINRT)
820 makeDirectory(dirname_cpy);
821 return dirname_cpy;
822#endif
823}
824
835bool vpIoTools::checkFilename(const std::string &filename)
836{
837#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
838 struct stat stbuf;
839#elif defined(_WIN32)
840 struct _stat stbuf;
841#endif
842
843 if (filename.empty()) {
844 return false;
845 }
846
847 std::string _filename = path(filename);
848#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
849 if (stat(_filename.c_str(), &stbuf) != 0)
850#elif defined(_WIN32)
851 if (_stat(_filename.c_str(), &stbuf) != 0)
852#endif
853 {
854 return false;
855 }
856 if ((stbuf.st_mode & S_IFREG) == 0) {
857 return false;
858 }
859#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
860 if ((stbuf.st_mode & S_IRUSR) == 0)
861#elif defined(_WIN32)
862 if ((stbuf.st_mode & S_IREAD) == 0)
863#endif
864 {
865 return false;
866 }
867 return true;
868}
869
877bool vpIoTools::copy(const std::string &src, const std::string &dst)
878{
879 // Check if we have to consider a file or a directory
880 if (vpIoTools::checkFilename(src)) {
881 // std::cout << "copy file: " << 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 std::stringstream cmd;
886 cmd << "cp -p ";
887 cmd << src;
888 cmd << " ";
889 cmd << dst;
890 int ret = system(cmd.str().c_str());
891 if (ret) {
892 }; // to avoid a warning
893 // std::cout << cmd << " return value: " << ret << std::endl;
894 return true;
895#else
896 throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src.c_str(),
897 dst.c_str()));
898#endif
899#elif defined(_WIN32)
900#if (!defined(WINRT))
901 std::stringstream cmd;
902 cmd << "copy ";
903 cmd << vpIoTools::path(src);
904 cmd << " ";
905 cmd << vpIoTools::path(dst);
906 int ret = system(cmd.str().c_str());
907 if (ret) {
908 }; // to avoid a warning
909 // std::cout << cmd << " return value: " << ret << std::endl;
910 return true;
911#else
912 throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
913 src.c_str(), dst.c_str()));
914#endif
915#endif
916 }
917 else if (vpIoTools::checkDirectory(src)) {
918 // std::cout << "copy directory: " << src << " in " << dst << std::endl;
919#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
920#if TARGET_OS_IOS == 0 // The following code is not working on iOS since
921 // wordexp() is not available
922 std::stringstream cmd;
923 cmd << "cp -p ";
924 cmd << src;
925 cmd << " ";
926 cmd << dst;
927 int ret = system(cmd.str().c_str());
928 if (ret) {
929 }; // to avoid a warning
930 // std::cout << cmd << " return value: " << ret << std::endl;
931 return true;
932#else
933 throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src.c_str(),
934 dst.c_str()));
935#endif
936#elif defined(_WIN32)
937#if (!defined(WINRT))
938 std::stringstream cmd;
939 cmd << "copy ";
940 cmd << vpIoTools::path(src);
941 cmd << " ";
942 cmd << vpIoTools::path(dst);
943 int ret = system(cmd.str().c_str());
944 if (ret) {
945 }; // to avoid a warning
946 // std::cout << cmd << " return value: " << ret << std::endl;
947 return true;
948#else
949 throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
950 src.c_str(), dst.c_str()));
951#endif
952#endif
953 }
954 else {
955 std::cout << "Cannot copy: " << src << " in " << dst << std::endl;
956 return false;
957 }
958}
959
970bool vpIoTools::remove(const std::string &file_or_dir)
971{
972 // Check if we have to consider a file or a directory
973 if (vpIoTools::checkFilename(file_or_dir)
974#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
975 || vpIoTools::checkFifo(std::string(file_or_dir))
976#endif
977 ) {
978 // std::cout << "remove file: " << file_or_dir << std::endl;
979 if (::remove(file_or_dir.c_str()) != 0)
980 return false;
981 else
982 return true;
983 }
984 else if (vpIoTools::checkDirectory(file_or_dir)) {
985 // std::cout << "remove directory: " << file_or_dir << std::endl;
986#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
987#if TARGET_OS_IOS == 0 // The following code is not working on iOS since
988 // wordexp() is not available
989 std::stringstream cmd;
990 cmd << "rm -rf \"";
991 cmd << file_or_dir;
992 cmd << "\"";
993 int ret = system(cmd.str().c_str());
994 if (ret) {
995 }; // to avoid a warning
996 // std::cout << cmd << " return value: " << ret << std::endl;
997 return true;
998#else
999 throw(vpIoException(vpException::fatalError, "Cannot remove %s: not implemented on iOS Platform",
1000 file_or_dir.c_str()));
1001#endif
1002#elif defined(_WIN32)
1003#if (!defined(WINRT))
1004 std::stringstream cmd;
1005 cmd << "rmdir /S /Q ";
1006 cmd << vpIoTools::path(file_or_dir);
1007 cmd << "\"";
1008 int ret = system(cmd.str().c_str());
1009 if (ret) {
1010 }; // to avoid a warning
1011 // std::cout << cmd << " return value: " << ret << std::endl;
1012 return true;
1013#else
1014 throw(vpIoException(vpException::fatalError, "Cannot remove %s: not implemented on Universal Windows Platform",
1015 file_or_dir.c_str()));
1016#endif
1017#endif
1018 }
1019 else {
1020 std::cout << "Cannot remove: " << file_or_dir << std::endl;
1021 return false;
1022 }
1023}
1024
1034bool vpIoTools::rename(const std::string &oldfilename, const std::string &newfilename)
1035{
1036 if (::rename(oldfilename.c_str(), newfilename.c_str()) != 0)
1037 return false;
1038 else
1039 return true;
1040}
1041
1052std::string vpIoTools::path(const std::string &pathname)
1053{
1054 std::string path(pathname);
1055
1056#if defined(_WIN32)
1057 for (unsigned int i = 0; i < path.length(); i++)
1058 if (path[i] == '/')
1059 path[i] = '\\';
1060#elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
1061 for (unsigned int i = 0; i < path.length(); i++)
1062 if (path[i] == '\\')
1063 path[i] = '/';
1064#if TARGET_OS_IOS == 0 // The following code is not working on iOS and android since
1065 // wordexp() is not available
1066#ifdef __ANDROID__
1067// Do nothing
1068#else
1069 wordexp_t exp_result;
1070
1071 // escape quote character
1072 replaceAll(path, "'", "'\\''");
1073 // add quotes to handle special characters like parentheses and spaces
1074 wordexp(std::string("'" + path + "'").c_str(), &exp_result, 0);
1075 path = exp_result.we_wordc == 1 ? exp_result.we_wordv[0] : "";
1076 wordfree(&exp_result);
1077#endif
1078#endif
1079#endif
1080
1081 return path;
1082}
1083
1092bool vpIoTools::loadConfigFile(const std::string &confFile)
1093{
1094 configFile = path(confFile);
1095 configVars.clear();
1096 configValues.clear();
1097 std::ifstream confContent(configFile.c_str(), std::ios::in);
1098
1099 if (confContent.is_open()) {
1100 std::string line, var, val;
1101 long unsigned int k;
1102 int c;
1103 std::string stop[3] = { " ", "\t", "#" };
1104 while (std::getline(confContent, line)) {
1105 if ((line.compare(0, 1, "#") != 0) && (line.size() > 2)) {
1106 try {
1107 // name of the variable
1108 k = static_cast<unsigned long>(line.find(" "));
1109 var = line.substr(0, k);
1110 // look for the end of the actual value
1111 c = 200;
1112 for (unsigned i = 0; i < 3; ++i)
1113 c = vpMath::minimum(c,
1114 static_cast<int>(line.find(stop[i], static_cast<size_t>(k) + static_cast<size_t>(1))));
1115 if (c == -1)
1116 c = static_cast<int>(line.size());
1117 long unsigned int c_ = static_cast<long unsigned int>(c);
1118 val = line.substr(static_cast<size_t>(k) + static_cast<size_t>(1),
1119 static_cast<size_t>(c_) - static_cast<size_t>(k) - static_cast<size_t>(1));
1120 configVars.push_back(var);
1121 configValues.push_back(val);
1122 }
1123 catch (...) {
1124 }
1125 }
1126 }
1127 confContent.close();
1128 }
1129 else {
1130 return false;
1131 }
1132 return true;
1133}
1134
1143bool vpIoTools::readConfigVar(const std::string &var, float &value)
1144{
1145 bool found = false;
1146 for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1147 if (configVars[k] == var) {
1148 if (configValues[k].compare("PI") == 0)
1149 value = static_cast<float>(M_PI);
1150 else if (configValues[k].compare("PI/2") == 0)
1151 value = static_cast<float>(M_PI / 2.0);
1152 else if (configValues[k].compare("-PI/2") == 0)
1153 value = static_cast<float>(-M_PI / 2.0);
1154 else
1155 value = static_cast<float>(atof(configValues[k].c_str()));
1156 found = true;
1157 }
1158 }
1159 if (found == false)
1160 std::cout << var << " not found in config file" << std::endl;
1161 return found;
1162}
1171bool vpIoTools::readConfigVar(const std::string &var, double &value)
1172{
1173 bool found = false;
1174 for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1175 if (configVars[k] == var) {
1176 if (configValues[k].compare("PI") == 0)
1177 value = M_PI;
1178 else if (configValues[k].compare("PI/2") == 0)
1179 value = M_PI / 2;
1180 else if (configValues[k].compare("-PI/2") == 0)
1181 value = -M_PI / 2;
1182 else
1183 value = atof(configValues[k].c_str());
1184 found = true;
1185 }
1186 }
1187 if (found == false)
1188 std::cout << var << " not found in config file" << std::endl;
1189 return found;
1190}
1191
1200bool vpIoTools::readConfigVar(const std::string &var, int &value)
1201{
1202 bool found = false;
1203 for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1204 if (configVars[k] == var) {
1205 value = atoi(configValues[k].c_str());
1206 found = true;
1207 }
1208 }
1209 if (found == false)
1210 std::cout << var << " not found in config file" << std::endl;
1211 return found;
1212}
1213
1222bool vpIoTools::readConfigVar(const std::string &var, unsigned int &value)
1223{
1224 int v = 0;
1225 bool found = readConfigVar(var, v);
1226 value = static_cast<unsigned int>(v);
1227 return found;
1228}
1229
1238bool vpIoTools::readConfigVar(const std::string &var, bool &value)
1239{
1240 int v = 0;
1241 bool found = readConfigVar(var, v);
1242 value = (v != 0);
1243 return found;
1244}
1245
1254bool vpIoTools::readConfigVar(const std::string &var, vpColor &value)
1255{
1256 unsigned int v = 0;
1257 bool found = readConfigVar(var, v);
1258 value = vpColor::getColor(v);
1259 return found;
1260}
1261
1270bool vpIoTools::readConfigVar(const std::string &var, std::string &value)
1271{
1272 bool found = false;
1273 for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1274 if (configVars[k] == var) {
1275 value = configValues[k];
1276 found = true;
1277 }
1278 }
1279 if (found == false)
1280 std::cout << var << " not found in config file" << std::endl;
1281 return found;
1282}
1283
1297bool vpIoTools::readConfigVar(const std::string &var, vpArray2D<double> &value, const unsigned int &nCols,
1298 const unsigned int &nRows)
1299{
1300 bool found = false;
1301 std::string nb;
1302 for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1303 if (configVars[k] == var) {
1304 found = true;
1305 // resize or not
1306 if (nCols != 0 && nRows != 0)
1307 value.resize(nRows, nCols);
1308 size_t ind = 0, ind2;
1309 for (unsigned int i = 0; i < value.getRows(); ++i)
1310 for (unsigned int j = 0; j < value.getCols(); ++j) {
1311 ind2 = configValues[k].find(",", ind);
1312 nb = configValues[k].substr(ind, ind2 - ind);
1313 if (nb.compare("PI") == 0)
1314 value[i][j] = M_PI;
1315 else if (nb.compare("PI/2") == 0)
1316 value[i][j] = M_PI / 2;
1317 else if (nb.compare("-PI/2") == 0)
1318 value[i][j] = -M_PI / 2;
1319 else
1320 value[i][j] = atof(nb.c_str());
1321 ind = ind2 + 1;
1322 }
1323 }
1324 }
1325 if (found == false)
1326 std::cout << var << " not found in config file" << std::endl;
1327 return found;
1328}
1329
1330// construct experiment filename & path
1331
1340void vpIoTools::addNameElement(const std::string &strTrue, const bool &cond, const std::string &strFalse)
1341{
1342 if (cond)
1343 baseName += "_" + strTrue;
1344 else if (strFalse != "")
1345 baseName += "_" + strFalse;
1346}
1347
1356void vpIoTools::addNameElement(const std::string &strTrue, const double &val)
1357{
1358 // if(val != 0.)
1359 if (std::fabs(val) < std::numeric_limits<double>::epsilon()) {
1360 std::stringstream valS;
1361 valS.precision(4);
1362 valS << val;
1363 baseName += "_" + strTrue + valS.str();
1364 }
1365}
1366
1375void vpIoTools::createBaseNamePath(const bool &empty)
1376{
1377 if (vpIoTools::checkDirectory(baseDir + baseName) == false) {
1379 std::cout << "creating directory " + baseDir + baseName << std::endl;
1380 }
1381 else {
1382 if (empty) {
1383 std::cout << "emptying directory " + baseDir + baseName << std::endl;
1385 }
1386 }
1387}
1388
1395void vpIoTools::saveConfigFile(const bool &actuallySave)
1396{
1397 if (actuallySave) {
1398 std::string dest = baseDir + "/" + baseName + "_config.txt";
1399 // file copy
1401 }
1402}
1403
1418{
1419 std::string data_path;
1420 std::string file_to_test("mbt/cube.cao");
1421 std::string filename;
1422 // Test if VISP_INPUT_IMAGE_PATH env var is set
1423 try {
1424 data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH");
1425 filename = data_path + "/" + file_to_test;
1426 if (vpIoTools::checkFilename(filename))
1427 return data_path;
1428 data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/ViSP-images";
1429 filename = data_path + "/" + file_to_test;
1430 if (vpIoTools::checkFilename(filename))
1431 return data_path;
1432 data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/visp-images";
1433 filename = data_path + "/" + file_to_test;
1434 if (vpIoTools::checkFilename(filename))
1435 return data_path;
1436 }
1437 catch (...) {
1438 }
1439#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1440 // Test if visp-images-data package is installed (Ubuntu and Debian)
1441 data_path = "/usr/share/visp-images-data/ViSP-images";
1442 filename = data_path + "/" + file_to_test;
1443 if (vpIoTools::checkFilename(filename))
1444 return data_path;
1445 data_path = "/usr/share/visp-images-data/visp-images";
1446 filename = data_path + "/" + file_to_test;
1447 if (vpIoTools::checkFilename(filename))
1448 return data_path;
1449#endif
1450 data_path = "";
1451 return data_path;
1452}
1453
1483std::string vpIoTools::getFileExtension(const std::string &pathname, bool checkFile)
1484{
1485 if (checkFile && (vpIoTools::checkDirectory(pathname) || !vpIoTools::checkFilename(pathname))) {
1486 return "";
1487 }
1488
1489#if defined(_WIN32)
1490 std::string sep = "\\";
1491 std::string altsep = "/";
1492 std::string extsep = ".";
1493#else
1494 // On Unix, or on the Mac
1495 std::string sep = "/";
1496 std::string altsep = "";
1497 std::string extsep = ".";
1498#endif
1499
1500 // Python 2.7.8 module.
1501 // # Split a path in root and extension.
1502 // # The extension is everything starting at the last dot in the last
1503 // # pathname component; the root is everything before that.
1504 // # It is always true that root + ext == p.
1505 //
1506 // # Generic implementation of splitext, to be parametrized with
1507 // # the separators
1508 // def _splitext(p, sep, altsep, extsep):
1509 // """Split the extension from a pathname.
1510 //
1511 // Extension is everything from the last dot to the end, ignoring
1512 // leading dots. Returns "(root, ext)"; ext may be empty."""
1513 //
1514 // sepIndex = p.rfind(sep)
1515 // if altsep:
1516 // altsepIndex = p.rfind(altsep)
1517 // sepIndex = max(sepIndex, altsepIndex)
1518 //
1519 // dotIndex = p.rfind(extsep)
1520 // if dotIndex > sepIndex:
1521 // # skip all leading dots
1522 // filenameIndex = sepIndex + 1
1523 // while filenameIndex < dotIndex:
1524 // if p[filenameIndex] != extsep:
1525 // return p[:dotIndex], p[dotIndex:]
1526 // filenameIndex += 1
1527 //
1528 // return p, ''
1529
1530 int sepIndex = static_cast<int>(pathname.rfind(sep));
1531 if (!altsep.empty()) {
1532 int altsepIndex = static_cast<int>(pathname.rfind(altsep));
1533 sepIndex = ((std::max))(sepIndex, altsepIndex);
1534 }
1535
1536 size_t dotIndex = pathname.rfind(extsep);
1537 if (dotIndex != std::string::npos) {
1538 // The extsep character exists
1539 size_t npos = std::string::npos;
1540 if ((sepIndex != static_cast<int>(npos) && static_cast<int>(dotIndex) > sepIndex) ||
1541 sepIndex == static_cast<int>(npos)) {
1542 if (sepIndex == static_cast<int>(npos)) {
1543 sepIndex = 0;
1544 }
1545 size_t filenameIndex = static_cast<size_t>(sepIndex) + static_cast<size_t>(1);
1546
1547 while (filenameIndex < dotIndex) {
1548 if (pathname.compare(filenameIndex, 1, extsep) != 0) {
1549 return pathname.substr(dotIndex);
1550 }
1551 filenameIndex++;
1552 }
1553 }
1554 }
1555
1556 return "";
1557}
1558
1564std::string vpIoTools::getName(const std::string &pathname)
1565{
1566 if (pathname.size() > 0) {
1567 std::string convertedPathname = vpIoTools::path(pathname);
1568
1569 size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1570 if (index != std::string::npos) {
1571 return convertedPathname.substr(index + 1);
1572 }
1573
1574 return convertedPathname;
1575 }
1576
1577 return "";
1578}
1579
1586std::string vpIoTools::getNameWE(const std::string &pathname)
1587{
1588 std::string name = vpIoTools::getName(pathname);
1589 size_t found = name.find_last_of(".");
1590 std::string name_we = name.substr(0, found);
1591 return name_we;
1592}
1593
1627long vpIoTools::getIndex(const std::string &filename, const std::string &format)
1628{
1629 size_t indexBegin = format.find_last_of('%');
1630 size_t indexEnd = format.find_first_of('d', indexBegin);
1631 size_t suffixLength = format.length() - indexEnd - 1;
1632 // Extracting index
1633 if (filename.length() <= suffixLength + indexBegin) {
1634 return -1;
1635 }
1636 size_t indexLength = filename.length() - suffixLength - indexBegin;
1637 std::string indexSubstr = filename.substr(indexBegin, indexLength);
1638 std::istringstream ss(indexSubstr);
1639 long index = 0;
1640 ss >> index;
1641 if (ss.fail() || index < 0 || !ss.eof()) {
1642 return -1;
1643 }
1644
1645 // Checking that format with inserted index equals filename
1646 char nameByFormat[FILENAME_MAX];
1647 snprintf(nameByFormat, FILENAME_MAX, format.c_str(), index);
1648 if (std::string(nameByFormat) != filename) {
1649 return -1;
1650 }
1651 return index;
1652}
1653
1669std::string vpIoTools::getParent(const std::string &pathname)
1670{
1671 if (pathname.size() > 0) {
1672 std::string convertedPathname = vpIoTools::path(pathname);
1673
1674 size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1675 if (index != std::string::npos) {
1676 return convertedPathname.substr(0, index);
1677 }
1678
1679 return ".";
1680 }
1681 else {
1682 return "";
1683 }
1684}
1685
1694std::string vpIoTools::toLowerCase(const std::string &input)
1695{
1696 std::string out;
1697#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
1698 for (size_t i = 0; i < input.size(); i++) {
1699 out += std::tolower(input[i]);
1700 }
1701#else
1702 for (std::string::const_iterator it = input.cbegin(); it != input.cend(); it++) {
1703 out += std::tolower(*it);
1704 }
1705#endif
1706 return out;
1707}
1708
1717std::string vpIoTools::toUpperCase(const std::string &input)
1718{
1719 std::string out;
1720#if (VISP_CXX_STANDARD < VISP_CXX_STANDARD_11)
1721 for (size_t i = 0; i < input.size(); i++) {
1722 out += std::toupper(input[i]);
1723 }
1724#else
1725 for (std::string::const_iterator it = input.cbegin(); it != input.cend(); it++) {
1726 out += std::toupper(*it);
1727 }
1728#endif
1729 return out;
1730}
1731
1740std::string vpIoTools::getAbsolutePathname(const std::string &pathname)
1741{
1742
1743#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1744 std::string real_path_str = pathname;
1745 char *real_path = realpath(pathname.c_str(), NULL);
1746
1747 if (real_path) {
1748 real_path_str = real_path;
1749 free(real_path);
1750 }
1751 return real_path_str;
1752#elif defined(_WIN32)
1753#if (!defined(WINRT))
1754 std::string real_path_str = pathname;
1755 DWORD retval = 0;
1756 TCHAR buffer[4096] = TEXT("");
1757
1758 retval = GetFullPathName(pathname.c_str(), 4096, buffer, 0);
1759 if (retval != 0) {
1760 real_path_str = buffer;
1761 }
1762 return real_path_str;
1763#else
1765 "Cannot get absolute path of %s: not implemented on "
1766 "Universal Windows Platform",
1767 pathname.c_str()));
1768#endif
1769#endif
1770}
1771
1782std::string vpIoTools::createFilePath(const std::string &parent, const std::string &child)
1783{
1784 if (child.size() == 0 && parent.size() == 0) {
1785 return "";
1786 }
1787
1788 if (child.size() == 0) {
1789 return vpIoTools::path(parent);
1790 }
1791
1792 if (parent.size() == 0) {
1793 return vpIoTools::path(child);
1794 }
1795
1796 std::string convertedParent = vpIoTools::path(parent);
1797 std::string convertedChild = vpIoTools::path(child);
1798
1799 std::stringstream ss;
1801 std::string stringSeparator;
1802 ss >> stringSeparator;
1803
1804 std::string lastConvertedParentChar = convertedParent.substr(convertedParent.size() - 1);
1805 std::string firstConvertedChildChar = convertedChild.substr(0, 1);
1806
1807 if (lastConvertedParentChar == stringSeparator) {
1808 convertedParent = convertedParent.substr(0, convertedParent.size() - 1);
1809 }
1810
1811 if (firstConvertedChildChar == stringSeparator) {
1812 convertedChild = convertedChild.substr(1);
1813 }
1814
1815 return std::string(convertedParent + vpIoTools::separator + convertedChild);
1816}
1817
1823bool vpIoTools::isAbsolutePathname(const std::string &pathname)
1824{
1825 // # Inspired by the Python 2.7.8 module.
1826 // # Return whether a path is absolute.
1827 // # Trivial in Posix, harder on the Mac or MS-DOS.
1828 // # For DOS it is absolute if it starts with a slash or backslash (current
1829 // # volume), or if a pathname after the volume letter and colon / UNC
1830 // resource # starts with a slash or backslash.
1831 //
1832 // def isabs(s):
1833 // """Test whether a path is absolute"""
1834 // s = splitdrive(s)[1]
1835 // return s != '' and s[:1] in '/\\'
1836 std::string path = splitDrive(pathname).second;
1837 return path.size() > 0 && (path.substr(0, 1) == "/" || path.substr(0, 1) == "\\");
1838}
1839
1847bool vpIoTools::isSamePathname(const std::string &pathname1, const std::string &pathname2)
1848{
1849 // Normalize path
1850 std::string path1_normalize = vpIoTools::path(pathname1);
1851 std::string path2_normalize = vpIoTools::path(pathname2);
1852
1853 // Get absolute path
1854 path1_normalize = vpIoTools::getAbsolutePathname(path1_normalize);
1855 path2_normalize = vpIoTools::getAbsolutePathname(path2_normalize);
1856
1857 return (path1_normalize == path2_normalize);
1858}
1859
1867std::pair<std::string, std::string> vpIoTools::splitDrive(const std::string &pathname)
1868{
1869 // # Split a path in a drive specification (a drive letter followed by a
1870 // # colon) and the path specification.
1871 // # It is always true that drivespec + pathspec == p
1872 // def splitdrive(p):
1873 // """Split a pathname into drive/UNC sharepoint and relative path
1874 // specifiers. Returns a 2-tuple (drive_or_unc, path); either part may be
1875 // empty.
1876 //
1877 // If you assign
1878 // result = splitdrive(p)
1879 // It is always true that:
1880 // result[0] + result[1] == p
1881 //
1882 // If the path contained a drive letter, drive_or_unc will contain
1883 // everything up to and including the colon. e.g. splitdrive("c:/dir")
1884 // returns ("c:", "/dir")
1885 //
1886 // If the path contained a UNC path, the drive_or_unc will contain the host
1887 // name and share up to but not including the fourth directory separator
1888 // character. e.g. splitdrive("//host/computer/dir") returns
1889 // ("//host/computer", "/dir")
1890 //
1891 // Paths cannot contain both a drive letter and a UNC path.
1892 //
1893 // """
1894 // if len(p) > 1:
1895 // normp = p.replace(altsep, sep)
1896 // if (normp[0:2] == sep*2) and (normp[2] != sep):
1897 // # is a UNC path:
1898 // # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
1899 // # \\machine\mountpoint\directory\etc\...
1900 // # directory ^^^^^^^^^^^^^^^
1901 // index = normp.find(sep, 2)
1902 // if index == -1:
1903 // return '', p
1904 // index2 = normp.find(sep, index + 1)
1905 // # a UNC path can't have two slashes in a row
1906 // # (after the initial two)
1907 // if index2 == index + 1:
1908 // return '', p
1909 // if index2 == -1:
1910 // index2 = len(p)
1911 // return p[:index2], p[index2:]
1912 // if normp[1] == ':':
1913 // return p[:2], p[2:]
1914 // return '', p
1915
1916 // On Unix, the drive is always empty.
1917 // On the Mac, the drive is always empty (don't use the volume name -- it
1918 // doesn't have the same syntactic and semantic oddities as DOS drive
1919 // letters, such as there being a separate current directory per drive).
1920#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
1921 return std::pair<std::string, std::string>("", pathname);
1922#else
1923 const std::string sep = "\\";
1924 const std::string sepsep = "\\\\";
1925 const std::string altsep = "/";
1926
1927 if (pathname.size() > 1) {
1928 std::string normPathname = pathname;
1929 std::replace(normPathname.begin(), normPathname.end(), *altsep.c_str(), *sep.c_str());
1930
1931 if (normPathname.substr(0, 2) == sepsep && normPathname.substr(2, 1) != sep) {
1932 // is a UNC path:
1933 // vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
1934 // \\machine\mountpoint\directory\etc\...
1935 // directory ^^^^^^^^^^^^^^^
1936 size_t index = normPathname.find(sep, 2);
1937 if (index == std::string::npos) {
1938 return std::pair<std::string, std::string>("", pathname);
1939 }
1940
1941 size_t index2 = normPathname.find(sep, index + 1);
1942 // # a UNC path can't have two slashes in a row
1943 // # (after the initial two)
1944 if (index2 == index + 1) {
1945 return std::pair<std::string, std::string>("", pathname);
1946 }
1947
1948 if (index2 == std::string::npos) {
1949 index2 = pathname.size();
1950 }
1951
1952 return std::pair<std::string, std::string>(pathname.substr(0, index2), pathname.substr(index2));
1953 }
1954
1955 if (normPathname[1] == ':') {
1956 return std::pair<std::string, std::string>(pathname.substr(0, 2), pathname.substr(2));
1957 }
1958 }
1959
1960 return std::pair<std::string, std::string>("", pathname);
1961#endif
1962}
1963
2012std::vector<std::string> vpIoTools::splitChain(const std::string &chain, const std::string &sep)
2013{
2014 size_t startIndex = 0;
2015
2016 std::string chainToSplit = chain;
2017 std::vector<std::string> subChain;
2018 size_t sepIndex = chainToSplit.find(sep);
2019
2020 while (sepIndex != std::string::npos) {
2021 std::string sub = chainToSplit.substr(startIndex, sepIndex);
2022 if (!sub.empty())
2023 subChain.push_back(sub);
2024 chainToSplit = chainToSplit.substr(sepIndex + 1, chain.size() - 1);
2025
2026 sepIndex = chainToSplit.find(sep);
2027 }
2028 if (!chainToSplit.empty())
2029 subChain.push_back(chainToSplit);
2030
2031 return subChain;
2032}
2033
2041std::vector<std::string> vpIoTools::getDirFiles(const std::string &pathname)
2042{
2043
2044 if (!checkDirectory(pathname)) {
2045 throw(vpIoException(vpException::fatalError, "Directory %s doesn't exist'", pathname.c_str()));
2046 }
2047 std::string dirName = path(pathname);
2048
2049#if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
2050
2051 std::vector<std::string> files;
2052 struct dirent **list = NULL;
2053 int filesCount = scandir(dirName.c_str(), &list, NULL, NULL);
2054 if (filesCount == -1) {
2055 throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
2056 }
2057 for (int i = 0; i < filesCount; i++) {
2058 std::string fileName = list[i]->d_name;
2059 if (fileName != "." && fileName != "..") {
2060 files.push_back(fileName);
2061 }
2062 free(list[i]);
2063 }
2064 free(list);
2065 std::sort(files.begin(), files.end());
2066 return files;
2067
2068#elif defined(_WIN32)
2069#if (!defined(WINRT))
2070
2071 std::vector<std::string> files;
2072 std::string fileMask = dirName;
2073 fileMask.append("\\*");
2074 WIN32_FIND_DATA FindFileData;
2075 HANDLE hFind = FindFirstFile(fileMask.c_str(), &FindFileData);
2076 // Directory is empty
2077 if (HandleToLong(&hFind) == ERROR_FILE_NOT_FOUND) {
2078 return files;
2079 }
2080 if (hFind == INVALID_HANDLE_VALUE) {
2081 throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
2082 }
2083 do {
2084 std::string fileName = FindFileData.cFileName;
2085 if (fileName != "." && fileName != "..") {
2086 files.push_back(fileName);
2087 }
2088 } while (FindNextFile(hFind, &FindFileData));
2089 FindClose(hFind);
2090 std::sort(files.begin(), files.end());
2091 return files;
2092
2093#else
2095 "Cannot read files of directory %s: not implemented on "
2096 "Universal Windows Platform",
2097 dirName.c_str()));
2098#endif
2099#endif
2100}
2101
2105void vpIoTools::readBinaryValueLE(std::ifstream &file, int16_t &short_value)
2106{
2107 file.read((char *)(&short_value), sizeof(short_value));
2108
2109#ifdef VISP_BIG_ENDIAN
2110 // Swap bytes order from little endian to big endian
2111 short_value = vpEndian::swap16bits((uint16_t)short_value);
2112#endif
2113}
2114
2118void vpIoTools::readBinaryValueLE(std::ifstream &file, uint16_t &ushort_value)
2119{
2120 file.read((char *)(&ushort_value), sizeof(ushort_value));
2121
2122#ifdef VISP_BIG_ENDIAN
2123 // Swap bytes order from little endian to big endian
2124 ushort_value = vpEndian::swap16bits(ushort_value);
2125#endif
2126}
2127
2131void vpIoTools::readBinaryValueLE(std::ifstream &file, int32_t &int_value)
2132{
2133 file.read((char *)(&int_value), sizeof(int_value));
2134
2135#ifdef VISP_BIG_ENDIAN
2136 // Swap bytes order from little endian to big endian
2137 int_value = vpEndian::swap32bits((uint32_t)int_value);
2138#endif
2139}
2140
2144void vpIoTools::readBinaryValueLE(std::ifstream &file, uint32_t &uint_value)
2145{
2146 file.read((char *)(&uint_value), sizeof(uint_value));
2147
2148#ifdef VISP_BIG_ENDIAN
2149 // Swap bytes order from little endian to big endian
2150 uint_value = vpEndian::swap32bits(uint_value);
2151#endif
2152}
2153
2157void vpIoTools::readBinaryValueLE(std::ifstream &file, float &float_value)
2158{
2159 file.read((char *)(&float_value), sizeof(float_value));
2160
2161#ifdef VISP_BIG_ENDIAN
2162 // Swap bytes order from little endian to big endian
2163 float_value = vpEndian::swapFloat(float_value);
2164#endif
2165}
2166
2170void vpIoTools::readBinaryValueLE(std::ifstream &file, double &double_value)
2171{
2172 file.read((char *)(&double_value), sizeof(double_value));
2173
2174#ifdef VISP_BIG_ENDIAN
2175 // Swap bytes order from little endian to big endian
2176 double_value = vpEndian::swapDouble(double_value);
2177#endif
2178}
2179
2183void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
2184{
2185#ifdef VISP_BIG_ENDIAN
2186 // Swap bytes order to little endian
2187 uint16_t swap_short = vpEndian::swap16bits((uint16_t)short_value);
2188 file.write((char *)(&swap_short), sizeof(swap_short));
2189#else
2190 file.write((char *)(&short_value), sizeof(short_value));
2191#endif
2192}
2193
2197void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint16_t ushort_value)
2198{
2199#ifdef VISP_BIG_ENDIAN
2200 // Swap bytes order to little endian
2201 uint16_t swap_ushort = vpEndian::swap16bits(ushort_value);
2202 file.write((char *)(&swap_ushort), sizeof(swap_ushort));
2203#else
2204 file.write((char *)(&ushort_value), sizeof(ushort_value));
2205#endif
2206}
2207
2211void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int32_t int_value)
2212{
2213#ifdef VISP_BIG_ENDIAN
2214 // Swap bytes order to little endian
2215 uint32_t swap_int = vpEndian::swap32bits((uint32_t)int_value);
2216 file.write((char *)(&swap_int), sizeof(swap_int));
2217#else
2218 file.write((char *)(&int_value), sizeof(int_value));
2219#endif
2220}
2221
2225void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint32_t uint_value)
2226{
2227#ifdef VISP_BIG_ENDIAN
2228 // Swap bytes order to little endian
2229 uint32_t swap_int = vpEndian::swap32bits(uint_value);
2230 file.write((char *)(&swap_int), sizeof(swap_int));
2231#else
2232 file.write((char *)(&uint_value), sizeof(uint_value));
2233#endif
2234}
2235
2239void vpIoTools::writeBinaryValueLE(std::ofstream &file, float float_value)
2240{
2241#ifdef VISP_BIG_ENDIAN
2242 // Swap bytes order to little endian
2243 float swap_float = vpEndian::swapFloat(float_value);
2244 file.write((char *)(&swap_float), sizeof(swap_float));
2245#else
2246 file.write((char *)(&float_value), sizeof(float_value));
2247#endif
2248}
2249
2253void vpIoTools::writeBinaryValueLE(std::ofstream &file, double double_value)
2254{
2255#ifdef VISP_BIG_ENDIAN
2256 // Swap bytes order to little endian
2257 double swap_double = vpEndian::swapDouble(double_value);
2258 file.write((char *)(&swap_double), sizeof(swap_double));
2259#else
2260 file.write((char *)(&double_value), sizeof(double_value));
2261#endif
2262}
2263
2264bool vpIoTools::parseBoolean(std::string input)
2265{
2266 std::transform(input.begin(), input.end(), input.begin(), ::tolower);
2267 std::istringstream is(input);
2268 bool b;
2269 // Parse string to boolean either in the textual representation
2270 // (True/False) or in numeric representation (1/0)
2271 is >> (input.size() > 1 ? std::boolalpha : std::noboolalpha) >> b;
2272 return b;
2273}
2274
2278std::string vpIoTools::trim(std::string s) { return ltrim(rtrim(s)); }
Implementation of a generic 2D array used as base class for matrices and vectors.
Definition vpArray2D.h:131
unsigned int getCols() const
Definition vpArray2D.h:280
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition vpArray2D.h:305
unsigned int getRows() const
Definition vpArray2D.h:290
Class to define RGB colors available for display functionalities.
Definition vpColor.h:152
static vpColor getColor(const unsigned int &i)
Definition vpColor.h:307
error that can be emitted by ViSP classes.
Definition vpException.h:59
@ notImplementedError
Not implemented.
Definition vpException.h:81
@ fatalError
Fatal error.
Definition vpException.h:84
Error that can be emitted by the vpIoTools class and its derivatives.
@ invalidDirectoryName
Directory name is invalid.
@ cantCreateDirectory
Unable to create a directory.
@ cantGetenv
Cannot get environment variable value.
static void getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
static std::string getViSPImagesDataPath()
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
static std::vector< std::string > configVars
Definition vpIoTools.h:252
static std::string path(const std::string &pathname)
static std::string getAbsolutePathname(const std::string &pathname)
static std::string toLowerCase(const std::string &input)
Return a lower-case version of the string input . Numbers and special characters stay the same.
static bool checkFilename(const std::string &filename)
static bool readConfigVar(const std::string &var, float &value)
static void setBaseName(const std::string &s)
static std::pair< std::string, std::string > splitDrive(const std::string &pathname)
static bool isSamePathname(const std::string &pathname1, const std::string &pathname2)
static std::string getTempPath()
static bool isAbsolutePathname(const std::string &pathname)
static void setBaseDir(const std::string &dir)
static std::string baseDir
Definition vpIoTools.h:250
static bool loadConfigFile(const std::string &confFile)
static bool copy(const std::string &src, const std::string &dst)
static std::string trim(std::string s)
static void readBinaryValueLE(std::ifstream &file, int16_t &short_value)
static void saveConfigFile(const bool &actuallySave=true)
static bool checkDirectory(const std::string &dirname)
static bool rename(const std::string &oldfilename, const std::string &newfilename)
static bool parseBoolean(std::string input)
static long getIndex(const std::string &filename, const std::string &format)
static std::string getUserName()
static std::string getFullName()
static void addNameElement(const std::string &strTrue, const bool &cond=true, const std::string &strFalse="")
static std::string createFilePath(const std::string &parent, const std::string &child)
static std::string getenv(const std::string &env)
static const std::string & getBuildInformation()
static std::string getBaseName()
static std::string getFileExtension(const std::string &pathname, bool checkFile=false)
static std::string baseName
Definition vpIoTools.h:249
static void createBaseNamePath(const bool &empty=false)
static std::vector< std::string > getDirFiles(const std::string &dirname)
static void makeDirectory(const std::string &dirname)
static std::string configFile
Definition vpIoTools.h:251
static std::vector< std::string > configValues
Definition vpIoTools.h:253
static void writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
static bool remove(const std::string &filename)
static std::string getNameWE(const std::string &pathname)
static std::string makeTempDirectory(const std::string &dirname)
static bool checkFifo(const std::string &filename)
static std::string getParent(const std::string &pathname)
static std::string getName(const std::string &pathname)
static std::string toUpperCase(const std::string &input)
Return a upper-case version of the string input . Numbers and special characters stay the same.
static const char separator
Definition vpIoTools.h:181
static void makeFifo(const std::string &dirname)
static Type minimum(const Type &a, const Type &b)
Definition vpMath.h:180
VISP_EXPORT float swapFloat(float f)
Definition vpEndian.cpp:65
VISP_EXPORT uint32_t swap32bits(uint32_t val)
Definition vpEndian.cpp:55
VISP_EXPORT double swapDouble(double d)
Definition vpEndian.cpp:84
VISP_EXPORT uint16_t swap16bits(uint16_t val)
Definition vpEndian.cpp:49