00001 #include "global.h"
00002 #include "MercuryINI.h"
00003 #include "MercuryUtil.h"
00004
00005
00006
00007
00008
00009 MercuryINI::MercuryINI( const MString &sFileName, bool bSaveOnExit )
00010 : m_bSaveOnExit( bSaveOnExit )
00011 {
00012 Open( sFileName );
00013 }
00014
00015 MercuryINI::~MercuryINI( )
00016 {
00017 if ( m_bSaveOnExit )
00018 {
00019 Save();
00020 }
00021 }
00022
00023 bool MercuryINI::Open( const MString &sFileName, bool bAddIncludes, bool bClearToStart )
00024 {
00025 if ( bClearToStart )
00026 m_mDatas.clear();
00027
00028 m_sFileName = sFileName;
00029 char * data;
00030 long len = DumpFromFile( sFileName, data );
00031 if ( len == -1)
00032 return false;
00033 bool ret = Load( data, len );
00034 free ( data );
00035
00036
00037
00038
00039
00040 if ( bAddIncludes )
00041 {
00042 MVector<MString> AllFiles;
00043 AllFiles.clear();
00044 EnumerateValues( "AdditionalFiles", AllFiles );
00045 for ( unsigned i = 0; i < AllFiles.size(); i++ )
00046 {
00047 if ( AllFiles.size() == 0 )
00048 continue;
00049 if ( m_mLoaded.find( AllFiles[i] ) != m_mLoaded.end() )
00050 continue;
00051 m_mLoaded[AllFiles[i]] = true;
00052 Open( AllFiles[i] );
00053 }
00054 }
00055 return ret;
00056 }
00057
00058 bool MercuryINI::Load( const char * sIniText, long slen )
00059 {
00060 int loc = 0;
00061 MString key = "";
00062 while ( loc < slen )
00063 {
00064 long k = BytesNUntil( sIniText, " ]\r\n", loc, slen, 4 );
00065 loc += k;
00066 if ( loc >= slen )
00067 break;
00068 char tchar = sIniText[loc];
00069 if ( tchar == '[' )
00070 {
00071 loc++;
00072 k = BytesUntil( sIniText, "]\r\n", loc, slen, 3 );
00073 key.assign( sIniText + loc, k );
00074 loc += k;
00075 } else {
00076 k = BytesUntil( sIniText,"=\r\n", loc, slen, 3 );
00077 MString sName, sValue;
00078 sName.assign( sIniText + loc, k );
00079 loc += k;
00080 if ( sIniText[loc] == '=' )
00081 {
00082 loc++;
00083 k = BytesUntil( sIniText, "\r\n", loc, slen, 2 );
00084 sValue.assign( sIniText + loc, k );
00085 loc +=k;
00086 }
00087 m_mDatas[key][sName] = sValue;
00088 }
00089 }
00090 return true;
00091 }
00092
00093 bool MercuryINI::Save( const MString sFileName )
00094 {
00095 MString sName = sFileName;
00096 if ( sName.length() == 0 )
00097 sName = m_sFileName;
00098 char * data;
00099 long len = Dump( data );
00100 bool ret = DumpToFile( sName, data, len );
00101 if ( data != NULL )
00102 free ( data );
00103 return ret;
00104 }
00105
00106 long MercuryINI::Dump( char * & toDump )
00107 {
00108 MString data;
00109 Dump( data );
00110 long len = data.length();
00111 toDump = (char *)malloc( len );
00112 memcpy( toDump, data.c_str(), len );
00113 return len;
00114 }
00115
00116 void MercuryINI::Dump( MString & data )
00117 {
00118 data = "";
00119
00120
00121 std::map< MString, MString >::iterator Xiter, Xend;
00122 Xend = m_mDatas[""].end();
00123 for ( Xiter = m_mDatas[""].begin(); Xiter != Xend; Xiter++ )
00124 {
00125 data += Xiter->first + '=' + ConvertToCFormat(Xiter->second) + PROPERRETURN;
00126 }
00127 data += PROPERRETURN;
00128
00129
00130
00131 std::map< MString, std::map< MString, MString > >::iterator iter,end;
00132 end = m_mDatas.end();
00133 for ( iter = m_mDatas.begin(); iter != end; iter++ )
00134 {
00135 MString key = iter->first;
00136 if ( key == "" )
00137 continue;
00138 data += "[" + key + "]" + PROPERRETURN;
00139 std::map< MString, MString >::iterator iter, end;
00140 end = m_mDatas[key].end();
00141 for ( iter = m_mDatas[key].begin(); iter != end; iter++ )
00142 {
00143 data += iter->first + '=' + ConvertToCFormat(iter->second) + PROPERRETURN;
00144 }
00145 data += PROPERRETURN;
00146 }
00147 }
00148
00149 void MercuryINI::EnumerateKeys( MVector<MString> &keys )
00150 {
00151 std::map< MString, std::map< MString, MString > >::iterator iter,end;
00152 end = m_mDatas.end();
00153 for ( iter = m_mDatas.begin(); iter != end; iter++ )
00154 keys.push_back( iter->first );
00155 }
00156
00157 void MercuryINI::EnumerateValues( const MString &key, MVector<MString> &values )
00158 {
00159 std::map< MString, MString >::iterator iter, end;
00160 end = m_mDatas[key].end();
00161 for ( iter = m_mDatas[key].begin(); iter != end; iter++ )
00162 values.push_back( iter->first );
00163 }
00164
00165 MString MercuryINI::GetValueS( const MString &key, const MString &value, MString sDefaultValue, bool bMakeValIfNoExist )
00166 {
00167 MString ret;
00168 if ( GetValue( key, value, ret ) )
00169 return ret;
00170 else
00171 {
00172 if ( bMakeValIfNoExist )
00173 SetValue( key, value, sDefaultValue );
00174 return sDefaultValue;
00175 }
00176 }
00177
00178 long MercuryINI::GetValueI( const MString &key, const MString &value, long iDefaultValue, bool bMakeValIfNoExist )
00179 {
00180 MString dat;
00181 if ( GetValue( key, value, dat ) )
00182 return atoi(dat.c_str());
00183 else
00184 {
00185 if ( bMakeValIfNoExist )
00186 SetValue( key, value, ssprintf("%ld", iDefaultValue ) );
00187 return iDefaultValue;
00188 }
00189 }
00190
00191 float MercuryINI::GetValueF( const MString &key, const MString &value, float fDefaultValue, bool bMakeValIfNoExist )
00192 {
00193 MString dat;
00194 if ( GetValue( key, value, dat ) )
00195 return float(atof(dat.c_str()));
00196 else
00197 {
00198 if ( bMakeValIfNoExist )
00199 SetValue( key, value, ssprintf("%f", fDefaultValue ) );
00200 return fDefaultValue;
00201 }
00202 }
00203
00204 bool MercuryINI::GetValueB( const MString &key, const MString &value, bool bDefaultValue, bool bMakeValIfNoExist )
00205 {
00206 MString dat;
00207 if ( GetValue( key, value, dat ) )
00208 return atoi(dat.c_str()) != 0;
00209 else
00210 {
00211 if ( bMakeValIfNoExist )
00212 SetValue( key, value, ssprintf("%i", bDefaultValue ) );
00213 return bDefaultValue;
00214 }
00215 }
00216
00217 bool MercuryINI::GetValue( const MString &key, const MString &value, MString &data )
00218 {
00219 if ( m_mDatas.find(key) != m_mDatas.end() )
00220 if ( m_mDatas[key].find( value ) != m_mDatas[key].end() )
00221 {
00222 data = m_mDatas[key][value];
00223 return true;
00224 }
00225 data = "";
00226 return false;
00227 }
00228
00229 void MercuryINI::SetValue( const MString &key, const MString &value, const MString& data )
00230 {
00231 m_mDatas[key][value] = data;
00232 }
00233
00234 bool MercuryINI::RemoveValue( const MString &key, const MString &value )
00235 {
00236 if ( m_mDatas[key].find( value ) == m_mDatas[key].end() )
00237 return false;
00238
00239 m_mDatas[key].erase( m_mDatas[key].find( value ) );
00240 return true;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270