//-***************************************************************************** // Get the dimensions directly off of the dataspace on the dataset // This isn't suitable for string and wstring void ReadDataSetDimensions( hid_t iParent, const std::string &iName, hsize_t iExtent, Dimensions &oDims ) { // Open the data set. hid_t dsetId = H5Dopen( iParent, iName.c_str(), H5P_DEFAULT ); ABCA_ASSERT( dsetId >= 0, "Cannot open dataset: " << iName ); DsetCloser dsetCloser( dsetId ); // Read the data space. hid_t dspaceId = H5Dget_space( dsetId ); ABCA_ASSERT( dspaceId >= 0, "Could not get dataspace for dataSet: " << iName ); DspaceCloser dspaceCloser( dspaceId ); H5S_class_t dspaceClass = H5Sget_simple_extent_type( dspaceId ); if ( dspaceClass == H5S_SIMPLE ) { // Get the dimensions int rank = H5Sget_simple_extent_ndims( dspaceId ); ABCA_ASSERT( rank == 1, "H5Sget_simple_extent_ndims() must be 1." ); hsize_t hdim = 0; rank = H5Sget_simple_extent_dims( dspaceId, &hdim, NULL ); oDims.setRank(1); oDims[0] = hdim / iExtent; } else { oDims.setRank(1); oDims[0] = 0; } }
void ReadStringT<std::string,char>( hid_t iParent, const std::string &iAttrName, std::string &oString ) { ABCA_ASSERT( iParent >= 0, "Invalid parent in ReadStringT" ); // Open the attribute. hid_t attrId = H5Aopen( iParent, iAttrName.c_str(), H5P_DEFAULT ); ABCA_ASSERT( attrId >= 0, "Couldn't open attribute named: " << iAttrName ); AttrCloser attrCloser( attrId ); // Checking code. hid_t attrFtype = H5Aget_type( attrId ); DtypeCloser dtypeCloser( attrFtype ); ssize_t numChars = H5Tget_size( attrFtype ); ABCA_ASSERT( numChars >= 0, "ReadStringT() H5Aget_size() failed" ); // Read and check space { hid_t attrSpace = H5Aget_space( attrId ); ABCA_ASSERT( attrSpace >= 0, "Couldn't get dataspace for attribute: " << iAttrName ); DspaceCloser dspaceCloser( attrSpace ); H5S_class_t attrSpaceClass = H5Sget_simple_extent_type( attrSpace ); ABCA_ASSERT( attrSpaceClass == H5S_SCALAR, "Tried to read non-scalar attribute: " << iAttrName << " as scalar" ); } // Create temporary char storage buffer. std::vector<char> charStorage( ( size_t )( 1 + numChars ), ( char )0 ); // Read into it. herr_t status = H5Aread( attrId, attrFtype, ( void * )&charStorage.front() ); ABCA_ASSERT( status >= 0, "Couldn't read from attribute: " << iAttrName ); // Return it. oString = ( const char * )&charStorage.front(); }
int_f nh5sget_simple_extent_type_c ( hid_t_f *space_id , int_f *classtype) { int ret_value = 0; hid_t c_space_id; H5S_class_t c_classtype; c_space_id = *space_id; c_classtype = H5Sget_simple_extent_type(c_space_id); if ( c_classtype < 0 ) ret_value = -1; *classtype = c_classtype; /* if (c_classtype == H5S_SCALAR) *classtype = H5S_SCALAR_F; if (c_classtype == H5S_SIMPLE) *classtype = H5S_SIMPLE_F; */ return ret_value; }
static herr_t trav_attr(hid_t #ifndef H5TRAV_PRINT_SPACE UNUSED #endif /* H5TRAV_PRINT_SPACE */ obj, const char *attr_name, const H5A_info_t UNUSED *ainfo, void *op_data) { char *buf; buf = (char*)op_data; if((strlen(buf)==1) && (*buf=='/')) printf(" %-10s %s%s", "attribute", buf, attr_name); else printf(" %-10s %s/%s", "attribute", buf, attr_name); #ifdef H5TRAV_PRINT_SPACE if(trav_verbosity < 2) { #endif printf("\n"); #ifdef H5TRAV_PRINT_SPACE } else { hid_t attr = -1; hid_t space = -1; hsize_t size[H5S_MAX_RANK]; int ndims; int i; H5S_class_t space_type; if((attr = H5Aopen(obj, attr_name, H5P_DEFAULT))) { space = H5Aget_space(attr); /* Data space */ ndims = H5Sget_simple_extent_dims(space, size, NULL); space_type = H5Sget_simple_extent_type(space); switch(space_type) { case H5S_SCALAR: /* scalar dataspace */ printf(" scalar\n"); break; case H5S_SIMPLE: /* simple dataspace */ printf(" {"); for (i=0; i<ndims; i++) { printf("%s" HSIZE_T_FORMAT, i?", ":"", size[i]); } printf("}\n"); break; case H5S_NULL: /* null dataspace */ printf(" null\n"); break; default: /* Unknown dataspace type */ printf(" unknown\n"); break; } /* end switch */ H5Sclose(space); H5Aclose(attr); } } #endif return(0); }
static AbcA::ArraySamplePtr ReadStringArrayT( AbcA::ReadArraySampleCachePtr iCache, hid_t iParent, const std::string &iName, const AbcA::DataType &iDataType ) { assert( iDataType.getExtent() > 0 ); // Open the data set. hid_t dsetId = H5Dopen( iParent, iName.c_str(), H5P_DEFAULT ); ABCA_ASSERT( dsetId >= 0, "Cannot open dataset: " << iName ); DsetCloser dsetCloser( dsetId ); // Read the digest, if there's a cache. AbcA::ArraySample::Key key; bool foundDigest = ReadKey( dsetId, "key", key ); // If we found a digest and there's a cache, see // if we're in there, and return it if so. if ( foundDigest && iCache ) { AbcA::ReadArraySampleID found = iCache->find( key ); if ( found ) { AbcA::ArraySamplePtr ret = found.getSample(); assert( ret ); if ( ret->getDataType() != iDataType ) { ABCA_THROW( "ERROR: Read data type for dset: " << iName << ": " << ret->getDataType() << " does not match expected data type: " << iDataType ); } // Got it! return ret; } } // Okay, we haven't found it in a cache. // Read the data type. // Checking code. { hid_t dsetFtype = H5Dget_type( dsetId ); DtypeCloser dtypeCloser( dsetFtype ); hid_t nativeDtype = GetNativeDtype<CharT>(); ABCA_ASSERT( H5Tget_class( dsetFtype ) == H5Tget_class( nativeDtype ) && H5Tget_sign( dsetFtype ) == H5Tget_sign( nativeDtype ) // CJH They can now be different // sizes, because wchar_t is sometimes 16-bit, // but we always store 32 bit. // && H5Tget_size( dsetFtype ) == //H5Tget_size( nativeDtype ), , "Invalid datatype for stringT" ); } // String array datatypes require a "dimensions" to be stored // externally, since the strings themselves are stored in a compacted // array of rank 1. // This is an attribute called "dims" that lives in the dset itself. Dimensions realDims; ReadDimensions( dsetId, "dims", realDims ); ABCA_ASSERT( realDims.rank() > 0, "Degenerate rank in Dataset read" ); // Read the data space. hid_t dspaceId = H5Dget_space( dsetId ); ABCA_ASSERT( dspaceId >= 0, "Could not get dataspace for dataSet: " << iName ); DspaceCloser dspaceCloser( dspaceId ); AbcA::ArraySamplePtr ret; H5S_class_t dspaceClass = H5Sget_simple_extent_type( dspaceId ); if ( dspaceClass == H5S_SIMPLE ) { ABCA_ASSERT( realDims.numPoints() > 0, "Degenerate dims in Dataset read" ); size_t totalNumStrings = realDims.numPoints() * iDataType.getExtent(); // Get the dimensions Dimensions dims; int rank = H5Sget_simple_extent_ndims( dspaceId ); ABCA_ASSERT( rank == realDims.rank(), "H5Sget_simple_extent_ndims() failed." ); HDimensions hdims; hdims.setRank( rank ); rank = H5Sget_simple_extent_dims( dspaceId, hdims.rootPtr(), NULL ); ABCA_ASSERT( rank == hdims.rank(), "H5Sget_simple_extent_dims() " "found inconsistent ranks." << std::endl << "Expecting rank: " << hdims.rank() << " instead was: " << rank ); dims = hdims; ABCA_ASSERT( dims.numPoints() > 0, "Degenerate dims in Dataset read" ); // Create temporary char storage buffer. size_t totalNumChars = dims.numPoints() + 1; std::vector<CharT> charStorage( totalNumChars, ( CharT )0 ); // Read into it. herr_t status = H5Dread( dsetId, GetNativeDtype<CharT>(), H5S_ALL, H5S_ALL, H5P_DEFAULT, ( void * )&charStorage.front() ); ABCA_ASSERT( status >= 0, "Could not read string array from data set. Weird." ); // Make an appropriately dimensionalized (and manageable) // array of strings using the ArraySamples. ret = AbcA::AllocateArraySample( iDataType, realDims ); StringT *strings = reinterpret_cast<StringT*>( const_cast<void*>( ret->getData() ) ); assert( strings != NULL ); // This part is hard. We have to go through the one dimensional // array extracting each string. ExtractStrings<StringT,CharT>( strings, ( const CharT * )&charStorage.front(), totalNumChars, totalNumStrings ); } else if ( dspaceClass == H5S_NULL ) { // Num points should be zero here. ABCA_ASSERT( realDims.numPoints() == 0, "Expecting zero points in dimensions" ); ret = AbcA::AllocateArraySample( iDataType, realDims ); } else { ABCA_THROW( "Unexpected scalar dataspace encountered." ); } // Store if there is a cache. if ( foundDigest && iCache ) { AbcA::ReadArraySampleID stored = iCache->store( key, ret ); if ( stored ) { return stored.getSample(); } } // Otherwise, just leave! ArraySamplePtr returned by AllocateArraySample // already has fancy-dan deleter built in. // I REALLY LOVE SMART PTRS. return ret; }
static int find_var_dim_max_length(NC_GRP_INFO_T *grp, int varid, int dimid, size_t *maxlen) { hid_t datasetid = 0, spaceid = 0; NC_VAR_INFO_T *var; hsize_t *h5dimlen = NULL, *h5dimlenmax = NULL; int d, dataset_ndims = 0; int retval = NC_NOERR; *maxlen = 0; /* Find this var. */ for (var = grp->var; var; var = var->l.next) if (var->varid == varid) break; if (!var) return NC_ENOTVAR; /* If the var hasn't been created yet, its size is 0. */ if (!var->created) { *maxlen = 0; } else { /* Get the number of records in the dataset. */ if ((retval = nc4_open_var_grp2(grp, var->varid, &datasetid))) BAIL(retval); if ((spaceid = H5Dget_space(datasetid)) < 0) BAIL(NC_EHDFERR); #ifdef EXTRA_TESTS num_spaces++; #endif /* If it's a scalar dataset, it has length one. */ if (H5Sget_simple_extent_type(spaceid) == H5S_SCALAR) { *maxlen = (var->dimids && var->dimids[0] == dimid) ? 1 : 0; } else { /* Check to make sure ndims is right, then get the len of each dim in the space. */ if ((dataset_ndims = H5Sget_simple_extent_ndims(spaceid)) < 0) BAIL(NC_EHDFERR); if (dataset_ndims != var->ndims) BAIL(NC_EHDFERR); if (!(h5dimlen = malloc(dataset_ndims * sizeof(hsize_t)))) BAIL(NC_ENOMEM); if (!(h5dimlenmax = malloc(dataset_ndims * sizeof(hsize_t)))) BAIL(NC_ENOMEM); if ((dataset_ndims = H5Sget_simple_extent_dims(spaceid, h5dimlen, h5dimlenmax)) < 0) BAIL(NC_EHDFERR); LOG((5, "find_var_dim_max_length: varid %d len %d max: %d", varid, (int)h5dimlen[0], (int)h5dimlenmax[0])); for (d=0; d<dataset_ndims; d++) { if (var->dimids[d] == dimid) { *maxlen = *maxlen > h5dimlen[d] ? *maxlen : h5dimlen[d]; } } } } exit: if (spaceid > 0 && H5Sclose(spaceid) < 0) BAIL2(NC_EHDFERR); #ifdef EXTRA_TESTS num_spaces--; #endif if (h5dimlen) free(h5dimlen); if (h5dimlenmax) free(h5dimlenmax); return retval; }
//-***************************************************************************** void ReadArray( void * iIntoLocation, hid_t iParent, const std::string &iName, const AbcA::DataType &iDataType, hid_t iType ) { // Dispatch string stuff. if ( iDataType.getPod() == kStringPOD ) { return ReadStringArray( iIntoLocation, iParent, iName, iDataType ); } else if ( iDataType.getPod() == kWstringPOD ) { return ReadWstringArray( iIntoLocation, iParent, iName, iDataType ); } assert( iDataType.getPod() != kStringPOD && iDataType.getPod() != kWstringPOD ); // Open the data set. hid_t dsetId = H5Dopen( iParent, iName.c_str(), H5P_DEFAULT ); ABCA_ASSERT( dsetId >= 0, "Cannot open dataset: " << iName ); DsetCloser dsetCloser( dsetId ); // Read the data space. hid_t dspaceId = H5Dget_space( dsetId ); ABCA_ASSERT( dspaceId >= 0, "Could not get dataspace for dataSet: " << iName ); DspaceCloser dspaceCloser( dspaceId ); // Read the data type. hid_t dtypeId = H5Dget_type( dsetId ); ABCA_ASSERT( dtypeId >= 0, "Could not get datatype for dataSet: " << iName ); DtypeCloser dtypeCloser( dtypeId ); H5S_class_t dspaceClass = H5Sget_simple_extent_type( dspaceId ); if ( dspaceClass == H5S_SIMPLE ) { // Get the dimensions int rank = H5Sget_simple_extent_ndims( dspaceId ); ABCA_ASSERT( rank == 1, "H5Sget_simple_extent_ndims() must be 1." ); hsize_t hdim = 0; rank = H5Sget_simple_extent_dims( dspaceId, &hdim, NULL ); ABCA_ASSERT( hdim > 0, "Degenerate dims in Dataset read" ); // And... read into it. herr_t status = H5Dread( dsetId, iType, H5S_ALL, H5S_ALL, H5P_DEFAULT, iIntoLocation ); ABCA_ASSERT( status >= 0, "H5Dread() failed." ); } else if ( dspaceClass != H5S_NULL ) { ABCA_THROW( "Unexpected scalar dataspace encountered." ); } }
//-***************************************************************************** AbcA::ArraySamplePtr ReadArray( AbcA::ReadArraySampleCachePtr iCache, hid_t iParent, const std::string &iName, const AbcA::DataType &iDataType, hid_t iFileType, hid_t iNativeType ) { // Dispatch string stuff. if ( iDataType.getPod() == kStringPOD ) { return ReadStringArray( iCache, iParent, iName, iDataType ); } else if ( iDataType.getPod() == kWstringPOD ) { return ReadWstringArray( iCache, iParent, iName, iDataType ); } assert( iDataType.getPod() != kStringPOD && iDataType.getPod() != kWstringPOD ); // Open the data set. hid_t dsetId = H5Dopen( iParent, iName.c_str(), H5P_DEFAULT ); ABCA_ASSERT( dsetId >= 0, "Cannot open dataset: " << iName ); DsetCloser dsetCloser( dsetId ); // Read the data space. hid_t dspaceId = H5Dget_space( dsetId ); ABCA_ASSERT( dspaceId >= 0, "Could not get dataspace for dataSet: " << iName ); DspaceCloser dspaceCloser( dspaceId ); AbcA::ArraySample::Key key; bool foundDigest = false; // if we are caching, get the key and see if it is being used if ( iCache ) { key.origPOD = iDataType.getPod(); key.readPOD = key.origPOD; key.numBytes = Util::PODNumBytes( key.readPOD ) * H5Sget_simple_extent_npoints( dspaceId ); foundDigest = ReadKey( dsetId, "key", key ); AbcA::ReadArraySampleID found = iCache->find( key ); if ( found ) { AbcA::ArraySamplePtr ret = found.getSample(); assert( ret ); if ( ret->getDataType().getPod() != iDataType.getPod() ) { ABCA_THROW( "ERROR: Read data type for dset: " << iName << ": " << ret->getDataType() << " does not match expected data type: " << iDataType ); } // Got it! return ret; } } // Okay, we haven't found it in a cache. // Read the data type. hid_t dtypeId = H5Dget_type( dsetId ); ABCA_ASSERT( dtypeId >= 0, "Could not get datatype for dataSet: " << iName ); DtypeCloser dtypeCloser( dtypeId ); ABCA_ASSERT( EquivalentDatatypes( iFileType, dtypeId ), "File DataType clash for array dataset: " << iName ); AbcA::ArraySamplePtr ret; H5S_class_t dspaceClass = H5Sget_simple_extent_type( dspaceId ); if ( dspaceClass == H5S_SIMPLE ) { // Get the dimensions int rank = H5Sget_simple_extent_ndims( dspaceId ); ABCA_ASSERT( rank == 1, "H5Sget_simple_extent_ndims() must be 1." ); hsize_t hdim = 0; rank = H5Sget_simple_extent_dims( dspaceId, &hdim, NULL ); Dimensions dims; std::string dimName = iName + ".dims"; if ( H5Aexists( iParent, dimName.c_str() ) ) { ReadDimensions( iParent, dimName, dims ); } else { dims.setRank(1); dims[0] = hdim / iDataType.getExtent(); } ABCA_ASSERT( dims.numPoints() > 0, "Degenerate dims in Dataset read" ); // Create a buffer into which we shall read. ret = AbcA::AllocateArraySample( iDataType, dims ); assert( ret->getData() ); // And... read into it. herr_t status = H5Dread( dsetId, iNativeType, H5S_ALL, H5S_ALL, H5P_DEFAULT, const_cast<void*>( ret->getData() ) ); ABCA_ASSERT( status >= 0, "H5Dread() failed." ); } else if ( dspaceClass == H5S_NULL ) { Dimensions dims; std::string dimName = iName + ".dims"; if ( H5Aexists( iParent, dimName.c_str() ) ) { ReadDimensions( iParent, dimName, dims ); ABCA_ASSERT( dims.rank() > 0, "Degenerate rank in Dataset read" ); // Num points should be zero here. ABCA_ASSERT( dims.numPoints() == 0, "Expecting zero points in dimensions" ); } else { dims.setRank(1); dims[0] = 0; } ret = AbcA::AllocateArraySample( iDataType, dims ); } else { ABCA_THROW( "Unexpected scalar dataspace encountered." ); } // Store if there is a cache. if ( foundDigest && iCache ) { AbcA::ReadArraySampleID stored = iCache->store( key, ret ); if ( stored ) { return stored.getSample(); } } // Otherwise, just leave! ArraySamplePtr returned by AllocateArraySample // already has fancy-dan deleter built in. // I REALLY LOVE SMART PTRS. return ret; }