Merge branch 'UTF8_Config'

This commit is contained in:
auria.mg 2018-06-04 19:34:07 -04:00
commit 3f1bd6b25e
11 changed files with 102 additions and 66 deletions

View File

@ -68,8 +68,8 @@ void Achievement::load(const XMLNode *node)
*/ */
void Achievement::save(UTFWriter &out) void Achievement::save(UTFWriter &out)
{ {
out << L" <achievement id=\"" << m_id << L"\" " out << " <achievement id=\"" << m_id << "\" "
<< L"achieved=\"" << m_achieved << "\""; << "achieved=\"" << m_achieved << "\"";
if (isAchieved()) if (isAchieved())
{ {
out << "/>\n"; out << "/>\n";

View File

@ -94,14 +94,14 @@ void AchievementsStatus::add(Achievement *achievement)
*/ */
void AchievementsStatus::save(UTFWriter &out) void AchievementsStatus::save(UTFWriter &out)
{ {
out << L" <achievements online=\"" << m_online << L"\"> \n"; out << " <achievements online=\"" << m_online << "\"> \n";
std::map<uint32_t, Achievement*>::const_iterator i; std::map<uint32_t, Achievement*>::const_iterator i;
for(i = m_achievements.begin(); i != m_achievements.end(); i++) for(i = m_achievements.begin(); i != m_achievements.end(); i++)
{ {
if (i->second != NULL) if (i->second != NULL)
i->second->save(out); i->second->save(out);
} }
out << L" </achievements>\n"; out << " </achievements>\n";
} // save } // save
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -104,15 +104,15 @@ bool ChallengeStatus::isGrandPrix()
void ChallengeStatus::save(UTFWriter& writer) void ChallengeStatus::save(UTFWriter& writer)
{ {
writer << L" <" << m_data->getChallengeId(); writer << " <" << m_data->getChallengeId();
if (isSolved(RaceManager::DIFFICULTY_BEST)) if (isSolved(RaceManager::DIFFICULTY_BEST))
writer << L" solved=\"best\"/>\n"; writer << " solved=\"best\"/>\n";
else if (isSolved(RaceManager::DIFFICULTY_HARD)) else if (isSolved(RaceManager::DIFFICULTY_HARD))
writer << L" solved=\"hard\"/>\n"; writer << " solved=\"hard\"/>\n";
else if (isSolved(RaceManager::DIFFICULTY_MEDIUM)) else if (isSolved(RaceManager::DIFFICULTY_MEDIUM))
writer << L" solved=\"medium\"/>\n"; writer << " solved=\"medium\"/>\n";
else if (isSolved(RaceManager::DIFFICULTY_EASY)) else if (isSolved(RaceManager::DIFFICULTY_EASY))
writer << L" solved=\"easy\"/>\n"; writer << " solved=\"easy\"/>\n";
else else
writer << L" solved=\"none\"/>\n"; writer << " solved=\"none\"/>\n";
} // save } // save

View File

@ -355,7 +355,7 @@ void StoryModeStatus::grandPrixFinished()
*/ */
void StoryModeStatus::save(UTFWriter &out) void StoryModeStatus::save(UTFWriter &out)
{ {
out << L" <story-mode first-time=\"" << m_first_time << L"\">\n"; out << " <story-mode first-time=\"" << m_first_time << L"\">\n";
std::map<std::string, ChallengeStatus*>::const_iterator i; std::map<std::string, ChallengeStatus*>::const_iterator i;
for(i = m_challenges_state.begin(); for(i = m_challenges_state.begin();
i != m_challenges_state.end(); i++) i != m_challenges_state.end(); i++)
@ -363,5 +363,5 @@ void StoryModeStatus::save(UTFWriter &out)
if (i->second != NULL) if (i->second != NULL)
i->second->save(out); i->second->save(out);
} }
out << L" </story-mode>\n"; out << " </story-mode>\n";
} // save } // save

View File

@ -261,14 +261,14 @@ void PlayerManager::save()
std::string filename = file_manager->getUserConfigFile("players.xml"); std::string filename = file_manager->getUserConfigFile("players.xml");
try try
{ {
UTFWriter players_file(filename.c_str()); UTFWriter players_file(filename.c_str(), false);
players_file << L"<?xml version=\"1.0\"?>\n"; players_file << "<?xml version=\"1.0\"?>\n";
players_file << L"<players version=\"1\" >\n"; players_file << "<players version=\"1\" >\n";
if(m_current_player) if(m_current_player)
{ {
players_file << L" <current player=\"" players_file << " <current player=\""
<< StringUtils::xmlEncode(m_current_player->getName(true/*ignoreRTL*/)) << L"\"/>\n"; << StringUtils::xmlEncode(m_current_player->getName(true/*ignoreRTL*/)) << L"\"/>\n";
} }
@ -278,7 +278,7 @@ void PlayerManager::save()
if(!player->isGuestAccount()) if(!player->isGuestAccount())
player->save(players_file); player->save(players_file);
} }
players_file << L"</players>\n"; players_file << "</players>\n";
players_file.close(); players_file.close();
} }
catch (std::runtime_error& e) catch (std::runtime_error& e)

View File

@ -87,7 +87,7 @@ PlayerProfile::PlayerProfile(const XMLNode* node)
node->get("saved-session", &m_saved_session ); node->get("saved-session", &m_saved_session );
node->get("saved-user", &m_saved_user_id ); node->get("saved-user", &m_saved_user_id );
node->get("saved-token", &m_saved_token ); node->get("saved-token", &m_saved_token );
node->get("last-online-name", &m_last_online_name ); node->getAndDecode("last-online-name", &m_last_online_name );
node->get("last-was-online", &m_last_was_online ); node->get("last-was-online", &m_last_was_online );
node->get("remember-password", &m_remember_password); node->get("remember-password", &m_remember_password);
node->get("icon-filename", &m_icon_filename ); node->get("icon-filename", &m_icon_filename );
@ -200,21 +200,21 @@ const std::string PlayerProfile::getIconFilename() const
*/ */
void PlayerProfile::save(UTFWriter &out) void PlayerProfile::save(UTFWriter &out)
{ {
out << L" <player name=\"" << StringUtils::xmlEncode(m_local_name) out << " <player name=\"" << StringUtils::xmlEncode(m_local_name)
<< L"\" guest=\"" << m_is_guest_account << "\" guest=\"" << m_is_guest_account
<< L"\" use-frequency=\"" << m_use_frequency << L"\"\n"; << "\" use-frequency=\"" << m_use_frequency << "\"\n";
out << L" icon-filename=\"" << m_icon_filename << L"\"\n"; out << " icon-filename=\"" << m_icon_filename << "\"\n";
out << L" unique-id=\"" << m_unique_id out << " unique-id=\"" << m_unique_id
<< L"\" saved-session=\"" << m_saved_session << L"\"\n"; << "\" saved-session=\"" << m_saved_session << "\"\n";
out << L" saved-user=\"" << m_saved_user_id out << " saved-user=\"" << m_saved_user_id
<< L"\" saved-token=\"" << m_saved_token << L"\"\n"; << "\" saved-token=\"" << m_saved_token << "\"\n";
out << L" last-online-name=\"" << m_last_online_name out << " last-online-name=\"" << StringUtils::xmlEncode(m_last_online_name)
<< L"\" last-was-online=\"" << m_last_was_online << L"\"\n"; << "\" last-was-online=\"" << m_last_was_online << "\"\n";
out << L" remember-password=\"" << m_remember_password << L"\"\n"; out << " remember-password=\"" << m_remember_password << "\"\n";
out << L" default-kart-color=\"" << m_default_kart_color << L"\">\n"; out << " default-kart-color=\"" << m_default_kart_color << "\">\n";
{ {
if(m_story_mode_status) if(m_story_mode_status)
m_story_mode_status->save(out); m_story_mode_status->save(out);
@ -222,7 +222,7 @@ void PlayerProfile::save(UTFWriter &out)
if(m_achievements_status) if(m_achievements_status)
m_achievements_status->save(out); m_achievements_status->save(out);
} }
out << L" </player>\n"; out << " </player>\n";
} // save } // save
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@ -25,27 +25,40 @@ using namespace irr;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
UTFWriter::UTFWriter(const char* dest) UTFWriter::UTFWriter(const char* dest, bool wide)
: m_base(dest, std::ios::out | std::ios::binary) : m_base(dest, std::ios::out | std::ios::binary)
{ {
m_wide = wide;
if (!m_base.is_open()) if (!m_base.is_open())
{ {
throw std::runtime_error("Failed to open file for writing : " + throw std::runtime_error("Failed to open file for writing : " +
std::string(dest)); std::string(dest));
} }
// FIXME: make sure to properly handle endianness if (wide)
// UTF-16 BOM is 0xFEFF; UTF-32 BOM is 0x0000FEFF. So this works in either case {
wchar_t BOM = 0xFEFF; // FIXME: make sure to properly handle endianness
// UTF-16 BOM is 0xFEFF; UTF-32 BOM is 0x0000FEFF. So this works in either case
wchar_t BOM = 0xFEFF;
m_base.write((char *) &BOM, sizeof(wchar_t)); m_base.write((char *) &BOM, sizeof(wchar_t));
}
} // UTFWriter } // UTFWriter
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
UTFWriter& UTFWriter::operator<< (const irr::core::stringw& txt) UTFWriter& UTFWriter::operator<< (const irr::core::stringw& txt)
{ {
m_base.write((char *) txt.c_str(), txt.size() * sizeof(wchar_t)); if (m_wide)
{
m_base.write((char *) txt.c_str(), txt.size() * sizeof(wchar_t));
}
else
{
std::string utf8 = StringUtils::wideToUtf8(txt);
operator<<(utf8);
}
return *this; return *this;
} // operator<< (stringw) } // operator<< (stringw)
@ -53,7 +66,15 @@ UTFWriter& UTFWriter::operator<< (const irr::core::stringw& txt)
UTFWriter& UTFWriter::operator<< (const wchar_t*txt) UTFWriter& UTFWriter::operator<< (const wchar_t*txt)
{ {
m_base.write((char *) txt, wcslen(txt) * sizeof(wchar_t)); if (m_wide)
{
m_base.write((char *) txt, wcslen(txt) * sizeof(wchar_t));
}
else
{
std::string utf8 = StringUtils::wideToUtf8(txt);
operator<<(utf8);
}
return *this; return *this;
} // operator<< (wchar_t) } // operator<< (wchar_t)

View File

@ -34,9 +34,12 @@
class UTFWriter class UTFWriter
{ {
std::ofstream m_base; std::ofstream m_base;
/** If true, use utf-16/32 (obsolete) */
bool m_wide;
public: public:
UTFWriter(const char* dest); UTFWriter(const char* dest, bool wide);
void close(); void close();
UTFWriter& operator<< (const irr::core::stringw& txt); UTFWriter& operator<< (const irr::core::stringw& txt);
@ -44,12 +47,24 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
UTFWriter& operator<< (const char *txt) UTFWriter& operator<< (const char *txt)
{ {
return operator<<(irr::core::stringw(txt)); if (m_wide)
{
return operator<<(irr::core::stringw(txt));
}
else
{
m_base.write((char *)txt, strlen(txt));
return *this;
}
} // operator<<(char*) } // operator<<(char*)
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
UTFWriter& operator<< (const std::string &txt) UTFWriter& operator<< (const std::string &txt)
{ {
return operator<< (irr::core::stringw(txt.c_str())); if (m_wide)
return operator<<(irr::core::stringw(txt.c_str()));
else
return operator<<(txt.c_str());
} // operator<<(std::string) } // operator<<(std::string)
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
UTFWriter& operator<< (const bool &b) UTFWriter& operator<< (const bool &b)

View File

@ -270,7 +270,7 @@ void GrandPrixData::reload()
throw std::runtime_error("Wrong root node name"); throw std::runtime_error("Wrong root node name");
} }
if (!root->get("name", &m_name)) if (!root->getAndDecode("name", &m_name))
{ {
Log::error("GrandPrixData", Log::error("GrandPrixData",
"Error while trying to read grandprix file '%s': " "Error while trying to read grandprix file '%s': "
@ -361,20 +361,20 @@ bool GrandPrixData::writeToFile()
{ {
try try
{ {
UTFWriter file(m_filename.c_str()); UTFWriter file(m_filename.c_str(), false);
if (file.is_open()) if (file.is_open())
{ {
file << L"\n<supertuxkart_grand_prix name=\"" << m_name file << "\n<supertuxkart_grand_prix name=\"" << StringUtils::xmlEncode(m_name)
<< L"\">\n\n"; << "\">\n\n";
for (unsigned int i = 0; i < m_tracks.size(); i++) for (unsigned int i = 0; i < m_tracks.size(); i++)
{ {
file << file <<
L"\t<track id=\"" << m_tracks[i] << "\t<track id=\"" << m_tracks[i] <<
L"\" laps=\"" << m_laps[i] << "\" laps=\"" << m_laps[i] <<
L"\" reverse=\"" << (m_reversed[i] ? L"true" : L"false") "\" reverse=\"" << (m_reversed[i] ? L"true" : L"false")
<< L"\" />\n"; << "\" />\n";
} }
file << L"\n</supertuxkart_grand_prix>\n"; file << "\n</supertuxkart_grand_prix>\n";
file.close(); file.close();

View File

@ -150,15 +150,15 @@ void HighscoreManager::saveHighscores()
try try
{ {
UTFWriter highscore_file(m_filename.c_str()); UTFWriter highscore_file(m_filename.c_str(), false);
highscore_file << L"<?xml version=\"1.0\"?>\n"; highscore_file << "<?xml version=\"1.0\"?>\n";
highscore_file << L"<highscores version=\"" << CURRENT_HSCORE_FILE_VERSION << "\">\n"; highscore_file << "<highscores version=\"" << CURRENT_HSCORE_FILE_VERSION << "\">\n";
for(unsigned int i=0; i<m_all_scores.size(); i++) for(unsigned int i=0; i<m_all_scores.size(); i++)
{ {
m_all_scores[i]->writeEntry(highscore_file); m_all_scores[i]->writeEntry(highscore_file);
} }
highscore_file << L"</highscores>\n"; highscore_file << "</highscores>\n";
highscore_file.close(); highscore_file.close();
} }
catch(std::exception &e) catch(std::exception &e)

View File

@ -83,7 +83,7 @@ void Highscores::readEntry(const XMLNode &node)
{ {
const XMLNode *entry = node.getNode(i); const XMLNode *entry = node.getNode(i);
entry->get("time", &m_time[i] ); entry->get("time", &m_time[i] );
entry->get("name", &m_name[i] ); entry->getAndDecode("name", &m_name[i] );
entry->get("kartname", &m_kart_name[i] ); entry->get("kartname", &m_kart_name[i] );
// a non-empty entry needs a non-empty kart name. // a non-empty entry needs a non-empty kart name.
@ -113,25 +113,25 @@ void Highscores::writeEntry(UTFWriter &writer)
one_is_set |= m_time[i]>=0; one_is_set |= m_time[i]>=0;
if(!one_is_set) return; if(!one_is_set) return;
writer << L" <highscore track-name =\"" << m_track.c_str() << "\"\n"; writer << " <highscore track-name =\"" << m_track.c_str() << "\"\n";
writer << L" number-karts =\"" << m_number_of_karts << "\"\n"; writer << " number-karts =\"" << m_number_of_karts << "\"\n";
writer << L" difficulty =\"" << m_difficulty << "\"\n"; writer << " difficulty =\"" << m_difficulty << "\"\n";
writer << L" hscore-type =\"" << m_highscore_type.c_str() << "\"\n"; writer << " hscore-type =\"" << m_highscore_type.c_str() << "\"\n";
writer << L" number-of-laps=\"" << m_number_of_laps << "\"\n"; writer << " number-of-laps=\"" << m_number_of_laps << "\"\n";
writer << L" reverse =\"" << m_reverse << "\">\n"; writer << " reverse =\"" << m_reverse << "\">\n";
for(int i=0; i<HIGHSCORE_LEN; i++) for(int i=0; i<HIGHSCORE_LEN; i++)
{ {
if (m_time[i] > 0.0f) if (m_time[i] > 0.0f)
{ {
assert(m_kart_name[i].size() > 0); assert(m_kart_name[i].size() > 0);
writer << L" <entry time =\"" << m_time[i] << L"\"\n"; writer << " <entry time =\"" << m_time[i] << L"\"\n";
writer << L" name =\"" << m_name[i] << L"\"\n"; writer << " name =\"" << StringUtils::xmlEncode(m_name[i]) << L"\"\n";
writer << L" kartname=\"" << m_kart_name[i].c_str() writer << " kartname=\"" << m_kart_name[i]
<< L"\"/>\n"; << "\"/>\n";
} }
} // for i } // for i
writer << L" </highscore>\n"; writer << " </highscore>\n";
} // writeEntry } // writeEntry
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------