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