GRIB-898: Encoding a constant field with grid_second_order generates error

This commit is contained in:
Shahram Najm 2015-12-16 17:38:09 +00:00
parent 0596e8df78
commit 59e226bfe7
2 changed files with 238 additions and 231 deletions

View File

@ -12,264 +12,262 @@
static int copy_values(grib_handle* h,grib_accessor* ga)
{
int i,j,k;
/* printf("copy_values stack is %ld\n",(long)h->values_stack);*/
for(j = 0; j < h->values_stack; j++)
{
for(i = 0; i < h->values_count[j]; i++)
{
for(k = 0; (k < MAX_ACCESSOR_NAMES) && (ga->all_names[k] != NULL); k++)
{
/*printf("copy_values: %s %s\n",h->values[j][i].name,ga->all_names[k]);*/
if(strcmp(h->values[j][i].name,ga->all_names[k]) == 0)
{
size_t len = 1;
/*printf("SET VALUES %s\n",h->values[j][i].name);*/
switch(h->values[j][i].type)
{
case GRIB_TYPE_LONG:
return grib_pack_long(ga,&h->values[j][i].long_value,&len);
break;
int i,j,k;
/* printf("copy_values stack is %ld\n",(long)h->values_stack);*/
for(j = 0; j < h->values_stack; j++)
{
for(i = 0; i < h->values_count[j]; i++)
{
for(k = 0; (k < MAX_ACCESSOR_NAMES) && (ga->all_names[k] != NULL); k++)
{
/*printf("copy_values: %s %s\n",h->values[j][i].name,ga->all_names[k]);*/
if(strcmp(h->values[j][i].name,ga->all_names[k]) == 0)
{
size_t len = 1;
/*printf("SET VALUES %s\n",h->values[j][i].name);*/
switch(h->values[j][i].type)
{
case GRIB_TYPE_LONG:
return grib_pack_long(ga,&h->values[j][i].long_value,&len);
break;
case GRIB_TYPE_DOUBLE:
return grib_pack_double(ga,&h->values[j][i].double_value,&len);
break;
case GRIB_TYPE_DOUBLE:
return grib_pack_double(ga,&h->values[j][i].double_value,&len);
break;
case GRIB_TYPE_STRING:
len = strlen(h->values[j][i].string_value);
return grib_pack_string(ga,h->values[j][i].string_value,&len);
break;
}
}
}
}
}
case GRIB_TYPE_STRING:
len = strlen(h->values[j][i].string_value);
return grib_pack_string(ga,h->values[j][i].string_value,&len);
break;
}
}
}
}
}
return GRIB_NOT_FOUND;
return GRIB_NOT_FOUND;
}
int grib_lookup_long_from_handle(grib_context* gc,grib_loader* loader,const char* name,long* value)
{
grib_handle* h = (grib_handle*)loader->data;
grib_accessor *b = grib_find_accessor(h,name);
size_t len = 1;
if(b) return grib_unpack_long(b,value,&len);
grib_handle* h = (grib_handle*)loader->data;
grib_accessor *b = grib_find_accessor(h,name);
size_t len = 1;
if(b) return grib_unpack_long(b,value,&len);
/* TODO: fix me. For now, we don't fail on a lookup. */
/* TODO: fix me. For now, we don't fail on a lookup. */
#if 1
*value = -1;
return GRIB_SUCCESS;
*value = -1;
return GRIB_SUCCESS;
#else
return GRIB_NOT_FOUND;
return GRIB_NOT_FOUND;
#endif
}
int grib_init_accessor_from_handle(grib_loader* loader,grib_accessor* ga,grib_arguments* default_value)
{
grib_handle* h = (grib_handle*)loader->data;
int ret = GRIB_SUCCESS;
size_t len = 0;
char* sval = NULL;
unsigned char* uval = NULL;
long* lval = NULL;
double* dval = NULL;
static int first = 1;
static const char* missing = 0;
const char* name = NULL;
int k = 0;
grib_handle *g;
int e, pack_missing = 0;
grib_context_log(h->context,GRIB_LOG_DEBUG, "XXXXX Copying %s", ga->name);
grib_handle* h = (grib_handle*)loader->data;
int ret = GRIB_SUCCESS;
size_t len = 0;
char* sval = NULL;
unsigned char* uval = NULL;
long* lval = NULL;
double* dval = NULL;
static int first = 1;
static const char* missing = 0;
const char* name = NULL;
int k = 0;
grib_handle *g;
int e, pack_missing = 0;
grib_context_log(h->context,GRIB_LOG_DEBUG, "XXXXX Copying %s", ga->name);
if(default_value)
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying: setting %s to default value",
ga->name);
grib_pack_expression(ga,grib_arguments_get_expression(h,default_value,0));
}
if(default_value)
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying: setting %s to default value",
ga->name);
grib_pack_expression(ga,grib_arguments_get_expression(h,default_value,0));
}
if( (ga->flags & GRIB_ACCESSOR_FLAG_NO_COPY) ||
((ga->flags & GRIB_ACCESSOR_FLAG_EDITION_SPECIFIC) &&
loader->changing_edition ) ||
(ga->flags & GRIB_ACCESSOR_FLAG_FUNCTION) ||
( (ga->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) &&
!(ga->flags & GRIB_ACCESSOR_FLAG_COPY_OK) ) )
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying %s ignored", ga->name);
return GRIB_SUCCESS;
}
if( (ga->flags & GRIB_ACCESSOR_FLAG_NO_COPY) ||
((ga->flags & GRIB_ACCESSOR_FLAG_EDITION_SPECIFIC) &&
loader->changing_edition ) ||
(ga->flags & GRIB_ACCESSOR_FLAG_FUNCTION) ||
( (ga->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) &&
!(ga->flags & GRIB_ACCESSOR_FLAG_COPY_OK) ) )
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying %s ignored", ga->name);
return GRIB_SUCCESS;
}
#if 0
if(h->values)
if(copy_values(h,ga) == GRIB_SUCCESS)
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying: setting %s to multi-set-value", ga->name);
return GRIB_SUCCESS;
}
if(h->values)
if(copy_values(h,ga) == GRIB_SUCCESS)
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying: setting %s to multi-set-value", ga->name);
return GRIB_SUCCESS;
}
#endif
#if 0
if(h->loader)
h->loader->init_accessor(h->loader,ga,default_value);
if(h->loader)
h->loader->init_accessor(h->loader,ga,default_value);
#else
/* COMEBACK here
/* COMEBACK here
this is needed if we reparse during reparse....
*/
*/
g = h;
while(g)
{
if(g->values) {
if(copy_values(g,ga) == GRIB_SUCCESS) {
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying: setting %s to multi-set-value", ga->name);
return GRIB_SUCCESS;
}
}
g = g->main;
}
g = h;
while(g)
{
if(g->values) {
if(copy_values(g,ga) == GRIB_SUCCESS) {
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying: setting %s to multi-set-value", ga->name);
return GRIB_SUCCESS;
}
}
g = g->main;
}
#endif
/* Check if the same name exists in the original message ... */
k = 0;
while( (k < MAX_ACCESSOR_NAMES) &&
((name = ga->all_names[k]) != NULL) &&
((ret = grib_get_size(h,name,&len)) != GRIB_SUCCESS)) k++;
/* Check if the same name exists in the original message ... */
k = 0;
while( (k < MAX_ACCESSOR_NAMES) &&
((name = ga->all_names[k]) != NULL) &&
((ret = grib_get_size(h,name,&len)) != GRIB_SUCCESS)) k++;
if(ret != GRIB_SUCCESS)
{
name = ga->name;
if(ret != GRIB_SUCCESS)
{
name = ga->name;
if(first)
{
missing = getenv("ECCODES_PRINT_MISSING");
first = 0;
}
if(first)
{
missing = getenv("ECCODES_PRINT_MISSING");
first = 0;
}
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying [%s] failed: %s",
name,grib_get_error_message(ret));
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying [%s] failed: %s",
name,grib_get_error_message(ret));
if(missing)
{
fprintf(stdout,"REPARSE: no value for %s",name);
if(default_value)
fprintf(stdout," (default value)");
fprintf(stdout,"\n");
}
if(missing)
{
fprintf(stdout,"REPARSE: no value for %s",name);
if(default_value)
fprintf(stdout," (default value)");
fprintf(stdout,"\n");
}
return GRIB_SUCCESS;
}
return GRIB_SUCCESS;
}
/* we copy also virtual keys*/
if(len == 0) {
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying %s failed, length is 0", name);
return GRIB_SUCCESS;
}
/* we copy also virtual keys*/
if(len == 0) {
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying %s failed, length is 0", name);
return GRIB_SUCCESS;
}
if((ga->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) && grib_is_missing(h,name,&e) && e == GRIB_SUCCESS && len == 1)
{
grib_pack_missing(ga);
pack_missing = 1;
}
if((ga->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) && grib_is_missing(h,name,&e) && e == GRIB_SUCCESS && len == 1)
{
grib_pack_missing(ga);
pack_missing = 1;
}
switch(grib_accessor_get_native_type(ga))
{
case GRIB_TYPE_STRING:
switch(grib_accessor_get_native_type(ga))
{
case GRIB_TYPE_STRING:
/* len = len > 1024 ? len : 1024; */
_grib_get_string_length(ga,&len);
sval = (char*)grib_context_malloc(h->context,len);
ret = grib_get_string_internal(h,name,sval,&len);
if(ret == GRIB_SUCCESS)
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying string %s to %s", sval, name);
ret = grib_pack_string(ga,sval,&len);
}
grib_context_free(h->context,sval);
/* len = len > 1024 ? len : 1024; */
_grib_get_string_length(ga,&len);
sval = (char*)grib_context_malloc(h->context,len);
ret = grib_get_string_internal(h,name,sval,&len);
if(ret == GRIB_SUCCESS)
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying string %s to %s", sval, name);
ret = grib_pack_string(ga,sval,&len);
}
grib_context_free(h->context,sval);
break;
break;
case GRIB_TYPE_LONG:
lval = (long*)grib_context_malloc(h->context,len*sizeof(long));
ret = grib_get_long_array_internal(h,name,lval,&len);
if(ret == GRIB_SUCCESS)
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying %d long(s) %d to %s", len, lval[0], name);
if(ga->same)
{
ret = grib_set_long_array(grib_handle_of_accessor(ga),ga->name,lval,len);
case GRIB_TYPE_LONG:
lval = (long*)grib_context_malloc(h->context,len*sizeof(long));
ret = grib_get_long_array_internal(h,name,lval,&len);
if(ret == GRIB_SUCCESS)
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying %d long(s) %d to %s", len, lval[0], name);
if(ga->same)
{
ret = grib_set_long_array(grib_handle_of_accessor(ga),ga->name,lval,len);
/* Allow for lists to be resized */
if((ret == GRIB_WRONG_ARRAY_SIZE || ret == GRIB_ARRAY_TOO_SMALL) && loader->list_is_resized)
ret = GRIB_SUCCESS;
}
else
{
/* See GRIB-492. This is NOT an ideal solution! */
if (*lval == GRIB_MISSING_LONG || pack_missing)
{
; /* No checks needed */
}
else
{
/* If we have just one key of type long which has one octet, then do not exceed maximum value */
const long num_octets = ga->length;
if (len == 1 && num_octets == 1 && *lval > 255)
{
*lval = 0; /* Reset to a reasonable value */
}
}
ret = grib_pack_long(ga,lval,&len);
}
}
/* Allow for lists to be resized */
if((ret == GRIB_WRONG_ARRAY_SIZE || ret == GRIB_ARRAY_TOO_SMALL) && loader->list_is_resized)
ret = GRIB_SUCCESS;
}
else
{
/* See GRIB-492. This is NOT an ideal solution! */
if (*lval == GRIB_MISSING_LONG || pack_missing)
{
; /* No checks needed */
}
else
{
/* If we have just one key of type long which has one octet, then do not exceed maximum value */
const long num_octets = ga->length;
if (len == 1 && num_octets == 1 && *lval > 255)
{
*lval = 0; /* Reset to a reasonable value */
}
}
ret = grib_pack_long(ga,lval,&len);
}
}
grib_context_free(h->context,lval);
grib_context_free(h->context,lval);
break;
break;
case GRIB_TYPE_DOUBLE:
dval = (double*)grib_context_malloc(h->context,len*sizeof(double));
ret = grib_get_double_array_internal(h,name,dval,&len);
if(ret == GRIB_SUCCESS)
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying %d double(s) %g to %s", len, dval[0], name);
if(ga->same)
{
ret = grib_set_double_array(grib_handle_of_accessor(ga),ga->name,dval,len);
case GRIB_TYPE_DOUBLE:
dval = (double*)grib_context_malloc(h->context,len*sizeof(double));
ret = grib_get_double_array(h,name,dval,&len); /* GRIB-898 */
if(ret == GRIB_SUCCESS)
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying %d double(s) %g to %s", len, dval[0], name);
if(ga->same)
{
ret = grib_set_double_array(grib_handle_of_accessor(ga),ga->name,dval,len);
/* Allow for lists to be resized */
if((ret == GRIB_WRONG_ARRAY_SIZE || ret == GRIB_ARRAY_TOO_SMALL) && loader->list_is_resized)
ret = GRIB_SUCCESS;
}
else ret = grib_pack_double(ga,dval,&len);
}
/* Allow for lists to be resized */
if((ret == GRIB_WRONG_ARRAY_SIZE || ret == GRIB_ARRAY_TOO_SMALL) && loader->list_is_resized)
ret = GRIB_SUCCESS;
}
else ret = grib_pack_double(ga,dval,&len);
}
grib_context_free(h->context,dval);
break;
grib_context_free(h->context,dval);
break;
case GRIB_TYPE_BYTES:
case GRIB_TYPE_BYTES:
uval = (unsigned char*)grib_context_malloc(h->context,len*sizeof(char));
ret = grib_get_bytes_internal(h,name,uval,&len);
if(ret == GRIB_SUCCESS)
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying %d byte(s) to %s", len, name);
ret = grib_pack_bytes(ga,uval,&len);
}
uval = (unsigned char*)grib_context_malloc(h->context,len*sizeof(char));
ret = grib_get_bytes_internal(h,name,uval,&len);
if(ret == GRIB_SUCCESS)
{
grib_context_log(h->context,GRIB_LOG_DEBUG, "Copying %d byte(s) to %s", len, name);
ret = grib_pack_bytes(ga,uval,&len);
}
grib_context_free(h->context,uval);
grib_context_free(h->context,uval);
break;
break;
case GRIB_TYPE_LABEL:
break;
case GRIB_TYPE_LABEL:
break;
default:
grib_context_log(h->context,GRIB_LOG_ERROR, "Copying %s, cannot establish type %d [%s]"
, name,grib_accessor_get_native_type(ga),ga->creator->cclass->name);
break;
}
return ret;
default:
grib_context_log(h->context,GRIB_LOG_ERROR, "Copying %s, cannot establish type %d [%s]"
, name,grib_accessor_get_native_type(ga),ga->creator->cclass->name);
break;
}
return ret;
}

View File

@ -61,7 +61,7 @@ int grib_set_long_internal(grib_handle* h, const char* name, long val) {
a = grib_find_accessor(h, name);
if (h->context->debug==-1)
if (h->context->debug)
printf("ECCODES DEBUG grib_set_long_internal %s=%ld\n",name,(long)val);
if(a){
@ -86,7 +86,7 @@ int grib_set_long(grib_handle* h, const char* name, long val) {
a = grib_find_accessor(h, name);
if (h->context->debug==-1)
if (h->context->debug)
printf("ECCODES DEBUG grib_set_long %s=%ld\n",name,(long)val);
if(a){
@ -109,7 +109,7 @@ int grib_set_double_internal(grib_handle* h, const char* name, double val) {
a = grib_find_accessor(h, name);
if (h->context->debug==-1)
if (h->context->debug)
printf("ECCODES DEBUG grib_set_double_internal %s=%g\n",name,val);
if(a){
@ -299,7 +299,7 @@ int grib_set_double(grib_handle* h, const char* name, double val) {
a = grib_find_accessor(h, name);
if (h->context->debug==-1)
if (h->context->debug)
printf("ECCODES DEBUG grib_set_double %s=%g\n",name,val);
if(a){
@ -324,7 +324,7 @@ int grib_set_string_internal(grib_handle* h, const char* name,
a = grib_find_accessor(h, name);
if (h->context->debug==-1)
if (h->context->debug)
printf("ECCODES DEBUG grib_set_string_internal %s=%s\n",name,val);
if(a){
@ -347,27 +347,33 @@ int grib_set_string(grib_handle* h, const char* name, const char* val, size_t *l
int ret=0;
grib_accessor* a;
#if 1
/* Second order doesn't have a proper representation for constant fields
the best is not to do the change of packing type if bitsPerValue=0
/* Second order doesn't have a proper representation for constant fields.
So best not to do the change of packing type
*/
if (!grib_inline_strcmp(name,"packingType") && !grib_inline_strcmp(val,"grid_second_order")) {
long bitsPerValue=0;
size_t numCodedVals = 0;
grib_get_long(h,"bitsPerValue",&bitsPerValue);
if (bitsPerValue==0) return 0;
if (bitsPerValue==0) {
if (h->context->debug) {
printf("ECCODES DEBUG grib_set_string packingType: Constant field cannot be encoded in second order. Packing not changed\n");
}
return 0;
}
/* GRIB-883: check if there are enough coded values */
ret = grib_get_size(h, "codedValues", &numCodedVals);
if (ret == GRIB_SUCCESS && numCodedVals < 3) {
if (h->context->debug) {
printf("ECCODES DEBUG grib_set_string packingType: not enough coded values for second order. Packing not changed\n");
}
return 0;
}
}
#endif
a = grib_find_accessor(h, name);
if (h->context->debug==-1)
if (h->context->debug)
printf("ECCODES DEBUG grib_set_string %s=%s\n",name,val);
if(a)
@ -625,7 +631,7 @@ int grib_set_double_array_internal(grib_handle* h, const char* name, const doubl
{
int ret=0;
if (h->context->debug==-1)
if (h->context->debug)
printf("ECCODES DEBUG grib_set_double_array_internal key=%s %ld values\n",name, (long)length);
if (length==0) {
@ -638,7 +644,7 @@ int grib_set_double_array_internal(grib_handle* h, const char* name, const doubl
if (ret!=GRIB_SUCCESS)
grib_context_log(h->context,GRIB_LOG_ERROR,"unable to set double array %s (%s)",
name,grib_get_error_message(ret));
/*if (h->context->debug==-1) printf("ECCODES DEBUG grib_set_double_array_internal key=%s --DONE\n",name);*/
/*if (h->context->debug) printf("ECCODES DEBUG grib_set_double_array_internal key=%s --DONE\n",name);*/
return ret;
}
@ -647,7 +653,7 @@ static int __grib_set_double_array(grib_handle* h, const char* name, const doubl
double v=val[0];
int constant,i;
if (h->context->debug==-1)
if (h->context->debug)
printf("ECCODES DEBUG grib_set_double_array key=%s %ld values\n",name,(long)length);
if (length==0) {
@ -688,10 +694,17 @@ static int __grib_set_double_array(grib_handle* h, const char* name, const doubl
!strcmp(packingType,"grid_second_order_SPD2") ||
!strcmp(packingType,"grid_second_order_SPD3")
) {
int ret = 0;
slen=11; /*length of 'grid_simple' */
if (h->context->debug == -1)
printf("ECCODES DEBUG grib_set_double_array forcing grid_simple\n");
grib_set_string(h,"packingType","grid_simple",&slen);
if (h->context->debug) {
printf("ECCODES DEBUG __grib_set_double_array: Cannot use second order packing for constant fields. Using simple packing\n");
}
ret = grib_set_string(h,"packingType","grid_simple",&slen);
if (ret != GRIB_SUCCESS) {
if (h->context->debug) {
printf("ECCODES DEBUG __grib_set_double_array: could not switch to simple packing!\n");
}
}
}
}
}
@ -999,7 +1012,6 @@ int grib_get_native_type(grib_handle* h, const char* name,int* type)
}
return GRIB_SUCCESS;
}
const char* grib_get_accessor_class_name(grib_handle* h, const char* name)
@ -1010,9 +1022,8 @@ const char* grib_get_accessor_class_name(grib_handle* h, const char* name)
int _grib_get_double_array_internal(grib_handle* h,grib_accessor* a,double* val, size_t buffer_len,size_t *decoded_length)
{
int err;
if(a) {
err = _grib_get_double_array_internal(h,a->same,val,buffer_len,decoded_length);
int err = _grib_get_double_array_internal(h,a->same,val,buffer_len,decoded_length);
if ( err == GRIB_SUCCESS )
{
@ -1041,7 +1052,6 @@ int grib_get_double_array_internal(grib_handle* h, const char* name, double* val
return ret;
}
int grib_get_double_array(grib_handle* h, const char* name, double* val, size_t *length)
{
size_t len = *length;
@ -1067,7 +1077,6 @@ int grib_get_double_array(grib_handle* h, const char* name, double* val, size_t
}
}
int _grib_get_string_length(grib_accessor* a, size_t* size)
{
size_t s=0;