diff options
Diffstat (limited to 'tools/lib/h5tools_ref.c')
-rw-r--r-- | tools/lib/h5tools_ref.c | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/tools/lib/h5tools_ref.c b/tools/lib/h5tools_ref.c new file mode 100644 index 0000000..7dcccad --- /dev/null +++ b/tools/lib/h5tools_ref.c @@ -0,0 +1,306 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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 <stdio.h> +#include <stdlib.h> +#include "h5tools_ref.h" +#include "H5private.h" +#include "h5tools.h" +#include "h5tools_utils.h" + + +/* + * Table to look up a path name for an object + * reference. + * + * This table stores mappings of reference -> path + * for all objects in the file that may be the target of + * an object reference. + * + * The 'path' is an absolute path by which the object + * can be accessed. When an object has > 1 such path, + * only one will be used in the table, with no particular + * method of selecting which one. + */ + + +extern hid_t thefile; +extern char *prefix; +extern char *progname; +extern int d_status; + + + +ref_path_table_entry_t *ref_path_table = NULL; /* the table */ + +/*------------------------------------------------------------------------- + * Function: ref_path_table_lookup + * + * Purpose: Looks up a table entry given a path name. + * Used during construction of the table. + * + * Return: The table entre (pte) or NULL if not in the + * table. + * + * Programmer: REMcG + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +ref_path_table_entry_t * +ref_path_table_lookup(const char *thepath) +{ + H5G_stat_t sb; + ref_path_table_entry_t *pte = ref_path_table; + + if(H5Gget_objinfo(thefile, thepath, TRUE, &sb)<0) { + /* fatal error ? */ + return NULL; + } + + while(pte!=NULL) { + if (sb.objno==pte->statbuf.objno) + return pte; + pte = pte->next; + } + + return NULL; +} + +/*------------------------------------------------------------------------- + * Function: ref_path_table_put + * + * Purpose: Enter the 'obj' with 'path' in the table if + * not already there. + * Create an object reference, pte, and store them + * in the table. + * + * Return: The object reference for the object. + * + * Programmer: REMcG + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +ref_path_table_entry_t * +ref_path_table_put(hid_t obj, const char *path) +{ + ref_path_table_entry_t *pte; + + /* look up 'obj'. If already in table, return */ + pte = ref_path_table_lookup(path); + if (pte != NULL) + return pte; + + /* if not found, then make new entry */ + + pte = (ref_path_table_entry_t *) malloc(sizeof(ref_path_table_entry_t)); + if (pte == NULL) { + /* fatal error? */ + return NULL; + } + + pte->obj = obj; + + pte->apath = HDstrdup(path); + + if(H5Gget_objinfo(thefile, path, TRUE, &pte->statbuf)<0) { + /* fatal error? */ + free(pte); + return NULL; + } + + pte->next = ref_path_table; + ref_path_table = pte; + + return pte; +} + +/* + * counter used to disambiguate multiple instances of same object. + */ +int xid = 1; + +int get_next_xid() { + return xid++; +} + +/* + * This counter is used to create fake object ID's + * The idea is to set it to the largest possible offest, which + * minimizes the chance of collision with a real object id. + * + */ +haddr_t fake_xid = HADDR_MAX; +haddr_t +get_fake_xid () { + return (fake_xid--); +} + +/* + * for an object that does not have an object id (e.g., soft link), + * create a table entry with a fake object id as the key. + */ + +ref_path_table_entry_t * +ref_path_table_gen_fake(const char *path) +{ + ref_path_table_entry_t *pte; + + /* look up 'obj'. If already in table, return */ + pte = ref_path_table_lookup(path); + if (pte != NULL) { + return pte; + } + + /* if not found, then make new entry */ + + pte = (ref_path_table_entry_t *) malloc(sizeof(ref_path_table_entry_t)); + if (pte == NULL) { + /* fatal error? */ + return NULL; + } + + pte->obj = (hid_t)-1; + + memset(&pte->statbuf,0,sizeof(H5G_stat_t)); + pte->statbuf.objno = get_fake_xid(); + + pte->apath = HDstrdup(path); + + pte->next = ref_path_table; + ref_path_table = pte; + + return pte; +} + +/*------------------------------------------------------------------------- + * Function: lookup_ref_path + * + * Purpose: Lookup the path to the object with refernce 'ref'. + * + * Return: Return a path to the object, or NULL if not found. + * + * Programmer: REMcG + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +char * +lookup_ref_path(hobj_ref_t ref) +{ + ref_path_table_entry_t *pte = ref_path_table; + + while(pte!=NULL) { + if (ref==pte->statbuf.objno) + return pte->apath; + pte = pte->next; + } + return NULL; +} + +/*------------------------------------------------------------------------- + * Function: fill_ref_path_table + * + * Purpose: Called by interator to create references for + * all objects and enter them in the table. + * + * Return: Error status. + * + * Programmer: REMcG + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +fill_ref_path_table(hid_t group, const char *name, void UNUSED * op_data) +{ + hid_t obj; + char *tmp; + H5G_stat_t statbuf; + ref_path_table_entry_t *pte; + char *thepath; + + H5Gget_objinfo(group, name, FALSE, &statbuf); + tmp = (char *) malloc(strlen(prefix) + strlen(name) + 2); + + if (tmp == NULL) + return FAIL; + + thepath = (char *) malloc(strlen(prefix) + strlen(name) + 2); + + if (thepath == NULL) { + free(tmp); + return FAIL; + } + + strcpy(tmp, prefix); + + strcpy(thepath, prefix); + strcat(thepath, "/"); + strcat(thepath, name); + + switch (statbuf.type) { + case H5G_DATASET: + if ((obj = H5Dopen(group, name)) >= 0) { + pte = ref_path_table_lookup(thepath); + if (pte == NULL) { + ref_path_table_put(obj, thepath); + } + H5Dclose(obj); + } else { + error_msg(progname, "unable to get dataset \"%s\"\n", name); + d_status = EXIT_FAILURE; + } + break; + case H5G_GROUP: + if ((obj = H5Gopen(group, name)) >= 0) { + strcat(strcat(prefix, "/"), name); + pte = ref_path_table_lookup(thepath); + if (pte == NULL) { + ref_path_table_put(obj, thepath); + H5Giterate(obj, ".", NULL, fill_ref_path_table, NULL); + strcpy(prefix, tmp); + } + H5Gclose(obj); + } else { + error_msg(progname, "unable to dump group \"%s\"\n", name); + d_status = EXIT_FAILURE; + } + break; + case H5G_TYPE: + if ((obj = H5Topen(group, name)) >= 0) { + pte = ref_path_table_lookup(thepath); + if (pte == NULL) { + ref_path_table_put(obj, thepath); + } + H5Tclose(obj); + } else { + error_msg(progname, "unable to get dataset \"%s\"\n", name); + d_status = EXIT_FAILURE; + } + break; + default: + break; + } + + free(tmp); + free(thepath); + return 0; +} + |