Пример #1
0
int
main (void)
{
    hid_t           file;           /* Handle */
    herr_t          status;
    H5G_stat_t      statbuf;
    struct opdata   od;

    /*
     * Open file and initialize the operator data structure.
     */
    file = H5Fopen (FILE, H5F_ACC_RDONLY, H5P_DEFAULT);
    status = H5Gget_objinfo (file, "/", 0, &statbuf);
    od.recurs = 0;
    od.prev = NULL;
    od.groupno[0] = statbuf.objno[0];
    od.groupno[1] = statbuf.objno[1];

    /*
     * Print the root group and formatting, begin iteration.
     */
    printf ("/ {\n");
    status = H5Giterate (file, "/", NULL, op_func, (void *) &od);
    printf ("}\n");

    /*
     * Close and release resources.
     */
    status = H5Fclose (file);

    return 0;
}
Пример #2
0
static int
scan_for_max_id( FileHandle* file_ptr, mhdf_Status* status )
{
  hid_t group_id;
  herr_t rval;
  
    /* Check for new format, with max_id as attrib of root group */
#if defined(H5Gopen_vers) && H5Gopen_vers > 1  
  group_id = H5Gopen2( file_ptr->hdf_handle, ROOT_GROUP, H5P_DEFAULT );
#else
  group_id = H5Gopen( file_ptr->hdf_handle, ROOT_GROUP );
#endif
  if (group_id < 0)
  {
    mhdf_setFail( status, "Internal error - invalid file.");
    return 0;
  }
  if (mhdf_read_scalar_attrib( group_id, MAX_ID_ATTRIB,
                               H5T_NATIVE_ULONG, &file_ptr->max_id,
                               status ))
  {
    H5Gclose( group_id );
    return 1;
  }
  
    /* Didn't find it, scan the elements group */
  rval = H5Giterate( group_id, ELEMENT_GROUP_NAME, 0, &max_id_iter, &file_ptr->max_id );
  if (rval)
  {
    H5Gclose( group_id );
    mhdf_setFail( status, "Internal error -- invalid file." );
    return 0;
  }
  
    /* Check node table too */
  rval = get_max_id( group_id, NODE_GROUP_NAME, "coordinates", (unsigned long*)(&file_ptr->max_id) );
  if (rval)
  {
    H5Gclose( group_id );
    mhdf_setFail( status, "Internal error -- invalid file." );
    return 0;
  }
  
    /* Check set table, if it exists */
  rval = mhdf_is_in_group( group_id, SET_GROUP_NAME, status );
  if (rval < 1)
  {
    H5Gclose( group_id );
    return !rval;
  }
  rval = get_max_id( group_id, SET_GROUP_NAME, SET_META_NAME, (unsigned long*)(&file_ptr->max_id) );
  H5Gclose( group_id );
  if (rval)
  {
    mhdf_setFail( status, "Internal error -- invalid file." );
    return 0;
  }

  return 1;
}    
Пример #3
0
/************************************************************

  Operator function.  This function prints the name and type
  of the object passed to it.  If the object is a group, it
  is first checked against other groups in its path using
  the group_check function, then if it is not a duplicate,
  H5Giterate is called for that group.  This guarantees that
  the program will not enter infinite recursion due to a
  circular path in the file.

 ************************************************************/
herr_t op_func (hid_t loc_id, const char *name, void *operator_data)
{
    herr_t          status, return_val = 0;
    H5G_stat_t      statbuf;
    struct opdata   *od = (struct opdata *) operator_data;
                                /* Type conversion */
    unsigned        spaces = 2*(od->recurs+1);
                                /* Number of whitespaces to prepend
                                   to output */

    /*
     * Get type of the object and display its name and type.
     * The name of the object is passed to this function by
     * the Library.
     */
    status = H5Gget_objinfo (loc_id, name, 0, &statbuf);
    printf ("%*s", spaces, "");     /* Format output */
    switch (statbuf.type) {
        case H5G_GROUP:
            printf ("Group: %s {\n", name);

            /*
             * Check group objno against linked list of operator
             * data structures.  Only necessary if there is more
             * than 1 link to the group.
             */
            if ( (statbuf.nlink > 1) && group_check (od, statbuf.objno) ) {
                printf ("%*s  Warning: Loop detected!\n", spaces, "");
            }
            else {

                /*
                 * Initialize new operator data structure and
                 * begin recursive iteration on the discovered
                 * group.  The new opdata structure is given a
                 * pointer to the current one.
                 */
                struct opdata nextod;
                nextod.recurs = od->recurs + 1;
                nextod.prev = od;
                nextod.groupno[0] = statbuf.objno[0];
                nextod.groupno[1] = statbuf.objno[1];
                return_val = H5Giterate (loc_id, name, NULL, op_func,
                            (void *) &nextod);
            }
            printf ("%*s}\n", spaces, "");
            break;
        case H5G_DATASET:
            printf ("Dataset: %s\n", name);
            break;
        case H5G_TYPE:
            printf ("Datatype: %s\n", name);
            break;
        default:
            printf ( "Unknown: %s\n", name);
    }

    return return_val;
}
Пример #4
0
//--------------------------------------------------------------------------
// Function:	CommonFG::iterateElems
///\brief	Iterates a user's function over the entries of a group.
///\param	name    - IN    : Name of group to iterate over
///\param	idx     - IN/OUT: Starting (IN) and ending (OUT) entry indices
///\param	op      - IN    : User's function to operate on each entry
///\param	op_data - IN/OUT: Data associated with the operation
///\return	The return value of the first operator that returns non-zero,
///		or zero if all members were processed with no operator
///		returning non-zero.
///\exception	H5::FileIException or H5::GroupIException
// Programmer	Binh-Minh Ribler - 2000
//--------------------------------------------------------------------------
int CommonFG::iterateElems( const char* name, int *idx, H5G_iterate_t op , void* op_data )
{
   int ret_value = H5Giterate( getLocId(), name, idx, op, op_data );
   if( ret_value < 0 )
   {
      throwException("iterateElems", "H5Giterate failed");
   }
   return( ret_value );
}
Пример #5
0
/*
 * - Nom de la fonction : _MEDobjetIdentifier
 * - Description : retrouve le nom de l'objet de rang "indice" 
 *                 se trouvant dans le datagroup "chemin"
 * - Parametres :
 *     - fid     (IN)     : l'ID du fichier ou se trouve le datagroup
 *     - chemin  (IN)     : chemin d'acces au datagroup
 *     - indice  (IN)     : indice de l'objet du datagroup dont on veut
 *                          le nom
 *     - nom     (OUT)    : le nom 
 * - Resultat : 0 en cas de succes, -1 sinon
 */ 
med_err
_MEDobjetIdentifier(med_idt fid,char *chemin,int indice,void *nom)
{
  int idx;

  if ((idx = H5Giterate(fid,chemin,&indice,_MEDindiceInfo,
			nom)) < 0)
    return -1;

  return 0;
}
Пример #6
0
CPLErr HDF5Dataset::ReadGlobalAttributes(int bSUBDATASET)
{
    HDF5GroupObjects *poRootGroup =
        static_cast<HDF5GroupObjects *>(CPLCalloc(sizeof(HDF5GroupObjects), 1));

    poH5RootGroup = poRootGroup;
    poRootGroup->pszName = CPLStrdup("/");
    poRootGroup->nType = H5G_GROUP;
    poRootGroup->poHparent = nullptr;
    poRootGroup->pszPath = nullptr;
    poRootGroup->pszUnderscorePath = nullptr;

    if( hHDF5 < 0 )
    {
        CPLError(CE_Failure, CPLE_AppDefined, "hHDF5 < 0!");
        return CE_None;
    }

    H5G_stat_t oStatbuf = {{0, 0}, {0, 0}, 0, H5G_UNKNOWN, 0, 0, {0, 0, 0, 0}};

    if( H5Gget_objinfo(hHDF5, "/", FALSE, &oStatbuf) < 0 )
        return CE_Failure;
    poRootGroup->objno[0] = oStatbuf.objno[0];
    poRootGroup->objno[1] = oStatbuf.objno[1];

    if( hGroupID > 0 )
        H5Gclose(hGroupID);
    hGroupID = H5Gopen(hHDF5, "/");
    if( hGroupID < 0 )
    {
        CPLError(CE_Failure, CPLE_AppDefined, "hGroupId <0!");
        return CE_None;
    }

    poRootGroup->nbAttrs = H5Aget_num_attrs(hGroupID);

    H5Gget_num_objs(hGroupID, &(poRootGroup->nbObjs));

    if( poRootGroup->nbObjs > 0 )
    {
        poRootGroup->poHchild = static_cast<HDF5GroupObjects *>(
            CPLCalloc(static_cast<size_t>(poRootGroup->nbObjs),
                      sizeof(HDF5GroupObjects)));
        H5Giterate(hGroupID, "/", nullptr, HDF5CreateGroupObjs, poRootGroup);
    }
    else
    {
        poRootGroup->poHchild = nullptr;
    }

    HDF5ListGroupObjects(poRootGroup, bSUBDATASET);
    return CE_None;
}
Пример #7
0
CPLErr HDF5Dataset::ReadGlobalAttributes(int bSUBDATASET)
{

    HDF5GroupObjects *poRootGroup;

    poRootGroup = (HDF5GroupObjects*) CPLCalloc(sizeof(HDF5GroupObjects), 1);

    poH5RootGroup=poRootGroup;
    poRootGroup->pszName   = CPLStrdup( "/" );
    poRootGroup->nType     = H5G_GROUP;
    poRootGroup->poHparent = NULL;
    poRootGroup->pszPath = NULL;
    poRootGroup->pszUnderscorePath = NULL;

    if( hHDF5 < 0 )  {
        printf( "hHDF5 <0!!\n" );
        return CE_None;
    }

    H5G_stat_t  oStatbuf;
    if( H5Gget_objinfo( hHDF5, "/", FALSE, &oStatbuf ) < 0  )
        return CE_Failure;
    poRootGroup->objno[0] = oStatbuf.objno[0];
    poRootGroup->objno[1] = oStatbuf.objno[1];

    if( hGroupID > 0 )
        H5Gclose( hGroupID );
    hGroupID = H5Gopen( hHDF5, "/" );
    if( hGroupID < 0 ){
        printf( "hGroupID <0!!\n" );
        return CE_None;
    }

    poRootGroup->nbAttrs = H5Aget_num_attrs( hGroupID );

    H5Gget_num_objs( hGroupID, &( poRootGroup->nbObjs ) );

    if( poRootGroup->nbObjs > 0 ) {
        poRootGroup->poHchild = ( HDF5GroupObjects * )
            CPLCalloc( poRootGroup->nbObjs,
            sizeof( HDF5GroupObjects ) );
        H5Giterate( hGroupID, "/", NULL,
               HDF5CreateGroupObjs, (void *)poRootGroup );
    }
    else poRootGroup->poHchild = NULL;

    HDF5ListGroupObjects( poRootGroup, bSUBDATASET );
    return CE_None;
}
Пример #8
0
static int find_objs(hid_t group, const char *name, void *op_data)
{
  hid_t obj;
  H5G_stat_t statbuf;
  unsigned int idx = 0;
  int status;
  h5item *parent = (h5item *)op_data;
  h5item *item = (h5item *)malloc(sizeof(h5item));
  h5item *itm;
  item->item_type = 0;
  item->name=strcpy(malloc(strlen(name)+1),name);
  item->child = 0;
  item->brother = 0;
  item->parent = parent;
  item->obj = 0;
  item->attribute = 0;
  if (parent->child == NULL)
  {
    parent->child = item;
  }
  else
  {
    for (itm = parent->child; itm->brother; itm = itm->brother);
    itm->brother = item;
  }
  if (parent->child == item)
/*     H5Aiterate(group,&idx,find_attr,(void *)item); */
    H5Aiterate(group,NULL,find_attr,(void *)item);
  //    H5Aiterate(group,&idx,find_attr,(void *)0);
  H5Gget_objinfo(group, name, 1, &statbuf);
  item->item_type = statbuf.type;
  switch (statbuf.type) {
  case H5G_GROUP:
    if ((obj = H5Gopen(group, name)) >= 0) {
      H5Giterate(obj, ".", NULL, find_objs, (void *)item);
      H5Gclose (obj);
    }
    break;
  case H5G_DATASET:
    if ((obj = H5Dopen (group, name)) >= 0) {
      item->obj = obj;
/*       H5Aiterate(obj,&idx,find_attr,(void *)item); */
      H5Aiterate(obj,&idx,find_attr,(void *)item);
    }
    break;
  }
  return 0;
}
Пример #9
0
void AbstractHdf5Converter<ELEMENT_DIM,SPACE_DIM>::GenerateListOfDatasets(const FileFinder& rH5Folder,
                                                                          const std::string& rFileName)
{
    /*
     * Open file.
     */
    std::string file_name = rH5Folder.GetAbsolutePath() + rFileName + ".h5";
    hid_t file = H5Fopen(file_name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);

    /*
     * Begin HDF5 iteration, calls a method that populates mDatasetNames.
     */
#if H5_VERS_MAJOR >= 1 && H5_VERS_MINOR >=8
    //std::cout << "HDF5 1.8.x or above detected.\n";
    H5Literate(file, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, op_func, &mDatasetNames);
#else
    //std::cout << "HDF5 1.6.x  detected.\n";
    H5Giterate(file, "/", NULL, op_func, &mDatasetNames);
#endif

    H5Fclose(file);

    // Remove datasets that end in "_Unlimited", as these are paired up with other ones!
    std::string ending = "_Unlimited";

    // Strip off the independent variables from the list
    std::vector<std::string>::iterator iter;
    for (iter = mDatasetNames.begin(); iter != mDatasetNames.end(); )
    {
        // If the dataset name is "Time" OR ...
        // it is longer than the ending we are looking for ("_Unlimited") ...
        // ... AND it ends with the string we are looking for,
        // then erase it.
        if ( (*(iter) == "Time") ||
             ( ( iter->length() > ending.length() ) &&
               ( 0 == iter->compare(iter->length() - ending.length(), ending.length(), ending) ) ) )
        {
            iter = mDatasetNames.erase(iter);
        }
        else
        {
            ++iter;
        }
    }
}
Пример #10
0
int luaC_h5_get_nsets(lua_State *L)
{
  const char *gname = luaL_checkstring(L, 1);

  if (PresentFile < 0) {
    luaL_error(L, "no open file");
  }

  Lua = L;
  lua_pushnumber(L, 0);

  PresentGroup = H5Gopen(PresentFile, gname, H5P_DEFAULT);
  H5Giterate(PresentGroup, ".", NULL, group_nelem, NULL);
  H5Gclose(PresentGroup);

  Lua = NULL;
  return 1;
}
Пример #11
0
int luaC_h5_read_numeric_table(lua_State *L)
{
  const char *gname = luaL_checkstring(L, 1);

  if (PresentFile < 0) {
    luaL_error(L, "no open file");
  }

  Lua = L;
  lua_newtable(L);

  PresentGroup = H5Gopen(PresentFile, gname, H5P_DEFAULT);
  H5Giterate(PresentGroup, ".", NULL, group_to_lua_table, NULL);
  H5Gclose(PresentGroup);

  Lua = NULL;
  return 1;
}
Пример #12
0
int hdf5open(char *fname)
{
    hid_t               fid, gid;
    void               *edata;
    hid_t               (*func)(void*);
    int                 i;
    int status;
    h5item *itm; 

    /* Disable error reporting */
    /*
    H5Eget_auto(&func, &edata);
    H5Eset_auto(NULL, NULL);
    */
    fid = H5Fopen(fname, 0, H5P_DEFAULT);

    if (fid < 0) {
        fprintf(stderr,"hdf5open, unable to open file \"%s\"\n", fname);
        return(-1);
    }
    if (current)
      hdf5close();
    current = (h5item *)malloc(sizeof(h5item));
    current->name=strcpy(malloc(1),"");
    current->item_type = -2;
    current->obj = fid;
    current->child = 0;
    current->brother = 0;
    current->parent = 0;
    current->attribute = 0;
    H5Giterate(fid, "/", NULL, find_objs, (void *)current);
    /*
    ListItem(h5files);
    */
    return fid;
}
Пример #13
0
/***************************  xxxxxx  �������xxxxx **********************************:*/
int _IsAttrExist(hid_t hFileID,char *strAttrName)
{
	hid_t status=0;
    	status =H5Giterate(hFileID, "/", NULL, _CheckAttrFC, strAttrName);
	return status;
}
Пример #14
0
/***************************  xxxxxx  �������xxxxx **********************************:*/
int _IsObjExist(hid_t hFileID,char *strSDSName)
{
	hid_t status=0;
    	status =H5Giterate(hFileID, "/", NULL, _CheckFC, strSDSName);
	return status;
}
Пример #15
0
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;
}
Пример #16
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;
}