annotate data/fileio/PlaylistFileReader.cpp @ 458:f60360209e5c

* Fix race condition in FFTFileCache when reading from the same FFT model from multiple threads (e.g. when applying more than one plugin at once)
author Chris Cannam
date Wed, 15 Oct 2008 12:08:02 +0000
parents 5746c559af15
children b4a8d8221eaf
rev   line source
Chris@297 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@297 2
Chris@297 3 /*
Chris@297 4 Sonic Visualiser
Chris@297 5 An audio file viewer and annotation editor.
Chris@297 6 Centre for Digital Music, Queen Mary, University of London.
Chris@297 7 This file copyright 2007 QMUL.
Chris@297 8
Chris@297 9 This program is free software; you can redistribute it and/or
Chris@297 10 modify it under the terms of the GNU General Public License as
Chris@297 11 published by the Free Software Foundation; either version 2 of the
Chris@297 12 License, or (at your option) any later version. See the file
Chris@297 13 COPYING included with this distribution for more information.
Chris@297 14 */
Chris@297 15
Chris@297 16 #include "PlaylistFileReader.h"
Chris@297 17
Chris@297 18 #include <QFile>
Chris@297 19 #include <QTextStream>
Chris@297 20 #include <QStringList>
Chris@440 21 #include <QFileInfo>
Chris@440 22 #include <QDir>
Chris@440 23
Chris@440 24 #include <iostream>
Chris@297 25
Chris@401 26 PlaylistFileReader::PlaylistFileReader(QString path) :
Chris@401 27 m_source(path),
Chris@401 28 m_file(0)
Chris@297 29 {
Chris@401 30 if (!m_source.isAvailable()) {
Chris@401 31 m_error = QFile::tr("File or URL \"%1\" could not be retrieved")
Chris@401 32 .arg(path);
Chris@401 33 return;
Chris@401 34 }
Chris@401 35 init();
Chris@401 36 }
Chris@401 37
Chris@401 38 PlaylistFileReader::PlaylistFileReader(FileSource source) :
Chris@401 39 m_source(source),
Chris@401 40 m_file(0)
Chris@401 41 {
Chris@401 42 if (!m_source.isAvailable()) {
Chris@401 43 m_error = QFile::tr("File or URL \"%1\" could not be retrieved")
Chris@401 44 .arg(source.getLocation());
Chris@401 45 return;
Chris@401 46 }
Chris@401 47 init();
Chris@401 48 }
Chris@401 49
Chris@401 50 PlaylistFileReader::~PlaylistFileReader()
Chris@401 51 {
Chris@401 52 if (m_file) m_file->close();
Chris@401 53 delete m_file;
Chris@401 54 }
Chris@401 55
Chris@401 56 void
Chris@401 57 PlaylistFileReader::init()
Chris@401 58 {
Chris@401 59 if (!m_source.isAvailable()) return;
Chris@401 60
Chris@401 61 m_source.waitForData();
Chris@401 62
Chris@440 63 QString filename = m_source.getLocalFilename();
Chris@440 64
Chris@440 65 m_file = new QFile(filename);
Chris@297 66 bool good = false;
Chris@297 67
Chris@297 68 if (!m_file->exists()) {
Chris@401 69 m_error = QFile::tr("File \"%1\" does not exist")
Chris@401 70 .arg(m_source.getLocation());
Chris@297 71 } else if (!m_file->open(QIODevice::ReadOnly | QIODevice::Text)) {
Chris@401 72 m_error = QFile::tr("Failed to open file \"%1\"")
Chris@401 73 .arg(m_source.getLocation());
Chris@297 74 } else {
Chris@297 75 good = true;
Chris@297 76 }
Chris@297 77
Chris@440 78 if (good) {
Chris@440 79 if (!m_source.isRemote()) {
Chris@440 80 m_basedir = QFileInfo(filename).dir().canonicalPath();
Chris@440 81 }
Chris@440 82 }
Chris@440 83
Chris@297 84 if (!good) {
Chris@297 85 delete m_file;
Chris@297 86 m_file = 0;
Chris@297 87 }
Chris@297 88 }
Chris@297 89
Chris@297 90 bool
Chris@297 91 PlaylistFileReader::isOK() const
Chris@297 92 {
Chris@297 93 return (m_file != 0);
Chris@297 94 }
Chris@297 95
Chris@297 96 QString
Chris@297 97 PlaylistFileReader::getError() const
Chris@297 98 {
Chris@297 99 return m_error;
Chris@297 100 }
Chris@297 101
Chris@297 102 PlaylistFileReader::Playlist
Chris@297 103 PlaylistFileReader::load() const
Chris@297 104 {
Chris@297 105 if (!m_file) return Playlist();
Chris@297 106
Chris@297 107 QTextStream in(m_file);
Chris@297 108 in.seek(0);
Chris@297 109
Chris@297 110 Playlist playlist;
Chris@297 111
Chris@297 112 while (!in.atEnd()) {
Chris@297 113
Chris@297 114 // cope with old-style Mac line endings (c.f. CSVFileReader)
Chris@297 115 // as well as DOS/Unix style
Chris@297 116
Chris@297 117 QString chunk = in.readLine();
Chris@297 118 QStringList lines = chunk.split('\r', QString::SkipEmptyParts);
Chris@297 119
Chris@440 120 for (int li = 0; li < lines.size(); ++li) {
Chris@297 121
Chris@297 122 QString line = lines[li];
Chris@297 123
Chris@297 124 if (line.startsWith("#")) continue;
Chris@297 125
Chris@440 126 // line is expected to be a URL or a file path. If it
Chris@440 127 // appears to be a local relative file path, then we
Chris@440 128 // should check whether it can be resolved relative to the
Chris@440 129 // location of the playlist file and, if so, do so.
Chris@440 130
Chris@440 131 if (!FileSource::isRemote(line)) {
Chris@440 132 if (QFileInfo(line).isRelative() && m_basedir != "") {
Chris@440 133 QString testpath = QDir(m_basedir).filePath(line);
Chris@440 134 if (QFileInfo(testpath).exists() &&
Chris@440 135 QFileInfo(testpath).isFile()) {
Chris@440 136 std::cerr << "Path \"" << line.toStdString()
Chris@440 137 << "\" is relative, resolving to \""
Chris@440 138 << testpath.toStdString() << "\""
Chris@440 139 << std::endl;
Chris@440 140 line = testpath;
Chris@440 141 }
Chris@440 142 }
Chris@440 143 }
Chris@440 144
Chris@297 145 playlist.push_back(line);
Chris@297 146 }
Chris@297 147 }
Chris@297 148
Chris@297 149 return playlist;
Chris@297 150 }
Chris@297 151
Chris@297 152 void
Chris@297 153 PlaylistFileReader::getSupportedExtensions(std::set<QString> &extensions)
Chris@297 154 {
Chris@297 155 extensions.insert("m3u");
Chris@297 156 }