Mercurial > hg > svcore
diff data/fileio/FileSource.cpp @ 742:c10cb8782576 coreaudio_tests
Merge from branch "default"
author | Chris Cannam |
---|---|
date | Sun, 01 Jul 2012 11:53:00 +0100 |
parents | 579b2da21e7a |
children | 3b2409646cc0 |
line wrap: on
line diff
--- a/data/fileio/FileSource.cpp Mon Nov 29 12:45:39 2010 +0000 +++ b/data/fileio/FileSource.cpp Sun Jul 01 11:53:00 2012 +0100 @@ -77,19 +77,28 @@ m_preferredContentType(preferredContentType), m_ok(false), m_lastStatus(0), + m_resource(fileOrUrl.startsWith(':')), m_remote(isRemote(fileOrUrl)), m_done(false), m_leaveLocalFile(false), m_reporter(reporter), m_refCounted(false) { + if (m_resource) { // qrc file + m_url = QUrl("qrc" + fileOrUrl); + } + + if (m_url.toString() == "") { + m_url = QUrl(fileOrUrl, QUrl::TolerantMode); + } + #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::FileSource(" << fileOrUrl.toStdString() << ")" << std::endl; + std::cerr << "FileSource::FileSource(" << fileOrUrl << "): url <" << m_url.toString() << ">" << std::endl; incCount(m_url.toString()); #endif if (!canHandleScheme(m_url)) { - std::cerr << "FileSource::FileSource: ERROR: Unsupported scheme in URL \"" << m_url.toString().toStdString() << "\"" << std::endl; + SVDEBUG << "FileSource::FileSource: ERROR: Unsupported scheme in URL \"" << m_url.toString() << "\"" << endl; m_errorString = tr("Unsupported scheme in URL"); return; } @@ -99,7 +108,7 @@ if (!isRemote() && !isAvailable()) { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::FileSource: Failed to open local file with URL \"" << m_url.toString().toStdString() << "; trying again assuming filename was encoded" << std::endl; + std::cerr << "FileSource::FileSource: Failed to open local file with URL \"" << m_url.toString() << "\"; trying again assuming filename was encoded" << std::endl; #endif m_url = QUrl::fromEncoded(fileOrUrl.toAscii()); init(); @@ -144,7 +153,7 @@ } #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::FileSource(string) exiting" << std::endl; + SVDEBUG << "FileSource::FileSource(string) exiting" << endl; #endif } @@ -155,6 +164,7 @@ m_localFile(0), m_ok(false), m_lastStatus(0), + m_resource(false), m_remote(isRemote(url.toString())), m_done(false), m_leaveLocalFile(false), @@ -162,12 +172,12 @@ m_refCounted(false) { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::FileSource(" << url.toString().toStdString() << ") [as url]" << std::endl; + SVDEBUG << "FileSource::FileSource(" << url.toString() << ") [as url]" << endl; incCount(m_url.toString()); #endif if (!canHandleScheme(m_url)) { - std::cerr << "FileSource::FileSource: ERROR: Unsupported scheme in URL \"" << m_url.toString().toStdString() << "\"" << std::endl; + SVDEBUG << "FileSource::FileSource: ERROR: Unsupported scheme in URL \"" << m_url.toString() << "\"" << endl; m_errorString = tr("Unsupported scheme in URL"); return; } @@ -175,7 +185,7 @@ init(); #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::FileSource(url) exiting" << std::endl; + SVDEBUG << "FileSource::FileSource(url) exiting" << endl; #endif } @@ -187,6 +197,7 @@ m_localFile(0), m_ok(rf.m_ok), m_lastStatus(rf.m_lastStatus), + m_resource(rf.m_resource), m_remote(rf.m_remote), m_done(false), m_leaveLocalFile(false), @@ -194,12 +205,12 @@ m_refCounted(false) { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::FileSource(" << m_url.toString().toStdString() << ") [copy ctor]" << std::endl; + SVDEBUG << "FileSource::FileSource(" << m_url.toString() << ") [copy ctor]" << endl; incCount(m_url.toString()); #endif if (!canHandleScheme(m_url)) { - std::cerr << "FileSource::FileSource: ERROR: Unsupported scheme in URL \"" << m_url.toString().toStdString() << "\"" << std::endl; + SVDEBUG << "FileSource::FileSource: ERROR: Unsupported scheme in URL \"" << m_url.toString() << "\"" << endl; m_errorString = tr("Unsupported scheme in URL"); return; } @@ -209,8 +220,8 @@ } else { QMutexLocker locker(&m_mapMutex); #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::FileSource(copy ctor): ref count is " - << m_refCountMap[m_url] << std::endl; + SVDEBUG << "FileSource::FileSource(copy ctor): ref count is " + << m_refCountMap[m_url] << endl; #endif if (m_refCountMap[m_url] > 0) { m_refCountMap[m_url]++; @@ -228,18 +239,18 @@ m_done = true; #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::FileSource(" << m_url.toString().toStdString() << ") [copy ctor]: note: local filename is \"" << m_localFilename.toStdString() << "\"" << std::endl; + SVDEBUG << "FileSource::FileSource(" << m_url.toString() << ") [copy ctor]: note: local filename is \"" << m_localFilename << "\"" << endl; #endif #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::FileSource(copy ctor) exiting" << std::endl; + SVDEBUG << "FileSource::FileSource(copy ctor) exiting" << endl; #endif } FileSource::~FileSource() { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource(" << m_url.toString().toStdString() << ")::~FileSource" << std::endl; + std::cerr << "FileSource(" << m_url.toString() << ")::~FileSource" << std::endl; decCount(m_url.toString()); #endif @@ -251,7 +262,23 @@ void FileSource::init() { - if (!isRemote()) { + if (isResource()) { +#ifdef DEBUG_FILE_SOURCE + std::cerr << "FileSource::init: Is a resource" << std::endl; +#endif + QString resourceFile = m_url.toString(); + resourceFile.replace(QRegExp("^qrc:"), ":"); + + if (!QFileInfo(resourceFile).exists()) { +#ifdef DEBUG_FILE_SOURCE + std::cerr << "FileSource::init: Resource file of this name does not exist, switching to non-resource URL" << std::endl; +#endif + m_url = resourceFile; + m_resource = false; + } + } + + if (!isRemote() && !isResource()) { #ifdef DEBUG_FILE_SOURCE std::cerr << "FileSource::init: Not a remote URL" << std::endl; #endif @@ -266,7 +293,8 @@ #ifdef DEBUG_FILE_SOURCE std::cerr << "FileSource::init: URL translates to local filename \"" - << m_localFilename.toStdString() << "\"" << std::endl; + << m_localFilename << "\" (with literal=" << literal << ")" + << std::endl; #endif m_ok = true; m_lastStatus = 200; @@ -307,26 +335,62 @@ } if (m_localFilename == "") return; + m_localFile = new QFile(m_localFilename); m_localFile->open(QFile::WriteOnly); - QString scheme = m_url.scheme().toLower(); + if (isResource()) { + + // Absent resource file case was dealt with at the top -- this + // is the successful case + + QString resourceFileName = m_url.toString(); + resourceFileName.replace(QRegExp("^qrc:"), ":"); + QFile resourceFile(resourceFileName); + resourceFile.open(QFile::ReadOnly); + QByteArray ba(resourceFile.readAll()); + +#ifdef DEBUG_FILE_SOURCE + std::cerr << "Copying " << ba.size() << " bytes from resource file to cache file" << std::endl; +#endif + + qint64 written = m_localFile->write(ba); + m_localFile->close(); + delete m_localFile; + m_localFile = 0; + + if (written != ba.size()) { +#ifdef DEBUG_FILE_SOURCE + std::cerr << "Copy failed (wrote " << written << " bytes)" << std::endl; +#endif + m_ok = false; + return; + } else { + m_ok = true; + m_lastStatus = 200; + m_done = true; + } + + } else { + + QString scheme = m_url.scheme().toLower(); #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::init: Don't have local copy of \"" - << m_url.toString().toStdString() << "\", retrieving" << std::endl; + std::cerr << "FileSource::init: Don't have local copy of \"" + << m_url.toString() << "\", retrieving" << std::endl; #endif - if (scheme == "http") { - initHttp(); + if (scheme == "http") { + initHttp(); #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource: initHttp succeeded" << std::endl; + std::cerr << "FileSource: initHttp succeeded" << std::endl; #endif - } else if (scheme == "ftp") { - initFtp(); - } else { - m_remote = false; - m_ok = false; + } else if (scheme == "ftp") { + initFtp(); + } else { + m_remote = false; + m_ok = false; + } } if (m_ok) { @@ -355,7 +419,7 @@ m_refCountMap[m_url]++; m_refCounted = true; - if (m_reporter) { + if (m_reporter && !m_done) { m_reporter->setMessage (tr("Downloading %1...").arg(m_url.toString())); connect(m_reporter, SIGNAL(cancelled()), this, SLOT(cancelled())); @@ -422,8 +486,8 @@ QString path = "/" + QString(m_url.toEncoded()).section('/', 3); #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource: path is \"" - << path.toStdString() << "\"" << std::endl; + SVDEBUG << "FileSource: path is \"" + << path << "\"" << endl; #endif if (m_preferredContentType == "") { @@ -431,7 +495,7 @@ } else { #ifdef DEBUG_FILE_SOURCE std::cerr << "FileSource: indicating preferred content type of \"" - << m_preferredContentType.toStdString() << "\"" << std::endl; + << m_preferredContentType << "\"" << std::endl; #endif QHttpRequestHeader header("GET", path); header.setValue("Host", m_url.host()); @@ -513,7 +577,8 @@ // Note that a "scheme" with length 1 is probably a DOS drive letter QString scheme = url.scheme().toLower(); return (scheme == "http" || scheme == "ftp" || - scheme == "file" || scheme == "" || scheme.length() == 1); + scheme == "file" || scheme == "qrc" || + scheme == "" || scheme.length() == 1); } bool @@ -524,8 +589,8 @@ if (!m_ok) available = false; else available = (m_lastStatus / 100 == 2); #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::isAvailable: " << (available ? "yes" : "no") - << std::endl; + SVDEBUG << "FileSource::isAvailable: " << (available ? "yes" : "no") + << endl; #endif return available; } @@ -543,7 +608,7 @@ FileSource::waitForData() { while (m_ok && !m_done) { -// std::cerr << "FileSource::waitForData: calling QApplication::processEvents" << std::endl; +// SVDEBUG << "FileSource::waitForData: calling QApplication::processEvents" << endl; QCoreApplication::processEvents(); usleep(10000); } @@ -568,6 +633,12 @@ } bool +FileSource::isResource() const +{ + return m_resource; +} + +bool FileSource::isRemote() const { return m_remote; @@ -586,6 +657,12 @@ } QString +FileSource::getBasename() const +{ + return QFileInfo(m_localFilename).fileName(); +} + +QString FileSource::getContentType() const { return m_contentType; @@ -617,14 +694,14 @@ FileSource::httpResponseHeaderReceived(const QHttpResponseHeader &resp) { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::httpResponseHeaderReceived" << std::endl; + SVDEBUG << "FileSource::httpResponseHeaderReceived" << endl; #endif if (resp.statusCode() / 100 == 3) { QString location = resp.value("Location"); #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::responseHeaderReceived: redirect to \"" - << location.toStdString() << "\" received" << std::endl; + SVDEBUG << "FileSource::responseHeaderReceived: redirect to \"" + << location << "\" received" << endl; #endif if (location != "") { QUrl newUrl(location); @@ -651,13 +728,13 @@ m_errorString = QString("%1 %2") .arg(resp.statusCode()).arg(resp.reasonPhrase()); #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::responseHeaderReceived: " - << m_errorString.toStdString() << std::endl; + SVDEBUG << "FileSource::responseHeaderReceived: " + << m_errorString << endl; #endif } else { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::responseHeaderReceived: " - << m_lastStatus << std::endl; + SVDEBUG << "FileSource::responseHeaderReceived: " + << m_lastStatus << endl; #endif if (resp.hasContentType()) m_contentType = resp.contentType(); } @@ -677,8 +754,8 @@ if (!error) { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::ftpCommandFinished: success for command " - << command << std::endl; + SVDEBUG << "FileSource::ftpCommandFinished: success for command " + << command << endl; #endif return; } @@ -766,7 +843,7 @@ FileSource::deleteCacheFile() { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::deleteCacheFile(\"" << m_localFilename.toStdString() << "\")" << std::endl; + SVDEBUG << "FileSource::deleteCacheFile(\"" << m_localFilename << "\")" << endl; #endif cleanup(); @@ -803,11 +880,11 @@ if (!QFile(m_localFilename).remove()) { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::deleteCacheFile: ERROR: Failed to delete file \"" << m_localFilename.toStdString() << "\"" << std::endl; + std::cerr << "FileSource::deleteCacheFile: ERROR: Failed to delete file \"" << m_localFilename << "\"" << std::endl; #endif } else { #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::deleteCacheFile: Deleted cache file \"" << m_localFilename.toStdString() << "\"" << std::endl; + SVDEBUG << "FileSource::deleteCacheFile: Deleted cache file \"" << m_localFilename << "\"" << endl; #endif m_localFilename = ""; } @@ -824,7 +901,7 @@ QMutexLocker locker(&m_mapMutex); #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::createCacheFile: refcount is " << m_refCountMap[m_url] << std::endl; + SVDEBUG << "FileSource::createCacheFile: refcount is " << m_refCountMap[m_url] << endl; #endif if (m_refCountMap[m_url] > 0) { @@ -871,7 +948,7 @@ QString filepath(dir.filePath(filename)); #ifdef DEBUG_FILE_SOURCE - std::cerr << "FileSource::createCacheFile: URL is \"" << m_url.toString().toStdString() << "\", dir is \"" << dir.path().toStdString() << "\", base \"" << base.toStdString() << "\", extension \"" << extension.toStdString() << "\", filebase \"" << filename.toStdString() << "\", filename \"" << filepath.toStdString() << "\"" << std::endl; + std::cerr << "FileSource::createCacheFile: URL is \"" << m_url.toString() << "\", dir is \"" << dir.path() << "\", base \"" << base << "\", extension \"" << extension << "\", filebase \"" << filename << "\", filename \"" << filepath << "\"" << std::endl; #endif QMutexLocker fcLocker(&m_fileCreationMutex); @@ -883,8 +960,8 @@ #ifdef DEBUG_FILE_SOURCE std::cerr << "FileSource::createCacheFile: Failed to create local file \"" - << filepath.toStdString() << "\" for URL \"" - << m_url.toString().toStdString() << "\" (or file already exists): appending suffix instead" << std::endl; + << filepath << "\" for URL \"" + << m_url.toString() << "\" (or file already exists): appending suffix instead" << std::endl; #endif if (extension == "") { @@ -899,8 +976,8 @@ #ifdef DEBUG_FILE_SOURCE std::cerr << "FileSource::createCacheFile: ERROR: Failed to create local file \"" - << filepath.toStdString() << "\" for URL \"" - << m_url.toString().toStdString() << "\" (or file already exists)" << std::endl; + << filepath << "\" for URL \"" + << m_url.toString() << "\" (or file already exists)" << std::endl; #endif return ""; @@ -909,8 +986,8 @@ #ifdef DEBUG_FILE_SOURCE std::cerr << "FileSource::createCacheFile: url " - << m_url.toString().toStdString() << " -> local filename " - << filepath.toStdString() << std::endl; + << m_url.toString() << " -> local filename " + << filepath << std::endl; #endif m_localFilename = filepath;