979ee78ab9b90c3cbb81b1b070cf3379800dd48a
[hsd_doku_tool.git] / src / FSHelper.cxx
1 ///////////////////////////////////////////////////////////////////////////
2 // Workfile: FSHelper.cxx
3 // Author: Daniel Giritzer <daniel@giritzer.eu>
4 // Date: 26.04.2018
5 // Description: Diese Klasse stellt plattformunabhängige funktionen auf das
6 //              Dateisystem zur verfügung. Bei fehler werden exeptions
7 //              des Typs std::string geworfen.
8 // Remarks: -
9 ///////////////////////////////////////////////////////////////////////////
10 #include "FSHelper.h"
11 #include <fstream>
12 #include <dirent.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <cstring>
16 #include <algorithm>
17
18 std::vector<FSHelper::File> FSHelper::listFiles(std::string const &src)
19 {
20     std::vector<File> retVal;
21     DIR *dir;
22     struct dirent *ent;
23
24     if((dir = opendir(src.c_str())) != nullptr)
25     {
26         while((ent = readdir(dir)) != nullptr)
27         {
28             File curFile;
29             curFile.first = addDirLastSlash(std::string(src));
30             curFile.second = std::string(ent->d_name);
31             retVal.push_back(curFile);
32         }
33         closedir(dir);
34     }
35     else
36         throw std::string("Directory could not be opened!");
37
38     return retVal;
39 }
40
41 bool FSHelper::copyFile(std::string const &src, std::string const &dest)
42 {
43     std::ifstream srcStream(src, std::ios::in | std::ios_base::binary);
44
45     if(!srcStream.good())
46         return false;
47
48     std::ofstream destStream(dest, std::ios::out |std::ios_base::binary);
49
50     if(!destStream.good())
51         return false;
52
53     destStream << srcStream.rdbuf();
54
55     destStream.close();
56     srcStream.close();
57
58     return true;
59 }
60
61 bool FSHelper::makeDir(std::string const& dir)
62 {
63     if(!dirExists(dir))
64 #if defined(_WIN32)
65         if(mkdir(dir.c_str()) < 0)
66 #else
67         if(mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) < 0)
68 #endif
69             return false;
70
71     return true;
72 }
73
74 bool FSHelper::createFile(std::string const& path)
75 {
76     std::ofstream file(path);
77
78     if(!file.good())
79         return false;
80
81     file.close();
82
83     return true;
84 }
85
86 bool FSHelper::copyFolder(std::string const &src, std::string const &dest)
87 {
88     std::string from = addDirLastSlash(src);
89     std::string to = addDirLastSlash(dest);
90
91     if(!dirExists(addDirLastSlash(from)))
92         return false;
93
94     if(!makeDir(to))
95         return false;
96
97     std::vector<File> files;
98     if(!listFilesRecursive(from, files, true))
99         return false;
100
101     std::vector<std::string> folders;
102     if(!listFoldersRecursive(from, folders, true))
103         return false;
104
105     // Erstelle Ordnerbaum
106     for(auto folder : folders)
107     {
108         folder.replace(folder.find(from), from.length(), to);
109         if(!makeDir(addDirLastSlash(folder)))
110             return false;
111     }
112
113     // Kopiere Dateien
114     for(auto inFile : files)
115     {
116         File outFile = inFile;
117         unsigned int idx = 0;
118
119         // ersetze Qellordner mit zielordner
120         outFile.first.replace(outFile.first.find(from), from.length(), to);
121         if(!makeDir(addDirLastSlash(outFile.first)))
122             return false;
123
124         if(!copyFile(inFile.first + inFile.second, outFile.first + outFile.second))
125             return false;
126     }
127
128     return true;
129 }
130
131
132 bool FSHelper::validFileName(std::string const &fName)
133 {
134     char invalidChars[] = { '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '~', '`', ' ', '\\',
135                             ';', ':', '+', '=', '*', '/', '<', '>', '?', ',', '[', ']', '{', '}'
136                           };
137
138     int pos = fName.find_first_of(invalidChars, 0, sizeof(invalidChars));
139     if (pos != std::string::npos)
140         return false;
141
142     return true;
143 }
144
145 bool FSHelper::dirExists(std::string const &directory)
146 {
147     std::string dir = rmDirLastSlash(directory);
148
149     // überprüfe existenz
150     struct stat info;
151     if( stat( dir.c_str(), &info ) != 0 )
152         return false;
153     if( info.st_mode & S_IFDIR )
154         return true;
155     else
156         return false;
157 }
158
159 bool FSHelper::fileExists(std::string const &file)
160 {
161     std::ifstream f(file);
162     bool retVal = f.good();
163     f.close();
164     return retVal;
165 }
166
167 std::string FSHelper::addDirLastSlash(std::string const& dir)
168 {
169     if(dir.back() != '\\' && dir.back() != '/')
170 #if defined(_WIN32)
171         return dir + "\\";
172 #else
173         return dir + "/";
174 #endif
175     else
176         return dir;
177 }
178
179 std::string FSHelper::rmDirLastSlash(std::string const& dir)
180 {
181     if(dir.back() == '\\' && dir.back() == '/')
182         return dir.substr(0, dir.size()-1);
183     else
184         return dir;
185 }
186
187 bool FSHelper::listFilesRecursive(const std::string& path, std::vector<FSHelper::File>& files,const bool showHiddenDirs)
188 {
189     std::string dir = addDirLastSlash(path);
190     DIR *dpdf;
191     struct dirent *epdf;
192     dpdf = opendir(dir.c_str());
193     if(dpdf != nullptr)
194     {
195         while((epdf = readdir(dpdf)) != nullptr)
196         {
197             struct stat s;
198
199
200             if(stat((dir + std::string(epdf->d_name)).c_str(), &s) < 0)
201                 return false;
202
203             if(S_ISREG(s.st_mode))
204             {
205                 File curFile;
206
207                 curFile.first = std::string(addDirLastSlash(dir));
208                 curFile.second = std::string(epdf->d_name);
209                 files.push_back(curFile);
210             }
211             else if(showHiddenDirs ? (S_ISDIR(s.st_mode) && std::string(epdf->d_name) != ".." && std::string(epdf->d_name) != "." ) :
212                     (S_ISDIR(s.st_mode) && strstr(epdf->d_name,"..") == NULL && strstr(epdf->d_name,".") == NULL ))
213             {
214                 listFilesRecursive(dir+epdf->d_name,files, showHiddenDirs);
215             }
216         }
217     }
218     closedir(dpdf);
219     return true;
220 }
221
222
223 bool FSHelper::listFoldersRecursive(const std::string& path, std::vector<std::string>& folders,const bool showHiddenDirs)
224 {
225     std::string dir = addDirLastSlash(path);
226     DIR *dpdf;
227     struct dirent *epdf;
228     dpdf = opendir(dir.c_str());
229     if(dpdf != nullptr)
230     {
231         while((epdf = readdir(dpdf)) != nullptr)
232         {
233             struct stat s;
234
235             if(stat((dir + std::string(epdf->d_name)).c_str(), &s) < 0)
236                 return false;
237
238             else if(showHiddenDirs ? (S_ISDIR(s.st_mode) && std::string(epdf->d_name) != ".." && std::string(epdf->d_name) != "." ) :
239                     (S_ISDIR(s.st_mode) && strstr(epdf->d_name,"..") == NULL && strstr(epdf->d_name,".") == NULL ))
240             {
241                 if(!(std::find(folders.begin(), folders.end(), dir+epdf->d_name) != folders.end()))
242                     folders.push_back(addDirLastSlash(dir+epdf->d_name));
243                 listFoldersRecursive(dir+epdf->d_name,folders, showHiddenDirs);
244             }
245         }
246     }
247     closedir(dpdf);
248     return true;
249 }
250
251 std::string FSHelper::convertPathToWindows(std::string dir)
252 {
253     std::replace(dir.begin(), dir.end(), '/', '\\');
254     return dir;
255 }
256
257 std::string FSHelper::convertPathToUnix(std::string dir)
258 {
259     std::replace(dir.begin(), dir.end(), '\\', '/');
260     return dir;
261 }