diff options
Diffstat (limited to 'src/H5Gloc.c')
-rw-r--r-- | src/H5Gloc.c | 938 |
1 files changed, 938 insertions, 0 deletions
diff --git a/src/H5Gloc.c b/src/H5Gloc.c new file mode 100644 index 0000000..c011cdf --- /dev/null +++ b/src/H5Gloc.c @@ -0,0 +1,938 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * 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 COPYING file, which can be found at the root of the source code * + * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * + * If you do not have access to either file, you may request a copy from * + * help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5Gloc.c + * Sep 13 2005 + * Quincey Koziol <koziol@ncsa.uiuc.edu> + * + * Purpose: Functions for working with group "locations" + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5Gmodule.h" /* This source code file is part of the H5G module */ + + +/***********/ +/* Headers */ +/***********/ +#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 */ +#include "H5Lprivate.h" /* Links */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + +/* User data for looking up an object in a group */ +typedef struct { + /* upward */ + H5G_loc_t *loc; /* Group location to set */ +} H5G_loc_fnd_t; + +/* User data for checking if an object exists */ +typedef struct { + /* upward */ + htri_t exists; /* Whether the object exists */ +} H5G_loc_exists_t; + +/* User data for looking up an object in a group by index */ +typedef struct { + /* downward */ + hid_t lapl_id; /* LAPL to use for operation */ + hid_t dxpl_id; /* DXPL to use for operation */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Iteration order within index */ + hsize_t n; /* Offset within index */ + + /* upward */ + H5G_loc_t *loc; /* Group location to set */ +} H5G_loc_fbi_t; + +/* User data for getting an object's info in a group */ +typedef struct { + /* downward */ + hid_t dxpl_id; /* DXPL to use for operation */ + hbool_t want_ih_info; /* Whether to retrieve the index & heap info */ + + /* upward */ + H5O_info_t *oinfo; /* Object information to retrieve */ +} H5G_loc_info_t; + +/* User data for setting an object's comment in a group */ +typedef struct { + /* downward */ + hid_t dxpl_id; /* DXPL to use for operation */ + const char *comment; /* Object comment buffer */ + + /* upward */ +} H5G_loc_sc_t; + +/* User data for getting an object's comment in a group */ +typedef struct { + /* downward */ + hid_t dxpl_id; /* DXPL to use for operation */ + char *comment; /* Object comment buffer */ + size_t bufsize; /* Size of object comment buffer */ + + /* upward */ + ssize_t comment_size; /* Actual size of object comment */ +} H5G_loc_gc_t; + + +/********************/ +/* Local Prototypes */ +/********************/ + +/* Group traversal callbacks */ +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, + H5G_own_loc_t *own_loc); +static herr_t H5G_loc_find_by_idx_cb(H5G_loc_t *grp_loc, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata, + H5G_own_loc_t *own_loc); +static herr_t H5G_loc_set_comment_cb(H5G_loc_t *grp_loc, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata, + H5G_own_loc_t *own_loc); +static herr_t H5G_loc_get_comment_cb(H5G_loc_t *grp_loc, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata, + H5G_own_loc_t *own_loc); + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * 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(FAIL) + + switch(H5I_get_type(loc_id)) { + case H5I_FILE: + { + H5F_t *f; + + /* Get the file struct */ + if(NULL == (f = (H5F_t *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file ID") + + /* Construct a group location for root group of the file */ + if(H5G_root_loc(f, loc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unable to create location for file") + } /* 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 = (H5G_t *)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 = (H5T_t *)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 = (H5D_t *)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 = (H5A_t *)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") + + case H5I_UNINIT: + case H5I_BADID: + case H5I_VFL: + case H5I_NTYPES: + 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, const H5G_loc_t *src, H5_copy_depth_t depth) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(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(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(FAIL) + + /* Check args. */ + HDassert(loc); + + /* Reset components of the location */ + if(H5G_name_free(loc->path) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to free path") + if(H5O_loc_free(loc->oloc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to free object header location") + +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 H5_ATTR_UNUSED *grp_loc/*in*/, const char *name, + const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + H5G_own_loc_t *own_loc/*out*/) +{ + H5G_loc_fnd_t *udata = (H5G_loc_fnd_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check if the name in this group resolved to a valid object */ + if(obj_loc == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object '%s' doesn't exist", name) + + /* 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); + *own_loc = H5G_OWN_OBJ_LOC; + +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(const H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc/*out*/, + hid_t lapl_id, hid_t dxpl_id) +{ + H5G_loc_fnd_t udata; /* User data for traversal callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(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, lapl_id, 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_find_by_idx_cb + * + * Purpose: Callback for retrieving object location for an object in a group + * according to the order within an index + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, November 20, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_loc_find_by_idx_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, + const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + H5G_own_loc_t *own_loc/*out*/) +{ + H5G_loc_fbi_t *udata = (H5G_loc_fbi_t *)_udata; /* User data passed in */ + H5O_link_t fnd_lnk; /* Link within group */ + hbool_t lnk_copied = FALSE; /* Whether the link was copied */ + size_t links_left = H5L_NUM_LINKS; /* # of links left to traverse */ + hbool_t obj_loc_valid = FALSE; /* Flag to indicate that the object location is valid */ + hbool_t obj_exists = FALSE; /* Whether the object exists (unused) */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check if the name in this group resolved to a valid link */ + if(obj_loc == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group doesn't exist") + + /* Query link */ + if(H5G_obj_lookup_by_idx(obj_loc->oloc, udata->idx_type, udata->order, + udata->n, &fnd_lnk, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "link not found") + lnk_copied = TRUE; + + /* Build the initial object location for the link */ + if(H5G__link_to_loc(obj_loc, &fnd_lnk, udata->loc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot initialize object location") + obj_loc_valid = TRUE; + + /* Perform any special traversals that the link needs */ + /* (soft links, user-defined links, file mounting, etc.) */ + /* (may modify the object location) */ + if(H5G__traverse_special(obj_loc, &fnd_lnk, H5G_TARGET_NORMAL, &links_left, TRUE, udata->loc, &obj_exists, udata->lapl_id, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "special link traversal failed") + +done: + /* Reset the link information, if we have a copy */ + if(lnk_copied) + H5O_msg_reset(H5O_LINK_ID, &fnd_lnk); + + /* Release the object location if we failed after copying it */ + if(ret_value < 0 && obj_loc_valid) + if(H5G_loc_free(udata->loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_loc = H5G_OWN_NONE; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_find_by_idx_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_loc_find_by_idx + * + * Purpose: Find a symbol from a location, according to the order in an index + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, November 20, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_loc_find_by_idx(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, H5G_loc_t *obj_loc/*out*/, hid_t lapl_id, + hid_t dxpl_id) +{ + H5G_loc_fbi_t udata; /* User data for traversal callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args. */ + HDassert(loc); + HDassert(group_name && *group_name); + HDassert(obj_loc); + + /* Set up user data for locating object */ + udata.dxpl_id = dxpl_id; + udata.lapl_id = lapl_id; + udata.idx_type = idx_type; + udata.order = order; + udata.n = n; + udata.loc = obj_loc; + + /* Traverse group hierarchy to locate object */ + if(H5G_traverse(loc, group_name, H5G_TARGET_NORMAL, H5G_loc_find_by_idx_cb, &udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_find_by_idx() */ + + +/*------------------------------------------------------------------------- + * 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, + H5O_type_t obj_type, const void *crt_info, hid_t dxpl_id) +{ + H5O_link_t lnk; /* Link for object to insert */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_PACKAGE + + /* Check args. */ + HDassert(grp_loc); + HDassert(name && *name); + HDassert(obj_loc); + + /* Create link object for the object location */ + lnk.type = H5L_TYPE_HARD; + lnk.cset = H5F_DEFAULT_CSET; + lnk.corder = 0; /* Will be reset if the group is tracking creation order */ + lnk.corder_valid = FALSE; /* Indicate that the creation order isn't valid (yet) */ + /* 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, TRUE, obj_type, crt_info, + 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_cb + * + * Purpose: Callback for checking if an object exists + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, February 2, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_loc_exists_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, + const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, + H5G_own_loc_t *own_loc/*out*/) +{ + H5G_loc_exists_t *udata = (H5G_loc_exists_t *)_udata; /* User data passed in */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Check if the name in this group resolved to a valid object */ + if(obj_loc == NULL) + if(lnk) + udata->exists = FALSE; + else + udata->exists = FAIL; + else + udata->exists = TRUE; + + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_loc = H5G_OWN_NONE; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5G_loc_exists_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_loc_exists + * + * Purpose: Check if an object actually exists at a location + * + * Return: Success: TRUE/FALSE + * Failure: Negative + * + * Programmer: Quincey Koziol + * Tuesday, February 2, 2010 + * + *------------------------------------------------------------------------- + */ +htri_t +H5G_loc_exists(const H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id) +{ + H5G_loc_exists_t udata; /* User data for traversal callback */ + htri_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args. */ + HDassert(loc); + HDassert(name && *name); + + /* Set up user data for locating object */ + udata.exists = FALSE; + + /* Traverse group hierarchy to locate object */ + if(H5G_traverse(loc, name, H5G_TARGET_EXISTS, H5G_loc_exists_cb, &udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't check if object exists") + + /* Set return value */ + ret_value = udata.exists; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_exists() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_loc_info_cb + * + * Purpose: Callback for retrieving object info for an object in a group + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, November 23, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_loc_info_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t H5_ATTR_UNUSED *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) +{ + H5G_loc_info_t *udata = (H5G_loc_info_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* 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") + + /* Query object information */ + if(H5O_get_info(obj_loc->oloc, udata->dxpl_id, udata->want_ih_info, udata->oinfo) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object info") + +done: + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_loc = H5G_OWN_NONE; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_info_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_loc_info + * + * Purpose: Retrieve the information for an object from a group location + * and path to that object + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, November 23, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_loc_info(H5G_loc_t *loc, const char *name, hbool_t want_ih_info, H5O_info_t *oinfo/*out*/, + hid_t lapl_id, hid_t dxpl_id) +{ + H5G_loc_info_t udata; /* User data for traversal callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args. */ + HDassert(loc); + HDassert(name && *name); + HDassert(oinfo); + + /* Set up user data for locating object */ + udata.dxpl_id = dxpl_id; + udata.want_ih_info = want_ih_info; + udata.oinfo = oinfo; + + /* Traverse group hierarchy to locate object */ + if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_info_cb, &udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_info() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_loc_set_comment_cb + * + * Purpose: Callback for (re)setting object comment for an object in a group + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, August 30, 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_loc_set_comment_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t H5_ATTR_UNUSED *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) +{ + H5G_loc_sc_t *udata = (H5G_loc_sc_t *)_udata; /* User data passed in */ + H5O_name_t comment; /* Object header "comment" message */ + htri_t exists; /* Whether a "comment" message already exists */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* 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") + + /* Check for existing comment message */ + if((exists = H5O_msg_exists(obj_loc->oloc, H5O_NAME_ID, udata->dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read object header") + + /* Remove the previous comment message if any */ + if(exists) + if(H5O_msg_remove(obj_loc->oloc, H5O_NAME_ID, 0, TRUE, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete existing comment object header message") + + /* Add the new message */ + if(udata->comment && *udata->comment) { + /* Casting away const OK -QAK */ + comment.s = (char *)udata->comment; + if(H5O_msg_create(obj_loc->oloc, H5O_NAME_ID, 0, H5O_UPDATE_TIME, &comment, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to set comment object header message") + } /* end if */ + +done: + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_loc = H5G_OWN_NONE; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_set_comment_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_loc_set_comment + * + * Purpose: (Re)set the information for an object from a group location + * and path to that object + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, August 30, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_loc_set_comment(H5G_loc_t *loc, const char *name, const char *comment, + hid_t lapl_id, hid_t dxpl_id) +{ + H5G_loc_sc_t udata; /* User data for traversal callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args. */ + HDassert(loc); + HDassert(name && *name); + + /* Set up user data for locating object */ + udata.dxpl_id = dxpl_id; + udata.comment = comment; + + /* Traverse group hierarchy to locate object */ + if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_set_comment_cb, &udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_set_comment() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_loc_get_comment_cb + * + * Purpose: Callback for retrieving object comment for an object in a group + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, August 30, 2007 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_loc_get_comment_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t H5_ATTR_UNUSED *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) +{ + H5G_loc_gc_t *udata = (H5G_loc_gc_t *)_udata; /* User data passed in */ + H5O_name_t comment; /* Object header "comment" message */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* 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") + + /* Query object comment */ + comment.s = NULL; + if(NULL == H5O_msg_read(obj_loc->oloc, H5O_NAME_ID, &comment, udata->dxpl_id)) { + if(udata->comment && udata->bufsize > 0) + udata->comment[0] = '\0'; + udata->comment_size = 0; + } else { + if(udata->comment && udata->bufsize) + HDstrncpy(udata->comment, comment.s, udata->bufsize); + udata->comment_size = (ssize_t)HDstrlen(comment.s); + H5O_msg_reset(H5O_NAME_ID, &comment); + } /* end else */ + +done: + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_loc = H5G_OWN_NONE; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_get_comment_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_loc_get_comment + * + * Purpose: Retrieve the information for an object from a group location + * and path to that object + * + * Return: Success: Number of bytes in the comment excluding the + * null terminator. Zero if the object has no + * comment. + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * Thursday, August 30, 2007 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5G_loc_get_comment(H5G_loc_t *loc, const char *name, char *comment/*out*/, + size_t bufsize, hid_t lapl_id, hid_t dxpl_id) +{ + H5G_loc_gc_t udata; /* User data for traversal callback */ + ssize_t ret_value = -1; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args. */ + HDassert(loc); + HDassert(name && *name); + + /* Set up user data for locating object */ + udata.dxpl_id = dxpl_id; + udata.comment = comment; + udata.bufsize = bufsize; + udata.comment_size = (-1); + + /* Traverse group hierarchy to locate object */ + if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_get_comment_cb, &udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") + + /* Set the return value */ + ret_value = udata.comment_size; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_get_comment() */ + |