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