aboutsummaryrefslogtreecommitdiffstats
path: root/src/base/songloading/songloading_strategy_txt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/songloading/songloading_strategy_txt.cpp')
-rw-r--r--src/base/songloading/songloading_strategy_txt.cpp137
1 files changed, 134 insertions, 3 deletions
diff --git a/src/base/songloading/songloading_strategy_txt.cpp b/src/base/songloading/songloading_strategy_txt.cpp
index e8238f4a..31604191 100644
--- a/src/base/songloading/songloading_strategy_txt.cpp
+++ b/src/base/songloading/songloading_strategy_txt.cpp
@@ -24,10 +24,17 @@
* $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)
{
}
@@ -36,9 +43,133 @@ namespace usdx
{
}
- Song* SongloadingStrategyTxt::loadSong(std::string filename)
+ 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 to : 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)
{
- // TODO
- return NULL;
+ 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);
}
};