annotate data/fileio/CSVStreamWriter.h @ 1671:82d03c9661f9 single-point

Rework isReady()/getCompletion() on models. Previously the new overhauled models were implementing getCompletion() but inheriting a version of isReady() (from the Model base) that didn't call it, referring only to isOK(). So they were reporting completion as soon as they had begun. Instead hoist getCompletion() to abstract base and call it from Model::isReady().
author Chris Cannam
date Wed, 27 Mar 2019 13:15:16 +0000
parents ea4f3593c39c
children 0d89abd631ac
rev   line source
dev@1430 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
dev@1430 2
dev@1430 3 /*
dev@1430 4 Sonic Visualiser
dev@1430 5 An audio file viewer and annotation editor.
dev@1430 6 Centre for Digital Music, Queen Mary, University of London.
dev@1438 7 This file copyright 2017 Queen Mary, University of London.
dev@1430 8
dev@1430 9 This program is free software; you can redistribute it and/or
dev@1430 10 modify it under the terms of the GNU General Public License as
dev@1430 11 published by the Free Software Foundation; either version 2 of the
dev@1430 12 License, or (at your option) any later version. See the file
dev@1430 13 COPYING included with this distribution for more information.
dev@1430 14 */
dev@1430 15
cannam@1452 16 #ifndef SV_CSV_STREAM_WRITER_H
cannam@1452 17 #define SV_CSV_STREAM_WRITER_H
dev@1430 18
dev@1434 19 #include "base/BaseTypes.h"
dev@1434 20 #include "base/Selection.h"
dev@1434 21 #include "base/ProgressReporter.h"
dev@1434 22 #include "base/DataExportOptions.h"
dev@1434 23 #include "data/model/Model.h"
dev@1434 24 #include <QString>
dev@1434 25 #include <algorithm>
dev@1445 26 #include <numeric>
dev@1441 27
dev@1438 28 namespace CSVStreamWriter
dev@1430 29 {
dev@1430 30
dev@1445 31 template <class OutStream>
dev@1445 32 bool
dev@1445 33 writeInChunks(OutStream& oss,
dev@1445 34 const Model& model,
dev@1445 35 const MultiSelection& regions,
dev@1445 36 ProgressReporter* reporter = nullptr,
dev@1445 37 QString delimiter = ",",
dev@1445 38 DataExportOptions options = DataExportDefaults,
dev@1445 39 const sv_frame_t blockSize = 16384)
dev@1445 40 {
dev@1447 41 const auto selections = regions.getSelections();
dev@1447 42 if (blockSize <= 0 || selections.empty()) return false;
dev@1445 43
dev@1445 44 // TODO, some form of checking validity of selections?
dev@1445 45 const auto nFramesToWrite = std::accumulate(
dev@1447 46 selections.begin(),
dev@1447 47 selections.end(),
dev@1445 48 0,
dev@1445 49 [](sv_frame_t acc, const Selection& current) -> sv_frame_t {
dev@1445 50 return acc + (current.getEndFrame() - current.getStartFrame());
dev@1445 51 }
dev@1445 52 );
dev@1445 53
dev@1445 54 const auto wasCancelled = [&reporter]() {
dev@1445 55 return reporter && reporter->wasCancelled();
dev@1445 56 };
dev@1445 57
dev@1445 58 sv_frame_t nFramesWritten = 0;
dev@1445 59 int previousProgress = 0;
Chris@1609 60 bool started = false;
dev@1445 61
dev@1447 62 for (const auto& extents : selections) {
dev@1445 63 const auto startFrame = extents.getStartFrame();
dev@1445 64 const auto endFrame = extents.getEndFrame();
dev@1445 65 auto readPtr = startFrame;
dev@1445 66 while (readPtr < endFrame) {
dev@1445 67 if (wasCancelled()) return false;
dev@1445 68
dev@1445 69 const auto start = readPtr;
dev@1445 70 const auto end = std::min(start + blockSize, endFrame);
dev@1449 71 const auto data = model.toDelimitedDataStringSubsetWithOptions(
dev@1445 72 delimiter,
dev@1445 73 options,
dev@1445 74 start,
dev@1445 75 end
dev@1449 76 ).trimmed();
dev@1449 77
dev@1449 78 if ( data != "" ) {
Chris@1609 79 if (started) {
Chris@1609 80 oss << "\n";
Chris@1609 81 } else {
Chris@1609 82 started = true;
Chris@1609 83 }
Chris@1609 84 oss << data;
dev@1449 85 }
dev@1449 86
dev@1445 87 nFramesWritten += end - start;
Chris@1454 88 const int currentProgress =
Chris@1454 89 int(100 * nFramesWritten / nFramesToWrite);
dev@1445 90 const bool hasIncreased = currentProgress > previousProgress;
dev@1445 91 if (hasIncreased) {
dev@1445 92 if (reporter) reporter->setProgress(currentProgress);
dev@1445 93 previousProgress = currentProgress;
dev@1445 94 }
dev@1445 95 readPtr = end;
dev@1445 96 }
dev@1445 97 }
dev@1445 98 return !wasCancelled(); // setProgress could process event loop
dev@1445 99 }
dev@1445 100
dev@1445 101 template <class OutStream>
dev@1441 102 bool
dev@1441 103 writeInChunks(OutStream& oss,
dev@1441 104 const Model& model,
dev@1441 105 const Selection& extents,
dev@1441 106 ProgressReporter* reporter = nullptr,
dev@1441 107 QString delimiter = ",",
dev@1441 108 DataExportOptions options = DataExportDefaults,
dev@1445 109 const sv_frame_t blockSize = 16384)
dev@1434 110 {
dev@1441 111 const auto startFrame = extents.isEmpty() ?
dev@1434 112 model.getStartFrame() : extents.getStartFrame();
dev@1441 113 const auto endFrame = extents.isEmpty() ?
dev@1434 114 model.getEndFrame() : extents.getEndFrame();
dev@1441 115 const auto hasValidExtents = startFrame >= 0 && endFrame > startFrame;
dev@1441 116 if (!hasValidExtents) return false;
dev@1445 117 Selection all {
dev@1445 118 startFrame,
dev@1445 119 endFrame
dev@1434 120 };
dev@1445 121 MultiSelection regions;
dev@1445 122 regions.addSelection(all);
dev@1445 123 return CSVStreamWriter::writeInChunks(
dev@1445 124 oss,
dev@1445 125 model,
dev@1445 126 regions,
dev@1445 127 reporter,
dev@1445 128 delimiter,
dev@1445 129 options,
dev@1445 130 blockSize
dev@1445 131 );
dev@1434 132 }
dev@1434 133
dev@1434 134 template <class OutStream>
dev@1441 135 bool
dev@1441 136 writeInChunks(OutStream& oss,
dev@1441 137 const Model& model,
dev@1441 138 ProgressReporter* reporter = nullptr,
dev@1441 139 QString delimiter = ",",
dev@1441 140 DataExportOptions options = DataExportDefaults,
dev@1441 141 const sv_frame_t blockSize = 16384)
dev@1434 142 {
dev@1434 143 const Selection empty;
dev@1444 144 return CSVStreamWriter::writeInChunks(
dev@1434 145 oss,
dev@1434 146 model,
dev@1434 147 empty,
dev@1434 148 reporter,
dev@1434 149 delimiter,
dev@1434 150 options,
dev@1434 151 blockSize
dev@1434 152 );
dev@1434 153 }
dev@1438 154 } // namespace CSVStreamWriter
cannam@1452 155 #endif