aboutsummaryrefslogblamecommitdiffstats
path: root/src/base/songloading/songloading_strategy_txt.cpp
blob: 841e6253fb30eeedbe9757c2b114337e02bb4f44 (plain) (tree)

























                                                                        

                    
                                       
                         


              



                                                                        







                                                             










                                                                                                         
                                                                              






































                                                                                                                  
         











































































                                                                                                 

         
/*
 * 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 <string>
#include <algorithm>
#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<std::string, std::string> 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<std::string, std::string> 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<std::string, std::string> 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);
	}
};