1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Directory management.
33  *
34  * Authors:
35  * Fabien Spindler
36  *
37  *****************************************************************************/
38 
39 #ifndef vpIoTools_HH
40 #define vpIoTools_HH
41 
42 /*!
43   \file vpIoTools.h
44   \brief File and directories basic tools.
45  */
46 
47 #include <visp3/core/vpConfig.h>
48 
49 #include <iostream>
50 #include <sstream>
51 #include <stdlib.h>
52 #include <string>
53 #include <vector>
54 #include <visp3/core/vpColor.h>
55 #include <stdint.h> //for uint32_t related types ; works also with >= VS2010 / _MSC_VER >= 1600
56 
57 /*!
58   \class vpIoTools
59   \ingroup group_core_files_io
60   \brief File and directories basic tools.
61 
62   The example below shows how to manipulate the functions of this
63   class to create first a directory which name corresponds to the user
64   name and then create a file in this directory.
65 
66   \code
67 #include <iostream>
68 #include <string>
69 #include <fstream>
70 #include <visp3/core/vpIoTools.h>
71 
72 int main()
73 {
74   std::string username;
75   vpIoTools::getUserName(username);
76 
77   // Test if a username directory exist. If no try to create it
78   if (vpIoTools::checkDirectory(username) == false) {
79      try {
80        // Create a directory with name "username"
81        vpIoTools::makeDirectory(username);
82      }
83      catch (...) {
84        std::cout << "Cannot create " << username << " directory" << std::endl;
85        return EXIT_FAILURE;
86      }
87    }
88   // Create a empty filename with name "username/file.txt"
89   std::ofstream f;
90   std::string filename = username + "/file.txt";
91   // Under Windows converts the filename string into "username\\file.txt"
92   filename = vpIoTools::path(filename);
93   std::cout << "Create: " << filename << std::endl;
94   f.open(filename.c_str());
95   f.close();
96 
97   // Rename the file
98   std::string newfilename = username + "/newfile.txt";
99   std::cout << "Rename: " << filename << " in: " << newfilename << std::endl;
100   if (vpIoTools::rename(filename, newfilename) == false)
101     std::cout << "Unable to rename: " << filename << std::endl;
102 
103   // Remove the file
104   std::cout << "Remove: " << newfilename << std::endl;
105   if (vpIoTools::remove(newfilename) == false)
106     std::cout << "Unable to remove: " << newfilename << std::endl;
107 
108   return EXIT_SUCCESS;
109 }
110   \endcode
111 
112   The example below shows how to read a configuration file and how to create a name
113   for experiment files. We assume the following file "/home/user/demo/config.txt" :
114   \code
115 expNumber 2
116 save 0
117 lambda 0.4
118 use2D 0
119 use3D 1
120   \endcode
121 
122   \code
123 #include <iostream>
124 #include <string>
125 #include <visp3/core/vpIoTools.h>
126 
127 int main()
128 {
129   // reading configuration file
130   vpIoTools::loadConfigFile("/home/user/demo/config.txt");
131   std::string nExp;vpIoTools::readConfigVar("expNumber", nExp); // nExp <- "2"
132   double lambda;vpIoTools::readConfigVar("lambda", lambda);     // lambda <- 0.4
133   bool use2D;vpIoTools::readConfigVar("use2D", use2D);          // use2D <- false
134   bool use3D;vpIoTools::readConfigVar("use3D", use3D);          // use3D <- true
135   bool doSave;vpIoTools::readConfigVar("save", doSave);         //  doSave <- false
136 
137   // creating name for experiment files
138   vpIoTools::setBaseDir("/home/user/data");
139   // full name <- "/home/user/data/exp2"
140   vpIoTools::setBaseName("exp" + nExp);
141   // full name <- "/home/user/data/exp2" since use2D==false
142   vpIoTools::addNameElement("2D", use2D);
143   // full name <- "/home/user/data/exp2_3D"
144   vpIoTools::addNameElement("3D", use3D);
145   // full name <- "/home/user/data/exp2_3D_lambda0.4"
146   vpIoTools::addNameElement("lambda", lambda);
147 
148   // Saving file.Would copy "/home/user/demo/config.txt" to
149   // "/home/user/data/exp2_3D_lambda0.4_config.txt" if doSave was true
150   vpIoTools::saveConfigFile(doSave);
151   // create sub directory
152   vpIoTools::createBaseNamePath();  // creates "/home/user/data/exp2_3D_lambda0.4/"
153 }
154   \endcode
155 
156  */
157 
158 class VISP_EXPORT vpIoTools
159 {
160 
161 public:
162   static const std::string &getBuildInformation();
163   static void getUserName(std::string &username);
164   static std::string getUserName();
165   static std::string getenv(const std::string &env);
166   static std::string getViSPImagesDataPath();
167   static void getVersion(const std::string &version, unsigned int &major, unsigned int &minor, unsigned int &patch);
168   static bool checkDirectory(const std::string &dirname);
169   static bool checkFifo(const std::string &filename);
170   static bool checkFilename(const std::string &filename);
171   static bool copy(const std::string &src, const std::string &dst);
172 
173   static void makeDirectory(const std::string &dirname);
174   static void makeFifo(const std::string &dirname);
175   static std::string makeTempDirectory(const std::string &dirname);
176   static std::string path(const std::string &pathname);
177 
178   static bool remove(const std::string &filename);
179   static bool rename(const std::string &oldfilename, const std::string &newfilename);
180 
181   /*!
182          Define the directory separator character, backslash ('\') for windows
183      platform or slash ('/') otherwise.
184    */
185   static const char separator =
186 #if defined(_WIN32)
187       '\\';
188 #else
189       '/';
190 #endif
191 
192   static std::string getAbsolutePathname(const std::string &pathname);
193   static std::string getFileExtension(const std::string &pathname, bool checkFile = false);
194   static std::string getName(const std::string &pathname);
195   static std::string getNameWE(const std::string &pathname);
196   static std::string getParent(const std::string &pathname);
197   static std::string createFilePath(const std::string &parent, const std::string &child);
198   static bool isAbsolutePathname(const std::string &pathname);
199   static bool isSamePathname(const std::string &pathname1, const std::string &pathname2);
200   static std::pair<std::string, std::string> splitDrive(const std::string &pathname);
201   static std::vector<std::string> splitChain(const std::string &chain, const std::string &sep);
202   static std::vector<std::string> getDirFiles(const std::string &dirname);
203 
204   /*!
205     @name Configuration file parsing
206   */
207   //@{
208   // read configuration file
209   static bool loadConfigFile(const std::string &confFile);
210   static bool readConfigVar(const std::string &var, float &value);
211   static bool readConfigVar(const std::string &var, double &value);
212   static bool readConfigVar(const std::string &var, int &value);
213   static bool readConfigVar(const std::string &var, unsigned int &value);
214   static bool readConfigVar(const std::string &var, bool &value);
215   static bool readConfigVar(const std::string &var, std::string &value);
216   static bool readConfigVar(const std::string &var, vpColor &value);
217   static bool readConfigVar(const std::string &var, vpArray2D<double> &value, const unsigned int &nCols = 0,
218                             const unsigned int &nRows = 0);
219 
220   // construct experiment filename & path
221   static void setBaseName(const std::string &s);
222   static void setBaseDir(const std::string &dir);
223   static void addNameElement(const std::string &strTrue, const bool &cond = true, const std::string &strFalse = "");
224   static void addNameElement(const std::string &strTrue, const double &val);
225   static std::string getBaseName();
226   static std::string getFullName();
227 
228   // write files
229   static void saveConfigFile(const bool &actuallySave = true);
230   static void createBaseNamePath(const bool &empty = false);
231   //@}
232 
233   static void readBinaryValueLE(std::ifstream &file, int16_t &short_value);
234   static void readBinaryValueLE(std::ifstream &file, uint16_t &ushort_value);
235   static void readBinaryValueLE(std::ifstream &file, int32_t &int_value);
236   static void readBinaryValueLE(std::ifstream &file, uint32_t &int_value);
237   static void readBinaryValueLE(std::ifstream &file, float &float_value);
238   static void readBinaryValueLE(std::ifstream &file, double &double_value);
239 
240   static void writeBinaryValueLE(std::ofstream &file, const int16_t short_value);
241   static void writeBinaryValueLE(std::ofstream &file, const uint16_t ushort_value);
242   static void writeBinaryValueLE(std::ofstream &file, const int32_t int_value);
243   static void writeBinaryValueLE(std::ofstream &file, const uint32_t int_value);
244   static void writeBinaryValueLE(std::ofstream &file, float float_value);
245   static void writeBinaryValueLE(std::ofstream &file, double double_value);
246 
247   static bool parseBoolean(std::string input);
248   static std::string trim(std::string s);
249 
250 protected:
251   static std::string baseName;
252   static std::string baseDir;
253   static std::string configFile;
254   static std::vector<std::string> configVars;
255   static std::vector<std::string> configValues;
256 
257 #ifndef DOXYGEN_SHOULD_SKIP_THIS
258   static int mkdir_p(const char *path, int mode);
259 #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS
260 };
261 #endif
262