From bfccddac23e1521a11d1a3cc403a30c57ee53935 Mon Sep 17 00:00:00 2001 From: Eugen Betke Date: Thu, 21 Dec 2023 16:38:32 +0000 Subject: [PATCH] ECC-1228: Add support for step range for instantaneous data --- src/step.cc | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/step.cc b/src/step.cc index 90c8ea2e1..ff5560378 100644 --- a/src/step.cc +++ b/src/step.cc @@ -24,7 +24,7 @@ namespace eccodes { Step step_from_string(const std::string& step, const Unit& force_unit) { - std::regex re("([0-9.]+)([smhDMYC]?)"); + std::regex re("([-]?[0-9.]+)([smhDMYC]?)"); std::smatch match; if (std::regex_match(step, match, re)) { if (match.size() == 3) { @@ -52,19 +52,44 @@ Step step_from_string(const std::string& step, const Unit& force_unit) return ret; } } - throw std::runtime_error("Could not parse step: " + step); + throw std::runtime_error("Could not parse step: \"" + step + "\""); } std::vector parse_range(const std::string& range_str, const Unit& force_unit) { + std::regex re1("([-]?[0-9.]+[smhDMYC]?)-([-]?[0-9.]+[smhDMYC]?)"); + std::regex re2("[-]?[0-9.]+[smhDMYC]?"); + + std::smatch match; std::vector steps; - std::string::size_type pos = 0; - std::string::size_type prev = 0; - while ((pos = range_str.find("-", prev)) != std::string::npos) { - steps.push_back(step_from_string(range_str.substr(prev, pos - prev), force_unit)); - prev = pos + 1; + if (std::regex_match(range_str, match, re1)) { + if (match.size() == 3) { + std::string v1 = match[1]; + std::string v2 = match[2]; + steps.push_back(step_from_string(v1, force_unit)); + steps.push_back(step_from_string(v2, force_unit)); + } + else if (match.size() == 2) { + std::string v1 = match[1]; + steps.push_back(step_from_string(v1, force_unit)); + } + else { + throw std::runtime_error("Could not parse step range for accumulated data: \"" + range_str + "\""); + } } - steps.push_back(step_from_string(range_str.substr(prev), force_unit)); + else if(std::regex_match(range_str, match, re2)) { + if (match.size() == 1) { + std::string v1 = match[0]; + steps.push_back(step_from_string(v1, force_unit)); + } + else { + throw std::runtime_error("Could not parse step range for instantaneous data: \"" + range_str + "\""); + } + } + else { + throw std::runtime_error("Could not parse step range: \"" + range_str + "\""); + } + return steps; }