MercuryINI.cpp

Go to the documentation of this file.
00001 #include "global.h"
00002 #include "MercuryINI.h"
00003 #include "MercuryUtil.h"
00004 
00005 /*  IMPORTANT NOTE ON EDITING THIS FILE:
00006     MercuryLog uses this file, using MercuryLog in here may
00007     create hazardous operating conditions! */
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     //Tricky: We have to load all additional files
00037     //      and watch all the other files in our folder.
00038     //      Otherwise -- we go into infinite recursion.
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     //First dump out all non-keyed elements.
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     //Traverse both maps.
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  * Copyright (c) 2005-2006, Charles Lohr
00245  * All rights reserved.
00246  *
00247  * Redistribution and use in source and binary forms, with or
00248  * without modification, are permitted provided that the following
00249  * conditions are met:
00250  *  -   Redistributions of source code must retain the above
00251  *      copyright notice, this list of conditions and the following disclaimer.
00252  *  -   Redistributions in binary form must reproduce the above copyright
00253  *      notice, this list of conditions and the following disclaimer in
00254  *      the documentation and/or other materials provided with the distribution.
00255  *  -   Neither the name of the Mercury Engine nor the names of its
00256  *      contributors may be used to endorse or promote products derived from
00257  *      this software without specific prior written permission.
00258  *
00259  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00260  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00261  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00262  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00263  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00264  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00265  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00266  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00267  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00268  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00269  */
00270 

Hosted by SourceForge.net Logo