summaryrefslogtreecommitdiffstats
path: root/src/H5G.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5G.c')
-rw-r--r--src/H5G.c213
1 files changed, 172 insertions, 41 deletions
diff --git a/src/H5G.c b/src/H5G.c
index 2fc408c..4582a0d 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -107,6 +107,7 @@ typedef struct {
typedef struct {
H5G_stat_t *statbuf; /* Stat buffer about object */
hbool_t follow_link; /* Whether we are following a link or not */
+ H5F_t *loc_file; /* Pointer to the file the location is in */
hid_t dxpl_id; /* Dataset transfer property list */
} H5G_trav_ud4_t;
@@ -116,6 +117,14 @@ typedef struct {
hid_t dxpl_id; /* Dataset transfer property list */
} H5G_trav_ud7_t;
+/* User data for path traversal routine for getting external link name */
+typedef struct {
+ hbool_t want_file_name; /* Whether to retrieve file name (or object name) */
+ size_t size; /* Size of user buffer */
+ char *lname; /* User name buffer */
+ size_t name_len; /* Full length of name found */
+} H5G_trav_ud8_t;
+
/* Package variables */
/* Local variables */
@@ -128,13 +137,15 @@ H5FL_DEFINE(H5G_shared_t);
static H5G_t *H5G_create(H5F_t *file, hid_t dxpl_id, hid_t gcpl_id, hid_t gapl_id);
static herr_t H5G_open_oid(H5G_t *grp, hid_t dxpl_id);
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*/);
+ const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
+ hbool_t *own_obj_loc/*out*/);
static herr_t H5G_set_comment(H5G_loc_t *loc, const char *name,
const char *buf, hid_t dxpl_id);
static int H5G_get_comment(H5G_loc_t *loc, const char *name,
size_t bufsize, char *buf, hid_t dxpl_id);
static herr_t H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char *name,
- const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/);
+ const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
+ hbool_t *own_obj_loc/*out*/);
static herr_t H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name,
hid_t ocpypl_id, hid_t lcpl_id);
@@ -224,17 +235,17 @@ H5Gcreate(hid_t loc_id, const char *name, size_t size_hint)
/* Create the group */
if(NULL == (grp = H5G_create(file, H5AC_dxpl_id, tmp_gcpl, H5P_DEFAULT)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
if((grp_id = H5I_register(H5I_GROUP, grp)) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
if(H5G_loc(grp_id, &grp_loc) <0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to get location for new group")
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get location for new group")
/* Link the group */
- if( H5L_link(&loc, name, &grp_loc, H5AC_dxpl_id, H5P_DEFAULT) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to create link to group")
+ if( H5L_link(&loc, name, &grp_loc, H5P_DEFAULT, H5P_DEFAULT, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link to group")
ret_value = grp_id;
@@ -314,14 +325,12 @@ H5Gcreate_expand(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id)
if(TRUE != H5P_isa_class(gcpl_id, H5P_GROUP_CREATE))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group create property list")
-#ifdef LATER
/* Check the group access property list */
if(H5P_DEFAULT == gapl_id)
gapl_id = H5P_GROUP_ACCESS_DEFAULT;
else
if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
-#endif /* LATER */
if(NULL == (grp = H5G_create(loc.oloc->file, H5AC_dxpl_id, gcpl_id, gapl_id)))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
@@ -382,7 +391,7 @@ H5Gopen(hid_t loc_id, const char *name)
H5G_loc_reset(&grp_loc);
/* Find the group object */
- if(H5G_loc_find(&loc, name, &grp_loc/*out*/, H5AC_dxpl_id) < 0)
+ if(H5G_loc_find(&loc, name, &grp_loc/*out*/, H5P_DEFAULT, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
ent_found = TRUE;
@@ -413,6 +422,86 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Gopen_expand
+ *
+ * Purpose: Opens an existing group for modification. When finished,
+ * call H5Gclose() to close it and release resources.
+ *
+ * This function allows the user the pass in a Group Access
+ * Property List, which H5Gopen() does not.
+ *
+ * Return: Success: Object ID of the group.
+ * Failure: FAIL
+ *
+ * Programmer: James Laird
+ * Thursday, July 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Gopen_expand(hid_t loc_id, const char *name, hid_t gapl_id)
+{
+ H5G_t *grp = NULL;
+ H5G_loc_t loc;
+ H5G_loc_t grp_loc; /* Location used to open group */
+ H5G_name_t grp_path; /* Opened object group hier. path */
+ H5O_loc_t grp_oloc; /* Opened object object location */
+ hbool_t ent_found = FALSE; /* Entry at 'name' found */
+ hid_t ret_value=FAIL; /* Return value */
+
+ FUNC_ENTER_API(H5Gopen_expand, FAIL);
+ H5TRACE3("i","isi",loc_id,name,gapl_id);
+
+ /* Check args */
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Check the group access property list */
+ if(H5P_DEFAULT == gapl_id)
+ gapl_id = H5P_GROUP_ACCESS_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
+
+ /* Set up opened group location to fill in */
+ grp_loc.oloc = &grp_oloc;
+ grp_loc.path = &grp_path;
+ H5G_loc_reset(&grp_loc);
+
+ /* Find the group object using the gapl passed in */
+ if(H5G_loc_find(&loc, name, &grp_loc/*out*/, gapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
+ ent_found = TRUE;
+
+ /* Check that the object found is the correct type */
+ if(H5O_obj_type(&grp_oloc, H5AC_dxpl_id) != H5G_GROUP)
+ HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not a group")
+
+ /* Open the group */
+ if((grp = H5G_open(&grp_loc, H5AC_dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
+
+ /* Register an atom for the group */
+ if((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
+
+done:
+ if(ret_value < 0) {
+ if(grp != NULL)
+ H5G_close(grp);
+ else {
+ if(ent_found)
+ H5G_name_free(&grp_path);
+ } /* end else */
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5Gclose
*
* Purpose: Closes the specified group. The group ID will no longer be
@@ -442,7 +531,7 @@ H5Gclose(hid_t group_id)
* reaches zero.
*/
if (H5I_dec_ref(group_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close group");
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group");
done:
FUNC_LEAVE_API(ret_value);
@@ -920,7 +1009,7 @@ H5Gcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
H5G_loc_reset(&src_loc);
/* Find the source object to copy */
- if(H5G_loc_find(&loc, src_name, &src_loc/*out*/, H5AC_dxpl_id) < 0)
+ if(H5G_loc_find(&loc, src_name, &src_loc/*out*/, H5P_DEFAULT, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found")
ent_found = TRUE;
@@ -985,7 +1074,7 @@ done:
static herr_t
H5G_init_interface(void)
{
- H5P_genclass_t *crt_pclass, *cpy_pclass;
+ H5P_genclass_t *crt_pclass, *acc_pclass, *cpy_pclass;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5G_init_interface);
@@ -1009,16 +1098,30 @@ H5G_init_interface(void)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class")
} /* end if */
+ /* ========== Group Access Property Class Initialization ============*/
+ assert(H5P_CLS_GROUP_ACCESS_g!=-1);
+
+ /* Get the pointer to group creation class */
+ if(NULL == (acc_pclass = H5I_object(H5P_CLS_GROUP_ACCESS_g)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
+
+ /* Only register the default property list if it hasn't been created yet */
+ if(H5P_LST_GROUP_ACCESS_g == (-1)) {
+ /* Register the default group creation property list */
+ if((H5P_LST_GROUP_ACCESS_g = H5P_create_id(acc_pclass))<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class")
+ } /* end if */
+
/* ========== Object Copy Property Class Initialization ============*/
assert(H5P_CLS_OBJECT_COPY_g!=-1);
- /* Get the pointer to group copy class */
+ /* Get the pointer to group access class */
if(NULL == (cpy_pclass = H5I_object(H5P_CLS_OBJECT_COPY_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class")
/* Only register the default property list if it hasn't been created yet */
if(H5P_LST_OBJECT_COPY_g == (-1)) {
- /* Register the default group copy property list */
+ /* Register the default group access property list */
if((H5P_LST_OBJECT_COPY_g = H5P_create_id(cpy_pclass))<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't insert property into class")
} /* end if */
@@ -1241,7 +1344,7 @@ H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *loc)
loc->oloc/*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry")
if(1 != H5O_link(loc->oloc, 1, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "internal error (wrong link count)")
+ HGOTO_ERROR(H5E_SYM, H5E_LINKCOUNT, FAIL, "internal error (wrong link count)")
} else {
/*
* Open the root object as a group.
@@ -1736,7 +1839,7 @@ H5G_fileof(H5G_t *grp)
*/
static herr_t
H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk,
- H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
H5G_trav_ud4_t *udata = (H5G_trav_ud4_t *)_udata; /* User data passed in */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1759,17 +1862,11 @@ H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_
if(H5F_get_fileno((obj_loc ? obj_loc : grp_loc)->oloc->file, &statbuf->fileno[0]) < 0)
HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "unable to read fileno")
- /* Get info for soft link */
- /* (If we don't follow the link, we can retrieve info about the soft link itself) */
- if(!udata->follow_link && lnk && lnk->type == H5L_LINK_SOFT) {
- /* Set object type */
- statbuf->type = H5G_LINK;
+ /* Info for soft and UD links is gotten by H5L_get_linkinfo. If we have
+ * a hard link, follow it and get info on the object */
+ if(udata->follow_link || !lnk ||
+ (lnk->type == H5L_LINK_HARD)) {
- /* Get length of link value */
- statbuf->linklen = HDstrlen(lnk->u.soft.name) + 1; /*count the null terminator*/
- } /* end if */
- /* Get info for hard link */
- else {
/* Get object type */
statbuf->type = H5O_obj_type(obj_loc->oloc, udata->dxpl_id);
if(statbuf->type == H5G_UNKNOWN)
@@ -1796,16 +1893,13 @@ H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_
/* Get object header information */
if(H5O_get_info(obj_loc->oloc, &(statbuf->ohdr), udata->dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object header information")
- } /* end else */
+ } /* end if */
} /* 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)
- */
- if(obj_loc)
- H5G_loc_free(obj_loc);
+ /* Indicate that this callback didn't take ownership of the group *
+ * location for the object */
+ *own_obj_loc = FALSE;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_get_objinfo_cb() */
@@ -1842,13 +1936,46 @@ H5G_get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link,
/* Set up user data for retrieving information */
udata.statbuf = statbuf;
udata.follow_link = follow_link;
+ udata.loc_file = loc->oloc->file;
udata.dxpl_id = dxpl_id;
/* Traverse the group hierarchy to locate the object to get info about */
- if(H5G_traverse(loc, name, (unsigned)(follow_link ? H5G_TARGET_NORMAL : H5G_TARGET_SLINK),
- H5G_get_objinfo_cb, &udata, dxpl_id) < 0)
+ if(H5G_traverse(loc, name, (unsigned)(follow_link ? H5G_TARGET_NORMAL : H5G_TARGET_SLINK|H5G_TARGET_UDLINK),
+ H5G_get_objinfo_cb, &udata, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist")
+ /* Assign object type and link length for soft links and UD links */
+ /* The default linklen (for non-links) is 0. */
+ if(statbuf)
+ statbuf->linklen = 0;
+
+ /* If we're pointing at a soft or UD link, get the real link length and type */
+ if(statbuf && follow_link == 0)
+ {
+ H5L_linkinfo_t linfo; /* Link information buffer */
+ herr_t ret;
+
+ /* Get information about link to the object. If this fails, e.g.
+ * because the object is ".", just treat the object as a hard link. */
+ H5E_BEGIN_TRY {
+ ret = H5L_get_linkinfo(loc, name, &linfo, H5P_DEFAULT, dxpl_id);
+ } H5E_END_TRY
+
+ if(ret >=0 && linfo.linkclass != H5L_LINK_HARD)
+ {
+ statbuf->linklen = linfo.u.link_size;
+ if(linfo.linkclass == H5L_LINK_SOFT)
+ {
+ statbuf->type = H5G_LINK;
+ }
+ else /* UD link. H5L_get_linkinfo checked for invalid link classes */
+ {
+ HDassert(linfo.linkclass >= H5L_LINK_UD_MIN && linfo.linkclass <= H5L_LINK_MAX);
+ statbuf->type = H5G_UDLINK;
+ }
+ }
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_get_objinfo() */
@@ -1876,7 +2003,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, NULL, &obj_oloc/*out*/, dxpl_id) < 0)
+ if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, NULL, &obj_oloc/*out*/, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
/* Remove the previous comment message if any */
@@ -1922,7 +2049,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, NULL, &obj_oloc/*out*/, dxpl_id) < 0)
+ if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, NULL, &obj_oloc/*out*/, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
/* Get the message */
@@ -1958,7 +2085,7 @@ done:
*/
static herr_t
H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk,
- H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/, hbool_t *own_obj_loc/*out*/)
{
H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1973,6 +2100,8 @@ H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H
/* Get file pointer for location */
udata->file = grp_loc->oloc->file;
+ *own_obj_loc = FALSE;
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_insertion_file_cb() */
@@ -2016,7 +2145,7 @@ H5G_insertion_file(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
* Look up the name to get the containing group and to make sure the name
* doesn't already exist.
*/
- if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_insertion_file_cb, &udata, dxpl_id) < 0)
+ if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_insertion_file_cb, &udata, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_EXISTS, NULL, "name already exists")
/* Set return value */
@@ -2168,6 +2297,7 @@ H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name,
H5G_loc_t new_loc; /* Group location of object copied */
hbool_t entry_inserted=FALSE; /* Flag to indicate that the new entry was inserted into a group */
unsigned cpy_option = 0; /* Copy options */
+ hid_t gcplist_id = H5P_DEFAULT; /* Group creation property list */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_copy, FAIL);
@@ -2197,7 +2327,7 @@ H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name,
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
/* Insert the new object in the destination file's group */
- if(H5L_link(dst_loc, dst_name, &new_loc, dxpl_id, lcpl_id) < 0)
+ if(H5L_link(dst_loc, dst_name, &new_loc, lcpl_id, H5P_DEFAULT, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link")
entry_inserted = TRUE;
@@ -2209,3 +2339,4 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_copy() */
+