2009-02-10 18:37:48 +00:00
/*
Copyright ( C ) 2004 Kimmo Pekkola
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
# pragma warning(disable: 4786)
# pragma warning(disable: 4996)
# include "ConfigParser.h"
# include "Litestep.h"
# include "Rainmeter.h"
2009-08-27 15:42:24 +00:00
# include <algorithm>
2009-02-10 18:37:48 +00:00
extern CRainmeter * Rainmeter ;
using namespace Gdiplus ;
/*
* * CConfigParser
* *
* * The constructor
* *
*/
CConfigParser : : CConfigParser ( )
{
2009-07-30 15:19:47 +00:00
m_Parser = MathParser_Create ( NULL ) ;
2009-02-10 18:37:48 +00:00
}
/*
* * ~ CConfigParser
* *
* * The destructor
* *
*/
CConfigParser : : ~ CConfigParser ( )
{
2009-07-30 15:19:47 +00:00
MathParser_Destroy ( m_Parser ) ;
2009-02-10 18:37:48 +00:00
}
/*
* * Initialize
* *
* *
*/
2009-07-26 21:08:46 +00:00
void CConfigParser : : Initialize ( LPCTSTR filename , CRainmeter * pRainmeter )
2009-02-10 18:37:48 +00:00
{
m_Filename = filename ;
2009-07-26 21:08:46 +00:00
m_Variables . clear ( ) ;
2009-08-26 17:37:15 +00:00
m_Measures . clear ( ) ;
2009-09-18 15:30:51 +00:00
m_Keys . clear ( ) ;
m_Values . clear ( ) ;
2009-09-19 07:15:28 +00:00
m_Sections . clear ( ) ;
2009-08-26 17:37:15 +00:00
2009-09-18 15:30:51 +00:00
// Set the default variables. Do this before the ini file is read so that the paths can be used with @include
2009-07-26 21:08:46 +00:00
if ( pRainmeter )
{
2009-08-27 15:42:24 +00:00
SetVariable ( L " PROGRAMPATH " , pRainmeter - > GetPath ( ) ) ;
SetVariable ( L " SETTINGSPATH " , pRainmeter - > GetSettingsPath ( ) ) ;
SetVariable ( L " SKINSPATH " , pRainmeter - > GetSkinPath ( ) ) ;
SetVariable ( L " PLUGINSPATH " , pRainmeter - > GetPluginPath ( ) ) ;
SetVariable ( L " CURRENTPATH " , CRainmeter : : ExtractPath ( filename ) ) ;
SetVariable ( L " ADDONSPATH " , pRainmeter - > GetPath ( ) + L " Addons \\ " ) ;
2009-07-30 15:19:47 +00:00
2009-08-01 11:46:15 +00:00
RECT workArea ;
SystemParametersInfo ( SPI_GETWORKAREA , 0 , & workArea , 0 ) ;
2009-07-30 15:19:47 +00:00
TCHAR buffer [ 256 ] ;
2009-08-01 15:38:03 +00:00
swprintf ( buffer , L " %i " , workArea . left ) ;
2009-08-27 15:42:24 +00:00
SetVariable ( L " WORKAREAX " , buffer ) ;
2009-08-01 15:38:03 +00:00
swprintf ( buffer , L " %i " , workArea . top ) ;
2009-08-27 15:42:24 +00:00
SetVariable ( L " WORKAREAY " , buffer ) ;
2009-08-01 11:46:15 +00:00
swprintf ( buffer , L " %i " , workArea . right - workArea . left ) ;
2009-08-27 15:42:24 +00:00
SetVariable ( L " WORKAREAWIDTH " , buffer ) ;
2009-08-01 11:46:15 +00:00
swprintf ( buffer , L " %i " , workArea . bottom - workArea . top ) ;
2009-08-27 15:42:24 +00:00
SetVariable ( L " WORKAREAHEIGHT " , buffer ) ;
2009-07-30 15:19:47 +00:00
swprintf ( buffer , L " %i " , GetSystemMetrics ( SM_CXSCREEN ) ) ;
2009-08-27 15:42:24 +00:00
SetVariable ( L " SCREENAREAWIDTH " , buffer ) ;
2009-07-30 15:19:47 +00:00
swprintf ( buffer , L " %i " , GetSystemMetrics ( SM_CYSCREEN ) ) ;
2009-08-27 15:42:24 +00:00
SetVariable ( L " SCREENAREAHEIGHT " , buffer ) ;
2009-07-26 21:08:46 +00:00
}
2009-09-18 15:30:51 +00:00
ReadIniFile ( m_Filename ) ;
2009-02-10 18:37:48 +00:00
ReadVariables ( ) ;
}
/*
* * ReadVariables
* *
* *
*/
void CConfigParser : : ReadVariables ( )
{
2009-08-26 17:37:15 +00:00
std : : vector < std : : wstring > listVariables = GetKeys ( L " Variables " ) ;
2009-02-10 18:37:48 +00:00
2009-08-26 17:37:15 +00:00
for ( size_t i = 0 ; i < listVariables . size ( ) ; i + + )
2009-02-10 18:37:48 +00:00
{
2009-08-27 16:04:06 +00:00
SetVariable ( listVariables [ i ] , ReadString ( L " Variables " , listVariables [ i ] . c_str ( ) , L " " , false ) ) ;
2009-02-10 18:37:48 +00:00
}
2009-08-26 17:37:15 +00:00
}
/**
* * Sets a new value for the variable . The DynamicVariables must be set to 1 in the
* * meter / measure for the changes to be applied .
* *
* * \ param strVariable
* * \ param strValue
*/
void CConfigParser : : SetVariable ( const std : : wstring & strVariable , const std : : wstring & strValue )
{
2009-09-18 15:30:51 +00:00
// DebugLog(L"Variable: %s=%s (size=%i)", strVariable.c_str(), strValue.c_str(), m_Variables.size());
2009-08-27 15:42:24 +00:00
std : : wstring strTmp ( strVariable ) ;
std : : transform ( strTmp . begin ( ) , strTmp . end ( ) , strTmp . begin ( ) , : : tolower ) ;
m_Variables [ strTmp ] = strValue ;
2009-02-10 18:37:48 +00:00
}
2009-09-18 15:30:51 +00:00
/**
* * Replaces environment and internal variables in the given string .
* *
* * \ param result The string where the variables are returned . The string is modified .
*/
void CConfigParser : : ReplaceVariables ( std : : wstring & result )
{
CRainmeter : : ExpandEnvironmentVariables ( result ) ;
// Check for variables (#VAR#)
size_t start = 0 ;
size_t end = std : : wstring : : npos ;
size_t pos = std : : wstring : : npos ;
bool loop = true ;
do
{
pos = result . find ( L ' # ' , start ) ;
if ( pos ! = std : : wstring : : npos )
{
end = result . find ( L ' # ' , pos + 1 ) ;
if ( end ! = std : : wstring : : npos )
{
std : : wstring strTmp ( result . begin ( ) + pos + 1 , result . begin ( ) + end ) ;
std : : transform ( strTmp . begin ( ) , strTmp . end ( ) , strTmp . begin ( ) , : : tolower ) ;
std : : map < std : : wstring , std : : wstring > : : iterator iter = m_Variables . find ( strTmp ) ;
if ( iter ! = m_Variables . end ( ) )
{
// Variable found, replace it with the value
result . replace ( result . begin ( ) + pos , result . begin ( ) + end + 1 , ( * iter ) . second ) ;
start = pos + ( * iter ) . second . length ( ) ;
}
else
{
start = end ;
}
}
else
{
loop = false ;
}
}
else
{
loop = false ;
}
} while ( loop ) ;
}
2009-02-10 18:37:48 +00:00
/*
* * ReadString
* *
* *
*/
2009-09-04 16:37:51 +00:00
const std : : wstring & CConfigParser : : ReadString ( LPCTSTR section , LPCTSTR key , LPCTSTR defValue , bool bReplaceMeasures )
2009-02-10 18:37:48 +00:00
{
static std : : wstring result ;
2009-09-04 16:37:51 +00:00
if ( section = = NULL )
{
section = L " " ;
}
if ( key = = NULL )
{
key = L " " ;
}
if ( defValue = = NULL )
{
defValue = L " " ;
}
2009-09-04 17:40:02 +00:00
std : : wstring strDefault = defValue ;
// If the template is defined read the value first from there.
if ( ! m_StyleTemplate . empty ( ) )
{
strDefault = GetValue ( m_StyleTemplate , key , strDefault ) ;
}
result = GetValue ( section , key , strDefault ) ;
2009-09-04 16:37:51 +00:00
if ( result = = defValue )
2009-02-10 18:37:48 +00:00
{
2009-09-04 16:37:51 +00:00
return result ;
2009-08-26 17:37:15 +00:00
}
2009-02-10 18:37:48 +00:00
// Check Litestep vars
if ( Rainmeter & & ! Rainmeter - > GetDummyLitestep ( ) )
{
std : : string ansi = ConvertToAscii ( result . c_str ( ) ) ;
char buffer [ 4096 ] ; // lets hope the buffer is large enough...
if ( ansi . size ( ) < 4096 )
{
VarExpansion ( buffer , ansi . c_str ( ) ) ;
result = ConvertToWide ( buffer ) ;
}
}
2009-09-18 15:30:51 +00:00
ReplaceVariables ( result ) ;
2009-02-10 18:37:48 +00:00
2009-08-26 17:37:15 +00:00
// Check for measures ([Measure])
2009-08-26 19:29:49 +00:00
if ( ! m_Measures . empty ( ) & & bReplaceMeasures )
2009-08-26 17:37:15 +00:00
{
2009-09-18 15:30:51 +00:00
size_t start = 0 ;
size_t end = std : : wstring : : npos ;
size_t pos = std : : wstring : : npos ;
2009-09-12 11:11:40 +00:00
size_t pos2 = std : : wstring : : npos ;
2009-09-18 15:30:51 +00:00
bool loop = true ;
2009-08-26 17:37:15 +00:00
do
{
pos = result . find ( L ' [ ' , start ) ;
if ( pos ! = std : : wstring : : npos )
{
2009-09-12 11:11:40 +00:00
end = result . find ( L ' ] ' , pos + 1 ) ;
2009-08-26 17:37:15 +00:00
if ( end ! = std : : wstring : : npos )
{
2009-09-12 11:11:40 +00:00
pos2 = result . find ( L ' [ ' , pos + 1 ) ;
if ( pos2 = = std : : wstring : : npos | | end < pos2 )
2009-08-26 17:37:15 +00:00
{
2009-09-12 11:11:40 +00:00
std : : wstring var ( result . begin ( ) + pos + 1 , result . begin ( ) + end ) ;
std : : map < std : : wstring , CMeasure * > : : iterator iter = m_Measures . find ( var ) ;
if ( iter ! = m_Measures . end ( ) )
{
std : : wstring value = ( * iter ) . second - > GetStringValue ( true , 1 , 5 , false ) ;
// Measure found, replace it with the value
result . replace ( result . begin ( ) + pos , result . begin ( ) + end + 1 , value ) ;
start = pos + value . length ( ) ;
}
else
{
start = end ;
}
2009-08-26 17:37:15 +00:00
}
else
{
2009-09-12 11:11:40 +00:00
start = pos2 ;
2009-08-26 17:37:15 +00:00
}
}
else
{
loop = false ;
}
}
else
{
loop = false ;
}
} while ( loop ) ;
}
2009-02-10 18:37:48 +00:00
return result ;
}
2009-08-26 17:37:15 +00:00
void CConfigParser : : AddMeasure ( CMeasure * pMeasure )
{
if ( pMeasure )
{
m_Measures [ pMeasure - > GetName ( ) ] = pMeasure ;
}
}
2009-02-10 18:37:48 +00:00
double CConfigParser : : ReadFloat ( LPCTSTR section , LPCTSTR key , double defValue )
{
TCHAR buffer [ 256 ] ;
swprintf ( buffer , L " %f " , defValue ) ;
const std : : wstring & result = ReadString ( section , key , buffer ) ;
return wcstod ( result . c_str ( ) , NULL ) ;
}
2009-07-27 11:48:57 +00:00
std : : vector < Gdiplus : : REAL > CConfigParser : : ReadFloats ( LPCTSTR section , LPCTSTR key )
{
std : : vector < Gdiplus : : REAL > result ;
std : : wstring tmp = ReadString ( section , key , L " " ) ;
if ( ! tmp . empty ( ) & & tmp [ tmp . length ( ) - 1 ] ! = L ' ; ' )
{
tmp + = L " ; " ;
}
// Tokenize and parse the floats
std : : vector < std : : wstring > tokens = Tokenize ( tmp , L " ; " ) ;
for ( size_t i = 0 ; i < tokens . size ( ) ; i + + )
{
result . push_back ( ( Gdiplus : : REAL ) wcstod ( tokens [ i ] . c_str ( ) , NULL ) ) ;
}
return result ;
}
2009-02-10 18:37:48 +00:00
int CConfigParser : : ReadInt ( LPCTSTR section , LPCTSTR key , int defValue )
{
TCHAR buffer [ 256 ] ;
swprintf ( buffer , L " %i " , defValue ) ;
const std : : wstring & result = ReadString ( section , key , buffer ) ;
return _wtoi ( result . c_str ( ) ) ;
}
2009-07-30 15:19:47 +00:00
// Works as ReadFloat except if the value is surrounded by parenthesis in which case it tries to evaluate the formula
double CConfigParser : : ReadFormula ( LPCTSTR section , LPCTSTR key , double defValue )
{
TCHAR buffer [ 256 ] ;
swprintf ( buffer , L " %f " , defValue ) ;
const std : : wstring & result = ReadString ( section , key , buffer ) ;
// Formulas must be surrounded by parenthesis
if ( ! result . empty ( ) & & result [ 0 ] = = L ' ( ' & & result [ result . size ( ) - 1 ] = = L ' ) ' )
{
double resultValue = defValue ;
char * errMsg = MathParser_Parse ( m_Parser , ConvertToAscii ( result . substr ( 1 , result . size ( ) - 2 ) . c_str ( ) ) . c_str ( ) , & resultValue ) ;
if ( errMsg ! = NULL )
{
DebugLog ( ConvertToWide ( errMsg ) . c_str ( ) ) ;
}
return resultValue ;
}
return wcstod ( result . c_str ( ) , NULL ) ;
}
2009-02-10 18:37:48 +00:00
Color CConfigParser : : ReadColor ( LPCTSTR section , LPCTSTR key , Color defValue )
{
TCHAR buffer [ 256 ] ;
swprintf ( buffer , L " %i, %i, %i, %i " , defValue . GetR ( ) , defValue . GetG ( ) , defValue . GetB ( ) , defValue . GetA ( ) ) ;
const std : : wstring & result = ReadString ( section , key , buffer ) ;
return ParseColor ( result . c_str ( ) ) ;
}
2009-07-27 11:48:57 +00:00
/*
* * Tokenize
* *
* * Splits the string from the delimiters
* *
* * http : //www.digitalpeer.com/id/simple
*/
std : : vector < std : : wstring > CConfigParser : : Tokenize ( const std : : wstring & str , const std : : wstring delimiters )
{
std : : vector < std : : wstring > tokens ;
std : : wstring : : size_type lastPos = str . find_first_not_of ( L " ; " , 0 ) ; // skip delimiters at beginning.
std : : wstring : : size_type pos = str . find_first_of ( delimiters , lastPos ) ; // find first "non-delimiter".
while ( std : : wstring : : npos ! = pos | | std : : wstring : : npos ! = lastPos )
{
tokens . push_back ( str . substr ( lastPos , pos - lastPos ) ) ; // found a token, add it to the vector.
lastPos = str . find_first_not_of ( delimiters , pos ) ; // skip delimiters. Note the "not_of"
pos = str . find_first_of ( delimiters , lastPos ) ; // find next "non-delimiter"
}
return tokens ;
}
2009-02-10 18:37:48 +00:00
/*
* * ParseColor
* *
* * This is a helper method that parses the color values from the given string .
* * The color can be supplied as three / four comma separated values or as one
* * hex - value .
* *
*/
Color CConfigParser : : ParseColor ( LPCTSTR string )
{
int R , G , B , A ;
if ( wcschr ( string , L ' , ' ) ! = NULL )
{
WCHAR * parseSz = _wcsdup ( string ) ;
WCHAR * token ;
token = wcstok ( parseSz , L " , " ) ;
if ( token ! = NULL )
{
R = _wtoi ( token ) ;
}
else
{
R = 255 ;
}
token = wcstok ( NULL , L " , " ) ;
if ( token ! = NULL )
{
G = _wtoi ( token ) ;
}
else
{
G = 255 ;
}
token = wcstok ( NULL , L " , " ) ;
if ( token ! = NULL )
{
B = _wtoi ( token ) ;
}
else
{
B = 255 ;
}
token = wcstok ( NULL , L " , " ) ;
if ( token ! = NULL )
{
A = _wtoi ( token ) ;
}
else
{
A = 255 ;
}
free ( parseSz ) ;
}
else
{
const WCHAR * start = string ;
if ( wcsncmp ( string , L " 0x " , 2 ) = = 0 )
{
start = string + 2 ;
}
if ( wcslen ( string ) > 6 & & ! isspace ( string [ 6 ] ) )
{
swscanf ( string , L " %02x%02x%02x%02x " , & R , & G , & B , & A ) ;
}
else
{
swscanf ( string , L " %02x%02x%02x " , & R , & G , & B ) ;
A = 255 ; // Opaque
}
}
return Color ( A , R , G , B ) ;
}
2009-08-26 17:37:15 +00:00
//==============================================================================
/**
* * Reads the given ini file and fills the m_Values and m_Keys maps .
* *
* * \ param iniFile The ini file to be read .
*/
2009-09-18 15:30:51 +00:00
void CConfigParser : : ReadIniFile ( const std : : wstring & iniFile , int depth )
2009-08-26 17:37:15 +00:00
{
2009-09-18 15:30:51 +00:00
// DebugLog(L"Reading file: %s", iniFile.c_str());
if ( depth > 100 ) // Is 100 enough to assume the include loop never ends?
{
MessageBox ( NULL , L " It looks like you've made an infinite \n loop with the @include statements. \n Please check your skin. " , L " Rainmeter " , MB_OK | MB_ICONERROR ) ;
return ;
}
2009-08-26 17:37:15 +00:00
// Get all the sections (i.e. different meters)
WCHAR * items = new WCHAR [ MAX_LINE_LENGTH ] ;
int size = MAX_LINE_LENGTH ;
// Get all the sections
while ( true )
{
items [ 0 ] = 0 ;
int res = GetPrivateProfileString ( NULL , NULL , NULL , items , size , iniFile . c_str ( ) ) ;
2009-09-12 11:11:40 +00:00
if ( res = = 0 ) { delete [ ] items ; return ; } // File not found
2009-09-04 16:37:51 +00:00
if ( res < size - 2 ) break ; // Fits in the buffer
2009-08-26 17:37:15 +00:00
delete [ ] items ;
size * = 2 ;
items = new WCHAR [ size ] ;
} ;
// Read the sections
WCHAR * pos = items ;
while ( wcslen ( pos ) > 0 )
{
2009-08-27 15:42:24 +00:00
std : : wstring strTmp ( pos ) ;
std : : transform ( strTmp . begin ( ) , strTmp . end ( ) , strTmp . begin ( ) , : : tolower ) ;
2009-09-18 15:30:51 +00:00
if ( m_Keys . find ( strTmp ) = = m_Keys . end ( ) )
{
m_Keys [ strTmp ] = std : : vector < std : : wstring > ( ) ;
2009-09-19 07:15:28 +00:00
m_Sections . push_back ( pos ) ;
2009-09-18 15:30:51 +00:00
}
2009-08-26 17:37:15 +00:00
pos = pos + wcslen ( pos ) + 1 ;
}
// Read the keys and values
int bufferSize = MAX_LINE_LENGTH ;
2009-09-12 11:11:40 +00:00
WCHAR * buffer = new WCHAR [ bufferSize ] ;
2009-08-26 17:37:15 +00:00
stdext : : hash_map < std : : wstring , std : : vector < std : : wstring > > : : iterator iter = m_Keys . begin ( ) ;
for ( ; iter ! = m_Keys . end ( ) ; iter + + )
{
while ( true )
{
items [ 0 ] = 0 ;
int res = GetPrivateProfileString ( ( * iter ) . first . c_str ( ) , NULL , NULL , items , size , iniFile . c_str ( ) ) ;
2009-09-04 16:37:51 +00:00
if ( res < size - 2 ) break ; // Fits in the buffer
2009-08-26 17:37:15 +00:00
delete [ ] items ;
size * = 2 ;
items = new WCHAR [ size ] ;
} ;
WCHAR * pos = items ;
while ( wcslen ( pos ) > 0 )
{
std : : wstring strKey = pos ;
while ( true )
{
buffer [ 0 ] = 0 ;
int res = GetPrivateProfileString ( ( * iter ) . first . c_str ( ) , strKey . c_str ( ) , L " " , buffer , bufferSize , iniFile . c_str ( ) ) ;
2009-09-04 16:37:51 +00:00
if ( res < bufferSize - 2 ) break ; // Fits in the buffer
2009-08-26 17:37:15 +00:00
delete [ ] buffer ;
bufferSize * = 2 ;
2009-09-04 16:37:51 +00:00
buffer = new WCHAR [ bufferSize ] ;
2009-08-26 17:37:15 +00:00
} ;
2009-09-18 15:30:51 +00:00
if ( wcsnicmp ( strKey . c_str ( ) , L " @include " , 8 ) = = 0 )
{
std : : wstring strIncludeFile = buffer ;
ReplaceVariables ( strIncludeFile ) ;
if ( strIncludeFile . find ( L ' : ' ) = = std : : wstring : : npos )
{
// It's a relative path so add the current path as a prefix
strIncludeFile = CRainmeter : : ExtractPath ( iniFile ) + strIncludeFile ;
}
ReadIniFile ( strIncludeFile , depth + 1 ) ;
}
else
{
SetValue ( ( * iter ) . first , strKey , buffer ) ;
}
2009-08-26 17:37:15 +00:00
pos = pos + wcslen ( pos ) + 1 ;
}
}
delete [ ] buffer ;
delete [ ] items ;
}
//==============================================================================
/**
* * Sets the value for the key under the given section .
* *
* * \ param strSection The name of the section .
* * \ param strKey The name of the key .
* * \ param strValue The value for the key .
*/
void CConfigParser : : SetValue ( const std : : wstring & strSection , const std : : wstring & strKey , const std : : wstring & strValue )
{
2009-09-18 15:30:51 +00:00
// DebugLog(L"[%s] %s=%s (size: %i)", strSection.c_str(), strKey.c_str(), strValue.c_str(), m_Values.size());
2009-08-27 15:42:24 +00:00
std : : wstring strTmpSection ( strSection ) ;
std : : wstring strTmpKey ( strKey ) ;
std : : transform ( strTmpSection . begin ( ) , strTmpSection . end ( ) , strTmpSection . begin ( ) , : : tolower ) ;
std : : transform ( strTmpKey . begin ( ) , strTmpKey . end ( ) , strTmpKey . begin ( ) , : : tolower ) ;
stdext : : hash_map < std : : wstring , std : : vector < std : : wstring > > : : iterator iter = m_Keys . find ( strTmpSection ) ;
2009-08-26 17:37:15 +00:00
if ( iter ! = m_Keys . end ( ) )
{
std : : vector < std : : wstring > & array = ( * iter ) . second ;
2009-08-27 15:42:24 +00:00
array . push_back ( strTmpKey ) ;
2009-08-26 17:37:15 +00:00
}
2009-08-27 15:42:24 +00:00
m_Values [ strTmpSection + L " :: " + strTmpKey ] = strValue ;
2009-08-26 17:37:15 +00:00
}
//==============================================================================
/**
* * Returns the value for the key under the given section .
* *
* * \ param strSection The name of the section .
* * \ param strKey The name of the key .
* * \ param strDefault The default value for the key .
* * \ return The value for the key .
*/
const std : : wstring & CConfigParser : : GetValue ( const std : : wstring & strSection , const std : : wstring & strKey , const std : : wstring & strDefault )
{
2009-08-27 15:42:24 +00:00
std : : wstring strTmp ( strSection + L " :: " + strKey ) ;
std : : transform ( strTmp . begin ( ) , strTmp . end ( ) , strTmp . begin ( ) , : : tolower ) ;
stdext : : hash_map < std : : wstring , std : : wstring > : : iterator iter = m_Values . find ( strTmp ) ;
2009-08-26 17:37:15 +00:00
if ( iter ! = m_Values . end ( ) )
{
return ( * iter ) . second ;
}
return strDefault ;
}
//==============================================================================
/**
* * Returns the list of sections in the ini file .
* *
* * \ return A list of sections in the ini file .
*/
2009-09-19 07:15:28 +00:00
const std : : vector < std : : wstring > & CConfigParser : : GetSections ( )
2009-08-26 17:37:15 +00:00
{
2009-09-19 07:15:28 +00:00
return m_Sections ;
2009-08-26 17:37:15 +00:00
}
//==============================================================================
/**
* * Returns a list of keys under the given section .
* *
* * \ param strSection The name of the section .
* * \ return A list of keys under the given section .
*/
std : : vector < std : : wstring > CConfigParser : : GetKeys ( const std : : wstring & strSection )
{
2009-08-27 15:42:24 +00:00
std : : wstring strTmp ( strSection ) ;
std : : transform ( strTmp . begin ( ) , strTmp . end ( ) , strTmp . begin ( ) , : : tolower ) ;
stdext : : hash_map < std : : wstring , std : : vector < std : : wstring > > : : iterator iter = m_Keys . find ( strTmp ) ;
2009-08-26 17:37:15 +00:00
if ( iter ! = m_Keys . end ( ) )
{
return ( * iter ) . second ;
}
return std : : vector < std : : wstring > ( ) ;
}