wsdlpull 1.23
Loading...
Searching...
No Matches
ConfigFile.h
Go to the documentation of this file.
1// ConfigFile.h
2// Class for reading named values from configuration files
3// Richard J. Wagner v2.1 24 May 2004 wagnerr@umich.edu
4
5// Copyright (c) 2004 Richard J. Wagner
6//
7// Permission is hereby granted, free of charge, to any person obtaining a copy
8// of this software and associated documentation files (the "Software"), to
9// deal in the Software without restriction, including without limitation the
10// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11// sell copies of the Software, and to permit persons to whom the Software is
12// furnished to do so, subject to the following conditions:
13//
14// The above copyright notice and this permission notice shall be included in
15// all copies or substantial portions of the Software.
16//
17// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23// IN THE SOFTWARE.
24
25// Typical usage
26// -------------
27//
28// Given a configuration file "settings.inp":
29// atoms = 25
30// length = 8.0 # nanometers
31// name = Reece Surcher
32//
33// Named values are read in various ways, with or without default values:
34// ConfigFile config( "settings.inp" );
35// int atoms = config.read<int>( "atoms" );
36// double length = config.read( "length", 10.0 );
37// string author, title;
38// config.readInto( author, "name" );
39// config.readInto( title, "title", string("Untitled") );
40//
41// See file example.cpp for more examples.
42
43#ifndef CONFIGFILE_H
44#define CONFIGFILE_H
45
46#include <string>
47#include <map>
48#include <iostream>
49#include <fstream>
50#include <sstream>
51
52using std::string;
53
55// Data
56protected:
57 string myDelimiter; // separator between key and value
58 string myComment; // separator between value and comments
59 string mySentry; // optional string to signal end of file
60 std::map<string,string> myContents; // extracted keys and values
61
62 typedef std::map<string,string>::iterator mapi;
63 typedef std::map<string,string>::const_iterator mapci;
64 std::string file;
66
67// Methods
68public:
69 ConfigFile( string filename,
70 bool isList=false,
71 string delimiter = "=",
72 string comment = "##",
73 string sentry = "EndConfigFile"
74 );
75 ConfigFile();
76
77 // Search for key and read value or optional default value
78 template<class T> T read( const string& key ) const; // call as read<T>
79 template<class T> T read( const string& key, const T& value ) const;
80 template<class T> bool readInto( T& var, const string& key ) const;
81 template<class T>
82 bool readInto( T& var, const string& key, const T& value ) const;
83
84 // Modify keys and values
85 template<class T> void add( string key, const T& value ,bool store=false);
86 template<class T> void add( const T& key ,bool store=false); //for simple list mode
87 void remove( const string& key );
88 template<class T>void remove( const T& key );//simple list mode
89
90 // Check whether key exists in configuration
91 bool keyExists( const string& key ) const;
92 template<class T> bool keyExists(const T & key) const;//for list mode
93
94 // Check or change configuration syntax
95 string getDelimiter() const { return myDelimiter; }
96 string getComment() const { return myComment; }
97 string getSentry() const { return mySentry; }
98 string setDelimiter( const string& s )
99 { string old = myDelimiter; myDelimiter = s; return old; }
100 string setComment( const string& s )
101 { string old = myComment; myComment = s; return old; }
102
103 // Write or read configuration
104 friend std::ostream& operator<<( std::ostream& os, const ConfigFile& cf );
105 friend std::istream& operator>>( std::istream& is, ConfigFile& cf );
106
107 void load(string filename,bool isList=false);
108 void save();
109
110protected:
111 template<class T> static string T_as_string( const T& t );
112 template<class T> static T string_as_T( const string& s );
113 static void trim( string& s );
114
115
116// Exception types
117public:
119 string filename;
120 file_not_found( const string& filename_ = string() )
121 : filename(filename_) {} };
122 struct key_not_found { // thrown only by T read(key) variant of read()
123 string key;
124 key_not_found( const string& key_ = string() )
125 : key(key_) {} };
126};
127
128
129/* static */
130template<class T>
131string ConfigFile::T_as_string( const T& t )
132{
133 // Convert from a T to a string
134 // Type T must support << operator
135 std::ostringstream ost;
136 ost << t;
137 return ost.str();
138}
139
140
141/* static */
142template<class T>
143T ConfigFile::string_as_T( const string& s )
144{
145 // Convert from a string to a T
146 // Type T must support >> operator
147 T t;
148 std::istringstream ist(s);
149 ist >> t;
150 return t;
151}
152
153
154/* static */
155template<>
156inline string ConfigFile::string_as_T<string>( const string& s )
157{
158 // Convert from a string to a string
159 // In other words, do nothing
160 return s;
161}
162
163
164/* static */
165template<>
166inline bool ConfigFile::string_as_T<bool>( const string& s )
167{
168 // Convert from a string to a bool
169 // Interpret "false", "F", "no", "n", "0" as false
170 // Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true
171 bool b = true;
172 string sup = s;
173 for( string::iterator p = sup.begin(); p != sup.end(); ++p )
174 *p = toupper(*p); // make string all caps
175 if( sup==string("FALSE") || sup==string("F") ||
176 sup==string("NO") || sup==string("N") ||
177 sup==string("0") || sup==string("NONE") )
178 b = false;
179 return b;
180}
181
182
183template<class T>
184T ConfigFile::read( const string& key ) const
185{
186 // Read the value corresponding to key
187 mapci p = myContents.find(key);
188 if( p == myContents.end() ) throw key_not_found(key);
189 return string_as_T<T>( p->second );
190}
191
192
193template<class T>
194T ConfigFile::read( const string& key, const T& value ) const
195{
196 // Return the value corresponding to key or given default value
197 // if key is not found
198 mapci p = myContents.find(key);
199 if( p == myContents.end() ) return value;
200 return string_as_T<T>( p->second );
201}
202
203
204template<class T>
205bool ConfigFile::readInto( T& var, const string& key ) const
206{
207 // Get the value corresponding to key and store in var
208 // Return true if key is found
209 // Otherwise leave var untouched
210 mapci p = myContents.find(key);
211 bool found = ( p != myContents.end() );
212 if( found ) var = string_as_T<T>( p->second );
213 return found;
214}
215
216
217template<class T>
218bool ConfigFile::readInto( T& var, const string& key, const T& value ) const
219{
220 // Get the value corresponding to key and store in var
221 // Return true if key is found
222 // Otherwise set var to given default
223 mapci p = myContents.find(key);
224 bool found = ( p != myContents.end() );
225 if( found )
226 var = string_as_T<T>( p->second );
227 else
228 var = value;
229 return found;
230}
231
232
233template<class T>
234void ConfigFile::add( string key, const T& value ,bool store)
235{
236 // Add a key with given value
237 string v = T_as_string( value );
238 trim(key);
239 trim(v);
240 myContents[key] = v;
241 if (store)
242 {
243 //append the values in the file immediately
244 std::ofstream os(file.c_str(),std::ios::app);
245 os << key << " " << myDelimiter << " ";
246 os << v << std::endl;
247 os.close();
248 }
249 return;
250}
251//for a list mode kind of config file
252template<class T>
253void ConfigFile::add( const T& key ,bool store)
254{
255 if(keyExists(key))
256 return;
257 string v = T_as_string( key );
258 trim(v);
259 myContents[v] = " ";
260 if(store)
261 {
262 std::ofstream os(file.c_str(),std::ios::app);
263 os << v << std::endl;
264 os.close();
265 }
266
267}
268
269template<class T>
270void ConfigFile::remove( const T& key )
271{
272 if(keyExists(key))
273 return;
274 string v = T_as_string( key );
275 trim(v);
276 myContents.erase( myContents.find( v ) );
277 save();
278
279}
280template<class T>
281bool ConfigFile::keyExists(const T & key) const
282{
283
284 string v = T_as_string( key );
285 mapci p = myContents.find( v );
286 return ( p != myContents.end() );
287
288}
289#endif // CONFIGFILE_H
290
291// Release notes:
292// v1.0 21 May 1999
293// + First release
294// + Template read() access only through non-member readConfigFile()
295// + ConfigurationFileBool is only built-in helper class
296//
297// v2.0 3 May 2002
298// + Shortened name from ConfigurationFile to ConfigFile
299// + Implemented template member functions
300// + Changed default comment separator from % to #
301// + Enabled reading of multiple-line values
302//
303// v2.1 24 May 2004
304// + Made template specializations inline to avoid compiler-dependent linkage
305// + Allowed comments within multiple-line values
306// + Enabled blank line termination for multiple-line values
307// + Added optional sentry to detect end of configuration file
308// + Rewrote messy trimWhitespace() function as elegant trim()
friend std::istream & operator>>(std::istream &is, ConfigFile &cf)
bool listmode
Definition ConfigFile.h:65
bool readInto(T &var, const string &key) const
Definition ConfigFile.h:205
ConfigFile(string filename, bool isList=false, string delimiter="=", string comment="##", string sentry="EndConfigFile")
Definition ConfigFile.cpp:7
string myComment
Definition ConfigFile.h:58
string setComment(const string &s)
Definition ConfigFile.h:100
string getComment() const
Definition ConfigFile.h:96
string getSentry() const
Definition ConfigFile.h:97
static T string_as_T(const string &s)
Definition ConfigFile.h:143
static void trim(string &s)
friend std::ostream & operator<<(std::ostream &os, const ConfigFile &cf)
std::map< string, string > myContents
Definition ConfigFile.h:60
std::map< string, string >::iterator mapi
Definition ConfigFile.h:62
static string T_as_string(const T &t)
Definition ConfigFile.h:131
bool keyExists(const string &key) const
std::string file
Definition ConfigFile.h:64
void load(string filename, bool isList=false)
void save()
string getDelimiter() const
Definition ConfigFile.h:95
string myDelimiter
Definition ConfigFile.h:57
string mySentry
Definition ConfigFile.h:59
string setDelimiter(const string &s)
Definition ConfigFile.h:98
std::map< string, string >::const_iterator mapci
Definition ConfigFile.h:63
T read(const string &key) const
Definition ConfigFile.h:184
void add(string key, const T &value, bool store=false)
Definition ConfigFile.h:234
void remove(const string &key)
STL iterator class.
file_not_found(const string &filename_=string())
Definition ConfigFile.h:120
key_not_found(const string &key_=string())
Definition ConfigFile.h:124