summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYoann Lopes <yoann.lopes@digia.com>2014-08-28 16:00:15 +0200
committerYoann Lopes <yoann.lopes@digia.com>2014-09-10 15:15:54 +0200
commit4c5aec9bb6fd95a65544aa433f1357320132ae9f (patch)
tree3608ecb2bbd94c5f82ec795b13bd88591f439574
parent90fd3ac39999389fd898dd43210f8af95adb5493 (diff)
Make PLS parser more permissive.
The PLS format is not clearly specified, some rules are just assumed and files don't always respect them. We now only look for 'File' entries, since that's the only thing we actually use. We ignore the Version, NumberOfEntries, Title, Length and any other unrecognized tags. Task-number: QTBUG-40515 Change-Id: I9c176b7b68fd1441abbd50364f88994ad5d6236f Reviewed-by: Christian Stromme <christian.stromme@digia.com>
-rw-r--r--src/multimedia/playback/playlistfileparser.cpp102
-rw-r--r--tests/auto/unit/qmediaplaylist/testdata/empty.pls (renamed from tests/auto/unit/qmediaplaylist/testdata/trash.pls)0
-rw-r--r--tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp22
3 files changed, 24 insertions, 100 deletions
diff --git a/src/multimedia/playback/playlistfileparser.cpp b/src/multimedia/playback/playlistfileparser.cpp
index 97c551c97..374d3fa0c 100644
--- a/src/multimedia/playback/playlistfileparser.cpp
+++ b/src/multimedia/playback/playlistfileparser.cpp
@@ -181,27 +181,9 @@ class PLSParser : public ParserBase
public:
PLSParser(QObject *parent)
: ParserBase(parent)
- , m_state(Header)
- , m_count(0)
- , m_readFlags(0)
{
}
- enum ReadFlags
- {
- FileRead = 0x1,
- TitleRead = 0x2,
- LengthRead = 0x4,
- All = FileRead | TitleRead | LengthRead
- };
-
- enum State
- {
- Header,
- Track,
- Footer
- };
-
/*
*
The format is essentially that of an INI file structured as follows:
@@ -240,89 +222,25 @@ NumberOfEntries=2
Version=2
*/
- inline bool containsFlag(const ReadFlags& flag)
+ void parseLine(int, const QString &line, const QUrl &root)
{
- return (m_readFlags & int(flag)) == flag;
- }
+ // We ignore everything but 'File' entries, since that's the only thing we care about.
+ if (!line.startsWith(QLatin1String("File")))
+ return;
- inline void setFlag(const ReadFlags& flag)
- {
- m_readFlags |= int(flag);
- }
+ QString value = getValue(line);
+ if (value.isEmpty())
+ return;
- void parseLine(int lineIndex, const QString &line, const QUrl &root)
- {
- switch (m_state) {
- case Header:
- if (line == QLatin1String("[playlist]")) {
- m_state = Track;
- setCount(1);
- }
- break;
- case Track:
- if (!containsFlag(FileRead) && line.startsWith(m_fileName)) {
- m_item[QLatin1String("url")] = expandToFullPath(root, getValue(lineIndex, line));
- setFlag(FileRead);
- } else if (!containsFlag(TitleRead) && line.startsWith(m_titleName)) {
- m_item[QMediaMetaData::Title] = getValue(lineIndex, line);
- setFlag(TitleRead);
- } else if (!containsFlag(LengthRead) && line.startsWith(m_lengthName)) {
- //convert from seconds to miliseconds
- int length = getValue(lineIndex, line).toInt();
- if (length > 0)
- m_item[QMediaMetaData::Duration] = length * 1000;
- setFlag(LengthRead);
- } else if (line.startsWith(QLatin1String("NumberOfEntries"))) {
- m_state = Footer;
- int entries = getValue(lineIndex, line).toInt();
- int count = m_readFlags == 0 ? (m_count - 1) : m_count;
- if (entries != count) {
- emit error(QPlaylistFileParser::FormatError, tr("Error parsing playlist: %1, expected count = %2").
- arg(line, QString::number(count)));
- }
- break;
- }
- if (m_readFlags == int(All)) {
- emit newItem(m_item);
- setCount(m_count + 1);
- }
- break;
- case Footer:
- if (line.startsWith(QLatin1String("Version"))) {
- int version = getValue(lineIndex, line).toInt();
- if (version != 2)
- emit error(QPlaylistFileParser::FormatError, QString(tr("Error parsing playlist at line[%1], expected version = 2")).arg(line));
- }
- break;
- }
+ emit newItem(expandToFullPath(root, value));
}
- QString getValue(int lineIndex, const QString& line) {
+ QString getValue(const QString& line) {
int start = line.indexOf('=');
- if (start < 0) {
- emit error(QPlaylistFileParser::FormatError, QString(tr("Error parsing playlist at line[%1]:%2")).arg(QString::number(lineIndex), line));
+ if (start < 0)
return QString();
- }
return line.midRef(start + 1).trimmed().toString();
}
-
- void setCount(int count) {
- m_count = count;
- m_fileName = QStringLiteral("File%1").arg(count);
- m_titleName = QStringLiteral("Title%1").arg(count);
- m_lengthName = QStringLiteral("Length%1").arg(count);
- m_item.clear();
- m_readFlags = 0;
- }
-
-private:
- State m_state;
- int m_count;
- QString m_titleName;
- QString m_fileName;
- QString m_lengthName;
- QVariantMap m_item;
- int m_readFlags;
};
}
diff --git a/tests/auto/unit/qmediaplaylist/testdata/trash.pls b/tests/auto/unit/qmediaplaylist/testdata/empty.pls
index 639c22b0c..639c22b0c 100644
--- a/tests/auto/unit/qmediaplaylist/testdata/trash.pls
+++ b/tests/auto/unit/qmediaplaylist/testdata/empty.pls
diff --git a/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp b/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp
index 748bcd306..82b7bdaf0 100644
--- a/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp
+++ b/tests/auto/unit/qmediaplaylist/tst_qmediaplaylist.cpp
@@ -471,14 +471,15 @@ void tst_QMediaPlaylist::loadPLSFile()
QVERIFY(!loadFailedSpy.isEmpty());
QVERIFY(playlist.error() != QMediaPlaylist::NoError);
- // Try to load bogus playlist
+ // Try to load empty playlist
loadSpy.clear();
loadFailedSpy.clear();
- testFileName = QFINDTESTDATA("testdata/trash.pls");
+ testFileName = QFINDTESTDATA("testdata/empty.pls");
playlist.load(QUrl::fromLocalFile(testFileName));
- QTRY_VERIFY(loadSpy.isEmpty());
- QVERIFY(!loadFailedSpy.isEmpty());
- QVERIFY(playlist.error() == QMediaPlaylist::FormatError);
+ QTRY_VERIFY(!loadSpy.isEmpty());
+ QVERIFY(loadFailedSpy.isEmpty());
+ QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
+ QCOMPARE(playlist.mediaCount(), 0);
// Try to load regular playlist
loadSpy.clear();
@@ -505,13 +506,18 @@ void tst_QMediaPlaylist::loadPLSFile()
QCOMPARE(playlist.media(6).canonicalUrl(), QUrl::fromLocalFile(testFileName));
// Try to load a totem-pl generated playlist
+ // (Format doesn't respect the spec)
loadSpy.clear();
loadFailedSpy.clear();
+ playlist.clear();
testFileName = QFINDTESTDATA("testdata/totem-pl-example.pls");
playlist.load(QUrl::fromLocalFile(testFileName));
- QTRY_VERIFY(loadSpy.isEmpty());
- QVERIFY(!loadFailedSpy.isEmpty());
- QVERIFY(playlist.error() == QMediaPlaylist::FormatError);
+ QTRY_VERIFY(!loadSpy.isEmpty());
+ QVERIFY(loadFailedSpy.isEmpty());
+ QCOMPARE(playlist.error(), QMediaPlaylist::NoError);
+ QCOMPARE(playlist.mediaCount(), 1);
+ QCOMPARE(playlist.media(0).canonicalUrl(), QUrl(QLatin1String("http://test.host/path")));
+
// check ability to load from QNetworkRequest
loadSpy.clear();