mirror of https://github.com/ecmwf/eccodes.git
ECC-1620: Fix handing multiple messages in a GRIB file
This commit is contained in:
parent
982f46d16a
commit
45267d146d
|
@ -14,9 +14,9 @@ codetable[1] indicatorOfUnitOfTimeRange ('4.4.table',masterDir,localDir) : dump
|
|||
#alias forecastTimeUnit = indicatorOfUnitOfTimeRange;
|
||||
#template_nofail default_step_units "grib2/localConcepts/[centre:s]/default_step_units.def";
|
||||
#codetable[1] stepUnits 'stepUnits.table' = defaultStepUnits : transient,dump,no_copy;
|
||||
codetable[1] stepUnits 'stepUnits.table' = 255 : transient,dump,no_copy;
|
||||
#transient useOptimalStepUnits = 0;
|
||||
meta optimalStepUnits optimal_step_units(forecastTime,indicatorOfUnitOfTimeRange,lengthOfTimeRange,indicatorOfUnitForTimeRange) : dump;
|
||||
meta stepUnits optimal_step_units(forecastTime,indicatorOfUnitOfTimeRange,lengthOfTimeRange,indicatorOfUnitForTimeRange) : dump;
|
||||
transient startStepUnit = 255;
|
||||
transient endStepUnit = 255;
|
||||
|
||||
# Forecast time in units defined by previous octet (GRIB-29: supports negative forecast time)
|
||||
signed[4] forecastTime : dump;
|
||||
|
|
|
@ -409,7 +409,7 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
|||
|
||||
|
||||
|
||||
static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
||||
static int pack_long_(grib_accessor* a, const long end_step_value, const long end_step_unit)
|
||||
{
|
||||
grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
|
@ -423,6 +423,7 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
|||
long second;
|
||||
|
||||
long start_step_value;
|
||||
long start_step_unit;
|
||||
long step_units, time_range_unit;
|
||||
long year_of_end_of_interval;
|
||||
long month_of_end_of_interval;
|
||||
|
@ -435,17 +436,16 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
|||
|
||||
double dend, dstep;
|
||||
|
||||
Step end_step{end_step_value, end_step_unit};
|
||||
|
||||
/*point in time */
|
||||
if (self->year == NULL) {
|
||||
err = grib_set_long_internal(h, self->start_step_value, *val);
|
||||
err = grib_set_long_internal(h, self->start_step_value, end_step.value<long>());
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = grib_get_long_internal(h, self->time_range_unit, &time_range_unit)))
|
||||
return err;
|
||||
//if ((err = grib_get_long_internal(h, self->step_units, &step_units)))
|
||||
//return err;
|
||||
step_units = get_step_units(h);
|
||||
if ((err = grib_get_long_internal(h, self->year, &year)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->month, &month)))
|
||||
|
@ -461,14 +461,23 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
|||
|
||||
if ((err = grib_get_long_internal(h, self->start_step_value, &start_step_value)))
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, "startStepUnit", &start_step_unit)))
|
||||
return err;
|
||||
if (start_step_unit == 255) {
|
||||
throw std::runtime_error("startStepUnit == 255");
|
||||
}
|
||||
|
||||
if ((err = grib_get_long_internal(h, self->typeOfTimeIncrement, &typeOfTimeIncrement)))
|
||||
return err;
|
||||
|
||||
time_range_v = *val - start_step_value;
|
||||
Step start_step{start_step_value, start_step_unit};
|
||||
|
||||
if (time_range_v < 0) {
|
||||
//time_range_v = *val - start_step_value;
|
||||
Step time_range = end_step - start_step;
|
||||
|
||||
if (time_range.value<double>() < 0) {
|
||||
grib_context_log(h->context, GRIB_LOG_ERROR,
|
||||
"endStep < startStep (%ld < %ld)", *val, start_step_value);
|
||||
"endStep < startStep (%s < %s)", end_step.to_string().c_str(), start_step.to_string().c_str());
|
||||
return GRIB_WRONG_STEP;
|
||||
}
|
||||
|
||||
|
@ -476,7 +485,7 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
|||
if (err != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
dstep = (((double)(*val)) * u2s[step_units]) / u2s[2]; /* in days */
|
||||
dstep = end_step.value<double>(UnitType{Unit::DAY});
|
||||
dend += dstep;
|
||||
|
||||
err = grib_julian_to_datetime(dend, &year_of_end_of_interval, &month_of_end_of_interval,
|
||||
|
@ -498,45 +507,46 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
|||
if ((err = grib_set_long_internal(h, self->second_of_end_of_interval, second_of_end_of_interval)))
|
||||
return err;
|
||||
|
||||
if (time_range_v * u2s[step_units] % u2s2[time_range_unit]) {
|
||||
time_range_unit = step_units;
|
||||
if ((err = grib_set_long_internal(h, self->time_range_unit, time_range_unit)))
|
||||
return err;
|
||||
time_range_value = time_range_v;
|
||||
}
|
||||
else
|
||||
time_range_value = (time_range_v * u2s[step_units]) / u2s2[time_range_unit];
|
||||
//if (time_range_v * u2s[step_units] % u2s2[time_range_unit]) {
|
||||
// time_range_unit = step_units;
|
||||
// if ((err = grib_set_long_internal(h, self->time_range_unit, time_range_unit)))
|
||||
// return err;
|
||||
// time_range_value = time_range_v;
|
||||
//}
|
||||
//else
|
||||
// time_range_value = (time_range_v * u2s[step_units]) / u2s2[time_range_unit];
|
||||
|
||||
|
||||
time_range_value = time_range_value * u2s[time_range_unit] / u2s2[step_units];
|
||||
time_range_unit = step_units;
|
||||
if ((err = grib_set_long_internal(h, self->time_range_value, time_range_value)))
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, self->time_range_unit, time_range_unit)))
|
||||
return err;
|
||||
//time_range_value = time_range_value * u2s[time_range_unit] / u2s2[step_units];
|
||||
//time_range_unit = step_units;
|
||||
//if ((err = grib_set_long_internal(h, self->time_range_value, time_range_value)))
|
||||
// return err;
|
||||
//if ((err = grib_set_long_internal(h, self->time_range_unit, time_range_unit)))
|
||||
// return err;
|
||||
|
||||
|
||||
|
||||
const char* forecast_time_value_key = "forecastTime";
|
||||
const char* forecast_time_unit_key = "indicatorOfUnitOfTimeRange";
|
||||
long forecast_time_value;
|
||||
long forecast_time_unit;
|
||||
if ((err = grib_get_long_internal(h, forecast_time_value_key, &forecast_time_value)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, forecast_time_unit_key, &forecast_time_unit)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
//long forecast_time_value;
|
||||
//long forecast_time_unit;
|
||||
//if ((err = grib_get_long_internal(h, forecast_time_value_key, &forecast_time_value)) != GRIB_SUCCESS)
|
||||
// return err;
|
||||
//if ((err = grib_get_long_internal(h, forecast_time_unit_key, &forecast_time_unit)) != GRIB_SUCCESS)
|
||||
// return err;
|
||||
|
||||
|
||||
//auto [forecast_time, time_range] = find_common_units(Step{forecast_time_value, forecast_time_unit}.optimize_unit(), Step{time_range_value, time_range_unit}.optimize_unit());
|
||||
auto [forecast_time, time_range] = find_common_units(Step{start_step_value, step_units}.optimize_unit(), Step{time_range_value, time_range_unit}.optimize_unit());
|
||||
//auto [forecast_time, time_range] = find_common_units(Step{start_step_value, step_units}.optimize_unit(), Step{time_range_value, time_range_unit}.optimize_unit());
|
||||
auto [forecast_time_opt, time_range_opt] = find_common_units(start_step, time_range);
|
||||
|
||||
if ((err = grib_set_long_internal(grib_handle_of_accessor(a), self->time_range_value, time_range.value<long>())) != GRIB_SUCCESS)
|
||||
if ((err = grib_set_long_internal(grib_handle_of_accessor(a), self->time_range_value, time_range_opt.value<long>())) != GRIB_SUCCESS)
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(grib_handle_of_accessor(a), self->time_range_unit, time_range.unit().to_long())) != GRIB_SUCCESS)
|
||||
if ((err = grib_set_long_internal(grib_handle_of_accessor(a), self->time_range_unit, time_range_opt.unit().to_long())) != GRIB_SUCCESS)
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(grib_handle_of_accessor(a), forecast_time_value_key, forecast_time.value<long>())) != GRIB_SUCCESS)
|
||||
if ((err = grib_set_long_internal(grib_handle_of_accessor(a), forecast_time_value_key, forecast_time_opt.value<long>())) != GRIB_SUCCESS)
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(grib_handle_of_accessor(a), forecast_time_unit_key, forecast_time.unit().to_long())) != GRIB_SUCCESS)
|
||||
if ((err = grib_set_long_internal(grib_handle_of_accessor(a), forecast_time_unit_key, forecast_time_opt.unit().to_long())) != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
|
||||
|
@ -552,6 +562,7 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
|||
}
|
||||
|
||||
|
||||
|
||||
static int unpack_string(grib_accessor* a, char* val, size_t* len)
|
||||
{
|
||||
grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
|
@ -573,16 +584,27 @@ static int unpack_string(grib_accessor* a, char* val, size_t* len)
|
|||
step.set_unit(step_units);
|
||||
|
||||
step.hide_hour_unit();
|
||||
//if (is_future_output_enabled(h)) {
|
||||
snprintf(val, *len, "%s", step.to_string().c_str());
|
||||
//}
|
||||
//else {
|
||||
// snprintf(val, *len, "%ld", step.value<long>());
|
||||
//}
|
||||
snprintf(val, *len, "%s", step.to_string().c_str());
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
||||
{
|
||||
grib_accessor_g2end_step* self = (grib_accessor_g2end_step*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret;
|
||||
|
||||
long end_step_unit;
|
||||
if ((ret = grib_get_long_internal(h, "endStepUnit", &end_step_unit)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if (end_step_unit == 255)
|
||||
end_step_unit = UnitType{Unit::HOUR}.to_long();
|
||||
|
||||
return pack_long_(a, *val, end_step_unit);
|
||||
}
|
||||
|
||||
|
||||
static int pack_string(grib_accessor* a, const char* val, size_t* len)
|
||||
{
|
||||
|
@ -591,13 +613,11 @@ static int pack_string(grib_accessor* a, const char* val, size_t* len)
|
|||
int ret = 0;
|
||||
Step end_step = step_from_string(val);
|
||||
end_step.optimize_unit();
|
||||
if ((ret = grib_set_long_internal(h, self->step_units, end_step.unit().to_long())) != GRIB_SUCCESS)
|
||||
|
||||
if ((ret = grib_set_long_internal(h, "endStepUnit", end_step.unit().to_long())) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
long end_step_value = end_step.value<long>();
|
||||
size_t end_step_len = 0;
|
||||
|
||||
if ((ret = pack_long(a, &end_step_value, &end_step_len)) != GRIB_SUCCESS)
|
||||
if ((ret = pack_long_(a, end_step.value<long>(), end_step.unit().to_long())) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -140,25 +140,28 @@ static int unpack_string(grib_accessor* a, char* val, size_t* len)
|
|||
char buf[100];
|
||||
int ret = 0;
|
||||
size_t size = 0;
|
||||
long end_start_value = 0;
|
||||
long start_step_value = 0;
|
||||
long end_step_value = 0;
|
||||
long step_units = 0;
|
||||
long step_units;
|
||||
|
||||
if ((ret = grib_get_long_internal(h, self->start_step, &end_start_value)) != GRIB_SUCCESS)
|
||||
if ((ret = grib_get_long_internal(h, self->start_step, &start_step_value)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
//if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
step_units = get_step_units(h);
|
||||
if ((ret= grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
if (step_units == 255) {
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Step start_step{end_start_value, step_units};
|
||||
Step start_step{start_step_value, step_units};
|
||||
start_step.hide_hour_unit();
|
||||
if (self->end_step == NULL) {
|
||||
//if (is_future_output_enabled(h)) {
|
||||
snprintf(buf, sizeof(buf), "%s", start_step.to_string().c_str());
|
||||
//}
|
||||
//else {
|
||||
// snprintf(buf, sizeof(buf), "%ld", end_start_value);
|
||||
// snprintf(buf, sizeof(buf), "%ld", start_step_value);
|
||||
//}
|
||||
}
|
||||
else {
|
||||
|
@ -168,7 +171,7 @@ static int unpack_string(grib_accessor* a, char* val, size_t* len)
|
|||
//if (is_future_output_enabled(h)) {
|
||||
Step end_step{end_step_value, step_units};
|
||||
end_step.hide_hour_unit();
|
||||
if (end_start_value == end_step_value) {
|
||||
if (start_step_value == end_step_value) {
|
||||
snprintf(buf, sizeof(buf), "%s", end_step.to_string().c_str());
|
||||
}
|
||||
else {
|
||||
|
@ -176,11 +179,11 @@ static int unpack_string(grib_accessor* a, char* val, size_t* len)
|
|||
}
|
||||
//}
|
||||
//else {
|
||||
// if (end_start_value == end_step_value) {
|
||||
// if (start_step_value == end_step_value) {
|
||||
// snprintf(buf, sizeof(buf), "%ld", end_step_value);
|
||||
// }
|
||||
// else {
|
||||
// snprintf(buf, sizeof(buf), "%ld-%ld", end_start_value, end_step_value);
|
||||
// snprintf(buf, sizeof(buf), "%ld-%ld", start_step_value, end_step_value);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
@ -199,33 +202,33 @@ static int unpack_string(grib_accessor* a, char* val, size_t* len)
|
|||
}
|
||||
|
||||
|
||||
static int pack_string_old(grib_accessor* a, const char* val, size_t* len)
|
||||
{
|
||||
grib_accessor_g2step_range* self = (grib_accessor_g2step_range*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret = 0;
|
||||
//static int pack_string_old(grib_accessor* a, const char* val, size_t* len)
|
||||
//{
|
||||
// grib_accessor_g2step_range* self = (grib_accessor_g2step_range*)a;
|
||||
// grib_handle* h = grib_handle_of_accessor(a);
|
||||
// int ret = 0;
|
||||
|
||||
std::vector<Step> steps = parse_range(val);
|
||||
if (steps.size() == 0)
|
||||
return GRIB_INVALID_ARGUMENT;
|
||||
// std::vector<Step> steps = parse_range(val);
|
||||
// if (steps.size() == 0)
|
||||
// return GRIB_INVALID_ARGUMENT;
|
||||
|
||||
Step step_0 = steps[0];
|
||||
Step step_1;
|
||||
if (steps.size() > 1) {
|
||||
std::tie(step_0, step_1) = find_common_units(steps[0].optimize_unit(), steps[1].optimize_unit());
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", step_0.unit().to_long())))
|
||||
return ret;
|
||||
}
|
||||
// Step step_0 = steps[0];
|
||||
// Step step_1;
|
||||
// if (steps.size() > 1) {
|
||||
// std::tie(step_0, step_1) = find_common_units(steps[0].optimize_unit(), steps[1].optimize_unit());
|
||||
// if ((ret = grib_set_long_internal(h, "stepUnits", step_0.unit().to_long())))
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
if ((ret = grib_set_long_internal(h, self->start_step, step_0.value<long>())))
|
||||
return ret;
|
||||
// if ((ret = grib_set_long_internal(h, self->start_step, step_0.value<long>())))
|
||||
// return ret;
|
||||
|
||||
if ((self->end_step != NULL) && (steps.size() > 1)) {
|
||||
if ((ret = grib_set_long_internal(h, self->end_step, step_1.value<long>())))
|
||||
return ret;
|
||||
}
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
// if ((self->end_step != NULL) && (steps.size() > 1)) {
|
||||
// if ((ret = grib_set_long_internal(h, self->end_step, step_1.value<long>())))
|
||||
// return ret;
|
||||
// }
|
||||
// return GRIB_SUCCESS;
|
||||
//}
|
||||
|
||||
|
||||
static int pack_string_new(grib_accessor* a, const char* val, size_t* len)
|
||||
|
@ -242,16 +245,16 @@ static int pack_string_new(grib_accessor* a, const char* val, size_t* len)
|
|||
Step step_1;
|
||||
if (steps.size() > 1) {
|
||||
std::tie(step_0, step_1) = find_common_units(steps[0].optimize_unit(), steps[1].optimize_unit());
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", step_0.unit().to_long())))
|
||||
return ret;
|
||||
}
|
||||
|
||||
//if ((ret = grib_set_long_internal(h, self->start_step, step_0.value<long>())))
|
||||
// return ret;
|
||||
if ((ret = grib_set_long_internal(h, "startStepUnit", step_0.unit().to_long())))
|
||||
return ret;
|
||||
if ((ret = set_step(h, "forecastTime" , "indicatorOfUnitOfTimeRange", step_0)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if ((self->end_step != NULL) && (steps.size() > 1)) {
|
||||
if ((ret = grib_set_long_internal(h, "endStepUnit", step_1.unit().to_long())))
|
||||
return ret;
|
||||
if ((ret = grib_set_long_internal(h, self->end_step, step_1.value<long>())))
|
||||
return ret;
|
||||
}
|
||||
|
@ -260,13 +263,7 @@ static int pack_string_new(grib_accessor* a, const char* val, size_t* len)
|
|||
|
||||
static int pack_string(grib_accessor* a, const char* val, size_t* len)
|
||||
{
|
||||
//grib_handle* h = grib_handle_of_accessor(a);
|
||||
//if (is_future_output_enabled(h)) {
|
||||
return pack_string_new(a, val, len);
|
||||
//}
|
||||
//else {
|
||||
// return pack_string_old(a, val, len);
|
||||
//}
|
||||
return pack_string_new(a, val, len);
|
||||
}
|
||||
|
||||
static int value_count(grib_accessor* a, long* count)
|
||||
|
@ -301,9 +298,12 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
|||
|
||||
if ((ret = grib_get_long_internal(h, self->start_step, &end_start_value)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
//if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
step_units = get_step_units(h);
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
throw std::runtime_error("Failed to get stepUnits");
|
||||
if (step_units == 255) {
|
||||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
}
|
||||
|
||||
Step start_step{end_start_value, step_units};
|
||||
start_step.hide_hour_unit();
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
START_CLASS_DEF
|
||||
CLASS = accessor
|
||||
SUPER = grib_accessor_class_gen
|
||||
IMPLEMENTS = unpack_long;dump
|
||||
IMPLEMENTS = unpack_string;dump
|
||||
IMPLEMENTS = pack_long,unpack_long;dump
|
||||
IMPLEMENTS = unpack_string,unpack_string;dump
|
||||
IMPLEMENTS = string_length
|
||||
IMPLEMENTS = init
|
||||
MEMBERS = const char* forecast_time_value
|
||||
|
@ -84,13 +84,13 @@ static grib_accessor_class _grib_accessor_class_optimal_step_units = {
|
|||
0, /* get sub_section */
|
||||
0, /* pack_missing */
|
||||
0, /* is_missing */
|
||||
0, /* pack_long */
|
||||
&pack_long, /* pack_long */
|
||||
&unpack_long, /* unpack_long */
|
||||
0, /* pack_double */
|
||||
0, /* pack_float */
|
||||
0, /* unpack_double */
|
||||
0, /* unpack_float */
|
||||
0, /* pack_string */
|
||||
&pack_string, /* pack_string */
|
||||
&unpack_string, /* unpack_string */
|
||||
0, /* pack_string_array */
|
||||
0, /* unpack_string_array */
|
||||
|
@ -150,44 +150,48 @@ static size_t string_length(grib_accessor* a)
|
|||
|
||||
static long staticStepUnits = UnitType{Unit::MISSING}.to_long();
|
||||
|
||||
//static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
||||
//{
|
||||
// staticStepUnits = *val;
|
||||
static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
||||
{
|
||||
staticStepUnits = *val;
|
||||
|
||||
// return GRIB_SUCCESS;
|
||||
//}
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
||||
{
|
||||
//if (staticStepUnits != 255) {
|
||||
// *val = staticStepUnits;
|
||||
// return GRIB_SUCCESS;
|
||||
//}
|
||||
if (staticStepUnits != 255) {
|
||||
*val = staticStepUnits;
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
grib_accessor_optimal_step_units* self = (grib_accessor_optimal_step_units*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
|
||||
auto forecast_time_opt = get_step(h, self->forecast_time_value, self->forecast_time_unit);
|
||||
auto time_range_opt = get_step(h, self->time_range_value, self->time_range_unit);
|
||||
|
||||
if (!(forecast_time_opt && time_range_opt)) {
|
||||
if (forecast_time_opt && time_range_opt) {
|
||||
auto [step_a, step_b] = find_common_units(forecast_time_opt.value().optimize_unit(), (forecast_time_opt.value() + time_range_opt.value()).optimize_unit());
|
||||
*val = step_a.unit().to_long();
|
||||
}
|
||||
else if (forecast_time_opt && !time_range_opt) {
|
||||
*val = forecast_time_opt.value().optimize_unit().unit().to_long();
|
||||
}
|
||||
else if (!forecast_time_opt && time_range_opt) {
|
||||
*val = time_range_opt.value().optimize_unit().unit().to_long();
|
||||
}
|
||||
else if (!forecast_time_opt && !time_range_opt) {
|
||||
*val = UnitType{Unit::HOUR}.to_long();
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
Step forecast_time = forecast_time_opt.value_or(Step{});
|
||||
Step time_range = time_range_opt.value_or(Step{});
|
||||
|
||||
auto [step_a, step_b] = find_common_units(forecast_time.optimize_unit(), (forecast_time + time_range).optimize_unit());
|
||||
*val = step_a.unit().to_long();
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
//static int pack_string(grib_accessor* a, const char* val, size_t* len)
|
||||
//{
|
||||
// staticStepUnits = UnitType{val}.to_long();
|
||||
// return GRIB_SUCCESS;
|
||||
//}
|
||||
static int pack_string(grib_accessor* a, const char* val, size_t* len)
|
||||
{
|
||||
staticStepUnits = UnitType{val}.to_long();
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
static int unpack_string(grib_accessor* a, char* val, size_t* len)
|
||||
{
|
||||
|
|
|
@ -181,40 +181,19 @@ static int unpack_long(grib_accessor* a, long* val, size_t* len)
|
|||
int factor = 0;
|
||||
long u2sf, u2sf_step_unit;
|
||||
|
||||
|
||||
if ((err= grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, self->forecast_time_unit, &forecast_time_unit)))
|
||||
return err;
|
||||
//if ((err = grib_get_long_internal(h, self->step_units, &step_units)))
|
||||
// return err;
|
||||
step_units = get_step_units(h);
|
||||
if ((err = grib_get_long_internal(h, self->forecast_time_value, &forecast_time_value)))
|
||||
return err;
|
||||
|
||||
if (step_units != forecast_time_unit) {
|
||||
*val = forecast_time_value * u2s2[forecast_time_unit];
|
||||
if (*val < 0) {
|
||||
factor = 60;
|
||||
if (u2s2[forecast_time_unit] % factor)
|
||||
return GRIB_DECODING_ERROR;
|
||||
if (u2s[step_units] % factor)
|
||||
return GRIB_DECODING_ERROR;
|
||||
u2sf = u2s2[forecast_time_unit] / factor;
|
||||
*val = forecast_time_value * u2sf;
|
||||
u2sf_step_unit = u2s[step_units] / factor;
|
||||
}
|
||||
else {
|
||||
u2sf_step_unit = u2s[step_units];
|
||||
}
|
||||
Step step{forecast_time_value, forecast_time_unit};
|
||||
|
||||
if (*val % u2sf_step_unit != 0) {
|
||||
err = grib_set_long_internal(h, self->step_units, forecast_time_unit);
|
||||
*val = forecast_time_value;
|
||||
return err;
|
||||
}
|
||||
*val = *val / u2sf_step_unit;
|
||||
}
|
||||
else
|
||||
*val = forecast_time_value;
|
||||
if ((err = grib_set_long_internal(h, "startStepUnit", UnitType{step_units}.to_long())) != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
*val = step.value<long>(UnitType{step_units});
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
@ -273,26 +252,31 @@ int pack_long_old_(grib_accessor* a, const long* val, size_t* len) {
|
|||
return grib_set_long_internal(grib_handle_of_accessor(a), self->forecast_time_value, forecast_time_value);
|
||||
}
|
||||
|
||||
int pack_long_new_(grib_accessor* a, const long* val, size_t* len) {
|
||||
int pack_long_new_(grib_accessor* a, const long start_step_value, const long start_step_unit) {
|
||||
grib_accessor_step_in_units* self = (grib_accessor_step_in_units*)a;
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int err = 0;
|
||||
//long forecast_time_value;
|
||||
long forecast_time_unit;
|
||||
long step_units;
|
||||
long start_step_value_old= 0;
|
||||
long start_step_value_old;
|
||||
long start_step_unit_old;
|
||||
size_t len = 0;
|
||||
//long time_range_unit;
|
||||
//long time_range_value;
|
||||
|
||||
if ((err = grib_get_long_internal(h, self->forecast_time_unit, &forecast_time_unit)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
if ((err = unpack_long(a, &start_step_value_old, len)) != GRIB_SUCCESS)
|
||||
if ((err = unpack_long(a, &start_step_value_old, &len)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
if ((err = grib_get_long_internal(h, "startStepUnit", &start_step_unit_old)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
//if ((err = grib_get_long_internal(h, self->step_units, &step_units)) != GRIB_SUCCESS)
|
||||
//return err;
|
||||
step_units = get_step_units(h);
|
||||
Step start_step_old(start_step_value_old, step_units);
|
||||
Step forecast_time(*val, step_units);
|
||||
//step_units = get_step_units(h);
|
||||
Step start_step_old(start_step_value_old, start_step_unit_old);
|
||||
Step forecast_time(start_step_value, start_step_unit);
|
||||
Step time_range_new{};
|
||||
|
||||
auto time_range_opt = get_step(h, self->time_range_value, self->time_range_unit);
|
||||
|
@ -302,12 +286,16 @@ int pack_long_new_(grib_accessor* a, const long* val, size_t* len) {
|
|||
auto [sa, sb] = find_common_units(forecast_time.optimize_unit(), time_range.optimize_unit());
|
||||
if ((err = set_step(h, self->forecast_time_value, self->forecast_time_unit, sa)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
if ((err = grib_set_long_internal(h, "startStepUnit", forecast_time.unit().to_long())) != GRIB_SUCCESS)
|
||||
return err;
|
||||
if ((err = set_step(h, self->time_range_value, self->time_range_unit, sb)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
return GRIB_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
forecast_time.optimize_unit();
|
||||
if ((err = grib_set_long_internal(h, "startStepUnit", forecast_time.unit().to_long())) != GRIB_SUCCESS)
|
||||
return err;
|
||||
if ((err = set_step(h, self->forecast_time_value, self->forecast_time_unit, forecast_time)) != GRIB_SUCCESS)
|
||||
return err;
|
||||
|
||||
|
@ -318,12 +306,17 @@ static int pack_long(grib_accessor* a, const long* val, size_t* len)
|
|||
{
|
||||
grib_handle* h = grib_handle_of_accessor(a);
|
||||
int ret;
|
||||
//if (is_future_output_enabled(h)) {
|
||||
ret = pack_long_new_(a, val, len);
|
||||
//}
|
||||
//else {
|
||||
// ret = pack_long_old_(a, val, len);
|
||||
//}
|
||||
//long step_units = UnitType{Unit::HOUR}.to_long();
|
||||
|
||||
|
||||
long start_step_unit;
|
||||
if ((ret = grib_get_long_internal(h, "startStepUnit", &start_step_unit)) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if (start_step_unit == 255)
|
||||
start_step_unit = UnitType{Unit::HOUR}.to_long();
|
||||
|
||||
ret = pack_long_new_(a, *val, start_step_unit);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -336,16 +329,8 @@ static int pack_string(grib_accessor* a, const char* val, size_t* len)
|
|||
size_t value_len = 0;
|
||||
|
||||
Step step = step_from_string(val);
|
||||
long step_units;
|
||||
//if ((ret = grib_get_long_internal(h, self->step_units, &step_units)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
step_units = get_step_units(h);
|
||||
|
||||
long value = step.value<long>();
|
||||
|
||||
if ((ret = grib_set_long_internal(h, "stepUnits", step.unit().to_long())) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
if ((ret = pack_long(a, &value, &value_len)) != GRIB_SUCCESS)
|
||||
if ((ret = pack_long_new_(a, step.value<long>(), step.unit().to_long())) != GRIB_SUCCESS)
|
||||
return ret;
|
||||
|
||||
return GRIB_SUCCESS;
|
||||
|
@ -362,8 +347,6 @@ static int unpack_string(grib_accessor* a, char* val, size_t* len)
|
|||
return ret;
|
||||
|
||||
long step_units;
|
||||
//if ((ret = grib_get_long_internal(h, self->step_units, &step_units)) != GRIB_SUCCESS)
|
||||
// return ret;
|
||||
step_units = get_step_units(h);
|
||||
|
||||
Step step{value, step_units};
|
||||
|
|
|
@ -114,7 +114,6 @@ Step Step::operator-(const Step& step) const
|
|||
}
|
||||
|
||||
|
||||
//std::pair<Step, Step> find_common_units(const Step& startStep, const Step& endStep)
|
||||
std::pair<Step, Step> find_common_units(const Step& startStep, const Step& endStep)
|
||||
{
|
||||
Step a = startStep;
|
||||
|
@ -140,7 +139,6 @@ std::pair<Step, Step> find_common_units(const Step& startStep, const Step& endSt
|
|||
b.recalculateValue();
|
||||
}
|
||||
else {
|
||||
// Find the highest common unit
|
||||
auto it = std::find_if(UnitType::unit_order_.begin(), UnitType::unit_order_.end(), [&](const auto& e) {
|
||||
return e == a.unit().to_value() || e == b.unit().to_value();
|
||||
});
|
||||
|
|
|
@ -47,9 +47,9 @@ long get_step_units(grib_handle* h)
|
|||
if ((ret = grib_get_long_internal(h, "stepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
throw std::runtime_error("Failed to get stepUnits");
|
||||
|
||||
if (step_units == 255) {
|
||||
if((ret = grib_get_long_internal(h, "optimalStepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
throw std::runtime_error("Failed to get optimalStepUnits");
|
||||
}
|
||||
//if (step_units == 255) {
|
||||
// if((ret = grib_get_long_internal(h, "optimalStepUnits", &step_units)) != GRIB_SUCCESS)
|
||||
// throw std::runtime_error("Failed to get optimalStepUnits");
|
||||
//}
|
||||
return step_units;
|
||||
}
|
||||
|
|
|
@ -8,26 +8,3 @@ std::optional<Step> get_step(grib_handle* h, const std::string& value_key, const
|
|||
bool is_future_output_enabled(grib_handle* h);
|
||||
int set_step(grib_handle* h, const std::string& value_key, const std::string& unit_key, const Step& step);
|
||||
long get_step_units(grib_handle* h);
|
||||
|
||||
//template <typename T>
|
||||
//int set_step(grib_handle* h, const std::string& value_key, const std::string& unit_key, const Step& step)
|
||||
//{
|
||||
// int err;
|
||||
// if constexpr (std::is_same_v<T, long>) {
|
||||
// if ((err = grib_set_long_internal(h, value_key.c_str(), step.value<T>())) != GRIB_SUCCESS)
|
||||
// return err;
|
||||
// }
|
||||
// else if constexpr (std::is_same_v<T, double>) {
|
||||
// if ((err = grib_set_double_internal(h, value_key.c_str(), step.value<T>())) != GRIB_SUCCESS)
|
||||
// return err;
|
||||
// }
|
||||
// else {
|
||||
// return GRIB_NOT_IMPLEMENTED;
|
||||
// }
|
||||
|
||||
// if ((err = grib_set_long_internal(h, unit_key.c_str(), step.unit().to_long())) != GRIB_SUCCESS)
|
||||
// return err;
|
||||
// return GRIB_SUCCESS;
|
||||
//}
|
||||
|
||||
|
||||
|
|
|
@ -146,102 +146,102 @@ grib_check_key_equals $temp2 "-p stepRange:s" "1488-2928"
|
|||
|
||||
fn="${data_dir}/reduced_gaussian_surface.grib2"
|
||||
low_level_keys="forecastTime,indicatorOfUnitOfTimeRange:s"
|
||||
keys__="step"
|
||||
keys__="step,stepUnits:s"
|
||||
keys_s="step:s"
|
||||
keys_i="step:i"
|
||||
keys_d="step:d"
|
||||
keys_i="step:i,stepUnits:s"
|
||||
keys_d="step:d,stepUnits:s"
|
||||
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=59,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
grib_check_key_equals $temp "-p $keys__ -s stepUnits=s" "3540"
|
||||
grib_check_key_equals $temp "-p $keys__ -s stepUnits=m" "59"
|
||||
grib_check_key_equals $temp "-p $keys__ -s stepUnits=s" "3540 s"
|
||||
grib_check_key_equals $temp "-p $keys__ -s stepUnits=m" "59 m"
|
||||
#grib_check_key_equals $temp "-p $keys__ -s stepUnits=h" "0" # TODO(EB): check behaviour (should be 0.983333)
|
||||
grib_check_key_equals $temp "-p $keys_s -s stepUnits=s" "3540s"
|
||||
grib_check_key_equals $temp "-p $keys_s -s stepUnits=m" "59m"
|
||||
#grib_check_key_equals $temp "-p $keys_s -F"%.2f" -s stepUnits=h" "0.983333" # TODO(EB): check behaviour // See tools for default output format
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=s" "3540"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=m" "59"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=s" "3540 s"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=m" "59 m"
|
||||
#grib_check_key_equals $temp "-p $keys_i -s stepUnits=h" "0" # TODO(EB): check behaviour
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=s" "3540"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=m" "59"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=s" "3540 s"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=m" "59 m"
|
||||
#grib_check_key_equals $temp "-p $keys_d -s stepUnits=h" "0.983333" # TODO(EB): check behaviour
|
||||
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=0,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=s" "0"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=m" "0"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=h" "0"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=s" "0"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=m" "0"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=h" "0"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=s" "0 s"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=m" "0 m"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=h" "0 h"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=s" "0 s"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=m" "0 m"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=h" "0 h"
|
||||
|
||||
|
||||
|
||||
fn="${data_dir}/reduced_gaussian_surface.grib2"
|
||||
low_level_keys="forecastTime,indicatorOfUnitOfTimeRange:s"
|
||||
keys__="step"
|
||||
keys_s="step:s"
|
||||
keys_i="step:i"
|
||||
keys_d="step:d"
|
||||
keys__="step,stepUnits:s"
|
||||
keys_s="step:s,stepUnits:s"
|
||||
keys_i="step:i,stepUnits:s"
|
||||
keys_d="step:d,stepUnits:s"
|
||||
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=0,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
grib_check_key_equals $temp "-p $low_level_keys" "0 m"
|
||||
grib_check_key_equals $temp "-p $keys__" "0"
|
||||
grib_check_key_equals $temp "-p $keys_s" "0"
|
||||
grib_check_key_equals $temp "-p $keys_i" "0"
|
||||
grib_check_key_equals $temp "-p $keys_d" "0"
|
||||
grib_check_key_equals $temp "-p $keys__" "0 m"
|
||||
grib_check_key_equals $temp "-p $keys_s" "0m m"
|
||||
grib_check_key_equals $temp "-p $keys_i" "0 m"
|
||||
grib_check_key_equals $temp "-p $keys_d" "0 m"
|
||||
|
||||
grib_check_key_equals $temp "-p $keys__ -s stepUnits=s" "0"
|
||||
grib_check_key_equals $temp "-p $keys__ -s stepUnits=m" "0"
|
||||
grib_check_key_equals $temp "-p $keys__ -s stepUnits=h" "0"
|
||||
grib_check_key_equals $temp "-p $keys_s -s stepUnits=s" "0s"
|
||||
grib_check_key_equals $temp "-p $keys_s -s stepUnits=m" "0m"
|
||||
grib_check_key_equals $temp "-p $keys_s -s stepUnits=h" "0"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=s" "0"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=m" "0"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=h" "0"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=s" "0"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=m" "0"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=h" "0"
|
||||
grib_check_key_equals $temp "-p $keys__ -s stepUnits=s" "0 s"
|
||||
grib_check_key_equals $temp "-p $keys__ -s stepUnits=m" "0 m"
|
||||
grib_check_key_equals $temp "-p $keys__ -s stepUnits=h" "0 h"
|
||||
grib_check_key_equals $temp "-p $keys_s -s stepUnits=s" "0s s"
|
||||
grib_check_key_equals $temp "-p $keys_s -s stepUnits=m" "0m m"
|
||||
grib_check_key_equals $temp "-p $keys_s -s stepUnits=h" "0 h"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=s" "0 s"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=m" "0 m"
|
||||
grib_check_key_equals $temp "-p $keys_i -s stepUnits=h" "0 h"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=s" "0 s"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=m" "0 m"
|
||||
grib_check_key_equals $temp "-p $keys_d -s stepUnits=h" "0 h"
|
||||
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=59,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
grib_check_key_equals $temp "-p $low_level_keys" "59 m"
|
||||
grib_check_key_equals $temp "-p $keys__" "59"
|
||||
grib_check_key_equals $temp "-p $keys__" "59 m"
|
||||
#grib_check_key_equals $temp "-p $keys_s" "59"
|
||||
grib_check_key_equals $temp "-p $keys_s" "59m"
|
||||
grib_check_key_equals $temp "-p $keys_i" "59"
|
||||
grib_check_key_equals $temp "-p $keys_d" "59"
|
||||
grib_check_key_equals $temp "-p $keys_s" "59m m"
|
||||
grib_check_key_equals $temp "-p $keys_i" "59 m"
|
||||
grib_check_key_equals $temp "-p $keys_d" "59 m"
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=60,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
grib_check_key_equals $temp "-p $low_level_keys" "60 m"
|
||||
grib_check_key_equals $temp "-p $keys__" "1"
|
||||
grib_check_key_equals $temp "-p $keys_s" "1"
|
||||
grib_check_key_equals $temp "-p $keys_i" "1"
|
||||
grib_check_key_equals $temp "-p $keys_d" "1"
|
||||
grib_check_key_equals $temp "-p $keys__" "1 h"
|
||||
grib_check_key_equals $temp "-p $keys_s" "1 h"
|
||||
grib_check_key_equals $temp "-p $keys_i" "1 h"
|
||||
grib_check_key_equals $temp "-p $keys_d" "1 h"
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=61,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
grib_check_key_equals $temp "-p $low_level_keys" "61 m"
|
||||
grib_check_key_equals $temp "-p $keys__" "61"
|
||||
grib_check_key_equals $temp "-p $keys__" "61 m"
|
||||
#grib_check_key_equals $temp "-p $keys_s" "61"
|
||||
grib_check_key_equals $temp "-p $keys_s" "61m"
|
||||
grib_check_key_equals $temp "-p $keys_i" "61"
|
||||
grib_check_key_equals $temp "-p $keys_d" "61"
|
||||
grib_check_key_equals $temp "-p $keys_s" "61m m"
|
||||
grib_check_key_equals $temp "-p $keys_i" "61 m"
|
||||
grib_check_key_equals $temp "-p $keys_d" "61 m"
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=24,indicatorOfUnitOfTimeRange=h $fn $temp
|
||||
grib_check_key_equals $temp "-p $low_level_keys" "24 h"
|
||||
grib_check_key_equals $temp "-p $keys__" "24"
|
||||
grib_check_key_equals $temp "-p $keys_s" "24"
|
||||
grib_check_key_equals $temp "-p $keys_i" "24"
|
||||
grib_check_key_equals $temp "-p $keys_d" "24"
|
||||
grib_check_key_equals $temp "-p $keys__" "24 h"
|
||||
grib_check_key_equals $temp "-p $keys_s" "24 h"
|
||||
grib_check_key_equals $temp "-p $keys_i" "24 h"
|
||||
grib_check_key_equals $temp "-p $keys_d" "24 h"
|
||||
|
||||
${tools_dir}/grib_set -s forecastTime=1440,indicatorOfUnitOfTimeRange=m $fn $temp
|
||||
grib_check_key_equals $temp "-p $low_level_keys" "1440 m"
|
||||
grib_check_key_equals $temp "-p $keys__" "24"
|
||||
grib_check_key_equals $temp "-p $keys_s" "24"
|
||||
grib_check_key_equals $temp "-p $keys_i" "24"
|
||||
grib_check_key_equals $temp "-p $keys_d" "24"
|
||||
grib_check_key_equals $temp "-p $keys__" "24 h"
|
||||
grib_check_key_equals $temp "-p $keys_s" "24 h"
|
||||
grib_check_key_equals $temp "-p $keys_i" "24 h"
|
||||
grib_check_key_equals $temp "-p $keys_d" "24 h"
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue