mirror of https://github.com/PCSX2/pcsx2.git
Fix gruesome errors in database loading/saving.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3191 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
d2b6171ce8
commit
e285ff4b50
|
@ -20,6 +20,47 @@
|
|||
#include <wx/tokenzr.h>
|
||||
#include <wx/gdicmn.h> // for wxPoint/wxRect stuff
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// pxToUTF8
|
||||
// --------------------------------------------------------------------------------------
|
||||
// Converts a string to UTF8 and provides an interface for getting its length.
|
||||
class pxToUTF8
|
||||
{
|
||||
DeclareNoncopyableObject( pxToUTF8 );
|
||||
|
||||
protected:
|
||||
wxCharBuffer m_result;
|
||||
int m_length;
|
||||
|
||||
public:
|
||||
explicit pxToUTF8(const wxString& src)
|
||||
: m_result( src.ToUTF8() )
|
||||
{
|
||||
m_length = -1;
|
||||
}
|
||||
|
||||
size_t Length()
|
||||
{
|
||||
if( -1 == m_length )
|
||||
m_length = strlen( m_result );
|
||||
return m_length;
|
||||
}
|
||||
|
||||
void Convert( const wxString& src )
|
||||
{
|
||||
m_result = src.ToUTF8();
|
||||
m_length = -1;
|
||||
}
|
||||
|
||||
const char* data() const { return m_result; }
|
||||
|
||||
operator const char*() const
|
||||
{
|
||||
return m_result.data();
|
||||
}
|
||||
};
|
||||
|
||||
extern void px_fputs( FILE* fp, const char* src );
|
||||
|
||||
extern wxString fromUTF8( const char* src );
|
||||
|
|
|
@ -82,7 +82,10 @@ void pxWriteLine( wxOutputStream& output )
|
|||
void pxWriteLine( wxOutputStream& output, const wxString& text )
|
||||
{
|
||||
if( !text.IsEmpty() )
|
||||
output.Write(text.ToUTF8(), text.Length());
|
||||
{
|
||||
pxToUTF8 utf8(text);
|
||||
output.Write(utf8, utf8.Length());
|
||||
}
|
||||
pxWriteLine( output );
|
||||
}
|
||||
|
||||
|
@ -92,7 +95,8 @@ void pxWriteMultiline( wxOutputStream& output, const wxString& src )
|
|||
|
||||
wxString result( src );
|
||||
result.Replace( L"\r\n", L"\n" );
|
||||
result.Replace( L"\r", wxEmptyString );
|
||||
result.Replace( L"\r", L"\n" );
|
||||
|
||||
output.Write(result.ToUTF8(), result.Length());
|
||||
pxToUTF8 utf8(result);
|
||||
output.Write(utf8, utf8.Length());
|
||||
}
|
||||
|
|
|
@ -19,37 +19,40 @@ void DataBase_Loader::doError(const wxString& line, key_pair& keyPair, bool doMs
|
|||
// [/section]
|
||||
//
|
||||
// ... where the =value part is OPTIONAL.
|
||||
void DataBase_Loader::extractMultiLine(key_pair& keyPair, wxInputStream& ffile) {
|
||||
bool DataBase_Loader::extractMultiLine(const wxString& line, key_pair& keyPair, wxInputStream& ffile) {
|
||||
|
||||
if (!keyPair.key.EndsWith(L"]")) {
|
||||
doError(keyPair.key, keyPair, true);
|
||||
return;
|
||||
if (line[0] != L'[') return false; // All multiline sections begin with a '['!
|
||||
|
||||
if (!line.EndsWith(L"]")) {
|
||||
doError(line, keyPair, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Use Mid() to strip off the left and right side brackets.
|
||||
ParsedAssignmentString set( keyPair.key.Mid(1, keyPair.key.Length()-2) );
|
||||
|
||||
wxString endString;
|
||||
endString.Printf( L"[/%s]", set.lvalue.c_str() );
|
||||
keyPair.key = line;
|
||||
|
||||
for(;;) {
|
||||
// Use Mid() to strip off the left and right side brackets.
|
||||
wxString midLine(line.Mid(1, line.Length()-2));
|
||||
wxString lvalue(midLine.BeforeFirst(L'=').Trim(true).Trim(false));
|
||||
//wxString rvalue(midLine.AfterFirst(L'=').Trim(true).Trim(false));
|
||||
|
||||
wxString endString;
|
||||
endString.Printf( L"[/%s]", lvalue.c_str() );
|
||||
|
||||
while(!ffile.Eof()) {
|
||||
pxReadLine( ffile, m_dest, m_intermediate );
|
||||
if (m_dest == endString) break;
|
||||
keyPair.value += m_dest + L"\n";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DataBase_Loader::extract(const wxString& line, key_pair& keyPair, wxInputStream& reader) {
|
||||
keyPair.key = line;
|
||||
keyPair.key.clear();
|
||||
keyPair.value.clear();
|
||||
|
||||
if( line.IsEmpty() ) return;
|
||||
|
||||
if (keyPair.key[0] == L'[') {
|
||||
extractMultiLine(keyPair, reader);
|
||||
return;
|
||||
}
|
||||
|
||||
if( extractMultiLine(line, keyPair, reader) ) return;
|
||||
if( !pxParseAssignmentString( line, keyPair.key, keyPair.value ) ) return;
|
||||
if( keyPair.value.IsEmpty() )
|
||||
doError(line, keyPair, true);
|
||||
|
|
|
@ -31,8 +31,15 @@ struct key_pair {
|
|||
wxString toString() const {
|
||||
if (key[0] == '[') {
|
||||
pxAssumeDev( key.EndsWith(L"]"), "Malformed multiline key detected: missing end bracket!" );
|
||||
return wxsFormat( L"%s\n%s\n[/%s\n",
|
||||
key.c_str(), value.c_str(), key.Mid(1, key.length()-1).c_str()
|
||||
|
||||
// Terminating tag must be written without the "rvalue" -- in the form of:
|
||||
// [/patches]
|
||||
// Use Mid() to strip off the left and right side brackets.
|
||||
wxString midLine(key.Mid(1, key.Length()-2));
|
||||
wxString keyLvalue(midLine.BeforeFirst(L'=').Trim(true).Trim(false));
|
||||
|
||||
return wxsFormat( L"%s\n%s[/%s]\n",
|
||||
key.c_str(), value.c_str(), keyLvalue.c_str()
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
@ -70,7 +77,7 @@ class DataBase_Loader {
|
|||
protected:
|
||||
bool isComment(const wxString& s);
|
||||
void doError(const wxString& line, key_pair& keyPair, bool doMsg = false);
|
||||
void extractMultiLine(key_pair& keyPair, wxInputStream& reader);
|
||||
bool extractMultiLine(const wxString& line, key_pair& keyPair, wxInputStream& reader);
|
||||
void extract(const wxString& line, key_pair& keyPair, wxInputStream& reader);
|
||||
|
||||
const wxString m_emptyString; // empty string for returning stuff .. never modify!
|
||||
|
|
|
@ -1385,7 +1385,7 @@ void PluginManager::SendSettingsFolder()
|
|||
ScopedLock lock( m_mtx_PluginStatus );
|
||||
if( m_SettingsFolder.IsEmpty() ) return;
|
||||
|
||||
wxCharBuffer utf8buffer( m_SettingsFolder.ToUTF8() );
|
||||
pxToUTF8 utf8buffer( m_SettingsFolder );
|
||||
|
||||
const PluginInfo* pi = tbl_PluginInfo; do {
|
||||
if( m_info[pi->id] ) m_info[pi->id]->CommonBindings.SetSettingsDir( utf8buffer );
|
||||
|
@ -1412,7 +1412,7 @@ void PluginManager::SendLogFolder()
|
|||
ScopedLock lock( m_mtx_PluginStatus );
|
||||
if( m_LogFolder.IsEmpty() ) return;
|
||||
|
||||
wxCharBuffer utf8buffer( m_LogFolder.ToUTF8() );
|
||||
pxToUTF8 utf8buffer( m_LogFolder );
|
||||
|
||||
const PluginInfo* pi = tbl_PluginInfo; do {
|
||||
if( m_info[pi->id] ) m_info[pi->id]->CommonBindings.SetLogFolder( utf8buffer );
|
||||
|
|
|
@ -111,8 +111,9 @@ void SaveStateBase::FreezeBios()
|
|||
memzero( descin );
|
||||
memzero( desccmp );
|
||||
|
||||
memcpy_fast( descin, descout.ToUTF8().data(), descout.Length() );
|
||||
memcpy_fast( desccmp, descout.ToUTF8().data(), descout.Length() );
|
||||
pxToUTF8 utf8(descout);
|
||||
memcpy_fast( descin, utf8, utf8.Length() );
|
||||
memcpy_fast( desccmp, utf8, utf8.Length() );
|
||||
|
||||
// ... and only freeze bios info once per state, since the user msg could
|
||||
// become really annoying on a corrupted state or something. (have to always
|
||||
|
@ -130,7 +131,7 @@ void SaveStateBase::FreezeBios()
|
|||
Console.Indent(2).Error(
|
||||
"Current Version: %s\n"
|
||||
"Savestate Version: %s\n",
|
||||
descout.ToUTF8().data(), descin
|
||||
utf8.data(), descin
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -359,14 +359,17 @@ namespace Panels
|
|||
wxTextCtrl* commentBox;
|
||||
wxTextCtrl* patchesBox;
|
||||
pxCheckBox* gameFixes[NUM_OF_GAME_FIXES];
|
||||
|
||||
public:
|
||||
GameDatabasePanel( wxWindow* parent );
|
||||
virtual ~GameDatabasePanel() throw() { }
|
||||
void PopulateFields();
|
||||
void WriteFieldsToDB();
|
||||
void Search_Click( wxCommandEvent& evt );
|
||||
void Apply();
|
||||
void AppStatusEvent_OnSettingsApplied();
|
||||
|
||||
protected:
|
||||
void PopulateFields();
|
||||
bool WriteFieldsToDB();
|
||||
void Search_Click( wxCommandEvent& evt );
|
||||
};
|
||||
|
||||
class SettingsDirPickerPanel : public DirPickerPanel
|
||||
|
|
|
@ -141,11 +141,12 @@ void Panels::GameDatabasePanel::PopulateFields() {
|
|||
else GameDB->writeBool(wxT(_key), _value); \
|
||||
}
|
||||
|
||||
void Panels::GameDatabasePanel::WriteFieldsToDB() {
|
||||
// returns True if the database is modified, or FALSE if no changes to save.
|
||||
bool Panels::GameDatabasePanel::WriteFieldsToDB() {
|
||||
wxString wxStr( serialBox->GetValue() );
|
||||
|
||||
if (wxStr.IsEmpty()) return;
|
||||
if (wxStr == GameDB->getString("Serial")) {
|
||||
if (wxStr.IsEmpty()) return false;
|
||||
if (wxStr != GameDB->getString("Serial")) {
|
||||
GameDB->addGame(wxStr);
|
||||
}
|
||||
|
||||
|
@ -163,6 +164,7 @@ void Panels::GameDatabasePanel::WriteFieldsToDB() {
|
|||
writeGameFixToDB("IPUWaitHack", gameFixes[6]->GetValue());
|
||||
writeGameFixToDB("EETimingHack", gameFixes[7]->GetValue());
|
||||
writeGameFixToDB("SkipMPEGHack", gameFixes[8]->GetValue());
|
||||
return true;
|
||||
}
|
||||
|
||||
void Panels::GameDatabasePanel::Search_Click(wxCommandEvent& evt) {
|
||||
|
@ -178,9 +180,11 @@ void Panels::GameDatabasePanel::Search_Click(wxCommandEvent& evt) {
|
|||
}
|
||||
|
||||
void Panels::GameDatabasePanel::Apply() {
|
||||
Console.WriteLn("Saving changes to Game Database...");
|
||||
WriteFieldsToDB();
|
||||
GameDB->saveToFile();
|
||||
if( WriteFieldsToDB() )
|
||||
{
|
||||
Console.WriteLn("Saving changes to Game Database...");
|
||||
GameDB->saveToFile();
|
||||
}
|
||||
}
|
||||
|
||||
void Panels::GameDatabasePanel::AppStatusEvent_OnSettingsApplied()
|
||||
|
|
Loading…
Reference in New Issue