From a82911310eece661ac43d9a10529cc3344aa01dd Mon Sep 17 00:00:00 2001 From: Eugen Betke Date: Tue, 17 Dec 2024 23:26:55 +0100 Subject: [PATCH] Modernisation: Dumper --- src/CMakeLists.txt | 37 +- src/accessor/grib_accessor.cc | 1 - src/accessor/grib_accessor.h | 7 +- src/accessor/grib_accessor_class_ascii.cc | 2 +- src/accessor/grib_accessor_class_bitmap.cc | 2 +- src/accessor/grib_accessor_class_blob.cc | 2 +- .../grib_accessor_class_bufr_data_array.cc | 2 +- .../grib_accessor_class_bufr_data_element.cc | 6 +- .../grib_accessor_class_bufr_group.cc | 2 +- .../grib_accessor_class_bufr_string_values.cc | 2 +- .../grib_accessor_class_closest_date.cc | 2 +- src/accessor/grib_accessor_class_codeflag.cc | 2 +- src/accessor/grib_accessor_class_codetable.cc | 2 +- src/accessor/grib_accessor_class_concept.cc | 2 +- .../grib_accessor_class_data_apply_bitmap.cc | 2 +- ...cessor_class_data_apply_boustrophedonic.cc | 2 +- ...class_data_apply_boustrophedonic_bitmap.cc | 2 +- ...g1second_order_general_extended_packing.cc | 2 +- ...ib_accessor_class_data_secondary_bitmap.cc | 2 +- ...ib_accessor_class_data_shsimple_packing.cc | 2 +- .../grib_accessor_class_dictionary.cc | 6 +- src/accessor/grib_accessor_class_double.cc | 2 +- ...ib_accessor_class_g1_half_byte_codeflag.cc | 2 +- ...b_accessor_class_g1day_of_the_year_date.cc | 2 +- .../grib_accessor_class_g1forecastmonth.cc | 2 +- .../grib_accessor_class_g1step_range.cc | 2 +- .../grib_accessor_class_g2end_step.cc | 2 +- .../grib_accessor_class_g2step_range.cc | 2 +- src/accessor/grib_accessor_class_gen.h | 1 + src/accessor/grib_accessor_class_group.cc | 2 +- .../grib_accessor_class_hash_array.cc | 2 +- src/accessor/grib_accessor_class_iterator.cc | 2 +- .../grib_accessor_class_julian_date.cc | 2 +- .../grib_accessor_class_julian_day.cc | 2 +- src/accessor/grib_accessor_class_label.cc | 2 +- src/accessor/grib_accessor_class_long.cc | 2 +- src/accessor/grib_accessor_class_lookup.cc | 2 +- .../grib_accessor_class_message_copy.cc | 2 +- src/accessor/grib_accessor_class_nearest.cc | 2 +- src/accessor/grib_accessor_class_non_alpha.cc | 2 +- .../grib_accessor_class_optimal_step_units.cc | 2 +- src/accessor/grib_accessor_class_padto.cc | 2 +- src/accessor/grib_accessor_class_position.cc | 2 +- src/accessor/grib_accessor_class_section.cc | 2 +- .../grib_accessor_class_section_length.cc | 2 +- ...grib_accessor_class_sexagesimal2decimal.cc | 2 +- src/accessor/grib_accessor_class_signed.cc | 4 +- .../grib_accessor_class_smart_table.cc | 2 +- .../grib_accessor_class_smart_table_column.cc | 4 +- .../grib_accessor_class_step_in_units.cc | 2 +- src/accessor/grib_accessor_class_to_double.cc | 2 +- .../grib_accessor_class_to_integer.cc | 2 +- src/accessor/grib_accessor_class_to_string.cc | 2 +- .../grib_accessor_class_transient_darray.cc | 2 +- src/accessor/grib_accessor_class_unsigned.cc | 4 +- src/accessor/grib_accessor_class_values.cc | 2 +- src/accessor/grib_accessor_class_variable.cc | 6 +- src/accessor/grib_accessor_class_when.cc | 2 +- src/accessor/run.sh | 91 ++ src/accessor/z_check_members.py | 186 ++++ src/accessor/z_compare.sh | 27 + src/accessor/z_constructor_headers.py | 65 ++ src/accessor/z_constructor_sources.py | 156 +++ src/accessor/z_destructor_headers.py | 44 + src/accessor/z_destructor_sources.py | 50 + src/accessor/z_factory_headers.py | 47 + src/accessor/z_factory_sources.py | 41 + src/accessor/z_find_constructors.sh | 34 + src/accessor/z_fix_init.py | 75 ++ src/accessor/z_init.py | 86 ++ src/accessor/z_melt_classes.py | 103 ++ src/accessor/z_melt_classes_sources.py | 80 ++ src/accessor/z_rm_constructor_headers.py | 41 + src/accessor/z_rm_constructor_sources.py | 28 + src/accessor/z_rm_dev.sh | 7 + src/accessor/z_transform.py | 165 +++ src/accessor/z_transform_class.py | 91 ++ src/dumper/grib_dumper.h | 67 ++ src/dumper/grib_dumper_class_bufr_decode_C.cc | 644 ++++++++++++ src/dumper/grib_dumper_class_bufr_decode_C.h | 52 + .../grib_dumper_class_bufr_decode_filter.cc | 493 +++++++++ .../grib_dumper_class_bufr_decode_filter.h | 50 + .../grib_dumper_class_bufr_decode_fortran.cc | 561 ++++++++++ .../grib_dumper_class_bufr_decode_fortran.h | 49 + .../grib_dumper_class_bufr_decode_python.cc | 560 ++++++++++ .../grib_dumper_class_bufr_decode_python.h | 51 + src/dumper/grib_dumper_class_bufr_encode_C.cc | 834 +++++++++++++++ src/dumper/grib_dumper_class_bufr_encode_C.h | 50 + .../grib_dumper_class_bufr_encode_filter.cc | 712 +++++++++++++ .../grib_dumper_class_bufr_encode_filter.h | 50 + .../grib_dumper_class_bufr_encode_fortran.cc | 863 ++++++++++++++++ .../grib_dumper_class_bufr_encode_fortran.h | 54 + .../grib_dumper_class_bufr_encode_python.cc | 793 +++++++++++++++ .../grib_dumper_class_bufr_encode_python.h | 53 + src/dumper/grib_dumper_class_bufr_simple.cc | 700 +++++++++++++ src/dumper/grib_dumper_class_bufr_simple.h | 48 + src/dumper/grib_dumper_class_debug.cc | 553 ++++++++++ src/dumper/grib_dumper_class_debug.h | 44 + src/dumper/grib_dumper_class_default.cc | 624 ++++++++++++ src/dumper/grib_dumper_class_default.h | 43 + src/dumper/grib_dumper_class_grib_encode_C.cc | 374 +++++++ src/dumper/grib_dumper_class_grib_encode_C.h | 42 + src/dumper/grib_dumper_class_json.cc | 524 ++++++++++ src/dumper/grib_dumper_class_json.h | 49 + src/dumper/grib_dumper_class_serialize.cc | 354 +++++++ src/dumper/grib_dumper_class_serialize.h | 37 + src/dumper/grib_dumper_class_wmo.cc | 586 +++++++++++ src/dumper/grib_dumper_class_wmo.h | 43 + src/eccodes_prototypes.h | 42 +- src/grib_api_internal.h | 43 - src/grib_dumper_class.cc | 118 +-- src/grib_dumper_class.h | 18 - src/grib_dumper_class_bufr_decode_C.cc | 737 -------------- src/grib_dumper_class_bufr_decode_filter.cc | 587 ----------- src/grib_dumper_class_bufr_decode_fortran.cc | 653 ------------ src/grib_dumper_class_bufr_decode_python.cc | 651 ------------ src/grib_dumper_class_bufr_encode_C.cc | 932 ----------------- src/grib_dumper_class_bufr_encode_filter.cc | 803 --------------- src/grib_dumper_class_bufr_encode_fortran.cc | 962 ------------------ src/grib_dumper_class_bufr_encode_python.cc | 884 ---------------- src/grib_dumper_class_bufr_simple.cc | 786 -------------- src/grib_dumper_class_debug.cc | 646 ------------ src/grib_dumper_class_default.cc | 708 ------------- src/grib_dumper_class_grib_encode_C.cc | 450 -------- src/grib_dumper_class_json.cc | 601 ----------- src/grib_dumper_class_serialize.cc | 423 -------- src/grib_dumper_class_wmo.cc | 660 ------------ src/grib_dumper_factory.cc | 155 +++ src/grib_dumper_factory.h | 59 +- src/grib_expression_class_unop.cc | 47 +- src/grib_ibmfloat.h | 19 +- tools/bufr_dump.cc | 19 +- tools/grib_dump.cc | 1 + 133 files changed, 11743 insertions(+), 10807 deletions(-) create mode 100755 src/accessor/run.sh create mode 100755 src/accessor/z_check_members.py create mode 100755 src/accessor/z_compare.sh create mode 100755 src/accessor/z_constructor_headers.py create mode 100755 src/accessor/z_constructor_sources.py create mode 100755 src/accessor/z_destructor_headers.py create mode 100755 src/accessor/z_destructor_sources.py create mode 100755 src/accessor/z_factory_headers.py create mode 100755 src/accessor/z_factory_sources.py create mode 100755 src/accessor/z_find_constructors.sh create mode 100755 src/accessor/z_fix_init.py create mode 100755 src/accessor/z_init.py create mode 100755 src/accessor/z_melt_classes.py create mode 100755 src/accessor/z_melt_classes_sources.py create mode 100755 src/accessor/z_rm_constructor_headers.py create mode 100755 src/accessor/z_rm_constructor_sources.py create mode 100755 src/accessor/z_rm_dev.sh create mode 100755 src/accessor/z_transform.py create mode 100755 src/accessor/z_transform_class.py create mode 100644 src/dumper/grib_dumper.h create mode 100644 src/dumper/grib_dumper_class_bufr_decode_C.cc create mode 100644 src/dumper/grib_dumper_class_bufr_decode_C.h create mode 100644 src/dumper/grib_dumper_class_bufr_decode_filter.cc create mode 100644 src/dumper/grib_dumper_class_bufr_decode_filter.h create mode 100644 src/dumper/grib_dumper_class_bufr_decode_fortran.cc create mode 100644 src/dumper/grib_dumper_class_bufr_decode_fortran.h create mode 100644 src/dumper/grib_dumper_class_bufr_decode_python.cc create mode 100644 src/dumper/grib_dumper_class_bufr_decode_python.h create mode 100644 src/dumper/grib_dumper_class_bufr_encode_C.cc create mode 100644 src/dumper/grib_dumper_class_bufr_encode_C.h create mode 100644 src/dumper/grib_dumper_class_bufr_encode_filter.cc create mode 100644 src/dumper/grib_dumper_class_bufr_encode_filter.h create mode 100644 src/dumper/grib_dumper_class_bufr_encode_fortran.cc create mode 100644 src/dumper/grib_dumper_class_bufr_encode_fortran.h create mode 100644 src/dumper/grib_dumper_class_bufr_encode_python.cc create mode 100644 src/dumper/grib_dumper_class_bufr_encode_python.h create mode 100644 src/dumper/grib_dumper_class_bufr_simple.cc create mode 100644 src/dumper/grib_dumper_class_bufr_simple.h create mode 100644 src/dumper/grib_dumper_class_debug.cc create mode 100644 src/dumper/grib_dumper_class_debug.h create mode 100644 src/dumper/grib_dumper_class_default.cc create mode 100644 src/dumper/grib_dumper_class_default.h create mode 100644 src/dumper/grib_dumper_class_grib_encode_C.cc create mode 100644 src/dumper/grib_dumper_class_grib_encode_C.h create mode 100644 src/dumper/grib_dumper_class_json.cc create mode 100644 src/dumper/grib_dumper_class_json.h create mode 100644 src/dumper/grib_dumper_class_serialize.cc create mode 100644 src/dumper/grib_dumper_class_serialize.h create mode 100644 src/dumper/grib_dumper_class_wmo.cc create mode 100644 src/dumper/grib_dumper_class_wmo.h delete mode 100644 src/grib_dumper_class.h delete mode 100644 src/grib_dumper_class_bufr_decode_C.cc delete mode 100644 src/grib_dumper_class_bufr_decode_filter.cc delete mode 100644 src/grib_dumper_class_bufr_decode_fortran.cc delete mode 100644 src/grib_dumper_class_bufr_decode_python.cc delete mode 100644 src/grib_dumper_class_bufr_encode_C.cc delete mode 100644 src/grib_dumper_class_bufr_encode_filter.cc delete mode 100644 src/grib_dumper_class_bufr_encode_fortran.cc delete mode 100644 src/grib_dumper_class_bufr_encode_python.cc delete mode 100644 src/grib_dumper_class_bufr_simple.cc delete mode 100644 src/grib_dumper_class_debug.cc delete mode 100644 src/grib_dumper_class_default.cc delete mode 100644 src/grib_dumper_class_grib_encode_C.cc delete mode 100644 src/grib_dumper_class_json.cc delete mode 100644 src/grib_dumper_class_serialize.cc delete mode 100644 src/grib_dumper_class_wmo.cc create mode 100644 src/grib_dumper_factory.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 01d497bb1..5c667eff3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,7 @@ # include_directories( + "${CMAKE_CURRENT_SOURCE_DIR}/dumper" "${CMAKE_CURRENT_SOURCE_DIR}/accessor" "${CMAKE_CURRENT_SOURCE_DIR}/geo_iterator" "${CMAKE_CURRENT_SOURCE_DIR}/geo_nearest" @@ -272,23 +273,22 @@ list( APPEND eccodes_src_files accessor/grib_accessor_class_reference_value_error.cc grib_memory.cc grib_buffer.cc - grib_dumper.cc - grib_dumper_class_serialize.cc - grib_dumper_class_debug.cc - grib_dumper_class_default.cc - grib_dumper_class_bufr_encode_C.cc - grib_dumper_class_bufr_encode_filter.cc - grib_dumper_class_bufr_encode_fortran.cc - grib_dumper_class_bufr_encode_python.cc - grib_dumper_class_bufr_decode_C.cc - grib_dumper_class_bufr_decode_filter.cc - grib_dumper_class_bufr_decode_fortran.cc - grib_dumper_class_bufr_decode_python.cc - grib_dumper_class_bufr_simple.cc - grib_dumper_class_json.cc - grib_dumper_class_grib_encode_C.cc - grib_dumper_class_wmo.cc - grib_dumper_class.cc + dumper/grib_dumper.cc + dumper/grib_dumper_class_serialize.cc + dumper/grib_dumper_class_debug.cc + dumper/grib_dumper_class_default.cc + dumper/grib_dumper_class_bufr_encode_C.cc + dumper/grib_dumper_class_bufr_encode_filter.cc + dumper/grib_dumper_class_bufr_encode_fortran.cc + dumper/grib_dumper_class_bufr_encode_python.cc + dumper/grib_dumper_class_bufr_decode_C.cc + dumper/grib_dumper_class_bufr_decode_filter.cc + dumper/grib_dumper_class_bufr_decode_fortran.cc + dumper/grib_dumper_class_bufr_decode_python.cc + dumper/grib_dumper_class_bufr_simple.cc + dumper/grib_dumper_class_json.cc + dumper/grib_dumper_class_grib_encode_C.cc + dumper/grib_dumper_class_wmo.cc grib_context.cc grib_date.cc grib_fieldset.cc @@ -361,8 +361,7 @@ list( APPEND eccodes_src_files grib_accessor_factory.h grib_api_internal.h eccodes_prototypes.h - grib_dumper_class.h - grib_dumper_factory.h + grib_dumper_factory.cc grib_iterator_factory.cc grib_nearest_factory.cc grib_yacc.h diff --git a/src/accessor/grib_accessor.cc b/src/accessor/grib_accessor.cc index f722e333c..af5f6dcf2 100644 --- a/src/accessor/grib_accessor.cc +++ b/src/accessor/grib_accessor.cc @@ -13,7 +13,6 @@ ***************************************************************************/ #include "grib_accessor.h" -#include // Note: A fast cut-down version of strcmp which does NOT return -1 // 0 means input strings are equal and 1 means not equal diff --git a/src/accessor/grib_accessor.h b/src/accessor/grib_accessor.h index 9af7b034d..26b04b09f 100644 --- a/src/accessor/grib_accessor.h +++ b/src/accessor/grib_accessor.h @@ -12,8 +12,11 @@ #pragma once #include "grib_api_internal.h" -#include "grib_dumper.h" -#include "grib_value.h" +#include "dumper/grib_dumper.h" + +namespace eccodes { +class Dumper; +} class grib_accessor { public: diff --git a/src/accessor/grib_accessor_class_ascii.cc b/src/accessor/grib_accessor_class_ascii.cc index 57a1ff57c..244ec79b0 100644 --- a/src/accessor/grib_accessor_class_ascii.cc +++ b/src/accessor/grib_accessor_class_ascii.cc @@ -33,7 +33,7 @@ size_t grib_accessor_ascii_t::string_length() void grib_accessor_ascii_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } long grib_accessor_ascii_t::get_native_type() diff --git a/src/accessor/grib_accessor_class_bitmap.cc b/src/accessor/grib_accessor_class_bitmap.cc index e4cc4be80..9eafa9cdc 100644 --- a/src/accessor/grib_accessor_class_bitmap.cc +++ b/src/accessor/grib_accessor_class_bitmap.cc @@ -74,7 +74,7 @@ void grib_accessor_bitmap_t::dump(eccodes::Dumper* dumper) value_count(&len); snprintf(label, sizeof(label), "Bitmap of %ld values", len); - grib_dump_bytes(dumper, this, label); + dumper->dump_bytes(this, label); } int grib_accessor_bitmap_t::unpack_long(long* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_blob.cc b/src/accessor/grib_accessor_class_blob.cc index 55f970cb0..6c238b774 100644 --- a/src/accessor/grib_accessor_class_blob.cc +++ b/src/accessor/grib_accessor_class_blob.cc @@ -41,5 +41,5 @@ int grib_accessor_blob_t::unpack_bytes(unsigned char* buffer, size_t* len) void grib_accessor_blob_t::dump(eccodes::Dumper* dumper) { - grib_dump_bytes(dumper, this, NULL); + dumper->dump_bytes(this, NULL); } diff --git a/src/accessor/grib_accessor_class_bufr_data_array.cc b/src/accessor/grib_accessor_class_bufr_data_array.cc index 6759f505f..d69f14d00 100644 --- a/src/accessor/grib_accessor_class_bufr_data_array.cc +++ b/src/accessor/grib_accessor_class_bufr_data_array.cc @@ -3229,7 +3229,7 @@ void grib_accessor_bufr_data_array_t::dump(eccodes::Dumper* dumper) { // grib_accessor_bufr_data_array_t *self =(grib_accessor_bufr_data_array_t*)a; // int err=process_elements(a,PROCESS_DECODE); - // grib_dump_section(dumper,a,self->dataKeys_ ->block); + // dumper->dump_section(a,self->dataKeys_ ->block); return; } diff --git a/src/accessor/grib_accessor_class_bufr_data_element.cc b/src/accessor/grib_accessor_class_bufr_data_element.cc index f7bdfbb56..69cef9407 100644 --- a/src/accessor/grib_accessor_class_bufr_data_element.cc +++ b/src/accessor/grib_accessor_class_bufr_data_element.cc @@ -85,13 +85,13 @@ void grib_accessor_bufr_data_element_t::dump(eccodes::Dumper* dumper) switch (ntype) { case GRIB_TYPE_LONG: - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); break; case GRIB_TYPE_DOUBLE: - grib_dump_values(dumper, this); + dumper->dump_values(this); break; case GRIB_TYPE_STRING: - grib_dump_string_array(dumper, this, NULL); + dumper->dump_string_array(this, NULL); break; } } diff --git a/src/accessor/grib_accessor_class_bufr_group.cc b/src/accessor/grib_accessor_class_bufr_group.cc index cbc1b27b8..437bf6ad3 100644 --- a/src/accessor/grib_accessor_class_bufr_group.cc +++ b/src/accessor/grib_accessor_class_bufr_group.cc @@ -15,7 +15,7 @@ grib_accessor* grib_accessor_bufr_group = &_grib_accessor_bufr_group; void grib_accessor_bufr_group_t::dump(eccodes::Dumper* dumper) { - grib_dump_section(dumper, this, sub_section_->block); + dumper->dump_section(this, sub_section_->block); } grib_accessor* grib_accessor_bufr_group_t::next(grib_accessor* a, int explore) diff --git a/src/accessor/grib_accessor_class_bufr_string_values.cc b/src/accessor/grib_accessor_class_bufr_string_values.cc index 910a06dd0..de74930ab 100644 --- a/src/accessor/grib_accessor_class_bufr_string_values.cc +++ b/src/accessor/grib_accessor_class_bufr_string_values.cc @@ -26,7 +26,7 @@ void grib_accessor_bufr_string_values_t::init(const long len, grib_arguments* ar void grib_accessor_bufr_string_values_t::dump(eccodes::Dumper* dumper) { - grib_dump_string_array(dumper, this, NULL); + dumper->dump_string_array(this, NULL); } grib_accessor* grib_accessor_bufr_string_values_t::get_accessor() diff --git a/src/accessor/grib_accessor_class_closest_date.cc b/src/accessor/grib_accessor_class_closest_date.cc index 893418bf5..f683e1008 100644 --- a/src/accessor/grib_accessor_class_closest_date.cc +++ b/src/accessor/grib_accessor_class_closest_date.cc @@ -35,7 +35,7 @@ void grib_accessor_closest_date_t::init(const long l, grib_arguments* c) void grib_accessor_closest_date_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } int grib_accessor_closest_date_t::unpack_long(long* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_codeflag.cc b/src/accessor/grib_accessor_class_codeflag.cc index b26b7fad8..3a0fa49c7 100644 --- a/src/accessor/grib_accessor_class_codeflag.cc +++ b/src/accessor/grib_accessor_class_codeflag.cc @@ -113,5 +113,5 @@ void grib_accessor_codeflag_t::dump(eccodes::Dumper* dumper) unpack_long(&v, &llen); grib_get_codeflag(v, flagname); - grib_dump_bits(dumper, this, flagname); + dumper->dump_bits(this, flagname); } diff --git a/src/accessor/grib_accessor_class_codetable.cc b/src/accessor/grib_accessor_class_codetable.cc index cce8109c5..ab2f6f67e 100644 --- a/src/accessor/grib_accessor_class_codetable.cc +++ b/src/accessor/grib_accessor_class_codetable.cc @@ -560,7 +560,7 @@ void grib_accessor_codetable_t::dump(eccodes::Dumper* dumper) } strcat(comment, ") "); - grib_dump_long(dumper, this, comment); + dumper->dump_long(this, comment); } int grib_accessor_codetable_t::unpack_string(char* buffer, size_t* len) diff --git a/src/accessor/grib_accessor_class_concept.cc b/src/accessor/grib_accessor_class_concept.cc index 9354cfa16..da4bf40f7 100644 --- a/src/accessor/grib_accessor_class_concept.cc +++ b/src/accessor/grib_accessor_class_concept.cc @@ -42,7 +42,7 @@ void grib_accessor_concept_t::init(const long len, grib_arguments* args) void grib_accessor_concept_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } // See ECC-1905 diff --git a/src/accessor/grib_accessor_class_data_apply_bitmap.cc b/src/accessor/grib_accessor_class_data_apply_bitmap.cc index cb4bc7a9f..298f5e394 100644 --- a/src/accessor/grib_accessor_class_data_apply_bitmap.cc +++ b/src/accessor/grib_accessor_class_data_apply_bitmap.cc @@ -29,7 +29,7 @@ void grib_accessor_data_apply_bitmap_t::init(const long v, grib_arguments* args) } void grib_accessor_data_apply_bitmap_t::dump(eccodes::Dumper* dumper) { - grib_dump_values(dumper, this); + dumper->dump_values(this); } int grib_accessor_data_apply_bitmap_t::value_count(long* count) diff --git a/src/accessor/grib_accessor_class_data_apply_boustrophedonic.cc b/src/accessor/grib_accessor_class_data_apply_boustrophedonic.cc index dfbd12bfe..b73c74a9d 100644 --- a/src/accessor/grib_accessor_class_data_apply_boustrophedonic.cc +++ b/src/accessor/grib_accessor_class_data_apply_boustrophedonic.cc @@ -28,7 +28,7 @@ void grib_accessor_data_apply_boustrophedonic_t::init(const long v, grib_argumen } void grib_accessor_data_apply_boustrophedonic_t::dump(eccodes::Dumper* dumper) { - grib_dump_values(dumper, this); + dumper->dump_values(this); } int grib_accessor_data_apply_boustrophedonic_t::value_count(long* numberOfPoints) diff --git a/src/accessor/grib_accessor_class_data_apply_boustrophedonic_bitmap.cc b/src/accessor/grib_accessor_class_data_apply_boustrophedonic_bitmap.cc index 3704d0022..5c4d37885 100644 --- a/src/accessor/grib_accessor_class_data_apply_boustrophedonic_bitmap.cc +++ b/src/accessor/grib_accessor_class_data_apply_boustrophedonic_bitmap.cc @@ -33,7 +33,7 @@ void grib_accessor_data_apply_boustrophedonic_bitmap_t::init(const long v, grib_ void grib_accessor_data_apply_boustrophedonic_bitmap_t::dump(eccodes::Dumper* dumper) { - grib_dump_values(dumper, this); + dumper->dump_values(this); } int grib_accessor_data_apply_boustrophedonic_bitmap_t::value_count(long* count) diff --git a/src/accessor/grib_accessor_class_data_g1second_order_general_extended_packing.cc b/src/accessor/grib_accessor_class_data_g1second_order_general_extended_packing.cc index 2ee15e425..9bd2eea03 100644 --- a/src/accessor/grib_accessor_class_data_g1second_order_general_extended_packing.cc +++ b/src/accessor/grib_accessor_class_data_g1second_order_general_extended_packing.cc @@ -45,7 +45,7 @@ long number_of_bits(grib_handle* h, unsigned long x) n++; i++; if (i >= count) { - /*grib_dump_content(h, stdout,"debug", ~0, NULL);*/ + /*h->dump_content(stdout,"debug", ~0, NULL);*/ grib_context_log(h->context, GRIB_LOG_FATAL, "grib_accessor_data_g1second_order_general_extended_packing: Number out of range: %ld", x); } diff --git a/src/accessor/grib_accessor_class_data_secondary_bitmap.cc b/src/accessor/grib_accessor_class_data_secondary_bitmap.cc index bde3ac250..566309d54 100644 --- a/src/accessor/grib_accessor_class_data_secondary_bitmap.cc +++ b/src/accessor/grib_accessor_class_data_secondary_bitmap.cc @@ -26,7 +26,7 @@ void grib_accessor_data_secondary_bitmap_t::init(const long v, grib_arguments* a void grib_accessor_data_secondary_bitmap_t::dump(eccodes::Dumper* dumper) { - grib_dump_values(dumper, this); + dumper->dump_values(this); } int grib_accessor_data_secondary_bitmap_t::unpack_double(double* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_data_shsimple_packing.cc b/src/accessor/grib_accessor_class_data_shsimple_packing.cc index 459017f17..897460856 100644 --- a/src/accessor/grib_accessor_class_data_shsimple_packing.cc +++ b/src/accessor/grib_accessor_class_data_shsimple_packing.cc @@ -26,7 +26,7 @@ void grib_accessor_data_shsimple_packing_t::init(const long v, grib_arguments* a void grib_accessor_data_shsimple_packing_t::dump(eccodes::Dumper* dumper) { - grib_dump_values(dumper, this); + dumper->dump_values(this); } int grib_accessor_data_shsimple_packing_t::pack_double(const double* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_dictionary.cc b/src/accessor/grib_accessor_class_dictionary.cc index 514fbab73..40fd31399 100644 --- a/src/accessor/grib_accessor_class_dictionary.cc +++ b/src/accessor/grib_accessor_class_dictionary.cc @@ -147,13 +147,13 @@ void grib_accessor_dictionary_t::dump(eccodes::Dumper* dumper) { switch (get_native_type()) { case GRIB_TYPE_STRING: - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); break; case GRIB_TYPE_LONG: - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); break; case GRIB_TYPE_DOUBLE: - grib_dump_double(dumper, this, NULL); + dumper->dump_double(this, NULL); break; } } diff --git a/src/accessor/grib_accessor_class_double.cc b/src/accessor/grib_accessor_class_double.cc index 8fd64bd97..bc440e025 100644 --- a/src/accessor/grib_accessor_class_double.cc +++ b/src/accessor/grib_accessor_class_double.cc @@ -55,7 +55,7 @@ int grib_accessor_double_t::unpack_string(char* v, size_t* len) void grib_accessor_double_t::dump(eccodes::Dumper* dumper) { - grib_dump_values(dumper, this); + dumper->dump_values(this); } int grib_accessor_double_t::compare(grib_accessor* b) diff --git a/src/accessor/grib_accessor_class_g1_half_byte_codeflag.cc b/src/accessor/grib_accessor_class_g1_half_byte_codeflag.cc index 8227aa761..75bb0c835 100644 --- a/src/accessor/grib_accessor_class_g1_half_byte_codeflag.cc +++ b/src/accessor/grib_accessor_class_g1_half_byte_codeflag.cc @@ -23,7 +23,7 @@ void grib_accessor_g1_half_byte_codeflag_t::init(const long len, grib_arguments* void grib_accessor_g1_half_byte_codeflag_t::dump(eccodes::Dumper* dumper) { - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); } int grib_accessor_g1_half_byte_codeflag_t::unpack_long(long* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_g1day_of_the_year_date.cc b/src/accessor/grib_accessor_class_g1day_of_the_year_date.cc index 581289969..2db251859 100644 --- a/src/accessor/grib_accessor_class_g1day_of_the_year_date.cc +++ b/src/accessor/grib_accessor_class_g1day_of_the_year_date.cc @@ -21,7 +21,7 @@ void grib_accessor_g1day_of_the_year_date_t::init(const long l, grib_arguments* void grib_accessor_g1day_of_the_year_date_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } int grib_accessor_g1day_of_the_year_date_t::unpack_string(char* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_g1forecastmonth.cc b/src/accessor/grib_accessor_class_g1forecastmonth.cc index fcf803ab0..81231dd17 100644 --- a/src/accessor/grib_accessor_class_g1forecastmonth.cc +++ b/src/accessor/grib_accessor_class_g1forecastmonth.cc @@ -31,7 +31,7 @@ void grib_accessor_g1forecastmonth_t::init(const long l, grib_arguments* c) void grib_accessor_g1forecastmonth_t::dump(eccodes::Dumper* dumper) { - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); } static int calculate_fcmonth(grib_accessor* a, long verification_yearmonth, long base_date, long day, long hour, long* result) diff --git a/src/accessor/grib_accessor_class_g1step_range.cc b/src/accessor/grib_accessor_class_g1step_range.cc index a116429ca..7d4a38b95 100644 --- a/src/accessor/grib_accessor_class_g1step_range.cc +++ b/src/accessor/grib_accessor_class_g1step_range.cc @@ -38,7 +38,7 @@ void grib_accessor_g1step_range_t::init(const long l, grib_arguments* c) void grib_accessor_g1step_range_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } static const int u2s1[] = { diff --git a/src/accessor/grib_accessor_class_g2end_step.cc b/src/accessor/grib_accessor_class_g2end_step.cc index b9fe1db32..6f3f600f1 100644 --- a/src/accessor/grib_accessor_class_g2end_step.cc +++ b/src/accessor/grib_accessor_class_g2end_step.cc @@ -47,7 +47,7 @@ void grib_accessor_g2end_step_t::init(const long l, grib_arguments* c) void grib_accessor_g2end_step_t::dump(eccodes::Dumper* dumper) { - grib_dump_double(dumper, this, NULL); + dumper->dump_double(this, NULL); } // See GRIB-488 diff --git a/src/accessor/grib_accessor_class_g2step_range.cc b/src/accessor/grib_accessor_class_g2step_range.cc index bab5cc4b3..0fed0aba6 100644 --- a/src/accessor/grib_accessor_class_g2step_range.cc +++ b/src/accessor/grib_accessor_class_g2step_range.cc @@ -30,7 +30,7 @@ void grib_accessor_g2step_range_t::init(const long l, grib_arguments* c) // static void dump(grib_accessor* a, eccodes::Dumper* dumper) //{ -// grib_dump_string(dumper, a, NULL); +// dumper->dump_string(a, NULL); //} int grib_accessor_g2step_range_t::unpack_string(char* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_gen.h b/src/accessor/grib_accessor_class_gen.h index 7b5e480fe..330b07ac5 100644 --- a/src/accessor/grib_accessor_class_gen.h +++ b/src/accessor/grib_accessor_class_gen.h @@ -12,6 +12,7 @@ #include "grib_api_internal.h" #include "grib_accessor.h" +#include "grib_value.h" #include diff --git a/src/accessor/grib_accessor_class_group.cc b/src/accessor/grib_accessor_class_group.cc index 957e01393..5a51394c1 100644 --- a/src/accessor/grib_accessor_class_group.cc +++ b/src/accessor/grib_accessor_class_group.cc @@ -63,7 +63,7 @@ size_t grib_accessor_group_t::string_length() void grib_accessor_group_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } long grib_accessor_group_t::get_native_type() diff --git a/src/accessor/grib_accessor_class_hash_array.cc b/src/accessor/grib_accessor_class_hash_array.cc index 415d2aa1f..556bec2e4 100644 --- a/src/accessor/grib_accessor_class_hash_array.cc +++ b/src/accessor/grib_accessor_class_hash_array.cc @@ -25,7 +25,7 @@ void grib_accessor_hash_array_t::init(const long len, grib_arguments* args) void grib_accessor_hash_array_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } int grib_accessor_hash_array_t::pack_double(const double* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_iterator.cc b/src/accessor/grib_accessor_class_iterator.cc index 9601730bd..8e946b1d9 100644 --- a/src/accessor/grib_accessor_class_iterator.cc +++ b/src/accessor/grib_accessor_class_iterator.cc @@ -22,5 +22,5 @@ void grib_accessor_iterator_t::init(const long l, grib_arguments* args) void grib_accessor_iterator_t::dump(eccodes::Dumper* dumper) { /* TODO: pass args */ - grib_dump_label(dumper, this, NULL); + dumper->dump_label(this, NULL); } diff --git a/src/accessor/grib_accessor_class_julian_date.cc b/src/accessor/grib_accessor_class_julian_date.cc index 500c9ebab..52c9aef90 100644 --- a/src/accessor/grib_accessor_class_julian_date.cc +++ b/src/accessor/grib_accessor_class_julian_date.cc @@ -50,7 +50,7 @@ void grib_accessor_julian_date_t::init(const long l, grib_arguments* c) void grib_accessor_julian_date_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } int grib_accessor_julian_date_t::unpack_double(double* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_julian_day.cc b/src/accessor/grib_accessor_class_julian_day.cc index ed8315f28..51fd78242 100644 --- a/src/accessor/grib_accessor_class_julian_day.cc +++ b/src/accessor/grib_accessor_class_julian_day.cc @@ -29,7 +29,7 @@ void grib_accessor_julian_day_t::init(const long l, grib_arguments* c) void grib_accessor_julian_day_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } int grib_accessor_julian_day_t::pack_long(const long* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_label.cc b/src/accessor/grib_accessor_class_label.cc index fc400da61..67632e54f 100644 --- a/src/accessor/grib_accessor_class_label.cc +++ b/src/accessor/grib_accessor_class_label.cc @@ -23,7 +23,7 @@ void grib_accessor_label_t::init(const long len, grib_arguments* arg) void grib_accessor_label_t::dump(eccodes::Dumper* dumper) { - grib_dump_label(dumper, this, NULL); + dumper->dump_label(this, NULL); } long grib_accessor_label_t::get_native_type() diff --git a/src/accessor/grib_accessor_class_long.cc b/src/accessor/grib_accessor_class_long.cc index 3b3137da0..50a139d1b 100644 --- a/src/accessor/grib_accessor_class_long.cc +++ b/src/accessor/grib_accessor_class_long.cc @@ -25,7 +25,7 @@ long grib_accessor_long_t::get_native_type() void grib_accessor_long_t::dump(eccodes::Dumper* dumper) { - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); } int grib_accessor_long_t::unpack_string(char* v, size_t* len) diff --git a/src/accessor/grib_accessor_class_lookup.cc b/src/accessor/grib_accessor_class_lookup.cc index d87a5e164..b959fdfd6 100644 --- a/src/accessor/grib_accessor_class_lookup.cc +++ b/src/accessor/grib_accessor_class_lookup.cc @@ -50,7 +50,7 @@ void grib_accessor_lookup_t::dump(eccodes::Dumper* dumper) snprintf(buf, sizeof(buf), "%s %lu %ld-%ld", msg, v, (long)offset_ + loffset_, (long)llength_); - grib_dump_long(dumper, this, buf); + dumper->dump_long(this, buf); } int grib_accessor_lookup_t::unpack_string(char* v, size_t* len) diff --git a/src/accessor/grib_accessor_class_message_copy.cc b/src/accessor/grib_accessor_class_message_copy.cc index a1ed6d1a0..03e9f29ef 100644 --- a/src/accessor/grib_accessor_class_message_copy.cc +++ b/src/accessor/grib_accessor_class_message_copy.cc @@ -22,7 +22,7 @@ void grib_accessor_message_copy_t::init(const long length, grib_arguments* args) void grib_accessor_message_copy_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } long grib_accessor_message_copy_t::get_native_type() diff --git a/src/accessor/grib_accessor_class_nearest.cc b/src/accessor/grib_accessor_class_nearest.cc index 4201dd8b4..2180b4743 100644 --- a/src/accessor/grib_accessor_class_nearest.cc +++ b/src/accessor/grib_accessor_class_nearest.cc @@ -22,6 +22,6 @@ void grib_accessor_nearest_t::init(const long l, grib_arguments* args) void grib_accessor_nearest_t::dump(eccodes::Dumper* dumper) { /* TODO: pass args */ - grib_dump_label(dumper, this, NULL); + dumper->dump_label(this, NULL); } diff --git a/src/accessor/grib_accessor_class_non_alpha.cc b/src/accessor/grib_accessor_class_non_alpha.cc index ab0e26026..63e3e0797 100644 --- a/src/accessor/grib_accessor_class_non_alpha.cc +++ b/src/accessor/grib_accessor_class_non_alpha.cc @@ -41,7 +41,7 @@ size_t grib_accessor_non_alpha_t::string_length() void grib_accessor_non_alpha_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } long grib_accessor_non_alpha_t::get_native_type() diff --git a/src/accessor/grib_accessor_class_optimal_step_units.cc b/src/accessor/grib_accessor_class_optimal_step_units.cc index dd1692f6b..4207d9c98 100644 --- a/src/accessor/grib_accessor_class_optimal_step_units.cc +++ b/src/accessor/grib_accessor_class_optimal_step_units.cc @@ -31,7 +31,7 @@ void grib_accessor_optimal_step_units_t::init(const long l, grib_arguments* c) void grib_accessor_optimal_step_units_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } size_t grib_accessor_optimal_step_units_t::string_length() diff --git a/src/accessor/grib_accessor_class_padto.cc b/src/accessor/grib_accessor_class_padto.cc index 84a7b8133..0a80cef69 100644 --- a/src/accessor/grib_accessor_class_padto.cc +++ b/src/accessor/grib_accessor_class_padto.cc @@ -37,5 +37,5 @@ void grib_accessor_padto_t::init(const long len, grib_arguments* arg) void grib_accessor_padto_t::dump(eccodes::Dumper* dumper) { - /*grib_dump_string(dumper,a,NULL);*/ + /*dumper->dump_string(a,NULL);*/ } diff --git a/src/accessor/grib_accessor_class_position.cc b/src/accessor/grib_accessor_class_position.cc index 241350f49..0a064845d 100644 --- a/src/accessor/grib_accessor_class_position.cc +++ b/src/accessor/grib_accessor_class_position.cc @@ -30,7 +30,7 @@ long grib_accessor_position_t::get_native_type() void grib_accessor_position_t::dump(eccodes::Dumper* dumper) { - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); } int grib_accessor_position_t::unpack_long(long* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_section.cc b/src/accessor/grib_accessor_class_section.cc index e29c79780..ceded90a1 100644 --- a/src/accessor/grib_accessor_class_section.cc +++ b/src/accessor/grib_accessor_class_section.cc @@ -23,7 +23,7 @@ void grib_accessor_section_t::init(const long len, grib_arguments* arg) void grib_accessor_section_t::dump(eccodes::Dumper* dumper) { - grib_dump_section(dumper, this, sub_section_->block); + dumper->dump_section(this, sub_section_->block); } long grib_accessor_section_t::byte_count() diff --git a/src/accessor/grib_accessor_class_section_length.cc b/src/accessor/grib_accessor_class_section_length.cc index ed393080e..f82247d1e 100644 --- a/src/accessor/grib_accessor_class_section_length.cc +++ b/src/accessor/grib_accessor_class_section_length.cc @@ -25,7 +25,7 @@ void grib_accessor_section_length_t::init(const long len, grib_arguments* arg) void grib_accessor_section_length_t::dump(eccodes::Dumper* dumper) { - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); } int grib_accessor_section_length_t::value_count(long* c) diff --git a/src/accessor/grib_accessor_class_sexagesimal2decimal.cc b/src/accessor/grib_accessor_class_sexagesimal2decimal.cc index 28bf8ff13..e261363ba 100644 --- a/src/accessor/grib_accessor_class_sexagesimal2decimal.cc +++ b/src/accessor/grib_accessor_class_sexagesimal2decimal.cc @@ -21,7 +21,7 @@ void grib_accessor_sexagesimal2decimal_t::init(const long len, grib_arguments* a void grib_accessor_sexagesimal2decimal_t::dump(eccodes::Dumper* dumper) { - grib_dump_double(dumper, this, NULL); + dumper->dump_double(this, NULL); } long grib_accessor_sexagesimal2decimal_t::get_native_type() diff --git a/src/accessor/grib_accessor_class_signed.cc b/src/accessor/grib_accessor_class_signed.cc index 12fac6487..7482422da 100644 --- a/src/accessor/grib_accessor_class_signed.cc +++ b/src/accessor/grib_accessor_class_signed.cc @@ -32,9 +32,9 @@ void grib_accessor_signed_t::dump(eccodes::Dumper* dumper) long rlen = 0; value_count(&rlen); if (rlen == 1) - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); else - grib_dump_values(dumper, this); + dumper->dump_values(this); } static const long ones[] = { diff --git a/src/accessor/grib_accessor_class_smart_table.cc b/src/accessor/grib_accessor_class_smart_table.cc index ddaa20cee..570ffb170 100644 --- a/src/accessor/grib_accessor_class_smart_table.cc +++ b/src/accessor/grib_accessor_class_smart_table.cc @@ -279,7 +279,7 @@ void grib_smart_table_delete(grib_context* c) void grib_accessor_smart_table_t::dump(eccodes::Dumper* dumper) { - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); } int grib_accessor_smart_table_t::unpack_string(char* buffer, size_t* len) diff --git a/src/accessor/grib_accessor_class_smart_table_column.cc b/src/accessor/grib_accessor_class_smart_table_column.cc index d7aeed97d..3c2143994 100644 --- a/src/accessor/grib_accessor_class_smart_table_column.cc +++ b/src/accessor/grib_accessor_class_smart_table_column.cc @@ -32,10 +32,10 @@ void grib_accessor_smart_table_column_t::dump(eccodes::Dumper* dumper) switch (type) { case GRIB_TYPE_LONG: - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); break; case GRIB_TYPE_STRING: - grib_dump_string_array(dumper, this, NULL); + dumper->dump_string_array(this, NULL); break; } } diff --git a/src/accessor/grib_accessor_class_step_in_units.cc b/src/accessor/grib_accessor_class_step_in_units.cc index 66abeb76d..7f731d221 100644 --- a/src/accessor/grib_accessor_class_step_in_units.cc +++ b/src/accessor/grib_accessor_class_step_in_units.cc @@ -30,7 +30,7 @@ void grib_accessor_step_in_units_t::init(const long l, grib_arguments* c) void grib_accessor_step_in_units_t::dump(eccodes::Dumper* dumper) { - grib_dump_double(dumper, this, NULL); + dumper->dump_double(this, NULL); } int grib_accessor_step_in_units_t::unpack_long(long* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_to_double.cc b/src/accessor/grib_accessor_class_to_double.cc index 8fd1b2b17..90c07a0d3 100644 --- a/src/accessor/grib_accessor_class_to_double.cc +++ b/src/accessor/grib_accessor_class_to_double.cc @@ -52,7 +52,7 @@ size_t grib_accessor_to_double_t::string_length() void grib_accessor_to_double_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } long grib_accessor_to_double_t::get_native_type() diff --git a/src/accessor/grib_accessor_class_to_integer.cc b/src/accessor/grib_accessor_class_to_integer.cc index 6bec1fe52..39fd944e0 100644 --- a/src/accessor/grib_accessor_class_to_integer.cc +++ b/src/accessor/grib_accessor_class_to_integer.cc @@ -49,7 +49,7 @@ size_t grib_accessor_to_integer_t::string_length() void grib_accessor_to_integer_t::dump(eccodes::Dumper* dumper) { - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); } long grib_accessor_to_integer_t::get_native_type() diff --git a/src/accessor/grib_accessor_class_to_string.cc b/src/accessor/grib_accessor_class_to_string.cc index 85a2da6bb..ed32a4738 100644 --- a/src/accessor/grib_accessor_class_to_string.cc +++ b/src/accessor/grib_accessor_class_to_string.cc @@ -48,7 +48,7 @@ size_t grib_accessor_to_string_t::string_length() void grib_accessor_to_string_t::dump(eccodes::Dumper* dumper) { - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); } long grib_accessor_to_string_t::get_native_type() diff --git a/src/accessor/grib_accessor_class_transient_darray.cc b/src/accessor/grib_accessor_class_transient_darray.cc index be23e1198..1d0d7c612 100644 --- a/src/accessor/grib_accessor_class_transient_darray.cc +++ b/src/accessor/grib_accessor_class_transient_darray.cc @@ -23,7 +23,7 @@ void grib_accessor_transient_darray_t::init(const long length, grib_arguments* a void grib_accessor_transient_darray_t::dump(eccodes::Dumper* dumper) { - grib_dump_double(dumper, this, NULL); + dumper->dump_double(this, NULL); } int grib_accessor_transient_darray_t::pack_double(const double* val, size_t* len) diff --git a/src/accessor/grib_accessor_class_unsigned.cc b/src/accessor/grib_accessor_class_unsigned.cc index 69c6a8bfc..f9e19f466 100644 --- a/src/accessor/grib_accessor_class_unsigned.cc +++ b/src/accessor/grib_accessor_class_unsigned.cc @@ -41,9 +41,9 @@ void grib_accessor_unsigned_t::dump(eccodes::Dumper* dumper) long rlen = 0; value_count(&rlen); if (rlen == 1) - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); else - grib_dump_values(dumper, this); + dumper->dump_values(this); } static const unsigned long ones[] = { diff --git a/src/accessor/grib_accessor_class_values.cc b/src/accessor/grib_accessor_class_values.cc index f612f76f3..a6758673f 100644 --- a/src/accessor/grib_accessor_class_values.cc +++ b/src/accessor/grib_accessor_class_values.cc @@ -65,7 +65,7 @@ long grib_accessor_values_t::get_native_type() void grib_accessor_values_t::dump(eccodes::Dumper* dumper) { - grib_dump_values(dumper, this); + dumper->dump_values(this); } long grib_accessor_values_t::byte_count() diff --git a/src/accessor/grib_accessor_class_variable.cc b/src/accessor/grib_accessor_class_variable.cc index dfe50fd4a..5b9bd750c 100644 --- a/src/accessor/grib_accessor_class_variable.cc +++ b/src/accessor/grib_accessor_class_variable.cc @@ -80,15 +80,15 @@ void grib_accessor_variable_t::dump(eccodes::Dumper* dumper) { switch (type_) { case GRIB_TYPE_DOUBLE: - grib_dump_double(dumper, this, NULL); + dumper->dump_double(this, NULL); break; case GRIB_TYPE_LONG: - grib_dump_long(dumper, this, NULL); + dumper->dump_long(this, NULL); break; default: - grib_dump_string(dumper, this, NULL); + dumper->dump_string(this, NULL); break; } } diff --git a/src/accessor/grib_accessor_class_when.cc b/src/accessor/grib_accessor_class_when.cc index f1bd6a52b..037e9a97e 100644 --- a/src/accessor/grib_accessor_class_when.cc +++ b/src/accessor/grib_accessor_class_when.cc @@ -23,7 +23,7 @@ void grib_accessor_when_t::init(const long len, grib_arguments* arg) void grib_accessor_when_t::dump(eccodes::Dumper* dumper) { - /* grib_dump_when(dumper,a,NULL); */ + /* dumper->dump_when(a,NULL); */ } int grib_accessor_when_t::notify_change(grib_accessor* changed) diff --git a/src/accessor/run.sh b/src/accessor/run.sh new file mode 100755 index 000000000..ee58ddc9d --- /dev/null +++ b/src/accessor/run.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +if [ $# -eq 0 ]; then + echo "Usage: $0 " + exit 1 +fi + + + +blacklist=( \ + "grib_accessor_class_gen.cc" \ + "grib_accessor_class_bits.cc" \ + "grib_accessor_class_bitmap.cc" \ + "grib_accessor_class_bufr_elements_table.cc" \ + "grib_accessor_class_bufr_data_array.cc" \ + "grib_accessor_class_bufr_data_element.cc" \ + "grib_accessor_class_unpack_bufr_values.cc" \ + "grib_accessor_class_bytes.cc" \ + "grib_accessor_class_smart_table_column.cc" \ + "grib_accessor_class_bufr_string_values.cc" \ + "grib_accessor_class_codetable_units.cc" \ + "grib_accessor_class_codetable_title.cc" \ + "grib_accessor_class_data_g22order_packing.cc" \ + "grib_accessor_class_g2step_range.cc " \ + "grib_accessor_class_mars_step.cc" \ + "grib_accessor_class_g2level.cc" \ + "grib_accessor_class_g2end_step.cc" \ + "grib_accessor_class_closest_date.cc" \ + "grib_accessor_class_scale.cc" \ + "grib_accessor_class_ibmfloat.cc" \ + "grib_accessor_class_ieeefloat.cc" \ + "grib_accessor_class_section_padding.cc" \ + "grib_accessor_class_section_pointer.cc" \ + "grib_accessor_class_signed.cc" \ + "grib_accessor_class_step_in_units.cc" \ + "grib_accessor_class_optimal_step_units.cc" \ + "grib_accessor_class_g1_message_length.cc" \ + "grib_accessor_class_sprintf.cc" \ + "grib_accessor_class_simple_packing_error.cc" \ + "grib_accessor_class_data_simple_packing.cc" \ + "grib_accessor_class_data_sh_packed.cc" \ + "grib_accessor_class_data_sh_unpacked.cc" \ + "grib_accessor_class_data_g1simple_packing.cc" \ + "grib_accessor_class_second_order_bits_per_value.cc" \ + "grib_accessor_class_data_g2simple_packing.cc" \ + "grib_accessor_class_data_g2simple_packing_with_preprocessing.cc" \ + "grib_accessor_class_data_g2complex_packing.cc" \ + "grib_accessor_class_data_g1second_order_row_by_row_packing.cc" \ + "grib_accessor_class_data_g1second_order_constant_width_packing.cc" \ + "grib_accessor_class_data_g1second_order_general_packing.cc" \ + + +) + +fns="$@" + +for fn in ${fns[@]}; do + echo "Processing $fn" + bn=$(basename $fn) + for bl in ${blacklist[@]}; do + if [ $bn == $bl ]; then + echo "Skipping $fn" + continue 2 + fi + done + + if [ $bn == "grib_accessor_gen.cc" ]; then + echo "Skipping $fn" + continue + fi + + #sed -i -E "s/#(accessor\/${bn})/\1/g" ../CMakeLists.txt + + #name=$(echo $bn | sed -E 's/\.cc//g') + #echo "name: $name" + #name=$(echo $name | sed -E 's/^.{20}//g') + #echo "name: $name" + + #sed -i -E "s/\/\/(\{ \"${name}\", &grib_accessor_class_${name}, \})/\1/g" ../grib_accessor_factory.h + #sed -i -E "s/#(${name}, &grib_accessor_class_${name})/\1/g" ../grib_accessor_factory_hash_list + #sed -i -E "s/\/\/(extern grib_accessor_class\* grib_accessor_class_${name})/\1/g" ../grib_accessor_class.h + + #pushd .. + #echo $PWD + #./make_accessor_class_hash.sh + #popd + + + ./transform.py $fn +done + diff --git a/src/accessor/z_check_members.py b/src/accessor/z_check_members.py new file mode 100755 index 000000000..e1cb2866a --- /dev/null +++ b/src/accessor/z_check_members.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python3 + +import sys +import re +from collections import defaultdict + + +class Member: + def __init__(self, line): + self.type = None + self.name = None + self.is_const = False + self.is_pointer = False + + # match: double dval_; + if m := re.match(r'\s*(?P\w+)\s+(?P\w+_);.*', line): + self.type = m.group('type') + self.name = m.group('name') + self.is_const = False + self.is_pointer = False + + # match: const double dval_; + if m := re.match(r'\s*const\s+(?P\w+)\s+(?P\w+_);.*', line): + self.type = m.group('type') + self.name = m.group('name') + self.is_const = True + self.is_pointer = False + + # match: double* dval_; + if m := re.match(r'\s*(?P\w+)\*\s+(?P\w+_);.*', line): + self.type = m.group('type') + self.name = m.group('name') + self.is_const = False + self.is_pointer = True + + # match: const double* dval_; + if m := re.match(r'\s*const\s+(?P\w+)\*\s+(?P\w+_);.*', line): + self.type = m.group('type') + self.name = m.group('name') + self.is_const = True + self.is_pointer = True + + + def __str__(self): + if self.is_const: + const = 'const ' + else: + const = '' + if self.is_pointer: + pointer = '*' + else: + pointer = '' + return f"{const}{self.type}{pointer} {self.name}" + + def is_member(self): + return self.type is not None + + +class Header: + def __init__(self, filename): + self.filename = filename + self.this_name = None + self.base_name = None + self.members = [] + + for line in open(filename): + member = Member(line) + if member.is_member(): + self.members.append(member) + continue + + # match: class grib_accessor_g2lon_t : public grib_accessor_double_t + # if m := re.match(r'\s*class grib_accessor_(?P[\w_]+)_t : public grib_accessor_(?P[\w_]+)_t', line): + if m := re.match(r'\s*class (?P[\w_]+) : public (?P[\w_]+)', line): + self.this_name = m.group('name') + self.base_name = m.group('base') + continue + + # match: class grib_accessor_g2lon_t : public grib_accessor_double_t + if m := re.match(r'\s*class (?P[\w_]+) : public grib_accessor', line): + self.this_name = m.group('name') + self.base_name = "grib_accessor" + continue + + # match: class grib_accessor: + if m := re.match(r'\s*class grib_accessor$', line): + self.this_name = "grib_accessor" + self.base_name = None + continue + + def as_string(self): + out = [] + out.append(f"this_name: {self.this_name}") + out.append(f"base_name: {self.base_name}") + out.append("Members:") + for member in self.members: + out.append(f" {member}\n") + return out + + + + +children = defaultdict(list) +headers = dict() +for fn in sys.argv[1:]: + print("Processing", fn) + h = Header(fn) + headers[h.this_name] = h + children[h.base_name].append(h.this_name) + # out = h.as_string() + # print(out) + +# print(headers["grib_accessor_variable_t"].members) +print(headers["grib_accessor"].members) +for name, header in headers.items(): + for member in header.members: + print(f"{name}: {member}") + + +def get_children_(base_name): + children_list = children[base_name] + if not children_list: + return [[base_name]] + else: + result = [] + for child in children_list: + children2 = get_children_(child) + for child2 in children2: + result.append([base_name] + child2) + return result + + +def make_hierarchy(): + hierarchy = [] + base_name = "grib_accessor" + children_ = children[base_name] + if not children_: + hierarchy.append([base_name]) + else: + for child in children_: + chains = get_children_(child) + for chain in chains: + hierarchy.append([base_name] + chain) + + return hierarchy + + +hierarchy = make_hierarchy() +print("Hierarchy:") +for chain in hierarchy: + print(" -> ".join(chain)) + # print(" -> ".join(chain[0:-1])) + # for name in chain: + # print(" ", name) + # for member in headers[name].members: + # print(" ", member) + + +# grib_accessor +# grib_accessor_abstract_long_vector_t (TODO) +# grib_accessor_abstract_vector_t (TODO) +# grib_accessor_ascii_t (DONE) +# grib_accessor_bitmap_t (DONE) +# grib_accessor_bytes_t (DONE) +# grib_accessor_data_complex_packing_t (DONE) +# grib_accessor_data_g1simple_packing_t (DONE) +# grib_accessor_data_g2simple_packing_t (DONE) +# grib_accessor_data_secondary_bitmap_t (DONE) +# grib_accessor_data_shsimple_packing_t (DONE) +# grib_accessor_data_simple_packing_t (DONE) +# grib_accessor_double_t (DONE) +# grib_accessor_evaluate_t (DONE) +# grib_accessor_g1date_t (DONE) +# grib_accessor_g1step_range_t (DONE) +# grib_accessor_gen_t (DONE) +# grib_accessor_long_t (DONE) +# grib_accessor_padding_t (DONE) +# grib_accessor_section_length_t (DONE) +# grib_accessor_to_double_t (DONE) +# grib_accessor_unsigned_t (DONE) +# grib_accessor_values_t (DONE) + +# sed -i -z 's/public/private/3' grib_accessor_class*.h + + +# sed -i 's/private/public/g' grib_accessor.h grib_accessor_class_abstract_long_vector.h grib_accessor_class_abstract_vector.h grib_accessor_class_ascii.h grib_accessor_class_bitmap.h grib_accessor_class_bytes.h grib_accessor_class_data_complex_packing.h grib_accessor_class_data_g1simple_packing.h grib_accessor_class_data_g2simple_packing.h grib_accessor_class_data_secondary_bitmap.h grib_accessor_class_data_shsimple_packing.h grib_accessor_class_data_simple_packing.h grib_accessor_class_double.h grib_accessor_class_evaluate.h grib_accessor_class_g1date.h grib_accessor_class_g1step_range.h grib_accessor_class_gen.h grib_accessor_class_long.h grib_accessor_class_padding.h grib_accessor_class_section_length.h grib_accessor_class_to_double.h grib_accessor_class_unsigned.h grib_accessor_class_values.h diff --git a/src/accessor/z_compare.sh b/src/accessor/z_compare.sh new file mode 100755 index 000000000..5842aa36b --- /dev/null +++ b/src/accessor/z_compare.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# if no command line parameters found +if [ $# -eq 0 ]; then + file=$(git status -s | grep "^ M" | sed "s/\s*\s/ /g" | cut -f 3 -d" " | head -1) + if [ -z "$file" ]; then + echo "No modified files found." + exit 1 + fi +else + file=$1 +fi + +echo "./src/accessor/$file" + +#diff --color=always /home/joobog/git/eccodes_develop/src/accessor/$file $file +diff -u /home/joobog/git/eccodes_develop/src/accessor/$file $file | diff-so-fancy --colors | less -R + +git status -s | grep "^M " | wc -l +git status -s | grep "^ M " | wc -l + +read -p "Enter y or n: " input +if [ "$input" = "y" ]; then\ + git add $file +else + echo "Skipping..." +fi diff --git a/src/accessor/z_constructor_headers.py b/src/accessor/z_constructor_headers.py new file mode 100755 index 000000000..26d216b0f --- /dev/null +++ b/src/accessor/z_constructor_headers.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 + +import sys +import re + +def convert(fn): + out = list() + class_name = None + + with open(fn, 'r') as f: + for line in f: + #match: grib_accessor_double_t() { class_name_ = "abstract_vector"; } + m = re.match(r'.*grib_accessor_(?P\w*)_t\(\)\s*{\s*class_name_\s*=\s*"(?P.*)"\s*;.*', line) + if m: + class_name = m.group('class_name') + break + + assert(class_name) + + with open(fn, 'r') as f: + members = list() + for line in f: + + # match: grib_accessor_abstract_vector_t() : + m = re.match(r'.*grib_accessor_(?P\w*)_t\(\)\s*:.*', line) + if m: + out.append(f" grib_accessor_{m.group('derived_name')}_t();\n") + out.append(f" grib_accessor_{m.group('derived_name')}_t(const char*, grib_section*, grib_action*, const long, grib_arguments*);\n") + continue + + #match: grib_accessor_double_t() { class_name_ = "abstract_vector"; } + m = re.match(r'.*grib_accessor_(?P\w*)_t\(\)\s*{\s*class_name_\s*=\s*"(?P.*)"\s*;.*', line) + if m: + continue + + # m = re.match(r'.*grib_accesso + # _class_[a-zA-Z0-9_]*_t\s*_grib_accessor_class_[a-zA-Z0-9_]*\s*{\s*"(?P.*)"\s*};.*', line) + # match grib_accessor* create_empty_accessor() override { return new grib_accessor_dictionary_t{}; } + m = re.match(r'.*grib_accessor\*\s*create_empty_accessor\(\)\s*override\s*{\s*return\s*new\s*grib_accessor_(?P[a-zA-Z0-9_]*)_t{};\s*}.*', line) + if m: + print("class_name:", m.group('class_name')) + out.append(f" grib_accessor* create_empty_accessor(grib_section* p, grib_action* creator, const long len, grib_arguments* args) override\n {{\n return new grib_accessor_{m.group('class_name')}_t{{\"{class_name}\", p, creator, len, args}};\n }}\n") + continue + + # match void init(const long len, grib_arguments* arg) override; + m = re.match(r'.*void\s*init\(\s*const\s*long\s*(?P\w*),\s*grib_arguments\*\s*(?P\w*)\s*\)\s*override;\s*', line) + if m: + continue + + # # match void destroy(grib_context* context) override; + # m = re.match(r'.*void\s*destroy\(\s*grib_context\*\s*context\s*\)\s*override;\s*', line) + # if m: + # continue + out.append(line) + return out + + +for fn in sys.argv[1:]: + print("Processing", fn) + out = convert(fn) + print(''.join(out)) + out_fn = fn.split('/')[-1] + with open(out_fn, 'w') as f: + print("Writing to", out_fn) + f.write(''.join(out)) diff --git a/src/accessor/z_constructor_sources.py b/src/accessor/z_constructor_sources.py new file mode 100755 index 000000000..d9221feac --- /dev/null +++ b/src/accessor/z_constructor_sources.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 + +import sys +import re + +def get_block(f): + out = [] + for line in f: + out.append(line) + if re.match(r'}', line): + break + return out + +def convert(fn): + fn_h = fn.replace('.cc', '.h') + class_name = None + base_name = None + derived_name = None + + with open(fn_h, 'r') as f_h: + members = []; + for line in f_h: + # match: starts with "//" + if re.match(r'\s*//', line): + continue + + # match: class grib_accessor_g2lon_t : public grib_accessor_double_t + m = re.match(r'\s*class\s+grib_accessor_(?P\w+)_t\s*:\s*public\s+grib_accessor_(?P\w+)_t.*', line) + if m: + derived_name = m.group('derived_name') + base_name = m.group('base_name') + continue + + # match: grib_accessor_gen_t() { class_name_ = "to_string"; } + m = re.match(r'.*grib_accessor_(?P\w*)_t\(\)\s*{\s*class_name_\s*=\s*(?P".*")\s*;.*', line) + if m: + # members.append({'type': 'std::string', 'name': 'class_name_', 'value': m.group('class_name')}) + class_name = m.group('class_name') + continue + # match: const char* key_; + m = re.match(r'\s*(?P.*\*)\s+(?P\w+)_;\s*', line) + if m: + members.append({'type': m.group('type'), 'name': m.group('member') + '_', 'value': 'nullptr'}) + continue + # match: long + m = re.match(r'\s*(?P.*)\s+(?P\w+)_;\s*', line) + if m: + members.append({'type': m.group('type'), 'name': m.group('member') + '_', 'value': '0'}) + continue + + for member in members: + print(f"{member['type']} {member['name']} = {member['value']};") + + assert(class_name) + assert(base_name) + assert(derived_name) + + + args = None + init_body = [] + with open(fn, 'r') as f: + # skip until init + try: + m = None + line = next(f) + while not m: + # match: void grib_accessor_g2latlon_t::init(const long l, grib_arguments* c) + m = re.match(r'.*grib_accessor_(?P\w+)_t::init\((?P.*)\).*', line) + if m: + args = m.group('args') + line = next(f) + while not re.match(r'{', line): + line = next(f) + line = next(f) + while not re.match(r'}', line): + # match: grib_accessor_double_t::init(l, c); + m = re.match(r'\s*grib_accessor_(?P\w+)_t::init\((?P.*)\);.*', line) + if not m: + init_body.append(line) + line = next(f) + except StopIteration: + pass + + if not args: + args = 'const long len, grib_arguments* args' + + # parse args + print(args) + m = re.match(r'.*const\s+long\s+(?P\w+),\s*grib_arguments\*\s+(?P\w+).*', args) + args_len = m.group('arg1') + assert(args_len) + args_args = m.group('arg2') + assert(args_args) + + + constructor1 = [] + constructor1.append(f"grib_accessor_{derived_name}_t::grib_accessor_{derived_name}_t() :\n grib_accessor_{base_name}_t{{}}") + if members: + constructor1.append(",\n") + members_list = [f" {member['name']}{{{member['value']}}}" for member in members] + constructor1.append(",\n".join(members_list)) + constructor1.append("{}\n\n") + # constructor1.append("\n") + # constructor1.append("{\n") + # constructor1.append(f' class_name_ = {class_name};\n') + # constructor1.append("}\n") + + constructor2 = [] + constructor2.append(f"grib_accessor_{derived_name}_t::grib_accessor_{derived_name}_t(const char* class_name, grib_section* section, grib_action* creator, {args}) :\n grib_accessor_{base_name}_t{{class_name, section, creator, {args_len}, {args_args}}}") + if members: + constructor2.append(",\n") + members_list = [f" {member['name']}{{{member['value']}}}" for member in members] + constructor2.append(",\n".join(members_list)) + constructor2.append("\n") + constructor2.append("{\n") + # constructor2.append(f' class_name_ = {class_name};\n') + constructor2.append(''.join(init_body)) + constructor2.append("}\n") + + + out = [] + with open(fn, 'r') as f: + for line in f: + # m = re.match(r'grib_accessor\*\s+grib_accessor_(?P\w+)\s*=\s*&_grib_accessor_(?P\w+)(?P.*)', line) + # if m: + # out.append(line) + # out.append(''.join(constructor1)) + # out.append(''.join(constructor2)) + # continue + + # match: void grib_accessor_bits_per_value_t::init(const long l, grib_arguments* args) + # void grib_accessor_g2latlon_t::init(const long l, grib_arguments* c) + m = re.match(r'(?P\w+)\s+grib_accessor_(?P\w+)_t::init\((?P.*)\)(?P.*)', line) + if m: + while not re.match(r'{', line): + line = next(f) + while not re.match(r'}', line): + line = next(f) + continue + out.append(line) + + out.append(''.join(constructor1)) + out.append(''.join(constructor2)) + + return out + + + +for fn in sys.argv[1:]: + print("Processing", fn) + out = convert(fn) + print(''.join(out)) + + out_fn = fn.split('/')[-1] + with open(out_fn, 'w') as f: + f.write(''.join(out)) diff --git a/src/accessor/z_destructor_headers.py b/src/accessor/z_destructor_headers.py new file mode 100755 index 000000000..5d2f5e533 --- /dev/null +++ b/src/accessor/z_destructor_headers.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python3 + +import sys +import re + +def convert(fn): + out = list() + class_name = None + name = None + + with open(fn, 'r') as f: + for line in f: + #match: grib_accessor_double_t() { class_name_ = "abstract_vector"; } + #match: grib_accessor_variable_t(); + m = re.match(r'.*grib_accessor_(?P\w*)_t\(\).*', line) + if m: + name = m.group('name') + break + + assert(name) + + with open(fn, 'r') as f: + members = list() + for line in f: + # match void destroy(grib_context*) override; + m = re.match(r'.*void\s*destroy\(\s*grib_context\*\s*\)\s*override;\s*', line) + if m: + # add a destructor + out.append(f' virtual ~grib_accessor_{name}_t();\n') + continue + + + out.append(line) + return out + + +for fn in sys.argv[1:]: + print("Processing", fn) + out = convert(fn) + print(''.join(out)) + out_fn = fn.split('/')[-1] + with open(out_fn, 'w') as f: + print("Writing to", out_fn) + f.write(''.join(out)) diff --git a/src/accessor/z_destructor_sources.py b/src/accessor/z_destructor_sources.py new file mode 100755 index 000000000..746a04e7e --- /dev/null +++ b/src/accessor/z_destructor_sources.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python3 + +import sys +import re + +def get_block(f): + out = [] + for line in f: + out.append(line) + if re.match(r'}', line): + break + return out + +def convert(fn): + + out = [] + with open(fn, 'r') as f: + for line in f: + # match: void grib_accessor_unsigned_t::destroy(grib_context* context) + m = re.match(r'(?P\w+)\s+grib_accessor_(?P\w+)_t::destroy\((?P.*)\)(?P.*)', line) + if m: + out.append(f"grib_accessor_{m.group('name')}_t::~grib_accessor_{m.group('name')}_t()\n") + continue + + # match: grib_accessor_long_t::destroy(context); + m = re.match(r'\s*grib_accessor_(?P\w+)_t::destroy\((?P.*)\);', line) + if m: + continue + + + # match: grib_context_free(c, v_); + m = re.match(r'\s*grib_context_free\(\s*c\s*,\s*(?P.*)\);', line) + if m: + out.append(f" grib_context_free(context_, {m.group('args')});\n") + continue + + out.append(line) + + return out + + + +for fn in sys.argv[1:]: + print("Processing", fn) + out = convert(fn) + print(''.join(out)) + + out_fn = fn.split('/')[-1] + with open(out_fn, 'w') as f: + f.write(''.join(out)) diff --git a/src/accessor/z_factory_headers.py b/src/accessor/z_factory_headers.py new file mode 100755 index 000000000..5a766d81c --- /dev/null +++ b/src/accessor/z_factory_headers.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 + +import sys +import re + +def convert(fn): + out = list() + class_name = None + + with open(fn, 'r') as f: + for line in f: + # match: grib_accessor_gen_t() { class_name_ = "variable"; } + m = re.match(r'\s*(?P[\w_]+)\(\) { class_name_ = "(?P[\w_]+)"; }', line) + if m: + class_name = m.group(2) + continue + + assert(class_name) + + with open(fn, 'r') as f: + members = list() + for line in f: + m = re.match(r'\s*(?P[\w_]+)\(\) { class_name_ = "(?P[\w_]+)"; }', line) + if m: + out.append(f" {m.group("class_name")}() {{}}\n") + out.append(f" static inline const AccessorType accessor_type{{\"{m.group("type_name")}\"}};\n") + out.append(f" const AccessorType& getClassName() const override {{ return accessor_type; }}\n") + continue + + # match: grib_accessor* create_empty_accessor() override { return new grib_accessor_variable_t{}; } + m = re.match(r'\s*grib_accessor\* create_empty_accessor\(\) override .*}', line) + if m: + continue + + out.append(line) + + return out + + +for fn in sys.argv[1:]: + print("Processing", fn) + out = convert(fn) + print(''.join(out)) + out_fn = fn.split('/')[-1] + with open(out_fn, 'w') as f: + print("Writing to", out_fn) + f.write(''.join(out)) diff --git a/src/accessor/z_factory_sources.py b/src/accessor/z_factory_sources.py new file mode 100755 index 000000000..efa3e4a7a --- /dev/null +++ b/src/accessor/z_factory_sources.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 + +import sys +import re + +def get_block(f): + out = [] + for line in f: + out.append(line) + if re.match(r'}', line): + break + return out + +def convert(fn): + out = [] + with open(fn, 'r') as f: + for line in f: + # match: grib_accessor_variable_t _grib_accessor_variable{}; + m = re.match(r'\s*(?P[\w_]+) (?P[\w_]+){};', line) + if m: + out.append(f'AccessorBuilder<{m.group("type")}> {m.group("name")}_builder{{}};\n') + continue + + # match: grib_accessor* grib_accessor_variable = &_grib_accessor_variable; + m = re.match(r'\s*(?P[\w_]+)\* (?P[\w_]+) = &(?P[\w_]+);', line) + if m: + continue + + out.append(line) + return out + + + +for fn in sys.argv[1:]: + print("Processing", fn) + out = convert(fn) + print(''.join(out)) + + out_fn = fn.split('/')[-1] + with open(out_fn, 'w') as f: + f.write(''.join(out)) diff --git a/src/accessor/z_find_constructors.sh b/src/accessor/z_find_constructors.sh new file mode 100755 index 000000000..c4356d569 --- /dev/null +++ b/src/accessor/z_find_constructors.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +vfuncs=( "dump" "pack_missing" "grib_pack_zero" "is_missing_internal" "pack_double" "pack_float" "pack_expression" "pack_string" "pack_string_array" "pack_long" "pack_bytes" "unpack_bytes" "unpack_double_subarray" "unpack_double" "unpack_float" "unpack_double_element" "unpack_float_element" "unpack_double_element_set" "unpack_float_element_set" "unpack_string" "unpack_string_array" "unpack_long" "get_native_type" "get_next_position_offset" "string_length" "byte_offset" "byte_count" "value_count" "notify_change" "clone" "update_size" "nearest_smaller_value" "preferred_size" "next_accessor" "resize" "compare_accessors" "compare" "add_attribute" "get_attribute_index" "has_attributes" "get_attribute" "init" "post_init" "sub_section" "is_missing" "next_offset" "next" "clear" "make_clone" ) + + +files=( $(find . -name "*.cc") ) +#files=( grib_accessor_class_variable.cc grib_accessor_class_check_internal_version.cc ) + +for f in "${files[@]}"; do + found=0 + for vf in "${vfuncs[@]}"; do + output=$(pcregrep -M "_t::grib_accessor_(\n|.)*}" $f | grep -E "\<$vf\>") + #echo $output + if [ -n "$output" ]; then + echo "Found $vf in $f" + found=1 + break + fi + done +done + +#Found pack_double in ./grib_accessor_class_codetable.cc +#Found dump in ./grib_accessor_class_gen.cc +#Found value_count in ./grib_accessor_class_ibmfloat.cc +#Found value_count in ./grib_accessor_class_ieeefloat.cc +#Found preferred_size in ./grib_accessor_class_pad.cc +#Found preferred_size in ./grib_accessor_class_padto.cc +#Found preferred_size in ./grib_accessor_class_padtoeven.cc +#Found preferred_size in ./grib_accessor_class_padtomultiple.cc + +#Found preferred_size in ./grib_accessor_class_section_padding.cc +#Found value_count in ./grib_accessor_class_signed.cc +#Found value_count in ./grib_accessor_class_unsigned.cc +#Found pack_double in ./grib_accessor_class_variable.cc diff --git a/src/accessor/z_fix_init.py b/src/accessor/z_fix_init.py new file mode 100755 index 000000000..f65448d3a --- /dev/null +++ b/src/accessor/z_fix_init.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 + +import regex as re +import sys + +class Editor: + def __init__(self, header_path, source_path): + self.header_path = header_path + self.source_path = source_path + + self.prepare() + + print(f"Name: {self.name}") + print(f"Parent Name: {self.parent_name}") + + def prepare(self): + with open(self.header_path, 'r') as f: + for line in f: + m = re.match(r'.*class grib_accessor_class_(?P\w*)_t : public grib_accessor_class_(?P\w*)_t.*', line) + if m: + self.name = m.group('name') + self.parent_name = m.group('super_name') + + def fix_init(self): + with open(self.source_path, 'r') as f: + for line in f: + m = re.match(r'\s*grib_accessor_class_(?P\w*)_t::init\(\s*\w+\s*,\s*\w+\s*,\s*\w+\s*\)', line) + if m: + return None + + with open(self.source_path, 'r') as f: + output = "" + for line in f: + m = re.match(r'void grib_accessor_class_(?P\w*)_t::init\(grib_accessor\*\s*(?P\w+)\s*,\s+const\s+long\s+(?P\w+)\s*, grib_arguments\*\s+(?P\w+)\s*\)(?P.*)', line) + if m: + output += line + if not m.group('end').strip().startswith("{"): + output += next(f) + + # output += f"void grib_accessor_class_{self.name}_t::init(grib_accessor* {m.group('accessor')}, const long {m.group('length')}, grib_arguments* {m.group('args')})\n" + # output += "{\n" + output += f" grib_accessor_class_{self.parent_name}_t::init({m.group('accessor')}, {m.group('length')}, {m.group('args')});\n" + continue + else: + output += line + return output + +if __name__ == "__main__": + paths= sys.argv[1:] + + black_list = [ + "grib_accessor.cc", + "grib_accessor_class.cc", + "grib_accessor_class_gen.cc", + "grib_accessors_list.cc", + ] + + for path in paths: + print(f"Processing {path}") + if path in black_list: + continue + basename = path.split('.')[0] + header_path = f"{basename}.h" + source_path = f"{basename}.cc" + + + editor = Editor(header_path, source_path) + new_source = editor.fix_init() + + if new_source is not None: + # print(new_source) + with open(source_path, 'w') as f: + f.write(new_source) + else: + print("Already fixed") diff --git a/src/accessor/z_init.py b/src/accessor/z_init.py new file mode 100755 index 000000000..0adab50b1 --- /dev/null +++ b/src/accessor/z_init.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python3 + +import sys +import re + +def convert(fn): + out = list() + + with open(fn, 'r') as f: + for line in f: + + # const char* seclen_; + m = re.match(r'(?P\s*)(?Pconst\s+char\s*\*)\s+(?P\w+)_;(?P\s*.*)\n', line) + if m: + out.append(f"{m.group('spaces')}{m.group('type')} {m.group('member')}_ = nullptr;{m.group('rest')}\n") + continue + + m = re.match(r'(?P\s*)(?Pchar\s*\*)\s+(?P\w+)_;(?P\s*.*)\n', line) + if m: + out.append(f"{m.group('spaces')}{m.group('type')} {m.group('member')}_ = nullptr;{m.group('rest')}\n") + continue + + m = re.match(r'(?P\s*)(?Pgrib_handle\s*\*)\s+(?P\w+)_;(?P\s*.*)\n', line) + if m: + out.append(f"{m.group('spaces')}{m.group('type')} {m.group('member')}_ = nullptr;{m.group('rest')}\n") + continue + + m = re.match(r'(?P\s*)(?P\w+\s*\*)\s+(?P\w+)_;(?P\s*.*)\n', line) + if m: + out.append(f"{m.group('spaces')}{m.group('type')} {m.group('member')}_ = nullptr;{m.group('rest')}\n") + continue + + # parse int values_dirty_; + m = re.match(r'(?P\s*)(?Pint)\s+(?P\w+)_;(?P\s*.*)\n', line) + if m: + out.append(f"{m.group('spaces')}{m.group('type')} {m.group('member')}_ = 0;{m.group('rest')}\n") + continue + + # parse int values_dirty_; + m = re.match(r'(?P\s*)(?Psize_t)\s+(?P\w+)_;(?P\s*.*)\n', line) + if m: + out.append(f"{m.group('spaces')}{m.group('type')} {m.group('member')}_ = 0;{m.group('rest')}\n") + continue + + # parse int values_dirty_; + m = re.match(r'(?P\s*)(?Punsigned long)\s+(?P\w+)_;(?P\s*.*)\n', line) + if m: + out.append(f"{m.group('spaces')}{m.group('type')} {m.group('member')}_ = 0;{m.group('rest')}\n") + continue + + # parse int values_dirty_; + m = re.match(r'(?P\s*)(?Pchar)\s+(?P\w+)_;(?P\s*.*)\n', line) + if m: + out.append(f"{m.group('spaces')}{m.group('type')} {m.group('member')}_ = 0;{m.group('rest')}\n") + continue + + # parse int values_dirty_; + m = re.match(r'(?P\s*)(?Pdouble)\s+(?P\w+)_;(?P\s*.*)\n', line) + if m: + out.append(f"{m.group('spaces')}{m.group('type')} {m.group('member')}_ = 0.;{m.group('rest')}\n") + continue + + # parse int values_dirty_; + m = re.match(r'(?P\s*)(?Pfloat)\s+(?P\w+)_;(?P\s*.*)\n', line) + if m: + out.append(f"{m.group('spaces')}{m.group('type')} {m.group('member')}_ = 0.f;{m.group('rest')}\n") + continue + + # parse int values_dirty_; + m = re.match(r'(?P\s*)(?Plong)\s+(?P\w+)_;(?P\s*.*)\n', line) + if m: + out.append(f"{m.group('spaces')}{m.group('type')} {m.group('member')}_ = 0;{m.group('rest')}\n") + continue + + out.append(line) + return out + + +for fn in sys.argv[1:]: + print("Processing", fn) + out = convert(fn) + print(''.join(out)) + out_fn = fn.split('/')[-1] + with open(out_fn, 'w') as f: + print("Writing to", out_fn) + f.write(''.join(out)) diff --git a/src/accessor/z_melt_classes.py b/src/accessor/z_melt_classes.py new file mode 100755 index 000000000..d1f34c9f2 --- /dev/null +++ b/src/accessor/z_melt_classes.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 + +import sys +import re + +def convert(fn): + out = list() + class_name = None + + ## Replace extension .h with .cc + fn_cc = fn.replace('.h', '.cc') + with open(fn_cc, 'r') as f: + for line in f: + # grib_accessor_class_validity_time_t _grib_accessor_class_validity_time{ "validity_time" }; + m = re.match(r'.*grib_accessor_class_[a-zA-Z0-9_]*_t\s*_grib_accessor_class_[a-zA-Z0-9_]*\s*{\s*"(?P.*)"\s*};.*', line) + if m: + print("class_name:", m.group('class_name')) + class_name = m.group('class_name') + break + + # if not class_name: + # print("Error: Could not find class_name in", fn) + # return + + print("class_name:", class_name) + + + with open(fn, 'r') as f: + members = list() + for line in f: + if re.match(r'class grib_accessor_class[a-zA-Z0-9]*', line): + while not re.match(r'public:', line): + out.append(line) + line = next(f) + while not re.match(r'};', line): + out.append(line) + line = next(f) + if members: + out.append("private:\n") + for member in members: + out.append(member) + + # class grib_accessor_constant_t : public grib_accessor_variable_t {}; + if re.match(r'class grib_accessor_.*{};', line): + print("Skipping", line) + continue + + if re.match(r'class grib_accessor_[a-zA-Z0-9]*', line): + while not re.match(r'public:', line): + line = next(f) + line = next(f) + while not re.match(r'};', line): + if not re.match(r'.*Members.*', line): + members.append(line) + line = next(f) + line = next(f) + + out.append(line) + + + prev = None + out2 = list() + for line in out: + if line == prev: + continue + out2.append(line) + prev = line + + # for line in out2: + # print(line, end='') + + out3 = list() + for line in out2: + # grib_accessor_class_validity_time_t(const char* name) : grib_accessor_class_long_t(name) {} + print(line) + m = re.match(r'(?P.*)grib_accessor_class_(?P[a-zA-Z0-9_]*)_t\(.*\)\s*:\s*grib_accessor_class_(?P[a-zA-Z0-9_]*)_t.*', line) + # m = re.match(r'.*grib_accessor_class_validity_time_t(const char* name) : grib_accessor_class_long_t(name) {}.*', line) + if m: + print("XXXX"); + line = f"{m.group('shift')}grib_accessor_{m.group('aname')}_t() : grib_accessor_{m.group('baseclass')}_t(){{class_name = \"{class_name}\";}}\n" + + # replace grib_accessor_class_ with grib_accessor_ + if not re.match(r'.*include.*', line): + line = re.sub(r'grib_accessor_class_', 'grib_accessor_', line) + line = re.sub('\(\s*grib_accessor\s*\*\s*,\s*', '(', line) # replace (grib_accessor*, with ( + line = re.sub('\(\s*grib_accessor\s*\*\s*\)', '()', line) # replace (grib_accessor*) with () + line = re.sub('\(\s*grib_accessor\s*\*\s*\w*\s*,\s*', '(', line) # replace (grib_accessor* name, with ( + line = re.sub('\(\s*grib_accessor\s*\*\s*\w*\s*\)', '()', line) # replace (grib_accessor* name) with () + line = re.sub('int get_native_type', 'long get_native_type', line) + + + out3.append(line) + return out3 + + +for fn in sys.argv[1:]: + print("Processing", fn) + out = convert(fn) + print(''.join(out)) + out_fn = fn.split('/')[-1] + with open(out_fn, 'w') as f: + print("Writing to", out_fn) + f.write(''.join(out)) diff --git a/src/accessor/z_melt_classes_sources.py b/src/accessor/z_melt_classes_sources.py new file mode 100755 index 000000000..2fe9969d6 --- /dev/null +++ b/src/accessor/z_melt_classes_sources.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +import sys +import re + +def convert(fn): + out = list() + with open(fn, 'r') as f: + members = list() + for line in f: + # grib_accessor_unsigned_t* self = (grib_accessor_unsigned_t*)a; + m = re.match(r'\s*grib_accessor_(?P\w+)_t\*\s+self\s=\s*.*', line) + if m: + continue + + m1 = re.match(r'static (?P\w+) (?P\w+)\((?P.+)\)', line) + m = re.match(r'(?P.*)\s*self->(?P\w+)\s*(?P.*)', line) + if m: + out.append(f"{m.group('before')}self->{m.group('name')}_ {m.group('after')}\n") + continue + + m = re.match(r'(?P.*)\s*a->(?P\w+\()\s*(?P.*)', line) + if m: + out.append(f"{m.group('before')}{m.group('name')}{m.group('after')}\n") + continue + + m = re.match(r'(?P.*)\s*a->(?P\w+)\s*(?P.*)', line) + if m: + out.append(f"{m.group('before')}{m.group('name')}_ {m.group('after')}\n") + continue + + # void grib_accessor_class_unsigned_t::init(grib_accessor* a) + m = re.match(r'(?P\w+)\s+grib_accessor_class_(?P\w+)_t::(?P\w+)\(grib_accessor\* a\)(?P.*)', line) + if m: + out.append(f"{m.group('rtype')} grib_accessor_{m.group('aname')}_t::{m.group('fname')}(){m.group('after')}\n") + continue + + + # void grib_accessor_class_unsigned_t::init(grib_accessor* a, const long len, grib_arguments* arg) + m = re.match(r'(?P\w+)\s+grib_accessor_class_(?P\w+)_t::(?P\w+)\(grib_accessor. a, (?P.*)', line) + if m: + out.append(f"{m.group('rtype')} grib_accessor_{m.group('aname')}_t::{m.group('fname')}({m.group('after')}\n") + continue + + # grib_accessor_class_unsigned_t _grib_accessor_class_unsigned("unsigned"); + m = re.match(r'grib_accessor_class_(?P\w+)_t\s+_grib_accessor_class_(?P\w+){\s*"(?P.*)"\s*}\s*;', line) + if m: + out.append(f"grib_accessor_{m.group('aname')}_t _grib_accessor_{m.group('aname2')}{{}};\n") + continue + + # grib_accessor_class* grib_accessor_class_unsigned = &_grib_accessor_class_unsigned; + m = re.match(r'grib_accessor_class\*\s+grib_accessor_class_(?P\w+)\s*=\s*&_grib_accessor_class_(?P\w+)(?P.*)', line) + if m: + out.append(f"grib_accessor* grib_accessor_{m.group('aname')} = &_grib_accessor_{m.group('aname')}{m.group('after')}\n") + continue + + out.append(line) + + + prev = None + out2 = list() + for line in out: + if line == prev: + continue + out2.append(line) + prev = line + + # for line in out2: + # print(line, end='') + return out2 + + +for fn in sys.argv[1:]: + print("Processing", fn) + out = convert(fn) + print(''.join(out)) + + out_fn = fn.split('/')[-1] + with open(out_fn, 'w') as f: + f.write(''.join(out)) diff --git a/src/accessor/z_rm_constructor_headers.py b/src/accessor/z_rm_constructor_headers.py new file mode 100755 index 000000000..fe3fd5999 --- /dev/null +++ b/src/accessor/z_rm_constructor_headers.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 + +import sys +import re + +def convert(fn): + out = list() + cname = None + super_cname = None + + with open(fn, 'r') as f: + for line in f: + # match: grib_accessor_gds_is_present_t(); + m = re.match(r'.*grib_accessor_(?P\w*)_t\(\);', line) + if m: + cname = m.group('name') + continue + + + + assert(cname is not None) + + with open(fn, 'r') as f: + members = list() + for line in f: + # match: grib_accessor_variable_t(); + m = re.match(r'\s*grib_accessor_(?P\w*)_t\(\);', line) + if m: + continue + out.append(line) + return out + + +for fn in sys.argv[1:]: + print("Processing", fn) + out = convert(fn) + print(''.join(out)) + out_fn = fn.split('/')[-1] + with open(out_fn, 'w') as f: + print("Writing to", out_fn) + f.write(''.join(out)) diff --git a/src/accessor/z_rm_constructor_sources.py b/src/accessor/z_rm_constructor_sources.py new file mode 100755 index 000000000..5bc8b1b84 --- /dev/null +++ b/src/accessor/z_rm_constructor_sources.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 + +import sys +import re + +def convert(fn): + out = [] + with open(fn, 'r') as f: + for line in f: + m = re.match(r'.*grib_accessor_(?P\w*)_t::grib_accessor_(?P\w*)_t\(\)\s*:', line) + if m: + while not re.match(r'.*{}$', line): + line = f.readline() + continue + continue + out.append(line) + return out + + + +for fn in sys.argv[1:]: + print("Processing", fn) + out = convert(fn) + print(''.join(out)) + + out_fn = fn.split('/')[-1] + with open(out_fn, 'w') as f: + f.write(''.join(out)) diff --git a/src/accessor/z_rm_dev.sh b/src/accessor/z_rm_dev.sh new file mode 100755 index 000000000..9fb42c359 --- /dev/null +++ b/src/accessor/z_rm_dev.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +for f in grib_accessor*; do + echo "Processing $f" + sed -i '/^<<<<<<>>>>>>/d' $f +done diff --git a/src/accessor/z_transform.py b/src/accessor/z_transform.py new file mode 100755 index 000000000..c98c4c002 --- /dev/null +++ b/src/accessor/z_transform.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 + +import regex as re +import sys + +licence_txt = ''' +/* + * (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. + */ +''' + + +virtual_func_names = ['create_empty_accessor', 'make_clone', 'next', 'ub_section', 'clear', 'compare', 'get_native_type', 'is_missing', 'nearest_smaller_value', 'notify_change', 'pack_bytes', 'pack_double', 'pack_expression', 'pack_float', 'pack_long', 'pack_missing', 'pack_string', 'pack_string_array', 'unpack_bytes', 'unpack_double', 'unpack_double_element', 'unpack_double_element_set', 'unpack_double_subarray', 'unpack_float', 'unpack_float_element', 'unpack_float_element_set', 'unpack_long', 'unpack_string', 'unpack_string_array', 'value_count', 'byte_count', 'byte_offset', 'next_offset', 'preferred_size', 'string_length', 'destroy', 'dump', 'init', 'post_init', 'resize', 'update_size'] + + +class Transform: + def __init__(self, file_path): + self.file_path = file_path + accessor_class_name = file_path.split('/')[-1].split('.')[0] + self.name = accessor_class_name[20:] + self.accessor_class = "" + self.super_name = "" + self.signatures = [] + + self.scan_file() + + def get_name(self): + return self.name + + def scan_file(self): + with open(self.file_path, 'r') as f: + for line in f: + if re.match(r'\/\* END_CLASS_IMP \*\/', line): + break + + signature = '' + + m = re.match(r'.*SUPER\s*=\s*(\w*).*', line) + if m: + super_class = m.group(1) + self.super_name = super_class[20:] + + m = re.match(r'static (\w*) (\w*)\(\);', line) + if m: + signature = f"{m.group(1)}" + ' ' + m.group(2) + '() override;' + self.signatures.append(signature) + m = re.match(r'static (\w*) (\w*)\((.*)\);', line) + + if m: + signature = f"{m.group(1)}" + ' ' + m.group(2) + '(' + m.group(3) + ') override;' + self.signatures.append(signature) + + m = re.match(r'typedef struct (\w*)', line) + if m: + self.accessor_class = f"class grib_accessor_{self.name}_t : public grib_accessor_{self.super_name}_t\n" + self.accessor_class += "{\n" + self.accessor_class += f"public:\n" + + while re.match(fr'.*Members defined in {self.name}*', line) is None: + line = next(f) + + while re.match(fr'.*\}}\s*grib_accessor_{self.name}\s*;\s*\n', line) is None: + self.accessor_class += line + line = next(f) + self.accessor_class += '};' + + + def make_source(self): + output = "" + output += licence_txt + output += '\n' + output += f'#include "grib_api_internal.h"\n' + output += f"#include \"grib_accessor_class_{self.name}.h\"\n" + output += f'\n' + output += f'grib_accessor_class_{self.name}_t _grib_accessor_class_{self.name}{{"{self.name}"}};\n' + output += f'grib_accessor_class* grib_accessor_class_{self.name} = &_grib_accessor_class_{self.name};\n' + output += f'\n' + + with open(self.file_path, 'r') as f: + while re.match(r'\/\* END_CLASS_IMP \*\/', next(f)) is None: + pass + for line in f: + + m = re.match(r'static (?P\w+) (?P\w+)\((?P.+)\);', line) + if m: + output += f"{m.group('return_type')} {m.group('function_name')}({m.group('parameters')});" + continue + + m = re.match(r'static (?P\w+) (?P\w+)\((?P.+)\)', line) + if m: + if m.group('function_name') in virtual_func_names: + output += f"{m.group('return_type')} grib_accessor_class_{self.name}_t::{m.group('function_name')}({m.group('parameters')})" + else: + output += f"{m.group('return_type')} {m.group('function_name')}({m.group('parameters')})" + continue + m = re.match(r'(?P(.*)\s*=\s*)grib_(?P\w*)\((?P[\w\->]*)\s*[,]*\s*(?P.*)\);', line) + if m and m.group('fname') in virtual_func_names: + output += f"{m.group('before')}{m.group('name')}->{m.group('fname')}({m.group('params')});" + continue + m = re.match(r'(?P.*\s*)grib_(?P\w*)\((?P[\w\->]*)\s*[,]*\s*(?P.*)\);', line) + if m and m.group('fname') in virtual_func_names: + output += f"{m.group('before')}{m.group('name')}->{m.group('fname')}({m.group('params')});" + continue + + # grib_accessor_getenv* self = (grib_accessor_getenv*)a; + m = re.match(fr'.*grib_accessor_{self.name}.*', line) + if m: + output += line.replace(f'grib_accessor_{self.name}', f'grib_accessor_{self.name}_t') + continue + + output += line + + return output + + + def make_header(self): + output = "" + output += licence_txt + output += '\n' + # output += '#pragma once\n' + output += f'#ifndef eccodes_accessor_{self.name}_h\n' + output += f'#define eccodes_accessor_{self.name}_h\n' + output += '\n' + output += '#include "../grib_api_internal.h"\n' + output += f'#include "grib_accessor_class_{self.super_name}.h"\n' + output += '\n' + output += self.accessor_class + output += '\n' + output += '\n' + output += f"class grib_accessor_class_{self.name}_t : public grib_accessor_class_{self.super_name}_t\n{{\n" + output += f"public:\n" + output += f" grib_accessor_class_{self.name}_t(const char* name) : grib_accessor_class_{self.super_name}_t(name) {{}}\n" + output += f" grib_accessor* create_empty_accessor() override {{ return new grib_accessor_{self.name}_t{{}}; }}\n" + for s in self.signatures: + output += f" {s}\n" + output += "};\n" + output += f"#endif /* eccodes_accessor_{self.name}_h */\n" + + return output + + + +if __name__ == '__main__': + args = sys.argv[1:] + file_path = args[0] + t = Transform(file_path) + header = t.make_header() + source = t.make_source() + + header_fn = f"grib_accessor_class_{t.get_name()}.h" + source_fn = f"grib_accessor_class_{t.get_name()}.cc" + + with open(header_fn, 'w') as f: + f.write(header) + # print(header) + + with open(source_fn, 'w') as f: + f.write(source) + # print(source) diff --git a/src/accessor/z_transform_class.py b/src/accessor/z_transform_class.py new file mode 100755 index 000000000..4612e2b51 --- /dev/null +++ b/src/accessor/z_transform_class.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 + +import regex as re +# Read file line by line + +virtual_func_names = ['create_empty_accessor', 'make_clone', 'next', 'sub_section', 'clear', 'compare', 'get_native_type', 'is_missing', 'nearest_smaller_value', 'notify_change', 'pack_bytes', 'pack_double', 'pack_expression', 'pack_float', 'pack_long', 'pack_missing', 'pack_string', 'pack_string_array', 'unpack_bytes', 'unpack_double', 'unpack_double_element', 'unpack_double_element_set', 'unpack_double_subarray', 'unpack_float', 'unpack_float_element', 'unpack_float_element_set', 'unpack_long', 'unpack_string', 'unpack_string_array', 'value_count', 'byte_count', 'byte_offset', 'next_offset', 'preferred_size', 'string_length', 'destroy', 'dump', 'init', 'post_init', 'resize', 'update_size'] + + +def convert_call(line): + # int err = grib_unpack_string(a, val, &l); + m = re.match(r'(?P(.*)\s*=\s*)grib_(?P\w*)\((?P\w*)\s*[,]*\s*(?P.*)\);', line) + if m and m.group('fname') in virtual_func_names: + return f"{m.group('before')}{m.group('name')}->{m.group('fname')}({m.group('params')});" + return line + +signatures = dict() + +class Transform: + def __init__(self, file_path): + self.file_path = file_path + + def read_file(self): + accessor_class_name = self.file_path.split('/')[-1].split('.')[0] + accessor_class = "" + name = accessor_class_name[20:] + super_name = "" + with open(self.file_path, 'r') as f: + signatures = [] + for line in f: + signature = '' + m = re.match(r'.*SUPER\s*=\s*(\w*).*', line) + if m: + super_class = m.group(1) + super_name = super_class[20:] + print(f"name {name} supername {super_name}") + m = re.match(r'static (\w*) (\w*)\(grib_accessor\*\);', line) + if m: + signature = f"{m.group(1)}" + ' ' + m.group(2) + '() override;' + signatures.append(signature) + m = re.match(r'static (\w*) (\w*)\(grib_accessor\*, (.*)\);', line) + if m: + signature = f"{m.group(1)}" + ' ' + m.group(2) + '(' + m.group(3) + ') override;' + signatures.append(signature) + + m = re.match(r'typedef struct (\w*)', line) + if m: + accessor_class = f"class grib_accessor_{name}_t : public grib_accessor_{super_name}_t\n" + line = next(f) + line = next(f) + accessor_class += "{\n" + accessor_class += f"public:" + while line != f'}} grib_accessor_{name};\n': + accessor_class += line + line = next(f) + accessor_class += '};' + + m1 = re.match(r'static (?P\w+) (?P\w+)\((?P.+)\)', line) + if m1: + function = "" + function += f"{m1.group('return_type')} grib_accessor_class_{name}_t::{m1.group('function_name')}({m1.group('parameters')})" + line = next(f) + line = next(f) + function += "\n{\n" + while re.match(r'}', line) is None: + function += convert_call(line) + line = next(f) + function += '}\n' + print(f"{function}") + + + print('#pragma once') + print('#include "../grib_api_internal.h"') + print(f'#include "grib_accessor_class_{super_name}.h"') + print(accessor_class) + print(f"class grib_accessor_class_{name}_t : public grib_accessor_class_{super_name}_t\n{{") + print(f"public:") + + print(f"\tgrib_accessor_class_{name}_t(const char* name) : grib_accessor_class_{super_name}_t(name) {{}}") + print(f"\tgrib_accessor* create_empty_accessor() override {{ return new grib_accessor_{name}_t{{}}; }}") + for s in signatures: + print(f"\t{s}") + print("};") + + + + + +if __name__ == '__main__': + file_path = 'todo/grib_accessor_class_ascii.cc' + t = Transform(file_path) + t.read_file() diff --git a/src/dumper/grib_dumper.h b/src/dumper/grib_dumper.h new file mode 100644 index 000000000..1f57a0027 --- /dev/null +++ b/src/dumper/grib_dumper.h @@ -0,0 +1,67 @@ +/* + * (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. + */ + +#pragma once + +#include +#include + +namespace eccodes +{ + +class Dumper +{ +public: + virtual int init() = 0; + virtual int destroy() = 0; + virtual void dump_long(grib_accessor*, const char*) = 0; + virtual void dump_double(grib_accessor*, const char*) = 0; + virtual void dump_string(grib_accessor*, const char*) = 0; + virtual void dump_string_array(grib_accessor*, const char*) + { + // TODO(maee): make abstract + throw std::runtime_error("Not implemented"); + }; + virtual void dump_label(grib_accessor*, const char*) = 0; + virtual void dump_bytes(grib_accessor*, const char*) = 0; + virtual void dump_bits(grib_accessor*, const char*) = 0; + virtual void dump_section(grib_accessor*, grib_block_of_accessors*) = 0; + virtual void dump_values(grib_accessor*) = 0; + virtual void header(const grib_handle*) + { + // TODO(maee): make abstract + throw std::runtime_error("Not implemented"); + }; + virtual void footer(const grib_handle*) + { + // TODO(maee): make abstract + throw std::runtime_error("Not implemented"); + }; + + long count() { return count_; } + void count(long count) { count_ = count; } + + int depth_ = 0; + void* arg_ = nullptr; + unsigned long option_flags_ = 0; + grib_context* context_ = nullptr; + FILE* out_ = nullptr; + +protected: + const char* class_name_ = nullptr; + long count_ = 0; + +private: + const char* name_ = nullptr; + size_t size_ = 0; + int inited_ = 0; +}; + +} // namespace eccodes diff --git a/src/dumper/grib_dumper_class_bufr_decode_C.cc b/src/dumper/grib_dumper_class_bufr_decode_C.cc new file mode 100644 index 000000000..231911206 --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_decode_C.cc @@ -0,0 +1,644 @@ +/* + * (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_dumper_class_bufr_decode_C.h" +#include "grib_dumper_factory.h" +#include + +eccodes::dumper::BufrDecodeC _grib_dumper_bufr_decode_c{}; +eccodes::Dumper* grib_dumper_bufr_decode_c = &_grib_dumper_bufr_decode_c; + +namespace eccodes::dumper { + +static int depth = 0; + + +int BufrDecodeC::init() +{ + section_offset_ = 0; + empty_ = 1; + count_ = 1; + isLeaf_ = 0; + isAttribute_ = 0; + keys_ = (grib_string_list*)grib_context_malloc_clear(context_, sizeof(grib_string_list)); + + return GRIB_SUCCESS; +} + +int BufrDecodeC::destroy() +{ + grib_string_list* next = keys_; + grib_string_list* cur = NULL; + while (next) { + cur = next; + next = next->next; + grib_context_free(context_, cur->value); + grib_context_free(context_, cur); + } + return GRIB_SUCCESS; +} + +static char* dval_to_string(grib_context* c, double v) +{ + char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * 40); + snprintf(sval, 1024, "%.18e", v); + return sval; +} + +void BufrDecodeC::dump_values(grib_accessor* a) +{ + double value = 0; + size_t size = 0; + int err = 0; + int r = 0; + long count = 0; + char* sval; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + + if (size <= 1) { + err = a->unpack_double(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + fprintf(out_, "\n"); + fprintf(out_, " free(dValues);\n"); + fprintf(out_, " dValues = (double*)malloc(%lu*sizeof(double));\n", (unsigned long)size); + fprintf(out_, " if (!dValues) { fprintf(stderr, \"Failed to allocate memory (dValues).\\n\"); return 1; }\n"); + fprintf(out_, " size = %lu;\n", (unsigned long)size); + + depth -= 2; + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " CODES_CHECK(codes_get_double_array(h, \"#%d#%s\",dValues, &size), 0);\n", r, a->name_); + else + fprintf(out_, " CODES_CHECK(codes_get_double_array(h, \"%s\", dValues, &size), 0);\n", a->name_); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_double(a, value)) { + sval = dval_to_string(context_, value); + if (r != 0) + fprintf(out_, " CODES_CHECK(codes_get_double(h, \"#%d#%s\", &dVal), 0);\n", r, a->name_); + else + fprintf(out_, " CODES_CHECK(codes_get_double(h, \"%s\", &dVal), 0);\n", a->name_); + + grib_context_free(context_, sval); + } + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(context_, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(context_, prefix); + depth -= 2; + } + + (void)err; /* TODO */ +} + +void BufrDecodeC::dump_values_attribute(grib_accessor* a, const char* prefix) +{ + double value = 0; + size_t size = 0; + int err = 0; + long count = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + + if (size <= 1) { + err = a->unpack_double(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + fprintf(out_, "\n"); + fprintf(out_, " free(dValues);\n"); + fprintf(out_, " dValues = (double*)malloc(%lu*sizeof(double));\n", (unsigned long)size); + fprintf(out_, " if (!dValues) { fprintf(stderr, \"Failed to allocate memory (dValues).\\n\"); return 1; }\n"); + fprintf(out_, " size = %lu\n;", (unsigned long)size); + + depth -= 2; + + fprintf(out_, " CODES_CHECK(codes_get_double_array(h, \"%s->%s\", dValues, &size), 0);\n", prefix, a->name_); + } + else { + /* int r=compute_bufr_key_rank(h,keys_,a->name_); */ + if (!grib_is_missing_double(a, value)) { + char* sval = dval_to_string(c, value); + fprintf(out_, " CODES_CHECK(codes_get_double(h, \"%s->%s\", &dVal), 0);\n", prefix, a->name_); + + grib_context_free(c, sval); + } + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth -= 2; + } + + (void)err; /* TODO */ +} + +void BufrDecodeC::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 0; + int err = 0; + int r = 0; + long count = 0; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + a->value_count(&count); + size = count; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + return; + } + + if (size <= 1) { + err = a->unpack_long(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + fprintf(out_, "\n"); + fprintf(out_, " free(iValues);\n"); + fprintf(out_, " iValues = (long*)malloc(%lu*sizeof(long));\n", (unsigned long)size); + fprintf(out_, " if (!iValues) { fprintf(stderr, \"Failed to allocate memory (iValues).\\n\"); return 1; }\n"); + fprintf(out_, " size = %lu;\n", (unsigned long)size); + + depth -= 2; + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " CODES_CHECK(codes_get_long_array(h, \"#%d#%s\", iValues, &size), 0);\n", r, a->name_); + else + fprintf(out_, " CODES_CHECK(codes_get_long_array(h, \"%s\", iValues, &size), 0);\n", a->name_); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!codes_bufr_key_exclude_from_dump(a->name_)) { + if (!grib_is_missing_long(a, value)) { + if (r != 0) + fprintf(out_, " CODES_CHECK(codes_get_long(h, \"#%d#%s\", &iVal), 0);\n", r, a->name_); + else + fprintf(out_, " CODES_CHECK(codes_get_long(h, \"%s\", &iVal), 0);\n", a->name_); + } + } + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + (void)err; /* TODO */ +} + +void BufrDecodeC::dump_long_attribute(grib_accessor* a, const char* prefix) +{ + long value = 0; + size_t size = 0; + int err = 0; + long count = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + + if (size <= 1) { + err = a->unpack_long(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + fprintf(out_, "\n"); + fprintf(out_, " free(iValues);\n"); + fprintf(out_, " iValues = (long*)malloc(%lu*sizeof(long));\n", (unsigned long)size); + fprintf(out_, " if (!iValues) { fprintf(stderr, \"Failed to allocate memory (iValues).\\n\"); return 1; }\n"); + fprintf(out_, " size = %lu;\n", (unsigned long)size); + + depth -= 2; + + fprintf(out_, " CODES_CHECK(codes_get_long_array(h, \"%s->%s\", iValues, &size), 0);\n", prefix, a->name_); + } + else { + /* int r=compute_bufr_key_rank(h,keys_,a->name_); */ + if (!codes_bufr_key_exclude_from_dump(prefix)) { + if (!grib_is_missing_long(a, value)) { + fprintf(out_, " CODES_CHECK(codes_get_long(h, \"%s->%s\", &iVal), 0);\n", prefix, a->name_); + } + } + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth -= 2; + } + (void)err; /* TODO */ +} + +void BufrDecodeC::dump_bits(grib_accessor* a, const char* comment) +{ +} + +void BufrDecodeC::dump_double(grib_accessor* a, const char* comment) +{ + double value = 0; + size_t size = 1; + int r; + char* sval; + grib_handle* h = grib_handle_of_accessor(a); + grib_context* c = h->context; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->unpack_double(&value, &size); + empty_ = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_double(a, value)) { + sval = dval_to_string(c, value); + if (r != 0) + fprintf(out_, " CODES_CHECK(codes_get_double(h, \"#%d#%s\", &dVal), 0);\n", r, a->name_); + else + fprintf(out_, " CODES_CHECK(codes_get_double(h, \"%s\", &dVal), 0);\n", a->name_); + + grib_context_free(c, sval); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } +} + +void BufrDecodeC::dump_string_array(grib_accessor* a, const char* comment) +{ + char** values; + size_t size = 0, i = 0; + grib_context* c = NULL; + int err = 0; + long count = 0; + int r = 0; + grib_handle* h = grib_handle_of_accessor(a); + + c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_string(a, comment); + return; + } + + fprintf(out_, "\n"); + fprintf(out_, " free(sValues);\n"); + fprintf(out_, " sValues = (char**)malloc(%lu * sizeof(char*));\n", (unsigned long)size); + fprintf(out_, " if (!sValues) { fprintf(stderr, \"Failed to allocate memory (sValues).\\n\"); return 1; }\n"); + fprintf(out_, " size = %lu;\n", (unsigned long)size); + + empty_ = 0; + 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); + + if (isLeaf_ == 0) { + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " codes_get_string_array(h, \"#%d#%s\", sValues, &size);\n", r, a->name_); + else + fprintf(out_, " codes_get_string_array(h, \"%s\", sValues, &size);\n", a->name_); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + + for (i = 0; i < size; i++) + grib_context_free(c, values[i]); + grib_context_free(c, values); + (void)err; /* TODO */ +} + +#define MAX_STRING_SIZE 4096 +void BufrDecodeC::dump_string(grib_accessor* a, const char* comment) +{ + char value[MAX_STRING_SIZE] = {0, }; /* See ECC-710 */ + size_t size = MAX_STRING_SIZE; + char* p = NULL; + grib_context* c = a->context_; + int r = 0, err = 0; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + empty_ = 0; + + err = a->unpack_string(value, &size); + p = value; + r = compute_bufr_key_rank(h, keys_, a->name_); + if (grib_is_missing_string(a, (unsigned char*)value, size)) { + return; + } + + while (*p) { + if (!isprint(*p)) + *p = '?'; + p++; + } + + fprintf(out_, " size = 1024;\n"); /* TODO */ + if (isLeaf_ == 0) { + depth += 2; + if (r != 0) + fprintf(out_, " CODES_CHECK(codes_get_string(h, \"#%d#%s\", sVal, &size), 0);\n", r, a->name_); + else + fprintf(out_, " CODES_CHECK(codes_get_string(h, \"%s\", sVal, &size), 0);\n", a->name_); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + + (void)err; /* TODO */ +} + +void BufrDecodeC::dump_bytes(grib_accessor* a, const char* comment) +{ +} + +void BufrDecodeC::dump_label(grib_accessor* a, const char* comment) +{ +} + +static void _dump_long_array(grib_handle* h, FILE* f, const char* key) +{ + size_t size = 0; + if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) + return; + + fprintf(f, " free(iValues);\n"); + fprintf(f, " iValues = (long*)malloc(%lu*sizeof(long));\n", (unsigned long)size); + fprintf(f, " if (!iValues) { fprintf(stderr, \"Failed to allocate memory (iValues).\\n\"); return 1; }\n"); + fprintf(f, " size = %lu;", (unsigned long)size); + + fprintf(f, " CODES_CHECK(codes_get_long_array(h, \"%s\", iValues, &size), 0);\n", key); +} + +void BufrDecodeC::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + if (strcmp(a->name_, "BUFR") == 0 || + strcmp(a->name_, "GRIB") == 0 || + strcmp(a->name_, "META") == 0) { + grib_handle* h = grib_handle_of_accessor(a); + depth = 2; + empty_ = 1; + depth += 2; + _dump_long_array(h, out_, "dataPresentIndicator"); + _dump_long_array(h, out_, "delayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "shortDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "extendedDelayedDescriptorReplicationFactor"); + /* Do not show the inputOverriddenReferenceValues array. That's more for ENCODING */ + /*_dump_long_array(h,out_,"inputOverriddenReferenceValues","inputOverriddenReferenceValues");*/ + grib_dump_accessors_block(this, block); + depth -= 2; + } + else if (strcmp(a->name_, "groupNumber") == 0) { + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + empty_ = 1; + depth += 2; + grib_dump_accessors_block(this, block); + depth -= 2; + } + else { + grib_dump_accessors_block(this, block); + } +} + +void BufrDecodeC::dump_attributes(grib_accessor* a, const char* prefix) +{ + int i = 0; + unsigned long flags; + while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { + isAttribute_ = 1; + if ((option_flags_ & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { + i++; + continue; + } + isLeaf_ = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; + flags = a->attributes_[i]->flags_; + a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; + switch (a->attributes_[i]->get_native_type()) { + case GRIB_TYPE_LONG: + dump_long_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_DOUBLE: + dump_values_attribute( a->attributes_[i], prefix); + break; + case GRIB_TYPE_STRING: + break; + } + a->attributes_[i]->flags_ = flags; + i++; + } + isLeaf_ = 0; + isAttribute_ = 0; +} + +void BufrDecodeC::header(const grib_handle* h) +{ + Assert(h->product_kind == PRODUCT_BUFR); + + if (count_ < 2) { + /* This is the first message being processed */ + fprintf(out_, "/* This program was automatically generated with bufr_dump -DC */\n"); + fprintf(out_, "/* Using ecCodes version: "); + grib_print_api_version(out_); + fprintf(out_, " */\n\n"); + fprintf(out_, "#include \"eccodes.h\"\n"); + fprintf(out_, "int main(int argc, char* argv[])\n"); + fprintf(out_, "{\n"); + fprintf(out_, " size_t size = 0;\n"); + fprintf(out_, " int err = 0;\n"); + fprintf(out_, " FILE* fin = NULL;\n"); + fprintf(out_, " codes_handle* h = NULL;\n"); + fprintf(out_, " long iVal = 0;\n"); + fprintf(out_, " double dVal = 0.0;\n"); + fprintf(out_, " char sVal[1024] = {0,};\n"); + fprintf(out_, " long* iValues = NULL;\n"); + fprintf(out_, " char** sValues = NULL;\n"); + fprintf(out_, " double* dValues = NULL;\n"); + fprintf(out_, " const char* infile_name = NULL;\n\n"); + + fprintf(out_, " if (argc != 2) {\n"); + fprintf(out_, " fprintf(stderr, \"Usage: %%s BUFR_file\\n\", argv[0]);\n"); + fprintf(out_, " return 1;\n"); + fprintf(out_, " }\n"); + fprintf(out_, " infile_name = argv[1];\n"); + fprintf(out_, " fin = fopen(infile_name, \"r\");\n"); + fprintf(out_, " if (!fin) {\n"); + fprintf(out_, " fprintf(stderr,\"ERROR: Unable to open input BUFR file %%s\\n\", infile_name);\n"); + fprintf(out_, " return 1;\n"); + fprintf(out_, " }\n\n"); + } + + fprintf(out_, " h = codes_handle_new_from_file(NULL, fin, PRODUCT_BUFR, &err);\n"); + fprintf(out_, " if (h == NULL) {\n"); + fprintf(out_, " fprintf(stderr, \"ERROR: cannot create BUFR handle\\n\");\n"); + fprintf(out_, " return 1;\n"); + fprintf(out_, " }\n"); + fprintf(out_, " CODES_CHECK(codes_set_long(h, \"unpack\", 1),0);\n\n"); +} + +void BufrDecodeC::footer(const grib_handle* h) +{ + + /*fprintf(out_," fout = fopen(\"outfile.bufr\", \"w\");");*/ + /*fprintf(out_," if (fclose(fout)) {\n"); + fprintf(out_," fprintf(stderr, \"Failed to close file handle.\\n\");\n"); + fprintf(out_," return 1;\n"); + fprintf(out_," }\n"); + */ + fprintf(out_, "\n"); + fprintf(out_, " codes_handle_delete(h);\n"); + fprintf(out_, " free(iValues); iValues = NULL;\n"); + fprintf(out_, " free(dValues); dValues = NULL;\n"); + fprintf(out_, " free(sValues); sValues = NULL;\n\n"); +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_decode_C.h b/src/dumper/grib_dumper_class_bufr_decode_C.h new file mode 100644 index 000000000..44a9f0c7d --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_decode_C.h @@ -0,0 +1,52 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class BufrDecodeC : public Dumper +{ +public: + BufrDecodeC() { class_name_ = "bufr_decode_C"; } + int init() override; + int destroy() override; + void dump_long(grib_accessor*, const char*) override; + void dump_bits(grib_accessor*, const char*) override; + void dump_double(grib_accessor*, const char*) override; + void dump_string(grib_accessor*, const char*) override; + void dump_string_array(grib_accessor*, const char*) override; + void dump_bytes(grib_accessor*, const char*) override; + void dump_values(grib_accessor*) override; + void dump_label(grib_accessor*, const char*) override; + void dump_section(grib_accessor*, grib_block_of_accessors*) override; + void header(const grib_handle*) override; + void footer(const grib_handle*) override; + + +private: + static inline int depth = 0; + + void dump_attributes(grib_accessor* a, const char* prefix); + void dump_values_attribute(grib_accessor* a, const char* prefix); + void dump_long_attribute(grib_accessor* a, const char* prefix); + + long section_offset_ = 0; + long empty_ = 0; + long end_ = 0; + long isLeaf_ = 0; + long isAttribute_ = 0; + grib_string_list* keys_ = nullptr; +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_decode_filter.cc b/src/dumper/grib_dumper_class_bufr_decode_filter.cc new file mode 100644 index 000000000..7bd149d73 --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_decode_filter.cc @@ -0,0 +1,493 @@ +/* + * (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_dumper_class_bufr_decode_filter.h" +#include "grib_dumper_factory.h" +#include + +eccodes::dumper::BufrDecodeFilter _grib_dumper_bufr_decode_filter; +eccodes::Dumper *grib_dumper_bufr_decode_filter = &_grib_dumper_bufr_decode_filter; + +namespace eccodes::dumper { + +static void dump_attributes(grib_accessor *a, const char *prefix); + +int BufrDecodeFilter::init() +{ + section_offset_ = 0; + empty_ = 1; + isLeaf_ = 0; + isAttribute_ = 0; + keys_ = (grib_string_list*)grib_context_malloc_clear( + context_, sizeof(grib_string_list)); + + return GRIB_SUCCESS; +} + +int BufrDecodeFilter::destroy() +{ + grib_string_list* next = keys_; + grib_string_list* cur = NULL; + while (next) { + cur = next; + next = next->next; + grib_context_free(context_, cur->value); + grib_context_free(context_, cur); + } + return GRIB_SUCCESS; +} + +void BufrDecodeFilter::dump_values(grib_accessor* a) +{ + double value = 0; + size_t size = 0; + int err = 0; + int r; + long count = 0; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + + if (size <= 1) { + err = a->unpack_double(&value, &size); + } + + begin_ = 0; + empty_ = 0; + + if (size > 1) { + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); + else + fprintf(out_, "print \"%s=[%s]\";\n", a->name_, a->name_); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_double(a, value)) { + if (r != 0) + fprintf(out_, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); + else + fprintf(out_, "print \"%s=[%s]\";\n", a->name_, a->name_); + } + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + + (void)err; /* TODO */ +} + +void BufrDecodeFilter::dump_values_attribute(grib_accessor* a, const char* prefix) +{ + double value = 0; + size_t size = 0; + int err = 0; + long count = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + + if (size <= 1) { + err = a->unpack_double(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + fprintf(out_, "print \"%s->%s = [%s->%s]\";\n", prefix, a->name_, prefix, a->name_); + } + else { + if (!grib_is_missing_double(a, value)) { + fprintf(out_, "print \"%s->%s = [%s->%s]\";\n", prefix, a->name_, prefix, a->name_); + } + } + + if (isLeaf_ == 0) { + char* prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth_ -= 2; + } + + (void)err; /* TODO */ +} + +void BufrDecodeFilter::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 0; + int err = 0; + int r = 0; + long count = 0; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + a->value_count(&count); + size = count; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + return; + } + + if (size <= 1) { + err = a->unpack_long(&value, &size); + } + + begin_ = 0; + empty_ = 0; + + if (size > 1) { + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); + else + fprintf(out_, "print \"%s=[%s]\";\n", a->name_, a->name_); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_long(a, value)) { + if (r != 0) + fprintf(out_, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); + else + fprintf(out_, "print \"%s=[%s]\";\n", a->name_, a->name_); + } + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + (void)err; /* TODO */ +} + +void BufrDecodeFilter::dump_long_attribute(grib_accessor* a, const char* prefix) +{ + int err = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + empty_ = 0; + if (!codes_bufr_key_exclude_from_dump(prefix)) { + fprintf(out_, "print \"%s->%s = [%s->%s]\";\n", prefix, a->name_, prefix, a->name_); + } + if (isLeaf_ == 0) { + char* prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth_ -= 2; + } + (void)err; /* TODO */ +} + +void BufrDecodeFilter::dump_bits(grib_accessor* a, const char* comment) {} + +void BufrDecodeFilter::dump_double(grib_accessor* a, const char* comment) +{ + double value = 0; + size_t size = 1; + int r; + grib_handle* h = grib_handle_of_accessor(a); + grib_context* c = h->context; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->unpack_double(&value, &size); + begin_ = 0; + empty_ = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_double(a, value)) { + if (r != 0) + fprintf(out_, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); + else + fprintf(out_, "print \"%s=[%s]\";\n", a->name_, a->name_); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } +} + +void BufrDecodeFilter::dump_string_array(grib_accessor* a, + const char* comment) +{ + size_t size = 0; + grib_context* c = NULL; + int err = 0; + long count = 0; + int r = 0; + grib_handle* h = grib_handle_of_accessor(a); + + c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_string(a, comment); + return; + } + + begin_ = 0; + + if (isLeaf_ == 0) { + depth_ += 2; + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); + else + fprintf(out_, "print \"%s=[%s]\";\n", a->name_, a->name_); + } + + empty_ = 0; + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + + (void)err; /* TODO */ +} + +#define MAX_STRING_SIZE 4096 +void BufrDecodeFilter::dump_string(grib_accessor* a, const char* comment) +{ + char value[MAX_STRING_SIZE] = {0, }; /* See ECC-710 */ + size_t size = MAX_STRING_SIZE; + char* p = NULL; + grib_context* c = a->context_; + int r = 0, err = 0; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + begin_ = 0; + + empty_ = 0; + + err = a->unpack_string(value, &size); + p = value; + r = compute_bufr_key_rank(h, keys_, a->name_); + if (grib_is_missing_string(a, (unsigned char*)value, size)) { + return; + } + + while (*p) { + if (!isprint(*p)) + *p = '.'; + p++; + } + + if (isLeaf_ == 0) { + depth_ += 2; + if (r != 0) + fprintf(out_, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); + else + fprintf(out_, "print \"%s=[%s]\";\n", a->name_, a->name_); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + + (void)err; /* TODO */ +} + +void BufrDecodeFilter::dump_bytes(grib_accessor* a, const char* comment) {} + +void BufrDecodeFilter::dump_label(grib_accessor* a, const char* comment) {} + +static void _dump_long_array(grib_handle* h, FILE* f, const char* key) +{ + size_t size = 0; + if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) + return; + if (size == 0) + return; + + fprintf(f, "print \"%s=[%s]\";\n", key, key); +} + +void BufrDecodeFilter::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + if (strcmp(a->name_, "BUFR") == 0 || strcmp(a->name_, "GRIB") == 0 || + strcmp(a->name_, "META") == 0) { + grib_handle* h = grib_handle_of_accessor(a); + depth_ = 2; + begin_ = 1; + empty_ = 1; + depth_ += 2; + _dump_long_array(h, out_, "dataPresentIndicator"); + _dump_long_array(h, out_, "delayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "shortDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "extendedDelayedDescriptorReplicationFactor"); + /* Do not show the inputOverriddenReferenceValues array. That's more for + * ENCODING */ + /*_dump_long_array(h,out_,"inputOverriddenReferenceValues","inputOverriddenReferenceValues");*/ + grib_dump_accessors_block(this, block); + depth_ -= 2; + } + else if (strcmp(a->name_, "groupNumber") == 0) { + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + begin_ = 1; + empty_ = 1; + depth_ += 2; + grib_dump_accessors_block(this, block); + depth_ -= 2; + } + else { + grib_dump_accessors_block(this, block); + } +} + +void BufrDecodeFilter::dump_attributes(grib_accessor* a, const char* prefix) +{ + int i = 0; + unsigned long flags; + while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { + isAttribute_ = 1; + if ((option_flags_ & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { + i++; + continue; + } + isLeaf_ = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; + /* fprintf(out_,","); */ + /* fprintf(out_,"\n%-*s",depth," "); */ + /* fprintf(out,"\"%s\" : ",a->attributes_[i]->name); */ + flags = a->attributes_[i]->flags_; + a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; + switch (a->attributes_[i]->get_native_type()) { + case GRIB_TYPE_LONG: + dump_long_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_DOUBLE: + dump_values_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_STRING: + break; + } + a->attributes_[i]->flags_ = flags; + i++; + } + isLeaf_ = 0; + isAttribute_ = 0; +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_decode_filter.h b/src/dumper/grib_dumper_class_bufr_decode_filter.h new file mode 100644 index 000000000..9e3d7a863 --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_decode_filter.h @@ -0,0 +1,50 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class BufrDecodeFilter : public Dumper +{ +public: + BufrDecodeFilter() { class_name_ = "bufr_decode_filter"; } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_string_array(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + +private: + static inline int depth_ = 0; + + long section_offset_ = 0; + long begin_ = 0; + long empty_ = 0; + long end_ = 0; + long isLeaf_ = 0; + long isAttribute_ = 0; + grib_string_list* keys_ = nullptr; + + void dump_attributes(grib_accessor* a, const char* prefix); + void dump_values_attribute(grib_accessor* a, const char* prefix); + void dump_long_attribute(grib_accessor* a, const char* prefix); +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_decode_fortran.cc b/src/dumper/grib_dumper_class_bufr_decode_fortran.cc new file mode 100644 index 000000000..a12e70e1a --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_decode_fortran.cc @@ -0,0 +1,561 @@ +/* + * (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_dumper_class_bufr_decode_fortran.h" +#include "grib_dumper_factory.h" +#include + +eccodes::dumper::BufrDecodeFortran _grib_dumper_bufr_decode_fortran; +eccodes::Dumper* grib_dumper_bufr_decode_fortran = &_grib_dumper_bufr_decode_fortran; + +namespace eccodes::dumper +{ + +static int depth = 0; + +int BufrDecodeFortran::init() +{ + grib_context* c = context_; + section_offset_ = 0; + empty_ = 1; + count_ = 1; + isLeaf_ = 0; + isAttribute_ = 0; + keys_ = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); + + return GRIB_SUCCESS; +} + +int BufrDecodeFortran::destroy() +{ + grib_string_list* next = keys_; + grib_string_list* cur = NULL; + grib_context* c = context_; + while (next) { + cur = next; + next = next->next; + grib_context_free(c, cur->value); + grib_context_free(c, cur); + } + return GRIB_SUCCESS; +} + +void BufrDecodeFortran::dump_values(grib_accessor* a) +{ + double value = 0; + size_t size = 0; + int err = 0; + int r = 0; + long count = 0; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + + if (size <= 1) { + err = a->unpack_double(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + depth -= 2; + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " call codes_get(ibufr, '#%d#%s', rValues)\n", r, a->name_); + else + fprintf(out_, " call codes_get(ibufr, '%s', rValues)\n", a->name_); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_double(a, value)) { + if (r != 0) + fprintf(out_, " call codes_get(ibufr, '#%d#%s', rVal)\n", r, a->name_); + else + fprintf(out_, " call codes_get(ibufr, '%s', rVal)\n", a->name_); + } + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + + (void)err; /* TODO */ +} + +void BufrDecodeFortran::dump_values_attribute(grib_accessor* a, const char* prefix) +{ + double value = 0; + size_t size = 0; + int err = 0; + long count = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + + if (size <= 1) { + err = a->unpack_double(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + fprintf(out_, " call codes_get(ibufr, '%s->%s', rValues)\n", prefix, a->name_); + } + else { + if (!grib_is_missing_double(a, value)) { + fprintf(out_, " call codes_get(ibufr, '%s->%s', rVal)\n", prefix, a->name_); + } + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth -= 2; + } + + (void)err; /* TODO */ +} + +void BufrDecodeFortran::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 0; + int err = 0; + int r = 0; + long count = 0; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + a->value_count(&count); + size = count; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + return; + } + + if (size <= 1) { + err = a->unpack_long(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + depth -= 2; + fprintf(out_, " if(allocated(iValues)) deallocate(iValues)\n"); + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " call codes_get(ibufr, '#%d#%s', iValues)\n", r, a->name_); + else + fprintf(out_, " call codes_get(ibufr, '%s', iValues)\n", a->name_); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_long(a, value)) { + if (r != 0) + fprintf(out_, " call codes_get(ibufr, '#%d#%s', iVal)\n", r, a->name_); + else + fprintf(out_, " call codes_get(ibufr, '%s', iVal)\n", a->name_); + } + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + (void)err; /* TODO */ +} + +void BufrDecodeFortran::dump_long_attribute(grib_accessor* a, const char* prefix) +{ + long value = 0; + size_t size = 0; + int err = 0; + long count = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + + if (size <= 1) { + err = a->unpack_long(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + depth -= 2; + fprintf(out_, " if(allocated(iValues)) deallocate(iValues)\n"); + + fprintf(out_, " call codes_get(ibufr, '%s->%s', iValues)\n", prefix, a->name_); + } + else { + if (!codes_bufr_key_exclude_from_dump(prefix)) { + if (!grib_is_missing_long(a, value)) { + fprintf(out_, " call codes_get(ibufr, '%s->%s', iVal)\n", prefix, a->name_); + } + } + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth -= 2; + } + (void)err; /* TODO */ +} + +void BufrDecodeFortran::dump_bits(grib_accessor* a, const char* comment) +{ +} + +void BufrDecodeFortran::dump_double(grib_accessor* a, const char* comment) +{ + double value; + size_t size = 1; + int r; + grib_handle* h = grib_handle_of_accessor(a); + grib_context* c = h->context; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->unpack_double(&value, &size); + empty_ = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_double(a, value)) { + if (r != 0) + fprintf(out_, " call codes_get(ibufr,'#%d#%s', rVal)\n", r, a->name_); + else + fprintf(out_, " call codes_get(ibufr,'%s', rVal)\n", a->name_); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } +} + +void BufrDecodeFortran::dump_string_array(grib_accessor* a, const char* comment) +{ + size_t size = 0; + grib_context* c = NULL; + int err = 0; + long count = 0; + int r = 0; + grib_handle* h = grib_handle_of_accessor(a); + + c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_string(a, comment); + return; + } + + fprintf(out_, " if(allocated(sValues)) deallocate(sValues)\n"); + fprintf(out_, " allocate(sValues(%lu))\n", (unsigned long)size); + + empty_ = 0; + + if (isLeaf_ == 0) { + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " call codes_get_string_array(ibufr,'#%d#%s',sValues)\n", r, a->name_); + else + fprintf(out_, " call codes_get_string_array(ibufr,'%s',sValues)\n", a->name_); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + + (void)err; /* TODO */ +} + +#define MAX_STRING_SIZE 4096 +void BufrDecodeFortran::dump_string(grib_accessor* a, const char* comment) +{ + char value[MAX_STRING_SIZE] = {0, }; /* See ECC-710 */ + size_t size = MAX_STRING_SIZE; + char* p = NULL; + grib_context* c = a->context_; + int r = 0, err = 0; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + empty_ = 0; + + err = a->unpack_string(value, &size); + p = value; + r = compute_bufr_key_rank(h, keys_, a->name_); + if (grib_is_missing_string(a, (unsigned char*)value, size)) { + return; + } + + while (*p) { + if (!isprint(*p)) + *p = '.'; + p++; + } + + if (isLeaf_ == 0) { + depth += 2; + if (r != 0) + fprintf(out_, " call codes_get(ibufr, '#%d#%s', sVal)\n", r, a->name_); + else + fprintf(out_, " call codes_get(ibufr, '%s', sVal)\n", a->name_); + } + /*fprintf(dumper_.out,"\'%s\')\n",value);*/ + + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + + (void)err; /* TODO */ +} + +void BufrDecodeFortran::dump_bytes(grib_accessor* a, const char* comment) +{ +} + +void BufrDecodeFortran::dump_label(grib_accessor* a, const char* comment) +{ +} + +static void _dump_long_array(grib_handle* h, FILE* f, const char* key) +{ + size_t size = 0; + if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) + return; + if (size == 0) + return; + + fprintf(f, " if(allocated(iValues)) deallocate(iValues)\n"); + fprintf(f, " call codes_get(ibufr, '%s', iValues)\n", key); +} + +void BufrDecodeFortran::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + if (strcmp(a->name_, "BUFR") == 0 || + strcmp(a->name_, "GRIB") == 0 || + strcmp(a->name_, "META") == 0) { + grib_handle* h = grib_handle_of_accessor(a); + depth = 2; + empty_ = 1; + depth += 2; + _dump_long_array(h, out_, "dataPresentIndicator"); + _dump_long_array(h, out_, "delayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "shortDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "extendedDelayedDescriptorReplicationFactor"); + /* Do not show the inputOverriddenReferenceValues array. That's more for ENCODING */ + /* _dump_long_array(h,out_,"inputOverriddenReferenceValues","inputOverriddenReferenceValues"); */ + grib_dump_accessors_block(this, block); + depth -= 2; + } + else if (strcmp(a->name_, "groupNumber") == 0) { + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + empty_ = 1; + depth += 2; + grib_dump_accessors_block(this, block); + depth -= 2; + } + else { + grib_dump_accessors_block(this, block); + } +} + +void BufrDecodeFortran::dump_attributes(grib_accessor* a, const char* prefix) +{ + int i = 0; + unsigned long flags; + while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { + isAttribute_ = 1; + if ((option_flags_ & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { + i++; + continue; + } + isLeaf_ = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; + flags = a->attributes_[i]->flags_; + a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; + switch (a->attributes_[i]->get_native_type()) { + case GRIB_TYPE_LONG: + dump_long_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_DOUBLE: + dump_values_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_STRING: + break; + } + a->attributes_[i]->flags_ = flags; + i++; + } + isLeaf_ = 0; + isAttribute_ = 0; +} + +void BufrDecodeFortran::header(const grib_handle* h) +{ + if (count_ < 2) { + /* This is the first message being processed */ + fprintf(out_, "! This program was automatically generated with bufr_dump -Dfortran\n"); + fprintf(out_, "! Using ecCodes version: "); + grib_print_api_version(out_); + fprintf(out_, "\n\n"); + fprintf(out_, "program bufr_decode\n"); + fprintf(out_, " use eccodes\n"); + fprintf(out_, " implicit none\n"); + fprintf(out_, " integer, parameter :: max_strsize = 200\n"); + fprintf(out_, " integer :: iret\n"); + fprintf(out_, " integer :: ifile\n"); + fprintf(out_, " integer :: ibufr\n"); + fprintf(out_, " integer(kind=4) :: iVal\n"); + fprintf(out_, " real(kind=8) :: rVal\n"); + fprintf(out_, " character(len=max_strsize) :: sVal\n"); + fprintf(out_, " integer(kind=4), dimension(:), allocatable :: iValues\n"); + fprintf(out_, " character(len=max_strsize) , dimension(:),allocatable :: sValues\n"); + fprintf(out_, " real(kind=8), dimension(:), allocatable :: rValues\n\n"); + fprintf(out_, " character(len=max_strsize) :: infile_name\n"); + fprintf(out_, " call getarg(1, infile_name)\n"); + fprintf(out_, " call codes_open_file(ifile, infile_name, 'r')\n\n"); + } + fprintf(out_, " ! Message number %ld\n ! -----------------\n", count_); + fprintf(out_, " write(*,*) 'Decoding message number %ld'\n", count_); + fprintf(out_, " call codes_bufr_new_from_file(ifile, ibufr)\n"); + fprintf(out_, " call codes_set(ibufr, 'unpack', 1)\n"); +} + +void BufrDecodeFortran::footer(const grib_handle* h) +{ + /*fprintf(dumper_.out," call codes_close_file(ifile)\n");*/ + fprintf(out_, " call codes_release(ibufr)\n"); +} +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_decode_fortran.h b/src/dumper/grib_dumper_class_bufr_decode_fortran.h new file mode 100644 index 000000000..ccf2ba48a --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_decode_fortran.h @@ -0,0 +1,49 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class BufrDecodeFortran : public Dumper +{ +public: + BufrDecodeFortran() { class_name_ = "bufr_decode_fortran"; } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_string_array(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + void header(const grib_handle*) override; + void footer(const grib_handle*) override; + +private: + long section_offset_ = 0; + long empty_ = 0; + long end_ = 0; + long isLeaf_ = 0; + long isAttribute_ = 0; + grib_string_list* keys_ = nullptr; + + void dump_attributes(grib_accessor* a, const char* prefix); + void dump_values_attribute(grib_accessor* a, const char* prefix); + void dump_long_attribute(grib_accessor* a, const char* prefix); +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_decode_python.cc b/src/dumper/grib_dumper_class_bufr_decode_python.cc new file mode 100644 index 000000000..434c60829 --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_decode_python.cc @@ -0,0 +1,560 @@ +/* + * (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_dumper_class_bufr_decode_python.h" +#include "grib_dumper_factory.h" +#include + +eccodes::dumper::BufrDecodePython _grib_dumper_bufr_decode_python; +eccodes::Dumper* grib_dumper_bufr_decode_python = &_grib_dumper_bufr_decode_python; + +namespace eccodes::dumper +{ + +static int depth = 0; + +int BufrDecodePython::init() +{ + grib_context* c = context_; + section_offset_ = 0; + empty_ = 1; + count_ = 1; + isLeaf_ = 0; + isAttribute_ = 0; + keys_ = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); + + return GRIB_SUCCESS; +} + +int BufrDecodePython::destroy() +{ + grib_string_list* next = keys_; + grib_string_list* cur = NULL; + grib_context* c = context_; + while (next) { + cur = next; + next = next->next; + grib_context_free(c, cur->value); + grib_context_free(c, cur); + } + return GRIB_SUCCESS; +} + +static char* dval_to_string(const grib_context* c, double v) +{ + char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * 40); + snprintf(sval, 1024, "%.18e", v); + return sval; +} + +void BufrDecodePython::dump_values(grib_accessor* a) +{ + double value = 0; + size_t size = 0; + int err = 0; + int r = 0; + long count = 0; + char* sval = NULL; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + + if (size <= 1) { + err = a->unpack_double(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + depth -= 2; + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " dVals = codes_get_array(ibufr, '#%d#%s')\n", r, a->name_); + else + fprintf(out_, " dVals = codes_get_array(ibufr, '%s')\n", a->name_); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_double(a, value)) { + sval = dval_to_string(c, value); + if (r != 0) + fprintf(out_, " dVal = codes_get(ibufr, '#%d#%s')\n", r, a->name_); + else + fprintf(out_, " dVal = codes_get(ibufr, '%s')\n", a->name_); + + grib_context_free(c, sval); + } + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + + (void)err; /* TODO */ +} + +void BufrDecodePython::dump_values_attribute(grib_accessor* a, const char* prefix) +{ + double value = 0; + size_t size = 0; + int err = 0; + long count = 0; + char* sval; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + + if (size <= 1) { + err = a->unpack_double(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + depth -= 2; + fprintf(out_, " dVals = codes_get_array(ibufr, '%s->%s')\n", prefix, a->name_); + } + else { + /* int r=compute_bufr_key_rank(h,keys_,a->name_); */ + if (!grib_is_missing_double(a, value)) { + sval = dval_to_string(c, value); + fprintf(out_, " dVal = codes_get(ibufr, '%s->%s')\n", prefix, a->name_); + + grib_context_free(c, sval); + } + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth -= 2; + } + + (void)err; /* TODO */ +} + +void BufrDecodePython::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 0; + int err = 0; + int r = 0; + long count = 0; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + a->value_count(&count); + size = count; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + return; + } + + if (size <= 1) { + err = a->unpack_long(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + depth -= 2; + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " iValues = codes_get_array(ibufr, '#%d#%s')\n", r, a->name_); + else + fprintf(out_, " iValues = codes_get_array(ibufr, '%s')\n", a->name_); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_long(a, value)) { + if (r != 0) + fprintf(out_, " iVal = codes_get(ibufr, '#%d#%s')\n", r, a->name_); + else + fprintf(out_, " iVal = codes_get(ibufr, '%s')\n", a->name_); + } + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + (void)err; /* TODO */ +} + +void BufrDecodePython::dump_long_attribute(grib_accessor* a, const char* prefix) +{ + long value = 0; + size_t size = 0; + int err = 0; + long count = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + + if (size <= 1) { + err = a->unpack_long(&value, &size); + } + + empty_ = 0; + + if (size > 1) { + depth -= 2; + fprintf(out_, " iVals = codes_get_array(ibufr, '%s->%s')\n", prefix, a->name_); + } + else { + if (!codes_bufr_key_exclude_from_dump(prefix)) { + if (!grib_is_missing_long(a, value)) { + fprintf(out_, " iVal = codes_get(ibufr, '%s->%s')\n", prefix, a->name_); + } + } + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth -= 2; + } + (void)err; /* TODO */ +} + +void BufrDecodePython::dump_bits(grib_accessor* a, const char* comment) +{ +} + +void BufrDecodePython::dump_double(grib_accessor* a, const char* comment) +{ + double value = 0; + size_t size = 1; + int r; + char* sval = NULL; + grib_handle* h = grib_handle_of_accessor(a); + grib_context* c = h->context; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->unpack_double(&value, &size); + empty_ = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_double(a, value)) { + sval = dval_to_string(c, value); + if (r != 0) + fprintf(out_, " dVal = codes_get(ibufr, '#%d#%s')\n", r, a->name_); + else + fprintf(out_, " dVal = codes_get(ibufr, '%s')\n", a->name_); + + grib_context_free(c, sval); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } +} + +void BufrDecodePython::dump_string_array(grib_accessor* a, const char* comment) +{ + size_t size = 0; + grib_context* c = NULL; + int err = 0; + long count = 0; + int r = 0; + grib_handle* h = grib_handle_of_accessor(a); + + c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_string(a, comment); + return; + } + + empty_ = 0; + + if (isLeaf_ == 0) { + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " sVals = codes_get_string_array(ibufr, '#%d#%s')\n", r, a->name_); + else + fprintf(out_, " sVals = codes_get_string_array(ibufr, '%s')\n", a->name_); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + + (void)err; /* TODO */ +} + +#define MAX_STRING_SIZE 4096 +void BufrDecodePython::dump_string(grib_accessor* a, const char* comment) +{ + char value[MAX_STRING_SIZE] = {0, }; /* See ECC-710 */ + char* p = NULL; + size_t size = MAX_STRING_SIZE; + grib_context* c = a->context_; + int r = 0, err = 0; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + empty_ = 0; + + err = a->unpack_string(value, &size); + p = value; + r = compute_bufr_key_rank(h, keys_, a->name_); + if (grib_is_missing_string(a, (unsigned char*)value, size)) { + return; + } + + while (*p) { + if (!isprint(*p)) + *p = '.'; + p++; + } + + if (isLeaf_ == 0) { + depth += 2; + if (r != 0) + fprintf(out_, " sVal = codes_get(ibufr, '#%d#%s')\n", r, a->name_); + else + fprintf(out_, " sVal = codes_get(ibufr, '%s')\n", a->name_); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + + (void)err; /* TODO */ +} + +void BufrDecodePython::dump_bytes(grib_accessor* a, const char* comment) +{ +} + +void BufrDecodePython::dump_label(grib_accessor* a, const char* comment) +{ +} + +static void _dump_long_array(grib_handle* h, FILE* f, const char* key) +{ + size_t size = 0; + if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) + return; + if (size == 0) + return; + + fprintf(f, " iVals = codes_get_array(ibufr, '%s')\n", key); +} + +void BufrDecodePython::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + if (strcmp(a->name_, "BUFR") == 0 || + strcmp(a->name_, "GRIB") == 0 || + strcmp(a->name_, "META") == 0) { + grib_handle* h = grib_handle_of_accessor(a); + depth = 2; + empty_ = 1; + depth += 2; + _dump_long_array(h, out_, "dataPresentIndicator"); + _dump_long_array(h, out_, "delayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "shortDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "extendedDelayedDescriptorReplicationFactor"); + /* Do not show the inputOverriddenReferenceValues array. That's more for ENCODING */ + /* _dump_long_array(h,out_,"inputOverriddenReferenceValues","inputOverriddenReferenceValues"); */ + grib_dump_accessors_block(this, block); + depth -= 2; + } + else if (strcmp(a->name_, "groupNumber") == 0) { + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + empty_ = 1; + depth += 2; + grib_dump_accessors_block(this, block); + depth -= 2; + } + else { + grib_dump_accessors_block(this, block); + } +} + +void BufrDecodePython::dump_attributes(grib_accessor* a, const char* prefix) +{ + int i = 0; + unsigned long flags; + while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { + isAttribute_ = 1; + if ((option_flags_ & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { + i++; + continue; + } + isLeaf_ = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; + flags = a->attributes_[i]->flags_; + a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; + switch (a->attributes_[i]->get_native_type()) { + case GRIB_TYPE_LONG: + dump_long_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_DOUBLE: + dump_values_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_STRING: + break; + } + a->attributes_[i]->flags_ = flags; + i++; + } + isLeaf_ = 0; + isAttribute_ = 0; +} + +void BufrDecodePython::header(const grib_handle* h) +{ + if (count_ < 2) { + /* This is the first message being processed */ + fprintf(out_, "# This program was automatically generated with bufr_dump -Dpython\n"); + fprintf(out_, "# Using ecCodes version: "); + grib_print_api_version(out_); + fprintf(out_, "\n\n"); + fprintf(out_, "import traceback\n"); + fprintf(out_, "import sys\n"); + fprintf(out_, "from eccodes import *\n\n\n"); + fprintf(out_, "def bufr_decode(input_file):\n"); + fprintf(out_, " f = open(input_file, 'rb')\n"); + } + fprintf(out_, " # Message number %ld\n # -----------------\n", count_); + fprintf(out_, " print ('Decoding message number %ld')\n", count_); + fprintf(out_, " ibufr = codes_bufr_new_from_file(f)\n"); + fprintf(out_, " codes_set(ibufr, 'unpack', 1)\n"); +} + +void BufrDecodePython::footer(const grib_handle* h) +{ + fprintf(out_, " codes_release(ibufr)\n"); +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_decode_python.h b/src/dumper/grib_dumper_class_bufr_decode_python.h new file mode 100644 index 000000000..ea3f69f78 --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_decode_python.h @@ -0,0 +1,51 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class BufrDecodePython : public Dumper +{ +public: + BufrDecodePython() { class_name_ = "bufr_decode_python"; } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_string_array(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + void header(const grib_handle*) override; + void footer(const grib_handle*) override; + +private: + static inline int depth_ = 0; + + long section_offset_ = 0; + long empty_ = 0; + long end_ = 0; + long isLeaf_ = 0; + long isAttribute_ = 0; + grib_string_list* keys_ = nullptr; + + void dump_attributes(grib_accessor* a, const char* prefix); + void dump_values_attribute(grib_accessor* a, const char* prefix); + void dump_long_attribute(grib_accessor* a, const char* prefix); +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_encode_C.cc b/src/dumper/grib_dumper_class_bufr_encode_C.cc new file mode 100644 index 000000000..3aef72260 --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_encode_C.cc @@ -0,0 +1,834 @@ +/* + * (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_dumper_class_bufr_encode_C.h" +#include "grib_dumper_factory.h" +#include + +eccodes::dumper::BufrEncodeC _grib_dumper_bufr_encode_c; +eccodes::Dumper* grib_dumper_bufr_encode_c = &_grib_dumper_bufr_encode_c; + +namespace eccodes::dumper +{ + +int BufrEncodeC::init() +{ + grib_context* c = context_; + section_offset_ = 0; + empty_ = 1; + count_ = 1; + isLeaf_ = 0; + isAttribute_ = 0; + keys_ = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); + + return GRIB_SUCCESS; +} + +int BufrEncodeC::destroy() +{ + grib_string_list* next = keys_; + grib_string_list* cur = NULL; + grib_context* c = context_; + while (next) { + cur = next; + next = next->next; + grib_context_free(c, cur->value); + grib_context_free(c, cur); + } + return GRIB_SUCCESS; +} + +static char* lval_to_string(grib_context* c, long v) +{ + const size_t svalMaxLen = 40; + char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * svalMaxLen); + if (v == GRIB_MISSING_LONG) + snprintf(sval, svalMaxLen, "CODES_MISSING_LONG"); + else + snprintf(sval, svalMaxLen, "%ld", v); + return sval; +} +static char* dval_to_string(grib_context* c, double v) +{ + const size_t svalMaxLen = 40; + char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * svalMaxLen); + if (v == GRIB_MISSING_DOUBLE) + snprintf(sval, svalMaxLen, "CODES_MISSING_DOUBLE"); + else + snprintf(sval, svalMaxLen, "%.18e", v); + return sval; +} + +void BufrEncodeC::dump_values(grib_accessor* a) +{ + double value = 0; + size_t size = 0, size2 = 0; + double* values = NULL; + int err = 0; + int i, r, icount; + int cols = 2; + long count = 0; + char* sval; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); + err = a->unpack_double(values, &size2); + } + else { + err = a->unpack_double(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, " free(rvalues); rvalues = NULL;\n\n"); + fprintf(out_, " size = %lu;\n", (unsigned long)size); + fprintf(out_, " rvalues = (double*)malloc(size * sizeof(double));\n"); + fprintf(out_, " if (!rvalues) { fprintf(stderr, \"Failed to allocate memory (%s).\\n\"); return 1; }", a->name_); + + icount = 0; + for (i = 0; i < size - 1; ++i) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + sval = dval_to_string(c, values[i]); + fprintf(out_, "rvalues[%d]=%s; ", i, sval); + grib_context_free(c, sval); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + sval = dval_to_string(c, values[i]); + fprintf(out_, "rvalues[%d]=%s;", i, sval); + grib_context_free(c, sval); + + depth_ -= 2; + fprintf(out_, "\n"); + grib_context_free(c, values); + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " CODES_CHECK(codes_set_double_array(h, \"#%d#%s\",rvalues, size), 0);\n", r, a->name_); + else + fprintf(out_, " CODES_CHECK(codes_set_double_array(h, \"%s\", rvalues, size), 0);\n", a->name_); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + sval = dval_to_string(c, value); + if (r != 0) + fprintf(out_, " CODES_CHECK(codes_set_double(h, \"#%d#%s\", %s), 0);\n", r, a->name_, sval); + else + fprintf(out_, " CODES_CHECK(codes_set_double(h, \"%s\", %s), 0);\n", a->name_, sval); + grib_context_free(c, sval); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + const size_t prefixMaxLen = strlen(a->name_) + 10; + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * prefixMaxLen); + dofree = 1; + snprintf(prefix, prefixMaxLen, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + + (void)err; /* TODO */ +} + +void BufrEncodeC::dump_values_attribute(grib_accessor* a, const char* prefix) +{ + double value = 0; + size_t size = 0, size2 = 0; + double* values = NULL; + int err = 0; + int i, icount; + int cols = 2; + long count = 0; + char* sval; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); + err = a->unpack_double(values, &size2); + } + else { + err = a->unpack_double(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, " free(rvalues); rvalues = NULL;\n"); + fprintf(out_, " size = %lu;\n", (unsigned long)size); + fprintf(out_, " rvalues = (double*)malloc(size * sizeof(double));\n"); + fprintf(out_, " if (!rvalues) { fprintf(stderr, \"Failed to allocate memory (%s).\\n\"); return 1; }", a->name_); + + icount = 0; + for (i = 0; i < size - 1; ++i) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + sval = dval_to_string(c, values[i]); + fprintf(out_, "rvalues[%d]=%s; ", i, sval); + grib_context_free(c, sval); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + sval = dval_to_string(c, values[i]); + fprintf(out_, "rvalues[%d]=%s;", i, sval); + grib_context_free(c, sval); + + depth_ -= 2; + fprintf(out_, "\n"); + grib_context_free(c, values); + + fprintf(out_, " CODES_CHECK(codes_set_double_array(h, \"%s->%s\", rvalues, size), 0);\n", prefix, a->name_); + } + else { + sval = dval_to_string(c, value); + fprintf(out_, " CODES_CHECK(codes_set_double(h, \"%s->%s\", %s), 0);\n", prefix, a->name_, sval); + grib_context_free(c, sval); + } + + if (isLeaf_ == 0) { + const size_t prefix1MaxLen = strlen(a->name_) + strlen(prefix) + 5; + char* prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * prefix1MaxLen); + snprintf(prefix1, prefix1MaxLen, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth_ -= 2; + } + + (void)err; /* TODO */ +} + +static int is_hidden(grib_accessor* a) +{ + return ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0); +} + +void BufrEncodeC::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 0, size2 = 0; + long* values = NULL; + int err = 0; + int i, r, icount; + int cols = 4; + long count = 0; + char* sval = NULL; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + int doing_unexpandedDescriptors = 0; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { /* key does not have the dump attribute */ + int skip = 1; + /* See ECC-1107 */ + if (!is_hidden(a) && strcmp(a->name_, "messageLength") == 0) skip = 0; + if (skip) return; + } + + doing_unexpandedDescriptors = (strcmp(a->name_, "unexpandedDescriptors") == 0); + a->value_count(&count); + size = size2 = count; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (r != 0) { + const size_t prefixMaxLen = strlen(a->name_) + 10; + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * prefixMaxLen); + dofree = 1; + snprintf(prefix, prefixMaxLen, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + return; + } + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size2); + } + else { + err = a->unpack_long(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, " free(ivalues); ivalues = NULL;\n\n"); + fprintf(out_, " size = %lu;\n", (unsigned long)size); + fprintf(out_, " ivalues = (long*)malloc(size * sizeof(long));\n"); + fprintf(out_, " if (!ivalues) { fprintf(stderr, \"Failed to allocate memory (%s).\\n\"); return 1; }", a->name_); + + icount = 0; + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + fprintf(out_, "ivalues[%d]=%ld; ", i, values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + fprintf(out_, "ivalues[%d]=%ld;", i, values[i]); + + depth_ -= 2; + fprintf(out_, "\n"); + grib_context_free(a->context_, values); + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) { + fprintf(out_, " CODES_CHECK(codes_set_long_array(h, \"#%d#%s\", ivalues, size), 0);\n", r, a->name_); + } + else { + if (doing_unexpandedDescriptors) { + fprintf(out_, "\n /* Create the structure of the data section */\n"); + /* fprintf(out_," CODES_CHECK(codes_set_long(h, \"skipExtraKeyAttributes\", 1), 0);\n"); */ + } + fprintf(out_, " CODES_CHECK(codes_set_long_array(h, \"%s\", ivalues, size), 0);\n", a->name_); + if (doing_unexpandedDescriptors) + fprintf(out_, "\n"); + } + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + sval = lval_to_string(c, value); + if (r != 0) { + fprintf(out_, " CODES_CHECK(codes_set_long(h, \"#%d#%s\", ", r, a->name_); + } + else { + if (doing_unexpandedDescriptors) { + fprintf(out_, "\n /* Create the structure of the data section */\n"); + /* fprintf(out_," CODES_CHECK(codes_set_long(h, \"skipExtraKeyAttributes\", 1), 0);\n"); */ + } + fprintf(out_, " CODES_CHECK(codes_set_long(h, \"%s\", ", a->name_); + } + + fprintf(out_, "%s), 0);\n", sval); + grib_context_free(c, sval); + if (doing_unexpandedDescriptors) + fprintf(out_, "\n"); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + const size_t prefixMaxLen = strlen(a->name_) + 10; + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * prefixMaxLen); + dofree = 1; + snprintf(prefix, prefixMaxLen, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + (void)err; /* TODO */ +} + +void BufrEncodeC::dump_long_attribute(grib_accessor* a, const char* prefix) +{ + long value = 0; + size_t size = 0, size2 = 0; + long* values = NULL; + int err = 0; + int i, icount; + int cols = 4; + long count = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size2); + } + else { + err = a->unpack_long(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, " free(ivalues); ivalues = NULL;\n"); + fprintf(out_, " size = %lu;\n", (unsigned long)size); + fprintf(out_, " ivalues = (long*)malloc(size * sizeof(long));\n"); + fprintf(out_, " if (!ivalues) { fprintf(stderr, \"Failed to allocate memory (%s).\\n\"); return 1; }", a->name_); + + icount = 0; + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + fprintf(out_, "ivalues[%d]=%ld; ", i, values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + fprintf(out_, "ivalues[%d]=%ld;", i, values[i]); + + depth_ -= 2; + fprintf(out_, "\n"); + grib_context_free(a->context_, values); + + fprintf(out_, " CODES_CHECK(codes_set_long_array(h, \"%s->%s\", ivalues, size), 0);\n", prefix, a->name_); + } + else { + if (!codes_bufr_key_exclude_from_dump(prefix)) { + char* sval = lval_to_string(c, value); + fprintf(out_, " CODES_CHECK(codes_set_long(h, \"%s->%s\", ", prefix, a->name_); + fprintf(out_, "%s), 0);\n", sval); + grib_context_free(c, sval); + } + } + + if (isLeaf_ == 0) { + const size_t prefix1MaxLen = strlen(a->name_) + strlen(prefix) + 5; + char* prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * prefix1MaxLen); + snprintf(prefix1, prefix1MaxLen, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth_ -= 2; + } + (void)err; /* TODO */ +} + +void BufrEncodeC::dump_bits(grib_accessor* a, const char* comment) +{ +} + +void BufrEncodeC::dump_double(grib_accessor* a, const char* comment) +{ + double value = 0; + size_t size = 1; + int r; + char* sval; + grib_handle* h = grib_handle_of_accessor(a); + grib_context* c = h->context; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->unpack_double(&value, &size); + empty_ = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + + sval = dval_to_string(c, value); + if (r != 0) + fprintf(out_, " CODES_CHECK(codes_set_double(h, \"#%d#%s\", %s), 0);\n", r, a->name_, sval); + else + fprintf(out_, " CODES_CHECK(codes_set_double(h, \"%s\", %s), 0);\n", a->name_, sval); + grib_context_free(c, sval); + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + const size_t prefixMaxLen = strlen(a->name_) + 10; + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * prefixMaxLen); + dofree = 1; + snprintf(prefix, prefixMaxLen, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } +} + +void BufrEncodeC::dump_string_array(grib_accessor* a, const char* comment) +{ + char** values; + size_t size = 0, i = 0; + grib_context* c = a->context_; + int err = 0; + long count = 0; + int r = 0; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_string(a, comment); + return; + } + + fprintf(out_, " free(svalues);\n"); + fprintf(out_, " size = %lu;\n", (unsigned long)size); + fprintf(out_, " svalues = (char**)malloc(size * sizeof(char*));\n"); + fprintf(out_, " if (!svalues) { fprintf(stderr, \"Failed to allocate memory (%s).\\n\"); return 1; }\n", a->name_); + + empty_ = 0; + values = (char**)grib_context_malloc_clear(c, size * sizeof(char*)); + if (!values) { + grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); + return; + } + + err = a->unpack_string_array(values, &size); + for (i = 0; i < size - 1; i++) { + fprintf(out_, " svalues[%lu]=\"%s\"; \n", (unsigned long)i, values[i]); + } + fprintf(out_, " svalues[%lu]=\"%s\";\n", (unsigned long)i, values[i]); + + if (isLeaf_ == 0) { + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " codes_set_string_array(h, \"#%d#%s\", (const char **)svalues, size);\n", r, a->name_); + else + fprintf(out_, " codes_set_string_array(h, \"%s\", (const char **)svalues, size);\n", a->name_); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + const size_t prefixMaxLen = strlen(a->name_) + 10; + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * prefixMaxLen); + dofree = 1; + snprintf(prefix, prefixMaxLen, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + + for (i = 0; i < size; i++) + grib_context_free(c, values[i]); + grib_context_free(c, values); + (void)err; /* TODO */ +} + +void BufrEncodeC::dump_string(grib_accessor* a, const char* comment) +{ + char* value = NULL; + char* p = NULL; + size_t size = 0; + grib_context* c = a->context_; + int r = 0, err = 0; + grib_handle* h = grib_handle_of_accessor(a); + const char* acc_name = a->name_; + + grib_get_string_length_acc(a, &size); + if (size == 0) + return; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + value = (char*)grib_context_malloc_clear(c, size); + if (!value) { + grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); + return; + } + + empty_ = 0; + + err = a->unpack_string(value, &size); + p = value; + r = compute_bufr_key_rank(h, keys_, acc_name); + if (grib_is_missing_string(a, (unsigned char*)value, size)) { + strcpy(value, ""); /* Empty string means MISSING string */ + } + + while (*p) { + if (!isprint(*p)) + *p = '?'; + if (*p == '"') + *p = '\''; /* ECC-1401 */ + p++; + } + + fprintf(out_, " size = %lu;\n", (unsigned long)size); + if (isLeaf_ == 0) { + depth_ += 2; + if (r != 0) + fprintf(out_, " codes_set_string(h, \"#%d#%s\", ", r, acc_name); + else + fprintf(out_, " codes_set_string(h, \"%s\", ", acc_name); + } + fprintf(out_, "\"%s\", &size);\n", value); + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + const size_t prefixMaxLen = strlen(acc_name) + 10; + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * prefixMaxLen); + dofree = 1; + snprintf(prefix, prefixMaxLen, "#%d#%s", r, acc_name); + } + else + prefix = (char*)acc_name; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + + grib_context_free(c, value); + (void)err; /* TODO */ +} + +void BufrEncodeC::dump_bytes(grib_accessor* a, const char* comment) +{ +} + +void BufrEncodeC::dump_label(grib_accessor* a, const char* comment) +{ +} + +static void _dump_long_array(grib_handle* h, FILE* f, const char* key, const char* print_key) +{ + long* val; + size_t size = 0, i; + int cols = 9, icount = 0; + + if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) + return; + if (size == 0) + return; + + fprintf(f, " free(ivalues); ivalues = NULL;\n"); + fprintf(f, " size = %lu;\n", (unsigned long)size); + fprintf(f, " ivalues = (long*)malloc(size * sizeof(long));\n"); + fprintf(f, " if (!ivalues) { fprintf(stderr, \"Failed to allocate memory (%s).\\n\"); return 1; }", key); + + val = (long*)grib_context_malloc_clear(h->context, sizeof(long) * size); + grib_get_long_array(h, key, val, &size); + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(f, "\n "); + icount = 0; + } + fprintf(f, "ivalues[%lu]=%ld; ", (unsigned long)i, val[i]); + icount++; + } + if (icount > cols) { + fprintf(f, "\n "); + } + fprintf(f, "ivalues[%lu]=%ld;\n", (unsigned long)(size - 1), val[size - 1]); + + grib_context_free(h->context, val); + fprintf(f, " CODES_CHECK(codes_set_long_array(h, \"%s\", ivalues, size), 0);\n", print_key); +} + +void BufrEncodeC::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + if (strcmp(a->name_, "BUFR") == 0 || + strcmp(a->name_, "GRIB") == 0 || + strcmp(a->name_, "META") == 0) { + grib_handle* h = grib_handle_of_accessor(a); + depth_ = 2; + empty_ = 1; + depth_ += 2; + _dump_long_array(h, out_, "dataPresentIndicator", "inputDataPresentIndicator"); + _dump_long_array(h, out_, "delayedDescriptorReplicationFactor", "inputDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "shortDelayedDescriptorReplicationFactor", "inputShortDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "extendedDelayedDescriptorReplicationFactor", "inputExtendedDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "inputOverriddenReferenceValues", "inputOverriddenReferenceValues"); + grib_dump_accessors_block(this, block); + depth_ -= 2; + } + else if (strcmp(a->name_, "groupNumber") == 0) { + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + empty_ = 1; + depth_ += 2; + grib_dump_accessors_block(this, block); + depth_ -= 2; + } + else { + grib_dump_accessors_block(this, block); + } +} + +void BufrEncodeC::dump_attributes(grib_accessor* a, const char* prefix) +{ + int i = 0; + unsigned long flags; + while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { + isAttribute_ = 1; + if ((option_flags_ & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { + i++; + continue; + } + isLeaf_ = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; + flags = a->attributes_[i]->flags_; + a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; + switch (a->attributes_[i]->get_native_type()) { + case GRIB_TYPE_LONG: + dump_long_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_DOUBLE: + dump_values_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_STRING: + break; + } + a->attributes_[i]->flags_ = flags; + i++; + } + isLeaf_ = 0; + isAttribute_ = 0; +} + +void BufrEncodeC::header(const grib_handle* h) +{ + char sampleName[200] = { 0 }; + long localSectionPresent, edition, bufrHeaderCentre, isSatellite; + + Assert(h->product_kind == PRODUCT_BUFR); + + grib_get_long(h, "localSectionPresent", &localSectionPresent); + grib_get_long(h, "bufrHeaderCentre", &bufrHeaderCentre); + grib_get_long(h, "edition", &edition); + + if (localSectionPresent && bufrHeaderCentre == 98) { + grib_get_long(h, "isSatellite", &isSatellite); + if (isSatellite) + snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local_satellite", edition); + else + snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local", edition); + } + else { + snprintf(sampleName, sizeof(sampleName), "BUFR%ld", edition); + } + + if (count_ < 2) { + fprintf(out_, "/* This program was automatically generated with bufr_dump -EC */\n"); + fprintf(out_, "/* Using ecCodes version: "); + grib_print_api_version(out_); + fprintf(out_, " */\n\n"); + fprintf(out_, "#include \"eccodes.h\"\n"); + fprintf(out_, "int main()\n"); + fprintf(out_, "{\n"); + fprintf(out_, " size_t size=0;\n"); + fprintf(out_, " const void* buffer = NULL;\n"); + fprintf(out_, " FILE* fout = NULL;\n"); + fprintf(out_, " codes_handle* h = NULL;\n"); + fprintf(out_, " long* ivalues = NULL;\n"); + fprintf(out_, " char** svalues = NULL;\n"); + fprintf(out_, " double* rvalues = NULL;\n"); + fprintf(out_, " const char* sampleName = \"%s\";\n\n", sampleName); + } + + fprintf(out_, " h = codes_bufr_handle_new_from_samples(NULL, sampleName);\n"); + fprintf(out_, " if (h == NULL) {\n"); + fprintf(out_, " fprintf(stderr, \"ERROR: Failed to create BUFR from %%s\\n\", sampleName);\n"); + fprintf(out_, " return 1;\n"); + fprintf(out_, " }\n"); +} + +void BufrEncodeC::footer(const grib_handle* h) +{ + fprintf(out_, "\n /* Encode the keys back in the data section */\n"); + fprintf(out_, " CODES_CHECK(codes_set_long(h, \"pack\", 1), 0);\n\n"); + if (count_ == 1) + fprintf(out_, " fout = fopen(\"outfile.bufr\", \"w\");\n"); + else + fprintf(out_, " fout = fopen(\"outfile.bufr\", \"a\");\n"); + + /*fprintf(out_," fout = fopen(\"outfile.bufr\", \"w\");");*/ + fprintf(out_, " if (!fout) {\n"); + fprintf(out_, " fprintf(stderr, \"ERROR: Failed to open output file 'outfile.bufr' for writing.\\n\");\n"); + fprintf(out_, " return 1;\n"); + fprintf(out_, " }\n"); + fprintf(out_, " CODES_CHECK(codes_get_message(h,&buffer,&size),0);\n"); + fprintf(out_, " if (fwrite(buffer,1,size,fout) != size) {\n"); + fprintf(out_, " fprintf(stderr, \"ERROR: Failed to write data.\\n\");\n"); + fprintf(out_, " return 1;\n"); + fprintf(out_, " }\n"); + fprintf(out_, " if (fclose(fout)!=0) {\n"); + fprintf(out_, " fprintf(stderr, \"ERROR: Failed to close output file handle.\\n\");\n"); + fprintf(out_, " return 1;\n"); + fprintf(out_, " }\n"); + fprintf(out_, " \n"); + fprintf(out_, " codes_handle_delete(h);\n"); + if (count_ == 1) + fprintf(out_, " printf(\"Created output BUFR file 'outfile.bufr'.\\n\");\n"); + fprintf(out_, " free(ivalues); ivalues = NULL;\n"); + fprintf(out_, " free(rvalues); rvalues = NULL;\n"); + fprintf(out_, " free(svalues); svalues = NULL;\n\n"); +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_encode_C.h b/src/dumper/grib_dumper_class_bufr_encode_C.h new file mode 100644 index 000000000..f742a1924 --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_encode_C.h @@ -0,0 +1,50 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class BufrEncodeC : public Dumper +{ +public: + BufrEncodeC() { class_name_ = "bufr_encode_C"; } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_string_array(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + void header(const grib_handle*) override; + void footer(const grib_handle*) override; + +private: + static inline int depth_ = 0; + long section_offset_ = 0; + long empty_ = 0; + long end_ = 0; + long isLeaf_ = 0; + long isAttribute_ = 0; + grib_string_list* keys_ = nullptr; + + void dump_attributes(grib_accessor* a, const char* prefix); + void dump_values_attribute(grib_accessor* a, const char* prefix); + void dump_long_attribute(grib_accessor* a, const char* prefix); +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_encode_filter.cc b/src/dumper/grib_dumper_class_bufr_encode_filter.cc new file mode 100644 index 000000000..201fb537e --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_encode_filter.cc @@ -0,0 +1,712 @@ +/* + * (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_dumper_class_bufr_encode_filter.h" +#include "grib_dumper_factory.h" +#include + +eccodes::dumper::BufrEncodeFilter _grib_dumper_bufr_encode_filter; +eccodes::Dumper* grib_dumper_bufr_encode_filter = &_grib_dumper_bufr_encode_filter; + +namespace eccodes::dumper +{ + +int BufrEncodeFilter::init() +{ + grib_context* c = context_; + section_offset_ = 0; + empty_ = 1; + isLeaf_ = 0; + isAttribute_ = 0; + keys_ = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); + + return GRIB_SUCCESS; +} + +int BufrEncodeFilter::destroy() +{ + grib_string_list* next = keys_; + grib_string_list* cur = NULL; + grib_context* c = context_; + while (next) { + cur = next; + next = next->next; + grib_context_free(c, cur->value); + grib_context_free(c, cur); + } + return GRIB_SUCCESS; +} + +void BufrEncodeFilter::dump_values(grib_accessor* a) +{ + double value = 0; + size_t size = 0, size2 = 0; + double* values = NULL; + int err = 0; + int i, r; + int cols = 9; + long count = 0; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); + err = a->unpack_double(values, &size2); + } + else { + err = a->unpack_double(&value, &size2); + } + Assert(size2 == size); + + begin_ = 0; + empty_ = 0; + + if (size > 1) { + int icount = 0; + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, "set #%d#%s=", r, a->name_); + else + fprintf(out_, "set %s=", a->name_); + + fprintf(out_, "{"); + + for (i = 0; i < size - 1; ++i) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + fprintf(out_, "%.18e, ", values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + fprintf(out_, "%.18e", values[i]); + + depth -= 2; + fprintf(out_, "};\n"); + grib_context_free(c, values); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_double(a, value)) { + if (r != 0) + fprintf(out_, "set #%d#%s=", r, a->name_); + else + fprintf(out_, "set %s=", a->name_); + + fprintf(out_, "%.18e;\n", value); + } + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + + (void)err; /* TODO */ +} + +void BufrEncodeFilter::dump_values_attribute(grib_accessor* a, const char* prefix) +{ + double value = 0; + size_t size = 0, size2 = 0; + double* values = NULL; + int err = 0; + int i, icount; + int cols = 2; + long count = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); + err = a->unpack_double(values, &size2); + } + else { + err = a->unpack_double(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, "set %s->%s = {", prefix, a->name_); + icount = 0; + for (i = 0; i < size - 1; ++i) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + fprintf(out_, "%.18e, ", values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + fprintf(out_, "%.18e", values[i]); + + depth -= 2; + fprintf(out_, "};\n"); + grib_context_free(c, values); + } + else { + /* int r=compute_bufr_key_rank(h,keys_,a->name_); */ + if (!grib_is_missing_double(a, value)) { + fprintf(out_, "set %s->%s = %.18e;\n", prefix, a->name_, value); + } + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth -= 2; + } + + (void)err; /* TODO */ +} + +void BufrEncodeFilter::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 0, size2 = 0; + long* values = NULL; + int err = 0; + int i, r, icount; + int cols = 9; + long count = 0; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + a->value_count(&count); + size = size2 = count; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + return; + } + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size2); + } + else { + err = a->unpack_long(&value, &size2); + } + Assert(size2 == size); + + begin_ = 0; + empty_ = 0; + + if (size > 1) { + icount = 0; + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, "set #%d#%s=", r, a->name_); + else + fprintf(out_, "set %s=", a->name_); + + fprintf(out_, "{"); + + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + fprintf(out_, "%ld, ", values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + fprintf(out_, "%ld ", values[i]); + + depth -= 2; + fprintf(out_, "};\n"); + grib_context_free(a->context_, values); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_long(a, value)) { + if (r != 0) + fprintf(out_, "set #%d#%s=", r, a->name_); + else + fprintf(out_, "set %s=", a->name_); + + fprintf(out_, "%ld;\n", value); + } + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + (void)err; /* TODO */ +} + +void BufrEncodeFilter::dump_long_attribute(grib_accessor* a, const char* prefix) +{ + long value = 0; + size_t size = 0, size2 = 0; + long* values = NULL; + int err = 0; + int i, icount; + int cols = 4; + long count = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size2); + } + else { + err = a->unpack_long(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, "set %s->%s = {", prefix, a->name_); + icount = 0; + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + fprintf(out_, "%ld, ", values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + fprintf(out_, "%ld ", values[i]); + depth -= 2; + fprintf(out_, "};\n"); + grib_context_free(a->context_, values); + } + else { + /* int r=compute_bufr_key_rank(h,keys_,a->name_); */ + if (!codes_bufr_key_exclude_from_dump(prefix)) { + if (!grib_is_missing_long(a, value)) { + fprintf(out_, "set %s->%s = ", prefix, a->name_); + fprintf(out_, "%ld ;\n", value); + } + } + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth -= 2; + } + (void)err; /* TODO */ +} + +void BufrEncodeFilter::dump_bits(grib_accessor* a, const char* comment) +{ +} + +void BufrEncodeFilter::dump_double(grib_accessor* a, const char* comment) +{ + double value = 0; + size_t size = 1; + int r; + grib_handle* h = grib_handle_of_accessor(a); + grib_context* c = h->context; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->unpack_double(&value, &size); + begin_ = 0; + empty_ = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (!grib_is_missing_double(a, value)) { + if (r != 0) + fprintf(out_, "set #%d#%s=", r, a->name_); + else + fprintf(out_, "set %s=", a->name_); + + fprintf(out_, "%.18e;\n", value); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } +} + +void BufrEncodeFilter::dump_string_array(grib_accessor* a, const char* comment) +{ + char** values = NULL; + size_t size = 0, i = 0; + grib_context* c = NULL; + int err = 0; + long count = 0; + int r = 0; + grib_handle* h = grib_handle_of_accessor(a); + + c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_string(a, comment); + return; + } + + begin_ = 0; + + if (isLeaf_ == 0) { + depth += 2; + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, "set #%d#%s=", r, a->name_); + else + fprintf(out_, "set %s=", a->name_); + } + + empty_ = 0; + + 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); + + fprintf(out_, "{"); + depth += 2; + for (i = 0; i < size - 1; i++) { + fprintf(out_, " \"%s\",\n", values[i]); + } + fprintf(out_, " \"%s\"\n", values[i]); + + depth -= 2; + + fprintf(out_, "};\n"); + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + for (i = 0; i < size; ++i) + grib_context_free(c, values[i]); + grib_context_free(c, values); + (void)err; /* TODO */ +} + +void BufrEncodeFilter::dump_string(grib_accessor* a, const char* comment) +{ + char* value = NULL; + char* p = NULL; + size_t size = 0; + grib_context* c = a->context_; + int r = 0, err = 0; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + grib_get_string_length_acc(a, &size); + if (size == 0) + return; + + value = (char*)grib_context_malloc_clear(c, size); + if (!value) { + grib_context_log(c, GRIB_LOG_ERROR, "unable to allocate %zu bytes", size); + return; + } + + begin_ = 0; + empty_ = 0; + + err = a->unpack_string(value, &size); + p = value; + r = compute_bufr_key_rank(h, keys_, a->name_); + if (grib_is_missing_string(a, (unsigned char*)value, size)) { + strcpy(value, ""); /* Empty string means MISSING string */ + } + + while (*p) { + if (!isprint(*p)) + *p = '?'; + if (*p == '"') + *p = '\''; /* ECC-1401 */ + p++; + } + + if (isLeaf_ == 0) { + depth += 2; + if (r != 0) + fprintf(out_, "set #%d#%s=", r, a->name_); + else + fprintf(out_, "set %s=", a->name_); + } + fprintf(out_, "\"%s\";\n", value); + + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth -= 2; + } + + grib_context_free(c, value); + (void)err; /* TODO */ +} + +void BufrEncodeFilter::dump_bytes(grib_accessor* a, const char* comment) +{ +} + +void BufrEncodeFilter::dump_label(grib_accessor* a, const char* comment) +{ +} + +static void _dump_long_array(grib_handle* h, FILE* f, const char* key, const char* print_key) +{ + long* val; + size_t size = 0, i; + int cols = 9, icount = 0; + + if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) + return; + if (size == 0) + return; + + val = (long*)grib_context_malloc_clear(h->context, sizeof(long) * size); + grib_get_long_array(h, key, val, &size); + fprintf(f, "set %s= {", print_key); + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(f, "\n "); + icount = 0; + } + fprintf(f, "%ld, ", val[i]); + icount++; + } + if (icount > cols) { + fprintf(f, "\n "); + } + fprintf(f, "%ld};\n", val[size - 1]); + + grib_context_free(h->context, val); +} + +void BufrEncodeFilter::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + if (strcmp(a->name_, "BUFR") == 0 || + strcmp(a->name_, "GRIB") == 0 || + strcmp(a->name_, "META") == 0) { + grib_handle* h = grib_handle_of_accessor(a); + depth = 2; + begin_ = 1; + empty_ = 1; + depth += 2; + _dump_long_array(h, out_, "dataPresentIndicator", "inputDataPresentIndicator"); + _dump_long_array(h, out_, "delayedDescriptorReplicationFactor", "inputDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "shortDelayedDescriptorReplicationFactor", "inputShortDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "extendedDelayedDescriptorReplicationFactor", "inputExtendedDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "inputOverriddenReferenceValues", "inputOverriddenReferenceValues"); + grib_dump_accessors_block(this, block); + depth -= 2; + } + else if (strcmp(a->name_, "groupNumber") == 0) { + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + begin_ = 1; + empty_ = 1; + depth += 2; + grib_dump_accessors_block(this, block); + depth -= 2; + } + else { + grib_dump_accessors_block(this, block); + } +} + +void BufrEncodeFilter::dump_attributes(grib_accessor* a, const char* prefix) +{ + int i = 0; + unsigned long flags; + while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { + isAttribute_ = 1; + if ((option_flags_ & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { + i++; + continue; + } + isLeaf_ = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; + /* fprintf(out_,","); */ + /* fprintf(out_,"\n%-*s",depth," "); */ + /* fprintf(out,"\"%s\" : ",a->attributes_[i]->name); */ + flags = a->attributes_[i]->flags_; + a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; + switch (a->attributes_[i]->get_native_type()) { + case GRIB_TYPE_LONG: + dump_long_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_DOUBLE: + dump_values_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_STRING: + break; + } + a->attributes_[i]->flags_ = flags; + i++; + } + isLeaf_ = 0; + isAttribute_ = 0; +} + +void BufrEncodeFilter::header(const grib_handle* h) +{ + char sampleName[128] = { 0 }; + long localSectionPresent, edition, bufrHeaderCentre, isSatellite; + + Assert(h->product_kind == PRODUCT_BUFR); + + grib_get_long(h, "localSectionPresent", &localSectionPresent); + grib_get_long(h, "bufrHeaderCentre", &bufrHeaderCentre); + grib_get_long(h, "edition", &edition); + + if (localSectionPresent && bufrHeaderCentre == 98) { + grib_get_long(h, "isSatellite", &isSatellite); + if (isSatellite) + snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local_satellite", edition); + else + snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local", edition); + } + else { + snprintf(sampleName, sizeof(sampleName), "BUFR%ld", edition); + } + + fprintf(out_, "# BUFR sample file: %s.tmpl\n", sampleName); +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_encode_filter.h b/src/dumper/grib_dumper_class_bufr_encode_filter.h new file mode 100644 index 000000000..fe4177501 --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_encode_filter.h @@ -0,0 +1,50 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class BufrEncodeFilter : public Dumper +{ +public: + BufrEncodeFilter() { class_name_ = "bufr_encode_filter"; } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_string_array(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + void header(const grib_handle*) override; + +private: + inline static int depth = 0; + long section_offset_ = 0; + long begin_ = 0; + long empty_ = 0; + long end_ = 0; + long isLeaf_ = 0; + long isAttribute_ = 0; + grib_string_list* keys_ = nullptr; + + void dump_attributes(grib_accessor* a, const char* prefix); + void dump_values_attribute(grib_accessor* a, const char* prefix); + void dump_long_attribute(grib_accessor* a, const char* prefix); +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_encode_fortran.cc b/src/dumper/grib_dumper_class_bufr_encode_fortran.cc new file mode 100644 index 000000000..1e3a6e9b6 --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_encode_fortran.cc @@ -0,0 +1,863 @@ +/* + * (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_dumper_class_bufr_encode_fortran.h" +#include "grib_dumper_factory.h" +#include + +eccodes::dumper::BufrEncodeFortran _grib_dumper_bufr_encode_fortran; +eccodes::Dumper* grib_dumper_bufr_encode_fortran = &_grib_dumper_bufr_encode_fortran; + +namespace eccodes::dumper +{ + +int BufrEncodeFortran::init() +{ + grib_context* c = context_; + section_offset_ = 0; + empty_ = 1; + count_ = 1; + isLeaf_ = 0; + isAttribute_ = 0; + keys_ = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); + + return GRIB_SUCCESS; +} + +int BufrEncodeFortran::destroy() +{ + grib_string_list* next = keys_; + grib_string_list* cur = NULL; + grib_context* c = context_; + while (next) { + cur = next; + next = next->next; + grib_context_free(c, cur->value); + grib_context_free(c, cur); + } + return GRIB_SUCCESS; +} + +static char* lval_to_string(grib_context* c, long v) +{ + char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * 40); + if (v == GRIB_MISSING_LONG) + snprintf(sval, 1024, "CODES_MISSING_LONG"); + else + snprintf(sval, 1024, "%ld", v); + return sval; +} +static char* dval_to_string(grib_context* c, double v) +{ + char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * 40); + if (v == GRIB_MISSING_DOUBLE) { + snprintf(sval, 1024, "CODES_MISSING_DOUBLE"); + } + else { + char* p; + snprintf(sval, 1024, "%.18e", v); + p = sval; + while (*p != 0) { + if (*p == 'e') + *p = 'd'; + p++; + } + } + return sval; +} + +/* Some lines can grow longer than Fortran compilers allow (=132). */ +/* This is mainly due to long key names with attributes. */ +/* The resturn value of this function must be freed by the caller */ +static char* break_line(grib_context* c, const char* input) +{ + /* Break a long line using Fortran continuation characters */ + char* a_token = NULL; + char* lasts = NULL; + int first = 1; + const size_t len = strlen(input); + /* Add a bit more for inserted newlines and continuation characters */ + char* result = (char*)grib_context_malloc_clear(c, sizeof(char) * len + 100); + + /* No need to alter input which is already too short or has newlines */ + if (len < 70 || strchr(input, '\n')) { + strcpy(result, input); + return result; + } + + /* A Fortran multi-line string has two ampersands. E.g. */ + /* 'hello & + * &world' is the same as 'hello world' + */ + a_token = strtok_r((char*)input, "->", &lasts); + while (a_token) { + if (first) { + first = 0; + strcat(result, a_token); + } + else { + char tmp[256] = {0, }; + snprintf(tmp, sizeof(tmp), "->&\n &%s", a_token); + strcat(result, tmp); + } + a_token = strtok_r(NULL, "->", &lasts); + } + + return result; +} + +void BufrEncodeFortran::dump_values(grib_accessor* a) +{ + double value = 0; + size_t size = 0, size2 = 0; + double* values = NULL; + int err = 0; + int i, r, icount; + int cols = 2; + long count = 0; + char* sval; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); + err = a->unpack_double(values, &size2); + } + else { + err = a->unpack_double(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, " if(allocated(rvalues)) deallocate(rvalues)\n"); + fprintf(out_, " allocate(rvalues(%lu))\n", (unsigned long)size); + + fprintf(out_, " rvalues=(/"); + + icount = 0; + for (i = 0; i < size - 1; ++i) { + if (icount > cols || i == 0) { + fprintf(out_, " &\n "); + icount = 0; + } + sval = dval_to_string(c, values[i]); + fprintf(out_, "%s, ", sval); + grib_context_free(c, sval); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, " &\n "); + } + sval = dval_to_string(c, values[size - 1]); + fprintf(out_, "%s", sval); + grib_context_free(c, sval); + + depth_ -= 2; + fprintf(out_, "/)\n"); + grib_context_free(c, values); + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " call codes_set(ibufr,'#%d#%s',rvalues)\n", r, a->name_); + else + fprintf(out_, " call codes_set(ibufr,'%s',rvalues)\n", a->name_); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + sval = dval_to_string(c, value); + if (r != 0) + fprintf(out_, " call codes_set(ibufr,'#%d#%s',%s)\n", r, a->name_, sval); + else + fprintf(out_, " call codes_set(ibufr,'%s',%s)\n", a->name_, sval); + grib_context_free(c, sval); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + + (void)err; /* TODO */ +} + +void BufrEncodeFortran::dump_values_attribute(grib_accessor* a, const char* prefix) +{ + double value = 0; + size_t size = 0, size2 = 0; + double* values = NULL; + int err = 0; + int i, icount; + int cols = 2; + long count = 0; + char* sval; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); + err = a->unpack_double(values, &size2); + } + else { + err = a->unpack_double(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, " if(allocated(rvalues)) deallocate(rvalues)\n"); + fprintf(out_, " allocate(rvalues(%lu))\n", (unsigned long)size); + + fprintf(out_, " rvalues=(/"); + + icount = 0; + for (i = 0; i < size - 1; ++i) { + if (icount > cols || i == 0) { + fprintf(out_, " &\n "); + icount = 0; + } + sval = dval_to_string(c, values[i]); + fprintf(out_, "%s, ", sval); + grib_context_free(c, sval); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, " &\n "); + } + sval = dval_to_string(c, values[size - 1]); + fprintf(out_, "%s", sval); + grib_context_free(c, sval); + + depth_ -= 2; + fprintf(out_, "/)\n"); + grib_context_free(c, values); + + fprintf(out_, " call codes_set(ibufr,'%s->%s' &\n,rvalues)\n", prefix, a->name_); + } + else { + sval = dval_to_string(c, value); + fprintf(out_, " call codes_set(ibufr,'%s->%s' &\n,%s)\n", prefix, a->name_, sval); + grib_context_free(c, sval); + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth_ -= 2; + } + + (void)err; /* TODO */ +} + +static int is_hidden(grib_accessor* a) +{ + return ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0); +} + +void BufrEncodeFortran::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 0, size2 = 0; + long* values = NULL; + int err = 0; + int i, r, icount; + int cols = 4; + long count = 0; + char* sval = NULL; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + int doing_unexpandedDescriptors = 0; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { /* key does not have the dump attribute */ + int skip = 1; + /* See ECC-1107 */ + if (!is_hidden(a) && strcmp(a->name_, "messageLength") == 0) skip = 0; + if (skip) return; + } + + doing_unexpandedDescriptors = (strcmp(a->name_, "unexpandedDescriptors") == 0); + a->value_count(&count); + size = size2 = count; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + return; + } + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size2); + } + else { + err = a->unpack_long(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, " if(allocated(ivalues)) deallocate(ivalues)\n"); + fprintf(out_, " allocate(ivalues(%lu))\n", (unsigned long)size); + + fprintf(out_, " ivalues=(/"); + icount = 0; + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(out_, " &\n "); + icount = 0; + } + fprintf(out_, "%ld, ", values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, " &\n "); + } + fprintf(out_, "%ld ", values[size - 1]); + + depth_ -= 2; + fprintf(out_, "/)\n"); + grib_context_free(a->context_, values); + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) { + fprintf(out_, " call codes_set(ibufr,'#%d#%s',ivalues)\n", r, a->name_); + } + else { + if (doing_unexpandedDescriptors) { + fprintf(out_, "\n ! Create the structure of the data section\n"); + /* fprintf(out_," call codes_set(ibufr,'skipExtraKeyAttributes',1)\n"); */ + } + fprintf(out_, " call codes_set(ibufr,'%s',ivalues)\n", a->name_); + if (doing_unexpandedDescriptors) + fprintf(out_, "\n"); + } + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + sval = lval_to_string(c, value); + if (r != 0) { + fprintf(out_, " call codes_set(ibufr,'#%d#%s',", r, a->name_); + } + else { + if (doing_unexpandedDescriptors) { + fprintf(out_, "\n ! Create the structure of the data section\n"); + /* fprintf(out_," call codes_set(ibufr,'skipExtraKeyAttributes',1)\n"); */ + } + fprintf(out_, " call codes_set(ibufr,'%s',", a->name_); + } + + fprintf(out_, "%s)\n", sval); + grib_context_free(c, sval); + if (doing_unexpandedDescriptors) + fprintf(out_, "\n"); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + (void)err; /* TODO */ +} + +void BufrEncodeFortran::dump_long_attribute(grib_accessor* a, const char* prefix) +{ + long value = 0; + size_t size = 0, size2 = 0; + long* values = NULL; + int err = 0; + int i, icount; + int cols = 4; + long count = 0; + char* pref = NULL; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size2); + } + else { + err = a->unpack_long(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + /* Fortran standard specifies the maximum length of a free-form source line is 132 characters */ + /* Break long prefix string into multiple lines to avoid compiler error */ + pref = break_line(c, prefix); + + if (size > 1) { + fprintf(out_, " if(allocated(ivalues)) deallocate(ivalues)\n"); + fprintf(out_, " allocate(ivalues(%lu))\n", (unsigned long)size); + + fprintf(out_, " ivalues=(/"); + icount = 0; + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(out_, " &\n "); + icount = 0; + } + fprintf(out_, "%ld, ", values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, " &\n "); + } + fprintf(out_, "%ld ", values[size - 1]); + + depth_ -= 2; + fprintf(out_, "/)\n"); + grib_context_free(a->context_, values); + + fprintf(out_, " call codes_set(ibufr,'%s->%s' &\n,ivalues)\n", pref, a->name_); + } + else { + if (!codes_bufr_key_exclude_from_dump(prefix)) { + char* sval = lval_to_string(c, value); + fprintf(out_, " call codes_set(ibufr,'%s->%s'&\n,", pref, a->name_); + fprintf(out_, "%s)\n", sval); + grib_context_free(c, sval); + } + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(pref) + 5)); + snprintf(prefix1, 1024, "%s->%s", pref, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth_ -= 2; + } + grib_context_free(c, pref); + (void)err; /* TODO */ +} + +void BufrEncodeFortran::dump_bits(grib_accessor* a, const char* comment) +{ +} + +void BufrEncodeFortran::dump_double(grib_accessor* a, const char* comment) +{ + double value = 0; + size_t size = 1; + int r; + char* sval; + grib_handle* h = grib_handle_of_accessor(a); + grib_context* c = h->context; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->unpack_double(&value, &size); + empty_ = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + + sval = dval_to_string(c, value); + if (r != 0) + fprintf(out_, " call codes_set(ibufr,'#%d#%s',%s)\n", r, a->name_, sval); + else + fprintf(out_, " call codes_set(ibufr,'%s',%s)\n", a->name_, sval); + grib_context_free(c, sval); + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } +} + +void BufrEncodeFortran::dump_string_array(grib_accessor* a, const char* comment) +{ + char** values; + size_t size = 0, i = 0; + grib_context* c = a->context_; + int err = 0; + long count = 0; + int r = 0; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_string(a, comment); + return; + } + + fprintf(out_, " if(allocated(svalues)) deallocate(svalues)\n"); + fprintf(out_, " allocate(svalues(%lu))\n", (unsigned long)size); + + fprintf(out_, " svalues=(/"); + + empty_ = 0; + + 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); + + for (i = 0; i < size - 1; i++) { + fprintf(out_, " \"%s\", &\n", values[i]); + } + fprintf(out_, " \"%s\" /)\n", values[size - 1]); + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " call codes_set_string_array(ibufr,'#%d#%s',svalues)\n", r, a->name_); + else + fprintf(out_, " call codes_set_string_array(ibufr,'%s',svalues)\n", a->name_); + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + for (i = 0; i < size; ++i) + grib_context_free(c, values[i]); + grib_context_free(c, values); + (void)err; /* TODO */ +} + +void BufrEncodeFortran::dump_string(grib_accessor* a, const char* comment) +{ + char* value = NULL; + char* p = NULL; + size_t size = 0; + grib_context* c = a->context_; + int r; + int err = 0; + grib_handle* h = grib_handle_of_accessor(a); + const char* acc_name = a->name_; + + grib_get_string_length_acc(a, &size); + if (size == 0) + return; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + value = (char*)grib_context_malloc_clear(c, size); + if (!value) { + grib_context_log(c, GRIB_LOG_ERROR, "unable to allocate %zu bytes", size); + return; + } + + empty_ = 0; + + err = a->unpack_string(value, &size); + p = value; + r = compute_bufr_key_rank(h, keys_, acc_name); + if (grib_is_missing_string(a, (unsigned char*)value, size)) { + strcpy(value, ""); /* Empty string means MISSING string */ + } + + while (*p) { + if (!isprint(*p)) + *p = '?'; + p++; + } + + if (isLeaf_ == 0) { + depth_ += 2; + if (r != 0) + fprintf(out_, " call codes_set(ibufr,'#%d#%s',", r, acc_name); + else + fprintf(out_, " call codes_set(ibufr,'%s',", acc_name); + } + fprintf(out_, "\'%s\')\n", value); + + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(acc_name) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, acc_name); + } + else + prefix = (char*)acc_name; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + + grib_context_free(c, value); + (void)err; /* TODO */ +} + +void BufrEncodeFortran::dump_bytes(grib_accessor* a, const char* comment) +{ +} + +void BufrEncodeFortran::dump_label(grib_accessor* a, const char* comment) +{ +} + +static void _dump_long_array(grib_handle* h, FILE* f, const char* key, const char* print_key) +{ + long* val; + size_t size = 0, i; + int cols = 9, icount = 0; + + if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) + return; + if (size == 0) + return; + + fprintf(f, " if(allocated(ivalues)) deallocate(ivalues)\n"); + fprintf(f, " allocate(ivalues(%lu))\n", (unsigned long)size); + + fprintf(f, " ivalues=(/ "); + + val = (long*)grib_context_malloc_clear(h->context, sizeof(long) * size); + grib_get_long_array(h, key, val, &size); + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(f, " &\n "); + icount = 0; + } + fprintf(f, "%ld, ", val[i]); + icount++; + } + if (icount > cols) { + fprintf(f, " &\n "); + } + fprintf(f, "%ld /)\n", val[size - 1]); + + grib_context_free(h->context, val); + fprintf(f, " call codes_set(ibufr,'%s',ivalues)\n", print_key); +} + +void BufrEncodeFortran::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + if (strcmp(a->name_, "BUFR") == 0 || + strcmp(a->name_, "GRIB") == 0 || + strcmp(a->name_, "META") == 0) { + grib_handle* h = grib_handle_of_accessor(a); + depth_ = 2; + empty_ = 1; + depth_ += 2; + _dump_long_array(h, out_, "dataPresentIndicator", "inputDataPresentIndicator"); + _dump_long_array(h, out_, "delayedDescriptorReplicationFactor", "inputDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "shortDelayedDescriptorReplicationFactor", "inputShortDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "extendedDelayedDescriptorReplicationFactor", "inputExtendedDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "inputOverriddenReferenceValues", "inputOverriddenReferenceValues"); + grib_dump_accessors_block(this, block); + depth_ -= 2; + } + else if (strcmp(a->name_, "groupNumber") == 0) { + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + empty_ = 1; + depth_ += 2; + grib_dump_accessors_block(this, block); + depth_ -= 2; + } + else { + grib_dump_accessors_block(this, block); + } +} + +void BufrEncodeFortran::dump_attributes(grib_accessor* a, const char* prefix) +{ + int i = 0; + unsigned long flags; + while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { + isAttribute_ = 1; + if ((option_flags_ & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { + i++; + continue; + } + isLeaf_ = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; + flags = a->attributes_[i]->flags_; + a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; + switch (a->attributes_[i]->get_native_type()) { + case GRIB_TYPE_LONG: + dump_long_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_DOUBLE: + dump_values_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_STRING: + break; + } + a->attributes_[i]->flags_ = flags; + i++; + } + isLeaf_ = 0; + isAttribute_ = 0; +} + +void BufrEncodeFortran::header(const grib_handle* h) +{ + char sampleName[200] = { 0 }; + long localSectionPresent, edition, bufrHeaderCentre, isSatellite; + + grib_get_long(h, "localSectionPresent", &localSectionPresent); + grib_get_long(h, "bufrHeaderCentre", &bufrHeaderCentre); + grib_get_long(h, "edition", &edition); + + if (localSectionPresent && bufrHeaderCentre == 98) { + grib_get_long(h, "isSatellite", &isSatellite); + if (isSatellite) + snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local_satellite", edition); + else + snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local", edition); + } + else { + snprintf(sampleName, sizeof(sampleName), "BUFR%ld", edition); + } + + if (count_ < 2) { + fprintf(out_, "! This program was automatically generated with bufr_dump -Efortran\n"); + fprintf(out_, "! Using ecCodes version: "); + grib_print_api_version(out_); + fprintf(out_, "\n\n"); + fprintf(out_, "program bufr_encode\n"); + fprintf(out_, " use eccodes\n"); + fprintf(out_, " implicit none\n"); + fprintf(out_, " integer :: iret\n"); + fprintf(out_, " integer :: outfile\n"); + fprintf(out_, " integer :: ibufr\n"); + fprintf(out_, " integer(kind=4), dimension(:), allocatable :: ivalues\n"); + fprintf(out_, " integer, parameter :: max_strsize = 100\n"); + fprintf(out_, " character(len=max_strsize) , dimension(:),allocatable :: svalues\n"); + fprintf(out_, " real(kind=8), dimension(:), allocatable :: rvalues\n"); + } + fprintf(out_, " call codes_bufr_new_from_samples(ibufr,'%s',iret)\n", sampleName); + fprintf(out_, " if (iret/=CODES_SUCCESS) then\n"); + fprintf(out_, " print *,'ERROR: Failed to create BUFR from %s'\n", sampleName); + fprintf(out_, " stop 1\n"); + fprintf(out_, " endif\n"); +} + +void BufrEncodeFortran::footer(const grib_handle* h) +{ + fprintf(out_, "\n ! Encode the keys back in the data section\n"); + fprintf(out_, " call codes_set(ibufr,'pack',1)\n\n"); + if (count_ == 1) + fprintf(out_, " call codes_open_file(outfile,'outfile.bufr','w')\n"); + else + fprintf(out_, " call codes_open_file(outfile,'outfile.bufr','a')\n"); + + fprintf(out_, " call codes_write(ibufr,outfile)\n"); + fprintf(out_, " call codes_close_file(outfile)\n"); + fprintf(out_, " call codes_release(ibufr)\n"); + if (count_ == 1) + fprintf(out_, " print *, \"Created output BUFR file 'outfile.bufr'\"\n"); + fprintf(out_, " if(allocated(ivalues)) deallocate(ivalues)\n"); + fprintf(out_, " if(allocated(rvalues)) deallocate(rvalues)\n"); + fprintf(out_, " if(allocated(svalues)) deallocate(svalues)\n"); +} + +} // namespace eccodes::dumper + diff --git a/src/dumper/grib_dumper_class_bufr_encode_fortran.h b/src/dumper/grib_dumper_class_bufr_encode_fortran.h new file mode 100644 index 000000000..14474e075 --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_encode_fortran.h @@ -0,0 +1,54 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class BufrEncodeFortran : public Dumper +{ +public: + BufrEncodeFortran() + { + class_name_ = "bufr_encode_fortran"; + } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_string_array(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + void header(const grib_handle*) override; + void footer(const grib_handle*) override; + +private: + static inline int depth_ = 0; + + long section_offset_ = 0; + long empty_ = 0; + long end_ = 0; + long isLeaf_ = 0; + long isAttribute_ = 0; + grib_string_list* keys_ = nullptr; + + void dump_attributes(grib_accessor* a, const char* prefix); + void dump_values_attribute(grib_accessor* a, const char* prefix); + void dump_long_attribute(grib_accessor* a, const char* prefix); +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_encode_python.cc b/src/dumper/grib_dumper_class_bufr_encode_python.cc new file mode 100644 index 000000000..9c50d6ce4 --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_encode_python.cc @@ -0,0 +1,793 @@ +/* + * (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_dumper_class_bufr_encode_python.h" +#include "grib_dumper_factory.h" +#include + +eccodes::dumper::BufrEncodePython _grib_dumper_bufr_encode_python; +eccodes::Dumper* grib_dumper_bufr_encode_python = &_grib_dumper_bufr_encode_python; + +namespace eccodes::dumper +{ + +int BufrEncodePython::init() +{ + grib_context* c = context_; + section_offset_ = 0; + empty_ = 1; + count_ = 1; + isLeaf_ = 0; + isAttribute_ = 0; + keys_ = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); + + return GRIB_SUCCESS; +} + +int BufrEncodePython::destroy() +{ + grib_string_list* next = keys_; + grib_string_list* cur = NULL; + grib_context* c = context_; + while (next) { + cur = next; + next = next->next; + grib_context_free(c, cur->value); + grib_context_free(c, cur); + } + return GRIB_SUCCESS; +} + +static char* lval_to_string(grib_context* c, long v) +{ + char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * 40); + if (v == GRIB_MISSING_LONG) + snprintf(sval, 1024, "CODES_MISSING_LONG"); + else + snprintf(sval, 1024, "%ld", v); + return sval; +} +static char* dval_to_string(const grib_context* c, double v) +{ + char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * 40); + if (v == GRIB_MISSING_DOUBLE) + snprintf(sval, 1024, "CODES_MISSING_DOUBLE"); + else + snprintf(sval, 1024, "%.18e", v); + return sval; +} + +void BufrEncodePython::dump_values(grib_accessor* a) +{ + double value = 0; + size_t size = 0, size2 = 0; + double* values = NULL; + int err = 0; + int i, r, icount; + int cols = 2; + long count = 0; + char* sval; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); + err = a->unpack_double(values, &size2); + } + else { + err = a->unpack_double(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, " rvalues = ("); + + icount = 0; + for (i = 0; i < size - 1; ++i) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + sval = dval_to_string(c, values[i]); + fprintf(out_, "%s, ", sval); + grib_context_free(c, sval); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + sval = dval_to_string(c, values[i]); + fprintf(out_, "%s", sval); + grib_context_free(c, sval); + + depth_ -= 2; + /* Note: In Python to make a tuple with one element, you need the trailing comma */ + if (size > 4) + fprintf(out_, ",) # %lu values\n", (unsigned long)size); + else + fprintf(out_, ",)\n"); + grib_context_free(c, values); + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " codes_set_array(ibufr, '#%d#%s', rvalues)\n", r, a->name_); + else + fprintf(out_, " codes_set_array(ibufr, '%s', rvalues)\n", a->name_); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + sval = dval_to_string(c, value); + if (r != 0) + fprintf(out_, " codes_set(ibufr, '#%d#%s', %s)\n", r, a->name_, sval); + else + fprintf(out_, " codes_set(ibufr, '%s', %s)\n", a->name_, sval); + grib_context_free(c, sval); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + + (void)err; /* TODO */ +} + +void BufrEncodePython::dump_values_attribute(grib_accessor* a, const char* prefix) +{ + double value = 0; + size_t size = 0, size2 = 0; + double* values = NULL; + int err = 0, i = 0, icount = 0; + int cols = 2; + long count = 0; + char* sval; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); + err = a->unpack_double(values, &size2); + } + else { + err = a->unpack_double(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, " rvalues = ("); + + icount = 0; + for (i = 0; i < size - 1; ++i) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + sval = dval_to_string(c, values[i]); + fprintf(out_, "%s, ", sval); + grib_context_free(c, sval); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + sval = dval_to_string(c, values[i]); + fprintf(out_, "%s", sval); + grib_context_free(c, sval); + + depth_ -= 2; + /* Note: In python to make a tuple with one element, you need the trailing comma */ + if (size > 4) + fprintf(out_, ",) # %lu values\n", (unsigned long)size); + else + fprintf(out_, ",)\n"); + grib_context_free(c, values); + + fprintf(out_, " codes_set_array(ibufr, '%s->%s' \n, rvalues)\n", prefix, a->name_); + } + else { + sval = dval_to_string(c, value); + fprintf(out_, " codes_set(ibufr, '%s->%s' \n,%s)\n", prefix, a->name_, sval); + grib_context_free(c, sval); + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth_ -= 2; + } + + (void)err; /* TODO */ +} + +static int is_hidden(grib_accessor* a) +{ + return ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0); +} + +void BufrEncodePython::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 0, size2 = 0; + long* values = NULL; + int err = 0, i = 0, r = 0, icount = 0; + int cols = 4; + long count = 0; + char* sval = NULL; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + int doing_unexpandedDescriptors = 0; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { /* key does not have the dump attribute */ + int skip = 1; + /* See ECC-1107 */ + if (!is_hidden(a) && strcmp(a->name_, "messageLength") == 0) skip = 0; + if (skip) return; + } + + doing_unexpandedDescriptors = (strcmp(a->name_, "unexpandedDescriptors") == 0); + a->value_count(&count); + size = size2 = count; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + return; + } + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size2); + } + else { + err = a->unpack_long(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, " ivalues = ("); + icount = 0; + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + fprintf(out_, "%ld, ", values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + fprintf(out_, "%ld", values[i]); + + depth_ -= 2; + /* Note: In python to make a tuple with one element, you need the trailing comma */ + if (size > 4) + fprintf(out_, ",) # %lu values\n", (unsigned long)size); + else + fprintf(out_, ",)\n"); + grib_context_free(a->context_, values); + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) { + fprintf(out_, " codes_set_array(ibufr, '#%d#%s', ivalues)\n", r, a->name_); + } + else { + if (doing_unexpandedDescriptors) { + fprintf(out_, "\n # Create the structure of the data section\n"); + /* fprintf(out_," codes_set(ibufr, 'skipExtraKeyAttributes', 1)\n"); */ + } + fprintf(out_, " codes_set_array(ibufr, '%s', ivalues)\n", a->name_); + if (doing_unexpandedDescriptors) + fprintf(out_, "\n"); + } + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + sval = lval_to_string(c, value); + if (r != 0) { + fprintf(out_, " codes_set(ibufr, '#%d#%s', ", r, a->name_); + } + else { + if (doing_unexpandedDescriptors) { + fprintf(out_, "\n # Create the structure of the data section\n"); + /* fprintf(out_," codes_set(ibufr, 'skipExtraKeyAttributes', 1)\n"); */ + } + fprintf(out_, " codes_set(ibufr, '%s', ", a->name_); + } + + fprintf(out_, "%s)\n", sval); + grib_context_free(c, sval); + if (doing_unexpandedDescriptors) + fprintf(out_, "\n"); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + (void)err; /* TODO */ +} + +void BufrEncodePython::dump_long_attribute(grib_accessor* a, const char* prefix) +{ + long value = 0; + size_t size = 0, size2 = 0; + long* values = NULL; + int err = 0, i = 0, icount = 0; + int cols = 4; + long count = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size2); + } + else { + err = a->unpack_long(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, " ivalues = ("); + icount = 0; + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(out_, " \n "); + icount = 0; + } + fprintf(out_, "%ld, ", values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, " \n "); + } + fprintf(out_, "%ld ", values[i]); + + depth_ -= 2; + /* Note: In python to make a tuple with one element, you need the trailing comma */ + if (size > 4) + fprintf(out_, ",) # %lu values\n", (unsigned long)size); + else + fprintf(out_, ",)\n"); + grib_context_free(a->context_, values); + + fprintf(out_, " codes_set_array(ibufr, '%s->%s', ivalues)\n", prefix, a->name_); + } + else { + if (!codes_bufr_key_exclude_from_dump(prefix)) { + char* sval = lval_to_string(c, value); + fprintf(out_, " codes_set(ibufr, '%s->%s', ", prefix, a->name_); + fprintf(out_, "%s)\n", sval); + grib_context_free(c, sval); + } + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + depth_ -= 2; + } + (void)err; /* TODO */ +} + +void BufrEncodePython::dump_bits(grib_accessor* a, const char* comment) +{ +} + +void BufrEncodePython::dump_double(grib_accessor* a, const char* comment) +{ + double value; + size_t size = 1; + int r; + char* sval; + grib_handle* h = grib_handle_of_accessor(a); + grib_context* c = h->context; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->unpack_double(&value, &size); + empty_ = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + + sval = dval_to_string(c, value); + if (r != 0) + fprintf(out_, " codes_set(ibufr, '#%d#%s', %s)\n", r, a->name_, sval); + else + fprintf(out_, " codes_set(ibufr, '%s', %s)\n", a->name_, sval); + grib_context_free(c, sval); + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } +} + +void BufrEncodePython::dump_string_array(grib_accessor* a, const char* comment) +{ + char** values; + size_t size = 0, i = 0; + grib_context* c = a->context_; + int err = 0; + long count = 0; + int r = 0; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_string(a, comment); + return; + } + + fprintf(out_, " svalues = ("); + + empty_ = 0; + + values = (char**)grib_context_malloc_clear(c, size * sizeof(char*)); + if (!values) { + grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); + return; + } + + err = a->unpack_string_array(values, &size); + + for (i = 0; i < size - 1; i++) { + fprintf(out_, " \"%s\", \n", values[i]); + } + fprintf(out_, " \"%s\", )\n", values[i]); + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, " codes_set_array(ibufr, '#%d#%s', svalues)\n", r, a->name_); + else + fprintf(out_, " codes_set_array(ibufr, '%s', svalues)\n", a->name_); + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + for (i = 0; i < size; ++i) + grib_context_free(c, values[i]); + grib_context_free(c, values); + (void)err; /* TODO */ +} + +void BufrEncodePython::dump_string(grib_accessor* a, const char* comment) +{ + char* value = NULL; + char* p = NULL; + size_t size = 0; + grib_context* c = a->context_; + int r = 0, err = 0; + grib_handle* h = grib_handle_of_accessor(a); + const char* acc_name = a->name_; + + grib_get_string_length_acc(a, &size); + if (size == 0) + return; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + value = (char*)grib_context_malloc_clear(c, size); + if (!value) { + grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); + return; + } + + empty_ = 0; + + err = a->unpack_string(value, &size); + p = value; + r = compute_bufr_key_rank(h, keys_, acc_name); + if (grib_is_missing_string(a, (unsigned char*)value, size)) { + strcpy(value, ""); /* Empty string means MISSING string */ + } + + while (*p) { + if (!isprint(*p)) + *p = '?'; + p++; + } + + if (isLeaf_ == 0) { + depth_ += 2; + if (r != 0) + fprintf(out_, " codes_set(ibufr, '#%d#%s',", r, acc_name); + else + fprintf(out_, " codes_set(ibufr, '%s',", acc_name); + } + fprintf(out_, "\'%s\')\n", value); + + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(acc_name) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, acc_name); + } + else + prefix = (char*)acc_name; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + depth_ -= 2; + } + + grib_context_free(c, value); + (void)err; /* TODO */ +} + +void BufrEncodePython::dump_bytes(grib_accessor* a, const char* comment) +{ +} + +void BufrEncodePython::dump_label(grib_accessor* a, const char* comment) +{ +} + +static void _dump_long_array(grib_handle* h, FILE* f, const char* key, const char* print_key) +{ + long* val; + size_t size = 0, i; + int cols = 9, icount = 0; + + if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) + return; + if (size == 0) + return; + + fprintf(f, " ivalues = ("); + + val = (long*)grib_context_malloc_clear(h->context, sizeof(long) * size); + grib_get_long_array(h, key, val, &size); + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(f, " \n "); + icount = 0; + } + fprintf(f, "%ld, ", val[i]); + icount++; + } + if (icount > cols) { + fprintf(f, " \n "); + } + /* Note: In python to make a tuple with one element, you need the trailing comma */ + if (size > 4) + fprintf(f, "%ld ,) # %lu values\n", val[size - 1], (unsigned long)size); + else + fprintf(f, "%ld ,)\n", val[size - 1]); + + grib_context_free(h->context, val); + fprintf(f, " codes_set_array(ibufr, '%s', ivalues)\n", print_key); +} + +void BufrEncodePython::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + if (strcmp(a->name_, "BUFR") == 0 || + strcmp(a->name_, "GRIB") == 0 || + strcmp(a->name_, "META") == 0) { + grib_handle* h = grib_handle_of_accessor(a); + depth_ = 2; + empty_ = 1; + depth_ += 2; + _dump_long_array(h, out_, "dataPresentIndicator", "inputDataPresentIndicator"); + _dump_long_array(h, out_, "delayedDescriptorReplicationFactor", "inputDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "shortDelayedDescriptorReplicationFactor", "inputShortDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "extendedDelayedDescriptorReplicationFactor", "inputExtendedDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "inputOverriddenReferenceValues", "inputOverriddenReferenceValues"); + grib_dump_accessors_block(this, block); + depth_ -= 2; + } + else if (strcmp(a->name_, "groupNumber") == 0) { + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + empty_ = 1; + depth_ += 2; + grib_dump_accessors_block(this, block); + depth_ -= 2; + } + else { + grib_dump_accessors_block(this, block); + } +} + +void BufrEncodePython::dump_attributes(grib_accessor* a, const char* prefix) +{ + int i = 0; + unsigned long flags; + while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { + isAttribute_ = 1; + if ((option_flags_ & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { + i++; + continue; + } + isLeaf_ = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; + flags = a->attributes_[i]->flags_; + a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; + switch (a->attributes_[i]->get_native_type()) { + case GRIB_TYPE_LONG: + dump_long_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_DOUBLE: + dump_values_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_STRING: + break; + } + a->attributes_[i]->flags_ = flags; + i++; + } + isLeaf_ = 0; + isAttribute_ = 0; +} + +void BufrEncodePython::header(const grib_handle* h) +{ + char sampleName[200] = { 0 }; + long localSectionPresent, edition, bufrHeaderCentre, isSatellite; + + grib_get_long(h, "localSectionPresent", &localSectionPresent); + grib_get_long(h, "bufrHeaderCentre", &bufrHeaderCentre); + grib_get_long(h, "edition", &edition); + + if (localSectionPresent && bufrHeaderCentre == 98) { + grib_get_long(h, "isSatellite", &isSatellite); + if (isSatellite) + snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local_satellite", edition); + else + snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local", edition); + } + else { + snprintf(sampleName, sizeof(sampleName), "BUFR%ld", edition); + } + + if (count_ < 2) { + /* This is the first message being processed */ + fprintf(out_, "# This program was automatically generated with bufr_dump -Epython\n"); + fprintf(out_, "# Using ecCodes version: "); + grib_print_api_version(out_); + fprintf(out_, "\n\n"); + fprintf(out_, "import sys\n"); + fprintf(out_, "import traceback\n\n"); + fprintf(out_, "from eccodes import *\n\n\n"); + fprintf(out_, "def bufr_encode():\n"); + } + fprintf(out_, " ibufr = codes_bufr_new_from_samples('%s')\n", sampleName); +} + +void BufrEncodePython::footer(const grib_handle* h) +{ + fprintf(out_, "\n # Encode the keys back in the data section\n"); + fprintf(out_, " codes_set(ibufr, 'pack', 1)\n\n"); + if (count_ == 1) + fprintf(out_, " outfile = open('outfile.bufr', 'wb')\n"); + else + fprintf(out_, " outfile = open('outfile.bufr', 'ab')\n"); + + fprintf(out_, " codes_write(ibufr, outfile)\n"); + if (count_ == 1) + fprintf(out_, " print (\"Created output BUFR file 'outfile.bufr'\")\n"); + /*fprintf(out_," codes_close_file(outfile)\n");*/ + fprintf(out_, " codes_release(ibufr)\n"); +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_encode_python.h b/src/dumper/grib_dumper_class_bufr_encode_python.h new file mode 100644 index 000000000..2e440cdac --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_encode_python.h @@ -0,0 +1,53 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class BufrEncodePython : public Dumper +{ +public: + BufrEncodePython() + { + class_name_ = "bufr_encode_python"; + } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_string_array(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + void header(const grib_handle*) override; + void footer(const grib_handle*) override; + +private: + static inline int depth_ = 0; + long section_offset_ = 0; + long empty_ = 0; + long end_ = 0; + long isLeaf_ = 0; + long isAttribute_ = 0; + grib_string_list* keys_ = nullptr; + + void dump_attributes(grib_accessor* a, const char* prefix); + void dump_values_attribute(grib_accessor* a, const char* prefix); + void dump_long_attribute(grib_accessor* a, const char* prefix); +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_simple.cc b/src/dumper/grib_dumper_class_bufr_simple.cc new file mode 100644 index 000000000..84b7a0cbc --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_simple.cc @@ -0,0 +1,700 @@ +/* + * (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_dumper_class_bufr_simple.h" +#include "grib_dumper_factory.h" +#include + +eccodes::dumper::BufrSimple _grib_dumper_bufr_simple; +eccodes::Dumper* grib_dumper_bufr_simple = &_grib_dumper_bufr_simple; + +namespace eccodes::dumper +{ + +int BufrSimple::init() +{ + grib_context* c = context_; + section_offset_ = 0; + empty_ = 1; + isLeaf_ = 0; + isAttribute_ = 0; + numberOfSubsets_ = 0; + keys_ = (grib_string_list*)grib_context_malloc_clear( + c, sizeof(grib_string_list)); + + return GRIB_SUCCESS; +} + +int BufrSimple::destroy() +{ + grib_string_list* next = keys_; + grib_string_list* cur = NULL; + grib_context* c = context_; + while (next) { + cur = next; + next = next->next; + grib_context_free(c, cur->value); + grib_context_free(c, cur); + } + return GRIB_SUCCESS; +} + +void BufrSimple::dump_values(grib_accessor* a) +{ + double value = 0; + size_t size = 0, size2 = 0; + double* values = NULL; + int err = 0; + int i, r; + int cols = 9; + long count = 0; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); + err = a->unpack_double(values, &size2); + } + else { + err = a->unpack_double(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + int icount = 0; + + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, "#%d#%s=", r, a->name_); + else + fprintf(out_, "%s=", a->name_); + + fprintf(out_, "{"); + + for (i = 0; i < size - 1; ++i) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + fprintf(out_, "%g, ", values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + fprintf(out_, "%g", values[i]); + + fprintf(out_, "}\n"); + grib_context_free(c, values); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + if (r != 0) + fprintf(out_, "#%d#%s=", r, a->name_); + else + fprintf(out_, "%s=", a->name_); + + if (!grib_is_missing_double(a, value)) { + fprintf(out_, "%g\n", value); + } + else { + fprintf(out_, "MISSING\n"); + } + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + } + + (void)err; /* TODO */ +} + +void BufrSimple::dump_values_attribute(grib_accessor* a, const char* prefix) +{ + double value = 0; + size_t size = 0, size2 = 0; + double* values = NULL; + int err = 0; + int i, icount; + int cols = 9; + long count = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); + err = a->unpack_double(values, &size2); + } + else { + err = a->unpack_double(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, "%s->%s = {", prefix, a->name_); + icount = 0; + for (i = 0; i < size - 1; ++i) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + fprintf(out_, "%g, ", values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + fprintf(out_, "%g", values[i]); + + fprintf(out_, "}\n"); + grib_context_free(c, values); + } + else { + /* int r=compute_bufr_key_rank(h,keys_,a->name_); */ + if (!grib_is_missing_double(a, value)) { + fprintf(out_, "%s->%s = %g\n", prefix, a->name_, value); + } + else { + fprintf(out_, "%s->%s = MISSING\n", prefix, a->name_); + } + } + + if (isLeaf_ == 0) { + char* prefix1; + + prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + } + + (void)err; /* TODO */ +} + +void BufrSimple::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 0, size2 = 0; + long* values = NULL; + int err = 0; + int i, r, icount; + int cols = 9; + long count = 0; + grib_context* c = a->context_; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + a->value_count(&count); + size = size2 = count; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + /* Note: the "subsetNumber" key is only there for UNCOMPRESSED BUFR messages */ + if (numberOfSubsets_ > 1 && strcmp(a->name_, "subsetNumber") == 0) { + err = a->unpack_long(&value, &size); + DEBUG_ASSERT(!err); + fprintf(out_, "%s=%ld\n", a->name_, value); + DEBUG_ASSERT(!grib_is_missing_long(a, value)); + (void)err; + return; + } + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + } + return; + } + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size2); + } + else { + err = a->unpack_long(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + int doing_unexpandedDescriptors = 0; + icount = 0; + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, "#%d#%s=", r, a->name_); + else + fprintf(out_, "%s=", a->name_); + + fprintf(out_, "{"); + if (strcmp(a->name_, "unexpandedDescriptors") == 0) + doing_unexpandedDescriptors = 1; + + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + if (doing_unexpandedDescriptors) + fprintf(out_, "%06ld, ", values[i]); + else + fprintf(out_, "%ld, ", values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + if (doing_unexpandedDescriptors) + fprintf(out_, "%06ld ", values[i]); + else + fprintf(out_, "%ld ", values[i]); + + fprintf(out_, "}\n"); + grib_context_free(a->context_, values); + } + else { + r = compute_bufr_key_rank(h, keys_, a->name_); + if (r != 0) + fprintf(out_, "#%d#%s=", r, a->name_); + else + fprintf(out_, "%s=", a->name_); + + if (!grib_is_missing_long(a, value)) { + fprintf(out_, "%ld\n", value); + } + else { + fprintf(out_, "MISSING\n"); + } + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + } + (void)err; /* TODO */ +} + +void BufrSimple::dump_long_attribute(grib_accessor* a, const char* prefix) +{ + long value = 0; + size_t size = 0, size2 = 0; + long* values = NULL; + int err = 0; + int i, icount; + int cols = 9; + long count = 0; + grib_context* c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size2); + } + else { + err = a->unpack_long(&value, &size2); + } + Assert(size2 == size); + + empty_ = 0; + + if (size > 1) { + fprintf(out_, "%s->%s = {", prefix, a->name_); + icount = 0; + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + icount = 0; + } + fprintf(out_, "%ld, ", values[i]); + icount++; + } + if (icount > cols || i == 0) { + fprintf(out_, "\n "); + } + fprintf(out_, "%ld ", values[i]); + fprintf(out_, "}\n"); + grib_context_free(a->context_, values); + } + else { + /* int r=compute_bufr_key_rank(h,keys_,a->name_); */ + if (!codes_bufr_key_exclude_from_dump(prefix)) { + if (!grib_is_missing_long(a, value)) { + fprintf(out_, "%s->%s = ", prefix, a->name_); + fprintf(out_, "%ld\n", value); + } + else { + fprintf(out_, "%s->%s = MISSING\n", prefix, a->name_); + } + } + } + + if (isLeaf_ == 0) { + char* prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); + snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); + + dump_attributes(a, prefix1); + + grib_context_free(c, prefix1); + } + (void)err; /* TODO */ +} + +void BufrSimple::dump_bits(grib_accessor* a, const char* comment) {} + +void BufrSimple::dump_double(grib_accessor* a, const char* comment) +{ + double value = 0; + size_t size = 1; + int r; + grib_handle* h = grib_handle_of_accessor(a); + grib_context* c = h->context; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->unpack_double(&value, &size); + + empty_ = 0; + + r = compute_bufr_key_rank(h, keys_, a->name_); + if (r != 0) + fprintf(out_, "#%d#%s=", r, a->name_); + else + fprintf(out_, "%s=", a->name_); + + if (!grib_is_missing_double(a, value)) { + fprintf(out_, "%g\n", value); + } + else { + fprintf(out_, "MISSING\n"); + } + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + } +} + +void BufrSimple::dump_string_array(grib_accessor* a, const char* comment) +{ + char** values = NULL; + size_t size = 0, i = 0; + grib_context* c = a->context_; + int err = 0; + int is_missing = 0; + long count = 0; + int r = 0; + grib_handle* h = grib_handle_of_accessor(a); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + return; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_string(a, comment); + return; + } + + if (isLeaf_ == 0) { + if ((r = compute_bufr_key_rank(h, keys_, a->name_)) != 0) + fprintf(out_, "#%d#%s=", r, a->name_); + else + fprintf(out_, "%s=", a->name_); + } + + empty_ = 0; + + values = (char**)grib_context_malloc_clear(c, size * sizeof(char*)); + if (!values) { + grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); + return; + } + + err = a->unpack_string_array(values, &size); + + fprintf(out_, "{"); + for (i = 0; i < size - 1; i++) { + is_missing = grib_is_missing_string(a, (unsigned char*)values[i], strlen(values[i])); + if (is_missing) + fprintf(out_, " %s,\n", "MISSING"); + else + fprintf(out_, " \"%s\",\n", values[i]); + } + is_missing = grib_is_missing_string(a, (unsigned char*)values[i], strlen(values[i])); + if (is_missing) + fprintf(out_, " %s\n", "MISSING"); + else + fprintf(out_, " \"%s\"\n", values[i]); + + fprintf(out_, "}\n"); + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, a->name_); + } + else + prefix = (char*)a->name_; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + } + for (i = 0; i < size; ++i) + grib_context_free(c, values[i]); + grib_context_free(c, values); + (void)err; /* TODO */ +} + +#define MAX_STRING_SIZE 4096 +void BufrSimple::dump_string(grib_accessor* a, const char* comment) +{ + char value[MAX_STRING_SIZE] = {0, }; /* See ECC-710 */ + char* p = NULL; + size_t size = MAX_STRING_SIZE; + grib_context* c = a->context_; + int r = 0; + int is_missing = 0; + int err = 0; + grib_handle* h = grib_handle_of_accessor(a); + const char* acc_name = a->name_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { + return; + } + + empty_ = 0; + + err = a->unpack_string(value, &size); + if (err) { + fprintf(out_, " *** ERR=%d (%s) [dump_string on '%s']", err, grib_get_error_message(err), acc_name); + return; + } + Assert(size < MAX_STRING_SIZE); + p = value; + r = compute_bufr_key_rank(h, keys_, acc_name); + if (grib_is_missing_string(a, (unsigned char*)value, size)) { + is_missing = 1; + } + + while (*p) { + if (!isprint(*p)) + *p = '?'; + if (*p == '"') + *p = '\''; /* ECC-1401 */ + p++; + } + + if (isLeaf_ == 0) { + if (r != 0) + fprintf(out_, "#%d#%s=", r, acc_name); + else + fprintf(out_, "%s=", acc_name); + } + if (is_missing) + fprintf(out_, "%s\n", "MISSING"); + else + fprintf(out_, "\"%s\"\n", value); + + if (isLeaf_ == 0) { + char* prefix; + int dofree = 0; + + if (r != 0) { + prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(acc_name) + 10)); + dofree = 1; + snprintf(prefix, 1024, "#%d#%s", r, acc_name); + } + else + prefix = (char*)acc_name; + + dump_attributes(a, prefix); + if (dofree) + grib_context_free(c, prefix); + } + + (void)err; /* TODO */ +} + +void BufrSimple::dump_bytes(grib_accessor* a, const char* comment) {} + +void BufrSimple::dump_label(grib_accessor* a, const char* comment) {} + +static void _dump_long_array(grib_handle* h, FILE* f, const char* key) +{ + long* val; + size_t size = 0, i; + int cols = 9, icount = 0; + + if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) + return; + if (size == 0) + return; + + val = (long*)grib_context_malloc_clear(h->context, sizeof(long) * size); + grib_get_long_array(h, key, val, &size); + fprintf(f, "%s= {", key); + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(f, "\n "); + icount = 0; + } + fprintf(f, "%ld, ", val[i]); + icount++; + } + if (icount > cols) { + fprintf(f, "\n "); + } + fprintf(f, "%ld}\n", val[size - 1]); + + grib_context_free(h->context, val); +} + +void BufrSimple::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + if (strcmp(a->name_, "BUFR") == 0 || + strcmp(a->name_, "GRIB") == 0 || + strcmp(a->name_, "META") == 0) { + int err = 0; + grib_handle* h = grib_handle_of_accessor(a); + empty_ = 1; + + err = grib_get_long(h, "numberOfSubsets", &(numberOfSubsets_)); + Assert(!err); + _dump_long_array(h, out_, "dataPresentIndicator"); + _dump_long_array(h, out_, "delayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "shortDelayedDescriptorReplicationFactor"); + _dump_long_array(h, out_, "extendedDelayedDescriptorReplicationFactor"); + /* Do not show the inputOverriddenReferenceValues array. That's more for + * ENCODING */ + /*_dump_long_array(h,out_,"inputOverriddenReferenceValues","inputOverriddenReferenceValues");*/ + grib_dump_accessors_block(this, block); + } + else if (strcmp(a->name_, "groupNumber") == 0) { + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + empty_ = 1; + grib_dump_accessors_block(this, block); + } + else { + grib_dump_accessors_block(this, block); + } +} + +void BufrSimple::dump_attributes(grib_accessor* a, const char* prefix) +{ + int i = 0; + unsigned long flags; + while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { + isAttribute_ = 1; + if ((option_flags_ & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { + i++; + continue; + } + isLeaf_ = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; + /* fprintf(out_,","); */ + /* fprintf(out_,"\n%-*s",depth," "); */ + /* fprintf(out,"\"%s\" : ",a->attributes_[i]->name); */ + flags = a->attributes_[i]->flags_; + a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; + switch (a->attributes_[i]->get_native_type()) { + case GRIB_TYPE_LONG: + dump_long_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_DOUBLE: + dump_values_attribute(a->attributes_[i], prefix); + break; + case GRIB_TYPE_STRING: + break; + } + a->attributes_[i]->flags_ = flags; + i++; + } + isLeaf_ = 0; + isAttribute_ = 0; +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_bufr_simple.h b/src/dumper/grib_dumper_class_bufr_simple.h new file mode 100644 index 000000000..b372f5bc1 --- /dev/null +++ b/src/dumper/grib_dumper_class_bufr_simple.h @@ -0,0 +1,48 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class BufrSimple : public Dumper +{ +public: + BufrSimple() { class_name_ = "bufr_simple"; } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_string_array(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + +private: + long section_offset_ = 0; + long empty_ = 0; + long end_ = 0; + long isLeaf_ = 0; + long isAttribute_ = 0; + long numberOfSubsets_ = 0; + grib_string_list* keys_ = nullptr; + + void dump_attributes(grib_accessor* a, const char* prefix); + void dump_values_attribute(grib_accessor* a, const char* prefix); + void dump_long_attribute(grib_accessor* a, const char* prefix); +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_debug.cc b/src/dumper/grib_dumper_class_debug.cc new file mode 100644 index 000000000..bfad53711 --- /dev/null +++ b/src/dumper/grib_dumper_class_debug.cc @@ -0,0 +1,553 @@ +/* + * (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_dumper_class_debug.h" +#include "grib_dumper_factory.h" +#include + +eccodes::dumper::Debug _grib_dumper_debug; +eccodes::Dumper* grib_dumper_debug = &_grib_dumper_debug; + +namespace eccodes::dumper +{ + +int Debug::init() +{ + section_offset_ = 0; + return GRIB_SUCCESS; +} + +int Debug::destroy() +{ + return GRIB_SUCCESS; +} + +void Debug::default_long_value(grib_accessor* a, long actualValue) +{ + grib_action* act = a->creator_; + if (act->default_value == NULL) + return; + + grib_handle* h = grib_handle_of_accessor(a); + grib_expression* expression = grib_arguments_get_expression(h, act->default_value, 0); + if (!expression) + return; + + const int type = grib_expression_native_type(h, expression); + if (type == GRIB_TYPE_LONG) { + long defaultValue = 0; + if (grib_expression_evaluate_long(h, expression, &defaultValue) == GRIB_SUCCESS && defaultValue != actualValue) { + if (defaultValue == GRIB_MISSING_LONG) + fprintf(out_, " (default=MISSING)"); + else + fprintf(out_, " (default=%ld)", defaultValue); + } + } +} + +// void Debug::default_string_value(grib_dumper* d, grib_accessor* a, const char* actualValue) +// { +// grib_action* act = a->creator_; +// if (act->default_value == NULL) +// return; + +// grib_handle* h = grib_handle_of_accessor(a); +// grib_expression* expression = grib_arguments_get_expression(h, act->default_value, 0); +// if (!expression) +// return; + +// const int type = grib_expression_native_type(h, expression); +// DEBUG_ASSERT(type == GRIB_TYPE_STRING); +// if (type == GRIB_TYPE_STRING) { +// char tmp[1024] = {0,}; +// size_t s_len = sizeof(tmp); +// int err = 0; +// const char* p = grib_expression_evaluate_string(h, expression, tmp, &s_len, &err); +// if (!err && !STR_EQUAL(p, actualValue)) { +// fprintf(out_, " (default=%s)", p); +// } +// } +// } + +void Debug::aliases(grib_accessor* a) +{ + int i; + + if (a->all_names_[1]) { + const char* sep = ""; + fprintf(out_, " ["); + + for (i = 1; i < MAX_ACCESSOR_NAMES; i++) { + if (a->all_names_[i]) { + if (a->all_name_spaces_[i]) + fprintf(out_, "%s%s.%s", sep, a->all_name_spaces_[i], a->all_names_[i]); + else + fprintf(out_, "%s%s", sep, a->all_names_[i]); + } + sep = ", "; + } + fprintf(out_, "]"); + } +} + +void Debug::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 0; + size_t more = 0; + long* values = NULL; /* array of long */ + long count = 0; + int err = 0, i = 0; + + if (a->length_ == 0 && (option_flags_ & GRIB_DUMP_FLAG_CODED) != 0) + return; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && (option_flags_ & GRIB_DUMP_FLAG_READ_ONLY) == 0) + return; + + a->value_count(&count); + size = count; + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size); + } + else { + err = a->unpack_long(&value, &size); + } + + set_begin_end(a); + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + + if (size > 1) { + fprintf(out_, "%ld-%ld %s %s = {\n", begin_, theEnd_, a->creator_->op, a->name_); + if (values) { + int k = 0; + if (size > 100) { + more = size - 100; + size = 100; + } + while (k < size) { + int j; + for (i = 0; i < depth_ + 3; i++) + fprintf(out_, " "); + for (j = 0; j < 8 && k < size; j++, k++) { + fprintf(out_, "%ld", values[k]); + if (k != size - 1) + fprintf(out_, ", "); + } + fprintf(out_, "\n"); + } + if (more) { + for (i = 0; i < depth_ + 3; i++) + fprintf(out_, " "); + fprintf(out_, "... %lu more values\n", (unsigned long)more); + } + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "} # %s %s \n", a->creator_->op, a->name_); + grib_context_free(a->context_, values); + } + } + else { + if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) + fprintf(out_, "%ld-%ld %s %s = MISSING", begin_, theEnd_, a->creator_->op, a->name_); + else + fprintf(out_, "%ld-%ld %s %s = %ld", begin_, theEnd_, a->creator_->op, a->name_, value); + if (comment) + fprintf(out_, " [%s]", comment); + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) + fprintf(out_, " (%s)", grib_get_type_name(a->get_native_type())); + if ((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) + fprintf(out_, " %s", "(can be missing)"); + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + fprintf(out_, " %s", "(read-only)"); + } + if (err) + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_debug::dump_long]", err, grib_get_error_message(err)); + aliases(a); + default_long_value(a, value); + + fprintf(out_, "\n"); +} + +static int test_bit(long a, long b) +{ + return a & (1 << b); +} + +void Debug::dump_bits(grib_accessor* a, const char* comment) +{ + if (a->length_ == 0 && (option_flags_ & GRIB_DUMP_FLAG_CODED) != 0) + return; + + size_t size = 1; + long value = 0; + int err = a->unpack_long(&value, &size); + set_begin_end(a); + + for (int i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "%ld-%ld %s %s = %ld [", begin_, theEnd_, a->creator_->op, a->name_, value); + for (long i = 0; i < (a->length_ * 8); i++) { + if (test_bit(value, a->length_ * 8 - i - 1)) + fprintf(out_, "1"); + else + fprintf(out_, "0"); + } + + if (comment) + fprintf(out_, ":%s]", comment); + else + fprintf(out_, "]"); + + if (err) + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_debug::dump_bits]", err, grib_get_error_message(err)); + aliases(a); + fprintf(out_, "\n"); +} + +void Debug::dump_double(grib_accessor* a, const char* comment) +{ + double value = 0; + size_t size = 1; + int err = a->unpack_double(&value, &size); + int i; + + if (a->length_ == 0 && (option_flags_ & GRIB_DUMP_FLAG_CODED) != 0) + return; + + set_begin_end(a); + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + + if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && + a->is_missing_internal()) + fprintf(out_, "%ld-%ld %s %s = MISSING", begin_, theEnd_, a->creator_->op, a->name_); + else + fprintf(out_, "%ld-%ld %s %s = %g", begin_, theEnd_, a->creator_->op, a->name_, value); + if (comment) + fprintf(out_, " [%s]", comment); + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) + fprintf(out_, " (%s)", grib_get_type_name(a->get_native_type())); + if (err) + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_debug::dump_double]", err, grib_get_error_message(err)); + aliases(a); + fprintf(out_, "\n"); +} + +void Debug::dump_string(grib_accessor* a, const char* comment) +{ + int err = 0; + int i; + size_t size = 0; + char* value = NULL; + char* p = NULL; + + if (a->length_ == 0 && (option_flags_ & GRIB_DUMP_FLAG_CODED) != 0) + return; + + grib_get_string_length_acc(a, &size); + if ((size < 2) && a->is_missing_internal()) { + /* GRIB-302: transients and missing keys. Need to re-adjust the size */ + size = 10; /* big enough to hold the string "missing" */ + } + + value = (char*)grib_context_malloc_clear(a->context_, size); + if (!value) + return; + err = a->unpack_string(value, &size); + + if (err) + strcpy(value, ""); + + p = value; + + set_begin_end(a); + + while (*p) { + if (!isprint(*p)) + *p = '.'; + p++; + } + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "%ld-%ld %s %s = %s", begin_, theEnd_, a->creator_->op, a->name_, value); + if (comment) + fprintf(out_, " [%s]", comment); + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) + fprintf(out_, " (%s)", grib_get_type_name(a->get_native_type())); + + if (err) + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_debug::dump_string]", err, grib_get_error_message(err)); + aliases(a); + fprintf(out_, "\n"); + + grib_context_free(a->context_, value); +} + +void Debug::dump_string_array(grib_accessor* a, const char* comment) +{ + 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(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(out_,d,a); + // print_offset(out_, begin_, theEnd_); + + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) { + fprintf(out_, " "); + fprintf(out_, "# type %s (str) \n", a->creator_->op); + } + + aliases(a); + if (comment) { + fprintf(out_, " "); + fprintf(out_, "# %s \n", comment); + } + if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) { + fprintf(out_, " "); + fprintf(out_, "#-READ ONLY- "); + tab = 13; + } + else + fprintf(out_, " "); + + tab++; + fprintf(out_, "%s = {\n", a->name_); + for (i = 0; i < size; i++) { + fprintf(out_, "%-*s\"%s\",\n", (int)(tab + strlen(a->name_) + 4), " ", values[i]); + } + fprintf(out_, " }"); + + if (err) { + fprintf(out_, " "); + fprintf(out_, "# *** ERR=%d (%s)", err, grib_get_error_message(err)); + } + + fprintf(out_, "\n"); + for (i = 0; i < size; ++i) + grib_context_free(c, values[i]); + grib_context_free(c, values); +} + +void Debug::dump_bytes(grib_accessor* a, const char* comment) +{ + int i, k, err = 0; + size_t more = 0; + size_t size = a->length_; + unsigned char* buf = (unsigned char*)grib_context_malloc(context_, size); + + if (a->length_ == 0 && (option_flags_ & GRIB_DUMP_FLAG_CODED) != 0) + return; + + set_begin_end(a); + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "%ld-%ld %s %s = %ld", begin_, theEnd_, a->creator_->op, a->name_, a->length_); + aliases(a); + fprintf(out_, " {"); + + if (!buf) { + if (size == 0) + fprintf(out_, "}\n"); + else + fprintf(out_, " *** ERR cannot malloc(%zu) }\n", size); + return; + } + + fprintf(out_, "\n"); + + err = a->unpack_bytes(buf, &size); + if (err) { + grib_context_free(context_, buf); + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_debug::dump_bytes]\n}", err, grib_get_error_message(err)); + return; + } + + if (size > 100) { + more = size - 100; + size = 100; + } + + k = 0; + /* if(size > 100) size = 100; */ + while (k < size) { + int j; + for (i = 0; i < depth_ + 3; i++) + fprintf(out_, " "); + for (j = 0; j < 16 && k < size; j++, k++) { + fprintf(out_, "%02x", buf[k]); + if (k != size - 1) + fprintf(out_, ", "); + } + fprintf(out_, "\n"); + } + + if (more) { + for (i = 0; i < depth_ + 3; i++) + fprintf(out_, " "); + fprintf(out_, "... %lu more values\n", (unsigned long)more); + } + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "} # %s %s \n", a->creator_->op, a->name_); + grib_context_free(context_, buf); +} + +void Debug::dump_values(grib_accessor* a) +{ + int i, k, err = 0; + size_t more = 0; + double* buf = NULL; + size_t size = 0; + long count = 0; + + if (a->length_ == 0 && (option_flags_ & GRIB_DUMP_FLAG_CODED) != 0) + return; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_double(a, NULL); + return; + } + buf = (double*)grib_context_malloc_clear(context_, size * sizeof(double)); + + set_begin_end(a); + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "%ld-%ld %s %s = (%ld,%ld)", begin_, theEnd_, a->creator_->op, a->name_, (long)size, a->length_); + aliases(a); + fprintf(out_, " {"); + + if (!buf) { + if (size == 0) + fprintf(out_, "}\n"); + else + fprintf(out_, " *** ERR cannot malloc(%zu) }\n", size); + return; + } + + fprintf(out_, "\n"); + + err = a->unpack_double(buf, &size); + if (err) { + grib_context_free(context_, buf); + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_debug::dump_values]\n}", err, grib_get_error_message(err)); + return; + } + + if (size > 100) { + more = size - 100; + size = 100; + } + + k = 0; + while (k < size) { + int j; + for (i = 0; i < depth_ + 3; i++) + fprintf(out_, " "); + for (j = 0; j < 8 && k < size; j++, k++) { + fprintf(out_, "%10g", buf[k]); + if (k != size - 1) + fprintf(out_, ", "); + } + fprintf(out_, "\n"); + } + if (more) { + for (i = 0; i < depth_ + 3; i++) + fprintf(out_, " "); + fprintf(out_, "... %lu more values\n", (unsigned long)more); + } + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "} # %s %s \n", a->creator_->op, a->name_); + grib_context_free(context_, buf); +} + +void Debug::dump_label(grib_accessor* a, const char* comment) +{ + int i; + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "----> %s %s %s\n", a->creator_->op, a->name_, comment ? comment : ""); +} + +void Debug::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + int i; + /* grib_section* s = grib_get_sub_section(a); */ + grib_section* s = a->sub_section_; + + if (a->name_[0] == '_') { + grib_dump_accessors_block(this, block); + return; + } + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "======> %s %s (%ld,%ld,%ld)\n", a->creator_->op, a->name_, a->length_, (long)s->length, (long)s->padding); + if (!strncmp(a->name_, "section", 7)) + section_offset_ = a->offset_; + /*printf("------------- section_offset = %ld\n",section_offset_);*/ + depth_ += 3; + grib_dump_accessors_block(this, block); + depth_ -= 3; + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "<===== %s %s\n", a->creator_->op, a->name_); +} + +void Debug::set_begin_end(grib_accessor* a) +{ + if ((option_flags_ & GRIB_DUMP_FLAG_OCTET) != 0) { + begin_ = a->offset_ - section_offset_ + 1; + theEnd_ = a->get_next_position_offset() - section_offset_; + } + else { + begin_ = a->offset_; + theEnd_ = a->get_next_position_offset(); + } +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_debug.h b/src/dumper/grib_dumper_class_debug.h new file mode 100644 index 000000000..7a6eb4d03 --- /dev/null +++ b/src/dumper/grib_dumper_class_debug.h @@ -0,0 +1,44 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class Debug : public Dumper +{ +public: + Debug() { class_name_ = "debug"; } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_string_array(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + +private: + long section_offset_ = 0; + long begin_ = 0; + long theEnd_ = 0; + + void set_begin_end(grib_accessor* a); + void default_long_value(grib_accessor* a, long actualValue); + void aliases(grib_accessor* a); +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_default.cc b/src/dumper/grib_dumper_class_default.cc new file mode 100644 index 000000000..dce3240a3 --- /dev/null +++ b/src/dumper/grib_dumper_class_default.cc @@ -0,0 +1,624 @@ +/* + * (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_dumper_class_default.h" +#include "grib_dumper_factory.h" +#include + +eccodes::dumper::Default _grib_dumper_default; +eccodes::Dumper* grib_dumper_default = &_grib_dumper_default; + +namespace eccodes::dumper +{ + +int Default::init() +{ + section_offset_ = 0; + + return GRIB_SUCCESS; +} + +int Default::destroy() +{ + return GRIB_SUCCESS; +} + +void Default::aliases(grib_accessor* a) +{ + int i; + + if ((option_flags_ & GRIB_DUMP_FLAG_ALIASES) == 0) + return; + + if (a->all_names_[1]) { + const char* sep = ""; + fprintf(out_, " "); + fprintf(out_, "# ALIASES: "); + + for (i = 1; i < MAX_ACCESSOR_NAMES; i++) { + if (a->all_names_[i]) { + if (a->all_name_spaces_[i]) + fprintf(out_, "%s%s.%s", sep, a->all_name_spaces_[i], a->all_names_[i]); + else + fprintf(out_, "%s%s", sep, a->all_names_[i]); + } + sep = ", "; + } + fprintf(out_, "\n"); + } +} + +void Default::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 1, size2 = 0; + long* values = NULL; + int err = 0; + int i; + long count = 0; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + a->value_count(&count); + size = size2 = count; + + print_offset(out_, a); + + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) { + fprintf(out_, " "); + fprintf(out_, "# type %s (int)\n", a->creator_->op); + } + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size2); + } + else { + err = a->unpack_long(&value, &size2); + } + Assert(size2 == size); + + aliases(a); + if (comment) { + fprintf(out_, " "); + fprintf(out_, "# %s \n", comment); + } + + if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) { + fprintf(out_, " "); + fprintf(out_, "#-READ ONLY- "); + } + else + fprintf(out_, " "); + + if (size > 1) { + int cols = 19; + int icount = 0; + fprintf(out_, "%s = { \t", a->name_); + for (int i = 0; i < size; i++) { + if (icount > cols) { + fprintf(out_, "\n\t\t\t\t"); + icount = 0; + } + fprintf(out_, "%ld ", values[i]); + icount++; + } + fprintf(out_, "}\n"); + grib_context_free(a->context_, values); + } + else { + if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) + fprintf(out_, "%s = MISSING;", a->name_); + else + fprintf(out_, "%s = %ld;", a->name_, value); + } + + if (err) { + fprintf(out_, " "); + fprintf(out_, "# *** ERR=%d (%s) [grib_dumper_default::dump_long]", err, grib_get_error_message(err)); + } + + fprintf(out_, "\n"); +} + +static int test_bit(long a, long b) +{ + return a & (1 << b); +} + +void Default::dump_bits(grib_accessor* a, const char* comment) +{ + long lvalue = 0; + size_t size = 1; + int err = 0; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + err = a->unpack_long(&lvalue, &size); + + print_offset(out_, a); + + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) { + fprintf(out_, " "); + fprintf(out_, "# type %s \n", a->creator_->op); + } + + aliases(a); + if (comment) { + fprintf(out_, " "); + fprintf(out_, "# %s \n", comment); + } + + fprintf(out_, " "); + fprintf(out_, "# flags: "); + for (long i = 0; i < (a->length_ * 8); i++) { + if (test_bit(lvalue, a->length_ * 8 - i - 1)) + fprintf(out_, "1"); + else + fprintf(out_, "0"); + } + fprintf(out_, "\n"); + + if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) { + fprintf(out_, " "); + fprintf(out_, "#-READ ONLY- "); + } + else { + fprintf(out_, " "); + } + + if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) + fprintf(out_, "%s = MISSING;", a->name_); + else { + fprintf(out_, "%s = %ld;", a->name_, lvalue); + } + + if (err) { + fprintf(out_, " "); + fprintf(out_, "# *** ERR=%d (%s) [grib_dumper_default::dump_bits]", err, grib_get_error_message(err)); + } + + fprintf(out_, "\n"); +} + +void Default::dump_double(grib_accessor* a, const char* comment) +{ + double value = 0; + size_t size = 1; + int err = a->unpack_double(&value, &size); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + print_offset(out_, a); + + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) { + fprintf(out_, " "); + fprintf(out_, "# type %s (double)\n", a->creator_->op); + } + + aliases(a); + if (comment) { + fprintf(out_, " "); + fprintf(out_, "# %s \n", comment); + } + + if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) { + fprintf(out_, " "); + fprintf(out_, "#-READ ONLY- "); + } + else + fprintf(out_, " "); + + if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) + fprintf(out_, "%s = MISSING;", a->name_); + else + fprintf(out_, "%s = %g;", a->name_, value); + + if (err) { + fprintf(out_, " "); + fprintf(out_, "# *** ERR=%d (%s) [grib_dumper_default::dump_double]", err, grib_get_error_message(err)); + } + + fprintf(out_, "\n"); +} + +void Default::dump_string_array(grib_accessor* a, const char* comment) +{ + char** values; + size_t size = 0, i = 0; + grib_context* c = a->context_; + int err = 0; + int tab = 0; + long count = 0; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_string(a, comment); + return; + } + + values = (char**)grib_context_malloc_clear(c, size * sizeof(char*)); + if (!values) { + grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); + return; + } + + err = a->unpack_string_array(values, &size); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + print_offset(out_, a); + + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) { + fprintf(out_, " "); + fprintf(out_, "# type %s (str)\n", a->creator_->op); + } + + aliases(a); + if (comment) { + fprintf(out_, " "); + fprintf(out_, "# %s \n", comment); + } + + if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) { + fprintf(out_, " "); + fprintf(out_, "#-READ ONLY- "); + tab = 13; + } + else { + fprintf(out_, " "); + } + + tab++; + fprintf(out_, "%s = {\n", a->name_); + for (i = 0; i < size; i++) { + fprintf(out_, "%-*s\"%s\",\n", (int)(tab + strlen(a->name_) + 4), " ", values[i]); + } + fprintf(out_, " }"); + + if (err) { + fprintf(out_, " "); + fprintf(out_, "# *** ERR=%d (%s)", err, grib_get_error_message(err)); + } + + fprintf(out_, "\n"); + grib_context_free(c, values); +} + +void Default::dump_string(grib_accessor* a, const char* comment) +{ + char* value = NULL; + char* p = NULL; + size_t size = 0; + grib_context* c = a->context_; + int err = 0; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { + return; + } + + grib_get_string_length_acc(a, &size); + if (size == 0) + return; + + value = (char*)grib_context_malloc_clear(c, size); + if (!value) { + grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); + return; + } + + err = a->unpack_string(value, &size); + p = value; + + while (*p) { + if (!isprint(*p)) + *p = '.'; + p++; + } + + print_offset(out_, a); + + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) { + fprintf(out_, " "); + fprintf(out_, "# type %s (str)\n", a->creator_->op); + } + + aliases(a); + if (comment) { + fprintf(out_, " "); + fprintf(out_, "# %s \n", comment); + } + + if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) { + fprintf(out_, " "); + fprintf(out_, "#-READ ONLY- "); + } + else + fprintf(out_, " "); + + if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && + a->is_missing_internal()) + fprintf(out_, "%s = MISSING;", a->name_); + else + fprintf(out_, "%s = %s;", a->name_, value); + + if (err) { + fprintf(out_, " "); + fprintf(out_, "# *** ERR=%d (%s) [grib_dumper_default::dump_string]", err, grib_get_error_message(err)); + } + + fprintf(out_, "\n"); + grib_context_free(c, value); +} + +void Default::dump_bytes(grib_accessor* a, const char* comment) +{ +// int i,k,err =0; +// size_t more = 0; +// size_t size = a->length_; +// unsigned char* buf = grib_context_malloc(context_,size); + +// if ( (a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) +// return; + +// if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) +// fprintf(out_,"-READ ONLY- "); + +// /*for(i = 0; i < depth_ ; i++) fprintf(out_," ");*/ +// /*print_offset(out_, theEnd_);*/ +// if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) +// fprintf(out_,"%s ",a->creator_->op); + +// fprintf(out_,"%s = %ld",a->name_,a->length_); +// aliases(d,a); +// fprintf(out_," {"); + +// if(!buf) +// { +// if(size == 0) +// fprintf(out_,"}\n"); +// else +// fprintf(out_," *** ERR cannot malloc(%ld) }\n",(long)size); +// return; +// } + +// fprintf(out_,"\n"); + +// err = a->unpack_bytes(buf,&size); +// if(err){ +// grib_context_free(context_,buf); +// fprintf(out_," *** ERR=%d (%s) [grib_dumper_default::dump_bytes]\n}",err,grib_get_error_message(err)); +// return ; +// } + +// if(size > 100) { +// more = size - 100; +// size = 100; +// } + +// k = 0; +// /* if(size > 100) size = 100; */ +// while(k < size) +// { +// int j; +// for(i = 0; i < depth_ + 3 ; i++) fprintf(out_," "); +// for(j = 0; j < 16 && k < size; j++, k++) +// { +// fprintf(out_,"%02x",buf[k]); +// if(k != size-1) +// fprintf(out_,", "); +// } +// fprintf(out_,"\n"); +// } + +// if(more) +// { +// for(i = 0; i < depth_ + 3 ; i++) fprintf(out_," "); +// fprintf(out_,"... %lu more values\n", (unsigned long)more); +// } + +// for(i = 0; i < depth_ ; i++) fprintf(out_," "); +// fprintf(out_,"} # %s %s \n",a->creator_->op, a->name_); +// grib_context_free(context_,buf); +} + +void Default::dump_values(grib_accessor* a) +{ + int k, err = 0; + size_t more = 0; + double* buf = NULL; + size_t size = 0; + long count = 0; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_double(a, NULL); + return; + } + + buf = (double*)grib_context_malloc(context_, size * sizeof(double)); + + print_offset(out_, a); + + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) { + char type_name[32] = ""; + const long native_type = a->get_native_type(); + if (native_type == GRIB_TYPE_LONG) + strcpy(type_name, "(int)"); + else if (native_type == GRIB_TYPE_DOUBLE) + strcpy(type_name, "(double)"); + else if (native_type == GRIB_TYPE_STRING) + strcpy(type_name, "(str)"); + fprintf(out_, " "); + fprintf(out_, "# type %s %s\n", a->creator_->op, type_name); + } + + aliases(a); + + if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) { + fprintf(out_, " "); + fprintf(out_, "#-READ ONLY- "); + } + else + fprintf(out_, " "); + + fprintf(out_, "%s(%zu) = ", a->name_, size); + aliases(a); + fprintf(out_, " {"); + + if (!buf) { + if (size == 0) + fprintf(out_, "}\n"); + else + fprintf(out_, " *** ERR cannot malloc(%zu) }\n", size); + return; + } + + fprintf(out_, "\n"); + + err = a->unpack_double(buf, &size); + + if (err) { + grib_context_free(context_, buf); + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_default::dump_values]\n}", err, grib_get_error_message(err)); + return; + } + + if (!(option_flags_ & GRIB_DUMP_FLAG_ALL_DATA) && size > 100) { + more = size - 100; + size = 100; + } + + k = 0; + while (k < size) { + int j; + fprintf(out_, " "); + for (j = 0; j < 5 && k < size; j++, k++) { + fprintf(out_, "%g", buf[k]); + if (k != size - 1) + fprintf(out_, ", "); + } + fprintf(out_, "\n"); + } + if (more) { + fprintf(out_, " "); + fprintf(out_, "... %lu more values\n", (unsigned long)more); + } + + fprintf(out_, " "); + fprintf(out_, "} \n"); + grib_context_free(context_, buf); +} + +void Default::dump_label(grib_accessor* a, const char* comment) +{ + /*grib_dumper_default *self = (grib_dumper_default*)d; + + for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," "); + fprintf(self->dumper.out,"----> %s %s %s\n",a->creator_->op, a->name_,comment?comment:"");*/ +} + +void Default::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + int is_default_section = 0; + char* upper = NULL; + char *p = NULL, *q = NULL; + if (!strncmp(a->name_, "section", 7)) + is_default_section = 1; + if (!strcmp(a->creator_->op, "bufr_group")) { + dump_long(a, NULL); + } + + /*for(i = 0; i < depth_ ; i++) fprintf(out_," ");*/ + if (is_default_section) { + /* char tmp[512]; */ + /* grib_section* s = a->sub_section; */ + upper = (char*)malloc(strlen(a->name_) + 1); + Assert(upper); + p = (char*)a->name_; + q = upper; + while (*p != '\0') { + *q = toupper(*p); + q++; + p++; + } + *q = '\0'; + + /* snprintf(tmp, sizeof(tmp), "%s ( length=%ld, padding=%ld )", upper, (long)s->length, (long)s->padding); */ + /* fprintf(out_,"#============== %-38s ==============\n",tmp); */ + free(upper); + section_offset_ = a->offset_; + } + + /*printf("------------- section_offset = %ld\n",section_offset_);*/ + depth_ += 3; + grib_dump_accessors_block(this, block); + depth_ -= 3; + /*for(i = 0; i < depth_ ; i++) fprintf(out_," ");*/ + /*fprintf(out_,"<===== %s %s\n",a->creator_->op, a->name_);*/ +} + +void Default::print_offset(FILE* out, grib_accessor* a) +{ + int i, k; + long offset; + long theBegin = 0, theEnd = 0; + size_t size = 0, more = 0; + grib_handle* h = grib_handle_of_accessor(a); + + theBegin = a->offset_ - section_offset_ + 1; + theEnd = a->get_next_position_offset() - section_offset_; + + if ((option_flags_ & GRIB_DUMP_FLAG_HEXADECIMAL) != 0 && a->length_ != 0) { + if (theBegin == theEnd) { + fprintf(out_, " "); + fprintf(out, "# Octet: "); + fprintf(out, "%ld", theBegin); + } + else { + fprintf(out_, " "); + fprintf(out, "# Octets: "); + fprintf(out, "%ld-%ld", theBegin, theEnd); + } + fprintf(out, " = "); + size = a->length_; + + if (!(option_flags_ & GRIB_DUMP_FLAG_ALL_DATA) && size > 112) { + more = size - 112; + size = 112; + } + + k = 0; + while (k < size) { + offset = a->offset_; + for (i = 0; i < 14 && k < size; i++, k++) { + fprintf(out, " 0x%.2X", h->buffer->data[offset]); + offset++; + } + if (k < size) + fprintf(out_, "\n #"); + } + if (more) { + fprintf(out_, "\n #... %lu more values\n", (unsigned long)more); + } + fprintf(out_, "\n"); + } +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_default.h b/src/dumper/grib_dumper_class_default.h new file mode 100644 index 000000000..8311dba29 --- /dev/null +++ b/src/dumper/grib_dumper_class_default.h @@ -0,0 +1,43 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class Default : public Dumper +{ +public: + Default() { class_name_ = "default"; } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_string_array(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + +private: + long section_offset_ = 0; + long begin_ = 0; + long theEnd_ = 0; + + void aliases(grib_accessor* a); + void print_offset(FILE* out, grib_accessor* a); +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_grib_encode_C.cc b/src/dumper/grib_dumper_class_grib_encode_C.cc new file mode 100644 index 000000000..60378508b --- /dev/null +++ b/src/dumper/grib_dumper_class_grib_encode_C.cc @@ -0,0 +1,374 @@ +/* + * (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_dumper_class_grib_encode_C.h" +#include "grib_dumper_factory.h" + + +eccodes::dumper::GribEncodeC _grib_dumper_grib_encode_c; +eccodes::Dumper* grib_dumper_grib_encode_c = &_grib_dumper_grib_encode_c; + +namespace eccodes::dumper { + +int GribEncodeC::init() +{ + return GRIB_SUCCESS; +} + +int GribEncodeC::destroy() +{ + return GRIB_SUCCESS; +} + +static void pcomment(FILE* f, long value, const char* p) +{ + int cr = 0; + fprintf(f, "\n /* %ld = ", value); + + while (*p) { + switch (*p) { + case ';': + fprintf(f, "\n "); + cr = 1; + break; + + case ':': + if (cr) + fprintf(f, "\n See "); + else + fprintf(f, ". See "); + break; + + default: + fputc(*p, f); + break; + } + + p++; + } + + fprintf(f, " */\n"); +} + +void GribEncodeC::dump_long(grib_accessor* a, const char* comment) +{ + long value; + size_t size = 1; + int err = a->unpack_long(&value, &size); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY)) + return; + + if (comment) + pcomment(out_, value, comment); + + if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && (value == GRIB_MISSING_LONG)) + fprintf(out_, " GRIB_CHECK(grib_set_missing(h,\"%s\"),%d);\n", a->name_, 0); + else + fprintf(out_, " GRIB_CHECK(grib_set_long(h,\"%s\",%ld),%d);\n", a->name_, value, 0); + + if (err) + fprintf(out_, " /* Error accessing %s (%s) */", a->name_, grib_get_error_message(err)); + + if (comment) + fprintf(out_, "\n"); +} + +static int test_bit(long a, long b) +{ + return a & (1 << b); +} + + +void GribEncodeC::dump_bits(grib_accessor* a, const char* comment) +{ + long value; + size_t size = 1; + int err = a->unpack_long(&value, &size); + int i; + + char buf[1024]; + + if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) + return; + + if (a->length_ == 0) + return; + + buf[0] = 0; + + for (i = 0; i < (a->length_ * 8); i++) { + if (test_bit(value, a->length_ * 8 - i - 1)) + strcat(buf, "1"); + else + strcat(buf, "0"); + } + + if (comment) { + strcat(buf, ";"); + strcat(buf, comment); + } + + pcomment(out_, value, buf); + + if (err) + fprintf(out_, " /* Error accessing %s (%s) */", a->name_, grib_get_error_message(err)); + else + fprintf(out_, " GRIB_CHECK(grib_set_long(h,\"%s\",%ld),%d);\n", a->name_, value, 0); + + fprintf(out_, "\n"); +} + +void GribEncodeC::dump_double(grib_accessor* a, const char* comment) +{ + double value; + size_t size = 1; + int err = a->unpack_double(&value, &size); + if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) + return; + + if (a->length_ == 0) + return; + + //if(comment) fprintf(out_,"/* %s */\n",comment); + + fprintf(out_, " GRIB_CHECK(grib_set_double(h,\"%s\",%g),%d);\n", a->name_, value, 0); + + if (err) + fprintf(out_, " /* Error accessing %s (%s) */", a->name_, grib_get_error_message(err)); +} + +void GribEncodeC::dump_string(grib_accessor* a, const char* comment) +{ + char value[1024]; + size_t size = sizeof(value); + int err = a->unpack_string(value, &size); + + if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) + return; + + if (a->length_ == 0) + return; + + if (comment) + fprintf(out_, "/* %s */\n", comment); + + fprintf(out_, " p = \"%s\";\n", value); + fprintf(out_, " size = strlen(p);\n"); + fprintf(out_, " GRIB_CHECK(grib_set_string(h,\"%s\",p,&size),%d);\n", a->name_, 0); + + if (err) + fprintf(out_, " /* Error accessing %s (%s) */", a->name_, grib_get_error_message(err)); +} + +void GribEncodeC::dump_bytes(grib_accessor* a, const char* comment) +{ + int err = 0; + size_t size = a->length_; + unsigned char* buf; + + if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) + return; + + if (size == 0) + return; + + buf = (unsigned char*)grib_context_malloc(context_, size); + + if (!buf) { + fprintf(out_, "/* %s: cannot malloc(%zu) */\n", a->name_, size); + return; + } + + err = a->unpack_bytes(buf, &size); + if (err) { + grib_context_free(context_, buf); + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_grib_encode_C::dump_bytes]\n}", err, grib_get_error_message(err)); + return; + } + + // if(size > 100) { + // more = size - 100; + // size = 100; + // } + + // k = 0; + // //if(size > 100) size = 100; + // while(k < size) + // { + // int j; + // for(i = 0; i < depth_ + 3 ; i++) fprintf(out_," "); + // for(j = 0; j < 16 && k < size; j++, k++) + // { + // fprintf(out_,"%02x",buf[k]); + // if(k != size-1) + // fprintf(out_,", "); + // } + // fprintf(out_,"\n"); + // } + + grib_context_free(context_, buf); +} + +void GribEncodeC::dump_values(grib_accessor* a) +{ + int k, err = 0; + double* buf = NULL; + int type = 0; + char stype[10]; + size_t size = 0; + long count = 0; + + stype[0] = '\0'; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) || ((a->flags_ & GRIB_ACCESSOR_FLAG_DATA) && (option_flags_ & GRIB_DUMP_FLAG_NO_DATA))) + return; + + a->value_count(&count); + size = count; + + if (size == 1) { + dump_double(a, NULL); + return; + } + + type = a->get_native_type(); + switch (type) { + case GRIB_TYPE_LONG: + snprintf(stype, sizeof(stype), "%s", "long"); + break; + case GRIB_TYPE_DOUBLE: + snprintf(stype, sizeof(stype), "%s", "double"); + break; + default: + return; + } + + buf = (double*)grib_context_malloc(context_, size * sizeof(double)); + if (!buf) { + fprintf(out_, "/* %s: cannot malloc(%zu) */\n", a->name_, size); + return; + } + + err = a->unpack_double(buf, &size); + + if (err) { + grib_context_free(context_, buf); + fprintf(out_, " /* Error accessing %s (%s) */", a->name_, grib_get_error_message(err)); + return; + } + + fprintf(out_, " size = %zu;\n", size); + fprintf(out_, " v%s = (%s*)calloc(size,sizeof(%s));\n", stype, stype, stype); + fprintf(out_, " if(!v%s) {\n", stype); + fprintf(out_, " fprintf(stderr,\"failed to allocate %%zu bytes\\n\",size*sizeof(%s));\n", stype); + fprintf(out_, " exit(1);\n"); + fprintf(out_, " }\n"); + + + fprintf(out_, "\n "); + k = 0; + while (k < size) { + fprintf(out_, " v%s[%4d] = %7g;", stype, k, buf[k]); + k++; + if (k % 4 == 0) + fprintf(out_, "\n "); + } + if (size % 4) + fprintf(out_, "\n"); + fprintf(out_, "\n"); + fprintf(out_, " GRIB_CHECK(grib_set_%s_array(h,\"%s\",v%s,size),%d);\n", stype, a->name_, stype, 0); + fprintf(out_, " free(v%s);\n", stype); + + grib_context_free(context_, buf); +} + +void GribEncodeC::dump_label(grib_accessor* a, const char* comment) +{ + fprintf(out_, "\n /* %s */\n\n", a->name_); +} + +void GribEncodeC::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + grib_dump_accessors_block(this, block); +} + +void GribEncodeC::header(const grib_handle* h) +{ + long edition = 0; + int ret = 0; + ret = grib_get_long(h, "editionNumber", &edition); + if (ret != GRIB_SUCCESS) { + grib_context_log(h->context, GRIB_LOG_ERROR, "Unable to get edition number."); + Assert(0); + } + + fprintf(out_, + "#include \n" + "\n" + "/* This code was generated automatically */\n" + "\n"); + + fprintf(out_, + "\n" + "int main(int argc,const char** argv)\n" + "{\n" + " grib_handle *h = NULL;\n" + " size_t size = 0;\n" + " double* vdouble = NULL;\n" + " long* vlong = NULL;\n" + " FILE* f = NULL;\n" + " const char* p = NULL;\n" + " const void* buffer = NULL;\n" + "\n" + " if(argc != 2) {\n" + " fprintf(stderr,\"usage: %%s out\\n\",argv[0]);\n" + " exit(1);\n" + " }\n" + "\n" + " h = grib_handle_new_from_samples(NULL,\"GRIB%ld\");\n" + " if(!h) {\n" + " fprintf(stderr,\"Cannot create grib handle\\n\");\n" + " exit(1);\n" + " }\n" + "\n", + (long)edition); +} + +void GribEncodeC::footer(const grib_handle* h) +{ + + fprintf(out_, + "/* Save the message */\n" + "\n" + " f = fopen(argv[1],\"w\");\n" + " if(!f) {\n" + " perror(argv[1]);\n" + " exit(1);\n" + " }\n" + "\n" + " GRIB_CHECK(grib_get_message(h,&buffer,&size),0);\n" + "\n" + " if(fwrite(buffer,1,size,f) != size) {\n" + " perror(argv[1]);\n" + " exit(1);\n" + " }\n" + "\n" + " if(fclose(f)) {\n" + " perror(argv[1]);\n" + " exit(1);\n" + " }\n" + "\n" + " grib_handle_delete(h);\n" + " return 0;\n" + "}\n"); +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_grib_encode_C.h b/src/dumper/grib_dumper_class_grib_encode_C.h new file mode 100644 index 000000000..5e179888c --- /dev/null +++ b/src/dumper/grib_dumper_class_grib_encode_C.h @@ -0,0 +1,42 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class GribEncodeC : public Dumper +{ +public: + GribEncodeC() + { + class_name_ = "grib_encode_C"; + } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + void header(const grib_handle*) override; + void footer(const grib_handle*) override; + +private: + int cr_ = 0; +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_json.cc b/src/dumper/grib_dumper_class_json.cc new file mode 100644 index 000000000..8da2b74d5 --- /dev/null +++ b/src/dumper/grib_dumper_class_json.cc @@ -0,0 +1,524 @@ +/* + * (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_dumper_class_json.h" +#include "grib_dumper_factory.h" +#include + + +eccodes::dumper::Json _grib_dumper_json; +eccodes::Dumper* grib_dumper_json = &_grib_dumper_json; + +namespace eccodes::dumper +{ + +int Json::init() +{ + section_offset_ = 0; + empty_ = 1; + isLeaf_ = 0; + isAttribute_ = 0; + + return GRIB_SUCCESS; +} + +int Json::destroy() +{ + return GRIB_SUCCESS; +} + +void Json::dump_values(grib_accessor* a) +{ + double value = 0; + size_t size = 1, size2 = 0; + double* values = NULL; + int err = 0; + int i; + int cols = 9; + long count = 0; + double missing_value = GRIB_MISSING_DOUBLE; + grib_handle* h = NULL; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + h = grib_handle_of_accessor(a); + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (double*)grib_context_malloc_clear(a->context_, sizeof(double) * size); + err = a->unpack_double(values, &size2); + } + else { + err = a->unpack_double(&value, &size2); + } + Assert(size2 == size); + (void)err; /* TODO */ + + if (begin_ == 0 && empty_ == 0 && isAttribute_ == 0) + fprintf(out_, ","); + else + begin_ = 0; + + empty_ = 0; + + if (isLeaf_ == 0) { + fprintf(out_, "\n%-*s{\n", depth_, " "); + depth_ += 2; + fprintf(out_, "%-*s", depth_, " "); + fprintf(out_, "\"key\" : \"%s\",\n", a->name_); + } + + err = grib_set_double(h, "missingValue", missing_value); + if (size > 1) { + int icount = 0; + if (isLeaf_ == 0) { + fprintf(out_, "%-*s", depth_, " "); + fprintf(out_, "\"value\" :\n"); + } + fprintf(out_, "%-*s[", depth_, " "); + depth_ += 2; + for (i = 0; i < size - 1; ++i) { + if (icount > cols || i == 0) { + fprintf(out_, "\n%-*s", depth_, " "); + icount = 0; + } + if (values[i] == missing_value) + fprintf(out_, "null, "); + else + fprintf(out_, "%g, ", values[i]); + icount++; + } + if (icount > cols) + fprintf(out_, "\n%-*s", depth_, " "); + if (grib_is_missing_double(a, values[i])) + fprintf(out_, "%s ", "null"); + else + fprintf(out_, "%g ", values[i]); + + depth_ -= 2; + fprintf(out_, "\n%-*s]", depth_, " "); + /* if (a->attributes_[0]) fprintf(out_,","); */ + grib_context_free(a->context_, values); + } + else { + if (isLeaf_ == 0) { + fprintf(out_, "%-*s", depth_, " "); + fprintf(out_, "\"value\" : "); + } + if (grib_is_missing_double(a, value)) + fprintf(out_, "null"); + else + fprintf(out_, "%g", value); + } + + if (isLeaf_ == 0) { + dump_attributes(a); + depth_ -= 2; + fprintf(out_, "\n%-*s}", depth_, " "); + } + + (void)err; /* TODO */ +} + +void Json::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 1, size2 = 0; + long* values = NULL; + int err = 0; + int i; + int cols = 9; + long count = 0; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + a->value_count(&count); + size = size2 = count; + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size2); + } + else { + err = a->unpack_long(&value, &size2); + } + Assert(size2 == size); + + if (begin_ == 0 && empty_ == 0 && isAttribute_ == 0) + fprintf(out_, ","); + else + begin_ = 0; + + empty_ = 0; + + if (isLeaf_ == 0) { + fprintf(out_, "\n%-*s{\n", depth_, " "); + depth_ += 2; + fprintf(out_, "%-*s", depth_, " "); + fprintf(out_, "\"key\" : \"%s\",\n", a->name_); + } + + if (size > 1) { + int doing_unexpandedDescriptors = 0; + int icount = 0; + if (isLeaf_ == 0) { + fprintf(out_, "%-*s", depth_, " "); + fprintf(out_, "\"value\" :\n"); + } + fprintf(out_, "%-*s[", depth_, " "); + /* See ECC-637: unfortunately json_xs says: + * malformed number (leading zero must not be followed by another digit + if (strcmp(a->name_, "unexpandedDescriptors")==0) + doing_unexpandedDescriptors = 1; + */ + depth_ += 2; + for (i = 0; i < size - 1; i++) { + if (icount > cols || i == 0) { + fprintf(out_, "\n%-*s", depth_, " "); + icount = 0; + } + if (grib_is_missing_long(a, values[i])) { + fprintf(out_, "null, "); + } + else { + if (doing_unexpandedDescriptors) + fprintf(out_, "%06ld, ", values[i]); + else + fprintf(out_, "%ld, ", values[i]); + } + icount++; + } + if (icount > cols) + fprintf(out_, "\n%-*s", depth_, " "); + if (doing_unexpandedDescriptors) { + fprintf(out_, "%06ld ", values[i]); + } + else { + if (grib_is_missing_long(a, values[i])) + fprintf(out_, "%s", "null"); + else + fprintf(out_, "%ld ", values[i]); + } + + depth_ -= 2; + fprintf(out_, "\n%-*s]", depth_, " "); + /* if (a->attributes_[0]) fprintf(out_,","); */ + grib_context_free(a->context_, values); + } + else { + if (isLeaf_ == 0) { + fprintf(out_, "%-*s", depth_, " "); + fprintf(out_, "\"value\" : "); + } + if (grib_is_missing_long(a, value)) + fprintf(out_, "null"); + else + fprintf(out_, "%ld", value); + /* if (a->attributes_[0]) fprintf(out_,","); */ + } + + if (isLeaf_ == 0) { + dump_attributes(a); + depth_ -= 2; + fprintf(out_, "\n%-*s}", depth_, " "); + } + (void)err; /* TODO */ +} + +void Json::dump_bits(grib_accessor* a, const char* comment) +{ +} + +void Json::dump_double(grib_accessor* a, const char* comment) +{ + double value = 0; + size_t size = 1; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + a->unpack_double(&value, &size); + + if (begin_ == 0 && empty_ == 0 && isAttribute_ == 0) + fprintf(out_, ",\n"); + else + begin_ = 0; + + empty_ = 0; + + if (isLeaf_ == 0) { + fprintf(out_, "%-*s{\n", depth_, " "); + depth_ += 2; + fprintf(out_, "%-*s", depth_, " "); + fprintf(out_, "\"key\" : \"%s\",\n", a->name_); + + fprintf(out_, "%-*s", depth_, " "); + fprintf(out_, "\"value\" : "); + } + + if (grib_is_missing_double(a, value)) + fprintf(out_, "null"); + else + fprintf(out_, "%g", value); + + /* if (a->attributes_[0]) fprintf(out_,","); */ + + if (isLeaf_ == 0) { + dump_attributes(a); + depth_ -= 2; + fprintf(out_, "\n%-*s}", depth_, " "); + } +} + +void Json::dump_string_array(grib_accessor* a, const char* comment) +{ + char** values = NULL; + size_t size = 0, i = 0; + grib_context* c = NULL; + int err = 0; + int is_missing = 0; + long count = 0; + c = a->context_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + + a->value_count(&count); + size = count; + if (size == 1) { + dump_string(a, comment); + return; + } + + if (begin_ == 0 && empty_ == 0 && isAttribute_ == 0) + fprintf(out_, ","); + else + begin_ = 0; + + if (isLeaf_ == 0) { + fprintf(out_, "\n%-*s{\n", depth_, " "); + depth_ += 2; + fprintf(out_, "%-*s", depth_, " "); + fprintf(out_, "\"key\" : \"%s\",\n", a->name_); + } + + empty_ = 0; + + values = (char**)grib_context_malloc_clear(c, size * sizeof(char*)); + if (!values) { + grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); + return; + } + + err = a->unpack_string_array(values, &size); + + if (isLeaf_ == 0) { + fprintf(out_, "%-*s", depth_, " "); + fprintf(out_, "\"value\" : "); + } + fprintf(out_, "\n%-*s[", depth_, " "); + depth_ += 2; + for (i = 0; i < size - 1; i++) { + is_missing = grib_is_missing_string(a, (unsigned char*)values[i], strlen(values[i])); + if (is_missing) + fprintf(out_, "%-*s%s,\n", depth_, " ", "null"); + else + fprintf(out_, "%-*s\"%s\",\n", depth_, " ", values[i]); + } + is_missing = grib_is_missing_string(a, (unsigned char*)values[i], strlen(values[i])); + if (is_missing) + fprintf(out_, "%-*s%s", depth_, " ", "null"); + else + fprintf(out_, "%-*s\"%s\"", depth_, " ", values[i]); + + depth_ -= 2; + fprintf(out_, "\n%-*s]", depth_, " "); + + /* if (a->attributes_[0]) fprintf(out_,","); */ + + if (isLeaf_ == 0) { + dump_attributes(a); + depth_ -= 2; + fprintf(out_, "\n%-*s}", depth_, " "); + } + + for (i = 0; i < size; i++) { + grib_context_free(c, values[i]); + } + grib_context_free(c, values); + (void)err; /* TODO */ +} + +#define MAX_STRING_SIZE 4096 +void Json::dump_string(grib_accessor* a, const char* comment) +{ + char value[MAX_STRING_SIZE] = {0, }; /* See ECC-710 */ + size_t size = MAX_STRING_SIZE; + char* p = NULL; + int is_missing = 0; + int err = 0; + const char* acc_name = a->name_; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { + return; + } + + /* ECC-710: It is MUCH slower determining the string length here + * than using a maximum size (and no need for malloc). + * Specially for BUFR elements */ + /* err = grib_get_string_length_acc(a,&size); + * if (size==0) return; + * value=(char*)grib_context_malloc_clear(a->context_,size); + * if (!value) { + * grib_context_log(a->context_,GRIB_LOG_ERROR,"Unable to allocate %zu bytes",size); + * return; + * } + */ + + if (begin_ == 0 && empty_ == 0 && isAttribute_ == 0) + fprintf(out_, ","); + else + begin_ = 0; + + empty_ = 0; + + err = a->unpack_string(value, &size); + if (err) { + snprintf(value, sizeof(value), " *** ERR=%d (%s) [dump_string on '%s']", + err, grib_get_error_message(err), a->name_); + } + else { + Assert(size < MAX_STRING_SIZE); + } + p = value; + if (grib_is_missing_string(a, (unsigned char*)value, size)) { + is_missing = 1; + } + + while (*p) { + if (!isprint(*p)) + *p = '?'; + if (*p == '"') + *p = '\''; /* ECC-1401 */ + p++; + } + + if (isLeaf_ == 0) { + fprintf(out_, "\n%-*s{", depth_, " "); + depth_ += 2; + fprintf(out_, "\n%-*s", depth_, " "); + fprintf(out_, "\"key\" : \"%s\",", acc_name); + fprintf(out_, "\n%-*s", depth_, " "); + fprintf(out_, "\"value\" : "); + } + if (is_missing) + fprintf(out_, "%s", "null"); + else + fprintf(out_, "\"%s\"", value); + + /* if (a->attributes_[0]) fprintf(out_,","); */ + + if (isLeaf_ == 0) { + dump_attributes(a); + depth_ -= 2; + fprintf(out_, "\n%-*s}", depth_, " "); + } + + /* grib_context_free(a->context_,value); */ + (void)err; /* TODO */ +} + +void Json::dump_bytes(grib_accessor* a, const char* comment) +{ +} + +void Json::dump_label(grib_accessor* a, const char* comment) +{ +} + +void Json::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + if (strcmp(a->name_, "BUFR") == 0 || + strcmp(a->name_, "GRIB") == 0 || + strcmp(a->name_, "META") == 0) { + depth_ = 2; + fprintf(out_, "%-*s", depth_, " "); + fprintf(out_, "[\n"); + begin_ = 1; + empty_ = 1; + depth_ += 2; + grib_dump_accessors_block(this, block); + depth_ -= 2; + fprintf(out_, "\n]\n"); + } + else if (strcmp(a->name_, "groupNumber") == 0) { + if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) + return; + if (!empty_) + fprintf(out_, ",\n"); + fprintf(out_, "%-*s", depth_, " "); + + fprintf(out_, "["); + + fprintf(out_, "\n"); + /* fprintf(out_,"%-*s",depth," "); */ + begin_ = 1; + empty_ = 1; + depth_ += 2; + grib_dump_accessors_block(this, block); + depth_ -= 2; + fprintf(out_, "\n"); + fprintf(out_, "%-*s", depth_, " "); + fprintf(out_, "]"); + } + else { + grib_dump_accessors_block(this, block); + } +} + +void Json::dump_attributes(grib_accessor* a) +{ + int i = 0; + FILE* out = out_; + unsigned long flags; + while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { + isAttribute_ = 1; + if ((option_flags_ & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { + i++; + continue; + } + isLeaf_ = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; + fprintf(out_, ","); + fprintf(out_, "\n%-*s", depth_, " "); + fprintf(out, "\"%s\" : ", a->attributes_[i]->name_); + flags = a->attributes_[i]->flags_; + a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; + switch (a->attributes_[i]->get_native_type()) { + case GRIB_TYPE_LONG: + dump_long(a->attributes_[i], 0); + break; + case GRIB_TYPE_DOUBLE: + dump_values(a->attributes_[i]); + break; + case GRIB_TYPE_STRING: + dump_string_array(a->attributes_[i], 0); + break; + } + a->attributes_[i]->flags_ = flags; + i++; + } + isLeaf_ = 0; + isAttribute_ = 0; +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_json.h b/src/dumper/grib_dumper_class_json.h new file mode 100644 index 000000000..dc9e168c9 --- /dev/null +++ b/src/dumper/grib_dumper_class_json.h @@ -0,0 +1,49 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class Json : public Dumper +{ +public: + Json() { class_name_ = "json"; } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_string_array(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + +private: + static inline int depth_ = 0; + + long section_offset_ = 0; + long begin_ = 0; + long empty_ = 0; + long end_ = 0; + long isLeaf_ = 0; + long isAttribute_ = 0; + + void dump_attributes(grib_accessor* a); + void dump_values_attribute(grib_accessor* a, const char* prefix); + void dump_long_attribute(grib_accessor* a, const char* prefix); +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_serialize.cc b/src/dumper/grib_dumper_class_serialize.cc new file mode 100644 index 000000000..1df154812 --- /dev/null +++ b/src/dumper/grib_dumper_class_serialize.cc @@ -0,0 +1,354 @@ +/* + * (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_dumper_class_serialize.h" +#include "grib_dumper_factory.h" +#include + + +eccodes::dumper::Serialize _grib_dumper_serialize; +eccodes::Dumper* grib_dumper_serialize = &_grib_dumper_serialize; + +namespace eccodes::dumper +{ + +int Serialize::init() +{ + format_ = (char*)arg_; + return GRIB_SUCCESS; +} + +int Serialize::destroy() +{ + return GRIB_SUCCESS; +} + +void Serialize::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 1; + int err = a->unpack_long(&value, &size); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0) + return; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && + (option_flags_ & GRIB_DUMP_FLAG_READ_ONLY) == 0 && + (strcmp(a->class_name_, "lookup") != 0)) + return; + + if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && (value == GRIB_MISSING_LONG)) + fprintf(out_, "%s = MISSING", a->name_); + else + fprintf(out_, "%s = %ld", a->name_, value); + + if (((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) && + (strcmp(a->class_name_, "lookup") != 0)) + fprintf(out_, " (read_only)"); + + // if(comment) fprintf(out_," [%s]",comment); + + if (err) + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_serialize::dump_long]", err, grib_get_error_message(err)); + + fprintf(out_, "\n"); +} + +// int Serialize::test_bit(long a, long b) {return a&(1<unpack_long(&value, &size); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0) + return; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && + (option_flags_ & GRIB_DUMP_FLAG_READ_ONLY) == 0) + return; + + fprintf(out_, "%s = %ld ", a->name_, value); + + // fprintf(out_,"["); + // for(i=0;i<(a->length_*8);i++) { + // if(test_bit(value,a->length_*8-i-1)) + // fprintf(out_,"1"); + // else + // fprintf(out_,"0"); + // } + + // if(comment) + // fprintf(out_,":%s]",comment); + // else + // fprintf(out_,"]"); + + if (err) + fprintf(out_, " *** ERR=%d (%s)", err, grib_get_error_message(err)); + + fprintf(out_, "\n"); +} + +void Serialize::dump_double(grib_accessor* a, const char* comment) +{ + double value; + size_t size = 1; + int err = a->unpack_double(&value, &size); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0) + return; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && + (option_flags_ & GRIB_DUMP_FLAG_READ_ONLY) == 0) + return; + + if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && (value == GRIB_MISSING_DOUBLE)) + fprintf(out_, "%s = MISSING", a->name_); + else + fprintf(out_, "%s = %g", a->name_, value); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + fprintf(out_, " (read_only)"); + + // if (comment) fprintf(out_," [%s]",comment); + + if (err) + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_serialize::dump_double]", err, grib_get_error_message(err)); + fprintf(out_, "\n"); +} + +void Serialize::dump_string(grib_accessor* a, const char* comment) +{ + char value[1024] = {0, }; + size_t size = sizeof(value); + int err = a->unpack_string(value, &size); + int i; + + char* p = value; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0) + return; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && + (option_flags_ & GRIB_DUMP_FLAG_READ_ONLY) == 0) + return; + + while (*p) { + if (!isprint(*p)) + *p = '.'; + p++; + } + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + + fprintf(out_, "%s = %s", a->name_, value); + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) + fprintf(out_, " (read_only)"); + + // if(comment) fprintf(out_," [%s]",comment); + + if (err) + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_serialize::dump_string]", err, grib_get_error_message(err)); + fprintf(out_, "\n"); +} + +void Serialize::dump_bytes(grib_accessor* a, const char* comment) +{ + int i, k, err = 0; + size_t more = 0; + size_t size = a->length_; + unsigned char* buf = (unsigned char*)grib_context_malloc(context_, size); + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0) + return; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && + (option_flags_ & GRIB_DUMP_FLAG_READ_ONLY) == 0) + return; + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "%s = (%ld) {", a->name_, a->length_); + + if (!buf) { + if (size == 0) + fprintf(out_, "}\n"); + else + fprintf(out_, " *** ERR cannot malloc(%zu) }\n", size); + return; + } + + fprintf(out_, "\n"); + + err = a->unpack_bytes(buf, &size); + if (err) { + grib_context_free(context_, buf); + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_serialize::dump_bytes]\n}", err, grib_get_error_message(err)); + return; + } + + if (size > 100) { + more = size - 100; + size = 100; + } + + k = 0; + /* if(size > 100) size = 100; */ + while (k < size) { + int j; + for (i = 0; i < depth_ + 3; i++) + fprintf(out_, " "); + for (j = 0; j < 16 && k < size; j++, k++) { + fprintf(out_, "%02x", buf[k]); + if (k != size - 1) + fprintf(out_, ", "); + } + fprintf(out_, "\n"); + } + + if (more) { + for (i = 0; i < depth_ + 3; i++) + fprintf(out_, " "); + fprintf(out_, "... %lu more values\n", (unsigned long)more); + } + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "} # %s %s \n", a->creator_->op, a->name_); + grib_context_free(context_, buf); +} + +void Serialize::dump_values(grib_accessor* a) +{ + int k, err = 0; + double* buf = NULL; + size_t last = 0; + int columns = 4; + char* values_format = NULL; + char* default_format = (char*)"%.16e"; + char* columns_str = NULL; + size_t len = 0; + char* pc = NULL; + char* pcf = NULL; + size_t size = 0; + long count = 0; + values_format = default_format; + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY)) + return; + + a->value_count(&count); + size = count; + + if (format_) { + if (format_[0] == '\"') + values_format = format_ + 1; + else + values_format = format_; + last = strlen(values_format) - 1; + if (values_format[last] == '\"') + values_format[last] = '\0'; + } + + pc = values_format; + pcf = values_format; + while (*pc != '\0' && *pc != '%') + pc++; + if (strlen(pc) > 1) { + values_format = pc; + len = pc - pcf; + } + else { + values_format = default_format; + len = 0; + } + + if (len > 0) { + columns_str = (char*)malloc((len + 1) * sizeof(char)); + Assert(columns_str); + columns_str = (char*)memcpy(columns_str, pcf, len); + columns_str[len] = '\0'; + columns = atoi(columns_str); + free(columns_str); + } + + if (size == 1) { + dump_double(a, NULL); + return; + } + + if ((option_flags_ & GRIB_DUMP_FLAG_VALUES) == 0) + return; + + buf = (double*)grib_context_malloc(context_, size * sizeof(double)); + + fprintf(out_, "%s (%zu) {", a->name_, size); + + if (!buf) { + if (size == 0) + fprintf(out_, "}\n"); + else + fprintf(out_, " *** ERR cannot malloc(%zu) }\n", size); + return; + } + + fprintf(out_, "\n"); + + err = a->unpack_double(buf, &size); + + if (err) { + grib_context_free(context_, buf); + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_serialize::dump_values]\n}", err, grib_get_error_message(err)); + return; + } + + k = 0; + while (k < size) { + int j; + for (j = 0; j < columns && k < size; j++, k++) { + fprintf(out_, values_format, buf[k]); + if (k != size - 1) + fprintf(out_, ", "); + } + fprintf(out_, "\n"); + } + fprintf(out_, "}\n"); + grib_context_free(context_, buf); +} + +void Serialize::dump_label(grib_accessor* a, const char* comment) +{ + // int i; + // for(i = 0; i < depth_ ; i++) fprintf(out_," "); + // fprintf(out_,"----> %s %s %s\n",a->creator_->op, a->name_,comment?comment:""); +} + +void Serialize::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + const char* secstr = "section"; + + size_t len = strlen(secstr); + + if (a->name_[0] == '_') { + grib_dump_accessors_block(this, block); + return; + } + + if (strncmp(secstr, a->name_, len) == 0) + fprintf(out_, "#------ %s -------\n", a->name_); + + grib_dump_accessors_block(this, block); + + // fprintf(out_,"<------ %s %s\n",a->creator_->op, a->name_); +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_serialize.h b/src/dumper/grib_dumper_class_serialize.h new file mode 100644 index 000000000..d8e2c7fa8 --- /dev/null +++ b/src/dumper/grib_dumper_class_serialize.h @@ -0,0 +1,37 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class Serialize : public Dumper +{ +public: + Serialize() { class_name_ = "serialize"; } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + +private: + char* format_ = nullptr; +}; + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_wmo.cc b/src/dumper/grib_dumper_class_wmo.cc new file mode 100644 index 000000000..d2d46d308 --- /dev/null +++ b/src/dumper/grib_dumper_class_wmo.cc @@ -0,0 +1,586 @@ +/* + * (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_dumper_class_wmo.h" +#include "grib_dumper_factory.h" +#include + + +eccodes::dumper::Wmo _grib_dumper_wmo; +eccodes::Dumper* grib_dumper_wmo = &_grib_dumper_wmo; + +namespace eccodes::dumper +{ + +static void print_hexadecimal(FILE* out, unsigned long flags, grib_accessor* a); + +int Wmo::init() +{ + section_offset_ = 0; + + return GRIB_SUCCESS; +} + +int Wmo::destroy() +{ + return GRIB_SUCCESS; +} + +static void print_offset(FILE* out, long begin, long theEnd, int width = 10) +{ + char tmp[50]; + + if (begin == theEnd) + fprintf(out, "%-*ld", width, begin); + else { + snprintf(tmp, sizeof(tmp), "%ld-%ld", begin, theEnd); + fprintf(out, "%-*s", width, tmp); + } +} + +void Wmo::aliases(grib_accessor* a) +{ + int i; + + if ((option_flags_ & GRIB_DUMP_FLAG_ALIASES) == 0) + return; + + if (a->all_names_[1]) { + const char* sep = ""; + fprintf(out_, " ["); + + for (i = 1; i < MAX_ACCESSOR_NAMES; i++) { + if (a->all_names_[i]) { + if (a->all_name_spaces_[i]) + fprintf(out_, "%s%s.%s", sep, a->all_name_spaces_[i], a->all_names_[i]); + else + fprintf(out_, "%s%s", sep, a->all_names_[i]); + } + sep = ", "; + } + fprintf(out_, "]"); + } +} + +void Wmo::dump_long(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 0; + long* values = NULL; + int err = 0, i = 0; + long count = 0; + + if (a->length_ == 0 && + (option_flags_ & GRIB_DUMP_FLAG_CODED) != 0) + return; + + a->value_count(&count); + size = count; + + if (size > 1) { + values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); + err = a->unpack_long(values, &size); + } + else { + err = a->unpack_long(&value, &size); + } + + if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && + (option_flags_ & GRIB_DUMP_FLAG_READ_ONLY) == 0) + return; + + set_begin_end(a); + + print_offset(out_, begin_, theEnd_); + + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) + fprintf(out_, "%s (int) ", a->creator_->op); + + if (size > 1) { + int cols = 19; + int icount = 0; + fprintf(out_, "%s = { \t", a->name_); + if (values) { + for (i = 0; i < size; i++) { + if (icount > cols) { + fprintf(out_, "\n\t\t\t\t"); + icount = 0; + } + fprintf(out_, "%ld ", values[i]); + icount++; + } + fprintf(out_, "}\n"); + grib_context_free(a->context_, values); + } + } + else { + if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) + fprintf(out_, "%s = MISSING", a->name_); + else + fprintf(out_, "%s = %ld", a->name_, value); + + print_hexadecimal(out_, option_flags_, a); + + if (comment) + fprintf(out_, " [%s]", comment); + } + if (err) + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_wmo::dump_long]", err, grib_get_error_message(err)); + + aliases(a); + + + fprintf(out_, "\n"); +} + +static int test_bit(long a, long b) +{ + return a & (1 << b); +} + +void Wmo::dump_bits(grib_accessor* a, const char* comment) +{ + long value = 0; + size_t size = 1; + int err = 0; + + if (a->length_ == 0 && + (option_flags_ & GRIB_DUMP_FLAG_CODED) != 0) + return; + + err = a->unpack_long(&value, &size); + set_begin_end(a); + + // for(i = 0; i < depth_ ; i++) fprintf(out_," "); + print_offset(out_, begin_, theEnd_); + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) + fprintf(out_, "%s (int) ", a->creator_->op); + + fprintf(out_, "%s = %ld [", a->name_, value); + + for (long i = 0; i < (a->length_ * 8); i++) { + if (test_bit(value, a->length_ * 8 - i - 1)) + fprintf(out_, "1"); + else + fprintf(out_, "0"); + } + + if (comment) { + // ECC-1186: Whole comment is too big, so pick the part that follows the ':' i.e. flag table file + const char* p = strchr(comment, ':'); + if (p) + fprintf(out_, " (%s) ]", p + 1); + else + fprintf(out_, "]"); + } + else { + fprintf(out_, "]"); + } + + if (err == 0) + print_hexadecimal(out_, option_flags_, a); + + if (err) + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_wmo::dump_bits]", err, grib_get_error_message(err)); + + aliases(a); + fprintf(out_, "\n"); +} + +void Wmo::dump_double(grib_accessor* a, const char* comment) +{ + double value = 0; + size_t size = 1; + int err = 0; + + if (a->length_ == 0 && + (option_flags_ & GRIB_DUMP_FLAG_CODED) != 0) + return; + + err = a->unpack_double(&value, &size); + set_begin_end(a); + + // for(i = 0; i < depth_ ; i++) fprintf(out_," "); + + print_offset(out_, begin_, theEnd_); + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) + fprintf(out_, "%s (double) ", a->creator_->op); + + if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) + fprintf(out_, "%s = MISSING", a->name_); + else + fprintf(out_, "%s = %g", a->name_, value); + // if(comment) fprintf(out_," [%s]",comment); + + if (err == 0) + print_hexadecimal(out_, option_flags_, a); + + if (err) + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_wmo::dump_double]", err, grib_get_error_message(err)); + aliases(a); + fprintf(out_, "\n"); +} + +void Wmo::dump_string(grib_accessor* a, const char* comment) +{ + size_t size = 0; + char* value = NULL; + char* p = NULL; + int err = 0; + + if (a->length_ == 0 && + (option_flags_ & GRIB_DUMP_FLAG_CODED) != 0) { + return; + } + + grib_get_string_length_acc(a, &size); + value = (char*)grib_context_malloc_clear(a->context_, size); + if (!value) { + grib_context_log(a->context_, GRIB_LOG_ERROR, "unable to allocate %zu bytes", size); + return; + } + err = a->unpack_string(value, &size); + p = value; + + set_begin_end(a); + + while (*p) { + if (!isprint(*p)) + *p = '.'; + p++; + } + + // for(i = 0; i < depth_ ; i++) fprintf(out_," "); + print_offset(out_, begin_, theEnd_); + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) + fprintf(out_, "%s (str) ", a->creator_->op); + + fprintf(out_, "%s = %s", a->name_, value); + + if (err == 0) + print_hexadecimal(out_, option_flags_, a); + + // if(comment) fprintf(out_," [%s]",comment); + if (err) + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_wmo::dump_string]", err, grib_get_error_message(err)); + aliases(a); + fprintf(out_, "\n"); + grib_context_free(a->context_, value); +} + +void Wmo::dump_bytes(grib_accessor* a, const char* comment) +{ + int i, k, err = 0; + size_t more = 0; + size_t size = a->length_; + unsigned char* buf = (unsigned char*)grib_context_malloc(context_, size); + + if (a->length_ == 0 && + (option_flags_ & GRIB_DUMP_FLAG_CODED) != 0) + return; + + set_begin_end(a); + + // for(i = 0; i < depth_ ; i++) fprintf(out_," "); + print_offset(out_, begin_, theEnd_); + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) + fprintf(out_, "%s ", a->creator_->op); + + fprintf(out_, "%s = %ld", a->name_, a->length_); + aliases(a); + fprintf(out_, " {"); + + if (!buf) { + if (size == 0) + fprintf(out_, "}\n"); + else + fprintf(out_, " *** ERR cannot malloc(%zu) }\n", size); + return; + } + + print_hexadecimal(out_, option_flags_, a); + + fprintf(out_, "\n"); + + err = a->unpack_bytes(buf, &size); + if (err) { + grib_context_free(context_, buf); + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_wmo::dump_bytes]\n}", err, grib_get_error_message(err)); + return; + } + + if (size > 100) { + more = size - 100; + size = 100; + } + + k = 0; + // if(size > 100) size = 100; + while (k < size) { + int j; + for (i = 0; i < depth_ + 3; i++) + fprintf(out_, " "); + for (j = 0; j < 16 && k < size; j++, k++) { + fprintf(out_, "%02x", buf[k]); + if (k != size - 1) + fprintf(out_, ", "); + } + fprintf(out_, "\n"); + } + + if (more) { + for (i = 0; i < depth_ + 3; i++) + fprintf(out_, " "); + fprintf(out_, "... %lu more values\n", (unsigned long)more); + } + + for (i = 0; i < depth_; i++) + fprintf(out_, " "); + fprintf(out_, "} # %s %s \n", a->creator_->op, a->name_); + grib_context_free(context_, buf); +} + +void Wmo::dump_values(grib_accessor* a) +{ + int k, err = 0; + size_t more = 0; + double* buf = NULL; + size_t size = 0; + long count = 0; + int is_char = 0; + + if (a->length_ == 0 && + (option_flags_ & GRIB_DUMP_FLAG_CODED) != 0) + return; + + a->value_count(&count); + size = count; + + if (size == 1) { + dump_double(a, NULL); + return; + } + buf = (double*)grib_context_malloc(context_, size * sizeof(double)); + + set_begin_end(a); + + // For the DIAG pseudo GRIBs. Key charValues uses 1-byte integers to represent a character + if (a->flags_ & GRIB_ACCESSOR_FLAG_STRING_TYPE) { + is_char = 1; + } + + print_offset(out_, begin_, theEnd_, 12); // ECC-1749 + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) { + char type_name[32] = ""; + const long native_type = a->get_native_type(); + if (native_type == GRIB_TYPE_LONG) + strcpy(type_name, "(int)"); + else if (native_type == GRIB_TYPE_DOUBLE) + strcpy(type_name, "(double)"); + else if (native_type == GRIB_TYPE_STRING) + strcpy(type_name, "(str)"); + fprintf(out_, "%s %s ", a->creator_->op, type_name); + } + + fprintf(out_, "%s = (%ld,%ld)", a->name_, (long)size, a->length_); + aliases(a); + fprintf(out_, " {"); + + if (!buf) { + if (size == 0) + fprintf(out_, "}\n"); + else + fprintf(out_, " *** ERR cannot malloc(%zu) }\n", size); + return; + } + + fprintf(out_, "\n"); + + err = a->unpack_double(buf, &size); + + if (err) { + grib_context_free(context_, buf); + fprintf(out_, " *** ERR=%d (%s) [grib_dumper_wmo::dump_values]\n}", err, grib_get_error_message(err)); + return; + } + + if (size > 100) { + more = size - 100; + size = 100; + } + + k = 0; + while (k < size) { + int j; + for (j = 0; j < 8 && k < size; j++, k++) { + if (is_char) + fprintf(out_, "'%c'", (char)buf[k]); + else + fprintf(out_, "%.10e", buf[k]); + if (k != size - 1) + fprintf(out_, ", "); + } + fprintf(out_, "\n"); + // if (is_char) + // fprintf(out_, "%d '%c'\n", k, (char)buf[k]); + // else + // fprintf(out_, "%d %g\n", k, buf[k]); + } + if (more) { + // for(i = 0; i < depth_ + 3 ; i++) fprintf(out_," "); + fprintf(out_, "... %lu more values\n", (unsigned long)more); + } + + fprintf(out_, "} # %s %s \n", a->creator_->op, a->name_); + grib_context_free(context_, buf); +} + +void Wmo::dump_label(grib_accessor* a, const char* comment) +{ + // for(i = 0; i < depth_ ; i++) fprintf(out_," "); + // fprintf(out_,"----> %s %s %s\n",a->creator_->op, a->name_,comment?comment:""); +} + +void Wmo::dump_section(grib_accessor* a, grib_block_of_accessors* block) +{ + grib_section* s = a->sub_section_; + int is_wmo_section = 0; + char* upper = NULL; + char tmp[512]; + char *p = NULL, *q = NULL; + if (!strncmp(a->name_, "section", 7)) + is_wmo_section = 1; + + if (is_wmo_section) { + upper = (char*)malloc(strlen(a->name_) + 1); + Assert(upper); + p = (char*)a->name_; + q = upper; + while (*p != '\0') { + *q = toupper(*p); + q++; + p++; + } + *q = '\0'; + snprintf(tmp, sizeof(tmp), "%s ( length=%ld, padding=%ld )", upper, (long)s->length, (long)s->padding); + fprintf(out_, "====================== %-35s ======================\n", tmp); + free(upper); + section_offset_ = a->offset_; + } + else { + } + + // printf("------------- section_offset = %ld\n",section_offset_); + depth_ += 3; + grib_dump_accessors_block(this, block); + depth_ -= 3; + + // for(i = 0; i < depth_ ; i++) fprintf(out_," "); + // fprintf(out_,"<===== %s %s\n",a->creator_->op, a->name_); +} + +void Wmo::set_begin_end(grib_accessor* a) +{ + if ((option_flags_ & GRIB_DUMP_FLAG_OCTET) != 0) { + begin_ = a->offset_ - section_offset_ + 1; + theEnd_ = a->get_next_position_offset() - section_offset_; + } + else { + begin_ = a->offset_; + theEnd_ = a->get_next_position_offset(); + } +} + +static void print_hexadecimal(FILE* out, unsigned long flags, grib_accessor* a) +{ + int i = 0; + unsigned long offset = 0; + grib_handle* h = grib_handle_of_accessor(a); + if ((flags & GRIB_DUMP_FLAG_HEXADECIMAL) != 0 && a->length_ != 0) { + fprintf(out, " ("); + offset = a->offset_; + for (i = 0; i < a->length_; i++) { + fprintf(out, " 0x%.2X", h->buffer->data[offset]); + offset++; + } + fprintf(out, " )"); + } +} + +void Wmo::dump_string_array(grib_accessor* a, const char* comment) +{ + 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(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(out_,d,a); + print_offset(out_, begin_, theEnd_); + + if ((option_flags_ & GRIB_DUMP_FLAG_TYPE) != 0) { + fprintf(out_, " "); + fprintf(out_, "# type %s (str) \n", a->creator_->op); + } + + aliases(a); + if (comment) { + fprintf(out_, " "); + fprintf(out_, "# %s \n", comment); + } + if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) { + fprintf(out_, " "); + fprintf(out_, "#-READ ONLY- "); + tab = 13; + } + else + fprintf(out_, " "); + + tab++; + fprintf(out_, "%s = {\n", a->name_); + for (i = 0; i < size; i++) { + fprintf(out_, "%-*s\"%s\",\n", (int)(tab + strlen(a->name_) + 4), " ", values[i]); + } + fprintf(out_, " }"); + + if (err) { + fprintf(out_, " "); + fprintf(out_, "# *** ERR=%d (%s)", err, grib_get_error_message(err)); + } + + fprintf(out_, "\n"); + for (i = 0; i < size; ++i) + grib_context_free(c, values[i]); + grib_context_free(c, values); +} + +} // namespace eccodes::dumper diff --git a/src/dumper/grib_dumper_class_wmo.h b/src/dumper/grib_dumper_class_wmo.h new file mode 100644 index 000000000..38c6fd5b1 --- /dev/null +++ b/src/dumper/grib_dumper_class_wmo.h @@ -0,0 +1,43 @@ +/* + * (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. + */ + +#pragma once + +#include "grib_dumper.h" + +namespace eccodes::dumper +{ + +class Wmo : public Dumper +{ +public: + Wmo() { class_name_ = "wmo"; } + int init() override; + int destroy() override; + void dump_long(grib_accessor* a, const char* comment) override; + void dump_bits(grib_accessor* a, const char* comment) override; + void dump_double(grib_accessor* a, const char* comment) override; + void dump_string(grib_accessor* a, const char* comment) override; + void dump_string_array(grib_accessor* a, const char* comment) override; + void dump_bytes(grib_accessor* a, const char* comment) override; + void dump_values(grib_accessor* a) override; + void dump_label(grib_accessor* a, const char* comment) override; + void dump_section(grib_accessor* a, grib_block_of_accessors* block) override; + +private: + long section_offset_ = 0; + long begin_ = 0; + long theEnd_ = 0; + + void set_begin_end(grib_accessor* a); + void aliases(grib_accessor* a); +}; + +} // namespace eccodes::dumper diff --git a/src/eccodes_prototypes.h b/src/eccodes_prototypes.h index 3b4602cb1..3fe5e7f2f 100644 --- a/src/eccodes_prototypes.h +++ b/src/eccodes_prototypes.h @@ -374,29 +374,29 @@ int grib_buffer_replace(grib_accessor* a, const unsigned char* data, size_t news void grib_update_sections_lengths(grib_handle* h); /* grib_dumper.cc */ -void grib_init_dumper(grib_dumper* d); -void grib_dumper_delete(grib_dumper* d); -void grib_dump_long(grib_dumper* d, grib_accessor* a, const char* comment); -void grib_dump_double(grib_dumper* d, grib_accessor* a, const char* comment); -void grib_dump_string(grib_dumper* d, grib_accessor* a, const char* comment); -void grib_dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment); -void grib_dump_label(grib_dumper* d, grib_accessor* a, const char* comment); -void grib_dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment); -void grib_dump_bits(grib_dumper* d, grib_accessor* a, const char* comment); -void grib_dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block); -void grib_dump_values(grib_dumper* d, grib_accessor* a); -void grib_dump_header(grib_dumper* d, const grib_handle* h); -void grib_dump_footer(grib_dumper* d, const grib_handle* h); +// void grib_init_dumper(grib_dumper* d); +// void grib_dumper_delete(grib_dumper* d); +// void grib_dump_long(grib_dumper* d, grib_accessor* a, const char* comment); +// void grib_dump_double(grib_dumper* d, grib_accessor* a, const char* comment); +// void grib_dump_string(grib_dumper* d, grib_accessor* a, const char* comment); +// void grib_dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment); +// void grib_dump_label(grib_dumper* d, grib_accessor* a, const char* comment); +// void grib_dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment); +// void grib_dump_bits(grib_dumper* d, grib_accessor* a, const char* comment); +// void grib_dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block); +// void grib_dump_values(grib_dumper* d, grib_accessor* a); +// void grib_dump_header(grib_dumper* d, const grib_handle* h); +// void grib_dump_footer(grib_dumper* d, const grib_handle* h); /* grib_dumper_class.cc */ -grib_dumper* grib_dumper_factory(const char* op, const grib_handle* h, FILE* out, unsigned long option_flags, void* arg); -void grib_dump_accessors_block(grib_dumper* dumper, grib_block_of_accessors* block); -void grib_dump_accessors_list(grib_dumper* dumper, grib_accessors_list* al); -int grib_print(grib_handle* h, const char* name, grib_dumper* d); -void grib_dump_content(const grib_handle* h, FILE* f, const char* mode, unsigned long flags, void* data); -void grib_dump_keys(grib_handle* h, FILE* f, const char* mode, unsigned long flags, void* data, const char** keys, size_t num_keys); -grib_dumper* grib_dump_content_with_dumper(grib_handle* h, grib_dumper* dumper, FILE* f, const char* mode, unsigned long flags, void* data); -void codes_dump_bufr_flat(grib_accessors_list* al, grib_handle* h, FILE* f, const char* mode, unsigned long flags, void* data); +// grib_dumper* grib_dumper_factory(const char* op, const grib_handle* h, FILE* out, unsigned long option_flags, void* arg); +// void grib_dump_accessors_block(grib_dumper* dumper, grib_block_of_accessors* block); +// void grib_dump_accessors_list(grib_dumper* dumper, grib_accessors_list* al); +// int grib_print(grib_handle* h, const char* name, grib_dumper* d); +// void grib_dump_content(const grib_handle* h, FILE* f, const char* mode, unsigned long flags, void* data); +// void grib_dump_keys(grib_handle* h, FILE* f, const char* mode, unsigned long flags, void* data, const char** keys, size_t num_keys); +// grib_dumper* grib_dump_content_with_dumper(grib_handle* h, grib_dumper* dumper, FILE* f, const char* mode, unsigned long flags, void* data); +// void codes_dump_bufr_flat(grib_accessors_list* al, grib_handle* h, FILE* f, const char* mode, unsigned long flags, void* data); /* grib_context.cc */ size_t grib_context_read(const grib_context* c, void* ptr, size_t size, void* stream); diff --git a/src/grib_api_internal.h b/src/grib_api_internal.h index 5a1f05f03..6f12b7ef7 100644 --- a/src/grib_api_internal.h +++ b/src/grib_api_internal.h @@ -256,8 +256,6 @@ typedef struct grib_iterator { eccodes::geo_iterator::Iterator* iterator; } grib_iterator; -typedef struct grib_dumper grib_dumper; -typedef struct grib_dumper_class grib_dumper_class; typedef struct grib_dependency grib_dependency; typedef struct codes_condition codes_condition; @@ -456,47 +454,6 @@ typedef struct grib_nearest { } grib_nearest; /* --------------- */ -typedef int (*dumper_init_proc)(grib_dumper*); -typedef void (*dumper_dump_proc)(grib_dumper*, grib_accessor*, const char* comment); -typedef void (*dumper_dump_section_proc)(grib_dumper*, grib_accessor*, grib_block_of_accessors* block); -typedef void (*dumper_dump_values_proc)(grib_dumper*, grib_accessor*); -typedef int (*dumper_destroy_proc)(grib_dumper*); -typedef void (*dumper_header_proc)(grib_dumper*, grib_handle*); -typedef void (*dumper_footer_proc)(grib_dumper*, grib_handle*); -typedef void (*dumper_init_class_proc)(grib_dumper_class*); - -struct grib_dumper -{ - FILE* out; - unsigned long option_flags; - void* arg; - int depth; - long count; - grib_context* context; - grib_dumper_class* cclass; -}; - -struct grib_dumper_class -{ - grib_dumper_class** super; - const char* name; - size_t size; - int inited; - dumper_init_class_proc init_class; - dumper_init_proc init; - dumper_destroy_proc destroy; - dumper_dump_proc dump_long; - dumper_dump_proc dump_double; - dumper_dump_proc dump_string; - dumper_dump_proc dump_string_array; - dumper_dump_proc dump_label; - dumper_dump_proc dump_bytes; - dumper_dump_proc dump_bits; - dumper_dump_section_proc dump_section; - dumper_dump_values_proc dump_values; - dumper_header_proc header; - dumper_footer_proc footer; -}; struct grib_dependency { diff --git a/src/grib_dumper_class.cc b/src/grib_dumper_class.cc index 4af527151..0ac62d361 100644 --- a/src/grib_dumper_class.cc +++ b/src/grib_dumper_class.cc @@ -11,24 +11,36 @@ #include "grib_api_internal.h" /* This file is generated by ./make_class.pl */ -#include "grib_dumper_class.h" +#include "dumper/grib_dumper.h" struct table_entry { const char* type; - grib_dumper_class** cclass; }; static struct table_entry table[] = { -/* This file is generated by ./make_class.pl */ -#include "grib_dumper_factory.h" + { "bufr_decode_C", &grib_dumper_class_bufr_decode_C, }, + { "bufr_decode_filter", &grib_dumper_class_bufr_decode_filter, }, + { "bufr_decode_fortran", &grib_dumper_class_bufr_decode_fortran, }, + { "bufr_decode_python", &grib_dumper_class_bufr_decode_python, }, + { "bufr_encode_C", &grib_dumper_class_bufr_encode_C, }, + { "bufr_encode_filter", &grib_dumper_class_bufr_encode_filter, }, + { "bufr_encode_fortran", &grib_dumper_class_bufr_encode_fortran, }, + { "bufr_encode_python", &grib_dumper_class_bufr_encode_python, }, + { "bufr_simple", &grib_dumper_class_bufr_simple, }, + { "debug", &grib_dumper_class_debug, }, + { "default", &grib_dumper_class_default, }, + { "grib_encode_C", &grib_dumper_class_grib_encode_C, }, + { "json", &grib_dumper_class_json, }, + { "serialize", &grib_dumper_class_serialize, }, + { "wmo", &grib_dumper_class_wmo, }, }; -grib_dumper* grib_dumper_factory(const char* op, const grib_handle* h, FILE* out, unsigned long option_flags, void* arg) +eccodes::Dumper* grib_dumper_factory(const char* op, const grib_handle* h, FILE* out, unsigned long option_flags, void* arg) { - size_t i = 0; + size_t i = 0; const size_t num_table_entries = sizeof(table) / sizeof(table[0]); for (i = 0; i < num_table_entries; i++) if (strcmp(op, table[i].type) == 0) { @@ -48,97 +60,3 @@ grib_dumper* grib_dumper_factory(const char* op, const grib_handle* h, FILE* out return NULL; } -void grib_dump_accessors_block(grib_dumper* dumper, grib_block_of_accessors* block) -{ - grib_accessor* a = block->first; - while (a) { - a->dump(dumper); - a = a->next_; - } -} - -void grib_dump_accessors_list(grib_dumper* dumper, grib_accessors_list* al) -{ - grib_accessors_list* cur = al; - while (cur) { - cur->accessor->dump(dumper); - cur = cur->next_; - } -} - -int grib_print(grib_handle* h, const char* name, grib_dumper* d) -{ - grib_accessor* act = grib_find_accessor(h, name); - if (act) { - act->dump(d); - return GRIB_SUCCESS; - } - return GRIB_NOT_FOUND; -} - -void grib_dump_content(const grib_handle* h, FILE* f, const char* mode, unsigned long flags, void* data) -{ - grib_dumper* dumper; - dumper = grib_dumper_factory(mode ? mode : "serialize", h, f, flags, data); - if (!dumper) { - fprintf(stderr, "Here are some possible values for the dumper mode:\n"); - const size_t num_table_entries = sizeof(table) / sizeof(table[0]); - for (size_t i = 0; i < num_table_entries; i++) { - const char* t = table[i].type; - if (strstr(t, "bufr") == NULL && strstr(t, "grib") == NULL) { - fprintf(stderr, "\t%s\n", t); - } - } - return; - } - grib_dump_header(dumper, h); - grib_dump_accessors_block(dumper, h->root->block); - grib_dump_footer(dumper, h); - grib_dumper_delete(dumper); -} - -void grib_dump_keys(grib_handle* h, FILE* f, const char* mode, unsigned long flags, void* data, const char** keys, size_t num_keys) -{ - size_t i; - grib_accessor* acc = NULL; - grib_dumper* dumper = grib_dumper_factory(mode ? mode : "serialize", h, f, flags, data); - if (!dumper) return; - for (i = 0; i < num_keys; ++i) { - acc = grib_find_accessor(h, keys[i]); - if (acc) - acc->dump(dumper); - } - grib_dumper_delete(dumper); -} - -/* Note: if the dumper passed in is non-NULL, it will be freed up */ -grib_dumper* grib_dump_content_with_dumper(grib_handle* h, grib_dumper* dumper, FILE* f, const char* mode, unsigned long flags, void* data) -{ - long count = 1; - if (dumper != NULL) { - count = dumper->count; - count++; - grib_dumper_delete(dumper); - } - dumper = grib_dumper_factory(mode ? mode : "serialize", h, f, flags, data); - if (!dumper) - return NULL; - dumper->count = count; - - grib_dump_header(dumper, h); - grib_dump_accessors_block(dumper, h->root->block); - grib_dump_footer(dumper, h); - return dumper; -} - -void codes_dump_bufr_flat(grib_accessors_list* al, grib_handle* h, FILE* f, const char* mode, unsigned long flags, void* data) -{ - grib_dumper* dumper = NULL; - Assert(h->product_kind == PRODUCT_BUFR); - dumper = grib_dumper_factory(mode ? mode : "serialize", h, f, flags, data); - if (!dumper) return; - grib_dump_header(dumper, h); - grib_dump_accessors_list(dumper, al); - grib_dump_footer(dumper, h); - grib_dumper_delete(dumper); -} diff --git a/src/grib_dumper_class.h b/src/grib_dumper_class.h deleted file mode 100644 index 6ccf0c046..000000000 --- a/src/grib_dumper_class.h +++ /dev/null @@ -1,18 +0,0 @@ -/* This file is automatically generated by ./make_class.pl, do not edit */ -extern grib_dumper_class* grib_dumper_class_bufr_decode_C; -extern grib_dumper_class* grib_dumper_class_bufr_decode_filter; -extern grib_dumper_class* grib_dumper_class_bufr_decode_fortran; -extern grib_dumper_class* grib_dumper_class_bufr_decode_python; -extern grib_dumper_class* grib_dumper_class_bufr_encode_C; -extern grib_dumper_class* grib_dumper_class_bufr_encode_filter; -extern grib_dumper_class* grib_dumper_class_bufr_encode_fortran; -extern grib_dumper_class* grib_dumper_class_bufr_encode_python; -extern grib_dumper_class* grib_dumper_class_bufr_simple; -extern grib_dumper_class* grib_dumper_class_debug; -extern grib_dumper_class* grib_dumper_class_default; -extern grib_dumper_class* grib_dumper_class_file; -extern grib_dumper_class* grib_dumper_class_grib_encode_C; -extern grib_dumper_class* grib_dumper_class_json; -extern grib_dumper_class* grib_dumper_class_serialize; -extern grib_dumper_class* grib_dumper_class_string; -extern grib_dumper_class* grib_dumper_class_wmo; diff --git a/src/grib_dumper_class_bufr_decode_C.cc b/src/grib_dumper_class_bufr_decode_C.cc deleted file mode 100644 index f1c1515e4..000000000 --- a/src/grib_dumper_class_bufr_decode_C.cc +++ /dev/null @@ -1,737 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - IMPLEMENTS = header;footer - MEMBERS = long section_offset - MEMBERS = long empty - MEMBERS = long end - MEMBERS = long isLeaf - MEMBERS = long isAttribute - MEMBERS = grib_string_list* keys - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); -static void header (grib_dumper*,grib_handle*); -static void footer (grib_dumper*,grib_handle*); - -typedef struct grib_dumper_bufr_decode_C { - grib_dumper dumper; - /* Members defined in bufr_decode_C */ - long section_offset; - long empty; - long end; - long isLeaf; - long isAttribute; - grib_string_list* keys; -} grib_dumper_bufr_decode_C; - - -static grib_dumper_class _grib_dumper_class_bufr_decode_C = { - 0, /* super */ - "bufr_decode_C", /* name */ - sizeof(grib_dumper_bufr_decode_C), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - &header, /* header */ - &footer, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_bufr_decode_C = &_grib_dumper_class_bufr_decode_C; - -/* END_CLASS_IMP */ -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix); - -static int depth = 0; - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - grib_context* c = d->context; - self->section_offset = 0; - self->empty = 1; - d->count = 1; - self->isLeaf = 0; - self->isAttribute = 0; - self->keys = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - grib_string_list* next = self->keys; - grib_string_list* cur = NULL; - grib_context* c = d->context; - while (next) { - cur = next; - next = next->next; - grib_context_free(c, cur->value); - grib_context_free(c, cur); - } - return GRIB_SUCCESS; -} - -static char* dval_to_string(grib_context* c, double v) -{ - char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * 40); - snprintf(sval, 1024, "%.18e", v); - return sval; -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - double value = 0; - size_t size = 0; - int err = 0; - int r = 0; - long count = 0; - char* sval; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - - if (size <= 1) { - err = a->unpack_double(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, "\n"); - fprintf(self->dumper.out, " free(dValues);\n"); - fprintf(self->dumper.out, " dValues = (double*)malloc(%lu*sizeof(double));\n", (unsigned long)size); - fprintf(self->dumper.out, " if (!dValues) { fprintf(stderr, \"Failed to allocate memory (dValues).\\n\"); return 1; }\n"); - fprintf(self->dumper.out, " size = %lu;\n", (unsigned long)size); - - depth -= 2; - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " CODES_CHECK(codes_get_double_array(h, \"#%d#%s\",dValues, &size), 0);\n", r, a->name_); - else - fprintf(self->dumper.out, " CODES_CHECK(codes_get_double_array(h, \"%s\", dValues, &size), 0);\n", a->name_); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_double(a, value)) { - sval = dval_to_string(c, value); - if (r != 0) - fprintf(self->dumper.out, " CODES_CHECK(codes_get_double(h, \"#%d#%s\", &dVal), 0);\n", r, a->name_); - else - fprintf(self->dumper.out, " CODES_CHECK(codes_get_double(h, \"%s\", &dVal), 0);\n", a->name_); - - grib_context_free(c, sval); - } - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_values_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - double value = 0; - size_t size = 0; - int err = 0; - long count = 0; - char* sval; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - - if (size <= 1) { - err = a->unpack_double(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, "\n"); - fprintf(self->dumper.out, " free(dValues);\n"); - fprintf(self->dumper.out, " dValues = (double*)malloc(%lu*sizeof(double));\n", (unsigned long)size); - fprintf(self->dumper.out, " if (!dValues) { fprintf(stderr, \"Failed to allocate memory (dValues).\\n\"); return 1; }\n"); - fprintf(self->dumper.out, " size = %lu\n;", (unsigned long)size); - - depth -= 2; - - fprintf(self->dumper.out, " CODES_CHECK(codes_get_double_array(h, \"%s->%s\", dValues, &size), 0);\n", prefix, a->name_); - } - else { - /* int r=compute_bufr_key_rank(h,self->keys,a->name_); */ - if (!grib_is_missing_double(a, value)) { - sval = dval_to_string(c, value); - fprintf(self->dumper.out, " CODES_CHECK(codes_get_double(h, \"%s->%s\", &dVal), 0);\n", prefix, a->name_); - - grib_context_free(c, sval); - } - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - long value = 0; - size_t size = 0; - int err = 0; - int r = 0; - long count = 0; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - a->value_count(&count); - size = count; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - return; - } - - if (size <= 1) { - err = a->unpack_long(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, "\n"); - fprintf(self->dumper.out, " free(iValues);\n"); - fprintf(self->dumper.out, " iValues = (long*)malloc(%lu*sizeof(long));\n", (unsigned long)size); - fprintf(self->dumper.out, " if (!iValues) { fprintf(stderr, \"Failed to allocate memory (iValues).\\n\"); return 1; }\n"); - fprintf(self->dumper.out, " size = %lu;\n", (unsigned long)size); - - depth -= 2; - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " CODES_CHECK(codes_get_long_array(h, \"#%d#%s\", iValues, &size), 0);\n", r, a->name_); - else - fprintf(self->dumper.out, " CODES_CHECK(codes_get_long_array(h, \"%s\", iValues, &size), 0);\n", a->name_); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!codes_bufr_key_exclude_from_dump(a->name_)) { - if (!grib_is_missing_long(a, value)) { - if (r != 0) - fprintf(self->dumper.out, " CODES_CHECK(codes_get_long(h, \"#%d#%s\", &iVal), 0);\n", r, a->name_); - else - fprintf(self->dumper.out, " CODES_CHECK(codes_get_long(h, \"%s\", &iVal), 0);\n", a->name_); - } - } - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - (void)err; /* TODO */ -} - -static void dump_long_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - long value = 0; - size_t size = 0; - int err = 0; - long count = 0; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - - if (size <= 1) { - err = a->unpack_long(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, "\n"); - fprintf(self->dumper.out, " free(iValues);\n"); - fprintf(self->dumper.out, " iValues = (long*)malloc(%lu*sizeof(long));\n", (unsigned long)size); - fprintf(self->dumper.out, " if (!iValues) { fprintf(stderr, \"Failed to allocate memory (iValues).\\n\"); return 1; }\n"); - fprintf(self->dumper.out, " size = %lu;\n", (unsigned long)size); - - depth -= 2; - - fprintf(self->dumper.out, " CODES_CHECK(codes_get_long_array(h, \"%s->%s\", iValues, &size), 0);\n", prefix, a->name_); - } - else { - /* int r=compute_bufr_key_rank(h,self->keys,a->name_); */ - if (!codes_bufr_key_exclude_from_dump(prefix)) { - if (!grib_is_missing_long(a, value)) { - fprintf(self->dumper.out, " CODES_CHECK(codes_get_long(h, \"%s->%s\", &iVal), 0);\n", prefix, a->name_); - } - } - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - (void)err; /* TODO */ -} - -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) -{ - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - double value = 0; - size_t size = 1; - int r; - char* sval; - grib_handle* h = grib_handle_of_accessor(a); - grib_context* c = h->context; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->unpack_double(&value, &size); - self->empty = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_double(a, value)) { - sval = dval_to_string(c, value); - if (r != 0) - fprintf(self->dumper.out, " CODES_CHECK(codes_get_double(h, \"#%d#%s\", &dVal), 0);\n", r, a->name_); - else - fprintf(self->dumper.out, " CODES_CHECK(codes_get_double(h, \"%s\", &dVal), 0);\n", a->name_); - - grib_context_free(c, sval); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } -} - -static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - char** values; - size_t size = 0, i = 0; - grib_context* c = NULL; - int err = 0; - long count = 0; - int r = 0; - grib_handle* h = grib_handle_of_accessor(a); - - c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - if (size == 1) { - dump_string(d, a, comment); - return; - } - - fprintf(self->dumper.out, "\n"); - fprintf(self->dumper.out, " free(sValues);\n"); - fprintf(self->dumper.out, " sValues = (char**)malloc(%lu * sizeof(char*));\n", (unsigned long)size); - fprintf(self->dumper.out, " if (!sValues) { fprintf(stderr, \"Failed to allocate memory (sValues).\\n\"); return 1; }\n"); - fprintf(self->dumper.out, " size = %lu;\n", (unsigned long)size); - - self->empty = 0; - 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); - - if (self->isLeaf == 0) { - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " codes_get_string_array(h, \"#%d#%s\", sValues, &size);\n", r, a->name_); - else - fprintf(self->dumper.out, " codes_get_string_array(h, \"%s\", sValues, &size);\n", a->name_); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - for (i = 0; i < size; i++) grib_context_free(c, values[i]); - grib_context_free(c, values); - (void)err; /* TODO */ -} - -#define MAX_STRING_SIZE 4096 -static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - char value[MAX_STRING_SIZE] = {0,}; /* See ECC-710 */ - size_t size = MAX_STRING_SIZE; - char* p = NULL; - grib_context* c = a->context_; - int r = 0, err = 0; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - self->empty = 0; - - err = a->unpack_string(value, &size); - p = value; - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (grib_is_missing_string(a, (unsigned char*)value, size)) { - return; - } - - while (*p) { - if (!isprint(*p)) - *p = '?'; - p++; - } - - fprintf(self->dumper.out, " size = 1024;\n"); /* TODO */ - if (self->isLeaf == 0) { - depth += 2; - if (r != 0) - fprintf(self->dumper.out, " CODES_CHECK(codes_get_string(h, \"#%d#%s\", sVal, &size), 0);\n", r, a->name_); - else - fprintf(self->dumper.out, " CODES_CHECK(codes_get_string(h, \"%s\", sVal, &size), 0);\n", a->name_); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void _dump_long_array(grib_handle* h, FILE* f, const char* key) -{ - size_t size = 0; - if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) - return; - - fprintf(f, " free(iValues);\n"); - fprintf(f, " iValues = (long*)malloc(%lu*sizeof(long));\n", (unsigned long)size); - fprintf(f, " if (!iValues) { fprintf(stderr, \"Failed to allocate memory (iValues).\\n\"); return 1; }\n"); - fprintf(f, " size = %lu;", (unsigned long)size); - - fprintf(f, " CODES_CHECK(codes_get_long_array(h, \"%s\", iValues, &size), 0);\n", key); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - if (strcmp(a->name_, "BUFR")==0 || - strcmp(a->name_, "GRIB")==0 || - strcmp(a->name_, "META")==0) { - grib_handle* h = grib_handle_of_accessor(a); - depth = 2; - self->empty = 1; - depth += 2; - _dump_long_array(h, self->dumper.out, "dataPresentIndicator"); - _dump_long_array(h, self->dumper.out, "delayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "shortDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "extendedDelayedDescriptorReplicationFactor"); - /* Do not show the inputOverriddenReferenceValues array. That's more for ENCODING */ - /*_dump_long_array(h,self->dumper.out,"inputOverriddenReferenceValues","inputOverriddenReferenceValues");*/ - grib_dump_accessors_block(d, block); - depth -= 2; - } - else if (strcmp(a->name_, "groupNumber")==0) { - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - self->empty = 1; - depth += 2; - grib_dump_accessors_block(d, block); - depth -= 2; - } - else { - grib_dump_accessors_block(d, block); - } -} - -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - int i = 0; - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - unsigned long flags; - while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { - self->isAttribute = 1; - if ((d->option_flags & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { - i++; - continue; - } - self->isLeaf = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; - flags = a->attributes_[i]->flags_; - a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; - switch (a->attributes_[i]->get_native_type()) { - case GRIB_TYPE_LONG: - dump_long_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_DOUBLE: - dump_values_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_STRING: - break; - } - a->attributes_[i]->flags_ = flags; - i++; - } - self->isLeaf = 0; - self->isAttribute = 0; -} - -static void header(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - Assert(h->product_kind == PRODUCT_BUFR); - - if (d->count < 2) { - /* This is the first message being processed */ - fprintf(self->dumper.out, "/* This program was automatically generated with bufr_dump -DC */\n"); - fprintf(self->dumper.out, "/* Using ecCodes version: "); - grib_print_api_version(self->dumper.out); - fprintf(self->dumper.out, " */\n\n"); - fprintf(self->dumper.out, "#include \"eccodes.h\"\n"); - fprintf(self->dumper.out, "int main(int argc, char* argv[])\n"); - fprintf(self->dumper.out, "{\n"); - fprintf(self->dumper.out, " size_t size = 0;\n"); - fprintf(self->dumper.out, " int err = 0;\n"); - fprintf(self->dumper.out, " FILE* fin = NULL;\n"); - fprintf(self->dumper.out, " codes_handle* h = NULL;\n"); - fprintf(self->dumper.out, " long iVal = 0;\n"); - fprintf(self->dumper.out, " double dVal = 0.0;\n"); - fprintf(self->dumper.out, " char sVal[1024] = {0,};\n"); - fprintf(self->dumper.out, " long* iValues = NULL;\n"); - fprintf(self->dumper.out, " char** sValues = NULL;\n"); - fprintf(self->dumper.out, " double* dValues = NULL;\n"); - fprintf(self->dumper.out, " const char* infile_name = NULL;\n\n"); - - fprintf(self->dumper.out, " if (argc != 2) {\n"); - fprintf(self->dumper.out, " fprintf(stderr, \"Usage: %%s BUFR_file\\n\", argv[0]);\n"); - fprintf(self->dumper.out, " return 1;\n"); - fprintf(self->dumper.out, " }\n"); - fprintf(self->dumper.out, " infile_name = argv[1];\n"); - fprintf(self->dumper.out, " fin = fopen(infile_name, \"r\");\n"); - fprintf(self->dumper.out, " if (!fin) {\n"); - fprintf(self->dumper.out, " fprintf(stderr,\"ERROR: Unable to open input BUFR file %%s\\n\", infile_name);\n"); - fprintf(self->dumper.out, " return 1;\n"); - fprintf(self->dumper.out, " }\n\n"); - } - - fprintf(self->dumper.out, " h = codes_handle_new_from_file(NULL, fin, PRODUCT_BUFR, &err);\n"); - fprintf(self->dumper.out, " if (h == NULL) {\n"); - fprintf(self->dumper.out, " fprintf(stderr, \"ERROR: cannot create BUFR handle\\n\");\n"); - fprintf(self->dumper.out, " return 1;\n"); - fprintf(self->dumper.out, " }\n"); - fprintf(self->dumper.out, " CODES_CHECK(codes_set_long(h, \"unpack\", 1),0);\n\n"); -} - -static void footer(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_decode_C* self = (grib_dumper_bufr_decode_C*)d; - - /*fprintf(self->dumper.out," fout = fopen(\"outfile.bufr\", \"w\");");*/ - /*fprintf(self->dumper.out," if (fclose(fout)) {\n"); - fprintf(self->dumper.out," fprintf(stderr, \"Failed to close file handle.\\n\");\n"); - fprintf(self->dumper.out," return 1;\n"); - fprintf(self->dumper.out," }\n"); - */ - fprintf(self->dumper.out, "\n"); - fprintf(self->dumper.out, " codes_handle_delete(h);\n"); - fprintf(self->dumper.out, " free(iValues); iValues = NULL;\n"); - fprintf(self->dumper.out, " free(dValues); dValues = NULL;\n"); - fprintf(self->dumper.out, " free(sValues); sValues = NULL;\n\n"); -} diff --git a/src/grib_dumper_class_bufr_decode_filter.cc b/src/grib_dumper_class_bufr_decode_filter.cc deleted file mode 100644 index 3c8811320..000000000 --- a/src/grib_dumper_class_bufr_decode_filter.cc +++ /dev/null @@ -1,587 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - MEMBERS = long section_offset - MEMBERS = long begin - MEMBERS = long empty - MEMBERS = long end - MEMBERS = long isLeaf - MEMBERS = long isAttribute - MEMBERS = grib_string_list* keys - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); - -typedef struct grib_dumper_bufr_decode_filter { - grib_dumper dumper; - /* Members defined in bufr_decode_filter */ - long section_offset; - long begin; - long empty; - long end; - long isLeaf; - long isAttribute; - grib_string_list* keys; -} grib_dumper_bufr_decode_filter; - - -static grib_dumper_class _grib_dumper_class_bufr_decode_filter = { - 0, /* super */ - "bufr_decode_filter", /* name */ - sizeof(grib_dumper_bufr_decode_filter), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - 0, /* header */ - 0, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_bufr_decode_filter = &_grib_dumper_class_bufr_decode_filter; - -/* END_CLASS_IMP */ -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix); - -static int depth = 0; - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_bufr_decode_filter* self = (grib_dumper_bufr_decode_filter*)d; - grib_context* c = d->context; - self->section_offset = 0; - self->empty = 1; - self->isLeaf = 0; - self->isAttribute = 0; - self->keys = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - grib_dumper_bufr_decode_filter* self = (grib_dumper_bufr_decode_filter*)d; - grib_string_list* next = self->keys; - grib_string_list* cur = NULL; - grib_context* c = d->context; - while (next) { - cur = next; - next = next->next; - grib_context_free(c, cur->value); - grib_context_free(c, cur); - } - return GRIB_SUCCESS; -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_bufr_decode_filter* self = (grib_dumper_bufr_decode_filter*)d; - double value = 0; - size_t size = 0; - int err = 0; - int r; - long count = 0; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - - if (size <= 1) { - err = a->unpack_double(&value, &size); - } - - self->begin = 0; - self->empty = 0; - - if (size > 1) { - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); - else - fprintf(self->dumper.out, "print \"%s=[%s]\";\n", a->name_, a->name_); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_double(a, value)) { - if (r != 0) - fprintf(self->dumper.out, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); - else - fprintf(self->dumper.out, "print \"%s=[%s]\";\n", a->name_, a->name_); - } - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_values_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_decode_filter* self = (grib_dumper_bufr_decode_filter*)d; - double value = 0; - size_t size = 0; - int err = 0; - long count = 0; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - - if (size <= 1) { - err = a->unpack_double(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, "print \"%s->%s = [%s->%s]\";\n", prefix, a->name_, prefix, a->name_); - } - else { - if (!grib_is_missing_double(a, value)) { - fprintf(self->dumper.out, "print \"%s->%s = [%s->%s]\";\n", prefix, a->name_, prefix, a->name_); - } - } - - if (self->isLeaf == 0) { - char* prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_decode_filter* self = (grib_dumper_bufr_decode_filter*)d; - long value = 0; - size_t size = 0; - int err = 0; - int r = 0; - long count = 0; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - a->value_count(&count); - size = count; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - return; - } - - if (size <= 1) { - err = a->unpack_long(&value, &size); - } - - self->begin = 0; - self->empty = 0; - - if (size > 1) { - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); - else - fprintf(self->dumper.out, "print \"%s=[%s]\";\n", a->name_, a->name_); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_long(a, value)) { - if (r != 0) - fprintf(self->dumper.out, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); - else - fprintf(self->dumper.out, "print \"%s=[%s]\";\n", a->name_, a->name_); - } - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - (void)err; /* TODO */ -} - -static void dump_long_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_decode_filter* self = (grib_dumper_bufr_decode_filter*)d; - int err = 0; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - self->empty = 0; - if (!codes_bufr_key_exclude_from_dump(prefix)) { - fprintf(self->dumper.out, "print \"%s->%s = [%s->%s]\";\n", prefix, a->name_, prefix, a->name_); - } - if (self->isLeaf == 0) { - char* prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - (void)err; /* TODO */ -} - -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) -{ - grib_dumper_bufr_decode_filter* self = (grib_dumper_bufr_decode_filter*)d; - double value = 0; - size_t size = 1; - int r; - grib_handle* h = grib_handle_of_accessor(a); - grib_context* c = h->context; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->unpack_double(&value, &size); - self->begin = 0; - self->empty = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_double(a, value)) { - if (r != 0) - fprintf(self->dumper.out, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); - else - fprintf(self->dumper.out, "print \"%s=[%s]\";\n", a->name_, a->name_); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } -} - -static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_decode_filter* self = (grib_dumper_bufr_decode_filter*)d; - size_t size = 0; - grib_context* c = NULL; - int err = 0; - long count = 0; - int r = 0; - grib_handle* h = grib_handle_of_accessor(a); - - c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - if (size == 1) { - dump_string(d, a, comment); - return; - } - - self->begin = 0; - - if (self->isLeaf == 0) { - depth += 2; - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); - else - fprintf(self->dumper.out, "print \"%s=[%s]\";\n", a->name_, a->name_); - } - - self->empty = 0; - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -#define MAX_STRING_SIZE 4096 -static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_decode_filter* self = (grib_dumper_bufr_decode_filter*)d; - char value[MAX_STRING_SIZE] = {0,}; /* See ECC-710 */ - size_t size = MAX_STRING_SIZE; - char* p = NULL; - grib_context* c = a->context_; - int r =0, err = 0; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - self->begin = 0; - - self->empty = 0; - - err = a->unpack_string(value, &size); - p = value; - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (grib_is_missing_string(a, (unsigned char*)value, size)) { - return; - } - - while (*p) { - if (!isprint(*p)) - *p = '.'; - p++; - } - - if (self->isLeaf == 0) { - depth += 2; - if (r != 0) - fprintf(self->dumper.out, "print \"#%d#%s=[#%d#%s]\";\n", r, a->name_, r, a->name_); - else - fprintf(self->dumper.out, "print \"%s=[%s]\";\n", a->name_, a->name_); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void _dump_long_array(grib_handle* h, FILE* f, const char* key) -{ - size_t size = 0; - if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) - return; - if (size == 0) - return; - - fprintf(f, "print \"%s=[%s]\";\n", key, key); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_bufr_decode_filter* self = (grib_dumper_bufr_decode_filter*)d; - if (strcmp(a->name_, "BUFR")==0 || - strcmp(a->name_, "GRIB")==0 || - strcmp(a->name_, "META")==0) { - grib_handle* h = grib_handle_of_accessor(a); - depth = 2; - self->begin = 1; - self->empty = 1; - depth += 2; - _dump_long_array(h, self->dumper.out, "dataPresentIndicator"); - _dump_long_array(h, self->dumper.out, "delayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "shortDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "extendedDelayedDescriptorReplicationFactor"); - /* Do not show the inputOverriddenReferenceValues array. That's more for ENCODING */ - /*_dump_long_array(h,self->dumper.out,"inputOverriddenReferenceValues","inputOverriddenReferenceValues");*/ - grib_dump_accessors_block(d, block); - depth -= 2; - } - else if (strcmp(a->name_, "groupNumber")==0) { - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - self->begin = 1; - self->empty = 1; - depth += 2; - grib_dump_accessors_block(d, block); - depth -= 2; - } - else { - grib_dump_accessors_block(d, block); - } -} - -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - int i = 0; - grib_dumper_bufr_decode_filter* self = (grib_dumper_bufr_decode_filter*)d; - unsigned long flags; - while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { - self->isAttribute = 1; - if ((d->option_flags & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { - i++; - continue; - } - self->isLeaf = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; - /* fprintf(self->dumper.out,","); */ - /* fprintf(self->dumper.out,"\n%-*s",depth," "); */ - /* fprintf(out,"\"%s\" : ",a->attributes_[i]->name); */ - flags = a->attributes_[i]->flags_; - a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; - switch (a->attributes_[i]->get_native_type()) { - case GRIB_TYPE_LONG: - dump_long_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_DOUBLE: - dump_values_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_STRING: - break; - } - a->attributes_[i]->flags_ = flags; - i++; - } - self->isLeaf = 0; - self->isAttribute = 0; -} diff --git a/src/grib_dumper_class_bufr_decode_fortran.cc b/src/grib_dumper_class_bufr_decode_fortran.cc deleted file mode 100644 index 10570df50..000000000 --- a/src/grib_dumper_class_bufr_decode_fortran.cc +++ /dev/null @@ -1,653 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - IMPLEMENTS = header;footer - MEMBERS = long section_offset - MEMBERS = long empty - MEMBERS = long end - MEMBERS = long isLeaf - MEMBERS = long isAttribute - MEMBERS = grib_string_list* keys - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); -static void header (grib_dumper*,grib_handle*); -static void footer (grib_dumper*,grib_handle*); - -typedef struct grib_dumper_bufr_decode_fortran { - grib_dumper dumper; - /* Members defined in bufr_decode_fortran */ - long section_offset; - long empty; - long end; - long isLeaf; - long isAttribute; - grib_string_list* keys; -} grib_dumper_bufr_decode_fortran; - - -static grib_dumper_class _grib_dumper_class_bufr_decode_fortran = { - 0, /* super */ - "bufr_decode_fortran", /* name */ - sizeof(grib_dumper_bufr_decode_fortran), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - &header, /* header */ - &footer, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_bufr_decode_fortran = &_grib_dumper_class_bufr_decode_fortran; - -/* END_CLASS_IMP */ -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix); - -static int depth = 0; - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - grib_context* c = d->context; - self->section_offset = 0; - self->empty = 1; - d->count = 1; - self->isLeaf = 0; - self->isAttribute = 0; - self->keys = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - grib_string_list* next = self->keys; - grib_string_list* cur = NULL; - grib_context* c = d->context; - while (next) { - cur = next; - next = next->next; - grib_context_free(c, cur->value); - grib_context_free(c, cur); - } - return GRIB_SUCCESS; -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - double value = 0; - size_t size = 0; - int err = 0; - int r = 0; - long count = 0; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - - if (size <= 1) { - err = a->unpack_double(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - depth -= 2; - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " call codes_get(ibufr, '#%d#%s', rValues)\n", r, a->name_); - else - fprintf(self->dumper.out, " call codes_get(ibufr, '%s', rValues)\n", a->name_); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_double(a, value)) { - if (r != 0) - fprintf(self->dumper.out, " call codes_get(ibufr, '#%d#%s', rVal)\n", r, a->name_); - else - fprintf(self->dumper.out, " call codes_get(ibufr, '%s', rVal)\n", a->name_); - } - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_values_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - double value = 0; - size_t size = 0; - int err = 0; - long count = 0; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - - if (size <= 1) { - err = a->unpack_double(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, " call codes_get(ibufr, '%s->%s', rValues)\n", prefix, a->name_); - } - else { - if (!grib_is_missing_double(a, value)) { - fprintf(self->dumper.out, " call codes_get(ibufr, '%s->%s', rVal)\n", prefix, a->name_); - } - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - long value = 0; - size_t size = 0; - int err = 0; - int r = 0; - long count = 0; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - a->value_count(&count); - size = count; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - return; - } - - if (size <= 1) { - err = a->unpack_long(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - depth -= 2; - fprintf(self->dumper.out, " if(allocated(iValues)) deallocate(iValues)\n"); - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " call codes_get(ibufr, '#%d#%s', iValues)\n", r, a->name_); - else - fprintf(self->dumper.out, " call codes_get(ibufr, '%s', iValues)\n", a->name_); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_long(a, value)) { - if (r != 0) - fprintf(self->dumper.out, " call codes_get(ibufr, '#%d#%s', iVal)\n", r, a->name_); - else - fprintf(self->dumper.out, " call codes_get(ibufr, '%s', iVal)\n", a->name_); - } - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024,"#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - (void)err; /* TODO */ -} - -static void dump_long_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - long value = 0; - size_t size = 0; - int err = 0; - long count = 0; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - - if (size <= 1) { - err = a->unpack_long(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - depth -= 2; - fprintf(self->dumper.out, " if(allocated(iValues)) deallocate(iValues)\n"); - - fprintf(self->dumper.out, " call codes_get(ibufr, '%s->%s', iValues)\n", prefix, a->name_); - } - else { - if (!codes_bufr_key_exclude_from_dump(prefix)) { - if (!grib_is_missing_long(a, value)) { - fprintf(self->dumper.out, " call codes_get(ibufr, '%s->%s', iVal)\n", prefix, a->name_); - } - } - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024,"%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - (void)err; /* TODO */ -} - -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) -{ - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - double value; - size_t size = 1; - int r; - grib_handle* h = grib_handle_of_accessor(a); - grib_context* c = h->context; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->unpack_double(&value, &size); - self->empty = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_double(a, value)) { - if (r != 0) - fprintf(self->dumper.out, " call codes_get(ibufr,'#%d#%s', rVal)\n", r, a->name_); - else - fprintf(self->dumper.out, " call codes_get(ibufr,'%s', rVal)\n", a->name_); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } -} - -static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - size_t size = 0; - grib_context* c = NULL; - int err = 0; - long count = 0; - int r = 0; - grib_handle* h = grib_handle_of_accessor(a); - - c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - if (size == 1) { - dump_string(d, a, comment); - return; - } - - fprintf(self->dumper.out, " if(allocated(sValues)) deallocate(sValues)\n"); - fprintf(self->dumper.out, " allocate(sValues(%lu))\n", (unsigned long)size); - - self->empty = 0; - - if (self->isLeaf == 0) { - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " call codes_get_string_array(ibufr,'#%d#%s',sValues)\n", r, a->name_); - else - fprintf(self->dumper.out, " call codes_get_string_array(ibufr,'%s',sValues)\n", a->name_); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -#define MAX_STRING_SIZE 4096 -static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - char value[MAX_STRING_SIZE] = {0,}; /* See ECC-710 */ - size_t size = MAX_STRING_SIZE; - char* p = NULL; - grib_context* c = a->context_; - int r = 0, err = 0; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - self->empty = 0; - - err = a->unpack_string(value, &size); - p = value; - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (grib_is_missing_string(a, (unsigned char*)value, size)) { - return; - } - - while (*p) { - if (!isprint(*p)) - *p = '.'; - p++; - } - - if (self->isLeaf == 0) { - depth += 2; - if (r != 0) - fprintf(self->dumper.out, " call codes_get(ibufr, '#%d#%s', sVal)\n", r, a->name_); - else - fprintf(self->dumper.out, " call codes_get(ibufr, '%s', sVal)\n", a->name_); - } - /*fprintf(self->dumper.out,"\'%s\')\n",value);*/ - - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void _dump_long_array(grib_handle* h, FILE* f, const char* key) -{ - size_t size = 0; - if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) - return; - if (size == 0) - return; - - fprintf(f, " if(allocated(iValues)) deallocate(iValues)\n"); - fprintf(f, " call codes_get(ibufr, '%s', iValues)\n", key); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - if (strcmp(a->name_, "BUFR")==0 || - strcmp(a->name_, "GRIB")==0 || - strcmp(a->name_, "META")==0) { - grib_handle* h = grib_handle_of_accessor(a); - depth = 2; - self->empty = 1; - depth += 2; - _dump_long_array(h, self->dumper.out, "dataPresentIndicator"); - _dump_long_array(h, self->dumper.out, "delayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "shortDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "extendedDelayedDescriptorReplicationFactor"); - /* Do not show the inputOverriddenReferenceValues array. That's more for ENCODING */ - /* _dump_long_array(h,self->dumper.out,"inputOverriddenReferenceValues","inputOverriddenReferenceValues"); */ - grib_dump_accessors_block(d, block); - depth -= 2; - } - else if (strcmp(a->name_, "groupNumber")==0) { - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - self->empty = 1; - depth += 2; - grib_dump_accessors_block(d, block); - depth -= 2; - } - else { - grib_dump_accessors_block(d, block); - } -} - -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - int i = 0; - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - unsigned long flags; - while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { - self->isAttribute = 1; - if ((d->option_flags & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { - i++; - continue; - } - self->isLeaf = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; - flags = a->attributes_[i]->flags_; - a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; - switch (a->attributes_[i]->get_native_type()) { - case GRIB_TYPE_LONG: - dump_long_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_DOUBLE: - dump_values_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_STRING: - break; - } - a->attributes_[i]->flags_ = flags; - i++; - } - self->isLeaf = 0; - self->isAttribute = 0; -} - -static void header(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - - if (d->count < 2) { - /* This is the first message being processed */ - fprintf(self->dumper.out, "! This program was automatically generated with bufr_dump -Dfortran\n"); - fprintf(self->dumper.out, "! Using ecCodes version: "); - grib_print_api_version(self->dumper.out); - fprintf(self->dumper.out, "\n\n"); - fprintf(self->dumper.out, "program bufr_decode\n"); - fprintf(self->dumper.out, " use eccodes\n"); - fprintf(self->dumper.out, " implicit none\n"); - fprintf(self->dumper.out, " integer, parameter :: max_strsize = 200\n"); - fprintf(self->dumper.out, " integer :: iret\n"); - fprintf(self->dumper.out, " integer :: ifile\n"); - fprintf(self->dumper.out, " integer :: ibufr\n"); - fprintf(self->dumper.out, " integer(kind=4) :: iVal\n"); - fprintf(self->dumper.out, " real(kind=8) :: rVal\n"); - fprintf(self->dumper.out, " character(len=max_strsize) :: sVal\n"); - fprintf(self->dumper.out, " integer(kind=4), dimension(:), allocatable :: iValues\n"); - fprintf(self->dumper.out, " character(len=max_strsize) , dimension(:),allocatable :: sValues\n"); - fprintf(self->dumper.out, " real(kind=8), dimension(:), allocatable :: rValues\n\n"); - fprintf(self->dumper.out, " character(len=max_strsize) :: infile_name\n"); - fprintf(self->dumper.out, " call getarg(1, infile_name)\n"); - fprintf(self->dumper.out, " call codes_open_file(ifile, infile_name, 'r')\n\n"); - } - fprintf(self->dumper.out, " ! Message number %ld\n ! -----------------\n", d->count); - fprintf(self->dumper.out, " write(*,*) 'Decoding message number %ld'\n", d->count); - fprintf(self->dumper.out, " call codes_bufr_new_from_file(ifile, ibufr)\n"); - fprintf(self->dumper.out, " call codes_set(ibufr, 'unpack', 1)\n"); -} - -static void footer(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_decode_fortran* self = (grib_dumper_bufr_decode_fortran*)d; - /*fprintf(self->dumper.out," call codes_close_file(ifile)\n");*/ - fprintf(self->dumper.out, " call codes_release(ibufr)\n"); -} diff --git a/src/grib_dumper_class_bufr_decode_python.cc b/src/grib_dumper_class_bufr_decode_python.cc deleted file mode 100644 index 0ab837040..000000000 --- a/src/grib_dumper_class_bufr_decode_python.cc +++ /dev/null @@ -1,651 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - IMPLEMENTS = header;footer - MEMBERS = long section_offset - MEMBERS = long empty - MEMBERS = long end - MEMBERS = long isLeaf - MEMBERS = long isAttribute - MEMBERS = grib_string_list* keys - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); -static void header (grib_dumper*,grib_handle*); -static void footer (grib_dumper*,grib_handle*); - -typedef struct grib_dumper_bufr_decode_python { - grib_dumper dumper; - /* Members defined in bufr_decode_python */ - long section_offset; - long empty; - long end; - long isLeaf; - long isAttribute; - grib_string_list* keys; -} grib_dumper_bufr_decode_python; - - -static grib_dumper_class _grib_dumper_class_bufr_decode_python = { - 0, /* super */ - "bufr_decode_python", /* name */ - sizeof(grib_dumper_bufr_decode_python), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - &header, /* header */ - &footer, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_bufr_decode_python = &_grib_dumper_class_bufr_decode_python; - -/* END_CLASS_IMP */ -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix); - -static int depth = 0; - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - grib_context* c = d->context; - self->section_offset = 0; - self->empty = 1; - d->count = 1; - self->isLeaf = 0; - self->isAttribute = 0; - self->keys = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - grib_string_list* next = self->keys; - grib_string_list* cur = NULL; - grib_context* c = d->context; - while (next) { - cur = next; - next = next->next; - grib_context_free(c, cur->value); - grib_context_free(c, cur); - } - return GRIB_SUCCESS; -} - -static char* dval_to_string(const grib_context* c, double v) -{ - char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * 40); - snprintf(sval, 1024, "%.18e", v); - return sval; -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - double value = 0; - size_t size = 0; - int err = 0; - int r = 0; - long count = 0; - char* sval = NULL; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - - if (size <= 1) { - err = a->unpack_double(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - depth -= 2; - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " dVals = codes_get_array(ibufr, '#%d#%s')\n", r, a->name_); - else - fprintf(self->dumper.out, " dVals = codes_get_array(ibufr, '%s')\n", a->name_); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_double(a, value)) { - sval = dval_to_string(c, value); - if (r != 0) - fprintf(self->dumper.out, " dVal = codes_get(ibufr, '#%d#%s')\n", r, a->name_); - else - fprintf(self->dumper.out, " dVal = codes_get(ibufr, '%s')\n", a->name_); - - grib_context_free(c, sval); - } - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_values_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - double value = 0; - size_t size = 0; - int err = 0; - long count = 0; - char* sval; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - - if (size <= 1) { - err = a->unpack_double(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - depth -= 2; - fprintf(self->dumper.out, " dVals = codes_get_array(ibufr, '%s->%s')\n", prefix, a->name_); - } - else { - /* int r=compute_bufr_key_rank(h,self->keys,a->name_); */ - if (!grib_is_missing_double(a, value)) { - sval = dval_to_string(c, value); - fprintf(self->dumper.out, " dVal = codes_get(ibufr, '%s->%s')\n", prefix, a->name_); - - grib_context_free(c, sval); - } - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - long value = 0; - size_t size = 0; - int err = 0; - int r = 0; - long count = 0; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - a->value_count(&count); - size = count; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - return; - } - - if (size <= 1) { - err = a->unpack_long(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - depth -= 2; - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " iValues = codes_get_array(ibufr, '#%d#%s')\n", r, a->name_); - else - fprintf(self->dumper.out, " iValues = codes_get_array(ibufr, '%s')\n", a->name_); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_long(a, value)) { - if (r != 0) - fprintf(self->dumper.out, " iVal = codes_get(ibufr, '#%d#%s')\n", r, a->name_); - else - fprintf(self->dumper.out, " iVal = codes_get(ibufr, '%s')\n", a->name_); - } - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - (void)err; /* TODO */ -} - -static void dump_long_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - long value = 0; - size_t size = 0; - int err = 0; - long count = 0; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - - if (size <= 1) { - err = a->unpack_long(&value, &size); - } - - self->empty = 0; - - if (size > 1) { - depth -= 2; - fprintf(self->dumper.out, " iVals = codes_get_array(ibufr, '%s->%s')\n", prefix, a->name_); - } - else { - if (!codes_bufr_key_exclude_from_dump(prefix)) { - if (!grib_is_missing_long(a, value)) { - fprintf(self->dumper.out, " iVal = codes_get(ibufr, '%s->%s')\n", prefix, a->name_); - } - } - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - (void)err; /* TODO */ -} - -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) -{ - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - double value = 0; - size_t size = 1; - int r; - char* sval = NULL; - grib_handle* h = grib_handle_of_accessor(a); - grib_context* c = h->context; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->unpack_double(&value, &size); - self->empty = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_double(a, value)) { - sval = dval_to_string(c, value); - if (r != 0) - fprintf(self->dumper.out, " dVal = codes_get(ibufr, '#%d#%s')\n", r, a->name_); - else - fprintf(self->dumper.out, " dVal = codes_get(ibufr, '%s')\n", a->name_); - - grib_context_free(c, sval); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } -} - -static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - size_t size = 0; - grib_context* c = NULL; - int err = 0; - long count = 0; - int r = 0; - grib_handle* h = grib_handle_of_accessor(a); - - c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - if (size == 1) { - dump_string(d, a, comment); - return; - } - - self->empty = 0; - - if (self->isLeaf == 0) { - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " sVals = codes_get_string_array(ibufr, '#%d#%s')\n", r, a->name_); - else - fprintf(self->dumper.out, " sVals = codes_get_string_array(ibufr, '%s')\n", a->name_); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -#define MAX_STRING_SIZE 4096 -static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - char value[MAX_STRING_SIZE] = {0,}; /* See ECC-710 */ - char* p = NULL; - size_t size = MAX_STRING_SIZE; - grib_context* c = a->context_; - int r = 0, err = 0; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - self->empty = 0; - - err = a->unpack_string(value, &size); - p = value; - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (grib_is_missing_string(a, (unsigned char*)value, size)) { - return; - } - - while (*p) { - if (!isprint(*p)) - *p = '.'; - p++; - } - - if (self->isLeaf == 0) { - depth += 2; - if (r != 0) - fprintf(self->dumper.out, " sVal = codes_get(ibufr, '#%d#%s')\n", r, a->name_); - else - fprintf(self->dumper.out, " sVal = codes_get(ibufr, '%s')\n", a->name_); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void _dump_long_array(grib_handle* h, FILE* f, const char* key) -{ - size_t size = 0; - if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) - return; - if (size == 0) - return; - - fprintf(f, " iVals = codes_get_array(ibufr, '%s')\n", key); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - if (strcmp(a->name_, "BUFR")==0 || - strcmp(a->name_, "GRIB")==0 || - strcmp(a->name_, "META")==0) { - grib_handle* h = grib_handle_of_accessor(a); - depth = 2; - self->empty = 1; - depth += 2; - _dump_long_array(h, self->dumper.out, "dataPresentIndicator"); - _dump_long_array(h, self->dumper.out, "delayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "shortDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "extendedDelayedDescriptorReplicationFactor"); - /* Do not show the inputOverriddenReferenceValues array. That's more for ENCODING */ - /* _dump_long_array(h,self->dumper.out,"inputOverriddenReferenceValues","inputOverriddenReferenceValues"); */ - grib_dump_accessors_block(d, block); - depth -= 2; - } - else if (strcmp(a->name_, "groupNumber")==0) { - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - self->empty = 1; - depth += 2; - grib_dump_accessors_block(d, block); - depth -= 2; - } - else { - grib_dump_accessors_block(d, block); - } -} - -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - int i = 0; - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - unsigned long flags; - while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { - self->isAttribute = 1; - if ((d->option_flags & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { - i++; - continue; - } - self->isLeaf = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; - flags = a->attributes_[i]->flags_; - a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; - switch (a->attributes_[i]->get_native_type()) { - case GRIB_TYPE_LONG: - dump_long_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_DOUBLE: - dump_values_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_STRING: - break; - } - a->attributes_[i]->flags_ = flags; - i++; - } - self->isLeaf = 0; - self->isAttribute = 0; -} - -static void header(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - - if (d->count < 2) { - /* This is the first message being processed */ - fprintf(self->dumper.out, "# This program was automatically generated with bufr_dump -Dpython\n"); - fprintf(self->dumper.out, "# Using ecCodes version: "); - grib_print_api_version(self->dumper.out); - fprintf(self->dumper.out, "\n\n"); - fprintf(self->dumper.out, "import traceback\n"); - fprintf(self->dumper.out, "import sys\n"); - fprintf(self->dumper.out, "from eccodes import *\n\n\n"); - fprintf(self->dumper.out, "def bufr_decode(input_file):\n"); - fprintf(self->dumper.out, " f = open(input_file, 'rb')\n"); - } - fprintf(self->dumper.out, " # Message number %ld\n # -----------------\n", d->count); - fprintf(self->dumper.out, " print ('Decoding message number %ld')\n", d->count); - fprintf(self->dumper.out, " ibufr = codes_bufr_new_from_file(f)\n"); - fprintf(self->dumper.out, " codes_set(ibufr, 'unpack', 1)\n"); -} - -static void footer(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_decode_python* self = (grib_dumper_bufr_decode_python*)d; - fprintf(self->dumper.out, " codes_release(ibufr)\n"); -} diff --git a/src/grib_dumper_class_bufr_encode_C.cc b/src/grib_dumper_class_bufr_encode_C.cc deleted file mode 100644 index 7813ec140..000000000 --- a/src/grib_dumper_class_bufr_encode_C.cc +++ /dev/null @@ -1,932 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - IMPLEMENTS = header;footer - MEMBERS = long section_offset - MEMBERS = long empty - MEMBERS = long end - MEMBERS = long isLeaf - MEMBERS = long isAttribute - MEMBERS = grib_string_list* keys - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); -static void header (grib_dumper*,grib_handle*); -static void footer (grib_dumper*,grib_handle*); - -typedef struct grib_dumper_bufr_encode_C { - grib_dumper dumper; - /* Members defined in bufr_encode_C */ - long section_offset; - long empty; - long end; - long isLeaf; - long isAttribute; - grib_string_list* keys; -} grib_dumper_bufr_encode_C; - - -static grib_dumper_class _grib_dumper_class_bufr_encode_C = { - 0, /* super */ - "bufr_encode_C", /* name */ - sizeof(grib_dumper_bufr_encode_C), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - &header, /* header */ - &footer, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_bufr_encode_C = &_grib_dumper_class_bufr_encode_C; - -/* END_CLASS_IMP */ -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix); - -static int depth = 0; - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - - grib_context* c = d->context; - self->section_offset = 0; - self->empty = 1; - d->count = 1; - self->isLeaf = 0; - self->isAttribute = 0; - self->keys = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - grib_string_list* next = self->keys; - grib_string_list* cur = NULL; - grib_context* c = d->context; - while (next) { - cur = next; - next = next->next; - grib_context_free(c, cur->value); - grib_context_free(c, cur); - } - return GRIB_SUCCESS; -} - -static char* lval_to_string(grib_context* c, long v) -{ - const size_t svalMaxLen = 40; - char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * svalMaxLen); - if (v == GRIB_MISSING_LONG) - snprintf(sval, svalMaxLen, "CODES_MISSING_LONG"); - else - snprintf(sval, svalMaxLen, "%ld", v); - return sval; -} -static char* dval_to_string(grib_context* c, double v) -{ - const size_t svalMaxLen = 40; - char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * svalMaxLen); - if (v == GRIB_MISSING_DOUBLE) - snprintf(sval, svalMaxLen, "CODES_MISSING_DOUBLE"); - else - snprintf(sval, svalMaxLen, "%.18e", v); - return sval; -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - - double value = 0; - size_t size = 0, size2 = 0; - double* values = NULL; - int err = 0; - int i, r, icount; - int cols = 2; - long count = 0; - char* sval; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); - err = a->unpack_double(values, &size2); - } - else { - err = a->unpack_double(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, " free(rvalues); rvalues = NULL;\n\n"); - fprintf(self->dumper.out, " size = %lu;\n", (unsigned long)size); - fprintf(self->dumper.out, " rvalues = (double*)malloc(size * sizeof(double));\n"); - fprintf(self->dumper.out, " if (!rvalues) { fprintf(stderr, \"Failed to allocate memory (%s).\\n\"); return 1; }", a->name_); - - icount = 0; - for (i = 0; i < size - 1; ++i) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - sval = dval_to_string(c, values[i]); - fprintf(self->dumper.out, "rvalues[%d]=%s; ", i, sval); - grib_context_free(c, sval); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - sval = dval_to_string(c, values[i]); - fprintf(self->dumper.out, "rvalues[%d]=%s;", i, sval); - grib_context_free(c, sval); - - depth -= 2; - fprintf(self->dumper.out, "\n"); - grib_context_free(c, values); - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " CODES_CHECK(codes_set_double_array(h, \"#%d#%s\",rvalues, size), 0);\n", r, a->name_); - else - fprintf(self->dumper.out, " CODES_CHECK(codes_set_double_array(h, \"%s\", rvalues, size), 0);\n", a->name_); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - sval = dval_to_string(c, value); - if (r != 0) - fprintf(self->dumper.out, " CODES_CHECK(codes_set_double(h, \"#%d#%s\", %s), 0);\n", r, a->name_, sval); - else - fprintf(self->dumper.out, " CODES_CHECK(codes_set_double(h, \"%s\", %s), 0);\n", a->name_, sval); - grib_context_free(c, sval); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - const size_t prefixMaxLen = strlen(a->name_) + 10; - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * prefixMaxLen); - dofree = 1; - snprintf(prefix, prefixMaxLen, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_values_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - - double value = 0; - size_t size = 0, size2 = 0; - double* values = NULL; - int err = 0; - int i, icount; - int cols = 2; - long count = 0; - char* sval; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); - err = a->unpack_double(values, &size2); - } - else { - err = a->unpack_double(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, " free(rvalues); rvalues = NULL;\n"); - fprintf(self->dumper.out, " size = %lu;\n", (unsigned long)size); - fprintf(self->dumper.out, " rvalues = (double*)malloc(size * sizeof(double));\n"); - fprintf(self->dumper.out, " if (!rvalues) { fprintf(stderr, \"Failed to allocate memory (%s).\\n\"); return 1; }", a->name_); - - icount = 0; - for (i = 0; i < size - 1; ++i) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - sval = dval_to_string(c, values[i]); - fprintf(self->dumper.out, "rvalues[%d]=%s; ", i, sval); - grib_context_free(c, sval); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - sval = dval_to_string(c, values[i]); - fprintf(self->dumper.out, "rvalues[%d]=%s;", i, sval); - grib_context_free(c, sval); - - depth -= 2; - fprintf(self->dumper.out, "\n"); - grib_context_free(c, values); - - fprintf(self->dumper.out, " CODES_CHECK(codes_set_double_array(h, \"%s->%s\", rvalues, size), 0);\n", prefix, a->name_); - } - else { - sval = dval_to_string(c, value); - fprintf(self->dumper.out, " CODES_CHECK(codes_set_double(h, \"%s->%s\", %s), 0);\n", prefix, a->name_, sval); - grib_context_free(c, sval); - } - - if (self->isLeaf == 0) { - const size_t prefix1MaxLen = strlen(a->name_) + strlen(prefix) + 5; - char* prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * prefix1MaxLen); - snprintf(prefix1, prefix1MaxLen, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static int is_hidden(grib_accessor* a) -{ - return ( (a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0 ); -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - - long value = 0; - size_t size = 0, size2 = 0; - long* values = NULL; - int err = 0; - int i, r, icount; - int cols = 4; - long count = 0; - char* sval = NULL; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - int doing_unexpandedDescriptors = 0; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { /* key does not have the dump attribute */ - int skip = 1; - /* See ECC-1107 */ - if (!is_hidden(a) && strcmp(a->name_, "messageLength") == 0) skip = 0; - if (skip) return; - } - - doing_unexpandedDescriptors = (strcmp(a->name_, "unexpandedDescriptors") == 0); - a->value_count(&count); - size = size2 = count; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (r != 0) { - const size_t prefixMaxLen = strlen(a->name_) + 10; - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * prefixMaxLen); - dofree = 1; - snprintf(prefix, prefixMaxLen, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - return; - } - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size2); - } - else { - err = a->unpack_long(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, " free(ivalues); ivalues = NULL;\n\n"); - fprintf(self->dumper.out, " size = %lu;\n", (unsigned long)size); - fprintf(self->dumper.out, " ivalues = (long*)malloc(size * sizeof(long));\n"); - fprintf(self->dumper.out, " if (!ivalues) { fprintf(stderr, \"Failed to allocate memory (%s).\\n\"); return 1; }", a->name_); - - icount = 0; - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - fprintf(self->dumper.out, "ivalues[%d]=%ld; ", i, values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - fprintf(self->dumper.out, "ivalues[%d]=%ld;", i, values[i]); - - depth -= 2; - fprintf(self->dumper.out, "\n"); - grib_context_free(a->context_, values); - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) { - fprintf(self->dumper.out, " CODES_CHECK(codes_set_long_array(h, \"#%d#%s\", ivalues, size), 0);\n", r, a->name_); - } - else { - if (doing_unexpandedDescriptors) { - fprintf(self->dumper.out, "\n /* Create the structure of the data section */\n"); - /* fprintf(self->dumper.out," CODES_CHECK(codes_set_long(h, \"skipExtraKeyAttributes\", 1), 0);\n"); */ - } - fprintf(self->dumper.out, " CODES_CHECK(codes_set_long_array(h, \"%s\", ivalues, size), 0);\n", a->name_); - if (doing_unexpandedDescriptors) - fprintf(self->dumper.out, "\n"); - } - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - sval = lval_to_string(c, value); - if (r != 0) { - fprintf(self->dumper.out, " CODES_CHECK(codes_set_long(h, \"#%d#%s\", ", r, a->name_); - } - else { - if (doing_unexpandedDescriptors) { - fprintf(self->dumper.out, "\n /* Create the structure of the data section */\n"); - /* fprintf(self->dumper.out," CODES_CHECK(codes_set_long(h, \"skipExtraKeyAttributes\", 1), 0);\n"); */ - } - fprintf(self->dumper.out, " CODES_CHECK(codes_set_long(h, \"%s\", ", a->name_); - } - - fprintf(self->dumper.out, "%s), 0);\n", sval); - grib_context_free(c, sval); - if (doing_unexpandedDescriptors) - fprintf(self->dumper.out, "\n"); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - const size_t prefixMaxLen = strlen(a->name_) + 10; - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * prefixMaxLen); - dofree = 1; - snprintf(prefix, prefixMaxLen, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - (void)err; /* TODO */ -} - -static void dump_long_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - - long value = 0; - size_t size = 0, size2 = 0; - long* values = NULL; - int err = 0; - int i, icount; - int cols = 4; - long count = 0; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size2); - } - else { - err = a->unpack_long(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, " free(ivalues); ivalues = NULL;\n"); - fprintf(self->dumper.out, " size = %lu;\n", (unsigned long)size); - fprintf(self->dumper.out, " ivalues = (long*)malloc(size * sizeof(long));\n"); - fprintf(self->dumper.out, " if (!ivalues) { fprintf(stderr, \"Failed to allocate memory (%s).\\n\"); return 1; }", a->name_); - - icount = 0; - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - fprintf(self->dumper.out, "ivalues[%d]=%ld; ", i, values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - fprintf(self->dumper.out, "ivalues[%d]=%ld;", i, values[i]); - - depth -= 2; - fprintf(self->dumper.out, "\n"); - grib_context_free(a->context_, values); - - fprintf(self->dumper.out, " CODES_CHECK(codes_set_long_array(h, \"%s->%s\", ivalues, size), 0);\n", prefix, a->name_); - } - else { - if (!codes_bufr_key_exclude_from_dump(prefix)) { - char* sval = lval_to_string(c, value); - fprintf(self->dumper.out, " CODES_CHECK(codes_set_long(h, \"%s->%s\", ", prefix, a->name_); - fprintf(self->dumper.out, "%s), 0);\n", sval); - grib_context_free(c, sval); - } - } - - if (self->isLeaf == 0) { - const size_t prefix1MaxLen = strlen(a->name_) + strlen(prefix) + 5; - char* prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * prefix1MaxLen); - snprintf(prefix1, prefix1MaxLen, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - (void)err; /* TODO */ -} - -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) -{ - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - - double value = 0; - size_t size = 1; - int r; - char* sval; - grib_handle* h = grib_handle_of_accessor(a); - grib_context* c = h->context; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->unpack_double(&value, &size); - self->empty = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - - sval = dval_to_string(c, value); - if (r != 0) - fprintf(self->dumper.out, " CODES_CHECK(codes_set_double(h, \"#%d#%s\", %s), 0);\n", r, a->name_, sval); - else - fprintf(self->dumper.out, " CODES_CHECK(codes_set_double(h, \"%s\", %s), 0);\n", a->name_, sval); - grib_context_free(c, sval); - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - const size_t prefixMaxLen = strlen(a->name_) + 10; - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * prefixMaxLen); - dofree = 1; - snprintf(prefix, prefixMaxLen, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } -} - -static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - char** values; - size_t size = 0, i = 0; - grib_context* c = a->context_; - int err = 0; - long count = 0; - int r = 0; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - if (size == 1) { - dump_string(d, a, comment); - return; - } - - fprintf(self->dumper.out, " free(svalues);\n"); - fprintf(self->dumper.out, " size = %lu;\n", (unsigned long)size); - fprintf(self->dumper.out, " svalues = (char**)malloc(size * sizeof(char*));\n"); - fprintf(self->dumper.out, " if (!svalues) { fprintf(stderr, \"Failed to allocate memory (%s).\\n\"); return 1; }\n", a->name_); - - self->empty = 0; - values = (char**)grib_context_malloc_clear(c, size * sizeof(char*)); - if (!values) { - grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); - return; - } - - err = a->unpack_string_array(values, &size); - for (i = 0; i < size - 1; i++) { - fprintf(self->dumper.out, " svalues[%lu]=\"%s\"; \n", (unsigned long)i, values[i]); - } - fprintf(self->dumper.out, " svalues[%lu]=\"%s\";\n", (unsigned long)i, values[i]); - - if (self->isLeaf == 0) { - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " codes_set_string_array(h, \"#%d#%s\", (const char **)svalues, size);\n", r, a->name_); - else - fprintf(self->dumper.out, " codes_set_string_array(h, \"%s\", (const char **)svalues, size);\n", a->name_); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - const size_t prefixMaxLen = strlen(a->name_) + 10; - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * prefixMaxLen); - dofree = 1; - snprintf(prefix, prefixMaxLen, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - for (i = 0; i < size; i++) grib_context_free(c, values[i]); - grib_context_free(c, values); - (void)err; /* TODO */ -} - -static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - - char* value = NULL; - char* p = NULL; - size_t size = 0; - grib_context* c = a->context_; - int r = 0, err = 0; - grib_handle* h = grib_handle_of_accessor(a); - const char* acc_name = a->name_; - - grib_get_string_length_acc(a, &size); - if (size == 0) - return; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - value = (char*)grib_context_malloc_clear(c, size); - if (!value) { - grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); - return; - } - - self->empty = 0; - - err = a->unpack_string(value, &size); - p = value; - r = compute_bufr_key_rank(h, self->keys, acc_name); - if (grib_is_missing_string(a, (unsigned char*)value, size)) { - strcpy(value, ""); /* Empty string means MISSING string */ - } - - while (*p) { - if (!isprint(*p)) - *p = '?'; - if (*p == '"') - *p = '\''; /* ECC-1401 */ - p++; - } - - fprintf(self->dumper.out, " size = %lu;\n", (unsigned long)size); - if (self->isLeaf == 0) { - depth += 2; - if (r != 0) - fprintf(self->dumper.out, " codes_set_string(h, \"#%d#%s\", ", r, acc_name); - else - fprintf(self->dumper.out, " codes_set_string(h, \"%s\", ", acc_name); - } - fprintf(self->dumper.out, "\"%s\", &size);\n", value); - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - const size_t prefixMaxLen = strlen(acc_name) + 10; - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * prefixMaxLen); - dofree = 1; - snprintf(prefix, prefixMaxLen, "#%d#%s", r, acc_name); - } - else - prefix = (char*)acc_name; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - grib_context_free(c, value); - (void)err; /* TODO */ -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void _dump_long_array(grib_handle* h, FILE* f, const char* key, const char* print_key) -{ - long* val; - size_t size = 0, i; - int cols = 9, icount = 0; - - if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) - return; - if (size == 0) - return; - - fprintf(f, " free(ivalues); ivalues = NULL;\n"); - fprintf(f, " size = %lu;\n", (unsigned long)size); - fprintf(f, " ivalues = (long*)malloc(size * sizeof(long));\n"); - fprintf(f, " if (!ivalues) { fprintf(stderr, \"Failed to allocate memory (%s).\\n\"); return 1; }", key); - - val = (long*)grib_context_malloc_clear(h->context, sizeof(long) * size); - grib_get_long_array(h, key, val, &size); - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(f, "\n "); - icount = 0; - } - fprintf(f, "ivalues[%lu]=%ld; ", (unsigned long)i, val[i]); - icount++; - } - if (icount > cols) { - fprintf(f, "\n "); - } - fprintf(f, "ivalues[%lu]=%ld;\n", (unsigned long)(size - 1), val[size - 1]); - - grib_context_free(h->context, val); - fprintf(f, " CODES_CHECK(codes_set_long_array(h, \"%s\", ivalues, size), 0);\n", print_key); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - if (strcmp(a->name_, "BUFR")==0 || - strcmp(a->name_, "GRIB")==0 || - strcmp(a->name_, "META")==0) { - grib_handle* h = grib_handle_of_accessor(a); - depth = 2; - self->empty = 1; - depth += 2; - _dump_long_array(h, self->dumper.out, "dataPresentIndicator", "inputDataPresentIndicator"); - _dump_long_array(h, self->dumper.out, "delayedDescriptorReplicationFactor", "inputDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "shortDelayedDescriptorReplicationFactor", "inputShortDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "extendedDelayedDescriptorReplicationFactor", "inputExtendedDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "inputOverriddenReferenceValues", "inputOverriddenReferenceValues"); - grib_dump_accessors_block(d, block); - depth -= 2; - } - else if (strcmp(a->name_, "groupNumber")==0) { - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - self->empty = 1; - depth += 2; - grib_dump_accessors_block(d, block); - depth -= 2; - } - else { - grib_dump_accessors_block(d, block); - } -} - -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - int i = 0; - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - unsigned long flags; - while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { - self->isAttribute = 1; - if ((d->option_flags & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { - i++; - continue; - } - self->isLeaf = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; - flags = a->attributes_[i]->flags_; - a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; - switch (a->attributes_[i]->get_native_type()) { - case GRIB_TYPE_LONG: - dump_long_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_DOUBLE: - dump_values_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_STRING: - break; - } - a->attributes_[i]->flags_ = flags; - i++; - } - self->isLeaf = 0; - self->isAttribute = 0; -} - -static void header(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - char sampleName[200] = { 0 }; - long localSectionPresent, edition, bufrHeaderCentre, isSatellite; - - Assert(h->product_kind == PRODUCT_BUFR); - - grib_get_long(h, "localSectionPresent", &localSectionPresent); - grib_get_long(h, "bufrHeaderCentre", &bufrHeaderCentre); - grib_get_long(h, "edition", &edition); - - if (localSectionPresent && bufrHeaderCentre == 98) { - grib_get_long(h, "isSatellite", &isSatellite); - if (isSatellite) - snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local_satellite", edition); - else - snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local", edition); - } - else { - snprintf(sampleName, sizeof(sampleName), "BUFR%ld", edition); - } - - if (d->count < 2) { - fprintf(self->dumper.out, "/* This program was automatically generated with bufr_dump -EC */\n"); - fprintf(self->dumper.out, "/* Using ecCodes version: "); - grib_print_api_version(self->dumper.out); - fprintf(self->dumper.out, " */\n\n"); - fprintf(self->dumper.out, "#include \"eccodes.h\"\n"); - fprintf(self->dumper.out, "int main()\n"); - fprintf(self->dumper.out, "{\n"); - fprintf(self->dumper.out, " size_t size=0;\n"); - fprintf(self->dumper.out, " const void* buffer = NULL;\n"); - fprintf(self->dumper.out, " FILE* fout = NULL;\n"); - fprintf(self->dumper.out, " codes_handle* h = NULL;\n"); - fprintf(self->dumper.out, " long* ivalues = NULL;\n"); - fprintf(self->dumper.out, " char** svalues = NULL;\n"); - fprintf(self->dumper.out, " double* rvalues = NULL;\n"); - fprintf(self->dumper.out, " const char* sampleName = \"%s\";\n\n", sampleName); - } - - fprintf(self->dumper.out, " h = codes_bufr_handle_new_from_samples(NULL, sampleName);\n"); - fprintf(self->dumper.out, " if (h == NULL) {\n"); - fprintf(self->dumper.out, " fprintf(stderr, \"ERROR: Failed to create BUFR from %%s\\n\", sampleName);\n"); - fprintf(self->dumper.out, " return 1;\n"); - fprintf(self->dumper.out, " }\n"); -} - -static void footer(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_encode_C* self = (grib_dumper_bufr_encode_C*)d; - fprintf(self->dumper.out, "\n /* Encode the keys back in the data section */\n"); - fprintf(self->dumper.out, " CODES_CHECK(codes_set_long(h, \"pack\", 1), 0);\n\n"); - if (d->count == 1) - fprintf(self->dumper.out, " fout = fopen(\"outfile.bufr\", \"w\");\n"); - else - fprintf(self->dumper.out, " fout = fopen(\"outfile.bufr\", \"a\");\n"); - - /*fprintf(self->dumper.out," fout = fopen(\"outfile.bufr\", \"w\");");*/ - fprintf(self->dumper.out, " if (!fout) {\n"); - fprintf(self->dumper.out, " fprintf(stderr, \"ERROR: Failed to open output file 'outfile.bufr' for writing.\\n\");\n"); - fprintf(self->dumper.out, " return 1;\n"); - fprintf(self->dumper.out, " }\n"); - fprintf(self->dumper.out, " CODES_CHECK(codes_get_message(h,&buffer,&size),0);\n"); - fprintf(self->dumper.out, " if (fwrite(buffer,1,size,fout) != size) {\n"); - fprintf(self->dumper.out, " fprintf(stderr, \"ERROR: Failed to write data.\\n\");\n"); - fprintf(self->dumper.out, " return 1;\n"); - fprintf(self->dumper.out, " }\n"); - fprintf(self->dumper.out, " if (fclose(fout)!=0) {\n"); - fprintf(self->dumper.out, " fprintf(stderr, \"ERROR: Failed to close output file handle.\\n\");\n"); - fprintf(self->dumper.out, " return 1;\n"); - fprintf(self->dumper.out, " }\n"); - fprintf(self->dumper.out, " \n"); - fprintf(self->dumper.out, " codes_handle_delete(h);\n"); - if (d->count == 1) - fprintf(self->dumper.out, " printf(\"Created output BUFR file 'outfile.bufr'.\\n\");\n"); - fprintf(self->dumper.out, " free(ivalues); ivalues = NULL;\n"); - fprintf(self->dumper.out, " free(rvalues); rvalues = NULL;\n"); - fprintf(self->dumper.out, " free(svalues); svalues = NULL;\n\n"); -} diff --git a/src/grib_dumper_class_bufr_encode_filter.cc b/src/grib_dumper_class_bufr_encode_filter.cc deleted file mode 100644 index 6ccee0088..000000000 --- a/src/grib_dumper_class_bufr_encode_filter.cc +++ /dev/null @@ -1,803 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - IMPLEMENTS = header - MEMBERS = long section_offset - MEMBERS = long begin - MEMBERS = long empty - MEMBERS = long end - MEMBERS = long isLeaf - MEMBERS = long isAttribute - MEMBERS = grib_string_list* keys - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); -static void header (grib_dumper*,grib_handle*); - -typedef struct grib_dumper_bufr_encode_filter { - grib_dumper dumper; - /* Members defined in bufr_encode_filter */ - long section_offset; - long begin; - long empty; - long end; - long isLeaf; - long isAttribute; - grib_string_list* keys; -} grib_dumper_bufr_encode_filter; - - -static grib_dumper_class _grib_dumper_class_bufr_encode_filter = { - 0, /* super */ - "bufr_encode_filter", /* name */ - sizeof(grib_dumper_bufr_encode_filter), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - &header, /* header */ - 0, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_bufr_encode_filter = &_grib_dumper_class_bufr_encode_filter; - -/* END_CLASS_IMP */ -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix); - -static int depth = 0; - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_bufr_encode_filter* self = (grib_dumper_bufr_encode_filter*)d; - grib_context* c = d->context; - self->section_offset = 0; - self->empty = 1; - self->isLeaf = 0; - self->isAttribute = 0; - self->keys = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - grib_dumper_bufr_encode_filter* self = (grib_dumper_bufr_encode_filter*)d; - grib_string_list* next = self->keys; - grib_string_list* cur = NULL; - grib_context* c = d->context; - while (next) { - cur = next; - next = next->next; - grib_context_free(c, cur->value); - grib_context_free(c, cur); - } - return GRIB_SUCCESS; -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_bufr_encode_filter* self = (grib_dumper_bufr_encode_filter*)d; - double value = 0; - size_t size = 0, size2 = 0; - double* values = NULL; - int err = 0; - int i, r; - int cols = 9; - long count = 0; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); - err = a->unpack_double(values, &size2); - } - else { - err = a->unpack_double(&value, &size2); - } - Assert(size2 == size); - - self->begin = 0; - self->empty = 0; - - if (size > 1) { - int icount = 0; - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, "set #%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "set %s=", a->name_); - - fprintf(self->dumper.out, "{"); - - for (i = 0; i < size - 1; ++i) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - fprintf(self->dumper.out, "%.18e, ", values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - fprintf(self->dumper.out, "%.18e", values[i]); - - depth -= 2; - fprintf(self->dumper.out, "};\n"); - grib_context_free(c, values); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_double(a, value)) { - if (r != 0) - fprintf(self->dumper.out, "set #%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "set %s=", a->name_); - - fprintf(self->dumper.out, "%.18e;\n", value); - } - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_values_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_encode_filter* self = (grib_dumper_bufr_encode_filter*)d; - double value = 0; - size_t size = 0, size2 = 0; - double* values = NULL; - int err = 0; - int i, icount; - int cols = 2; - long count = 0; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); - err = a->unpack_double(values, &size2); - } - else { - err = a->unpack_double(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, "set %s->%s = {", prefix, a->name_); - icount = 0; - for (i = 0; i < size - 1; ++i) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - fprintf(self->dumper.out, "%.18e, ", values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - fprintf(self->dumper.out, "%.18e", values[i]); - - depth -= 2; - fprintf(self->dumper.out, "};\n"); - grib_context_free(c, values); - } - else { - /* int r=compute_bufr_key_rank(h,self->keys,a->name_); */ - if (!grib_is_missing_double(a, value)) { - fprintf(self->dumper.out, "set %s->%s = %.18e;\n", prefix, a->name_, value); - } - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_encode_filter* self = (grib_dumper_bufr_encode_filter*)d; - long value = 0; - size_t size = 0, size2 = 0; - long* values = NULL; - int err = 0; - int i, r, icount; - int cols = 9; - long count = 0; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - a->value_count(&count); - size = size2 = count; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - return; - } - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size2); - } - else { - err = a->unpack_long(&value, &size2); - } - Assert(size2 == size); - - self->begin = 0; - self->empty = 0; - - if (size > 1) { - icount = 0; - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, "set #%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "set %s=", a->name_); - - fprintf(self->dumper.out, "{"); - - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - fprintf(self->dumper.out, "%ld, ", values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - fprintf(self->dumper.out, "%ld ", values[i]); - - depth -= 2; - fprintf(self->dumper.out, "};\n"); - grib_context_free(a->context_, values); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_long(a, value)) { - if (r != 0) - fprintf(self->dumper.out, "set #%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "set %s=", a->name_); - - fprintf(self->dumper.out, "%ld;\n", value); - } - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - (void)err; /* TODO */ -} - -static void dump_long_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_encode_filter* self = (grib_dumper_bufr_encode_filter*)d; - long value = 0; - size_t size = 0, size2 = 0; - long* values = NULL; - int err = 0; - int i, icount; - int cols = 4; - long count = 0; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size2); - } - else { - err = a->unpack_long(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, "set %s->%s = {", prefix, a->name_); - icount = 0; - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - fprintf(self->dumper.out, "%ld, ", values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - fprintf(self->dumper.out, "%ld ", values[i]); - depth -= 2; - fprintf(self->dumper.out, "};\n"); - grib_context_free(a->context_, values); - } - else { - /* int r=compute_bufr_key_rank(h,self->keys,a->name_); */ - if (!codes_bufr_key_exclude_from_dump(prefix)) { - if (!grib_is_missing_long(a, value)) { - fprintf(self->dumper.out, "set %s->%s = ", prefix, a->name_); - fprintf(self->dumper.out, "%ld ;\n", value); - } - } - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - (void)err; /* TODO */ -} - -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) -{ - grib_dumper_bufr_encode_filter* self = (grib_dumper_bufr_encode_filter*)d; - double value = 0; - size_t size = 1; - int r; - grib_handle* h = grib_handle_of_accessor(a); - grib_context* c = h->context; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->unpack_double(&value, &size); - self->begin = 0; - self->empty = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (!grib_is_missing_double(a, value)) { - if (r != 0) - fprintf(self->dumper.out, "set #%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "set %s=", a->name_); - - fprintf(self->dumper.out, "%.18e;\n", value); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } -} - -static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_encode_filter* self = (grib_dumper_bufr_encode_filter*)d; - char** values = NULL; - size_t size = 0, i = 0; - grib_context* c = NULL; - int err = 0; - long count = 0; - int r = 0; - grib_handle* h = grib_handle_of_accessor(a); - - c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - if (size == 1) { - dump_string(d, a, comment); - return; - } - - self->begin = 0; - - if (self->isLeaf == 0) { - depth += 2; - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, "set #%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "set %s=", a->name_); - } - - self->empty = 0; - - 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); - - fprintf(self->dumper.out, "{"); - depth += 2; - for (i = 0; i < size - 1; i++) { - fprintf(self->dumper.out, " \"%s\",\n", values[i]); - } - fprintf(self->dumper.out, " \"%s\"\n", values[i]); - - depth -= 2; - - fprintf(self->dumper.out, "};\n"); - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - for (i=0; icontext_; - int r = 0, err = 0; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - grib_get_string_length_acc(a, &size); - if (size == 0) - return; - - value = (char*)grib_context_malloc_clear(c, size); - if (!value) { - grib_context_log(c, GRIB_LOG_ERROR, "unable to allocate %zu bytes", size); - return; - } - - self->begin = 0; - self->empty = 0; - - err = a->unpack_string(value, &size); - p = value; - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (grib_is_missing_string(a, (unsigned char*)value, size)) { - strcpy(value, ""); /* Empty string means MISSING string */ - } - - while (*p) { - if (!isprint(*p)) - *p = '?'; - if (*p == '"') - *p = '\''; /* ECC-1401 */ - p++; - } - - if (self->isLeaf == 0) { - depth += 2; - if (r != 0) - fprintf(self->dumper.out, "set #%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "set %s=", a->name_); - } - fprintf(self->dumper.out, "\"%s\";\n", value); - - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - grib_context_free(c, value); - (void)err; /* TODO */ -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void _dump_long_array(grib_handle* h, FILE* f, const char* key, const char* print_key) -{ - long* val; - size_t size = 0, i; - int cols = 9, icount = 0; - - if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) - return; - if (size == 0) - return; - - val = (long*)grib_context_malloc_clear(h->context, sizeof(long) * size); - grib_get_long_array(h, key, val, &size); - fprintf(f, "set %s= {", print_key); - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(f, "\n "); - icount = 0; - } - fprintf(f, "%ld, ", val[i]); - icount++; - } - if (icount > cols) { - fprintf(f, "\n "); - } - fprintf(f, "%ld};\n", val[size - 1]); - - grib_context_free(h->context, val); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_bufr_encode_filter* self = (grib_dumper_bufr_encode_filter*)d; - if (strcmp(a->name_, "BUFR")==0 || - strcmp(a->name_, "GRIB")==0 || - strcmp(a->name_, "META")==0) { - grib_handle* h = grib_handle_of_accessor(a); - depth = 2; - self->begin = 1; - self->empty = 1; - depth += 2; - _dump_long_array(h, self->dumper.out, "dataPresentIndicator", "inputDataPresentIndicator"); - _dump_long_array(h, self->dumper.out, "delayedDescriptorReplicationFactor", "inputDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "shortDelayedDescriptorReplicationFactor", "inputShortDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "extendedDelayedDescriptorReplicationFactor", "inputExtendedDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "inputOverriddenReferenceValues", "inputOverriddenReferenceValues"); - grib_dump_accessors_block(d, block); - depth -= 2; - } - else if (strcmp(a->name_, "groupNumber")==0) { - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - self->begin = 1; - self->empty = 1; - depth += 2; - grib_dump_accessors_block(d, block); - depth -= 2; - } - else { - grib_dump_accessors_block(d, block); - } -} - -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - int i = 0; - grib_dumper_bufr_encode_filter* self = (grib_dumper_bufr_encode_filter*)d; - unsigned long flags; - while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { - self->isAttribute = 1; - if ((d->option_flags & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { - i++; - continue; - } - self->isLeaf = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; - /* fprintf(self->dumper.out,","); */ - /* fprintf(self->dumper.out,"\n%-*s",depth," "); */ - /* fprintf(out,"\"%s\" : ",a->attributes_[i]->name); */ - flags = a->attributes_[i]->flags_; - a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; - switch (a->attributes_[i]->get_native_type()) { - case GRIB_TYPE_LONG: - dump_long_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_DOUBLE: - dump_values_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_STRING: - break; - } - a->attributes_[i]->flags_ = flags; - i++; - } - self->isLeaf = 0; - self->isAttribute = 0; -} - -static void header(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_encode_filter* self = (grib_dumper_bufr_encode_filter*)d; - char sampleName[128] = { 0 }; - long localSectionPresent, edition, bufrHeaderCentre, isSatellite; - - Assert(h->product_kind == PRODUCT_BUFR); - - grib_get_long(h, "localSectionPresent", &localSectionPresent); - grib_get_long(h, "bufrHeaderCentre", &bufrHeaderCentre); - grib_get_long(h, "edition", &edition); - - if (localSectionPresent && bufrHeaderCentre == 98) { - grib_get_long(h, "isSatellite", &isSatellite); - if (isSatellite) - snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local_satellite", edition); - else - snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local", edition); - } - else { - snprintf(sampleName, sizeof(sampleName), "BUFR%ld", edition); - } - - fprintf(self->dumper.out, "# BUFR sample file: %s.tmpl\n", sampleName); -} diff --git a/src/grib_dumper_class_bufr_encode_fortran.cc b/src/grib_dumper_class_bufr_encode_fortran.cc deleted file mode 100644 index 5c3004696..000000000 --- a/src/grib_dumper_class_bufr_encode_fortran.cc +++ /dev/null @@ -1,962 +0,0 @@ -/* - * (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" -#include - -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - IMPLEMENTS = header;footer - MEMBERS = long section_offset - MEMBERS = long empty - MEMBERS = long end - MEMBERS = long isLeaf - MEMBERS = long isAttribute - MEMBERS = grib_string_list* keys - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); -static void header (grib_dumper*,grib_handle*); -static void footer (grib_dumper*,grib_handle*); - -typedef struct grib_dumper_bufr_encode_fortran { - grib_dumper dumper; - /* Members defined in bufr_encode_fortran */ - long section_offset; - long empty; - long end; - long isLeaf; - long isAttribute; - grib_string_list* keys; -} grib_dumper_bufr_encode_fortran; - - -static grib_dumper_class _grib_dumper_class_bufr_encode_fortran = { - 0, /* super */ - "bufr_encode_fortran", /* name */ - sizeof(grib_dumper_bufr_encode_fortran), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - &header, /* header */ - &footer, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_bufr_encode_fortran = &_grib_dumper_class_bufr_encode_fortran; - -/* END_CLASS_IMP */ -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix); - -static int depth = 0; - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_bufr_encode_fortran* self = (grib_dumper_bufr_encode_fortran*)d; - - grib_context* c = d->context; - self->section_offset = 0; - self->empty = 1; - d->count = 1; - self->isLeaf = 0; - self->isAttribute = 0; - self->keys = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - grib_dumper_bufr_encode_fortran* self = (grib_dumper_bufr_encode_fortran*)d; - - grib_string_list* next = self->keys; - grib_string_list* cur = NULL; - grib_context* c = d->context; - while (next) { - cur = next; - next = next->next; - grib_context_free(c, cur->value); - grib_context_free(c, cur); - } - return GRIB_SUCCESS; -} - -static char* lval_to_string(grib_context* c, long v) -{ - char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * 40); - if (v == GRIB_MISSING_LONG) - snprintf(sval, 1024, "CODES_MISSING_LONG"); - else - snprintf(sval, 1024, "%ld", v); - return sval; -} -static char* dval_to_string(grib_context* c, double v) -{ - char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * 40); - if (v == GRIB_MISSING_DOUBLE) { - snprintf(sval, 1024, "CODES_MISSING_DOUBLE"); - } - else { - char* p; - snprintf(sval, 1024, "%.18e", v); - p = sval; - while (*p != 0) { - if (*p == 'e') - *p = 'd'; - p++; - } - } - return sval; -} - -/* Some lines can grow longer than Fortran compilers allow (=132). */ -/* This is mainly due to long key names with attributes. */ -/* The resturn value of this function must be freed by the caller */ -static char* break_line(grib_context* c, const char* input) -{ - /* Break a long line using Fortran continuation characters */ - char* a_token = NULL; - char* lasts = NULL; - int first = 1; - const size_t len = strlen(input); - /* Add a bit more for inserted newlines and continuation characters */ - char* result = (char*)grib_context_malloc_clear(c, sizeof(char) * len + 100); - - /* No need to alter input which is already too short or has newlines */ - if (len < 70 || strchr(input, '\n')) { - strcpy(result, input); - return result; - } - - /* A Fortran multi-line string has two ampersands. E.g. */ - /* 'hello & - * &world' is the same as 'hello world' - */ - a_token = strtok_r((char*)input, "->", &lasts); - while (a_token) { - if (first) { - first = 0; - strcat(result, a_token); - } - else { - char tmp[256] = {0,}; - snprintf(tmp, sizeof(tmp), "->&\n &%s", a_token); - strcat(result, tmp); - } - a_token = strtok_r(NULL, "->", &lasts); - } - - return result; -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_bufr_encode_fortran* self = (grib_dumper_bufr_encode_fortran*)d; - - double value = 0; - size_t size = 0, size2 = 0; - double* values = NULL; - int err = 0; - int i, r, icount; - int cols = 2; - long count = 0; - char* sval; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); - err = a->unpack_double(values, &size2); - } - else { - err = a->unpack_double(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, " if(allocated(rvalues)) deallocate(rvalues)\n"); - fprintf(self->dumper.out, " allocate(rvalues(%lu))\n", (unsigned long)size); - - fprintf(self->dumper.out, " rvalues=(/"); - - icount = 0; - for (i = 0; i < size - 1; ++i) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, " &\n "); - icount = 0; - } - sval = dval_to_string(c, values[i]); - fprintf(self->dumper.out, "%s, ", sval); - grib_context_free(c, sval); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, " &\n "); - } - sval = dval_to_string(c, values[size - 1]); - fprintf(self->dumper.out, "%s", sval); - grib_context_free(c, sval); - - depth -= 2; - fprintf(self->dumper.out, "/)\n"); - grib_context_free(c, values); - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " call codes_set(ibufr,'#%d#%s',rvalues)\n", r, a->name_); - else - fprintf(self->dumper.out, " call codes_set(ibufr,'%s',rvalues)\n", a->name_); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - sval = dval_to_string(c, value); - if (r != 0) - fprintf(self->dumper.out, " call codes_set(ibufr,'#%d#%s',%s)\n", r, a->name_, sval); - else - fprintf(self->dumper.out, " call codes_set(ibufr,'%s',%s)\n", a->name_, sval); - grib_context_free(c, sval); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_values_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_encode_fortran* self = (grib_dumper_bufr_encode_fortran*)d; - - double value = 0; - size_t size = 0, size2 = 0; - double* values = NULL; - int err = 0; - int i, icount; - int cols = 2; - long count = 0; - char* sval; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); - err = a->unpack_double(values, &size2); - } - else { - err = a->unpack_double(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, " if(allocated(rvalues)) deallocate(rvalues)\n"); - fprintf(self->dumper.out, " allocate(rvalues(%lu))\n", (unsigned long)size); - - fprintf(self->dumper.out, " rvalues=(/"); - - icount = 0; - for (i = 0; i < size - 1; ++i) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, " &\n "); - icount = 0; - } - sval = dval_to_string(c, values[i]); - fprintf(self->dumper.out, "%s, ", sval); - grib_context_free(c, sval); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, " &\n "); - } - sval = dval_to_string(c, values[size - 1]); - fprintf(self->dumper.out, "%s", sval); - grib_context_free(c, sval); - - depth -= 2; - fprintf(self->dumper.out, "/)\n"); - grib_context_free(c, values); - - fprintf(self->dumper.out, " call codes_set(ibufr,'%s->%s' &\n,rvalues)\n", prefix, a->name_); - } - else { - sval = dval_to_string(c, value); - fprintf(self->dumper.out, " call codes_set(ibufr,'%s->%s' &\n,%s)\n", prefix, a->name_, sval); - grib_context_free(c, sval); - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static int is_hidden(grib_accessor* a) -{ - return ( (a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0 ); -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_encode_fortran* self = (grib_dumper_bufr_encode_fortran*)d; - - long value = 0; - size_t size = 0, size2 = 0; - long* values = NULL; - int err = 0; - int i, r, icount; - int cols = 4; - long count = 0; - char* sval = NULL; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - int doing_unexpandedDescriptors = 0; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { /* key does not have the dump attribute */ - int skip = 1; - /* See ECC-1107 */ - if (!is_hidden(a) && strcmp(a->name_, "messageLength") == 0) skip = 0; - if (skip) return; - } - - doing_unexpandedDescriptors = (strcmp(a->name_, "unexpandedDescriptors") == 0); - a->value_count(&count); - size = size2 = count; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - return; - } - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size2); - } - else { - err = a->unpack_long(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, " if(allocated(ivalues)) deallocate(ivalues)\n"); - fprintf(self->dumper.out, " allocate(ivalues(%lu))\n", (unsigned long)size); - - fprintf(self->dumper.out, " ivalues=(/"); - icount = 0; - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, " &\n "); - icount = 0; - } - fprintf(self->dumper.out, "%ld, ", values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, " &\n "); - } - fprintf(self->dumper.out, "%ld ", values[size - 1]); - - depth -= 2; - fprintf(self->dumper.out, "/)\n"); - grib_context_free(a->context_, values); - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) { - fprintf(self->dumper.out, " call codes_set(ibufr,'#%d#%s',ivalues)\n", r, a->name_); - } - else { - if (doing_unexpandedDescriptors) { - fprintf(self->dumper.out, "\n ! Create the structure of the data section\n"); - /* fprintf(self->dumper.out," call codes_set(ibufr,'skipExtraKeyAttributes',1)\n"); */ - } - fprintf(self->dumper.out, " call codes_set(ibufr,'%s',ivalues)\n", a->name_); - if (doing_unexpandedDescriptors) - fprintf(self->dumper.out, "\n"); - } - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - sval = lval_to_string(c, value); - if (r != 0) { - fprintf(self->dumper.out, " call codes_set(ibufr,'#%d#%s',", r, a->name_); - } - else { - if (doing_unexpandedDescriptors) { - fprintf(self->dumper.out, "\n ! Create the structure of the data section\n"); - /* fprintf(self->dumper.out," call codes_set(ibufr,'skipExtraKeyAttributes',1)\n"); */ - } - fprintf(self->dumper.out, " call codes_set(ibufr,'%s',", a->name_); - } - - fprintf(self->dumper.out, "%s)\n", sval); - grib_context_free(c, sval); - if (doing_unexpandedDescriptors) - fprintf(self->dumper.out, "\n"); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - (void)err; /* TODO */ -} - -static void dump_long_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_encode_fortran* self = (grib_dumper_bufr_encode_fortran*)d; - - long value = 0; - size_t size = 0, size2 = 0; - long* values = NULL; - int err = 0; - int i, icount; - int cols = 4; - long count = 0; - char* pref = NULL; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size2); - } - else { - err = a->unpack_long(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - /* Fortran standard specifies the maximum length of a free-form source line is 132 characters */ - /* Break long prefix string into multiple lines to avoid compiler error */ - pref = break_line(c, prefix); - - if (size > 1) { - fprintf(self->dumper.out, " if(allocated(ivalues)) deallocate(ivalues)\n"); - fprintf(self->dumper.out, " allocate(ivalues(%lu))\n", (unsigned long)size); - - fprintf(self->dumper.out, " ivalues=(/"); - icount = 0; - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, " &\n "); - icount = 0; - } - fprintf(self->dumper.out, "%ld, ", values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, " &\n "); - } - fprintf(self->dumper.out, "%ld ", values[size - 1]); - - depth -= 2; - fprintf(self->dumper.out, "/)\n"); - grib_context_free(a->context_, values); - - fprintf(self->dumper.out, " call codes_set(ibufr,'%s->%s' &\n,ivalues)\n", pref, a->name_); - } - else { - if (!codes_bufr_key_exclude_from_dump(prefix)) { - char* sval = lval_to_string(c, value); - fprintf(self->dumper.out, " call codes_set(ibufr,'%s->%s'&\n,", pref, a->name_); - fprintf(self->dumper.out, "%s)\n", sval); - grib_context_free(c, sval); - } - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(pref) + 5)); - snprintf(prefix1, 1024, "%s->%s", pref, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - grib_context_free(c, pref); - (void)err; /* TODO */ -} - -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) -{ - grib_dumper_bufr_encode_fortran* self = (grib_dumper_bufr_encode_fortran*)d; - - double value = 0; - size_t size = 1; - int r; - char* sval; - grib_handle* h = grib_handle_of_accessor(a); - grib_context* c = h->context; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->unpack_double(&value, &size); - self->empty = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - - sval = dval_to_string(c, value); - if (r != 0) - fprintf(self->dumper.out, " call codes_set(ibufr,'#%d#%s',%s)\n", r, a->name_, sval); - else - fprintf(self->dumper.out, " call codes_set(ibufr,'%s',%s)\n", a->name_, sval); - grib_context_free(c, sval); - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } -} - -static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_encode_fortran* self = (grib_dumper_bufr_encode_fortran*)d; - char** values; - size_t size = 0, i = 0; - grib_context* c = a->context_; - int err = 0; - long count = 0; - int r = 0; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - if (size == 1) { - dump_string(d, a, comment); - return; - } - - fprintf(self->dumper.out, " if(allocated(svalues)) deallocate(svalues)\n"); - fprintf(self->dumper.out, " allocate(svalues(%lu))\n", (unsigned long)size); - - fprintf(self->dumper.out, " svalues=(/"); - - self->empty = 0; - - 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); - - for (i = 0; i < size - 1; i++) { - fprintf(self->dumper.out, " \"%s\", &\n", values[i]); - } - fprintf(self->dumper.out, " \"%s\" /)\n", values[size - 1]); - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " call codes_set_string_array(ibufr,'#%d#%s',svalues)\n", r, a->name_); - else - fprintf(self->dumper.out, " call codes_set_string_array(ibufr,'%s',svalues)\n", a->name_); - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - for (i=0; icontext_; - int r; - int err = 0; - grib_handle* h = grib_handle_of_accessor(a); - const char* acc_name = a->name_; - - grib_get_string_length_acc(a, &size); - if (size == 0) - return; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - value = (char*)grib_context_malloc_clear(c, size); - if (!value) { - grib_context_log(c, GRIB_LOG_ERROR, "unable to allocate %zu bytes", size); - return; - } - - self->empty = 0; - - err = a->unpack_string(value, &size); - p = value; - r = compute_bufr_key_rank(h, self->keys, acc_name); - if (grib_is_missing_string(a, (unsigned char*)value, size)) { - strcpy(value, ""); /* Empty string means MISSING string */ - } - - while (*p) { - if (!isprint(*p)) - *p = '?'; - p++; - } - - if (self->isLeaf == 0) { - depth += 2; - if (r != 0) - fprintf(self->dumper.out, " call codes_set(ibufr,'#%d#%s',", r, acc_name); - else - fprintf(self->dumper.out, " call codes_set(ibufr,'%s',", acc_name); - } - fprintf(self->dumper.out, "\'%s\')\n", value); - - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(acc_name) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, acc_name); - } - else - prefix = (char*)acc_name; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - grib_context_free(c, value); - (void)err; /* TODO */ -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void _dump_long_array(grib_handle* h, FILE* f, const char* key, const char* print_key) -{ - long* val; - size_t size = 0, i; - int cols = 9, icount = 0; - - if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) - return; - if (size == 0) - return; - - fprintf(f, " if(allocated(ivalues)) deallocate(ivalues)\n"); - fprintf(f, " allocate(ivalues(%lu))\n", (unsigned long)size); - - fprintf(f, " ivalues=(/ "); - - val = (long*)grib_context_malloc_clear(h->context, sizeof(long) * size); - grib_get_long_array(h, key, val, &size); - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(f, " &\n "); - icount = 0; - } - fprintf(f, "%ld, ", val[i]); - icount++; - } - if (icount > cols) { - fprintf(f, " &\n "); - } - fprintf(f, "%ld /)\n", val[size - 1]); - - grib_context_free(h->context, val); - fprintf(f, " call codes_set(ibufr,'%s',ivalues)\n", print_key); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_bufr_encode_fortran* self = (grib_dumper_bufr_encode_fortran*)d; - if (strcmp(a->name_, "BUFR")==0 || - strcmp(a->name_, "GRIB")==0 || - strcmp(a->name_, "META")==0) { - grib_handle* h = grib_handle_of_accessor(a); - depth = 2; - self->empty = 1; - depth += 2; - _dump_long_array(h, self->dumper.out, "dataPresentIndicator", "inputDataPresentIndicator"); - _dump_long_array(h, self->dumper.out, "delayedDescriptorReplicationFactor", "inputDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "shortDelayedDescriptorReplicationFactor", "inputShortDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "extendedDelayedDescriptorReplicationFactor", "inputExtendedDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "inputOverriddenReferenceValues", "inputOverriddenReferenceValues"); - grib_dump_accessors_block(d, block); - depth -= 2; - } - else if (strcmp(a->name_, "groupNumber")==0) { - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - self->empty = 1; - depth += 2; - grib_dump_accessors_block(d, block); - depth -= 2; - } - else { - grib_dump_accessors_block(d, block); - } -} - -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - int i = 0; - grib_dumper_bufr_encode_fortran* self = (grib_dumper_bufr_encode_fortran*)d; - unsigned long flags; - while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { - self->isAttribute = 1; - if ((d->option_flags & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { - i++; - continue; - } - self->isLeaf = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; - flags = a->attributes_[i]->flags_; - a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; - switch (a->attributes_[i]->get_native_type()) { - case GRIB_TYPE_LONG: - dump_long_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_DOUBLE: - dump_values_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_STRING: - break; - } - a->attributes_[i]->flags_ = flags; - i++; - } - self->isLeaf = 0; - self->isAttribute = 0; -} - -static void header(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_encode_fortran* self = (grib_dumper_bufr_encode_fortran*)d; - char sampleName[200] = { 0 }; - long localSectionPresent, edition, bufrHeaderCentre, isSatellite; - - grib_get_long(h, "localSectionPresent", &localSectionPresent); - grib_get_long(h, "bufrHeaderCentre", &bufrHeaderCentre); - grib_get_long(h, "edition", &edition); - - if (localSectionPresent && bufrHeaderCentre == 98) { - grib_get_long(h, "isSatellite", &isSatellite); - if (isSatellite) - snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local_satellite", edition); - else - snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local", edition); - } - else { - snprintf(sampleName, sizeof(sampleName), "BUFR%ld", edition); - } - - if (d->count < 2) { - fprintf(self->dumper.out, "! This program was automatically generated with bufr_dump -Efortran\n"); - fprintf(self->dumper.out, "! Using ecCodes version: "); - grib_print_api_version(self->dumper.out); - fprintf(self->dumper.out, "\n\n"); - fprintf(self->dumper.out, "program bufr_encode\n"); - fprintf(self->dumper.out, " use eccodes\n"); - fprintf(self->dumper.out, " implicit none\n"); - fprintf(self->dumper.out, " integer :: iret\n"); - fprintf(self->dumper.out, " integer :: outfile\n"); - fprintf(self->dumper.out, " integer :: ibufr\n"); - fprintf(self->dumper.out, " integer(kind=4), dimension(:), allocatable :: ivalues\n"); - fprintf(self->dumper.out, " integer, parameter :: max_strsize = 100\n"); - fprintf(self->dumper.out, " character(len=max_strsize) , dimension(:),allocatable :: svalues\n"); - fprintf(self->dumper.out, " real(kind=8), dimension(:), allocatable :: rvalues\n"); - } - fprintf(self->dumper.out, " call codes_bufr_new_from_samples(ibufr,'%s',iret)\n", sampleName); - fprintf(self->dumper.out, " if (iret/=CODES_SUCCESS) then\n"); - fprintf(self->dumper.out, " print *,'ERROR: Failed to create BUFR from %s'\n", sampleName); - fprintf(self->dumper.out, " stop 1\n"); - fprintf(self->dumper.out, " endif\n"); -} - -static void footer(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_encode_fortran* self = (grib_dumper_bufr_encode_fortran*)d; - fprintf(self->dumper.out, "\n ! Encode the keys back in the data section\n"); - fprintf(self->dumper.out, " call codes_set(ibufr,'pack',1)\n\n"); - if (d->count == 1) - fprintf(self->dumper.out, " call codes_open_file(outfile,'outfile.bufr','w')\n"); - else - fprintf(self->dumper.out, " call codes_open_file(outfile,'outfile.bufr','a')\n"); - - fprintf(self->dumper.out, " call codes_write(ibufr,outfile)\n"); - fprintf(self->dumper.out, " call codes_close_file(outfile)\n"); - fprintf(self->dumper.out, " call codes_release(ibufr)\n"); - if (d->count == 1) - fprintf(self->dumper.out, " print *, \"Created output BUFR file 'outfile.bufr'\"\n"); - fprintf(self->dumper.out, " if(allocated(ivalues)) deallocate(ivalues)\n"); - fprintf(self->dumper.out, " if(allocated(rvalues)) deallocate(rvalues)\n"); - fprintf(self->dumper.out, " if(allocated(svalues)) deallocate(svalues)\n"); -} diff --git a/src/grib_dumper_class_bufr_encode_python.cc b/src/grib_dumper_class_bufr_encode_python.cc deleted file mode 100644 index 48494fb06..000000000 --- a/src/grib_dumper_class_bufr_encode_python.cc +++ /dev/null @@ -1,884 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - IMPLEMENTS = header;footer - MEMBERS = long section_offset - MEMBERS = long empty - MEMBERS = long end - MEMBERS = long isLeaf - MEMBERS = long isAttribute - MEMBERS = grib_string_list* keys - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); -static void header (grib_dumper*,grib_handle*); -static void footer (grib_dumper*,grib_handle*); - -typedef struct grib_dumper_bufr_encode_python { - grib_dumper dumper; - /* Members defined in bufr_encode_python */ - long section_offset; - long empty; - long end; - long isLeaf; - long isAttribute; - grib_string_list* keys; -} grib_dumper_bufr_encode_python; - - -static grib_dumper_class _grib_dumper_class_bufr_encode_python = { - 0, /* super */ - "bufr_encode_python", /* name */ - sizeof(grib_dumper_bufr_encode_python), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - &header, /* header */ - &footer, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_bufr_encode_python = &_grib_dumper_class_bufr_encode_python; - -/* END_CLASS_IMP */ -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix); - -static int depth = 0; - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_bufr_encode_python* self = (grib_dumper_bufr_encode_python*)d; - grib_context* c = d->context; - self->section_offset = 0; - self->empty = 1; - d->count = 1; - self->isLeaf = 0; - self->isAttribute = 0; - self->keys = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - grib_dumper_bufr_encode_python* self = (grib_dumper_bufr_encode_python*)d; - grib_string_list* next = self->keys; - grib_string_list* cur = NULL; - grib_context* c = d->context; - while (next) { - cur = next; - next = next->next; - grib_context_free(c, cur->value); - grib_context_free(c, cur); - } - return GRIB_SUCCESS; -} - -static char* lval_to_string(grib_context* c, long v) -{ - char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * 40); - if (v == GRIB_MISSING_LONG) - snprintf(sval, 1024, "CODES_MISSING_LONG"); - else - snprintf(sval, 1024, "%ld", v); - return sval; -} -static char* dval_to_string(const grib_context* c, double v) -{ - char* sval = (char*)grib_context_malloc_clear(c, sizeof(char) * 40); - if (v == GRIB_MISSING_DOUBLE) - snprintf(sval, 1024, "CODES_MISSING_DOUBLE"); - else - snprintf(sval, 1024, "%.18e", v); - return sval; -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_bufr_encode_python* self = (grib_dumper_bufr_encode_python*)d; - double value = 0; - size_t size = 0, size2 = 0; - double* values = NULL; - int err = 0; - int i, r, icount; - int cols = 2; - long count = 0; - char* sval; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); - err = a->unpack_double(values, &size2); - } - else { - err = a->unpack_double(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, " rvalues = ("); - - icount = 0; - for (i = 0; i < size - 1; ++i) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - sval = dval_to_string(c, values[i]); - fprintf(self->dumper.out, "%s, ", sval); - grib_context_free(c, sval); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - sval = dval_to_string(c, values[i]); - fprintf(self->dumper.out, "%s", sval); - grib_context_free(c, sval); - - depth -= 2; - /* Note: In Python to make a tuple with one element, you need the trailing comma */ - if (size > 4) - fprintf(self->dumper.out, ",) # %lu values\n", (unsigned long)size); - else - fprintf(self->dumper.out, ",)\n"); - grib_context_free(c, values); - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " codes_set_array(ibufr, '#%d#%s', rvalues)\n", r, a->name_); - else - fprintf(self->dumper.out, " codes_set_array(ibufr, '%s', rvalues)\n", a->name_); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - sval = dval_to_string(c, value); - if (r != 0) - fprintf(self->dumper.out, " codes_set(ibufr, '#%d#%s', %s)\n", r, a->name_, sval); - else - fprintf(self->dumper.out, " codes_set(ibufr, '%s', %s)\n", a->name_, sval); - grib_context_free(c, sval); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static void dump_values_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_encode_python* self = (grib_dumper_bufr_encode_python*)d; - double value = 0; - size_t size = 0, size2 = 0; - double* values = NULL; - int err = 0, i = 0, icount = 0; - int cols = 2; - long count = 0; - char* sval; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); - err = a->unpack_double(values, &size2); - } - else { - err = a->unpack_double(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, " rvalues = ("); - - icount = 0; - for (i = 0; i < size - 1; ++i) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - sval = dval_to_string(c, values[i]); - fprintf(self->dumper.out, "%s, ", sval); - grib_context_free(c, sval); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - sval = dval_to_string(c, values[i]); - fprintf(self->dumper.out, "%s", sval); - grib_context_free(c, sval); - - depth -= 2; - /* Note: In python to make a tuple with one element, you need the trailing comma */ - if (size > 4) - fprintf(self->dumper.out, ",) # %lu values\n", (unsigned long)size); - else - fprintf(self->dumper.out, ",)\n"); - grib_context_free(c, values); - - fprintf(self->dumper.out, " codes_set_array(ibufr, '%s->%s' \n, rvalues)\n", prefix, a->name_); - } - else { - sval = dval_to_string(c, value); - fprintf(self->dumper.out, " codes_set(ibufr, '%s->%s' \n,%s)\n", prefix, a->name_, sval); - grib_context_free(c, sval); - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - - (void)err; /* TODO */ -} - -static int is_hidden(grib_accessor* a) -{ - return ( (a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0 ); -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_encode_python* self = (grib_dumper_bufr_encode_python*)d; - long value = 0; - size_t size = 0, size2 = 0; - long* values = NULL; - int err = 0, i = 0, r = 0, icount = 0; - int cols = 4; - long count = 0; - char* sval = NULL; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - int doing_unexpandedDescriptors = 0; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { /* key does not have the dump attribute */ - int skip = 1; - /* See ECC-1107 */ - if (!is_hidden(a) && strcmp(a->name_, "messageLength") == 0) skip = 0; - if (skip) return; - } - - doing_unexpandedDescriptors = (strcmp(a->name_, "unexpandedDescriptors") == 0); - a->value_count(&count); - size = size2 = count; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - return; - } - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size2); - } - else { - err = a->unpack_long(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, " ivalues = ("); - icount = 0; - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - fprintf(self->dumper.out, "%ld, ", values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - fprintf(self->dumper.out, "%ld", values[i]); - - depth -= 2; - /* Note: In python to make a tuple with one element, you need the trailing comma */ - if (size > 4) - fprintf(self->dumper.out, ",) # %lu values\n", (unsigned long)size); - else - fprintf(self->dumper.out, ",)\n"); - grib_context_free(a->context_, values); - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) { - fprintf(self->dumper.out, " codes_set_array(ibufr, '#%d#%s', ivalues)\n", r, a->name_); - } - else { - if (doing_unexpandedDescriptors) { - fprintf(self->dumper.out, "\n # Create the structure of the data section\n"); - /* fprintf(self->dumper.out," codes_set(ibufr, 'skipExtraKeyAttributes', 1)\n"); */ - } - fprintf(self->dumper.out, " codes_set_array(ibufr, '%s', ivalues)\n", a->name_); - if (doing_unexpandedDescriptors) - fprintf(self->dumper.out, "\n"); - } - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - sval = lval_to_string(c, value); - if (r != 0) { - fprintf(self->dumper.out, " codes_set(ibufr, '#%d#%s', ", r, a->name_); - } - else { - if (doing_unexpandedDescriptors) { - fprintf(self->dumper.out, "\n # Create the structure of the data section\n"); - /* fprintf(self->dumper.out," codes_set(ibufr, 'skipExtraKeyAttributes', 1)\n"); */ - } - fprintf(self->dumper.out, " codes_set(ibufr, '%s', ", a->name_); - } - - fprintf(self->dumper.out, "%s)\n", sval); - grib_context_free(c, sval); - if (doing_unexpandedDescriptors) - fprintf(self->dumper.out, "\n"); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - (void)err; /* TODO */ -} - -static void dump_long_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_encode_python* self = (grib_dumper_bufr_encode_python*)d; - long value = 0; - size_t size = 0, size2 = 0; - long* values = NULL; - int err = 0, i = 0, icount = 0; - int cols = 4; - long count = 0; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size2); - } - else { - err = a->unpack_long(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, " ivalues = ("); - icount = 0; - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, " \n "); - icount = 0; - } - fprintf(self->dumper.out, "%ld, ", values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, " \n "); - } - fprintf(self->dumper.out, "%ld ", values[i]); - - depth -= 2; - /* Note: In python to make a tuple with one element, you need the trailing comma */ - if (size > 4) - fprintf(self->dumper.out, ",) # %lu values\n", (unsigned long)size); - else - fprintf(self->dumper.out, ",)\n"); - grib_context_free(a->context_, values); - - fprintf(self->dumper.out, " codes_set_array(ibufr, '%s->%s', ivalues)\n", prefix, a->name_); - } - else { - if (!codes_bufr_key_exclude_from_dump(prefix)) { - char* sval = lval_to_string(c, value); - fprintf(self->dumper.out, " codes_set(ibufr, '%s->%s', ", prefix, a->name_); - fprintf(self->dumper.out, "%s)\n", sval); - grib_context_free(c, sval); - } - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - depth -= 2; - } - (void)err; /* TODO */ -} - -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) -{ - grib_dumper_bufr_encode_python* self = (grib_dumper_bufr_encode_python*)d; - double value; - size_t size = 1; - int r; - char* sval; - grib_handle* h = grib_handle_of_accessor(a); - grib_context* c = h->context; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->unpack_double(&value, &size); - self->empty = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - - sval = dval_to_string(c, value); - if (r != 0) - fprintf(self->dumper.out, " codes_set(ibufr, '#%d#%s', %s)\n", r, a->name_, sval); - else - fprintf(self->dumper.out, " codes_set(ibufr, '%s', %s)\n", a->name_, sval); - grib_context_free(c, sval); - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } -} - -static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_encode_python* self = (grib_dumper_bufr_encode_python*)d; - char** values; - size_t size = 0, i = 0; - grib_context* c = a->context_; - int err = 0; - long count = 0; - int r = 0; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - if (size == 1) { - dump_string(d, a, comment); - return; - } - - fprintf(self->dumper.out, " svalues = ("); - - self->empty = 0; - - values = (char**)grib_context_malloc_clear(c, size * sizeof(char*)); - if (!values) { - grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); - return; - } - - err = a->unpack_string_array(values, &size); - - for (i = 0; i < size - 1; i++) { - fprintf(self->dumper.out, " \"%s\", \n", values[i]); - } - fprintf(self->dumper.out, " \"%s\", )\n", values[i]); - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, " codes_set_array(ibufr, '#%d#%s', svalues)\n", r, a->name_); - else - fprintf(self->dumper.out, " codes_set_array(ibufr, '%s', svalues)\n", a->name_); - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - for (i=0; icontext_; - int r = 0, err = 0; - grib_handle* h = grib_handle_of_accessor(a); - const char* acc_name = a->name_; - - grib_get_string_length_acc(a, &size); - if (size == 0) - return; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - value = (char*)grib_context_malloc_clear(c, size); - if (!value) { - grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); - return; - } - - self->empty = 0; - - err = a->unpack_string(value, &size); - p = value; - r = compute_bufr_key_rank(h, self->keys, acc_name); - if (grib_is_missing_string(a, (unsigned char*)value, size)) { - strcpy(value, ""); /* Empty string means MISSING string */ - } - - while (*p) { - if (!isprint(*p)) - *p = '?'; - p++; - } - - if (self->isLeaf == 0) { - depth += 2; - if (r != 0) - fprintf(self->dumper.out, " codes_set(ibufr, '#%d#%s',", r, acc_name); - else - fprintf(self->dumper.out, " codes_set(ibufr, '%s',", acc_name); - } - fprintf(self->dumper.out, "\'%s\')\n", value); - - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(acc_name) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, acc_name); - } - else - prefix = (char*)acc_name; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - depth -= 2; - } - - grib_context_free(c, value); - (void)err; /* TODO */ -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void _dump_long_array(grib_handle* h, FILE* f, const char* key, const char* print_key) -{ - long* val; - size_t size = 0, i; - int cols = 9, icount = 0; - - if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) - return; - if (size == 0) - return; - - fprintf(f, " ivalues = ("); - - val = (long*)grib_context_malloc_clear(h->context, sizeof(long) * size); - grib_get_long_array(h, key, val, &size); - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(f, " \n "); - icount = 0; - } - fprintf(f, "%ld, ", val[i]); - icount++; - } - if (icount > cols) { - fprintf(f, " \n "); - } - /* Note: In python to make a tuple with one element, you need the trailing comma */ - if (size > 4) - fprintf(f, "%ld ,) # %lu values\n", val[size - 1], (unsigned long)size); - else - fprintf(f, "%ld ,)\n", val[size - 1]); - - grib_context_free(h->context, val); - fprintf(f, " codes_set_array(ibufr, '%s', ivalues)\n", print_key); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_bufr_encode_python* self = (grib_dumper_bufr_encode_python*)d; - if (strcmp(a->name_, "BUFR")==0 || - strcmp(a->name_, "GRIB")==0 || - strcmp(a->name_, "META")==0) { - grib_handle* h = grib_handle_of_accessor(a); - depth = 2; - self->empty = 1; - depth += 2; - _dump_long_array(h, self->dumper.out, "dataPresentIndicator", "inputDataPresentIndicator"); - _dump_long_array(h, self->dumper.out, "delayedDescriptorReplicationFactor", "inputDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "shortDelayedDescriptorReplicationFactor", "inputShortDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "extendedDelayedDescriptorReplicationFactor", "inputExtendedDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "inputOverriddenReferenceValues", "inputOverriddenReferenceValues"); - grib_dump_accessors_block(d, block); - depth -= 2; - } - else if (strcmp(a->name_, "groupNumber")==0) { - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - self->empty = 1; - depth += 2; - grib_dump_accessors_block(d, block); - depth -= 2; - } - else { - grib_dump_accessors_block(d, block); - } -} - -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - int i = 0; - grib_dumper_bufr_encode_python* self = (grib_dumper_bufr_encode_python*)d; - unsigned long flags; - while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { - self->isAttribute = 1; - if ((d->option_flags & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { - i++; - continue; - } - self->isLeaf = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; - flags = a->attributes_[i]->flags_; - a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; - switch (a->attributes_[i]->get_native_type()) { - case GRIB_TYPE_LONG: - dump_long_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_DOUBLE: - dump_values_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_STRING: - break; - } - a->attributes_[i]->flags_ = flags; - i++; - } - self->isLeaf = 0; - self->isAttribute = 0; -} - -static void header(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_encode_python* self = (grib_dumper_bufr_encode_python*)d; - char sampleName[200] = { 0 }; - long localSectionPresent, edition, bufrHeaderCentre, isSatellite; - - grib_get_long(h, "localSectionPresent", &localSectionPresent); - grib_get_long(h, "bufrHeaderCentre", &bufrHeaderCentre); - grib_get_long(h, "edition", &edition); - - if (localSectionPresent && bufrHeaderCentre == 98) { - grib_get_long(h, "isSatellite", &isSatellite); - if (isSatellite) - snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local_satellite", edition); - else - snprintf(sampleName, sizeof(sampleName), "BUFR%ld_local", edition); - } - else { - snprintf(sampleName, sizeof(sampleName), "BUFR%ld", edition); - } - - if (d->count < 2) { - /* This is the first message being processed */ - fprintf(self->dumper.out, "# This program was automatically generated with bufr_dump -Epython\n"); - fprintf(self->dumper.out, "# Using ecCodes version: "); - grib_print_api_version(self->dumper.out); - fprintf(self->dumper.out, "\n\n"); - fprintf(self->dumper.out, "import sys\n"); - fprintf(self->dumper.out, "import traceback\n\n"); - fprintf(self->dumper.out, "from eccodes import *\n\n\n"); - fprintf(self->dumper.out, "def bufr_encode():\n"); - } - fprintf(self->dumper.out, " ibufr = codes_bufr_new_from_samples('%s')\n", sampleName); -} - -static void footer(grib_dumper* d, grib_handle* h) -{ - grib_dumper_bufr_encode_python* self = (grib_dumper_bufr_encode_python*)d; - fprintf(self->dumper.out, "\n # Encode the keys back in the data section\n"); - fprintf(self->dumper.out, " codes_set(ibufr, 'pack', 1)\n\n"); - if (d->count == 1) - fprintf(self->dumper.out, " outfile = open('outfile.bufr', 'wb')\n"); - else - fprintf(self->dumper.out, " outfile = open('outfile.bufr', 'ab')\n"); - - fprintf(self->dumper.out, " codes_write(ibufr, outfile)\n"); - if (d->count == 1) - fprintf(self->dumper.out, " print (\"Created output BUFR file 'outfile.bufr'\")\n"); - /*fprintf(self->dumper.out," codes_close_file(outfile)\n");*/ - fprintf(self->dumper.out, " codes_release(ibufr)\n"); -} diff --git a/src/grib_dumper_class_bufr_simple.cc b/src/grib_dumper_class_bufr_simple.cc deleted file mode 100644 index eb9206cef..000000000 --- a/src/grib_dumper_class_bufr_simple.cc +++ /dev/null @@ -1,786 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - MEMBERS = long section_offset - MEMBERS = long empty - MEMBERS = long end - MEMBERS = long isLeaf - MEMBERS = long isAttribute - MEMBERS = long numberOfSubsets - MEMBERS = grib_string_list* keys - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); - -typedef struct grib_dumper_bufr_simple { - grib_dumper dumper; - /* Members defined in bufr_simple */ - long section_offset; - long empty; - long end; - long isLeaf; - long isAttribute; - long numberOfSubsets; - grib_string_list* keys; -} grib_dumper_bufr_simple; - - -static grib_dumper_class _grib_dumper_class_bufr_simple = { - 0, /* super */ - "bufr_simple", /* name */ - sizeof(grib_dumper_bufr_simple), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - 0, /* header */ - 0, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_bufr_simple = &_grib_dumper_class_bufr_simple; - -/* END_CLASS_IMP */ -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix); - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_bufr_simple* self = (grib_dumper_bufr_simple*)d; - grib_context* c = d->context; - self->section_offset = 0; - self->empty = 1; - self->isLeaf = 0; - self->isAttribute = 0; - self->numberOfSubsets = 0; - self->keys = (grib_string_list*)grib_context_malloc_clear(c, sizeof(grib_string_list)); - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - grib_dumper_bufr_simple* self = (grib_dumper_bufr_simple*)d; - grib_string_list* next = self->keys; - grib_string_list* cur = NULL; - grib_context* c = d->context; - while (next) { - cur = next; - next = next->next; - grib_context_free(c, cur->value); - grib_context_free(c, cur); - } - return GRIB_SUCCESS; -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_bufr_simple* self = (grib_dumper_bufr_simple*)d; - double value = 0; - size_t size = 0, size2 = 0; - double* values = NULL; - int err = 0; - int i, r; - int cols = 9; - long count = 0; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); - err = a->unpack_double(values, &size2); - } - else { - err = a->unpack_double(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - int icount = 0; - - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, "#%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "%s=", a->name_); - - fprintf(self->dumper.out, "{"); - - for (i = 0; i < size - 1; ++i) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - fprintf(self->dumper.out, "%g, ", values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - fprintf(self->dumper.out, "%g", values[i]); - - fprintf(self->dumper.out, "}\n"); - grib_context_free(c, values); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (r != 0) - fprintf(self->dumper.out, "#%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "%s=", a->name_); - - if (!grib_is_missing_double(a, value)) { - fprintf(self->dumper.out, "%g\n", value); - } - else { - fprintf(self->dumper.out, "MISSING\n"); - } - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - } - - (void)err; /* TODO */ -} - -static void dump_values_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_simple* self = (grib_dumper_bufr_simple*)d; - double value = 0; - size_t size = 0, size2 = 0; - double* values = NULL; - int err = 0; - int i, icount; - int cols = 9; - long count = 0; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (double*)grib_context_malloc_clear(c, sizeof(double) * size); - err = a->unpack_double(values, &size2); - } - else { - err = a->unpack_double(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, "%s->%s = {", prefix, a->name_); - icount = 0; - for (i = 0; i < size - 1; ++i) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - fprintf(self->dumper.out, "%g, ", values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - fprintf(self->dumper.out, "%g", values[i]); - - fprintf(self->dumper.out, "}\n"); - grib_context_free(c, values); - } - else { - /* int r=compute_bufr_key_rank(h,self->keys,a->name_); */ - if (!grib_is_missing_double(a, value)) { - fprintf(self->dumper.out, "%s->%s = %g\n", prefix, a->name_, value); - } - else { - fprintf(self->dumper.out, "%s->%s = MISSING\n", prefix, a->name_); - } - } - - if (self->isLeaf == 0) { - char* prefix1; - - prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - } - - (void)err; /* TODO */ -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_simple* self = (grib_dumper_bufr_simple*)d; - long value = 0; - size_t size = 0, size2 = 0; - long* values = NULL; - int err = 0; - int i, r, icount; - int cols = 9; - long count = 0; - grib_context* c = a->context_; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - a->value_count(&count); - size = size2 = count; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - /* Note: the "subsetNumber" key is only there for UNCOMPRESSED BUFR messages */ - if (self->numberOfSubsets > 1 && strcmp(a->name_, "subsetNumber") == 0) { - err = a->unpack_long(&value, &size); - DEBUG_ASSERT(!err); - fprintf(self->dumper.out, "%s=%ld\n", a->name_, value); - DEBUG_ASSERT(!grib_is_missing_long(a, value)); - (void)err; - return; - } - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - } - return; - } - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size2); - } - else { - err = a->unpack_long(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - int doing_unexpandedDescriptors = 0; - icount = 0; - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, "#%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "%s=", a->name_); - - fprintf(self->dumper.out, "{"); - if (strcmp(a->name_, "unexpandedDescriptors") == 0) - doing_unexpandedDescriptors = 1; - - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - if (doing_unexpandedDescriptors) - fprintf(self->dumper.out, "%06ld, ", values[i]); - else - fprintf(self->dumper.out, "%ld, ", values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - if (doing_unexpandedDescriptors) - fprintf(self->dumper.out, "%06ld ", values[i]); - else - fprintf(self->dumper.out, "%ld ", values[i]); - - fprintf(self->dumper.out, "}\n"); - grib_context_free(a->context_, values); - } - else { - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (r != 0) - fprintf(self->dumper.out, "#%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "%s=", a->name_); - - if (!grib_is_missing_long(a, value)) { - fprintf(self->dumper.out, "%ld\n", value); - } - else { - fprintf(self->dumper.out, "MISSING\n"); - } - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - } - (void)err; /* TODO */ -} - -static void dump_long_attribute(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - grib_dumper_bufr_simple* self = (grib_dumper_bufr_simple*)d; - long value = 0; - size_t size = 0, size2 = 0; - long* values = NULL; - int err = 0; - int i, icount; - int cols = 9; - long count = 0; - grib_context* c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size2); - } - else { - err = a->unpack_long(&value, &size2); - } - Assert(size2 == size); - - self->empty = 0; - - if (size > 1) { - fprintf(self->dumper.out, "%s->%s = {", prefix, a->name_); - icount = 0; - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - icount = 0; - } - fprintf(self->dumper.out, "%ld, ", values[i]); - icount++; - } - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n "); - } - fprintf(self->dumper.out, "%ld ", values[i]); - fprintf(self->dumper.out, "}\n"); - grib_context_free(a->context_, values); - } - else { - /* int r=compute_bufr_key_rank(h,self->keys,a->name_); */ - if (!codes_bufr_key_exclude_from_dump(prefix)) { - if (!grib_is_missing_long(a, value)) { - fprintf(self->dumper.out, "%s->%s = ", prefix, a->name_); - fprintf(self->dumper.out, "%ld\n", value); - } - else { - fprintf(self->dumper.out, "%s->%s = MISSING\n", prefix, a->name_); - } - } - } - - if (self->isLeaf == 0) { - char* prefix1 = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + strlen(prefix) + 5)); - snprintf(prefix1, 1024, "%s->%s", prefix, a->name_); - - dump_attributes(d, a, prefix1); - - grib_context_free(c, prefix1); - } - (void)err; /* TODO */ -} - -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) -{ - grib_dumper_bufr_simple* self = (grib_dumper_bufr_simple*)d; - double value = 0; - size_t size = 1; - int r; - grib_handle* h = grib_handle_of_accessor(a); - grib_context* c = h->context; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->unpack_double(&value, &size); - - self->empty = 0; - - r = compute_bufr_key_rank(h, self->keys, a->name_); - if (r != 0) - fprintf(self->dumper.out, "#%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "%s=", a->name_); - - if (!grib_is_missing_double(a, value)) { - fprintf(self->dumper.out, "%g\n", value); - } - else { - fprintf(self->dumper.out, "MISSING\n"); - } - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - } -} - -static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_bufr_simple* self = (grib_dumper_bufr_simple*)d; - char** values = NULL; - size_t size = 0, i = 0; - grib_context* c = a->context_; - int err = 0; - int is_missing = 0; - long count = 0; - int r = 0; - grib_handle* h = grib_handle_of_accessor(a); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - return; - - a->value_count(&count); - size = count; - if (size == 1) { - dump_string(d, a, comment); - return; - } - - if (self->isLeaf == 0) { - if ((r = compute_bufr_key_rank(h, self->keys, a->name_)) != 0) - fprintf(self->dumper.out, "#%d#%s=", r, a->name_); - else - fprintf(self->dumper.out, "%s=", a->name_); - } - - self->empty = 0; - - values = (char**)grib_context_malloc_clear(c, size * sizeof(char*)); - if (!values) { - grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); - return; - } - - err = a->unpack_string_array(values, &size); - - fprintf(self->dumper.out, "{"); - for (i = 0; i < size - 1; i++) { - is_missing = grib_is_missing_string(a, (unsigned char*)values[i], strlen(values[i])); - if (is_missing) fprintf(self->dumper.out, " %s,\n", "MISSING"); - else fprintf(self->dumper.out, " \"%s\",\n", values[i]); - } - is_missing = grib_is_missing_string(a, (unsigned char*)values[i], strlen(values[i])); - if (is_missing) fprintf(self->dumper.out, " %s\n", "MISSING"); - else fprintf(self->dumper.out, " \"%s\"\n", values[i]); - - fprintf(self->dumper.out, "}\n"); - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(a->name_) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, a->name_); - } - else - prefix = (char*)a->name_; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - } - for (i=0; icontext_; - int r = 0; - int is_missing = 0; - int err = 0; - grib_handle* h = grib_handle_of_accessor(a); - const char* acc_name = a->name_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0 || (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) { - return; - } - - self->empty = 0; - - err = a->unpack_string(value, &size); - if (err) { - fprintf(self->dumper.out, " *** ERR=%d (%s) [dump_string on '%s']", err, grib_get_error_message(err), acc_name); - return; - } - Assert(size < MAX_STRING_SIZE); - p = value; - r = compute_bufr_key_rank(h, self->keys, acc_name); - if (grib_is_missing_string(a, (unsigned char*)value, size)) { - is_missing = 1; - } - - while (*p) { - if (!isprint(*p)) - *p = '?'; - if (*p == '"') - *p = '\''; /* ECC-1401 */ - p++; - } - - if (self->isLeaf == 0) { - if (r != 0) - fprintf(self->dumper.out, "#%d#%s=", r, acc_name); - else - fprintf(self->dumper.out, "%s=", acc_name); - } - if (is_missing) - fprintf(self->dumper.out, "%s\n", "MISSING"); - else - fprintf(self->dumper.out, "\"%s\"\n", value); - - if (self->isLeaf == 0) { - char* prefix; - int dofree = 0; - - if (r != 0) { - prefix = (char*)grib_context_malloc_clear(c, sizeof(char) * (strlen(acc_name) + 10)); - dofree = 1; - snprintf(prefix, 1024, "#%d#%s", r, acc_name); - } - else - prefix = (char*)acc_name; - - dump_attributes(d, a, prefix); - if (dofree) - grib_context_free(c, prefix); - } - - (void)err; /* TODO */ -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void _dump_long_array(grib_handle* h, FILE* f, const char* key) -{ - long* val; - size_t size = 0, i; - int cols = 9, icount = 0; - - if (grib_get_size(h, key, &size) == GRIB_NOT_FOUND) - return; - if (size == 0) - return; - - val = (long*)grib_context_malloc_clear(h->context, sizeof(long) * size); - grib_get_long_array(h, key, val, &size); - fprintf(f, "%s= {", key); - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(f, "\n "); - icount = 0; - } - fprintf(f, "%ld, ", val[i]); - icount++; - } - if (icount > cols) { - fprintf(f, "\n "); - } - fprintf(f, "%ld}\n", val[size - 1]); - - grib_context_free(h->context, val); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_bufr_simple* self = (grib_dumper_bufr_simple*)d; - if (strcmp(a->name_, "BUFR")==0 || - strcmp(a->name_, "GRIB")==0 || - strcmp(a->name_, "META")==0) { - int err = 0; - grib_handle* h = grib_handle_of_accessor(a); - self->empty = 1; - - err = grib_get_long(h, "numberOfSubsets", &(self->numberOfSubsets)); - Assert(!err); - _dump_long_array(h, self->dumper.out, "dataPresentIndicator"); - _dump_long_array(h, self->dumper.out, "delayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "shortDelayedDescriptorReplicationFactor"); - _dump_long_array(h, self->dumper.out, "extendedDelayedDescriptorReplicationFactor"); - /* Do not show the inputOverriddenReferenceValues array. That's more for ENCODING */ - /*_dump_long_array(h,self->dumper.out,"inputOverriddenReferenceValues","inputOverriddenReferenceValues");*/ - grib_dump_accessors_block(d, block); - } - else if (strcmp(a->name_, "groupNumber")==0) { - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - self->empty = 1; - grib_dump_accessors_block(d, block); - } - else { - grib_dump_accessors_block(d, block); - } -} - -static void dump_attributes(grib_dumper* d, grib_accessor* a, const char* prefix) -{ - int i = 0; - grib_dumper_bufr_simple* self = (grib_dumper_bufr_simple*)d; - unsigned long flags; - while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { - self->isAttribute = 1; - if ((d->option_flags & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { - i++; - continue; - } - self->isLeaf = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; - /* fprintf(self->dumper.out,","); */ - /* fprintf(self->dumper.out,"\n%-*s",depth," "); */ - /* fprintf(out,"\"%s\" : ",a->attributes_[i]->name); */ - flags = a->attributes_[i]->flags_; - a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; - switch (a->attributes_[i]->get_native_type()) { - case GRIB_TYPE_LONG: - dump_long_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_DOUBLE: - dump_values_attribute(d, a->attributes_[i], prefix); - break; - case GRIB_TYPE_STRING: - break; - } - a->attributes_[i]->flags_ = flags; - i++; - } - self->isLeaf = 0; - self->isAttribute = 0; -} diff --git a/src/grib_dumper_class_debug.cc b/src/grib_dumper_class_debug.cc deleted file mode 100644 index 3bfd48217..000000000 --- a/src/grib_dumper_class_debug.cc +++ /dev/null @@ -1,646 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - MEMBERS = long section_offset - MEMBERS = long begin - MEMBERS = long theEnd - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); - -typedef struct grib_dumper_debug { - grib_dumper dumper; - /* Members defined in debug */ - long section_offset; - long begin; - long theEnd; -} grib_dumper_debug; - - -static grib_dumper_class _grib_dumper_class_debug = { - 0, /* super */ - "debug", /* name */ - sizeof(grib_dumper_debug), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - 0, /* header */ - 0, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_debug = &_grib_dumper_class_debug; - -/* END_CLASS_IMP */ -static void set_begin_end(grib_dumper* d, grib_accessor* a); - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_debug* self = (grib_dumper_debug*)d; - self->section_offset = 0; - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - return GRIB_SUCCESS; -} - -static void default_long_value(grib_dumper* d, grib_accessor* a, long actualValue) -{ - grib_dumper_debug* self = (grib_dumper_debug*)d; - grib_action* act = a->creator_; - if (act->default_value == NULL) - return; - - grib_handle* h = grib_handle_of_accessor(a); - grib_expression* expression = grib_arguments_get_expression(h, act->default_value, 0); - if (!expression) - return; - - const int type = grib_expression_native_type(h, expression); - if (type == GRIB_TYPE_LONG) { - long defaultValue = 0; - if (grib_expression_evaluate_long(h, expression, &defaultValue) == GRIB_SUCCESS && defaultValue != actualValue) { - if (defaultValue == GRIB_MISSING_LONG) - fprintf(self->dumper.out, " (default=MISSING)"); - else - fprintf(self->dumper.out, " (default=%ld)",defaultValue); - } - } -} - -// static void default_string_value(grib_dumper* d, grib_accessor* a, const char* actualValue) -// { -// grib_dumper_debug* self = (grib_dumper_debug*)d; -// grib_action* act = a->creator_; -// if (act->default_value == NULL) -// return; - -// grib_handle* h = grib_handle_of_accessor(a); -// grib_expression* expression = grib_arguments_get_expression(h, act->default_value, 0); -// if (!expression) -// return; - -// const int type = grib_expression_native_type(h, expression); -// DEBUG_ASSERT(type == GRIB_TYPE_STRING); -// if (type == GRIB_TYPE_STRING) { -// char tmp[1024] = {0,}; -// size_t s_len = sizeof(tmp); -// int err = 0; -// const char* p = grib_expression_evaluate_string(h, expression, tmp, &s_len, &err); -// if (!err && !STR_EQUAL(p, actualValue)) { -// fprintf(self->dumper.out, " (default=%s)", p); -// } -// } -// } - -static void aliases(grib_dumper* d, grib_accessor* a) -{ - int i; - grib_dumper_debug* self = (grib_dumper_debug*)d; - - if (a->all_names_[1]) { - const char* sep = ""; - fprintf(self->dumper.out, " ["); - - for (i = 1; i < MAX_ACCESSOR_NAMES; i++) { - if (a->all_names_[i]) { - if (a->all_name_spaces_[i]) - fprintf(self->dumper.out, "%s%s.%s", sep, a->all_name_spaces_[i], a->all_names_[i]); - else - fprintf(self->dumper.out, "%s%s", sep, a->all_names_[i]); - } - sep = ", "; - } - fprintf(self->dumper.out, "]"); - } -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_debug* self = (grib_dumper_debug*)d; - long value = 0; - size_t size = 0; - size_t more = 0; - long* values = NULL; /* array of long */ - long count = 0; - int err = 0, i = 0; - - if (a->length_ == 0 && (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0) - return; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && - (d->option_flags & GRIB_DUMP_FLAG_READ_ONLY) == 0) - return; - - a->value_count(&count); - size = count; - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size); - } - else { - err = a->unpack_long(&value, &size); - } - - set_begin_end(d, a); - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - - if (size > 1) { - fprintf(self->dumper.out, "%ld-%ld %s %s = {\n", self->begin, self->theEnd, a->creator_->op, a->name_); - if (values) { - int k = 0; - if (size > 100) { - more = size - 100; - size = 100; - } - while (k < size) { - int j; - for (i = 0; i < d->depth + 3; i++) - fprintf(self->dumper.out, " "); - for (j = 0; j < 8 && k < size; j++, k++) { - fprintf(self->dumper.out, "%ld", values[k]); - if (k != size - 1) - fprintf(self->dumper.out, ", "); - } - fprintf(self->dumper.out, "\n"); - } - if (more) { - for (i = 0; i < d->depth + 3; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "... %lu more values\n", (unsigned long)more); - } - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "} # %s %s \n", a->creator_->op, a->name_); - grib_context_free(a->context_, values); - } - } - else { - if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) - fprintf(self->dumper.out, "%ld-%ld %s %s = MISSING", self->begin, self->theEnd, a->creator_->op, a->name_); - else - fprintf(self->dumper.out, "%ld-%ld %s %s = %ld", self->begin, self->theEnd, a->creator_->op, a->name_, value); - if (comment) - fprintf(self->dumper.out, " [%s]", comment); - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) - fprintf(self->dumper.out, " (%s)", grib_get_type_name(a->get_native_type())); - if ((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) - fprintf(self->dumper.out, " %s", "(can be missing)"); - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - fprintf(self->dumper.out, " %s", "(read-only)"); - } - if (err) - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_debug::dump_long]", err, grib_get_error_message(err)); - - aliases(d, a); - default_long_value(d, a, value); - - fprintf(self->dumper.out, "\n"); -} - -static int test_bit(long a, long b) -{ - return a & (1 << b); -} - -static void dump_bits(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_debug* self = (grib_dumper_debug*)d; - - if (a->length_ == 0 && - (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0) - return; - - size_t size = 1; - long value = 0; - int err = a->unpack_long(&value, &size); - set_begin_end(d, a); - - for (int i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "%ld-%ld %s %s = %ld [", self->begin, self->theEnd, a->creator_->op, a->name_, value); - - for (long i = 0; i < (a->length_ * 8); i++) { - if (test_bit(value, a->length_ * 8 - i - 1)) - fprintf(self->dumper.out, "1"); - else - fprintf(self->dumper.out, "0"); - } - - if (comment) - fprintf(self->dumper.out, ":%s]", comment); - else - fprintf(self->dumper.out, "]"); - - if (err) - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_debug::dump_bits]", err, grib_get_error_message(err)); - - aliases(d, a); - fprintf(self->dumper.out, "\n"); -} - -static void dump_double(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_debug* self = (grib_dumper_debug*)d; - double value = 0; - size_t size = 1; - int err = a->unpack_double(&value, &size); - int i; - - if (a->length_ == 0 && - (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0) - return; - - set_begin_end(d, a); - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - - if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) - fprintf(self->dumper.out, "%ld-%ld %s %s = MISSING", self->begin, self->theEnd, a->creator_->op, a->name_); - else - fprintf(self->dumper.out, "%ld-%ld %s %s = %g", self->begin, self->theEnd, a->creator_->op, a->name_, value); - if (comment) - fprintf(self->dumper.out, " [%s]", comment); - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) - fprintf(self->dumper.out, " (%s)", grib_get_type_name(a->get_native_type())); - if (err) - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_debug::dump_double]", err, grib_get_error_message(err)); - aliases(d, a); - fprintf(self->dumper.out, "\n"); -} - -static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_debug* self = (grib_dumper_debug*)d; - int err = 0; - int i; - size_t size = 0; - char* value = NULL; - char* p = NULL; - - if (a->length_ == 0 && (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0) - return; - - grib_get_string_length_acc(a, &size); - if ((size < 2) && a->is_missing_internal()) { - /* GRIB-302: transients and missing keys. Need to re-adjust the size */ - size = 10; /* big enough to hold the string "missing" */ - } - - value = (char*)grib_context_malloc_clear(a->context_, size); - if (!value) - return; - err = a->unpack_string(value, &size); - - if (err) - strcpy(value, ""); - - p = value; - - set_begin_end(d, a); - - while (*p) { - if (!isprint(*p)) - *p = '.'; - p++; - } - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "%ld-%ld %s %s = %s", self->begin, self->theEnd, a->creator_->op, a->name_, value); - - if (comment) - fprintf(self->dumper.out, " [%s]", comment); - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) - fprintf(self->dumper.out, " (%s)", grib_get_type_name(a->get_native_type())); - - if (err) - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_debug::dump_string]", err, grib_get_error_message(err)); - aliases(d, a); - fprintf(self->dumper.out, "\n"); - - 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; ilength_; - unsigned char* buf = (unsigned char*)grib_context_malloc(d->context, size); - - if (a->length_ == 0 && - (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0) - return; - - set_begin_end(d, a); - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "%ld-%ld %s %s = %ld", self->begin, self->theEnd, a->creator_->op, a->name_, a->length_); - aliases(d, a); - fprintf(self->dumper.out, " {"); - - if (!buf) { - if (size == 0) - fprintf(self->dumper.out, "}\n"); - else - fprintf(self->dumper.out, " *** ERR cannot malloc(%zu) }\n", size); - return; - } - - fprintf(self->dumper.out, "\n"); - - err = a->unpack_bytes(buf, &size); - if (err) { - grib_context_free(d->context, buf); - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_debug::dump_bytes]\n}", err, grib_get_error_message(err)); - return; - } - - if (size > 100) { - more = size - 100; - size = 100; - } - - k = 0; - /* if(size > 100) size = 100; */ - while (k < size) { - int j; - for (i = 0; i < d->depth + 3; i++) - fprintf(self->dumper.out, " "); - for (j = 0; j < 16 && k < size; j++, k++) { - fprintf(self->dumper.out, "%02x", buf[k]); - if (k != size - 1) - fprintf(self->dumper.out, ", "); - } - fprintf(self->dumper.out, "\n"); - } - - if (more) { - for (i = 0; i < d->depth + 3; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "... %lu more values\n", (unsigned long)more); - } - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "} # %s %s \n", a->creator_->op, a->name_); - grib_context_free(d->context, buf); -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_debug* self = (grib_dumper_debug*)d; - int i, k, err = 0; - size_t more = 0; - double* buf = NULL; - size_t size = 0; - long count = 0; - - if (a->length_ == 0 && - (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0) - return; - - a->value_count(&count); - size = count; - if (size == 1) { - dump_double(d, a, NULL); - return; - } - buf = (double*)grib_context_malloc_clear(d->context, size * sizeof(double)); - - set_begin_end(d, a); - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "%ld-%ld %s %s = (%ld,%ld)", self->begin, self->theEnd, a->creator_->op, a->name_, (long)size, a->length_); - aliases(d, a); - fprintf(self->dumper.out, " {"); - - if (!buf) { - if (size == 0) - fprintf(self->dumper.out, "}\n"); - else - fprintf(self->dumper.out, " *** ERR cannot malloc(%zu) }\n", size); - return; - } - - fprintf(self->dumper.out, "\n"); - - err = a->unpack_double(buf, &size); - if (err) { - grib_context_free(d->context, buf); - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_debug::dump_values]\n}", err, grib_get_error_message(err)); - return; - } - - if (size > 100) { - more = size - 100; - size = 100; - } - - k = 0; - while (k < size) { - int j; - for (i = 0; i < d->depth + 3; i++) - fprintf(self->dumper.out, " "); - for (j = 0; j < 8 && k < size; j++, k++) { - fprintf(self->dumper.out, "%10g", buf[k]); - if (k != size - 1) - fprintf(self->dumper.out, ", "); - } - fprintf(self->dumper.out, "\n"); - } - if (more) { - for (i = 0; i < d->depth + 3; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "... %lu more values\n", (unsigned long)more); - } - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "} # %s %s \n", a->creator_->op, a->name_); - grib_context_free(d->context, buf); -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_debug* self = (grib_dumper_debug*)d; - int i; - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "----> %s %s %s\n", a->creator_->op, a->name_, comment ? comment : ""); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_debug* self = (grib_dumper_debug*)d; - int i; - /* grib_section* s = grib_get_sub_section(a); */ - grib_section* s = a->sub_section_; - - if (a->name_[0] == '_') { - grib_dump_accessors_block(d, block); - return; - } - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "======> %s %s (%ld,%ld,%ld)\n", a->creator_->op, - a->name_, a->length_, (long)s->length, (long)s->padding); - if (!strncmp(a->name_, "section", 7)) - self->section_offset = a->offset_; - /*printf("------------- section_offset = %ld\n",self->section_offset);*/ - d->depth += 3; - grib_dump_accessors_block(d, block); - d->depth -= 3; - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "<===== %s %s\n", a->creator_->op, a->name_); -} - -static void set_begin_end(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_debug* self = (grib_dumper_debug*)d; - if ((d->option_flags & GRIB_DUMP_FLAG_OCTET) != 0) { - self->begin = a->offset_ - self->section_offset + 1; - self->theEnd = a->get_next_position_offset() - self->section_offset; - } - else { - self->begin = a->offset_; - self->theEnd = a->get_next_position_offset(); - } -} diff --git a/src/grib_dumper_class_default.cc b/src/grib_dumper_class_default.cc deleted file mode 100644 index 0a8411a82..000000000 --- a/src/grib_dumper_class_default.cc +++ /dev/null @@ -1,708 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - MEMBERS = long section_offset - MEMBERS = long begin - MEMBERS = long theEnd - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); - -typedef struct grib_dumper_default { - grib_dumper dumper; - /* Members defined in default */ - long section_offset; - long begin; - long theEnd; -} grib_dumper_default; - - -static grib_dumper_class _grib_dumper_class_default = { - 0, /* super */ - "default", /* name */ - sizeof(grib_dumper_default), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - 0, /* header */ - 0, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_default = &_grib_dumper_class_default; - -/* END_CLASS_IMP */ - -static void print_offset(FILE* out, grib_dumper* d, grib_accessor* a); - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_default* self = (grib_dumper_default*)d; - self->section_offset = 0; - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - return GRIB_SUCCESS; -} - - -static void aliases(grib_dumper* d, grib_accessor* a) -{ - int i; - grib_dumper_default* self = (grib_dumper_default*)d; - - if ((d->option_flags & GRIB_DUMP_FLAG_ALIASES) == 0) - return; - - if (a->all_names_[1]) { - const char* sep = ""; - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "# ALIASES: "); - - for (i = 1; i < MAX_ACCESSOR_NAMES; i++) { - if (a->all_names_[i]) { - if (a->all_name_spaces_[i]) - fprintf(self->dumper.out, "%s%s.%s", sep, a->all_name_spaces_[i], a->all_names_[i]); - else - fprintf(self->dumper.out, "%s%s", sep, a->all_names_[i]); - } - sep = ", "; - } - fprintf(self->dumper.out, "\n"); - } -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_default* self = (grib_dumper_default*)d; - long value = 0; - size_t size = 1, size2 = 0; - long* values = NULL; - int err = 0; - int i; - long count = 0; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - a->value_count(&count); - size = size2 = count; - - print_offset(self->dumper.out, d, a); - - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) { - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "# type %s (int)\n", a->creator_->op); - } - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size2); - } - else { - err = a->unpack_long(&value, &size2); - } - Assert(size2 == size); - - 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- "); - } - else - fprintf(self->dumper.out, " "); - - if (size > 1) { - int cols = 19; - int icount = 0; - fprintf(self->dumper.out, "%s = { \t", a->name_); - for (i = 0; i < size; i++) { - if (icount > cols) { - fprintf(self->dumper.out, "\n\t\t\t\t"); - icount = 0; - } - fprintf(self->dumper.out, "%ld ", values[i]); - icount++; - } - fprintf(self->dumper.out, "}\n"); - grib_context_free(a->context_, values); - } - else { - if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) - fprintf(self->dumper.out, "%s = MISSING;", a->name_); - else - fprintf(self->dumper.out, "%s = %ld;", a->name_, value); - } - - if (err) { - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "# *** ERR=%d (%s) [grib_dumper_default::dump_long]", err, grib_get_error_message(err)); - } - - fprintf(self->dumper.out, "\n"); -} - -static int test_bit(long a, long b) -{ - return a & (1 << b); -} - -static void dump_bits(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_default* self = (grib_dumper_default*)d; - long lvalue = 0; - size_t size = 1; - int err = 0; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - err = a->unpack_long(&lvalue, &size); - - print_offset(self->dumper.out, d, a); - - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) { - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "# type %s \n", a->creator_->op); - } - - aliases(d, a); - if (comment) { - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "# %s \n", comment); - } - - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "# flags: "); - for (long i = 0; i < (a->length_ * 8); i++) { - if (test_bit(lvalue, a->length_ * 8 - i - 1)) - fprintf(self->dumper.out, "1"); - else - fprintf(self->dumper.out, "0"); - } - fprintf(self->dumper.out, "\n"); - - if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) { - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "#-READ ONLY- "); - } - else { - fprintf(self->dumper.out, " "); - } - - if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) - fprintf(self->dumper.out, "%s = MISSING;", a->name_); - else { - fprintf(self->dumper.out, "%s = %ld;", a->name_, lvalue); - } - - if (err) { - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "# *** ERR=%d (%s) [grib_dumper_default::dump_bits]", err, grib_get_error_message(err)); - } - - fprintf(self->dumper.out, "\n"); -} - -static void dump_double(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_default* self = (grib_dumper_default*)d; - double value = 0; - size_t size = 1; - int err = a->unpack_double(&value, &size); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - print_offset(self->dumper.out, d, a); - - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) { - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "# type %s (double)\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- "); - } - else - fprintf(self->dumper.out, " "); - - if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) - fprintf(self->dumper.out, "%s = MISSING;", a->name_); - else - fprintf(self->dumper.out, "%s = %g;", a->name_, value); - - if (err) { - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "# *** ERR=%d (%s) [grib_dumper_default::dump_double]", err, grib_get_error_message(err)); - } - - fprintf(self->dumper.out, "\n"); -} - -static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_default* self = (grib_dumper_default*)d; - char** values; - size_t size = 0, i = 0; - grib_context* c = a->context_; - int err = 0; - int tab = 0; - long count = 0; - - a->value_count(&count); - 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, "Memory allocation error: %zu bytes", size); - return; - } - - err = a->unpack_string_array(values, &size); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - print_offset(self->dumper.out, d, a); - - 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"); - grib_context_free(c, values); -} - -static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_default* self = (grib_dumper_default*)d; - char* value = NULL; - char* p = NULL; - size_t size = 0; - grib_context* c = a->context_; - int err = 0; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { - return; - } - - grib_get_string_length_acc(a, &size); - if (size == 0) - return; - - value = (char*)grib_context_malloc_clear(c, size); - if (!value) { - grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); - return; - } - - err = a->unpack_string(value, &size); - p = value; - - while (*p) { - if (!isprint(*p)) - *p = '.'; - p++; - } - - print_offset(self->dumper.out, d, a); - - 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- "); - } - else - fprintf(self->dumper.out, " "); - - if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) - fprintf(self->dumper.out, "%s = MISSING;", a->name_); - else - fprintf(self->dumper.out, "%s = %s;", a->name_, value); - - - if (err) { - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "# *** ERR=%d (%s) [grib_dumper_default::dump_string]", err, grib_get_error_message(err)); - } - - fprintf(self->dumper.out, "\n"); - grib_context_free(c, value); -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ -// grib_dumper_default *self = (grib_dumper_default*)d; -// int i,k,err =0; -// size_t more = 0; -// size_t size = a->length_; -// unsigned char* buf = grib_context_malloc(d->context,size); - -// if ( (a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) -// return; - - -// if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) -// fprintf(self->dumper.out,"-READ ONLY- "); - -// /*for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," ");*/ -// /*print_offset(self->dumper.out,self->begin,self->theEnd);*/ -// if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) -// fprintf(self->dumper.out,"%s ",a->creator_->op); - -// fprintf(self->dumper.out,"%s = %ld",a->name_,a->length_); -// aliases(d,a); -// fprintf(self->dumper.out," {"); - -// if(!buf) -// { -// if(size == 0) -// fprintf(self->dumper.out,"}\n"); -// else -// fprintf(self->dumper.out," *** ERR cannot malloc(%ld) }\n",(long)size); -// return; -// } - -// fprintf(self->dumper.out,"\n"); - -// err = a->unpack_bytes(buf,&size); -// if(err){ -// grib_context_free(d->context,buf); -// fprintf(self->dumper.out," *** ERR=%d (%s) [grib_dumper_default::dump_bytes]\n}",err,grib_get_error_message(err)); -// return ; -// } - -// if(size > 100) { -// more = size - 100; -// size = 100; -// } - -// k = 0; -// /* if(size > 100) size = 100; */ -// while(k < size) -// { -// int j; -// for(i = 0; i < d->depth + 3 ; i++) fprintf(self->dumper.out," "); -// for(j = 0; j < 16 && k < size; j++, k++) -// { -// fprintf(self->dumper.out,"%02x",buf[k]); -// if(k != size-1) -// fprintf(self->dumper.out,", "); -// } -// fprintf(self->dumper.out,"\n"); -// } - -// if(more) -// { -// for(i = 0; i < d->depth + 3 ; i++) fprintf(self->dumper.out," "); -// fprintf(self->dumper.out,"... %lu more values\n", (unsigned long)more); -// } - -// for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," "); -// fprintf(self->dumper.out,"} # %s %s \n",a->creator_->op, a->name_); -// grib_context_free(d->context,buf); -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_default* self = (grib_dumper_default*)d; - int k, err = 0; - size_t more = 0; - double* buf = NULL; - size_t size = 0; - long count = 0; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - a->value_count(&count); - size = count; - if (size == 1) { - dump_double(d, a, NULL); - return; - } - - buf = (double*)grib_context_malloc(d->context, size * sizeof(double)); - - print_offset(self->dumper.out, d, a); - - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) { - char type_name[32] = ""; - const long native_type = a->get_native_type(); - if (native_type == GRIB_TYPE_LONG) - strcpy(type_name, "(int)"); - else if (native_type == GRIB_TYPE_DOUBLE) - strcpy(type_name, "(double)"); - else if (native_type == GRIB_TYPE_STRING) - strcpy(type_name, "(str)"); - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "# type %s %s\n", a->creator_->op, type_name); - } - - aliases(d, a); - - if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) { - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "#-READ ONLY- "); - } - else - fprintf(self->dumper.out, " "); - - fprintf(self->dumper.out, "%s(%zu) = ", a->name_, size); - aliases(d, a); - fprintf(self->dumper.out, " {"); - - if (!buf) { - if (size == 0) - fprintf(self->dumper.out, "}\n"); - else - fprintf(self->dumper.out, " *** ERR cannot malloc(%zu) }\n", size); - return; - } - - fprintf(self->dumper.out, "\n"); - - err = a->unpack_double(buf, &size); - - if (err) { - grib_context_free(d->context, buf); - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_default::dump_values]\n}", err, grib_get_error_message(err)); - return; - } - - if (!(d->option_flags & GRIB_DUMP_FLAG_ALL_DATA) && size > 100) { - more = size - 100; - size = 100; - } - - k = 0; - while (k < size) { - int j; - fprintf(self->dumper.out, " "); - for (j = 0; j < 5 && k < size; j++, k++) { - fprintf(self->dumper.out, "%g", buf[k]); - if (k != size - 1) - fprintf(self->dumper.out, ", "); - } - fprintf(self->dumper.out, "\n"); - } - if (more) { - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "... %lu more values\n", (unsigned long)more); - } - - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "} \n"); - grib_context_free(d->context, buf); -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ - /*grib_dumper_default *self = (grib_dumper_default*)d; - - for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," "); - fprintf(self->dumper.out,"----> %s %s %s\n",a->creator_->op, a->name_,comment?comment:"");*/ -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_default* self = (grib_dumper_default*)d; - - int is_default_section = 0; - char* upper = NULL; - char *p = NULL, *q = NULL; - if (!strncmp(a->name_, "section", 7)) - is_default_section = 1; - if (!strcmp(a->creator_->op, "bufr_group")) { - dump_long(d, a, NULL); - } - - /*for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," ");*/ - if (is_default_section) { - /* char tmp[512]; */ - /* grib_section* s = a->sub_section; */ - upper = (char*)malloc(strlen(a->name_) + 1); - Assert(upper); - p = (char*)a->name_; - q = upper; - while (*p != '\0') { - *q = toupper(*p); - q++; - p++; - } - *q = '\0'; - - /* snprintf(tmp, sizeof(tmp), "%s ( length=%ld, padding=%ld )", upper, (long)s->length, (long)s->padding); */ - /* fprintf(self->dumper.out,"#============== %-38s ==============\n",tmp); */ - free(upper); - self->section_offset = a->offset_; - } - - /*printf("------------- section_offset = %ld\n",self->section_offset);*/ - d->depth += 3; - grib_dump_accessors_block(d, block); - d->depth -= 3; - /*for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," ");*/ - /*fprintf(self->dumper.out,"<===== %s %s\n",a->creator_->op, a->name_);*/ -} - -static void print_offset(FILE* out, grib_dumper* d, grib_accessor* a) -{ - int i, k; - long offset; - long theBegin = 0, theEnd = 0; - size_t size = 0, more = 0; - grib_dumper_default* self = (grib_dumper_default*)d; - grib_handle* h = grib_handle_of_accessor(a); - - theBegin = a->offset_ - self->section_offset + 1; - theEnd = a->get_next_position_offset() - self->section_offset; - - if ((d->option_flags & GRIB_DUMP_FLAG_HEXADECIMAL) != 0 && a->length_ != 0) { - if (theBegin == theEnd) { - fprintf(self->dumper.out, " "); - fprintf(out, "# Octet: "); - fprintf(out, "%ld", theBegin); - } - else { - fprintf(self->dumper.out, " "); - fprintf(out, "# Octets: "); - fprintf(out, "%ld-%ld", theBegin, theEnd); - } - fprintf(out, " = "); - size = a->length_; - - if (!(d->option_flags & GRIB_DUMP_FLAG_ALL_DATA) && size > 112) { - more = size - 112; - size = 112; - } - - k = 0; - while (k < size) { - offset = a->offset_; - for (i = 0; i < 14 && k < size; i++, k++) { - fprintf(out, " 0x%.2X", h->buffer->data[offset]); - offset++; - } - if (k < size) - fprintf(self->dumper.out, "\n #"); - } - if (more) { - fprintf(self->dumper.out, "\n #... %lu more values\n", (unsigned long)more); - } - fprintf(self->dumper.out, "\n"); - } -} diff --git a/src/grib_dumper_class_grib_encode_C.cc b/src/grib_dumper_class_grib_encode_C.cc deleted file mode 100644 index 208f7bc90..000000000 --- a/src/grib_dumper_class_grib_encode_C.cc +++ /dev/null @@ -1,450 +0,0 @@ -/* - * (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 = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - IMPLEMENTS = header;footer - MEMBERS = int cr - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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_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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); -static void header (grib_dumper*,grib_handle*); -static void footer (grib_dumper*,grib_handle*); - -typedef struct grib_dumper_grib_encode_C { - grib_dumper dumper; - /* Members defined in grib_encode_C */ - int cr; -} grib_dumper_grib_encode_C; - - -static grib_dumper_class _grib_dumper_class_grib_encode_C = { - 0, /* super */ - "grib_encode_C", /* name */ - sizeof(grib_dumper_grib_encode_C), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - 0, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - &header, /* header */ - &footer, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_grib_encode_C = &_grib_dumper_class_grib_encode_C; - -/* END_CLASS_IMP */ -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - /* grib_dumper_grib_encode_C *self = (grib_dumper_grib_encode_C*)d; */ - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - return GRIB_SUCCESS; -} - -static void pcomment(FILE* f, long value, const char* p) -{ - int cr = 0; - fprintf(f, "\n /* %ld = ", value); - - while (*p) { - switch (*p) { - case ';': - fprintf(f, "\n "); - cr = 1; - break; - - case ':': - if (cr) - fprintf(f, "\n See "); - else - fprintf(f, ". See "); - break; - - default: - fputc(*p, f); - break; - } - - p++; - } - - fprintf(f, " */\n"); -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_grib_encode_C* self = (grib_dumper_grib_encode_C*)d; - long value; - size_t size = 1; - int err = a->unpack_long(&value, &size); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY)) - return; - - if (comment) - pcomment(self->dumper.out, value, comment); - - if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && (value == GRIB_MISSING_LONG)) - fprintf(self->dumper.out, " GRIB_CHECK(grib_set_missing(h,\"%s\"),%d);\n", a->name_, 0); - else - fprintf(self->dumper.out, " GRIB_CHECK(grib_set_long(h,\"%s\",%ld),%d);\n", a->name_, value, 0); - - if (err) - fprintf(self->dumper.out, " /* Error accessing %s (%s) */", a->name_, grib_get_error_message(err)); - - if (comment) - fprintf(self->dumper.out, "\n"); -} - -static int test_bit(long a, long b) -{ - return a & (1 << b); -} - - -static void dump_bits(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_grib_encode_C* self = (grib_dumper_grib_encode_C*)d; - long value; - size_t size = 1; - int err = a->unpack_long(&value, &size); - int i; - - char buf[1024]; - - if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) - return; - - if (a->length_ == 0) - return; - - buf[0] = 0; - - for (i = 0; i < (a->length_ * 8); i++) { - if (test_bit(value, a->length_ * 8 - i - 1)) - strcat(buf, "1"); - else - strcat(buf, "0"); - } - - if (comment) { - strcat(buf, ";"); - strcat(buf, comment); - } - - pcomment(self->dumper.out, value, buf); - - if (err) - fprintf(self->dumper.out, " /* Error accessing %s (%s) */", a->name_, grib_get_error_message(err)); - else - fprintf(self->dumper.out, " GRIB_CHECK(grib_set_long(h,\"%s\",%ld),%d);\n", a->name_, value, 0); - - fprintf(self->dumper.out, "\n"); -} - -static void dump_double(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_grib_encode_C* self = (grib_dumper_grib_encode_C*)d; - double value; - size_t size = 1; - int err = a->unpack_double(&value, &size); - if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) - return; - - if (a->length_ == 0) - return; - - //if(comment) fprintf(self->dumper.out,"/* %s */\n",comment); - - fprintf(self->dumper.out, " GRIB_CHECK(grib_set_double(h,\"%s\",%g),%d);\n", a->name_, value, 0); - - if (err) - fprintf(self->dumper.out, " /* Error accessing %s (%s) */", a->name_, grib_get_error_message(err)); -} - -static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_grib_encode_C* self = (grib_dumper_grib_encode_C*)d; - char value[1024]; - size_t size = sizeof(value); - int err = a->unpack_string(value, &size); - - if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) - return; - - if (a->length_ == 0) - return; - - if (comment) - fprintf(self->dumper.out, "/* %s */\n", comment); - - fprintf(self->dumper.out, " p = \"%s\";\n", value); - fprintf(self->dumper.out, " size = strlen(p);\n"); - fprintf(self->dumper.out, " GRIB_CHECK(grib_set_string(h,\"%s\",p,&size),%d);\n", a->name_, 0); - - if (err) - fprintf(self->dumper.out, " /* Error accessing %s (%s) */", a->name_, grib_get_error_message(err)); -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_grib_encode_C* self = (grib_dumper_grib_encode_C*)d; - int err = 0; - size_t size = a->length_; - unsigned char* buf; - - if (a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) - return; - - if (size == 0) - return; - - buf = (unsigned char*)grib_context_malloc(d->context, size); - - if (!buf) { - fprintf(self->dumper.out, "/* %s: cannot malloc(%zu) */\n", a->name_, size); - return; - } - - err = a->unpack_bytes(buf, &size); - if (err) { - grib_context_free(d->context, buf); - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_grib_encode_C::dump_bytes]\n}", err, grib_get_error_message(err)); - return; - } - - // if(size > 100) { - // more = size - 100; - // size = 100; - // } - - // k = 0; - // //if(size > 100) size = 100; - // while(k < size) - // { - // int j; - // for(i = 0; i < d->depth + 3 ; i++) fprintf(self->dumper.out," "); - // for(j = 0; j < 16 && k < size; j++, k++) - // { - // fprintf(self->dumper.out,"%02x",buf[k]); - // if(k != size-1) - // fprintf(self->dumper.out,", "); - // } - // fprintf(self->dumper.out,"\n"); - // } - - grib_context_free(d->context, buf); -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_grib_encode_C* self = (grib_dumper_grib_encode_C*)d; - int k, err = 0; - double* buf = NULL; - int type = 0; - char stype[10]; - size_t size = 0; - long count = 0; - - stype[0] = '\0'; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) || ((a->flags_ & GRIB_ACCESSOR_FLAG_DATA) && (d->option_flags & GRIB_DUMP_FLAG_NO_DATA))) - return; - - a->value_count(&count); - size = count; - - if (size == 1) { - dump_double(d, a, NULL); - return; - } - - type = a->get_native_type(); - switch (type) { - case GRIB_TYPE_LONG: - snprintf(stype, sizeof(stype), "%s", "long"); - break; - case GRIB_TYPE_DOUBLE: - snprintf(stype, sizeof(stype), "%s", "double"); - break; - default: - return; - } - - buf = (double*)grib_context_malloc(d->context, size * sizeof(double)); - if (!buf) { - fprintf(self->dumper.out, "/* %s: cannot malloc(%zu) */\n", a->name_, size); - return; - } - - err = a->unpack_double(buf, &size); - - if (err) { - grib_context_free(d->context, buf); - fprintf(self->dumper.out, " /* Error accessing %s (%s) */", a->name_, grib_get_error_message(err)); - return; - } - - fprintf(self->dumper.out, " size = %zu;\n", size); - fprintf(self->dumper.out, " v%s = (%s*)calloc(size,sizeof(%s));\n", stype, stype, stype); - fprintf(self->dumper.out, " if(!v%s) {\n", stype); - fprintf(self->dumper.out, " fprintf(stderr,\"failed to allocate %%zu bytes\\n\",size*sizeof(%s));\n", stype); - fprintf(self->dumper.out, " exit(1);\n"); - fprintf(self->dumper.out, " }\n"); - - - fprintf(self->dumper.out, "\n "); - k = 0; - while (k < size) { - fprintf(self->dumper.out, " v%s[%4d] = %7g;", stype, k, buf[k]); - k++; - if (k % 4 == 0) - fprintf(self->dumper.out, "\n "); - } - if (size % 4) - fprintf(self->dumper.out, "\n"); - fprintf(self->dumper.out, "\n"); - fprintf(self->dumper.out, " GRIB_CHECK(grib_set_%s_array(h,\"%s\",v%s,size),%d);\n", stype, a->name_, stype, 0); - fprintf(self->dumper.out, " free(v%s);\n", stype); - - grib_context_free(d->context, buf); -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_grib_encode_C* self = (grib_dumper_grib_encode_C*)d; - fprintf(self->dumper.out, "\n /* %s */\n\n", a->name_); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - /*grib_dumper_grib_encode_C *self = (grib_dumper_grib_encode_C*)d;*/ - grib_dump_accessors_block(d, block); -} - -static void header(grib_dumper* d, grib_handle* h) -{ - long edition = 0; - int ret = 0; - grib_dumper_grib_encode_C* self = (grib_dumper_grib_encode_C*)d; - ret = grib_get_long(h, "editionNumber", &edition); - if (ret != GRIB_SUCCESS) { - grib_context_log(h->context, GRIB_LOG_ERROR, "Unable to get edition number."); - Assert(0); - } - - fprintf(self->dumper.out, - "#include \n" - "\n" - "/* This code was generated automatically */\n" - "\n"); - - fprintf(self->dumper.out, - "\n" - "int main(int argc,const char** argv)\n" - "{\n" - " grib_handle *h = NULL;\n" - " size_t size = 0;\n" - " double* vdouble = NULL;\n" - " long* vlong = NULL;\n" - " FILE* f = NULL;\n" - " const char* p = NULL;\n" - " const void* buffer = NULL;\n" - "\n" - " if(argc != 2) {\n" - " fprintf(stderr,\"usage: %%s out\\n\",argv[0]);\n" - " exit(1);\n" - " }\n" - "\n" - " h = grib_handle_new_from_samples(NULL,\"GRIB%ld\");\n" - " if(!h) {\n" - " fprintf(stderr,\"Cannot create grib handle\\n\");\n" - " exit(1);\n" - " }\n" - "\n", - (long)edition); -} - -static void footer(grib_dumper* d, grib_handle* h) -{ - grib_dumper_grib_encode_C* self = (grib_dumper_grib_encode_C*)d; - - fprintf(self->dumper.out, - "/* Save the message */\n" - "\n" - " f = fopen(argv[1],\"w\");\n" - " if(!f) {\n" - " perror(argv[1]);\n" - " exit(1);\n" - " }\n" - "\n" - " GRIB_CHECK(grib_get_message(h,&buffer,&size),0);\n" - "\n" - " if(fwrite(buffer,1,size,f) != size) {\n" - " perror(argv[1]);\n" - " exit(1);\n" - " }\n" - "\n" - " if(fclose(f)) {\n" - " perror(argv[1]);\n" - " exit(1);\n" - " }\n" - "\n" - " grib_handle_delete(h);\n" - " return 0;\n" - "}\n"); -} diff --git a/src/grib_dumper_class_json.cc b/src/grib_dumper_class_json.cc deleted file mode 100644 index c7cdbbe80..000000000 --- a/src/grib_dumper_class_json.cc +++ /dev/null @@ -1,601 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - MEMBERS = long section_offset - MEMBERS = long begin - MEMBERS = long empty - MEMBERS = long end - MEMBERS = long isLeaf - MEMBERS = long isAttribute - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); - -typedef struct grib_dumper_json { - grib_dumper dumper; - /* Members defined in json */ - long section_offset; - long begin; - long empty; - long end; - long isLeaf; - long isAttribute; -} grib_dumper_json; - - -static grib_dumper_class _grib_dumper_class_json = { - 0, /* super */ - "json", /* name */ - sizeof(grib_dumper_json), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - 0, /* header */ - 0, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_json = &_grib_dumper_class_json; - -/* END_CLASS_IMP */ -static void dump_attributes(grib_dumper* d, grib_accessor* a); - -static int depth = 0; - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_json* self = (grib_dumper_json*)d; - self->section_offset = 0; - self->empty = 1; - self->isLeaf = 0; - self->isAttribute = 0; - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - return GRIB_SUCCESS; -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_json* self = (grib_dumper_json*)d; - double value = 0; - size_t size = 1, size2 = 0; - double* values = NULL; - int err = 0; - int i; - int cols = 9; - long count = 0; - double missing_value = GRIB_MISSING_DOUBLE; - grib_handle* h = NULL; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - h = grib_handle_of_accessor(a); - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (double*)grib_context_malloc_clear(a->context_, sizeof(double) * size); - err = a->unpack_double(values, &size2); - } - else { - err = a->unpack_double(&value, &size2); - } - Assert(size2 == size); - (void)err; /* TODO */ - - if (self->begin == 0 && self->empty == 0 && self->isAttribute == 0) - fprintf(self->dumper.out, ","); - else - self->begin = 0; - - self->empty = 0; - - if (self->isLeaf == 0) { - fprintf(self->dumper.out, "\n%-*s{\n", depth, " "); - depth += 2; - fprintf(self->dumper.out, "%-*s", depth, " "); - fprintf(self->dumper.out, "\"key\" : \"%s\",\n", a->name_); - } - - err = grib_set_double(h, "missingValue", missing_value); - if (size > 1) { - int icount = 0; - if (self->isLeaf == 0) { - fprintf(self->dumper.out, "%-*s", depth, " "); - fprintf(self->dumper.out, "\"value\" :\n"); - } - fprintf(self->dumper.out, "%-*s[", depth, " "); - depth += 2; - for (i = 0; i < size - 1; ++i) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n%-*s", depth, " "); - icount = 0; - } - if (values[i] == missing_value) - fprintf(self->dumper.out, "null, "); - else - fprintf(self->dumper.out, "%g, ", values[i]); - icount++; - } - if (icount > cols) - fprintf(self->dumper.out, "\n%-*s", depth, " "); - if (grib_is_missing_double(a, values[i])) - fprintf(self->dumper.out, "%s ", "null"); - else - fprintf(self->dumper.out, "%g ", values[i]); - - depth -= 2; - fprintf(self->dumper.out, "\n%-*s]", depth, " "); - /* if (a->attributes_[0]) fprintf(self->dumper.out,","); */ - grib_context_free(a->context_, values); - } - else { - if (self->isLeaf == 0) { - fprintf(self->dumper.out, "%-*s", depth, " "); - fprintf(self->dumper.out, "\"value\" : "); - } - if (grib_is_missing_double(a, value)) - fprintf(self->dumper.out, "null"); - else - fprintf(self->dumper.out, "%g", value); - } - - if (self->isLeaf == 0) { - dump_attributes(d, a); - depth -= 2; - fprintf(self->dumper.out, "\n%-*s}", depth, " "); - } - - (void)err; /* TODO */ -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_json* self = (grib_dumper_json*)d; - long value = 0; - size_t size = 1, size2 = 0; - long* values = NULL; - int err = 0; - int i; - int cols = 9; - long count = 0; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - a->value_count(&count); - size = size2 = count; - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size2); - } - else { - err = a->unpack_long(&value, &size2); - } - Assert(size2 == size); - - if (self->begin == 0 && self->empty == 0 && self->isAttribute == 0) - fprintf(self->dumper.out, ","); - else - self->begin = 0; - - self->empty = 0; - - if (self->isLeaf == 0) { - fprintf(self->dumper.out, "\n%-*s{\n", depth, " "); - depth += 2; - fprintf(self->dumper.out, "%-*s", depth, " "); - fprintf(self->dumper.out, "\"key\" : \"%s\",\n", a->name_); - } - - if (size > 1) { - int doing_unexpandedDescriptors = 0; - int icount = 0; - if (self->isLeaf == 0) { - fprintf(self->dumper.out, "%-*s", depth, " "); - fprintf(self->dumper.out, "\"value\" :\n"); - } - fprintf(self->dumper.out, "%-*s[", depth, " "); - /* See ECC-637: unfortunately json_xs says: - * malformed number (leading zero must not be followed by another digit - if (strcmp(a->name_, "unexpandedDescriptors")==0) - doing_unexpandedDescriptors = 1; - */ - depth += 2; - for (i = 0; i < size - 1; i++) { - if (icount > cols || i == 0) { - fprintf(self->dumper.out, "\n%-*s", depth, " "); - icount = 0; - } - if (grib_is_missing_long(a, values[i])) { - fprintf(self->dumper.out, "null, "); - } - else { - if (doing_unexpandedDescriptors) - fprintf(self->dumper.out, "%06ld, ", values[i]); - else - fprintf(self->dumper.out, "%ld, ", values[i]); - } - icount++; - } - if (icount > cols) - fprintf(self->dumper.out, "\n%-*s", depth, " "); - if (doing_unexpandedDescriptors) { - fprintf(self->dumper.out, "%06ld ", values[i]); - } else { - if (grib_is_missing_long(a, values[i])) - fprintf(self->dumper.out, "%s", "null"); - else - fprintf(self->dumper.out, "%ld ", values[i]); - } - - depth -= 2; - fprintf(self->dumper.out, "\n%-*s]", depth, " "); - /* if (a->attributes_[0]) fprintf(self->dumper.out,","); */ - grib_context_free(a->context_, values); - } - else { - if (self->isLeaf == 0) { - fprintf(self->dumper.out, "%-*s", depth, " "); - fprintf(self->dumper.out, "\"value\" : "); - } - if (grib_is_missing_long(a, value)) - fprintf(self->dumper.out, "null"); - else - fprintf(self->dumper.out, "%ld", value); - /* if (a->attributes_[0]) fprintf(self->dumper.out,","); */ - } - - if (self->isLeaf == 0) { - dump_attributes(d, a); - depth -= 2; - fprintf(self->dumper.out, "\n%-*s}", depth, " "); - } - (void)err; /* TODO */ -} - -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) -{ - grib_dumper_json* self = (grib_dumper_json*)d; - double value = 0; - size_t size = 1; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - a->unpack_double(&value, &size); - - if (self->begin == 0 && self->empty == 0 && self->isAttribute == 0) - fprintf(self->dumper.out, ",\n"); - else - self->begin = 0; - - self->empty = 0; - - if (self->isLeaf == 0) { - fprintf(self->dumper.out, "%-*s{\n", depth, " "); - depth += 2; - fprintf(self->dumper.out, "%-*s", depth, " "); - fprintf(self->dumper.out, "\"key\" : \"%s\",\n", a->name_); - - fprintf(self->dumper.out, "%-*s", depth, " "); - fprintf(self->dumper.out, "\"value\" : "); - } - - if (grib_is_missing_double(a, value)) - fprintf(self->dumper.out, "null"); - else - fprintf(self->dumper.out, "%g", value); - - /* if (a->attributes_[0]) fprintf(self->dumper.out,","); */ - - if (self->isLeaf == 0) { - dump_attributes(d, a); - depth -= 2; - fprintf(self->dumper.out, "\n%-*s}", depth, " "); - } -} - -static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_json* self = (grib_dumper_json*)d; - char** values = NULL; - size_t size = 0, i = 0; - grib_context* c = NULL; - int err = 0; - int is_missing = 0; - long count = 0; - c = a->context_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - - a->value_count(&count); - size = count; - if (size == 1) { - dump_string(d, a, comment); - return; - } - - if (self->begin == 0 && self->empty == 0 && self->isAttribute == 0) - fprintf(self->dumper.out, ","); - else - self->begin = 0; - - if (self->isLeaf == 0) { - fprintf(self->dumper.out, "\n%-*s{\n", depth, " "); - depth += 2; - fprintf(self->dumper.out, "%-*s", depth, " "); - fprintf(self->dumper.out, "\"key\" : \"%s\",\n", a->name_); - } - - self->empty = 0; - - values = (char**)grib_context_malloc_clear(c, size * sizeof(char*)); - if (!values) { - grib_context_log(c, GRIB_LOG_ERROR, "Memory allocation error: %zu bytes", size); - return; - } - - err = a->unpack_string_array(values, &size); - - if (self->isLeaf == 0) { - fprintf(self->dumper.out, "%-*s", depth, " "); - fprintf(self->dumper.out, "\"value\" : "); - } - fprintf(self->dumper.out, "\n%-*s[", depth, " "); - depth += 2; - for (i = 0; i < size - 1; i++) { - is_missing = grib_is_missing_string(a, (unsigned char*)values[i], strlen(values[i])); - if (is_missing) fprintf(self->dumper.out, "%-*s%s,\n", depth, " ", "null"); - else fprintf(self->dumper.out, "%-*s\"%s\",\n", depth, " ", values[i]); - } - is_missing = grib_is_missing_string(a, (unsigned char*)values[i], strlen(values[i])); - if (is_missing) fprintf(self->dumper.out, "%-*s%s", depth, " ", "null"); - else fprintf(self->dumper.out, "%-*s\"%s\"", depth, " ", values[i]); - - depth -= 2; - fprintf(self->dumper.out, "\n%-*s]", depth, " "); - - /* if (a->attributes_[0]) fprintf(self->dumper.out,","); */ - - if (self->isLeaf == 0) { - dump_attributes(d, a); - depth -= 2; - fprintf(self->dumper.out, "\n%-*s}", depth, " "); - } - - for (i = 0; i < size; i++) { - grib_context_free(c, values[i]); - } - grib_context_free(c, values); - (void)err; /* TODO */ -} - -#define MAX_STRING_SIZE 4096 -static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_json* self = (grib_dumper_json*)d; - char value[MAX_STRING_SIZE] = {0,}; /* See ECC-710 */ - size_t size = MAX_STRING_SIZE; - char* p = NULL; - int is_missing = 0; - int err = 0; - const char* acc_name = a->name_; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { - return; - } - - /* ECC-710: It is MUCH slower determining the string length here - * than using a maximum size (and no need for malloc). - * Specially for BUFR elements */ - /* err = grib_get_string_length_acc(a,&size); - * if (size==0) return; - * value=(char*)grib_context_malloc_clear(a->context_,size); - * if (!value) { - * grib_context_log(a->context_,GRIB_LOG_ERROR,"Unable to allocate %zu bytes",size); - * return; - * } - */ - - if (self->begin == 0 && self->empty == 0 && self->isAttribute == 0) - fprintf(self->dumper.out, ","); - else - self->begin = 0; - - self->empty = 0; - - err = a->unpack_string(value, &size); - if (err) { - snprintf(value, sizeof(value), " *** ERR=%d (%s) [dump_string on '%s']", - err, grib_get_error_message(err), a->name_); - } else { - Assert(size < MAX_STRING_SIZE); - } - p = value; - if (grib_is_missing_string(a, (unsigned char*)value, size)) { - is_missing = 1; - } - - while (*p) { - if (!isprint(*p)) - *p = '?'; - if (*p == '"') - *p = '\''; /* ECC-1401 */ - p++; - } - - if (self->isLeaf == 0) { - fprintf(self->dumper.out, "\n%-*s{", depth, " "); - depth += 2; - fprintf(self->dumper.out, "\n%-*s", depth, " "); - fprintf(self->dumper.out, "\"key\" : \"%s\",", acc_name); - fprintf(self->dumper.out, "\n%-*s", depth, " "); - fprintf(self->dumper.out, "\"value\" : "); - } - if (is_missing) - fprintf(self->dumper.out, "%s", "null"); - else - fprintf(self->dumper.out, "\"%s\"", value); - - /* if (a->attributes_[0]) fprintf(self->dumper.out,","); */ - - if (self->isLeaf == 0) { - dump_attributes(d, a); - depth -= 2; - fprintf(self->dumper.out, "\n%-*s}", depth, " "); - } - - /* grib_context_free(a->context_,value); */ - (void)err; /* TODO */ -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_json* self = (grib_dumper_json*)d; - if (strcmp(a->name_, "BUFR")==0 || - strcmp(a->name_, "GRIB")==0 || - strcmp(a->name_, "META")==0) { - depth = 2; - fprintf(self->dumper.out, "%-*s", depth, " "); - fprintf(self->dumper.out, "[\n"); - self->begin = 1; - self->empty = 1; - depth += 2; - grib_dump_accessors_block(d, block); - depth -= 2; - fprintf(self->dumper.out, "\n]\n"); - } - else if (strcmp(a->name_, "groupNumber")==0) { - if ((a->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) - return; - if (!self->empty) - fprintf(self->dumper.out, ",\n"); - fprintf(self->dumper.out, "%-*s", depth, " "); - - fprintf(self->dumper.out, "["); - - fprintf(self->dumper.out, "\n"); - /* fprintf(self->dumper.out,"%-*s",depth," "); */ - self->begin = 1; - self->empty = 1; - depth += 2; - grib_dump_accessors_block(d, block); - depth -= 2; - fprintf(self->dumper.out, "\n"); - fprintf(self->dumper.out, "%-*s", depth, " "); - fprintf(self->dumper.out, "]"); - } - else { - grib_dump_accessors_block(d, block); - } -} - -static void dump_attributes(grib_dumper* d, grib_accessor* a) -{ - int i = 0; - grib_dumper_json* self = (grib_dumper_json*)d; - FILE* out = self->dumper.out; - unsigned long flags; - while (i < MAX_ACCESSOR_ATTRIBUTES && a->attributes_[i]) { - self->isAttribute = 1; - if ((d->option_flags & GRIB_DUMP_FLAG_ALL_ATTRIBUTES) == 0 && (a->attributes_[i]->flags_ & GRIB_ACCESSOR_FLAG_DUMP) == 0) { - i++; - continue; - } - self->isLeaf = a->attributes_[i]->attributes_[0] == NULL ? 1 : 0; - fprintf(self->dumper.out, ","); - fprintf(self->dumper.out, "\n%-*s", depth, " "); - fprintf(out, "\"%s\" : ", a->attributes_[i]->name_); - flags = a->attributes_[i]->flags_; - a->attributes_[i]->flags_ |= GRIB_ACCESSOR_FLAG_DUMP; - switch (a->attributes_[i]->get_native_type()) { - case GRIB_TYPE_LONG: - dump_long(d, a->attributes_[i], 0); - break; - case GRIB_TYPE_DOUBLE: - dump_values(d, a->attributes_[i]); - break; - case GRIB_TYPE_STRING: - dump_string_array(d, a->attributes_[i], 0); - break; - } - a->attributes_[i]->flags_ = flags; - i++; - } - self->isLeaf = 0; - self->isAttribute = 0; -} diff --git a/src/grib_dumper_class_serialize.cc b/src/grib_dumper_class_serialize.cc deleted file mode 100644 index 11844997e..000000000 --- a/src/grib_dumper_class_serialize.cc +++ /dev/null @@ -1,423 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - MEMBERS = char* format - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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_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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); - -typedef struct grib_dumper_serialize { - grib_dumper dumper; - /* Members defined in serialize */ - char* format; -} grib_dumper_serialize; - - -static grib_dumper_class _grib_dumper_class_serialize = { - 0, /* super */ - "serialize", /* name */ - sizeof(grib_dumper_serialize), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - 0, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - 0, /* header */ - 0, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_serialize = &_grib_dumper_class_serialize; - -/* END_CLASS_IMP */ -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_serialize* self = (grib_dumper_serialize*)d; - self->format = (char*)d->arg; - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - return GRIB_SUCCESS; -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_serialize* self = (grib_dumper_serialize*)d; - long value = 0; - size_t size = 1; - int err = a->unpack_long(&value, &size); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0) - return; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && - (d->option_flags & GRIB_DUMP_FLAG_READ_ONLY) == 0 && - (strcmp(a->class_name_, "lookup") != 0)) - return; - - if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && (value == GRIB_MISSING_LONG)) - fprintf(self->dumper.out, "%s = MISSING", a->name_); - else - fprintf(self->dumper.out, "%s = %ld", a->name_, value); - - if (((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) && - (strcmp(a->class_name_, "lookup") != 0)) - fprintf(self->dumper.out, " (read_only)"); - - //if(comment) fprintf(self->dumper.out," [%s]",comment); - - if (err) - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_serialize::dump_long]", err, grib_get_error_message(err)); - - fprintf(self->dumper.out, "\n"); -} - -//static int test_bit(long a, long b) {return a&(1<unpack_long(&value, &size); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0) - return; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && - (d->option_flags & GRIB_DUMP_FLAG_READ_ONLY) == 0) - return; - - fprintf(self->dumper.out, "%s = %ld ", a->name_, value); - - // fprintf(self->dumper.out,"["); - // for(i=0;i<(a->length_*8);i++) { - // if(test_bit(value,a->length_*8-i-1)) - // fprintf(self->dumper.out,"1"); - // else - // fprintf(self->dumper.out,"0"); - // } - - // if(comment) - // fprintf(self->dumper.out,":%s]",comment); - // else - // fprintf(self->dumper.out,"]"); - - if (err) - fprintf(self->dumper.out, " *** ERR=%d (%s)", err, grib_get_error_message(err)); - - fprintf(self->dumper.out, "\n"); -} - -static void dump_double(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_serialize* self = (grib_dumper_serialize*)d; - double value; - size_t size = 1; - int err = a->unpack_double(&value, &size); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0) - return; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && - (d->option_flags & GRIB_DUMP_FLAG_READ_ONLY) == 0) - return; - - if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && (value == GRIB_MISSING_DOUBLE)) - fprintf(self->dumper.out, "%s = MISSING", a->name_); - else - fprintf(self->dumper.out, "%s = %g", a->name_, value); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - fprintf(self->dumper.out, " (read_only)"); - - //if (comment) fprintf(self->dumper.out," [%s]",comment); - - if (err) - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_serialize::dump_double]", err, grib_get_error_message(err)); - fprintf(self->dumper.out, "\n"); -} - -static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_serialize* self = (grib_dumper_serialize*)d; - char value[1024] = {0,}; - size_t size = sizeof(value); - int err = a->unpack_string(value, &size); - int i; - - char* p = value; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0) - return; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && - (d->option_flags & GRIB_DUMP_FLAG_READ_ONLY) == 0) - return; - - while (*p) { - if (!isprint(*p)) - *p = '.'; - p++; - } - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - - fprintf(self->dumper.out, "%s = %s", a->name_, value); - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) - fprintf(self->dumper.out, " (read_only)"); - - // if(comment) fprintf(self->dumper.out," [%s]",comment); - - if (err) - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_serialize::dump_string]", err, grib_get_error_message(err)); - fprintf(self->dumper.out, "\n"); -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_serialize* self = (grib_dumper_serialize*)d; - int i, k, err = 0; - size_t more = 0; - size_t size = a->length_; - unsigned char* buf = (unsigned char*)grib_context_malloc(d->context, size); - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_HIDDEN) != 0) - return; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && - (d->option_flags & GRIB_DUMP_FLAG_READ_ONLY) == 0) - return; - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "%s = (%ld) {", a->name_, a->length_); - - if (!buf) { - if (size == 0) - fprintf(self->dumper.out, "}\n"); - else - fprintf(self->dumper.out, " *** ERR cannot malloc(%zu) }\n", size); - return; - } - - fprintf(self->dumper.out, "\n"); - - err = a->unpack_bytes(buf, &size); - if (err) { - grib_context_free(d->context, buf); - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_serialize::dump_bytes]\n}", err, grib_get_error_message(err)); - return; - } - - if (size > 100) { - more = size - 100; - size = 100; - } - - k = 0; - /* if(size > 100) size = 100; */ - while (k < size) { - int j; - for (i = 0; i < d->depth + 3; i++) - fprintf(self->dumper.out, " "); - for (j = 0; j < 16 && k < size; j++, k++) { - fprintf(self->dumper.out, "%02x", buf[k]); - if (k != size - 1) - fprintf(self->dumper.out, ", "); - } - fprintf(self->dumper.out, "\n"); - } - - if (more) { - for (i = 0; i < d->depth + 3; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "... %lu more values\n", (unsigned long)more); - } - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "} # %s %s \n", a->creator_->op, a->name_); - grib_context_free(d->context, buf); -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_serialize* self = (grib_dumper_serialize*)d; - int k, err = 0; - double* buf = NULL; - size_t last = 0; - int columns = 4; - char* values_format = NULL; - char* default_format = (char*)"%.16e"; - char* columns_str = NULL; - size_t len = 0; - char* pc = NULL; - char* pcf = NULL; - size_t size = 0; - long count = 0; - values_format = default_format; - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY)) - return; - - a->value_count(&count); - size = count; - - if (self->format) { - if (self->format[0] == '\"') - values_format = self->format + 1; - else - values_format = self->format; - last = strlen(values_format) - 1; - if (values_format[last] == '\"') - values_format[last] = '\0'; - } - - pc = values_format; - pcf = values_format; - while (*pc != '\0' && *pc != '%') - pc++; - if (strlen(pc) > 1) { - values_format = pc; - len = pc - pcf; - } - else { - values_format = default_format; - len = 0; - } - - if (len > 0) { - columns_str = (char*)malloc((len + 1) * sizeof(char)); - Assert(columns_str); - columns_str = (char*)memcpy(columns_str, pcf, len); - columns_str[len] = '\0'; - columns = atoi(columns_str); - free(columns_str); - } - - if (size == 1) { - dump_double(d, a, NULL); - return; - } - - if ((d->option_flags & GRIB_DUMP_FLAG_VALUES) == 0) - return; - - buf = (double*)grib_context_malloc(d->context, size * sizeof(double)); - - fprintf(self->dumper.out, "%s (%zu) {", a->name_, size); - - if (!buf) { - if (size == 0) - fprintf(self->dumper.out, "}\n"); - else - fprintf(self->dumper.out, " *** ERR cannot malloc(%zu) }\n", size); - return; - } - - fprintf(self->dumper.out, "\n"); - - err = a->unpack_double(buf, &size); - - if (err) { - grib_context_free(d->context, buf); - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_serialize::dump_values]\n}", err, grib_get_error_message(err)); - return; - } - - k = 0; - while (k < size) { - int j; - for (j = 0; j < columns && k < size; j++, k++) { - fprintf(self->dumper.out, values_format, buf[k]); - if (k != size - 1) - fprintf(self->dumper.out, ", "); - } - fprintf(self->dumper.out, "\n"); - } - fprintf(self->dumper.out, "}\n"); - grib_context_free(d->context, buf); -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ - // grib_dumper_serialize *self = (grib_dumper_serialize*)d; - // int i; - // for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," "); - // fprintf(self->dumper.out,"----> %s %s %s\n",a->creator_->op, a->name_,comment?comment:""); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - const char* secstr = "section"; - grib_dumper_serialize* self = (grib_dumper_serialize*)d; - - size_t len = strlen(secstr); - - if (a->name_[0] == '_') { - grib_dump_accessors_block(d, block); - return; - } - - if (strncmp(secstr, a->name_, len) == 0) - fprintf(self->dumper.out, "#------ %s -------\n", a->name_); - - grib_dump_accessors_block(d, block); - - //fprintf(self->dumper.out,"<------ %s %s\n",a->creator_->op, a->name_); -} diff --git a/src/grib_dumper_class_wmo.cc b/src/grib_dumper_class_wmo.cc deleted file mode 100644 index 723a09eae..000000000 --- a/src/grib_dumper_class_wmo.cc +++ /dev/null @@ -1,660 +0,0 @@ -/* - * (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" -#include -/* - This is used by make_class.pl - - START_CLASS_DEF - CLASS = dumper - IMPLEMENTS = dump_long;dump_bits - IMPLEMENTS = dump_double;dump_string;dump_string_array - IMPLEMENTS = dump_bytes;dump_values - IMPLEMENTS = dump_label;dump_section - IMPLEMENTS = init;destroy - MEMBERS = long section_offset - MEMBERS = long begin - MEMBERS = long theEnd - 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 "dumper.class" and rerun ./make_class.pl - -*/ - -static void init_class (grib_dumper_class*); -static int init (grib_dumper* d); -static int destroy (grib_dumper*); -static void dump_long (grib_dumper* d, grib_accessor* a,const char* comment); -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); -static void dump_section (grib_dumper* d, grib_accessor* a,grib_block_of_accessors* block); - -typedef struct grib_dumper_wmo { - grib_dumper dumper; - /* Members defined in wmo */ - long section_offset; - long begin; - long theEnd; -} grib_dumper_wmo; - - -static grib_dumper_class _grib_dumper_class_wmo = { - 0, /* super */ - "wmo", /* name */ - sizeof(grib_dumper_wmo), /* size */ - 0, /* inited */ - &init_class, /* init_class */ - &init, /* init */ - &destroy, /* free mem */ - &dump_long, /* dump long */ - &dump_double, /* dump double */ - &dump_string, /* dump string */ - &dump_string_array, /* dump string array */ - &dump_label, /* dump labels */ - &dump_bytes, /* dump bytes */ - &dump_bits, /* dump bits */ - &dump_section, /* dump section */ - &dump_values, /* dump values */ - 0, /* header */ - 0, /* footer */ -}; - -grib_dumper_class* grib_dumper_class_wmo = &_grib_dumper_class_wmo; - -/* END_CLASS_IMP */ -static void set_begin_end(grib_dumper* d, grib_accessor* a); -static void print_hexadecimal(FILE* out, unsigned long flags, grib_accessor* a); - -static void init_class(grib_dumper_class* c) {} - -static int init(grib_dumper* d) -{ - grib_dumper_wmo* self = (grib_dumper_wmo*)d; - self->section_offset = 0; - - return GRIB_SUCCESS; -} - -static int destroy(grib_dumper* d) -{ - return GRIB_SUCCESS; -} - -static void print_offset(FILE* out, long begin, long theEnd, int width=10) -{ - char tmp[50]; - - if (begin == theEnd) - fprintf(out, "%-*ld", width, begin); - else { - snprintf(tmp, sizeof(tmp), "%ld-%ld", begin, theEnd); - fprintf(out, "%-*s", width, tmp); - } -} - -static void aliases(grib_dumper* d, grib_accessor* a) -{ - int i; - grib_dumper_wmo* self = (grib_dumper_wmo*)d; - - if ((d->option_flags & GRIB_DUMP_FLAG_ALIASES) == 0) - return; - - if (a->all_names_[1]) { - const char* sep = ""; - fprintf(self->dumper.out, " ["); - - for (i = 1; i < MAX_ACCESSOR_NAMES; i++) { - if (a->all_names_[i]) { - if (a->all_name_spaces_[i]) - fprintf(self->dumper.out, "%s%s.%s", sep, a->all_name_spaces_[i], a->all_names_[i]); - else - fprintf(self->dumper.out, "%s%s", sep, a->all_names_[i]); - } - sep = ", "; - } - fprintf(self->dumper.out, "]"); - } -} - -static void dump_long(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_wmo* self = (grib_dumper_wmo*)d; - long value = 0; - size_t size = 0; - long* values = NULL; - int err = 0, i = 0; - long count = 0; - - if (a->length_ == 0 && - (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0) - return; - - a->value_count(&count); - size = count; - - if (size > 1) { - values = (long*)grib_context_malloc_clear(a->context_, sizeof(long) * size); - err = a->unpack_long(values, &size); - } - else { - err = a->unpack_long(&value, &size); - } - - if ((a->flags_ & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 && - (d->option_flags & GRIB_DUMP_FLAG_READ_ONLY) == 0) - return; - - set_begin_end(d, a); - - print_offset(self->dumper.out, self->begin, self->theEnd); - - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) - fprintf(self->dumper.out, "%s (int) ", a->creator_->op); - - if (size > 1) { - int cols = 19; - int icount = 0; - fprintf(self->dumper.out, "%s = { \t", a->name_); - if (values) { - for (i = 0; i < size; i++) { - if (icount > cols) { - fprintf(self->dumper.out, "\n\t\t\t\t"); - icount = 0; - } - fprintf(self->dumper.out, "%ld ", values[i]); - icount++; - } - fprintf(self->dumper.out, "}\n"); - grib_context_free(a->context_, values); - } - } - else { - if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) - fprintf(self->dumper.out, "%s = MISSING", a->name_); - else - fprintf(self->dumper.out, "%s = %ld", a->name_, value); - - print_hexadecimal(self->dumper.out, d->option_flags, a); - - if (comment) - fprintf(self->dumper.out, " [%s]", comment); - } - if (err) - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_wmo::dump_long]", err, grib_get_error_message(err)); - - aliases(d, a); - - - fprintf(self->dumper.out, "\n"); -} - -static int test_bit(long a, long b) -{ - return a & (1 << b); -} - -static void dump_bits(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_wmo* self = (grib_dumper_wmo*)d; - long value = 0; - size_t size = 1; - int err = 0; - - if (a->length_ == 0 && - (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0) - return; - - err = a->unpack_long(&value, &size); - set_begin_end(d, a); - - //for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," "); - print_offset(self->dumper.out, self->begin, self->theEnd); - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) - fprintf(self->dumper.out, "%s (int) ", a->creator_->op); - - fprintf(self->dumper.out, "%s = %ld [", a->name_, value); - - for (long i = 0; i < (a->length_ * 8); i++) { - if (test_bit(value, a->length_ * 8 - i - 1)) - fprintf(self->dumper.out, "1"); - else - fprintf(self->dumper.out, "0"); - } - - if(comment) { - // ECC-1186: Whole comment is too big, so pick the part that follows the ':' i.e. flag table file - const char* p = strchr(comment, ':'); - if (p) fprintf(self->dumper.out," (%s) ]", p+1); - else fprintf(self->dumper.out, "]"); - } else { - fprintf(self->dumper.out, "]"); - } - - if (err == 0) - print_hexadecimal(self->dumper.out, d->option_flags, a); - - if (err) - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_wmo::dump_bits]", err, grib_get_error_message(err)); - - aliases(d, a); - fprintf(self->dumper.out, "\n"); -} - -static void dump_double(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_wmo* self = (grib_dumper_wmo*)d; - double value = 0; - size_t size = 1; - int err = 0; - - if (a->length_ == 0 && - (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0) - return; - - err = a->unpack_double(&value, &size); - set_begin_end(d, a); - - //for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," "); - - print_offset(self->dumper.out, self->begin, self->theEnd); - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) - fprintf(self->dumper.out, "%s (double) ", a->creator_->op); - - if (((a->flags_ & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && a->is_missing_internal()) - fprintf(self->dumper.out, "%s = MISSING", a->name_); - else - fprintf(self->dumper.out, "%s = %g", a->name_, value); - // if(comment) fprintf(self->dumper.out," [%s]",comment); - - if (err == 0) - print_hexadecimal(self->dumper.out, d->option_flags, a); - - if (err) - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_wmo::dump_double]", err, grib_get_error_message(err)); - aliases(d, a); - fprintf(self->dumper.out, "\n"); -} - -static void dump_string(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_wmo* self = (grib_dumper_wmo*)d; - size_t size = 0; - char* value = NULL; - char* p = NULL; - int err = 0; - - if (a->length_ == 0 && - (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0) { - return; - } - - grib_get_string_length_acc(a, &size); - value = (char*)grib_context_malloc_clear(a->context_, size); - if (!value) { - grib_context_log(a->context_, GRIB_LOG_ERROR, "unable to allocate %zu bytes", size); - return; - } - err = a->unpack_string(value, &size); - p = value; - - set_begin_end(d, a); - - while (*p) { - if (!isprint(*p)) - *p = '.'; - p++; - } - - //for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," "); - print_offset(self->dumper.out, self->begin, self->theEnd); - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) - fprintf(self->dumper.out, "%s (str) ", a->creator_->op); - - fprintf(self->dumper.out, "%s = %s", a->name_, value); - - if (err == 0) - print_hexadecimal(self->dumper.out, d->option_flags, a); - - // if(comment) fprintf(self->dumper.out," [%s]",comment); - if (err) - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_wmo::dump_string]", err, grib_get_error_message(err)); - aliases(d, a); - fprintf(self->dumper.out, "\n"); - grib_context_free(a->context_, value); -} - -static void dump_bytes(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_wmo* self = (grib_dumper_wmo*)d; - int i, k, err = 0; - size_t more = 0; - size_t size = a->length_; - unsigned char* buf = (unsigned char*)grib_context_malloc(d->context, size); - - if (a->length_ == 0 && - (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0) - return; - - set_begin_end(d, a); - - // for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," "); - print_offset(self->dumper.out, self->begin, self->theEnd); - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) - fprintf(self->dumper.out, "%s ", a->creator_->op); - - fprintf(self->dumper.out, "%s = %ld", a->name_, a->length_); - aliases(d, a); - fprintf(self->dumper.out, " {"); - - if (!buf) { - if (size == 0) - fprintf(self->dumper.out, "}\n"); - else - fprintf(self->dumper.out, " *** ERR cannot malloc(%zu) }\n", size); - return; - } - - print_hexadecimal(self->dumper.out, d->option_flags, a); - - fprintf(self->dumper.out, "\n"); - - err = a->unpack_bytes(buf, &size); - if (err) { - grib_context_free(d->context, buf); - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_wmo::dump_bytes]\n}", err, grib_get_error_message(err)); - return; - } - - if (size > 100) { - more = size - 100; - size = 100; - } - - k = 0; - // if(size > 100) size = 100; - while (k < size) { - int j; - for (i = 0; i < d->depth + 3; i++) - fprintf(self->dumper.out, " "); - for (j = 0; j < 16 && k < size; j++, k++) { - fprintf(self->dumper.out, "%02x", buf[k]); - if (k != size - 1) - fprintf(self->dumper.out, ", "); - } - fprintf(self->dumper.out, "\n"); - } - - if (more) { - for (i = 0; i < d->depth + 3; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "... %lu more values\n", (unsigned long)more); - } - - for (i = 0; i < d->depth; i++) - fprintf(self->dumper.out, " "); - fprintf(self->dumper.out, "} # %s %s \n", a->creator_->op, a->name_); - grib_context_free(d->context, buf); -} - -static void dump_values(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_wmo* self = (grib_dumper_wmo*)d; - int k, err = 0; - size_t more = 0; - double* buf = NULL; - size_t size = 0; - long count = 0; - int is_char = 0; - - if (a->length_ == 0 && - (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0) - return; - - a->value_count(&count); - size = count; - - if (size == 1) { - dump_double(d, a, NULL); - return; - } - buf = (double*)grib_context_malloc(d->context, size * sizeof(double)); - - set_begin_end(d, a); - - // For the DIAG pseudo GRIBs. Key charValues uses 1-byte integers to represent a character - if (a->flags_ & GRIB_ACCESSOR_FLAG_STRING_TYPE) { - is_char = 1; - } - - print_offset(self->dumper.out, self->begin, self->theEnd, 12); // ECC-1749 - if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) { - char type_name[32] = ""; - const long native_type = a->get_native_type(); - if (native_type == GRIB_TYPE_LONG) - strcpy(type_name, "(int)"); - else if (native_type == GRIB_TYPE_DOUBLE) - strcpy(type_name, "(double)"); - else if (native_type == GRIB_TYPE_STRING) - strcpy(type_name, "(str)"); - fprintf(self->dumper.out, "%s %s ", a->creator_->op, type_name); - } - - fprintf(self->dumper.out, "%s = (%ld,%ld)", a->name_, (long)size, a->length_); - aliases(d, a); - fprintf(self->dumper.out, " {"); - - if (!buf) { - if (size == 0) - fprintf(self->dumper.out, "}\n"); - else - fprintf(self->dumper.out, " *** ERR cannot malloc(%zu) }\n", size); - return; - } - - fprintf(self->dumper.out, "\n"); - - err = a->unpack_double(buf, &size); - - if (err) { - grib_context_free(d->context, buf); - fprintf(self->dumper.out, " *** ERR=%d (%s) [grib_dumper_wmo::dump_values]\n}", err, grib_get_error_message(err)); - return; - } - - if (size > 100) { - more = size - 100; - size = 100; - } - - k = 0; - while (k < size) { - int j; - for (j = 0; j < 8 && k < size; j++, k++) { - if (is_char) - fprintf(self->dumper.out, "'%c'", (char)buf[k]); - else - fprintf(self->dumper.out, "%.10e", buf[k]); - if (k != size - 1) - fprintf(self->dumper.out, ", "); - } - fprintf(self->dumper.out, "\n"); - // if (is_char) - // fprintf(self->dumper.out, "%d '%c'\n", k, (char)buf[k]); - // else - // fprintf(self->dumper.out, "%d %g\n", k, buf[k]); - } - if (more) { - //for(i = 0; i < d->depth + 3 ; i++) fprintf(self->dumper.out," "); - fprintf(self->dumper.out, "... %lu more values\n", (unsigned long)more); - } - - fprintf(self->dumper.out, "} # %s %s \n", a->creator_->op, a->name_); - grib_context_free(d->context, buf); -} - -static void dump_label(grib_dumper* d, grib_accessor* a, const char* comment) -{ -// grib_dumper_wmo *self = (grib_dumper_wmo*)d; -// for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," "); -// fprintf(self->dumper.out,"----> %s %s %s\n",a->creator_->op, a->name_,comment?comment:""); -} - -static void dump_section(grib_dumper* d, grib_accessor* a, grib_block_of_accessors* block) -{ - grib_dumper_wmo* self = (grib_dumper_wmo*)d; - grib_section* s = a->sub_section_; - int is_wmo_section = 0; - char* upper = NULL; - char tmp[512]; - char *p = NULL, *q = NULL; - if (!strncmp(a->name_, "section", 7)) - is_wmo_section = 1; - - if (is_wmo_section) { - upper = (char*)malloc(strlen(a->name_) + 1); - Assert(upper); - p = (char*)a->name_; - q = upper; - while (*p != '\0') { - *q = toupper(*p); - q++; - p++; - } - *q = '\0'; - snprintf(tmp, sizeof(tmp), "%s ( length=%ld, padding=%ld )", upper, (long)s->length, (long)s->padding); - fprintf(self->dumper.out, "====================== %-35s ======================\n", tmp); - free(upper); - self->section_offset = a->offset_; - } - else { - } - - //printf("------------- section_offset = %ld\n",self->section_offset); - d->depth += 3; - grib_dump_accessors_block(d, block); - d->depth -= 3; - - //for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," "); - //fprintf(self->dumper.out,"<===== %s %s\n",a->creator_->op, a->name_); -} - -static void set_begin_end(grib_dumper* d, grib_accessor* a) -{ - grib_dumper_wmo* self = (grib_dumper_wmo*)d; - if ((d->option_flags & GRIB_DUMP_FLAG_OCTET) != 0) { - self->begin = a->offset_ - self->section_offset + 1; - self->theEnd = a->get_next_position_offset() - self->section_offset; - } - else { - self->begin = a->offset_; - self->theEnd = a->get_next_position_offset(); - } -} - -static void print_hexadecimal(FILE* out, unsigned long flags, grib_accessor* a) -{ - int i = 0; - unsigned long offset = 0; - grib_handle* h = grib_handle_of_accessor(a); - if ((flags & GRIB_DUMP_FLAG_HEXADECIMAL) != 0 && a->length_ != 0) { - fprintf(out, " ("); - offset = a->offset_; - for (i = 0; i < a->length_; i++) { - fprintf(out, " 0x%.2X", h->buffer->data[offset]); - offset++; - } - fprintf(out, " )"); - } -} - -static void dump_string_array(grib_dumper* d, grib_accessor* a, const char* comment) -{ - grib_dumper_wmo* self = (grib_dumper_wmo*)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; idepth_ = 0; + d->context_ = h->context; + d->option_flags_ = option_flags; + d->arg_ = arg; + d->out_ = out; + d->init(); + grib_context_log( + h->context, GRIB_LOG_DEBUG, "Creating dumper of type : %s ", op); + return d; + } + grib_context_log( + h->context, GRIB_LOG_ERROR, "Unknown type : '%s' for dumper", op); + return NULL; +} + +void grib_dump_content(const grib_handle *h, FILE *f, const char *mode, unsigned long flags, void *data) { + eccodes::Dumper *dumper; + dumper = grib_dumper_factory(mode ? mode : "serialize", h, f, flags, data); + if (!dumper) { + fprintf(stderr, "Here are some possible values for the dumper mode:\n"); + const size_t num_table_entries = sizeof(table) / sizeof(table[0]); + for (size_t i = 0; i < num_table_entries; i++) { + const char *t = table[i].type; + if (strstr(t, "bufr") == NULL && strstr(t, "grib") == NULL) { + fprintf(stderr, "\t%s\n", t); + } + } + return; + } + dumper->header(h); + grib_dump_accessors_block(dumper, h->root->block); + dumper->footer(h); + dumper->destroy(); +} + + +void grib_dump_accessors_block(eccodes::Dumper *dumper, grib_block_of_accessors *block) { + grib_accessor *a = block->first; + while (a) { + a->dump(dumper); + a = a->next_; + } +} + +void grib_dump_accessors_list(eccodes::Dumper *dumper, grib_accessors_list *al) { + grib_accessors_list *cur = al; + while (cur) { + cur->accessor->dump(dumper); + cur = cur->next_; + } +} + +int grib_print(grib_handle *h, const char *name, eccodes::Dumper *d) { + grib_accessor *act = grib_find_accessor(h, name); + if (act) { + act->dump(d); + return GRIB_SUCCESS; + } + return GRIB_NOT_FOUND; +} + + +void grib_dump_keys(grib_handle *h, FILE *f, const char *mode, unsigned long flags, void *data, const char **keys, size_t num_keys) +{ + size_t i; + grib_accessor *acc = NULL; + eccodes::Dumper *dumper = + grib_dumper_factory(mode ? mode : "serialize", h, f, flags, data); + if (!dumper) + return; + for (i = 0; i < num_keys; ++i) { + acc = grib_find_accessor(h, keys[i]); + if (acc) + acc->dump(dumper); + } + dumper->destroy(); +} + +/* Note: if the dumper passed in is non-NULL, it will be freed up */ +eccodes::Dumper *grib_dump_content_with_dumper(grib_handle *h, eccodes::Dumper *dumper, FILE *f, const char *mode, unsigned long flags, void *data) +{ + long count = 1; + if (dumper != NULL) { + count = dumper->count(); + count++; + dumper->destroy(); + } + dumper = grib_dumper_factory(mode ? mode : "serialize", h, f, flags, data); + if (!dumper) + return NULL; + dumper->count(count); + + dumper->header(h); + grib_dump_accessors_block(dumper, h->root->block); + dumper->footer(h); + return dumper; +} + +void codes_dump_bufr_flat(grib_accessors_list *al, grib_handle *h, FILE *f, const char *mode, unsigned long flags, void *data) +{ + eccodes::Dumper *dumper = NULL; + Assert(h->product_kind == PRODUCT_BUFR); + dumper = grib_dumper_factory(mode ? mode : "serialize", h, f, flags, data); + if (!dumper) + return; + dumper->header(h); + grib_dump_accessors_list(dumper, al); + dumper->footer(h); + dumper->destroy(); +} diff --git a/src/grib_dumper_factory.h b/src/grib_dumper_factory.h index 0b4135077..8322c1ac7 100644 --- a/src/grib_dumper_factory.h +++ b/src/grib_dumper_factory.h @@ -1,16 +1,43 @@ -/* This file is automatically generated by ./make_class.pl, do not edit */ -{ "bufr_decode_C", &grib_dumper_class_bufr_decode_C, }, -{ "bufr_decode_filter", &grib_dumper_class_bufr_decode_filter, }, -{ "bufr_decode_fortran", &grib_dumper_class_bufr_decode_fortran, }, -{ "bufr_decode_python", &grib_dumper_class_bufr_decode_python, }, -{ "bufr_encode_C", &grib_dumper_class_bufr_encode_C, }, -{ "bufr_encode_filter", &grib_dumper_class_bufr_encode_filter, }, -{ "bufr_encode_fortran", &grib_dumper_class_bufr_encode_fortran, }, -{ "bufr_encode_python", &grib_dumper_class_bufr_encode_python, }, -{ "bufr_simple", &grib_dumper_class_bufr_simple, }, -{ "debug", &grib_dumper_class_debug, }, -{ "default", &grib_dumper_class_default, }, -{ "grib_encode_C", &grib_dumper_class_grib_encode_C, }, -{ "json", &grib_dumper_class_json, }, -{ "serialize", &grib_dumper_class_serialize, }, -{ "wmo", &grib_dumper_class_wmo, }, +/* + * (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. + */ + +#pragma once + +#include "dumper/grib_dumper.h" + +extern eccodes::Dumper* grib_dumper_bufr_decode_c; +extern eccodes::Dumper* grib_dumper_bufr_decode_filter; +extern eccodes::Dumper* grib_dumper_bufr_decode_fortran; +extern eccodes::Dumper* grib_dumper_bufr_decode_python; +extern eccodes::Dumper* grib_dumper_bufr_encode_c; +extern eccodes::Dumper* grib_dumper_bufr_encode_filter; +extern eccodes::Dumper* grib_dumper_bufr_encode_fortran; +extern eccodes::Dumper* grib_dumper_bufr_encode_python; +extern eccodes::Dumper* grib_dumper_bufr_simple; +extern eccodes::Dumper* grib_dumper_debug; +extern eccodes::Dumper* grib_dumper_default; +extern eccodes::Dumper* grib_dumper_file; +extern eccodes::Dumper* grib_dumper_grib_encode_c; +extern eccodes::Dumper* grib_dumper_json; +extern eccodes::Dumper* grib_dumper_serialize; +extern eccodes::Dumper* grib_dumper_string; +extern eccodes::Dumper* grib_dumper_wmo; + +eccodes::Dumper* grib_dumper_factory(const char* op, const grib_handle* h, FILE* out, unsigned long option_flags, void* arg); +int grib_print(grib_handle* h, const char* name, eccodes::Dumper* d); +void grib_dump_keys(grib_handle* h, FILE* f, const char* mode, unsigned long flags, void* data, const char** keys, size_t num_keys); + +eccodes::Dumper* grib_dump_content_with_dumper(grib_handle* h, eccodes::Dumper* dumper, FILE* f, const char* mode, unsigned long flags, void* data); +void codes_dump_bufr_flat(grib_accessors_list* al, grib_handle* h, FILE* f, const char* mode, unsigned long flags, void* data); + +void grib_dump_accessors_block(eccodes::Dumper* dumper, grib_block_of_accessors* block); +void grib_dump_accessors_list(eccodes::Dumper* dumper, grib_accessors_list* al); + +void grib_dump_content(const grib_handle* h, FILE* f, const char* mode, unsigned long flags, void* data); diff --git a/src/grib_expression_class_unop.cc b/src/grib_expression_class_unop.cc index 18eb073fb..3bbf657e7 100644 --- a/src/grib_expression_class_unop.cc +++ b/src/grib_expression_class_unop.cc @@ -40,30 +40,31 @@ or edit "expression.class" and rerun ./make_class.pl typedef const char* string; /* to keep make_class.pl happy */ -static void destroy(grib_context*,grib_expression* e); -static void print(grib_context*, grib_expression*, grib_handle*, FILE*); -static void add_dependency(grib_expression* e, grib_accessor* observer); -static string get_name(grib_expression* e); -static int native_type(grib_expression*,grib_handle*); -static int evaluate_long(grib_expression*,grib_handle*,long*); -static int evaluate_double(grib_expression*,grib_handle*,double*); - -typedef struct grib_expression_unop{ - grib_expression base; +static void destroy(grib_context*, grib_expression* e); +static void print(grib_context*, grib_expression*, grib_handle*, FILE*); +static void add_dependency(grib_expression* e, grib_accessor* observer); +static string get_name(grib_expression* e); +static int native_type(grib_expression*, grib_handle*); +static int evaluate_long(grib_expression*, grib_handle*, long*); +static int evaluate_double(grib_expression*, grib_handle*, double*); + +typedef struct grib_expression_unop +{ + grib_expression base; /* Members defined in unop */ - grib_expression *exp; - grib_unop_long_proc long_func; - grib_unop_double_proc double_func; + grib_expression* exp; + grib_unop_long_proc long_func; + grib_unop_double_proc double_func; } grib_expression_unop; static grib_expression_class _grib_expression_class_unop = { - 0, /* super */ - "unop", /* name */ - sizeof(grib_expression_unop),/* size of instance */ - 0, /* inited */ - 0, /* constructor */ - &destroy, /* destructor */ + 0, /* super */ + "unop", /* name */ + sizeof(grib_expression_unop), /* size of instance */ + 0, /* inited */ + 0, /* constructor */ + &destroy, /* destructor */ &print, &add_dependency, &native_type, @@ -79,9 +80,9 @@ grib_expression_class* grib_expression_class_unop = &_grib_expression_class_unop static int evaluate_long(grib_expression* g, grib_handle* h, long* lres) { - long v = 0; + long v = 0; grib_expression_unop* e = (grib_expression_unop*)g; - int ret = grib_expression_evaluate_long(h, e->exp, &v); + int ret = grib_expression_evaluate_long(h, e->exp, &v); if (ret != GRIB_SUCCESS) return ret; *lres = e->long_func(v); @@ -90,9 +91,9 @@ static int evaluate_long(grib_expression* g, grib_handle* h, long* lres) static int evaluate_double(grib_expression* g, grib_handle* h, double* dres) { - double v = 0; + double v = 0; grib_expression_unop* e = (grib_expression_unop*)g; - int ret = grib_expression_evaluate_double(h, e->exp, &v); + int ret = grib_expression_evaluate_double(h, e->exp, &v); if (ret != GRIB_SUCCESS) return ret; *dres = e->double_func ? e->double_func(v) : e->long_func(v); diff --git a/src/grib_ibmfloat.h b/src/grib_ibmfloat.h index e521076f5..1b55a2a50 100644 --- a/src/grib_ibmfloat.h +++ b/src/grib_ibmfloat.h @@ -32,23 +32,24 @@ The table layout is as follows: +-------+----------------+------------------------+ | idx (i) | multiplier (e) | value (v = mmin * e) | +-------+----------------+------------------------+ -| 0 | 16^(-70) | 0x100000 * 2^(-70) | -| 1 | 16^(-69) | 0x100000 * 2^(-69) | +| 0 | 16^(-70) | 0x100000 * 16^(-70) | +| 1 | 16^(-69) | 0x100000 * 16^(-69) | | ... | ... | ... | -| 126 | 16^56 | 0x100000 * 2^56 | -| 127 | 16^57 | 0x100000 * 2^57 | +| 126 | 16^56 | 0x100000 * 16^56 | +| 127 | 16^57 | 0x100000 * 16^57 | +-------+----------------+------------------------+ The vmin and vmax boundaries are defined as: -- vmin = 0x100000 * 2^(-70) -- vmax = 0xffffff * 2^57 +- vmin = 0x100000 * 16^(-70) +- vmax = 0xffffff * 16^57 */ -struct IbmTable { +struct IbmTable +{ private: - using ValueType = double; - static constexpr int TABLESIZE = 128; + using ValueType = double; + static constexpr int TABLESIZE = 128; static constexpr uint32_t mantissa_min = 0x100000; static constexpr uint32_t mantissa_max = 0xffffff; diff --git a/tools/bufr_dump.cc b/tools/bufr_dump.cc index bc11a8e8f..bc250eb37 100644 --- a/tools/bufr_dump.cc +++ b/tools/bufr_dump.cc @@ -9,6 +9,7 @@ */ #include "grib_tools.h" +#include "grib_dumper_factory.h" #include "accessor/grib_accessor_class_bufr_data_array.h" grib_option grib_options[] = { @@ -59,15 +60,15 @@ grib_option grib_options[] = { /* {"x",0,0,0,1,0} */ }; -const char* tool_description = "Dump the content of a BUFR file in different formats."; -const char* tool_name = "bufr_dump"; -const char* tool_online_doc = "https://confluence.ecmwf.int/display/ECC/bufr_dump"; -const char* tool_usage = "[options] bufr_file bufr_file ..."; -static int json = 0; -static int dump_descriptors = 0; -static char* json_option = 0; -static int first_handle = 1; -static grib_dumper* dumper = 0; +const char* tool_description = "Dump the content of a BUFR file in different formats."; +const char* tool_name = "bufr_dump"; +const char* tool_online_doc = "https://confluence.ecmwf.int/display/ECC/bufr_dump"; +const char* tool_usage = "[options] bufr_file bufr_file ..."; +static int json = 0; +static int dump_descriptors = 0; +static char* json_option = 0; +static int first_handle = 1; +static eccodes::Dumper* dumper = 0; int grib_options_count = sizeof(grib_options) / sizeof(grib_option); diff --git a/tools/grib_dump.cc b/tools/grib_dump.cc index bcc2def10..7227ca8fa 100644 --- a/tools/grib_dump.cc +++ b/tools/grib_dump.cc @@ -9,6 +9,7 @@ */ #include "grib_tools.h" +#include "grib_dumper_factory.h" grib_option grib_options[] = { /* {id, args, help}, on, command_line, value*/