Mercurial > hg > svcore
diff data/fileio/CSVStreamWriter.h @ 1434:0684c6698e3f streaming-csv-writer
Added utility function for splitting a model selection into chunks and writing to a stream.
author | Lucas Thompson <dev@lucas.im> |
---|---|
date | Tue, 17 Apr 2018 10:03:49 +0100 |
parents | b5283878cca2 |
children | 09c2ba31a711 |
line wrap: on
line diff
--- a/data/fileio/CSVStreamWriter.h Tue Apr 17 10:03:49 2018 +0100 +++ b/data/fileio/CSVStreamWriter.h Tue Apr 17 10:03:49 2018 +0100 @@ -16,11 +16,85 @@ #ifndef _CSV_STREAM_WRITER_H_ #define _CSV_STREAM_WRITER_H_ -class CSVStreamWriter +#include "base/BaseTypes.h" +#include "base/Selection.h" +#include "base/ProgressReporter.h" +#include "base/DataExportOptions.h" +#include "data/model/Model.h" +#include <QString> +#include <algorithm> + +namespace CSV { +using Completed = bool; -}; +template <class OutStream> +auto writeToStreamInChunks( + OutStream& oss, + const Model& model, + const Selection& extents, + ProgressReporter* reporter = nullptr, + QString delimiter = ",", + DataExportOptions options = DataExportDefaults, + const sv_frame_t blockSize = 16384 +) -> Completed +{ + if (blockSize <= 0) return false; + sv_frame_t readPtr = extents.isEmpty() ? + model.getStartFrame() : extents.getStartFrame(); + sv_frame_t endFrame = extents.isEmpty() ? + model.getEndFrame() : extents.getEndFrame(); + int previousPercentagePoint = 0; -#endif + const auto wasCancelled = [&reporter]() { + return reporter && reporter->wasCancelled(); + }; - + while (readPtr < endFrame) { + if (wasCancelled()) return false; + + const auto start = readPtr; + const auto end = std::min(start + blockSize, endFrame); + + oss << model.toDelimitedDataStringSubsetWithOptions( + delimiter, + options, + start, + end + ) << (end < endFrame ? "\n" : ""); + + const auto currentPercentage = 100 * end / endFrame; + const bool hasIncreased = currentPercentage > previousPercentagePoint; + + if (hasIncreased) { + if (reporter) reporter->setProgress(currentPercentage); + previousPercentagePoint = currentPercentage; + } + readPtr = end; + } + return !wasCancelled(); // setProgress could process event loop +} + +template <class OutStream> +auto writeToStreamInChunks( + OutStream& oss, + const Model& model, + ProgressReporter* reporter = nullptr, + QString delimiter = ",", + DataExportOptions options = DataExportDefaults, + const sv_frame_t blockSize = 16384 +) -> Completed +{ + const Selection empty; + return CSV::writeToStreamInChunks( + oss, + model, + empty, + reporter, + delimiter, + options, + blockSize + ); +} +} // namespace +#endif \ No newline at end of file