/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /*------------------------------------------------------------------------- * * Created: H5Gloc.c * Sep 13 2005 * Quincey Koziol * * Purpose: Functions for working with group "locations" * *------------------------------------------------------------------------- */ #define H5G_PACKAGE /*suppress error about including H5Gpkg */ /* Packages needed by this file... */ #include "H5private.h" /* Generic Functions */ #include "H5Aprivate.h" /* Attributes */ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ /* Private typedefs */ /* User data for looking up an object in a group */ typedef struct { H5G_loc_t *loc; /* Group location to set */ } H5G_loc_ud1_t; /* Private macros */ /* Local variables */ /* PRIVATE PROTOTYPES */ static herr_t H5G_loc_find_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata); /*------------------------------------------------------------------------- * Function: H5G_loc * * Purpose: Given an object ID return a location for the object. * * Return: Success: Group pointer. * Failure: NULL * * Programmer: Quincey Koziol * Tuesday, September 13, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_loc(hid_t loc_id, H5G_loc_t *loc) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_loc, FAIL) switch(H5I_get_type(loc_id)) { case H5I_FILE: { H5F_t *f; if(NULL == (f = H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file ID") if(NULL == (loc->oloc = H5G_oloc(H5G_rootof(f)))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group") if(NULL == (loc->path = H5G_nameof(H5G_rootof(f)))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group") /* Patch up root group's object location to reflect this file */ /* (Since the root group info is only stored once for files which * share an underlying low-level file) */ /* (but only for non-mounted files) */ if(!H5F_is_mount(f)) loc->oloc->file = f; } /* end case */ break; case H5I_GENPROP_CLS: case H5I_GENPROP_LST: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of property list") case H5I_ERROR_CLASS: case H5I_ERROR_MSG: case H5I_ERROR_STACK: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of error class, message or stack") case H5I_GROUP: { H5G_t *group; if(NULL == (group = H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid group ID") if(NULL == (loc->oloc = H5G_oloc(group))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of group") if(NULL == (loc->path = H5G_nameof(group))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of group") } /* end case */ break; case H5I_DATATYPE: { H5T_t *dt; if(NULL == (dt = H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid type ID") if(NULL == (loc->oloc = H5T_oloc(dt))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of datatype") if(NULL == (loc->path = H5T_nameof(dt))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of datatype") } /* end case */ break; case H5I_DATASPACE: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of dataspace") case H5I_DATASET: { H5D_t *dset; if(NULL == (dset = H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid data ID") if(NULL == (loc->oloc = H5D_oloc(dset))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of dataset") if(NULL == (loc->path = H5D_nameof(dset))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of dataset") } /* end case */ break; case H5I_ATTR: { H5A_t *attr; if(NULL == (attr = H5I_object(loc_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid attribute ID") if(NULL == (loc->oloc = H5A_oloc(attr))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of attribute") if(NULL == (loc->path = H5A_nameof(attr))) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of attribute") } /* end case */ break; case H5I_REFERENCE: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of reference") default: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object ID") } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc() */ /*------------------------------------------------------------------------- * Function: H5G_loc_copy * * Purpose: Copy over information for a location * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, September 13, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_loc_copy(H5G_loc_t *dst, H5G_loc_t *src, H5_copy_depth_t depth) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_loc_copy, FAIL) /* Check args. */ HDassert(dst); HDassert(src); /* Copy components of the location */ if(H5O_loc_copy(dst->oloc, src->oloc, depth) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") if(H5G_name_copy(dst->path, src->path, depth) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to copy path") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_copy() */ /*------------------------------------------------------------------------- * Function: H5G_loc_reset * * Purpose: Reset information for a location * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, September 13, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_loc_reset(H5G_loc_t *loc) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_loc_reset, FAIL) /* Check args. */ HDassert(loc); /* Reset components of the location */ if(H5O_loc_reset(loc->oloc) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to reset entry") if(H5G_name_reset(loc->path) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to reset path") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_reset() */ /*------------------------------------------------------------------------- * Function: H5G_loc_free * * Purpose: Free information for a location * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, September 13, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_loc_free(H5G_loc_t *loc) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_loc_free, FAIL) /* Check args. */ HDassert(loc); /* Reset components of the location */ #ifdef NOT_YET if(H5G_ent_free(loc->ent) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to free entry") #endif /* NOT_YET */ if(H5G_name_free(loc->path) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to free path") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_free() */ /*------------------------------------------------------------------------- * Function: H5G_loc_find_cb * * Purpose: Callback for retrieving object location for an object in a group * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Monday, October 17, 2005 * *------------------------------------------------------------------------- */ static herr_t H5G_loc_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/) { H5G_loc_ud1_t *udata = (H5G_loc_ud1_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_loc_find_cb) /* Check if the name in this group resolved to a valid link */ if(obj_loc == NULL) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") /* Take ownership of the object's group location */ /* (Group traversal callbacks are responsible for either taking ownership * of the group location for the object, or freeing it. - QAK) */ H5G_loc_copy(udata->loc, obj_loc, H5_COPY_SHALLOW); done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_find_cb() */ /*------------------------------------------------------------------------- * Function: H5G_loc_find * * Purpose: Find a symbol from a location * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, September 13, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_loc_find(H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc/*out*/, hid_t dxpl_id) { H5G_loc_ud1_t udata; /* User data for traversal callback */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_loc_find, FAIL) /* Check args. */ HDassert(loc); HDassert(name && *name); HDassert(obj_loc); /* Set up user data for locating object */ udata.loc = obj_loc; /* Traverse group hierarchy to locate object */ if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_find_cb, &udata, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_find() */ /*------------------------------------------------------------------------- * Function: H5G_loc_insert * * Purpose: Insert an object at a location * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Tuesday, September 13, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_loc_insert(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc, hbool_t inc_link, hid_t dxpl_id) { H5O_link_t lnk; /* Link for object to insert */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_loc_insert, FAIL) /* Check args. */ HDassert(grp_loc); HDassert(name && *name); HDassert(obj_loc); /* "Translate" object location into link object */ lnk.type = H5G_LINK_HARD; #ifdef H5_HAVE_GETTIMEOFDAY { struct timeval now_tv; HDgettimeofday(&now_tv, NULL); lnk.ctime = now_tv.tv_sec; } #else /* H5_HAVE_GETTIMEOFDAY */ lnk.ctime = HDtime(NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ lnk.cset = H5T_CSET_ASCII; /* XXX: Allow user to set this */ /* Casting away const OK -QAK */ lnk.name = (char *)name; lnk.u.hard.addr = obj_loc->oloc->addr; /* Insert new group into current group's symbol table */ if(H5G_obj_insert(grp_loc->oloc, name, &lnk, inc_link, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert object") /* Set the name of the object location */ if(H5G_name_set(grp_loc->path, obj_loc->path, name) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot set name") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_insert() */ /*------------------------------------------------------------------------- * Function: H5G_loc_exists * * Purpose: Check if a symbol exists in a location * * Return: Non-negative if object exists/Negative if object doesn't exist * * Programmer: Quincey Koziol * Monday, September 19, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_loc_exists(const H5G_loc_t *loc, const char *name, hid_t dxpl_id) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_loc_exists, FAIL) /* Check args. */ HDassert(loc); HDassert(name && *name); /* Get information for object in current group */ if(H5G_obj_lookup(loc->oloc, name, NULL, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_exists() */ /*------------------------------------------------------------------------- * Function: H5G_loc_remove * * Purpose: Remove a link from a group * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * Monday, September 19, 2005 * *------------------------------------------------------------------------- */ herr_t H5G_loc_remove(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc, hid_t dxpl_id) { H5G_obj_t obj_type; /* Type of object removed */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_loc_remove, FAIL) /* Check args. */ HDassert(grp_loc); HDassert(name && *name); /* Remove object from group */ if(H5G_obj_remove(grp_loc->oloc, name, &obj_type, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found") /* Search the open IDs and replace names for unlinked object */ if(H5G_name_replace(obj_type, obj_loc, NULL, NULL, H5G_NAME_UNLINK) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to replace name") done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_remove() */