1 /***************************************************************************
2 conf.cpp - description
3 -------------------
4 begin : august 1st, 2004
5 copyright : (C) 2004-2010 by Duong Khang NGUYEN
6 email : neoneurone @ gmail com
7
8 $Id: conf.cpp 450 2010-11-21 19:11:43Z neoneurone $
9 ***************************************************************************/
10
11 /***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * any later version. *
17 * *
18 ***************************************************************************/
19
20 #include "conf.h"
21
22 #include <fstream> // for file IO
23 #include <cerrno>
24 #include <cctype> // for isspace()
25 #include <cstring> // for C string functions
26
27
28 /*=====================================================================*/
29 const OPENCITY_ERR_CODE
Open(const string & fileName)30 Conf::Open( const string& fileName )
31 {
32 std::ifstream inFile( fileName.c_str() );
33
34 // Is the file opened ?
35 if ( inFile == NULL ) {
36 OPENCITY_DEBUG( "WARNING: File open error, see below: " );
37 OPENCITY_DEBUG( fileName.c_str() );
38 return OC_ERR_FILE;
39 }
40
41 char strTemp[ OC_MAX_CONF_LINE ];
42 char* strNew;
43 char* strFirst;
44 char* strSecond;
45 char* strEmpty = (char*)"";
46
47 // Read the first line
48 inFile.getline( strTemp, OC_MAX_CONF_LINE );
49 if ( !inFile.good() ) {
50 inFile.close();
51 OPENCITY_DEBUG( "WARNING: File read error" );
52 return OC_ERR_FILE;
53 }
54
55 // Process the file
56 while ( inFile.good() ) {
57 if ( (strlen(strTemp) != 0)
58 && (strTemp[0] != OC_CONF_COMMENT_START) ) {
59
60 strNew = strTemp;
61
62 // Get the first token, it's the name of the parameter
63 strFirst = strtok( strNew, OC_CONF_KEY_VALUE_SEPARATOR );
64
65 // Get the second token, it's the value of the parameter
66 strSecond = strtok( NULL, OC_CONF_KEY_VALUE_SEPARATOR );
67
68 // Trim out spaces from the datas if applicable
69 (strFirst != NULL) ? strFirst = Conf::RTrim( strFirst ) : strFirst = strEmpty;
70 (strSecond != NULL) ? strSecond = Conf::LTrim( strSecond ) : strSecond = strEmpty;
71
72 // Add the pair to the _mapData if the key is not empty
73 if (strlen(strFirst) > 0)
74 _mapData[ strFirst ] = strSecond;
75
76 //debug cout << "StrFirst/StrSecond: " << strFirst << "/" << strSecond << endl;
77 //debug
78 /*
79 __gnu_cxx::hash<const char *> H;
80 cout << "'" << (string) strFirst << "' = '" << (string) strSecond << "'" << endl;
81 cout << "hash : " << H(strFirst) << " / " << H(strSecond) << endl;
82 cout << (long) strFirst << "=" << (long) strSecond << endl;
83 cout << "new" << (long) strNew << endl;
84 delete strNew;
85 */
86 }
87
88 // Read the next line
89 inFile.getline( strTemp, OC_MAX_CONF_LINE );
90 }
91
92 // Close the file.
93 if (inFile.eof()) {
94 inFile.close();
95 return OC_ERR_FREE;
96 }
97
98 // Close the file on error.
99 inFile.close();
100 OPENCITY_DEBUG("FATAL: out of buffer ?");
101 assert( 0 );
102 return OC_ERR_SOMETHING;
103 }
104
105
106 /*=====================================================================*/
107 void
Close()108 Conf::Close()
109 {
110 //debug
111 /*
112 __gnu_cxx::hash_map<string, string, myHash>::iterator iter;
113 for ( iter = _mapData.begin(); iter != _mapData.end(); iter++ ) {
114 cout << "first '" << iter->first << "', second '" << iter->second << "'" << endl;
115 }
116 */
117 _mapData.clear();
118 }
119
120
121 /*=====================================================================*/
122 const string &
GetValue(const string & key,const string & defaultValue)123 Conf::GetValue(
124 const string& key,
125 const string& defaultValue )
126 {
127 //debug
128 /*cout << "key is : '" << key << "', data is : '" << _mapData[ key ] << "'" << endl;
129 __gnu_cxx::hash_map<string, string, myHash>::iterator
130 iter = _mapData.find( key );
131 return iter != _mapData.end() ? iter->second : "";
132 */
133
134 // IF the key is not in the hash_map THEN return the default value
135 if (_mapData.find( key ) == _mapData.end())
136 return defaultValue;
137 else
138 return _mapData[ key ];
139 }
140
141
142 /*=====================================================================*/
143 const OPENCITY_ERR_CODE
GetBool(const string & key,bool & rbool,const bool defaultValue)144 Conf::GetBool(
145 const string & key,
146 bool & rbool,
147 const bool defaultValue )
148 {
149 // IF the key is not in the hash_map THEN return the default value
150 if (_mapData.find( key ) == _mapData.end()) {
151 rbool = defaultValue;
152 return OC_ERR_FREE;
153 }
154
155 if (_mapData[key] == "") {
156 return OC_ERR_INVALID;
157 }
158
159 if ((strcasecmp(_mapData[key].c_str(), "no") == 0)
160 || (strcasecmp(_mapData[key].c_str(), "n") == 0)
161 || (strcasecmp(_mapData[key].c_str(), "false") == 0)
162 || (strcasecmp(_mapData[key].c_str(), "off") == 0)
163 || (strcasecmp(_mapData[key].c_str(), "0") == 0)) {
164 rbool = false;
165 }
166 else {
167 rbool = true;
168 }
169
170 return OC_ERR_FREE;
171 }
172
173
174 /*=====================================================================*/
175 const OPENCITY_ERR_CODE
GetLint(const string & key,OC_LINT & rlint,const OC_LINT defaultValue)176 Conf::GetLint(
177 const string & key,
178 OC_LINT & rlint,
179 const OC_LINT defaultValue )
180 {
181 /* debug
182 for (__gnu_cxx::hash_map<string, string, myHash>::iterator i = _mapData.begin();
183 i != _mapData.end(); i++) {
184 cout << "Map key: " << i->first << "/ value: " << i->second << endl;
185 }
186 */
187
188 // IF the key is not in the hash_map THEN return the default value
189 if (_mapData.find( key ) == _mapData.end()) {
190 //debug cout << "key: " << key << "/ default: " << def << endl;
191 rlint = defaultValue;
192 return OC_ERR_FREE;
193 }
194
195 errno = 0; // Reset the errno integer
196 rlint = strtol(_mapData[key].c_str(), NULL, 0);
197
198 //debug cout << __PRETTY_FUNCTION__ << "read: " << (long int)rlint << endl;
199
200 // FIXME: better check
201 if (errno != 0) {
202 OPENCITY_DEBUG( "Errno: " << errno << "/ Str: " << strerror(errno) );
203 return OC_ERR_INVALID;
204 }
205 else {
206 return OC_ERR_FREE;
207 }
208
209 // return OC_ERR_FREE;
210 }
211
212
213 /*=====================================================================*/
214 const OPENCITY_ERR_CODE
GetFloat(const string & key,float & rfloat,const float defaultValue)215 Conf::GetFloat(
216 const string& key,
217 float& rfloat,
218 const float defaultValue )
219 {
220 // IF the key is not in the hash_map THEN return the default value
221 if (_mapData.find( key ) == _mapData.end()) {
222 rfloat = defaultValue;
223 return OC_ERR_FREE;
224 }
225
226 // Win32 port
227 //rfloat = strtof(_mapData[key].c_str(), NULL);
228 rfloat = atof(_mapData[key].c_str());
229
230 return OC_ERR_FREE;
231 }
232
233
234 /*=====================================================================*/
235 /* STATIC METHOD */
236 /*=====================================================================*/
237 char* const
RTrim(char * const str)238 Conf::RTrim( char* const str )
239 {
240 char* strSpace = NULL;
241
242 if (str != NULL) {
243 strSpace = str + strlen( str ) - 1;
244 while ((strSpace >= str) && (isspace(*strSpace) != 0))
245 *strSpace-- = '\0';
246 }
247
248 return str;
249 }
250
251
252 /*=====================================================================*/
253 char* const
LTrim(char * const str)254 Conf::LTrim( char* const str )
255 {
256 char* strSpace = NULL;
257 char* strEnd = NULL;
258
259 if (str != NULL) {
260 strSpace = str;
261 strEnd = str;
262 strEnd = strEnd + strlen( str );
263 while ((strSpace < strEnd) && (isspace((unsigned char)*strSpace) != 0))
264 *strSpace++ = '\0';
265 }
266
267 return strSpace;
268 }
269
270
271
272
273
274
275
276
277
278
279
280
281
282