changeset 604:4541581067f3

* Better handling of failed-to-open-output-stream situations; ensure CSV writer closes files when they're finished rather than when it's finished
author Chris Cannam
date Tue, 08 Sep 2009 16:52:36 +0000
parents e43368ec5ff0
children 133418f4e74c
files transform/CSVFeatureWriter.cpp transform/CSVFeatureWriter.h transform/FeatureWriter.h transform/FileFeatureWriter.cpp
diffstat 4 files changed, 36 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/transform/CSVFeatureWriter.cpp	Tue Sep 08 11:27:26 2009 +0000
+++ b/transform/CSVFeatureWriter.cpp	Tue Sep 08 16:52:36 2009 +0000
@@ -79,7 +79,9 @@
     // combination
 
     QTextStream *sptr = getOutputStream(trackId, transform.getIdentifier());
-    if (!sptr) return; //!!! this is probably better handled with an exception
+    if (!sptr) {
+        throw FailedToOpenOutputStream(trackId, transform.getIdentifier());
+    }
 
     QTextStream &stream = *sptr;
 
--- a/transform/CSVFeatureWriter.h	Tue Sep 08 11:27:26 2009 +0000
+++ b/transform/CSVFeatureWriter.h	Tue Sep 08 16:52:36 2009 +0000
@@ -49,7 +49,7 @@
                        const Vamp::Plugin::FeatureList &features,
                        std::string summaryType = "");
 
-    virtual void finish() { }
+    virtual QString getWriterTag() const { return "csv"; }
 
 private:
     QString m_separator;
--- a/transform/FeatureWriter.h	Tue Sep 08 11:27:26 2009 +0000
+++ b/transform/FeatureWriter.h	Tue Sep 08 16:52:36 2009 +0000
@@ -59,6 +59,24 @@
     };
     virtual void setTrackMetadata(QString trackid, TrackMetadata metadata) { }
 
+    class FailedToOpenOutputStream : virtual public std::exception
+    {
+    public:
+        FailedToOpenOutputStream(QString trackId, QString transformId) throw() :
+            m_trackId(trackId),
+            m_transformId(transformId)
+        { }
+        virtual ~FailedToOpenOutputStream() throw() { }
+        virtual const char *what() const throw() {
+            return QString("Failed to open output stream for track id \"%1\", transform id \"%2\"")
+                .arg(m_trackId).arg(m_transformId).toLocal8Bit().data();
+        }            
+        
+    protected:
+        QString m_trackId;
+        QString m_transformId;
+    };
+
     // may throw FailedToOpenFile or other exceptions
 
     virtual void write(QString trackid,
@@ -70,6 +88,8 @@
     virtual void flush() { } // whatever the last stream was
 
     virtual void finish() = 0;
+
+    virtual QString getWriterTag() const = 0;
 };
 
 #endif
--- a/transform/FileFeatureWriter.cpp	Tue Sep 08 11:27:26 2009 +0000
+++ b/transform/FileFeatureWriter.cpp	Tue Sep 08 16:52:36 2009 +0000
@@ -59,6 +59,8 @@
         m_streams.erase(m_streams.begin());
     }
     while (!m_files.empty()) {
+        cerr << "FileFeatureWriter::~FileFeatureWriter: NOTE: Closing feature file \""
+             << m_files.begin()->second->fileName().toStdString() << "\"" << endl;
         delete m_files.begin()->second;
         m_files.erase(m_files.begin());
     }
@@ -156,7 +158,8 @@
 {
     if (m_singleFileName != "") {
         if (QFileInfo(m_singleFileName).exists() && !(m_force || m_append)) {
-            cerr << "FileFeatureWriter: ERROR: Specified output file \"" << m_singleFileName.toStdString() << "\" exists and neither force nor append flag is specified -- not overwriting" << endl;
+            cerr << endl << "FileFeatureWriter: ERROR: Specified output file \"" << m_singleFileName.toStdString() << "\" exists and neither --" << getWriterTag().toStdString() << "-force nor --" << getWriterTag().toStdString() << "-append flag is specified -- not overwriting" << endl;
+            cerr << "NOTE: To find out how to fix this problem, read the help for the --" << getWriterTag().toStdString() << "-force" << endl << "and --" << getWriterTag().toStdString() << "-append options" << endl;
             return "";
         }
         return m_singleFileName;
@@ -178,14 +181,15 @@
         infilename = scheme + ":" + infilename; // DOS drive!
     }
 
-//    cerr << "trackId = " << trackId.toStdString() << ", url = " << url.toString().toStdString() << ", infilename = "
-//         << infilename.toStdString() << ", basename = " << basename.toStdString() << endl;
-
+    cerr << "trackId = " << trackId.toStdString() << ", url = " << url.toString().toStdString() << ", infilename = "
+         << infilename.toStdString() << ", basename = " << basename.toStdString() << ", m_baseDir = " << m_baseDir.toStdString() << endl;
 
     if (m_baseDir != "") dirname = QFileInfo(m_baseDir).absoluteFilePath();
     else if (local) dirname = QFileInfo(infilename).absolutePath();
     else dirname = QDir::currentPath();
 
+    cerr << "dirname = " << dirname.toStdString() << endl;
+
     QString filename;
 
     if (m_manyFiles && transformId != "") {
@@ -199,7 +203,8 @@
     filename = QDir(dirname).filePath(filename);
 
     if (QFileInfo(filename).exists() && !(m_force || m_append)) {
-        cerr << "FileFeatureWriter: ERROR: Output file \"" << filename.toStdString() << "\" exists (for input file or URL \"" << trackId.toStdString() << "\" and transform \"" << transformId.toStdString() << "\") and neither force nor append is specified -- not overwriting" << endl;
+        cerr << endl << "FileFeatureWriter: ERROR: Output file \"" << filename.toStdString() << "\" exists (for input file or URL \"" << trackId.toStdString() << "\" and transform \"" << transformId.toStdString() << "\") and neither --" << getWriterTag().toStdString() << "-force nor --" << getWriterTag().toStdString() << "-append is specified -- not overwriting" << endl;
+        cerr << "NOTE: To find out how to fix this problem, read the help for the --" << getWriterTag().toStdString() << "-force" << endl << "and --" << getWriterTag().toStdString() << "-append options" << endl;
         return "";
     }
     
@@ -304,6 +309,8 @@
         m_streams.erase(m_streams.begin());
     }
     while (!m_files.empty()) {
+        cerr << "FileFeatureWriter::finish: NOTE: Closing feature file \""
+             << m_files.begin()->second->fileName().toStdString() << "\"" << endl;
         delete m_files.begin()->second;
         m_files.erase(m_files.begin());
     }