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); 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 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; } #endif #if 0 if(h->loader) h->loader->init_accessor(h->loader,ga,default_value); #else /* 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; } #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++; if(ret != GRIB_SUCCESS) { name = ga->name; if(first) { missing = getenv("GRIB_PRINT_MISSING"); first = 0; } 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"); } 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; } switch(grib_accessor_get_native_type(ga)) { case GRIB_TYPE_STRING: /* len = len > 1024 ? len : 1024; */ grib_get_string_length(h,name,&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; 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(ga->parent->h,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); } } grib_context_free(h->context,lval); 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(ga->parent->h,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); } grib_context_free(h->context,dval); break; 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); } grib_context_free(h->context,uval); 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; }
static int notify_change(grib_action* act, grib_accessor * notified, grib_accessor* changed) { if(act->default_value) return grib_pack_expression(notified,grib_arguments_get_expression(grib_handle_of_accessor(notified),act->default_value,0)); return GRIB_SUCCESS; }
int grib_init_accessor_from_array(grib_loader* loader,grib_accessor* ga,grib_arguments* default_value) { grib_handle* h = ga->parent->h; int retval =GRIB_SUCCESS; char* strvalue; size_t len=0; int type=0; double* dvalue=0; long* lvalue=0; long lval=0; double dval=0; int i=0; grib_associative_array* ar=NULL; grib_runtime_type* value=NULL; ar=(grib_associative_array*)loader->data; grib_context_log(h->context,GRIB_LOG_DEBUG, "Initialize %s", ga->name); retval= grib_associative_array_get(ar,ga->name,&value); if((retval != GRIB_ARRAY_SUCCESS) && default_value) { grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting %s to default value", ga->name); grib_pack_expression(ga,grib_arguments_get_expression(h,default_value,0)); return GRIB_SUCCESS; } if(ga->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) { grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting %s ignored (read only)", ga->name); return GRIB_SUCCESS; } if (retval != GRIB_ARRAY_SUCCESS) { grib_context_log(h->context,GRIB_LOG_DEBUG, "Grib array error %d",retval); if ((ga->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING)) { grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting %s ignored (optional or can be missing)", ga->name); return GRIB_SUCCESS; } else { grib_context_log(h->context,GRIB_LOG_ERROR, "%s required", ga->name); return retval; } } if (value && grib_runtimetype_get_type(value,&type) == GRIB_RUNTIMETYPE_SUCCESS) { if (type == GRIB_RUNTIMETYPE_CHAR ) { grib_runtimetype_get_char(value,&strvalue,&len); switch(grib_accessor_get_native_type(ga)) { case GRIB_TYPE_STRING: grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting %s to string %s", ga->name, strvalue); grib_set_string_internal(h,ga->name,strvalue,&len); break; case GRIB_TYPE_LONG: if (!strcmp(strvalue,"MISSING")) lval=GRIB_MISSING_LONG; else lval=atol(strvalue); grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting %s to long %d", ga->name, lval); grib_set_long_internal(h,ga->name,lval); break; case GRIB_TYPE_DOUBLE: if (!strcmp(strvalue,"MISSING")) dval=GRIB_MISSING_DOUBLE; else if (sscanf(strvalue,"%lg",&dval)!=1) { grib_context_log(h->context,GRIB_LOG_ERROR, "Unable to set %s wrong value format", ga->name); } grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting %s to double %lg (%s)", ga->name, dval,strvalue); grib_set_double_internal(h,ga->name,dval); break; case GRIB_TYPE_BYTES: grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting %s to string %s", ga->name, strvalue); grib_set_bytes_internal(h,ga->name,(unsigned char*)strvalue,&len); break; case GRIB_TYPE_LABEL: break; default: grib_context_log(h->context,GRIB_LOG_ERROR, "Setting %s, cannot establish type %d [%s]" , ga->name,grib_accessor_get_native_type(ga),ga->creator->cclass->name); break; } } else { if (grib_runtimetype_get_double(value,&dvalue,&len) == GRIB_RUNTIMETYPE_SUCCESS) { switch(grib_accessor_get_native_type(ga)) { case GRIB_TYPE_LONG: lvalue=(long*)malloc(sizeof(long)*len); for (i=0;i<len;i++) lvalue[i]=(long)dvalue[i]; grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting long array %s",ga->name); grib_set_long_array(h,ga->name,lvalue,len); free(lvalue); break; case GRIB_TYPE_DOUBLE: grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting double array %s",ga->name); grib_set_double_array(h,ga->name,dvalue,len); break; default: grib_context_log(h->context,GRIB_LOG_ERROR, "Setting array %s, wrong type [%d]" , ga->name,grib_accessor_get_native_type(ga)); break; } } else grib_context_log(h->context,GRIB_LOG_ERROR, "Unable to set %s to double, wrong type (%d)", ga->name,type); } #if 0 switch(grib_accessor_get_native_type(ga)) { case GRIB_TYPE_STRING: if (grib_runtimetype_get_char(value,&strvalue,&strvalue_size) == GRIB_RUNTIMETYPE_SUCCESS) { grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting %s to string %s", ga->name, strvalue); len=strlen(strvalue); grib_set_string_internal(h,ga->name,strvalue,&len); } else grib_context_log(h->context,GRIB_LOG_ERROR, "Unable to set %s to string, wrong type", ga->name); break; case GRIB_TYPE_LONG: if (grib_runtimetype_get_long(value,&lval,&len) == GRIB_RUNTIMETYPE_SUCCESS) { grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting %s to long %d", ga->name, lval); grib_set_long_internal(h,ga->name,*lval); } else grib_context_log(h->context,GRIB_LOG_ERROR, "Unable to set %s to long, wrong type", ga->name); break; case GRIB_TYPE_DOUBLE: if (grib_runtimetype_get_double(value,&dval,&len) == GRIB_RUNTIMETYPE_SUCCESS) { grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting %s to long %d", ga->name, dval); grib_set_double_internal(h,ga->name,*dval); } else grib_context_log(h->context,GRIB_LOG_ERROR, "Unable to set %s to double, wrong type", ga->name); break; case GRIB_TYPE_BYTES: if (grib_runtimetype_get_char(value,&strvalue,&len) == GRIB_RUNTIMETYPE_SUCCESS) { grib_context_log(h->context,GRIB_LOG_DEBUG, "Setting %s to string %s", ga->name, strvalue); grib_set_bytes_internal(h,ga->name,(unsigned char*)strvalue,&len); } else grib_context_log(h->context,GRIB_LOG_ERROR, "Unable to set %s to string, wrong type", ga->name); break; case GRIB_TYPE_LABEL: break; default: grib_context_log(h->context,GRIB_LOG_ERROR, "Setting %s, cannot establish type %d [%s]" , ga->name,grib_accessor_get_native_type(ga),ga->creator->cclass->name); break; } #endif } return retval; }