Use map<> in IniFile.

This has a side-effect: written INIs are sorted by key and name.
Unintentional, but not necessarily a bad thing ...
This commit is contained in:
Glenn Maynard
2002-10-24 23:08:18 +00:00
parent dc43775b83
commit 0a73e01186
4 changed files with 74 additions and 127 deletions
+47 -91
View File
@@ -86,16 +86,18 @@ bool IniFile::ReadFile()
void IniFile::WriteFile() void IniFile::WriteFile()
{ {
FILE* fp = fopen( path, "w" ); FILE* fp = fopen( path, "w" );
for (unsigned keynum = 0; keynum < names.size(); keynum++) for (keymap::const_iterator k = keys.begin(); k != keys.end(); ++k)
{ {
if (keys[keynum].names.GetSize() != 0) if (k->second.empty())
{ continue;
fprintf( fp, "[%s]\n", names[keynum] );
for (unsigned valuenum = 0; valuenum < keys[keynum].names.size(); valuenum++) fprintf( fp, "[%s]\n", k->first.GetString() );
fprintf( fp, "%s=%s\n", keys[keynum].names[valuenum], keys[keynum].values[valuenum] );
for (key::const_iterator i = k->second.begin(); i != k->second.end(); ++i)
fprintf( fp, "%s=%s\n", i->first.GetString(), i->second.GetString() );
fprintf( fp, "\n" ); fprintf( fp, "\n" );
} }
}
fclose( fp ); fclose( fp );
} }
@@ -103,44 +105,44 @@ void IniFile::WriteFile()
void IniFile::Reset() void IniFile::Reset()
{ {
keys.clear(); keys.clear();
names.clear();
} }
//returns number of keys currently in the ini //returns number of keys currently in the ini
int IniFile::GetNumKeys() int IniFile::GetNumKeys() const
{ {
return keys.GetSize(); return keys.size();
} }
//returns number of values stored for specified key, or -1 if key found //returns number of values stored for specified key, or -1 if key not found
int IniFile::GetNumValues(const CString &keyname) int IniFile::GetNumValues(const CString &keyname) const
{ {
int keynum = FindKey(keyname); keymap::const_iterator k = keys.find(keyname);
if (keynum == -1) if (k == keys.end())
return -1; return -1;
else
return keys[keynum].names.GetSize(); return k->second.size();
} }
//gets value of [keyname] valuename = //gets value of [keyname] valuename =
//overloaded to return CString, int, and double //overloaded to return CString, int, and double
bool IniFile::GetValue(const CString &keyname, const CString &valuename, CString& value) bool IniFile::GetValue(const CString &keyname, const CString &valuename, CString& value)
{ {
int keynum = FindKey(keyname), valuenum = FindValue(keynum,valuename); keymap::const_iterator k = keys.find(keyname);
if (k == keys.end())
if (keynum == -1)
{ {
error = "Unable to locate specified key."; error = "Unable to locate specified key.";
return false; return false;
} }
if (valuenum == -1) key::const_iterator i = k->second.find(valuename);
if (i == k->second.end())
{ {
error = "Unable to locate specified value."; error = "Unable to locate specified value.";
return false; return false;
} }
value = keys[keynum].values[valuenum]; value = i->second;
return true; return true;
} }
@@ -186,31 +188,15 @@ bool IniFile::GetValueB(const CString &keyname, const CString &valuename, bool&
//overloaded to accept CString, int, and double //overloaded to accept CString, int, and double
bool IniFile::SetValue(const CString &keyname, const CString &valuename, const CString &value, bool create) bool IniFile::SetValue(const CString &keyname, const CString &valuename, const CString &value, bool create)
{ {
int keynum = FindKey(keyname), valuenum = 0; if (!create && keys.find(keyname) == keys.end()) //if key doesn't exist
//find key return false; // stop entering this key
if (keynum == -1) //if key doesn't exist
{
if (!create) //and user does not want to create it,
return 0; //stop entering this key
names.SetSize(names.GetSize()+1);
keys.SetSize(keys.GetSize()+1);
keynum = names.GetSize()-1;
names[keynum] = keyname;
}
// find value // find value
valuenum = FindValue(keynum,valuename); if (!create && keys[keyname].find(valuename) == keys[keyname].end())
if (valuenum == -1) return false;
{
if (!create) keys[keyname][valuename] = value;
return 0; return true;
keys[keynum].names.SetSize(keys[keynum].names.GetSize()+1);
keys[keynum].values.SetSize(keys[keynum].names.GetSize()+1);
valuenum = keys[keynum].names.GetSize()-1;
keys[keynum].names[valuenum] = valuename;
}
keys[keynum].values[valuenum] = value;
return 1;
} }
//sets value of [keyname] valuename =. //sets value of [keyname] valuename =.
@@ -250,61 +236,31 @@ bool IniFile::SetValueB(const CString &keyname, const CString &valuename, bool v
//returns true if value existed and deleted, false otherwise //returns true if value existed and deleted, false otherwise
bool IniFile::DeleteValue(const CString &keyname, const CString &valuename) bool IniFile::DeleteValue(const CString &keyname, const CString &valuename)
{ {
int keynum = FindKey(keyname), valuenum = FindValue(keynum,valuename); keymap::iterator k = keys.find(keyname);
if (keynum == -1 || valuenum == -1) if (k == keys.end())
return 0; return false;
keys[keynum].names.RemoveAt(valuenum); key::iterator i = k->second.find(valuename);
keys[keynum].values.RemoveAt(valuenum); if(i == k->second.end())
return 1; return false;
k->second.erase(i);
return true;
} }
//deletes specified key and all values contained within //deletes specified key and all values contained within
//returns true if key existed and deleted, false otherwise //returns true if key existed and deleted, false otherwise
bool IniFile::DeleteKey(const CString &keyname) bool IniFile::DeleteKey(const CString &keyname)
{ {
int keynum = FindKey(keyname); keymap::iterator k = keys.find(keyname);
if (keynum == -1) if (k == keys.end())
return 0; return false;
keys.RemoveAt(keynum);
names.RemoveAt(keynum); keys.erase(k);
return 1; return true;
} }
//deletes specified key and all values contained within IniFile::const_iterator IniFile::GetKey(const CString &keyname) const
//returns true if key existed and deleted, false otherwise
IniFile::key* IniFile::GetKey(const CString &keyname)
{ {
int keynum = FindKey(keyname); return keys.find(keyname);
if (keynum == -1)
return NULL;
return &keys[keynum];
}
/////////////////////////////////////////////////////////////////////
// Private Functions
/////////////////////////////////////////////////////////////////////
//returns index of specified key, or -1 if not found
int IniFile::FindKey(const CString &keyname)
{
int keynum = 0;
while ( keynum < keys.GetSize() && names[keynum] != keyname)
keynum++;
if (keynum == keys.GetSize())
return -1;
return keynum;
}
//returns index of specified value, in the specified key, or -1 if not found
int IniFile::FindValue(int keynum, const CString &valuename)
{
if (keynum == -1)
return -1;
int valuenum = 0;
while (valuenum < keys[keynum].names.GetSize() && keys[keynum].names[valuenum] != valuename)
valuenum++;
if (valuenum == keys[keynum].names.GetSize())
return -1;
return valuenum;
} }
+13 -24
View File
@@ -11,36 +11,26 @@
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
*/ */
#include <map>
class IniFile class IniFile
{ {
public: public:
// all keys are of this type // all keys are of this type
struct key
{
//list of values in key
CArray<CString, CString> values;
//corresponding list of value names typedef map<CString, CString> key;
CArray<CString, CString> names; typedef map<CString, key> keymap;
};
typedef keymap::const_iterator const_iterator;
const_iterator begin() const { return keys.begin(); }
const_iterator end() const { return keys.end(); }
private: private:
//stores pathname of ini file to read/write //stores pathname of ini file to read/write
CString path; CString path;
//list of keys in ini // keys in ini
CArray<key, key> keys; keymap keys;
//corresponding list of keynames
CArray<CString, CString> names;
private:
//returns index of specified value, in the specified key, or -1 if not found
int FindValue(int keynum, const CString &valuename);
//returns index of specified key, or -1 if not found
int FindKey(const CString &keyname);
public: public:
@@ -49,7 +39,6 @@ public:
//ended up not using much, just in ReadFile and GetValue //ended up not using much, just in ReadFile and GetValue
CString error; CString error;
//constructor, can specify pathname here instead of using SetPath later //constructor, can specify pathname here instead of using SetPath later
IniFile(CString inipath = ""); IniFile(CString inipath = "");
@@ -70,10 +59,10 @@ public:
void Reset(); void Reset();
//returns number of keys currently in the ini //returns number of keys currently in the ini
int GetNumKeys(); int GetNumKeys() const;
//returns number of values stored for specified key //returns number of values stored for specified key
int GetNumValues(const CString &keyname); int GetNumValues(const CString &keyname) const;
//gets value of [keyname] valuename = //gets value of [keyname] valuename =
//overloaded to return CString, int, and double, //overloaded to return CString, int, and double,
@@ -100,5 +89,5 @@ public:
//returns true if key existed and deleted, false otherwise //returns true if key existed and deleted, false otherwise
bool DeleteKey(const CString &keyname); bool DeleteKey(const CString &keyname);
key* GetKey(const CString &keyname); const_iterator GetKey(const CString &keyname) const;
}; };
+6 -5
View File
@@ -74,14 +74,15 @@ void InputMapper::ReadMappingsFromDisk()
if( !ini.ReadFile() ) if( !ini.ReadFile() )
LOG->Warn( "could not input mapping file '%s'.", sPath ); LOG->Warn( "could not input mapping file '%s'.", sPath );
IniFile::key* pKey = ini.GetKey( "Input" ); IniFile::const_iterator Key = ini.GetKey( "Input" );
if( pKey != NULL ) if( Key != ini.end() )
{ {
for( int i=0; i<pKey->names.GetSize(); i++ ) for( IniFile::key::const_iterator i = Key->second.begin();
i != Key->second.end(); ++i )
{ {
CString name = pKey->names[i]; CString name = i->first;
CString value = pKey->values[i]; CString value = i->second;
GameInput GameI; GameInput GameI;
GameI.fromString( name ); GameI.fromString( name );
+6 -5
View File
@@ -259,13 +259,14 @@ void SongManager::ReadStatisticsFromDisk()
// load song statistics // load song statistics
IniFile::key* pKey = ini.GetKey( "Statistics" ); IniFile::const_iterator Key = ini.GetKey( "Statistics" );
if( pKey ) if( Key != ini.end() )
{ {
for( int i=0; i<pKey->names.GetSize(); i++ ) for( IniFile::key::const_iterator i = Key->second.begin();
i != Key->second.end(); ++i )
{ {
CString name = pKey->names[i]; CString name = i->first;
CString value = pKey->values[i]; CString value = i->second;
// Each value has the format "SongName::StepsName=TimesPlayed::TopGrade::TopScore::MaxCombo". // Each value has the format "SongName::StepsName=TimesPlayed::TopGrade::TopScore::MaxCombo".
char szSongDir[256]; char szSongDir[256];