diff --git a/src/grib_accessor.c b/src/grib_accessor.c index fa53578b6..a22ab3659 100644 --- a/src/grib_accessor.c +++ b/src/grib_accessor.c @@ -618,6 +618,10 @@ grib_accessor* _grib_accessor_get_attribute(grib_accessor* a,const char* name,in return NULL; } +int grib_accessor_has_attributes(grib_accessor* a) { + return a->attributes[0] ? 1 : 0 ; +} + grib_accessor* grib_accessor_get_attribute(grib_accessor* a,const char* name) { int i=0,index=0; char* p=0; diff --git a/src/grib_accessor_class_bufr_data_array.c b/src/grib_accessor_class_bufr_data_array.c index 379e54003..bf22cc5c2 100644 --- a/src/grib_accessor_class_bufr_data_array.c +++ b/src/grib_accessor_class_bufr_data_array.c @@ -671,14 +671,16 @@ static int create_keys(grib_accessor* a) { grib_accessor* elementAccessor=0; long iss,end,elementsInSubset,ide; grib_section* section=NULL; + grib_section* rootSection=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; + int* bitmap=NULL; + int bitmap_start=0; grib_context* c=a->parent->h->context; grib_accessor* gaGroup=0; @@ -694,7 +696,7 @@ static int create_keys(grib_accessor* a) { creatorGroup.set = 0; groupNumberIndex=grib_iarray_new(c,100,100); - + end= self->compressedData ? 1 : self->numberOfSubsets; groupNumber=1; @@ -703,12 +705,12 @@ static int create_keys(grib_accessor* a) { gaGroup->bufr_group_number=groupNumber; gaGroup->sub_section=grib_section_create(a->parent->h,gaGroup); section=gaGroup->sub_section; + rootSection=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; @@ -728,17 +730,9 @@ static int create_keys(grib_accessor* a) { 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++; - } + groupSection=section; + depth++; } gaGroup = grib_accessor_factory(groupSection, &creatorGroup, 0, NULL); @@ -755,6 +749,10 @@ static int create_keys(grib_accessor* a) { significanceQualifierGroup[sidx]=gaGroup; significanceQualifierDepth[sidx]=depth; } + if (descriptor->code == 31031) { + /* bitmap */ + section=rootSection; + } elementAccessor=create_accessor_from_descriptor(a,section,ide,iss); if (elementAccessor) grib_push_accessor(elementAccessor,section->block); diff --git a/src/grib_api_prototypes.h b/src/grib_api_prototypes.h index d7885c678..ca33f0c15 100644 --- a/src/grib_api_prototypes.h +++ b/src/grib_api_prototypes.h @@ -139,6 +139,7 @@ int grib_accessor_delete_attribute(grib_accessor *a, const char *name); grib_accessor *grib_accessor_get_attribute_by_index(grib_accessor *a, int index); const char *grib_accessor_get_name(grib_accessor *a); grib_accessor *_grib_accessor_get_attribute(grib_accessor *a, const char *name, int *index); +int grib_accessor_has_attributes(grib_accessor *a); grib_accessor *grib_accessor_get_attribute(grib_accessor *a, const char *name); /* grib_concept.c */ @@ -1077,6 +1078,7 @@ grib_action *grib_parse_file(grib_context *gc, const char *filename); int grib_type_to_int(char id); /* grib_query.c */ +char *grib_split_name_attribute(grib_context *c, const char *name, char *attribute_name); grib_accessor *grib_find_accessor(grib_handle *h, const char *name); grib_accessor *grib_find_attribute(grib_handle *h, const char *name, const char *attr_name, int *err); int grib_find_all_accessors(grib_handle *h, const char *name, search_all_callback_proc callback, void *data); diff --git a/src/grib_dumper_class_json.c b/src/grib_dumper_class_json.c index 960fff77d..0cadd7c93 100644 --- a/src/grib_dumper_class_json.c +++ b/src/grib_dumper_class_json.c @@ -111,33 +111,47 @@ static int destroy (grib_dumper* d) return GRIB_SUCCESS; } +static void print_accessor(grib_accessor* a,FILE* out) { + size_t len=1; + long lval; + double dval; + char* cval=NULL; + switch (grib_accessor_get_native_type(a)) { + case GRIB_TYPE_LONG: + grib_unpack_long(a,&lval,&len); + fprintf(out,"%ld",lval); + break; + case GRIB_TYPE_DOUBLE: + grib_unpack_double(a,&dval,&len); + fprintf(out,"%g",dval); + break; + case GRIB_TYPE_STRING: + len=grib_string_length(a)+1; + cval=grib_context_malloc_clear(a->parent->h->context,len); + grib_unpack_string(a,cval,&len); + fprintf(out,"\"%s\"",cval); + grib_context_free(a->parent->h->context,cval); + break; + } +} + static void dump_attributes(grib_dumper* d,grib_accessor* a,FILE* out) { - int i=0; - size_t len=1; - long lval; - double dval; - char* cval=NULL; - while (a->attributes[i]) { - fprintf(out,",\"%s\":",a->attributes[i]->name); - switch (grib_accessor_get_native_type(a->attributes[i])) { - case GRIB_TYPE_LONG: - grib_unpack_long(a->attributes[i],&lval,&len); - fprintf(out,"%ld",lval); - break; - case GRIB_TYPE_DOUBLE: - grib_unpack_double(a->attributes[i],&dval,&len); - fprintf(out,"%g",dval); - break; - case GRIB_TYPE_STRING: - len=grib_string_length(a->attributes[i])+1; - cval=grib_context_malloc_clear(a->parent->h->context,len); - grib_unpack_string(a->attributes[i],cval,&len); - fprintf(out,"\"%s\"",cval); - grib_context_free(a->parent->h->context,cval); - break; - } - i++; + int i=0; + int has_attributes=0; + while (a->attributes[i] || i > MAX_ACCESSOR_ATTRIBUTES) { + has_attributes=grib_accessor_has_attributes(a->attributes[i]); + fprintf(out,",\"%s\":",a->attributes[i]->name); + if (has_attributes) { + fprintf(out," { \"key\" : \"%s\", \"value\" : ",a->attributes[i]->name); + print_accessor(a->attributes[i],out); + fprintf(out,", \n"); + dump_attributes(d,a->attributes[i],out); + fprintf(out,"}\n"); + } else { + print_accessor(a->attributes[i],out); } + i++; + } } static void dump_values(grib_dumper* d,grib_accessor* a) @@ -203,7 +217,7 @@ static void dump_values(grib_dumper* d,grib_accessor* a) else fprintf(self->dumper.out," %g",value); } - /* dump_attributes(d,a,self->dumper.out); */ + dump_attributes(d,a,self->dumper.out); fprintf(self->dumper.out," }"); @@ -271,7 +285,7 @@ static void dump_long(grib_dumper* d,grib_accessor* a,const char* comment) else fprintf(self->dumper.out,"%ld",value); } - /* dump_attributes(d,a,self->dumper.out); */ + dump_attributes(d,a,self->dumper.out); fprintf(self->dumper.out," }"); @@ -304,7 +318,7 @@ static void dump_double(grib_dumper* d,grib_accessor* a,const char* comment) else fprintf(self->dumper.out,"%g",value); - /* dump_attributes(d,a,self->dumper.out); */ + dump_attributes(d,a,self->dumper.out); fprintf(self->dumper.out," }"); } @@ -354,7 +368,7 @@ static void dump_string_array(grib_dumper* d,grib_accessor* a,const char* commen fprintf(self->dumper.out,"%-*s\"%s\"\n",(int)(tab+strlen(a->name)+4)," ",values[i]); fprintf(self->dumper.out,"%-*s",mydepth," "); fprintf(self->dumper.out," ]"); - /* dump_attributes(d,a,self->dumper.out); */ + dump_attributes(d,a,self->dumper.out); fprintf(self->dumper.out,"} "); grib_context_free(c,values); @@ -399,7 +413,7 @@ static void dump_string(grib_dumper* d,grib_accessor* a,const char* comment) else fprintf(self->dumper.out,"\"%s\"",value); - /* dump_attributes(d,a,self->dumper.out); */ + dump_attributes(d,a,self->dumper.out); fprintf(self->dumper.out,"} "); grib_context_free(c,value); diff --git a/src/grib_query.c b/src/grib_query.c index a1397a3de..076b19c0e 100644 --- a/src/grib_query.c +++ b/src/grib_query.c @@ -164,7 +164,7 @@ static grib_accessor* search_and_cache(grib_handle* h, const char* name,const ch } -grib_accessor* grib_find_accessor(grib_handle* h, const char* name) +static grib_accessor* _grib_find_accessor(grib_handle* h, const char* name) { grib_accessor* a = NULL; char* p=NULL; @@ -197,6 +197,46 @@ grib_accessor* grib_find_accessor(grib_handle* h, const char* name) return a; } +char* grib_split_name_attribute(grib_context* c,const char* name,char* attribute_name) { + /*returns accessor name and attribute*/ + char* p=0; + size_t size=0; + char* accessor_name=NULL; + p=(char*)name; + while ( *(p+1) != '\0' && ( *p != '-' || *(p+1)!= '>' ) ) p++; + if (*(p+1) == '\0') { + *attribute_name=0; + return (char*)name; + } + size=name-p ; + accessor_name=grib_context_malloc_clear(c,size+1); + accessor_name=memcpy(accessor_name,name,size); + p+=2; + strcpy(attribute_name,p); + return accessor_name; +} + +grib_accessor* grib_find_accessor(grib_handle* h, const char* name) +{ + char* accessor_name=NULL; + char attribute_name[512]={0,}; + grib_accessor* a=NULL; + grib_accessor* aret=NULL; + + accessor_name=grib_split_name_attribute(h->context,name,attribute_name); + + a=_grib_find_accessor(h,accessor_name); + + if (*attribute_name==0) { + aret=a; + } else { + aret=grib_accessor_get_attribute(a,attribute_name); + grib_context_free(h->context,accessor_name); + } + + return aret; +} + grib_accessor* grib_find_attribute(grib_handle* h, const char* name,const char* attr_name, int* err) { grib_accessor* a = NULL;