void h5_value_doubles(hid_t file_id, char *group, char *name, double **values, int *numValues) { int kk; hid_t group_id = H5Gopen(file_id, group, H5P_DEFAULT); hid_t data_id = H5Dopen(group_id, name, H5P_DEFAULT); hid_t data_space = H5Dget_space(data_id); int rank = H5Sget_simple_extent_ndims(data_space); hsize_t dims[H5S_MAX_RANK], maxdim[H5S_MAX_RANK]; H5Sget_simple_extent_dims(data_space, dims, maxdim); hid_t data_type = H5Dget_type(data_id); H5T_class_t data_class = H5Tget_native_type(data_type, H5T_DIR_DEFAULT); size_t data_size = H5Tget_size(data_class); hsize_t elements = 1; for (kk=0; kk<rank; kk++) elements *= dims[kk]; void *buf = (void *) MALLOC((size_t)(elements*data_size)); H5Dread(data_id, data_class, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf); *values = buf; *numValues = elements; H5Tclose(data_type); H5Tclose(data_class); H5Sclose(data_space); H5Dclose(data_id); H5Gclose(group_id); }
VsDataset::VsDataset(VsRegistry* r, VsObject* parentObject, const std::string& datasetName, hid_t id): VsObject(r, parentObject, datasetName, id) { dataType = H5Tget_native_type(H5Dget_type(id), H5T_DIR_DEFAULT); loadDims(); registry->add(this); }
bool isCharType(hid_t dataType) { if (H5Tequal(dataType, H5T_NATIVE_CHAR)) { return true; } hid_t nativeType = H5Tget_native_type(dataType, H5T_DIR_ASCEND); bool answer = H5Tequal(nativeType, H5T_NATIVE_CHAR); H5Tclose(nativeType); return answer; }
/*------------------------------------------------------------------------- * Function: h5tools_get_native_type * * Purpose: Wrapper around H5Tget_native_type() to work around * Problems with bitfields. * * Return: Success: datatype ID * * Failure: FAIL * * Programmer: Quincey Koziol * Tuesday, October 5, 2004 * * Modifications: * *------------------------------------------------------------------------- */ hid_t h5tools_get_native_type(hid_t type) { hid_t p_type; H5T_class_t type_class; type_class = H5Tget_class(type); if(type_class==H5T_BITFIELD) p_type=H5Tcopy(type); else p_type = H5Tget_native_type(type,H5T_DIR_DEFAULT); return(p_type); }
bool GH5_FetchAttribute( hid_t loc_id, const char *pszAttrName, CPLString &osResult, bool bReportError ) { bool retVal = false; hid_t hAttr = H5Aopen_name( loc_id, pszAttrName ); osResult.clear(); if( hAttr < 0 ) { if( bReportError ) CPLError( CE_Failure, CPLE_AppDefined, "Attempt to read attribute %s failed, not found.", pszAttrName ); return false; } hid_t hAttrTypeID = H5Aget_type( hAttr ); hid_t hAttrNativeType = H5Tget_native_type( hAttrTypeID, H5T_DIR_DEFAULT ); if( H5Tget_class( hAttrNativeType ) == H5T_STRING ) { int nAttrSize = H5Tget_size( hAttrTypeID ); char *pachBuffer = (char *) CPLCalloc(nAttrSize+1,1); H5Aread( hAttr, hAttrNativeType, pachBuffer ); osResult = pachBuffer; CPLFree( pachBuffer ); retVal = true; } else { if( bReportError ) CPLError( CE_Failure, CPLE_AppDefined, "Attribute %s of unsupported type for conversion to string.", pszAttrName ); retVal = false; } H5Tclose( hAttrNativeType ); H5Tclose( hAttrTypeID ); H5Aclose( hAttr ); return retVal; }
static int NC4_get_propattr(NC_HDF5_FILE_INFO_T* h5) { int ncstat = NC_NOERR; size_t size; H5T_class_t t_class; hid_t grp = -1; hid_t attid = -1; hid_t aspace = -1; hid_t atype = -1; hid_t ntype = -1; herr_t herr = 0; char* text = NULL; /* Get root group */ grp = h5->root_grp->hdf_grpid; /* get root group */ /* Try to extract the NCPROPS attribute */ if(H5Aexists(grp,NCPROPS) > 0) { /* Does exist */ attid = H5Aopen_name(grp, NCPROPS); herr = -1; aspace = H5Aget_space(attid); /* dimensions of attribute data */ atype = H5Aget_type(attid); /* Verify that atype and size */ t_class = H5Tget_class(atype); if(t_class != H5T_STRING) {ncstat = NC_EATTMETA; goto done;} size = H5Tget_size(atype); if(size == 0) goto done; text = (char*)malloc(size+1); if(text == NULL) {ncstat = NC_ENOMEM; goto done;} HCHECK((ntype = H5Tget_native_type(atype, H5T_DIR_ASCEND))); HCHECK((H5Aread(attid, ntype, text))); /* Make sure its null terminated */ text[size] = '\0'; /* Try to parse text */ ncstat = NC4_properties_parse(&h5->fileinfo->propattr,text); herr = 0; } done: if(attid >= 0) HCHECK((H5Aclose(attid))); if(aspace >= 0) HCHECK((H5Sclose(aspace))); if(ntype >= 0) HCHECK((H5Tclose(ntype))); if(atype >= 0) HCHECK((H5Tclose(atype))); if(text != NULL) free(text); return ncstat; }
void h5_att_str(hid_t file_id, char *group, char *name, char *value) { int ii, kk; void *buf = NULL; hid_t attr_id; H5O_info_t object_info; char *attr_name = (char *) MALLOC(sizeof(char)*50); H5Oget_info_by_name(file_id, group, &object_info, H5P_DEFAULT); for (ii=0; ii<object_info.num_attrs; ii++) { attr_id = H5Aopen_by_idx(file_id, group, H5_INDEX_NAME, H5_ITER_NATIVE, ii, H5P_DEFAULT, H5P_DEFAULT); H5Aget_name(attr_id, 50, attr_name); if (strcmp_case(name, attr_name) == 0) { hid_t attr_type = H5Aget_type(attr_id); H5T_class_t data_type = H5Tget_native_type(attr_type, H5T_DIR_DEFAULT); size_t data_size = H5Tget_size(data_type); hid_t attr_space = H5Aget_space(attr_id); hsize_t dims[H5S_MAX_RANK]; int rank = H5Sget_simple_extent_dims(attr_space, dims, NULL); hsize_t elements = 1; for (kk=0; kk<rank; kk++) elements *= dims[kk]; buf = (void *) MALLOC((unsigned)(elements*data_size)); H5Aread(attr_id, attr_type, buf); H5Tclose(attr_type); H5Tclose(data_type); H5Sclose(attr_space); } else { H5Aclose(attr_id); continue; } H5Aclose(attr_id); } if (buf) { strcpy(value, buf); FREE(buf); } else strcpy(value, "???"); FREE(attr_name); }
static int NC4_get_propattr(NC_HDF5_FILE_INFO_T* h5) { int ncstat = NC_NOERR; size_t size; H5T_class_t t_class; char text[NCPROPS_LENGTH+1]; hid_t grp = -1; hid_t attid = -1; hid_t aspace = -1; hid_t atype = -1; hid_t ntype = -1; herr_t herr = 0; /* Get root group */ grp = h5->root_grp->hdf_grpid; /* get root group */ /* Try to extract the NCPROPS attribute */ attid = H5Aopen_name(grp, NCPROPS); if(attid >= 0) { herr = -1; aspace = H5Aget_space(attid); /* dimensions of attribute data */ atype = H5Aget_type(attid); /* Verify that atype and size */ t_class = H5Tget_class(atype); if(t_class != H5T_STRING) {ncstat = NC_EATTMETA; goto done;} size = H5Tget_size(atype); if(size != NCPROPS_LENGTH) {ncstat = NC_EATTMETA; goto done;} HCHECK((ntype = H5Tget_native_type(atype, H5T_DIR_ASCEND))); HCHECK((H5Aread(attid, ntype, text))); /* Try to parse text */ strncpy(h5->fileinfo->propattr.text,text,NCPROPS_LENGTH); h5->fileinfo->propattr.text[NCPROPS_LENGTH-1] = '\0'; ncstat = NC4_properties_parse(&h5->fileinfo->propattr); herr = 0; } done: if(attid >= 0) HCHECK((H5Aclose(attid))); if(aspace >= 0) HCHECK((H5Sclose(aspace))); if(ntype >= 0) HCHECK((H5Tclose(ntype))); if(atype >= 0) HCHECK((H5Tclose(atype))); return ncstat; }
std::string fast5_get_string_attribute(fast5_file& fh, const std::string& group_name, const std::string& attribute_name) { hid_t group, attribute, attribute_type, native_type; std::string out; // according to http://hdf-forum.184993.n3.nabble.com/check-if-dataset-exists-td194725.html // we should use H5Lexists to check for the existence of a group/dataset using an arbitrary path // HDF5 1.8 returns 0 on the root group, so we explicitly check for it int ret = group_name == "/" ? 1 : H5Lexists(fh.hdf5_file, group_name.c_str(), H5P_DEFAULT); if(ret <= 0) { return ""; } // Open the group containing the attribute we want group = H5Gopen(fh.hdf5_file, group_name.c_str(), H5P_DEFAULT); if(group < 0) { #ifdef DEBUG_FAST5_IO fprintf(stderr, "could not open group %s\n", group_name.c_str()); #endif goto close_group; } // Ensure attribute exists ret = H5Aexists(group, attribute_name.c_str()); if(ret <= 0) { goto close_group; } // Open the attribute attribute = H5Aopen(group, attribute_name.c_str(), H5P_DEFAULT); if(attribute < 0) { #ifdef DEBUG_FAST5_IO fprintf(stderr, "could not open attribute: %s\n", attribute_name.c_str()); #endif goto close_attr; } // Get data type and check it is a fixed-length string attribute_type = H5Aget_type(attribute); if(attribute_type < 0) { #ifdef DEBUG_FAST5_IO fprintf(stderr, "failed to get attribute type %s\n", attribute_name.c_str()); #endif goto close_type; } if(H5Tget_class(attribute_type) != H5T_STRING) { #ifdef DEBUG_FAST5_IO fprintf(stderr, "attribute %s is not a string\n", attribute_name.c_str()); #endif goto close_type; } native_type = H5Tget_native_type(attribute_type, H5T_DIR_ASCEND); if(native_type < 0) { #ifdef DEBUG_FAST5_IO fprintf(stderr, "failed to get native type for %s\n", attribute_name.c_str()); #endif goto close_native_type; } if(H5Tis_variable_str(attribute_type) > 0) { // variable length string char* buffer; ret = H5Aread(attribute, native_type, &buffer); if(ret < 0) { fprintf(stderr, "error reading attribute %s\n", attribute_name.c_str()); exit(EXIT_FAILURE); } out = buffer; free(buffer); buffer = NULL; } else { // fixed length string size_t storage_size; char* buffer; // Get the storage size and allocate storage_size = H5Aget_storage_size(attribute); buffer = (char*)calloc(storage_size + 1, sizeof(char)); // finally read the attribute ret = H5Aread(attribute, attribute_type, buffer); if(ret >= 0) { out = buffer; } // clean up free(buffer); } close_native_type: H5Tclose(native_type); close_type: H5Tclose(attribute_type); close_attr: H5Aclose(attribute); close_group: H5Gclose(group); return out; }
/*------------------------------------------------------------------------------ * Purpose: Read data from file * Parameters: H5Dataset* d -- The dataset whose value to be retrieved from file * to server: { opID, fid, fullpath, type, space } * * to client: { value, error } * * Return: Returns a non-negative value if successful; otherwise returns a negative value. *------------------------------------------------------------------------------ */ int H5Dataset_read(H5Dataset* ind, H5Dataset* outd) { int ret_value=0, i=0; hid_t did=-1, sid=-1, tid=-1, msid=-1, ftid=-1; unsigned int npoints=1; hsize_t start[H5S_MAX_RANK], stride[H5S_MAX_RANK], count[H5S_MAX_RANK], mdims[1]; time_t t0=0, t1=0; H5Eclear(); if (ind->space.rank <=0 ) H5Dataset_init(ind); t0 = time(NULL); if ( (did = H5Dopen(ind->fid, ind->fullpath)) < 0) THROW_H5LIBRARY_ERROR(ind->error,ret_value, done); /* TODO at H5Dataset -- we need to convert the datatype to the datatype which is passed * from client machine so that the data reading from file will be right for * the client. The byte order of the client machine, server machine, and data * in the file can be all different. * * For the first version, we assume the server machine and client machine * have the same byte order. */ ftid = H5Dget_type(did); tid = H5Tget_native_type(ftid, H5T_DIR_ASCEND); H5Tclose(ftid); /* TODO at H5Dataset -- to support different byte order between the server and client */ if (ind->type.order != get_machine_endian()) THROW_ERROR(ind->error, "H5Dataset_read", "The byte order is different between the server and client", ret_value, done); sid = msid = H5S_ALL; npoints = 1; for (i=0; i<ind->space.rank; i++) npoints *= ind->space.count[i]; ind->space.npoints = npoints; mdims[0] = npoints; /* cannot select hyperslab for scalar data point or 1D array with a single data point */ if ( (ind->space.rank>0) && (ind->space.rank * ind->space.dims[0]>1) ) { sid = H5Dget_space(did); for (i=0; i<ind->space.rank; i++) { start[i] = ind->space.start[i]; stride[i] = ind->space.stride[i]; count[i] = ind->space.count[i]; } if (H5Sselect_hyperslab(sid, H5S_SELECT_SET, start, stride, count, NULL)<0) THROW_H5LIBRARY_ERROR(ind->error,ret_value, done); msid = H5Screate_simple(1, mdims, NULL); } if (ind->value) H5Dataset_freeBuffer(ind->value, ind->space, ind->type, ind->nvalue); if (NULL == (ind->value = malloc(npoints*ind->type.size)) ) THROW_ERROR(ind->error, "H5Dataset_read", "unable to allocate memory to read data from file", ret_value, done); ind->nvalue = npoints*ind->type.size; ind->tclass = ind->type.tclass; if ( H5Dread(did, tid, msid, sid, H5P_DEFAULT, ind->value) < 0) { free (ind->value); ind->value = NULL; THROW_H5LIBRARY_ERROR(ind->error,ret_value, done); } /* convert compound and variable length data into strings * so that the client application is able to display it */ if ( (H5DATATYPE_VLEN == ind->type.tclass ) || (H5DATATYPE_COMPOUND == ind->type.tclass) || (H5DATATYPE_STRING == ind->type.tclass ) ) { H5Dataset_value_to_string(ind, tid, msid); } done: if (msid > 0) H5Sclose(msid); if (sid > 0 ) H5Sclose(sid); if (tid > 0 ) H5Tclose(tid); if (did > 0 ) H5Dclose(did); t1 = time(NULL); #ifndef HDF5_LOCAL memset (outd, 0, sizeof (H5Dataset)); /* pass on the value */ outd->nvalue = ind->nvalue; outd->value = ind->value; outd->tclass = ind->tclass; outd->error = ind->error; outd->time = (long)(t1-t0); ind->value = NULL; ind->nvalue = 0; #endif return ret_value; }
/*------------------------------------------------------------------------------ * Purpose: Read data value of an attribute from file * Parameters: H5Attribute* a -- The attribute whose value is read from file * Return: Returns a non-negative value if successful; otherwise returns a negative value. *------------------------------------------------------------------------------ */ int H5Attribute_read(H5Attribute *a) { int ret_value=0, i=0; unsigned int npoints; hid_t aid=-1, loc_id=-1, tid=-1, ftid=-1, sid=-1; assert(a); H5Eclear(); if (a->obj_type == H5OBJECT_DATASET) loc_id = H5Dopen(a->fid, a->obj_path); else if (a->obj_type == H5OBJECT_GROUP) loc_id = H5Gopen(a->fid, a->obj_path); else THROW_ERROR(a->error, "H5Attribute_read", "Object must be either H5Dataset or H5Group", ret_value, done); if (loc_id < 0) THROW_H5LIBRARY_ERROR(a->error, ret_value, done); if ( (aid = H5Aopen_name(loc_id, a->name)) < 0) THROW_H5LIBRARY_ERROR(a->error, ret_value, done); if ( (ftid = H5Aget_type(aid)) < 0) THROW_H5LIBRARY_ERROR(a->error, ret_value, done); tid = H5Tget_native_type(ftid, H5T_DIR_ASCEND); H5Tclose(ftid); /* TODO at H5Attribute -- to support different byte order between the server and client */ if (a->type.order != get_machine_endian()) THROW_ERROR(a->error, "H5Attribute_read", "Different byte-order between server and client", ret_value, done); npoints = 1; for (i=0; i<a->space.rank; i++) npoints *= a->space.dims[i]; a->space.npoints = npoints; if (a->value) H5Dataset_freeBuffer(a->value, a->space, a->type, a->nvalue); if (NULL == (a->value = malloc(npoints*a->type.size)) ) THROW_ERROR(a->error, "H5Attribute_read", "unable to allocate memory to read data from file", ret_value, done); a->nvalue = npoints*a->type.size; if ( H5Aread(aid, tid, a->value) < 0) { free (a->value); a->value = NULL; THROW_H5LIBRARY_ERROR(a->error, ret_value, done); } /* convert compound and variable length data into strings * so that the client application is able to display it */ if ( (H5DATATYPE_VLEN == a->type.tclass ) || (H5DATATYPE_COMPOUND == a->type.tclass) || (H5DATATYPE_STRING == a->type.tclass ) ) { sid = H5Aget_space(aid); H5Attribute_value_to_string(a, tid, sid); H5Sclose(sid); } done: if (tid > 0 ) H5Tclose(tid); if (aid > 0) H5Aclose(aid); if (loc_id > 0) { if (a->obj_type == H5OBJECT_DATASET) H5Dclose(loc_id); else if (a->obj_type == H5OBJECT_GROUP) H5Gclose(loc_id); } return ret_value; }
bool BAGRasterBand::Initialize( hid_t hDatasetID, const char *pszName ) { SetDescription( pszName ); this->hDatasetID = hDatasetID; hid_t datatype = H5Dget_type( hDatasetID ); dataspace = H5Dget_space( hDatasetID ); hid_t n_dims = H5Sget_simple_extent_ndims( dataspace ); native = H5Tget_native_type( datatype, H5T_DIR_ASCEND ); hsize_t dims[3], maxdims[3]; eDataType = GH5_GetDataType( native ); if( n_dims == 2 ) { H5Sget_simple_extent_dims( dataspace, dims, maxdims ); nRasterXSize = dims[1]; nRasterYSize = dims[0]; } else { CPLError( CE_Failure, CPLE_AppDefined, "Dataset not of rank 2." ); return false; } nBlockXSize = nRasterXSize; nBlockYSize = 1; /* -------------------------------------------------------------------- */ /* Check for chunksize, and use it as blocksize for optimized */ /* reading. */ /* -------------------------------------------------------------------- */ hid_t listid = H5Dget_create_plist( hDatasetID ); if (listid>0) { if(H5Pget_layout(listid) == H5D_CHUNKED) { hsize_t panChunkDims[3]; int nDimSize = H5Pget_chunk(listid, 3, panChunkDims); nBlockXSize = panChunkDims[nDimSize-1]; nBlockYSize = panChunkDims[nDimSize-2]; } H5Pclose(listid); } /* -------------------------------------------------------------------- */ /* Load min/max information. */ /* -------------------------------------------------------------------- */ if( EQUAL(pszName,"elevation") && GH5_FetchAttribute( hDatasetID, "Maximum Elevation Value", dfMaximum ) && GH5_FetchAttribute( hDatasetID, "Minimum Elevation Value", dfMinimum ) ) bMinMaxSet = true; else if( EQUAL(pszName,"uncertainty") && GH5_FetchAttribute( hDatasetID, "Maximum Uncertainty Value", dfMaximum ) && GH5_FetchAttribute( hDatasetID, "Minimum Uncertainty Value", dfMinimum ) ) bMinMaxSet = true; else if( EQUAL(pszName,"nominal_elevation") && GH5_FetchAttribute( hDatasetID, "max_value", dfMaximum ) && GH5_FetchAttribute( hDatasetID, "min_value", dfMinimum ) ) bMinMaxSet = true; return true; }
static herr_t HDF5AttrIterate( hid_t hH5ObjID, const char *pszAttrName, // TODO(schwehr): void * -> HDF5Dataset * void *pDS ) { char **papszTokens = nullptr; CPLString osKey; HDF5Dataset *const poDS = static_cast<HDF5Dataset *>(pDS); // Convert "/" into "_" for the path component const char *pszPath = poDS->poH5CurrentObject->pszUnderscorePath; if(pszPath != nullptr && strlen(pszPath) > 0) { papszTokens = CSLTokenizeString2(pszPath, "/", CSLT_HONOURSTRINGS); for( hsize_t i = 0; papszTokens != nullptr && papszTokens[i] != nullptr; ++i ) { if( i != 0) osKey += '_'; osKey += papszTokens[i]; } CSLDestroy(papszTokens); } // Convert whitespaces into "_" for the attribute name component papszTokens = CSLTokenizeString2( pszAttrName, " ", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES); for( hsize_t i = 0; papszTokens != nullptr && papszTokens[i] != nullptr; ++i ) { if(!osKey.empty()) osKey += '_'; osKey += papszTokens[i]; } CSLDestroy(papszTokens); const hid_t hAttrID = H5Aopen_name(hH5ObjID, pszAttrName); const hid_t hAttrTypeID = H5Aget_type(hAttrID); const hid_t hAttrNativeType = H5Tget_native_type(hAttrTypeID, H5T_DIR_DEFAULT); const hid_t hAttrSpace = H5Aget_space(hAttrID); if( H5Tget_class(hAttrNativeType) == H5T_VLEN ) return 0; hsize_t nSize[64] = {}; const unsigned int nAttrDims = H5Sget_simple_extent_dims(hAttrSpace, nSize, nullptr); unsigned int nAttrElmts = 1; for( hsize_t i = 0; i < nAttrDims; i++ ) { nAttrElmts *= static_cast<int>(nSize[i]); } char *szData = nullptr; hsize_t nAttrSize = 0; char *szValue = nullptr; if( H5Tget_class(hAttrNativeType) == H5T_STRING ) { if ( H5Tis_variable_str(hAttrNativeType) ) { char **papszStrings = static_cast<char **>(CPLMalloc(nAttrElmts * sizeof(char *))); // Read the values. H5Aread(hAttrID, hAttrNativeType, papszStrings); // Concatenate all values as one string separated by a space. CPLString osVal = papszStrings[0]; for( hsize_t i = 1; i < nAttrElmts; i++ ) { osVal += " "; osVal += papszStrings[i]; } szValue = static_cast<char *>(CPLMalloc(osVal.length() + 1)); strcpy(szValue, osVal.c_str()); H5Dvlen_reclaim(hAttrNativeType, hAttrSpace, H5P_DEFAULT, papszStrings); CPLFree(papszStrings); } else { nAttrSize = H5Aget_storage_size(hAttrID); szValue = static_cast<char *>(CPLMalloc((size_t)(nAttrSize + 1))); H5Aread(hAttrID, hAttrNativeType, szValue); szValue[nAttrSize] = '\0'; } } else { const size_t nDataLen = 8192; void *buf = nullptr; if( nAttrElmts > 0 ) { buf = CPLMalloc(nAttrElmts * H5Tget_size(hAttrNativeType)); szData = static_cast<char *>(CPLMalloc(nDataLen)); szValue = static_cast<char *>(CPLMalloc(MAX_METADATA_LEN)); szData[0] = '\0'; szValue[0] = '\0'; H5Aread(hAttrID, hAttrNativeType, buf); } if( H5Tequal(H5T_NATIVE_CHAR, hAttrNativeType ) || H5Tequal(H5T_NATIVE_SCHAR, hAttrNativeType) ) { for( hsize_t i = 0; i < nAttrElmts; i++ ) { snprintf(szData, nDataLen, "%c ", static_cast<char *>(buf)[i]); if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError(CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated"); } } else if( H5Tequal(H5T_NATIVE_UCHAR, hAttrNativeType) ) { for( hsize_t i = 0; i < nAttrElmts; i++ ) { snprintf(szData, nDataLen, "%c", static_cast<char *>(buf)[i]); if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError(CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated"); } } else if( H5Tequal(H5T_NATIVE_SHORT, hAttrNativeType) ) { for( hsize_t i = 0; i < nAttrElmts; i++ ) { snprintf(szData, nDataLen, "%d ", static_cast<short *>(buf)[i]); if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError(CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated"); } } else if( H5Tequal(H5T_NATIVE_USHORT, hAttrNativeType) ) { for( hsize_t i = 0; i < nAttrElmts; i++ ) { snprintf(szData, nDataLen, "%ud ", static_cast<unsigned short *>(buf)[i]); if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError(CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated"); } } else if( H5Tequal(H5T_NATIVE_INT, hAttrNativeType) ) { for( hsize_t i=0; i < nAttrElmts; i++ ) { snprintf(szData, nDataLen, "%d ", static_cast<int *>(buf)[i]); if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError(CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated"); } } else if( H5Tequal(H5T_NATIVE_UINT, hAttrNativeType) ) { for( hsize_t i = 0; i < nAttrElmts; i++ ) { snprintf(szData, nDataLen, "%ud ", static_cast<unsigned int *>(buf)[i]); if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError(CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated"); } } else if( H5Tequal(H5T_NATIVE_LONG, hAttrNativeType) ) { for( hsize_t i = 0; i < nAttrElmts; i++ ) { snprintf(szData, nDataLen, "%ld ", static_cast<long *>(buf)[i]); if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError(CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated"); } } else if( H5Tequal(H5T_NATIVE_ULONG, hAttrNativeType) ) { for( hsize_t i = 0; i < nAttrElmts; i++ ) { snprintf(szData, nDataLen, "%lu ", static_cast<unsigned long *>(buf)[i]); if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError(CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated"); } } else if( H5Tequal(H5T_NATIVE_FLOAT, hAttrNativeType) ) { for( hsize_t i = 0; i < nAttrElmts; i++ ) { CPLsnprintf(szData, nDataLen, "%.8g ", static_cast<float *>(buf)[i]); if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError(CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated"); } } else if( H5Tequal(H5T_NATIVE_DOUBLE, hAttrNativeType) ) { for( hsize_t i = 0; i < nAttrElmts; i++ ) { CPLsnprintf(szData, nDataLen, "%.15g ", static_cast<double *>(buf)[i]); if( CPLStrlcat(szValue, szData, MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError(CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated"); } } CPLFree(buf); } H5Sclose(hAttrSpace); H5Tclose(hAttrNativeType); H5Tclose(hAttrTypeID); H5Aclose(hAttrID); poDS->papszMetadata = CSLSetNameValue(poDS->papszMetadata, osKey, szValue); CPLFree(szData); CPLFree(szValue); return 0; }
herr_t HDF5CreateGroupObjs( hid_t hHDF5, const char *pszObjName, void *poHObjParent) { HDF5GroupObjects *const poHparent = static_cast<HDF5GroupObjects *>(poHObjParent); HDF5GroupObjects *poHchild = poHparent->poHchild; H5G_stat_t oStatbuf; if( H5Gget_objinfo(hHDF5, pszObjName, FALSE, &oStatbuf) < 0 ) return -1; // Look for next child. unsigned idx = 0; // idx is used after the for loop. for( ; idx < poHparent->nbObjs; idx++ ) { if( poHchild->pszName == nullptr ) break; poHchild++; } if( idx == poHparent->nbObjs ) return -1; // All children parsed. // Save child information. poHchild->pszName = CPLStrdup(pszObjName); poHchild->nType = oStatbuf.type; poHchild->nIndex = idx; poHchild->poHparent = poHparent; poHchild->nRank = 0; poHchild->paDims = nullptr; poHchild->HDatatype = 0; poHchild->objno[0] = oStatbuf.objno[0]; poHchild->objno[1] = oStatbuf.objno[1]; if( poHchild->pszPath == nullptr ) { CreatePath(poHchild); } if( poHparent->pszPath == nullptr ) { CreatePath(poHparent); } switch( oStatbuf.type ) { case H5G_LINK: { poHchild->nbAttrs = 0; poHchild->nbObjs = 0; poHchild->poHchild = nullptr; poHchild->nRank = 0; poHchild->paDims = nullptr; poHchild->HDatatype = 0; break; } case H5G_GROUP: { hid_t hGroupID = H5I_INVALID_HID; // Identifier of group. if( (hGroupID = H5Gopen(hHDF5, pszObjName)) == -1) { CPLError(CE_Failure, CPLE_AppDefined, "unable to access \"%s\" group.", pszObjName); return -1; } // Number of attributes in object. const int nbAttrs = H5Aget_num_attrs(hGroupID); hsize_t nbObjs = 0; // Number of objects in a group. H5Gget_num_objs(hGroupID, &nbObjs); poHchild->nbAttrs = nbAttrs; poHchild->nbObjs = static_cast<int>(nbObjs); poHchild->nRank = 0; poHchild->paDims = nullptr; poHchild->HDatatype = 0; if( nbObjs > 0 ) { poHchild->poHchild = static_cast<HDF5GroupObjects *>( CPLCalloc(static_cast<int>(nbObjs), sizeof(HDF5GroupObjects))); memset(poHchild->poHchild, 0, static_cast<size_t>(sizeof(HDF5GroupObjects) * nbObjs)); } else { poHchild->poHchild = nullptr; } if( !HDF5GroupCheckDuplicate(poHparent, oStatbuf.objno) ) H5Giterate(hHDF5, pszObjName, nullptr, HDF5CreateGroupObjs, poHchild); else CPLDebug("HDF5", "avoiding link looping on node '%s'.", pszObjName); H5Gclose(hGroupID); break; } case H5G_DATASET: { hid_t hDatasetID = H5I_INVALID_HID; // Identifier of dataset. if( (hDatasetID = H5Dopen(hHDF5, pszObjName)) == -1) { CPLError(CE_Failure, CPLE_AppDefined, "unable to access \"%s\" dataset.", pszObjName); return -1; } const int nbAttrs = H5Aget_num_attrs(hDatasetID); const hid_t datatype = H5Dget_type(hDatasetID); const hid_t dataspace = H5Dget_space(hDatasetID); const int n_dims = H5Sget_simple_extent_ndims(dataspace); const hid_t native = H5Tget_native_type(datatype, H5T_DIR_ASCEND); hsize_t *maxdims = nullptr; hsize_t *dims = nullptr; if( n_dims > 0 ) { dims = static_cast<hsize_t *>(CPLCalloc(n_dims, sizeof(hsize_t))); maxdims = static_cast<hsize_t *>(CPLCalloc(n_dims, sizeof(hsize_t))); } H5Sget_simple_extent_dims(dataspace, dims, maxdims); if( maxdims != nullptr ) CPLFree(maxdims); if( n_dims > 0 ) { poHchild->nRank = n_dims; // rank of the array poHchild->paDims = dims; // dimension of the array. poHchild->HDatatype = datatype; // HDF5 datatype } else { poHchild->nRank = -1; poHchild->paDims = nullptr; poHchild->HDatatype = 0; } poHchild->nbAttrs = nbAttrs; poHchild->nbObjs = 0; poHchild->poHchild = nullptr; poHchild->native = native; H5Tclose(datatype); H5Sclose(dataspace); H5Dclose(hDatasetID); break; } case H5G_TYPE: { poHchild->nbAttrs = 0; poHchild->nbObjs = 0; poHchild->poHchild = nullptr; poHchild->nRank = 0; poHchild->paDims = nullptr; poHchild->HDatatype = 0; break; } default: break; } return 0; }
/** * Reads an array of double attributes from the HDF5 metadata. * It reads the attributes directly on its binary form directly, * thus avoiding string conversions. * * Important: It allocates the memory for the attributes internally, * so the caller must free the returned array after using it. * @param pszAttrName Name of the attribute to be read. * the attribute name must be the form: * root attribute name * SUBDATASET/subdataset attribute name * @param pdfValues pointer which will store the array of doubles read. * @param nLen it stores the length of the array read. If NULL it doesn't * inform the length of the array. * @return CPLErr CE_None in case of success, CE_Failure in case of failure */ CPLErr HDF5Dataset::HDF5ReadDoubleAttr(const char *pszAttrFullPath, double **pdfValues, int *nLen) { CPLString osAttrFullPath(pszAttrFullPath); // Search for the last "/" in order to get the path to the attribute. const size_t nSlashPos = osAttrFullPath.find_last_of("/"); CPLString osObjName; CPLString osAttrName; // If objects name have been found. if( nSlashPos != CPLString::npos ) { // Split Object name (dataset, group). osObjName = osAttrFullPath.substr(0, nSlashPos); // Split attribute name. osAttrName = osAttrFullPath.substr(nSlashPos + 1); } else { // By default the group is root, and // the attribute is the full path. osObjName = "/"; osAttrName = pszAttrFullPath; } const hid_t hObjAttrID = H5Oopen(hHDF5, osObjName.c_str(), H5P_DEFAULT); CPLErr retVal = CE_Failure; if(hObjAttrID < 0) { CPLError(CE_Failure, CPLE_OpenFailed, "Object %s could not be opened", pszAttrFullPath); retVal = CE_Failure; } else { // Open attribute handler by name, from the object handler opened // earlier. const hid_t hAttrID = H5Aopen_name(hObjAttrID, osAttrName.c_str()); // Check for errors opening the attribute. if( hAttrID < 0 ) { CPLError(CE_Failure, CPLE_OpenFailed, "Attribute %s could not be opened", pszAttrFullPath); retVal = CE_Failure; } else { const hid_t hAttrTypeID = H5Aget_type(hAttrID); const hid_t hAttrNativeType = H5Tget_native_type(hAttrTypeID, H5T_DIR_DEFAULT); const hid_t hAttrSpace = H5Aget_space(hAttrID); hsize_t nSize[64] = {}; const unsigned int nAttrDims = H5Sget_simple_extent_dims(hAttrSpace, nSize, nullptr); if( !H5Tequal(H5T_NATIVE_DOUBLE, hAttrNativeType) ) { CPLError(CE_Failure, CPLE_OpenFailed, "Attribute %s is not of type double", pszAttrFullPath); retVal = CE_Failure; } else { // Get the amount of elements. unsigned int nAttrElmts = 1; for( hsize_t i = 0; i < nAttrDims; i++ ) { // For multidimensional attributes nAttrElmts *= static_cast<unsigned int>(nSize[i]); } if(nLen != nullptr) *nLen = nAttrElmts; *pdfValues = static_cast<double *>( CPLMalloc(nAttrElmts * sizeof(double))); // Read the attribute contents if( H5Aread(hAttrID, hAttrNativeType, *pdfValues) < 0 ) { CPLError(CE_Failure, CPLE_OpenFailed, "Attribute %s could not be opened", pszAttrFullPath); retVal = CE_Failure; } else { retVal = CE_None; } } H5Tclose(hAttrNativeType); H5Tclose(hAttrTypeID); H5Sclose(hAttrSpace); H5Aclose(hAttrID); } H5Oclose(hObjAttrID); } return retVal; }
/*------------------------------------------------------------------------- * Function: copy_attr * * Purpose: copy attributes located in LOC_IN, which is obtained either from * loc_id = H5Gopen2( fid, name); * loc_id = H5Dopen2( fid, name); * loc_id = H5Topen2( fid, name); * * Return: 0, ok, -1 no *------------------------------------------------------------------------- */ int copy_attr(hid_t loc_in, hid_t loc_out, named_dt_t **named_dt_head_p, trav_table_t *travt, pack_opt_t *options) { int ret_value = 0; hid_t attr_id = -1; /* attr ID */ hid_t attr_out = -1; /* attr ID */ hid_t space_id = -1; /* space ID */ hid_t ftype_id = -1; /* file type ID */ hid_t wtype_id = -1; /* read/write type ID */ size_t msize; /* size of type */ void *buf = NULL; /* data buffer */ hsize_t nelmts; /* number of elements in dataset */ int rank; /* rank of dataset */ htri_t is_named; /* Whether the datatype is named */ hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */ char name[255]; H5O_info_t oinfo; /* object info */ int j; unsigned u; hbool_t is_ref = 0; H5T_class_t type_class = -1; if (H5Oget_info(loc_in, &oinfo) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Oget_info failed"); /*------------------------------------------------------------------------- * copy all attributes *------------------------------------------------------------------------- */ for (u = 0; u < (unsigned) oinfo.num_attrs; u++) { /* open attribute */ if ((attr_id = H5Aopen_by_idx(loc_in, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t) u, H5P_DEFAULT, H5P_DEFAULT)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aopen_by_idx failed"); /* get name */ if (H5Aget_name(attr_id, (size_t) 255, name) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose failed"); /* get the file datatype */ if ((ftype_id = H5Aget_type(attr_id)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aget_type failed"); /* Check if the datatype is committed */ if ((is_named = H5Tcommitted(ftype_id)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tcommitted failed"); if (is_named && travt) { hid_t fidout = -1; /* Create out file id */ if ((fidout = H5Iget_file_id(loc_out)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Iget_file_id failed"); /* Copy named dt */ if ((wtype_id = copy_named_datatype(ftype_id, fidout, named_dt_head_p, travt, options)) < 0) { H5Fclose(fidout); HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "copy_named_datatype failed"); } /* end if */ if (H5Fclose(fidout) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Fclose failed"); } /* end if */ else { if (options->use_native == 1) wtype_id = H5Tget_native_type(ftype_id, H5T_DIR_DEFAULT); else wtype_id = H5Tcopy(ftype_id); } /* end else */ /* get the dataspace handle */ if ((space_id = H5Aget_space(attr_id)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aget_space failed"); /* get dimensions */ if ((rank = H5Sget_simple_extent_dims(space_id, dims, NULL)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_dims failed"); nelmts = 1; for (j = 0; j < rank; j++) nelmts *= dims[j]; if ((msize = H5Tget_size(wtype_id)) == 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_size failed"); /*------------------------------------------------------------------------- * object references are a special case. We cannot just copy the buffers, * but instead we recreate the reference. * This is done on a second sweep of the file that just copies the referenced * objects at copy_refs_attr() *------------------------------------------------------------------------- */ type_class = H5Tget_class(wtype_id); is_ref = (type_class == H5T_REFERENCE); if (type_class == H5T_VLEN || type_class == H5T_ARRAY) { hid_t base_type = -1; base_type = H5Tget_super(ftype_id); is_ref = (is_ref || (H5Tget_class(base_type) == H5T_REFERENCE)); if (H5Tclose(base_type) < 0) H5TOOLS_INFO(H5E_tools_min_id_g, "H5Tclose base_type failed"); } if (type_class == H5T_COMPOUND) { int nmembers = H5Tget_nmembers(wtype_id); for (j = 0; j < nmembers; j++) { hid_t mtid = H5Tget_member_type(wtype_id, (unsigned)j); H5T_class_t mtclass = H5Tget_class(mtid); if (H5Tclose(mtid) < 0) H5TOOLS_INFO(H5E_tools_min_id_g, "H5Tclose mtid failed"); if (mtclass == H5T_REFERENCE) { is_ref = 1; break; } } /* for (j=0; i<nmembers; j++) */ } /* if (type_class == H5T_COMPOUND) */ if (!is_ref) { /*------------------------------------------------------------------------- * read to memory *------------------------------------------------------------------------- */ buf = (void *)HDmalloc((size_t)(nelmts * msize)); if (buf == NULL) { HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "HDmalloc failed"); } /* end if */ if (H5Aread(attr_id, wtype_id, buf) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aread failed"); /*------------------------------------------------------------------------- * copy *------------------------------------------------------------------------- */ if ((attr_out = H5Acreate2(loc_out, name, wtype_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Acreate2 failed on ,%s>", name); if (H5Awrite(attr_out, wtype_id, buf) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Awrite failed"); /*close*/ if (H5Aclose(attr_out) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aclose failed"); /* Check if we have VL data and string in the attribute's datatype that must * be reclaimed */ if (TRUE == h5tools_detect_vlen(wtype_id)) H5Dvlen_reclaim(wtype_id, space_id, H5P_DEFAULT, buf); HDfree(buf); buf = NULL; } /*H5T_REFERENCE*/ if (options->verbose) printf(FORMAT_OBJ_ATTR, "attr", name); /*------------------------------------------------------------------------- * close *------------------------------------------------------------------------- */ if (H5Sclose(space_id) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sclose failed"); space_id = -1; if (H5Tclose(wtype_id) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed"); wtype_id = -1; if (H5Tclose(ftype_id) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose failed"); ftype_id = -1; if (H5Aclose(attr_id) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Aclose failed"); attr_id = -1; } /* for u */ done: H5E_BEGIN_TRY { if (buf) { /* Check if we have VL data and string in the attribute's datatype that must * be reclaimed */ if (TRUE == h5tools_detect_vlen(wtype_id)) H5Dvlen_reclaim(wtype_id, space_id, H5P_DEFAULT, buf); /* Free buf */ HDfree(buf); } /* end if */ H5Aclose(attr_out); H5Sclose(space_id); H5Tclose(wtype_id); H5Tclose(ftype_id); H5Aclose(attr_id); } H5E_END_TRY; return ret_value; } /* end copy_attr() */
/*------------------------------------------------------------------------- * Function: copy_named_datatype * * Purpose: Copies the specified datatype anonymously, and returns an open * id for that datatype in the output file. The first time this * is called it scans every named datatype in travt into a * private stack, afterwards it simply scans that stack. The id * returned must be closed after it is no longer needed. * named_datatype_free must be called before the program exits * to free the stack. *------------------------------------------------------------------------- */ hid_t copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_head_p, trav_table_t *travt, pack_opt_t *options) { named_dt_t *dt = *named_dt_head_p; /* Stack pointer */ named_dt_t *dt_ret = NULL; /* Datatype to return */ H5O_info_t oinfo; /* Object info of input dtype */ hid_t ret_value = -1; /* The identifier of the named dtype in the out file */ if (H5Oget_info(type_in, &oinfo) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Oget_info failed"); if (*named_dt_head_p) { /* Stack already exists, search for the datatype */ while (dt && dt->addr_in != oinfo.addr) dt = dt->next; dt_ret = dt; } else { /* Create the stack */ size_t i; for (i = 0; i < travt->nobjs; i++) { if (travt->objs[i].type == H5TRAV_TYPE_NAMED_DATATYPE) { /* Push onto the stack */ if (NULL == (dt = (named_dt_t *)HDmalloc(sizeof(named_dt_t)))) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "buffer allocation failed failed"); dt->next = *named_dt_head_p; *named_dt_head_p = dt; /* Update the address and id */ dt->addr_in = travt->objs[i].objno; dt->id_out = -1; /* Check if this type is the one requested */ if (oinfo.addr == dt->addr_in) { dt_ret = dt; } /* end if */ } /* end if */ } /* end for */ } /* end else */ /* Handle the case that the requested datatype was not found. This is * possible if the datatype was committed anonymously in the input file. */ if (!dt_ret) { /* Push the new datatype onto the stack */ if (NULL == (dt_ret = (named_dt_t *)HDmalloc(sizeof(named_dt_t)))) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "buffer allocation failed failed"); dt_ret->next = *named_dt_head_p; *named_dt_head_p = dt_ret; /* Update the address and id */ dt_ret->addr_in = oinfo.addr; dt_ret->id_out = -1; } /* end if */ /* If the requested datatype does not yet exist in the output file, copy it * anonymously */ if (dt_ret->id_out < 0) { if (options->use_native == 1) dt_ret->id_out = H5Tget_native_type(type_in, H5T_DIR_DEFAULT); else dt_ret->id_out = H5Tcopy(type_in); if (dt_ret->id_out < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tget_native_type-H5Tcopy failed"); if (H5Tcommit_anon(fidout, dt_ret->id_out, H5P_DEFAULT, H5P_DEFAULT) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tcommit_anon failed"); } /* end if */ /* Set return value */ ret_value = dt_ret->id_out; /* Increment the ref count on id_out, because the calling function will try to close it */ if(H5Iinc_ref(ret_value) < 0) HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Iinc_ref failed"); done: return ret_value; } /* end copy_named_datatype */
bool BAGRasterBand::Initialize( hid_t hDatasetID, const char *pszName ) { SetDescription( pszName ); this->hDatasetID = hDatasetID; hid_t datatype = H5Dget_type( hDatasetID ); dataspace = H5Dget_space( hDatasetID ); int n_dims = H5Sget_simple_extent_ndims( dataspace ); native = H5Tget_native_type( datatype, H5T_DIR_ASCEND ); hsize_t dims[3], maxdims[3]; eDataType = GH5_GetDataType( native ); if( n_dims == 2 ) { H5Sget_simple_extent_dims( dataspace, dims, maxdims ); nRasterXSize = (int) dims[1]; nRasterYSize = (int) dims[0]; } else { CPLError( CE_Failure, CPLE_AppDefined, "Dataset not of rank 2." ); return false; } nBlockXSize = nRasterXSize; nBlockYSize = 1; /* -------------------------------------------------------------------- */ /* Check for chunksize, and use it as blocksize for optimized */ /* reading. */ /* -------------------------------------------------------------------- */ hid_t listid = H5Dget_create_plist( hDatasetID ); if (listid>0) { if(H5Pget_layout(listid) == H5D_CHUNKED) { hsize_t panChunkDims[3]; int nDimSize = H5Pget_chunk(listid, 3, panChunkDims); nBlockXSize = (int) panChunkDims[nDimSize-1]; nBlockYSize = (int) panChunkDims[nDimSize-2]; } int nfilters = H5Pget_nfilters( listid ); H5Z_filter_t filter; char name[120]; size_t cd_nelmts = 20; unsigned int cd_values[20]; unsigned int flags; for (int i = 0; i < nfilters; i++) { filter = H5Pget_filter(listid, i, &flags, (size_t *)&cd_nelmts, cd_values, 120, name); if (filter == H5Z_FILTER_DEFLATE) poDS->SetMetadataItem( "COMPRESSION", "DEFLATE", "IMAGE_STRUCTURE" ); else if (filter == H5Z_FILTER_NBIT) poDS->SetMetadataItem( "COMPRESSION", "NBIT", "IMAGE_STRUCTURE" ); else if (filter == H5Z_FILTER_SCALEOFFSET) poDS->SetMetadataItem( "COMPRESSION", "SCALEOFFSET", "IMAGE_STRUCTURE" ); else if (filter == H5Z_FILTER_SZIP) poDS->SetMetadataItem( "COMPRESSION", "SZIP", "IMAGE_STRUCTURE" ); } H5Pclose(listid); } /* -------------------------------------------------------------------- */ /* Load min/max information. */ /* -------------------------------------------------------------------- */ if( EQUAL(pszName,"elevation") && GH5_FetchAttribute( hDatasetID, "Maximum Elevation Value", dfMaximum ) && GH5_FetchAttribute( hDatasetID, "Minimum Elevation Value", dfMinimum ) ) bMinMaxSet = true; else if( EQUAL(pszName,"uncertainty") && GH5_FetchAttribute( hDatasetID, "Maximum Uncertainty Value", dfMaximum ) && GH5_FetchAttribute( hDatasetID, "Minimum Uncertainty Value", dfMinimum ) ) { /* Some products where uncertainty band is completely set to nodata */ /* wrongly declare minimum and maximum to 0.0 */ if( dfMinimum != 0.0 && dfMaximum != 0.0 ) bMinMaxSet = true; } else if( EQUAL(pszName,"nominal_elevation") && GH5_FetchAttribute( hDatasetID, "max_value", dfMaximum ) && GH5_FetchAttribute( hDatasetID, "min_value", dfMinimum ) ) bMinMaxSet = true; return true; }
bool GH5_FetchAttribute( hid_t loc_id, const char *pszAttrName, double &dfResult, bool bReportError ) { hid_t hAttr = H5Aopen_name( loc_id, pszAttrName ); dfResult = 0.0; if( hAttr < 0 ) { if( bReportError ) CPLError( CE_Failure, CPLE_AppDefined, "Attempt to read attribute %s failed, not found.", pszAttrName ); return false; } hid_t hAttrTypeID = H5Aget_type( hAttr ); hid_t hAttrNativeType = H5Tget_native_type( hAttrTypeID, H5T_DIR_DEFAULT ); /* -------------------------------------------------------------------- */ /* Confirm that we have a single element value. */ /* -------------------------------------------------------------------- */ hid_t hAttrSpace = H5Aget_space( hAttr ); hsize_t anSize[64]; int nAttrDims = H5Sget_simple_extent_dims( hAttrSpace, anSize, NULL ); int i, nAttrElements = 1; for( i=0; i < nAttrDims; i++ ) { nAttrElements *= (int) anSize[i]; } if( nAttrElements != 1 ) { if( bReportError ) CPLError( CE_Failure, CPLE_AppDefined, "Attempt to read attribute %s failed, count=%d, not 1.", pszAttrName, nAttrElements ); H5Sclose( hAttrSpace ); H5Tclose( hAttrNativeType ); H5Tclose( hAttrTypeID ); H5Aclose( hAttr ); return false; } /* -------------------------------------------------------------------- */ /* Read the value. */ /* -------------------------------------------------------------------- */ void *buf = (void *)CPLMalloc( H5Tget_size( hAttrNativeType )); H5Aread( hAttr, hAttrNativeType, buf ); /* -------------------------------------------------------------------- */ /* Translate to double. */ /* -------------------------------------------------------------------- */ if( H5Tequal( H5T_NATIVE_INT, hAttrNativeType ) ) dfResult = *((int *) buf); else if( H5Tequal( H5T_NATIVE_FLOAT, hAttrNativeType ) ) dfResult = *((float *) buf); else if( H5Tequal( H5T_NATIVE_DOUBLE, hAttrNativeType ) ) dfResult = *((double *) buf); else { if( bReportError ) CPLError( CE_Failure, CPLE_AppDefined, "Attribute %s of unsupported type for conversion to double.", pszAttrName ); CPLFree( buf ); H5Sclose( hAttrSpace ); H5Tclose( hAttrNativeType ); H5Tclose( hAttrTypeID ); H5Aclose( hAttr ); return false; } CPLFree( buf ); H5Sclose( hAttrSpace ); H5Tclose( hAttrNativeType ); H5Tclose( hAttrTypeID ); H5Aclose( hAttr ); return true; }
/* HDF5 Specific attribute read/write of _NCProperties */ int NC4_read_ncproperties(NC_FILE_INFO_T* h5) { int retval = NC_NOERR; hid_t hdf5grpid = -1; hid_t attid = -1; hid_t aspace = -1; hid_t atype = -1; hid_t ntype = -1; char* text = NULL; H5T_class_t t_class; hsize_t size; LOG((3, "%s", __func__)); hdf5grpid = ((NC_HDF5_GRP_INFO_T *)(h5->root_grp->format_grp_info))->hdf_grpid; if(H5Aexists(hdf5grpid,NCPROPS) <= 0) { /* Does not exist */ /* File did not contain a _NCProperties attribute */ retval=NC4_get_provenance(h5,NULL,&globalpropinfo); goto done; } /* NCPROPS Attribute exists, make sure it is legitimate */ attid = H5Aopen_name(hdf5grpid, NCPROPS); assert(attid > 0); aspace = H5Aget_space(attid); atype = H5Aget_type(attid); /* Verify atype and size */ t_class = H5Tget_class(atype); if(t_class != H5T_STRING) {retval = NC_EINVAL; goto done;} size = H5Tget_size(atype); if(size == 0) {retval = NC_EINVAL; goto done;} text = (char*)malloc(1+(size_t)size); if(text == NULL) {retval = NC_ENOMEM; goto done;} if((ntype = H5Tget_native_type(atype, H5T_DIR_DEFAULT)) < 0) {retval = NC_EHDFERR; goto done;} if((H5Aread(attid, ntype, text)) < 0) {retval = NC_EHDFERR; goto done;} /* Make sure its null terminated */ text[(size_t)size] = '\0'; /* Process the _NCProperties value */ if((retval = NC4_get_provenance(h5, text, &globalpropinfo))) goto done; done: if(text != NULL) free(text); /* Close out the HDF5 objects */ if(attid > 0 && H5Aclose(attid) < 0) retval = NC_EHDFERR; if(aspace > 0 && H5Sclose(aspace) < 0) retval = NC_EHDFERR; if(atype > 0 && H5Tclose(atype) < 0) retval = NC_EHDFERR; if(ntype > 0 && H5Tclose(ntype) < 0) retval = NC_EHDFERR; /* For certain errors, actually fail, else log that attribute was invalid and ignore */ if(retval != NC_NOERR) { if(retval != NC_ENOMEM && retval != NC_EHDFERR) { LOG((0,"Invalid _NCProperties attribute: ignored")); retval = NC_NOERR; } } return retval; }
void BAGDataset::LoadMetadata() { /* -------------------------------------------------------------------- */ /* Load the metadata from the file. */ /* -------------------------------------------------------------------- */ hid_t hMDDS = H5Dopen( hHDF5, "/BAG_root/metadata" ); hid_t datatype = H5Dget_type( hMDDS ); hid_t dataspace = H5Dget_space( hMDDS ); hid_t native = H5Tget_native_type( datatype, H5T_DIR_ASCEND ); hsize_t dims[3], maxdims[3]; H5Sget_simple_extent_dims( dataspace, dims, maxdims ); pszXMLMetadata = (char *) CPLCalloc(dims[0]+1,1); H5Dread( hMDDS, native, H5S_ALL, dataspace, H5P_DEFAULT, pszXMLMetadata ); H5Sclose( dataspace ); H5Tclose( datatype ); H5Dclose( hMDDS ); if( strlen(pszXMLMetadata) == 0 ) return; /* -------------------------------------------------------------------- */ /* Try to get the geotransform. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRoot = CPLParseXMLString( pszXMLMetadata ); if( psRoot == NULL ) return; CPLStripXMLNamespace( psRoot, NULL, TRUE ); CPLXMLNode *psGeo = CPLSearchXMLNode( psRoot, "=MD_Georectified" ); if( psGeo != NULL ) { char **papszCornerTokens = CSLTokenizeStringComplex( CPLGetXMLValue( psGeo, "cornerPoints.Point.coordinates", "" ), " ,", FALSE, FALSE ); if( CSLCount(papszCornerTokens ) == 4 ) { double dfLLX = atof( papszCornerTokens[0] ); double dfLLY = atof( papszCornerTokens[1] ); double dfURX = atof( papszCornerTokens[2] ); double dfURY = atof( papszCornerTokens[3] ); adfGeoTransform[0] = dfLLX; adfGeoTransform[1] = (dfURX - dfLLX) / (GetRasterXSize()-1); adfGeoTransform[3] = dfURY; adfGeoTransform[5] = (dfLLY - dfURY) / (GetRasterYSize()-1); adfGeoTransform[0] -= adfGeoTransform[1] * 0.5; adfGeoTransform[3] -= adfGeoTransform[5] * 0.5; } CSLDestroy( papszCornerTokens ); } CPLDestroyXMLNode( psRoot ); /* -------------------------------------------------------------------- */ /* Try to get the coordinate system. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; if( OGR_SRS_ImportFromISO19115( &oSRS, pszXMLMetadata ) == OGRERR_NONE ) { oSRS.exportToWkt( &pszProjection ); } }
static int read_data(char *fname) { char pathname[1024]; char *srcdir = getenv("srcdir"); /*where the src code is located*/ hid_t file, dataset; /* handles */ hid_t datatype; hid_t dt; double data_in[NX][NY]; /* input buffer */ double data_out[NX][NY]; /* output buffer */ int i, j; unsigned nerrors = 0; pathname[0] = '\0'; /* Generate correct name for test file by prepending the source path */ if(srcdir && ((strlen(srcdir) + strlen(fname) + 1) < sizeof(pathname))) { strcpy(pathname, srcdir); strcat(pathname, "/"); } strcat(pathname, fname); /* * Data and output buffer initialization. */ for (j = 0; j < NX; j++) { for (i = 0; i < NY; i++) { data_in[j][i] = i + j; data_out[j][i] = 0; } } /* * 0 1 2 3 4 5 * 1 2 3 4 5 6 * 2 3 4 5 6 7 * 3 4 5 6 7 8 * 4 5 6 7 8 9 */ /* * Open the file and the dataset. */ if((file = H5Fopen(pathname, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0) TEST_ERROR; if((dataset = H5Dopen2(file, DATASETNAME, H5P_DEFAULT)) < 0) TEST_ERROR; /* * Get datatype and dataspace handles and then query * dataset class, order, size, rank and dimensions. */ if((dt = H5Dget_type(dataset)) < 0) /* datatype handle */ TEST_ERROR; if((datatype = H5Tget_native_type(dt, H5T_DIR_DEFAULT)) < 0) TEST_ERROR; /* * Read data from hyperslab in the file into the hyperslab in * memory and display. */ if(H5Dread(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, data_out) < 0) TEST_ERROR; /* Check results */ for (j=0; j<NX; j++) { for (i=0; i<NY; i++) { if (data_out[j][i] != data_in[j][i]) { if (!nerrors++) { H5_FAILED(); printf("element [%d][%d] is %g but should have been %g\n", j, i, data_out[j][i], data_in[j][i]); } } } } /* * Close/release resources. */ H5Tclose(dt); H5Tclose(datatype); H5Dclose(dataset); H5Fclose(file); /* Failure */ if (nerrors) { printf("total of %d errors out of %d elements\n", nerrors, NX*NY); return 1; } PASSED(); return 0; error: H5E_BEGIN_TRY { H5Fclose(file); } H5E_END_TRY; return 1; }
/*------------------------------------------------------------------------- * Function: process_cmpd_fields * * Purpose: To check whether the fields selected in "g_list_of_fields" * are valid fields associated with the dataset. * * Return: 0 on success; negative on failure * * Programmer: Vailin Choi; August 2010 * *------------------------------------------------------------------------- */ static herr_t process_cmpd_fields(hid_t fid, char *dsetname) { hid_t did=-1; /* dataset id */ hid_t dtid=-1, tid=-1; /* dataset's data type id */ size_t len; /* number of comma-separated fields in "g_list_of_fields" */ herr_t ret_value = SUCCEED; /* Return value */ HDassert(g_list_of_fields && *g_list_of_fields); /* Open the dataset */ if((did = H5Dopen2(fid, dsetname, H5P_DEFAULT)) < 0) { error_msg("error in opening dataset \"%s\"\n", dsetname); ret_value = FAIL; goto done; } /* Get the dataset's datatype */ if(((dtid = H5Dget_type(did)) < 0) || (tid = H5Tget_native_type(dtid, H5T_DIR_DEFAULT)) < 0) { error_msg("error in getting dataset's datatype\n"); ret_value = FAIL; goto done; } /* Check to make sure that the dataset's datatype is compound type */ if(H5Tget_class(dtid) != H5T_COMPOUND) { error_msg("dataset should be compound type for <list_of_fields>\n"); ret_value = FAIL; goto done; } /* Make a copy of "g_list_of_fields" */ if((g_dup_fields = HDstrdup(g_list_of_fields)) == NULL) { error_msg("error in duplicating g_list_of_fields\n"); ret_value = FAIL; goto done; } /* Estimate the number of comma-separated fields in "g_list of_fields" */ len = HDstrlen(g_list_of_fields)/2 + 2; /* Allocate memory for a list vector of H5LD_memb_t structures to store "g_list_of_fields" info */ if((g_listv = (H5LD_memb_t **)HDcalloc(len, sizeof(H5LD_memb_t *))) == NULL) { error_msg("error in allocating memory for H5LD_memb_t\n"); ret_value = FAIL; goto done; } /* Process and store info for "g_listv" */ if(H5LD_construct_vector(g_dup_fields, g_listv, tid) < 0) { error_msg("error in processing <list_of_fields>\n"); ret_value = FAIL; goto done; } /* Will free memory for g_listv and g_dup_fields when exiting from h5watch */ done: /* Closing */ H5E_BEGIN_TRY H5Tclose(dtid); H5Tclose(tid); H5Dclose(did); H5E_END_TRY return(ret_value); } /* process_cmpd_fields() */
int H5Attribute_init(H5Attribute *a, hid_t aid) { int ret_value=0, i=0; hsize_t dims[H5S_MAX_RANK]; hid_t sid=-1, tid=-1, ftid=-1; unsigned int npoints; if (NULL == a || aid < 0) { ret_value = -1; goto done; } if (a->space.rank > 0) goto done; /* already called */ ftid = H5Aget_type(aid); tid = H5Tget_native_type(ftid, H5T_DIR_ASCEND); if (ftid > 0) H5Tclose(ftid); a->name = (char *)malloc(MAX_NAME_LEN); H5Aget_name(aid, MAX_NAME_LEN, a->name); a->tclass = a->type.tclass = (H5Datatype_class_t)H5Tget_class(tid); a->type.size = H5Tget_size(tid); if ( a->type.tclass == H5DATATYPE_INTEGER || a->type.tclass == H5DATATYPE_FLOAT || a->type.tclass == H5DATATYPE_BITFIELD || a->type.tclass == H5DATATYPE_REFERENCE || a->type.tclass == H5DATATYPE_ENUM ) { a->type.order = (H5Datatype_order_t)H5Tget_order(tid); if (a->type.tclass == H5DATATYPE_INTEGER) { a->type.sign = (H5Datatype_sign_t)H5Tget_sign(tid); } } else if (a->type.tclass == H5DATATYPE_COMPOUND) { a->type.nmembers = H5Tget_nmembers(tid ); a->type.mnames = (char **)malloc(a->type.nmembers*sizeof(char*)); a->type.mtypes = (int *)malloc(a->type.nmembers*sizeof(int)); for (i=0; i<a->type.nmembers; i++) { a->type.mnames[i] = H5Tget_member_name(tid, i); a->type.mtypes[i] = H5Tget_class(H5Tget_member_type(tid, i)); } } sid = H5Aget_space(aid); a->space.rank = H5Sget_simple_extent_ndims(sid); if ( H5Sget_simple_extent_dims(sid, dims, NULL) < 0 ) THROW_H5LIBRARY_ERROR(a->error,ret_value, done); if (a->space.rank<=0) { a->space.rank = 1; dims[0] = 1; } npoints = 1; for (i=0; i<a->space.rank; i++) { a->space.dims[i] = dims[i]; a->space.start[i] = 0; a->space.stride[i] = 1; a->space.count[i] = dims[i]; npoints *= dims[i]; } a->space.npoints = npoints; done: if (sid > 0 ) H5Sclose(sid); if (tid > 0 ) H5Tclose(tid); return ret_value; }
GDALDataset *HDF5ImageDataset::Open( GDALOpenInfo * poOpenInfo ) { int i; HDF5ImageDataset *poDS; char szFilename[2048]; if(!EQUALN( poOpenInfo->pszFilename, "HDF5:", 5 ) || strlen(poOpenInfo->pszFilename) > sizeof(szFilename) - 3 ) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The HDF5ImageDataset driver does not support update access to existing" " datasets.\n" ); return NULL; } poDS = new HDF5ImageDataset(); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ /* printf("poOpenInfo->pszFilename %s\n",poOpenInfo->pszFilename); */ char **papszName = CSLTokenizeString2( poOpenInfo->pszFilename, ":", CSLT_HONOURSTRINGS|CSLT_PRESERVEESCAPES ); if( !((CSLCount(papszName) == 3) || (CSLCount(papszName) == 4)) ) { CSLDestroy(papszName); delete poDS; return NULL; } poDS->SetDescription( poOpenInfo->pszFilename ); /* -------------------------------------------------------------------- */ /* Check for drive name in windows HDF5:"D:\... */ /* -------------------------------------------------------------------- */ strcpy(szFilename, papszName[1]); if( strlen(papszName[1]) == 1 && papszName[3] != NULL ) { strcat(szFilename, ":"); strcat(szFilename, papszName[2]); poDS->SetSubdatasetName( papszName[3] ); } else poDS->SetSubdatasetName( papszName[2] ); CSLDestroy(papszName); papszName = NULL; if( !H5Fis_hdf5(szFilename) ) { delete poDS; return NULL; } poDS->SetPhysicalFilename( szFilename ); /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ poDS->hHDF5 = H5Fopen(szFilename, H5F_ACC_RDONLY, H5P_DEFAULT ); if( poDS->hHDF5 < 0 ) { delete poDS; return NULL; } poDS->hGroupID = H5Gopen( poDS->hHDF5, "/" ); if( poDS->hGroupID < 0 ) { poDS->bIsHDFEOS=false; delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* THIS IS AN HDF5 FILE */ /* -------------------------------------------------------------------- */ poDS->bIsHDFEOS=TRUE; poDS->ReadGlobalAttributes( FALSE ); /* -------------------------------------------------------------------- */ /* Create HDF5 Data Hierarchy in a link list */ /* -------------------------------------------------------------------- */ poDS->poH5Objects = poDS->HDF5FindDatasetObjectsbyPath( poDS->poH5RootGroup, (char *)poDS->GetSubdatasetName() ); if( poDS->poH5Objects == NULL ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Retrieve HDF5 data information */ /* -------------------------------------------------------------------- */ poDS->dataset_id = H5Dopen( poDS->hHDF5,poDS->poH5Objects->pszPath ); poDS->dataspace_id = H5Dget_space( poDS->dataset_id ); poDS->ndims = H5Sget_simple_extent_ndims( poDS->dataspace_id ); poDS->dims = (hsize_t*)CPLCalloc( poDS->ndims, sizeof(hsize_t) ); poDS->maxdims = (hsize_t*)CPLCalloc( poDS->ndims, sizeof(hsize_t) ); poDS->dimensions = H5Sget_simple_extent_dims( poDS->dataspace_id, poDS->dims, poDS->maxdims ); poDS->datatype = H5Dget_type( poDS->dataset_id ); poDS->clas = H5Tget_class( poDS->datatype ); poDS->size = H5Tget_size( poDS->datatype ); poDS->address = H5Dget_offset( poDS->dataset_id ); poDS->native = H5Tget_native_type( poDS->datatype, H5T_DIR_ASCEND ); poDS->nRasterYSize=(int)poDS->dims[poDS->ndims-2]; // Y poDS->nRasterXSize=(int)poDS->dims[poDS->ndims-1]; // X alway last poDS->nBands=1; if( poDS->ndims == 3 ) poDS->nBands=(int) poDS->dims[0]; for( i = 1; i <= poDS->nBands; i++ ) { HDF5ImageRasterBand *poBand = new HDF5ImageRasterBand( poDS, i, poDS->GetDataType( poDS->native ) ); poDS->SetBand( i, poBand ); if( poBand->bNoDataSet ) poBand->SetNoDataValue( 255 ); } poDS->CreateProjections( ); poDS->SetMetadata( poDS->papszMetadata ); /* -------------------------------------------------------------------- */ /* Setup/check for pam .aux.xml. */ /* -------------------------------------------------------------------- */ poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Setup overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" ); return( poDS ); }
herr_t HDF5CreateGroupObjs(hid_t hHDF5, const char *pszObjName, void *poHObjParent) { herr_t ret; /* error return status */ hid_t hGroupID; /* identifier of group */ hid_t hDatasetID; /* identifier of dataset */ hsize_t nbObjs=0; /* number of objects in a group */ int nbAttrs=0; /* number of attributes in object */ int idx; int n_dims; H5G_stat_t oStatbuf; hsize_t *dims=NULL; hsize_t *maxdims=NULL; hid_t datatype; hid_t dataspace; hid_t native; herr_t status; char *CreatePath( HDF5GroupObjects *poH5Object ); HDF5GroupObjects *poHchild; HDF5GroupObjects *poHparent; poHparent = ( HDF5GroupObjects * ) poHObjParent; poHchild=poHparent->poHchild; if( H5Gget_objinfo( hHDF5, pszObjName, FALSE, &oStatbuf ) < 0 ) return -1; /* -------------------------------------------------------------------- */ /* Look for next child */ /* -------------------------------------------------------------------- */ for( idx=0; idx < poHparent->nbObjs; idx++ ) { if( poHchild->pszName == NULL ) break; poHchild++; } if( idx == poHparent->nbObjs ) return -1; // all children parsed /* -------------------------------------------------------------------- */ /* Save child information */ /* -------------------------------------------------------------------- */ poHchild->pszName = CPLStrdup( pszObjName ); poHchild->nType = oStatbuf.type; poHchild->nIndex = idx; poHchild->poHparent = poHparent; poHchild->nRank = 0; poHchild->paDims = 0; poHchild->HDatatype = 0; poHchild->objno[0] = oStatbuf.objno[0]; poHchild->objno[1] = oStatbuf.objno[1]; if( poHchild->pszPath == NULL ) { poHchild->pszPath = CreatePath( poHchild ); } if( poHparent->pszPath == NULL ) { poHparent->pszPath = CreatePath( poHparent ); } switch ( oStatbuf.type ) { case H5G_LINK: poHchild->nbAttrs = 0; poHchild->nbObjs = 0; poHchild->poHchild = NULL; poHchild->nRank = 0; poHchild->paDims = 0; poHchild->HDatatype = 0; break; case H5G_GROUP: if( ( hGroupID = H5Gopen( hHDF5, pszObjName ) ) == -1 ) { printf( "Error: unable to access \"%s\" group.\n", pszObjName ); return -1; } nbAttrs = H5Aget_num_attrs( hGroupID ); ret = H5Gget_num_objs( hGroupID, &nbObjs ); poHchild->nbAttrs= nbAttrs; poHchild->nbObjs = (int) nbObjs; poHchild->nRank = 0; poHchild->paDims = 0; poHchild->HDatatype = 0; if( nbObjs > 0 ) { poHchild->poHchild =( HDF5GroupObjects * ) CPLCalloc( (int)nbObjs, sizeof( HDF5GroupObjects ) ); memset( poHchild->poHchild,0, (size_t) (sizeof( HDF5GroupObjects ) * nbObjs) ); } else poHchild->poHchild = NULL; if( !HDF5GroupCheckDuplicate( poHparent, oStatbuf.objno ) ) H5Giterate( hHDF5, pszObjName, NULL, HDF5CreateGroupObjs, (void*) poHchild ); else CPLDebug( "HDF5", "avoiding link looping on node '%s'.", pszObjName ); H5Gclose( hGroupID ); break; case H5G_DATASET: if( ( hDatasetID = H5Dopen( hHDF5, pszObjName ) ) == -1 ) { printf( "Error: unable to access \"%s\" dataset.\n", pszObjName ); return -1; } nbAttrs = H5Aget_num_attrs( hDatasetID ); datatype = H5Dget_type( hDatasetID ); dataspace = H5Dget_space( hDatasetID ); n_dims = H5Sget_simple_extent_ndims( dataspace ); native = H5Tget_native_type( datatype, H5T_DIR_ASCEND ); if( n_dims > 0 ) { dims = (hsize_t *) CPLCalloc( n_dims,sizeof( hsize_t ) ); maxdims = (hsize_t *) CPLCalloc( n_dims,sizeof( hsize_t ) ); } status = H5Sget_simple_extent_dims( dataspace, dims, maxdims ); if( maxdims != NULL ) CPLFree( maxdims ); if( n_dims > 0 ) { poHchild->nRank = n_dims; // rank of the array poHchild->paDims = dims; // dimmension of the array. poHchild->HDatatype = datatype; // HDF5 datatype } else { poHchild->nRank = -1; poHchild->paDims = NULL; poHchild->HDatatype = 0; } poHchild->nbAttrs = nbAttrs; poHchild->nbObjs = 0; poHchild->poHchild = NULL; poHchild->native = native; ret = H5Dclose( hDatasetID ); break; case H5G_TYPE: poHchild->nbAttrs = 0; poHchild->nbObjs = 0; poHchild->poHchild = NULL; poHchild->nRank = 0; poHchild->paDims = 0; poHchild->HDatatype = 0; break; default: break; } return 0; }
/* Purpose: retrieve datatype and dataspace information from file * Parameters: H5Dataset *d -- The dataset to be initialized * Return: Returns a non-negative value if successful; otherwise returns a negative value. */ int H5Dataset_init(H5Dataset *d) { int ret_value=0, i=0; hsize_t dims[H5S_MAX_RANK]; hid_t did=-1, sid=-1, tid=-1, ftid=-1; unsigned int npoints; assert (d); H5Eclear(); if (d->space.rank > 0) goto done; /* already called */ if ( (did = H5Dopen(d->fid, d->fullpath)) < 0) THROW_H5LIBRARY_ERROR(d->error,ret_value, done); ftid = H5Dget_type(did); tid = H5Tget_native_type(ftid, H5T_DIR_ASCEND); if ( ftid > 0) H5Tclose(ftid); d->tclass = d->type.tclass = (H5Datatype_class_t)H5Tget_class(tid); d->type.size = H5Tget_size(tid); if ( d->type.tclass == H5DATATYPE_INTEGER || d->type.tclass == H5DATATYPE_FLOAT || d->type.tclass == H5DATATYPE_BITFIELD || d->type.tclass == H5DATATYPE_REFERENCE || d->type.tclass == H5DATATYPE_ENUM ) { d->type.order = (H5Datatype_order_t)H5Tget_order(tid); if (d->type.tclass == H5DATATYPE_INTEGER) { d->type.sign = (H5Datatype_sign_t)H5Tget_sign(tid); /* check palette for image */ H5Dataset_readPalette(d, did); H5Dataset_check_image(d, did); } } else if (d->type.tclass == H5DATATYPE_COMPOUND) { d->type.nmembers = H5Tget_nmembers(tid ); d->type.mnames = (char **)malloc(d->type.nmembers*sizeof(char*)); d->type.mtypes = (int *)malloc(d->type.nmembers*sizeof(int)); for (i=0; i<d->type.nmembers; i++) { hid_t mtid = -1; int mtype = 0, mclass, msign, msize; d->type.mnames[i] = H5Tget_member_name(tid, i); mtid = H5Tget_member_type(tid, i); mclass = H5Tget_class(mtid); msign = H5Tget_sign(mtid); msize = H5Tget_size(mtid); mtype = mclass<<28 | msign<<24 | msize; d->type.mtypes[i] = mtype; H5Tclose(mtid); } } sid = H5Dget_space(did); d->space.rank = H5Sget_simple_extent_ndims(sid); if ( H5Sget_simple_extent_dims(sid, dims, NULL) < 0 ) THROW_H5LIBRARY_ERROR(d->error,ret_value, done); if (d->space.rank<=0) { d->space.rank = 1; dims[0] = 1; } npoints = 1; for (i=0; i<d->space.rank; i++) { d->space.dims[i] = dims[i]; d->space.start[i] = 0; d->space.stride[i] = 1; d->space.count[i] = dims[i]; npoints *= dims[i]; } d->space.npoints = npoints; done: if (sid > 0 ) H5Sclose(sid); if (tid > 0 ) H5Tclose(tid); if (did > 0 ) H5Dclose(did); return ret_value; }
herr_t HDF5AttrIterate( hid_t hH5ObjID, const char *AttrName, void *pDS ) { hid_t hAttrID; hid_t hAttrTypeID; hid_t hAttrNativeType; hid_t hAttrSpace; char *szData = NULL; hsize_t nSize[64]; unsigned int nAttrElmts; hsize_t nAttrSize; hsize_t i; void *buf = NULL; unsigned int nAttrDims; HDF5Dataset *poDS; char *szTemp = (char*) CPLMalloc( 8192 ); char *szValue = NULL; poDS = (HDF5Dataset *) pDS; sprintf( szTemp, "%s:%s", poDS->poH5CurrentObject->pszName, AttrName ); hAttrID = H5Aopen_name( hH5ObjID, AttrName ); hAttrTypeID = H5Aget_type( hAttrID ); hAttrNativeType = H5Tget_native_type( hAttrTypeID, H5T_DIR_DEFAULT ); hAttrSpace = H5Aget_space( hAttrID ); nAttrDims = H5Sget_simple_extent_dims( hAttrSpace, nSize, NULL ); if( H5Tget_class( hAttrNativeType ) == H5T_STRING ) { nAttrSize = H5Aget_storage_size( hAttrID ); szData = (char*) CPLMalloc((size_t) (nAttrSize+1)); szValue = (char*) CPLMalloc((size_t) (nAttrSize+1)); H5Aread( hAttrID, hAttrNativeType, szData ); szData[nAttrSize]='\0'; sprintf( szValue, "%s", szData ); } else { nAttrElmts = 1; for( i=0; i < nAttrDims; i++ ) { nAttrElmts *= (int) nSize[i]; } if( nAttrElmts > 0 ){ buf = (void *) CPLMalloc( nAttrElmts* H5Tget_size( hAttrNativeType )); szData = (char*) CPLMalloc( 8192 ); szValue = (char*) CPLMalloc( MAX_METADATA_LEN ); szData[0]='\0'; szValue[0] ='\0'; H5Aread( hAttrID, hAttrNativeType, buf ); } if( H5Tequal( H5T_NATIVE_CHAR, hAttrNativeType ) ){ for( i=0; i < nAttrElmts; i++ ) { sprintf( szData, "%c ", ((char *) buf)[i]); if( CPLStrlcat(szValue,szData,MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError( CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated\n"); } } else if( H5Tequal( H5T_NATIVE_UCHAR, hAttrNativeType ) ) { for( i=0; i < nAttrElmts; i++ ) { sprintf( szData, "%c", ((char *) buf)[i] ); if( CPLStrlcat(szValue,szData,MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError( CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated\n"); } } else if( H5Tequal( H5T_NATIVE_SHORT, hAttrNativeType ) ) { for( i=0; i < nAttrElmts; i++ ) { sprintf( szData, "%d ", ((short *) buf)[i] ); if( CPLStrlcat(szValue,szData,MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError( CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated\n"); } } else if( H5Tequal( H5T_NATIVE_USHORT, hAttrNativeType ) ) { for( i=0; i < nAttrElmts; i++ ) { sprintf( szData, "%ud ", ((unsigned short *) buf)[i] ); if( CPLStrlcat(szValue,szData,MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError( CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated\n"); } } else if( H5Tequal( H5T_NATIVE_INT, hAttrNativeType ) ) { for( i=0; i < nAttrElmts; i++ ) { sprintf( szData, "%d ", ((int *) buf)[i] ); if( CPLStrlcat(szValue,szData,MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError( CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated\n"); } } else if( H5Tequal( H5T_NATIVE_UINT, hAttrNativeType ) ) { for( i=0; i < nAttrElmts; i++ ) { sprintf( szData, "%ud ", ((unsigned int *) buf)[i] ); if( CPLStrlcat(szValue,szData,MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError( CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated\n"); } } else if( H5Tequal( H5T_NATIVE_LONG, hAttrNativeType ) ) { for( i=0; i < nAttrElmts; i++ ) { sprintf( szData, "%ld ", ((long *)buf)[i] ); if( CPLStrlcat(szValue,szData,MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError( CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated\n"); } } else if( H5Tequal( H5T_NATIVE_ULONG, hAttrNativeType ) ) { for( i=0; i < nAttrElmts; i++ ) { sprintf( szData, "%ld ", ((unsigned long *)buf)[i] ); if( CPLStrlcat(szValue,szData,MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError( CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated\n"); } } else if( H5Tequal( H5T_NATIVE_FLOAT, hAttrNativeType ) ) { for( i=0; i < nAttrElmts; i++ ) { sprintf( szData, "%f ", ((float *)buf)[i] ); if( CPLStrlcat(szValue,szData,MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError( CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated\n"); } } else if( H5Tequal( H5T_NATIVE_DOUBLE, hAttrNativeType ) ) { for( i=0; i < nAttrElmts; i++ ) { sprintf( szData, "%g ", ((double *)buf)[i] ); if( CPLStrlcat(szValue,szData,MAX_METADATA_LEN) >= MAX_METADATA_LEN ) CPLError( CE_Warning, CPLE_OutOfMemory, "Header data too long. Truncated\n"); } } CPLFree( buf ); } H5Sclose(hAttrSpace); H5Tclose(hAttrNativeType); H5Tclose(hAttrTypeID); H5Aclose( hAttrID ); //printf( "%s = %s\n",szTemp, szValue ); poDS->papszMetadata = CSLSetNameValue( poDS->papszMetadata, szTemp, CPLSPrintf( "%s", szValue ) ); CPLFree( szTemp ); CPLFree( szData ); CPLFree( szValue ); return 0; }
/*------------------------------------------------------------------------- * Function: H5PTopen * * Purpose: Opens a dataset containing a table and returns the Identifier * of the table. * * Return: Success: table ID, Failure: Negative * * Programmer: Nat Furrer, [email protected] * James Laird, [email protected] * * Date: March 10, 2004 * * Comments: * * Modifications: * * John Mainzer -- 4/23/08 * Added error check on malloc of table, initialized fields * in table to keep lower level code from choking on bogus * data in error cases. * *------------------------------------------------------------------------- */ hid_t H5PTopen( hid_t loc_id, const char *dset_name ) { hid_t type_id=H5I_BADID; hid_t space_id=H5I_BADID; htbl_t * table = NULL; hid_t ret_value; hsize_t dims[1]; /* Register the packet table ID type if this is the first table created */ if( H5PT_ptable_id_type < 0) if((H5PT_ptable_id_type = H5Iregister_type((size_t)H5PT_HASH_TABLE_SIZE, 0, (H5I_free_t)free)) < 0) goto out; table = (htbl_t *)malloc(sizeof(htbl_t)); if ( table == NULL ) { goto out; } table->dset_id = H5I_BADID; table->type_id = H5I_BADID; /* Open the dataset */ if((table->dset_id = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0) goto out; if(table->dset_id < 0) goto out; /* Get the dataset's disk datatype */ if((type_id = H5Dget_type(table->dset_id)) < 0) goto out; /* Get the table's native datatype */ if((table->type_id = H5Tget_native_type(type_id, H5T_DIR_ASCEND)) < 0) goto out; if(H5Tclose(type_id) < 0) goto out; /* Initialize the current record pointer */ if((H5PT_create_index(table)) < 0) goto out; /* Get number of records in table */ if((space_id=H5Dget_space(table->dset_id)) < 0) goto out; if( H5Sget_simple_extent_dims( space_id, dims, NULL) < 0) goto out; if(H5Sclose(space_id) < 0) goto out; table->size = dims[0]; /* Get an ID for this table */ ret_value = H5Iregister(H5PT_ptable_id_type, table); if(ret_value != H5I_INVALID_HID) H5PT_ptable_count++; else H5PT_close(table); return ret_value; out: H5E_BEGIN_TRY H5Tclose(type_id); H5Sclose(space_id); if(table) { H5Dclose(table->dset_id); H5Tclose(table->type_id); free(table); } H5E_END_TRY return H5I_INVALID_HID; }
int main() { printf("\n*** Checking HDF5 attribute functions some more.\n"); printf("*** Creating tst_xplatform2_3.nc with HDF only..."); { hid_t fapl_id, fcpl_id; size_t chunk_cache_size = MY_CHUNK_CACHE_SIZE; size_t chunk_cache_nelems = CHUNK_CACHE_NELEMS; float chunk_cache_preemption = CHUNK_CACHE_PREEMPTION; hid_t fileid, grpid, attid, spaceid; hid_t s1_typeid, vlen_typeid, s3_typeid; hid_t file_typeid1[NUM_OBJ], native_typeid1[NUM_OBJ]; hid_t file_typeid2, native_typeid2; hsize_t num_obj; H5O_info_t obj_info; char obj_name[STR_LEN + 1]; hsize_t dims[1] = {ATT_LEN}; /* netcdf attributes always 1-D. */ struct s1 { float x; double y; }; struct s3 { hvl_t data[NUM_VL]; }; /* cvc stands for "Compound with Vlen of Compound." */ struct s3 cvc_out[ATT_LEN]; int i, j, k; /* Create some output data: a struct s3 array (length ATT_LEN) * which holds an array of vlen (length NUM_VL) of struct s1. */ for (i = 0; i < ATT_LEN; i++) for (j = 0; j < NUM_VL; j++) { cvc_out[i].data[j].len = i + 1; if (!(cvc_out[i].data[j].p = calloc(sizeof(struct s1), cvc_out[i].data[j].len))) ERR; for (k = 0; k < cvc_out[i].data[j].len; k++) { ((struct s1 *)cvc_out[i].data[j].p)[k].x = 42.42; ((struct s1 *)cvc_out[i].data[j].p)[k].y = 2.0; } } /* Create the HDF5 file, with cache control, creation order, and * all the timmings. */ if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR; if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG)) ERR; if (H5Pset_cache(fapl_id, 0, chunk_cache_nelems, chunk_cache_size, chunk_cache_preemption) < 0) ERR; if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) ERR; if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR; if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) < 0) ERR; if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) < 0) ERR; if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) ERR; if (H5Pclose(fapl_id) < 0) ERR; if (H5Pclose(fcpl_id) < 0) ERR; /* Open the root group. */ if ((grpid = H5Gopen2(fileid, "/", H5P_DEFAULT)) < 0) ERR; /* Create the compound type for struct s1. */ if ((s1_typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR; if (H5Tinsert(s1_typeid, X_NAME, offsetof(struct s1, x), H5T_NATIVE_FLOAT) < 0) ERR; if (H5Tinsert(s1_typeid, Y_NAME, offsetof(struct s1, y), H5T_NATIVE_DOUBLE) < 0) ERR; if (H5Tcommit(grpid, S1_TYPE_NAME, s1_typeid) < 0) ERR; /* Create a vlen type. Its a vlen of struct s1. */ if ((vlen_typeid = H5Tvlen_create(s1_typeid)) < 0) ERR; if (H5Tcommit(grpid, VLEN_TYPE_NAME, vlen_typeid) < 0) ERR; /* Create the struct s3 type, which contains the vlen. */ if ((s3_typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct s3))) < 0) ERR; if (H5Tinsert(s3_typeid, VL_NAME, offsetof(struct s3, data), vlen_typeid) < 0) ERR; if (H5Tcommit(grpid, S3_TYPE_NAME, s3_typeid) < 0) ERR; /* Create an attribute of this new type. */ if ((spaceid = H5Screate_simple(1, dims, NULL)) < 0) ERR; if ((attid = H5Acreate(grpid, S3_ATT_NAME, s3_typeid, spaceid, H5P_DEFAULT)) < 0) ERR; if (H5Awrite(attid, s3_typeid, cvc_out) < 0) ERR; /* Close the types. */ if (H5Tclose(s1_typeid) < 0 || H5Tclose(vlen_typeid) < 0 || H5Tclose(s3_typeid) < 0) ERR; /* Close the att. */ if (H5Aclose(attid) < 0) ERR; /* Close the space. */ if (H5Sclose(spaceid) < 0) ERR; /* Close the group and file. */ if (H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; /* Reopen the file. */ if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR; if ((grpid = H5Gopen(fileid, "/")) < 0) ERR; /* How many objects in this group? (There should be 3, the * types. Atts don't count as objects to HDF5.) */ if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR; if (num_obj != NUM_OBJ) ERR; /* For each object in the group... */ for (i = 0; i < num_obj; i++) { /* Get the name, and make sure this is a type. */ if (H5Oget_info_by_idx(grpid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, i, &obj_info, H5P_DEFAULT) < 0) ERR; if (H5Lget_name_by_idx(grpid, ".", H5_INDEX_NAME, H5_ITER_INC, i, obj_name, STR_LEN + 1, H5P_DEFAULT) < 0) ERR; if (obj_info.type != H5O_TYPE_NAMED_DATATYPE) ERR; /* Get the typeid and native typeid. */ if ((file_typeid1[i] = H5Topen2(grpid, obj_name, H5P_DEFAULT)) < 0) ERR; if ((native_typeid1[i] = H5Tget_native_type(file_typeid1[i], H5T_DIR_DEFAULT)) < 0) ERR; } /* There is one att: open it by index. */ if ((attid = H5Aopen_idx(grpid, 0)) < 0) ERR; /* Get file and native typeids of the att. */ if ((file_typeid2 = H5Aget_type(attid)) < 0) ERR; if ((native_typeid2 = H5Tget_native_type(file_typeid2, H5T_DIR_DEFAULT)) < 0) ERR; /* Close the attribute. */ if (H5Aclose(attid) < 0) ERR; /* Close the typeids. */ for (i = 0; i < NUM_OBJ; i++) { if (H5Tclose(file_typeid1[i]) < 0) ERR; if (H5Tclose(native_typeid1[i]) < 0) ERR; } if (H5Tclose(file_typeid2) < 0) ERR; if (H5Tclose(native_typeid2) < 0) ERR; /* Close the group and file. */ if (H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; /* Deallocate our vlens. */ for (i = 0; i < ATT_LEN; i++) for (j = 0; j < NUM_VL; j++) free(cvc_out[i].data[j].p); } SUMMARIZE_ERR; printf("*** Checking vlen of compound file..."); { #define NUM_OBJ_1 1 #define ATT_NAME "Poseidon" hid_t fapl_id, fcpl_id; hid_t fileid, grpid, attid, spaceid; hid_t vlen_typeid; hid_t file_typeid1[NUM_OBJ_1], native_typeid1[NUM_OBJ_1]; hid_t file_typeid2, native_typeid2; hsize_t num_obj; H5O_info_t obj_info; char obj_name[STR_LEN + 1]; hsize_t dims[1] = {ATT_LEN}; /* netcdf attributes always 1-D. */ /* vc stands for "Vlen of Compound." */ hvl_t vc_out[ATT_LEN]; int i, k; /* Create some output data: an array of vlen (length ATT_LEN) of * int. */ for (i = 0; i < ATT_LEN; i++) { vc_out[i].len = i + 1; if (!(vc_out[i].p = calloc(sizeof(int), vc_out[i].len))) ERR; for (k = 0; k < vc_out[i].len; k++) ((int *)vc_out[i].p)[k] = 42; } /* Create the HDF5 file with creation order. */ if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR; if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR; if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) < 0) ERR; if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED | H5P_CRT_ORDER_INDEXED)) < 0) ERR; if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) ERR; if (H5Pclose(fapl_id) < 0) ERR; if (H5Pclose(fcpl_id) < 0) ERR; /* Open the root group. */ if ((grpid = H5Gopen2(fileid, "/", H5P_DEFAULT)) < 0) ERR; /* Create a vlen type. Its a vlen of int. */ if ((vlen_typeid = H5Tvlen_create(H5T_NATIVE_INT)) < 0) ERR; if (H5Tcommit(grpid, VLEN_TYPE_NAME, vlen_typeid) < 0) ERR; /* Create an attribute of this new type. */ if ((spaceid = H5Screate_simple(1, dims, NULL)) < 0) ERR; if ((attid = H5Acreate(grpid, ATT_NAME, vlen_typeid, spaceid, H5P_DEFAULT)) < 0) ERR; if (H5Awrite(attid, vlen_typeid, vc_out) < 0) ERR; /* Close the type. */ if (H5Tclose(vlen_typeid) < 0) ERR; /* Close the att. */ if (H5Aclose(attid) < 0) ERR; /* Close the space. */ if (H5Sclose(spaceid) < 0) ERR; /* Close the group and file. */ if (H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; /* Reopen the file. */ if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) ERR; if ((grpid = H5Gopen(fileid, "/")) < 0) ERR; /* How many objects in this group? (There should be 2, the * types. Atts don't count as objects to HDF5.) */ if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR; if (num_obj != NUM_OBJ_1) ERR; /* For each object in the group... */ for (i = 0; i < num_obj; i++) { /* Get the name, and make sure this is a type. */ if (H5Oget_info_by_idx(grpid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, i, &obj_info, H5P_DEFAULT) < 0) ERR; if (H5Lget_name_by_idx(grpid, ".", H5_INDEX_NAME, H5_ITER_INC, i, obj_name, STR_LEN + 1, H5P_DEFAULT) < 0) ERR; if (obj_info.type != H5O_TYPE_NAMED_DATATYPE) ERR; /* Get the typeid and native typeid. */ if ((file_typeid1[i] = H5Topen2(grpid, obj_name, H5P_DEFAULT)) < 0) ERR; if ((native_typeid1[i] = H5Tget_native_type(file_typeid1[i], H5T_DIR_DEFAULT)) < 0) ERR; } /* There is one att: open it by index. */ if ((attid = H5Aopen_idx(grpid, 0)) < 0) ERR; /* Get file and native typeids of the att. */ if ((file_typeid2 = H5Aget_type(attid)) < 0) ERR; if ((native_typeid2 = H5Tget_native_type(file_typeid2, H5T_DIR_DEFAULT)) < 0) ERR; /* Close the attribute. */ if (H5Aclose(attid) < 0) ERR; /* Close the typeids. */ for (i = 0; i < NUM_OBJ_1; i++) { if (H5Tclose(file_typeid1[i]) < 0) ERR; if (H5Tclose(native_typeid1[i]) < 0) ERR; } if (H5Tclose(file_typeid2) < 0) ERR; if (H5Tclose(native_typeid2) < 0) ERR; /* Close the group and file. */ if (H5Gclose(grpid) < 0 || H5Fclose(fileid) < 0) ERR; /* Deallocate our vlens. */ for (i = 0; i < ATT_LEN; i++) free(vc_out[i].p); } SUMMARIZE_ERR; FINAL_RESULTS; }