]> git.stg.codes - stg.git/blob - stglibs/conffiles.lib/conffiles.cpp
В класс CONFIGFILE добавлена поддержка записи с переименованием
[stg.git] / stglibs / conffiles.lib / conffiles.cpp
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Date: 27.10.2002
19  */
20
21 /*
22  *    Author : Boris Mikhailenko <stg34@ua.fm>
23  */
24
25  /*
26  $Revision: 1.5 $
27  $Date: 2009/10/22 11:40:22 $
28  */
29
30 //---------------------------------------------------------------------------
31
32 // getpid
33 #include <sys/types.h>
34 #include <unistd.h>
35
36 #include <cerrno> // E*
37 #include <cstring>
38 #include <cstdlib>
39
40 #include <fstream>
41
42 #include "conffiles.h"
43 #include "common.h"
44
45 using namespace std;
46
47 //---------------------------------------------------------------------------
48 bool StringCaseCmp(const string & str1, const string & str2)
49 {
50 return (strcasecmp(str1.c_str(), str2.c_str()) < 0);
51 }
52 //---------------------------------------------------------------------------
53 CONFIGFILE::CONFIGFILE(const string & fn, bool nook)
54     : param_val(StringCaseCmp),
55       fileName(fn),
56       error(0)
57 {
58 ifstream f(fileName.c_str());
59
60 if (!f)
61     {
62     if (!nook)
63         error = -1;
64     return;
65     }
66
67 string line;
68 while (getline(f, line))
69     {
70     size_t pos = line.find('#');
71     if (pos != string::npos)
72         line.resize(pos);
73
74     if (line.find_first_not_of(" \t\r") == string::npos)
75         continue;
76
77     pos = line.find_first_of('=');
78     if (pos == string::npos)
79         {
80         error = -1;
81         return;
82         }
83
84     string parameter = line.substr(0, pos);
85     string value = line.substr(pos + 1);
86     param_val[parameter] = value;
87     }
88 }
89 //---------------------------------------------------------------------------
90 CONFIGFILE::~CONFIGFILE()
91 {
92 Flush();
93 }
94 //---------------------------------------------------------------------------
95 const string & CONFIGFILE::GetFileName() const
96 {
97 return fileName;
98 }
99 //---------------------------------------------------------------------------
100 int CONFIGFILE::Error() const
101 {
102 int e = error;
103 error = 0;
104 return e;
105 }
106 /*//---------------------------------------------------------------------------
107 int CONFIGFILE::ReadString(const string & param, char * str, int * maxLen, const char * defaultVal) const
108 {
109 it = param_val.find(param);
110 // îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
111
112 if (it != param_val.end())
113     {
114     // þÔÏ-ÔÏ ÓÔÏÉÔ
115     strncpy(str, param_val[param].c_str(), *maxLen);
116     *maxLen = param_val[param].size();
117     return 0;
118     }
119
120 strncpy(str, defaultVal, *maxLen);
121 *maxLen = strlen(defaultVal);
122 return -1;
123 }*/
124 //---------------------------------------------------------------------------
125 int CONFIGFILE::ReadString(const string & param, string * val, const string & defaultVal) const
126 {
127 const map<string, string>::const_iterator it(param_val.find(param));
128 // îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
129
130 if (it != param_val.end())
131     {
132     // þÔÏ-ÔÏ ÓÔÏÉÔ
133     *val = it->second;
134     return 0;
135     }
136
137 *val = defaultVal;
138 return -1;
139 }
140 //---------------------------------------------------------------------------
141 void CONFIGFILE::WriteString(const string & param, const string &val)
142 {
143 param_val[param] = val;
144 }
145 //---------------------------------------------------------------------------
146 int CONFIGFILE::ReadTime(const string & param, time_t * val, time_t defaultVal) const
147 {
148 const map<string, string>::const_iterator it(param_val.find(param));
149
150 if (it != param_val.end())
151     {
152     char *res;
153     *val = strtol(it->second.c_str(), &res, 10);
154     if (*res != 0)
155         {
156         *val = defaultVal; //Error!
157         return EINVAL;
158         }
159     return 0;
160     }
161
162 *val = defaultVal;
163 return -1;
164 }
165 //---------------------------------------------------------------------------
166 int CONFIGFILE::ReadInt(const string & param, int * val, int defaultVal) const
167 {
168 const map<string, string>::const_iterator it(param_val.find(param));
169 // îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
170
171 if (it != param_val.end())
172     {
173     // þÔÏ-ÔÏ ÓÔÏÉÔ
174     char *res;
175     *val = strtol(it->second.c_str(), &res, 10);
176     if (*res != 0)
177         {
178         *val = defaultVal; //Error!
179         return EINVAL;
180         }
181     return 0;
182     }
183
184 *val = defaultVal;
185 return -1;
186 }
187 //---------------------------------------------------------------------------
188 int CONFIGFILE::ReadUInt(const string & param, unsigned int * val, unsigned int defaultVal) const
189 {
190 const map<string, string>::const_iterator it(param_val.find(param));
191 // îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
192
193 if (it != param_val.end())
194     {
195     // þÔÏ-ÔÏ ÓÔÏÉÔ
196     char *res;
197     *val = strtoul(it->second.c_str(), &res, 10);
198     if (*res != 0)
199         {
200         *val = defaultVal; //Error!
201         return EINVAL;
202         }
203     return 0;
204     }
205
206 *val = defaultVal;
207 return -1;
208 }
209 //---------------------------------------------------------------------------
210 int CONFIGFILE::ReadLongInt(const string & param, long int * val, long int defaultVal) const
211 {
212 const map<string, string>::const_iterator it(param_val.find(param));
213 // îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
214
215 if (it != param_val.end())
216     {
217     // þÔÏ-ÔÏ ÓÔÏÉÔ
218     char *res;
219     *val = strtol(it->second.c_str(), &res, 10);
220     if (*res != 0)
221         {
222         *val = defaultVal; //Error!
223         return EINVAL;
224         }
225     return 0;
226     }
227
228 *val = defaultVal;
229 return -1;
230 }
231 //---------------------------------------------------------------------------
232 int CONFIGFILE::ReadULongInt(const string & param, unsigned long int * val, unsigned long int defaultVal) const
233 {
234 const map<string, string>::const_iterator it(param_val.find(param));
235 // îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
236
237 if (it != param_val.end())
238     {
239     // þÔÏ-ÔÏ ÓÔÏÉÔ
240     char *res;
241     *val = strtoul(it->second.c_str(), &res, 10);
242     if (*res != 0)
243         {
244         *val = defaultVal; //Error!
245         return EINVAL;
246         }
247     return 0;
248     }
249
250 *val = defaultVal;
251 return -1;
252 }
253 //---------------------------------------------------------------------------
254 int CONFIGFILE::ReadLongLongInt(const string & param, int64_t * val, int64_t defaultVal) const
255 {
256 const map<string, string>::const_iterator it(param_val.find(param));
257 // îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
258
259 if (it != param_val.end())
260     {
261     // þÔÏ-ÔÏ ÓÔÏÉÔ
262     char *res;
263     *val = strtoll(it->second.c_str(), &res, 10);
264     if (*res != 0)
265         {
266         *val = defaultVal; //Error!
267         return EINVAL;
268         }
269     return 0;
270     }
271
272 *val = defaultVal;
273 return -1;
274 }
275 //---------------------------------------------------------------------------
276 int CONFIGFILE::ReadULongLongInt(const string & param, uint64_t * val, uint64_t defaultVal) const
277 {
278 const map<string, string>::const_iterator it(param_val.find(param));
279 // îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
280
281 if (it != param_val.end())
282     {
283     // þÔÏ-ÔÏ ÓÔÏÉÔ
284     char *res;
285     *val = strtoull(it->second.c_str(), &res, 10);
286     if (*res != 0)
287         {
288         *val = defaultVal; //Error!
289         return EINVAL;
290         }
291     return 0;
292     }
293
294 *val = defaultVal;
295 return -1;
296 }
297 //---------------------------------------------------------------------------
298 int CONFIGFILE::ReadShortInt(const string & param, short int * val, short int defaultVal) const
299 {
300 const map<string, string>::const_iterator it(param_val.find(param));
301 // îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
302
303 if (it != param_val.end())
304     {
305     // þÔÏ-ÔÏ ÓÔÏÉÔ
306     char *res;
307     *val = (short)strtol(it->second.c_str(), &res, 10);
308     if (*res != 0)
309         {
310         *val = defaultVal; //Error!
311         return EINVAL;
312         }
313     return 0;
314     }
315
316 *val = defaultVal;
317 return -1;
318 }
319 //---------------------------------------------------------------------------
320 int CONFIGFILE::ReadUShortInt(const string & param, unsigned short int * val, unsigned short int defaultVal) const
321 {
322 const map<string, string>::const_iterator it(param_val.find(param));
323 // îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
324
325 if (it != param_val.end())
326     {
327     // þÔÏ-ÔÏ ÓÔÏÉÔ
328     char *res;
329     *val = (short)strtoul(it->second.c_str(), &res, 10);
330     if (*res != 0)
331         {
332         *val = defaultVal; //Error!
333         return EINVAL;
334         }
335     return 0;
336     }
337
338 *val = defaultVal;
339 return -1;
340 }
341 //---------------------------------------------------------------------------
342 void CONFIGFILE::WriteInt(const string & param, int64_t val)
343 {
344 string s;
345 x2str(val, s);
346 param_val[param] = s;
347 }
348 //---------------------------------------------------------------------------
349 int CONFIGFILE::ReadDouble(const string & param, double * val, double defaultVal) const
350 {
351 const map<string, string>::const_iterator it(param_val.find(param));
352 // îÁÛÌÉ ÎÕÖÎÕÀ ÐÅÒÅÍÅÎÎÕÀ
353
354 if (it != param_val.end())
355     {
356     // þÔÏ-ÔÏ ÓÔÏÉÔ
357     char *res;
358     *val = strtod(it->second.c_str(), &res);
359     if (*res != 0)
360         {
361         *val = defaultVal; //Error!
362         return EINVAL;
363         }
364     return 0;
365     }
366
367 *val = defaultVal;
368 return -1;
369 }
370 //---------------------------------------------------------------------------
371 void CONFIGFILE::WriteDouble(const string & param, double val)
372 {
373 char s[30];
374 snprintf(s, 30, "%f", val);
375 param_val[param] = s;
376 }
377 //---------------------------------------------------------------------------
378 int CONFIGFILE::Flush(const std::string & path) const
379 {
380 ofstream f(path.c_str());
381 if (!f.is_open())
382     {
383     error = EIO;
384     return EIO;
385     }
386
387 map<string, string>::const_iterator it = param_val.begin();
388 while (it != param_val.end())
389     {
390     f << it->first << "=" << it->second << "\n";
391     ++it;
392     }
393
394 f.close();
395 return 0;
396 }
397 //---------------------------------------------------------------------------
398 int CONFIGFILE::Flush() const
399 {
400 std::string pid;
401 x2str(getpid(), pid);
402
403 if (Flush(fileName + "." + pid))
404     return -1;
405
406 if (rename((fileName + "." + pid).c_str(), fileName.c_str()))
407     return -1;
408
409 return 0;
410 }
411 //---------------------------------------------------------------------------