]> pilppa.org Git - libplp.git/blob - src/FileUtil.cc
w1 independent file cleanups.
[libplp.git] / src / FileUtil.cc
1 /*
2  * FileUtil.cc
3  *
4  *  Created on: Mar 5, 2011
5  *      Author: lamikr
6  */
7
8 #include <algorithm>
9 #include <string>
10 #include <iostream>
11 #include <fstream>
12 #include <sstream>
13
14 #include <errno.h>
15 #include <string.h>
16 #include <sys/stat.h>
17 #include <stdbool.h>
18
19 #include "log.h"
20 #include "FileUtil.hh"
21 #include "DeviceConfig.hh"
22
23 using namespace std;
24 using namespace plp;
25
26 template <class NumberDataType>
27 bool string_to_number(NumberDataType& result,
28                  const std::string& string_param,
29                  std::ios_base& (*format)(std::ios_base&))
30 {
31         std::istringstream iss(string_param);
32         return !(iss >> format >> result).fail();
33 }
34
35 FileUtil::FileUtil() {
36 }
37
38 FileUtil::~FileUtil() {
39 }
40
41 char *FileUtil::parse_directory_path(const char *file_path) {
42         char    *p;
43         size_t  b_count;
44         size_t  f_size;
45         char    *ret_val;
46
47         ret_val = NULL;
48         if (file_path != NULL) {
49                 f_size  = 0;
50                 b_count = strlen(file_path);
51                 for (p = &((char *)file_path)[b_count]; p != (char *)file_path; p--) {
52                         f_size++;
53                         if ((*p == '/') ||
54                             (*p == '\\')) {
55                                 b_count = (b_count - f_size) + 1;
56                                 ret_val = strndup(file_path, b_count);
57                                 log_debug("dir: %s\n", ret_val);
58                                 break;
59                         }
60                 }
61         }
62         return ret_val;
63 }
64
65 bool FileUtil::mkdirs(const char *path) {
66         bool    ret_val;
67         char    *p;
68         int     err_flg;
69
70         ret_val = true;
71         if (path != NULL) {
72                 // go through each directory one by and and create if not exist
73                 for (p = (char *)path; *p; p++) {
74                     if ((p != path) &&
75                         ((*p == '/') ||
76                          (*p == '\\'))) {
77                                 *p = '\0';
78                                 // if dir does not exist, create it
79                                 if (access(path, F_OK) != 0) {
80                                         //log_debug("trying to create directory: %s\n", path);
81                                         err_flg = mkdir(path, S_IRWXU);
82                                         if (err_flg != 0) {
83                                                 log_error("Could not create directory: %s\n", path);
84                                                 ret_val = false;
85                                                 break;
86                                         }
87                                 }
88                                 *p = '/';
89                         }
90                 }
91                 if (ret_val == true) {
92                         // if dir does not exist, create it
93                         if (access(path, F_OK) != 0) {
94                                 //log_debug("trying to create directory: %s\n", path);
95                                 err_flg = mkdir(path, S_IRWXU);
96                                 if (err_flg != 0) {
97                                         log_error("Could not create directory: %s\n", path);
98                                         ret_val = false;
99                                 }
100                         }
101                 }
102         }
103         else {
104                 ret_val = false;
105                 log_error("Could not create NULL directory\n");
106         }
107         return ret_val;
108 }
109
110 std::ofstream *FileUtil::open_for_writing(const char *f_path) {
111         char            *d_path;
112         size_t          b_count;
113         ofstream        *ret_val;
114         bool            b_flg;
115
116         ret_val = NULL;
117         if (f_path != NULL) {
118                 b_count = strlen(f_path);
119                 if ((f_path[b_count - 1] != '/') &&
120                     (f_path[b_count - 1] != '\\')) {
121                         ret_val = new ofstream();
122                         ret_val->open(f_path, ios::app);
123                         if (ret_val->is_open() == false) {
124                                 d_path  = parse_directory_path(f_path);
125                                 if (d_path != NULL) {
126                                         b_flg   = mkdirs(d_path);
127                                         free(d_path);
128                                 }
129                                 if (b_flg == true) {
130                                         ret_val->open(f_path, ios::app);
131                                 }
132                         }
133                 }
134                 else {
135                         log_error("Could not open file, invalid file name. (%s)\n", f_path);
136                 }
137         }
138         else {
139                 log_error("Could not open file, invalid file name. (= NULL)\n");
140         }
141         return ret_val;
142 }
143
144 string FileUtil::concat_paths(string path_start, string path_end) {
145         return concat_paths(path_start.c_str(), path_end.c_str());
146 }
147
148 string FileUtil::concat_paths(const char *path_start, const char *path_end) {
149         string  ret_val;
150         string  end_str;
151         int     pos;
152         int     b_count;
153
154         if (path_start != NULL) {
155                 ret_val = path_start;
156                 if (path_end != NULL) {
157                         end_str = path_end;
158                         b_count = ret_val.length();
159                         pos     = ret_val.find_last_of("/");
160                         if (pos == (b_count -1)) {
161                                 ret_val.append(end_str);
162                         }
163                         else {
164                                 pos     = end_str.find_first_of("/");
165                                 if (pos == 0) {
166                                         ret_val.append(end_str);
167                                 }
168                                 else {
169                                         ret_val.append("/");
170                                         ret_val.append(end_str);
171                                 }
172                         }
173                 }
174         }
175         else {
176                 if (path_end != NULL) {
177                         ret_val = path_end;
178                 }
179         }
180         return ret_val;
181 }
182
183 bool FileUtil::is_subdirectory(const char *path, dirent *direntry) {
184         bool            ret_val;
185         struct stat     stat_info;
186         string          fname;
187
188         ret_val = false;
189         if (direntry != NULL) {
190                 if ((strcmp(direntry->d_name, ".") == 0) ||
191                     (strcmp(direntry->d_name, "..") == 0)) {
192                         ret_val = false;
193                 }
194                 else {
195                         fname   = concat_paths(path, direntry->d_name);
196                         stat(fname.c_str(), &stat_info);
197                         ret_val = S_ISDIR(stat_info.st_mode);
198                         //log_debug("stat for: %s: %d\n", fname.c_str(), ret_val);
199                 }
200         }
201         return ret_val;
202 }
203
204 bool FileUtil::is_datafile(const char *path, dirent *direntry) {
205         bool            ret_val;
206         struct stat     stat_info;
207         string          name;
208         int             pos;
209         string          fname;
210
211         ret_val = false;
212         if (direntry != NULL) {
213                 name    = direntry->d_name;
214                 pos     = name.find(DATAFILE_SUFFIX);
215                 if (pos > 0) {
216                         fname   = concat_paths(path, direntry->d_name);
217                         stat(fname.c_str(), &stat_info);
218                         ret_val = S_ISREG(stat_info.st_mode);
219                 }
220         }
221         return ret_val;
222 }
223
224 /**
225  * get sub-directories sorted in alphabetical order.
226  */
227 vector<string> FileUtil::get_subdirectories(const string& path) {
228         dirent          *direntry;
229         DIR             *dir;
230         bool            bool_flg;
231         vector<string>  ret_val;
232
233         //log_debug("scanning path: %s\n", path.c_str());
234         errno   = 0;
235         if (path.empty() == false) {
236                 dir     = opendir(path.c_str());
237                 if (dir) {
238                         while (true) {
239                                 errno           = 0;
240                                 direntry        = readdir(dir);
241                                 if (direntry != NULL) {
242                                         bool_flg        = is_subdirectory(path.c_str(), direntry);
243                                         if (bool_flg == true) {
244                                                 ret_val.push_back(string(direntry->d_name));
245                                                 //log_debug("added dir: %s\n", direntry->d_name);
246                                         }
247                                 }
248                                 else {
249                                         break;
250                                 }
251                         }
252                         closedir(dir);
253                         sort(ret_val.begin(), ret_val.end());
254                 }
255         }
256         return ret_val;
257 }
258
259 /**
260  * get sub-directories sorted in alphabetical order.
261  */
262 vector<string> FileUtil::get_data_files(const string& path) {
263         dirent          *direntry;
264         DIR             *dir;
265         vector<string>  ret_val;
266
267         errno   = 0;
268         if (path.empty() == false) {
269                 dir     = opendir(path.c_str());
270                 if (dir) {
271                         while (true) {
272                                 errno           = 0;
273                                 direntry        = readdir(dir);
274                                 if (direntry != NULL) {
275                                         if (is_datafile(path.c_str(), direntry) == true) {
276                                                 ret_val.push_back(string(direntry->d_name));
277                                         }
278                                 }
279                                 else {
280                                         break;
281                                 }
282                         }
283                         closedir(dir);
284                         sort(ret_val.begin(), ret_val.end());
285                 }
286         }
287         return ret_val;
288 }