From f22153bd1a140813adaf506df400f46a46b96386 Mon Sep 17 00:00:00 2001 From: Enrico Fucile Date: Tue, 4 Nov 2014 13:59:20 +0000 Subject: [PATCH] created class for descriptors. Improved design and performance (see tests/bufrdc_ref.sh) --- definitions/bufr/section.3.def | 29 +-- examples/C/set_data.c | 1 - fortran/grib_api_constants.h | 1 + python/grib_errors.h | 2 + src/CMakeLists.txt | 1 + src/Makefile.am | 1 + src/grib_accessor_class.h | 1 + src/grib_accessor_class_bufr_data_array.c | 46 +++- src/grib_accessor_class_bufr_data_element.c | 204 ++++++------------ ...grib_accessor_class_expanded_descriptors.c | 92 +++----- src/grib_accessor_factory.h | 1 + src/grib_accessor_factory_hash_list | 1 + src/grib_api.h | 2 + src/grib_api_internal.h | 33 ++- src/grib_api_prototypes.h | 22 +- src/grib_bufr_descriptor.c | 100 ++++++--- src/grib_bufr_descriptors_array.c | 2 +- src/grib_context.c | 7 +- src/grib_errors.c | 1 + src/grib_errors.txt | 1 + tests/CMakeLists.txt | 1 + tests/Makefile.am | 2 +- tests/bufrdc_desc_ref.sh | 2 +- tests/bufrdc_ref.sh | 2 +- 24 files changed, 275 insertions(+), 280 deletions(-) diff --git a/definitions/bufr/section.3.def b/definitions/bufr/section.3.def index fb92f594c..f2004c4e3 100644 --- a/definitions/bufr/section.3.def +++ b/definitions/bufr/section.3.def @@ -67,21 +67,22 @@ position offsetDescriptors; meta numberOfUnexpandedDescriptors evaluate( (section3Length - 7) / 2 ) ; meta unexpandedDescriptors unexpanded_descriptors(numberOfUnexpandedDescriptors) :dump; -transient elementCode="000000"; -elementAbbreviation=dict_search("element.table",elementCode,1,tablesMasterDir,tablesLocalDir) : string_type,hidden ; -elementType=dict_search("element.table",elementCode,2,tablesMasterDir,tablesLocalDir) : string_type,hidden ; -elementName=dict_search("element.table",elementCode,3,tablesMasterDir,tablesLocalDir) : string_type,hidden ; -elementUnit=dict_search("element.table",elementCode,4,tablesMasterDir,tablesLocalDir) : string_type,hidden ; -elementScale=dict_search("element.table",elementCode,5,tablesMasterDir,tablesLocalDir) : string_type,hidden ; -elementReference=dict_search("element.table",elementCode,6,tablesMasterDir,tablesLocalDir) : string_type,hidden ; -elementWidth=dict_search("element.table",elementCode,7,tablesMasterDir,tablesLocalDir) : string_type,hidden ; +meta elementsTable bufr_elements_table("element.table",tablesMasterDir,tablesLocalDir) : hidden; -meta expandedCodes expanded_descriptors(expandedCodes,0,unexpandedDescriptors,sequences,elementCode, - elementUnit,elementScale,elementReference,elementWidth); -meta expandedScales expanded_descriptors(expandedCodes,1); -meta expandedReferences expanded_descriptors(expandedCodes,2); -meta expandedWidths expanded_descriptors(expandedCodes,3); -meta expandedFlags expanded_descriptors(expandedCodes,4); +#transient elementCode="000000"; +#elementAbbreviation=dict_search("element.table",elementCode,1,tablesMasterDir,tablesLocalDir) : string_type,hidden ; +#elementType=dict_search("element.table",elementCode,2,tablesMasterDir,tablesLocalDir) : string_type,hidden ; +#elementName=dict_search("element.table",elementCode,3,tablesMasterDir,tablesLocalDir) : string_type,hidden ; +#elementUnit=dict_search("element.table",elementCode,4,tablesMasterDir,tablesLocalDir) : string_type,hidden ; +#elementScale=dict_search("element.table",elementCode,5,tablesMasterDir,tablesLocalDir) : string_type,hidden ; +#elementReference=dict_search("element.table",elementCode,6,tablesMasterDir,tablesLocalDir) : string_type,hidden ; +#elementWidth=dict_search("element.table",elementCode,7,tablesMasterDir,tablesLocalDir) : string_type,hidden ; + +meta expandedCodes expanded_descriptors(elementsTable,expandedCodes,0,unexpandedDescriptors,sequences); +#meta expandedScales expanded_descriptors(elemetsTable,expandedCodes,1); +#meta expandedReferences expanded_descriptors(elemetsTable,expandedCodes,2); +#meta expandedWidths expanded_descriptors(elemetsTable,expandedCodes,3); +#meta expandedType expanded_descriptors(elemetsTable,expandedCodes,4); meta bufrdcExpandedDescriptors bufrdc_expanded_descriptors(expandedCodes); diff --git a/examples/C/set_data.c b/examples/C/set_data.c index dd69d8fa5..3312d89cc 100644 --- a/examples/C/set_data.c +++ b/examples/C/set_data.c @@ -37,7 +37,6 @@ int main(int argc, char** argv) /* setting the environment variable GRIB_SAMPLES_PATH */ const char* sample_filename = "regular_ll_pl_grib1"; /* Here is how you can get the samples path */ - const char* samples_path = grib_samples_path(NULL); grib_handle *h = NULL; double d,e; long count; diff --git a/fortran/grib_api_constants.h b/fortran/grib_api_constants.h index ccae7a42a..728d55260 100644 --- a/fortran/grib_api_constants.h +++ b/fortran/grib_api_constants.h @@ -1,3 +1,4 @@ + integer, parameter,public :: GRIB_NULL_POINTER = -60 integer, parameter,public :: GRIB_MISSING_BUFR_ENTRY = -59 integer, parameter,public :: GRIB_WRONG_CONVERSION = -58 integer, parameter,public :: GRIB_STRING_TOO_SMALL = -57 diff --git a/python/grib_errors.h b/python/grib_errors.h index b24d40d0c..b689cf1b4 100644 --- a/python/grib_errors.h +++ b/python/grib_errors.h @@ -125,5 +125,7 @@ Error codes returned by the grib_api functions. #define GRIB_WRONG_CONVERSION -58 /** Missing BUFR table entry for descriptor */ #define GRIB_MISSING_BUFR_ENTRY -59 +/** Null pointer */ +#define GRIB_NULL_POINTER -60 /*! @}*/ #endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9a222d050..80b76314f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -60,6 +60,7 @@ list( APPEND grib_api_srcs grib_accessor_class_unpack_bufr_values.c grib_accessor_class_bufr_uncompressed_data.c grib_accessor_class_bufr_element.c + grib_accessor_class_bufr_elements_table.c grib_accessor_class_bufr_has_delayed_replication.c grib_accessor_class_bufr_subset_number.c grib_accessor_class_bufr_group_number.c diff --git a/src/Makefile.am b/src/Makefile.am index 8ba5b5c26..1f85dc451 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -69,6 +69,7 @@ libgrib_api_la_prototypes= \ grib_accessor_class_unpack_bufr_values.c \ grib_accessor_class_bufr_uncompressed_data.c \ grib_accessor_class_bufr_element.c \ + grib_accessor_class_bufr_elements_table.c \ grib_accessor_class_bufr_has_delayed_replication.c \ grib_accessor_class_bufr_subset_number.c \ grib_accessor_class_bufr_group_number.c \ diff --git a/src/grib_accessor_class.h b/src/grib_accessor_class.h index 4c97f3e30..4ef19890f 100644 --- a/src/grib_accessor_class.h +++ b/src/grib_accessor_class.h @@ -15,6 +15,7 @@ extern grib_accessor_class* grib_accessor_class_bufr_data; extern grib_accessor_class* grib_accessor_class_bufr_data_array; extern grib_accessor_class* grib_accessor_class_bufr_data_element; extern grib_accessor_class* grib_accessor_class_bufr_element; +extern grib_accessor_class* grib_accessor_class_bufr_elements_table; extern grib_accessor_class* grib_accessor_class_bufr_group; extern grib_accessor_class* grib_accessor_class_bufr_group_number; extern grib_accessor_class* grib_accessor_class_bufr_has_delayed_replication; diff --git a/src/grib_accessor_class_bufr_data_array.c b/src/grib_accessor_class_bufr_data_array.c index 8f356a364..ccdeb8256 100644 --- a/src/grib_accessor_class_bufr_data_array.c +++ b/src/grib_accessor_class_bufr_data_array.c @@ -430,7 +430,7 @@ static void decode_element(grib_context* c,grib_accessor_bufr_data_array* self, int index=0,ii,sar_size; char* csval=0; double cdval=0,x; - if (self->expanded->v[i]->flags & BUFR_DESCRIPTOR_FLAG_IS_STRING) { + if (self->expanded->v[i]->type==BUFR_DESCRIPTOR_TYPE_STRING) { /* string */ if (self->compressedData) { sar=decode_string_array(c,data,pos,i,self); @@ -568,6 +568,48 @@ static void push_zero_element(grib_accessor_bufr_data_array* self,grib_darray* d } } +/* +static grib_accessor* create_accessor_from_descriptor(grib_accessor* a,long ide,long subset) { + grib_accessor_bufr_data_array *self =(grib_accessor_bufr_data_array*)a; + grib_accessor* elementAccessor=NULL; + grib_action creator = {0, }; + creator.op = "bufr_data_element"; + creator.name_space = ""; + creator.flags = GRIB_ACCESSOR_FLAG_DUMP; + creator.set = 0; + + creator.name=self->expanded->v[self->elementsDescriptorsIndex->v[ide]]->name; + elementAccessor = grib_accessor_factory(section, &creator, 0, NULL); + 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); + accessor_bufr_data_element_set_stringValue(elementAccessor,self->stringValue); + accessor_bufr_data_element_set_compressedData(elementAccessor,self->compressedData); + + return elementAccessor; +} + +static int create_keys(grib_accessor* a) { + grib_accessor_bufr_data_array *self =(grib_accessor_bufr_data_array*)a; + int err=0; + long iss,end,elementsInSubset,ide; + grib_context* c=a->parent->h->context; + + end= self->compressedData ? 1 : self->numberOfDataSubsets; + + for (iss=0;isscompressedData ? grib_viarray_used_size(self->elementsDescriptorsIndex) : + grib_iarray_used_size(self->elementsDescriptorsIndex->v[iss]); + for (ide=0;idesubsection->block); + } + } + + return err; +} +*/ + #define MAX_NESTED_REPLICATIONS 8 static int decode_elements(grib_accessor* a) { @@ -795,6 +837,8 @@ static int decode_elements(grib_accessor* 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 cd510862d..40d7efa61 100644 --- a/src/grib_accessor_class_bufr_data_element.c +++ b/src/grib_accessor_class_bufr_data_element.c @@ -23,12 +23,13 @@ IMPLEMENTS = init;dump IMPLEMENTS = unpack_string;unpack_string_array;unpack_long; unpack_double IMPLEMENTS = value_count; destroy; get_native_type; + MEMBERS = long index MEMBERS = int type - MEMBERS = size_t numberOfValues - MEMBERS = double* dvalues - MEMBERS = long* lvalues - MEMBERS = grib_sarray* svalues - MEMBERS = int isConstant + MEMBERS = long compressedData + MEMBERS = bufr_descriptors_array* descriptors + MEMBERS = grib_vdarray* numericValues + MEMBERS = grib_vsarray* stringValues + MEMBERS = grib_viarray* elementsDescriptorsIndex END_CLASS_DEF @@ -59,12 +60,13 @@ typedef struct grib_accessor_bufr_data_element { grib_accessor att; /* Members defined in gen */ /* Members defined in bufr_data_element */ + long index; int type; - size_t numberOfValues; - double* dvalues; - long* lvalues; - grib_sarray* svalues; - int isConstant; + long compressedData; + bufr_descriptors_array* descriptors; + grib_vdarray* numericValues; + grib_vsarray* stringValues; + grib_viarray* elementsDescriptorsIndex; } grib_accessor_bufr_data_element; extern grib_accessor_class* grib_accessor_class_gen; @@ -145,14 +147,45 @@ static void init_class(grib_accessor_class* c) /* END_CLASS_IMP */ +void accessor_bufr_data_element_set_index(grib_accessor* a,long index) { + grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; + self->index=index; +} + +void accessor_bufr_data_element_set_type(grib_accessor* a,int type) { + grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; + self->type=type; +} + +void accessor_bufr_data_element_set_compressedData(grib_accessor* a,int compressedData) { + grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; + self->compressedData=compressedData; +} + +void accessor_bufr_data_element_set_descriptors(grib_accessor* a,bufr_descriptors_array* descriptors) { + grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; + self->descriptors=descriptors; +} + +void accessor_bufr_data_element_set_numericValues(grib_accessor* a,grib_vdarray* numericValues) { + grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; + self->numericValues=numericValues; +} + +void accessor_bufr_data_element_set_stringValues(grib_accessor* a,grib_vsarray* stringValues) { + grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; + self->stringValues=stringValues; +} + +void accessor_bufr_data_element_set_elementsDescriptorsIndex(grib_accessor* a,grib_viarray* elementsDescriptorsIndex) { + grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; + self->elementsDescriptorsIndex=elementsDescriptorsIndex; +} static void init(grib_accessor* a, const long len, grib_arguments* params) { - grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; + /* grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; */ a->length = 0; - self->dvalues=0; - self->lvalues=0; - self->svalues=0; /* a->flags |= GRIB_ACCESSOR_FLAG_READ_ONLY; */ } @@ -175,162 +208,45 @@ static void dump(grib_accessor* a, grib_dumper* dumper) static int unpack_string_array (grib_accessor* a, char** val, size_t *len) { - grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; - long i=0; - long size=0; - int err=0; + /* grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; */ - err=value_count(a,&size); - if (err) return err; - - if (*len < size) return GRIB_ARRAY_TOO_SMALL; - - for (i=0;isvalues->v[i]; - *len=size; - - return GRIB_SUCCESS; + return GRIB_NOT_IMPLEMENTED; } static int unpack_string (grib_accessor* a, char* val, size_t *len) { - grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; - char buffer[100]={0,}; - - if (self->type==GRIB_TYPE_STRING) { - if (*len < strlen(self->svalues->v[0]) ) - return GRIB_ARRAY_TOO_SMALL; - sprintf(val,"%s",self->svalues->v[0]); - } else { - sprintf(buffer,"%g",self->dvalues[0]); - if (*len < strlen(buffer) ) - return GRIB_ARRAY_TOO_SMALL; - sprintf(val,"%s",buffer); - } - - return GRIB_SUCCESS; + return GRIB_NOT_IMPLEMENTED; } static int unpack_long (grib_accessor* a, long* val, size_t *len) { - grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; - size_t i=0,j=0; - long size=0; - int err=0; - long subsetNumber; - size_t start,end; - double missingValue=GRIB_MISSING_DOUBLE; - int navigate_subgroups; - - if (self->type == GRIB_TYPE_STRING) return GRIB_WRONG_TYPE; - - err=value_count(a,&size); - if (err) return err; - - if (*len < size) return GRIB_ARRAY_TOO_SMALL; - - navigate_subgroups=a->parent->h->navigate_subgroups; - a->parent->h->navigate_subgroups=0; - grib_get_double(a->parent->h,"missingValue",&missingValue); - - if (self->isConstant) { - subsetNumber=0; - size=1; - } else { - grib_get_long(a->parent->h,"subsetNumber",&subsetNumber); - } - - if (subsetNumber) { - start=subsetNumber-1; - end=subsetNumber-1; - } else { - start=0; - end=size-1; - } - - j=0; - for (i=start;i<=end;i++) { - if (self->dvalues[i]==GRIB_MISSING_DOUBLE) - val[j]=missingValue; - else - val[j]=self->dvalues[i]; - - j++; - } - *len=end-start+1; - a->parent->h->navigate_subgroups=navigate_subgroups; - - return GRIB_SUCCESS; + return GRIB_NOT_IMPLEMENTED; } static int unpack_double (grib_accessor* a, double* val, size_t *len) { - grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; - int err=0; - size_t i=0,j=0; - long size=0; - size_t start,end; - double missingValue=GRIB_MISSING_DOUBLE; - long subsetNumber=0; - int navigate_subgroups; - - if (self->type == GRIB_TYPE_STRING) return GRIB_WRONG_TYPE; - - err=value_count(a,&size); - if (err) return err; - - if (*len < size) return GRIB_ARRAY_TOO_SMALL; - navigate_subgroups=a->parent->h->navigate_subgroups; - a->parent->h->navigate_subgroups=0; - grib_get_double(a->parent->h,"missingValue",&missingValue); - - if (self->isConstant) { - subsetNumber=0; - size=1; - } else { - grib_get_long(a->parent->h,"subsetNumber",&subsetNumber); - } - - if (subsetNumber) { - start=subsetNumber-1; - end=subsetNumber-1; - } else { - start=0; - end=size-1; - } - - j=0; - for (i=start;i<=end;i++) { - if (self->dvalues[i]==GRIB_MISSING_DOUBLE) - val[j]=missingValue; - else - val[j]=self->dvalues[i]; - - j++; - } - *len=end-start+1; - a->parent->h->navigate_subgroups=navigate_subgroups; - - return GRIB_SUCCESS; + return GRIB_NOT_IMPLEMENTED; } static int value_count(grib_accessor* a,long* count) { - grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; - if (self->isConstant) *count=1; - else *count=self->numberOfValues; - return 0; } static void destroy(grib_context* context,grib_accessor* a) { - grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; - if (self->dvalues) grib_context_free(a->parent->h->context,self->dvalues); - if (self->svalues) grib_sarray_delete(a->parent->h->context,self->svalues); } static int get_native_type(grib_accessor* a){ grib_accessor_bufr_data_element* self = (grib_accessor_bufr_data_element*)a; + +/* + if (self->compressedData) { + + } else { + } + */ + return self->type; } diff --git a/src/grib_accessor_class_expanded_descriptors.c b/src/grib_accessor_class_expanded_descriptors.c index 98f2fd71f..101782396 100644 --- a/src/grib_accessor_class_expanded_descriptors.c +++ b/src/grib_accessor_class_expanded_descriptors.c @@ -29,15 +29,12 @@ IMPLEMENTS = value_count; get_native_type MEMBERS = const char* unexpandedDescriptors MEMBERS = const char* sequence MEMBERS = const char* expandedName -MEMBERS = const char* elementCode -MEMBERS = const char* elementUnit -MEMBERS = const char* elementScale -MEMBERS = const char* elementReference -MEMBERS = const char* elementWidth +MEMBERS = const char* tablesAccessorName MEMBERS = bufr_descriptors_array* expanded MEMBERS = int rank MEMBERS = grib_accessor* expandedAccessor MEMBERS = int dirty +MEMBERS = grib_accessor* tablesAccessor END_CLASS_DEF @@ -71,15 +68,12 @@ typedef struct grib_accessor_expanded_descriptors { const char* unexpandedDescriptors; const char* sequence; const char* expandedName; - const char* elementCode; - const char* elementUnit; - const char* elementScale; - const char* elementReference; - const char* elementWidth; + const char* tablesAccessorName; bufr_descriptors_array* expanded; int rank; grib_accessor* expandedAccessor; int dirty; + grib_accessor* tablesAccessor; } grib_accessor_expanded_descriptors; extern grib_accessor_class* grib_accessor_class_long; @@ -176,6 +170,7 @@ static void init(grib_accessor* a, const long len , grib_arguments* args ) { grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a; int n=0; + self->tablesAccessorName=grib_arguments_get_name(a->parent->h,args,n++); self->expandedName=grib_arguments_get_name(a->parent->h,args,n++); self->rank=grib_arguments_get_long(a->parent->h,args,n++); if (self->rank!=0) { @@ -185,11 +180,6 @@ static void init(grib_accessor* a, const long len , grib_arguments* args ) } self->unexpandedDescriptors=grib_arguments_get_name(a->parent->h,args,n++); self->sequence=grib_arguments_get_name(a->parent->h,args,n++); - self->elementCode=grib_arguments_get_name(a->parent->h,args,n++); - self->elementUnit=grib_arguments_get_name(a->parent->h,args,n++); - self->elementScale=grib_arguments_get_name(a->parent->h,args,n++); - self->elementReference=grib_arguments_get_name(a->parent->h,args,n++); - self->elementWidth=grib_arguments_get_name(a->parent->h,args,n++); self->dirty=1; self->expanded=0; a->length = 0; @@ -208,12 +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; - long scale,reference,width; size_t size; - char code[]="000000"; - size_t len_code=6; - char unit[100]={0,}; - size_t len_unit=100; long* v; bufr_descriptor* u; bufr_descriptor* vv; @@ -256,7 +241,7 @@ static size_t __expand(grib_accessor* a,bufr_descriptors_array* unexpanded,bufr_ inner_unexpanded=grib_bufr_descriptors_array_new(c,100,100); inner_expanded=grib_bufr_descriptors_array_new(c,100,100); for (i=0;itablesAccessor,v[i],err); inner_unexpanded=grib_bufr_descriptors_array_push(inner_unexpanded,vv); } grib_context_free(c,v); @@ -305,7 +290,7 @@ static size_t __expand(grib_accessor* a,bufr_descriptors_array* unexpanded,bufr_ #endif expanded=grib_bufr_descriptors_array_append(expanded,inner_expanded); uidx=grib_bufr_descriptors_array_get(expanded,idx); - grib_bufr_descriptor_set_code(uidx,(size-1)*1000+100000); + grib_bufr_descriptor_set_code(0,(size-1)*1000+100000,uidx); size++; } else { u=grib_bufr_descriptors_array_pop_front(unexpanded); @@ -328,7 +313,7 @@ static size_t __expand(grib_accessor* a,bufr_descriptors_array* unexpanded,bufr_ } for (k=1;kY;k++) { for (j=0;jX;j++) { - grib_bufr_descriptors_array_push(inner_unexpanded,grib_bufr_descriptor_clone(c,ur[j])); + grib_bufr_descriptors_array_push(inner_unexpanded,grib_bufr_descriptor_clone(ur[j])); } } inner_expanded=_expand(a,inner_unexpanded,ccp,err); @@ -349,43 +334,13 @@ static size_t __expand(grib_accessor* a,bufr_descriptors_array* unexpanded,bufr_ #if MYDEBUG for (idepth=0;idepthcode); -#endif - if ((u->flags & BUFR_DESCRIPTOR_FLAG_HAS_VALUES) == 0) { - sprintf(code,"%06ld",u->code); - len_code=strlen(code); - grib_set_string(a->parent->h,self->elementCode,code,&len_code); - *err=grib_get_long(a->parent->h,self->elementScale,&scale); - if (*err==GRIB_SUCCESS) { - *err=grib_get_long(a->parent->h,self->elementReference,&reference); - *err=grib_get_long(a->parent->h,self->elementWidth,&width); - grib_bufr_descriptor_set_values(u,scale,reference,width); - *err=grib_get_string(a->parent->h,self->elementUnit,unit,&len_unit); - if (strstr(unit,"CCITT")) u->flags |= BUFR_DESCRIPTOR_FLAG_IS_STRING; - else if (strstr(unit,"TABLE") ) { - if (strstr(unit,"FLAG")) { - u->flags |= BUFR_DESCRIPTOR_FLAG_IS_FLAG; - } else { - u->flags |= BUFR_DESCRIPTOR_FLAG_IS_TABLE; - } - } - u->flags |= BUFR_DESCRIPTOR_FLAG_HAS_VALUES; - } else { - grib_context_log(c,GRIB_LOG_ERROR,"element %s not in table B",code); - return 0; - } - } -#if MYDEBUG for (idepth=0;idepthcode, - (u->flags & BUFR_DESCRIPTOR_FLAG_HAS_VALUES)==BUFR_DESCRIPTOR_FLAG_HAS_VALUES, - (u->flags & BUFR_DESCRIPTOR_FLAG_IS_FLAG)==BUFR_DESCRIPTOR_FLAG_IS_FLAG, - (u->flags & BUFR_DESCRIPTOR_FLAG_IS_TABLE)==BUFR_DESCRIPTOR_FLAG_IS_TABLE, - (u->flags & BUFR_DESCRIPTOR_FLAG_IS_STRING)==BUFR_DESCRIPTOR_FLAG_IS_STRING, - u->scale,u->reference,u->width); + printf("+++ push %06ld [type=%d] (%ld %g %ld)",u->code, + u->type,u->scale,u->reference,u->width); #endif - if ((u->flags & ( BUFR_DESCRIPTOR_FLAG_IS_FLAG | - BUFR_DESCRIPTOR_FLAG_IS_TABLE | - BUFR_DESCRIPTOR_FLAG_IS_STRING)) == 0) { + if ( u->type!=BUFR_DESCRIPTOR_TYPE_FLAG && + u->type!=BUFR_DESCRIPTOR_TYPE_TABLE && + u->type!=BUFR_DESCRIPTOR_TYPE_STRING ) { if (ccp->localDescriptorWidth>0) { u->width=ccp->localDescriptorWidth; u->reference=0; @@ -403,7 +358,7 @@ static size_t __expand(grib_accessor* a,bufr_descriptors_array* unexpanded,bufr_ grib_bufr_descriptors_array_push(expanded,u); size=1; if (ccp->associatedFieldWidth) { - bufr_descriptor* au=grib_bufr_descriptor_new(c,999999); + bufr_descriptor* au=grib_bufr_descriptor_new(self->tablesAccessor,999999,err); au->width=ccp->associatedFieldWidth; #if MYDEBUG for (idepth=0;idepthcode); - if (xx->flags & BUFR_DESCRIPTOR_FLAG_HAS_VALUES) { - printf("%ld %g %ld",xx->scale,xx->reference,xx->width); - } + printf("%ld %g %ld",xx->scale,xx->reference,xx->width); printf("\n"); } for (idepth=0;idepthdirty=0; + if (!self->tablesAccessor) { + self->tablesAccessor=grib_find_accessor(a->parent->h,self->tablesAccessorName); + Assert(self->tablesAccessor); + } if (self->rank!=0) { err=expand(self->expandedAccessor); @@ -564,8 +521,9 @@ static int expand(grib_accessor* a) if (err) return err; unexpanded=grib_bufr_descriptors_array_new(c,unexpandedSize,100); - for (i=0;itablesAccessor,u[i],&err)); + } grib_context_free(c,u); @@ -651,7 +609,7 @@ static int unpack_long (grib_accessor* a, long* val, size_t *len) for (i=0;i<*len;i++) val[i]=self->expanded->v[i]->width; break; case 4: - for (i=0;i<*len;i++) val[i]=self->expanded->v[i]->flags; + for (i=0;i<*len;i++) val[i]=self->expanded->v[i]->type; break; } @@ -685,7 +643,9 @@ static int value_count(grib_accessor* a,long* rlen) static void destroy(grib_context* c,grib_accessor* a) { grib_accessor_expanded_descriptors* self = (grib_accessor_expanded_descriptors*)a; - if (self->rank==0 && self->expanded) grib_context_free(c,self->expanded); + if (self->rank==0 && self->expanded) { + grib_bufr_descriptors_array_delete(self->expanded); + } } static int get_native_type(grib_accessor* a) diff --git a/src/grib_accessor_factory.h b/src/grib_accessor_factory.h index 844b7a3f5..1777caca2 100644 --- a/src/grib_accessor_factory.h +++ b/src/grib_accessor_factory.h @@ -15,6 +15,7 @@ { "bufr_data_array", &grib_accessor_class_bufr_data_array, }, { "bufr_data_element", &grib_accessor_class_bufr_data_element, }, { "bufr_element", &grib_accessor_class_bufr_element, }, +{ "bufr_elements_table", &grib_accessor_class_bufr_elements_table, }, { "bufr_group", &grib_accessor_class_bufr_group, }, { "bufr_group_number", &grib_accessor_class_bufr_group_number, }, { "bufr_has_delayed_replication", &grib_accessor_class_bufr_has_delayed_replication, }, diff --git a/src/grib_accessor_factory_hash_list b/src/grib_accessor_factory_hash_list index a831437b8..8616ad04c 100644 --- a/src/grib_accessor_factory_hash_list +++ b/src/grib_accessor_factory_hash_list @@ -15,6 +15,7 @@ bufr_data, &grib_accessor_class_bufr_data bufr_data_array, &grib_accessor_class_bufr_data_array bufr_data_element, &grib_accessor_class_bufr_data_element bufr_element, &grib_accessor_class_bufr_element +bufr_elements_table, &grib_accessor_class_bufr_elements_table bufr_group, &grib_accessor_class_bufr_group bufr_group_number, &grib_accessor_class_bufr_group_number bufr_has_delayed_replication, &grib_accessor_class_bufr_has_delayed_replication diff --git a/src/grib_api.h b/src/grib_api.h index 868a21fa6..627e31b18 100644 --- a/src/grib_api.h +++ b/src/grib_api.h @@ -1598,5 +1598,7 @@ Error codes returned by the grib_api functions. #define GRIB_WRONG_CONVERSION -58 /** Missing BUFR table entry for descriptor */ #define GRIB_MISSING_BUFR_ENTRY -59 +/** Null pointer */ +#define GRIB_NULL_POINTER -60 /*! @}*/ #endif diff --git a/src/grib_api_internal.h b/src/grib_api_internal.h index 961c28dd9..a44652676 100644 --- a/src/grib_api_internal.h +++ b/src/grib_api_internal.h @@ -200,12 +200,6 @@ double rint(double x); #define MAX_SMART_TABLE_COLUMNS 20 #define MAX_CODETABLE_ENTRIES 65536 -/* types of BUFR table B elements */ -#define BUFR_TYPE_STRING 1 -#define BUFR_TYPE_DOUBLE 2 -#define BUFR_TYPE_CODETABLE 3 -#define BUFR_TYPE_FLAGTABLE 4 - /* ACCESSOR COMPARE FLAGS */ #define GRIB_COMPARE_NAMES (1<<0) #define GRIB_COMPARE_TYPES (1<<1) @@ -514,13 +508,6 @@ struct grib_accessor }; -#define BUFR_DESCRIPTOR_FLAG_HAS_VALUES (1<<1) -#define BUFR_DESCRIPTOR_FLAG_DEFAULT_VALUES (1<<2) -#define BUFR_DESCRIPTOR_FLAG_MODIFIED_VALUES (1<<3) -#define BUFR_DESCRIPTOR_FLAG_IS_TABLE (1<<4) -#define BUFR_DESCRIPTOR_FLAG_IS_FLAG (1<<5) -#define BUFR_DESCRIPTOR_FLAG_IS_STRING (1<<6) - #define GRIB_ACCESSOR_FLAG_READ_ONLY (1<<1) #define GRIB_ACCESSOR_FLAG_DUMP (1<<2) #define GRIB_ACCESSOR_FLAG_EDITION_SPECIFIC (1<<3) @@ -750,12 +737,27 @@ struct grib_viarray { grib_context* context; } ; +/* types of BUFR descriptors used in bufr_descriptor->type*/ +#define BUFR_DESCRIPTOR_TYPE_UNKNOWN 0 +#define BUFR_DESCRIPTOR_TYPE_STRING 1 +#define BUFR_DESCRIPTOR_TYPE_DOUBLE 2 +#define BUFR_DESCRIPTOR_TYPE_LONG 3 +#define BUFR_DESCRIPTOR_TYPE_TABLE 4 +#define BUFR_DESCRIPTOR_TYPE_FLAG 5 +#define BUFR_DESCRIPTOR_TYPE_REPLICATION 6 +#define BUFR_DESCRIPTOR_TYPE_OPERATOR 7 +#define BUFR_DESCRIPTOR_TYPE_SEQUENCE 8 + struct bufr_descriptor { + grib_context* context; long code; int F; int X; int Y; - int flags; + int type; + char* name; + char* shortName; + char* units; long scale; double factor; double reference; @@ -774,8 +776,6 @@ struct bufr_descriptors_array { #define MAX_SET_VALUES 10 #define MAX_ACCESSOR_CACHE 100 - - struct grib_handle { grib_context* context; /** < context attached to this handle */ @@ -991,7 +991,6 @@ struct grib_context int hash_array_count; grib_hash_array_value* hash_array[MAX_NUM_HASH_ARRAY]; grib_trie* def_files; - grib_string_list* blacklist; int ieee_packing; int unpack; diff --git a/src/grib_api_prototypes.h b/src/grib_api_prototypes.h index 07412f307..37304d938 100644 --- a/src/grib_api_prototypes.h +++ b/src/grib_api_prototypes.h @@ -146,11 +146,13 @@ grib_hash_array_value *grib_double_hash_array_value_new(grib_context *c, const c void grib_hash_array_value_delete(grib_context *c, grib_hash_array_value *v); /* grib_bufr_descriptor.c */ -bufr_descriptor *grib_bufr_descriptor_new(grib_context *c, int code); -bufr_descriptor *grib_bufr_descriptor_clone(grib_context *c, bufr_descriptor *d); -void grib_bufr_descriptor_set_code(bufr_descriptor *v, int code); +bufr_descriptor *grib_bufr_descriptor_new(grib_accessor *tables_accessor, int code, int *err); +bufr_descriptor *grib_bufr_descriptor_clone(bufr_descriptor *d); void grib_bufr_descriptor_set_values(bufr_descriptor *v, int scale, int reference, int width); -void grib_bufr_descriptor_set_scale(bufr_descriptor *v, int scale); +int grib_bufr_descriptor_set_code(grib_accessor *tables_accessor, int code, bufr_descriptor *v); +void grib_bufr_descriptor_set_reference(bufr_descriptor *v, double reference); +void grib_bufr_descriptor_set_width(bufr_descriptor *v, long width); +void grib_bufr_descriptor_set_scale(bufr_descriptor *v, long scale); void grib_bufr_descriptor_delete(grib_context *c, bufr_descriptor *v); /* grib_bufr_descriptors_array.c */ @@ -249,6 +251,13 @@ size_t grib_viarray_used_size(grib_viarray *v); /* grib_accessor_class_bufr_data_array.c */ /* grib_accessor_class_bufr_data_element.c */ +void accessor_bufr_data_element_set_index(grib_accessor *a, long index); +void accessor_bufr_data_element_set_type(grib_accessor *a, int type); +void accessor_bufr_data_element_set_compressedData(grib_accessor *a, int compressedData); +void accessor_bufr_data_element_set_descriptors(grib_accessor *a, bufr_descriptors_array *descriptors); +void accessor_bufr_data_element_set_numericValues(grib_accessor *a, grib_vdarray *numericValues); +void accessor_bufr_data_element_set_stringValues(grib_accessor *a, grib_vsarray *stringValues); +void accessor_bufr_data_element_set_elementsDescriptorsIndex(grib_accessor *a, grib_viarray *elementsDescriptorsIndex); /* grib_accessor_class_bufr_group.c */ @@ -258,6 +267,10 @@ size_t grib_viarray_used_size(grib_viarray *v); /* grib_accessor_class_bufr_element.c */ +/* grib_accessor_class_bufr_elements_table.c */ +char **str_split(char *a_str, const char a_delim); +bufr_descriptor *accessor_bufr_elements_table_get_descriptor(grib_accessor *a, int code, int *err); + /* grib_accessor_class_bufr_has_delayed_replication.c */ /* grib_accessor_class_bufr_subset_number.c */ @@ -1255,6 +1268,7 @@ double grib_arguments_get_double(grib_handle *h, grib_arguments *args, int n); grib_expression *grib_arguments_get_expression(grib_handle *h, grib_arguments *args, int n); /* grib_util.c */ +double rint(double x); grib_handle *grib_util_sections_copy(grib_handle *hfrom, grib_handle *hto, int what, int *err); grib_string_list *grib_util_get_param_id(const char *mars_param); grib_string_list *grib_util_get_mars_param(const char *param_id); diff --git a/src/grib_bufr_descriptor.c b/src/grib_bufr_descriptor.c index 0cf98b03a..807582306 100644 --- a/src/grib_bufr_descriptor.c +++ b/src/grib_bufr_descriptor.c @@ -11,49 +11,92 @@ #include "grib_api_internal.h" -bufr_descriptor* grib_bufr_descriptor_new(grib_context* c,int code) { - bufr_descriptor* v=NULL; - - if (!c) c=grib_context_get_default(); - - v=(bufr_descriptor*)grib_context_malloc_clear(c,sizeof(bufr_descriptor)); - if (!v) { - grib_context_log(c,GRIB_LOG_ERROR, - "grib_bufr_descriptor_new unable to allocate %d bytes\n",sizeof(bufr_descriptor)); - return NULL; - } - - grib_bufr_descriptor_set_code(v,code); - - return v; +bufr_descriptor* grib_bufr_descriptor_new(grib_accessor* tables_accessor,int code,int *err) { + bufr_descriptor* ret=accessor_bufr_elements_table_get_descriptor(tables_accessor,code,err); + if (*err) grib_context_log(tables_accessor->parent->h->context,GRIB_LOG_ERROR, + "unable to get descriptor %06d from table",code); + return ret; } -bufr_descriptor* grib_bufr_descriptor_clone(grib_context* c,bufr_descriptor* d) { +bufr_descriptor* grib_bufr_descriptor_clone(bufr_descriptor* d) { + + bufr_descriptor* cd=0; if (!d) return NULL; - return grib_bufr_descriptor_new(c,d->code); -} + cd=grib_context_malloc_clear(d->context,sizeof(bufr_descriptor)); -void grib_bufr_descriptor_set_code(bufr_descriptor* v,int code) { - if (!v) return; + cd->code=d->code; + cd->F=d->F; + cd->X=d->X; + cd->Y=d->Y; + cd->name=grib_context_strdup(d->context,d->name); + cd->shortName=grib_context_strdup(d->context,d->shortName); + cd->units=grib_context_strdup(d->context,d->units); + cd->scale=d->scale; + cd->factor=d->factor; + cd->width=d->width; + cd->reference=d->reference; + cd->type=d->type; - v->code=code; - v->F=code/100000; - v->X=(code-v->F*100000)/1000; - v->Y=(code-v->F*100000)%1000; + return cd; } void grib_bufr_descriptor_set_values(bufr_descriptor* v,int scale,int reference,int width) { if (!v) return; v->scale=scale; - v->reference=reference; v->width=width; - v->flags=BUFR_DESCRIPTOR_FLAG_HAS_VALUES; v->factor=grib_power(-scale,10); } -void grib_bufr_descriptor_set_scale(bufr_descriptor* v,int scale) { +int grib_bufr_descriptor_set_code(grib_accessor* tables_accessor,int code,bufr_descriptor* v) { + int err=0; + grib_context* c; + bufr_descriptor* d; + + if (!v) return GRIB_NULL_POINTER; + + c=v->context; + + if (v->type==BUFR_DESCRIPTOR_TYPE_REPLICATION || v->type==BUFR_DESCRIPTOR_TYPE_OPERATOR) { + v->code=code; + v->F=code/100000; + v->X=(code-v->F*100000)/1000; + v->Y=(code-v->F*100000)%1000; + } else { + if (tables_accessor==NULL) return GRIB_NULL_POINTER; + d=accessor_bufr_elements_table_get_descriptor(tables_accessor,code,&err); + v->code=d->code; + v->F=d->F; + v->X=d->X; + v->Y=d->Y; + grib_context_free(c,v->name); + v->name=grib_context_strdup(c,d->name); + grib_context_free(c,v->shortName); + v->shortName=grib_context_strdup(c,d->shortName); + grib_context_free(c,v->units); + v->units=grib_context_strdup(c,d->units); + v->scale=d->scale; + v->factor=d->factor; + v->width=d->width; + v->reference=d->reference; + v->type=d->type; + grib_bufr_descriptor_delete(c,d); + } + return err; +} + +void grib_bufr_descriptor_set_reference(bufr_descriptor* v,double reference) { + if (!v) return; + v->reference=reference; +} + +void grib_bufr_descriptor_set_width(bufr_descriptor* v,long width) { + if (!v) return; + v->width=width; +} + +void grib_bufr_descriptor_set_scale(bufr_descriptor* v,long scale) { if (!v) return; v->scale=scale; v->factor=grib_power(-scale,10); @@ -63,6 +106,9 @@ void grib_bufr_descriptor_delete(grib_context* c,bufr_descriptor* v) { if (!v) return; + grib_context_free(c,v->name); + grib_context_free(c,v->shortName); + grib_context_free(c,v->units); grib_context_free(c,v); } diff --git a/src/grib_bufr_descriptors_array.c b/src/grib_bufr_descriptors_array.c index 43dd20c45..80e07fd46 100644 --- a/src/grib_bufr_descriptors_array.c +++ b/src/grib_bufr_descriptors_array.c @@ -175,7 +175,7 @@ bufr_descriptor** grib_bufr_descriptors_array_get_array(bufr_descriptors_array* grib_context* c=grib_context_get_default(); vv=(bufr_descriptor**)grib_context_malloc_clear(c,sizeof(bufr_descriptor*)*v->n); - for (i=0;in;i++) vv[i]=grib_bufr_descriptor_clone(c,v->v[i]); + for (i=0;in;i++) vv[i]=grib_bufr_descriptor_clone(v->v[i]); return vv; } diff --git a/src/grib_context.c b/src/grib_context.c index d874ed75a..467712bc9 100644 --- a/src/grib_context.c +++ b/src/grib_context.c @@ -728,8 +728,11 @@ void* grib_context_realloc(const grib_context* c, void *p,size_t size) char* grib_context_strdup(const grib_context* c,const char* s) { - char *dup = (char*)grib_context_malloc(c,(strlen(s)*sizeof(char))+1); - if(dup) strcpy(dup,s); + char *dup=0; + if (s) { + dup = (char*)grib_context_malloc(c,(strlen(s)*sizeof(char))+1); + if(dup) strcpy(dup,s); + } return dup; } diff --git a/src/grib_errors.c b/src/grib_errors.c index 6bfa752d2..c10938249 100644 --- a/src/grib_errors.c +++ b/src/grib_errors.c @@ -63,6 +63,7 @@ static const char *errors[] = { "String is smaller than requested", /* -57 GRIB_STRING_TOO_SMALL */ "Wrong type conversion", /* -58 GRIB_WRONG_CONVERSION */ "Missing BUFR table entry for descriptor", /* -59 GRIB_MISSING_BUFR_ENTRY */ +"Null pointer", /* -60 GRIB_NULL_POINTER */ "Value mismatch", /* 1 GRIB_VALUE_MISMATCH */ "double values are different", /* 2 GRIB_DOUBLE_VALUE_MISMATCH */ "long values are different", /* 3 GRIB_LONG_VALUE_MISMATCH */ diff --git a/src/grib_errors.txt b/src/grib_errors.txt index 0036843fb..30db451c4 100644 --- a/src/grib_errors.txt +++ b/src/grib_errors.txt @@ -65,3 +65,4 @@ GRIB_INVALID_KEY_VALUE Invalid key value GRIB_STRING_TOO_SMALL String is smaller than requested GRIB_WRONG_CONVERSION Wrong type conversion GRIB_MISSING_BUFR_ENTRY Missing BUFR table entry for descriptor +GRIB_NULL_POINTER Null pointer diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 57157e379..ca1f2c781 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -29,6 +29,7 @@ endforeach() list( APPEND tests definitions bufr_dump + bufrdc_desc_ref bufrdc_ref ieee grib1to2 diff --git a/tests/Makefile.am b/tests/Makefile.am index e1f99a36b..2dd6c7342 100755 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,5 +1,5 @@ TESTS = definitions.sh \ - bufrdc_ref.sh bufr_dump.sh \ + bufrdc_desc_ref.sh bufrdc_ref.sh bufr_dump.sh \ ieee.sh grib1to2.sh \ unit_tests.sh \ grib2to1.sh badgrib.sh ls.sh filter.sh \ diff --git a/tests/bufrdc_desc_ref.sh b/tests/bufrdc_desc_ref.sh index 7714fa43d..1e11862ea 100755 --- a/tests/bufrdc_desc_ref.sh +++ b/tests/bufrdc_desc_ref.sh @@ -8,7 +8,7 @@ # virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. # -set -e +set -ex . ./include.sh REDIRECT=/dev/null diff --git a/tests/bufrdc_ref.sh b/tests/bufrdc_ref.sh index c593bf3b8..142f938ce 100755 --- a/tests/bufrdc_ref.sh +++ b/tests/bufrdc_ref.sh @@ -8,7 +8,7 @@ # virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. # -set -e +set -ex . ./include.sh