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
static int    pack_long   (grib_accessor* a, const long *val, size_t *len)
{
	grib_accessor_bit *ac = (grib_accessor_bit*) a;
	grib_accessor* owner = NULL;
	unsigned char *mdata = 0;
	if(*len < 1)
	{
		grib_context_log(a->parent->h->context, GRIB_LOG_ERROR, "grib_accessor_bit : pack_long : At least one value to pack for %s", a->name );
		*len = 0;
		return GRIB_ARRAY_TOO_SMALL;
	}

	owner = grib_find_accessor(a->parent->h,ac->owner);

	if(!owner){
		grib_context_log(a->parent->h->context, GRIB_LOG_ERROR, "grib_accessor_bit : Cannot get the owner %s for computing the bit value of %s ",ac->owner, a->name);
		*len = 0;
		return GRIB_NOT_FOUND;
	}

	mdata = a->parent->h->buffer->data;
	mdata += grib_byte_offset(owner);

	grib_set_bit( mdata,7-ac->bit_index , *val>0);

	*len = 1;
	return GRIB_SUCCESS;
}
static int unpack_double(grib_accessor* a, double* val, size_t *len)
{
    grib_accessor_bits* self = (grib_accessor_bits*)a;
    grib_accessor* x=NULL;
    unsigned char* p=NULL;
    grib_handle* h=grib_handle_of_accessor(a);
    long start,length;
    int ret=0;

    if(*len < 1) return GRIB_WRONG_ARRAY_SIZE;

    start=self->start;
    length=self->len;

    x=grib_find_accessor(grib_handle_of_accessor(a),self->argument);
    if (!x) return GRIB_NOT_FOUND;

    p  = h->buffer->data + grib_byte_offset(x);
    *val=grib_decode_unsigned_long(p,&start,length);

    *val=((long)*val+self->referenceValue)/self->scale;

    *len=1;

    return ret;
}
static int  unpack_double(grib_accessor* a, double* val, size_t *len)
{
    grib_accessor_data_dummy_field* self =  (grib_accessor_data_dummy_field*)a;
    size_t i = 0;
    size_t n_vals = 0;
    long numberOfPoints;
    double missing_value = 0;
    int err = 0;

    if((err = grib_get_long_internal(a->parent->h,self->numberOfPoints, &numberOfPoints))
            != GRIB_SUCCESS)  return err;
    n_vals =numberOfPoints;

    if((err = grib_get_double_internal(a->parent->h,self->missing_value, &missing_value))
            != GRIB_SUCCESS)		return err;

    if(*len < n_vals) {
        *len = n_vals;
        return GRIB_ARRAY_TOO_SMALL;
    }

    for(i=0; i < n_vals; i++)
        val[i] = missing_value;

    if(grib_find_accessor(a->parent->h,self->bitmap)) {
        if((err = grib_set_double_array_internal(a->parent->h,self->bitmap,val,n_vals)) != GRIB_SUCCESS)
            return err;
    }

    *len = (long) n_vals;
    return err;
}
Пример #5
0
grib_accessor* grib_find_accessor(grib_handle* h, const char* name)
{
    grib_accessor* a = NULL;
    char* p=NULL;

    p=(char*)name;
    Assert(name);

    while ( *p != '.' && *p != '\0' ) p++;
    if ( *p == '.' ) {
        int i=0,len=0;
        char name_space[1024];
        char* basename=NULL;
        basename=p+1;
        p--;
        i=0;
        len=p-name+1;

        for ( i=0;i<len;i++ ) name_space[i] = *(name+i);

        name_space[len]='\0';

        a = search_and_cache(h,basename,name_space);
    } else {
        a = search_and_cache(h,name,NULL);
    }

    if(a == NULL && h->main)
        a = grib_find_accessor(h->main,name);

    return a;
}
Пример #6
0
static int create_accessor(grib_section* p, grib_action* act,grib_loader *h)
{
	grib_action_put* a = ( grib_action_put*)act;

	grib_section* ts = NULL;

	grib_accessor* ga = NULL;

	ga = grib_find_accessor(p->h, grib_arguments_get_name(p->h,a->args,1));
	if(ga)
		ts = ga->sub_section;
		/* ts = grib_get_sub_section(ga); */
	else  return GRIB_BUFFER_TOO_SMALL;

	if(ts){
		ga = grib_accessor_factory( ts, act,0,a->args);
		if(ga)grib_push_accessor(ga,ts->block);
		else  return GRIB_BUFFER_TOO_SMALL;

	}
	else{
		grib_context_log(act->context, GRIB_LOG_ERROR, "Action_class_put  : create_accessor_buffer : No Section named %s to export %s ", grib_arguments_get_name(p->h,a->args,1), grib_arguments_get_name(p->h,a->args,0));
	}
	return GRIB_SUCCESS; 
}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
  int ret=GRIB_SUCCESS;
  long bitmap_present=0;

  grib_accessor_data_apply_gdsnotpresent* self =  (grib_accessor_data_apply_gdsnotpresent*)a;

  if (*len ==0) return GRIB_NO_VALUES;

  ret=grib_set_long(a->parent->h,self->bitmap_present,bitmap_present);
  if(ret) {
    grib_context_log(a->parent->h->context, GRIB_LOG_ERROR,
       "Accessor %s cannont pack value for %s error %d \n", a->name, self->bitmap_present, ret);
    return ret;
  }

#if 0
  if(!grib_find_accessor(a->parent->h,self->bitmap)){
    grib_context_log(a->parent->h->context, GRIB_LOG_ERROR,
       "Accessor %s cannont access bitmap \n", a->name, self->bitmap_present, ret);
    return ret;
  }
#endif


  ret = grib_set_double_array_internal(a->parent->h,self->coded_values,val,*len);
  if(ret) {
    grib_context_log(a->parent->h->context, GRIB_LOG_ERROR,
       "Accessor %s cannont pack value for %s error %d \n", a->name, self->coded_values, ret);
    return ret;
  }

  return ret;
}
static int    pack_long   (grib_accessor* a, const long* val, size_t *len)
{
  grib_accessor_dirty* self = (grib_accessor_dirty*)a;
  grib_accessor* x=grib_find_accessor(a->parent->h,self->accessor);

  if (x) x->dirty=*val;

  return GRIB_SUCCESS;
}
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
    grib_accessor_data_apply_bitmap* self =  (grib_accessor_data_apply_bitmap*)a;
    int err = 0;
    size_t bmaplen = *len;
    long coded_n_vals = 0;
    double* coded_vals = NULL;
    long i = 0;
    long j = 0;
    double missing_value = 0;

    if (*len ==0) return GRIB_NO_VALUES;

    if(!grib_find_accessor(a->parent->h,self->bitmap)){
        err = grib_set_double_array_internal(a->parent->h,self->coded_values,val,*len);
        /*printf("SETTING TOTAL number_of_data_points %s %ld\n",self->number_of_data_points,*len);*/
        if(self->number_of_data_points)
            grib_set_long_internal(a->parent->h,self->number_of_data_points,*len);
        return err;
    }

    if((err = grib_get_double_internal(a->parent->h,self->missing_value,&missing_value)) != GRIB_SUCCESS)
        return err;

    if((err = grib_set_double_array_internal(a->parent->h,self->bitmap,val,bmaplen)) != GRIB_SUCCESS)
        return err;

    coded_n_vals = *len;

    if(coded_n_vals <  1){
        err = grib_set_double_array_internal(a->parent->h,self->coded_values,NULL,0);
        return err;
    }

    coded_vals = (double*)grib_context_malloc_clear(a->parent->h->context,coded_n_vals*sizeof(double));
    if(!coded_vals) return GRIB_OUT_OF_MEMORY;

    for(i=0; i<*len ; i++)
    {
        if(val[i] != missing_value) {
            coded_vals[j++] = val[i];
        }
    }

    err = grib_set_double_array_internal(a->parent->h,self->coded_values,coded_vals,j);
    if (j==0) {
        if (self->number_of_values)
            err=grib_set_long_internal(a->parent->h,self->number_of_values,0);
        if (self->binary_scale_factor)
            err=grib_set_long_internal(a->parent->h,self->binary_scale_factor,0);
    }

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

    return err;
}
Пример #10
0
static int unpack_string(grib_accessor*a , char*  v, size_t *len){
  grib_accessor_md5* self = (grib_accessor_md5*)a;
  unsigned mess_len;
  unsigned char* mess;
  unsigned char* p;
  unsigned char digest[16];
  long offset,length;
  grib_string_list* blacklist=NULL;
  grib_accessor* b=NULL;
  int ret=0;
  char* s=NULL;
  int i=0;
  struct cvs_MD5Context md5c;

  if (*len <32 ) {
    grib_context_log(a->parent->h->context,GRIB_LOG_ERROR,"md5: array too small");
    return GRIB_ARRAY_TOO_SMALL;
  }
  
  if((ret = grib_get_long_internal(a->parent->h,self->offset,&offset))
      != GRIB_SUCCESS)
    return ret;
  if((ret = grib_get_long_internal(a->parent->h,self->length,&length))
      != GRIB_SUCCESS)
    return ret;

  
  mess=grib_context_malloc(a->parent->h->context,length);
  memcpy(mess,a->parent->h->buffer->data+offset,length);
  mess_len=length;

  blacklist=a->parent->h->context->blacklist;
  while (blacklist && blacklist->value) {
    
    b=grib_find_accessor(a->parent->h,blacklist->value);
    if (!b) return GRIB_NOT_FOUND;

    p=mess+b->offset-offset;
    for (i=0;i<b->length;i++) *(p++)=0;

    blacklist=blacklist->next;
  }

  cvs_MD5Init(&md5c);
  cvs_MD5Update(&md5c,mess,mess_len);
  cvs_MD5Final(digest,&md5c);

  s=v;
  for (i = 0; i < 16; i++)
  {
    sprintf (s,"%02x", (unsigned int) digest[i]);
    s+=2;
  }

  return ret;
}
Пример #11
0
static int unpack_string(grib_accessor*a , char*  v, size_t *len){
    grib_accessor_md5* self = (grib_accessor_md5*)a;
    unsigned mess_len;
    unsigned char* mess;
    unsigned char* p;
    long offset,length;
    grib_string_list* blacklist=NULL;
    grib_accessor* b=NULL;
    int ret=0;
    int i=0;
    struct grib_md5_state md5c;

    if (*len <32 ) {
        grib_context_log(a->context,GRIB_LOG_ERROR,"md5: array too small");
        return GRIB_ARRAY_TOO_SMALL;
    }

    if((ret = grib_get_long_internal(grib_handle_of_accessor(a),self->offset,&offset))
            != GRIB_SUCCESS)
        return ret;
  if((ret = grib_expression_evaluate_long(grib_handle_of_accessor(a),self->length,&length))
            != GRIB_SUCCESS)
        return ret;

    mess=(unsigned char*)grib_context_malloc(a->context,length);
    memcpy(mess,grib_handle_of_accessor(a)->buffer->data+offset,length);
    mess_len=length;

    blacklist=a->context->blacklist;
  /* passed blacklist overrides context blacklist. 
     Consider to modify following line to extend context blacklist.
  */
  if (self->blacklist) blacklist=self->blacklist;
    while (blacklist && blacklist->value) {
        b=grib_find_accessor(grib_handle_of_accessor(a),blacklist->value);
        if (!b) {
            grib_context_free(a->context,mess);
            return GRIB_NOT_FOUND;
        }

        p=mess+b->offset-offset;
        for (i=0;i<b->length;i++) *(p++)=0;

        blacklist=blacklist->next;
    }

    grib_md5_init(&md5c);
    grib_md5_add(&md5c,mess,mess_len);
    grib_md5_end(&md5c,v);
    grib_context_free(a->context,mess);

    return ret;
}
static int value_count(grib_accessor* a,long* count)
{
    grib_accessor_data_apply_boustrophedonic_bitmap *self =(grib_accessor_data_apply_boustrophedonic_bitmap*)a;
    size_t len = 0;
    int ret = 0;

    /* This accessor is for data with a bitmap after all */
    Assert(grib_find_accessor(a->parent->h, self->bitmap));

    ret = grib_get_size(a->parent->h, self->bitmap, &len);
    *count=len;
    return ret;
}
static void  add_dependency(grib_expression* g, grib_accessor* observer){
  grib_expression_accessor* e = (grib_expression_accessor*)g;
  grib_accessor *observed = grib_find_accessor(observer->parent->h,e->name);

  if(!observed)
  {
    /* grib_context_log(observer->parent->h->context, GRIB_LOG_ERROR, */
         /* "Error in accessor_add_dependency: cannot find [%s]", e->name); */
       /* Assert(observed); */
    return;
  }

  grib_dependency_add(observer,observed);
}
Пример #14
0
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 int value_count(grib_accessor* a,long* count)
{
    grib_accessor_data_apply_bitmap *self =(grib_accessor_data_apply_bitmap*)a;
    size_t len = 0;
    int ret = 0;

    if(grib_find_accessor(a->parent->h,self->bitmap))
        ret =  grib_get_size(a->parent->h,self->bitmap,&len);
    else
        ret =  grib_get_size(a->parent->h,self->coded_values,&len);

    *count=len;

    return ret;
}
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 unpack_double(grib_accessor* a, double* val, size_t *len) {
  long lval=0;
  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;
  
  err=unpack_long(a,&lval,len);

  *val = (double)v->v[self->index];

  return err;
}
grib_nearest* grib_nearest_new(grib_handle* h,int* error)
{
  grib_accessor* a = NULL;
  grib_accessor_nearest* na =NULL;
  grib_nearest* n =NULL;
  *error=GRIB_NOT_IMPLEMENTED;
  a = grib_find_accessor(h,"NEAREST");
  na = (grib_accessor_nearest*)a;

  if (!a) return NULL;

  n = grib_nearest_factory(h,na->args);

  if (n) *error=GRIB_SUCCESS;

  return n;
}
grib_iterator* grib_iterator_new(grib_handle* h,unsigned long flags,int* error)
{   
	grib_accessor* a = NULL;
	grib_accessor_iterator* ita =NULL; 
	grib_iterator* iter =NULL;
	*error=GRIB_NOT_IMPLEMENTED;
	a = grib_find_accessor(h,"ITERATOR");
	ita = (grib_accessor_iterator*)a;

	if (!a) return NULL;

	iter = grib_iterator_factory(h,ita->args,flags,error);

	if (iter) *error=GRIB_SUCCESS;

	return iter;
}
Пример #20
0
grib_box* grib_box_new(grib_handle* h,int* error)
{
  grib_accessor* a = NULL;
  grib_accessor_box* na =NULL;
  grib_box* n =NULL;
  *error=GRIB_NOT_IMPLEMENTED;
  a = grib_find_accessor(h,"BOX");
  na = (grib_accessor_box*)a;

  if (!a) return NULL;

  n = grib_box_factory(h,na->args);

  if (n) *error=GRIB_SUCCESS;

  return n;
}
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 int unpack_long(grib_accessor* a, long* val,size_t *len)
{
    grib_accessor_g1_message_length *self = (grib_accessor_g1_message_length*)a;
    int ret;

    long total_length, sec4_length;

    if((ret = grib_get_g1_message_size(a->parent->h,
                                       a,
                                       grib_find_accessor(a->parent->h,self->sec4_length),
                                       &total_length,
                                       &sec4_length)) != GRIB_SUCCESS)
        return ret;


    *val = total_length;
    return GRIB_SUCCESS;
}
Пример #23
0
static int create_accessor(grib_section* p, grib_action* act,grib_loader *h)
{
	grib_action_modify* a = ( grib_action_modify*)act;


	grib_accessor* ga = NULL;

	ga = grib_find_accessor(p->h, a->name);

	if(ga)
		ga->flags = a->flags;

	else{
		grib_context_log(act->context, GRIB_LOG_DEBUG, "action_class_modify: create_accessor_buffer : No accessor named %s to modify.", a->name);
	}
	return GRIB_SUCCESS;


}
static void init(grib_accessor* a,const long l, grib_arguments* c)
{
  grib_accessor_long_vector* self = (grib_accessor_long_vector*)a;
  grib_accessor* va=NULL;
  grib_accessor_abstract_long_vector* v =NULL;
  int n = 0;

  self->vector = grib_arguments_get_name(a->parent->h,c,n++);

  va=(grib_accessor*)grib_find_accessor(a->parent->h,self->vector);
  v=(grib_accessor_abstract_long_vector*)va;

  self->index = grib_arguments_get_long(a->parent->h,c,n++);

  /* check self->index on init and never change it */
  Assert(self->index < v->number_of_elements && self->index>=0);

  a->length=0;
}
Пример #25
0
static int pack_long(grib_accessor* a, const long* val, size_t *len)
{
  grib_accessor_bits* self = (grib_accessor_bits*)a;
  grib_accessor* x=NULL;
  grib_handle* h=a->parent->h;
  unsigned char* p=NULL;
  long start,length;

  if(*len != 1) return GRIB_WRONG_ARRAY_SIZE;

  start  = self->start;
  length = self->len;
  
  x=grib_find_accessor(a->parent->h,self->argument);
  if (!x) return GRIB_NOT_FOUND;

  p=h->buffer->data + grib_byte_offset(x);
  return grib_encode_unsigned_longb(p,*val,&start,length);

}
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;
}
Пример #27
0
static int pack_double(grib_accessor* a, const double* val, size_t *len)
{
    grib_accessor_bits* self = (grib_accessor_bits*)a;
    grib_accessor* x=NULL;
    grib_handle* h=grib_handle_of_accessor(a);
    unsigned char* p=NULL;
    long start,length,lval;

    if(*len != 1) return GRIB_WRONG_ARRAY_SIZE;

    start  = self->start;
    length = self->len;

    x=grib_find_accessor(grib_handle_of_accessor(a),self->argument);
    if (!x) return GRIB_NOT_FOUND;

    p=h->buffer->data + grib_byte_offset(x);

    lval= round(*val * self->scale) - self->referenceValue;
    return grib_encode_unsigned_longb(p,lval,&start,length);
}
static void compute_size(grib_accessor* a)
{
    long slen = 0;
    long off = 0;

    grib_accessor_bitmap* self = (grib_accessor_bitmap*)a;
    grib_get_long_internal(a->parent->h, self->offsetbsec,&off);
    grib_get_long_internal(a->parent->h, self->sLength, &slen);

    if(slen == 0)
    {
        grib_accessor* seclen;
        size_t size;
        /* Assume reparsing */
        Assert(a->parent->h->loader != 0);
        if (a->parent->h->loader != 0) {
            seclen = grib_find_accessor(a->parent->h, self->sLength);
            Assert(seclen);
            grib_get_block_length(seclen->parent,&size);
            slen = size;
        }
    }

#if 0
    printf("compute_size off=%ld slen=%ld a->offset=%ld\n",
            (long)off,(long)slen,(long)a->offset);
#endif

    a->length = off+(slen-a->offset);

    if(a->length < 0)
    {
        /* Assume reparsing */
        /*Assert(a->parent->h->loader != 0);*/
        a->length = 0;
    }

    Assert(a->length>=0);
}
Пример #29
0
static int pack_long(grib_accessor* a, const long* val, size_t *len)
{
    grib_accessor_bits* self = (grib_accessor_bits*)a;
    grib_accessor* x=NULL;
    grib_handle* h=grib_handle_of_accessor(a);
    unsigned char* p=NULL;
    long start,length, maxval;

    if(*len != 1) return GRIB_WRONG_ARRAY_SIZE;

    if (get_native_type(a) == GRIB_TYPE_DOUBLE) {
        /* ECC-402 */
        const double dVal = (double)(*val);
        return pack_double(a, &dVal, len);
    }

    start  = self->start;
    length = self->len;

    x=grib_find_accessor(grib_handle_of_accessor(a),self->argument);
    if (!x) return GRIB_NOT_FOUND;

    /* Check the input value */
    if (*val < 0) {
        grib_context_log(h->context, GRIB_LOG_ERROR, "key=%s: value cannot be negative",a->name);
        return GRIB_ENCODING_ERROR;
    }
    maxval = (1 << length) - 1;
    if (*val > maxval){
        grib_context_log(h->context, GRIB_LOG_ERROR,
                "key=%s: Trying to encode value of %ld but the maximum allowable value is %ld (number of bits=%ld)",
                a->name, *val, maxval, length);
        return GRIB_ENCODING_ERROR;
    }

    p=h->buffer->data + grib_byte_offset(x);
    return grib_encode_unsigned_longb(p,*val,&start,length);
}
static int unpack_double_element(grib_accessor* a, size_t idx,double* val)
{
    grib_accessor_data_apply_boustrophedonic_bitmap* self =  (grib_accessor_data_apply_boustrophedonic_bitmap*)a;
    int err = 0,i=0;
    size_t cidx=0;
    double missing_value = 0;
    double* bvals=NULL;
    size_t n_vals = 0;
    long nn=0;

    err=grib_value_count(a,&nn);
    n_vals=nn;
    if (err) return err;

    if(!grib_find_accessor(a->parent->h,self->bitmap))
        return grib_get_double_element_internal(a->parent->h,self->coded_values,idx,val);

    if((err = grib_get_double_internal(a->parent->h,self->missing_value,&missing_value)) != GRIB_SUCCESS)
        return err;

    if((err = grib_get_double_element_internal(a->parent->h,self->bitmap,idx,val)) != GRIB_SUCCESS)
        return err;

    if (*val == 0) {*val=missing_value;return GRIB_SUCCESS;}

    bvals = (double*)grib_context_malloc(a->parent->h->context,n_vals*sizeof(double));
    if(bvals == NULL) return GRIB_OUT_OF_MEMORY;

    if((err = grib_get_double_array_internal(a->parent->h,self->bitmap,bvals,&n_vals)) != GRIB_SUCCESS)
        return err;

    cidx=0;
    for (i=0;i<idx;i++) {cidx+=bvals[i];}

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

    return grib_get_double_element_internal(a->parent->h,self->coded_values,cidx,val);
}