diff options
Diffstat (limited to 'tools/lib/h5trav.c')
-rw-r--r-- | tools/lib/h5trav.c | 461 |
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; +} + |