Botan  2.1.0
Crypto and TLS for C++11
filesystem.cpp
Go to the documentation of this file.
1 /*
2 * (C) 2015 Jack Lloyd
3 * (C) 2015 Simon Warta (Kullo GmbH)
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/exceptn.h>
9 #include <botan/internal/filesystem.h>
10 #include <algorithm>
11 
12 #if defined(BOTAN_TARGET_OS_HAS_STL_FILESYSTEM_MSVC) && defined(BOTAN_BUILD_COMPILER_IS_MSVC)
13  #include <filesystem>
14 #elif defined(BOTAN_HAS_BOOST_FILESYSTEM)
15  #include <boost/filesystem.hpp>
16 #elif defined(BOTAN_TARGET_OS_HAS_READDIR)
17  #include <sys/types.h>
18  #include <sys/stat.h>
19  #include <dirent.h>
20  #include <deque>
21  #include <memory>
22  #include <functional>
23 #endif
24 
25 namespace Botan {
26 
27 namespace {
28 
29 #if defined(BOTAN_TARGET_OS_HAS_STL_FILESYSTEM_MSVC) && defined(BOTAN_BUILD_COMPILER_IS_MSVC)
30 std::vector<std::string> impl_stl_filesystem(const std::string& dir)
31  {
32  using namespace std::tr2::sys;
33 
34  std::vector<std::string> out;
35 
36  path p(dir);
37 
38  if (is_directory(p))
39  {
40  for (recursive_directory_iterator itr(p), end; itr != end; ++itr)
41  {
42  if (is_regular_file(itr->path()))
43  {
44  out.push_back(itr->path().string());
45  }
46  }
47  }
48 
49  return out;
50  }
51 #elif defined(BOTAN_HAS_BOOST_FILESYSTEM)
52 std::vector<std::string> impl_boost_filesystem(const std::string& dir_path)
53 {
54  namespace fs = boost::filesystem;
55 
56  std::vector<std::string> out;
57 
58  for(fs::recursive_directory_iterator dir(dir_path), end; dir != end; ++dir)
59  {
60  if(fs::is_regular_file(dir->path()))
61  {
62  out.push_back(dir->path().string());
63  }
64  }
65 
66  return out;
67 }
68 #elif defined(BOTAN_TARGET_OS_HAS_READDIR)
69 std::vector<std::string> impl_readdir(const std::string& dir_path)
70  {
71  std::vector<std::string> out;
72  std::deque<std::string> dir_list;
73  dir_list.push_back(dir_path);
74 
75  while(!dir_list.empty())
76  {
77  const std::string cur_path = dir_list[0];
78  dir_list.pop_front();
79 
80  std::unique_ptr<DIR, std::function<int (DIR*)>> dir(::opendir(cur_path.c_str()), ::closedir);
81 
82  if(dir)
83  {
84  while(struct dirent* dirent = ::readdir(dir.get()))
85  {
86  const std::string filename = dirent->d_name;
87  if(filename == "." || filename == "..")
88  continue;
89  const std::string full_path = cur_path + "/" + filename;
90 
91  struct stat stat_buf;
92 
93  if(::stat(full_path.c_str(), &stat_buf) == -1)
94  continue;
95 
96  if(S_ISDIR(stat_buf.st_mode))
97  dir_list.push_back(full_path);
98  else if(S_ISREG(stat_buf.st_mode))
99  out.push_back(full_path);
100  }
101  }
102  }
103 
104  return out;
105  }
106 #endif
107 
108 }
109 
110 std::vector<std::string> get_files_recursive(const std::string& dir)
111  {
112  std::vector<std::string> files;
113 
114 #if defined(BOTAN_TARGET_OS_HAS_STL_FILESYSTEM_MSVC) && defined(BOTAN_BUILD_COMPILER_IS_MSVC)
115  files = impl_stl_filesystem(dir);
116 #elif defined(BOTAN_HAS_BOOST_FILESYSTEM)
117  files = impl_boost_filesystem(dir);
118 #elif defined(BOTAN_TARGET_OS_HAS_READDIR)
119  files = impl_readdir(dir);
120 #else
121  BOTAN_UNUSED(dir);
122  throw No_Filesystem_Access();
123 #endif
124 
125  std::sort(files.begin(), files.end());
126 
127  return files;
128  }
129 
130 }
#define BOTAN_UNUSED(v)
Definition: assert.h:92
Definition: alg_id.cpp:13
std::vector< std::string > get_files_recursive(const std::string &dir)
Definition: filesystem.cpp:110