static int pack_long(grib_accessor* a, const long* val,size_t *len)
{
    grib_accessor_g1_message_length *self = (grib_accessor_g1_message_length*)a;
    /*grib_accessor_class* super = *(a->cclass->super);*/

    /* Here we assume that the totalLength will be coded AFTER the section4 length, and
    the section4 length will be overwritten by the totalLength accessor for large GRIBs */

    grib_accessor* s4 = grib_find_accessor(a->parent->h,self->sec4_length);
    long tlen,slen;
    long t120;
    int ret;

    tlen = *val;
    if((tlen < 0x800000 || !a->parent->h->context->gribex_mode_on) && tlen < 0xFFFFFF  )
    {
        /* printf("ENCODING small grib total = %ld\n",tlen); */
        /*return super->pack_long(a,val,len);*/

        /* Do not directly call pack_long on base class */
        /* because in this special case we want to skip the checks. */
        /* So we call the helper function which has an extra argument */
        return pack_long_unsigned_helper(a,val,len, /*check=*/0);
    }

    if(!s4) return GRIB_NOT_FOUND;

    /* special case for large GRIBs */
    tlen -= 4;
    t120  = (tlen+119)/120;
    slen  = t120*120 - tlen;
    tlen  = 0x800000 | t120;

    /* printf("ENCODING large grib total = %ld tlen=%ld slen=%ld \n",*val,tlen,slen);  */
    *len = 1;
    if((ret = grib_pack_long(s4,&slen,len)) != GRIB_SUCCESS)
        return ret;

    *len = 1;
    /* Do not do the length checks in this special case */
    if((ret = pack_long_unsigned_helper(a,&tlen,len,/*check=*/0)) != GRIB_SUCCESS)
        return ret;
    /*
    if((ret = super->pack_long(a,&tlen,len)) != GRIB_SUCCESS)
      return ret;
    */

    {
        long total_length = -1, sec4_length = -1;
        grib_get_g1_message_size(a->parent->h,
                                 a,
                                 grib_find_accessor(a->parent->h,self->sec4_length),
                                 &total_length,
                                 &sec4_length);

        Assert(total_length == *val);
    }

    return GRIB_SUCCESS;
}
示例#2
0
/* new GCC compiler v4.5.0 complains function is defined but not used*/
void grib_recompute_sections_lengths(grib_section* s)
{
    if(s)
    {
        long   plen = 0;
        size_t  len = 1;

        grib_accessor* a = s->block->first;

        while(a)
        {
            /* grib_recompute_sections_lengths(grib_get_sub_section(a)); */
            grib_recompute_sections_lengths(a->sub_section);
            a = a->next;
        }

        if(s->aclength)
        {
            int ret;
            if(s->owner)
                plen = grib_get_next_position_offset(s->block->last) - s->owner->offset;
            else
                plen = grib_get_next_position_offset(s->block->last);

            if((ret = grib_pack_long(s->aclength, &plen, &len)) != GRIB_SUCCESS)
                ;

#if 0
            if(s->h->context->debug)
                printf("SECTION updating length %ld .. %s\n",plen,s->owner->name);
#endif

        }
    }
}
static int pack_string(grib_accessor* a, const char* val, size_t *len)
{
  char* theEnd=NULL;
  long v=strtol(val,&theEnd,10);
  if (theEnd) {
    grib_context_log(a->parent->h->context,GRIB_LOG_ERROR,"trying to pack \"%s\" as long",val);
    return GRIB_WRONG_TYPE;
  }
  return grib_pack_long( a,&v,len);
}
static int pack_missing(grib_accessor* a){

  size_t one = 1;
  long value = GRIB_MISSING_LONG;

  if(a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING)
    return grib_pack_long(a,&value,&one);

  return GRIB_VALUE_CANNOT_BE_MISSING;
}
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 int    pack_long   (grib_accessor* a, const long* val, size_t *len) {
  int err=0;
  grib_accessor_long_vector* self = (grib_accessor_long_vector*)a;
  grib_accessor* va=NULL;
  grib_accessor_abstract_long_vector* v =NULL;
  
  va=(grib_accessor*)grib_find_accessor(a->parent->h,self->vector);
  v=(grib_accessor_abstract_long_vector*)va;

  v->pack_index=self->index;

  err=grib_pack_long(va,val,len);

  return err;
}
static int pack_expression(grib_accessor* a, grib_expression *e){
  const char* cval;
  int ret=0;
  long lval=0;
  size_t len = 1;
  char tmp[1024];

  if (strcmp(e->cclass->name,"long")==0) {
    ret=grib_expression_evaluate_long(a->parent->h,e,&lval);
    ret = grib_pack_long(a,&lval,&len);
  } else {
    len = sizeof(tmp);
    cval = grib_expression_evaluate_string(a->parent->h,e,tmp,&len,&ret);
    if (ret!=GRIB_SUCCESS) {
      grib_context_log(a->parent->h->context,GRIB_LOG_ERROR,"grib_accessor_codetable.pack_expression: unable to evaluate string %s to be set in %s\n",grib_expression_get_name(e),a->name);
	  return ret;
    }
    len = strlen(cval) + 1;
    ret = grib_pack_string(a,cval,&len);
  }
  return ret;
}
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;

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

        }
      }

    }
  }

  return GRIB_NOT_FOUND;
}
示例#9
0
/* new GCC compiler v4.5.0 complains function is defined but not used*/
static void update_sections_lengths(grib_section* s)
{
    long   plen = 0;
    size_t  len = 1;

    if(!s) return;


    if(s->aclength)
    {
        int ret;
        if(s->owner)
            plen = grib_get_next_position_offset(s->block->last) - s->owner->offset;
        else
            plen = grib_get_next_position_offset(s->block->last);

        /* if(s->owner) */
        /* s->owner->length = plen; */

        /* if(s->aclength)  */
        if((ret = grib_pack_long(s->aclength, &plen, &len)) != GRIB_SUCCESS)
            ;

        if(s->h->context->debug)
        {
            printf("SECTION updating length %ld .. %s\n",plen,s->owner->name);
            printf("NEXT_POS = %ld, owner offset= %ld %s %s\n",
                    grib_get_next_position_offset(s->block->last),
                    s->owner ? s->owner->offset : 0L, s->owner->name,
                            s->block->last->name);
        }
    }

    if(s->owner)
        update_sections_lengths(s->owner->parent);

}
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 pack_string(grib_accessor* a, const char* buffer, size_t *len)
{
  grib_accessor_codetable* self = (grib_accessor_codetable*)a;
  grib_codetable*          table ;

  long i;
  size_t size = 1;

  typedef int (*cmpproc)(const char*, const char*);

  cmpproc cmp = a->flags | GRIB_ACCESSOR_FLAG_LOWERCASE ? strcasecmp : strcmp;

  if(!self->table) self->table = load_table(self);
  table=self->table;

  if(!table)
    return GRIB_ENCODING_ERROR;

  if (a->set) {
	  int err=grib_set_string(a->parent->h,a->set,buffer,len);
	  if (err!=0) return err;
  }

  for(i = 0 ; i < table->size; i++)
    if(table->entries[i].abbreviation)
		  if(cmp(table->entries[i].abbreviation,buffer) == 0)
        return grib_pack_long(a,&i,&size);

  if (a->flags & GRIB_ACCESSOR_FLAG_NO_FAIL) {
	  grib_action* act=(grib_action*)(a->creator);
	  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);
					  return ret;
				  }
				  len = strlen(p)+1;
				  pack_string(a,p,&len);
				  break;
		  }
		  return GRIB_SUCCESS;
	  }
	
  }
  return GRIB_ENCODING_ERROR;
}