ECC-991: New function to return string value of header key

This commit is contained in:
Shahram Najm 2019-11-18 18:20:12 +00:00
parent 54ba4cf72d
commit 2eaef6a4f7
6 changed files with 105 additions and 91 deletions

View File

@ -645,3 +645,78 @@ int codes_bufr_extract_headers_malloc(grib_context* c, const char* filename, cod
fclose(fp); fclose(fp);
return GRIB_SUCCESS; return GRIB_SUCCESS;
} }
int codes_bufr_header_get_string(codes_bufr_header* bh, const char* key, char *val, size_t *len)
{
static const char* NOT_FOUND = "not_found";
int isEcmwfLocal = 0;
Assert(bh);
Assert(key);
isEcmwfLocal = (bh->ecmwfLocalSectionPresent == 1 && bh->bufrHeaderCentre == 98);
if (strcmp(key, "message_offset")==0) *len = sprintf(val, "%lu", bh->message_offset);
else if (strcmp(key, "offset")==0) *len = sprintf(val, "%lu", bh->message_offset);
else if (strcmp(key, "message_size")==0) *len = sprintf(val, "%lu", bh->message_size);
else if (strcmp(key, "totalLength")==0) *len = sprintf(val, "%lu", bh->message_size);
else if (strcmp(key, "edition")==0) *len = sprintf(val, "%ld", bh->edition);
else if (strcmp(key, "masterTableNumber")==0) *len = sprintf(val, "%ld", bh->masterTableNumber);
else if (strcmp(key, "bufrHeaderSubCentre")==0) *len = sprintf(val, "%ld", bh->bufrHeaderSubCentre);
else if (strcmp(key, "bufrHeaderCentre")==0) *len = sprintf(val, "%ld", bh->bufrHeaderCentre);
else if (strcmp(key, "updateSequenceNumber")==0) *len = sprintf(val, "%ld", bh->updateSequenceNumber);
else if (strcmp(key, "dataCategory")==0) *len = sprintf(val, "%ld", bh->dataCategory);
else if (strcmp(key, "dataSubCategory")==0) *len = sprintf(val, "%ld", bh->dataSubCategory);
else if (strcmp(key, "masterTablesVersionNumber")==0) *len = sprintf(val, "%ld", bh->masterTablesVersionNumber);
else if (strcmp(key, "localTablesVersionNumber")==0) *len = sprintf(val, "%ld", bh->localTablesVersionNumber);
else if (strcmp(key, "typicalYear")==0) *len = sprintf(val, "%ld", bh->typicalYear);
else if (strcmp(key, "typicalMonth")==0) *len = sprintf(val, "%ld", bh->typicalMonth);
else if (strcmp(key, "typicalDay")==0) *len = sprintf(val, "%ld", bh->typicalDay);
else if (strcmp(key, "typicalHour")==0) *len = sprintf(val, "%ld", bh->typicalHour);
else if (strcmp(key, "typicalMinute")==0) *len = sprintf(val, "%ld", bh->typicalMinute);
else if (strcmp(key, "typicalSecond")==0) *len = sprintf(val, "%ld", bh->typicalSecond);
else if (strcmp(key, "typicalDate")==0) *len = sprintf(val, "%06ld", bh->typicalDate);
else if (strcmp(key, "typicalTime")==0) *len = sprintf(val, "%06ld", bh->typicalTime);
else if (strcmp(key, "internationalDataSubCategory")==0) *len = sprintf(val, "%ld", bh->internationalDataSubCategory);
else if (strcmp(key, "localSectionPresent")==0) *len = sprintf(val, "%ld", bh->ecmwfLocalSectionPresent);
/* Local ECMWF keys. Can be absent so must return NOT_FOUND */
else if (strcmp(key, "rdbType")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->rdbType); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "oldSubtype")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->oldSubtype); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "ident")==0) {
if (!isEcmwfLocal || bh->ident == NULL || strlen(bh->ident)==0) *len = sprintf(val, NOT_FOUND);
else *len = sprintf(val, "%s", bh->ident);
}
else if (strcmp(key, "localYear")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->localYear); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "localMonth")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->localMonth); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "localDay")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->localDay); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "localHour")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->localHour); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "localMinute")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->localMinute); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "localSecond")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->localSecond); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "rdbtimeDay")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->rdbtimeDay); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "rdbtimeHour")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->rdbtimeHour); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "rdbtimeMinute")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->rdbtimeMinute); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "rdbtimeSecond")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->rdbtimeSecond); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "rectimeDay")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->rectimeDay); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "rectimeHour")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->rectimeHour); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "rectimeMinute")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->rectimeMinute); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "rectimeSecond")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->rectimeSecond); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "isSatellite")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->isSatellite); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "localLongitude1")==0) { if (isEcmwfLocal) *len = sprintf(val, "%g", bh->localLongitude1); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "localLatitude1")==0) { if (isEcmwfLocal) *len = sprintf(val, "%g", bh->localLatitude1); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "localLongitude2")==0) { if (isEcmwfLocal) *len = sprintf(val, "%g", bh->localLongitude2); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "localLatitude2")==0) { if (isEcmwfLocal) *len = sprintf(val, "%g", bh->localLatitude2); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "localLatitude")==0) { if (isEcmwfLocal) *len = sprintf(val, "%g", bh->localLatitude); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "localLongitude")==0) { if (isEcmwfLocal) *len = sprintf(val, "%g", bh->localLongitude); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "qualityControl")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->qualityControl); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "newSubtype")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->newSubtype); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "daLoop")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->daLoop); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "localNumberOfObservations")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->localNumberOfObservations); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "satelliteID")==0) { if (isEcmwfLocal) *len = sprintf(val, "%ld", bh->satelliteID); else *len = sprintf(val, NOT_FOUND); }
else if (strcmp(key, "numberOfSubsets")==0) *len = sprintf(val, "%lu", bh->numberOfSubsets);
else if (strcmp(key, "observedData")==0) *len = sprintf(val, "%ld", bh->observedData);
else if (strcmp(key, "compressedData")==0) *len = sprintf(val, "%ld", bh->compressedData);
else return GRIB_NOT_FOUND;
return GRIB_SUCCESS;
}

View File

@ -1271,6 +1271,7 @@ codes_handle *codes_grib_util_set_spec(codes_handle *h,
* returns 0 if OK, integer value on error. * returns 0 if OK, integer value on error.
*/ */
int codes_bufr_extract_headers_malloc(codes_context* c, const char* filename, codes_bufr_header** result, int* num_messages, int strict_mode); int codes_bufr_extract_headers_malloc(codes_context* c, const char* filename, codes_bufr_header** result, int* num_messages, int strict_mode);
int codes_bufr_header_get_string(codes_bufr_header* bh, const char* key, char *val, size_t *len);
/* --------------------------------------- */ /* --------------------------------------- */
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -1585,8 +1585,8 @@ typedef struct codes_bufr_header {
long typicalHour; long typicalHour;
long typicalMinute; long typicalMinute;
long typicalSecond; long typicalSecond;
long typicalDate; // computed key long typicalDate; /* computed key */
long typicalTime; // computed key long typicalTime; /* computed key */
long internationalDataSubCategory; /*BUFR4-specific*/ long internationalDataSubCategory; /*BUFR4-specific*/

View File

@ -1486,6 +1486,7 @@ int compute_bufr_key_rank(grib_handle *h, grib_string_list *keys, const char *ke
char **codes_bufr_copy_data_return_copied_keys(grib_handle *hin, grib_handle *hout, size_t *nkeys, int *err); char **codes_bufr_copy_data_return_copied_keys(grib_handle *hin, grib_handle *hout, size_t *nkeys, int *err);
int codes_bufr_copy_data(grib_handle *hin, grib_handle *hout); int codes_bufr_copy_data(grib_handle *hin, grib_handle *hout);
int codes_bufr_extract_headers_malloc(grib_context* c, const char* filename, codes_bufr_header** result, int* num_messages, int strict_mode); int codes_bufr_extract_headers_malloc(grib_context* c, const char* filename, codes_bufr_header** result, int* num_messages, int strict_mode);
int codes_bufr_header_get_string(codes_bufr_header* bh, const char* key, char *val, size_t *len);
/* string_util.c */ /* string_util.c */

View File

@ -9,28 +9,7 @@
*/ */
#include "eccodes.h" #include "eccodes.h"
#include <assert.h>
static const char* not_found = "not_found";
static void print_rdb_key(int local, long value)
{
if (local) printf("%ld ", value);
else printf("%s ", not_found);
}
static void print_rdb_key_double(int local, double value)
{
if (local) printf("%g ", value);
else printf("%s ", not_found);
}
static void print_rdb_ident(int local, const char* value)
{
if (!local || value == NULL || strlen(value) == 0)
printf("%s ", not_found);
else
printf("%s ", value);
}
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
@ -40,8 +19,11 @@ int main(int argc, char* argv[])
codes_bufr_header* header_array = NULL; codes_bufr_header* header_array = NULL;
codes_context* c = codes_context_get_default(); codes_context* c = codes_context_get_default();
const int strict_mode = 1; const int strict_mode = 1;
const int MAX_KEYS=100;
int requested_print_keys_count = MAX_KEYS;
codes_values requested_print_keys[MAX_KEYS];
if (argc != 3) return 1; assert (argc == 3);
keys = argv[1]; /* comma-separated like bufr_ls/bufr_get */ keys = argv[1]; /* comma-separated like bufr_ls/bufr_get */
filename = argv[2]; filename = argv[2];
@ -51,71 +33,19 @@ int main(int argc, char* argv[])
printf("ERROR: %s\n",grib_get_error_message(err)); printf("ERROR: %s\n",grib_get_error_message(err));
return 1; return 1;
} }
/* Mimic the behaviour of bufr_get -f -p keys for testing */
err = parse_keyval_string(NULL, keys, 0, GRIB_TYPE_UNDEFINED, requested_print_keys, &requested_print_keys_count);
assert(requested_print_keys_count > 0);
for (i=0; i < num_messages; ++i) { for (i=0; i < num_messages; ++i) {
codes_bufr_header bh = header_array[i]; int j;
/* for (j=0; j<requested_print_keys_count; ++j) {
* Mimic the behaviour of bufr_get -f -p keys for testing size_t vlen = 0;
*/ char value[512]={0,};
const int has_ecmwf_local = (bh.ecmwfLocalSectionPresent == 1 && bh.bufrHeaderCentre == 98); CODES_CHECK( codes_bufr_header_get_string(&header_array[i], requested_print_keys[j].name, value, &vlen), 0);
assert(vlen > 0);
if (strstr(keys, "message_offset")) printf("%ld ", bh.message_offset); printf("%s ", value);
if (strstr(keys, "message_size")) printf("%ld ", bh.message_size); }
if (strstr(keys, "edition")) printf("%ld ", bh.edition);
if (strstr(keys, "totalLength")) printf("%ld ", bh.message_size);
if (strstr(keys, "masterTableNumber")) printf("%ld ", bh.masterTableNumber);
if (strstr(keys, "bufrHeaderSubCentre")) printf("%ld ", bh.bufrHeaderSubCentre);
if (strstr(keys, "bufrHeaderCentre")) printf("%ld ", bh.bufrHeaderCentre);
if (strstr(keys, "updateSequenceNumber")) printf("%ld ", bh.updateSequenceNumber);
if (strstr(keys, "dataCategory")) printf("%ld ", bh.dataCategory);
if (strstr(keys, "dataSubCategory")) printf("%ld ", bh.dataSubCategory);
if (strstr(keys, "masterTablesVersionNumber")) printf("%ld ", bh.masterTablesVersionNumber);
if (strstr(keys, "localTablesVersionNumber")) printf("%ld ", bh.localTablesVersionNumber);
if (strstr(keys, "typicalYear")) printf("%ld ", bh.typicalYear);
if (strstr(keys, "typicalMonth")) printf("%ld ", bh.typicalMonth);
if (strstr(keys, "typicalDay")) printf("%ld ", bh.typicalDay);
if (strstr(keys, "typicalHour")) printf("%ld ", bh.typicalHour);
if (strstr(keys, "typicalMinute")) printf("%ld ", bh.typicalMinute);
if (strstr(keys, "typicalDate")) printf("%ld ", bh.typicalDate);
if (strstr(keys, "typicalTime")) printf("%ld ", bh.typicalTime);
if (strstr(keys, "internationalDataSubCategory")) printf("%ld ", bh.internationalDataSubCategory);
if (strstr(keys, "typicalSecond")) printf("%ld ", bh.typicalSecond);
if (strstr(keys, "localSectionPresent")) printf("%ld ", bh.ecmwfLocalSectionPresent);
if (strstr(keys, "rdbType")) print_rdb_key(has_ecmwf_local, bh.rdbType);
if (strstr(keys, "oldSubtype")) print_rdb_key(has_ecmwf_local, bh.oldSubtype);
if (strstr(keys, "localYear")) print_rdb_key(has_ecmwf_local, bh.localYear);
if (strstr(keys, "localMonth")) print_rdb_key(has_ecmwf_local, bh.localMonth);
if (strstr(keys, "localDay")) print_rdb_key(has_ecmwf_local, bh.localDay);
if (strstr(keys, "localHour")) print_rdb_key(has_ecmwf_local, bh.localHour);
if (strstr(keys, "localMinute")) print_rdb_key(has_ecmwf_local, bh.localMinute);
if (strstr(keys, "localSecond")) print_rdb_key(has_ecmwf_local, bh.localSecond);
if (strstr(keys, "rdbtimeDay")) print_rdb_key(has_ecmwf_local, bh.rdbtimeDay);
if (strstr(keys, "rdbtimeHour")) print_rdb_key(has_ecmwf_local, bh.rdbtimeHour);
if (strstr(keys, "rdbtimeMinute")) print_rdb_key(has_ecmwf_local, bh.rdbtimeMinute);
if (strstr(keys, "rdbtimeSecond")) print_rdb_key(has_ecmwf_local, bh.rdbtimeSecond);
if (strstr(keys, "rectimeDay")) print_rdb_key(has_ecmwf_local, bh.rectimeDay);
if (strstr(keys, "rectimeHour")) print_rdb_key(has_ecmwf_local, bh.rectimeHour);
if (strstr(keys, "rectimeMinute")) print_rdb_key(has_ecmwf_local, bh.rectimeMinute);
if (strstr(keys, "rectimeSecond")) print_rdb_key(has_ecmwf_local, bh.rectimeSecond);
if (strstr(keys, "qualityControl")) print_rdb_key(has_ecmwf_local, bh.qualityControl);
if (strstr(keys, "newSubtype")) print_rdb_key(has_ecmwf_local, bh.newSubtype);
if (strstr(keys, "daLoop")) print_rdb_key(has_ecmwf_local, bh.daLoop);
if (strstr(keys, "localLongitude1")) print_rdb_key_double(has_ecmwf_local, bh.localLongitude1);
if (strstr(keys, "localLatitude1")) print_rdb_key_double(has_ecmwf_local, bh.localLatitude1);
if (strstr(keys, "localLongitude2")) print_rdb_key_double(has_ecmwf_local, bh.localLongitude2);
if (strstr(keys, "localLatitude2")) print_rdb_key_double(has_ecmwf_local, bh.localLatitude2);
if (strstr(keys, "localNumberOfObservations")) printf("%ld ", bh.localNumberOfObservations);
if (strstr(keys, "satelliteID")) printf("%ld ", bh.satelliteID);
if (strstr(keys, "numberOfSubsets")) printf("%ld ", bh.numberOfSubsets);
if (strstr(keys, "observedData")) printf("%ld ", bh.observedData);
if (strstr(keys, "compressedData")) printf("%ld ", bh.compressedData);
if (strstr(keys, "ident")) print_rdb_ident(has_ecmwf_local, bh.ident);
printf("\n"); printf("\n");
} }

View File

@ -30,10 +30,17 @@ done
# Multi-message BUFR # Multi-message BUFR
input=${data_dir}/bufr/aeolus_wmo_26.bufr input=${data_dir}/bufr/aeolus_wmo_26.bufr
$EXEC ${test_dir}/bufr_extract_headers edition,totalLength,message_offset $input > $temp1 KEYS='offset,edition,totalLength'
${tools_dir}/bufr_get -p offset,edition,totalLength $input > $temp2 $EXEC ${test_dir}/bufr_extract_headers $KEYS $input > $temp1
${tools_dir}/bufr_get -p $KEYS $input > $temp2
diff -w $temp1 $temp2 diff -w $temp1 $temp2
# Test local ECMWF keys; should be "not_found"
input=${data_dir}/bufr/synop.bufr
KEYS='localSectionPresent,rdbType,ident,isSatellite,satelliteID'
$EXEC ${test_dir}/bufr_extract_headers $KEYS $input > $temp1
${tools_dir}/bufr_get -f -p $KEYS $input > $temp2
diff -w $temp1 $temp2
# BUFRs with localLatitude1, localLongitude1, localLongitude2 etc # BUFRs with localLatitude1, localLongitude1, localLongitude2 etc
bufr_files=" bufr_files="