Mercurial > audlegacy-plugins
comparison src/projectm-1.0/ConfigFile.h @ 2136:9bdb5aba5e00
Backed out changeset 3bbb2673419b
I've decided to put the projectM 1.x plugin back for now.
author | William Pitcock <nenolod@atheme.org> |
---|---|
date | Sat, 27 Oct 2007 15:52:23 -0500 |
parents | a6d84a2cfaa7 |
children |
comparison
equal
deleted
inserted
replaced
2135:3bbb2673419b | 2136:9bdb5aba5e00 |
---|---|
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 | |
52 using std::string; | |
53 | |
54 class ConfigFile { | |
55 // Data | |
56 protected: | |
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 | |
65 // Methods | |
66 public: | |
67 ConfigFile( string filename, | |
68 string delimiter = "=", | |
69 string comment = "#", | |
70 string sentry = "EndConfigFile" ); | |
71 ConfigFile(); | |
72 | |
73 // Search for key and read value or optional default value | |
74 template<class T> T read( const string& key ) const; // call as read<T> | |
75 template<class T> T read( const string& key, const T& value ) const; | |
76 template<class T> bool readInto( T& var, const string& key ) const; | |
77 template<class T> | |
78 bool readInto( T& var, const string& key, const T& value ) const; | |
79 | |
80 // Modify keys and values | |
81 template<class T> void add( string key, const T& value ); | |
82 void remove( const string& key ); | |
83 | |
84 // Check whether key exists in configuration | |
85 bool keyExists( const string& key ) const; | |
86 | |
87 // Check or change configuration syntax | |
88 string getDelimiter() const { return myDelimiter; } | |
89 string getComment() const { return myComment; } | |
90 string getSentry() const { return mySentry; } | |
91 string setDelimiter( const string& s ) | |
92 { string old = myDelimiter; myDelimiter = s; return old; } | |
93 string setComment( const string& s ) | |
94 { string old = myComment; myComment = s; return old; } | |
95 | |
96 // Write or read configuration | |
97 friend std::ostream& operator<<( std::ostream& os, const ConfigFile& cf ); | |
98 friend std::istream& operator>>( std::istream& is, ConfigFile& cf ); | |
99 | |
100 protected: | |
101 template<class T> static string T_as_string( const T& t ); | |
102 template<class T> static T string_as_T( const string& s ); | |
103 static void trim( string& s ); | |
104 | |
105 | |
106 // Exception types | |
107 public: | |
108 struct file_not_found { | |
109 string filename; | |
110 file_not_found( const string& filename_ = string() ) | |
111 : filename(filename_) {} }; | |
112 struct key_not_found { // thrown only by T read(key) variant of read() | |
113 string key; | |
114 key_not_found( const string& key_ = string() ) | |
115 : key(key_) {} }; | |
116 }; | |
117 | |
118 | |
119 /* static */ | |
120 template<class T> | |
121 string ConfigFile::T_as_string( const T& t ) | |
122 { | |
123 // Convert from a T to a string | |
124 // Type T must support << operator | |
125 std::ostringstream ost; | |
126 ost << t; | |
127 return ost.str(); | |
128 } | |
129 | |
130 | |
131 /* static */ | |
132 template<class T> | |
133 T ConfigFile::string_as_T( const string& s ) | |
134 { | |
135 // Convert from a string to a T | |
136 // Type T must support >> operator | |
137 T t; | |
138 std::istringstream ist(s); | |
139 ist >> t; | |
140 return t; | |
141 } | |
142 | |
143 | |
144 /* static */ | |
145 template<> | |
146 inline string ConfigFile::string_as_T<string>( const string& s ) | |
147 { | |
148 // Convert from a string to a string | |
149 // In other words, do nothing | |
150 return s; | |
151 } | |
152 | |
153 | |
154 /* static */ | |
155 template<> | |
156 inline bool ConfigFile::string_as_T<bool>( const string& s ) | |
157 { | |
158 // Convert from a string to a bool | |
159 // Interpret "false", "F", "no", "n", "0" as false | |
160 // Interpret "true", "T", "yes", "y", "1", "-1", or anything else as true | |
161 bool b = true; | |
162 string sup = s; | |
163 for( string::iterator p = sup.begin(); p != sup.end(); ++p ) | |
164 *p = toupper(*p); // make string all caps | |
165 if( sup==string("FALSE") || sup==string("F") || | |
166 sup==string("NO") || sup==string("N") || | |
167 sup==string("0") || sup==string("NONE") ) | |
168 b = false; | |
169 return b; | |
170 } | |
171 | |
172 | |
173 template<class T> | |
174 T ConfigFile::read( const string& key ) const | |
175 { | |
176 // Read the value corresponding to key | |
177 mapci p = myContents.find(key); | |
178 if( p == myContents.end() ) throw key_not_found(key); | |
179 return string_as_T<T>( p->second ); | |
180 } | |
181 | |
182 | |
183 template<class T> | |
184 T ConfigFile::read( const string& key, const T& value ) const | |
185 { | |
186 // Return the value corresponding to key or given default value | |
187 // if key is not found | |
188 mapci p = myContents.find(key); | |
189 if( p == myContents.end() ) return value; | |
190 return string_as_T<T>( p->second ); | |
191 } | |
192 | |
193 | |
194 template<class T> | |
195 bool ConfigFile::readInto( T& var, const string& key ) const | |
196 { | |
197 // Get the value corresponding to key and store in var | |
198 // Return true if key is found | |
199 // Otherwise leave var untouched | |
200 mapci p = myContents.find(key); | |
201 bool found = ( p != myContents.end() ); | |
202 if( found ) var = string_as_T<T>( p->second ); | |
203 return found; | |
204 } | |
205 | |
206 | |
207 template<class T> | |
208 bool ConfigFile::readInto( T& var, const string& key, const T& value ) const | |
209 { | |
210 // Get the value corresponding to key and store in var | |
211 // Return true if key is found | |
212 // Otherwise set var to given default | |
213 mapci p = myContents.find(key); | |
214 bool found = ( p != myContents.end() ); | |
215 if( found ) | |
216 var = string_as_T<T>( p->second ); | |
217 else | |
218 var = value; | |
219 return found; | |
220 } | |
221 | |
222 | |
223 template<class T> | |
224 void ConfigFile::add( string key, const T& value ) | |
225 { | |
226 // Add a key with given value | |
227 string v = T_as_string( value ); | |
228 trim(key); | |
229 trim(v); | |
230 myContents[key] = v; | |
231 return; | |
232 } | |
233 | |
234 #endif // CONFIGFILE_H | |
235 | |
236 // Release notes: | |
237 // v1.0 21 May 1999 | |
238 // + First release | |
239 // + Template read() access only through non-member readConfigFile() | |
240 // + ConfigurationFileBool is only built-in helper class | |
241 // | |
242 // v2.0 3 May 2002 | |
243 // + Shortened name from ConfigurationFile to ConfigFile | |
244 // + Implemented template member functions | |
245 // + Changed default comment separator from % to # | |
246 // + Enabled reading of multiple-line values | |
247 // | |
248 // v2.1 24 May 2004 | |
249 // + Made template specializations inline to avoid compiler-dependent linkage | |
250 // + Allowed comments within multiple-line values | |
251 // + Enabled blank line termination for multiple-line values | |
252 // + Added optional sentry to detect end of configuration file | |
253 // + Rewrote messy trimWhitespace() function as elegant trim() |