mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-01-18 15:15:56 +08:00
[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)
This commit is contained in:
parent
2f694358c4
commit
5c1fedcb90
271
src/H5G.c
271
src/H5G.c
@ -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*/);
|
||||
@ -597,88 +572,6 @@ done:
|
||||
FUNC_LEAVE_API(ret_value)
|
||||
} /* end H5Gget_num_objs() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* 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
|
||||
@ -1564,164 +1457,6 @@ H5G_map_obj_type(H5O_type_t obj_type)
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5G_map_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
|
||||
@ -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)
|
||||
|
246
src/H5Gdeprec.c
246
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() */
|
||||
|
||||
|
@ -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 {
|
||||
|
87
src/H5Gloc.c
87
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() */
|
||||
|
||||
|
168
src/H5Gname.c
168
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")
|
||||
/* We only care about hard links */
|
||||
if(link_info->type == H5L_TYPE_HARD) {
|
||||
H5G_loc_t loc; /* Group location of parent */
|
||||
|
||||
/* 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
|
||||
/* 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 == objno && udata->loc->file == loc.oloc->file) {
|
||||
size_t len_needed; /* Length of container string needed */
|
||||
/* 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, FAIL, "can't allocate path string")
|
||||
udata->max_container_len = len_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(H5_ITER_STOP)
|
||||
} /* 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)
|
||||
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 */
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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 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, "/");
|
||||
|
||||
/* 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 */
|
||||
} /* 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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
204
src/H5O.c
204
src/H5O.c
@ -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() */
|
||||
|
||||
@ -3105,65 +3087,6 @@ done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5O_delete_msg() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* 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
|
||||
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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.
|
||||
|
29
src/H5Odbg.c
29
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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -2975,10 +2975,10 @@ test_nested_survive(hid_t fapl)
|
||||
if(H5Funmount(gidA, ".") < 0)
|
||||
TEST_ERROR
|
||||
|
||||
/* Check name (should be unavailable) */
|
||||
/* Check name */
|
||||
if((name_len = H5Iget_name(gidAM, name, (size_t)NAME_BUF_SIZE )) < 0)
|
||||
TEST_ERROR
|
||||
if(name_len != 0)
|
||||
if(name_len == 0 || HDstrcmp(name, "/M"))
|
||||
TEST_ERROR
|
||||
|
||||
/* Open object in file #3 through file #1 mount path (should fail) */
|
||||
|
Loading…
Reference in New Issue
Block a user