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)
{
out << L" <achievement id=\"" << m_id << L"\" "
<< L"achieved=\"" << m_achieved << "\"";
out << " <achievement id=\"" << m_id << "\" "
<< "achieved=\"" << m_achieved << "\"";
if (isAchieved())
{
out << "/>\n";

View File

@ -94,14 +94,14 @@ void AchievementsStatus::add(Achievement *achievement)
*/
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;
for(i = m_achievements.begin(); i != m_achievements.end(); i++)
{
if (i->second != NULL)
i->second->save(out);
}
out << L" </achievements>\n";
out << " </achievements>\n";
} // save
// ----------------------------------------------------------------------------

View File

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

View File

@ -355,7 +355,7 @@ void StoryModeStatus::grandPrixFinished()
*/
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;
for(i = m_challenges_state.begin();
i != m_challenges_state.end(); i++)
@ -363,5 +363,5 @@ void StoryModeStatus::save(UTFWriter &out)
if (i->second != NULL)
i->second->save(out);
}
out << L" </story-mode>\n";
out << " </story-mode>\n";
} // save

View File

@ -261,14 +261,14 @@ void PlayerManager::save()
std::string filename = file_manager->getUserConfigFile("players.xml");
try
{
UTFWriter players_file(filename.c_str());
UTFWriter players_file(filename.c_str(), false);
players_file << L"<?xml version=\"1.0\"?>\n";
players_file << L"<players version=\"1\" >\n";
players_file << "<?xml version=\"1.0\"?>\n";
players_file << "<players version=\"1\" >\n";
if(m_current_player)
{
players_file << L" <current player=\""
players_file << " <current player=\""
<< StringUtils::xmlEncode(m_current_player->getName(true/*ignoreRTL*/)) << L"\"/>\n";
}
@ -278,7 +278,7 @@ void PlayerManager::save()
if(!player->isGuestAccount())
player->save(players_file);
}
players_file << L"</players>\n";
players_file << "</players>\n";
players_file.close();
}
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-user", &m_saved_user_id );
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("remember-password", &m_remember_password);
node->get("icon-filename", &m_icon_filename );
@ -200,21 +200,21 @@ const std::string PlayerProfile::getIconFilename() const
*/
void PlayerProfile::save(UTFWriter &out)
{
out << L" <player name=\"" << StringUtils::xmlEncode(m_local_name)
<< L"\" guest=\"" << m_is_guest_account
<< L"\" use-frequency=\"" << m_use_frequency << L"\"\n";
out << " <player name=\"" << StringUtils::xmlEncode(m_local_name)
<< "\" guest=\"" << m_is_guest_account
<< "\" 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
<< L"\" saved-session=\"" << m_saved_session << L"\"\n";
out << " unique-id=\"" << m_unique_id
<< "\" saved-session=\"" << m_saved_session << "\"\n";
out << L" saved-user=\"" << m_saved_user_id
<< L"\" saved-token=\"" << m_saved_token << L"\"\n";
out << L" last-online-name=\"" << m_last_online_name
<< L"\" last-was-online=\"" << m_last_was_online << L"\"\n";
out << L" remember-password=\"" << m_remember_password << L"\"\n";
out << L" default-kart-color=\"" << m_default_kart_color << L"\">\n";
out << " saved-user=\"" << m_saved_user_id
<< "\" saved-token=\"" << m_saved_token << "\"\n";
out << " last-online-name=\"" << StringUtils::xmlEncode(m_last_online_name)
<< "\" last-was-online=\"" << m_last_was_online << "\"\n";
out << " remember-password=\"" << m_remember_password << "\"\n";
out << " default-kart-color=\"" << m_default_kart_color << "\">\n";
{
if(m_story_mode_status)
m_story_mode_status->save(out);
@ -222,7 +222,7 @@ void PlayerProfile::save(UTFWriter &out)
if(m_achievements_status)
m_achievements_status->save(out);
}
out << L" </player>\n";
out << " </player>\n";
} // 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_wide = wide;
if (!m_base.is_open())
{
throw std::runtime_error("Failed to open file for writing : " +
std::string(dest));
}
// 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;
if (wide)
{
// 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::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;
} // operator<< (stringw)
@ -53,7 +66,15 @@ UTFWriter& UTFWriter::operator<< (const irr::core::stringw& 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;
} // operator<< (wchar_t)

View File

@ -34,9 +34,12 @@
class UTFWriter
{
std::ofstream m_base;
/** If true, use utf-16/32 (obsolete) */
bool m_wide;
public:
UTFWriter(const char* dest);
UTFWriter(const char* dest, bool wide);
void close();
UTFWriter& operator<< (const irr::core::stringw& txt);
@ -44,12 +47,24 @@ public:
// ------------------------------------------------------------------------
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*)
// ------------------------------------------------------------------------
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)
// ------------------------------------------------------------------------
UTFWriter& operator<< (const bool &b)

View File

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

View File

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

View File

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