summaryrefslogtreecommitdiffstats
path: root/tools/lib/h5trav.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/h5trav.c')
-rw-r--r--tools/lib/h5trav.c461
1 files changed, 461 insertions, 0 deletions
diff --git a/tools/lib/h5trav.c b/tools/lib/h5trav.c
new file mode 100644
index 0000000..09c2033
--- /dev/null
+++ b/tools/lib/h5trav.c
@@ -0,0 +1,461 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+#include "h5trav.h"
+#include "H5private.h"
+
+
+
+/* functions for traversal */
+int traverse( hid_t loc_id,
+ const char *group_name,
+ trav_table_t *table,
+ trav_info_t *info,
+ int *idx );
+
+herr_t get_nobjects( hid_t loc_id,
+ const char *group_name );
+
+herr_t get_name_type( hid_t loc_id,
+ const char *group_name,
+ int idx,
+ char **name,
+ int *type );
+
+/*-------------------------------------------------------------------------
+ * Function: h5trav_getinfo
+ *
+ * Purpose: get an array of "trav_info_t" , containing the name and type of
+ * objects in the file
+ *
+ * Return: number of objects in file
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: November 6, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int h5trav_getinfo( hid_t file_id, trav_info_t *info )
+{
+
+ trav_table_t *table=NULL;
+ int nobjects=0;
+
+ /* init table */
+ trav_table_init( &table );
+
+ /* iterate starting on the root group */
+ if (( nobjects = traverse( file_id, "/", table, info, &nobjects )) < 0 )
+ return -1;
+
+ /* free table */
+ trav_table_free( table );
+
+ return nobjects;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: h5trav_getindex
+ *
+ * Purpose: get index of OBJ in list
+ *
+ * Return: index, -1 if not found
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: May 9, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int h5trav_getindex( const char *obj, int nobjs, trav_info_t *info )
+{
+ char *pdest;
+ int result;
+ int i;
+
+ for ( i = 0; i < nobjs; i++)
+ {
+ if ( strcmp(obj,info[i].name)==0 )
+ return i;
+
+ pdest = strstr( info[i].name, obj );
+ result = (int)(pdest - info[i].name);
+
+ /* found at position 1, meaning without '/' */
+ if( pdest != NULL && result==1 )
+ return i;
+ }
+ return -1;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: h5trav_freeinfo
+ *
+ * Purpose: free info memory
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void h5trav_freeinfo( trav_info_t *info, int nobjs )
+{
+ int i;
+ if ( info )
+ {
+ for ( i = 0; i < nobjs; i++)
+ {
+ if (info[i].name)
+ HDfree( info[i].name );
+ }
+ HDfree(info);
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: count_objects
+ *
+ * Purpose: operator function
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: October 10, 2002
+ *
+ * Comments:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static herr_t count_objects( hid_t loc_id, const char *name, void *op_data)
+{
+
+ H5G_stat_t statbuf;
+
+ if (H5Gget_objinfo( loc_id, name, 0, &statbuf) < 0 )
+ return 1;
+
+ (*(int *)op_data)++;
+
+ /* Define a default zero value for return. This will cause the iterator to continue */
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: get_nobjects
+ *
+ * Purpose: Counts the number of objects in the group GROUP_NAME
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: October 10, 2002
+ *
+ * Return:
+ * Success: The return value of the first operator that
+ * returns non-zero, or zero if all members were
+ * processed with no operator returning non-zero.
+ *
+ * Failure: Negative if something goes wrong within the
+ * library, or the negative value returned by one
+ * of the operators.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t get_nobjects( hid_t loc_id, const char *group_name )
+{
+
+ int nobjs = 0;
+
+ if ( H5Giterate( loc_id, group_name, NULL, count_objects, (void *)&nobjs ) < 0 )
+ return -1;
+
+ return nobjs;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: opget_info
+ *
+ * Purpose: operator function
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: October 10, 2002
+ *
+ * Comments:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static herr_t opget_info( hid_t loc_id, const char *name, void *op_data)
+{
+
+ H5G_stat_t statbuf;
+
+ if (H5Gget_objinfo( loc_id, name, 0, &statbuf) < 0 )
+ return -1;
+
+ ((trav_info_t *)op_data)->type = statbuf.type;
+ ((trav_info_t *)op_data)->name = (char *)HDstrdup(name);
+
+ /* Define 1 for return. This will cause the iterator to stop */
+ return 1;
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: get_name_type
+ *
+ * Purpose:
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: October 10, 2002
+ *
+ * Return:
+ * Success: The return value of the first operator that
+ * returns non-zero, or zero if all members were
+ * processed with no operator returning non-zero.
+ *
+ * Failure: Negative if something goes wrong within the
+ * library, or the negative value returned by one
+ * of the operators.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t get_name_type( hid_t loc_id, const char *group_name, int idx, char **name, int *type )
+{
+
+ trav_info_t info;
+
+ if (H5Giterate( loc_id, group_name, &idx, opget_info, (void *)&info) < 0 )
+ return -1;
+
+ *name = info.name;
+ *type = info.type;
+
+ return 0;
+}
+
+/*-------------------------------------------------------------------------
+ * Function: traverse
+ *
+ * Purpose: recursive function that searches HDF5 objects in LOC_ID
+ *
+ * Return: number of objects found in LOC_ID
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: November 4, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int traverse( hid_t loc_id,
+ const char *group_name,
+ trav_table_t *table,
+ trav_info_t *info,
+ int *idx )
+{
+
+ char *name=NULL;
+ int type;
+ int nobjs;
+ int i;
+ char *path=NULL;
+ H5G_stat_t statbuf;
+ int inserted_objs=0;
+ int j;
+
+ if (( nobjs = get_nobjects( loc_id, group_name )) < 0 )
+ return -1;
+
+ for ( i = 0; i < nobjs; i++)
+ {
+
+ if (get_name_type( loc_id, group_name, i, &name, &type ) < 0 )
+ return -1;
+
+ /* allocate path buffer */
+ path = (char*) HDmalloc(strlen(group_name) + strlen(name) + 2);
+
+ /* initialize path */
+ strcpy( path, group_name );
+ if ( strcmp(group_name,"/")!=0 )
+ strcat( path, "/" );
+ strcat( path, name );
+
+ /* disable error reporting */
+ H5E_BEGIN_TRY {
+
+ /* get info */
+ H5Gget_objinfo( loc_id, path, 1, &statbuf);
+ } H5E_END_TRY;
+
+ /* add to array */
+ if ( info )
+ {
+ info[*idx].name = (char *)HDstrdup(path);
+ info[*idx].type = type;
+ (*idx)++;
+ }
+
+
+ switch ( type )
+ {
+
+ /*-------------------------------------------------------------------------
+ * H5G_GROUP
+ *-------------------------------------------------------------------------
+ */
+
+ case H5G_GROUP:
+
+ /* increment */
+ inserted_objs++;
+
+ /* nlink is number of hard links to object */
+ if (statbuf.nlink > 0 && trav_table_search(statbuf.objno, table ) == -1)
+ {
+ /* add object to table */
+ trav_table_add(statbuf.objno, path, H5G_GROUP, table );
+
+ /* recurse with the absolute name */
+ inserted_objs += traverse( loc_id, path, table, info, idx );
+ }
+
+ /* search table
+ group with more than one link to it */
+ if (statbuf.nlink > 1)
+ {
+ if ((j = trav_table_search(statbuf.objno, table )) < 0 )
+ return -1;
+
+ if ( table->objs[j].displayed == 0 )
+ {
+ table->objs[j].displayed = 1;
+ }
+ else
+ {
+ printf("%s %s\n", "HARDLINK", table->objs[j].objname);
+ }
+
+ }
+
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5G_DATASET
+ *-------------------------------------------------------------------------
+ */
+
+ case H5G_DATASET:
+
+ /* increment */
+ inserted_objs++;
+
+ /* nlink is number of hard links to object */
+ if (statbuf.nlink > 0 && trav_table_search(statbuf.objno, table ) == -1)
+ {
+ /* add object to table */
+ trav_table_add(statbuf.objno, path, H5G_DATASET, table );
+ }
+
+ /* search table
+ dataset with more than one link to it */
+ if (statbuf.nlink > 1)
+ {
+ if ((j = trav_table_search(statbuf.objno, table )) < 0 )
+ return -1;
+
+ if ( table->objs[j].displayed == 0 )
+ {
+ table->objs[j].displayed = 1;
+ }
+ else
+ {
+ printf("%s %s\n", "HARDLINK", table->objs[j].objname);
+ }
+
+ }
+
+
+ break;
+
+ /*-------------------------------------------------------------------------
+ * H5G_TYPE
+ *-------------------------------------------------------------------------
+ */
+
+ case H5G_TYPE:
+
+ /* increment */
+ inserted_objs++;
+
+ /* nlink is number of hard links to object */
+ if (statbuf.nlink > 0 && trav_table_search(statbuf.objno, table ) == -1)
+ {
+ /* add object to table */
+ trav_table_add(statbuf.objno, path, H5G_TYPE, table );
+ }
+
+ break;
+
+
+ /*-------------------------------------------------------------------------
+ * H5G_LINK
+ *-------------------------------------------------------------------------
+ */
+
+ case H5G_LINK:
+
+ /* increment */
+ inserted_objs++;
+
+ break;
+
+
+ default:
+ break;
+
+ }
+
+ /*-------------------------------------------------------------------------
+ * end switch
+ *-------------------------------------------------------------------------
+ */
+
+ if ( name )
+ HDfree( name );
+
+ if ( path )
+ HDfree( path );
+
+ } /* i */
+
+ return inserted_objs;
+}
+