ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/auterman/Demo/PATJetIDAnalyzer/bin/ConfigFile.h
Revision: 1.1
Committed: Mon Feb 25 15:54:04 2008 UTC (17 years, 2 months ago) by auterman
Content type: text/plain
Branch point for: tex, JetID, Demo, MAIN
Log Message:
Initial revision

File Contents

# User Rev Content
1 auterman 1.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     #include <vector>
52    
53     using std::string;
54    
55    
56     template<class datatype> class bag_of : public std::vector<datatype> {
57     public:
58     bag_of(std::string s = "");
59     };
60    
61     template<class datatype> bag_of<datatype>::bag_of(std::string s)
62     : std::vector<datatype>::vector() {
63     // constructor
64     std::stringstream ss(s);
65    
66     datatype buffer;
67    
68     while (!ss.eof()) {
69     ss >> buffer;
70     this->push_back(buffer);
71     }
72     }
73    
74     class bag_of_string : public std::vector<std::string> {
75     public:
76     bag_of_string(std::string s = "null;");
77     };
78    
79    
80     class ConfigFile {
81     // Data
82     protected:
83     string myDelimiter; // separator between key and value
84     string myComment; // separator between value and comments
85     string mySentry; // optional string to signal end of file
86     std::map<string,string> myContents; // extracted keys and values
87    
88     typedef std::map<string,string>::iterator mapi;
89     typedef std::map<string,string>::const_iterator mapci;
90    
91     // Methods
92     public:
93     ConfigFile( string filename,
94     string delimiter = "=",
95     string comment = "#",
96     string sentry = "EndConfigFile" );
97     ConfigFile();
98    
99     // Search for key and read value or optional default value
100     template<class T> T read( const string& key ) const; // call as read<T>
101     template<class T> T read( const string& key, const T& value ) const;
102     template<class T> bool readInto( T& var, const string& key ) const;
103     template<class T> bool readInto( T& var, const string& key, const T& value ) const;
104    
105     // template<class T> std::vector<T> readvec( const string& key ) const;
106    
107     // Modify keys and values
108     template<class T> void add( string key, const T& value );
109     void remove( const string& key );
110    
111     // Check whether key exists in configuration
112     bool keyExists( const string& key ) const;
113    
114     // Check or change configuration syntax
115     string getDelimiter() const { return myDelimiter; }
116     string getComment() const { return myComment; }
117     string getSentry() const { return mySentry; }
118     string setDelimiter( const string& s )
119     { string old = myDelimiter; myDelimiter = s; return old; }
120     string setComment( const string& s )
121     { string old = myComment; myComment = s; return old; }
122    
123     // Write or read configuration
124     friend std::ostream& operator<<( std::ostream& os, const ConfigFile& cf );
125     friend std::istream& operator>>( std::istream& is, ConfigFile& cf );
126    
127     protected:
128     template<class T> static string T_as_string( const T& t );
129     template<class T> static T string_as_T( const string& s );
130     static void trim( string& s );
131    
132    
133     // Exception types
134     public:
135     struct file_not_found {
136     string filename;
137     file_not_found( const string& filename_ = string() )
138     : filename(filename_) {} };
139     struct key_not_found { // thrown only by T read(key) variant of read()
140     string key;
141     key_not_found( const string& key_ = string() )
142     : key(key_) {} };
143     };
144    
145    
146     /* static */
147     template<class T>
148     string ConfigFile::T_as_string( const T& t )
149     {
150     // Convert from a T to a string
151     // Type T must support << operator
152     std::ostringstream ost;
153     ost << t;
154     return ost.str();
155     }
156    
157    
158     /* static */
159     template<class T>
160     T ConfigFile::string_as_T( const string& s )
161     {
162     // Convert from a string to a T
163     // Type T must support >> operator
164     T t;
165     std::istringstream ist(s);
166     ist >> t;
167     return t;
168     }
169    
170    
171     /* static */
172     template<>
173     inline string ConfigFile::string_as_T<string>( const string& s )
174     {
175     // Convert from a string to a string
176     // In other words, do nothing
177     return s;
178     }
179    
180    
181     /* static */
182     template<>
183     inline bool ConfigFile::string_as_T<bool>( const string& s )
184     {
185     // Convert from a string to a bool
186     // Interpret "false", "F", "no", "n", "0" as false
187     // Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true
188     bool b = true;
189     string sup = s;
190     for( string::iterator p = sup.begin(); p != sup.end(); ++p )
191     *p = toupper(*p); // make string all caps
192     if( sup==string("FALSE") || sup==string("F") ||
193     sup==string("NO") || sup==string("N") ||
194     sup==string("0") || sup==string("NONE") )
195     b = false;
196     return b;
197     }
198    
199    
200     template<class T>
201     T ConfigFile::read( const string& key ) const
202     {
203     // Read the value corresponding to key
204     mapci p = myContents.find(key);
205     if( p == myContents.end() ) throw key_not_found(key);
206     return string_as_T<T>( p->second );
207     }
208    
209    
210     template<class T>
211     T ConfigFile::read( const string& key, const T& value ) const
212     {
213     // Return the value corresponding to key or given default value
214     // if key is not found
215     mapci p = myContents.find(key);
216     if( p == myContents.end() ) return value;
217     return string_as_T<T>( p->second );
218     }
219    
220     // CTA -------------------------------------------------------------------
221     //template<class T>
222     //std::vector<T> ConfigFile::readvec( const string& key ) const
223     //{
224     // std::vector<int> t;
225     // t.push_back(0);
226     // t.push_back(3);
227     // return t;
228     //}
229     // CTA -------------------------------------------------------------------
230    
231     template<class T>
232     bool ConfigFile::readInto( T& var, const string& key ) const
233     {
234     // Get the value corresponding to key and store in var
235     // Return true if key is found
236     // Otherwise leave var untouched
237     mapci p = myContents.find(key);
238     bool found = ( p != myContents.end() );
239     if( found ) var = string_as_T<T>( p->second );
240     return found;
241     }
242    
243    
244     template<class T>
245     bool ConfigFile::readInto( T& var, const string& key, const T& value ) const
246     {
247     // Get the value corresponding to key and store in var
248     // Return true if key is found
249     // Otherwise set var to given default
250     mapci p = myContents.find(key);
251     bool found = ( p != myContents.end() );
252     if( found )
253     var = string_as_T<T>( p->second );
254     else
255     var = value;
256     return found;
257     }
258    
259    
260     template<class T>
261     void ConfigFile::add( string key, const T& value )
262     {
263     // Add a key with given value
264     string v = T_as_string( value );
265     trim(key);
266     trim(v);
267     myContents[key] = v;
268     return;
269     }
270    
271     #endif // CONFIGFILE_H
272    
273     // Release notes:
274     // v1.0 21 May 1999
275     // + First release
276     // + Template read() access only through non-member readConfigFile()
277     // + ConfigurationFileBool is only built-in helper class
278     //
279     // v2.0 3 May 2002
280     // + Shortened name from ConfigurationFile to ConfigFile
281     // + Implemented template member functions
282     // + Changed default comment separator from % to #
283     // + Enabled reading of multiple-line values
284     //
285     // v2.1 24 May 2004
286     // + Made template specializations inline to avoid compiler-dependent linkage
287     // + Allowed comments within multiple-line values
288     // + Enabled blank line termination for multiple-line values
289     // + Added optional sentry to detect end of configuration file
290     // + Rewrote messy trimWhitespace() function as elegant trim()