summaryrefslogtreecommitdiffstats
path: root/tools/lib
diff options
context:
space:
mode:
authorcvs2svn <no_author@cvs2svn>2004-03-10 23:00:36 (GMT)
committercvs2svn <no_author@cvs2svn>2004-03-10 23:00:36 (GMT)
commitcdcf0e1e12259c617626518ad4db84285e27bb99 (patch)
tree2df02e2fe964fddb7944d06f8b5d760c5bf78b08 /tools/lib
parent4644afd4afa287a1ffce555cb18c486a1536609f (diff)
downloadhdf5-cdcf0e1e12259c617626518ad4db84285e27bb99.zip
hdf5-cdcf0e1e12259c617626518ad4db84285e27bb99.tar.gz
hdf5-cdcf0e1e12259c617626518ad4db84285e27bb99.tar.bz2
[svn-r8248] This commit was manufactured by cvs2svn to create branch 'hdf5_1_6'.
Diffstat (limited to 'tools/lib')
-rw-r--r--tools/lib/h5trav.c651
1 files changed, 651 insertions, 0 deletions
diff --git a/tools/lib/h5trav.c b/tools/lib/h5trav.c
new file mode 100644
index 0000000..9c1db43
--- /dev/null
+++ b/tools/lib/h5trav.c
@@ -0,0 +1,651 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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_nnames( 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,
+ H5G_obj_t *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 object names 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 nnames=0;
+
+ /* init table */
+ trav_table_init( &table );
+
+ /* iterate starting on the root group */
+ if (( nnames = traverse( file_id, "/", table, info, &nnames )) < 0 )
+ return -1;
+
+ /* free table */
+ trav_table_free( table );
+
+ return nnames;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: h5trav_gettable
+ *
+ * Purpose: get the trav_table_t struct
+ *
+ * Return: 0, -1 on error
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: December 17, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int h5trav_gettable(hid_t fid, trav_table_t *travt)
+{
+ int nnames=0;
+
+ /* iterate starting on the root group */
+ if (( nnames = traverse(fid,"/",travt,NULL,&nnames))<0)
+ return -1;
+
+ return 0;
+
+}
+
+
+/*-------------------------------------------------------------------------
+ * 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_names
+ *
+ * Purpose: operator function
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: October 10, 2002
+ *
+ * Comments:
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static herr_t count_names( 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_nnames
+ *
+ * Purpose: Counts the number of names 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_nnames( hid_t loc_id, const char *group_name )
+{
+
+ int nobjs = 0;
+
+ if ( H5Giterate( loc_id, group_name, NULL, count_names, (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,
+ H5G_obj_t *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;
+ H5G_obj_t type;
+ int n_names;
+ char *path=NULL;
+ H5G_stat_t statbuf;
+ int inserted_objs=0;
+ int i, j;
+
+
+ /* get the number of names */
+ if (( n_names = get_nnames( loc_id, group_name )) < 0 )
+ return -1;
+
+ for ( i = 0; i < n_names; 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;
+ trav_table_addlink(table,j,path);
+ }
+ else
+ {
+#if defined (H5_TRAV_DEBUG)
+ printf("<%s> HARDLINK\n", path);
+#endif
+ trav_table_addlink(table,j,path);
+ }
+
+ }
+
+ 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;
+ trav_table_addlink(table,j,path);
+ }
+ else
+ {
+#if defined (H5_TRAV_DEBUG)
+ printf("<%s> HARDLINK\n", path);
+#endif
+ trav_table_addlink(table,j,path);
+ } /* displayed==1 */
+ } /* nlink>1 */
+
+
+ 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++;
+
+ /* add object to table */
+ trav_table_add(statbuf.objno, path, H5G_LINK, table );
+
+ break;
+
+
+ default:
+ break;
+
+ }
+
+ /*-------------------------------------------------------------------------
+ * end switch
+ *-------------------------------------------------------------------------
+ */
+
+ if ( name )
+ HDfree( name );
+
+ if ( path )
+ HDfree( path );
+
+ } /* i */
+
+ return inserted_objs;
+}
+
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: h5trav_printinfo
+ *
+ * Purpose: print list of names in file
+ *
+ * Return: void
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: May 9, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+void h5trav_printinfo(int nobjs, trav_info_t *travi)
+{
+ int i;
+ for ( i = 0; i < nobjs; i++)
+ {
+ switch ( travi[i].type )
+ {
+ case H5G_GROUP:
+ printf(" %-10s %s\n", "group", travi[i].name );
+ break;
+ case H5G_DATASET:
+ printf(" %-10s %s\n", "dataset", travi[i].name );
+ break;
+ case H5G_TYPE:
+ printf(" %-10s %s\n", "datatype", travi[i].name );
+ break;
+ case H5G_LINK:
+ printf(" %-10s %s\n", "link", travi[i].name );
+ break;
+ default:
+ printf(" %-10s %s\n", "User defined object", travi[i].name );
+ break;
+ }
+ }
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: h5trav_printtable
+ *
+ * Purpose: print list of objects in file
+ *
+ * Return: void
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: May 9, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+void h5trav_printtable(trav_table_t *table)
+{
+ int i, j;
+
+ for ( i = 0; i < table->nobjs; i++)
+ {
+ switch ( table->objs[i].type )
+ {
+ case H5G_GROUP:
+ printf(" %-10s %s\n", "group", table->objs[i].name );
+ break;
+ case H5G_DATASET:
+ printf(" %-10s %s\n", "dataset", table->objs[i].name );
+ break;
+ case H5G_TYPE:
+ printf(" %-10s %s\n", "datatype", table->objs[i].name );
+ break;
+ case H5G_LINK:
+ printf(" %-10s %s\n", "link", table->objs[i].name );
+ break;
+ default:
+ printf(" %-10s %s\n", "User defined object", table->objs[i].name );
+ break;
+ }
+
+ if (table->objs[i].nlinks)
+ {
+ for ( j=0; j<table->objs[i].nlinks; j++)
+ {
+ printf(" %-10s %s\n", " hardlink", table->objs[i].links[j].new_name );
+ }
+ }
+
+ }
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: h5trav_getindext
+ *
+ * Purpose: get index of NAME in list
+ *
+ * Return: index, -1 if not found
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: December 18, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int h5trav_getindext(const char *name, trav_table_t *table)
+{
+ char *pdest;
+ int result;
+ int i, j;
+
+ for ( i = 0; i < table->nobjs; i++)
+ {
+ if ( strcmp(name,table->objs[i].name)==0 )
+ return i;
+
+ pdest = strstr( table->objs[i].name, name );
+ result = (int)(pdest - table->objs[i].name);
+
+ /* found at position 1, meaning without '/' */
+ if( pdest != NULL && result==1 && strlen(table->objs[i].name)-1==strlen(name))
+ return i;
+
+ /* search also in the list of links */
+ if (table->objs[i].nlinks)
+ {
+ for ( j=0; j<table->objs[i].nlinks; j++)
+ {
+ if ( strcmp(name,table->objs[i].links[j].new_name)==0 )
+ return i;
+
+ pdest = strstr( table->objs[i].links[j].new_name, name );
+ result = (int)(pdest - table->objs[i].links[j].new_name);
+
+ /* found at position 1, meaning without '/' */
+ if( pdest != NULL && result==1 )
+ return i;
+
+ }
+ }
+
+ }
+ return -1;
+}
+