ECC-1698: Add format specifier keys for converting a number (float or int) into a string

This commit is contained in:
Shahram Najm 2023-10-03 15:20:52 +00:00
parent 98df806ed0
commit 3a1ea5a54b
5 changed files with 65 additions and 10 deletions

View File

@ -52,6 +52,9 @@ transient unitsFactor=1 : hidden;
transient unitsBias=0 : hidden;
constant globalDomain = "g";
transient timeRangeIndicatorFromStepRange=-1 : hidden;
# Format specifiers for converting a number (float or int) into a string
transient formatForDoubles = "%g" : no_copy,hidden;
transient formatForLongs = "%ld" : no_copy,hidden;
# ECC-868
transient produceLargeConstantFields = 0 : hidden;

View File

@ -8,10 +8,6 @@
* virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
*/
/************************************************
* Enrico Fucile
***********************************************/
#include "grib_api_internal.h"
/*
This is used by make_class.pl
@ -115,13 +111,18 @@ static int unpack_string(grib_accessor* a, char* v, size_t* len)
double val = 0;
size_t l = 1;
char repres[1024];
char format[32] = "%g";
grib_handle* h = grib_handle_of_accessor(a);
grib_unpack_double(a, &val, &l);
if ((val == GRIB_MISSING_DOUBLE) && ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0))
if ((val == GRIB_MISSING_DOUBLE) && ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0)) {
snprintf(repres, sizeof(repres), "MISSING");
else
snprintf(repres, sizeof(repres), "%g", val);
} else {
size_t size = sizeof(format);
grib_get_string(h, "formatForDoubles", format, &size);
snprintf(repres, sizeof(repres), format, val);
}
l = strlen(repres) + 1;

View File

@ -120,6 +120,8 @@ static int unpack_string(grib_accessor* a, char* v, size_t* len)
long val = 0;
size_t l = 1;
char repres[1024];
char format[32] = "%ld";
grib_handle* h = grib_handle_of_accessor(a);
err = grib_unpack_long(a, &val, &l);
/* TODO: We should catch all errors but in this case the test ERA_Gen.sh will fail
@ -127,10 +129,13 @@ static int unpack_string(grib_accessor* a, char* v, size_t* len)
/* if (err) return err; */
(void)err;
if ((val == GRIB_MISSING_LONG) && ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0))
if ((val == GRIB_MISSING_LONG) && ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0)) {
snprintf(repres, sizeof(repres), "MISSING");
else
snprintf(repres, sizeof(repres), "%ld", val);
} else {
size_t size = sizeof(format);
grib_get_string(h, "formatForLongs", format, &size);
snprintf(repres, sizeof(repres), format, val);
}
l = strlen(repres) + 1;

View File

@ -236,6 +236,7 @@ if( HAVE_BUILD_TOOLS )
grib_set_bytes
grib_set_force
bufr_ecc-556
codes_ecc-1698
gts_get
gts_ls
gts_count

45
tests/codes_ecc-1698.sh Executable file
View File

@ -0,0 +1,45 @@
#!/bin/sh
# (C) Copyright 2005- ECMWF.
#
# This software is licensed under the terms of the Apache Licence Version 2.0
# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
#
# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
#
. ./include.ctest.sh
REDIRECT=/dev/null
label="codes_ecc-1698_test"
tempGrib=temp.$label.grib
tempBufr=temp.$label.bufr
tempFilt=temp.$label.filt
tempLog=temp.$label.log
tempRef=temp.$label.ref
sample_grib2=$ECCODES_SAMPLES_PATH/GRIB2.tmpl
sample_bufr4=$ECCODES_SAMPLES_PATH/BUFR4.tmpl
# Double to string
# ------------------
infile=$sample_grib2
result=$(${tools_dir}/grib_get -p maximum:s $infile)
[ "$result" = "1" ]
result=$(${tools_dir}/grib_get -s formatForDoubles=%e -p maximum:s $infile)
[ "$result" = "1.000000e+00" ]
infile=${data_dir}/sample.grib2
result=$(${tools_dir}/grib_get -s formatForDoubles=%e -p minimum:s $infile)
[ "$result" = "2.704668e+02" ]
# Integer to string
# ------------------
infile=${data_dir}/sample.grib2
result=$(${tools_dir}/grib_get -s formatForLongs=%lX -p year:s $infile)
[ "$result" = "7D8" ]
rm -f $tempGrib $tempBufr $tempFilt $tempLog $tempRef