source: rrlib_util/sFileIOUtils.h @ 53:f2b76db078b0

Last change on this file since 53:f2b76db078b0 was 53:f2b76db078b0, checked in by Jens Wettach <wettach@…>, 8 years ago

added support for reading/writing a std::vector<T> from/to a bzipped file

File size: 13.0 KB
Line 
1//
2// You received this file as part of RRLib
3// Robotics Research Library
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public License
9// as published by the Free Software Foundation; either version 2
10// of the License, or (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20//
21//----------------------------------------------------------------------
22/*!\file    sFileIOUtils.h
23 *
24 * \author  Bernd Helge Schaefer
25 * \author  Jens Wettach
26 * \date    15.11.05
27 *
28 * \brief   Contains static class sFileIOUtils
29 *
30 */
31//----------------------------------------------------------------------
32// Includes
33//----------------------------------------------------------------------
34#ifndef _rrlib_util_sFileIOUtils_h_
35#define _rrlib_util_sFileIOUtils_h_
36
37//rrlib includes
38#include "rrlib/util/sStringUtils.h"
39#include "rrlib/logging/messages.h"
40
41//STL includes
42#include <string>
43#include <vector>
44#include <map>
45#include <fstream>
46#include <iterator>
47
48//boost includes
49#include <boost/iostreams/filtering_stream.hpp>
50#include <boost/iostreams/filter/bzip2.hpp>
51
52extern "C"
53{
54#include <arpa/inet.h> // inet_ntoa
55}
56
57//----------------------------------------------------------------------
58// Namespace declaration
59//----------------------------------------------------------------------
60namespace rrlib
61{
62namespace util
63{
64
65class sFileIOUtils
66{
67public:
68  /*!
69   * \brief Returns all files in a given directory
70   *
71   * \return Returns whether or not the read was possible
72   */
73  static bool GetAllFilesInDirectory(std::string dir, std::vector<std::string> &files);
74
75  /*!
76   * \brief Returns the current directory
77   *
78   * \return Returns a string containing the current directory
79   */
80  static std::string GetCurrentDirectory();
81  /*!
82   * \brief Setsthe current directory
83   *
84   * Changes the current directory to \param dir .
85   * \return returns an error code similar to the chdir C command
86   */
87  static int ChangeCurrentDirectory(const std::string& dir);
88
89  /*!
90   * \brief Creates a new directory at the path provided as parameter.
91   *
92   * \param path Complete relative or absolute path to be created.
93   * \return returns false if directory creation fails, true otherwise.
94   * The existance of the folder is not regarded as a failure here!
95   */
96  static bool CreateDirectory(const std::string& path); // throw(runtime_error);
97
98  /*!
99   * \brief Creates a new temporary file via "mktemp".
100   *
101   * \return the new temp file
102   */
103  static std::string CreateTempfile();
104
105  /*!
106   * \brief Removes file with given name.
107   */
108  static void DeleteFile(const std::string& filename);
109
110  /*!
111   * \brief Calls "gzip" on input file and writes result to output file.
112   *
113   * \note output file gets suffix ".gz" automatically if not yet the case.
114   */
115  static void CompressFile(const std::string& input_filename, std::string& output_filename);
116
117  /*!
118   * \brief Calls "gunzip" on input file and writes result to output file.
119   *
120   * \note input file must have suffix ".gz".
121   */
122  static void DecompressFile(const std::string& input_filename, const std::string& output_filename);
123
124
125  /*!
126   * \brief Writes content of given container to file with given name
127   *
128   * \returns true iff file could be processed as expected
129   *
130   * \note If filename has suffix ".bz2" it is compressed accordingly.
131   */
132  template <class T>
133  static bool WriteContainerToFile(const std::vector<T> &content, const std::string& filename)
134  {
135    std::ofstream output_file_stream;
136    RRLIB_LOG_PRINT(rrlib::logging::eLL_DEBUG_VERBOSE_1, "got file <", filename, ">");
137    if (sStringUtils::EndsWith(filename, ".bz2"))
138    {
139      RRLIB_LOG_PRINT(rrlib::logging::eLL_DEBUG_VERBOSE_1, "compressing");
140      boost::iostreams::filtering_ostream out;
141      out.push(boost::iostreams::bzip2_compressor());
142      output_file_stream.open(filename.c_str());
143      if ( output_file_stream )
144      {
145        out.push(output_file_stream);
146        std::copy(content.begin(), content.end(), std::ostream_iterator<T>(out));
147        return true;
148      }
149    }
150    else
151    {
152      output_file_stream.open(filename.c_str());
153      if ( output_file_stream )
154      {
155        std::copy(content.begin(), content.end(), std::ostream_iterator<T>(output_file_stream));
156        output_file_stream.close();
157        return true;
158      }
159    }
160    return false;
161  }
162
163  /*!
164   * \brief Reads file with given name and writes its content to given container
165   *
166   * \returns true iff file could be processed as expected
167   *
168   * \note If filename has suffix ".bz2" it is decompressed accordingly before reading.
169   */
170  template <class T>
171  static bool ReadContainerFromFile(std::vector<T> &content, const std::string& filename)
172  {
173    std::ifstream input_file_stream;
174    RRLIB_LOG_PRINT(rrlib::logging::eLL_DEBUG_VERBOSE_1, "got file <", filename, ">");
175    if (sStringUtils::EndsWith(filename, ".bz2"))
176    {
177      RRLIB_LOG_PRINT(rrlib::logging::eLL_DEBUG_VERBOSE_1, "decompressing");
178      boost::iostreams::filtering_istream in;
179      in.push(boost::iostreams::bzip2_decompressor());
180      input_file_stream.open(filename.c_str());
181      if (input_file_stream)
182      {
183        in.push(input_file_stream);
184        std::copy(std::istream_iterator<T>(in), std::istream_iterator<T>(), std::back_inserter(content));
185        return true;
186      }
187    }
188    else
189    {
190      input_file_stream.open(filename.c_str());
191      if (input_file_stream)
192      {
193        std::copy(std::istream_iterator<T>(input_file_stream), std::istream_iterator<T>(), std::back_inserter(content));
194      }
195      input_file_stream.close();
196      return true;
197    }
198    return false;
199  }
200
201
202
203
204  /*! Expands the given filename via a pipe and echo command in order to replace all contained environment variables with their actual value.
205   *
206   * \param file_name   file name to be expanded (will contain the result afterwards)
207   *
208   * \returns Whether the method could be executed without failure or not
209   */
210  static bool ShellExpandFilename(std::string &file_name) __attribute__((__warn_unused_result__));
211
212  /*! Expands the given filename via a pipe and echo command in order to replace all contained environment variables with their actual value.
213  *
214  * Thus variables as e.g. $MCAPROJECTHOME can be used for specifying OIV files in scene description files.
215  *
216  * \param result      reference to std::string object that should contain the result afterwards
217  * \param file_name   file name to be expanded
218  *
219  * \returns Whether the method could be executed without failure or not
220  */
221  static bool ShellExpandFilename(std::string &result, const std::string& file_name) __attribute__((__warn_unused_result__));
222
223
224  /*!
225   *    Splits the given filename into directory, single file name and file extension
226   *    \param complete_name complete file name (input)
227   *    \param file_dir directory (output)
228   *    \param file_base single file name (output)
229   *    \param file_ext file extension (output)
230   */
231  static void SplitFullQualifiedFilename(const std::string& complete_name, std::string& file_dir, std::string& file_base, std::string& file_ext);
232
233
234  /*!
235   * Retrieves network host name via "hostname" and returns result.
236   * \param fqdn whether FQDN  (Fully  Qualified Domain Name) or short name shall be retrieved
237   */
238  static std::string GetHostName(bool fqdn = true);
239
240
241  /*!
242   * Retrieves ip address of host with given network name via "gethostbyname" and returns result.
243   */
244  static struct in_addr HostToIpViaGetHostByName(const std::string& name);
245
246  /*!
247   * Retrieves ip address of host with given network name via "nslookup" and returns result.
248   */
249  static struct in_addr HostToIpViaNslookup(const std::string& name);
250
251  /*!
252   * Retrieves ip address of host with given network name via "host" and returns result.
253   */
254  static struct in_addr HostToIpViaHost(const std::string& name);
255
256  /*!
257   * Retrieves ip address of host with given network name from "/etc/hosts" and returns result.
258   */
259  static struct in_addr HostToIpViaHostsFile(const std::string& name);
260
261  /*!
262   * Retrieves ip address of host with given network name using
263   * 1. \sa HostToIpViaHostsFile()
264   * 2. \sa HostToIpViaHostx()
265   * 2. \sa HostToIpViaNslookup()
266   */
267  static struct in_addr HostToIp(const std::string& name);
268
269  /*!
270   * Fetches file with given source_file_name from server (either addressed by network name or ip address) at given source_directory
271   * and puts it to the given target_directory (via <system( rsync -av ...)> ).
272   *
273   * \params source_host_name network name of server
274   * \params source_host_ip_address ip address name of server (used alternatively to its name)
275   * \params source_directory directory on server
276   * \params source_file_name file to fetch from server
277   * \params target_directory local directory for fetched file
278   * \params optional_rsync_flags optional flags for rsync command, appended to -av
279   *
280   * \returns result of system call
281   */
282  static int RSyncFile(const std::string& source_host_name, const std::string& source_host_ip_address, const std::string& source_directory, const std::string& source_file_name, const std::string& target_directory, const std::string &optional_rsync_flags = "");
283
284
285  /*!
286   * Fetches files with given source_file_names from server (either addressed by network name or ip address) at given source_directory
287   * and puts it to the given target_directory (via <system( rsync -avr --files-from ...)> ). Uses temp file on local host to
288   * compose list with files to fetch.
289   *
290   * \params source_host_name network name of server
291   * \params source_host_ip_address ip address name of server (used alternatively to its name)
292   * \params source_directory directory on server
293   * \params source_file_names files to fetch from server
294   * \params target_directory local directory for fetched file
295   * \params optional_rsync_flags optional flags for rsync command, appended to -avr
296   *
297   * \returns result of system call
298   */
299  static int RSyncFiles(const std::string& source_host_name, const std::string& source_host_ip_address, const std::string& source_directory, const std::vector<std::string>& source_file_names, const std::string& target_directory, const std::string &optional_rsync_flags = "");
300
301
302  /*!
303   * Checks whether given file is available on local host or can be rsync'ed from resource server and returns full qualified file_name on local host.
304   * The following checks are performed (with decreasing priority):
305   * 1. check location of file: "./ + resource_repository + filename"
306   * 2. check location of file: "local_resource_directory + resource_repository + filename"
307   * 3. check location of file: "server_resource_directory + resource_repository + filename" --> rsync to "local_resource_directory + resource_repository + file_name"
308   * As soon as one check succeeds the remaining checks are not executed.
309   *
310   * \param file_name name of file to search and fetch (may contain relative path)
311   * \param full_local_file_name full qualified name of file on local host after successful check/fetch operation (result)
312   * \param resource_repository relative path to be used as resource repository (on local host and on server, may be empty)
313   * \param resource_server network name of resource server (optional)
314   * \param local_resource_directory absolute path to resource_repository on local host (may be empty)
315   * \param server_resource_directory absolute path to resource_repository on server (may be empty)
316   * \param use_cache whether to take local host name and server ip address from local static cache or not
317   *
318   * \returns success of check/fetch operation
319   */
320  static bool CheckAndGetFile(const std::string &file_name, std::string &full_local_file_name, const std::string& resource_repository = "", const std::string& resource_server = "", const std::string& local_resource_directory = "", const std::string& server_resource_directory = "", bool use_cache = false);
321
322  /*!
323   * Clear cached local host name and server ip addresses
324   * \sa CheckAndGetFile()
325   */
326  static void ClearCaches();
327
328  /*!
329   * Clear cached resource file names
330   * \sa CheckAndGetFile()
331   */
332  static void ClearResourceCache();
333
334private:
335  static std::string cached_local_host; //!< local static variable to store name of local host
336  static std::map<std::string, std::string> host_name_to_ip_cache; //!< local static variable to store server ip addresses
337  static std::map<std::string, std::string> resource_cache; //!< local static variable to store names of already loaded resource files
338};
339//----------------------------------------------------------------------
340// End of namespace declaration
341//----------------------------------------------------------------------
342}; // namespace util
343}; // namespace rrlib
344#endif
Note: See TracBrowser for help on using the repository browser.