Skip to content

Commit

Permalink
GRIB message validity checker - Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
shahramn committed Dec 13, 2024
1 parent 41a0cb2 commit 42793ae
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 89 deletions.
2 changes: 2 additions & 0 deletions definitions/boot.def
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ constant definitionFilesVersion="2.0.0.0" : hidden;
constant internalVersion=30 : hidden;
meta checkInternalVersion check_internal_version(internalVersion) : hidden;

meta isMessageValid message_is_valid() : hidden;

# ECC-806: Local concepts precedence order
preferLocalConceptsEnvVar = getenv("ECCODES_GRIB_PREFER_LOCAL_CONCEPTS","0") : hidden;
transient preferLocalConcepts = preferLocalConceptsEnvVar : hidden;
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ list( APPEND eccodes_src_files
accessor/grib_accessor_class_data_g22order_packing.cc
accessor/grib_accessor_class_mars_step.cc
accessor/grib_accessor_class_message_copy.cc
accessor/grib_accessor_class_message_is_valid.cc
accessor/grib_accessor_class_dictionary.cc
accessor/grib_accessor_class_latlon_increment.cc
accessor/grib_accessor_class_g2date.cc
Expand Down
83 changes: 83 additions & 0 deletions src/accessor/grib_accessor_class_message_is_valid.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* (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_accessor_class_message_is_valid.h"

grib_accessor_message_is_valid_t _grib_accessor_message_is_valid{};
grib_accessor* grib_accessor_message_is_valid = &_grib_accessor_message_is_valid;

void grib_accessor_message_is_valid_t::init(const long l, grib_arguments* c)
{
grib_accessor_long_t::init(l, c);
flags_ |= GRIB_ACCESSOR_FLAG_READ_ONLY;
length_ = 0;
}

static int check_grid_pl_array(grib_handle* h)
{
int ret = GRIB_SUCCESS;
long Ni = 0,plpresent = 0;
long* pl = NULL; // pl array
size_t plsize = 0;
grib_context* c = h->context;

// is there a PL array?
ret = grib_get_long(h, "PLPresent", &plpresent);
if (ret != GRIB_SUCCESS || plpresent == 0)
return GRIB_SUCCESS;

if ((ret = grib_get_size(h, "pl", &plsize)) != GRIB_SUCCESS)
return ret;
if (plsize == 0) { // pl array must have at least one element
return GRIB_WRONG_GRID;
}

// If we have a PL array and PLPresent=true, then Ni must be missing
ret = grib_get_long(h, "Ni", &Ni);
if (ret == GRIB_SUCCESS && Ni != GRIB_MISSING_LONG) {
grib_context_log(c, GRIB_LOG_ERROR, "Invalid Ni: If there is a PL array, Ni must be set to MISSING");
return GRIB_WRONG_GRID;
}

pl = (long*)grib_context_malloc_clear(c, sizeof(long) * plsize);
if (!pl) {
return GRIB_OUT_OF_MEMORY;
}
if ((ret = grib_get_long_array(h, "pl", pl, &plsize)) != GRIB_SUCCESS)
return ret;

for (size_t j = 0; j < plsize; j++) {
if (pl[j] == 0) {
grib_context_log(c, GRIB_LOG_ERROR, "Invalid PL array: entry at index=%d is zero", j);
return GRIB_WRONG_GRID;
}
}
grib_context_free(c, pl);

return GRIB_SUCCESS;
}

int grib_accessor_message_is_valid_t::unpack_long(long* val, size_t* len)
{
grib_handle* h = grib_handle_of_accessor(this);
*len = 1;
*val = 0;

// TODO: Move all checks to dedicated classes, e.g.,
// GribDataIntegrityChecker
// BufrDataIntegrityChecker
// etc.
int ret = check_grid_pl_array(h); // Just prototyping
if (ret == GRIB_SUCCESS) {
*val = 1;
}

return GRIB_SUCCESS;
}
23 changes: 23 additions & 0 deletions src/accessor/grib_accessor_class_message_is_valid.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* (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_accessor_class_long.h"

class grib_accessor_message_is_valid_t : public grib_accessor_long_t
{
public:
grib_accessor_message_is_valid_t() :
grib_accessor_long_t() { class_name_ = "message_is_valid"; }
grib_accessor* create_empty_accessor() override { return new grib_accessor_message_is_valid_t{}; }
int unpack_long(long* val, size_t* len) override;
void init(const long, grib_arguments*) override;
};
1 change: 1 addition & 0 deletions src/grib_accessor_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ extern grib_accessor* grib_accessor_mars_step;
extern grib_accessor* grib_accessor_md5;
extern grib_accessor* grib_accessor_message;
extern grib_accessor* grib_accessor_message_copy;
extern grib_accessor* grib_accessor_message_is_valid;
extern grib_accessor* grib_accessor_multdouble;
extern grib_accessor* grib_accessor_nearest;
extern grib_accessor* grib_accessor_non_alpha;
Expand Down
Loading

0 comments on commit 42793ae

Please sign in to comment.