diff --git a/src/geo/GribSpec.cc b/src/geo/GribSpec.cc index b1bfbfbab..76b27a1c0 100644 --- a/src/geo/GribSpec.cc +++ b/src/geo/GribSpec.cc @@ -344,6 +344,24 @@ const char* get_key(const std::string& name, codes_handle* h) } +std::string get_string(codes_handle* h, const char* key) +{ + if (codes_is_defined(h, key) != 0) { + char buffer[64]; + size_t size = sizeof(buffer); + + CHECK_CALL(codes_get_string(h, key, buffer, &size)); + ASSERT(size < sizeof(buffer) - 1); + + if (std::strcmp(buffer, "MISSING") != 0) { + return buffer; + } + } + + return ""; +}; + + template struct ProcessingT { @@ -581,22 +599,8 @@ ProcessingT>* vector_double(std::initializer_list* packing() { return new ProcessingT([](codes_handle* h, std::string& value) { - auto get = [](codes_handle* h, const char* key) -> std::string { - if (codes_is_defined(h, key) != 0) { - char buffer[64]; - size_t size = sizeof(buffer); - - CHECK_CALL(codes_get_string(h, key, buffer, &size)); - ASSERT(size < sizeof(buffer) - 1); + const auto packingType = get_string(h, "packingType"); - if (std::strcmp(buffer, "MISSING") != 0) { - return buffer; - } - } - return ""; - }; - - auto packingType = get(h, "packingType"); for (const auto& prefix : std::vector{ "grid_", "spectral_" }) { if (packingType.find(prefix) == 0) { value = packingType.substr(prefix.size()); @@ -610,6 +614,26 @@ ProcessingT* packing() } +ProcessingT* healpix_ordering() +{ + return new ProcessingT([](codes_handle* h, std::string& value) { + const auto ordering = get_string(h, "ordering"); + + if (ordering == "0") { + value = "ring"; + return true; + } + + if (ordering == "1") { + value = "nested"; + return true; + } + + return false; + }); +} + + template struct ConditionedProcessingT { @@ -693,6 +717,19 @@ bool GribSpec::get(const std::string& name, std::string& value) const return false; } + static const ProcessingList keys_override{ + { "ordering", healpix_ordering(), is("gridType", "healpix") }, + }; + + for (auto& p : keys_override) { + if (name == p.name) { + if (!p.condition || p.condition->eval(handle_)) { + ASSERT(p.processing); + return p.processing->eval(handle_, value); + } + } + } + char buffer[10240]; size_t size = sizeof(buffer); int err = codes_get_string(handle_, key, buffer, &size); @@ -974,7 +1011,7 @@ bool GribSpec::get(const std::string& name, std::vector& value) const } size_t count = 0; - int err = codes_get_size(handle_, key, &count); + int err = codes_get_size(handle_, key, &count); CHECK_ERROR(err, key); ASSERT(count > 0); @@ -1076,7 +1113,9 @@ void GribSpec::json(eckit::JSON& j) const } if (type == CODES_TYPE_STRING) { - char value[1024] = {0,}; + char value[1024] = { + 0, + }; size_t length = sizeof(value); CHECK_CALL(codes_get_string(handle_, name, value, &length)); j << name << value;