diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2005-12-26 05:28:18 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2005-12-26 05:28:18 (GMT) |
commit | 83929ea716220890e41f923566aa5c89e8e735d3 (patch) | |
tree | 22193da0d9129fc7c06a57db35b2f4a57458cf50 /src | |
parent | db551ec15e771b4536c35cc6f3eabb7d28681510 (diff) | |
download | hdf5-83929ea716220890e41f923566aa5c89e8e735d3.zip hdf5-83929ea716220890e41f923566aa5c89e8e735d3.tar.gz hdf5-83929ea716220890e41f923566aa5c89e8e735d3.tar.bz2 |
[svn-r11838] Purpose:
Bug fix
Description:
Retrieving an object's name could fail (in various ways) under certain
circumstances (mostly having to do with mounted files).
Solution:
Re-write & simplify "get object name" code to fix error in a better way
than adding yet another hack to the previous pile of hacks... :-)
Platforms tested:
FreeBSD 4.11 (sleipnir)
h5committest
Diffstat (limited to 'src')
-rw-r--r-- | src/H5A.c | 18 | ||||
-rw-r--r-- | src/H5D.c | 6 | ||||
-rw-r--r-- | src/H5Fmount.c | 50 | ||||
-rw-r--r-- | src/H5G.c | 230 | ||||
-rw-r--r-- | src/H5Gent.c | 12 | ||||
-rw-r--r-- | src/H5Glink.c | 2 | ||||
-rw-r--r-- | src/H5Gloc.c | 28 | ||||
-rw-r--r-- | src/H5Gname.c | 792 | ||||
-rw-r--r-- | src/H5Gnode.c | 74 | ||||
-rw-r--r-- | src/H5Gobj.c | 32 | ||||
-rw-r--r-- | src/H5Gpkg.h | 20 | ||||
-rw-r--r-- | src/H5Gprivate.h | 25 | ||||
-rw-r--r-- | src/H5Gtest.c | 87 | ||||
-rw-r--r-- | src/H5Gtraverse.c | 53 | ||||
-rw-r--r-- | src/H5I.c | 44 | ||||
-rw-r--r-- | src/H5O.c | 12 | ||||
-rw-r--r-- | src/H5Odtype.c | 4 | ||||
-rw-r--r-- | src/H5Olink.c | 4 | ||||
-rw-r--r-- | src/H5Oprivate.h | 8 | ||||
-rw-r--r-- | src/H5RS.c | 4 | ||||
-rw-r--r-- | src/H5T.c | 13 | ||||
-rw-r--r-- | src/H5Tcommit.c | 18 | ||||
-rw-r--r-- | src/H5private.h | 6 |
23 files changed, 852 insertions, 690 deletions
@@ -256,11 +256,11 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, attr->initialized = TRUE; /*for now, set to false later*/ /* Copy the object header information */ - if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5O_COPY_DEEP) < 0) + if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") /* Deep copy of the group hierarchy path */ - if(H5G_name_copy(&(attr->path), loc->path, H5G_COPY_DEEP) < 0) + if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy path") /* Compute the size of pieces on disk */ @@ -526,12 +526,22 @@ H5A_open(H5G_loc_t *loc, unsigned idx, hid_t dxpl_id) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to load attribute info from dataset header") attr->initialized = TRUE; +#if defined(H5_USING_PURIFY) || !defined(NDEBUG) + /* Clear object location */ + if(H5O_loc_reset(&(attr->oloc)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to reset location") + + /* Clear path name */ + if(H5G_name_reset(&(attr->path)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to reset path") +#endif /* H5_USING_PURIFY */ + /* Deep copy of the symbol table entry */ - if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5O_COPY_DEEP) < 0) + if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") /* Deep copy of the group hier. path */ - if(H5G_name_copy(&(attr->path), loc->path, H5G_COPY_DEEP) < 0) + if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") /* Hold the symbol table entry (and file) open */ @@ -2384,11 +2384,11 @@ H5D_open(const H5G_loc_t *loc, hid_t dxpl_id) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Shallow copy (take ownership) of the object location object */ - if(H5O_loc_copy(&(dataset->oloc), loc->oloc, H5O_COPY_SHALLOW) < 0) + if(H5O_loc_copy(&(dataset->oloc), loc->oloc, H5_COPY_SHALLOW) < 0) HGOTO_ERROR (H5E_DATASET, H5E_CANTCOPY, NULL, "can't copy object location") /* Shallow copy (take ownership) of the group hier. path */ - if(H5G_name_copy(&(dataset->path), loc->path, H5G_COPY_SHALLOW) < 0) + if(H5G_name_copy(&(dataset->path), loc->path, H5_COPY_SHALLOW) < 0) HGOTO_ERROR (H5E_DATASET, H5E_CANTCOPY, NULL, "can't copy path") /* Check if dataset was already open */ @@ -3103,6 +3103,8 @@ H5D_alloc_storage (H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_allo assert(layout->u.compact.size>0); if (NULL==(layout->u.compact.buf=H5MM_malloc(layout->u.compact.size))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for compact dataset") + if(!full_overwrite) + HDmemset(layout->u.compact.buf, 0, layout->u.compact.size); layout->u.compact.dirty = TRUE; /* Indicate that we set the storage addr */ diff --git a/src/H5Fmount.c b/src/H5Fmount.c index ebb76fb..17014dd 100644 --- a/src/H5Fmount.c +++ b/src/H5Fmount.c @@ -124,8 +124,7 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, H5G_loc_t mp_loc; /* entry of moint point to be opened */ H5G_name_t mp_path; /* Mount point group hier. path */ H5O_loc_t mp_oloc; /* Mount point object location */ - H5O_loc_t *mnt_oloc; /* Mount point object location */ - H5RS_str_t *name_r; /* Ref-counted version of name */ + H5G_loc_t root_loc; /* Group location of root of file to mount */ herr_t ret_value = SUCCEED; /*return value */ FUNC_ENTER_NOAPI_NOINIT(H5F_mount) @@ -152,13 +151,22 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, if(NULL == (mount_point = H5G_open(&mp_loc, dxpl_id))) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount point not found") + /* Retrieve information from the mount point group */ + /* (Some of which we had before but was reset in mp_loc when the group + * "took over" the group location - QAK) + */ parent = H5G_fileof(mount_point); - mnt_oloc = H5G_oloc(mount_point); + HDassert(parent); + mp_loc.oloc = H5G_oloc(mount_point); + HDassert(mp_loc.oloc); + mp_loc.path = H5G_nameof(mount_point); + HDassert(mp_loc.path); for(ancestor = parent; ancestor; ancestor = ancestor->mtab.parent) { if(ancestor == child) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount would introduce a cycle") } /* end for */ + /* Make certain that the parent & child files have the same "file close degree" */ if(parent->shared->fc_degree != child->shared->fc_degree) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mounted file has different file close degree than parent") @@ -175,7 +183,7 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, md = (lt + rt) / 2; oloc = H5G_oloc(parent->mtab.child[md].group); - cmp = H5F_addr_cmp(mnt_oloc->addr, oloc->addr); + cmp = H5F_addr_cmp(mp_loc.oloc->addr, oloc->addr); if(cmp < 0) rt = md; else if(cmp > 0) @@ -209,14 +217,16 @@ H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, if(H5G_mount(parent->mtab.child[md].group) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to set group mounted flag") + /* Get the group location for the root group in the file to unmount */ + if(NULL == (root_loc.oloc = H5G_oloc(child->shared->root_grp))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group") + if(NULL == (root_loc.path = H5G_nameof(child->shared->root_grp))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group") + /* Search the open IDs and replace names for mount operation */ /* We pass H5G_UNKNOWN as object type; search all IDs */ - name_r = H5RS_wrap(name); - HDassert(name_r); - if(H5G_name_replace(H5G_UNKNOWN, loc, name_r, NULL, NULL, NULL, OP_MOUNT) < 0) + if(H5G_name_replace(H5G_UNKNOWN, &mp_loc, NULL, &root_loc, H5G_NAME_MOUNT) < 0) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to replace name") - if(H5RS_decr(name_r) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "unable to decrement name string") done: if(ret_value < 0 && mount_point) @@ -249,7 +259,6 @@ static herr_t H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) { H5G_t *child_group = NULL; /* Child's group in parent mtab */ - H5F_t *child_file = NULL; /* Child's file in parent mtab */ H5F_t *child = NULL; /*mounted file */ H5F_t *parent = NULL; /*file where mounted */ H5O_loc_t *mnt_oloc; /* symbol table entry for root of mounted file */ @@ -257,6 +266,7 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) H5O_loc_t mp_oloc; /* Mount point object location */ H5G_loc_t mp_loc; /* entry used to open mount point*/ hbool_t mp_loc_setup = FALSE; /* Whether mount point location is set up */ + H5G_loc_t root_loc; /* Group location of root of file to unmount */ int child_idx; /* Index of child in parent's mtab */ herr_t ret_value = SUCCEED; /*return value */ @@ -327,16 +337,22 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) mp_loc_setup = FALSE; mp_loc.oloc = mnt_oloc; mp_loc.path = H5G_nameof(parent->mtab.child[md].group); + child = parent->mtab.child[child_idx].file; } /* end else */ HDassert(child_idx >= 0); - /* Search the open IDs replace names to reflect unmount operation */ - if(H5G_name_replace(H5G_UNKNOWN, &mp_loc, mp_loc.path->user_path_r, NULL, NULL, NULL, OP_UNMOUNT) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name") - /* Save the information about the child from the mount table */ child_group = parent->mtab.child[child_idx].group; - child_file = parent->mtab.child[child_idx].file; + + /* Get the group location for the root group in the file to unmount */ + if(NULL == (root_loc.oloc = H5G_oloc(child->shared->root_grp))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group") + if(NULL == (root_loc.path = H5G_nameof(child->shared->root_grp))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group") + + /* Search the open IDs replace names to reflect unmount operation */ + if(H5G_name_replace(H5G_UNKNOWN, &mp_loc, NULL, &root_loc, H5G_NAME_UNMOUNT) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name") /* Eliminate the mount point from the table */ HDmemmove(parent->mtab.child + child_idx, parent->mtab.child + child_idx + 1, @@ -350,8 +366,8 @@ H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close unmounted group") /* Detach child file from parent & see if it should close */ - child_file->mtab.parent = NULL; - if(H5F_try_close(child_file) < 0) + child->mtab.parent = NULL; + if(H5F_try_close(child) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close unmounted file") done: @@ -105,8 +105,6 @@ typedef struct { /* User data for path traversal routine for moving a link */ typedef struct { H5G_obj_t type; /* Type of object being moved */ - const char *src_name; /* Source name for moving object */ - H5G_loc_t *src_loc; /* Source location for moving object */ const char *dst_name; /* Destination name for moving object */ H5G_loc_t *dst_loc; /* Destination location for moving object */ } H5G_trav_ud2_t; @@ -157,12 +155,14 @@ static H5G_t *H5G_create(H5G_loc_t *loc, const char *name, hid_t dxpl_id, static herr_t H5G_open_oid(H5G_t *grp, hid_t dxpl_id); static herr_t H5G_insert_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); -static herr_t H5G_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); static herr_t H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5G_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5G_link_real(H5G_loc_t *link_loc, const char *link_name, + H5F_t *file, H5O_link_t *lnk, hid_t dxpl_id); static herr_t H5G_link(H5G_loc_t *cur_loc, const char *cur_name, - H5G_loc_t *new_loc, const char *new_name, H5G_link_t type, + H5G_loc_t *link_loc, const char *link_name, H5G_link_t type, unsigned traverse_flags, hid_t dxpl_id); static herr_t H5G_linkval_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); @@ -210,8 +210,6 @@ static herr_t H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, * Programmer: Robb Matzke * Wednesday, September 24, 1997 * - * Modifications: - * *------------------------------------------------------------------------- */ hid_t @@ -371,8 +369,6 @@ done: * Programmer: Robb Matzke * Wednesday, December 31, 1997 * - * Modifications: - * *------------------------------------------------------------------------- */ hid_t @@ -442,8 +438,6 @@ done: * Programmer: Robb Matzke * Wednesday, December 31, 1997 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -597,8 +591,6 @@ done: * Programmer: Raymond Lu * Nov 20, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ ssize_t @@ -638,8 +630,6 @@ done: * Programmer: Raymond Lu * Nov 20, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ H5G_obj_t @@ -680,11 +670,6 @@ done: * Programmer: Robb Matzke * Monday, April 6, 1998 * - * Modifications: - * - * Raymond Lu - * Thursday, April 18, 2002 - * *------------------------------------------------------------------------- */ herr_t @@ -750,8 +735,6 @@ done: * Programmer: Robb Matzke * Monday, April 6, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -812,8 +795,6 @@ done: * Programmer: Robb Matzke * Monday, April 6, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -853,8 +834,6 @@ done: * Programmer: Robb Matzke * Monday, April 13, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -896,8 +875,6 @@ done: * Programmer: Robb Matzke * Monday, April 13, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -1268,8 +1245,6 @@ H5G_component(const char *name, size_t *size_p) * Programmer: Quincey Koziol * Saturday, August 16, 2003 * - * Modifications: - * *------------------------------------------------------------------------- */ static char * @@ -1413,7 +1388,7 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *loc) /* Shallow copy (take ownership) of the group object info */ root_loc.oloc = &(f->shared->root_grp->oloc); root_loc.path = &(f->shared->root_grp->path); - if(H5G_loc_copy(&root_loc, loc, H5G_COPY_SHALLOW) < 0) + if(H5G_loc_copy(&root_loc, loc, H5_COPY_SHALLOW) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "can't copy group object location") f->shared->root_grp->shared->fo_count = 1; @@ -1557,9 +1532,9 @@ H5G_open(H5G_loc_t *loc, hid_t dxpl_id) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for group") /* Shallow copy (take ownership) of the group location object */ - if(H5O_loc_copy(&(grp->oloc), loc->oloc, H5O_COPY_SHALLOW) < 0) + if(H5O_loc_copy(&(grp->oloc), loc->oloc, H5_COPY_SHALLOW) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy object location") - if(H5G_name_copy(&(grp->path), loc->path, H5G_COPY_SHALLOW) < 0) + if(H5G_name_copy(&(grp->path), loc->path, H5_COPY_SHALLOW) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy path") /* Check if group was already open */ @@ -1748,8 +1723,6 @@ done: * Programmer: James Laird * Tuesday, September 7, 2004 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -1785,8 +1758,6 @@ done: * Programmer: Robb Matzke * Tuesday, October 13, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ H5G_t * @@ -1984,6 +1955,8 @@ static herr_t H5G_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/) { + char *old_link_name; /* Pointer to hold the old link name */ + hbool_t old_link_name_set = FALSE; /* Indicate that we've replaced the old link name */ H5G_trav_ud3_t *udata = (H5G_trav_ud3_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2003,7 +1976,9 @@ H5G_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED /* Set the link's name correctly */ /* Casting away const OK -QAK */ + old_link_name = udata->lnk->name; udata->lnk->name = name; + old_link_name_set = TRUE; /* Insert link into group */ if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, (hbool_t)(udata->lnk->type == H5G_LINK_HARD ? TRUE : FALSE), udata->dxpl_id) < 0) @@ -2019,11 +1994,55 @@ done: H5G_loc_free(obj_loc); } /* end if */ + /* Return the link's name to it's original value */ + if(old_link_name_set) + udata->lnk->name = old_link_name; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_link_cb() */ /*------------------------------------------------------------------------- + * Function: H5G_link_real + * + * Purpose: Creates a link at a path location + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, December 5, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_link_real(H5G_loc_t *link_loc, const char *link_name, H5F_t *file, + H5O_link_t *lnk, hid_t dxpl_id) +{ + H5G_trav_ud3_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_link_real) + + /* Check args */ + HDassert(link_loc); + HDassert(link_name && *link_name); + HDassert(lnk); + + /* Set up user data */ + udata.file = file; + udata.lnk = lnk; + udata.dxpl_id = dxpl_id; + + /* Traverse the destination path & create new link */ + if(H5G_traverse(link_loc, link_name, H5G_TARGET_NORMAL, H5G_link_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert link") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_link_real() */ + + +/*------------------------------------------------------------------------- * Function: H5G_link * * Purpose: Creates a link from NEW_NAME to CUR_NAME. See H5Glink() for @@ -2034,20 +2053,16 @@ done: * Programmer: Robb Matzke * Monday, April 6, 1998 * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002 - * Added `id to name' support. - * *------------------------------------------------------------------------- */ static herr_t -H5G_link(H5G_loc_t *cur_loc, const char *cur_name, H5G_loc_t *new_loc, - const char *new_name, H5G_link_t type, unsigned traverse_flags, hid_t dxpl_id) +H5G_link(H5G_loc_t *cur_loc, const char *cur_name, + H5G_loc_t *link_loc, const char *link_name, + H5G_link_t type, unsigned traverse_flags, hid_t dxpl_id) { char *norm_cur_name = NULL; /* Pointer to normalized current name */ - char *norm_new_name = NULL; /* Pointer to normalized current name */ - H5G_trav_ud3_t udata; /* User data for callback */ + char *norm_link_name = NULL; /* Pointer to normalized link name */ + H5F_t *link_file = NULL; /* Pointer to file to link to */ H5O_link_t lnk; /* Link to insert */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2055,48 +2070,47 @@ H5G_link(H5G_loc_t *cur_loc, const char *cur_name, H5G_loc_t *new_loc, /* Check args */ HDassert(cur_loc); - HDassert(new_loc); + HDassert(link_loc); HDassert(cur_name && *cur_name); - HDassert(new_name && *new_name); + HDassert(link_name && *link_name); /* Get normalized copies of the current and new names */ if((norm_cur_name = H5G_normalize(cur_name)) == NULL) HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") - if((norm_new_name = H5G_normalize(new_name)) == NULL) + if((norm_link_name = H5G_normalize(link_name)) == NULL) HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") switch(type) { - case H5G_LINK_SOFT: - /* Construct link information for eventual insertion */ - lnk.type = H5G_LINK_SOFT; - lnk.u.soft.name = norm_cur_name; - - /* Set up user data for creating soft link */ - udata.file = NULL; /* no file info necessary for soft link */ - break; - case H5G_LINK_HARD: { H5O_loc_t obj_oloc; /* Location of object to link to */ /* Get object location for object pointed to */ - if(H5G_obj_find(cur_loc, norm_cur_name, traverse_flags, &obj_oloc, dxpl_id) < 0) + if(H5G_obj_find(cur_loc, norm_cur_name, traverse_flags, NULL, &obj_oloc, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found") /* Construct link information for eventual insertion */ - lnk.type = H5G_LINK_HARD; lnk.u.hard.addr = obj_oloc.addr; - /* Set up user data for creating hard link */ - udata.file = obj_oloc.file; + /* Set destination's file information */ + link_file = obj_oloc.file; } /* end case */ break; + case H5G_LINK_SOFT: + /* Construct link information for eventual insertion */ + lnk.u.soft.name = norm_cur_name; + + /* Set destination's file information */ + link_file = NULL; /* no file info necessary for soft link */ + break; + default: HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type") } /* end switch */ /* Set up common link data */ + lnk.type = type; #ifdef H5_HAVE_GETTIMEOFDAY { struct timeval now_tv; @@ -2110,20 +2124,16 @@ H5G_link(H5G_loc_t *cur_loc, const char *cur_name, H5G_loc_t *new_loc, lnk.cset = H5T_CSET_ASCII; /* XXX: Allow user to set this */ /* lnk.name = name; */ /* This will be set in callback */ - /* Set up common user data */ - udata.lnk = &lnk; - udata.dxpl_id = dxpl_id; - - /* Traverse the destination path & create new link */ - if(H5G_traverse(new_loc, norm_new_name, H5G_TARGET_NORMAL, H5G_link_cb, &udata, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert link") + /* Create actual link to the object */ + if(H5G_link_real(link_loc, norm_link_name, link_file, &lnk, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object") done: /* Free the normalized path names */ if(norm_cur_name) H5MM_xfree(norm_cur_name); - if(norm_new_name) - H5MM_xfree(norm_new_name); + if(norm_link_name) + H5MM_xfree(norm_link_name); FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_link() */ @@ -2379,7 +2389,7 @@ H5G_set_comment(H5G_loc_t *loc, const char *name, const char *buf, hid_t dxpl_id FUNC_ENTER_NOAPI_NOINIT(H5G_set_comment) /* Get the symbol table entry for the object */ - if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, &obj_oloc/*out*/, dxpl_id) < 0) + if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, NULL, &obj_oloc/*out*/, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") /* Remove the previous comment message if any */ @@ -2425,7 +2435,7 @@ H5G_get_comment(H5G_loc_t *loc, const char *name, size_t bufsize, char *buf, hid FUNC_ENTER_NOAPI_NOINIT(H5G_get_comment) /* Get the symbol table entry for the object */ - if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, &obj_oloc/*out*/, dxpl_id) < 0) + if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, NULL, &obj_oloc/*out*/, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") /* Get the message */ @@ -2554,7 +2564,6 @@ H5G_move_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_ H5G_loc_t *obj_loc, void *_udata/*in,out*/) { H5G_trav_ud2_t *udata = (H5G_trav_ud2_t *)_udata; /* User data passed in */ - H5RS_str_t *src_name_r = NULL; /* Ref-counted version of src name */ H5RS_str_t *dst_name_r = NULL; /* Ref-counted version of dest name */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2565,17 +2574,13 @@ H5G_move_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") /* Fix names up */ - src_name_r = H5RS_wrap(udata->src_name); - HDassert(src_name_r); dst_name_r = H5RS_wrap(udata->dst_name); HDassert(dst_name_r); - if(H5G_name_replace(udata->type, obj_loc, src_name_r, udata->src_loc, dst_name_r, udata->dst_loc, OP_MOVE) < 0) + if(H5G_name_replace(udata->type, obj_loc, dst_name_r, udata->dst_loc, H5G_NAME_MOVE) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name ") done: /* Cleanup */ - if(src_name_r) - H5RS_decr(src_name_r); if(dst_name_r) H5RS_decr(dst_name_r); @@ -2606,7 +2611,9 @@ static herr_t H5G_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, const char *dst_name, hid_t dxpl_id) { - H5G_stat_t sb; /* Object info for link to move */ + H5O_loc_t src_oloc; /* Location of object linked to */ + H5O_link_t lnk; /* Link information for object to move */ + hbool_t link_valid = FALSE; /* Flag to indicate that the link information is valid */ H5G_trav_ud2_t udata; /* User data for traversal */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2618,47 +2625,50 @@ H5G_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, HDassert(src_name && *src_name); HDassert(dst_name && *dst_name); - if(H5G_get_objinfo(src_loc, src_name, FALSE, &sb, dxpl_id) < 0) + /* Get copy of link to move */ + if(H5G_obj_find(src_loc, src_name, (H5G_TARGET_MOUNT|H5G_TARGET_SLINK), &lnk, &src_oloc, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") - if(H5G_LINK == sb.type) { - char *linkval = NULL; + link_valid = TRUE; - /* - * When renaming a symbolic link we rename the link but don't change - * the value of the link. - */ - if(NULL == (linkval = H5MM_malloc(sb.u.slink.linklen))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate space for symbolic link value") - if(H5G_linkval(src_loc, src_name, sb.u.slink.linklen, linkval, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read symbolic link value") - if(H5G_link(src_loc, linkval, dst_loc, dst_name, H5G_LINK_SOFT, H5G_TARGET_NORMAL, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to rename symbolic link") - H5MM_xfree(linkval); - } else { - /* - * Rename the object. - */ - if(H5G_link(src_loc, src_name, dst_loc, dst_name, H5G_LINK_HARD, H5G_TARGET_MOUNT, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object") - } /* end else */ + /* Release name for link (it will have a new name in destination) */ + lnk.name = H5MM_xfree(lnk.name); + + /* Create new link to the object */ + if(H5G_link_real(dst_loc, dst_name, src_oloc.file, &lnk, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object") /* Set up user data for name replacement */ - udata.type = sb.type; - udata.src_name = src_name; - udata.src_loc = src_loc; + /* Get object type */ + switch(lnk.type) { + case H5G_LINK_HARD: + if(H5G_UNKNOWN == (udata.type = H5O_obj_type(&src_oloc, dxpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object type to move") + break; + + case H5G_LINK_SOFT: + udata.type = H5G_LINK; + break; + + default: + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type") + } /* end switch */ udata.dst_name = dst_name; udata.dst_loc = dst_loc; /* Search the open ID list and replace names for the move operation */ - if(H5G_traverse(src_loc, src_name, H5G_TARGET_NORMAL|H5G_TARGET_SLINK, H5G_move_cb, &udata, dxpl_id) < 0) + if(H5G_traverse(src_loc, src_name, H5G_TARGET_MOUNT|H5G_TARGET_SLINK, H5G_move_cb, &udata, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link") /* Remove the old name */ if(H5G_unlink(src_loc, src_name, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to deregister old object name") + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to unlink old object name") done: + /* If there's valid information in the link, reset it */ + if(link_valid) + H5O_reset(H5O_LINK_ID, &lnk); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_move() */ @@ -2795,8 +2805,6 @@ done: * Programmer: Quincey Koziol * Tuesday, July 5, 2005 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -2821,8 +2829,6 @@ H5G_get_shared_count(H5G_t *grp) * Programmer: Quincey Koziol * Tuesday, July 19, 2005 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -2851,8 +2857,6 @@ H5G_mount(H5G_t *grp) * Programmer: Quincey Koziol * Tuesday, July 19, 2005 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t @@ -2881,8 +2885,6 @@ H5G_unmount(H5G_t *grp) * Programmer: Peter Cao * June 4, 2005 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t diff --git a/src/H5Gent.c b/src/H5Gent.c index 08f7e77..e2e512b 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -327,34 +327,34 @@ H5G_ent_encode(H5F_t *f, uint8_t **pp, const H5G_entry_t *ent) * * Notes: 'depth' parameter determines how much of the group entry * structure we want to copy. The values are: - * H5G_COPY_SHALLOW - Copy all the fields from the source + * H5_COPY_SHALLOW - Copy all the fields from the source * to the destination, including the user path and * canonical path. (Destination "takes ownership" of * user and canonical paths) - * H5G_COPY_DEEP - Copy all the fields from the source to + * H5_COPY_DEEP - Copy all the fields from the source to * the destination, deep copying the user and canonical * paths. * *------------------------------------------------------------------------- */ herr_t -H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src, H5G_copy_depth_t depth) +H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src, H5_copy_depth_t depth) { FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_copy) /* Check arguments */ HDassert(src); HDassert(dst); - HDassert(depth == H5G_COPY_SHALLOW || depth == H5G_COPY_DEEP); + HDassert(depth == H5_COPY_SHALLOW || depth == H5_COPY_DEEP); /* Copy the top level information */ HDmemcpy(dst, src, sizeof(H5G_entry_t)); /* Deep copy the names */ - if(depth == H5G_COPY_DEEP) { + if(depth == H5_COPY_DEEP) { /* Nothing currently */ ; - } else if(depth == H5G_COPY_SHALLOW) { + } else if(depth == H5_COPY_SHALLOW) { /* Discarding 'const' qualifier OK - QAK */ H5G_ent_reset((H5G_entry_t *)src); } /* end if */ diff --git a/src/H5Glink.c b/src/H5Glink.c index 0213422..6eb9dfc 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -314,7 +314,7 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap, s = H5HL_offset_into(ent->file, heap, ent->cache.slink.lval_offset); HDassert(s); - /* Copy to for link */ + /* Copy to link */ lnk->u.soft.name = H5MM_xstrdup(s); HDassert(lnk->u.soft.name); } diff --git a/src/H5Gloc.c b/src/H5Gloc.c index e2a293f..a9e907f 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -77,11 +77,11 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc) 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 symbol table entry for root group") + 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 symbol table entry to reflect this file */ + /* 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) */ @@ -93,12 +93,12 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc) case H5I_GENPROP_CLS: case H5I_GENPROP_LST: - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of property list") + 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 symbol table entry of error class, message or stack") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of error class, message or stack") case H5I_GROUP: { @@ -107,7 +107,7 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc) 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 symbol table entry of 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 */ @@ -120,14 +120,14 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc) 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 symbol table entry of datatype") + 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 symbol table entry of dataspace") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of dataspace") case H5I_DATASET: { @@ -136,7 +136,7 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc) 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 symbol table entry of dataset") + 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 */ @@ -149,14 +149,14 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc) 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 symbol table entry of attribute") + 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 symbol table entry of 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") @@ -180,7 +180,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_loc_copy(H5G_loc_t *dst, H5G_loc_t *src, H5G_copy_depth_t depth) +H5G_loc_copy(H5G_loc_t *dst, H5G_loc_t *src, H5_copy_depth_t depth) { herr_t ret_value = SUCCEED; /* Return value */ @@ -191,7 +191,7 @@ H5G_loc_copy(H5G_loc_t *dst, H5G_loc_t *src, H5G_copy_depth_t depth) HDassert(src); /* Copy components of the location */ - if(H5O_loc_copy(dst->oloc, src->oloc, (depth == H5G_COPY_SHALLOW ? H5O_COPY_SHALLOW : H5O_COPY_DEEP)) < 0) + 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") @@ -298,7 +298,7 @@ H5G_loc_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const /* (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, H5O_COPY_SHALLOW); + H5G_loc_copy(udata->loc, obj_loc, H5_COPY_SHALLOW); done: FUNC_LEAVE_NOAPI(ret_value) @@ -460,7 +460,7 @@ H5G_loc_remove(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc, hid_t d 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, NULL, NULL, OP_UNLINK) < 0) + 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: diff --git a/src/H5Gname.c b/src/H5Gname.c index 1d1a141..c4f5c95 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -34,18 +34,16 @@ #include "H5FLprivate.h" /* Free Lists */ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ -#include "H5MMprivate.h" /* Memory management */ /* Private typedefs */ /* Struct used by change name callback function */ typedef struct H5G_names_t { - H5G_loc_t *loc; - H5RS_str_t *src_name; - H5G_loc_t *src_loc; - H5RS_str_t *dst_name; - H5G_loc_t *dst_loc; - H5G_names_op_t op; + H5G_names_op_t op; /* Operation performed on file */ + H5G_loc_t *loc; /* [src] Location affected */ + H5F_t *top_loc_file; /* Top file in src location's mounted file hier. */ + H5G_loc_t *dst_loc; /* Destination location */ + H5RS_str_t *dst_name; /* Name of object relative to destination location */ } H5G_names_t; /* Private macros */ @@ -60,6 +58,8 @@ static htri_t H5G_common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *pr static H5RS_str_t *H5G_build_fullpath(const char *prefix, const char *name); static H5RS_str_t *H5G_build_fullpath_refstr_refstr(const H5RS_str_t *prefix_r, const H5RS_str_t *name_r); static H5RS_str_t *H5G_build_fullpath_refstr_str(H5RS_str_t *path_r, const char *name); +static herr_t H5G_name_move_path(H5RS_str_t **path_r_ptr, + const char *full_suffix, const char *src_path, const char *dst_path); static int H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key); @@ -223,7 +223,7 @@ H5G_build_fullpath_refstr_str(H5RS_str_t *prefix_r, const char *name) /*------------------------------------------------------------------------- - * Function: H5G_name_concat_refstr_refstr + * Function: H5G_name_build_refstr_refstr * * Purpose: Build a full path from a prefix & base pair of reference counted * strings @@ -280,11 +280,11 @@ H5G_name_init(H5G_name_t *name, const char *path) HDassert(name); /* Set the initial paths for a name object */ - name->user_path_r=H5RS_create(path); + name->full_path_r = H5RS_create(path); + HDassert(name->full_path_r); + name->user_path_r = H5RS_create(path); HDassert(name->user_path_r); - name->canon_path_r=H5RS_create(path); - HDassert(name->canon_path_r); - name->user_path_hidden=0; + name->obj_hidden = 0; FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_name_init() */ @@ -317,6 +317,13 @@ H5G_name_set(H5G_name_t *loc, H5G_name_t *obj, const char *name) /* Free & reset the object's previous paths info (if they exist) */ H5G_name_free(obj); + /* Create the object's full path, if a full path exists in the location */ + if(loc->full_path_r) { + /* Go build the new full path */ + if((obj->full_path_r = H5G_build_fullpath_refstr_str(loc->full_path_r, name)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build user path name") + } /* end if */ + /* Create the object's user path, if a user path exists in the location */ if(loc->user_path_r) { /* Go build the new user path */ @@ -324,13 +331,6 @@ H5G_name_set(H5G_name_t *loc, H5G_name_t *obj, const char *name) HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build user path name") } /* end if */ - /* Create the object's canonical path, if a canonical path exists in the location */ - if(loc->canon_path_r) { - /* Go build the new canonical path */ - if((obj->canon_path_r = H5G_build_fullpath_refstr_str(loc->canon_path_r, name)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build canonical path name") - } /* end if */ - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_name_set() */ @@ -348,48 +348,38 @@ done: * Monday, September 12, 2005 * * Notes: 'depth' parameter determines how much of the group entry - * structure we want to copy. The new depths are: - * H5G_COPY_SHALLOW - Copy all the fields from the source + * structure we want to copy. The depths are: + * H5_COPY_SHALLOW - Copy all the fields from the source * to the destination, including the user path and * canonical path. (Destination "takes ownership" of * user and canonical paths) - * H5G_COPY_CANON - Deep copy the canonical path and leave - * the user path alone - * H5G_COPY_DEEP - Copy all the fields from the source to + * H5_COPY_DEEP - Copy all the fields from the source to * the destination, deep copying the user and canonical * paths. * *------------------------------------------------------------------------- */ herr_t -H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5G_copy_depth_t depth) +H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth) { - H5RS_str_t *tmp_user_path_r = NULL; /* Temporary string pointer for entry's user path */ - FUNC_ENTER_NOAPI_NOFUNC(H5G_name_copy) /* Check arguments */ HDassert(src); HDassert(dst); - HDassert(depth == H5G_COPY_SHALLOW || depth == H5G_COPY_DEEP || depth == H5G_COPY_CANON); - - /* If only copying the canonical path, keep the old user path */ - if(depth == H5G_COPY_CANON) { - tmp_user_path_r = dst->user_path_r; - if(dst->canon_path_r) - H5RS_decr(dst->canon_path_r); - } /* end if */ +#if defined(H5_USING_PURIFY) || !defined(NDEBUG) + HDassert(dst->full_path_r == NULL); + HDassert(dst->user_path_r == NULL); +#endif /* H5_USING_PURIFY */ + HDassert(depth == H5_COPY_SHALLOW || depth == H5_COPY_DEEP); /* Copy the top level information */ HDmemcpy(dst, src, sizeof(H5G_name_t)); /* Deep copy the names */ - if(depth == H5G_COPY_DEEP) { + if(depth == H5_COPY_DEEP) { + dst->full_path_r = H5RS_dup(src->full_path_r); dst->user_path_r = H5RS_dup(src->user_path_r); - dst->canon_path_r = H5RS_dup(src->canon_path_r); - } else if(depth == H5G_COPY_CANON) { - dst->user_path_r = tmp_user_path_r; - dst->canon_path_r = H5RS_dup(src->canon_path_r); } else { /* Discarding 'const' qualifier OK - QAK */ H5G_name_reset((H5G_name_t *)src); @@ -400,6 +390,51 @@ H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5G_copy_depth_t depth) /*------------------------------------------------------------------------- + * Function: H5G_get_name + * + * Purpose: Gets a name of an object from its ID. + * + * Notes: Internal routine for H5Iget_name(). + + * Return: Success: Non-negative, length of name + * Failure: Negative + * + * Programmer: Quincey Koziol + * Tuesday, December 13, 2005 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5G_get_name(hid_t id, char *name/*out*/, size_t size) +{ + H5G_loc_t loc; /* Object location */ + ssize_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOFUNC(H5G_get_name) + + /* get object location */ + if(H5G_loc(id, &loc) >= 0) { + size_t len = 0; + + if(loc.path->user_path_r != NULL && loc.path->obj_hidden == 0) { + len = H5RS_len(loc.path->user_path_r); + + if(name) { + HDstrncpy(name, H5RS_get_str(loc.path->user_path_r), MIN(len + 1, size)); + if(len >= size) + name[size-1] = '\0'; + } /* end if */ + } /* end if */ + + /* Set return value */ + ret_value = (ssize_t)len; + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_get_name() */ + + +/*------------------------------------------------------------------------- * Function: H5G_name_reset * * Purpose: Reset a group hierarchy name to an empty state @@ -448,20 +483,124 @@ H5G_name_free(H5G_name_t *name) /* Check args */ HDassert(name); + if(name->full_path_r) { + H5RS_decr(name->full_path_r); + name->full_path_r = NULL; + } /* end if */ if(name->user_path_r) { H5RS_decr(name->user_path_r); - name->user_path_r=NULL; - } /* end if */ - if(name->canon_path_r) { - H5RS_decr(name->canon_path_r); - name->canon_path_r=NULL; + name->user_path_r = NULL; } /* end if */ + name->obj_hidden = 0; FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_name_free() */ /*------------------------------------------------------------------------- + * Function: H5G_name_move_path + * + * Purpose: Update a user or canonical path after an object moves + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * Tuesday, December 13, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_name_move_path(H5RS_str_t **path_r_ptr, const char *full_suffix, const char *src_path, + const char *dst_path) +{ + const char *path; /* Path to update */ + size_t path_len; /* Length of path */ + size_t full_suffix_len; /* Length of full suffix */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_name_move_path) + + /* Check arguments */ + HDassert(path_r_ptr && *path_r_ptr); + HDassert(full_suffix); + HDassert(src_path); + HDassert(dst_path); + + /* Get pointer to path to update */ + path = H5RS_get_str(*path_r_ptr); + HDassert(path); + + /* Check if path needs to be updated */ + full_suffix_len = HDstrlen(full_suffix); + path_len = HDstrlen(path); + if(full_suffix_len < path_len) { + const char *dst_suffix; /* Destination suffix that changes */ + const char *src_suffix; /* Source suffix that changes */ + const char *path_prefix; /* Prefix for path */ + size_t path_prefix_len; /* Length of path prefix */ + const char *path_prefix2; /* 2nd prefix for path */ + size_t path_prefix2_len; /* Length of 2nd path prefix */ + const char *common_prefix; /* Common prefix for src & dst paths */ + size_t common_prefix_len; /* Length of common prefix */ + char *new_path; /* Pointer to new path */ + size_t new_path_len; /* Length of new path */ + + + /* Compute path prefix before full suffix*/ + path_prefix = path; + path_prefix_len = path_len - full_suffix_len; + + /* Determine the common prefix for src & dst paths */ + common_prefix = src_path; + common_prefix_len = 0; + /* Find first character that is different */ + while(*(src_path + common_prefix_len) == *(dst_path + common_prefix_len)) + common_prefix_len++; + /* Back up to previous '/' */ + while(*(common_prefix + common_prefix_len) != '/') + common_prefix_len--; + /* Include '/' */ + common_prefix_len++; + + /* Determine source suffix */ + src_suffix = src_path + (common_prefix_len - 1); + + /* Determine destination suffix */ + dst_suffix = dst_path + (common_prefix_len - 1); + + /* Compute path prefix before src suffix*/ + path_prefix2 = path; + path_prefix2_len = path_prefix_len - HDstrlen(src_suffix); + + /* Allocate space for the new path */ + new_path_len = path_prefix2_len + HDstrlen(dst_suffix) + full_suffix_len; + if(NULL == (new_path = H5FL_BLK_MALLOC(str_buf, new_path_len + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Create the new path */ + if(path_prefix2_len > 0) { + HDstrncpy(new_path, path_prefix2, path_prefix2_len); + HDstrcpy(new_path + path_prefix2_len, dst_suffix); + } /* end if */ + else + HDstrcpy(new_path, dst_suffix); + if(full_suffix_len > 0) + HDstrcat(new_path, full_suffix); + + /* Release previous path */ + H5RS_decr(*path_r_ptr); + + /* Take ownership of the new full path */ + *path_r_ptr = H5RS_own(new_path); + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_name_move_path() */ + + +/*------------------------------------------------------------------------- * Function: H5G_name_replace_cb * * Purpose: H5I_search callback function to replace group entry names @@ -480,8 +619,8 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key) const H5G_names_t *names = (const H5G_names_t *)key; /* Get operation's information */ H5O_loc_t *oloc; /* Object location for object that the ID refers to */ H5G_name_t *obj_path; /* Pointer to group hier. path for obj */ - H5F_t *top_ent_file; /* Top file in entry's mounted file chain */ - H5F_t *top_loc_file; /* Top file in location's mounted file chain */ + H5F_t *top_obj_file; /* Top file in object's mounted file hier. */ + hbool_t obj_in_child = FALSE; /* Flag to indicate that the object is in the child mount hier. */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_name_replace_cb) @@ -515,268 +654,211 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key) HDassert(oloc); HDassert(obj_path); + /* Check if the object has a full path still */ + if(!obj_path->full_path_r) + HGOTO_DONE(SUCCEED) /* No need to look at object, it's path is already invalid */ + + /* Find the top file in object's mount hier. */ + if(oloc->file->mtab.parent) { + /* Check if object is in child file (for mount & unmount operations) */ + if(names->dst_loc && oloc->file->shared == names->dst_loc->oloc->file->shared) + obj_in_child = TRUE; + + /* Find the "top" file in the chain of mounted files */ + top_obj_file = oloc->file->mtab.parent; + while(top_obj_file->mtab.parent != NULL) { + /* Check if object is in child mount hier. (for mount & unmount operations) */ + if(names->dst_loc && top_obj_file->shared == names->dst_loc->oloc->file->shared) + obj_in_child = TRUE; + + top_obj_file = top_obj_file->mtab.parent; + } /* end while */ + } /* end if */ + else + top_obj_file = oloc->file; + + /* Check if object is in top of child mount hier. (for mount & unmount operations) */ + if(names->dst_loc && top_obj_file->shared == names->dst_loc->oloc->file->shared) + obj_in_child = TRUE; + + /* Check if the object is in same file mount hier. */ + if(top_obj_file->shared != names->top_loc_file->shared) + HGOTO_DONE(SUCCEED) /* No need to look at object, it's path is already invalid */ + switch(names->op) { /*------------------------------------------------------------------------- - * OP_MOUNT + * H5G_NAME_MOUNT *------------------------------------------------------------------------- */ - case OP_MOUNT: - if(obj_path->user_path_r) { - if(oloc->file->mtab.parent && H5RS_cmp(obj_path->user_path_r, obj_path->canon_path_r)) { - /* Find the "top" file in the chain of mounted files */ - top_ent_file = oloc->file->mtab.parent; - while(top_ent_file->mtab.parent != NULL) - top_ent_file = top_ent_file->mtab.parent; - } /* end if */ - else - top_ent_file = oloc->file; - - /* Check for entry being in correct file (or mounted file) */ - if(top_ent_file->shared == names->loc->oloc->file->shared) { - /* Check if the source is along the entry's path */ - /* (But not actually the entry itself) */ - if(H5G_common_path(obj_path->user_path_r, names->src_name) && - H5RS_cmp(obj_path->user_path_r, names->src_name) != 0) { - /* Hide the user path */ - (obj_path->user_path_hidden)++; - } /* end if */ - } /* end if */ - } /* end if */ + case H5G_NAME_MOUNT: + /* Check if object is in child mount hier. */ + if(obj_in_child) { + const char *full_path; /* Full path of current object */ + const char *src_path; /* Full path of source object */ + char *new_full_path; /* New full path of object */ + size_t new_full_len; /* Length of new full path */ + + /* Get pointers to paths of interest */ + full_path = H5RS_get_str(obj_path->full_path_r); + src_path = H5RS_get_str(names->loc->path->full_path_r); + + /* Build new full path */ + + /* Allocate space for the new full path */ + new_full_len = HDstrlen(src_path) + HDstrlen(full_path); + if(NULL == (new_full_path = H5FL_BLK_MALLOC(str_buf, new_full_len + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Create the new full path */ + HDstrcpy(new_full_path, src_path); + HDstrcat(new_full_path, full_path); + + /* Release previous full path */ + H5RS_decr(obj_path->full_path_r); + + /* Take ownership of the new full path */ + obj_path->full_path_r = H5RS_own(new_full_path); + } /* end if */ + /* Object must be in parent mount file hier. */ + else { + /* Check if the source is along the entry's path */ + /* (But not actually the entry itself) */ + if(H5G_common_path(obj_path->full_path_r, names->loc->path->full_path_r) && + H5RS_cmp(obj_path->full_path_r, names->loc->path->full_path_r)) { + /* Hide the user path */ + (obj_path->obj_hidden)++; + } /* end if */ + } /* end else */ break; /*------------------------------------------------------------------------- - * OP_UNMOUNT + * H5G_NAME_UNMOUNT *------------------------------------------------------------------------- */ - case OP_UNMOUNT: - if(obj_path->user_path_r) { - if(oloc->file->mtab.parent) { - /* Find the "top" file in the chain of mounted files for the entry */ - top_ent_file = oloc->file->mtab.parent; - while(top_ent_file->mtab.parent != NULL) - top_ent_file=top_ent_file->mtab.parent; - } /* end if */ - else - top_ent_file = oloc->file; - - if(names->loc->oloc->file->mtab.parent) { - /* Find the "top" file in the chain of mounted files for the location */ - top_loc_file = names->loc->oloc->file->mtab.parent; - while(top_loc_file->mtab.parent != NULL) - top_loc_file = top_loc_file->mtab.parent; - } /* end if */ - else - top_loc_file = names->loc->oloc->file; - - /* If the ID's entry is not in the file we operated on, skip it */ - if(top_ent_file->shared == top_loc_file->shared) { - if(obj_path->user_path_hidden) { - if(H5G_common_path(obj_path->user_path_r, names->src_name)) { - /* Un-hide the user path */ - (obj_path->user_path_hidden)--; - } /* end if */ - } /* end if */ - else { - if(H5G_common_path(obj_path->user_path_r, names->src_name)) { - /* Free user path */ - H5RS_decr(obj_path->user_path_r); - obj_path->user_path_r = NULL; - } /* end if */ - } /* end else */ - } /* end if */ - } /* end if */ + case H5G_NAME_UNMOUNT: + if(obj_in_child) { + const char *full_path; /* Full path of current object */ + const char *full_suffix; /* Full path after source path */ + const char *src_path; /* Full path of source object */ + char *new_full_path; /* New full path of object */ + + /* Get pointers to paths of interest */ + full_path = H5RS_get_str(obj_path->full_path_r); + src_path = H5RS_get_str(names->loc->path->full_path_r); + + /* Construct full path suffix */ + full_suffix = full_path + HDstrlen(src_path); + + /* Build new full path */ + + /* Create the new full path */ + if(NULL == (new_full_path = H5FL_BLK_MALLOC(str_buf, HDstrlen(full_suffix) + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + HDstrcpy(new_full_path, full_suffix); + + /* Release previous full path */ + H5RS_decr(obj_path->full_path_r); + + /* Take ownership of the new full path */ + obj_path->full_path_r = H5RS_own(new_full_path); + + /* Check if the object's user path should be invalidated */ + if(obj_path->user_path_r && HDstrlen(new_full_path) < (size_t)H5RS_len(obj_path->user_path_r)) { + /* Free user path */ + H5RS_decr(obj_path->user_path_r); + obj_path->user_path_r = NULL; + } /* end if */ + } /* end if */ + else { + /* Check if file being unmounted was hiding the object */ + if(H5G_common_path(obj_path->full_path_r, names->loc->path->full_path_r) && + H5RS_cmp(obj_path->full_path_r, names->loc->path->full_path_r)) { + /* Un-hide the user path */ + (obj_path->obj_hidden)--; + } /* end if */ + } /* end else */ break; /*------------------------------------------------------------------------- - * OP_UNLINK + * H5G_NAME_UNLINK *------------------------------------------------------------------------- */ - case OP_UNLINK: - /* If the ID's entry is not in the file we operated on, skip it */ - if(oloc->file->shared == names->loc->oloc->file->shared && - names->loc->path->canon_path_r && obj_path->canon_path_r && obj_path->user_path_r) { - /* Check if we are referring to the same object */ - if(H5F_addr_eq(oloc->addr, names->loc->oloc->addr)) { - /* Check if the object was opened with the same canonical path as the one being moved */ - if(H5RS_cmp(obj_path->canon_path_r, names->loc->path->canon_path_r) == 0) { - /* Free user path */ - H5RS_decr(obj_path->user_path_r); - obj_path->user_path_r=NULL; - } /* end if */ - } /* end if */ - else { - /* Check if the location being unlinked is in the canonical path for the current object */ - if(H5G_common_path(obj_path->canon_path_r, names->loc->path->canon_path_r)) { - /* Free user path */ - H5RS_decr(obj_path->user_path_r); - obj_path->user_path_r=NULL; - } /* end if */ - } /* end else */ + case H5G_NAME_UNLINK: + /* Check if the location being unlinked is in the path for the current object */ + if(H5G_common_path(obj_path->full_path_r, names->loc->path->full_path_r)) { + /* Free paths for object */ + H5G_name_free(obj_path); } /* end if */ break; /*------------------------------------------------------------------------- - * OP_MOVE + * H5G_NAME_MOVE *------------------------------------------------------------------------- */ - case OP_MOVE: /* H5Gmove case, check for relative names case */ - /* If the ID's entry is not in the file we operated on, skip it */ - if(oloc->file->shared == names->loc->oloc->file->shared) { - if(obj_path->user_path_r && names->loc->path->user_path_r && - names->src_loc->path->user_path_r && names->dst_loc->path->user_path_r) { - H5RS_str_t *src_path_r; /* Full user path of source name */ - H5RS_str_t *dst_path_r; /* Full user path of destination name */ - H5RS_str_t *canon_src_path_r; /* Copy of canonical part of source path */ - H5RS_str_t *canon_dst_path_r; /* Copy of canonical part of destination path */ - - /* Sanity check */ - HDassert(names->src_name); - HDassert(names->dst_name); - - /* Make certain that the source and destination names are full (not relative) paths */ - if(*(H5RS_get_str(names->src_name)) != '/') { - /* Create reference counted string for full src path */ - if((src_path_r = H5G_build_fullpath_refstr_refstr(names->src_loc->path->user_path_r, names->src_name)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build source path name") - } /* end if */ - else - src_path_r = H5RS_dup(names->src_name); - if(*(H5RS_get_str(names->dst_name)) != '/') { - /* Create reference counted string for full dst path */ - if((dst_path_r = H5G_build_fullpath_refstr_refstr(names->dst_loc->path->user_path_r, names->dst_name)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build destination path name") - } /* end if */ - else - dst_path_r = H5RS_dup(names->dst_name); - - /* Get the canonical parts of the source and destination names */ - - /* Check if the object being moved was accessed through a mounted file */ - if(H5RS_cmp(names->loc->path->user_path_r, names->loc->path->canon_path_r) != 0) { - size_t non_canon_name_len; /* Length of non-canonical part of name */ - - /* Get current string lengths */ - non_canon_name_len = H5RS_len(names->loc->path->user_path_r) - H5RS_len(names->loc->path->canon_path_r); - - canon_src_path_r = H5RS_create(H5RS_get_str(src_path_r) + non_canon_name_len); - canon_dst_path_r = H5RS_create(H5RS_get_str(dst_path_r) + non_canon_name_len); - } /* end if */ - else { - canon_src_path_r = H5RS_dup(src_path_r); - canon_dst_path_r = H5RS_dup(dst_path_r); - } /* end else */ - - /* Check if the link being changed in the file is along the canonical path for this object */ - if(H5G_common_path(obj_path->canon_path_r, canon_src_path_r)) { - size_t user_dst_len; /* Length of destination user path */ - size_t canon_dst_len; /* Length of destination canonical path */ - const char *old_user_path; /* Pointer to previous user path */ - char *new_user_path; /* Pointer to new user path */ - char *new_canon_path; /* Pointer to new canonical path */ - const char *tail_path; /* Pointer to "tail" of path */ - size_t tail_len; /* Pointer to "tail" of path */ - char *src_canon_prefix; /* Pointer to source canonical path prefix of component which is moving */ - size_t src_canon_prefix_len;/* Length of the source canonical path prefix */ - char *dst_canon_prefix; /* Pointer to destination canonical path prefix of component which is moving */ - size_t dst_canon_prefix_len;/* Length of the destination canonical path prefix */ - char *user_prefix; /* Pointer to user path prefix of component which is moving */ - size_t user_prefix_len; /* Length of the user path prefix */ - char *src_comp; /* The source name of the component which is actually changing */ - char *dst_comp; /* The destination name of the component which is actually changing */ - const char *canon_src_path; /* pointer to canonical part of source path */ - const char *canon_dst_path; /* pointer to canonical part of destination path */ - - /* Get the pointers to the raw strings */ - canon_src_path = H5RS_get_str(canon_src_path_r); - canon_dst_path = H5RS_get_str(canon_dst_path_r); - - /* Get the source & destination components */ - src_comp = HDstrrchr(canon_src_path, '/'); - HDassert(src_comp); - dst_comp = HDstrrchr(canon_dst_path, '/'); - HDassert(dst_comp); - - /* Find the canonical prefixes for the entry */ - src_canon_prefix_len = HDstrlen(canon_src_path) - HDstrlen(src_comp); - if(NULL == (src_canon_prefix = H5MM_malloc(src_canon_prefix_len + 1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - HDstrncpy(src_canon_prefix, canon_src_path, src_canon_prefix_len); - src_canon_prefix[src_canon_prefix_len] = '\0'; - - dst_canon_prefix_len = HDstrlen(canon_dst_path) - HDstrlen(dst_comp); - if(NULL == (dst_canon_prefix = H5MM_malloc(dst_canon_prefix_len + 1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - HDstrncpy(dst_canon_prefix, canon_dst_path, dst_canon_prefix_len); - dst_canon_prefix[dst_canon_prefix_len] = '\0'; - - /* Hold this for later use */ - old_user_path = H5RS_get_str(obj_path->user_path_r); - - /* Find the user prefix for the entry */ - user_prefix_len = HDstrlen(old_user_path) - H5RS_len(obj_path->canon_path_r); - if(NULL == (user_prefix = H5MM_malloc(user_prefix_len + 1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - HDstrncpy(user_prefix, old_user_path, user_prefix_len); - user_prefix[user_prefix_len] = '\0'; - - /* Set the tail path info */ - tail_path = old_user_path+user_prefix_len + src_canon_prefix_len + HDstrlen(src_comp); - tail_len = HDstrlen(tail_path); - - /* Get the length of the destination paths */ - user_dst_len = user_prefix_len + dst_canon_prefix_len + HDstrlen(dst_comp) + tail_len; - canon_dst_len = dst_canon_prefix_len + HDstrlen(dst_comp) + tail_len; - - /* Allocate space for the new user path */ - if(NULL == (new_user_path = H5FL_BLK_MALLOC(str_buf, user_dst_len + 1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Allocate space for the new canonical path */ - if(NULL == (new_canon_path = H5FL_BLK_MALLOC(str_buf, canon_dst_len + 1))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Create the new names */ - HDstrcpy(new_user_path, user_prefix); - HDstrcat(new_user_path, dst_canon_prefix); - HDstrcat(new_user_path, dst_comp); - HDstrcat(new_user_path, tail_path); - HDstrcpy(new_canon_path, dst_canon_prefix); - HDstrcat(new_canon_path, dst_comp); - HDstrcat(new_canon_path, tail_path); - - /* Release the old user & canonical paths */ - H5RS_decr(obj_path->user_path_r); - H5RS_decr(obj_path->canon_path_r); - - /* Take ownership of the new user & canonical paths */ - obj_path->user_path_r = H5RS_own(new_user_path); - obj_path->canon_path_r = H5RS_own(new_canon_path); - - /* Free the extra paths allocated */ - H5MM_xfree(src_canon_prefix); - H5MM_xfree(dst_canon_prefix); - H5MM_xfree(user_prefix); - } /* end if */ - - - /* Free the extra paths allocated */ - H5RS_decr(src_path_r); - H5RS_decr(dst_path_r); - H5RS_decr(canon_src_path_r); - H5RS_decr(canon_dst_path_r); - } /* end if */ - else { - /* Release the old user path */ - if(obj_path->user_path_r) { - H5RS_decr(obj_path->user_path_r); - obj_path->user_path_r = NULL; - } /* end if */ - } /* end else */ + case H5G_NAME_MOVE: /* H5Gmove case, check for relative names case */ + /* Check if the src object moved is in the current object's path */ + if(H5G_common_path(obj_path->full_path_r, names->loc->path->full_path_r)) { + const char *full_path; /* Full path of current object */ + const char *full_suffix; /* Suffix of full path, after src_path */ + char *new_full_path; /* New full path of object */ + size_t new_full_len; /* Length of new full path */ + H5RS_str_t *src_path_r; /* Full path of source name */ + const char *src_path; /* Full path of source object */ + H5RS_str_t *dst_path_r; /* Full path of destination name */ + const char *dst_path; /* Full path of destination object */ + + /* Sanity check */ + HDassert(*(H5RS_get_str(names->loc->path->full_path_r)) == '/'); + HDassert(names->dst_name); + + /* Make certain that the source and destination names are full (not relative) paths */ + src_path_r = H5RS_dup(names->loc->path->full_path_r); + if(*(H5RS_get_str(names->dst_name)) != '/') { + /* Create reference counted string for full dst path */ + if((dst_path_r = H5G_build_fullpath_refstr_refstr(names->dst_loc->path->full_path_r, names->dst_name)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build destination path name") + } /* end if */ + else + dst_path_r = H5RS_dup(names->dst_name); + + /* Get pointers to paths of interest */ + full_path = H5RS_get_str(obj_path->full_path_r); + src_path = H5RS_get_str(src_path_r); + dst_path = H5RS_get_str(dst_path_r); + + /* Get pointer to "full suffix" */ + full_suffix = full_path + HDstrlen(src_path); + + /* Update the user path, if one exists */ + if(obj_path->user_path_r) + if(H5G_name_move_path(&(obj_path->user_path_r), full_suffix, src_path, dst_path) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build user path name") + + /* Build new full path */ + + /* Allocate space for the new full path */ + new_full_len = HDstrlen(dst_path) + HDstrlen(full_suffix); + if(NULL == (new_full_path = H5FL_BLK_MALLOC(str_buf, new_full_len + 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Create the new full path */ + HDstrcpy(new_full_path, dst_path); + HDstrcat(new_full_path, full_suffix); + + /* Release previous full path */ + H5RS_decr(obj_path->full_path_r); + + /* Take ownership of the new full path */ + obj_path->full_path_r = H5RS_own(new_full_path); + + /* Release source & destination full paths */ + H5RS_decr(src_path_r); + H5RS_decr(dst_path_r); } /* end if */ break; default: - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid call") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid operation") } /* end switch */ done: @@ -789,10 +871,9 @@ done: * * Purpose: Search the list of open IDs and replace names according to a * particular operation. The operation occured on the LOC - * entry, which had SRC_NAME previously. The new name (if there - * is one) is DST_NAME. Additional entry location information - * (currently only needed for the 'move' operation) is passed - * in SRC_LOC and DST_LOC. + * entry. The new name (if there is one) is DST_NAME. + * Additional entry location information (currently only needed + * for the 'move' operation) is passed in DST_LOC. * * Return: Success: 0, Failure: -1 * @@ -804,75 +885,92 @@ done: */ herr_t H5G_name_replace(H5G_obj_t type, H5G_loc_t *loc, - H5RS_str_t *src_name, H5G_loc_t *src_loc, H5RS_str_t *dst_name, H5G_loc_t *dst_loc, H5G_names_op_t op) { - H5G_names_t names; /* Structure to hold operation information for callback */ - unsigned search_group = 0; /* Flag to indicate that groups are to be searched */ - unsigned search_dataset = 0; /* Flag to indicate that datasets are to be searched */ - unsigned search_datatype = 0; /* Flag to indicate that datatypes are to be searched */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(H5G_name_replace, FAIL) - /* Set up common information for callback */ - names.src_name = src_name; - names.dst_name = dst_name; - names.loc = loc; - names.src_loc = src_loc; - names.dst_loc = dst_loc; - names.op = op; - - /* Determine which types of IDs need to be operated on */ - switch(type) { - /* Object is a group */ - case H5G_GROUP: - /* Search and replace names through group IDs */ - search_group = 1; - break; - - /* Object is a dataset */ - case H5G_DATASET: - /* Search and replace names through dataset IDs */ - search_dataset = 1; - break; - - /* Object is a named datatype */ - case H5G_TYPE: - /* Search and replace names through datatype IDs */ - search_datatype = 1; - break; - - case H5G_UNKNOWN: /* We pass H5G_UNKNOWN as object type when we need to search all IDs */ - case H5G_LINK: /* Symbolic links might resolve to any object, so we need to search all IDs */ - /* Check if we will need to search groups */ - if(H5I_nmembers(H5I_GROUP) > 0) + /* Check if the object we are manipulating has a path */ + if(loc->path->full_path_r) { + unsigned search_group = 0; /* Flag to indicate that groups are to be searched */ + unsigned search_dataset = 0; /* Flag to indicate that datasets are to be searched */ + unsigned search_datatype = 0; /* Flag to indicate that datatypes are to be searched */ + + /* Determine which types of IDs need to be operated on */ + switch(type) { + /* Object is a group */ + case H5G_GROUP: + /* Search and replace names through group IDs */ search_group = 1; + break; - /* Check if we will need to search datasets */ - if(H5I_nmembers(H5I_DATASET) > 0) + /* Object is a dataset */ + case H5G_DATASET: + /* Search and replace names through dataset IDs */ search_dataset = 1; + break; - /* Check if we will need to search datatypes */ - if(H5I_nmembers(H5I_DATATYPE) > 0) + /* Object is a named datatype */ + case H5G_TYPE: + /* Search and replace names through datatype IDs */ search_datatype = 1; - break; - - default: - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not valid object type"); - } /* end switch */ - - /* Search through group IDs */ - if(search_group) - H5I_search(H5I_GROUP, H5G_name_replace_cb, &names); - - /* Search through dataset IDs */ - if(search_dataset) - H5I_search(H5I_DATASET, H5G_name_replace_cb, &names); - - /* Search through datatype IDs */ - if(search_datatype) - H5I_search(H5I_DATATYPE, H5G_name_replace_cb, &names); + break; + + case H5G_UNKNOWN: /* We pass H5G_UNKNOWN as object type when we need to search all IDs */ + case H5G_LINK: /* Symbolic links might resolve to any object, so we need to search all IDs */ + /* Check if we will need to search groups */ + if(H5I_nmembers(H5I_GROUP) > 0) + search_group = 1; + + /* Check if we will need to search datasets */ + if(H5I_nmembers(H5I_DATASET) > 0) + search_dataset = 1; + + /* Check if we will need to search datatypes */ + if(H5I_nmembers(H5I_DATATYPE) > 0) + search_datatype = 1; + break; + + default: + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not valid object type") + } /* end switch */ + + /* Check if we need to operate on the objects affected */ + if(search_group || search_dataset || search_datatype) { + H5G_names_t names; /* Structure to hold operation information for callback */ + H5F_t *top_loc_file; /* Top file in src location's mounted file hier. */ + + /* Find top file in src location's mount hierarchy */ + if(loc->oloc->file->mtab.parent) { + /* Find the "top" file in the chain of mounted files for the location */ + top_loc_file = loc->oloc->file->mtab.parent; + while(top_loc_file->mtab.parent != NULL) + top_loc_file = top_loc_file->mtab.parent; + } /* end if */ + else + top_loc_file = loc->oloc->file; + + /* Set up common information for callback */ + names.loc = loc; + names.top_loc_file = top_loc_file; + names.dst_loc = dst_loc; + names.dst_name = dst_name; + names.op = op; + + /* Search through group IDs */ + if(search_group) + H5I_search(H5I_GROUP, H5G_name_replace_cb, &names); + + /* Search through dataset IDs */ + if(search_dataset) + H5I_search(H5I_DATASET, H5G_name_replace_cb, &names); + + /* Search through datatype IDs */ + if(search_datatype) + H5I_search(H5I_DATATYPE, H5G_name_replace_cb, &names); + } /* end if */ + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5Gnode.c b/src/H5Gnode.c index ca605b8..1f0ae62 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -49,6 +49,19 @@ typedef struct H5G_node_key_t { size_t offset; /*offset into heap for name */ } H5G_node_key_t; +/* + * A symbol table node is a collection of symbol table entries. It can + * be thought of as the lowest level of the B-link tree that points to + * a collection of symbol table entries that belong to a specific symbol + * table or group. + */ +typedef struct H5G_node_t { + H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ + /* first field in structure */ + unsigned nsyms; /*number of symbols */ + H5G_entry_t *entry; /*array of symbol table entries */ +} H5G_node_t; + /* Private macros */ #define H5G_NODE_VERS 1 /*symbol table node version number */ #define H5G_NODE_SIZEOF_HDR(F) (H5G_NODE_SIZEOF_MAGIC + 4) @@ -677,15 +690,6 @@ H5G_compute_size(const H5F_t *f, const H5G_node_t UNUSED *sym, size_t *size_ptr) * matzke@llnl.gov * Jun 23 1997 * - * Modifications: - * - * John Mainzer 6/8/05 - * Removed code setting the is_dirty field of the cache info. - * This is no longer pemitted, as the cache code is now - * manageing this field. Since this function uses a call to - * H5AC_set() (which marks the entry dirty automaticly), no - * other change is required. - * *------------------------------------------------------------------------- */ static herr_t @@ -1131,7 +1135,7 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, (insert_into->nsyms - idx) * sizeof(H5G_entry_t)); /* Copy new entry into table */ - H5G_ent_copy(&(insert_into->entry[idx]), &ent, H5G_COPY_SHALLOW); + H5G_ent_copy(&(insert_into->entry[idx]), &ent, H5_COPY_SHALLOW); /* Flag entry as dirty */ insert_into->entry[idx].dirty = TRUE; @@ -1175,21 +1179,6 @@ done: * Programmer: Robb Matzke * Thursday, September 24, 1998 * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002 - * Added `id to name' support. - * - * Quincey Koziol, 2003-03-22 - * Added support for deleting all the entries at once. - * - * John Mainzer, 6/8/05 - * Modified the function to use the new dirtied parameter of - * of H5AC_unprotect() instead of modifying the is_dirty - * field of the cache info. - * *------------------------------------------------------------------------- */ static H5B_ins_t @@ -1432,18 +1421,6 @@ done: * matzke@llnl.gov * Jun 24 1997 * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - * - * Quincey Koziol, 2002-04-22 - * Changed to callback from H5B_iterate - * - * John Mainzer, 6/8/05 - * Modified the function to use the new dirtied parameter of - * of H5AC_unprotect() instead of modifying the is_dirty - * field of the cache info. - * *------------------------------------------------------------------------- */ int @@ -1551,13 +1528,6 @@ done: * Programmer: Raymond Lu * Nov 20, 2002 * - * Modifications: - * - * John Mainzer, 6/17/05 - * Modified the function to use the new dirtied parameter of - * of H5AC_unprotect() instead of modifying the is_dirty - * field of the cache info. - * *------------------------------------------------------------------------- */ int @@ -1603,13 +1573,6 @@ done: * Programmer: Raymond Lu * Nov 20, 2002 * - * Modifications: - * - * John Mainzer, 6/17/05 - * Modified the function to use the new dirtied parameter of - * of H5AC_unprotect() instead of modifying the is_dirty - * field of the cache info. - * *------------------------------------------------------------------------- */ int @@ -2042,15 +2005,6 @@ done: * matzke@llnl.gov * Aug 4 1997 * - * Modifications: - * Robb Matzke, 1999-07-28 - * The ADDR and HEAP arguments are passed by value. - * - * John Mainzer, 6/8/05 - * Modified the function to use the new dirtied parameter of - * of H5AC_unprotect() instead of modifying the is_dirty - * field of the cache info. - * *------------------------------------------------------------------------- */ herr_t diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 903e7a0..aa8250f 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -47,6 +47,7 @@ typedef struct { /* User data for looking up an object in a group */ typedef struct { + H5O_link_t *lnk; /* Link information to set for object */ H5O_loc_t *oloc; /* Object location to set */ } H5G_obj_ud2_t; @@ -819,7 +820,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5G_obj_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk, +H5G_obj_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/) { H5G_obj_ud2_t *udata = (H5G_obj_ud2_t *)_udata; /* User data passed in */ @@ -827,20 +828,34 @@ H5G_obj_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const FUNC_ENTER_NOAPI_NOINIT(H5G_obj_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") + /* Copy link for object */ + if(udata->lnk) { + /* Check if the name in this group resolved to a valid link */ + if(lnk == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + + /* Copy link information */ + if(H5O_copy(H5O_LINK_ID, lnk, udata->lnk) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, H5O_ITER_ERROR, "can't copy link message") + } /* end if */ /* Copy object location for object */ - H5O_loc_copy(udata->oloc, obj_loc->oloc, H5O_COPY_DEEP); + if(udata->oloc) { + /* Check if the name in this group resolved to a valid object */ + if(obj_loc == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + + H5O_loc_copy(udata->oloc, obj_loc->oloc, H5_COPY_DEEP); + } /* end if */ +done: /* Release the group location for the object */ /* (Group traversal callbacks are responsible for either taking ownership * of the group location for the object, or freeing it. - QAK) */ - H5G_loc_free(obj_loc); + if(obj_loc) + H5G_loc_free(obj_loc); -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_obj_find_cb() */ @@ -860,7 +875,7 @@ done: */ herr_t H5G_obj_find(H5G_loc_t *loc, const char *name, unsigned traverse_flags, - H5O_loc_t *obj_oloc, hid_t dxpl_id) + H5O_link_t *lnk, H5O_loc_t *obj_oloc, hid_t dxpl_id) { H5G_obj_ud2_t udata; /* User data for traversal callback */ herr_t ret_value = SUCCEED; /* Return value */ @@ -873,6 +888,7 @@ H5G_obj_find(H5G_loc_t *loc, const char *name, unsigned traverse_flags, HDassert(obj_oloc); /* Set up user data for locating object */ + udata.lnk = lnk; udata.oloc = obj_oloc; /* Traverse group hierarchy to locate object */ diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 80a3413..e40e83c 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -87,19 +87,6 @@ typedef struct H5G_entry_t { } H5G_entry_t; /* - * A symbol table node is a collection of symbol table entries. It can - * be thought of as the lowest level of the B-link tree that points to - * a collection of symbol table entries that belong to a specific symbol - * table or group. - */ -typedef struct H5G_node_t { - H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ - /* first field in structure */ - unsigned nsyms; /*number of symbols */ - H5G_entry_t *entry; /*array of symbol table entries */ -} H5G_node_t; - -/* * Shared information for all open group objects */ struct H5G_shared_t { @@ -319,7 +306,7 @@ H5_DLL herr_t H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name, * Functions that understand symbol table entries. */ H5_DLL herr_t H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src, - H5G_copy_depth_t depth); + H5_copy_depth_t depth); H5_DLL herr_t H5G_ent_reset(H5G_entry_t *ent); H5_DLL herr_t H5G_ent_decode_vec(H5F_t *f, const uint8_t **pp, H5G_entry_t *ent, unsigned n); @@ -381,7 +368,7 @@ H5_DLL H5G_obj_t H5G_obj_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, H5_DLL herr_t H5G_obj_remove(H5O_loc_t *oloc, const char *name, H5G_obj_t *obj_type, hid_t dxpl_id); H5_DLL herr_t H5G_obj_find(H5G_loc_t *loc, const char *name, - unsigned traverse_flags, H5O_loc_t *obj_oloc, hid_t dxpl_id); + unsigned traverse_flags, H5O_link_t *lnk, H5O_loc_t *obj_oloc, hid_t dxpl_id); /* * These functions operate on group hierarchy names. @@ -392,7 +379,7 @@ H5_DLL herr_t H5G_name_set(H5G_name_t *loc, H5G_name_t *obj, const char *name); /* * These functions operate on group "locations" */ -H5_DLL herr_t H5G_loc_copy(H5G_loc_t *dst, H5G_loc_t *src, H5G_copy_depth_t depth); +H5_DLL herr_t H5G_loc_copy(H5G_loc_t *dst, H5G_loc_t *src, H5_copy_depth_t depth); H5_DLL 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); H5_DLL herr_t H5G_loc_exists(const H5G_loc_t *loc, const char *name, hid_t dxpl_id); @@ -405,6 +392,7 @@ H5_DLL htri_t H5G_is_empty_test(hid_t gid); H5_DLL htri_t H5G_has_links_test(hid_t gid, unsigned *nmsgs); H5_DLL htri_t H5G_has_stab_test(hid_t gid); H5_DLL herr_t H5G_lheap_size_test(hid_t gid, size_t *lheap_size); +H5_DLL herr_t H5G_user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsigned *user_path_hidden); #endif /* H5G_TESTING */ #endif diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index fdec753..d05aba0 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -81,17 +81,17 @@ /* Type of operation being performed for call to H5G_name_replace() */ typedef enum { - OP_MOVE = 0, /* H5*move call */ - OP_UNLINK, /* H5Gunlink call */ - OP_MOUNT, /* H5Fmount call */ - OP_UNMOUNT /* H5Funmount call */ + H5G_NAME_MOVE = 0, /* H5*move call */ + H5G_NAME_UNLINK, /* H5Gunlink call */ + H5G_NAME_MOUNT, /* H5Fmount call */ + H5G_NAME_UNMOUNT /* H5Funmount call */ } H5G_names_op_t; /* Structure to store information about the name an object was opened with */ typedef struct { + H5RS_str_t *full_path_r; /* Path to object, as seen from root of current file mounting hierarchy */ H5RS_str_t *user_path_r; /* Path to object, as opened by user */ - H5RS_str_t *canon_path_r; /* Path to object, as found in file */ - unsigned user_path_hidden; /* Whether the user's path is valid */ + unsigned obj_hidden; /* Whether the object is visible in group hier. */ } H5G_name_t; /* Forward declarations (for prototypes & struct definitions) */ @@ -111,14 +111,6 @@ typedef struct { typedef struct H5G_t H5G_t; typedef struct H5G_shared_t H5G_shared_t; -/* Depth of group entry copy */ -/* (Also used for group hier. name copies) */ -typedef enum { - H5G_COPY_SHALLOW, /* Copy from source to destination, including name & old name fields */ - H5G_COPY_CANON, /* Keep user path the same, but deep copy canonical path */ - H5G_COPY_DEEP /* Deep copy from source to destination, including duplicating name & old name fields */ -} H5G_copy_depth_t; - /* * Library prototypes... These are the ones that other packages routinely * call. @@ -160,11 +152,11 @@ H5_DLL herr_t H5G_obj_ent_encode(H5F_t *f, uint8_t **pp, * These functions operate on group hierarchy names. */ H5_DLL herr_t H5G_name_replace(H5G_obj_t type, H5G_loc_t *loc, - H5RS_str_t *src_name, H5G_loc_t *src_loc, H5RS_str_t *dst_name, H5G_loc_t *dst_loc, H5G_names_op_t op); H5_DLL herr_t H5G_name_reset(H5G_name_t *name); -H5_DLL herr_t H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5G_copy_depth_t depth); +H5_DLL herr_t H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth); H5_DLL herr_t H5G_name_free(H5G_name_t *name); +H5_DLL ssize_t H5G_get_name(hid_t id, char *name/*out*/, size_t size); /* * These functions operate on group "locations" @@ -176,3 +168,4 @@ H5_DLL herr_t H5G_loc_reset(H5G_loc_t *loc); H5_DLL herr_t H5G_loc_free(H5G_loc_t *loc); #endif + diff --git a/src/H5Gtest.c b/src/H5Gtest.c index 73511a2..83f561e 100644 --- a/src/H5Gtest.c +++ b/src/H5Gtest.c @@ -23,6 +23,7 @@ #include "H5private.h" /* Generic Functions */ +#include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Gpkg.h" /* Groups */ #include "H5HLprivate.h" /* Local Heaps */ @@ -229,3 +230,89 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5G_lheap_size_test() */ + +/*-------------------------------------------------------------------------- + NAME + H5G_user_path_test + PURPOSE + Retrieve the user path for an ID + USAGE + herr_t H5G_user_path_test(obj_id, user_path, user_path_len) + hid_t obj_id; IN: ID to check + char *user_path; OUT: Pointer to buffer for User path + size_t *user_path_len; OUT: Size of user path + unsigned *obj_hidden; OUT: Whether object is hidden + RETURNS + Non-negative on success, negative on failure + DESCRIPTION + Retrieves the user path for an ID. A zero for the length is returned in + the case of no user path. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t +H5G_user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsigned *obj_hidden) +{ + void *obj_ptr; /* Pointer to object for ID */ + H5G_name_t *obj_path; /* Pointer to group hier. path for obj */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_user_path_test, FAIL) + + /* Sanity check */ + HDassert(user_path_len); + HDassert(obj_hidden); + + /* Get pointer to object for ID */ + if(NULL == (obj_ptr = H5I_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get object for ID") + + /* Get the symbol table entry */ + switch(H5I_get_type(obj_id)) { + case H5I_GROUP: + obj_path = H5G_nameof((H5G_t *)obj_ptr); + break; + + case H5I_DATASET: + obj_path = H5D_nameof((H5D_t *)obj_ptr); + break; + + case H5I_DATATYPE: + /* Avoid non-named datatypes */ + if(!H5T_is_named((H5T_t *)obj_ptr)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a named datatype") + + obj_path = H5T_nameof((H5T_t *)obj_ptr); + break; + + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object type") + } /* end switch */ + HDassert(obj_path); + + /* Retrieve a copy of the user path and put it into the buffer */ + if(obj_path->user_path_r) { + size_t len = H5RS_len(obj_path->user_path_r); + + /* Set the user path, if given */ + if(user_path) + HDstrcpy(user_path, H5RS_get_str(obj_path->user_path_r)); + + /* Set the length of the path */ + *user_path_len = len; + + /* Set the user path hidden flag */ + *obj_hidden = obj_path->obj_hidden; + } /* end if */ + else { + *user_path_len = 0; + *obj_hidden = 0; + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5G_user_path_test() */ + diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index c43ffbb..8a53064 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -48,7 +48,7 @@ static char *H5G_comp_g = NULL; /*component buffer */ static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */ /* PRIVATE PROTOTYPES */ -static herr_t H5G_traverse_slink_cb(H5G_loc_t *grp_loc/*in*/, const char *name, +static herr_t H5G_traverse_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); static herr_t H5G_traverse_slink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk, H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t dxpl_id); @@ -87,9 +87,9 @@ H5G_traverse_term_interface(void) /*------------------------------------------------------------------------- - * Function: H5G_traverse_slink_cb + * Function: H5G_traverse_link_cb * - * Purpose: Callback for symbolic link traversal. This routine sets the + * Purpose: Callback for link traversal. This routine sets the * correct information for the object location. * * Return: Non-negative on success/Negative on failure @@ -100,20 +100,20 @@ H5G_traverse_term_interface(void) *------------------------------------------------------------------------- */ static herr_t -H5G_traverse_slink_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, const H5O_link_t UNUSED *lnk, +H5G_traverse_link_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, const H5O_link_t UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/) { H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_slink_cb) + FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_link_cb) /* Check for dangling soft link */ if(obj_loc == NULL) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found") /* Copy new location information for resolved object */ - H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5O_COPY_DEEP); + H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5_COPY_DEEP); done: /* Release the group location for the object */ @@ -124,7 +124,7 @@ done: H5G_loc_free(obj_loc); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_traverse_slink_cb() */ +} /* end H5G_traverse_link_cb() */ /*------------------------------------------------------------------------- @@ -172,32 +172,32 @@ H5G_traverse_slink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk, /* Portably initialize the temporary objects */ H5G_loc_reset(&tmp_grp_loc); + H5G_name_reset(&tmp_obj_path); /* Clone the group location, so we can track the names properly */ /* ("tracking the names properly" means to ignore the effects of the - * soft link traversal on the object's & group's paths - QAK) + * link traversal on the object's & group's paths - QAK) */ - H5G_loc_copy(&tmp_grp_loc, grp_loc, H5G_COPY_DEEP); + H5G_loc_copy(&tmp_grp_loc, grp_loc, H5_COPY_DEEP); tmp_grp_path_set = TRUE; /* Hold the object's group hier. path to restore later */ /* (Part of "tracking the names properly") */ - H5G_name_reset(&tmp_obj_path); - H5G_name_copy(&tmp_obj_path, obj_loc->path, H5G_COPY_SHALLOW); + H5G_name_copy(&tmp_obj_path, obj_loc->path, H5_COPY_SHALLOW); tmp_obj_path_set = TRUE; /* Set up user data for traversal callback */ udata.obj_loc = obj_loc; - /* Traverse to the link's last component */ - if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, H5G_TARGET_NORMAL, nlinks, H5G_traverse_slink_cb, &udata, dxpl_id) < 0) + /* Traverse the link */ + if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, H5G_TARGET_NORMAL, nlinks, H5G_traverse_link_cb, &udata, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link") done: /* Restore object's group hier. path */ if(tmp_obj_path_set) { H5G_name_free(obj_loc->path); - H5G_name_copy(obj_loc->path, &tmp_obj_path, H5G_COPY_SHALLOW); + H5G_name_copy(obj_loc->path, &tmp_obj_path, H5_COPY_SHALLOW); } /* end if */ /* Release cloned copy of group path */ @@ -259,20 +259,13 @@ H5G_traverse_mount(H5G_loc_t *obj_loc/*in,out*/) /* Copy root info over to ENT */ if(0 == cmp) { - H5G_name_t *root_path; /* Path of root group */ - /* Get the location for the root group in the child's file */ oloc = H5G_oloc(parent->mtab.child[md].file->shared->root_grp); - root_path = H5G_nameof(parent->mtab.child[md].file->shared->root_grp); /* Copy the entry for the root group */ - if(H5O_loc_copy(obj_loc->oloc, oloc, H5O_COPY_DEEP) < 0) + if(H5O_loc_copy(obj_loc->oloc, oloc, H5_COPY_DEEP) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location") - /* Don't lose the user path of the group when we copy the root group's path */ - if(H5G_name_copy(obj_loc->path, root_path, H5G_COPY_CANON) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object path") - /* Switch to child's file */ parent = oloc->file; } /* end if */ @@ -353,8 +346,14 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, obj_loc.oloc = &obj_oloc; obj_loc.path = &obj_path; +#if defined(H5_USING_PURIFY) || !defined(NDEBUG) + /* Clear group location */ + if(H5G_loc_reset(&grp_loc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to reset location") +#endif /* H5_USING_PURIFY */ + /* Deep copy of the starting location to group location */ - if(H5G_loc_copy(&grp_loc, &loc, H5G_COPY_DEEP) < 0) + if(H5G_loc_copy(&grp_loc, &loc, H5_COPY_DEEP) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to copy location") group_copy = TRUE; @@ -403,7 +402,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, } /* end if */ /* Get information for object in current group */ - /* (Defer issuing error for back lookup until later) */ + /* (Defer issuing error for bad lookup until later) */ lookup_status = H5G_obj_lookup(grp_loc.oloc, H5G_comp_g, &lnk/*out*/, dxpl_id); /* If the lookup was OK, try traversing soft links and mount points, if allowed */ @@ -430,9 +429,9 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, if(H5G_LINK_SOFT == lnk.type && (0 == (target & H5G_TARGET_SLINK) || !last_comp)) { if((*nlinks)-- <= 0) - HGOTO_ERROR(H5E_SYM, H5E_SLINK, FAIL, "too many links") + HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "too many links") if(H5G_traverse_slink(&grp_loc/*in,out*/, &lnk/*in*/, &obj_loc, nlinks, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "symbolic link traversal failed") + HGOTO_ERROR(H5E_SYM, H5E_SLINK, FAIL, "symbolic link traversal failed") } /* end if */ /* @@ -510,7 +509,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Transfer "ownership" of the object's information to the group object */ H5G_loc_free(&grp_loc); - H5G_loc_copy(&grp_loc, &obj_loc, H5G_COPY_SHALLOW); + H5G_loc_copy(&grp_loc, &obj_loc, H5_COPY_SHALLOW); H5G_loc_reset(&obj_loc); obj_loc_valid = FALSE; @@ -1825,29 +1825,25 @@ done: * Failure: NULL * * Programmer: James Laird - * Nathaniel Furrer + * Nathaniel Furrer * Friday, April 23, 2004 * - * Modifications: - * *------------------------------------------------------------------------- */ void *H5Isearch(H5I_type_t type, H5I_search_func_t func, void *key) { - void * ret_value; /* Return value */ + void * ret_value; /* Return value */ - FUNC_ENTER_API(H5Isearch, NULL); + FUNC_ENTER_API(H5Isearch, NULL) - if( H5I_IS_LIB_TYPE( type ) ) - { - HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type"); - } + if( H5I_IS_LIB_TYPE( type ) ) + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, NULL, "cannot call public function on library type") - ret_value = H5I_search(type, func, key); + ret_value = H5I_search(type, func, key); - done: - FUNC_LEAVE_API(ret_value); -} +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Isearch() */ /*------------------------------------------------------------------------- @@ -1997,35 +1993,19 @@ H5I_find_id(hid_t id) * If a zero is returned for the name's length, then there is no name * associated with the ID. * - * Modifications: - * *------------------------------------------------------------------------- */ ssize_t H5Iget_name(hid_t id, char *name/*out*/, size_t size) { - H5G_loc_t loc; /* Object location */ - size_t len = 0; ssize_t ret_value; FUNC_ENTER_API(H5Iget_name, FAIL) H5TRACE3("Zs","ixz",id,name,size); - /* get object location */ - if(H5G_loc(id, &loc) >= 0) { - if(loc.path->user_path_r != NULL && loc.path->user_path_hidden == 0) { - len = H5RS_len(loc.path->user_path_r); - - if(name) { - HDstrncpy(name, H5RS_get_str(loc.path->user_path_r), MIN(len + 1, size)); - if(len >= size) - name[size-1] = '\0'; - } /* end if */ - } /* end if */ - } /* end if */ - - /* Set return value */ - ret_value = (ssize_t)len; + /* Call internal group routine to retrieve object's name */ + if((ret_value = H5G_get_name(id, name, size)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object name") done: FUNC_LEAVE_API(ret_value) @@ -3969,32 +3969,32 @@ H5O_loc_reset(H5O_loc_t *loc) * * Notes: 'depth' parameter determines how much of the group entry * structure we want to copy. The values are: - * H5O_COPY_SHALLOW - Copy all the field values from the source + * H5_COPY_SHALLOW - Copy all the field values from the source * to the destination, but not copying objects pointed to. * (Destination "takes ownership" of objects pointed to) - * H5O_COPY_DEEP - Copy all the fields from the source to + * H5_COPY_DEEP - Copy all the fields from the source to * the destination, deep copying objects pointed to. * *------------------------------------------------------------------------- */ herr_t -H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5O_copy_depth_t depth) +H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5_copy_depth_t depth) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_loc_copy) /* Check arguments */ HDassert(src); HDassert(dst); - HDassert(depth == H5O_COPY_SHALLOW || depth == H5O_COPY_DEEP); + HDassert(depth == H5_COPY_SHALLOW || depth == H5_COPY_DEEP); /* Copy the top level information */ HDmemcpy(dst, src, sizeof(H5O_loc_t)); /* Deep copy the names */ - if(depth == H5G_COPY_DEEP) { + if(depth == H5_COPY_DEEP) { /* Nothing currently */ ; - } else if(depth == H5G_COPY_SHALLOW) { + } else if(depth == H5_COPY_SHALLOW) { /* Discarding 'const' qualifier OK - QAK */ H5O_loc_reset((H5O_loc_t *)src); } /* end if */ diff --git a/src/H5Odtype.c b/src/H5Odtype.c index af2a6c7..fc3f641 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -1123,7 +1123,7 @@ H5O_dtype_get_share(H5F_t UNUSED *f, const void *_mesg, HDassert(H5T_STATE_NAMED == dt->shared->state || H5T_STATE_OPEN == dt->shared->state); /* Copy object location info */ - H5O_loc_copy(&(sh->oloc), &(dt->oloc), H5O_COPY_DEEP); + H5O_loc_copy(&(sh->oloc), &(dt->oloc), H5_COPY_DEEP); done: FUNC_LEAVE_NOAPI(ret_value) @@ -1154,7 +1154,7 @@ H5O_dtype_set_share(H5F_t UNUSED *f, void *_mesg/*in,out*/, HDassert(sh); /* Retrieve object location information */ - H5O_loc_copy(&(dt->oloc), &(sh->oloc), H5O_COPY_DEEP); + H5O_loc_copy(&(dt->oloc), &(sh->oloc), H5_COPY_DEEP); /* Note that the datatype is a named datatype */ dt->shared->state = H5T_STATE_NAMED; diff --git a/src/H5Olink.c b/src/H5Olink.c index 062359b..d9c84c7 100644 --- a/src/H5Olink.c +++ b/src/H5Olink.c @@ -409,9 +409,7 @@ H5O_link_free(void *_mesg) HDassert(lnk); /* Free information for link */ - if(lnk->type == H5G_LINK_SOFT) - lnk->u.soft.name = H5MM_xfree(lnk->u.soft.name); - lnk->name = H5MM_xfree(lnk->name); + H5O_link_reset(lnk); H5FL_FREE(H5O_link_t, lnk); FUNC_LEAVE_NOAPI(SUCCEED) diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 415ef03..b257e98 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -287,12 +287,6 @@ typedef struct H5O_stab_t { typedef herr_t (*H5O_operator_t)(const void *mesg/*in*/, unsigned idx, void *operator_data/*in,out*/); -/* Depth of object location copy */ -typedef enum { - H5O_COPY_SHALLOW, /* Copy from source to destination, just copy field pointers */ - H5O_COPY_DEEP /* Deep copy from source to destination, including duplicating fields pointed to */ -} H5O_copy_depth_t; - /* Forward declarations for prototype arguments */ struct H5SL_t; struct H5O_t; @@ -354,7 +348,7 @@ H5_DLL herr_t H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, in * These functions operate on object locations */ H5_DLL herr_t H5O_loc_reset(H5O_loc_t *loc); -H5_DLL herr_t H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5O_copy_depth_t depth); +H5_DLL herr_t H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5_copy_depth_t depth); /* Layout operators */ H5_DLL size_t H5O_layout_meta_size(const H5F_t *f, const void *_mesg); @@ -315,7 +315,7 @@ H5RS_dup(H5RS_str_t *ret_value) /*-------------------------------------------------------------------------- NAME - H5RS_dup + H5RS_dup_str PURPOSE "Duplicate" a regular string into a ref-counted string USAGE @@ -338,7 +338,7 @@ H5RS_dup_str(const char *s) size_t path_len; /* Length of the path */ H5RS_str_t *ret_value; - FUNC_ENTER_NOAPI(H5RS_dup_str, FAIL) + FUNC_ENTER_NOAPI(H5RS_dup_str, NULL) /* Sanity check */ HDassert(s); @@ -3209,9 +3209,18 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method) if(new_dt->shared->state == H5T_STATE_NAMED || new_dt->shared->state == H5T_STATE_OPEN) { if(!H5F_addr_defined(old_dt->oloc.addr)) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "named dataype with invalid address") - if(H5O_loc_copy(&(new_dt->oloc), &(old_dt->oloc), H5O_COPY_DEEP) < 0) +#if defined(H5_USING_PURIFY) || !defined(NDEBUG) + /* Clear object location */ + if(H5O_loc_reset(&(new_dt->oloc)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to reset location") + + /* Clear path name */ + if(H5G_name_reset(&(new_dt->path)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to reset path") +#endif /* H5_USING_PURIFY */ + if(H5O_loc_copy(&(new_dt->oloc), &(old_dt->oloc), H5_COPY_DEEP) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to copy entry") - if(H5G_name_copy(&(new_dt->path), &(old_dt->path), H5G_COPY_DEEP) < 0) + if(H5G_name_copy(&(new_dt->path), &(old_dt->path), H5_COPY_DEEP) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to copy path") } /* end if */ else { diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index 3e5e0eb..3866db1 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -485,12 +485,22 @@ H5T_open(H5G_loc_t *loc, hid_t dxpl_id) if(NULL == (dt = H5FL_MALLOC(H5T_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for datatype") +#if defined(H5_USING_PURIFY) || !defined(NDEBUG) + /* Clear object location */ + if(H5O_loc_reset(&(dt->oloc)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to reset location") + + /* Clear path name */ + if(H5G_name_reset(&(dt->path)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to reset path") +#endif /* H5_USING_PURIFY */ + /* Shallow copy (take ownership) of the object location object */ - if(H5O_loc_copy(&(dt->oloc), loc->oloc, H5O_COPY_SHALLOW) < 0) + if(H5O_loc_copy(&(dt->oloc), loc->oloc, H5_COPY_SHALLOW) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy object location") /* Shallow copy (take ownership) of the group hier. path */ - if(H5G_name_copy(&(dt->path), loc->path, H5G_COPY_SHALLOW) < 0) + if(H5G_name_copy(&(dt->path), loc->path, H5_COPY_SHALLOW) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy path") dt->shared = shared_fo; @@ -560,11 +570,11 @@ H5T_open_oid(H5G_loc_t *loc, hid_t dxpl_id) dt->shared->state = H5T_STATE_OPEN; /* Shallow copy (take ownership) of the object location object */ - if(H5O_loc_copy(&(dt->oloc), loc->oloc, H5O_COPY_SHALLOW) < 0) + if(H5O_loc_copy(&(dt->oloc), loc->oloc, H5_COPY_SHALLOW) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy object location") /* Shallow copy (take ownership) of the group hier. path */ - if(H5G_name_copy(&(dt->path), loc->path, H5G_COPY_SHALLOW) < 0) + if(H5G_name_copy(&(dt->path), loc->path, H5_COPY_SHALLOW) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy path") /* Set return value */ diff --git a/src/H5private.h b/src/H5private.h index 088551e..1b904e3 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -537,6 +537,12 @@ H5_DLL void H5_timer_end (H5_timer_t *sum/*in,out*/, H5_timer_t *timer/*in,out*/); H5_DLL void H5_bandwidth(char *buf/*out*/, double nbytes, double nseconds); +/* Depth of object copy */ +typedef enum { + H5_COPY_SHALLOW, /* Shallow copy from source to destination, just copy field pointers */ + H5_COPY_DEEP /* Deep copy from source to destination, including duplicating fields pointed to */ +} H5_copy_depth_t; + /* * Redefine all the POSIX functions. We should never see a POSIX * function (or any other non-HDF5 function) in the source! |