From 4b70074484696afd9a970c1637ae765a36aac37a 2017-07-12 07:47:39 From: Alexandre Leroux Date: 2017-07-12 07:47:39 Subject: [PATCH] Improves controls when reading results --- diff --git a/plugins/amda/src/AmdaResultParser.cpp b/plugins/amda/src/AmdaResultParser.cpp index 8c1b114..2438d51 100644 --- a/plugins/amda/src/AmdaResultParser.cpp +++ b/plugins/amda/src/AmdaResultParser.cpp @@ -13,6 +13,9 @@ namespace { /// Format for dates in result files const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz"); +/// Separator between values in a result line +const auto RESULT_LINE_SEPARATOR = QRegularExpression{QStringLiteral("\\s+")}; + /// Regex to find unit in a line. Examples of valid lines: /// ... - Units : nT - ... /// ... -Units:nT- ... @@ -20,11 +23,13 @@ const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz"); /// ... - Units : m/s - ... const auto UNIT_REGEX = QRegularExpression{QStringLiteral("-\\s*Units\\s*:\\s*(.+?)\\s*-")}; -/// @todo ALX +/// Converts a string date to a double date +/// @return a double that represents the date in seconds, NaN if the string date can't be converted double doubleDate(const QString &stringDate) noexcept { auto dateTime = QDateTime::fromString(stringDate, DATE_FORMAT); - return dateTime.toMSecsSinceEpoch() / 1000.; + return dateTime.isValid() ? (dateTime.toMSecsSinceEpoch() / 1000.) + : std::numeric_limits::quiet_NaN(); } /** @@ -55,6 +60,48 @@ Unit readXAxisUnit(QTextStream &stream) return Unit{{}, true}; } +/** + * Reads stream to retrieve results + * @param stream the stream to read + * @return the pair of vectors x-axis data/values data that has been read in the stream + */ +QPair, QVector > readResults(QTextStream &stream) +{ + auto xData = QVector{}; + auto valuesData = QVector{}; + + QString line{}; + while (stream.readLineInto(&line)) { + auto lineData = line.split(RESULT_LINE_SEPARATOR, QString::SkipEmptyParts); + if (lineData.size() == 2) { + // X : the data is converted from date to double (in secs) + auto x = doubleDate(lineData.at(0)); + + // Value + bool valueOk; + auto value = lineData.at(1).toDouble(&valueOk); + + // Adds result only if x and value are valid + if (!std::isnan(x) && !std::isnan(value) && valueOk) { + xData.push_back(x); + valuesData.push_back(value); + } + else { + qCWarning(LOG_AmdaResultParser()) + << QObject::tr( + "Can't retrieve results from line %1: x and/or value are invalid") + .arg(line); + } + } + else { + qCWarning(LOG_AmdaResultParser()) + << QObject::tr("Can't retrieve results from line %1: invalid line").arg(line); + } + } + + return qMakePair(std::move(xData), std::move(valuesData)); +} + } // namespace std::shared_ptr AmdaResultParser::readTxt(const QString &filePath) noexcept @@ -68,36 +115,18 @@ std::shared_ptr AmdaResultParser::readTxt(const QString &filePath) return nullptr; } - auto xData = QVector{}; - auto valuesData = QVector{}; - QTextStream stream{&file}; // Ignore first two lines (comments lines) stream.readLine(); stream.readLine(); - QString line{}; - // Reads x-axis unit auto xAxisUnit = readXAxisUnit(stream); // Reads results - auto lineRegex = QRegExp{QStringLiteral("\\s+")}; - while (stream.readLineInto(&line)) { - auto lineData = line.split(lineRegex, QString::SkipEmptyParts); - if (lineData.size() == 2) { - // X : the data is converted from date to double (in secs) - xData.push_back(doubleDate(lineData.at(0))); - - // Value - valuesData.push_back(lineData.at(1).toDouble()); - } - else { - /// @todo ALX : log - } - } + auto results = readResults(stream); - return std::make_shared(std::move(xData), std::move(valuesData), xAxisUnit, - Unit{}); + return std::make_shared(std::move(results.first), std::move(results.second), + xAxisUnit, Unit{}); }