diff --git a/src/grib_accessor_class_bufr_data_array.c b/src/grib_accessor_class_bufr_data_array.c index 26f6d4a38..477463e93 100644 --- a/src/grib_accessor_class_bufr_data_array.c +++ b/src/grib_accessor_class_bufr_data_array.c @@ -464,7 +464,7 @@ static void decode_element(grib_context* c,grib_accessor_bufr_data_array* self, } static int build_bitmap(grib_accessor_bufr_data_array *self,unsigned char* data,long* pos,grib_iarray* elementsDescriptorsIndex,int iBitmapOperator) { - int bitmapSize,iDelayedReplication=0; + int bitmapSize=0,iDelayedReplication=0; int i,localReference,width,bitmapEndElementsDescriptorsIndex; long ppos,n; grib_accessor* a=(grib_accessor*)self; @@ -567,11 +567,9 @@ static void push_zero_element(grib_accessor_bufr_data_array* self,grib_darray* d } } -#if 0 -static grib_accessor* create_accessor_from_descriptor(grib_accessor* a,long ide,long subset) { +static grib_accessor* create_accessor_from_descriptor(grib_accessor* a,grib_section* section,long ide,long subset) { grib_accessor_bufr_data_array *self =(grib_accessor_bufr_data_array*)a; int idx=0; - grib_section* section=0; grib_accessor* elementAccessor=NULL; grib_action creator = {0, }; creator.op = "bufr_data_element"; @@ -580,12 +578,12 @@ static grib_accessor* create_accessor_from_descriptor(grib_accessor* a,long ide, creator.set = 0; idx = self->compressedData ? self->elementsDescriptorsIndex->v[0]->v[ide] : - self->elementsDescriptorsIndex->v[ide]->v[subset]; + self->elementsDescriptorsIndex->v[subset]->v[ide] ; creator.name=self->expanded->v[idx]->shortName; if (creator.name) { - section=a->sub_section; elementAccessor = grib_accessor_factory(section, &creator, 0, NULL); + if (self->canBeMissing[idx]) elementAccessor->flags |= GRIB_ACCESSOR_FLAG_CAN_BE_MISSING; accessor_bufr_data_element_set_index(elementAccessor,ide); accessor_bufr_data_element_set_descriptors(elementAccessor,self->expanded); accessor_bufr_data_element_set_numericValues(elementAccessor,self->numericValues); @@ -599,27 +597,125 @@ static grib_accessor* create_accessor_from_descriptor(grib_accessor* a,long ide, return elementAccessor; } +#define IS_QUALIFIER(a) (a==8 || a==1 || a==2) +#define NUMBER_OF_QUALIFIERS_PER_CATEGORY 256 +#define NUMBER_OF_QUALIFIERS_CATEGORIES 3 + +static int number_of_qualifiers=NUMBER_OF_QUALIFIERS_PER_CATEGORY*NUMBER_OF_QUALIFIERS_CATEGORIES; + +static GRIB_INLINE int significanceQualifierIndex(int X,int Y) { + int a[]={-1,0,1,-1,-1,-1,-1,-1,2}; + return Y+a[X]*NUMBER_OF_QUALIFIERS_PER_CATEGORY; +} + + +static GRIB_INLINE void reset_deeper_qualifiers(grib_accessor* significanceQualifierGroup[],int* significanceQualifierDepth, int depth) { + int i; + for (i=0;idepth) { + significanceQualifierGroup[i]=0; + } + } +} + static int create_keys(grib_accessor* a) { grib_accessor_bufr_data_array *self =(grib_accessor_bufr_data_array*)a; int err=0; grib_accessor* elementAccessor=0; long iss,end,elementsInSubset,ide; - grib_section* section=a->sub_section; + grib_section* section=NULL; + bufr_descriptor* descriptor; + grib_section* sectionUp=0; + grib_section* groupSection=0; + long groupNumber=0; + int forceGroupClosure=0,forceOneLevelClosure=0; + long indexOfGroupNumber=0; + int depth; + int idx; + grib_context* c=a->parent->h->context; + + grib_accessor* gaGroup=0; + grib_action creatorGroup = {0, }; + grib_iarray* groupNumberIndex=0; + grib_accessor* significanceQualifierGroup[NUMBER_OF_QUALIFIERS_PER_CATEGORY*NUMBER_OF_QUALIFIERS_CATEGORIES]={0,}; + int significanceQualifierDepth[NUMBER_OF_QUALIFIERS_PER_CATEGORY*NUMBER_OF_QUALIFIERS_CATEGORIES]={0,}; + + creatorGroup.op = "bufr_group"; + creatorGroup.name="groupNumber"; + creatorGroup.name_space = ""; + creatorGroup.flags = GRIB_ACCESSOR_FLAG_DUMP; + creatorGroup.set = 0; + + groupNumberIndex=grib_iarray_new(c,100,100); + end= self->compressedData ? 1 : self->numberOfSubsets; + groupNumber=1; + + gaGroup = grib_accessor_factory(a->sub_section, &creatorGroup, 0, NULL); + gaGroup->bufr_group_number=groupNumber; + gaGroup->sub_section=grib_section_create(a->parent->h,gaGroup); + section=gaGroup->sub_section; + sectionUp=a->sub_section; + accessor_constant_set_type(gaGroup,GRIB_TYPE_LONG); + accessor_constant_set_dval(gaGroup,groupNumber); + grib_push_accessor(gaGroup,a->sub_section->block); + + forceGroupClosure=0; + indexOfGroupNumber=0; + depth=0; for (iss=0;isscompressedData ? grib_iarray_used_size(self->elementsDescriptorsIndex->v[0]) : grib_iarray_used_size(self->elementsDescriptorsIndex->v[iss]); for (ide=0;idecompressedData ? self->elementsDescriptorsIndex->v[0]->v[ide] : + self->elementsDescriptorsIndex->v[iss]->v[ide] ; + + descriptor=self->expanded->v[idx]; + if (descriptor->F==0 && IS_QUALIFIER(descriptor->X)) { + int sidx=significanceQualifierIndex(descriptor->X,descriptor->Y); + groupNumber++; + + if (significanceQualifierGroup[sidx]) { + groupSection=significanceQualifierGroup[sidx]->parent; + depth=significanceQualifierDepth[sidx]; + reset_deeper_qualifiers(significanceQualifierGroup,significanceQualifierDepth,depth); + forceGroupClosure=0; + } else { + if (forceGroupClosure) { + groupSection=sectionUp; + forceGroupClosure=0; + forceOneLevelClosure=1; + depth=0; + } else { + groupSection=section; + depth++; + } + } + + gaGroup = grib_accessor_factory(groupSection, &creatorGroup, 0, NULL); + a->parent->h->groups[groupNumber]=gaGroup; + gaGroup->sub_section=grib_section_create(a->parent->h,gaGroup); + gaGroup->bufr_group_number=groupNumber; + accessor_constant_set_type(gaGroup,GRIB_TYPE_LONG); + accessor_constant_set_dval(gaGroup,groupNumber); + grib_push_accessor(gaGroup,groupSection->block); + + section=gaGroup->sub_section; + sectionUp=gaGroup->parent; + + significanceQualifierGroup[sidx]=gaGroup; + significanceQualifierDepth[sidx]=depth; + } + + elementAccessor=create_accessor_from_descriptor(a,section,ide,iss); if (elementAccessor) grib_push_accessor(elementAccessor,section->block); } } return err; } -#endif #define MAX_NESTED_REPLICATIONS 8 @@ -848,7 +944,7 @@ static int decode_elements(grib_accessor* a) { } } - /* err=create_keys(a); */ + err=create_keys(a); return err; } diff --git a/src/grib_accessor_class_bufr_data_element.c b/src/grib_accessor_class_bufr_data_element.c index 5d6bcbcae..890a2dd94 100644 --- a/src/grib_accessor_class_bufr_data_element.c +++ b/src/grib_accessor_class_bufr_data_element.c @@ -232,8 +232,8 @@ static int unpack_string_array (grib_accessor* a, char** val, size_t *len) if (*lencompressedData) { + idx=((int)self->numericValues->v[self->index]->v[0]/1000-1)/self->numberOfSubsets; for (i=0;inumericValues->v[self->index]->v[i]/1000; val[i]=grib_context_strdup(c,self->stringValues->v[idx]->v[i]); } } else { @@ -262,10 +262,12 @@ static int unpack_long (grib_accessor* a, long* val, size_t *len) if (self->compressedData) { for (i=0;inumericValues->v[self->index]->v[i]; + val[i]= self->numericValues->v[self->index]->v[i] == GRIB_MISSING_DOUBLE ? + GRIB_MISSING_LONG : (long)self->numericValues->v[self->index]->v[i]; } } else { - val[0]=(long)self->numericValues->v[self->subsetNumber]->v[self->index]; + val[0]= self->numericValues->v[self->subsetNumber]->v[self->index] == GRIB_MISSING_DOUBLE ? + GRIB_MISSING_LONG : (long)self->numericValues->v[self->subsetNumber]->v[self->index]; } return ret; @@ -294,14 +296,23 @@ static int unpack_double (grib_accessor* a, double* val, size_t *len) static int value_count(grib_accessor* a,long* count) { - int ret,size; + int ret=0,size,type,idx; grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; - if (!self->compressedData) return 1; + if (!self->compressedData) { + *count=1; + return 0; + } + type=get_native_type(a); - size=grib_darray_used_size(self->numericValues->v[self->index]); + if (type==GRIB_TYPE_STRING) { + idx=((int)self->numericValues->v[self->index]->v[0]/1000-1)/self->numberOfSubsets; + size=grib_sarray_used_size(self->stringValues->v[idx]); + } else { + size=grib_darray_used_size(self->numericValues->v[self->index]); + } - ret= size == 1 ? 1 : self->numberOfSubsets; + *count = size == 1 ? 1 : self->numberOfSubsets; return ret; } diff --git a/src/grib_accessor_class_constant.c b/src/grib_accessor_class_constant.c index 2f96e194d..06c74c7b7 100644 --- a/src/grib_accessor_class_constant.c +++ b/src/grib_accessor_class_constant.c @@ -134,6 +134,16 @@ static void init_class(grib_accessor_class* c) /* END_CLASS_IMP */ +void accessor_constant_set_type(grib_accessor* a,int type) { + grib_accessor_constant* self = (grib_accessor_constant*)a; + self->type=type; +} + +void accessor_constant_set_dval(grib_accessor* a,double dval) { + grib_accessor_constant* self = (grib_accessor_constant*)a; + self->dval=dval; +} + static void init(grib_accessor* a, const long len , grib_arguments* arg ) { diff --git a/src/grib_accessor_class_count_missing.c b/src/grib_accessor_class_count_missing.c index 2fda5127a..40e0cbe9e 100644 --- a/src/grib_accessor_class_count_missing.c +++ b/src/grib_accessor_class_count_missing.c @@ -151,6 +151,7 @@ static const unsigned char bitsoff[]={ 2, 1, 4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0 }; +/* static const unsigned char bitson[]={ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, @@ -168,6 +169,7 @@ static const unsigned char bitson[]={ 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 }; +*/ static void init(grib_accessor* a, const long len , grib_arguments* arg ) diff --git a/src/grib_accessor_class_expanded_descriptors.c b/src/grib_accessor_class_expanded_descriptors.c index 101782396..09f206726 100644 --- a/src/grib_accessor_class_expanded_descriptors.c +++ b/src/grib_accessor_class_expanded_descriptors.c @@ -198,7 +198,7 @@ static size_t __expand(grib_accessor* a,bufr_descriptors_array* unexpanded,bufr_ change_coding_params* ccp,int* err) { int k,j,i; grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a; - size_t size; + size_t size=0; long* v; bufr_descriptor* u; bufr_descriptor* vv; diff --git a/src/grib_accessor_class_hash_array.c b/src/grib_accessor_class_hash_array.c index 9ef65cffa..0d8f18d6e 100644 --- a/src/grib_accessor_class_hash_array.c +++ b/src/grib_accessor_class_hash_array.c @@ -141,11 +141,6 @@ static void init_class(grib_accessor_class* c) #define MAX_HASH_ARRAY_STRING_LENGTH 255 -GRIB_INLINE static int grib_inline_strcmp(const char* a,const char* b) { - if (*a != *b) return 1; - while((*a!=0 && *b!=0) && *(a) == *(b) ) {a++;b++;} - return (*a==0 && *b==0) ? 0 : 1; -} static void init(grib_accessor* a, const long len , grib_arguments* args ) { diff --git a/src/grib_api_internal.h b/src/grib_api_internal.h index acf97a964..922a081e4 100644 --- a/src/grib_api_internal.h +++ b/src/grib_api_internal.h @@ -1410,6 +1410,7 @@ typedef struct j2k_encode_helper { } j2k_encode_helper; + #include "grib_api_prototypes.h" diff --git a/src/grib_api_prototypes.h b/src/grib_api_prototypes.h index 5a93b56d8..e33eadc57 100644 --- a/src/grib_api_prototypes.h +++ b/src/grib_api_prototypes.h @@ -430,6 +430,8 @@ int grib_g1_step_apply_units(long *start, long *theEnd, long *step_unit, long *P /* grib_accessor_class_ieeefloat.c */ /* grib_accessor_class_constant.c */ +void accessor_constant_set_type(grib_accessor *a, int type); +void accessor_constant_set_dval(grib_accessor *a, double dval); /* grib_accessor_class_iterator.c */ grib_iterator *grib_iterator_new(grib_handle *h, unsigned long flags, int *error); @@ -1023,6 +1025,10 @@ int grib_keys_iterator_next(grib_keys_iterator *kiter); const char *grib_keys_iterator_get_name(grib_keys_iterator *kiter); grib_accessor *grib_keys_iterator_get_accessor(grib_keys_iterator *kiter); int grib_keys_iterator_delete(grib_keys_iterator *kiter); +int grib_keys_iterator_get_long(grib_keys_iterator *kiter, long *v, size_t *len); +int grib_keys_iterator_get_double(grib_keys_iterator *kiter, double *v, size_t *len); +int grib_keys_iterator_get_string(grib_keys_iterator *kiter, char *v, size_t *len); +int grib_keys_iterator_get_bytes(grib_keys_iterator *kiter, unsigned char *v, size_t *len); int grib_keys_iterator_get_native_type(grib_keys_iterator *kiter); /* grib_parse_utils.c */ @@ -1081,6 +1087,8 @@ int grib_set_bytes(grib_handle *h, const char *name, const unsigned char *val, s int grib_clear(grib_handle *h, const char *name); int grib_set_missing_internal(grib_handle *h, const char *name); int grib_set_missing(grib_handle *h, const char *name); +int grib_is_missing_long(grib_accessor *a, long x); +int grib_is_missing_double(grib_accessor *a, double x); int grib_is_missing(grib_handle *h, const char *name, int *err); int grib_is_defined(grib_handle *h, const char *name); int grib_set_flag(grib_handle *h, const char *name, unsigned long flag); diff --git a/src/grib_dumper_class_json.c b/src/grib_dumper_class_json.c index 624834e05..e31f2caa0 100644 --- a/src/grib_dumper_class_json.c +++ b/src/grib_dumper_class_json.c @@ -118,7 +118,7 @@ static void dump_values(grib_dumper* d,grib_accessor* a) long more=0; long count=0; int mydepth=depth+2; - double missing_value = 9999; + double missing_value = GRIB_MISSING_DOUBLE; grib_value_count(a,&count); @@ -142,6 +142,7 @@ static void dump_values(grib_dumper* d,grib_accessor* a) if (!self->begin) fprintf(self->dumper.out,",\n"); else self->begin=0; + err = grib_set_double(a->parent->h, "missingValue", missing_value); if (size>1) { int cols=4; int count=0; @@ -150,7 +151,6 @@ static void dump_values(grib_dumper* d,grib_accessor* a) fprintf(self->dumper.out,"\"%s\" : [ ",a->name); tab=lens+mydepth+7; - err = grib_get_double(a->parent->h, "missingValue", &missing_value); for (i=0; icols || i==0) {fprintf(self->dumper.out,"\n%-*s",tab," ");count=0;} if (values[i] == missing_value) @@ -160,7 +160,7 @@ static void dump_values(grib_dumper* d,grib_accessor* a) count++; } if (count>cols) fprintf(self->dumper.out,"\n%-*s",tab," "); - if (values[i] == missing_value) + if (grib_is_missing_double(a,values[i])) fprintf(self->dumper.out, "%s ","null"); else fprintf(self->dumper.out, "%g ",values[i]); @@ -172,7 +172,7 @@ static void dump_values(grib_dumper* d,grib_accessor* a) grib_context_free(a->parent->h->context,values); } else { fprintf(self->dumper.out,"%-*s",mydepth," "); - if( ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && grib_is_missing_internal(a) ) + if( grib_is_missing_double(a,value) ) fprintf(self->dumper.out,"\"%s\" : null",a->name); else fprintf(self->dumper.out,"\"%s\" : %g",a->name,value); @@ -221,7 +221,11 @@ static void dump_long(grib_dumper* d,grib_accessor* a,const char* comment) tab=lens+mydepth+7; for (i=0;icols || i==0) {fprintf(self->dumper.out,"\n%-*s",tab," ");count=0;} - fprintf(self->dumper.out,"%ld, ",values[i]); + if (grib_is_missing_long(a,values[i])) { + fprintf(self->dumper.out,"null, "); + } else { + fprintf(self->dumper.out,"%ld, ",values[i]); + } count++; } if (count>cols) fprintf(self->dumper.out,"\n%-*s",tab," "); @@ -234,7 +238,7 @@ static void dump_long(grib_dumper* d,grib_accessor* a,const char* comment) grib_context_free(a->parent->h->context,values); } else { fprintf(self->dumper.out,"%-*s",mydepth," "); - if( ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && grib_is_missing_internal(a) ) + if( grib_is_missing_long(a,value) ) fprintf(self->dumper.out,"\"%s\" : null",a->name); else fprintf(self->dumper.out,"\"%s\" : %ld",a->name,value); @@ -260,7 +264,7 @@ static void dump_double(grib_dumper* d,grib_accessor* a,const char* comment) else self->begin=0; fprintf(self->dumper.out,"%-*s",mydepth," "); - if( ((a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING) != 0) && grib_is_missing_internal(a) ) + if( grib_is_missing_double(a,value) ) fprintf(self->dumper.out,"\"%s\" : null",a->name); else fprintf(self->dumper.out,"\"%s\" : %g",a->name,value); diff --git a/src/grib_parse_utils.c b/src/grib_parse_utils.c index 1da898448..3b39f9f75 100644 --- a/src/grib_parse_utils.c +++ b/src/grib_parse_utils.c @@ -53,11 +53,11 @@ static void init() int grib_recompose_name(grib_handle* h, grib_accessor *observer, const char* uname, char* fname,int fail) { grib_accessor* a; - char loc[1024]; + char loc[1024]={0,}; int i = 0; int ret = 0; int mode = -1; - char val[1024]; + char val[1024]={0,}; double dval=0; long lval=0; int type=GRIB_TYPE_STRING; @@ -87,7 +87,7 @@ int grib_recompose_name(grib_handle* h, grib_accessor *observer, const char* una } else { switch (type) { case GRIB_TYPE_STRING: - replen = sizeof(val)/sizeof(*val); + replen = 1024; ret = grib_unpack_string(a,val,&replen); break; case GRIB_TYPE_DOUBLE: diff --git a/src/grib_value.c b/src/grib_value.c index 2c7a397a1..634e0d5fe 100644 --- a/src/grib_value.c +++ b/src/grib_value.c @@ -486,6 +486,15 @@ int grib_set_missing(grib_handle* h, const char* name) return GRIB_NOT_FOUND; } +int grib_is_missing_long(grib_accessor* a,long x) { + int ret = ( a==NULL || (a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING)) && (x==GRIB_MISSING_LONG) ? 1 : 0; + return ret; +} +int grib_is_missing_double(grib_accessor* a,double x) { + int ret = ( a==NULL || (a->flags & GRIB_ACCESSOR_FLAG_CAN_BE_MISSING)) && (x==GRIB_MISSING_DOUBLE) ? 1 : 0; + return ret; +} + int grib_is_missing(grib_handle* h, const char* name,int* err) { grib_accessor* a = grib_find_accessor(h, name); diff --git a/tools/grib_merge.c b/tools/grib_merge.c index 5b82fd1d2..1459f9ce7 100644 --- a/tools/grib_merge.c +++ b/tools/grib_merge.c @@ -73,7 +73,7 @@ int grib_tool_new_file_action(grib_runtime_options* options,grib_tools_file* fil return 0; } -inline int idx(double lat,double lon,double latFirst,double lonFirst,double latLast,double lonLast, +int idx(double lat,double lon,double latFirst,double lonFirst,double latLast,double lonLast, long Ni,double di,double dj) { long ilon,ilat; if ((ilon=(lon-lonFirst)/di) < 0 ) return -1;