dev@1430: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ dev@1430: dev@1430: /* dev@1430: Sonic Visualiser dev@1430: An audio file viewer and annotation editor. dev@1430: Centre for Digital Music, Queen Mary, University of London. dev@1438: This file copyright 2017 Queen Mary, University of London. dev@1430: dev@1430: This program is free software; you can redistribute it and/or dev@1430: modify it under the terms of the GNU General Public License as dev@1430: published by the Free Software Foundation; either version 2 of the dev@1430: License, or (at your option) any later version. See the file dev@1430: COPYING included with this distribution for more information. dev@1430: */ dev@1430: dev@1438: #ifndef CSV_STREAM_WRITER_H dev@1438: #define CSV_STREAM_WRITER_H dev@1430: dev@1434: #include "base/BaseTypes.h" dev@1434: #include "base/Selection.h" dev@1434: #include "base/ProgressReporter.h" dev@1434: #include "base/DataExportOptions.h" dev@1434: #include "data/model/Model.h" dev@1434: #include dev@1434: #include dev@1434: dev@1441: namespace dev@1441: { dev@1441: const auto initProgressCalculator = [](sv_frame_t nFramesToWrite) { dev@1441: return [nFramesToWrite](sv_frame_t nFramesWritten) { dev@1441: return 100 * nFramesWritten / nFramesToWrite; dev@1441: }; dev@1441: }; dev@1441: } // namespace dev@1441: dev@1438: namespace CSVStreamWriter dev@1430: { dev@1430: dev@1441: template < dev@1441: class OutStream, dev@1441: class ProgressCalculatorInit = decltype(initProgressCalculator) dev@1441: > dev@1441: bool dev@1441: writeInChunks(OutStream& oss, dev@1441: const Model& model, dev@1441: const Selection& extents, dev@1441: ProgressReporter* reporter = nullptr, dev@1441: QString delimiter = ",", dev@1441: DataExportOptions options = DataExportDefaults, dev@1441: const sv_frame_t blockSize = 16384, dev@1441: const ProgressCalculatorInit& initCalc = initProgressCalculator) dev@1434: { dev@1434: if (blockSize <= 0) return false; dev@1441: const auto startFrame = extents.isEmpty() ? dev@1434: model.getStartFrame() : extents.getStartFrame(); dev@1441: const auto endFrame = extents.isEmpty() ? dev@1434: model.getEndFrame() : extents.getEndFrame(); dev@1441: const auto hasValidExtents = startFrame >= 0 && endFrame > startFrame; dev@1441: if (!hasValidExtents) return false; dev@1441: const auto calculateProgress = initCalc(endFrame - startFrame); dev@1441: dev@1441: auto readPtr = startFrame; dev@1434: int previousPercentagePoint = 0; dev@1430: dev@1434: const auto wasCancelled = [&reporter]() { dev@1434: return reporter && reporter->wasCancelled(); dev@1434: }; dev@1430: dev@1434: while (readPtr < endFrame) { dev@1434: if (wasCancelled()) return false; dev@1434: dev@1434: const auto start = readPtr; dev@1434: const auto end = std::min(start + blockSize, endFrame); dev@1434: dev@1434: oss << model.toDelimitedDataStringSubsetWithOptions( dev@1434: delimiter, dev@1434: options, dev@1434: start, dev@1434: end dev@1434: ) << (end < endFrame ? "\n" : ""); dev@1441: const auto nFramesWritten = end - startFrame; dev@1441: const auto currentPercentage = calculateProgress(nFramesWritten); dev@1434: const bool hasIncreased = currentPercentage > previousPercentagePoint; dev@1434: dev@1434: if (hasIncreased) { dev@1434: if (reporter) reporter->setProgress(currentPercentage); dev@1434: previousPercentagePoint = currentPercentage; dev@1434: } dev@1434: readPtr = end; dev@1434: } dev@1434: return !wasCancelled(); // setProgress could process event loop dev@1434: } dev@1434: dev@1434: template dev@1441: bool dev@1441: writeInChunks(OutStream& oss, dev@1441: const Model& model, dev@1441: ProgressReporter* reporter = nullptr, dev@1441: QString delimiter = ",", dev@1441: DataExportOptions options = DataExportDefaults, dev@1441: const sv_frame_t blockSize = 16384) dev@1434: { dev@1434: const Selection empty; dev@1438: return CSV::writeInChunks( dev@1434: oss, dev@1434: model, dev@1434: empty, dev@1434: reporter, dev@1434: delimiter, dev@1434: options, dev@1434: blockSize dev@1434: ); dev@1434: } dev@1438: } // namespace CSVStreamWriter dev@1434: #endif