ECC-1126: BUFR: ECMWF Local use section key 'ident' should be trimmed (Part 1)

This commit is contained in:
Shahram Najm 2020-06-26 19:37:53 +01:00
parent 41f44aa18a
commit 8e8a5eb2b8
12 changed files with 724 additions and 466 deletions

View File

@ -82,8 +82,9 @@ if (section2Present && bufrHeaderCentre==98 && section2Length==52) {
} else {
meta ls.localLatitude bits(keyData,72,25,-9000000,100000) : dump,no_copy;
meta ls.localLongitude bits(keyData,40,26,-18000000,100000) : dump,no_copy;
meta mars.ident sprintf("%s", keyMore) : string_type, no_copy;
alias ls.ident=keyMore : dump,string_type,no_copy;
meta identTrimmed trim(keyMore,1,1): no_copy, hidden;
meta mars.ident sprintf("%s", identTrimmed) : string_type, no_copy;
alias ls.ident=identTrimmed : dump,string_type,no_copy;
}
}

View File

@ -184,6 +184,7 @@ list( APPEND grib_api_srcs
grib_accessor_class_spectral_truncation.c
grib_accessor_class_time.c
grib_accessor_class_transient.c
grib_accessor_class_trim.c
grib_accessor_class_transient_darray.c
grib_accessor_class_values.c
grib_accessor_class_simple_packing_error.c

View File

@ -201,6 +201,7 @@ libeccodes_la_prototypes= \
grib_accessor_class_spectral_truncation.c \
grib_accessor_class_time.c \
grib_accessor_class_transient.c \
grib_accessor_class_trim.c \
grib_accessor_class_values.c \
grib_accessor_class_simple_packing_error.c \
grib_accessor_class_data_simple_packing.c \

View File

@ -261,7 +261,7 @@ static int bufr_decode_extra_rdb_keys(const void* message, long offset_section2,
}
}
else {
size_t i = 0;
size_t i = 0, j = 0;
long lValue = 0;
start = 72;
lValue = (long)grib_decode_unsigned_long(pKeyData, &start, 25);
@ -272,9 +272,15 @@ static int bufr_decode_extra_rdb_keys(const void* message, long offset_section2,
/* interpret keyMore as a string */
for (i = 0; i < 8; ++i) {
hdr->ident[i] = *pKeyMore++;
const char c = *pKeyMore;
//printf("Lookin at %c, i=%lu, j=%lu\n", c, i, j);
if (c != ' ') {
//printf(" not space so copy to %lu\n", j);
hdr->ident[j++] = c;
}
pKeyMore++;
}
hdr->ident[i] = '\0';
hdr->ident[j] = '\0';
}
return GRIB_SUCCESS;

View File

@ -208,6 +208,7 @@ extern grib_accessor_class* grib_accessor_class_to_integer;
extern grib_accessor_class* grib_accessor_class_to_string;
extern grib_accessor_class* grib_accessor_class_transient;
extern grib_accessor_class* grib_accessor_class_transient_darray;
extern grib_accessor_class* grib_accessor_class_trim;
extern grib_accessor_class* grib_accessor_class_uint16;
extern grib_accessor_class* grib_accessor_class_uint16_little_endian;
extern grib_accessor_class* grib_accessor_class_uint32;

View File

@ -0,0 +1,212 @@
/*
* (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 "grib_api_internal.h"
/*
This is used by make_class.pl
START_CLASS_DEF
CLASS = accessor
SUPER = grib_accessor_class_ascii
IMPLEMENTS = unpack_string;pack_string
IMPLEMENTS = init
MEMBERS= const char* input
MEMBERS= int trimleft
MEMBERS= int trimright
END_CLASS_DEF
*/
/* START_CLASS_IMP */
/*
Don't edit anything between START_CLASS_IMP and END_CLASS_IMP
Instead edit values between START_CLASS_DEF and END_CLASS_DEF
or edit "accessor.class" and rerun ./make_class.pl
*/
static int pack_string(grib_accessor*, const char*, size_t* len);
static int unpack_string(grib_accessor*, char*, size_t* len);
static void init(grib_accessor*, const long, grib_arguments*);
static void init_class(grib_accessor_class*);
typedef struct grib_accessor_trim
{
grib_accessor att;
/* Members defined in gen */
/* Members defined in ascii */
/* Members defined in trim */
const char* input;
int trimleft;
int trimright;
} grib_accessor_trim;
extern grib_accessor_class* grib_accessor_class_ascii;
static grib_accessor_class _grib_accessor_class_trim = {
&grib_accessor_class_ascii, /* super */
"trim", /* name */
sizeof(grib_accessor_trim), /* size */
0, /* inited */
&init_class, /* init_class */
&init, /* init */
0, /* post_init */
0, /* free mem */
0, /* describes himself */
0, /* get length of section */
0, /* get length of string */
0, /* get number of values */
0, /* get number of bytes */
0, /* get offset to bytes */
0, /* get native type */
0, /* get sub_section */
0, /* grib_pack procedures long */
0, /* grib_pack procedures long */
0, /* grib_pack procedures long */
0, /* grib_unpack procedures long */
0, /* grib_pack procedures double */
0, /* grib_unpack procedures double */
&pack_string, /* grib_pack procedures string */
&unpack_string, /* grib_unpack procedures string */
0, /* grib_pack array procedures string */
0, /* grib_unpack array procedures string */
0, /* grib_pack procedures bytes */
0, /* grib_unpack procedures bytes */
0, /* pack_expression */
0, /* notify_change */
0, /* update_size */
0, /* preferred_size */
0, /* resize */
0, /* nearest_smaller_value */
0, /* next accessor */
0, /* compare vs. another accessor */
0, /* unpack only ith value */
0, /* unpack a subarray */
0, /* clear */
0, /* clone accessor */
};
grib_accessor_class* grib_accessor_class_trim = &_grib_accessor_class_trim;
static void init_class(grib_accessor_class* c)
{
c->dump = (*(c->super))->dump;
c->next_offset = (*(c->super))->next_offset;
c->string_length = (*(c->super))->string_length;
c->value_count = (*(c->super))->value_count;
c->byte_count = (*(c->super))->byte_count;
c->byte_offset = (*(c->super))->byte_offset;
c->get_native_type = (*(c->super))->get_native_type;
c->sub_section = (*(c->super))->sub_section;
c->pack_missing = (*(c->super))->pack_missing;
c->is_missing = (*(c->super))->is_missing;
c->pack_long = (*(c->super))->pack_long;
c->unpack_long = (*(c->super))->unpack_long;
c->pack_double = (*(c->super))->pack_double;
c->unpack_double = (*(c->super))->unpack_double;
c->pack_string_array = (*(c->super))->pack_string_array;
c->unpack_string_array = (*(c->super))->unpack_string_array;
c->pack_bytes = (*(c->super))->pack_bytes;
c->unpack_bytes = (*(c->super))->unpack_bytes;
c->pack_expression = (*(c->super))->pack_expression;
c->notify_change = (*(c->super))->notify_change;
c->update_size = (*(c->super))->update_size;
c->preferred_size = (*(c->super))->preferred_size;
c->resize = (*(c->super))->resize;
c->nearest_smaller_value = (*(c->super))->nearest_smaller_value;
c->next = (*(c->super))->next;
c->compare = (*(c->super))->compare;
c->unpack_double_element = (*(c->super))->unpack_double_element;
c->unpack_double_subarray = (*(c->super))->unpack_double_subarray;
c->clear = (*(c->super))->clear;
c->make_clone = (*(c->super))->make_clone;
}
/* END_CLASS_IMP */
static void init(grib_accessor* a, const long l, grib_arguments* arg)
{
int n = 0;
grib_accessor_trim* self = (grib_accessor_trim*)a;
grib_handle* h = grib_handle_of_accessor(a);
self->input = grib_arguments_get_name(h, arg, n++);
self->trimleft = grib_arguments_get_long(h, arg, n++);
self->trimright= grib_arguments_get_long(h, arg, n++);
DebugAssert(self->trimleft == 0 || self->trimleft == 1);
DebugAssert(self->trimright == 0 || self->trimright == 1);
}
static void trim(char** x)
{
char* p = 0;
while (**x == ' ' && **x != '\0')
(*x)++;
if (**x == '\0')
return;
p = (*x) + strlen(*x) - 1;
while (*p == ' ') {
*p = '\0';
p--;
}
if (*p == ' ')
*p = '\0';
}
static int unpack_string(grib_accessor* a, char* val, size_t* len)
{
grib_accessor_trim* self = (grib_accessor_trim*)a;
int err = 0;
grib_handle* h = grib_handle_of_accessor(a);
char input[256] = {0,};
size_t size = sizeof(input) / sizeof(*input);
char* pInput = input;
err = grib_get_string(h, self->input, input, &size);
if (err) return err;
DebugAssert(size < 9);
trim(&pInput);
sprintf(val, "%s", pInput);
size = strlen(val);
*len = size + 1;
return err;
}
static int pack_string(grib_accessor* a, const char* val, size_t* len)
{
char input[256] = {0,};
size_t inputLen = 256;
char buf[256] = {0,};
char* pBuf = NULL;
int err;
grib_handle* h = grib_handle_of_accessor(a);
grib_accessor_trim* self = (grib_accessor_trim*)a;
grib_accessor* inputAccesstor = grib_find_accessor(h, self->input);
if (!inputAccesstor) {
grib_context_log(a->context, GRIB_LOG_ERROR, "Accessor for %s not found", self->input);
return GRIB_NOT_FOUND;
}
if ((err = grib_get_string(h, self->input, input, &inputLen)) != GRIB_SUCCESS)
return err;
sprintf(buf, "%s", val);
pBuf = buf;
trim(&pBuf);
return grib_pack_string(inputAccesstor, pBuf, len);
}

File diff suppressed because it is too large Load Diff

View File

@ -207,6 +207,7 @@
{ "to_string", &grib_accessor_class_to_string, },
{ "transient", &grib_accessor_class_transient, },
{ "transient_darray", &grib_accessor_class_transient_darray, },
{ "trim", &grib_accessor_class_trim, },
{ "uint16", &grib_accessor_class_uint16, },
{ "uint16_little_endian", &grib_accessor_class_uint16_little_endian, },
{ "uint32", &grib_accessor_class_uint32, },

View File

@ -208,6 +208,7 @@ to_integer, &grib_accessor_class_to_integer
to_string, &grib_accessor_class_to_string
transient, &grib_accessor_class_transient
transient_darray, &grib_accessor_class_transient_darray
trim, &grib_accessor_class_trim
uint16, &grib_accessor_class_uint16
uint16_little_endian, &grib_accessor_class_uint16_little_endian
uint32, &grib_accessor_class_uint32

View File

@ -649,9 +649,13 @@ static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment)
/* ECC-356: Solution for the special local section key 'keyMore' and its alias 'ident' */
int skip = 1;
if ((a->flags & GRIB_ACCESSOR_FLAG_HIDDEN) != 0) {
/* We've come across a key which is hidden */
if (strcmp(a->name, "keyMore") == 0 && grib_is_defined(h, "ls.ident")) {
grib_accessor* acc = NULL;
skip = 0;
acc_name = "ident";
acc = grib_find_accessor(h, "identTrimmed");
if (acc) a = acc;
}
}
if (skip)

View File

@ -460,8 +460,8 @@ static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment)
/* ECC-356: Solution for the special local section key 'keyMore' and its alias 'ident' */
int skip = 1;
if ((a->flags & GRIB_ACCESSOR_FLAG_HIDDEN) != 0) {
grib_handle* h = grib_handle_of_accessor(a);
if (strcmp(a->name, "keyMore") == 0 && grib_is_defined(h, "ls.ident")) {
//grib_handle* h = grib_handle_of_accessor(a);
if (strcmp(a->name, "identTrimmed") == 0) {
skip = 0;
acc_name = "ident";
}

View File

@ -70,15 +70,15 @@ result=`${tools_dir}/bufr_get -s unpack=1 -p satelliteIdentifier wavb_134.bufr`
result=`${tools_dir}/bufr_get -m aaen_55.bufr`
[ "$result" = "55 20121102 0000" ]
result=`${tools_dir}/bufr_get -m syno_1.bufr`
[ "$result" = "1 20121030 0000 91334 " ]
[ "$result" = "1 20121030 0000 91334" ]
#-------------------------------------------
# Local ECMWF section: 'ident' key
#-------------------------------------------
result=`${tools_dir}/bufr_get -p isSatellite,ident syno_1.bufr`
[ "$result" = "0 91334 " ]
[ "$result" = "0 91334" ]
result=`${tools_dir}/bufr_get -p isSatellite,ident temp_102.bufr`
[ "$result" = "0 ASDE3 " ]
[ "$result" = "0 ASDE3" ]
result=`${tools_dir}/bufr_get -p isSatellite,ident b004_145.bufr`
[ "$result" = "0 FAVRTLZA" ]