mirror of https://github.com/ecmwf/eccodes.git
ECC-445: Add integrity check in grib_util_set_spec
This commit is contained in:
parent
318577fd8c
commit
e9f4216eb1
|
@ -1463,6 +1463,7 @@ int is_index_file(const char *filename);
|
|||
char get_dir_separator_char(void);
|
||||
char *codes_getenv(const char *name);
|
||||
int expandedBoundingBox(grib_handle* h);
|
||||
size_t sum_of_pl_array(const long* pl, size_t plsize);
|
||||
|
||||
/* bufr_util.c */
|
||||
int compute_bufr_key_rank(grib_handle *h, grib_string_list *keys, const char *key);
|
||||
|
|
|
@ -104,13 +104,11 @@ static int next(grib_iterator* i, double *lat, double *lon, double *val)
|
|||
|
||||
typedef void (*get_reduced_row_proc)(long pl, double lon_first, double lon_last, long* npoints, long* ilon_first, long* ilon_last);
|
||||
|
||||
/* For a reduced Gaussian grid which is GLOBAL, the number of points is the sum of the 'pl' array */
|
||||
/* i.e. the total number of points on all latitudes */
|
||||
static size_t count_global_points(long* pl, size_t plsize)
|
||||
{
|
||||
long i, count=0;
|
||||
for (i=0;i<plsize;i++) {
|
||||
count += pl[i];
|
||||
}
|
||||
return count;
|
||||
return sum_of_pl_array(pl, plsize);
|
||||
}
|
||||
static size_t count_subarea_points(grib_handle* h, get_reduced_row_proc get_reduced_row,
|
||||
long* pl, size_t plsize, double lon_first, double lon_last)
|
||||
|
@ -292,9 +290,9 @@ static int init(grib_iterator* iter, grib_handle* h, grib_arguments* args)
|
|||
for (i=0;i<row_count;i++) {
|
||||
|
||||
if(iter->e >= iter->nv){
|
||||
//grib_context_log(h->context,GRIB_LOG_ERROR, "Failed to initialise reduced Gaussian iterator (global)");
|
||||
//return GRIB_WRONG_GRID;
|
||||
//Try now as NON-global
|
||||
/*grib_context_log(h->context,GRIB_LOG_ERROR, "Failed to initialise reduced Gaussian iterator (global)");*/
|
||||
/*return GRIB_WRONG_GRID;*/
|
||||
/*Try now as NON-global*/
|
||||
ret = iterate_reduced_gaussian_subarea_wrapper(iter, h, lat_first, lon_first, lat_last, lon_last, lats, pl, plsize);
|
||||
if (ret !=GRIB_SUCCESS) grib_context_log(h->context,GRIB_LOG_ERROR, "Failed to initialise reduced Gaussian iterator (global)");
|
||||
goto finalise;
|
||||
|
|
|
@ -547,6 +547,47 @@ static double normalise_angle(double angle)
|
|||
return angle;
|
||||
}*/
|
||||
|
||||
static int integrity_check(grib_handle* handle, const grib_util_grid_spec2* spec,
|
||||
const double* data_values,
|
||||
size_t data_values_count,
|
||||
int specified_as_global)
|
||||
{
|
||||
int err = 0;
|
||||
size_t i = 0;
|
||||
|
||||
/* Data values check */
|
||||
for (i=0; i<data_values_count; i++) {
|
||||
double val = data_values[i];
|
||||
if ( !(val < DBL_MAX && val > -DBL_MAX && val != NAN) ) {
|
||||
printf("invalid data value: i=%ld, val=%g\n",i, val);
|
||||
return GRIB_ENCODING_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (spec->pl && spec->pl_size!=0 &&
|
||||
(spec->grid_type==GRIB_UTIL_GRID_SPEC_REDUCED_GG || spec->grid_type==GRIB_UTIL_GRID_SPEC_REDUCED_ROTATED_GG))
|
||||
{
|
||||
long deduced_as_global = 0;
|
||||
size_t sum = 0;
|
||||
/* Do we think it's global? */
|
||||
if ((err = grib_get_long(handle,"global",&deduced_as_global)) != 0) return err;
|
||||
/* If specified_as_global==1, it means the client passed in the key "global" and wants the output to be global
|
||||
* If deduced_as_global==1, it means we inspected the resulting message and deduced from its geometry that it's global
|
||||
*/
|
||||
if (deduced_as_global || specified_as_global) {
|
||||
char msg[100] = {0,};
|
||||
if (deduced_as_global) strcpy(msg, "Deduced to be global from geometry");
|
||||
if (specified_as_global) strcpy(msg, "Specified to be global (in spec)");
|
||||
sum = sum_of_pl_array(spec->pl, spec->pl_size);
|
||||
if (sum != data_values_count) {
|
||||
printf("invalid reduced gaussian grid: %s, data_values_count != sum_of_pl_array (%ld!=%ld)\n",msg, data_values_count,sum);
|
||||
return GRIB_WRONG_GRID;
|
||||
}
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Check what is coded in the handle is what is requested by the spec. */
|
||||
/* Return GRIB_SUCCESS if the geometry matches, otherwise the error code */
|
||||
|
@ -1343,6 +1384,15 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
|
|||
fprintf(stderr,"SET_GRID_DATA_DESCRIPTION: Cannot set pl %s\n",grib_get_error_message(*err));
|
||||
goto cleanup;
|
||||
}
|
||||
// Check global??
|
||||
if (global_grid) {
|
||||
size_t sum = sum_of_pl_array(spec->pl, spec->pl_size);
|
||||
if (data_values_count != sum) {
|
||||
printf("invalid reduced gaussian grid: specified as global, data_values_count=%ld but sum of pl array=%ld\n",data_values_count,sum);
|
||||
*err = GRIB_WRONG_GRID;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (h->context->debug==-1) {
|
||||
|
@ -1492,6 +1542,15 @@ grib_handle* grib_util_set_spec2(grib_handle* h,
|
|||
Assert(e == 0);
|
||||
}
|
||||
|
||||
if ( (*err = integrity_check(outh, spec, data_values, data_values_count, global_grid)) != GRIB_SUCCESS)
|
||||
{
|
||||
grib_context* c=grib_context_get_default();
|
||||
fprintf(stderr,"GRIB_UTIL_SET_SPEC: Integrity check failed! %s\n", grib_get_error_message(*err));
|
||||
if (c->write_on_fail)
|
||||
grib_write_message(outh,"error.grib","w");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Disable check: need to re-examine GRIB-864 */
|
||||
#if 0
|
||||
if ( (*err = check_handle_against_spec(outh, editionNumber, spec, global_grid)) != GRIB_SUCCESS)
|
||||
|
@ -1858,3 +1917,12 @@ int expandedBoundingBox(grib_handle* h)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t sum_of_pl_array(const long* pl, size_t plsize)
|
||||
{
|
||||
long i, count=0;
|
||||
for (i=0;i<plsize;i++) {
|
||||
count += pl[i];
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue