2015-05-24 06:55:12 +02:00
// Copyright 2008 Dolphin Emulator Project
2015-05-18 01:08:10 +02:00
// Licensed under GPLv2+
2013-04-17 23:09:55 -04:00
// Refer to the license.txt file included.
2008-12-08 04:46:09 +00:00
2014-02-10 13:54:46 -05:00
#pragma once
2008-12-08 04:46:09 +00:00
2014-02-20 04:11:52 +01:00
#include <cstring>
2014-06-24 12:28:02 -05:00
#include <list>
2013-09-06 19:56:19 +02:00
#include <map>
2014-02-17 05:18:15 -05:00
#include <string>
2010-06-03 18:05:08 +00:00
#include <vector>
2010-06-03 04:55:39 +00:00
2014-02-20 04:11:52 +01:00
#include "Common/CommonTypes.h"
2014-02-17 05:18:15 -05:00
#include "Common/StringUtil.h"
2008-12-08 04:46:09 +00:00
2013-09-06 19:56:19 +02:00
struct CaseInsensitiveStringCompare
{
bool operator () ( const std :: string & a , const std :: string & b ) const
{
return strcasecmp ( a . c_str (), b . c_str ()) < 0 ;
}
};
2010-06-03 18:05:08 +00:00
class IniFile
2010-06-03 04:55:39 +00:00
{
public :
2010-06-04 19:56:34 +00:00
class Section
{
2010-06-05 05:30:23 +00:00
friend class IniFile ;
2010-06-04 19:56:34 +00:00
2010-06-05 05:30:23 +00:00
public :
Section () {}
Section ( const std :: string & _name ) : name ( _name ) {}
2010-06-04 19:56:34 +00:00
2014-02-08 18:50:37 +13:00
bool Exists ( const std :: string & key ) const ;
bool Delete ( const std :: string & key );
2010-06-04 19:56:34 +00:00
2014-02-08 18:50:37 +13:00
void Set ( const std :: string & key , const std :: string & newValue );
void Set ( const std :: string & key , const std :: string & newValue , const std :: string & defaultValue );
2010-06-05 05:30:23 +00:00
2014-08-30 16:14:56 -04:00
void Set ( const std :: string & key , u32 newValue )
{
2014-02-08 18:50:37 +13:00
Set ( key , StringFromFormat ( "0x%08x" , newValue ));
2010-06-04 19:56:34 +00:00
}
2014-08-30 16:14:56 -04:00
void Set ( const std :: string & key , float newValue )
{
2014-02-08 18:50:37 +13:00
Set ( key , StringFromFormat ( "%f" , newValue ));
2010-06-04 19:56:34 +00:00
}
2014-08-30 16:14:56 -04:00
void Set ( const std :: string & key , double newValue )
{
2014-02-08 18:50:37 +13:00
Set ( key , StringFromFormat ( "%f" , newValue ));
2010-06-04 19:56:34 +00:00
}
2013-10-29 01:23:17 -04:00
2014-08-30 16:14:56 -04:00
void Set ( const std :: string & key , int newValue )
{
2014-02-08 18:50:37 +13:00
Set ( key , StringFromInt ( newValue ));
2010-06-04 19:56:34 +00:00
}
2013-10-29 01:23:17 -04:00
2014-08-30 16:14:56 -04:00
void Set ( const std :: string & key , bool newValue )
{
2014-02-08 18:50:37 +13:00
Set ( key , StringFromBool ( newValue ));
2010-06-04 19:56:34 +00:00
}
2014-09-04 03:29:49 -04:00
template < typename T >
void Set ( const std :: string & key , T newValue , const T defaultValue )
{
if ( newValue != defaultValue )
Set ( key , newValue );
else
Delete ( key );
}
2014-02-08 18:50:37 +13:00
void Set ( const std :: string & key , const std :: vector < std :: string >& newValues );
2010-06-04 19:56:34 +00:00
2015-08-19 22:22:28 -04:00
bool Get ( const std :: string & key , std :: string * value , const std :: string & defaultValue = NULL_STRING ) const ;
bool Get ( const std :: string & key , int * value , int defaultValue = 0 ) const ;
bool Get ( const std :: string & key , u32 * value , u32 defaultValue = 0 ) const ;
bool Get ( const std :: string & key , bool * value , bool defaultValue = false ) const ;
bool Get ( const std :: string & key , float * value , float defaultValue = 0.0f ) const ;
bool Get ( const std :: string & key , double * value , double defaultValue = 0.0 ) const ;
bool Get ( const std :: string & key , std :: vector < std :: string >* values ) const ;
2010-06-04 19:56:34 +00:00
2014-08-30 16:14:56 -04:00
bool operator < ( const Section & other ) const
{
2010-06-04 19:56:34 +00:00
return name < other . name ;
}
2010-06-05 05:30:23 +00:00
protected :
std :: string name ;
2013-09-06 19:56:19 +02:00
std :: vector < std :: string > keys_order ;
std :: map < std :: string , std :: string , CaseInsensitiveStringCompare > values ;
std :: vector < std :: string > lines ;
2010-06-05 05:30:23 +00:00
};
2010-06-03 04:55:39 +00:00
2013-09-06 19:56:19 +02:00
/**
* Loads sections and keys.
* @param filename filename of the ini file which should be loaded
* @param keep_current_data If true, "extends" the currently loaded list of sections and keys with the loaded data (and replaces existing entries). If false, existing data will be erased.
* @warning Using any other operations than "Get*" and "Exists" is untested and will behave unexpectedly
* @todo This really is just a hack to support having two levels of gameinis (defaults and user-specified) and should eventually be replaced with a less stupid system.
*/
2014-02-08 18:50:37 +13:00
bool Load ( const std :: string & filename , bool keep_current_data = false );
2013-09-06 19:56:19 +02:00
2014-02-08 18:50:37 +13:00
bool Save ( const std :: string & filename );
2010-06-03 04:55:39 +00:00
2010-06-04 19:56:34 +00:00
// Returns true if key exists in section
2014-02-08 18:50:37 +13:00
bool Exists ( const std :: string & sectionName , const std :: string & key ) const ;
2010-06-03 18:05:08 +00:00
2014-02-08 18:50:37 +13:00
template < typename T > bool GetIfExists ( const std :: string & sectionName , const std :: string & key , T value )
2011-02-13 22:36:12 +00:00
{
if ( Exists ( sectionName , key ))
2014-06-16 01:12:43 -04:00
return GetOrCreateSection ( sectionName ) -> Get ( key , value );
2011-02-13 22:36:12 +00:00
return false ;
}
2014-03-15 03:29:53 +01:00
bool GetKeys ( const std :: string & sectionName , std :: vector < std :: string >* keys ) const ;
2010-06-04 19:56:34 +00:00
2014-03-15 03:29:53 +01:00
void SetLines ( const std :: string & sectionName , const std :: vector < std :: string >& lines );
bool GetLines ( const std :: string & sectionName , std :: vector < std :: string >* lines , const bool remove_comments = true ) const ;
2010-06-03 18:05:08 +00:00
2014-02-08 18:50:37 +13:00
bool DeleteKey ( const std :: string & sectionName , const std :: string & key );
bool DeleteSection ( const std :: string & sectionName );
2010-06-03 18:05:08 +00:00
void SortSections ();
2014-02-08 18:50:37 +13:00
Section * GetOrCreateSection ( const std :: string & section );
2010-06-03 18:05:08 +00:00
2014-07-29 11:47:56 -05:00
// This function is related to parsing data from lines of INI files
// It's used outside of IniFile, which is why it is exposed publicly
// In particular it is used in PostProcessing for its configuration
static void ParseLine ( const std :: string & line , std :: string * keyOut , std :: string * valueOut );
2010-06-03 18:05:08 +00:00
private :
2014-06-24 12:28:02 -05:00
std :: list < Section > sections ;
2010-06-03 18:05:08 +00:00
2014-02-08 18:50:37 +13:00
const Section * GetSection ( const std :: string & section ) const ;
Section * GetSection ( const std :: string & section );
std :: string * GetLine ( const std :: string & section , const std :: string & key );
void CreateSection ( const std :: string & section );
2014-03-29 11:05:44 +01:00
2014-02-08 18:50:37 +13:00
static const std :: string & NULL_STRING ;
2008-12-08 04:46:09 +00:00
};