diff options
Diffstat (limited to 'src/multimedia')
-rw-r--r-- | src/multimedia/playback/playback.pri | 4 | ||||
-rw-r--r-- | src/multimedia/playback/qmedianetworkplaylistprovider.cpp | 10 | ||||
-rw-r--r-- | src/multimedia/playback/qplaylistfileparser.cpp (renamed from src/multimedia/playback/playlistfileparser.cpp) | 438 | ||||
-rw-r--r-- | src/multimedia/playback/qplaylistfileparser_p.h (renamed from src/multimedia/playback/playlistfileparser_p.h) | 36 |
4 files changed, 312 insertions, 176 deletions
diff --git a/src/multimedia/playback/playback.pri b/src/multimedia/playback/playback.pri index 3bbb8ce15..cc55fc1b0 100644 --- a/src/multimedia/playback/playback.pri +++ b/src/multimedia/playback/playback.pri @@ -12,7 +12,7 @@ PRIVATE_HEADERS += \ playback/qmediaplaylistioplugin_p.h \ playback/qmediaplaylistnavigator_p.h \ playback/qmedianetworkplaylistprovider_p.h \ - playback/playlistfileparser_p.h + playback/qplaylistfileparser_p.h SOURCES += \ playback/qmedianetworkplaylistprovider.cpp \ @@ -23,4 +23,4 @@ SOURCES += \ playback/qmediaplaylistnavigator.cpp \ playback/qmediaplaylistprovider.cpp \ playback/qmediaresource.cpp \ - playback/playlistfileparser.cpp + playback/qplaylistfileparser.cpp diff --git a/src/multimedia/playback/qmedianetworkplaylistprovider.cpp b/src/multimedia/playback/qmedianetworkplaylistprovider.cpp index 7de90d9a1..a4ad97251 100644 --- a/src/multimedia/playback/qmedianetworkplaylistprovider.cpp +++ b/src/multimedia/playback/qmedianetworkplaylistprovider.cpp @@ -41,7 +41,7 @@ #include "qmediaplaylistprovider_p.h" #include "qmediacontent.h" #include "qmediaobject_p.h" -#include "playlistfileparser_p.h" +#include "qplaylistfileparser_p.h" QT_BEGIN_NAMESPACE @@ -62,8 +62,8 @@ public: bool QMediaNetworkPlaylistProviderPrivate::load(const QNetworkRequest &request) { - parser.stop(); - parser.start(request, false); + parser.abort(); + parser.start(request); return true; } @@ -83,12 +83,14 @@ void QMediaNetworkPlaylistProviderPrivate::_q_handleParserError(QPlaylistFilePar case QPlaylistFileParser::FormatNotSupportedError: playlistError = QMediaPlaylist::FormatNotSupportedError; break; + case QPlaylistFileParser::ResourceError: + // fall through case QPlaylistFileParser::NetworkError: playlistError = QMediaPlaylist::NetworkError; break; } - parser.stop(); + parser.abort(); emit q->loadFailed(playlistError, errorMessage); } diff --git a/src/multimedia/playback/playlistfileparser.cpp b/src/multimedia/playback/qplaylistfileparser.cpp index 237e417a6..424e54d34 100644 --- a/src/multimedia/playback/playlistfileparser.cpp +++ b/src/multimedia/playback/qplaylistfileparser.cpp @@ -37,31 +37,48 @@ ** ****************************************************************************/ -#include "playlistfileparser_p.h" +#include "qplaylistfileparser_p.h" #include <qfileinfo.h> #include <QtCore/QDebug> +#include <QtCore/qiodevice.h> #include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkRequest> +#include "qmediaplayer.h" #include "qmediaobject_p.h" -#include <private/qobject_p.h> #include "qmediametadata.h" +#include "qmediacontent.h" +#include "qmediaresource.h" QT_BEGIN_NAMESPACE namespace { -class ParserBase : public QObject + +class ParserBase { - Q_OBJECT public: - ParserBase(QObject *parent) - : QObject(parent) + explicit ParserBase(QPlaylistFileParser *parent) + : m_parent(parent) + , m_aborted(false) + { + Q_ASSERT(m_parent); + } + + bool parseLine(int lineIndex, const QString& line, const QUrl& root) { + if (m_aborted) + return false; + + const bool ok = parseLineImpl(lineIndex, line, root); + return ok && !m_aborted; } - virtual void parseLine(int lineIndex, const QString& line, const QUrl& root) = 0; + virtual void abort() { m_aborted = true; } + virtual ~ParserBase() { } protected: - QUrl expandToFullPath(const QUrl &root, const QString &line) + virtual bool parseLineImpl(int lineIndex, const QString& line, const QUrl& root) = 0; + + static QUrl expandToFullPath(const QUrl &root, const QString &line) { // On Linux, backslashes are not converted to forward slashes :/ if (line.startsWith(QLatin1String("//")) || line.startsWith(QLatin1String("\\\\"))) { @@ -84,22 +101,22 @@ protected: return url; } -Q_SIGNALS: - void newItem(const QVariant& content); - void finished(); - void error(QPlaylistFileParser::ParserError err, const QString& errorMsg); + void newItemFound(const QVariant& content) { Q_EMIT m_parent->newItem(content); } + +private: + QPlaylistFileParser *m_parent; + bool m_aborted; }; class M3UParser : public ParserBase { public: - M3UParser(QObject *parent) - : ParserBase(parent) + explicit M3UParser(QPlaylistFileParser *q) + : ParserBase(q) , m_extendedFormat(false) { } - /* * Extended M3U directives @@ -117,7 +134,7 @@ public: C:\Documents and Settings\I\My Music\Greatest Hits\Example.ogg */ - void parseLine(int lineIndex, const QString& line, const QUrl& root) + bool parseLineImpl(int lineIndex, const QString& line, const QUrl& root) { if (line[0] == '#' ) { if (m_extendedFormat) { @@ -149,9 +166,11 @@ public: } } else { m_extraInfo[QLatin1String("url")] = expandToFullPath(root, line); - emit newItem(QVariant(m_extraInfo)); + newItemFound(QVariant(m_extraInfo)); m_extraInfo.clear(); } + + return true; } int getSplitIndex(const QString& line, int startPos) @@ -172,16 +191,15 @@ public: } private: - bool m_extendedFormat; QVariantMap m_extraInfo; + bool m_extendedFormat; }; class PLSParser : public ParserBase { - Q_OBJECT public: - PLSParser(QObject *parent) - : ParserBase(parent) + explicit PLSParser(QPlaylistFileParser *q) + : ParserBase(q) { } @@ -223,17 +241,19 @@ NumberOfEntries=2 Version=2 */ - void parseLine(int, const QString &line, const QUrl &root) + bool parseLineImpl(int, const QString &line, const QUrl &root) { // We ignore everything but 'File' entries, since that's the only thing we care about. if (!line.startsWith(QLatin1String("File"))) - return; + return true; QString value = getValue(line); if (value.isEmpty()) - return; + return true; - emit newItem(expandToFullPath(root, value)); + newItemFound(expandToFullPath(root, value)); + + return true; } QString getValue(const QString& line) { @@ -247,75 +267,84 @@ Version=2 ///////////////////////////////////////////////////////////////////////////////////////////////// -class QPlaylistFileParserPrivate : public QObjectPrivate +class QPlaylistFileParserPrivate { Q_DECLARE_PUBLIC(QPlaylistFileParser) public: - QPlaylistFileParserPrivate() - : m_source(0) + QPlaylistFileParserPrivate(QPlaylistFileParser *q) + : q_ptr(q) + , m_stream(0) + , m_type(QPlaylistFileParser::UNKNOWN) , m_scanIndex(0) - , m_utf8(false) , m_lineIndex(-1) - , m_type(QPlaylistFileParser::UNKNOWN) - , m_currentParser(0) + , m_utf8(false) + , m_aborted(false) { } - void _q_handleData(); - void _q_handleError(); - void _q_handleParserError(QPlaylistFileParser::ParserError err, const QString& errorMsg); - void _q_handleParserFinished(); + void handleData(); + void handleParserFinished(); + void abort(); + void reset(); - QNetworkReply *m_source; + QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> m_source; + QScopedPointer<ParserBase> m_currentParser; QByteArray m_buffer; - int m_scanIndex; QUrl m_root; - bool m_utf8; - int m_lineIndex; - QPlaylistFileParser::FileType m_type; - ParserBase *m_currentParser; QNetworkAccessManager m_mgr; + QString m_mimeType; + QPlaylistFileParser *q_ptr; + QIODevice *m_stream; + QPlaylistFileParser::FileType m_type; + struct ParserJob + { + QIODevice *m_stream; + QMediaResource m_resource; + bool isValid() const { return m_stream || !m_resource.isNull(); } + void reset() { m_stream = 0; m_resource = QMediaResource(); } + } m_pendingJob; + int m_scanIndex; + int m_lineIndex; + bool m_utf8; + bool m_aborted; private: - void processLine(int startIndex, int length); + bool processLine(int startIndex, int length); }; #define LINE_LIMIT 4096 #define READ_LIMIT 64 -void QPlaylistFileParserPrivate::processLine(int startIndex, int length) +bool QPlaylistFileParserPrivate::processLine(int startIndex, int length) { Q_Q(QPlaylistFileParser); m_lineIndex++; if (!m_currentParser) { - Q_ASSERT(!m_currentParser); - - QString mimeType = m_source->header(QNetworkRequest::ContentTypeHeader).toString(); - m_type = QPlaylistFileParser::findPlaylistType(m_root.toString(), mimeType, m_buffer.constData(), m_buffer.size()); + const QString urlString = m_root.toString(); + const QString &suffix = !urlString.isEmpty() ? QFileInfo(urlString).suffix() : urlString; + const QString &mimeType = m_source->header(QNetworkRequest::ContentTypeHeader).toString(); + m_type = QPlaylistFileParser::findPlaylistType(suffix, !mimeType.isEmpty() ? mimeType : m_mimeType, m_buffer.constData(), quint32(m_buffer.size())); switch (m_type) { case QPlaylistFileParser::UNKNOWN: emit q->error(QPlaylistFileParser::FormatError, QPlaylistFileParser::tr("%1 playlist type is unknown").arg(m_root.toString())); - q->stop(); - return; + q->abort(); + return false; case QPlaylistFileParser::M3U: - m_currentParser = new M3UParser(q); + m_currentParser.reset(new M3UParser(q)); break; case QPlaylistFileParser::M3U8: - m_currentParser = new M3UParser(q); + m_currentParser.reset(new M3UParser(q)); m_utf8 = true; break; case QPlaylistFileParser::PLS: - m_currentParser = new PLSParser(q); + m_currentParser.reset(new PLSParser(q)); break; } - Q_ASSERT(m_currentParser); - QObject::connect(m_currentParser, SIGNAL(newItem(QVariant)), q, SIGNAL(newItem(QVariant))); - QObject::connect(m_currentParser, SIGNAL(finished()), q, SLOT(_q_handleParserFinished())); - QObject::connect(m_currentParser, SIGNAL(error(QPlaylistFileParser::ParserError,QString)), - q, SLOT(_q_handleParserError(QPlaylistFileParser::ParserError,QString))); + + Q_ASSERT(!m_currentParser.isNull()); } QString line; @@ -326,26 +355,28 @@ void QPlaylistFileParserPrivate::processLine(int startIndex, int length) line = QString::fromLatin1(m_buffer.constData() + startIndex, length).trimmed(); } if (line.isEmpty()) - return; + return true; Q_ASSERT(m_currentParser); - m_currentParser->parseLine(m_lineIndex, line, m_root); + return m_currentParser->parseLine(m_lineIndex, line, m_root); } -void QPlaylistFileParserPrivate::_q_handleData() +void QPlaylistFileParserPrivate::handleData() { Q_Q(QPlaylistFileParser); - while (m_source->bytesAvailable()) { + while (m_source->bytesAvailable() && !m_aborted) { int expectedBytes = qMin(READ_LIMIT, int(qMin(m_source->bytesAvailable(), qint64(LINE_LIMIT - m_buffer.size())))); m_buffer.push_back(m_source->read(expectedBytes)); int processedBytes = 0; - while (m_scanIndex < m_buffer.length()) { + while (m_scanIndex < m_buffer.length() && !m_aborted) { char s = m_buffer[m_scanIndex]; if (s == '\r' || s == '\n') { int l = m_scanIndex - processedBytes; - if (l > 0) - processLine(processedBytes, l); + if (l > 0) { + if (!processLine(processedBytes, l)) + break; + } processedBytes = m_scanIndex + 1; if (!m_source) { //some error happened, so exit parsing @@ -355,11 +386,13 @@ void QPlaylistFileParserPrivate::_q_handleData() m_scanIndex++; } + if (m_aborted) + break; + if (m_buffer.length() - processedBytes >= LINE_LIMIT) { - qWarning() << "error parsing playlist["<< m_root << "] with line content >= 4096 bytes."; emit q->error(QPlaylistFileParser::FormatError, QPlaylistFileParser::tr("invalid line in playlist file")); - q->stop(); - return; + q->abort(); + break; } if (m_source->isFinished() && !m_source->bytesAvailable()) { @@ -382,143 +415,226 @@ void QPlaylistFileParserPrivate::_q_handleData() m_scanIndex = 0; } - if (m_source->isFinished()) { - _q_handleParserFinished(); - } + handleParserFinished(); } -void QPlaylistFileParserPrivate::_q_handleError() +QPlaylistFileParser::QPlaylistFileParser(QObject *parent) + : QObject(parent) + , d_ptr(new QPlaylistFileParserPrivate(this)) { - Q_Q(QPlaylistFileParser); - emit q->error(QPlaylistFileParser::NetworkError, m_source->errorString()); - q->stop(); + } -void QPlaylistFileParserPrivate::_q_handleParserError(QPlaylistFileParser::ParserError err, const QString& errorMsg) +QPlaylistFileParser::~QPlaylistFileParser() { - Q_Q(QPlaylistFileParser); - emit q->error(err, errorMsg); + } -void QPlaylistFileParserPrivate::_q_handleParserFinished() +QPlaylistFileParser::FileType QPlaylistFileParser::findByMimeType(const QString &mime) { - Q_Q(QPlaylistFileParser); - bool isParserValid = (m_currentParser != 0); - if (!isParserValid) - emit q->error(QPlaylistFileParser::FormatNotSupportedError, QPlaylistFileParser::tr("Empty file provided")); + if (mime == QLatin1String("text/uri-list") || mime == QLatin1String("audio/x-mpegurl") || mime == QLatin1String("audio/mpegurl")) + return QPlaylistFileParser::M3U; - q->stop(); + if (mime == QLatin1String("application/x-mpegURL") || mime == QLatin1String("application/vnd.apple.mpegurl")) + return QPlaylistFileParser::M3U8; - if (isParserValid) - emit q->finished(); -} + if (mime == QLatin1String("audio/x-scpls")) + return QPlaylistFileParser::PLS; + return QPlaylistFileParser::UNKNOWN; +} -QPlaylistFileParser::QPlaylistFileParser(QObject *parent) - : QObject(*new QPlaylistFileParserPrivate, parent) +QPlaylistFileParser::FileType QPlaylistFileParser::findBySuffixType(const QString &suffix) { + const QString &s = suffix.toLower(); + + if (s == QLatin1String("m3u")) + return QPlaylistFileParser::M3U; + + if (s == QLatin1String("m3u8")) + return QPlaylistFileParser::M3U8; + if (s == QLatin1String("pls")) + return QPlaylistFileParser::PLS; + + return QPlaylistFileParser::UNKNOWN; } -QPlaylistFileParser::FileType QPlaylistFileParser::findPlaylistType(const QString& uri, const QString& mime, const void *data, quint32 size) +QPlaylistFileParser::FileType QPlaylistFileParser::findByDataHeader(const char *data, quint32 size) { - if (!data || !size) - return UNKNOWN; - - FileType uriType = UNKNOWN; - QString suffix = QFileInfo(uri).suffix().toLower(); - if (suffix == QLatin1String("m3u")) - uriType = M3U; - else if (suffix == QLatin1String("m3u8")) - uriType = M3U8; - else if (suffix == QLatin1String("pls")) - uriType = PLS; - - FileType mimeType = UNKNOWN; - if (mime == QLatin1String("text/uri-list") || mime == QLatin1String("audio/x-mpegurl") || mime == QLatin1String("audio/mpegurl")) - mimeType = QPlaylistFileParser::M3U; - else if (mime == QLatin1String("application/x-mpegURL") || mime == QLatin1String("application/vnd.apple.mpegurl")) - mimeType = QPlaylistFileParser::M3U8; - else if (mime == QLatin1String("audio/x-scpls")) - mimeType = QPlaylistFileParser::PLS; - - FileType bufferType = UNKNOWN; - if (size >= 7 && strncmp((const char*)data, "#EXTM3U", 7) == 0) - bufferType = M3U; - else if (size >= 10 && strncmp((const char*)data, "[playlist]", 10) == 0) - bufferType = PLS; - else { - // Make sure every line is a text string - quint32 n; - for (n = 0; n < size; n++) - if (!QChar(QLatin1Char(((const char*)data)[n])).isPrint()) - break; - if (n == size) - bufferType = M3U; - } + if (!data || size == 0) + return QPlaylistFileParser::UNKNOWN; - if (bufferType == M3U && (uriType == M3U8 || mimeType == M3U8)) - bufferType = M3U8; + if (size >= 7 && strncmp(data, "#EXTM3U", 7) == 0) + return QPlaylistFileParser::M3U; + + if (size >= 10 && strncmp(data, "[playlist]", 10) == 0) + return QPlaylistFileParser::PLS; + + return QPlaylistFileParser::UNKNOWN; +} - if (bufferType != UNKNOWN) - return bufferType; +QPlaylistFileParser::FileType QPlaylistFileParser::findPlaylistType(const QString& suffix, + const QString& mime, + const char *data, + quint32 size) +{ - if (uriType != UNKNOWN) - return uriType; + FileType dataHeaderType = findByDataHeader(data, size); + if (dataHeaderType != UNKNOWN) + return dataHeaderType; + FileType mimeType = findByMimeType(mime); if (mimeType != UNKNOWN) return mimeType; + FileType suffixType = findBySuffixType(suffix); + if (suffixType != UNKNOWN) + return suffixType; + return UNKNOWN; } -void QPlaylistFileParser::start(const QNetworkRequest& request, bool utf8) +/* + * Delegating + */ +void QPlaylistFileParser::start(const QMediaContent &media, QIODevice *stream) +{ + const QMediaResource &mediaResource = media.canonicalResource(); + const QString &mimeType = mediaResource.mimeType(); + + if (stream) { + start(stream, mediaResource.mimeType()); + } else { + const QNetworkRequest &request = mediaResource.request(); + const QUrl &url = mediaResource.url(); + + if (request.url().isValid()) + start(request, mimeType); + else + start(QNetworkRequest(url), mimeType); + } +} + +void QPlaylistFileParser::start(QIODevice *stream, const QString &mimeType) { Q_D(QPlaylistFileParser); - stop(); + const bool validStream = stream ? (stream->isOpen() && stream->isReadable()) : false; + + if (!validStream) { + Q_EMIT error(ResourceError, tr("Invalid stream")); + return; + } + + if (!d->m_currentParser.isNull()) { + abort(); + d->m_pendingJob = { stream, QMediaResource(QUrl(), mimeType) }; + return; + } + + d->reset(); + d->m_mimeType = mimeType; + d->m_stream = stream; + connect(d->m_stream, SIGNAL(readyRead()), this, SLOT(_q_handleData())); + d->handleData(); +} - d->m_type = UNKNOWN; - d->m_utf8 = utf8; - d->m_root = request.url(); +void QPlaylistFileParser::start(const QNetworkRequest& request, const QString &mimeType) +{ + Q_D(QPlaylistFileParser); + const QUrl &url = request.url(); - if (d->m_root.isLocalFile() && !QFile::exists(d->m_root.toLocalFile())) { - emit error(NetworkError, QString(tr("%1 does not exist")).arg(d->m_root.toString())); + if (url.isLocalFile() && !QFile::exists(url.toLocalFile())) { + emit error(ResourceError, QString(tr("%1 does not exist")).arg(url.toString())); return; } - d->m_source = d->m_mgr.get(request); + if (!d->m_currentParser.isNull()) { + abort(); + d->m_pendingJob = { Q_NULLPTR, QMediaResource(request, mimeType) }; + return; + } - connect(d->m_source, SIGNAL(readyRead()), this, SLOT(_q_handleData())); - connect(d->m_source, SIGNAL(finished()), this, SLOT(_q_handleData())); - connect(d->m_source, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(_q_handleError())); + d->reset(); + d->m_root = url; + d->m_mimeType = mimeType; + d->m_source.reset(d->m_mgr.get(request)); + connect(d->m_source.data(), SIGNAL(readyRead()), this, SLOT(handleData())); + connect(d->m_source.data(), SIGNAL(finished()), this, SLOT(handleData())); + connect(d->m_source.data(), SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(handleError())); - d->_q_handleData(); + d->handleData(); } -void QPlaylistFileParser::stop() +void QPlaylistFileParser::abort() { Q_D(QPlaylistFileParser); - if (d->m_currentParser) { - disconnect(d->m_currentParser, SIGNAL(newItem(QVariant)), this, SIGNAL(newItem(QVariant))); - disconnect(d->m_currentParser, SIGNAL(finished()), this, SLOT(_q_handleParserFinished())); - disconnect(d->m_currentParser, SIGNAL(error(QPlaylistFileParser::ParserError,QString)), - this, SLOT(_q_handleParserError(QPlaylistFileParser::ParserError,QString))); - d->m_currentParser->deleteLater(); - d->m_currentParser = 0; - } + d->abort(); + + if (d->m_source) + d->m_source->disconnect(); - d->m_buffer.clear(); - d->m_scanIndex = 0; - d->m_lineIndex = -1; - if (d->m_source) { - disconnect(d->m_source, SIGNAL(readyRead()), this, SLOT(_q_handleData())); - disconnect(d->m_source, SIGNAL(finished()), this, SLOT(_q_handleData())); - disconnect(d->m_source, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(_q_handleError())); - d->m_source->deleteLater(); - d->m_source = 0; + if (d->m_stream) + disconnect(d->m_stream, SIGNAL(readyRead()), this, SLOT(handleData())); +} + +void QPlaylistFileParser::handleData() +{ + Q_D(QPlaylistFileParser); + d->handleData(); +} + +void QPlaylistFileParserPrivate::handleParserFinished() +{ + Q_Q(QPlaylistFileParser); + const bool isParserValid = !m_currentParser.isNull(); + if (!isParserValid && !m_aborted) + emit q->error(QPlaylistFileParser::FormatNotSupportedError, QPlaylistFileParser::tr("Empty file provided")); + + if (isParserValid && !m_aborted) { + m_currentParser.reset(); + emit q->finished(); } + + if (!m_aborted) + q->abort(); + + if (!m_source.isNull()) + m_source.reset(); + + if (m_pendingJob.isValid()) + q->start(m_pendingJob.m_resource, m_pendingJob.m_stream); +} + +void QPlaylistFileParserPrivate::abort() +{ + m_aborted = true; + if (!m_currentParser.isNull()) + m_currentParser->abort(); +} + +void QPlaylistFileParserPrivate::reset() +{ + Q_ASSERT(m_currentParser.isNull()); + Q_ASSERT(m_source.isNull()); + m_buffer.clear(); + m_root.clear(); + m_mimeType.clear(); + m_stream = 0; + m_type = QPlaylistFileParser::UNKNOWN; + m_scanIndex = 0; + m_lineIndex = -1; + m_utf8 = false; + m_aborted = false; + m_pendingJob.reset(); +} + +void QPlaylistFileParser::handleError() +{ + Q_D(QPlaylistFileParser); + const QString &errorString = d->m_source->errorString(); + Q_EMIT error(QPlaylistFileParser::NetworkError, errorString); + abort(); } -#include "moc_playlistfileparser_p.cpp" -#include "playlistfileparser.moc" QT_END_NAMESPACE diff --git a/src/multimedia/playback/playlistfileparser_p.h b/src/multimedia/playback/qplaylistfileparser_p.h index bdf95fe7a..927dbb739 100644 --- a/src/multimedia/playback/playlistfileparser_p.h +++ b/src/multimedia/playback/qplaylistfileparser_p.h @@ -52,10 +52,14 @@ // #include "qtmultimediaglobal.h" -#include <QtNetwork/QNetworkRequest> +#include <QtCore/qobject.h> QT_BEGIN_NAMESPACE +class QIODevice; +class QMediaContent; +class QNetworkRequest; + class QPlaylistFileParserPrivate; class Q_MULTIMEDIA_EXPORT QPlaylistFileParser : public QObject @@ -63,6 +67,7 @@ class Q_MULTIMEDIA_EXPORT QPlaylistFileParser : public QObject Q_OBJECT public: QPlaylistFileParser(QObject *parent = 0); + ~QPlaylistFileParser(); enum FileType { @@ -77,26 +82,39 @@ public: NoError, FormatError, FormatNotSupportedError, + ResourceError, NetworkError }; - static FileType findPlaylistType(const QString& uri, const QString& mime, const void *data, quint32 size); - - void start(const QNetworkRequest &request, bool utf8 = false); - void stop(); + void start(const QMediaContent &media, QIODevice *stream = 0); + void start(const QNetworkRequest &request, const QString &mimeType = QString()); + void abort(); Q_SIGNALS: void newItem(const QVariant& content); void finished(); void error(QPlaylistFileParser::ParserError err, const QString& errorMsg); +private Q_SLOTS: + void handleData(); + void handleError(); + private: + void start(QIODevice *stream, const QString &mimeType = QString()); + + static FileType findByMimeType(const QString &mime); + static FileType findBySuffixType(const QString &suffix); + static FileType findByDataHeader(const char *data, quint32 size); + static FileType findPlaylistType(QIODevice *device, + const QString& mime); + static FileType findPlaylistType(const QString &suffix, + const QString& mime, + const char *data = 0, + quint32 size = 0); + Q_DISABLE_COPY(QPlaylistFileParser) Q_DECLARE_PRIVATE(QPlaylistFileParser) - Q_PRIVATE_SLOT(d_func(), void _q_handleData()) - Q_PRIVATE_SLOT(d_func(), void _q_handleError()) - Q_PRIVATE_SLOT(d_func(), void _q_handleParserError(QPlaylistFileParser::ParserError err, const QString& errorMsg)) - Q_PRIVATE_SLOT(d_func(), void _q_handleParserFinished()) + QScopedPointer<QPlaylistFileParserPrivate> d_ptr; }; QT_END_NAMESPACE |