#include "H5Lmodule.h"
#include "H5private.h"
#include "H5ACprivate.h"
#include "H5CXprivate.h"
#include "H5Dprivate.h"
#include "H5Eprivate.h"
#include "H5Fprivate.h"
#include "H5Gprivate.h"
#include "H5Iprivate.h"
#include "H5Lpkg.h"
#include "H5MMprivate.h"
#include "H5Oprivate.h"
#include "H5Pprivate.h"
#define H5L_MIN_TABLE_SIZE 32
typedef struct {
H5L_info_t *linfo;
} H5L_trav_gi_t;
typedef struct {
H5F_t *file;
H5P_genplist_t *lc_plist;
H5G_name_t *path;
H5O_obj_create_t *ocrt_info;
H5O_link_t *lnk;
} H5L_trav_cr_t;
typedef struct {
const char *dst_name;
H5T_cset_t cset;
const H5G_loc_t *dst_loc;
unsigned dst_target_flags;
hbool_t copy;
size_t orig_nlinks;
} H5L_trav_mv_t;
typedef struct {
H5F_t *file;
H5O_link_t *lnk;
hbool_t copy;
} H5L_trav_mv2_t;
typedef struct {
char *sep;
hbool_t exists;
} H5L_trav_le_t;
typedef struct {
size_t size;
void *buf;
} H5L_trav_gv_t;
static int H5L_find_class_idx(H5L_type_t id);
static herr_t H5L__link_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc);
static herr_t H5L__create_real(const H5G_loc_t *link_loc, const char *link_name,
H5G_name_t *obj_path, H5F_t *obj_file, H5O_link_t *lnk, H5O_obj_create_t *ocrt_info,
hid_t lcpl_id);
static herr_t H5L__get_val_real(const H5O_link_t *lnk, void *buf, size_t size);
static herr_t H5L__get_val_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc);
static herr_t H5L__get_val_by_idx_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc);
static herr_t H5L__get_val_by_idx(const H5G_loc_t *loc, const char *name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
void *buf, size_t size);
static herr_t H5L__delete_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc);
static herr_t H5L__delete_by_idx_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc);
static herr_t H5L__delete_by_idx(const H5G_loc_t *loc, const char *name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n);
static herr_t H5L__move_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc);
static herr_t H5L__move_dest_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc);
static herr_t H5L__exists_final_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc);
static herr_t H5L__exists_inter_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc);
static htri_t H5L__exists(const H5G_loc_t *loc, const char *name);
static herr_t H5L__get_info_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc);
static herr_t H5L__get_info_by_idx_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc);
static herr_t H5L__get_info_by_idx(const H5G_loc_t *loc, const char *name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
H5L_info_t *linfo );
static herr_t H5L__get_name_by_idx_cb(H5G_loc_t *grp_loc,
const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc);
static ssize_t H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
char *name , size_t size);
static herr_t H5L__iterate(hid_t grp_id, const char *group_name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p,
H5L_iterate_t op, void *op_data);
hbool_t H5_PKG_INIT_VAR = FALSE;
static size_t H5L_table_alloc_g = 0;
static size_t H5L_table_used_g = 0;
static H5L_class_t *H5L_table_g = NULL;
herr_t
H5L_init(void)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L__init_package(void)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
if(H5L_register_external() < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to register external link class")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
int
H5L_term_package(void)
{
int n = 0;
FUNC_ENTER_NOAPI_NOINIT_NOERR
if(H5_PKG_INIT_VAR) {
if(H5L_table_g) {
H5L_table_g = (H5L_class_t *)H5MM_xfree(H5L_table_g);
H5L_table_used_g = H5L_table_alloc_g = 0;
n++;
}
if(0 == n)
H5_PKG_INIT_VAR = FALSE;
}
FUNC_LEAVE_NOAPI(n)
}
herr_t
H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
const char *dst_name, hid_t lcpl_id, hid_t lapl_id)
{
H5G_loc_t src_loc, *src_loc_p;
H5G_loc_t dst_loc, *dst_loc_p;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE6("e", "i*si*sii", src_loc_id, src_name, dst_loc_id, dst_name, lcpl_id,
lapl_id);
if(src_loc_id == H5L_SAME_LOC && dst_loc_id == H5L_SAME_LOC)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not both be H5L_SAME_LOC")
if(src_loc_id != H5L_SAME_LOC && H5G_loc(src_loc_id, &src_loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(dst_loc_id != H5L_SAME_LOC && H5G_loc(dst_loc_id, &dst_loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!src_name || !*src_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified")
if(!dst_name || !*dst_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified")
if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
if(H5P_DEFAULT == lcpl_id)
lcpl_id = H5P_LINK_CREATE_DEFAULT;
H5CX_set_lcpl(lcpl_id);
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC,
((src_loc_id != H5L_SAME_LOC) ? src_loc_id : dst_loc_id), TRUE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
src_loc_p = &src_loc;
dst_loc_p = &dst_loc;
if(src_loc_id == H5L_SAME_LOC)
src_loc_p = dst_loc_p;
else if(dst_loc_id == H5L_SAME_LOC)
dst_loc_p = src_loc_p;
if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name, FALSE, lcpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
const char *dst_name, hid_t lcpl_id, hid_t lapl_id)
{
H5G_loc_t src_loc, *src_loc_p;
H5G_loc_t dst_loc, *dst_loc_p;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE6("e", "i*si*sii", src_loc_id, src_name, dst_loc_id, dst_name, lcpl_id,
lapl_id);
if(src_loc_id == H5L_SAME_LOC && dst_loc_id == H5L_SAME_LOC)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not both be H5L_SAME_LOC")
if(src_loc_id != H5L_SAME_LOC && H5G_loc(src_loc_id, &src_loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(dst_loc_id != H5L_SAME_LOC && H5G_loc(dst_loc_id, &dst_loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!src_name || !*src_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified")
if(!dst_name || !*dst_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified")
if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
if(H5P_DEFAULT == lcpl_id)
lcpl_id = H5P_LINK_CREATE_DEFAULT;
H5CX_set_lcpl(lcpl_id);
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC,
((src_loc_id != H5L_SAME_LOC) ? src_loc_id : dst_loc_id), TRUE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
src_loc_p = &src_loc;
dst_loc_p = &dst_loc;
if(src_loc_id == H5L_SAME_LOC)
src_loc_p = dst_loc_p;
else if(dst_loc_id == H5L_SAME_LOC)
dst_loc_p = src_loc_p;
if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name, TRUE, lcpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to copy link")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Lcreate_soft(const char *link_target, hid_t link_loc_id, const char *link_name,
hid_t lcpl_id, hid_t lapl_id)
{
H5G_loc_t link_loc;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE5("e", "*si*sii", link_target, link_loc_id, link_name, lcpl_id, lapl_id);
if(H5G_loc(link_loc_id, &link_loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!link_target)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_target parameter cannot be NULL")
if(!*link_target)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_target parameter cannot be an empty string")
if(!link_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_name parameter cannot be NULL")
if(!*link_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link_name parameter cannot be an empty string")
if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
if(H5P_DEFAULT == lcpl_id)
lcpl_id = H5P_LINK_CREATE_DEFAULT;
H5CX_set_lcpl(lcpl_id);
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, link_loc_id, TRUE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
if(H5L_create_soft(link_target, &link_loc, link_name, lcpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create soft link")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name,
hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id)
{
H5G_loc_t cur_loc, *cur_loc_p;
H5G_loc_t new_loc, *new_loc_p;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE6("e", "i*si*sii", cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id,
lapl_id);
if(cur_loc_id == H5L_SAME_LOC && new_loc_id == H5L_SAME_LOC)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not be both H5L_SAME_LOC")
if(cur_loc_id != H5L_SAME_LOC && H5G_loc(cur_loc_id, &cur_loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(new_loc_id != H5L_SAME_LOC && H5G_loc(new_loc_id, &new_loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!cur_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cur_name parameter cannot be NULL")
if(!*cur_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cur_name parameter cannot be an empty string")
if(!new_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new_name parameter cannot be NULL")
if(!*new_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new_name parameter cannot be an empty string")
if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list")
if(H5P_DEFAULT == lcpl_id)
lcpl_id = H5P_LINK_CREATE_DEFAULT;
H5CX_set_lcpl(lcpl_id);
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, cur_loc_id, TRUE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
cur_loc_p = &cur_loc;
new_loc_p = &new_loc;
if(cur_loc_id == H5L_SAME_LOC)
cur_loc_p = new_loc_p;
else if(new_loc_id == H5L_SAME_LOC)
new_loc_p = cur_loc_p;
else if(cur_loc_p->oloc->file != new_loc_p->oloc->file)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file.")
if(H5L_create_hard(cur_loc_p, cur_name, new_loc_p, new_name, lcpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create link")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Lcreate_ud(hid_t link_loc_id, const char *link_name, H5L_type_t link_type,
const void *udata, size_t udata_size, hid_t lcpl_id, hid_t lapl_id)
{
H5G_loc_t link_loc;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE7("e", "i*sLl*xzii", link_loc_id, link_name, link_type, udata,
udata_size, lcpl_id, lapl_id);
if(H5G_loc(link_loc_id, &link_loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!link_name || !*link_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no link name specified")
if(link_type < H5L_TYPE_UD_MIN || link_type > H5L_TYPE_MAX)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link class")
if(H5P_DEFAULT == lcpl_id)
lcpl_id = H5P_LINK_CREATE_DEFAULT;
H5CX_set_lcpl(lcpl_id);
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, link_loc_id, TRUE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
if(H5L__create_ud(&link_loc, link_name, udata, udata_size, link_type, lcpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Ldelete(hid_t loc_id, const char *name, hid_t lapl_id)
{
H5G_loc_t loc;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE3("e", "i*si", loc_id, name, lapl_id);
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")
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
if(H5L_delete(&loc, name) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Ldelete_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, hid_t lapl_id)
{
H5G_loc_t loc;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE6("e", "i*sIiIohi", loc_id, group_name, idx_type, order, n, lapl_id);
if(H5G_loc(loc_id, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!group_name || !*group_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
if(H5L__delete_by_idx(&loc, group_name, idx_type, order, n) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Lget_val(hid_t loc_id, const char *name, void *buf, size_t size,
hid_t lapl_id)
{
H5G_loc_t loc;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE5("e", "i*sxzi", loc_id, name, buf, size, lapl_id);
if(H5G_loc(loc_id, &loc))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
if(H5L_get_val(&loc, name, buf, size) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link value for '%s'", name)
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, void *buf, size_t size,
hid_t lapl_id)
{
H5G_loc_t loc;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE8("e", "i*sIiIohxzi", loc_id, group_name, idx_type, order, n, buf, size,
lapl_id);
if(H5G_loc(loc_id, &loc))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!group_name || !*group_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
if(H5L__get_val_by_idx(&loc, group_name, idx_type, order, n, buf, size) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link value for")
done:
FUNC_LEAVE_API(ret_value)
}
htri_t
H5Lexists(hid_t loc_id, const char *name, hid_t lapl_id)
{
H5G_loc_t loc;
htri_t ret_value;
FUNC_ENTER_API(FAIL)
H5TRACE3("t", "i*si", loc_id, name, lapl_id);
if(H5G_loc(loc_id, &loc))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be NULL")
if(!*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "name parameter cannot be an empty string")
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
if((ret_value = H5L__exists(&loc, name)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Lget_info(hid_t loc_id, const char *name, H5L_info_t *linfo ,
hid_t lapl_id)
{
H5G_loc_t loc;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE4("e", "i*sxi", loc_id, name, linfo, lapl_id);
if(H5G_loc(loc_id, &loc))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
if(H5L_get_info(&loc, name, linfo) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Lget_info_by_idx(hid_t loc_id, const char *group_name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
H5L_info_t *linfo , hid_t lapl_id)
{
H5G_loc_t loc;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE7("e", "i*sIiIohxi", loc_id, group_name, idx_type, order, n, linfo,
lapl_id);
if(H5G_loc(loc_id, &loc))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!group_name || !*group_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
if(H5L__get_info_by_idx(&loc, group_name, idx_type, order, n, linfo) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Lregister(const H5L_class_t *cls)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE1("e", "*x", cls);
if(cls == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link class")
if(cls->version > H5L_LINK_CLASS_T_VERS)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid H5L_class_t version number")
if(cls->id < H5L_TYPE_UD_MIN || cls->id > H5L_TYPE_MAX)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link identification number")
if(cls->trav_func == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no traversal function specified")
if(H5L_register(cls) < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to register link type")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Lunregister(H5L_type_t id)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE1("e", "Ll", id);
if(id < 0 || id > H5L_TYPE_MAX)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link type")
if(H5L_unregister(id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to unregister link type")
done:
FUNC_LEAVE_API(ret_value)
}
htri_t
H5Lis_registered(H5L_type_t id)
{
size_t i;
htri_t ret_value = FALSE;
FUNC_ENTER_API(FAIL)
H5TRACE1("t", "Ll", id);
if(id < 0 || id > H5L_TYPE_MAX)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid link type id number")
for(i = 0; i < H5L_table_used_g; i++)
if(H5L_table_g[i].id == id) {
ret_value = TRUE;
break;
}
done:
FUNC_LEAVE_API(ret_value)
}
ssize_t
H5Lget_name_by_idx(hid_t loc_id, const char *group_name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n,
char *name , size_t size, hid_t lapl_id)
{
H5G_loc_t loc;
ssize_t ret_value;
FUNC_ENTER_API((-1))
H5TRACE8("Zs", "i*sIiIohxzi", loc_id, group_name, idx_type, order, n, name, size,
lapl_id);
if(H5G_loc(loc_id, &loc))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!group_name || !*group_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "no name specified")
if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid index type specified")
if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, (-1), "invalid iteration order specified")
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, TRUE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, (-1), "can't set access property list info")
if((ret_value = H5L__get_name_by_idx(&loc, group_name, idx_type, order, n, name, size)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, (-1), "unable to get link name")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Literate(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order,
hsize_t *idx_p, H5L_iterate_t op, void *op_data)
{
H5I_type_t id_type;
herr_t ret_value;
FUNC_ENTER_API(FAIL)
H5TRACE6("e", "iIiIo*hx*x", grp_id, idx_type, order, idx_p, op, op_data);
id_type = H5I_get_type(grp_id);
if (!(H5I_GROUP == id_type || H5I_FILE == id_type))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument")
if (idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
if (order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
if (!op)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified")
if((ret_value = H5L__iterate(grp_id, ".", idx_type, order, idx_p, op, op_data)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Literate_by_name(hid_t loc_id, const char *group_name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p,
H5L_iterate_t op, void *op_data, hid_t lapl_id)
{
herr_t ret_value;
FUNC_ENTER_API(FAIL)
H5TRACE8("e", "i*sIiIo*hx*xi", loc_id, group_name, idx_type, order, idx_p, op,
op_data, lapl_id);
if(!group_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_name parameter cannot be NULL")
if(!*group_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_name parameter cannot be an empty string")
if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
if(!op)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified")
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
if((ret_value = H5L__iterate(loc_id, group_name, idx_type, order, idx_p, op, op_data)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Lvisit(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order,
H5L_iterate_t op, void *op_data)
{
H5I_type_t id_type;
herr_t ret_value;
FUNC_ENTER_API(FAIL)
H5TRACE5("e", "iIiIox*x", grp_id, idx_type, order, op, op_data);
id_type = H5I_get_type(grp_id);
if(!(H5I_GROUP == id_type || H5I_FILE == id_type))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument")
if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
if(!op)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified")
if((ret_value = H5G_visit(grp_id, ".", idx_type, order, op, op_data)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed")
done:
FUNC_LEAVE_API(ret_value)
}
herr_t
H5Lvisit_by_name(hid_t loc_id, const char *group_name, H5_index_t idx_type,
H5_iter_order_t order, H5L_iterate_t op, void *op_data, hid_t lapl_id)
{
herr_t ret_value;
FUNC_ENTER_API(FAIL)
H5TRACE7("e", "i*sIiIox*xi", loc_id, group_name, idx_type, order, op, op_data,
lapl_id);
if(!group_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_name parameter cannot be NULL")
if(!*group_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group_name parameter cannot be an empty string")
if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
if(!op)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified")
if(H5CX_set_apl(&lapl_id, H5P_CLS_LACC, loc_id, FALSE) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't set access property list info")
if((ret_value = H5G_visit(loc_id, group_name, idx_type, order, op, op_data)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed")
done:
FUNC_LEAVE_API(ret_value)
}
static int
H5L_find_class_idx(H5L_type_t id)
{
size_t i;
int ret_value = FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
for(i = 0; i < H5L_table_used_g; i++)
if(H5L_table_g[i].id == id)
HGOTO_DONE((int)i)
done:
FUNC_LEAVE_NOAPI(ret_value)
}
const H5L_class_t *
H5L_find_class(H5L_type_t id)
{
int idx;
H5L_class_t *ret_value = NULL;
FUNC_ENTER_NOAPI(NULL)
if((idx = H5L_find_class_idx(id)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, NULL, "unable to find link class")
ret_value = H5L_table_g+idx;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L_register(const H5L_class_t *cls)
{
size_t i;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(cls);
HDassert(cls->id >= 0 && cls->id <= H5L_TYPE_MAX);
for(i = 0; i < H5L_table_used_g; i++)
if(H5L_table_g[i].id == cls->id)
break;
if(i >= H5L_table_used_g) {
if(H5L_table_used_g >= H5L_table_alloc_g) {
size_t n = MAX(H5L_MIN_TABLE_SIZE, (2 * H5L_table_alloc_g));
H5L_class_t *table = (H5L_class_t *)H5MM_realloc(H5L_table_g, (n * sizeof(H5L_class_t)));
if(!table)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to extend link type table")
H5L_table_g = table;
H5L_table_alloc_g = n;
}
i = H5L_table_used_g++;
}
H5MM_memcpy(H5L_table_g + i, cls, sizeof(H5L_class_t));
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L_unregister(H5L_type_t id)
{
size_t i;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(id >= 0 && id <= H5L_TYPE_MAX);
for(i = 0; i < H5L_table_used_g; i++)
if(H5L_table_g[i].id == id)
break;
if(i >= H5L_table_used_g)
HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "link class is not registered")
HDmemmove(&H5L_table_g[i], &H5L_table_g[i + 1], sizeof(H5L_class_t) * ((H5L_table_used_g - 1) - i));
H5L_table_used_g--;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L_link(const H5G_loc_t *new_loc, const char *new_name, H5G_loc_t *obj_loc, hid_t lcpl_id)
{
H5O_link_t lnk;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT
HDassert(new_loc);
HDassert(obj_loc);
HDassert(new_name && *new_name);
lnk.type = H5L_TYPE_HARD;
lnk.u.hard.addr = obj_loc->oloc->addr;
if(H5L__create_real(new_loc, new_name, obj_loc->path, obj_loc->oloc->file, &lnk, NULL, lcpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L_link_object(const H5G_loc_t *new_loc, const char *new_name,
H5O_obj_create_t *ocrt_info, hid_t lcpl_id)
{
H5O_link_t lnk;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT
HDassert(new_loc);
HDassert(new_name && *new_name);
HDassert(ocrt_info);
lnk.type = H5L_TYPE_HARD;
if(H5L__create_real(new_loc, new_name, NULL, NULL, &lnk, ocrt_info, lcpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__link_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t H5_ATTR_UNUSED *lnk,
H5G_loc_t *obj_loc, void *_udata, H5G_own_loc_t *own_loc)
{
H5L_trav_cr_t *udata = (H5L_trav_cr_t *)_udata;
H5G_t *grp = NULL;
hid_t grp_id = FAIL;
H5G_loc_t temp_loc;
hbool_t temp_loc_init = FALSE;
hbool_t obj_created = FALSE;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
if(obj_loc != NULL)
HGOTO_ERROR(H5E_LINK, H5E_EXISTS, FAIL, "name already exists")
if(udata->lnk->type == H5L_TYPE_HARD) {
if(udata->ocrt_info) {
H5G_loc_t new_loc;
if(NULL == (udata->ocrt_info->new_obj = H5O_obj_create(grp_loc->oloc->file, udata->ocrt_info->obj_type, udata->ocrt_info->crt_info, &new_loc)))
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create object")
udata->lnk->u.hard.addr = new_loc.oloc->addr;
udata->path = new_loc.path;
obj_created = TRUE;
}
else {
if(!H5F_SAME_SHARED(grp_loc->oloc->file, udata->file))
HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "interfile hard links are not allowed")
}
}
udata->lnk->corder = 0;
udata->lnk->corder_valid = FALSE;
if(udata->lc_plist) {
if(H5CX_get_encoding(&udata->lnk->cset) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get 'character set' property")
}
else
udata->lnk->cset = H5F_DEFAULT_CSET;
udata->lnk->name = (char *)name;
if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, TRUE,
udata->ocrt_info ? udata->ocrt_info->obj_type : H5O_TYPE_UNKNOWN,
udata->ocrt_info ? udata->ocrt_info->crt_info : NULL) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link for object")
if(udata->path != NULL && udata->path->user_path_r == NULL)
if(H5G_name_set(grp_loc->path, udata->path, name) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "cannot set name")
if(udata->lnk->type >= H5L_TYPE_UD_MIN) {
const H5L_class_t *link_class;
if(NULL == (link_class = H5L_find_class(udata->lnk->type)))
HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to get class of UD link")
if(link_class->create_func != NULL) {
H5O_loc_t temp_oloc;
H5G_name_t temp_path;
H5G_name_reset(&temp_path);
if(H5O_loc_copy_deep(&temp_oloc, grp_loc->oloc) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy object location")
temp_loc.oloc = &temp_oloc;
temp_loc.path = &temp_path;
temp_loc_init = TRUE;
if(NULL == (grp = H5G_open(&temp_loc)))
HGOTO_ERROR(H5E_LINK, H5E_CANTOPENOBJ, FAIL, "unable to open group")
if((grp_id = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTREGISTER, FAIL, "unable to register ID for group")
if((link_class->create_func)(name, grp_id, udata->lnk->u.ud.udata, udata->lnk->u.ud.size, H5P_DEFAULT) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "link creation callback failed")
}
}
done:
if(obj_created) {
H5O_loc_t oloc;
HDmemset(&oloc, 0, sizeof(oloc));
oloc.file = grp_loc->oloc->file;
oloc.addr = udata->lnk->u.hard.addr;
if(H5O_dec_rc_by_loc(&oloc) < 0)
HDONE_ERROR(H5E_LINK, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object")
}
if(grp_id >= 0) {
if(H5I_dec_app_ref(grp_id) < 0)
HDONE_ERROR(H5E_LINK, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
}
else if(grp != NULL) {
if(H5G_close(grp) < 0)
HDONE_ERROR(H5E_LINK, H5E_CANTRELEASE, FAIL, "unable to close group given to UD callback")
}
else if(temp_loc_init)
H5G_loc_free(&temp_loc);
*own_loc = H5G_OWN_NONE;
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__create_real(const H5G_loc_t *link_loc, const char *link_name,
H5G_name_t *obj_path, H5F_t *obj_file, H5O_link_t *lnk,
H5O_obj_create_t *ocrt_info, hid_t lcpl_id)
{
char *norm_link_name = NULL;
unsigned target_flags = H5G_TARGET_NORMAL;
H5P_genplist_t *lc_plist = NULL;
H5L_trav_cr_t udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
HDassert(link_loc);
HDassert(link_name && *link_name);
HDassert(lnk);
HDassert(lnk->type >= H5L_TYPE_HARD && lnk->type <= H5L_TYPE_MAX);
if((norm_link_name = H5G_normalize(link_name)) == NULL)
HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "can't normalize name")
if(lcpl_id != H5P_DEFAULT && lcpl_id != H5P_LINK_CREATE_DEFAULT) {
unsigned crt_intmd_group;
if(NULL == (lc_plist = (H5P_genplist_t *)H5I_object(lcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
if(H5CX_get_intermediate_group(&crt_intmd_group) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get 'create intermediate group' property")
if(crt_intmd_group > 0)
target_flags |= H5G_CRT_INTMD_GROUP;
}
udata.file = obj_file;
udata.lc_plist = lc_plist;
udata.path = obj_path;
udata.ocrt_info = ocrt_info;
udata.lnk = lnk;
if(H5G_traverse(link_loc, link_name, target_flags, H5L__link_cb, &udata) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINSERT, FAIL, "can't insert link")
done:
if(norm_link_name)
H5MM_xfree(norm_link_name);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name,
const H5G_loc_t *link_loc, const char *link_name, hid_t lcpl_id)
{
char *norm_cur_name = NULL;
H5F_t *link_file = NULL;
H5O_link_t lnk;
H5G_loc_t obj_loc;
H5G_name_t path;
H5O_loc_t oloc;
hbool_t loc_valid = FALSE;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(cur_loc);
HDassert(cur_name && *cur_name);
HDassert(link_loc);
HDassert(link_name && *link_name);
if((norm_cur_name = H5G_normalize(cur_name)) == NULL)
HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "can't normalize name")
lnk.type = H5L_TYPE_HARD;
obj_loc.path = &path;
obj_loc.oloc = &oloc;
H5G_loc_reset(&obj_loc);
if(H5G_loc_find(cur_loc, norm_cur_name, &obj_loc) < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "source object not found")
loc_valid = TRUE;
lnk.u.hard.addr = obj_loc.oloc->addr;
link_file = obj_loc.oloc->file;
if(H5L__create_real(link_loc, link_name, NULL, link_file, &lnk, NULL, lcpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object")
done:
if(loc_valid)
if(H5G_loc_free(&obj_loc) < 0)
HDONE_ERROR(H5E_LINK, H5E_CANTRELEASE, FAIL, "unable to free location")
if(norm_cur_name)
H5MM_xfree(norm_cur_name);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L_create_soft(const char *target_path, const H5G_loc_t *link_loc,
const char *link_name, hid_t lcpl_id)
{
char *norm_target = NULL;
H5O_link_t lnk;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(link_loc);
HDassert(target_path && *target_path);
HDassert(link_name && *link_name);
if((norm_target = H5G_normalize(target_path)) == NULL)
HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "can't normalize name")
lnk.type = H5L_TYPE_SOFT;
lnk.u.soft.name = norm_target;
if(H5L__create_real(link_loc, link_name, NULL, NULL, &lnk, NULL, lcpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object")
done:
if(norm_target)
H5MM_xfree(norm_target);
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L__create_ud(const H5G_loc_t *link_loc, const char *link_name,
const void *ud_data, size_t ud_data_size, H5L_type_t type, hid_t lcpl_id)
{
H5O_link_t lnk;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(type >= H5L_TYPE_UD_MIN && type <= H5L_TYPE_MAX);
HDassert(link_loc);
HDassert(link_name && *link_name);
HDassert(ud_data_size == 0 || ud_data);
lnk.u.ud.udata = NULL;
if(H5L_find_class_idx(type) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "link class has not been registered with library")
if(ud_data_size > 0) {
lnk.u.ud.udata = H5MM_malloc((size_t)ud_data_size);
H5MM_memcpy(lnk.u.ud.udata, ud_data, (size_t) ud_data_size);
}
else
lnk.u.ud.udata = NULL;
lnk.u.ud.size = ud_data_size;
lnk.type = type;
if(H5L__create_real(link_loc, link_name, NULL, NULL, &lnk, NULL, lcpl_id) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to register new name for object")
done:
H5MM_xfree(lnk.u.ud.udata);
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__get_val_real(const H5O_link_t *lnk, void *buf, size_t size)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
HDassert(lnk);
if(H5L_TYPE_SOFT == lnk->type) {
if(size > 0 && buf) {
HDstrncpy((char *)buf, lnk->u.soft.name, size);
if(HDstrlen(lnk->u.soft.name) >= size)
((char *)buf)[size - 1] = '\0';
}
}
else if(lnk->type >= H5L_TYPE_UD_MIN) {
const H5L_class_t *link_class;
link_class = H5L_find_class(lnk->type);
if(link_class != NULL && link_class->query_func != NULL) {
if((link_class->query_func)(lnk->name, lnk->u.ud.udata, lnk->u.ud.size, buf, size) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "query callback returned failure")
}
else if(buf && size > 0)
((char *)buf)[0] = '\0';
}
else
HGOTO_ERROR(H5E_LINK, H5E_BADTYPE, FAIL, "object is not a symbolic or user-defined link")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__get_val_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc, const char *name, const H5O_link_t *lnk,
H5G_loc_t H5_ATTR_UNUSED *obj_loc, void *_udata, H5G_own_loc_t *own_loc)
{
H5L_trav_gv_t *udata = (H5L_trav_gv_t *)_udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
if(lnk == NULL)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "'%s' doesn't exist", name)
if(H5L__get_val_real(lnk, udata->buf, udata->size) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't retrieve link value")
done:
*own_loc = H5G_OWN_NONE;
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L_get_val(const H5G_loc_t *loc, const char *name, void *buf, size_t size)
{
H5L_trav_gv_t udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(loc);
HDassert(name && *name);
udata.size = size;
udata.buf = buf;
if(H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__get_val_cb, &udata) < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "name doesn't exist")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__get_val_by_idx_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc, const char H5_ATTR_UNUSED *name,
const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc)
{
H5L_trav_gvbi_t *udata = (H5L_trav_gvbi_t *)_udata;
H5O_link_t fnd_lnk;
hbool_t lnk_copied = FALSE;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
if(obj_loc == NULL)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "group doesn't exist")
if(H5G_obj_lookup_by_idx(obj_loc->oloc, udata->idx_type, udata->order, udata->n, &fnd_lnk) < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "link not found")
lnk_copied = TRUE;
if(H5L__get_val_real(&fnd_lnk, udata->buf, udata->size) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't retrieve link value")
done:
if(lnk_copied)
H5O_msg_reset(H5O_LINK_ID, &fnd_lnk);
*own_loc = H5G_OWN_NONE;
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__get_val_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, void *buf, size_t size)
{
H5L_trav_gvbi_t udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
HDassert(loc);
HDassert(name && *name);
udata.idx_type = idx_type;
udata.order = order;
udata.n = n;
udata.buf = buf;
udata.size = size;
if(H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__get_val_by_idx_cb, &udata) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get link info for index: %llu", (unsigned long long)n)
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__delete_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t *lnk,
H5G_loc_t H5_ATTR_UNUSED *obj_loc, void H5_ATTR_UNUSED *_udata,
H5G_own_loc_t *own_loc)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
if(grp_loc == NULL)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "group doesn't exist")
if(name == NULL)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "name doesn't exist")
if(lnk == NULL)
HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "callback link pointer is NULL (specified link may be '.' or not exist)")
if(H5G_obj_remove(grp_loc->oloc, grp_loc->path->full_path_r, name) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to remove link from group")
done:
*own_loc = H5G_OWN_NONE;
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L_delete(const H5G_loc_t *loc, const char *name)
{
char *norm_name = NULL;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(loc);
HDassert(name && *name);
if((norm_name = H5G_normalize(name)) == NULL)
HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "can't normalize name")
if(H5G_traverse(loc, norm_name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK | H5G_TARGET_MOUNT, H5L__delete_cb, NULL) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTREMOVE, FAIL, "can't unlink object")
done:
if(norm_name)
H5MM_xfree(norm_name);
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__delete_by_idx_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc, const char H5_ATTR_UNUSED *name,
const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc)
{
H5L_trav_gvbi_t *udata = (H5L_trav_gvbi_t *)_udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC_TAG((obj_loc) ? (obj_loc->oloc->addr) : HADDR_UNDEF)
if(obj_loc == NULL)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "group doesn't exist")
if(H5G_obj_remove_by_idx(obj_loc->oloc, obj_loc->path->full_path_r, udata->idx_type, udata->order, udata->n) < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "link not found")
done:
*own_loc = H5G_OWN_NONE;
FUNC_LEAVE_NOAPI_TAG(ret_value)
}
static herr_t
H5L__delete_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n)
{
H5L_trav_rmbi_t udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
HDassert(loc);
HDassert(name && *name);
udata.idx_type = idx_type;
udata.order = order;
udata.n = n;
if(H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK | H5G_TARGET_MOUNT, H5L__delete_by_idx_cb, &udata) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "link doesn't exist")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__move_dest_cb(H5G_loc_t *grp_loc, const char *name,
const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc)
{
H5L_trav_mv2_t *udata = (H5L_trav_mv2_t *)_udata;
H5G_t *grp = NULL;
hid_t grp_id = FAIL;
H5G_loc_t temp_loc;
hbool_t temp_loc_init = FALSE;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
if(obj_loc != NULL)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "an object with that name already exists")
if(udata->lnk->type == H5L_TYPE_HARD)
if(!H5F_SAME_SHARED(grp_loc->oloc->file, udata->file))
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "moving a link across files is not allowed")
HDassert(udata->lnk->name == NULL);
udata->lnk->name = (char *)name;
if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, TRUE, H5O_TYPE_UNKNOWN, NULL) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create new link to object")
if(udata->lnk->type >= H5L_TYPE_UD_MIN) {
const H5L_class_t *link_class;
if(NULL == (link_class = H5L_find_class(udata->lnk->type)))
HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "link class is not registered")
if((!udata->copy && link_class->move_func) || (udata->copy && link_class->copy_func)) {
H5O_loc_t temp_oloc;
H5G_name_t temp_path;
H5G_name_reset(&temp_path);
if(H5O_loc_copy_deep(&temp_oloc, grp_loc->oloc) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy object location")
temp_loc.oloc = &temp_oloc;
temp_loc.path = &temp_path;
temp_loc_init = TRUE;
if(NULL == (grp = H5G_open(&temp_loc)))
HGOTO_ERROR(H5E_LINK, H5E_CANTOPENOBJ, FAIL, "unable to open group")
if((grp_id = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTREGISTER, FAIL, "unable to register group ID")
if(udata->copy) {
if((link_class->copy_func)(udata->lnk->name, grp_id, udata->lnk->u.ud.udata, udata->lnk->u.ud.size) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "UD copy callback returned error")
}
else {
if((link_class->move_func)(udata->lnk->name, grp_id, udata->lnk->u.ud.udata, udata->lnk->u.ud.size) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "UD move callback returned error")
}
}
}
done:
if(grp_id >= 0) {
if(H5I_dec_app_ref(grp_id) < 0)
HDONE_ERROR(H5E_LINK, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
}
else if(grp != NULL) {
if(H5G_close(grp) < 0)
HDONE_ERROR(H5E_LINK, H5E_CANTRELEASE, FAIL, "unable to close group given to UD callback")
}
else if(temp_loc_init)
H5G_loc_free(&temp_loc);
*own_loc = H5G_OWN_NONE;
udata->lnk->name = NULL;
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__move_cb(H5G_loc_t *grp_loc, const char *name, const H5O_link_t *lnk,
H5G_loc_t *obj_loc, void *_udata, H5G_own_loc_t *own_loc)
{
H5L_trav_mv_t *udata = (H5L_trav_mv_t *)_udata;
H5L_trav_mv2_t udata_out;
char * orig_name = NULL;
hbool_t link_copied = FALSE;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
if(obj_loc == NULL)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "name doesn't exist")
if(lnk == NULL)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "the name of a link must be supplied to move or copy")
if(NULL == (udata_out.lnk = (H5O_link_t *)H5O_msg_copy(H5O_LINK_ID, lnk, NULL)))
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy link to be moved")
udata_out.lnk->name = (char *)H5MM_xfree(udata_out.lnk->name);
link_copied = TRUE;
udata_out.lnk->cset = udata->cset;
udata_out.file = grp_loc->oloc->file;
udata_out.copy = udata->copy;
orig_name = H5MM_xstrdup(name);
if(H5CX_set_nlinks(udata->orig_nlinks) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTSET, FAIL, "can't reset # of soft / UD links to traverse")
if(H5G_traverse(udata->dst_loc, udata->dst_name, udata->dst_target_flags, H5L__move_dest_cb, &udata_out) < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to follow symbolic link")
if(!udata->copy) {
H5RS_str_t *dst_name_r;
if(*(udata->dst_name) != '/') {
HDassert(udata->dst_loc->path->full_path_r);
if((dst_name_r = H5G_build_fullpath_refstr_str(udata->dst_loc->path->full_path_r,
udata->dst_name)) == NULL)
HGOTO_ERROR(H5E_LINK, H5E_PATH, FAIL, "can't build destination path name")
}
else
dst_name_r = H5RS_wrap(udata->dst_name);
HDassert(dst_name_r);
if(H5G_name_replace(lnk, H5G_NAME_MOVE, obj_loc->oloc->file, obj_loc->path->full_path_r,
udata->dst_loc->oloc->file, dst_name_r) < 0) {
H5RS_decr(dst_name_r);
HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to replace name")
}
if(H5G_obj_remove(grp_loc->oloc, grp_loc->path->full_path_r, orig_name) < 0) {
H5RS_decr(dst_name_r);
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to remove old name")
}
H5RS_decr(dst_name_r);
}
done:
if(orig_name)
H5MM_xfree(orig_name);
if(link_copied)
H5O_msg_free(H5O_LINK_ID, udata_out.lnk);
*own_loc = H5G_OWN_NONE;
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L_move(const H5G_loc_t *src_loc, const char *src_name, const H5G_loc_t *dst_loc,
const char *dst_name, hbool_t copy_flag, hid_t lcpl_id)
{
unsigned dst_target_flags = H5G_TARGET_NORMAL;
H5T_cset_t char_encoding = H5F_DEFAULT_CSET;
H5P_genplist_t* lc_plist;
H5L_trav_mv_t udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(src_loc);
HDassert(dst_loc);
HDassert(src_name && *src_name);
HDassert(dst_name && *dst_name);
if(lcpl_id != H5P_DEFAULT && lcpl_id != H5P_LINK_CREATE_DEFAULT) {
unsigned crt_intmd_group;
if(NULL == (lc_plist = (H5P_genplist_t *)H5I_object(lcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
if(H5CX_get_intermediate_group(&crt_intmd_group) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for creating missing groups")
if(crt_intmd_group > 0)
dst_target_flags |= H5G_CRT_INTMD_GROUP;
if(H5CX_get_encoding(&char_encoding) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for character encoding")
}
udata.dst_loc = dst_loc;
udata.dst_name= dst_name;
udata.dst_target_flags = dst_target_flags;
udata.cset = char_encoding;
udata.copy = copy_flag;
if(H5CX_get_nlinks(&udata.orig_nlinks) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve # of soft / UD links to traverse")
if(H5G_traverse(src_loc, src_name, H5G_TARGET_MOUNT | H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__move_cb, &udata) < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to find link")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__exists_final_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc, const char H5_ATTR_UNUSED *name,
const H5O_link_t *lnk, H5G_loc_t H5_ATTR_UNUSED *obj_loc, void *_udata,
H5G_own_loc_t *own_loc)
{
H5L_trav_le_t *udata = (H5L_trav_le_t *)_udata;
FUNC_ENTER_STATIC_NOERR
udata->exists = (hbool_t)(lnk != NULL);
*own_loc = H5G_OWN_NONE;
FUNC_LEAVE_NOAPI(SUCCEED)
}
static herr_t
H5L__exists_inter_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc, const char H5_ATTR_UNUSED *name,
const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc)
{
H5L_trav_le_t *udata = (H5L_trav_le_t *)_udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
if(lnk != NULL) {
if(udata->sep) {
H5G_traverse_t cb_func;
char *next;
next = udata->sep;
if(NULL == (udata->sep = HDstrchr(udata->sep, '/')))
cb_func = H5L__exists_final_cb;
else {
do {
*udata->sep = '\0';
udata->sep++;
} while('/' == *udata->sep);
cb_func = H5L__exists_inter_cb;
}
if(H5G_traverse(obj_loc, next, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, cb_func, udata) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if link exists")
}
else
udata->exists = TRUE;
}
else
udata->exists = FALSE;
*own_loc = H5G_OWN_NONE;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
htri_t
H5L_exists_tolerant(const H5G_loc_t *loc, const char *name)
{
H5L_trav_le_t udata;
H5G_traverse_t cb_func;
char *name_copy = NULL;
char *name_trav;
htri_t ret_value = FAIL;
FUNC_ENTER_NOAPI(FAIL)
HDassert(loc);
HDassert(name);
name_trav = name_copy = H5MM_strdup(name);
while('/' == *name_trav)
name_trav++;
if('\0' == *name_trav)
HGOTO_DONE(TRUE)
udata.exists = FALSE;
if(NULL == (udata.sep = HDstrchr(name_trav, '/')))
cb_func = H5L__exists_final_cb;
else {
do {
*udata.sep = '\0';
udata.sep++;
} while('/' == *udata.sep);
cb_func = H5L__exists_inter_cb;
}
if(H5G_traverse(loc, name_trav, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, cb_func, &udata) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't determine if link exists")
ret_value = (htri_t)udata.exists;
done:
H5MM_xfree(name_copy);
FUNC_LEAVE_NOAPI(ret_value)
}
htri_t
H5L__exists(const H5G_loc_t *loc, const char *name)
{
H5L_trav_le_t udata;
htri_t ret_value = FAIL;
FUNC_ENTER_STATIC
if(0 == HDstrcmp(name, "/"))
HGOTO_DONE(TRUE)
udata.exists = FALSE;
if(H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__exists_final_cb, &udata) < 0)
HGOTO_ERROR(H5E_LINK, H5E_EXISTS, FAIL, "path doesn't exist")
ret_value = (htri_t)udata.exists;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__get_info_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc, const char H5_ATTR_UNUSED *name,
const H5O_link_t *lnk, H5G_loc_t H5_ATTR_UNUSED *obj_loc, void *_udata,
H5G_own_loc_t *own_loc)
{
H5L_trav_gi_t *udata = (H5L_trav_gi_t *)_udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
if(lnk == NULL)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "name doesn't exist")
if(H5G_link_to_info(lnk, udata->linfo) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get link info")
done:
*own_loc = H5G_OWN_NONE;
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L_get_info(const H5G_loc_t *loc, const char *name, H5L_info_t *linfo)
{
H5L_trav_gi_t udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
udata.linfo = linfo;
if(H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__get_info_cb, &udata) < 0)
HGOTO_ERROR(H5E_LINK, H5E_EXISTS, FAIL, "name doesn't exist")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__get_info_by_idx_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc, const char H5_ATTR_UNUSED *name,
const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc)
{
H5L_trav_gibi_t *udata = (H5L_trav_gibi_t *)_udata;
H5O_link_t fnd_lnk;
hbool_t lnk_copied = FALSE;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
if(obj_loc == NULL)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "group doesn't exist")
if(H5G_obj_lookup_by_idx(obj_loc->oloc, udata->idx_type, udata->order, udata->n, &fnd_lnk) < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "link not found")
lnk_copied = TRUE;
if(H5G_link_to_info(&fnd_lnk, udata->linfo) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get link info")
done:
if(lnk_copied)
H5O_msg_reset(H5O_LINK_ID, &fnd_lnk);
*own_loc = H5G_OWN_NONE;
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__get_info_by_idx(const H5G_loc_t *loc, const char *name, H5_index_t idx_type,
H5_iter_order_t order, hsize_t n, H5L_info_t *linfo )
{
H5L_trav_gibi_t udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
HDassert(loc);
HDassert(name && *name);
HDassert(linfo);
udata.idx_type = idx_type;
udata.order = order;
udata.n = n;
udata.linfo = linfo;
if(H5G_traverse(loc, name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__get_info_by_idx_cb, &udata) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to get link info")
done:
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__get_name_by_idx_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc, const char H5_ATTR_UNUSED *name,
const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata,
H5G_own_loc_t *own_loc)
{
H5L_trav_gnbi_t *udata = (H5L_trav_gnbi_t *)_udata;
herr_t ret_value = SUCCEED;
FUNC_ENTER_STATIC
if(obj_loc == NULL)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "group doesn't exist")
if((udata->name_len = H5G_obj_get_name_by_idx(obj_loc->oloc, udata->idx_type, udata->order, udata->n, udata->name, udata->size)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "link not found")
done:
*own_loc = H5G_OWN_NONE;
FUNC_LEAVE_NOAPI(ret_value)
}
static ssize_t
H5L__get_name_by_idx(const H5G_loc_t *loc, const char *group_name,
H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name ,
size_t size)
{
H5L_trav_gnbi_t udata;
ssize_t ret_value = FAIL;
FUNC_ENTER_STATIC
HDassert(loc);
HDassert(group_name && *group_name);
udata.idx_type = idx_type;
udata.order = order;
udata.n = n;
udata.name = name;
udata.size = size;
udata.name_len = -1;
if(H5G_traverse(loc, group_name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L__get_name_by_idx_cb, &udata) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get name")
ret_value = udata.name_len;
done:
FUNC_LEAVE_NOAPI(ret_value)
}
herr_t
H5L__link_copy_file(H5F_t *dst_file, const H5O_link_t *_src_lnk,
const H5O_loc_t *src_oloc, H5O_link_t *dst_lnk, H5O_copy_t *cpy_info)
{
H5O_link_t tmp_src_lnk;
const H5O_link_t *src_lnk = _src_lnk;
hbool_t dst_lnk_init = FALSE;
hbool_t expanded_link_open = FALSE;
H5G_loc_t tmp_src_loc;
H5G_name_t tmp_src_path;
H5O_loc_t tmp_src_oloc;
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
HDassert(dst_file);
HDassert(src_lnk);
HDassert(dst_lnk);
HDassert(cpy_info);
if((H5L_TYPE_SOFT == src_lnk->type && cpy_info->expand_soft_link)
|| (H5L_TYPE_EXTERNAL == src_lnk->type
&& cpy_info->expand_ext_link)) {
H5G_loc_t lnk_grp_loc;
H5G_name_t lnk_grp_path;
htri_t tar_exists;
H5G_name_reset(&lnk_grp_path);
lnk_grp_loc.path = &lnk_grp_path;
lnk_grp_loc.oloc = (H5O_loc_t *)src_oloc;
if((tar_exists = H5G_loc_exists(&lnk_grp_loc, src_lnk->name)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to check if target object exists")
if(tar_exists) {
if(NULL == H5O_msg_copy(H5O_LINK_ID, src_lnk, &tmp_src_lnk))
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy message")
tmp_src_loc.path = &tmp_src_path;
tmp_src_loc.oloc = &tmp_src_oloc;
if(H5G_loc_reset(&tmp_src_loc) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to reset location")
if(H5G_loc_find(&lnk_grp_loc, src_lnk->name, &tmp_src_loc) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to find target object")
expanded_link_open = TRUE;
if(tmp_src_lnk.type == H5L_TYPE_SOFT)
tmp_src_lnk.u.soft.name =
(char *)H5MM_xfree(tmp_src_lnk.u.soft.name);
else if(tmp_src_lnk.u.ud.size > 0)
tmp_src_lnk.u.ud.udata = H5MM_xfree(tmp_src_lnk.u.ud.udata);
tmp_src_lnk.type = H5L_TYPE_HARD;
tmp_src_lnk.u.hard.addr = tmp_src_oloc.addr;
src_lnk = &tmp_src_lnk;
}
}
if(NULL == H5O_msg_copy(H5O_LINK_ID, src_lnk, dst_lnk))
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy message")
dst_lnk_init = TRUE;
if(H5L_TYPE_HARD == src_lnk->type) {
H5O_loc_t new_dst_oloc;
H5O_loc_reset(&new_dst_oloc);
new_dst_oloc.file = dst_file;
if(!expanded_link_open) {
H5O_loc_reset(&tmp_src_oloc);
tmp_src_oloc.file = src_oloc->file;
tmp_src_oloc.addr = src_lnk->u.hard.addr;
}
HDassert(H5F_addr_defined(tmp_src_oloc.addr));
if(H5O_copy_header_map(&tmp_src_oloc, &new_dst_oloc, cpy_info, TRUE, NULL, NULL) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy object")
dst_lnk->u.hard.addr = new_dst_oloc.addr;
}
done:
if(src_lnk != _src_lnk) {
HDassert(src_lnk == &tmp_src_lnk);
H5O_msg_reset(H5O_LINK_ID, &tmp_src_lnk);
}
if(ret_value < 0)
if(dst_lnk_init)
H5O_msg_reset(H5O_LINK_ID, dst_lnk);
if(expanded_link_open)
if(H5G_loc_free(&tmp_src_loc) < 0)
HDONE_ERROR(H5E_LINK, H5E_CANTFREE, FAIL, "unable to free object")
FUNC_LEAVE_NOAPI(ret_value)
}
static herr_t
H5L__iterate(hid_t grp_id, const char *group_name, H5_index_t idx_type,
H5_iter_order_t order, hsize_t *idx_p, H5L_iterate_t op, void *op_data)
{
H5G_link_iterate_t lnk_op;
hsize_t last_lnk;
hsize_t idx;
herr_t ret_value = FAIL;
FUNC_ENTER_STATIC
HDassert(group_name);
HDassert(op);
idx = (idx_p == NULL ? 0 : *idx_p);
last_lnk = 0;
lnk_op.op_type = H5G_LINK_OP_NEW;
lnk_op.op_func.op_new = op;
if((ret_value = H5G_iterate(grp_id, group_name, idx_type, order, idx, &last_lnk, &lnk_op, op_data)) < 0)
HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link iteration failed")
if(idx_p)
*idx_p = last_lnk;
done:
FUNC_LEAVE_NOAPI(ret_value)
}