![[]](/images/special/trans.gif)
LibN2L-4 Library Code ReferenceClassesCompounds Files Members Method Index Full Reference cConfiguration.cppGo to the documentation of this file.00001 /************************************************************************ 00002 Nova-2 Library (libN2L, or simply n2l) Game development C++ Library 00003 Copyright (C) 2003 Aaron Cameron 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; either 00008 version 2.1 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 A copy of the GNU Lesser General Public License has been provided with 00020 this library in the file 'COPYING'. 00021 00022 Contact information for the author of this library has been provided 00023 with this library in the file 'AUTHOR'. 00024 ************************************************************************/ 00025 00026 #include "cConfiguration.h" 00027 00028 #include "cConfParsingErrors.h" 00029 #include "cConfParsingError.h" 00030 #include "cConfFailedValidationException.h" 00031 00032 #include <vector> 00033 00034 #include <iostream> 00035 00036 using namespace std; 00037 using namespace std; 00038 00039 00040 /******************************************************************************/ 00041 namespace n2l 00042 { 00043 00044 /**************************************************************************/ 00045 cConfiguration::cConfiguration() 00046 { 00047 } 00048 00049 00050 /**************************************************************************/ 00051 cConfiguration::~cConfiguration() 00052 { 00053 } 00054 00055 00056 /**************************************************************************/ 00057 const cConfiguration::tConstIterator cConfiguration::begin() const 00058 { 00059 return mValues.begin(); 00060 } 00061 00062 00063 /**************************************************************************/ 00064 const cConfiguration::tIterator cConfiguration::begin() 00065 { 00066 return mValues.begin(); 00067 } 00068 00069 00070 /**************************************************************************/ 00071 const cConfiguration::tConstIterator cConfiguration::end() const 00072 { 00073 return mValues.end(); 00074 } 00075 00076 00077 /**************************************************************************/ 00078 const cConfiguration::tIterator cConfiguration::end() 00079 { 00080 return mValues.end(); 00081 } 00082 00083 00084 /**************************************************************************/ 00085 const cConfiguration::tConstIterator cConfiguration::find( 00086 const tString &iName ) const 00087 { 00088 const tString LCName( strToLower(iName) ); 00089 for (tContainer::const_iterator i = mValues.begin(); 00090 i!=mValues.end(); ++i) 00091 { 00092 if (strToLower(i->first) == LCName) 00093 return i; 00094 } 00095 return end(); 00096 } 00097 00098 00099 /**************************************************************************/ 00100 const cConfiguration::tIterator cConfiguration::find( 00101 const tString &iName ) 00102 { 00103 //return mValues.find(iName); 00104 const tString LCName( strToLower(iName) ); 00105 for (tContainer::iterator i = mValues.begin(); 00106 i!=mValues.end(); ++i) 00107 { 00108 if (strToLower(i->first) == LCName) 00109 return i; 00110 } 00111 return end(); 00112 } 00113 00114 /**************************************************************************/ 00115 const tBool cConfiguration::isSet( const tString & iName ) const 00116 { 00117 const tConstIterator Found = mValues.find(iName); 00118 return Found!=end(); 00119 } 00120 00121 /**************************************************************************/ 00122 cDynVar & cConfiguration::operator []( const tString & iName ) 00123 { 00124 tIterator i = find(iName); 00125 if (i==end()) return mValues[iName]; 00126 return i->second; 00127 } 00128 00129 00130 /**************************************************************************/ 00131 const cDynVar & cConfiguration::operator []( const tString & iName ) const 00132 { 00133 tConstIterator valueIT( find(iName) ); 00134 00135 if (valueIT==end()) 00136 throw cOutOfBoundsException("cConfiguration::operator []", 00137 tString("No such key: ")+iName); 00138 return valueIT->second; 00139 } 00140 00141 /**************************************************************************/ 00142 const cConfiguration::tIterator cConfiguration::erase( 00143 const tIterator iIt ) 00144 { 00145 tIterator temp = iIt; 00146 ++temp; 00147 mValues.erase(iIt); 00148 return temp; 00149 } 00150 00151 /**************************************************************************/ 00152 const tBool cConfiguration::empty() const 00153 { 00154 return mValues.empty(); 00155 } 00156 00157 00158 /**************************************************************************/ 00159 const cConfiguration::tSize cConfiguration::size() const 00160 { 00161 return mValues.size(); 00162 } 00163 00164 00165 /**************************************************************************/ 00166 void cConfiguration::clear() 00167 { 00168 mValues.clear(); 00169 } 00170 00171 /**************************************************************************/ 00172 const cConfiguration cConfiguration::configDiff( 00173 const cConfiguration &iOther ) const 00174 { 00175 cConfiguration conf; 00176 for (tConstIterator ai = begin(); ai!=end(); ++ai) 00177 { 00178 if (!iOther.isSet(ai->first) || 00179 iOther[ai->first] != ai->second) 00180 { 00181 conf[ai->first] = ai->second; 00182 } 00183 } 00184 return conf; 00185 } 00186 00187 /**************************************************************************/ 00188 void cConfiguration::decodeBuffer( const tString &iEncodedBuffer ) 00189 { 00190 cConfParsingErrors errors; 00191 00192 vector<tString> lines; 00193 tString tempBuffer = substringReplace( "\r", "", iEncodedBuffer ); 00194 explode( tempBuffer,lines,'\n','\\','\"',false ); 00195 00196 tUint lineNumber = 1; 00197 vector<tString>::const_iterator lineIT = lines.begin(); 00198 const vector<tString>::const_iterator EndLineIT = lines.end(); 00199 for (; EndLineIT!=lineIT; ++lineIT,++lineNumber) { 00200 if (lineIT->empty()) continue; 00201 // Check for comments 00202 tString::size_type commentPos = findUnescaped( 00203 *lineIT,'#',0,'\\','\"'); 00204 tString lineToUse; 00205 if (commentPos!=tString::npos) 00206 lineToUse = lineIT->substr(0,commentPos); 00207 else lineToUse = *lineIT; 00208 tString::size_type eqPos = 00209 findUnescaped(lineToUse,'=',0,'\\','\"'); 00210 00211 if (trimmed(lineToUse).empty()) continue; 00212 if (eqPos==tString::npos) { 00213 errors.add( cConfParsingError( 00214 cConfParsingError::ErrorType_Syntax, 00215 "No \'=\' in configuration line", 00216 "","",lineNumber) ); 00217 continue; 00218 } 00219 tString key = unescapedString(trimmed(lineToUse.substr(0,eqPos)), 00220 '\\','\"'); 00221 if (key.empty()) { 00222 errors.add( cConfParsingError( 00223 cConfParsingError::ErrorType_Syntax, 00224 "No key in configuration line", 00225 "","",lineNumber) ); 00226 continue; 00227 } 00228 // const tContainer::const_iterator ExistingKeyIT = mValues.find(key); 00229 // if (ExistingKeyIT!=mValues.end()) ; // This is something we should 00230 // eventually report 00231 tString value = unescapedString(trimmed( 00232 lineToUse.substr(eqPos+1,(eqPos+1)-lineToUse.size()) ),'\\','\"'); 00233 cDynVar temp; 00234 temp.eval(value); 00235 (*this)[key] = temp; 00236 // mValues[key].eval(value); 00237 } 00238 if (!errors.empty()) 00239 throw cConfFailedValidationException( errors ); 00240 } 00241 00242 00243 /**************************************************************************/ 00244 const tString cConfiguration::encodeBuffer() const 00245 { 00246 # ifdef WIN32 00247 static const tString NL("\r\n"); 00248 # else 00249 static const tString NL("\n"); 00250 # endif 00251 00252 tString temp; 00253 tConstIterator setting = begin(); 00254 const tConstIterator EndSetting = end(); 00255 for (; EndSetting!=setting; ++setting) { 00256 temp += setting->first; 00257 temp += " =\t"; 00258 temp += tString(setting->second); 00259 temp += NL; 00260 } 00261 return temp; 00262 } 00263 00264 /**************************************************************************/ 00265 const tString cConfiguration::dump() const 00266 { 00267 # ifdef WIN32 00268 static const tString NL("\r\n"); 00269 # else 00270 static const tString NL("\n"); 00271 # endif 00272 tString temp("<configuration>\n"); 00273 tConstIterator setting = begin(); 00274 const tConstIterator EndSetting = end(); 00275 for (; EndSetting!=setting; ++setting) 00276 temp += (tString("\t") + setting->first + " =\t" + 00277 setting->second.dump() + NL); 00278 temp += "</configuration>"; 00279 return temp; 00280 } 00281 00282 00283 00284 } // namespace |