diff --git a/src/achievements/achievement.cpp b/src/achievements/achievement.cpp index d6dbb3589..7aa60397b 100644 --- a/src/achievements/achievement.cpp +++ b/src/achievements/achievement.cpp @@ -68,8 +68,8 @@ void Achievement::load(const XMLNode *node) */ void Achievement::save(UTFWriter &out) { - out << L" \n"; diff --git a/src/achievements/achievements_status.cpp b/src/achievements/achievements_status.cpp index bccf443d2..2b51abe7e 100644 --- a/src/achievements/achievements_status.cpp +++ b/src/achievements/achievements_status.cpp @@ -94,14 +94,14 @@ void AchievementsStatus::add(Achievement *achievement) */ void AchievementsStatus::save(UTFWriter &out) { - out << L" \n"; + out << " \n"; std::map::const_iterator i; for(i = m_achievements.begin(); i != m_achievements.end(); i++) { if (i->second != NULL) i->second->save(out); } - out << L" \n"; + out << " \n"; } // save // ---------------------------------------------------------------------------- diff --git a/src/challenges/challenge_status.cpp b/src/challenges/challenge_status.cpp index 1c0c36863..1397422ea 100644 --- a/src/challenges/challenge_status.cpp +++ b/src/challenges/challenge_status.cpp @@ -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 diff --git a/src/challenges/story_mode_status.cpp b/src/challenges/story_mode_status.cpp index 8fb8d820a..266f6548d 100644 --- a/src/challenges/story_mode_status.cpp +++ b/src/challenges/story_mode_status.cpp @@ -355,7 +355,7 @@ void StoryModeStatus::grandPrixFinished() */ void StoryModeStatus::save(UTFWriter &out) { - out << L" \n"; + out << " \n"; std::map::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" \n"; + out << " \n"; } // save diff --git a/src/config/player_manager.cpp b/src/config/player_manager.cpp index 416600b46..f52e470e4 100644 --- a/src/config/player_manager.cpp +++ b/src/config/player_manager.cpp @@ -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"\n"; - players_file << L"\n"; + players_file << "\n"; + players_file << "\n"; if(m_current_player) { - players_file << L" getName(true/*ignoreRTL*/)) << L"\"/>\n"; } @@ -278,7 +278,7 @@ void PlayerManager::save() if(!player->isGuestAccount()) player->save(players_file); } - players_file << L"\n"; + players_file << "\n"; players_file.close(); } catch (std::runtime_error& e) diff --git a/src/config/player_profile.cpp b/src/config/player_profile.cpp index a7b10f42a..913c70aa5 100644 --- a/src/config/player_profile.cpp +++ b/src/config/player_profile.cpp @@ -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" \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" \n"; + out << " \n"; } // save //------------------------------------------------------------------------------ diff --git a/src/io/utf_writer.cpp b/src/io/utf_writer.cpp index 4232f20ab..9e12f3770 100644 --- a/src/io/utf_writer.cpp +++ b/src/io/utf_writer.cpp @@ -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) diff --git a/src/io/utf_writer.hpp b/src/io/utf_writer.hpp index 02f8ebcd7..9ac71f7a5 100644 --- a/src/io/utf_writer.hpp +++ b/src/io/utf_writer.hpp @@ -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) diff --git a/src/race/grand_prix_data.cpp b/src/race/grand_prix_data.cpp index 1a662f091..90ca62cb3 100644 --- a/src/race/grand_prix_data.cpp +++ b/src/race/grand_prix_data.cpp @@ -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\n\n"; + file << "\n\n\n"; for (unsigned int i = 0; i < m_tracks.size(); i++) { file << - L"\t\n"; + "\t\n"; } - file << L"\n\n"; + file << "\n\n"; file.close(); diff --git a/src/race/highscore_manager.cpp b/src/race/highscore_manager.cpp index 92eff9094..e0fc094f4 100644 --- a/src/race/highscore_manager.cpp +++ b/src/race/highscore_manager.cpp @@ -150,15 +150,15 @@ void HighscoreManager::saveHighscores() try { - UTFWriter highscore_file(m_filename.c_str()); - highscore_file << L"\n"; - highscore_file << L"\n"; + UTFWriter highscore_file(m_filename.c_str(), false); + highscore_file << "\n"; + highscore_file << "\n"; for(unsigned int i=0; iwriteEntry(highscore_file); } - highscore_file << L"\n"; + highscore_file << "\n"; highscore_file.close(); } catch(std::exception &e) diff --git a/src/race/highscores.cpp b/src/race/highscores.cpp index bc5a4f2c5..54daf277e 100644 --- a/src/race/highscores.cpp +++ b/src/race/highscores.cpp @@ -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" \n"; + writer << " \n"; for(int i=0; i 0.0f) { assert(m_kart_name[i].size() > 0); - writer << L" \n"; + writer << " \n"; } } // for i - writer << L" \n"; + writer << " \n"; } // writeEntry // -----------------------------------------------------------------------------