Esempio n. 1
0
int grib_compare_accessors(grib_accessor* a1,grib_accessor* a2,int compare_flags) {
  int ret=0;
  long type1=0;
  long type2=0;
  int type_mismatch=0;
  grib_accessor_class *c1=NULL;

  if ((compare_flags & GRIB_COMPARE_NAMES) && strcmp(a1->name,a2->name))
      return GRIB_NAME_MISMATCH;

  if ( compare_flags & GRIB_COMPARE_TYPES ) {
    type1=grib_accessor_get_native_type( a1 );
    type2=grib_accessor_get_native_type( a2 );

    type_mismatch = type1 != type2 ? 1 : 0;
  }

  ret=GRIB_UNABLE_TO_COMPARE_ACCESSORS;
  c1 = a1->cclass;
  while(c1)
  {

    if(c1->compare)
    {
      ret = c1->compare(a1, a2);
      break;
    }
    c1 = c1->super ? *(c1->super) : NULL;
  }

  if (ret == GRIB_VALUE_MISMATCH && type_mismatch)
    ret = GRIB_TYPE_AND_VALUE_MISMATCH;

  return ret;
}
static void init(grib_accessor* a, const long len, grib_arguments* params) {
  int n=0;
  grib_accessor_codetable* self  = (grib_accessor_codetable*)a;
  grib_action* act=(grib_action*)(a->creator);

  self->tablename = grib_arguments_get_string(a->parent->h,params,n++);
  self->masterDir = grib_arguments_get_name(a->parent->h,params,n++);
  self->localDir = grib_arguments_get_name(a->parent->h,params,n++);

  /*if (a->flags & GRIB_ACCESSOR_FLAG_STRING_TYPE)
    printf("-------- %s type string (%ld)\n",a->name,a->flags);*/

  if (a->flags & GRIB_ACCESSOR_FLAG_TRANSIENT) {
    a->length = 0;
	if (!a->vvalue) 
		a->vvalue = grib_context_malloc_clear(a->parent->h->context,sizeof(grib_virtual_value));
    a->vvalue->type=grib_accessor_get_native_type(a);
    a->vvalue->length=len;
    if (act->default_value!=NULL) {
      const char* p = 0;
      size_t len = 1;
      long l;
      int ret=0;
      double d;
      char tmp[1024];
      grib_expression* expression=grib_arguments_get_expression(a->parent->h,act->default_value,0);
      int type = grib_expression_native_type(a->parent->h,expression);
      switch(type) {
        case GRIB_TYPE_DOUBLE:
          grib_expression_evaluate_double(a->parent->h,expression,&d);
          grib_pack_double(a,&d,&len);
          break;

        case GRIB_TYPE_LONG:
          grib_expression_evaluate_long(a->parent->h,expression,&l);
          grib_pack_long(a,&l,&len);
          break;

        default:
          len = sizeof(tmp);
          p = grib_expression_evaluate_string(a->parent->h,expression,tmp,&len,&ret);
          if (ret != GRIB_SUCCESS) {
			  grib_context_log(a->parent->h->context,GRIB_LOG_FATAL,
							   "unable to evaluate %s as string",a->name);
          }
          len = strlen(p)+1;
          pack_string(a,p,&len);
          break;
      }
    }
  } else
    a->length = len;

}
static void dump_values(grib_dumper* d,grib_accessor* a)
{
  grib_dumper_c_code *self = (grib_dumper_c_code*)d;
  int k,err =0;
  double*  buf = NULL;
  int type=0;
  char stype[10];
  size_t size=0;
  stype[0]='\0';

  if((a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY)
      || ((a->flags & GRIB_ACCESSOR_FLAG_DATA)
          && (d->option_flags & GRIB_DUMP_FLAG_NO_DATA)   ) )
    return;

  size=grib_value_count(a);
  if(size == 1){
    dump_double(d,a,NULL);
    return ;
  }

  type=grib_accessor_get_native_type(a);
  switch (type) {
     case GRIB_TYPE_LONG:
       sprintf(stype,"%s","long");
       break;
     case GRIB_TYPE_DOUBLE:
       sprintf(stype,"%s","double");
       break;
     default:
       return;
  }

  buf = grib_context_malloc(d->handle->context,size * sizeof(double));
  if(!buf)
  {
    fprintf(self->dumper.out,"/* %s: cannot malloc(%ld) */\n",a->name,(long)size);
    return;
  }

  err =  grib_unpack_double(a,buf,&size);

  if(err){
    grib_context_free(d->handle->context,buf);
    fprintf(self->dumper.out," /*  Error accessing %s (%s) */",a->name,grib_get_error_message(err));
    return ;
  }

  fprintf(self->dumper.out,"    size = %ld;\n",(long)size);
  fprintf(self->dumper.out,"    v%s    = (%s*)calloc(size,sizeof(%s));\n",stype,stype,stype);
  fprintf(self->dumper.out,"    if(!v%s) {\n",stype);
  fprintf(self->dumper.out,"        fprintf(stderr,\"failed to allocate %%d bytes\\n\",size*sizeof(%s));\n",stype);
  fprintf(self->dumper.out,"        exit(1);\n");
  fprintf(self->dumper.out,"    }\n");


  fprintf(self->dumper.out,"\n   ");
  k = 0;
  while(k < size)
  {
    fprintf(self->dumper.out," v%s[%4d] = %7g;",stype,k,buf[k]);
    k++;
    if(k%4 == 0) fprintf(self->dumper.out,"\n   ");

  }
  if(size%4) fprintf(self->dumper.out,"\n");
  fprintf(self->dumper.out,"\n");
  fprintf(self->dumper.out,"    GRIB_CHECK(grib_set_%s_array(h,\"%s\",v%s,size),%d);\n",stype,a->name,stype,0);
  fprintf(self->dumper.out,"    free(v%s);\n",stype);

  grib_context_free(d->handle->context,buf);
}
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;

}
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;

}