static int compare(grib_accessor* a,grib_accessor* b) {
    long aval=0;
    long bval=0;

    long count=0;
    size_t alen = 0;
    size_t blen = 0;
    int err=0;

    err=grib_value_count(a,&count);
    if (err) return err;
    alen=count;

    err=grib_value_count(b,&count);
    if (err) return err;
    blen=count;

    if (alen !=1 || blen != 1) return GRIB_COUNT_MISMATCH;

    grib_unpack_long(a,&aval,&alen);
    grib_unpack_long(b,&bval,&blen);

    if (bval != aval) return GRIB_VALUE_MISMATCH;
    return GRIB_SUCCESS;
}
static void dump_long(grib_dumper* d,grib_accessor* a,const char* comment)
{
    grib_dumper_debug *self = (grib_dumper_debug*)d;
    long value; size_t size = 1;
    int err = grib_unpack_long(a,&value,&size);
    int i;

    if( a->length == 0  &&
            (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0)
        return;

    if( (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 &&
            (d->option_flags & GRIB_DUMP_FLAG_READ_ONLY) == 0)
        return;

    set_begin_end(d,a);

    for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," ");

    if( ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && grib_is_missing_internal(a))
        fprintf(self->dumper.out,"%ld-%ld %s %s = MISSING",self->begin,self->theEnd,a->creator->op, a->name);
    else
        fprintf(self->dumper.out,"%ld-%ld %s %s = %ld",self->begin,self->theEnd,a->creator->op, a->name,value);
    if(comment) fprintf(self->dumper.out," [%s]",comment);
    if(err)
        fprintf(self->dumper.out," *** ERR=%d (%s) [grib_dumper_debug::dump_long]",err,grib_get_error_message(err));

    aliases(d,a);


    fprintf(self->dumper.out,"\n");
}
static int unpack_string(grib_accessor*a , char*  v, size_t *len){

  long val = 0;
  size_t l = 1;
  char repres[1024];

  grib_unpack_long (a , &val, &l);

  if ((val == GRIB_MISSING_LONG) && ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) )
    sprintf(repres,"MISSING");
  else
    sprintf(repres,"%ld", val);

  l = strlen(repres)+1;

  if(l >*len ){
    grib_context_log(a->parent->h->context, GRIB_LOG_ERROR, "grib_accessor_long : unpack_string : Buffer too small for %s ", a->name );

    *len = l;
    return GRIB_BUFFER_TOO_SMALL;
  }
  grib_context_log(a->parent->h->context,GRIB_LOG_DEBUG, "grib_accessor_long: Casting long %s to string ", a->name);

  *len = l;

  strcpy(v,repres);
  return GRIB_SUCCESS;

}
static void dump_long(grib_dumper* d,grib_accessor* a,const char* comment)
{
  grib_dumper_serialize *self = (grib_dumper_serialize*)d;
  long value; size_t size = 1;
  int err = grib_unpack_long(a,&value,&size);

  if(  (a->flags & GRIB_ACCESSOR_FLAG_HIDDEN) != 0 )
    return;

  if( (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 &&
      (d->option_flags & GRIB_DUMP_FLAG_READ_ONLY) == 0 &&
      (strcmp(a->cclass->name,"lookup") != 0) )
    return;

  if( ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && (value == GRIB_MISSING_LONG))
    fprintf(self->dumper.out,"%s = MISSING", a->name);
  else
    fprintf(self->dumper.out,"%s = %ld", a->name,value);

  if ( ((a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0) &&
      (strcmp(a->cclass->name,"lookup") != 0) )
    fprintf(self->dumper.out," (read_only)");

#if 0
  if(comment) fprintf(self->dumper.out," [%s]",comment);
#endif
  if(err)
    fprintf(self->dumper.out," *** ERR=%d (%s) [grib_dumper_serialize::dump_long]",err,grib_get_error_message(err));

  fprintf(self->dumper.out,"\n");

}
static void dump_bits(grib_dumper* d,grib_accessor* a,const char* comment)
{
    grib_dumper_debug *self = (grib_dumper_debug*)d;
    long value; size_t size = 1;
    int err = grib_unpack_long(a,&value,&size);
    int i;

    if( a->length == 0  &&
            (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0)
        return;

    set_begin_end(d,a);

    for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," ");
    fprintf(self->dumper.out,"%ld-%ld %s %s = %ld [",self->begin,self->theEnd, a->creator->op,a->name,value);

    for(i=0;i<(a->length*8);i++) {
        if(test_bit(value,a->length*8-i-1))
            fprintf(self->dumper.out,"1");
        else
            fprintf(self->dumper.out,"0");
    }

    if(comment)
        fprintf(self->dumper.out,":%s]",comment);
    else
        fprintf(self->dumper.out,"]");

    if(err)
        fprintf(self->dumper.out," *** ERR=%d (%s) [grib_dumper_debug::dump_bits]",err,grib_get_error_message(err));

    aliases(d,a);
    fprintf(self->dumper.out,"\n");
}
static int unpack_double(grib_accessor* a, double* val,size_t *len){
  size_t rlen = 0;
  long count=0;
  unsigned long i = 0;
  long   *values = NULL;
  long   oneval = 0;
  int ret = GRIB_SUCCESS;

  ret=grib_value_count(a,&count);
  if (ret) return ret;
  rlen=count;

  if(*len < rlen)
  {
    grib_context_log(a->parent->h->context, GRIB_LOG_ERROR, " wrong size for %s it contains %d values ", a->name , rlen);
    *len = 0;
    return GRIB_ARRAY_TOO_SMALL;
  }

  if(rlen == 1){
    ret = grib_unpack_long(a,&oneval,&rlen);
    if(ret != GRIB_SUCCESS) return ret;
    *val =  oneval;
    *len = 1;
    return GRIB_SUCCESS;
  }

  values = (long*)grib_context_malloc(a->parent->h->context,rlen*sizeof(long));
  if(!values) return GRIB_INTERNAL_ERROR;


  ret = grib_unpack_long(a,values,&rlen);
  if(ret != GRIB_SUCCESS){
    grib_context_free(a->parent->h->context,values);
    return ret;
  }
  for(i=0; i< rlen;i++)
    val[i] = values[i];

  grib_context_free(a->parent->h->context,values);

  *len = rlen;
  return GRIB_SUCCESS;
}
static void dump_bits(grib_dumper* d,grib_accessor* a,const char* comment)
{
  grib_dumper_default *self = (grib_dumper_default*)d;
  int i;
  long value; size_t size = 1;
  int err = grib_unpack_long(a,&value,&size);

  if ( (a->flags & GRIB_ACCESSOR_FLAG_DUMP) == 0)
    return;

  print_offset(self->dumper.out,d,a);

  if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0) {
    fprintf(self->dumper.out,"  ");
    fprintf(self->dumper.out,"# type %s \n",a->creator->op);
  }

  aliases(d,a);
  if(comment) {
    fprintf(self->dumper.out,"  ");
    fprintf(self->dumper.out,"# %s \n",comment);
  }

  fprintf(self->dumper.out,"  ");
  fprintf(self->dumper.out,"# flags: ");
  for(i=0;i<(a->length*8);i++) {
    if(test_bit(value,a->length*8-i-1))
      fprintf(self->dumper.out,"1");
    else
      fprintf(self->dumper.out,"0");
  }
  fprintf(self->dumper.out,"\n");

  if (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) {
    fprintf(self->dumper.out,"  ");
    fprintf(self->dumper.out,"#-READ ONLY- ");
  } else
    fprintf(self->dumper.out,"  ");

  if( ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && grib_is_missing_internal(a) )
    fprintf(self->dumper.out,"%s = MISSING;",a->name);
  else
    fprintf(self->dumper.out,"%s = %ld;",a->name,value);


  if(err) {
    fprintf(self->dumper.out,"  ");
    fprintf(self->dumper.out,"# *** ERR=%d (%s) [grib_dumper_default::dump_bits]",err,grib_get_error_message(err));
  }

  fprintf(self->dumper.out,"\n");
}
static int compare(grib_accessor* a,grib_accessor* b) {
  int retval=0;
  long *aval=0;
  long *bval=0;
  long count=0;

  size_t alen = 0;
  size_t blen = 0;
  int err=0;

  err=grib_value_count(a,&count);
  if (err) return err;
  alen=count;

  err=grib_value_count(b,&count);
  if (err) return err;
  blen=count;

  if (alen != blen) return GRIB_COUNT_MISMATCH;

  aval=(long*)grib_context_malloc(a->parent->h->context,alen*sizeof(long));
  bval=(long*)grib_context_malloc(b->parent->h->context,blen*sizeof(long));

  grib_unpack_long(a,aval,&alen);
  grib_unpack_long(b,bval,&blen);

  retval = GRIB_SUCCESS;
  while (alen != 0) {
    if (*bval != *aval) retval = GRIB_LONG_VALUE_MISMATCH;
  alen--;
  }

  grib_context_free(a->parent->h->context,aval);
  grib_context_free(b->parent->h->context,bval);

  return retval;
}
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);

	/* TODO: fix me. For now, we don't fail on a lookup. */
#if 1
	*value = -1;
	return GRIB_SUCCESS;
#else
	return GRIB_NOT_FOUND;
#endif
}
static void dump(grib_accessor* a, grib_dumper* dumper)
{
    grib_accessor_codeflag* self = (grib_accessor_codeflag*)a;
    long v;
    char flagname[1024];
    char fname[1024];

    size_t llen = 1;

    grib_recompose_name(a->parent->h,NULL, self->tablename, fname,1);
    grib_unpack_long(a, &v, &llen);

    grib_get_codeflag(a, v, flagname);

    grib_dump_bits(dumper,a,flagname);
}
static int unpack_string (grib_accessor* a, char* buffer, size_t *len)
{
  grib_accessor_codetable* self = (grib_accessor_codetable*)a;
  grib_codetable*          table = NULL;

  size_t size = 1;
  long   value;
  int err = GRIB_SUCCESS;
  char tmp[1024];
  size_t l = 0;

  if( (err = grib_unpack_long(a,&value,&size)) != GRIB_SUCCESS)
    return err;

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

  if(table && (value >= 0) && (value < table->size) && table->entries[value].abbreviation)
  {
    strcpy(tmp,table->entries[value].abbreviation);
  }
  else
  {

#if 1
    sprintf(tmp,"%d",(int)value);
#else
    return GRIB_DECODING_ERROR;
#endif
  }


  l = strlen(tmp) + 1;

  if(*len < l)
  {
    *len = l;
    return GRIB_BUFFER_TOO_SMALL;
  }

  strcpy(buffer,tmp);
  *len = l;

  return GRIB_SUCCESS;
}
static int unpack_string (grib_accessor* a, char* buffer, size_t *len)
{
  grib_accessor_codetable_title* self = (grib_accessor_codetable_title*)a;
  grib_codetable*          table = NULL;

  size_t size = 1;
  long   value;
  int err = GRIB_SUCCESS;
  char tmp[1024];
  size_t l = 1024;
  grib_accessor_codetable* ca=(grib_accessor_codetable*)grib_find_accessor(a->parent->h,self->codetable);

  if( (err = grib_unpack_long((grib_accessor*)ca,&value,&size)) != GRIB_SUCCESS)
    return err;

  table=ca->table;

  if(table && (value >= 0) && (value < table->size) && table->entries[value].title)
  {
    strcpy(tmp,table->entries[value].title);
  }
  else
  {

#if 1
    sprintf(tmp,"%d",(int)value);
#else
    return GRIB_DECODING_ERROR;
#endif
  }


  l = strlen(tmp) + 1;

  if(*len < l)
  {
    *len = l;
    return GRIB_BUFFER_TOO_SMALL;
  }

  strcpy(buffer,tmp);
  *len = l;

  return GRIB_SUCCESS;
}
static void dump_bits(grib_dumper* d,grib_accessor* a,const char* comment)
{
  grib_dumper_wmo *self = (grib_dumper_wmo*)d;
  int i;
  long value = 0; size_t size = 1;
  int err = grib_unpack_long(a,&value,&size);

  if( a->length == 0  &&
      (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0)
    return;

  set_begin_end(d,a);

  /*for(i = 0; i < d->depth ; i++) fprintf(self->dumper.out," ");*/
  print_offset(self->dumper.out,self->begin,self->theEnd);
  if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0)
        fprintf(self->dumper.out,"%s ",a->creator->op);

  fprintf(self->dumper.out,"%s = %ld [",a->name,value);

  for(i=0;i<(a->length*8);i++) {
    if(test_bit(value,a->length*8-i-1))
      fprintf(self->dumper.out,"1");
    else
      fprintf(self->dumper.out,"0");
  }
/*
  if(comment)
    fprintf(self->dumper.out,":%s]",comment);
  else
*/
  fprintf(self->dumper.out,"]");

  if (err==0) print_hexadecimal(self->dumper.out,d->option_flags,a);

  if(err)
    fprintf(self->dumper.out," *** ERR=%d (%s) [grib_dumper_wmo::dump_bits]",err,grib_get_error_message(err));

  aliases(d,a);
  fprintf(self->dumper.out,"\n");
}
static int unpack_long(grib_accessor* a, long* val, size_t *len) {
  size_t size=0;
  long* vector;
  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;

  /*TODO implement the dirty mechanism to avoid to unpack every time */
  grib_get_size(a->parent->h,self->vector,&size);
  vector=(long*)grib_context_malloc(a->parent->h->context,sizeof(long)*size);
  grib_unpack_long(va,vector,&size);
  grib_context_free(a->parent->h->context,vector);
  

  *val = v->v[self->index];

  return GRIB_SUCCESS;
}
static void dump_bits(grib_dumper* d,grib_accessor* a,const char* comment)
{
  grib_dumper_c_code *self = (grib_dumper_c_code*)d;
  long value; size_t size = 1;
  int err = grib_unpack_long(a,&value,&size);
  int i;

  char buf[1024];

  if(a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY)
    return;

  if(a->length == 0)
    return;

  buf[0] = 0;

  for(i=0;i<(a->length*8);i++) {
    if(test_bit(value,a->length*8-i-1))
      strcat(buf,"1");
    else
      strcat(buf,"0");
  }

  if(comment) {
    strcat(buf,";");
    strcat(buf,comment);
  }

  pcomment(self->dumper.out,value,buf);

  if(err)
    fprintf(self->dumper.out," /*  Error accessing %s (%s) */",a->name,grib_get_error_message(err));
  else
    fprintf(self->dumper.out,"    GRIB_CHECK(grib_set_long(h,\"%s\",%ld),%d);\n",a->name,value,0);

  fprintf(self->dumper.out,"\n");
}
static void dump_bits(grib_dumper* d,grib_accessor* a,const char* comment)
{
  grib_dumper_serialize *self = (grib_dumper_serialize*)d;
  long value; size_t size = 1;
  int err = grib_unpack_long(a,&value,&size);

  if(  (a->flags & GRIB_ACCESSOR_FLAG_HIDDEN) != 0 )
    return;

  if( (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 &&
      (d->option_flags & GRIB_DUMP_FLAG_READ_ONLY) == 0)
    return;

  fprintf(self->dumper.out,"%s = %ld ", a->name,value);

#if 0

  fprintf(self->dumper.out,"[");
  for(i=0;i<(a->length*8);i++) {
    if(test_bit(value,a->length*8-i-1))
      fprintf(self->dumper.out,"1");
    else
      fprintf(self->dumper.out,"0");
  }

  if(comment)
    fprintf(self->dumper.out,":%s]",comment);
  else
    fprintf(self->dumper.out,"]");
#endif
  if(err)
    fprintf(self->dumper.out," *** ERR=%d (%s)",err,grib_get_error_message(err));

  fprintf(self->dumper.out,"\n");

}
static void dump_long(grib_dumper* d,grib_accessor* a,const char* comment)
{
  grib_dumper_c_code *self = (grib_dumper_c_code*)d;
  long value; size_t size = 1;
  int err = grib_unpack_long(a,&value,&size);

  if((a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY))
    return;

#if 1
  if(comment) pcomment(self->dumper.out,value,comment);
#endif

  if( ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && (value == GRIB_MISSING_LONG))
    fprintf(self->dumper.out,"    GRIB_CHECK(grib_set_missing(h,\"%s\"),%d);\n",a->name,0);
  else
    fprintf(self->dumper.out,"    GRIB_CHECK(grib_set_long(h,\"%s\",%ld),%d);\n",a->name,value,0);

  if(err)
    fprintf(self->dumper.out," /*  Error accessing %s (%s) */",a->name,grib_get_error_message(err));

  if(comment) fprintf(self->dumper.out,"\n");

}
static void dump_long(grib_dumper* d,grib_accessor* a,const char* comment)
{
  grib_dumper_wmo *self = (grib_dumper_wmo*)d;
  long value = 0; size_t size =0;
  long *values=NULL;
  int err = 0;
  int i=0;
  long count=0;

  grib_value_count(a,&count);
  size=count;


  if (size>1) {
  	values=(long*)grib_context_malloc_clear(a->parent->h->context,sizeof(long)*size);
	err=grib_unpack_long(a,values,&size);
  } else {
	err=grib_unpack_long(a,&value,&size);
  }

  if( a->length == 0  &&
      (d->option_flags & GRIB_DUMP_FLAG_CODED) != 0)
    return;

  if( (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) != 0 &&
      (d->option_flags & GRIB_DUMP_FLAG_READ_ONLY) == 0)
    return;

  set_begin_end(d,a);


  print_offset(self->dumper.out,self->begin,self->theEnd);

  if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0)
        fprintf(self->dumper.out,"%s ",a->creator->op);

  if (size>1) {
	int cols=19;
	int count=0;
	fprintf(self->dumper.out,"%s = { \t",a->name);
	for (i=0;i<size;i++) {
		if (count>cols) {fprintf(self->dumper.out,"\n\t\t\t\t");count=0;}
		fprintf(self->dumper.out,"%ld ",values[i]);
		count++;
	}
	fprintf(self->dumper.out,"}\n");
	grib_context_free(a->parent->h->context,values);
  } else {
	  if( ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && grib_is_missing_internal(a) )
		fprintf(self->dumper.out,"%s = MISSING",a->name);
	  else
		fprintf(self->dumper.out,"%s = %ld",a->name,value);

	  print_hexadecimal(self->dumper.out,d->option_flags,a);

	  if(comment) fprintf(self->dumper.out," [%s]",comment);
  }
  if(err)
    fprintf(self->dumper.out," *** ERR=%d (%s) [grib_dumper_wmo::dump_long]",err,grib_get_error_message(err));

  aliases(d,a);


  fprintf(self->dumper.out,"\n");
}
static void dump(grib_accessor* a, grib_dumper* dumper) {
  grib_accessor_codetable* self  = (grib_accessor_codetable*)a;
  char comment[2048];
  grib_codetable* table;

  size_t llen = 1;
  long value;

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

  grib_unpack_long(a, &value,&llen);

  if(value == GRIB_MISSING_LONG)
  {
    if(a->length < 4)
    {
      value = (1L << a->length) - 1;
    }
  }

  if(table && value >= 0 && value < table->size)
  {
    if(table->entries[value].abbreviation)
    {
      int b = atol(table->entries[value].abbreviation);
      if(b == value)
        strcpy(comment,table->entries[value].title);
      else
        sprintf(comment,"%s", table->entries[value].title);

      if (table->entries[value].units!=NULL && strcmp(table->entries[value].units,"unknown")) {
        strcat(comment," (");
        strcat(comment,table->entries[value].units);
        strcat(comment,") ");
      }
    }
    else
    {
      strcpy(comment,"Unknown code table entry");
    }

  }
  else
  {
    strcpy(comment,"Unknown code table entry");
  }

  strcat(comment," (");
  if (table) {
    strcat(comment,table->recomposed_name[0]);
    if (table->recomposed_name[1]!=NULL) {
      strcat(comment," , ");
      strcat(comment,table->recomposed_name[1]);
    }
  }
  strcat(comment,") ");

  grib_dump_long(dumper,a,comment);

}
static void dump_long(grib_dumper* d,grib_accessor* a,const char* comment)
{
  grib_dumper_default *self = (grib_dumper_default*)d;
  long value; size_t size = 1;
  long *values=NULL;
  int err = 0;
  int i;
  long count=0;

  grib_value_count(a,&count);
  size=count;

  if ( (a->flags & GRIB_ACCESSOR_FLAG_DUMP) == 0)
    return;

  print_offset(self->dumper.out,d,a);

  if ((d->option_flags & GRIB_DUMP_FLAG_TYPE) != 0){
    fprintf(self->dumper.out,"  ");
    fprintf(self->dumper.out,"# type %s \n",a->creator->op);
  }

  if (size>1) {
    values=(long *)grib_context_malloc_clear(a->parent->h->context,sizeof(long)*size);
    err=grib_unpack_long(a,values,&size);
  } else {
    err=grib_unpack_long(a,&value,&size);
  }

  aliases(d,a);
  if(comment) {
    fprintf(self->dumper.out,"  ");
    fprintf(self->dumper.out,"# %s \n",comment);
  }

  if (a->flags & GRIB_ACCESSOR_FLAG_READ_ONLY) {
    fprintf(self->dumper.out,"  ");
    fprintf(self->dumper.out,"#-READ ONLY- ");
  } else
    fprintf(self->dumper.out,"  ");

  if (size>1) {
    int cols=19;
    int count=0;
    fprintf(self->dumper.out,"%s = { \t",a->name);
    for (i=0;i<size;i++) {
        if (count>cols) {fprintf(self->dumper.out,"\n\t\t\t\t");count=0;}
        fprintf(self->dumper.out,"%ld ",values[i]);
        count++;
    }
    fprintf(self->dumper.out,"}\n");
    grib_context_free(a->parent->h->context,values);
  } else {
	  if( ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && grib_is_missing_internal(a) )
		fprintf(self->dumper.out,"%s = MISSING;",a->name);
	  else
		fprintf(self->dumper.out,"%s = %ld;",a->name,value);
  }

  if(err) {
    fprintf(self->dumper.out,"  ");
    fprintf(self->dumper.out,"# *** ERR=%d (%s) [grib_dumper_default::dump_long]",err,grib_get_error_message(err));
  }

  fprintf(self->dumper.out,"\n");
}