From ad9a1b91b1ef0d1b0405750500b6927fb7ae6c89 Mon Sep 17 00:00:00 2001 From: tradke Date: Wed, 7 Jan 2004 13:32:17 +0000 Subject: Fixed handling of string attributes. These are treated as HDF5 native strings now rather than arrays of chars. git-svn-id: http://svn.cactuscode.org/arrangements/CactusExternal/FlexIO/trunk@51 21a6bef8-4479-4f54-8f8d-0db94a2919ef --- src/H5IO.cc | 126 +++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 74 insertions(+), 52 deletions(-) diff --git a/src/H5IO.cc b/src/H5IO.cc index 009bdbd..d5d8795 100644 --- a/src/H5IO.cc +++ b/src/H5IO.cc @@ -37,14 +37,14 @@ hid_t H5IO::DataType2H5(IObase::DataType nt){ } } -IObase::DataType H5IO::H5DataType2DataType(hid_t nt){ +IObase::DataType H5IO::H5DataType2DataType(hid_t nt){ H5T_class_t typeclass; size_t typesize; - + typeclass = H5Tget_class(nt); typesize = H5Tget_size(nt); //fprintf(stderr,"class=%d size=%d\n",typeclass,typesize); - + switch(typeclass){ case H5T_INTEGER: // printf("Int %d bytes\n",typesize); @@ -98,7 +98,7 @@ IObase::DataType H5IO::H5DataType2DataType(hid_t nt){ case H5T_OPAQUE: puts("Cannot convert type Opaque"); break; - case H5T_COMPOUND: + case H5T_COMPOUND: default: puts("Cannot convert type Unknown"); break; @@ -136,7 +136,7 @@ IObase::DataType H5IO::H52DataType(hid_t &nt){ fprintf(stderr,"H5IO::H52DataType(): Don't recognize type %d\n",(int)nt); return Error; } -#endif +#endif int H5IO::createdataspace(int rank,CONST int *dims){ if(dataspacevalid && rankf==(hsize_t) rank){ // lets compare dims @@ -170,8 +170,8 @@ int H5IO::createdatatype(IObase::DataType dt){ int H5IO::selectdataset(int i){ // printf("datasetvalid=%u i=%d index=%d nitems=%d\n",datasetvalid,i,index,nitems); - - if(index==i && datasetvalid) + + if(index==i && datasetvalid) return index; index=i; if(index>=nitems) index=nitems-1; @@ -201,22 +201,22 @@ int H5IO::selectdataset(int i){ } herr_t H5IOcounter(hid_t group_id, - const char *member_name, + const char *member_name, void *operator_data){ int *count = (int*)operator_data; /* typedef struct H5G_stat_t { unsigned long fileno[2]; - unsigned long objno[2]; - unsigned nlink; - int type; - time_t mtime; + unsigned long objno[2]; + unsigned nlink; + int type; + time_t mtime; size_t linklen; } H5G_stat_t */ H5G_stat_t objinfo; // request info about the type of objects in root group - if(H5Gget_objinfo(group_id, + if(H5Gget_objinfo(group_id, member_name, - 1 /* follow links */, + 1 /* follow links */, &objinfo)<0) { //fprintf(stderr,"\tcounter: Bad Info [%s] count=%u\n",member_name,*count); return 0; // error (probably bad symlink) @@ -236,18 +236,18 @@ struct H5IO_getname_t { char *name; }; herr_t H5IOgetname(hid_t group_id, - const char *member_name, + const char *member_name, void *operator_data){ H5IO_getname_t *getn = (H5IO_getname_t*)operator_data; // check type first (only respond if it is a dataset) H5G_stat_t objinfo; // request info about the type of objects in root group - if(H5Gget_objinfo(group_id, + if(H5Gget_objinfo(group_id, member_name, - 1 /* follow links */, + 1 /* follow links */, &objinfo)<0) return 0; // error (probably bad symlink) // only count objects that are datasets (not subgroups) - if(objinfo.type!=H5G_DATASET) + if(objinfo.type!=H5G_DATASET) return 0; // do not increment count if it isn't a dataset. if(getn->index==getn->count){ strcpy(getn->name,member_name); @@ -402,7 +402,7 @@ int H5IO::write(IObase::DataType typeID,int rank,CONST int *dims,const void *dat //} int H5IO::readInfo(char *name,IObase::DataType &typeID,int &rank,int *dims,int maxdims){ - + // name shouls be attribute "long_name"); if(hasread){ //printf("hasread=1, so get next dataset index %u\n",index+1); @@ -494,7 +494,7 @@ int H5IO::readAnnotation(int number,char *annotation,int maxlen){ #endif if(maxlen>30) sprintf(annotation,"not-implemented"); - else if(annotation) + else if(annotation) *annotation=0; return 1; } @@ -505,7 +505,7 @@ int H5IO::nAnnotations(){ select(index); int32 ref=SDidtoref(sid); if(DFANgetlablen(filename,DFTAG_NDG,ref)<=0) return 0; // no labels found - return 1; // always 1 annotation per object limit for H5 is appears + return 1; // always 1 annotation per object limit for H5 is appears #endif return 0; } @@ -515,13 +515,26 @@ int H5IO::writeAttribute(CONST char *name,IObase::DataType typeID,Long length,co selectdataset(index); // make sure it is selected //printf("\tindex=%u\n",index); // create a datashape - hsize_t dimsa[2]={0,0}; - dimsa[0]=length; - hid_t shape = H5Screate_simple(1, dimsa, NULL); - hid_t attrib = H5Acreate(dataset,name,DataType2H5(typeID),shape,H5P_DEFAULT); - H5Awrite(attrib, DataType2H5(typeID), data); + hid_t datatype = DataType2H5(typeID); + int is_string = datatype == H5T_NATIVE_CHAR; + if (is_string) + { + datatype = H5Tcopy (H5T_C_S1); + // we want the string length (without the trailing '\0') + H5Tset_size (datatype, length - 1); + length = 1; + } + hsize_t dimsa = length; + hid_t shape = dimsa > 1 ? H5Screate_simple (1, &dimsa, NULL) : + H5Screate (H5S_SCALAR); + hid_t attrib = H5Acreate(dataset,name,datatype,shape,H5P_DEFAULT); + H5Awrite(attrib, datatype, data); H5Aclose(attrib); H5Sclose(shape); + if (is_string) + { + H5Tclose (datatype); + } return 1; } @@ -531,18 +544,21 @@ int H5IO::readAttributeInfo(int number,char *name,IObase::DataType &typeID,Long hid_t atype = H5Aget_type(attrib); hid_t ashape = H5Aget_space(attrib); H5Aget_name(attrib,maxnamelen,name); - /* hsize_t ranka = */ H5Sget_simple_extent_ndims(ashape); - // rank should always be 1; - hsize_t dimsa[5]={0,0,0,0,0},ndimsa=0,npointsa; - if(H5Sget_simple_extent_dims(ashape,dimsa,NULL)<0) dimsa[0]=0; - ndimsa=H5Sget_simple_extent_ndims(ashape); - npointsa=H5Sget_simple_extent_npoints(ashape); - // fprintf(stderr,"dimsa[0]=%d ndimsa=%d npoints=%u\n",dimsa[0],ndimsa,npointsa); - typeID = H5DataType2DataType(atype); - if(typeID==Char8 && dimsa[0]==0) // special case for strings - dimsa[0] = H5Tget_size(atype); - nelem = dimsa[0]; // single-dimensional array for attributes - + // rank should always be 0 for scalars and 1 for arrays; + hsize_t arank = H5Sget_simple_extent_ndims(ashape); + hsize_t adims; + if ((arank != 0 && arank != 1) || + H5Sget_simple_extent_dims (ashape, &adims, NULL) < 0) + { + return (0); + } + typeID = H5DataType2DataType(atype); + nelem = arank ? adims : 1; // single-dimensional array for attributes + if (H5Tget_class (atype) == H5T_STRING) + { + nelem = H5Tget_size(atype); + } + H5Tclose(atype); H5Sclose(ashape); H5Aclose(attrib); @@ -554,11 +570,11 @@ struct H5IOatt_name2index_t { int count; }; herr_t H5IOattr_name2index(hid_t group_id, - const char *member_name, + const char *member_name, void *operator_data){ H5IOatt_name2index_t *s=(H5IOatt_name2index_t*)operator_data; s->count++; - if(!strcmp(member_name,s->name)) + if(!strcmp(member_name,s->name)) return s->count; else{ return 0; @@ -566,7 +582,7 @@ herr_t H5IOattr_name2index(hid_t group_id, } herr_t H5IOattr_count(hid_t group_id, - const char *member_name, + const char *member_name, void *operator_data){ // cycle through all attribs as a dummy counter int *count = (int *)operator_data; @@ -586,15 +602,21 @@ int H5IO::readAttributeInfo(CONST char *name,IObase::DataType &typeID,Long &nele hid_t attrib = H5Aopen_name(dataset,name); hid_t atype = H5Aget_type(attrib); hid_t ashape = H5Aget_space(attrib); - /* hsize_t ranka = */ H5Sget_simple_extent_ndims(ashape); - // rank should always be 1; - hsize_t dimsa[5]; - H5Sget_simple_extent_dims(ashape,dimsa,NULL); + // rank should always be 0 for scalars and 1 for arrays; + hsize_t arank = H5Sget_simple_extent_ndims(ashape); + hsize_t adims; + if ((arank != 0 && arank != 1) || + H5Sget_simple_extent_dims (ashape, &adims, NULL) < 0) + { + return (0); + } typeID = H5DataType2DataType(atype); - if(typeID==Char8 && dimsa[0]==0) // special case for strings - dimsa[0] = H5Tget_size(atype); - nelem = dimsa[0]; // single-dimensional array for attributes - + nelem = arank ? adims : 1; // single-dimensional array for attributes + if (H5Tget_class (atype) == H5T_STRING) + { + nelem = H5Tget_size(atype); + } + H5Tclose(atype); H5Sclose(ashape); H5Aclose(attrib); @@ -627,7 +649,7 @@ int H5IO::reserveChunk(IObase::DataType typeID,int rank,CONST int *dims){ create(rank,dims,typeID); current_rank=rank; return 1; -#endif +#endif return 1; } @@ -675,7 +697,7 @@ Long8 f_h5_open (char *file,char *accessname,int flen,int alen){ return 0; } IObase *fid=new H5IO(file,mode); - if(fid->isValid()) + if(fid->isValid()) return (Long8)fid; else delete fid; // file open failed @@ -706,7 +728,7 @@ IOFile H5IOopen (char *file,char *accessname){ mode=IObase::Read; else if(*accessname=='a') mode=IObase::Append; - else if(!strcmp(accessname,"write") || + else if(!strcmp(accessname,"write") || !strcmp(accessname,"create") || !strcmp(accessname,"wb")) mode = IObase::Write; -- cgit v1.2.3