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