diff --git a/definitions/bufr/rdb_key.def b/definitions/bufr/rdb_key.def index eea896d3e..a32343acb 100644 --- a/definitions/bufr/rdb_key.def +++ b/definitions/bufr/rdb_key.def @@ -1,4 +1,5 @@ # RDB stands for REPORT DATA BASE +# See https://confluence.ecmwf.int/pages/viewpage.action?pageId=24316441 unsigned[1] rdbType : dump; unsigned[1] oldSubtype: dump; diff --git a/definitions/bufr/section.3.def b/definitions/bufr/section.3.def index d223bbbb2..56fa58ad1 100644 --- a/definitions/bufr/section.3.def +++ b/definitions/bufr/section.3.def @@ -50,7 +50,7 @@ unsigned[1] reservedSection3 = 0; unsigned[2] numberOfSubsets : dump; alias ls.numberOfSubsets=numberOfSubsets; -if (section2Present && bufrHeaderCentre==98 && section2Length==52) { +if (section2Present && bufrHeaderCentre == 98 && section2Length == 52) { if ( rdbType == 2 || rdbType == 3 || rdbType == 8 || rdbType == 12 || rdbType == 30 ) { transient isSatelliteType=1; } else { @@ -69,10 +69,11 @@ if (section2Present && bufrHeaderCentre==98 && section2Length==52) { meta localLatitude2 bits(keyMore,32,25,-9000000,100000) : dump,no_copy; # This rule is taken from BUFRDC. See bufrdc_wmo/buukey.F - # Also see ECC-686 - if (oldSubtype == 255 || numberOfSubsets>255 || - ( oldSubtype>=121 && oldSubtype <=130 ) || - oldSubtype==31) { + # See ECC-686 + # and https://confluence.ecmwf.int/pages/viewpage.action?pageId=24316441 + if (oldSubtype == 255 || numberOfSubsets > 255 || + ( oldSubtype >= 121 && oldSubtype <= 130 ) || + oldSubtype == 31) { meta ls.localNumberOfObservations bits(keySat,0,16) : dump,long_type,no_copy; meta ls.satelliteID bits(keySat,16,16) : dump,long_type,no_copy; } else { @@ -114,16 +115,16 @@ meta bufrdcExpandedDescriptors bufrdc_expanded_descriptors(expandedCodes) : no_c #smart_table NAME (VALUES,FILE_NAME,MASTER_DIRECTORY,LOCAL_DIRECTORY,WIDTH_OF_CODE_IN_BITS,EXTRA_DIRECTORY,EXTRA_FILE_NAME); #Note: The WIDTH_OF_CODE_IN_BITS has to be big enough so 2^width > the highest BUFR descriptor code smart_table expandedOriginalCodes (expandedCodes,"element.table",tablesMasterDir,tablesLocalDir,18,rootTablesDir,"operators.table") :no_copy; -meta expandedAbbreviations smart_table_column(expandedOriginalCodes,0,1) : string_type,no_copy; -meta expandedTypes smart_table_column(expandedOriginalCodes,1,0) : string_type,no_copy; -meta expandedNames smart_table_column(expandedOriginalCodes,2,0) : string_type,no_copy; -meta expandedUnits smart_table_column(expandedOriginalCodes,3,0) : string_type,no_copy; -meta expandedOriginalScales smart_table_column(expandedOriginalCodes,4,0) : long_type,no_copy; -meta expandedOriginalReferences smart_table_column(expandedOriginalCodes,5,0) : long_type,no_copy; -meta expandedOriginalWidths smart_table_column(expandedOriginalCodes,6,0) : long_type,no_copy; -meta expandedCrex_units smart_table_column(expandedOriginalCodes,7,0) : long_type,no_copy; -meta expandedCrex_scales smart_table_column(expandedOriginalCodes,8,0) : long_type,no_copy; -meta expandedCrex_widths smart_table_column(expandedOriginalCodes,9,0) : long_type,no_copy; +meta expandedAbbreviations smart_table_column(expandedOriginalCodes,0,1) : string_type,no_copy; +meta expandedTypes smart_table_column(expandedOriginalCodes,1,0) : string_type,no_copy; +meta expandedNames smart_table_column(expandedOriginalCodes,2,0) : string_type,no_copy; +meta expandedUnits smart_table_column(expandedOriginalCodes,3,0) : string_type,no_copy; +meta expandedOriginalScales smart_table_column(expandedOriginalCodes,4,0) : long_type,no_copy; +meta expandedOriginalReferences smart_table_column(expandedOriginalCodes,5,0) : long_type,no_copy; +meta expandedOriginalWidths smart_table_column(expandedOriginalCodes,6,0) : long_type,no_copy; +meta expandedCrex_units smart_table_column(expandedOriginalCodes,7,0) : long_type,no_copy; +meta expandedCrex_scales smart_table_column(expandedOriginalCodes,8,0) : long_type,no_copy; +meta expandedCrex_widths smart_table_column(expandedOriginalCodes,9,0) : long_type,no_copy; position endDescriptors; section_padding section3Padding; diff --git a/src/grib_dumper.cc b/src/grib_dumper.cc index f8d826f65..6f9f48e67 100644 --- a/src/grib_dumper.cc +++ b/src/grib_dumper.cc @@ -84,7 +84,6 @@ void grib_dump_long(grib_dumper* d, grib_accessor* a, const char* comment) } c = c->super ? *(c->super) : NULL; } - Assert(0); } void grib_dump_double(grib_dumper* d, grib_accessor* a, const char* comment) @@ -97,7 +96,6 @@ void grib_dump_double(grib_dumper* d, grib_accessor* a, const char* comment) } c = c->super ? *(c->super) : NULL; } - Assert(0); } void grib_dump_string(grib_dumper* d, grib_accessor* a, const char* comment) @@ -110,7 +108,6 @@ void grib_dump_string(grib_dumper* d, grib_accessor* a, const char* comment) } c = c->super ? *(c->super) : NULL; } - Assert(0); } void grib_dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) @@ -147,7 +144,6 @@ void grib_dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) } c = c->super ? *(c->super) : NULL; } - Assert(0); } void grib_dump_bits(grib_dumper* d, grib_accessor* a, const char* comment) @@ -160,7 +156,6 @@ void grib_dump_bits(grib_dumper* d, grib_accessor* a, const char* comment) } c = c->super ? *(c->super) : NULL; } - Assert(0); } void grib_dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) @@ -173,7 +168,6 @@ void grib_dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors } c = c->super ? *(c->super) : NULL; } - Assert(0); } void grib_dump_values(grib_dumper* d, grib_accessor* a) @@ -186,7 +180,6 @@ void grib_dump_values(grib_dumper* d, grib_accessor* a) } c = c->super ? *(c->super) : NULL; } - Assert(0); } void grib_dump_header(grib_dumper* d, const grib_handle* ch) diff --git a/src/grib_dumper_class_debug.cc b/src/grib_dumper_class_debug.cc index d740e4523..ed416d019 100644 --- a/src/grib_dumper_class_debug.cc +++ b/src/grib_dumper_class_debug.cc @@ -16,7 +16,7 @@ START_CLASS_DEF CLASS = dumper IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string + IMPLEMENTS = dump_double;dump_string;dump_string_array IMPLEMENTS = dump_bytes;dump_values IMPLEMENTS = dump_label;dump_section IMPLEMENTS = init;destroy @@ -45,6 +45,7 @@ static void dump_long (grib_dumper* d, grib_accessor* a,const char* commen static void dump_bits (grib_dumper* d, grib_accessor* a,const char* comment); static void dump_double (grib_dumper* d, grib_accessor* a,const char* comment); static void dump_string (grib_dumper* d, grib_accessor* a,const char* comment); +static void dump_string_array (grib_dumper* d, grib_accessor* a,const char* comment); static void dump_bytes (grib_dumper* d, grib_accessor* a,const char* comment); static void dump_values (grib_dumper* d, grib_accessor* a); static void dump_label (grib_dumper* d, grib_accessor* a,const char* comment); @@ -70,7 +71,7 @@ static grib_dumper_class _grib_dumper_class_debug = { &dump_long, /* dump long */ &dump_double, /* dump double */ &dump_string, /* dump string */ - 0, /* dump string array */ + &dump_string_array, /* dump string array */ &dump_label, /* dump labels */ &dump_bytes, /* dump bytes */ &dump_bits, /* dump bits */ @@ -381,6 +382,76 @@ static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) grib_context_free(a->context, value); } +static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) +{ + grib_dumper_debug* self = (grib_dumper_debug*)d; + + char** values; + size_t size = 0, i = 0; + grib_context* c = NULL; + int err = 0; + int tab = 0; + long count = 0; + + if ((a->flags & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + c = a->context; + a->value_count(&count); + if (count == 0) + return; + size = count; + if (size == 1) { + dump_string(d, a, comment); + return; + } + + values = (char**)grib_context_malloc_clear(c, size * sizeof(char*)); + if (!values) { + grib_context_log(c, GRIB_LOG_ERROR, "unable to allocate %zu bytes", size); + return; + } + + err = a->unpack_string_array(values, &size); + + // print_offset(self->dumper.out,d,a); + //print_offset(self->dumper.out, self->begin, self->theEnd); + + if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) { + fprintf(self->dumper.out, " "); + fprintf(self->dumper.out, "# type %s (str) \n", a->creator->op); + } + + aliases(d, a); + if (comment) { + fprintf(self->dumper.out, " "); + fprintf(self->dumper.out, "# %s \n", comment); + } + if (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) { + fprintf(self->dumper.out, " "); + fprintf(self->dumper.out, "#-READ ONLY- "); + tab = 13; + } + else + fprintf(self->dumper.out, " "); + + tab++; + fprintf(self->dumper.out, "%s = {\n", a->name); + for (i = 0; i < size; i++) { + fprintf(self->dumper.out, "%-*s\"%s\",\n", (int)(tab + strlen(a->name) + 4), " ", values[i]); + } + fprintf(self->dumper.out, " }"); + + if (err) { + fprintf(self->dumper.out, " "); + fprintf(self->dumper.out, "# *** ERR=%d (%s)", err, grib_get_error_message(err)); + } + + fprintf(self->dumper.out, "\n"); + for (i=0; i $temp 2>&1 +${tools_dir}/grib_dump -Da -TB -s unpack=1 $infile > $temp 2>&1 + + # Clean up rm -f $temp