diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2006-11-25 04:10:32 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2006-11-25 04:10:32 (GMT) |
commit | 5c1fedcb9003ab614db83a15723bb0fc0389e3c7 (patch) | |
tree | ec8d663d5767b75a432d3d91c5cbb0a84db55530 /src | |
parent | 2f694358c4c7ae4fa79057ae7d87f95859fbea73 (diff) | |
download | hdf5-5c1fedcb9003ab614db83a15723bb0fc0389e3c7.zip hdf5-5c1fedcb9003ab614db83a15723bb0fc0389e3c7.tar.gz hdf5-5c1fedcb9003ab614db83a15723bb0fc0389e3c7.tar.bz2 |
[svn-r12973] Description:
Finish removing library's internal code that uses H5G_get_objinfo() and
retarget it at either getting the link information or the object information,
as appropriate. (Still need to add user-level tests for H5Oget_info(), but
since several internal components of the library depend on the internal version,
it appears to be working correctly).
Tested on:
FreeBSD/32 4.11 (sleipnir)
Linux/322.4 (heping)
Linux/64 2.4 (mir)
AIX/32 5.? (copper)
Mac OS X/32 10.4.8 (amazon)
Diffstat (limited to 'src')
-rw-r--r-- | src/H5G.c | 271 | ||||
-rw-r--r-- | src/H5Gdeprec.c | 246 | ||||
-rw-r--r-- | src/H5Glink.c | 13 | ||||
-rw-r--r-- | src/H5Gloc.c | 87 | ||||
-rw-r--r-- | src/H5Gname.c | 172 | ||||
-rw-r--r-- | src/H5Gnode.c | 13 | ||||
-rw-r--r-- | src/H5Gprivate.h | 4 | ||||
-rw-r--r-- | src/H5Gpublic.h | 6 | ||||
-rw-r--r-- | src/H5O.c | 204 | ||||
-rw-r--r-- | src/H5Ocache.c | 3 | ||||
-rw-r--r-- | src/H5Ocopy.c | 1 | ||||
-rw-r--r-- | src/H5Odbg.c | 29 | ||||
-rw-r--r-- | src/H5Omtime.c | 4 | ||||
-rw-r--r-- | src/H5Opkg.h | 3 | ||||
-rw-r--r-- | src/H5Oprivate.h | 2 | ||||
-rw-r--r-- | src/H5Opublic.h | 6 | ||||
-rw-r--r-- | src/H5Oshared.c | 43 |
17 files changed, 605 insertions, 502 deletions
@@ -100,29 +100,7 @@ /* User data for path traversal routine for "insertion file" routine */ typedef struct { H5G_loc_t *loc; /* Pointer to the location for insertion */ -} H5G_trav_ud1_t; - -/* User data for path traversal routine for getting object info */ -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; - -/* User data for path traversal routine for inserting object */ -typedef struct { - H5G_loc_t *obj_loc; /* Object location */ - 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; +} H5G_trav_ins_t; /* Package variables */ @@ -135,9 +113,6 @@ H5FL_DEFINE(H5G_shared_t); /* Private prototypes */ 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*/, - H5G_own_loc_t *own_loc/*out*/); static herr_t H5G_insertion_loc_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/); @@ -599,88 +574,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Gget_objtype_by_idx - * - * Purpose: Returns the type of objects in the group by giving index. - * - * - * Return: Success: H5G_GROUP(1), H5G_DATASET(2), H5G_TYPE(3) - * - * Failure: H5G_UNKNOWN - * - * Programmer: Raymond Lu - * Nov 20, 2002 - * - *------------------------------------------------------------------------- - */ -H5G_obj_t -H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx) -{ - H5G_loc_t loc; /* Object location */ - H5O_type_t obj_type; /* Type of object at location */ - H5G_obj_t ret_value; - - FUNC_ENTER_API(H5Gget_objtype_by_idx, H5G_UNKNOWN) - H5TRACE2("Go","ih",loc_id,idx); - - /* Check args */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a location ID") - if(H5O_obj_type(loc.oloc, &obj_type, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object type") - if(obj_type != H5O_TYPE_GROUP) - HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not a group") - - /* Call internal function*/ - if((ret_value = H5G_obj_get_type_by_idx(loc.oloc, idx, H5AC_ind_dxpl_id)) == H5G_UNKNOWN) - HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "can't get object type") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Gget_objtype_by_idx() */ - - -/*------------------------------------------------------------------------- - * Function: H5Gget_objinfo - * - * Purpose: Returns information about an object. If FOLLOW_LINK is - * non-zero then all symbolic links are followed; otherwise all - * links except the last component of the name are followed. - * - * Return: Non-negative on success, with the fields of STATBUF (if - * non-null) initialized. Negative on failure. - * - * Programmer: Robb Matzke - * Monday, April 13, 1998 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, - H5G_stat_t *statbuf/*out*/) -{ - H5G_loc_t loc; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Gget_objinfo, FAIL) - H5TRACE4("e","isbx",loc_id,name,follow_link,statbuf); - - /* Check arguments */ - 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 specified") - - /* Get info */ - if(H5G_get_objinfo(&loc, name, follow_link, statbuf, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "cannot stat object") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Gget_objinfo() */ - - -/*------------------------------------------------------------------------- * Function: H5Gget_create_plist * * Purpose: Returns a copy of the group creation property list. @@ -1566,164 +1459,6 @@ H5G_map_obj_type(H5O_type_t obj_type) /*------------------------------------------------------------------------- - * Function: H5G_get_objinfo_cb - * - * Purpose: Callback for retrieving info about an object. This routine - * gets the info - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, September 20, 2005 - * - *------------------------------------------------------------------------- - */ -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_own_loc_t *own_loc/*out*/) -{ - H5G_trav_ud4_t *udata = (H5G_trav_ud4_t *)_udata; /* User data passed in */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_get_objinfo_cb) - - /* Check if the name in this group resolved to a valid link */ - if(lnk == NULL && obj_loc == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") - - /* Only modify user's buffer if it's available */ - if(udata->statbuf) { - H5G_stat_t *statbuf = udata->statbuf; /* Convenience pointer for statbuf */ - - /* Reset buffer */ - HDmemset(statbuf, 0, sizeof(H5G_stat_t)); - - /* Common code to retrieve the file's fileno */ - /* (Use the object location's file info, if it's available) */ - 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") - - /* Info for soft and UD links is gotten by H5L_get_info. If we have - * a hard link, follow it and get info on the object - */ - if(udata->follow_link || !lnk || (lnk->type == H5L_TYPE_HARD)) { - H5O_type_t obj_type; /* Type of object */ - - /* Get object type */ - if(H5O_obj_type(obj_loc->oloc, &obj_type, udata->dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object type") - - /* Map object type to older group object type */ - statbuf->type = H5G_map_obj_type(obj_type); - - /* Get basic info for object */ - statbuf->objno[0] = (unsigned long)(obj_loc->oloc->addr); -#if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG - statbuf->objno[1] = (unsigned long)(obj_loc->oloc->addr >> 8 * sizeof(long)); -#else - statbuf->objno[1] = 0; -#endif - statbuf->nlink = H5O_link(obj_loc->oloc, 0, udata->dxpl_id); - - /* Get creation time for object */ - if(NULL == H5O_read(obj_loc->oloc, H5O_MTIME_ID, 0, &(statbuf->mtime), udata->dxpl_id)) { - H5E_clear_stack(NULL); - if(NULL == H5O_read(obj_loc->oloc, H5O_MTIME_NEW_ID, 0, &(statbuf->mtime), udata->dxpl_id)) { - H5E_clear_stack(NULL); - statbuf->mtime = 0; - } /* end if */ - } /* end if */ - - /* Get object header information */ - if(H5O_get_stat(obj_loc->oloc, &(statbuf->ohdr), udata->dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object header information") - } /* end if */ - } /* end if */ - -done: - /* Indicate that this callback didn't take ownership of the group * - * location for the object */ - *own_loc = H5G_OWN_NONE; - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_get_objinfo_cb() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_get_objinfo - * - * Purpose: Returns information about an object. - * - * Return: Success: Non-negative with info about the object - * returned through STATBUF if it isn't the null - * pointer. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Monday, April 13, 1998 - * - *------------------------------------------------------------------------- - */ -herr_t -H5G_get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link, - H5G_stat_t *statbuf/*out*/, hid_t dxpl_id) -{ - H5G_trav_ud4_t udata; /* User data for callback */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5G_get_objinfo, FAIL) - - HDassert(loc); - HDassert(name && *name); - - /* 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_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_info_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_info(loc, name, &linfo, H5P_DEFAULT, dxpl_id); - } H5E_END_TRY - - if(ret >=0 && linfo.type != H5L_TYPE_HARD) - { - statbuf->linklen = linfo.u.val_size; - if(linfo.type == H5L_TYPE_SOFT) - statbuf->type = H5G_LINK; - else /* UD link. H5L_get_info checked for invalid link classes */ - { - HDassert(linfo.type >= H5L_TYPE_UD_MIN && linfo.type <= H5L_TYPE_MAX); - statbuf->type = H5G_UDLINK; - } - } /* end if */ - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_get_objinfo() */ - - -/*------------------------------------------------------------------------- * Function: H5G_insertion_loc_cb * * Purpose: Callback for finding insertion location. This routine sets the @@ -1740,7 +1475,7 @@ static herr_t H5G_insertion_loc_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_own_loc_t *own_loc/*out*/) { - H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */ + H5G_trav_ins_t *udata = (H5G_trav_ins_t *)_udata; /* User data passed in */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_insertion_loc_cb) @@ -1781,7 +1516,7 @@ herr_t H5G_insertion_loc(H5G_loc_t *src_loc, const char *name, H5G_loc_t *insertion_loc/*out*/, hid_t dxpl_id) { - H5G_trav_ud1_t udata; /* User data for traversal */ + H5G_trav_ins_t udata; /* User data for traversal */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_insertion_loc, FAIL) diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c index 3178159..2a3d150 100644 --- a/src/H5Gdeprec.c +++ b/src/H5Gdeprec.c @@ -54,6 +54,14 @@ /* Local Typedefs */ /******************/ +/* User data for path traversal routine for getting object info */ +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_goi_t; + /********************/ /* Package Typedefs */ @@ -72,6 +80,11 @@ 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_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*/, + H5G_own_loc_t *own_loc/*out*/); +static herr_t H5G_get_objinfo(const H5G_loc_t *loc, const char *name, + hbool_t follow_link, H5G_stat_t *statbuf/*out*/, hid_t dxpl_id); /*********************/ @@ -744,3 +757,236 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Giterate() */ + +/*------------------------------------------------------------------------- + * Function: H5Gget_objtype_by_idx + * + * Purpose: Returns the type of objects in the group by giving index. + * + * Note: Deprecated in favor of H5Lget_info/H5Oget_info + * + * Return: Success: H5G_GROUP(1), H5G_DATASET(2), H5G_TYPE(3) + * + * Failure: H5G_UNKNOWN + * + * Programmer: Raymond Lu + * Nov 20, 2002 + * + *------------------------------------------------------------------------- + */ +H5G_obj_t +H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx) +{ + H5G_loc_t loc; /* Object location */ + H5O_type_t obj_type; /* Type of object at location */ + H5G_obj_t ret_value; + + FUNC_ENTER_API(H5Gget_objtype_by_idx, H5G_UNKNOWN) + H5TRACE2("Go","ih",loc_id,idx); + + /* Check args */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a location ID") + if(H5O_obj_type(loc.oloc, &obj_type, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object type") + if(obj_type != H5O_TYPE_GROUP) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not a group") + + /* Call internal function*/ + if((ret_value = H5G_obj_get_type_by_idx(loc.oloc, idx, H5AC_ind_dxpl_id)) == H5G_UNKNOWN) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "can't get object type") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Gget_objtype_by_idx() */ + + +/*------------------------------------------------------------------------- + * Function: H5Gget_objinfo + * + * Purpose: Returns information about an object. If FOLLOW_LINK is + * non-zero then all symbolic links are followed; otherwise all + * links except the last component of the name are followed. + * + * Note: Deprecated in favor of H5Lget_info/H5Oget_info + * + * Return: Non-negative on success, with the fields of STATBUF (if + * non-null) initialized. Negative on failure. + * + * Programmer: Robb Matzke + * Monday, April 13, 1998 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, + H5G_stat_t *statbuf/*out*/) +{ + H5G_loc_t loc; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Gget_objinfo, FAIL) + H5TRACE4("e","isbx",loc_id,name,follow_link,statbuf); + + /* Check arguments */ + 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 specified") + + /* Get info */ + if(H5G_get_objinfo(&loc, name, follow_link, statbuf, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "cannot stat object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Gget_objinfo() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_get_objinfo_cb + * + * Purpose: Callback for retrieving info about an object. This routine + * gets the info + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, September 20, 2005 + * + *------------------------------------------------------------------------- + */ +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_own_loc_t *own_loc/*out*/) +{ + H5G_trav_goi_t *udata = (H5G_trav_goi_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_get_objinfo_cb) + + /* Check if the name in this group resolved to a valid link */ + if(lnk == NULL && obj_loc == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + + /* Only modify user's buffer if it's available */ + if(udata->statbuf) { + H5G_stat_t *statbuf = udata->statbuf; /* Convenience pointer for statbuf */ + + /* Common code to retrieve the file's fileno */ + /* (Use the object location's file info, if it's available) */ + 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") + + /* Info for soft and UD links is gotten by H5L_get_info. If we have + * a hard link, follow it and get info on the object + */ + if(udata->follow_link || !lnk || (lnk->type == H5L_TYPE_HARD)) { + H5O_info_t oinfo; /* Object information */ + + /* Go retrieve the object information */ + if(H5O_get_info(obj_loc->oloc, &oinfo, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get object info") + + /* Get mapped object type */ + statbuf->type = H5G_map_obj_type(oinfo.type); + + /* Get object number (i.e. address) for object */ + statbuf->objno[0] = (unsigned long)(oinfo.addr); +#if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG + statbuf->objno[1] = (unsigned long)(oinfo.addr >> 8 * sizeof(long)); +#else + statbuf->objno[1] = 0; +#endif + /* Get # of hard links pointing to object */ + statbuf->nlink = oinfo.rc; + + /* Get modification time for object */ + statbuf->mtime = oinfo.mtime; + + /* Retrieve the object header information */ + statbuf->ohdr.size = oinfo.hdr.hdr_size; + statbuf->ohdr.free = oinfo.hdr.free_space; + statbuf->ohdr.nmesgs = oinfo.hdr.nmesgs; + statbuf->ohdr.nchunks = oinfo.hdr.nchunks; + } /* end if */ + } /* end if */ + +done: + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_loc = H5G_OWN_NONE; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_get_objinfo_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_get_objinfo + * + * Purpose: Returns information about an object. + * + * Return: Success: Non-negative with info about the object + * returned through STATBUF if it isn't the null + * pointer. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, April 13, 1998 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link, + H5G_stat_t *statbuf/*out*/, hid_t dxpl_id) +{ + H5G_trav_goi_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_get_objinfo) + + HDassert(loc); + HDassert(name && *name); + + /* Reset stat buffer, if one was given */ + if(statbuf) + HDmemset(statbuf, 0, sizeof(H5G_stat_t)); + + /* 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_TARGET_UDLINK), + H5G_get_objinfo_cb, &udata, H5P_DEFAULT, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") + + /* If we're pointing at a soft or UD link, get the real link length and type */ + if(statbuf && follow_link == 0) { + H5L_info_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_info(loc, name, &linfo, H5P_DEFAULT, dxpl_id); + } H5E_END_TRY + + if(ret >= 0 && linfo.type != H5L_TYPE_HARD) { + statbuf->linklen = linfo.u.val_size; + if(linfo.type == H5L_TYPE_SOFT) + statbuf->type = H5G_LINK; + else { /* UD link. H5L_get_info checked for invalid link classes */ + HDassert(linfo.type >= H5L_TYPE_UD_MIN && linfo.type <= H5L_TYPE_MAX); + statbuf->type = H5G_UDLINK; + } /* end else */ + } /* end if */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_get_objinfo() */ + diff --git a/src/H5Glink.c b/src/H5Glink.c index de8e7aa..23e5f4b 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -495,7 +495,7 @@ H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id, const H5O_link_t *_src_lnk, /* Expand soft link */ if(H5L_TYPE_SOFT == src_lnk->type && cpy_info->expand_soft_link) { - H5G_stat_t statbuf; /* Information about object pointed to by soft link */ + H5O_info_t oinfo; /* Information about object pointed to by soft link */ H5G_loc_t grp_loc; /* Group location holding soft link */ H5G_name_t grp_path; /* Path for group holding soft link */ @@ -509,18 +509,11 @@ H5G_link_copy_file(H5F_t *dst_file, hid_t dxpl_id, const H5O_link_t *_src_lnk, grp_loc.oloc = (H5O_loc_t *)src_oloc; /* Casting away const OK -QAK */ /* Check if the object pointed by the soft link exists in the source file */ - /* (It would be more efficient to make a specialized traversal callback, - * but this is good enough for now... -QAK) - */ - if(H5G_get_objinfo(&grp_loc, tmp_src_lnk.u.soft.name, TRUE, &statbuf, dxpl_id) >= 0) { + if(H5G_loc_info(&grp_loc, tmp_src_lnk.u.soft.name, &oinfo, H5P_DEFAULT, dxpl_id) >= 0) { /* Convert soft link to hard link */ tmp_src_lnk.u.soft.name = H5MM_xfree(tmp_src_lnk.u.soft.name); tmp_src_lnk.type = H5L_TYPE_HARD; -#if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG - tmp_src_lnk.u.hard.addr = (((haddr_t)statbuf.objno[1]) << (8 * sizeof(long))) | (haddr_t)statbuf.objno[0]; -#else - tmp_src_lnk.u.hard.addr = statbuf.objno[0]; -#endif + tmp_src_lnk.u.hard.addr = oinfo.addr; src_lnk = &tmp_src_lnk; } /* end if */ else { diff --git a/src/H5Gloc.c b/src/H5Gloc.c index 89f2861..bdd41a5 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -68,6 +68,15 @@ typedef struct { H5G_loc_t *loc; /* Group location to set */ } H5G_loc_fbi_t; +/* User data for getting an object's info in a group */ +typedef struct { + /* downward */ + hid_t dxpl_id; /* DXPL to use for operation */ + + /* upward */ + H5O_info_t *oinfo; /* Object information to retrieve */ +} H5G_loc_info_t; + /********************/ /* Local Prototypes */ @@ -551,3 +560,81 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_insert() */ + +/*------------------------------------------------------------------------- + * Function: H5G_loc_info_cb + * + * Purpose: Callback for retrieving object info for an object in a group + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, November 23, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_loc_info_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/) +{ + H5G_loc_info_t *udata = (H5G_loc_info_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_loc_info_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") + + /* Query object information */ + if(H5O_get_info(obj_loc->oloc, udata->oinfo, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object info") + +done: + /* Indicate that this callback didn't take ownership of the group * + * location for the object */ + *own_loc = H5G_OWN_NONE; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_info_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_loc_info + * + * Purpose: Retrieve the information for an object from a group location + * and path to that object + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, November 23, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_loc_info(H5G_loc_t *loc, const char *name, H5O_info_t *oinfo/*out*/, + hid_t lapl_id, hid_t dxpl_id) +{ + H5G_loc_info_t udata; /* User data for traversal callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_loc_info, FAIL) + + /* Check args. */ + HDassert(loc); + HDassert(name && *name); + HDassert(oinfo); + + /* Set up user data for locating object */ + udata.dxpl_id = dxpl_id; + udata.oinfo = oinfo; + + /* Traverse group hierarchy to locate object */ + if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_info_cb, &udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_loc_info() */ + diff --git a/src/H5Gname.c b/src/H5Gname.c index 56df3d6..1e1cf16 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -34,6 +34,7 @@ #include "H5FLprivate.h" /* Free Lists */ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory wrappers */ /* Private typedefs */ @@ -81,7 +82,8 @@ static H5RS_str_t *H5G_build_fullpath_refstr_refstr(const H5RS_str_t *prefix_r, 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); -static herr_t H5G_refname_iterator(hid_t group, const char *name, void *_iter); +static herr_t H5G_refname_iterator(hid_t group, const char *name, + const H5L_info_t *link_info, void *_udata); static herr_t H5G_free_ref_path_node(void *item, void *key, void *operator_data/*in,out*/); @@ -1045,102 +1047,104 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5G_refname_iterator(hid_t group, const char *name, void *_udata) +H5G_refname_iterator(hid_t group, const char *name, const H5L_info_t *link_info, + void *_udata) { H5G_ref_path_iter_t *udata = (H5G_ref_path_iter_t*)_udata; - H5G_stat_t sb; /* Stat buffer for object */ - H5G_loc_t loc; /* Group location of parent */ - haddr_t objno; /* Address of current object */ - herr_t ret_value = 0; /* Return value */ + herr_t ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_refname_iterator) - /* Look up group's location */ - if(H5G_loc(group, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - - /* Get information for object in group */ - if(H5G_get_objinfo(&loc, name, FALSE, &sb, udata->dxpl_id) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "cannot stat object") -#if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG - objno = (haddr_t)sb.objno[0] | ((haddr_t)sb.objno[1] << (8 * sizeof(long))); -#else - objno = (haddr_t)sb.objno[0]; -#endif - - /* Check for finding the object */ - /* (checks against the file in the location as well, to make certain that - * the correct object is found in a mounted file hierarchy) - */ - if(udata->loc->addr == objno && udata->loc->file == loc.oloc->file) { - size_t len_needed; /* Length of container string needed */ - - /* Build the object's full name */ - len_needed = HDstrlen(udata->container) + HDstrlen(name) + 2; - if(len_needed > udata->max_container_len) { - if(NULL == (udata->container = H5MM_realloc(udata->container, len_needed))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate path string") - udata->max_container_len = len_needed; - } /* end if */ - HDstrcat(udata->container, name); + /* We only care about hard links */ + if(link_info->type == H5L_TYPE_HARD) { + H5G_loc_t loc; /* Group location of parent */ + + /* Look up group's location */ + if(H5G_loc(group, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5_ITER_ERROR, "not a location") + + /* Check for finding the object */ + /* (checks against the file in the location as well, to make certain that + * the correct object is found in a mounted file hierarchy) + */ + if(udata->loc->addr == link_info->u.address && udata->loc->file == loc.oloc->file) { + size_t len_needed; /* Length of container string needed */ + + /* Build the object's full name */ + len_needed = HDstrlen(udata->container) + HDstrlen(name) + 2; + if(len_needed > udata->max_container_len) { + if(NULL == (udata->container = H5MM_realloc(udata->container, len_needed))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate path string") + udata->max_container_len = len_needed; + } /* end if */ + HDstrcat(udata->container, name); - /* We found a match so we return immediately */ - HGOTO_DONE(1) - } /* end if */ - else { - /* See if we've seen this object before */ - if(H5SL_search(udata->ref_path_table, &objno)) - HGOTO_DONE(0) + /* We found a match so we return immediately */ + HGOTO_DONE(H5_ITER_STOP) + } /* end if */ else { - /* If not, we add it to the list of visited objects if it's ref count is > 1 */ - if(sb.nlink > 1) { + H5O_info_t oinfo; /* Object information */ + H5O_loc_t tmp_oloc; /* Temporary object location */ + + /* Check if we've seen this object before */ + if(H5SL_search(udata->ref_path_table, &link_info->u.address)) + HGOTO_DONE(H5_ITER_CONT) + + /* Go retrieve the object information */ + tmp_oloc.file = loc.oloc->file; + tmp_oloc.addr = link_info->u.address; + if(H5O_get_info(&tmp_oloc, &oinfo, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5_ITER_ERROR, "unable to get object info") + + /* If its ref count is > 1, we add it to the list of visited objects */ + if(oinfo.rc > 1) { haddr_t *new_node; /* New path node for table */ /* Allocate new path node */ if((new_node = H5FL_MALLOC(haddr_t)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate path node") + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate path node") /* Set node information */ - *new_node = objno; + *new_node = link_info->u.address; /* Insert into skip list */ if(H5SL_insert(udata->ref_path_table, new_node, new_node) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert path node into table") + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5_ITER_ERROR, "can't insert path node into table") } /* end if */ - } /* end else */ - - /* If it's a group, we recurse into it */ - if(sb.type == H5G_GROUP) { - H5G_link_iterate_t lnk_op; /* Link operator */ - hsize_t last_obj; - size_t len_needed; /* Length of container string needed */ - size_t len; - /* Build full path name of group to recurse into */ - len = HDstrlen(udata->container); - len_needed = len + HDstrlen(name) + 2; - if(len_needed > udata->max_container_len) { - if(NULL == (udata->container = H5MM_realloc(udata->container, len_needed))) - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't allocate path string") - udata->max_container_len = len_needed; - } /* end if */ - if(!udata->is_root_group) - HDstrcat(udata->container, name); - else - udata->is_root_group = FALSE; - HDstrcat(udata->container, "/"); + /* If it's a group, we recurse into it */ + if(oinfo.type == H5G_GROUP) { + H5G_link_iterate_t lnk_op; /* Link operator */ + hsize_t last_obj; + size_t len_needed; /* Length of container string needed */ + size_t len; + + /* Build full path name of group to recurse into */ + len = HDstrlen(udata->container); + len_needed = len + HDstrlen(name) + 2; + if(len_needed > udata->max_container_len) { + if(NULL == (udata->container = H5MM_realloc(udata->container, len_needed))) + HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, H5_ITER_ERROR, "can't allocate path string") + udata->max_container_len = len_needed; + } /* end if */ + if(!udata->is_root_group) + HDstrcat(udata->container, name); + else + udata->is_root_group = FALSE; + HDstrcat(udata->container, "/"); + + /* Build iterator operator */ + lnk_op.op_type = H5G_LINK_OP_APP; + lnk_op.u.app_op = H5G_refname_iterator; + + ret_value = H5G_obj_iterate(udata->file, udata->container, H5L_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, &last_obj, &lnk_op, udata, udata->dxpl_id); - /* Build iterator operator */ - lnk_op.op_type = H5G_LINK_OP_OLD; - lnk_op.u.old_op = H5G_refname_iterator; - - ret_value = H5G_obj_iterate(udata->file, udata->container, H5L_INDEX_NAME, H5_ITER_NATIVE, (hsize_t)0, &last_obj, &lnk_op, udata, udata->dxpl_id); - - /* If we didn't find the object, truncate the name to not include group name anymore */ - if(!ret_value) - udata->container[len] = '\0'; - } /* end if */ - } /* end else */ + /* If we didn't find the object, truncate the name to not include group name anymore */ + if(!ret_value) + udata->container[len] = '\0'; + } /* end if */ + } /* end else */ + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -1199,11 +1203,20 @@ H5G_get_refobj_name(hid_t file, hid_t dxpl_id, const H5O_loc_t *loc, char *name, size_t size) { H5G_ref_path_iter_t udata; /* User data for iteration */ + H5G_loc_t root_loc; /* Root location */ + H5L_info_t root_info; /* Link info for root group */ herr_t status; /* Status from iteration */ ssize_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5G_get_refobj_name, FAIL) + /* Construct the link info for the root group */ + if(H5G_loc(file, &root_loc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get root group's location") + HDmemset(&root_info, 0, sizeof(root_info)); + root_info.type = H5L_TYPE_HARD; + root_info.u.address = root_loc.oloc->addr; + /* Set up user data for iterator */ udata.file = file; udata.dxpl_id = dxpl_id; @@ -1218,7 +1231,7 @@ H5G_get_refobj_name(hid_t file, hid_t dxpl_id, const H5O_loc_t *loc, HGOTO_ERROR(H5E_SYM, H5E_CANTCREATE, FAIL, "can't create skip list for path nodes") /* Iterate over all the objects in the file */ - if((status = H5G_refname_iterator(file, "/", &udata)) < 0) + if((status = H5G_refname_iterator(file, "/", &root_info, &udata)) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group iteration failed while looking for object name") else if(status > 0) { /* Set the length of the full path */ @@ -1235,6 +1248,7 @@ H5G_get_refobj_name(hid_t file, hid_t dxpl_id, const H5O_loc_t *loc, ret_value = 0; done: + /* Release resources */ H5MM_xfree(udata.container); if(udata.ref_path_table) H5SL_destroy(udata.ref_path_table, H5G_free_ref_path_node, NULL); diff --git a/src/H5Gnode.c b/src/H5Gnode.c index c2fbad4..714661c 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -1829,7 +1829,7 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, /* expand soft link */ if(H5G_CACHED_SLINK == src_ent->type && cpy_info->expand_soft_link) { - H5G_stat_t statbuf; /* Information about object pointed to by soft link */ + H5O_info_t oinfo; /* Information about object pointed to by soft link */ H5G_loc_t grp_loc; /* Group location holding soft link */ H5G_name_t grp_path; /* Path for group holding soft link */ char *link_name; /* Pointer to value of soft link */ @@ -1846,15 +1846,8 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, link_name = (char *)H5HL_offset_into(f, heap, tmp_src_ent.cache.slink.lval_offset); /* Check if the object pointed by the soft link exists in the source file */ - /* (It would be more efficient to make a specialized traversal callback, - * but this is good enough for now... -QAK) - */ - if(H5G_get_objinfo(&grp_loc, link_name, TRUE, &statbuf, dxpl_id) >= 0) { -#if H5_SIZEOF_UINT64_T > H5_SIZEOF_LONG - tmp_src_ent.header = (((haddr_t)statbuf.objno[1]) << (8 * sizeof(long))) | (haddr_t)statbuf.objno[0]; -#else - tmp_src_ent.header = statbuf.objno[0]; -#endif + if(H5G_loc_info(&grp_loc, link_name, &oinfo, H5P_DEFAULT, dxpl_id) >= 0) { + tmp_src_ent.header = oinfo.addr; src_ent = &tmp_src_ent; } /* end if */ else diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index 786b6a6..807b971 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -149,8 +149,6 @@ H5_DLL H5F_t *H5G_fileof(H5G_t *grp); H5_DLL herr_t H5G_free(H5G_t *grp); H5_DLL H5G_t *H5G_open(H5G_loc_t *loc, hid_t dxpl_id); H5_DLL herr_t H5G_close(H5G_t *grp); -H5_DLL herr_t H5G_get_objinfo(const H5G_loc_t *loc, const char *name, - hbool_t follow_link, H5G_stat_t *statbuf/*out*/, hid_t dxpl_id); H5_DLL herr_t H5G_insertion_loc(H5G_loc_t *src_loc, const char *name, H5G_loc_t *insertion_loc/*out*/, hid_t dxpl_id); H5_DLL herr_t H5G_free_grp_name(H5G_t *grp); @@ -196,6 +194,8 @@ H5_DLL herr_t H5G_loc_find(H5G_loc_t *loc, const char *name, H5_DLL herr_t H5G_loc_find_by_idx(H5G_loc_t *loc, const char *group_name, H5L_index_t idx_type, H5_iter_order_t order, hsize_t n, H5G_loc_t *obj_loc/*out*/, hid_t lapl_id, hid_t dxpl_id); +H5_DLL herr_t H5G_loc_info(H5G_loc_t *loc, const char *name, H5O_info_t *oinfo/*out*/, + hid_t lapl_id, hid_t dxpl_id); H5_DLL herr_t H5G_loc_reset(H5G_loc_t *loc); H5_DLL herr_t H5G_loc_free(H5G_loc_t *loc); diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index d7fc5ea..26e6c89 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -105,9 +105,6 @@ H5_DLL hid_t H5Gcreate_expand(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id); H5_DLL hid_t H5Gopen(hid_t loc_id, const char *name); H5_DLL hid_t H5Gopen_expand(hid_t loc_id, const char *name, hid_t gapl_id); H5_DLL herr_t H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs); -H5_DLL H5G_obj_t H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx); -H5_DLL herr_t H5Gget_objinfo(hid_t loc_id, const char *name, - hbool_t follow_link, H5G_stat_t *statbuf/*out*/); H5_DLL hid_t H5Gget_create_plist(hid_t group_id); H5_DLL herr_t H5Gclose(hid_t group_id); @@ -134,6 +131,9 @@ H5_DLL int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf); H5_DLL herr_t H5Giterate(hid_t loc_id, const char *name, int *idx, H5G_iterate_t op, void *op_data); +H5_DLL H5G_obj_t H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx); +H5_DLL herr_t H5Gget_objinfo(hid_t loc_id, const char *name, + hbool_t follow_link, H5G_stat_t *statbuf/*out*/); #ifdef __cplusplus } @@ -125,6 +125,8 @@ static void * H5O_copy_real(const H5O_msg_class_t *type, const void *mesg, void *dst); static int H5O_count_real(H5O_loc_t *loc, const H5O_msg_class_t *type, hid_t dxpl_id); +static void *H5O_read_real(H5F_t *f, H5O_t *oh, unsigned type_id, int sequence, + void *mesg, hid_t dxpl_id); static unsigned H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t **type_p, int sequence); static int H5O_modify_real(H5O_loc_t *loc, const H5O_msg_class_t *type, @@ -147,7 +149,6 @@ static herr_t H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type H5AC_protect_t prot, hbool_t internal, H5O_mesg_operator_t op, void *op_data, hid_t dxpl_id); static const H5O_obj_class_t *H5O_obj_class(H5O_loc_t *loc, hid_t dxpl_id); static herr_t H5O_obj_type_real(H5O_t *oh, H5O_type_t *obj_type); -static herr_t H5O_get_info(H5O_loc_t *oloc, H5O_info_t *oinfo, hid_t dxpl_id); /*********************/ /* Package Variables */ @@ -581,14 +582,9 @@ herr_t H5Oget_info(hid_t loc_id, const char *name, H5O_info_t *oinfo, hid_t lapl_id) { H5G_loc_t loc; /* Location of group */ - H5G_loc_t obj_loc; /* Location used to open object */ - H5G_name_t obj_path; /* Opened object group hier. path */ - H5O_loc_t obj_oloc; /* Opened object object location */ - hbool_t loc_found = FALSE; /* Entry at 'name' found */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(H5Oopen, FAIL) - H5TRACE3("i","isi",loc_id,name,lapl_id); + FUNC_ENTER_API(H5Oget_info, FAIL) /* Check args */ if(H5G_loc(loc_id, &loc) < 0) @@ -603,25 +599,11 @@ H5Oget_info(hid_t loc_id, const char *name, H5O_info_t *oinfo, hid_t lapl_id) if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Set up opened object location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); - - /* Find the object's location */ - if(H5G_loc_find(&loc, name, &obj_loc/*out*/, lapl_id, H5AC_dxpl_id) < 0) + /* Retrieve the object's information */ + if(H5G_loc_info(&loc, name, oinfo/*out*/, lapl_id, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") - loc_found = TRUE; - - /* Get the information about the object */ - if(H5O_get_info(obj_loc.oloc, oinfo, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") done: - if(loc_found) - if(H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") - FUNC_LEAVE_API(ret_value) } /* end H5Oget_info() */ @@ -801,6 +783,7 @@ H5O_new(H5F_t *f, hid_t dxpl_id, size_t chunk_size, H5O_loc_t *loc/*out*/, /* Initialize rudimentary information object object header */ oh->version = H5F_USE_LATEST_FORMAT(f) ? H5O_VERSION_LATEST : H5O_VERSION_1; oh->nlink = 0; + oh->skipped_mesg_size = 0; /* Compute total size of initial object header */ /* (i.e. object header prefix and first chunk) */ @@ -1512,7 +1495,7 @@ H5O_exists_oh(H5O_t *oh, unsigned type_id, int sequence) void * H5O_read(const H5O_loc_t *loc, unsigned type_id, int sequence, void *mesg, hid_t dxpl_id) { - const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ + H5O_t *oh = NULL; /* Object header to use */ void *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_read, NULL) @@ -1522,15 +1505,20 @@ H5O_read(const H5O_loc_t *loc, unsigned type_id, int sequence, void *mesg, hid_t HDassert(loc->file); HDassert(H5F_addr_defined(loc->addr)); HDassert(type_id < NELMTS(H5O_msg_class_g)); - type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ - HDassert(type); HDassert(sequence >= 0); + /* Get the object header */ + if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header") + /* Call the "real" read routine */ - if((ret_value = H5O_read_real(loc, type, sequence, mesg, dxpl_id)) == NULL) + if((ret_value = H5O_read_real(loc->file, oh, type_id, sequence, mesg, dxpl_id)) == NULL) HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to load object header") done: + if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_OHDR, H5E_PROTECT, NULL, "unable to release object header") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_read() */ @@ -1558,28 +1546,25 @@ done: * *------------------------------------------------------------------------- */ -void * -H5O_read_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, int sequence, void *mesg, hid_t dxpl_id) +static void * +H5O_read_real(H5F_t *f, H5O_t *oh, unsigned type_id, int sequence, void *mesg, hid_t dxpl_id) { - H5O_t *oh = NULL; + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ int idx; void *ret_value = NULL; FUNC_ENTER_NOAPI_NOINIT(H5O_read_real) /* check args */ - HDassert(loc); - HDassert(loc->file); - HDassert(H5F_addr_defined(loc->addr)); + HDassert(f); + HDassert(oh); + HDassert(type_id < NELMTS(H5O_msg_class_g)); + type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); HDassert(sequence >= 0); - /* copy the message to the user-supplied buffer */ - if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header") - /* can we get it from the object header? */ - if((idx = H5O_find_in_ohdr(loc->file, dxpl_id, oh, &type, sequence)) < 0) + if((idx = H5O_find_in_ohdr(f, dxpl_id, oh, &type, sequence)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, NULL, "unable to find message in object header") if(oh->mesg[idx].flags & H5O_FLAG_SHARED) { @@ -1591,7 +1576,7 @@ H5O_read_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, int sequence, v H5O_shared_t *shared; shared = (H5O_shared_t *)(oh->mesg[idx].native); - ret_value = H5O_shared_read(loc->file, dxpl_id, shared, type, mesg); + ret_value = H5O_shared_read(f, dxpl_id, shared, type, mesg); } else { /* * The message is not shared, but rather exists in the object @@ -1599,14 +1584,11 @@ H5O_read_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, int sequence, v * the raw message) so we must copy the native message before * returning. */ - if(NULL == (ret_value = (type->copy) (oh->mesg[idx].native, mesg, 0))) + if(NULL == (ret_value = (type->copy)(oh->mesg[idx].native, mesg, 0))) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy message to user space") } /* end else */ done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_OHDR, H5E_PROTECT, NULL, "unable to release object header") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_read_real() */ @@ -3107,65 +3089,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5O_get_stat - * - * Purpose: Retrieve information about an object header - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Oct 7 2003 - * - *------------------------------------------------------------------------- - */ -herr_t -H5O_get_stat(H5O_loc_t *loc, H5O_stat_t *ostat, hid_t dxpl_id) -{ - H5O_t *oh = NULL; /* Object header information */ - H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */ - hsize_t total_size; /* Total amount of space used in file */ - hsize_t free_space; /* Free space in object header */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5O_get_stat, FAIL) - - /* Check args */ - HDassert(loc); - HDassert(ostat); - - /* Get the object header information */ - if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") - - /* Iterate over all the messages, accumulating the total size & free space */ - total_size = H5O_SIZEOF_HDR_OH(oh); - free_space = 0; - for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) { - /* Accumulate the size for this message */ - total_size += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; - - /* Check for this message being free space */ - if(H5O_NULL_ID == curr_msg->type->id) - free_space += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; - } /* end for */ - - /* Set the information for this object header */ - ostat->size = total_size; - ostat->free = free_space; - ostat->nmesgs = oh->nmesgs; - ostat->nchunks = oh->nchunks; - -done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_get_stat() */ - - -/*------------------------------------------------------------------------- * Function: H5O_encode * * Purpose: Encode an object(data type and simple data space only) @@ -3867,10 +3790,13 @@ done: * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5O_get_info(H5O_loc_t *oloc, H5O_info_t *oinfo, hid_t dxpl_id) { H5O_t *oh = NULL; /* Object header */ + H5O_chunk_t *curr_chunk; /* Pointer to current message being operated on */ + H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */ + unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5O_get_info, FAIL) @@ -3879,10 +3805,80 @@ H5O_get_info(H5O_loc_t *oloc, H5O_info_t *oinfo, hid_t dxpl_id) HDassert(oloc); HDassert(oinfo); - /* Get the object header information */ + /* Get the object header */ if(NULL == (oh = H5AC_protect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, NULL, NULL, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") + /* Retrieve the file's fileno */ + if(H5F_get_fileno(oloc->file, &oinfo->fileno) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to read fileno") + + /* Set the object's address */ + oinfo->addr = oloc->addr; + + /* Retrieve the type of the object */ + if(H5O_obj_type_real(oh, &oinfo->type) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type") + + /* Set the object's reference count */ + oinfo->rc = oh->nlink; + + /* Get modification time for object */ + if(NULL == H5O_read_real(oloc->file, oh, H5O_MTIME_ID, 0, &oinfo->mtime, dxpl_id)) { + H5E_clear_stack(NULL); + if(NULL == H5O_read_real(oloc->file, oh, H5O_MTIME_NEW_ID, 0, &oinfo->mtime, dxpl_id)) { + H5E_clear_stack(NULL); + oinfo->mtime = 0; + } /* end if */ + } /* end if */ + + /* Set the version for the object header */ + oinfo->hdr.version = oh->version; + + /* Set the number of messages & chunks */ + oinfo->hdr.nmesgs = oh->nmesgs; + oinfo->hdr.nchunks = oh->nchunks; + + /* Iterate over all the messages, accumulating message size & type information */ + oinfo->hdr.meta_space = H5O_SIZEOF_HDR_OH(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1)); + oinfo->hdr.mesg_space = 0; + oinfo->hdr.free_space = 0; + oinfo->hdr.msg_present = 0; + oinfo->hdr.msg_shared = 0; + for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) { + uint64_t type_flag; /* Flag for message type */ + + /* Accumulate information, based on the type of message */ + if(H5O_NULL_ID == curr_msg->type->id) + oinfo->hdr.free_space += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; + else if(H5O_CONT_ID == curr_msg->type->id) + oinfo->hdr.meta_space += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; + else { + oinfo->hdr.meta_space += H5O_SIZEOF_MSGHDR_OH(oh); + oinfo->hdr.mesg_space += curr_msg->raw_size; + } /* end else */ + + /* Set flag to indicate present of message type */ + type_flag = ((uint64_t)1) << curr_msg->type->id; + oinfo->hdr.msg_present |= type_flag; + + /* Set flag if the message is shared in some way */ + if(curr_msg->flags & H5O_FLAG_SHARED) \ + oinfo->hdr.msg_shared |= type_flag; + } /* end for */ + + /* Iterate over all the chunks, adding any gaps to the free space */ + oinfo->hdr.hdr_size = 0; + for(u = 0, curr_chunk = &oh->chunk[0]; u < oh->nchunks; u++, curr_chunk++) { + /* Accumulate the size of the header on header */ + oinfo->hdr.hdr_size += curr_chunk->size; + + /* If the chunk has a gap, add it to the free space */ + oinfo->hdr.free_space += curr_chunk->gap; + } /* end for */ + + /* Sanity check that all the bytes are accounted for */ + HDassert(oinfo->hdr.hdr_size == (oinfo->hdr.free_space + oinfo->hdr.meta_space + oinfo->hdr.mesg_space + oh->skipped_mesg_size)); done: if(oh && H5AC_unprotect(oloc->file, dxpl_id, H5AC_OHDR, oloc->addr, oh, H5AC__NO_FLAGS_SET) < 0) diff --git a/src/H5Ocache.c b/src/H5Ocache.c index b2e64ab..8ebb6c2 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -390,6 +390,9 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, /* Skip header messages we don't know about */ /* (Usually from future versions of the library) */ if(id >= NELMTS(H5O_msg_class_g) || NULL == H5O_msg_class_g[id]) { + /* Increment the size of the message skipped over (for later sanity checking) */ + oh->skipped_mesg_size += H5O_SIZEOF_MSGHDR_OH(oh) + mesg_size; + /* Increment skipped messages counter */ skipped_msgs++; } /* end if */ diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index a312b5a..ea8f1c6 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -336,6 +336,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, /* Initialize header information */ oh_dst->version = oh_src->version; oh_dst->nlink = 0; + oh_dst->skipped_mesg_size = 0; /* Initialize size of chunk array. The destination always has only one * chunk. diff --git a/src/H5Odbg.c b/src/H5Odbg.c index 72c6d93..46a7a62 100644 --- a/src/H5Odbg.c +++ b/src/H5Odbg.c @@ -93,12 +93,28 @@ H5O_assert(const H5O_t *oh) { H5O_mesg_t *curr_msg; /* Pointer to current message to examine */ H5O_mesg_t *tmp_msg; /* Pointer to temporary message to examine */ + size_t meta_space; /* Size of header metadata */ + size_t mesg_space; /* Size of message raw data */ + size_t free_space; /* Size of free space in header */ + size_t hdr_size; /* Size of header's chunks */ unsigned u, v; /* Local index variables */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_assert) + /* Initialize the space tracking variables */ + hdr_size = 0; + meta_space = H5O_SIZEOF_HDR_OH(oh) + (H5O_SIZEOF_CHKHDR_OH(oh) * (oh->nchunks - 1)); + mesg_space = 0; + free_space = 0; + /* Loop over all chunks in object header */ for(u = 0; u < oh->nchunks; u++) { + /* Accumulate the size of the header on header */ + hdr_size += oh->chunk[u].size; + + /* If the chunk has a gap, add it to the free space */ + free_space += oh->chunk[u].gap; + /* Check for valid raw data image */ HDassert(oh->chunk[u].image); HDassert(oh->chunk[u].size > (size_t)H5O_SIZEOF_CHKHDR_OH(oh)); @@ -121,6 +137,16 @@ H5O_assert(const H5O_t *oh) /* Loop over all messages in object header */ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) { + /* Accumulate information, based on the type of message */ + if(H5O_NULL_ID == curr_msg->type->id) + free_space += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; + else if(H5O_CONT_ID == curr_msg->type->id) + meta_space += H5O_SIZEOF_MSGHDR_OH(oh) + curr_msg->raw_size; + else { + meta_space += H5O_SIZEOF_MSGHDR_OH(oh); + mesg_space += curr_msg->raw_size; + } /* end else */ + /* Make certain that the message is in a valid chunk */ HDassert(curr_msg->chunkno < oh->nchunks); @@ -143,6 +169,9 @@ H5O_assert(const H5O_t *oh) } /* end for */ } /* end for */ + /* Sanity check that all the bytes are accounted for */ + HDassert(hdr_size == (free_space + meta_space + mesg_space + oh->skipped_mesg_size)); + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_assert() */ #endif /* H5O_DEBUG */ diff --git a/src/H5Omtime.c b/src/H5Omtime.c index b526162..f9c1b68 100644 --- a/src/H5Omtime.c +++ b/src/H5Omtime.c @@ -266,8 +266,8 @@ H5O_mtime_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p) * The catch-all. If we can't convert a character string universal * coordinated time to a time_t value reliably then we can't decode the * modification time message. This really isn't as bad as it sounds -- the - * only way a user can get the modification time is from H5Gget_objinfo() - * and H5G_get_objinfo() can gracefully recover. + * only way a user can get the modification time is from our internal + * query routines, which can gracefully recover. */ /* Irix64 */ diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 907208b..70474da 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -186,6 +186,7 @@ struct H5O_t { /* first field in structure */ unsigned version; /*version number */ int nlink; /*link count */ + size_t skipped_mesg_size; /*size of skipped messages (for sanity checking) */ size_t nmesgs; /*number of messages */ size_t alloc_nmesgs; /*number of message slots */ H5O_mesg_t *mesg; /*array of messages */ @@ -340,8 +341,6 @@ H5_DLLVAR const H5O_obj_class_t H5O_OBJ_DATATYPE[1]; /* Package-local function prototypes */ H5_DLL herr_t H5O_flush_msgs(H5F_t *f, H5O_t *oh); -H5_DLL void * H5O_read_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, - int sequence, void *mesg, hid_t dxpl_id); H5_DLL herr_t H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link); H5_DLL herr_t H5O_free_mesg(H5O_mesg_t *mesg); diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index c068359..b0c50dc 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -408,7 +408,7 @@ H5_DLL htri_t H5O_is_shared(unsigned type_id, const void *mesg); H5_DLL herr_t H5O_set_share(H5F_t *f, H5O_shared_t *share, unsigned type_id, void *mesg); H5_DLL herr_t H5O_reset_share(H5F_t *f, unsigned type_id, void *mesg); -H5_DLL herr_t H5O_get_stat(H5O_loc_t *loc, H5O_stat_t *ostat, hid_t dxpl_id); +H5_DLL herr_t H5O_get_info(H5O_loc_t *oloc, H5O_info_t *oinfo, hid_t dxpl_id); H5_DLL herr_t H5O_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t op, void *op_data, hid_t dxpl_id); H5_DLL herr_t H5O_obj_type(const H5O_loc_t *loc, H5O_type_t *obj_type, hid_t dxpl_id); diff --git a/src/H5Opublic.h b/src/H5Opublic.h index b9e887b..fc91d23 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -89,10 +89,12 @@ typedef struct H5O_info_t { time_t mtime; /* Modification time */ struct { unsigned version; /* Version number of header format in file */ - hsize_t size; /* Total size of object header in file */ - hsize_t free; /* Free space within object header */ unsigned nmesgs; /* Number of object header messages */ unsigned nchunks; /* Number of object header chunks */ + hsize_t hdr_size; /* Total size of object header in file */ + hsize_t meta_space; /* Space within header for object header metadata information */ + hsize_t mesg_space; /* Space within header for actual message information */ + hsize_t free_space; /* Free space within object header */ uint64_t msg_present; /* Flags to indicate presence of message type in header */ uint64_t msg_shared; /* Flags to indicate message type is shared in header */ } hdr; diff --git a/src/H5Oshared.c b/src/H5Oshared.c index 00a1091..19c57b0 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -101,16 +101,14 @@ const H5O_msg_class_t H5O_MSG_SHARED[1] = {{ * koziol@ncsa.uiuc.edu * Sep 24 2003 * - * Modifications: - * *------------------------------------------------------------------------- */ void * -H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared, const H5O_msg_class_t *type, void *mesg) +H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared, + const H5O_msg_class_t *type, void *mesg) { - haddr_t fheap_addr; H5HF_t *fheap = NULL; - unsigned char *buf=NULL; /* Pointer to raw message in heap */ + unsigned char *buf = NULL; /* Pointer to raw message in heap */ void * native_mesg = NULL; /* Only used for messages shared in heap */ void *ret_value = NULL; /* Return value */ @@ -126,16 +124,20 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared, const H5O_msg_cla */ HDassert(shared->flags != H5O_NOT_SHARED); - if(shared->flags & H5O_SHARED_IN_HEAP_FLAG ) - { + /* Check for implicit shared object header message */ + if(shared->flags & H5O_SHARED_IN_HEAP_FLAG) { + haddr_t fheap_addr; size_t buf_size; + /* Retrieve the fractal heap address for shared messages */ if((fheap_addr = H5SM_get_fheap_addr(f, type->id, dxpl_id)) == HADDR_UNDEF) HGOTO_ERROR(H5E_SOHM, H5E_CANTGET, NULL, "can't get fheap address for shared messages") - if(NULL == (fheap =H5HF_open(f, dxpl_id, fheap_addr))) + /* Open the fractal heap */ + if(NULL == (fheap = H5HF_open(f, dxpl_id, fheap_addr))) HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, NULL, "unable to open fractal heap") + /* Get the size of the message in the heap */ if(H5HF_get_obj_len(fheap, dxpl_id, &(shared->u.heap_id), &buf_size) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, NULL, "can't get message size from fractal heap.") @@ -143,6 +145,7 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared, const H5O_msg_cla if(NULL == (buf = HDmalloc(buf_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + /* Retrieve the message from the heap */ if(H5HF_read(fheap, dxpl_id, &(shared->u.heap_id), buf) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "can't read message from fractal heap.") @@ -151,23 +154,25 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared, const H5O_msg_cla HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode shared message.") /* Make sure that this message is labeled as shared */ - assert(type->set_share); + HDassert(type->set_share); if(((type->set_share)(f, native_mesg, shared)) < 0) - HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information") + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information") - ret_value = H5O_copy(type->id, native_mesg, mesg); - } - else - { + /* Get a copy of the message to return */ + if(NULL == (ret_value = H5O_copy(type->id, native_mesg, mesg))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy message") + } /* end if */ + else { HDassert(shared->flags & H5O_COMMITTED_FLAG); - /* Get the shared message from an object header*/ - if(NULL == (ret_value = H5O_read_real(&(shared->u.oloc), type, 0, mesg, dxpl_id))) - HGOTO_ERROR (H5E_OHDR, H5E_READERROR, NULL, "unable to read message") - } + + /* Get the shared message from an object header */ + if(NULL == (ret_value = H5O_read(&(shared->u.oloc), type->id, 0, mesg, dxpl_id))) + HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read message") + } /* end else */ /* Mark the message as shared */ if(type->set_share && (type->set_share)(f, ret_value, shared) < 0) - HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information") + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information") done: if(buf) |