/* * UltraStar Deluxe - Karaoke Game * * UltraStar Deluxe is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * $URL$ * $Id$ */ #include #include #include "songloading_strategy_txt.hpp" #include "utils/file.hpp" namespace usdx { log4cxx::LoggerPtr SongloadingStrategyTxt::log = log4cxx::Logger::getLogger( "usdx.base.songloading.SongloadingStrategyTxt"); SongloadingStrategyTxt::SongloadingStrategyTxt(void) { } SongloadingStrategyTxt::~SongloadingStrategyTxt(void) { } std::pair SongloadingStrategyTxt::split_header_field(std::string &line) { std::size_t pos = line.find(':'); if (line[0] != '#' || pos == std::string::npos) { LOG4CXX_DEBUG(log, "Tried to parse invalid header line: '" << line << "'"); throw "Invalid header!"; } std::pair result; // copy the substring until ':', without # to result.first and // transform to upper case result.first.resize(pos - 1); std::transform(line.begin() + 1, line.begin() + pos, result.first.begin(), toupper); // line is already ltrimmed rtrim(result.first); result.second = line.substr(pos + 1); // line is already rtrimmed ltrim(result.second); LOG4CXX_DEBUG(log, "Found header: '" << result.first << "' with value '" << result.second << "'"); return result; } std::string& SongloadingStrategyTxt::ltrim(std::string& line) { std::size_t found = line.find_first_not_of(" \t\n\r"); if (found != std::string::npos && found >= 1) { line.erase(0, found - 1); } return line; } std::string& SongloadingStrategyTxt::rtrim(std::string& line) { std::size_t found = line.find_last_not_of(" \t\n\r"); if (found != std::string::npos) { line.erase(found + 1); } return line; } std::string& SongloadingStrategyTxt::trim(std::string& line) { return ltrim(rtrim(line)); } Song* SongloadingStrategyTxt::load_song(Song *song) { File file(song->get_filename()); std::string line; while (file.stream().good()) { file.stream() >> line; // do not remove spaces at line ending, that are maybe // spaces in lyrics ltrim(line); if (line[0] == '#') { // ignore, header already read } else if (line[0] == 'E') { // song end break; } else if (line[0] == '-') { // line break } else if (line[0] == 'B') { // new bpm } else { // normal line } } // fill song return song; } Song* SongloadingStrategyTxt::load_header(const std::string& filename) { File file(filename); std::string line; std::map header_fields; bool header = true, notes_found = false; while (file.stream().good()) { std::getline(file.stream(), line); trim(line); LOG4CXX_DEBUG(log, "Line: " << line); if (header && line[0] == '#') { // header header_fields.insert(split_header_field(line)); } else { if (header) { // end of header header = false; } if (line[0] == ':' || line[0] == '*' || line[0] == 'F') { notes_found = true; break; } } } if (! notes_found) { LOG4CXX_WARN(log, "Song: '" << filename << "' has no notes. Ignoring!"); throw "No notes."; } // fill song return new Song(filename, header_fields); } };