source: rrlib_util/fileio.cpp @ 145:ace18c6c0493

Last change on this file since 145:ace18c6c0493 was 145:ace18c6c0493, checked in by Jens Wettach <wettach@…>, 4 years ago

cleaned code; added function for retrieving extension from a file name

File size: 10.5 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 modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (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 along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    rrlib/util/sFileIOUtils.cpp
23 *
24 * \author  Bernd Helge Schaefer
25 * \author  Jens Wettach
26 * \author  Tim Braun
27 *
28 * \date    2016-04-28
29 *
30 */
31//----------------------------------------------------------------------
32// Includes
33//----------------------------------------------------------------------
34#include "rrlib/util/fileio.h"
35
36#include <algorithm>
37#include <iostream>
38#include <fstream>
39#include <sstream>
40#include <iterator>
41
42extern "C"
43{
44#include <unistd.h>
45#include <dirent.h>
46#include <wordexp.h>
47#include <sys/stat.h>
48#include <sys/types.h>
49}
50
51#include "rrlib/util/join.h"
52#include "rrlib/logging/messages.h"
53
54//----------------------------------------------------------------------
55// Debug
56//----------------------------------------------------------------------
57#include <cassert>
58#include <cstring>
59#include <cerrno>
60
61//----------------------------------------------------------------------
62// Namespace usage
63//----------------------------------------------------------------------
64using namespace std;
65
66//----------------------------------------------------------------------
67// Namespace declaration
68//----------------------------------------------------------------------
69namespace rrlib
70{
71namespace util
72{
73namespace fileio
74{
75
76
77//----------------------------------------------------------------------
78// GetAllFilesInDirectory()
79//----------------------------------------------------------------------
80bool GetAllFilesInDirectory(const std::string& dir, std::vector<std::string> &files)
81{
82  DIR *dp;
83  struct dirent *dirp;
84  files.clear();
85  if ((dp  = opendir(dir.c_str())) == NULL)
86  {
87    throw runtime_error("Cannot open directory " + dir + ": " + strerror(errno));
88  }
89
90  while ((dirp = readdir(dp)) != NULL)
91  {
92    files.push_back(std::string(dirp->d_name));
93  }
94
95  closedir(dp);
96  return true;
97}
98
99
100
101//----------------------------------------------------------------------
102// GetCurrentDirectory()
103//----------------------------------------------------------------------
104std::string GetCurrentDirectory()
105{
106  char *temp_path(nullptr);
107  // POSIX.1 extension allocates buffer for path if given buffer is NULL and size = 0
108  temp_path = getcwd(temp_path, 0);
109  if (temp_path == nullptr)
110  {
111    throw runtime_error("Cannot get current directory: " + string(strerror(errno)));
112  }
113  std::string path(temp_path);
114  path += "/";
115  free(temp_path);
116  return path;
117}
118
119//----------------------------------------------------------------------
120// ChangeCurrentDirectory()
121//----------------------------------------------------------------------
122bool ChangeCurrentDirectory(const std::string& dir)
123{
124  if (chdir(dir.c_str()) != 0)
125  {
126    throw runtime_error("Cannot change to directory <" + dir + ">: " + strerror(errno));
127  }
128  return true;
129}
130
131//----------------------------------------------------------------------
132// CreateDirectory()
133//----------------------------------------------------------------------
134bool CreateDirectory(const std::string& path)    //throw(runtime_error)
135{
136  if (mkdir(path.c_str(), S_IFDIR | S_IRWXU) != 0)
137  {
138    throw runtime_error("Cannot create directory <" + path + ">: " + strerror(errno));
139  }
140  return true;
141}
142
143//----------------------------------------------------------------------
144// CreateTemp()
145//----------------------------------------------------------------------
146std::string CreateTemp(const std::string& root_directory, bool directory)
147{
148  std::string command = std::string("mktemp") + (directory ? " -d " : "") + (!root_directory.empty() ? (" -p " + root_directory) : "");
149  RRLIB_LOG_PRINT(DEBUG, "executing command <", command, ">");
150  FILE * pipe = popen(command.c_str(), "r");
151  char buf[ 1024 ];
152  if (fgets(buf, sizeof(buf), pipe) == 0)
153  {
154    throw runtime_error("Error creating temp file!");
155  }
156  std::string tempfile = buf;
157  tempfile = tempfile.substr(0, tempfile.find("\n"));
158  pclose(pipe);
159  return tempfile;
160} // CreateTemp()
161
162//----------------------------------------------------------------------
163// CreateTempFile()
164//----------------------------------------------------------------------
165std::string CreateTempFile(const std::string& root_directory)
166{
167  return CreateTemp(root_directory, false);
168} // CreateTempFile()
169
170//----------------------------------------------------------------------
171// CreateTempDirectory()
172//----------------------------------------------------------------------
173std::string CreateTempDirectory(const std::string& root_directory)
174{
175  return CreateTemp(root_directory, true);
176} // CreateTempDirectory()
177
178//----------------------------------------------------------------------
179// DeleteFile()
180//----------------------------------------------------------------------
181bool DeleteFile(const std::string& file_name)
182{
183  if (remove(file_name.c_str()) != 0)
184  {
185    throw runtime_error("Could not delete file <" + file_name + ">: " + strerror(errno));
186  }
187  return true;
188} // DeleteFile()
189
190//----------------------------------------------------------------------
191// DeleteDirectory()
192//----------------------------------------------------------------------
193bool DeleteDirectory(const std::string& directoryname)
194{
195  if (remove(directoryname.c_str()) != 0)
196  {
197    throw runtime_error("Could not delete directory <" + directoryname + ">: " + strerror(errno));
198  }
199  return true;
200}
201
202//----------------------------------------------------------------------
203// FileExists()
204//----------------------------------------------------------------------
205bool FileExists(const std::string &file_name)
206{
207  return (access(file_name.c_str(), F_OK) != -1);
208} // FileExists()
209
210
211//----------------------------------------------------------------------
212// CountLineNumbers()
213//----------------------------------------------------------------------
214size_t CountLineNumbers(const std::string &file_name)
215{
216  std::ifstream file(file_name);
217  if (!file.good())
218    throw runtime_error("Could not open file <" + file_name + ">.");
219  return std::count(std::istreambuf_iterator<char>(file),
220                    std::istreambuf_iterator<char>(), '\n');
221} // CountLineNumbers()
222
223
224//----------------------------------------------------------------------
225// ShellExpandFilename()
226//----------------------------------------------------------------------
227bool ShellExpandFilename(std::string &file_name)
228{
229  return ShellExpandFilename(file_name, file_name);
230} // ShellExpandFilename()
231
232
233//----------------------------------------------------------------------
234// ShellExpandFilename()
235//----------------------------------------------------------------------
236std::string ShellExpandFilename(const std::string &file_name)
237{
238  std::string result("");
239  if (!ShellExpandFilename(result, file_name))
240    throw runtime_error("Cannot expand file name <" + file_name + ">");
241  return result;
242} // ShellExpandFilename()
243
244
245//----------------------------------------------------------------------
246// ShellExpandFilename()
247//----------------------------------------------------------------------
248bool ShellExpandFilename(std::string &result, const std::string &file_name)
249{
250  std::string file_name_to_expand(file_name);
251  result.clear();
252  wordexp_t expansion;
253  int error = wordexp(file_name_to_expand.c_str(), &expansion, WRDE_SHOWERR | WRDE_UNDEF);
254  if (error)
255  {
256    const char *error_msg = 0;
257    switch (error)
258    {
259    case WRDE_BADCHAR:
260      error_msg = "Illegal occurrence of newline or one of |, &, ;, <, >, (, ), {, }";
261      break;
262    case WRDE_BADVAL:
263      error_msg = "An undefined shell variable was referenced";
264      break;
265    case WRDE_NOSPACE:
266      error_msg = "Out of memory";
267      break;
268    case WRDE_SYNTAX:
269      error_msg = "Shell syntax error, such as unbalanced parentheses or unmatched quotes";
270      break;
271    default:
272      error_msg = "Unknown error";
273    }
274    throw std::runtime_error("Could not expand '" + file_name_to_expand + "': " + error_msg + "!");
275  }
276
277  std::stringstream stream;
278  stream << util::Join(expansion.we_wordv + expansion.we_offs, expansion.we_wordv + expansion.we_offs + expansion.we_wordc, " ");
279  wordfree(&expansion);
280
281  result = stream.str();
282
283  return true;
284} // ShellExpandFilename()
285
286
287//----------------------------------------------------------------------
288// SplitFullQualifiedFilename()
289//----------------------------------------------------------------------
290void SplitFullQualifiedFilename(const std::string& complete_name, std::string& file_dir, std::string& file_base, std::string& file_ext)
291{
292
293  std::string::size_type pos_slash = complete_name.find_last_of("/");
294  std::string::size_type pos_name = pos_slash + 1;
295
296  if (pos_slash == std::string::npos)
297  {
298    // no slash found
299    file_dir = "./";
300    pos_name = 0;
301    pos_slash = 0;
302  }
303  else
304  {
305    file_dir = complete_name.substr(0, pos_slash);
306  }
307
308  std::string::size_type pos_dot = complete_name.find_last_of(".");
309  if (pos_dot == std::string::npos || pos_dot < pos_slash)
310  {
311    // no dot found or dot in directory
312    file_base = complete_name.substr(pos_name);
313    file_ext = "";
314  }
315  else
316  {
317    file_base = complete_name.substr(pos_name, pos_dot - pos_name);
318    file_ext = complete_name.substr(pos_dot);
319  }
320
321} // SplitFullQualifiedFilename()
322
323
324//----------------------------------------------------------------------
325// GetFileExtension()
326//----------------------------------------------------------------------
327std::string GetFileExtension(const std::string &file_name)
328{
329  auto pos = file_name.rfind('.');
330  if (pos != std::string::npos)
331  {
332    return file_name.substr(pos + 1);
333  }
334  else
335  {
336    RRLIB_LOG_PRINT(WARNING, "No file extension found in file name <", file_name, ">.");
337    return "";
338  }
339} // GetFileExtension()
340
341
342//----------------------------------------------------------------------
343// End of namespace declaration
344//----------------------------------------------------------------------
345}
346}
347}
Note: See TracBrowser for help on using the repository browser.