Finish m3u parser

This commit is contained in:
John Maguire 2010-03-05 11:57:06 +00:00
parent 4773d7cadc
commit 1ad24804cc
3 changed files with 54 additions and 3 deletions

View File

@ -11,18 +11,19 @@ M3UParser::M3UParser(QIODevice* device, const QDir& directory, QObject* parent)
const QList<Song>& M3UParser::Parse() {
QString line = QString::fromLatin1(device_->readLine());
if (line == "#EXTM3U") {
if (line.startsWith("#EXTM3U")) {
// This is in extended M3U format.
type_ = EXTENDED;
line = QString::fromLatin1(device_->readLine());
}
do {
forever {
if (line.startsWith('#')) {
// Extended info or comment.
if (type_ == EXTENDED && line.startsWith("#EXT")) {
if (!ParseMetadata(line, &current_metadata_)) {
qWarning() << "Failed to parse metadata: " << line;
continue;
}
}
} else {
@ -30,10 +31,23 @@ const QList<Song>& M3UParser::Parse() {
QUrl url;
if (!ParseTrackLocation(line, &url)) {
qWarning() << "Failed to parse location: " << line;
continue;
}
Song song;
song.set_title(current_metadata_.title);
song.set_artist(current_metadata_.artist);
song.set_length(current_metadata_.length);
song.set_filename(url.toString());
songs_ << song;
current_metadata_.artist.clear();
current_metadata_.title.clear();
current_metadata_.length = -1;
}
if (!device_->canReadLine()) {
break;
}
line = QString::fromLatin1(device_->readLine());
} while (device_->canReadLine());
}
return songs_;
}

View File

@ -20,6 +20,7 @@ class M3UParser : public QObject {
const SongList& Parse();
struct Metadata {
Metadata() : length(-1) {}
QString artist;
QString title;
int length;

View File

@ -3,6 +3,8 @@
#include "m3uparser.h"
#include <QBuffer>
class M3UParserTest : public ::testing::Test {
protected:
M3UParserTest()
@ -51,3 +53,37 @@ TEST_F(M3UParserTest, ParsesTrackLocationAbsoluteWindows) {
EXPECT_EQ(QUrl("file:///c:/foo/bar.mp3"), url);
}
#endif // Q_OS_WIN32
TEST_F(M3UParserTest, ParsesSongsFromDevice) {
QByteArray data = "#EXTM3U\n"
"#EXTINF:123,Some Artist - Some Title\n"
"foo/bar/somefile.mp3\n";
QBuffer buffer(&data);
buffer.open(QIODevice::ReadOnly);
M3UParser parser(&buffer, QDir("somedir"));
const QList<Song>& songs = parser.Parse();
ASSERT_EQ(1, songs.size());
Song s = songs[0];
EXPECT_EQ("Some Artist", s.artist());
EXPECT_EQ("Some Title", s.title());
EXPECT_EQ(123, s.length());
EXPECT_PRED_FORMAT2(::testing::IsSubstring,
"somedir/foo/bar/somefile.mp3", s.filename().toStdString());
}
TEST_F(M3UParserTest, ParsesNonExtendedM3U) {
QByteArray data = "foo/bar/somefile.mp3\n"
"baz/thing.mp3\n";
QBuffer buffer(&data);
buffer.open(QIODevice::ReadOnly);
M3UParser parser(&buffer, QDir("somedir"));
const QList<Song>& songs = parser.Parse();
ASSERT_EQ(2, songs.size());
EXPECT_PRED_FORMAT2(::testing::IsSubstring,
"somedir/foo/bar/somefile.mp3", songs[0].filename().toStdString());
EXPECT_PRED_FORMAT2(::testing::IsSubstring,
"somedir/baz/thing.mp3", songs[1].filename().toStdString());
EXPECT_EQ(-1, songs[0].length());
EXPECT_EQ(-1, songs[1].length());
EXPECT_TRUE(songs[0].artist().isEmpty());
}