From b1843f0e04dde5ec2f438e840ff9df6f65aabb41 Mon Sep 17 00:00:00 2001 From: Emanuele Danovaro Date: Mon, 8 Apr 2024 17:13:47 +0200 Subject: [PATCH] added to-by support for stepranges --- VERSION | 2 +- src/metkit/mars/StepRange.cc | 3 +- src/metkit/mars/StepRange.h | 9 ++++ src/metkit/mars/TypeRange.cc | 25 ++++++----- src/metkit/mars/TypeRange.h | 5 +++ tests/test_expand.cc | 84 +++++++++++++++++++++--------------- 6 files changed, 81 insertions(+), 47 deletions(-) diff --git a/VERSION b/VERSION index 361ffc5b..f33bbfa1 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.11.9 +1.11.10 diff --git a/src/metkit/mars/StepRange.cc b/src/metkit/mars/StepRange.cc index 6feed4b3..18f05060 100644 --- a/src/metkit/mars/StepRange.cc +++ b/src/metkit/mars/StepRange.cc @@ -102,7 +102,8 @@ void StepRange::print(std::ostream& s) const eckit::Time t{static_cast(to_*3600.), true}; TimeUnit unit = std::min(maxUnit(f), maxUnit(t)); - s << canonical(f, unit) << '-' << canonical(t, unit); + // s << canonical(f, unit) << '-' << canonical(t, unit); + s << canonical(f) << '-' << canonical(t); } } diff --git a/src/metkit/mars/StepRange.h b/src/metkit/mars/StepRange.h index 5026f85f..9d0a0b7b 100644 --- a/src/metkit/mars/StepRange.h +++ b/src/metkit/mars/StepRange.h @@ -60,6 +60,12 @@ class StepRange { operator std::string() const; + StepRange& operator+=(const eckit::Time& step) { + from_ += step/3600.; + to_ += step/3600.; + return *this; + } + bool operator==(const StepRange& other) const { return from_ == other.from_ && to_ == other.to_; } @@ -69,6 +75,9 @@ class StepRange { bool operator<(const StepRange& other) const { return (from_ != other.from_)?(from_(const StepRange& other) const { return other < *this; } diff --git a/src/metkit/mars/TypeRange.cc b/src/metkit/mars/TypeRange.cc index 27e03b41..efadc813 100644 --- a/src/metkit/mars/TypeRange.cc +++ b/src/metkit/mars/TypeRange.cc @@ -40,16 +40,14 @@ void TypeRange::print(std::ostream &out) const { out << "TypeRange[name=" << name_ << "]"; } -bool TypeRange::expand(const MarsExpandContext& ctx, std::string& value) const { - +StepRange TypeRange::parse(std::string& value) const { eckit::Tokenizer parse("-"); std::vector result; parse(value, result); switch (result.size()) { case 1: { - value = StepRange(eckit::Time(result[0], true)); - return true; + return StepRange(eckit::Time(result[0], true)); } case 2: { eckit::Time start = eckit::Time(result[0], true); @@ -60,15 +58,20 @@ bool TypeRange::expand(const MarsExpandContext& ctx, std::string& value) const { oss << name_ + ": initial value " << start << " cannot be greater that final value " << end; throw eckit::BadValue(oss.str()); } - value = StepRange(start, end); - return true; + return StepRange(start, end); } default: std::ostringstream oss; oss << name_ + ": invalid value " << value << " " << result.size(); throw eckit::BadValue(oss.str()); - } - return false; + } +} + +bool TypeRange::expand(const MarsExpandContext& ctx, std::string& value) const { + + value = parse(value); + return true; + } void TypeRange::expand(const MarsExpandContext& ctx, std::vector& values) const { @@ -93,10 +96,10 @@ void TypeRange::expand(const MarsExpandContext& ctx, std::vector& v throw eckit::BadValue(oss.str()); } - eckit::Time from = eckit::Time(values[i - 1], true); + StepRange from = parse(values[i - 1]); // unit = maxUnit(from); - eckit::Time to = eckit::Time(values[i + 1], true); + StepRange to = parse(values[i + 1]); eckit::Time by = by_; if (i+2 < values.size() && eckit::StringTools::lower(values[i + 2]) == "by") { @@ -121,7 +124,7 @@ void TypeRange::expand(const MarsExpandContext& ctx, std::vector& v oss << name_ + ": 'by' value " << by << " must be a positive number"; throw eckit::BadValue(name_ + ": 'by' value must be a positive number"); } - eckit::Time j = from; + StepRange j = from; j += by; for (; j <= to; j += by) { newval.emplace_back(StepRange(j)); diff --git a/src/metkit/mars/TypeRange.h b/src/metkit/mars/TypeRange.h index 7eef8a0e..edca7cda 100644 --- a/src/metkit/mars/TypeRange.h +++ b/src/metkit/mars/TypeRange.h @@ -19,6 +19,7 @@ namespace metkit { namespace mars { +class StepRange; //---------------------------------------------------------------------------------------------------------------------- class TypeRange : public Type { @@ -36,6 +37,10 @@ class TypeRange : public Type { virtual void expand(const MarsExpandContext& ctx, std::vector& values) const override; + StepRange parse(std::string& value) const; + +private: // attributes + eckit::Time by_; }; diff --git a/tests/test_expand.cc b/tests/test_expand.cc index 3a6b988b..ab3fac60 100644 --- a/tests/test_expand.cc +++ b/tests/test_expand.cc @@ -20,6 +20,7 @@ #include "metkit/mars/Type.h" #include "eckit/testing/Test.h" +#include "eckit/utils/Tokenizer.h" using namespace eckit::testing; @@ -233,44 +234,59 @@ CASE( "test_metkit_expand_12_time" ) { void stepThrows(std::vector values) { expandKeyThrows("step", values); } -void step(std::vector values, std::vector expected) { +void step(std::string valuesStr, std::string expectedStr) { + eckit::Tokenizer parse("/"); + std::vector values; + std::vector expected; + + parse(valuesStr, values); + parse(expectedStr, expected); + expandKey("step", values, expected); } CASE( "test_metkit_expand_13_step" ) { - step({"0"}, {"0"}); - step({"1"}, {"1"}); - step({"24"}, {"24"}); - step({"144"}, {"144"}); - step({"012"}, {"12"}); - step({"12:30"}, {"12h30m"}); - step({"1:00"}, {"1"}); - step({"1:0:0"}, {"1"}); - step({"1h"}, {"1"}); - step({"60m"}, {"1"}); - step({"1h60m"}, {"2"}); - step({"0:5"}, {"5m"}); - step({"0:05"}, {"5m"}); - step({"0:05:0"}, {"5m"}); - step({"0:06"}, {"6m"}); - step({"0:10"}, {"10m"}); - step({"0:12"}, {"12m"}); - step({"0:15"}, {"15m"}); - step({"0:20"}, {"20m"}); - step({"0:25"}, {"25m"}); - step({"0:30"}, {"30m"}); - step({"0:35"}, {"35m"}); - step({"0:40"}, {"40m"}); - step({"0:45"}, {"45m"}); - step({"0:50"}, {"50m"}); - step({"0:55"}, {"55m"}); - step({"0-24"}, {"0-24"}); - step({"0-24s"}, {"0s-24s"}); - step({"0-120s"}, {"0m-2m"}); - step({"0s-120m"}, {"0-2"}); - step({"1-2"}, {"1-2"}); - step({"30m-1"}, {"30m-60m"}); - + step("0", "0"); + step("1", "1"); + step("24", "24"); + step("144", "144"); + step("012", "12"); + step("12:30", "12h30m"); + step("1:00", "1"); + step("1:0:0", "1"); + step("1h", "1"); + step("60m", "1"); + step("1h60m", "2"); + step("0:5", "5m"); + step("0:05", "5m"); + step("0:05:0", "5m"); + step("0:06", "6m"); + step("0:10", "10m"); + step("0:12", "12m"); + step("0:15", "15m"); + step("0:20", "20m"); + step("0:25", "25m"); + step("0:30", "30m"); + step("0:35", "35m"); + step("0:40", "40m"); + step("0:45", "45m"); + step("0:50", "50m"); + step("0:55", "55m"); + step("0-24", "0-24"); + step("0-24s", "0-24s"); + step("0-120s", "0-2m"); + step("0s-120m", "0-2"); + step("1-2", "1-2"); + step("30m-1", "30m-1"); + step("30m-90m", "30m-1h30m"); + + step("0/to/24/by/3", "0/3/6/9/12/15/18/21/24"); + step("12/to/48/by/12", "12/24/36/48"); + step("12/to/47/by/12", "12/24/36"); + step("0/to/6/by/30m", "0/30m/1/1h30m/2/2h30m/3/3h30m/4/4h30m/5/5h30m/6"); + step("0-6/to/18-24/by/6", "0-6/6-12/12-18/18-24"); + step("0-24/to/48-72/by/24", "0-24/24-48/48-72"); + step("0/to/24/by/3/0-6/to/18-24/by/6", "0/3/6/9/12/15/18/21/24/0-6/6-12/12-18/18-24"); }