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; }
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; }