Visual Servoing Platform  version 3.6.1 under development (2024-02-13)
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 
98 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
99 #define VP_STAT stat
100 #elif defined(_WIN32) && defined(__MINGW32__)
101 #define VP_STAT stat
102 #elif defined(_WIN32)
103 #define VP_STAT _stat
104 #else
105 #define VP_STAT stat
106 #endif
107 
108 #if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
109 #define USE_ZLIB_API 0
110 
111 #if !USE_ZLIB_API
112 // See: https://github.com/BinomialLLC/basis_universal/blob/master/encoder/basisu_miniz.h
113 // Apache License, Version 2.0
114 #include "basisu_miniz.h"
115 
116 using namespace buminiz;
117 #else
118 #include <zlib.h>
119 #endif
120 
121 // To avoid warnings such as: warning: unused variable ‘littleEndian’ [-Wunused-variable]
122 #define _unused(x) ((void)(x)) // see: https://stackoverflow.com/a/777359
123 
124 // Copyright (C) 2011 Carl Rogers
125 // Released under MIT License
126 // license available in LICENSE file, or at http://www.opensource.org/licenses/mit-license.php
127 
128 #include <regex>
129 
131 {
132  int x = 1;
133  return (((char *)&x)[0]) ? '<' : '>';
134 }
135 
136 char visp::cnpy::map_type(const std::type_info &t)
137 {
138  if (t == typeid(float)) return 'f';
139  if (t == typeid(double)) return 'f';
140  if (t == typeid(long double)) return 'f';
141 
142  if (t == typeid(int)) return 'i';
143  if (t == typeid(char)) return 'i';
144  if (t == typeid(short)) return 'i';
145  if (t == typeid(long)) return 'i';
146  if (t == typeid(long long)) return 'i';
147 
148  if (t == typeid(unsigned char)) return 'u';
149  if (t == typeid(unsigned short)) return 'u';
150  if (t == typeid(unsigned long)) return 'u';
151  if (t == typeid(unsigned long long)) return 'u';
152  if (t == typeid(unsigned int)) return 'u';
153 
154  if (t == typeid(bool)) return 'b';
155 
156  if (t == typeid(std::complex<float>)) return 'c';
157  if (t == typeid(std::complex<double>)) return 'c';
158  if (t == typeid(std::complex<long double>)) return 'c';
159 
160  else return '?';
161 }
162 
163 void visp::cnpy::parse_npy_header(unsigned char *buffer, size_t &word_size, std::vector<size_t> &shape, bool &fortran_order)
164 {
165  //std::string magic_string(buffer,6);
166  // uint8_t major_version = *reinterpret_cast<uint8_t*>(buffer+6);
167  // uint8_t minor_version = *reinterpret_cast<uint8_t*>(buffer+7);
168  uint16_t header_len = *reinterpret_cast<uint16_t *>(buffer+8);
169  std::string header(reinterpret_cast<char *>(buffer+9), header_len);
170 
171  //fortran order
172  size_t loc1 = header.find("fortran_order")+16;
173  fortran_order = (header.substr(loc1, 4) == "True" ? true : false);
174 
175  //shape
176  loc1 = header.find("(");
177  size_t loc2 = header.find(")");
178 
179  std::regex num_regex("[0-9][0-9]*");
180  std::smatch sm;
181  shape.clear();
182 
183  std::string str_shape = header.substr(loc1+1, loc2-loc1-1);
184  while (std::regex_search(str_shape, sm, num_regex)) {
185  shape.push_back(std::stoi(sm[0].str()));
186  str_shape = sm.suffix().str();
187  }
188 
189  //endian, word size, data type
190  //byte order code | stands for not applicable.
191  //not sure when this applies except for byte array
192  loc1 = header.find("descr")+9;
193  bool littleEndian = (header[loc1] == '<' || header[loc1] == '|' ? true : false);
194  _unused(littleEndian); assert(littleEndian);
195 
196  //char type = header[loc1+1];
197  //assert(type == map_type(T));
198 
199  std::string str_ws = header.substr(loc1+2);
200  loc2 = str_ws.find("'");
201  word_size = atoi(str_ws.substr(0, loc2).c_str());
202 }
203 
204 void visp::cnpy::parse_npy_header(FILE *fp, size_t &word_size, std::vector<size_t> &shape, bool &fortran_order)
205 {
206  char buffer[256];
207  size_t res = fread(buffer, sizeof(char), 11, fp);
208  if (res != 11)
209  throw std::runtime_error("parse_npy_header: failed fread");
210  std::string header = fgets(buffer, 256, fp);
211  assert(header[header.size()-1] == '\n');
212 
213  size_t loc1, loc2;
214 
215  //fortran order
216  loc1 = header.find("fortran_order");
217  if (loc1 == std::string::npos)
218  throw std::runtime_error("parse_npy_header: failed to find header keyword: 'fortran_order'");
219  loc1 += 16;
220  fortran_order = (header.substr(loc1, 4) == "True" ? true : false);
221 
222  //shape
223  loc1 = header.find("(");
224  loc2 = header.find(")");
225  if (loc1 == std::string::npos || loc2 == std::string::npos)
226  throw std::runtime_error("parse_npy_header: failed to find header keyword: '(' or ')'");
227 
228  std::regex num_regex("[0-9][0-9]*");
229  std::smatch sm;
230  shape.clear();
231 
232  std::string str_shape = header.substr(loc1+1, loc2-loc1-1);
233  while (std::regex_search(str_shape, sm, num_regex)) {
234  shape.push_back(std::stoi(sm[0].str()));
235  str_shape = sm.suffix().str();
236  }
237 
238  //endian, word size, data type
239  //byte order code | stands for not applicable.
240  //not sure when this applies except for byte array
241  loc1 = header.find("descr");
242  if (loc1 == std::string::npos)
243  throw std::runtime_error("parse_npy_header: failed to find header keyword: 'descr'");
244  loc1 += 9;
245  bool littleEndian = (header[loc1] == '<' || header[loc1] == '|' ? true : false);
246  _unused(littleEndian); assert(littleEndian);
247 
248  //char type = header[loc1+1];
249  //assert(type == map_type(T));
250 
251  std::string str_ws = header.substr(loc1+2);
252  loc2 = str_ws.find("'");
253  word_size = atoi(str_ws.substr(0, loc2).c_str());
254 }
255 
256 void visp::cnpy::parse_zip_footer(FILE *fp, uint16_t &nrecs, size_t &global_header_size, size_t &global_header_offset)
257 {
258  std::vector<char> footer(22);
259  fseek(fp, -22, SEEK_END);
260  size_t res = fread(&footer[0], sizeof(char), 22, fp);
261  if (res != 22)
262  throw std::runtime_error("parse_zip_footer: failed fread");
263 
264  uint16_t disk_no, disk_start, nrecs_on_disk, comment_len;
265  disk_no = *(uint16_t *)&footer[4];
266  disk_start = *(uint16_t *)&footer[6];
267  nrecs_on_disk = *(uint16_t *)&footer[8];
268  nrecs = *(uint16_t *)&footer[10];
269  global_header_size = *(uint32_t *)&footer[12];
270  global_header_offset = *(uint32_t *)&footer[16];
271  comment_len = *(uint16_t *)&footer[20];
272 
273  _unused(disk_no); assert(disk_no == 0);
274  _unused(disk_start); assert(disk_start == 0);
275  _unused(nrecs_on_disk); assert(nrecs_on_disk == nrecs);
276  _unused(comment_len); assert(comment_len == 0);
277 }
278 
279 visp::cnpy::NpyArray load_the_npy_file(FILE *fp)
280 {
281  std::vector<size_t> shape;
282  size_t word_size;
283  bool fortran_order;
284  visp::cnpy::parse_npy_header(fp, word_size, shape, fortran_order);
285 
286  visp::cnpy::NpyArray arr(shape, word_size, fortran_order);
287  size_t nread = fread(arr.data<char>(), 1, arr.num_bytes(), fp);
288  if (nread != arr.num_bytes())
289  throw std::runtime_error("load_the_npy_file: failed fread");
290  return arr;
291 }
292 
293 visp::cnpy::NpyArray load_the_npz_array(FILE *fp, uint32_t compr_bytes, uint32_t uncompr_bytes)
294 {
295  std::vector<unsigned char> buffer_compr(compr_bytes);
296  std::vector<unsigned char> buffer_uncompr(uncompr_bytes);
297  size_t nread = fread(&buffer_compr[0], 1, compr_bytes, fp);
298  if (nread != compr_bytes)
299  throw std::runtime_error("load_the_npy_file: failed fread");
300 
301  z_stream d_stream;
302 
303  d_stream.zalloc = Z_NULL;
304  d_stream.zfree = Z_NULL;
305  d_stream.opaque = Z_NULL;
306  d_stream.avail_in = 0;
307  d_stream.next_in = Z_NULL;
308  int err = inflateInit2(&d_stream, -MAX_WBITS);
309  _unused(err); assert(err == 0);
310 
311  d_stream.avail_in = compr_bytes;
312  d_stream.next_in = &buffer_compr[0];
313  d_stream.avail_out = uncompr_bytes;
314  d_stream.next_out = &buffer_uncompr[0];
315 
316  err = inflate(&d_stream, Z_FINISH);
317  _unused(err); assert(err == 0);
318  err = inflateEnd(&d_stream);
319  _unused(err); assert(err == 0);
320 
321  std::vector<size_t> shape;
322  size_t word_size;
323  bool fortran_order;
324  visp::cnpy::parse_npy_header(&buffer_uncompr[0], word_size, shape, fortran_order);
325 
326  visp::cnpy::NpyArray array(shape, word_size, fortran_order);
327 
328  size_t offset = uncompr_bytes - array.num_bytes();
329  memcpy(array.data<unsigned char>(), &buffer_uncompr[0]+offset, array.num_bytes());
330 
331  return array;
332 }
333 
343 {
344  FILE *fp = fopen(fname.c_str(), "rb");
345 
346  if (!fp) {
347  throw std::runtime_error("npz_load: Error! Unable to open file "+fname+"!");
348  }
349 
350  visp::cnpy::npz_t arrays;
351 
352  while (1) {
353  std::vector<char> local_header(30);
354  size_t headerres = fread(&local_header[0], sizeof(char), 30, fp);
355  if (headerres != 30)
356  throw std::runtime_error("npz_load: failed fread");
357 
358  //if we've reached the global header, stop reading
359  if (local_header[2] != 0x03 || local_header[3] != 0x04) break;
360 
361  //read in the variable name
362  uint16_t name_len = *(uint16_t *)&local_header[26];
363  std::string varname(name_len, ' ');
364  size_t vname_res = fread(&varname[0], sizeof(char), name_len, fp);
365  if (vname_res != name_len)
366  throw std::runtime_error("npz_load: failed fread");
367 
368  //erase the lagging .npy
369  varname.erase(varname.end()-4, varname.end());
370 
371  //read in the extra field
372  uint16_t extra_field_len = *(uint16_t *)&local_header[28];
373  if (extra_field_len > 0) {
374  std::vector<char> buff(extra_field_len);
375  size_t efield_res = fread(&buff[0], sizeof(char), extra_field_len, fp);
376  if (efield_res != extra_field_len)
377  throw std::runtime_error("npz_load: failed fread");
378  }
379 
380  uint16_t compr_method = *reinterpret_cast<uint16_t *>(&local_header[0]+8);
381  uint32_t compr_bytes = *reinterpret_cast<uint32_t *>(&local_header[0]+18);
382  uint32_t uncompr_bytes = *reinterpret_cast<uint32_t *>(&local_header[0]+22);
383 
384  if (compr_method == 0) { arrays[varname] = load_the_npy_file(fp); }
385  else { arrays[varname] = load_the_npz_array(fp, compr_bytes, uncompr_bytes); }
386  }
387 
388  fclose(fp);
389  return arrays;
390 }
391 
401 visp::cnpy::NpyArray visp::cnpy::npz_load(std::string fname, std::string varname)
402 {
403  FILE *fp = fopen(fname.c_str(), "rb");
404 
405  if (!fp) throw std::runtime_error("npz_load: Unable to open file "+fname);
406 
407  while (1) {
408  std::vector<char> local_header(30);
409  size_t header_res = fread(&local_header[0], sizeof(char), 30, fp);
410  if (header_res != 30)
411  throw std::runtime_error("npz_load: failed fread");
412 
413  //if we've reached the global header, stop reading
414  if (local_header[2] != 0x03 || local_header[3] != 0x04) break;
415 
416  //read in the variable name
417  uint16_t name_len = *(uint16_t *)&local_header[26];
418  std::string vname(name_len, ' ');
419  size_t vname_res = fread(&vname[0], sizeof(char), name_len, fp);
420  if (vname_res != name_len)
421  throw std::runtime_error("npz_load: failed fread");
422  vname.erase(vname.end()-4, vname.end()); //erase the lagging .npy
423 
424  //read in the extra field
425  uint16_t extra_field_len = *(uint16_t *)&local_header[28];
426  fseek(fp, extra_field_len, SEEK_CUR); //skip past the extra field
427 
428  uint16_t compr_method = *reinterpret_cast<uint16_t *>(&local_header[0]+8);
429  uint32_t compr_bytes = *reinterpret_cast<uint32_t *>(&local_header[0]+18);
430  uint32_t uncompr_bytes = *reinterpret_cast<uint32_t *>(&local_header[0]+22);
431 
432  if (vname == varname) {
433  NpyArray array = (compr_method == 0) ? load_the_npy_file(fp) : load_the_npz_array(fp, compr_bytes, uncompr_bytes);
434  fclose(fp);
435  return array;
436  }
437  else {
438  //skip past the data
439  uint32_t size = *(uint32_t *)&local_header[22];
440  fseek(fp, size, SEEK_CUR);
441  }
442  }
443 
444  fclose(fp);
445 
446  //if we get here, we haven't found the variable in the file
447  throw std::runtime_error("npz_load: Variable name "+varname+" not found in "+fname);
448 }
449 
459 {
460 
461  FILE *fp = fopen(fname.c_str(), "rb");
462 
463  if (!fp) throw std::runtime_error("npy_load: Unable to open file "+fname);
464 
465  NpyArray arr = load_the_npy_file(fp);
466 
467  fclose(fp);
468  return arr;
469 }
470 
471 #endif
472 
473 std::string vpIoTools::baseName = "";
474 std::string vpIoTools::baseDir = "";
475 std::string vpIoTools::configFile = "";
476 std::vector<std::string> vpIoTools::configVars = std::vector<std::string>();
477 std::vector<std::string> vpIoTools::configValues = std::vector<std::string>();
478 
479 const char vpIoTools::separator =
480 #if defined(_WIN32)
481 '\\';
482 #else
483 '/';
484 #endif
485 
486 namespace
487 {
488 // The following code is not working on iOS since wordexp() is not available
489 // The function is not used on Android
490 #if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
491 #if (TARGET_OS_IOS == 0) && !defined(__ANDROID__)
492 void replaceAll(std::string &str, const std::string &search, const std::string &replace)
493 {
494  size_t start_pos = 0;
495  while ((start_pos = str.find(search, start_pos)) != std::string::npos) {
496  str.replace(start_pos, search.length(), replace);
497  start_pos += replace.length(); // Handles case where 'replace' is a
498  // substring of 'search'
499  }
500 }
501 #endif
502 #endif
503 
504 std::string &ltrim(std::string &s)
505 {
506 #if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
507  s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](int c) { return !std::isspace(c); }));
508 #else
509  s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
510 #endif
511  return s;
512 }
513 
514 std::string &rtrim(std::string &s)
515 {
516 #if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
517  s.erase(std::find_if(s.rbegin(), s.rend(), [](int c) { return !std::isspace(c); }).base(), s.end());
518 #else
519  s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
520 #endif
521  return s;
522 }
523 } // namespace
524 
528 const std::string &vpIoTools::getBuildInformation()
529 {
530  static std::string build_info =
531 #include "version_string.inc"
532  ;
533  return build_info;
534 }
535 
588 {
589 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
590  std::string username;
591  vpIoTools::getUserName(username);
592  return "/tmp/" + username;
593 #elif defined(_WIN32) && !defined(WINRT)
594  // https://docs.microsoft.com/en-us/windows/win32/fileio/creating-and-using-a-temporary-file
595  // Gets the temp path env string (no guarantee it's a valid path).
596  TCHAR lpTempPathBuffer[MAX_PATH];
597  DWORD dwRetVal = GetTempPath(MAX_PATH /* length of the buffer */, lpTempPathBuffer /* buffer for path */);
598  if (dwRetVal > MAX_PATH || (dwRetVal == 0)) {
599  throw vpIoException(vpIoException::cantGetenv, "Error with GetTempPath() call!");
600  }
601  std::string temp_path(lpTempPathBuffer);
602  if (!temp_path.empty()) {
603  if (temp_path.back() == '\\') {
604  temp_path.resize(temp_path.size() - 1);
605  }
606  }
607  else {
608  temp_path = "C:\temp";
609  try {
610  vpIoTools::makeDirectory(temp_path);
611  }
612  catch (...) {
613  throw(vpException(vpException::fatalError, "Cannot set temp path to %s", temp_path.c_str()));
614  }
615  }
616  return temp_path;
617 #else
618  throw vpIoException(vpException::fatalError, "Not implemented on this platform!");
619 #endif
620 }
621 
627 void vpIoTools::setBaseName(const std::string &s) { baseName = s; }
628 
634 void vpIoTools::setBaseDir(const std::string &dir) { baseDir = dir + "/"; }
635 
641 std::string vpIoTools::getBaseName() { return baseName; }
642 
648 std::string vpIoTools::getFullName() { return baseDir + baseName; }
649 
663 void vpIoTools::getUserName(std::string &username)
664 {
665  // With MinGW, UNIX and _WIN32 are defined
666 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
667  // Get the user name.
668  char *_username = ::getenv("LOGNAME");
669  if (!_username) {
670  username = "unknown";
671  }
672  else {
673  username = _username;
674  }
675 #elif defined(_WIN32)
676 #if (!defined(WINRT))
677  unsigned int info_buffer_size = 1024;
678  TCHAR *infoBuf = new TCHAR[info_buffer_size];
679  DWORD bufCharCount = (DWORD)info_buffer_size;
680  // Get the user name.
681  if (!GetUserName(infoBuf, &bufCharCount)) {
682  username = "unknown";
683  }
684  else {
685  username = infoBuf;
686  }
687  delete[] infoBuf;
688 #else
689  // Universal platform
690  username = "unknown";
691 #endif
692 #else
693  username = "unknown";
694 #endif
695 }
696 
712 {
713  std::string username;
714  getUserName(username);
715  return username;
716 }
717 
748 std::string vpIoTools::getenv(const std::string &env)
749 {
750 #if defined(_WIN32) && defined(WINRT)
751  throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value: not "
752  "implemented on Universal Windows Platform"));
753 #else
754  std::string value;
755  // Get the environment variable value.
756  char *_value = ::getenv(env.c_str());
757  if (!_value) {
758  throw(vpIoException(vpIoException::cantGetenv, "Cannot get the environment variable value"));
759  }
760  value = _value;
761 
762  return value;
763 #endif
764 }
765 
775 void vpIoTools::getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
776 {
777  if (version.size() == 0) {
778  major = 0;
779  minor = 0;
780  patch = 0;
781  }
782  else {
783  size_t major_pos = version.find('.');
784  std::string major_str = version.substr(0, major_pos);
785  major = static_cast<unsigned>(atoi(major_str.c_str()));
786 
787  if (major_pos != std::string::npos) {
788  size_t minor_pos = version.find('.', major_pos + 1);
789  std::string minor_str = version.substr(major_pos + 1, (minor_pos - (major_pos + 1)));
790  minor = static_cast<unsigned>(atoi(minor_str.c_str()));
791 
792  if (minor_pos != std::string::npos) {
793  std::string patch_str = version.substr(minor_pos + 1);
794  patch = static_cast<unsigned>(atoi(patch_str.c_str()));
795  }
796  else {
797  patch = 0;
798  }
799  }
800  else {
801  minor = 0;
802  patch = 0;
803  }
804  }
805 }
806 
818 bool vpIoTools::checkDirectory(const std::string &dirname)
819 {
820 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
821  struct stat stbuf;
822 #elif defined(_WIN32) && defined(__MINGW32__)
823  struct stat stbuf;
824 #elif defined(_WIN32)
825  struct _stat stbuf;
826 #endif
827 
828  if (dirname.empty()) {
829  return false;
830  }
831 
832  std::string _dirname = path(dirname);
833 
834  if (VP_STAT(_dirname.c_str(), &stbuf) != 0) {
835  std::cout << "DEBUG 1 _dirname: " << _dirname << " is not a dir" << std::endl;
836  // Test adding the separator if not already present
837  if (_dirname.at(_dirname.size() - 1) != separator) {
838  std::cout << "DEBUG 2 test if _dirname + separator: " << _dirname + separator << " is a dir ?" << std::endl;
839  if (VP_STAT((_dirname + separator).c_str(), &stbuf) != 0) {
840  std::cout << "DEBUG 2 _dirname + separator: " << _dirname + separator << " is not a dir" << std::endl;
841  return false;
842  }
843  }
844  // Test removing the separator if already present
845  if (_dirname.at(_dirname.size() - 1) == separator) {
846  std::cout << "DEBUG 2 test if _dirname - separator: " << _dirname.substr(0, _dirname.size() - 1) << " is a dir ?" << std::endl;
847  if (VP_STAT((_dirname.substr(0, _dirname.size() - 1)).c_str(), &stbuf) != 0) {
848  std::cout << "DEBUG 3 _dirname - separator: " << _dirname.substr(0, _dirname.size() - 1) << " is not a dir" << std::endl;
849  return false;
850  }
851  }
852  }
853 
854 #if defined(_WIN32) || (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
855  if ((stbuf.st_mode & S_IFDIR) == 0)
856 #endif
857  {
858  return false;
859  }
860 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
861  if ((stbuf.st_mode & S_IWUSR) == 0)
862 #elif defined(_WIN32)
863  if ((stbuf.st_mode & S_IWRITE) == 0)
864 #endif
865  {
866  return false;
867  }
868  return true;
869 }
870 
883 bool vpIoTools::checkFifo(const std::string &fifofilename)
884 {
885 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
886  struct stat stbuf;
887 
888  std::string _filename = path(fifofilename);
889  if (stat(_filename.c_str(), &stbuf) != 0) {
890  return false;
891  }
892  if ((stbuf.st_mode & S_IFIFO) == 0) {
893  return false;
894  }
895  if ((stbuf.st_mode & S_IRUSR) == 0)
896 
897  {
898  return false;
899  }
900  return true;
901 #elif defined(_WIN32)
902  (void)fifofilename;
903  throw(vpIoException(vpIoException::notImplementedError, "Fifo files are not supported on Windows platforms."));
904 #endif
905 }
906 
907 #ifndef DOXYGEN_SHOULD_SKIP_THIS
908 int vpIoTools::mkdir_p(const std::string &path, int mode)
909 {
910  errno = 0;
911  if (path.size() > PATH_MAX) {
912  errno = ENAMETOOLONG;
913  return -1;
914  }
915 
916  // Iterate over the string
917  std::string _path = path;
918  std::string _sub_path;
919  for (size_t pos = 0; (pos = _path.find(vpIoTools::separator)) != std::string::npos;) {
920  _sub_path += _path.substr(0, pos + 1);
921  // Continue if sub_path = separator
922  if (pos == 0) {
923  _path.erase(0, pos + 1);
924  continue;
925  }
926 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
927  if (mkdir(_sub_path.c_str(), static_cast<mode_t>(mode)) != 0)
928 #elif defined(_WIN32)
929  (void)mode; // var not used
930  if (!checkDirectory(_sub_path) && _mkdir(_sub_path.c_str()) != 0)
931 #endif
932  {
933  if (errno != EEXIST) {
934  return -1;
935  }
936  }
937  _path.erase(0, pos + 1);
938  }
939 
940  if (!_path.empty()) {
941  _sub_path += _path;
942 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
943  if (mkdir(_sub_path.c_str(), static_cast<mode_t>(mode)) != 0)
944 #elif defined(_WIN32)
945 
946  if (_mkdir(_sub_path.c_str()) != 0)
947 #endif
948  {
949  if (errno != EEXIST) {
950  return -1;
951  }
952  }
953  }
954 
955  return 0;
956 }
957 
958 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
959 
972 void vpIoTools::makeDirectory(const std::string &dirname)
973 {
974 #if ((!defined(__unix__) && !defined(__unix) && (!defined(__APPLE__) || !defined(__MACH__)))) && !defined(_WIN32)
975  std::cerr << "Unsupported platform for vpIoTools::makeDirectory()!" << std::endl;
976  return;
977 #endif
978 
979 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
980  struct stat stbuf;
981 #elif defined(_WIN32) && defined(__MINGW32__)
982  struct stat stbuf;
983 #elif defined(_WIN32)
984  struct _stat stbuf;
985 #endif
986 
987  if (dirname.empty()) {
988  throw(vpIoException(vpIoException::invalidDirectoryName, "invalid directory name"));
989  }
990 
991  std::string _dirname = path(dirname);
992 
993 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
994  if (stat(_dirname.c_str(), &stbuf) != 0)
995 #elif defined(_WIN32) && defined(__MINGW32__)
996  if (stat(_dirname.c_str(), &stbuf) != 0)
997 #elif defined(_WIN32)
998  if (_stat(_dirname.c_str(), &stbuf) != 0)
999 #endif
1000  {
1001  if (vpIoTools::mkdir_p(_dirname, 0755) != 0) {
1002  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'", dirname.c_str()));
1003  }
1004  }
1005 
1006  if (checkDirectory(dirname) == false) {
1007  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'", dirname.c_str()));
1008  }
1009 }
1010 
1023 void vpIoTools::makeFifo(const std::string &fifoname)
1024 {
1025 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1026 
1027  // If dirname is a directory, we throw an error
1028  if (vpIoTools::checkDirectory(fifoname)) {
1030  "Unable to create fifo file. '%s' is an existing directory.", fifoname.c_str()));
1031  }
1032 
1033  // If dirname refers to an already existing file, we throw an error
1034  else if (vpIoTools::checkFilename(fifoname)) {
1035  throw(vpIoException(vpIoException::invalidDirectoryName, "Unable to create fifo file '%s'. File already exists.",
1036  fifoname.c_str()));
1037  // If dirname refers to an already existing fifo, we throw an error
1038  }
1039  else if (vpIoTools::checkFifo(fifoname)) {
1040  throw(vpIoException(vpIoException::invalidDirectoryName, "Unable to create fifo file '%s'. Fifo already exists.",
1041  fifoname.c_str()));
1042  }
1043 
1044  else if (mkfifo(fifoname.c_str(), 0666) < 0) {
1045  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create fifo file '%s'.", fifoname.c_str()));
1046  }
1047 #elif defined(_WIN32)
1048  (void)fifoname;
1049  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create fifo on Windows platforms."));
1050 #endif
1051 }
1052 
1053 #if defined(_WIN32) && !defined(WINRT)
1054 std::string getUuid()
1055 {
1056  UUID uuid;
1057  if (UuidCreate(&uuid) != RPC_S_OK) {
1058  throw(vpIoException(vpIoException::fatalError, "UuidCreate() failed!"));
1059  }
1060 
1061  RPC_CSTR stringUuid;
1062  if (UuidToString(&uuid, &stringUuid) != RPC_S_OK) {
1063  throw(vpIoException(vpIoException::fatalError, "UuidToString() failed!"));
1064  }
1065 
1066  return reinterpret_cast<char *>(stringUuid);
1067 }
1068 #endif
1069 
1126 std::string vpIoTools::makeTempDirectory(const std::string &dirname)
1127 {
1128 #if defined(WINRT) || !defined(_WIN32) && !(defined(__unix__) || defined(__unix) || \
1129  (defined(__APPLE__) && defined(__MACH__))) // not UNIX and not Windows
1130  throw(vpIoException(vpIoException::cantCreateDirectory, "makeTempDirectory() is not supported on this platform!"));
1131 #endif
1132 
1133  std::string dirname_cpy = std::string(dirname);
1134  std::string correctEnding = "XXXXXX";
1135 
1136  // If dirname is an unexisting directory, it should end with XXXXXX in order to create a temp directory
1137  if (!vpIoTools::checkDirectory(dirname_cpy)) {
1138 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1139  // Check if dirname ends with XXXXXX
1140  if (dirname_cpy.rfind(correctEnding) == std::string::npos) {
1141  if (dirname_cpy.at(dirname_cpy.length() - 1) != '/') {
1142  dirname_cpy = dirname_cpy + "/";
1143  }
1144  try {
1145  vpIoTools::makeDirectory(dirname_cpy);
1146  }
1147  catch (const vpException &e) {
1148  throw e;
1149  }
1150 
1151  dirname_cpy = dirname_cpy + "XXXXXX";
1152  }
1153 
1154 #elif defined(_WIN32) && !defined(WINRT)
1155  // Remove XXXXXX
1156  dirname_cpy = dirname_cpy.substr(0, dirname_cpy.rfind(correctEnding));
1157  // Append UUID
1158  dirname_cpy = dirname_cpy + getUuid();
1159 #endif
1160 
1161  }
1162  else {
1163  // If dirname is an existing directory, we create a temp directory inside
1164 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1165  if (dirname_cpy.at(dirname_cpy.length() - 1) != '/') {
1166  dirname_cpy = dirname_cpy + "/";
1167  }
1168  dirname_cpy = dirname_cpy + "XXXXXX";
1169 #elif defined(_WIN32) && !defined(WINRT)
1170  dirname_cpy = createFilePath(dirname_cpy, getUuid());
1171 #endif
1172  }
1173 
1174 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1175  char *dirname_char = new char[dirname_cpy.length() + 1];
1176  strcpy(dirname_char, dirname_cpy.c_str());
1177 
1178  char *computedDirname = mkdtemp(dirname_char);
1179 
1180  if (!computedDirname) {
1181  delete[] dirname_char;
1182  throw(vpIoException(vpIoException::cantCreateDirectory, "Unable to create directory '%s'.", dirname_cpy.c_str()));
1183  }
1184 
1185  std::string res(computedDirname);
1186  delete[] dirname_char;
1187  return res;
1188 #elif defined(_WIN32) && !defined(WINRT)
1189  makeDirectory(dirname_cpy);
1190  return dirname_cpy;
1191 #endif
1192 }
1193 
1204 bool vpIoTools::checkFilename(const std::string &filename)
1205 {
1206 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1207  struct stat stbuf;
1208 #elif defined(_WIN32)
1209  struct _stat stbuf;
1210 #endif
1211 
1212  if (filename.empty()) {
1213  return false;
1214  }
1215 
1216  std::string _filename = path(filename);
1217 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1218  if (stat(_filename.c_str(), &stbuf) != 0)
1219 #elif defined(_WIN32)
1220  if (_stat(_filename.c_str(), &stbuf) != 0)
1221 #endif
1222  {
1223  return false;
1224  }
1225  if ((stbuf.st_mode & S_IFREG) == 0) {
1226  return false;
1227  }
1228 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1229  if ((stbuf.st_mode & S_IRUSR) == 0)
1230 #elif defined(_WIN32)
1231  if ((stbuf.st_mode & S_IREAD) == 0)
1232 #endif
1233  {
1234  return false;
1235  }
1236  return true;
1237 }
1238 
1246 bool vpIoTools::copy(const std::string &src, const std::string &dst)
1247 {
1248  // Check if we have to consider a file or a directory
1249  if (vpIoTools::checkFilename(src)) {
1250  // std::cout << "copy file: " << src << " in " << dst << std::endl;
1251 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1252 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
1253  // wordexp() is not available
1254  std::stringstream cmd;
1255  cmd << "cp -p ";
1256  cmd << src;
1257  cmd << " ";
1258  cmd << dst;
1259  int ret = system(cmd.str().c_str());
1260  if (ret) {
1261  }; // to avoid a warning
1262  // std::cout << cmd << " return value: " << ret << std::endl;
1263  return true;
1264 #else
1265  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src.c_str(),
1266  dst.c_str()));
1267 #endif
1268 #elif defined(_WIN32)
1269 #if (!defined(WINRT))
1270  std::stringstream cmd;
1271  cmd << "copy ";
1272  cmd << vpIoTools::path(src);
1273  cmd << " ";
1274  cmd << vpIoTools::path(dst);
1275  int ret = system(cmd.str().c_str());
1276  if (ret) {
1277  }; // to avoid a warning
1278  // std::cout << cmd << " return value: " << ret << std::endl;
1279  return true;
1280 #else
1281  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
1282  src.c_str(), dst.c_str()));
1283 #endif
1284 #endif
1285  }
1286  else if (vpIoTools::checkDirectory(src)) {
1287  // std::cout << "copy directory: " << src << " in " << dst << std::endl;
1288 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1289 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
1290  // wordexp() is not available
1291  std::stringstream cmd;
1292  cmd << "cp -p ";
1293  cmd << src;
1294  cmd << " ";
1295  cmd << dst;
1296  int ret = system(cmd.str().c_str());
1297  if (ret) {
1298  }; // to avoid a warning
1299  // std::cout << cmd << " return value: " << ret << std::endl;
1300  return true;
1301 #else
1302  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on iOS Platform", src.c_str(),
1303  dst.c_str()));
1304 #endif
1305 #elif defined(_WIN32)
1306 #if (!defined(WINRT))
1307  std::stringstream cmd;
1308  cmd << "copy ";
1309  cmd << vpIoTools::path(src);
1310  cmd << " ";
1311  cmd << vpIoTools::path(dst);
1312  int ret = system(cmd.str().c_str());
1313  if (ret) {
1314  }; // to avoid a warning
1315  // std::cout << cmd << " return value: " << ret << std::endl;
1316  return true;
1317 #else
1318  throw(vpIoException(vpException::fatalError, "Cannot copy %s in %s: not implemented on Universal Windows Platform",
1319  src.c_str(), dst.c_str()));
1320 #endif
1321 #endif
1322  }
1323  else {
1324  std::cout << "Cannot copy: " << src << " in " << dst << std::endl;
1325  return false;
1326  }
1327 }
1328 
1339 bool vpIoTools::remove(const std::string &file_or_dir)
1340 {
1341  // Check if we have to consider a file or a directory
1342  if (vpIoTools::checkFilename(file_or_dir)
1343 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1344  || vpIoTools::checkFifo(std::string(file_or_dir))
1345 #endif
1346  ) {
1347  // std::cout << "remove file: " << file_or_dir << std::endl;
1348  if (::remove(file_or_dir.c_str()) != 0)
1349  return false;
1350  else
1351  return true;
1352  }
1353  else if (vpIoTools::checkDirectory(file_or_dir)) {
1354  // std::cout << "remove directory: " << file_or_dir << std::endl;
1355 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1356 #if TARGET_OS_IOS == 0 // The following code is not working on iOS since
1357  // wordexp() is not available
1358  std::stringstream cmd;
1359  cmd << "rm -rf \"";
1360  cmd << file_or_dir;
1361  cmd << "\"";
1362  int ret = system(cmd.str().c_str());
1363  if (ret) {
1364  }; // to avoid a warning
1365  // std::cout << cmd << " return value: " << ret << std::endl;
1366  return true;
1367 #else
1368  throw(vpIoException(vpException::fatalError, "Cannot remove %s: not implemented on iOS Platform",
1369  file_or_dir.c_str()));
1370 #endif
1371 #elif defined(_WIN32)
1372 #if (!defined(WINRT))
1373  std::stringstream cmd;
1374  cmd << "rmdir /S /Q ";
1375  cmd << vpIoTools::path(file_or_dir);
1376  cmd << "\"";
1377  int ret = system(cmd.str().c_str());
1378  if (ret) {
1379  }; // to avoid a warning
1380  // std::cout << cmd << " return value: " << ret << std::endl;
1381  return true;
1382 #else
1383  throw(vpIoException(vpException::fatalError, "Cannot remove %s: not implemented on Universal Windows Platform",
1384  file_or_dir.c_str()));
1385 #endif
1386 #endif
1387  }
1388  else {
1389  std::cout << "Cannot remove: " << file_or_dir << std::endl;
1390  return false;
1391  }
1392 }
1393 
1403 bool vpIoTools::rename(const std::string &oldfilename, const std::string &newfilename)
1404 {
1405  if (::rename(oldfilename.c_str(), newfilename.c_str()) != 0)
1406  return false;
1407  else
1408  return true;
1409 }
1410 
1421 std::string vpIoTools::path(const std::string &pathname)
1422 {
1423  std::string path(pathname);
1424 
1425 #if defined(_WIN32)
1426  for (unsigned int i = 0; i < path.length(); i++)
1427  if (path[i] == '/')
1428  path[i] = '\\';
1429 #elif defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
1430  for (unsigned int i = 0; i < path.length(); i++)
1431  if (path[i] == '\\')
1432  path[i] = '/';
1433 #if TARGET_OS_IOS == 0 // The following code is not working on iOS and android since
1434  // wordexp() is not available
1435 #ifdef __ANDROID__
1436 // Do nothing
1437 #else
1438  wordexp_t exp_result;
1439 
1440  // escape quote character
1441  replaceAll(path, "'", "'\\''");
1442  // add quotes to handle special characters like parentheses and spaces
1443  wordexp(std::string("'" + path + "'").c_str(), &exp_result, 0);
1444  path = exp_result.we_wordc == 1 ? exp_result.we_wordv[0] : "";
1445  wordfree(&exp_result);
1446 #endif
1447 #endif
1448 #endif
1449 
1450  return path;
1451 }
1452 
1461 bool vpIoTools::loadConfigFile(const std::string &confFile)
1462 {
1463  configFile = path(confFile);
1464  configVars.clear();
1465  configValues.clear();
1466  std::ifstream confContent(configFile.c_str(), std::ios::in);
1467 
1468  if (confContent.is_open()) {
1469  std::string line, var, val;
1470  long unsigned int k;
1471  int c;
1472  std::string stop[3] = { " ", "\t", "#" };
1473  while (std::getline(confContent, line)) {
1474  if ((line.compare(0, 1, "#") != 0) && (line.size() > 2)) {
1475  try {
1476  // name of the variable
1477  k = static_cast<unsigned long>(line.find(" "));
1478  var = line.substr(0, k);
1479  // look for the end of the actual value
1480  c = 200;
1481  for (unsigned i = 0; i < 3; ++i)
1482  c = vpMath::minimum(c,
1483  static_cast<int>(line.find(stop[i], static_cast<size_t>(k) + static_cast<size_t>(1))));
1484  if (c == -1)
1485  c = static_cast<int>(line.size());
1486  long unsigned int c_ = static_cast<long unsigned int>(c);
1487  val = line.substr(static_cast<size_t>(k) + static_cast<size_t>(1),
1488  static_cast<size_t>(c_) - static_cast<size_t>(k) - static_cast<size_t>(1));
1489  configVars.push_back(var);
1490  configValues.push_back(val);
1491  }
1492  catch (...) {
1493  }
1494  }
1495  }
1496  confContent.close();
1497  }
1498  else {
1499  return false;
1500  }
1501  return true;
1502 }
1503 
1512 bool vpIoTools::readConfigVar(const std::string &var, float &value)
1513 {
1514  bool found = false;
1515  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1516  if (configVars[k] == var) {
1517  if (configValues[k].compare("PI") == 0)
1518  value = static_cast<float>(M_PI);
1519  else if (configValues[k].compare("PI/2") == 0)
1520  value = static_cast<float>(M_PI / 2.0);
1521  else if (configValues[k].compare("-PI/2") == 0)
1522  value = static_cast<float>(-M_PI / 2.0);
1523  else
1524  value = static_cast<float>(atof(configValues[k].c_str()));
1525  found = true;
1526  }
1527  }
1528  if (found == false)
1529  std::cout << var << " not found in config file" << std::endl;
1530  return found;
1531 }
1540 bool vpIoTools::readConfigVar(const std::string &var, double &value)
1541 {
1542  bool found = false;
1543  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1544  if (configVars[k] == var) {
1545  if (configValues[k].compare("PI") == 0)
1546  value = M_PI;
1547  else if (configValues[k].compare("PI/2") == 0)
1548  value = M_PI / 2;
1549  else if (configValues[k].compare("-PI/2") == 0)
1550  value = -M_PI / 2;
1551  else
1552  value = atof(configValues[k].c_str());
1553  found = true;
1554  }
1555  }
1556  if (found == false)
1557  std::cout << var << " not found in config file" << std::endl;
1558  return found;
1559 }
1560 
1569 bool vpIoTools::readConfigVar(const std::string &var, int &value)
1570 {
1571  bool found = false;
1572  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1573  if (configVars[k] == var) {
1574  value = atoi(configValues[k].c_str());
1575  found = true;
1576  }
1577  }
1578  if (found == false)
1579  std::cout << var << " not found in config file" << std::endl;
1580  return found;
1581 }
1582 
1591 bool vpIoTools::readConfigVar(const std::string &var, unsigned int &value)
1592 {
1593  int v = 0;
1594  bool found = readConfigVar(var, v);
1595  value = static_cast<unsigned int>(v);
1596  return found;
1597 }
1598 
1607 bool vpIoTools::readConfigVar(const std::string &var, bool &value)
1608 {
1609  int v = 0;
1610  bool found = readConfigVar(var, v);
1611  value = (v != 0);
1612  return found;
1613 }
1614 
1623 bool vpIoTools::readConfigVar(const std::string &var, vpColor &value)
1624 {
1625  unsigned int v = 0;
1626  bool found = readConfigVar(var, v);
1627  value = vpColor::getColor(v);
1628  return found;
1629 }
1630 
1639 bool vpIoTools::readConfigVar(const std::string &var, std::string &value)
1640 {
1641  bool found = false;
1642  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1643  if (configVars[k] == var) {
1644  value = configValues[k];
1645  found = true;
1646  }
1647  }
1648  if (found == false)
1649  std::cout << var << " not found in config file" << std::endl;
1650  return found;
1651 }
1652 
1666 bool vpIoTools::readConfigVar(const std::string &var, vpArray2D<double> &value, const unsigned int &nCols,
1667  const unsigned int &nRows)
1668 {
1669  bool found = false;
1670  std::string nb;
1671  for (unsigned int k = 0; k < configVars.size() && found == false; ++k) {
1672  if (configVars[k] == var) {
1673  found = true;
1674  // resize or not
1675  if (nCols != 0 && nRows != 0)
1676  value.resize(nRows, nCols);
1677  size_t ind = 0, ind2;
1678  for (unsigned int i = 0; i < value.getRows(); ++i)
1679  for (unsigned int j = 0; j < value.getCols(); ++j) {
1680  ind2 = configValues[k].find(",", ind);
1681  nb = configValues[k].substr(ind, ind2 - ind);
1682  if (nb.compare("PI") == 0)
1683  value[i][j] = M_PI;
1684  else if (nb.compare("PI/2") == 0)
1685  value[i][j] = M_PI / 2;
1686  else if (nb.compare("-PI/2") == 0)
1687  value[i][j] = -M_PI / 2;
1688  else
1689  value[i][j] = atof(nb.c_str());
1690  ind = ind2 + 1;
1691  }
1692  }
1693  }
1694  if (found == false)
1695  std::cout << var << " not found in config file" << std::endl;
1696  return found;
1697 }
1698 
1699 // construct experiment filename & path
1700 
1709 void vpIoTools::addNameElement(const std::string &strTrue, const bool &cond, const std::string &strFalse)
1710 {
1711  if (cond)
1712  baseName += "_" + strTrue;
1713  else if (strFalse != "")
1714  baseName += "_" + strFalse;
1715 }
1716 
1725 void vpIoTools::addNameElement(const std::string &strTrue, const double &val)
1726 {
1727  // if(val != 0.)
1728  if (std::fabs(val) < std::numeric_limits<double>::epsilon()) {
1729  std::stringstream valS;
1730  valS.precision(4);
1731  valS << val;
1732  baseName += "_" + strTrue + valS.str();
1733  }
1734 }
1735 
1744 void vpIoTools::createBaseNamePath(const bool &empty)
1745 {
1746  if (vpIoTools::checkDirectory(baseDir + baseName) == false) {
1747  vpIoTools::makeDirectory(baseDir + baseName);
1748  std::cout << "creating directory " + baseDir + baseName << std::endl;
1749  }
1750  else {
1751  if (empty) {
1752  std::cout << "emptying directory " + baseDir + baseName << std::endl;
1753  vpIoTools::remove(baseDir + baseName + "/*");
1754  }
1755  }
1756 }
1757 
1764 void vpIoTools::saveConfigFile(const bool &actuallySave)
1765 {
1766  if (actuallySave) {
1767  std::string dest = baseDir + "/" + baseName + "_config.txt";
1768  // file copy
1769  vpIoTools::copy(configFile, dest);
1770  }
1771 }
1772 
1787 {
1788  std::string data_path;
1789  std::string file_to_test("mbt/cube.cao");
1790  std::string filename;
1791  // Test if VISP_INPUT_IMAGE_PATH env var is set
1792  try {
1793  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH");
1794  filename = data_path + "/" + file_to_test;
1795  if (vpIoTools::checkFilename(filename))
1796  return data_path;
1797  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/ViSP-images";
1798  filename = data_path + "/" + file_to_test;
1799  if (vpIoTools::checkFilename(filename))
1800  return data_path;
1801  data_path = vpIoTools::getenv("VISP_INPUT_IMAGE_PATH") + "/visp-images";
1802  filename = data_path + "/" + file_to_test;
1803  if (vpIoTools::checkFilename(filename))
1804  return data_path;
1805  }
1806  catch (...) {
1807  }
1808 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
1809  // Test if visp-images-data package is installed (Ubuntu and Debian)
1810  data_path = "/usr/share/visp-images-data/ViSP-images";
1811  filename = data_path + "/" + file_to_test;
1812  if (vpIoTools::checkFilename(filename))
1813  return data_path;
1814  data_path = "/usr/share/visp-images-data/visp-images";
1815  filename = data_path + "/" + file_to_test;
1816  if (vpIoTools::checkFilename(filename))
1817  return data_path;
1818 #endif
1819  data_path = "";
1820  return data_path;
1821 }
1822 
1852 std::string vpIoTools::getFileExtension(const std::string &pathname, bool checkFile)
1853 {
1854  if (checkFile && (vpIoTools::checkDirectory(pathname) || !vpIoTools::checkFilename(pathname))) {
1855  return "";
1856  }
1857 
1858 #if defined(_WIN32)
1859  std::string sep = "\\";
1860  std::string altsep = "/";
1861  std::string extsep = ".";
1862 #else
1863  // On Unix, or on the Mac
1864  std::string sep = "/";
1865  std::string altsep = "";
1866  std::string extsep = ".";
1867 #endif
1868 
1869  // Python 2.7.8 module.
1870  // # Split a path in root and extension.
1871  // # The extension is everything starting at the last dot in the last
1872  // # pathname component; the root is everything before that.
1873  // # It is always true that root + ext == p.
1874  //
1875  // # Generic implementation of splitext, to be parametrized with
1876  // # the separators
1877  // def _splitext(p, sep, altsep, extsep):
1878  // """Split the extension from a pathname.
1879  //
1880  // Extension is everything from the last dot to the end, ignoring
1881  // leading dots. Returns "(root, ext)"; ext may be empty."""
1882  //
1883  // sepIndex = p.rfind(sep)
1884  // if altsep:
1885  // altsepIndex = p.rfind(altsep)
1886  // sepIndex = max(sepIndex, altsepIndex)
1887  //
1888  // dotIndex = p.rfind(extsep)
1889  // if dotIndex > sepIndex:
1890  // # skip all leading dots
1891  // filenameIndex = sepIndex + 1
1892  // while filenameIndex < dotIndex:
1893  // if p[filenameIndex] != extsep:
1894  // return p[:dotIndex], p[dotIndex:]
1895  // filenameIndex += 1
1896  //
1897  // return p, ''
1898 
1899  int sepIndex = static_cast<int>(pathname.rfind(sep));
1900  if (!altsep.empty()) {
1901  int altsepIndex = static_cast<int>(pathname.rfind(altsep));
1902  sepIndex = std::max<int>(sepIndex, altsepIndex);
1903  }
1904 
1905  size_t dotIndex = pathname.rfind(extsep);
1906  if (dotIndex != std::string::npos) {
1907  // The extsep character exists
1908  size_t npos = std::string::npos;
1909  if ((sepIndex != static_cast<int>(npos) && static_cast<int>(dotIndex) > sepIndex) ||
1910  sepIndex == static_cast<int>(npos)) {
1911  if (sepIndex == static_cast<int>(npos)) {
1912  sepIndex = 0;
1913  }
1914  size_t filenameIndex = static_cast<size_t>(sepIndex) + static_cast<size_t>(1);
1915 
1916  while (filenameIndex < dotIndex) {
1917  if (pathname.compare(filenameIndex, 1, extsep) != 0) {
1918  return pathname.substr(dotIndex);
1919  }
1920  filenameIndex++;
1921  }
1922  }
1923  }
1924 
1925  return "";
1926 }
1927 
1933 std::string vpIoTools::getName(const std::string &pathname)
1934 {
1935  if (pathname.size() > 0) {
1936  std::string convertedPathname = vpIoTools::path(pathname);
1937 
1938  size_t index = convertedPathname.find_last_of(vpIoTools::separator);
1939  if (index != std::string::npos) {
1940  return convertedPathname.substr(index + 1);
1941  }
1942 
1943  return convertedPathname;
1944  }
1945 
1946  return "";
1947 }
1948 
1955 std::string vpIoTools::getNameWE(const std::string &pathname)
1956 {
1957  std::string name = vpIoTools::getName(pathname);
1958  size_t found = name.find_last_of(".");
1959  std::string name_we = name.substr(0, found);
1960  return name_we;
1961 }
1962 
1996 long vpIoTools::getIndex(const std::string &filename, const std::string &format)
1997 {
1998  size_t indexBegin = format.find_last_of('%');
1999  size_t indexEnd = format.find_first_of('d', indexBegin);
2000  size_t suffixLength = format.length() - indexEnd - 1;
2001  // Extracting index
2002  if (filename.length() <= suffixLength + indexBegin) {
2003  return -1;
2004  }
2005  size_t indexLength = filename.length() - suffixLength - indexBegin;
2006  std::string indexSubstr = filename.substr(indexBegin, indexLength);
2007  std::istringstream ss(indexSubstr);
2008  long index = 0;
2009  ss >> index;
2010  if (ss.fail() || index < 0 || !ss.eof()) {
2011  return -1;
2012  }
2013 
2014  // Checking that format with inserted index equals filename
2015  char nameByFormat[FILENAME_MAX];
2016  snprintf(nameByFormat, FILENAME_MAX, format.c_str(), index);
2017  if (std::string(nameByFormat) != filename) {
2018  return -1;
2019  }
2020  return index;
2021 }
2022 
2038 std::string vpIoTools::getParent(const std::string &pathname)
2039 {
2040  if (pathname.size() > 0) {
2041  std::string convertedPathname = vpIoTools::path(pathname);
2042 
2043  size_t index = convertedPathname.find_last_of(vpIoTools::separator);
2044  if (index != std::string::npos) {
2045  return convertedPathname.substr(0, index);
2046  }
2047 
2048  return ".";
2049  }
2050  else {
2051  return "";
2052  }
2053 }
2054 
2063 std::string vpIoTools::toLowerCase(const std::string &input)
2064 {
2065  std::string out;
2066 #if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
2067  for (std::string::const_iterator it = input.cbegin(); it != input.cend(); it++) {
2068 #else
2069  for (std::string::const_iterator it = input.begin(); it != input.end(); it++) {
2070 #endif
2071  out += std::tolower(*it);
2072  }
2073  return out;
2074 }
2075 
2084 std::string vpIoTools::toUpperCase(const std::string &input)
2085 {
2086  std::string out;
2087 #if VISP_CXX_STANDARD > VISP_CXX_STANDARD_98
2088  for (std::string::const_iterator it = input.cbegin(); it != input.cend(); it++) {
2089 #else
2090  for (std::string::const_iterator it = input.begin(); it != input.end(); it++) {
2091 #endif
2092  out += std::toupper(*it);
2093  }
2094  return out;
2095 }
2096 
2105 std::string vpIoTools::getAbsolutePathname(const std::string &pathname)
2106 {
2107 
2108 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
2109  std::string real_path_str = pathname;
2110  char *real_path = realpath(pathname.c_str(), nullptr);
2111 
2112  if (real_path) {
2113  real_path_str = real_path;
2114  free(real_path);
2115  }
2116  return real_path_str;
2117 #elif defined(_WIN32)
2118 #if (!defined(WINRT))
2119  std::string real_path_str = pathname;
2120  DWORD retval = 0;
2121  TCHAR buffer[4096] = TEXT("");
2122 
2123  retval = GetFullPathName(pathname.c_str(), 4096, buffer, 0);
2124  if (retval != 0) {
2125  real_path_str = buffer;
2126  }
2127  return real_path_str;
2128 #else
2130  "Cannot get absolute path of %s: not implemented on "
2131  "Universal Windows Platform",
2132  pathname.c_str()));
2133 #endif
2134 #endif
2135 }
2136 
2147 std::string vpIoTools::createFilePath(const std::string &parent, const std::string &child)
2148 {
2149  if (child.size() == 0 && parent.size() == 0) {
2150  return "";
2151  }
2152 
2153  if (child.size() == 0) {
2154  return vpIoTools::path(parent);
2155  }
2156 
2157  if (parent.size() == 0) {
2158  return vpIoTools::path(child);
2159  }
2160 
2161  std::string convertedParent = vpIoTools::path(parent);
2162  std::string convertedChild = vpIoTools::path(child);
2163 
2164  std::stringstream ss;
2165  ss << vpIoTools::separator;
2166  std::string stringSeparator;
2167  ss >> stringSeparator;
2168 
2169  std::string lastConvertedParentChar = convertedParent.substr(convertedParent.size() - 1);
2170  std::string firstConvertedChildChar = convertedChild.substr(0, 1);
2171 
2172  if (lastConvertedParentChar == stringSeparator) {
2173  convertedParent = convertedParent.substr(0, convertedParent.size() - 1);
2174  }
2175 
2176  if (firstConvertedChildChar == stringSeparator) {
2177  convertedChild = convertedChild.substr(1);
2178  }
2179 
2180  return std::string(convertedParent + vpIoTools::separator + convertedChild);
2181 }
2182 
2188 bool vpIoTools::isAbsolutePathname(const std::string &pathname)
2189 {
2190  // # Inspired by the Python 2.7.8 module.
2191  // # Return whether a path is absolute.
2192  // # Trivial in Posix, harder on the Mac or MS-DOS.
2193  // # For DOS it is absolute if it starts with a slash or backslash (current
2194  // # volume), or if a pathname after the volume letter and colon / UNC
2195  // resource # starts with a slash or backslash.
2196  //
2197  // def isabs(s):
2198  // """Test whether a path is absolute"""
2199  // s = splitdrive(s)[1]
2200  // return s != '' and s[:1] in '/\\'
2201  std::string path = splitDrive(pathname).second;
2202  return path.size() > 0 && (path.substr(0, 1) == "/" || path.substr(0, 1) == "\\");
2203 }
2204 
2212 bool vpIoTools::isSamePathname(const std::string &pathname1, const std::string &pathname2)
2213 {
2214  // Normalize path
2215  std::string path1_normalize = vpIoTools::path(pathname1);
2216  std::string path2_normalize = vpIoTools::path(pathname2);
2217 
2218  // Get absolute path
2219  path1_normalize = vpIoTools::getAbsolutePathname(path1_normalize);
2220  path2_normalize = vpIoTools::getAbsolutePathname(path2_normalize);
2221 
2222  return (path1_normalize == path2_normalize);
2223 }
2224 
2232 std::pair<std::string, std::string> vpIoTools::splitDrive(const std::string &pathname)
2233 {
2234  // # Split a path in a drive specification (a drive letter followed by a
2235  // # colon) and the path specification.
2236  // # It is always true that drivespec + pathspec == p
2237  // def splitdrive(p):
2238  // """Split a pathname into drive/UNC sharepoint and relative path
2239  // specifiers. Returns a 2-tuple (drive_or_unc, path); either part may be
2240  // empty.
2241  //
2242  // If you assign
2243  // result = splitdrive(p)
2244  // It is always true that:
2245  // result[0] + result[1] == p
2246  //
2247  // If the path contained a drive letter, drive_or_unc will contain
2248  // everything up to and including the colon. e.g. splitdrive("c:/dir")
2249  // returns ("c:", "/dir")
2250  //
2251  // If the path contained a UNC path, the drive_or_unc will contain the host
2252  // name and share up to but not including the fourth directory separator
2253  // character. e.g. splitdrive("//host/computer/dir") returns
2254  // ("//host/computer", "/dir")
2255  //
2256  // Paths cannot contain both a drive letter and a UNC path.
2257  //
2258  // """
2259  // if len(p) > 1:
2260  // normp = p.replace(altsep, sep)
2261  // if (normp[0:2] == sep*2) and (normp[2] != sep):
2262  // # is a UNC path:
2263  // # vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
2264  // # \\machine\mountpoint\directory\etc\...
2265  // # directory ^^^^^^^^^^^^^^^
2266  // index = normp.find(sep, 2)
2267  // if index == -1:
2268  // return '', p
2269  // index2 = normp.find(sep, index + 1)
2270  // # a UNC path can't have two slashes in a row
2271  // # (after the initial two)
2272  // if index2 == index + 1:
2273  // return '', p
2274  // if index2 == -1:
2275  // index2 = len(p)
2276  // return p[:index2], p[index2:]
2277  // if normp[1] == ':':
2278  // return p[:2], p[2:]
2279  // return '', p
2280 
2281  // On Unix, the drive is always empty.
2282  // On the Mac, the drive is always empty (don't use the volume name -- it
2283  // doesn't have the same syntactic and semantic oddities as DOS drive
2284  // letters, such as there being a separate current directory per drive).
2285 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__)))
2286  return std::pair<std::string, std::string>("", pathname);
2287 #else
2288  const std::string sep = "\\";
2289  const std::string sepsep = "\\\\";
2290  const std::string altsep = "/";
2291 
2292  if (pathname.size() > 1) {
2293  std::string normPathname = pathname;
2294  std::replace(normPathname.begin(), normPathname.end(), *altsep.c_str(), *sep.c_str());
2295 
2296  if (normPathname.substr(0, 2) == sepsep && normPathname.substr(2, 1) != sep) {
2297  // is a UNC path:
2298  // vvvvvvvvvvvvvvvvvvvv drive letter or UNC path
2299  // \\machine\mountpoint\directory\etc\...
2300  // directory ^^^^^^^^^^^^^^^
2301  size_t index = normPathname.find(sep, 2);
2302  if (index == std::string::npos) {
2303  return std::pair<std::string, std::string>("", pathname);
2304  }
2305 
2306  size_t index2 = normPathname.find(sep, index + 1);
2307  // # a UNC path can't have two slashes in a row
2308  // # (after the initial two)
2309  if (index2 == index + 1) {
2310  return std::pair<std::string, std::string>("", pathname);
2311  }
2312 
2313  if (index2 == std::string::npos) {
2314  index2 = pathname.size();
2315  }
2316 
2317  return std::pair<std::string, std::string>(pathname.substr(0, index2), pathname.substr(index2));
2318  }
2319 
2320  if (normPathname[1] == ':') {
2321  return std::pair<std::string, std::string>(pathname.substr(0, 2), pathname.substr(2));
2322  }
2323  }
2324 
2325  return std::pair<std::string, std::string>("", pathname);
2326 #endif
2327 }
2328 
2377 std::vector<std::string> vpIoTools::splitChain(const std::string &chain, const std::string &sep)
2378 {
2379  size_t startIndex = 0;
2380 
2381  std::string chainToSplit = chain;
2382  std::vector<std::string> subChain;
2383  size_t sepIndex = chainToSplit.find(sep);
2384 
2385  while (sepIndex != std::string::npos) {
2386  std::string sub = chainToSplit.substr(startIndex, sepIndex);
2387  if (!sub.empty())
2388  subChain.push_back(sub);
2389  chainToSplit = chainToSplit.substr(sepIndex + 1, chain.size() - 1);
2390 
2391  sepIndex = chainToSplit.find(sep);
2392  }
2393  if (!chainToSplit.empty())
2394  subChain.push_back(chainToSplit);
2395 
2396  return subChain;
2397 }
2398 
2406 std::vector<std::string> vpIoTools::getDirFiles(const std::string &pathname)
2407 {
2408 
2409  if (!checkDirectory(pathname)) {
2410  throw(vpIoException(vpException::fatalError, "Directory %s doesn't exist'", pathname.c_str()));
2411  }
2412  std::string dirName = path(pathname);
2413 
2414 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) // UNIX
2415 
2416  std::vector<std::string> files;
2417  struct dirent **list = nullptr;
2418  int filesCount = scandir(dirName.c_str(), &list, nullptr, nullptr);
2419  if (filesCount == -1) {
2420  throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
2421  }
2422  for (int i = 0; i < filesCount; i++) {
2423  std::string fileName = list[i]->d_name;
2424  if (fileName != "." && fileName != "..") {
2425  files.push_back(fileName);
2426  }
2427  free(list[i]);
2428  }
2429  free(list);
2430  std::sort(files.begin(), files.end());
2431  return files;
2432 
2433 #elif defined(_WIN32)
2434 #if (!defined(WINRT))
2435 
2436  std::vector<std::string> files;
2437  std::string fileMask = dirName;
2438  fileMask.append("\\*");
2439  WIN32_FIND_DATA FindFileData;
2440  HANDLE hFind = FindFirstFile(fileMask.c_str(), &FindFileData);
2441  // Directory is empty
2442  if (HandleToLong(&hFind) == ERROR_FILE_NOT_FOUND) {
2443  return files;
2444  }
2445  if (hFind == INVALID_HANDLE_VALUE) {
2446  throw(vpIoException(vpException::fatalError, "Cannot read files of directory %s", dirName.c_str()));
2447  }
2448  do {
2449  std::string fileName = FindFileData.cFileName;
2450  if (fileName != "." && fileName != "..") {
2451  files.push_back(fileName);
2452  }
2453  } while (FindNextFile(hFind, &FindFileData));
2454  FindClose(hFind);
2455  std::sort(files.begin(), files.end());
2456  return files;
2457 
2458 #else
2460  "Cannot read files of directory %s: not implemented on "
2461  "Universal Windows Platform",
2462  dirName.c_str()));
2463 #endif
2464 #endif
2465 }
2466 
2470 void vpIoTools::readBinaryValueLE(std::ifstream &file, int16_t &short_value)
2471 {
2472  file.read((char *)(&short_value), sizeof(short_value));
2473 
2474 #ifdef VISP_BIG_ENDIAN
2475  // Swap bytes order from little endian to big endian
2476  short_value = vpEndian::swap16bits((uint16_t)short_value);
2477 #endif
2478 }
2479 
2483 void vpIoTools::readBinaryValueLE(std::ifstream &file, uint16_t &ushort_value)
2484 {
2485  file.read((char *)(&ushort_value), sizeof(ushort_value));
2486 
2487 #ifdef VISP_BIG_ENDIAN
2488  // Swap bytes order from little endian to big endian
2489  ushort_value = vpEndian::swap16bits(ushort_value);
2490 #endif
2491 }
2492 
2496 void vpIoTools::readBinaryValueLE(std::ifstream &file, int32_t &int_value)
2497 {
2498  file.read((char *)(&int_value), sizeof(int_value));
2499 
2500 #ifdef VISP_BIG_ENDIAN
2501  // Swap bytes order from little endian to big endian
2502  int_value = vpEndian::swap32bits((uint32_t)int_value);
2503 #endif
2504 }
2505 
2509 void vpIoTools::readBinaryValueLE(std::ifstream &file, uint32_t &uint_value)
2510 {
2511  file.read((char *)(&uint_value), sizeof(uint_value));
2512 
2513 #ifdef VISP_BIG_ENDIAN
2514  // Swap bytes order from little endian to big endian
2515  uint_value = vpEndian::swap32bits(uint_value);
2516 #endif
2517 }
2518 
2522 void vpIoTools::readBinaryValueLE(std::ifstream &file, float &float_value)
2523 {
2524  file.read((char *)(&float_value), sizeof(float_value));
2525 
2526 #ifdef VISP_BIG_ENDIAN
2527  // Swap bytes order from little endian to big endian
2528  float_value = vpEndian::swapFloat(float_value);
2529 #endif
2530 }
2531 
2535 void vpIoTools::readBinaryValueLE(std::ifstream &file, double &double_value)
2536 {
2537  file.read((char *)(&double_value), sizeof(double_value));
2538 
2539 #ifdef VISP_BIG_ENDIAN
2540  // Swap bytes order from little endian to big endian
2541  double_value = vpEndian::swapDouble(double_value);
2542 #endif
2543 }
2544 
2548 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
2549 {
2550 #ifdef VISP_BIG_ENDIAN
2551  // Swap bytes order to little endian
2552  uint16_t swap_short = vpEndian::swap16bits((uint16_t)short_value);
2553  file.write((char *)(&swap_short), sizeof(swap_short));
2554 #else
2555  file.write((char *)(&short_value), sizeof(short_value));
2556 #endif
2557 }
2558 
2562 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint16_t ushort_value)
2563 {
2564 #ifdef VISP_BIG_ENDIAN
2565  // Swap bytes order to little endian
2566  uint16_t swap_ushort = vpEndian::swap16bits(ushort_value);
2567  file.write((char *)(&swap_ushort), sizeof(swap_ushort));
2568 #else
2569  file.write((char *)(&ushort_value), sizeof(ushort_value));
2570 #endif
2571 }
2572 
2576 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const int32_t int_value)
2577 {
2578 #ifdef VISP_BIG_ENDIAN
2579  // Swap bytes order to little endian
2580  uint32_t swap_int = vpEndian::swap32bits((uint32_t)int_value);
2581  file.write((char *)(&swap_int), sizeof(swap_int));
2582 #else
2583  file.write((char *)(&int_value), sizeof(int_value));
2584 #endif
2585 }
2586 
2590 void vpIoTools::writeBinaryValueLE(std::ofstream &file, const uint32_t uint_value)
2591 {
2592 #ifdef VISP_BIG_ENDIAN
2593  // Swap bytes order to little endian
2594  uint32_t swap_int = vpEndian::swap32bits(uint_value);
2595  file.write((char *)(&swap_int), sizeof(swap_int));
2596 #else
2597  file.write((char *)(&uint_value), sizeof(uint_value));
2598 #endif
2599 }
2600 
2604 void vpIoTools::writeBinaryValueLE(std::ofstream &file, float float_value)
2605 {
2606 #ifdef VISP_BIG_ENDIAN
2607  // Swap bytes order to little endian
2608  float swap_float = vpEndian::swapFloat(float_value);
2609  file.write((char *)(&swap_float), sizeof(swap_float));
2610 #else
2611  file.write((char *)(&float_value), sizeof(float_value));
2612 #endif
2613 }
2614 
2618 void vpIoTools::writeBinaryValueLE(std::ofstream &file, double double_value)
2619 {
2620 #ifdef VISP_BIG_ENDIAN
2621  // Swap bytes order to little endian
2622  double swap_double = vpEndian::swapDouble(double_value);
2623  file.write((char *)(&swap_double), sizeof(swap_double));
2624 #else
2625  file.write((char *)(&double_value), sizeof(double_value));
2626 #endif
2627 }
2628 
2629 bool vpIoTools::parseBoolean(std::string input)
2630 {
2631  std::transform(input.begin(), input.end(), input.begin(), ::tolower);
2632  std::istringstream is(input);
2633  bool b;
2634  // Parse string to boolean either in the textual representation
2635  // (True/False) or in numeric representation (1/0)
2636  is >> (input.size() > 1 ? std::boolalpha : std::noboolalpha) >> b;
2637  return b;
2638 }
2639 
2643 std::string vpIoTools::trim(std::string s) { return ltrim(rtrim(s)); }
unsigned int getCols() const
Definition: vpArray2D.h:274
void resize(unsigned int nrows, unsigned int ncols, bool flagNullify=true, bool recopy_=true)
Definition: vpArray2D.h:299
unsigned int getRows() const
Definition: vpArray2D.h:284
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.
Definition: vpIoException.h:54
@ invalidDirectoryName
Directory name is invalid.
Definition: vpIoException.h:62
@ cantCreateDirectory
Unable to create a directory.
Definition: vpIoException.h:63
@ cantGetenv
Cannot get environment variable value.
Definition: vpIoException.h:65
static void getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch)
Definition: vpIoTools.cpp:775
static std::string getViSPImagesDataPath()
Definition: vpIoTools.cpp:1786
static std::vector< std::string > splitChain(const std::string &chain, const std::string &sep)
Definition: vpIoTools.cpp:2377
static std::vector< std::string > configVars
Definition: vpIoTools.h:585
static std::string path(const std::string &pathname)
Definition: vpIoTools.cpp:1421
static std::string getAbsolutePathname(const std::string &pathname)
Definition: vpIoTools.cpp:2105
static std::string toLowerCase(const std::string &input)
Return a lower-case version of the string input . Numbers and special characters stay the same.
Definition: vpIoTools.cpp:2063
static bool checkFilename(const std::string &filename)
Definition: vpIoTools.cpp:1204
static bool readConfigVar(const std::string &var, float &value)
Definition: vpIoTools.cpp:1512
static void setBaseName(const std::string &s)
Definition: vpIoTools.cpp:627
static std::pair< std::string, std::string > splitDrive(const std::string &pathname)
Definition: vpIoTools.cpp:2232
static bool isSamePathname(const std::string &pathname1, const std::string &pathname2)
Definition: vpIoTools.cpp:2212
static std::string getTempPath()
Definition: vpIoTools.cpp:587
static bool isAbsolutePathname(const std::string &pathname)
Definition: vpIoTools.cpp:2188
static void setBaseDir(const std::string &dir)
Definition: vpIoTools.cpp:634
static std::string baseDir
Definition: vpIoTools.h:583
static bool loadConfigFile(const std::string &confFile)
Definition: vpIoTools.cpp:1461
static bool copy(const std::string &src, const std::string &dst)
Definition: vpIoTools.cpp:1246
static std::string trim(std::string s)
Definition: vpIoTools.cpp:2643
static void readBinaryValueLE(std::ifstream &file, int16_t &short_value)
Definition: vpIoTools.cpp:2470
static void saveConfigFile(const bool &actuallySave=true)
Definition: vpIoTools.cpp:1764
static bool checkDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:818
static bool rename(const std::string &oldfilename, const std::string &newfilename)
Definition: vpIoTools.cpp:1403
static bool parseBoolean(std::string input)
Definition: vpIoTools.cpp:2629
static long getIndex(const std::string &filename, const std::string &format)
Definition: vpIoTools.cpp:1996
static std::string getUserName()
Definition: vpIoTools.cpp:711
static std::string getFullName()
Definition: vpIoTools.cpp:648
static void addNameElement(const std::string &strTrue, const bool &cond=true, const std::string &strFalse="")
Definition: vpIoTools.cpp:1709
static std::string createFilePath(const std::string &parent, const std::string &child)
Definition: vpIoTools.cpp:2147
static std::string getenv(const std::string &env)
Definition: vpIoTools.cpp:748
static const std::string & getBuildInformation()
Definition: vpIoTools.cpp:528
static std::string getBaseName()
Definition: vpIoTools.cpp:641
static std::string getFileExtension(const std::string &pathname, bool checkFile=false)
Definition: vpIoTools.cpp:1852
static std::string baseName
Definition: vpIoTools.h:582
static void createBaseNamePath(const bool &empty=false)
Definition: vpIoTools.cpp:1744
static std::vector< std::string > getDirFiles(const std::string &dirname)
Definition: vpIoTools.cpp:2406
static void makeDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:972
static std::string configFile
Definition: vpIoTools.h:584
static std::vector< std::string > configValues
Definition: vpIoTools.h:586
static void writeBinaryValueLE(std::ofstream &file, const int16_t short_value)
Definition: vpIoTools.cpp:2548
static bool remove(const std::string &filename)
Definition: vpIoTools.cpp:1339
static std::string getNameWE(const std::string &pathname)
Definition: vpIoTools.cpp:1955
static std::string makeTempDirectory(const std::string &dirname)
Definition: vpIoTools.cpp:1126
static bool checkFifo(const std::string &filename)
Definition: vpIoTools.cpp:883
static std::string getParent(const std::string &pathname)
Definition: vpIoTools.cpp:2038
static std::string getName(const std::string &pathname)
Definition: vpIoTools.cpp:1933
static std::string toUpperCase(const std::string &input)
Return a upper-case version of the string input . Numbers and special characters stay the same.
Definition: vpIoTools.cpp:2084
static const char separator
Definition: vpIoTools.h:518
static void makeFifo(const std::string &dirname)
Definition: vpIoTools.cpp:1023
static Type minimum(const Type &a, const Type &b)
Definition: vpMath.h:260
VISP_EXPORT char map_type(const std::type_info &t)
Definition: vpIoTools.cpp:136
VISP_EXPORT npz_t npz_load(std::string fname)
Definition: vpIoTools.cpp:342
VISP_EXPORT void parse_zip_footer(FILE *fp, uint16_t &nrecs, size_t &global_header_size, size_t &global_header_offset)
Definition: vpIoTools.cpp:256
VISP_EXPORT void parse_npy_header(FILE *fp, size_t &word_size, std::vector< size_t > &shape, bool &fortran_order)
Definition: vpIoTools.cpp:204
std::map< std::string, NpyArray > npz_t
Definition: vpIoTools.h:126
VISP_EXPORT NpyArray npy_load(std::string fname)
Definition: vpIoTools.cpp:458
VISP_EXPORT char BigEndianTest()
Definition: vpIoTools.cpp:130
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