ASF files aren't really XML - try to correct the mismatching case

This commit is contained in:
David Sansome 2010-06-15 17:00:48 +00:00
parent f7d4c3ca8b
commit 8c7539f02e
5 changed files with 76 additions and 3 deletions

View File

@ -16,12 +16,14 @@
#include "asxparser.h"
#include <QBuffer>
#include <QDomDocument>
#include <QFile>
#include <QIODevice>
#include <QRegExp>
#include <QUrl>
#include <QXmlStreamReader>
#include <QtDebug>
ASXParser::ASXParser(QObject* parent)
: XMLParser(parent)
@ -29,9 +31,27 @@ ASXParser::ASXParser(QObject* parent)
}
SongList ASXParser::Load(QIODevice *device, const QDir&) const {
// We have to load everything first so we can munge the "XML".
QByteArray data = device->readAll();
// (thanks Amarok...)
// ASX looks a lot like xml, but doesn't require tags to be case sensitive,
// meaning we have to accept things like: <Abstract>...</abstract>
// We use a dirty way to achieve this: we make all tags lower case
QRegExp ex("(<[/]?[^>]*[A-Z]+[^>]*>)");
ex.setCaseSensitivity(Qt::CaseInsensitive);
int index = 0;
while ((index = ex.indexIn(data, index)) != -1) {
data.replace(ex.cap(1).toLocal8Bit(), ex.cap(1).toLower().toLocal8Bit());
index += ex.matchedLength();
}
QBuffer buffer(&data);
buffer.open(QIODevice::ReadOnly);
SongList ret;
QXmlStreamReader reader(device);
QXmlStreamReader reader(&buffer);
if (!ParseUntilElement(&reader, "asx")) {
return ret;
}
@ -51,6 +71,7 @@ Song ASXParser::ParseTrack(QXmlStreamReader* reader) const {
QString title, artist, album;
while (!reader->atEnd()) {
QXmlStreamReader::TokenType type = reader->readNext();
switch (type) {
case QXmlStreamReader::StartElement: {
QStringRef name = reader->name();
@ -79,6 +100,7 @@ Song ASXParser::ParseTrack(QXmlStreamReader* reader) const {
song.Init(title, artist, album, -1);
return song;
}
break;
}
default:
break;

View File

@ -34,8 +34,6 @@ bool XMLParser::ParseUntilElement(QXmlStreamReader* reader, const QString& name)
case QXmlStreamReader::StartElement:
if (reader->name() == name) {
return true;
} else {
IgnoreElement(reader);
}
break;
default:

View File

@ -88,3 +88,16 @@ TEST_F(ASXParserTest, SavesSong) {
EXPECT_THAT(data.constData(), HasSubstr("<title>foo</title>"));
EXPECT_THAT(data.constData(), HasSubstr("<author>bar</author>"));
}
TEST_F(ASXParserTest, ParsesSomaFM) {
QFile somafm(":/testdata/secretagent.asx");
somafm.open(QIODevice::ReadOnly);
ASXParser parser;
SongList songs = parser.Load(&somafm);
ASSERT_EQ(4, songs.count());
EXPECT_EQ("SomaFM: Secret Agent", songs[0].title());
EXPECT_EQ("Keep us on the air! Click Support SomaFM above!", songs[0].artist());
EXPECT_EQ("http://streamer-ntc-aa03.somafm.com:80/stream/1021", songs[0].filename());
}

View File

@ -0,0 +1,39 @@
<ASX version="3.0">
<repeat>
<entry>
<ref href="http://streamer-ntc-aa03.somafm.com:80/stream/1021" />
<PARAM name="HTMLView" value="http://somafm.com/wma128/?secretagent"/>
<Abstract>Loading: Secret Agent from SomaFM.com</abstract>
<Title>SomaFM: Secret Agent</Title>
<Author>Keep us on the air! Click Support SomaFM above!</Author>
</entry>
<entry>
<ref href="http://streamer-ntc-aa04.somafm.com:80/stream/1021" />
<PARAM name="HTMLView" value="http://somafm.com/wma128/?secretagent"/>
<Abstract>Loading: Secret Agent from SomaFM.com</abstract>
<Title>SomaFM: Secret Agent</Title>
<Author>Keep us on the air! Click Support SomaFM above!</Author>
</entry>
<entry>
<ref href="http://streamer-mtc-aa03.somafm.com:80/stream/1021" />
<PARAM name="HTMLView" value="http://somafm.com/wma128/?secretagent"/>
<Abstract>Loading: Secret Agent from SomaFM.com</abstract>
<Title>SomaFM: Secret Agent</Title>
<Author>Keep us on the air! Click Support SomaFM above!</Author>
</entry>
<entry>
<ref href="http://ice.somafm.com/secretagent" />
<PARAM name="HTMLView" value="http://somafm.com/wma128/?secretagent"/>
<Abstract>Loading firewall friendly stream: Secret Agent from SomaFM.com</abstract>
<Title>SomaFM: Secret Agent</Title>
<Author>Keep us on the air! Click Support SomaFM above!</Author>
</entry>
</repeat>
</ASX>

View File

@ -12,5 +12,6 @@
<file>test.m3u</file>
<file>test.xspf</file>
<file>test.asx</file>
<file>secretagent.asx</file>
</qresource>
</RCC>