/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright by The HDF Group. * * All rights reserved. * * * * This file is part of HDF5. The full HDF5 copyright notice, including * * terms governing use, modification, and redistribution, is contained in * * the COPYING file, which can be found at the root of the source code * * distribution tree, or in https://www.hdfgroup.org/licenses. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * Purpose: Link callbacks for the native VOL connector * */ /****************/ /* Module Setup */ /****************/ #define H5L_FRIEND /* Suppress error about including H5Lpkg */ /***********/ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5Gprivate.h" /* Groups */ #include "H5Lpkg.h" /* Links */ #include "H5VLprivate.h" /* Virtual Object Layer */ #include "H5VLnative_private.h" /* Native VOL connector */ /****************/ /* Local Macros */ /****************/ /******************/ /* Local Typedefs */ /******************/ /********************/ /* Local Prototypes */ /********************/ /*********************/ /* Package Variables */ /*********************/ /*****************************/ /* Library Private Variables */ /*****************************/ /*******************/ /* Local Variables */ /*******************/ /*------------------------------------------------------------------------- * Function: H5VL__native_link_create * * Purpose: Handles the link create callback * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5VL__native_link_create(H5VL_link_create_args_t *args, void *obj, const H5VL_loc_params_t *loc_params, hid_t lcpl_id, hid_t H5_ATTR_UNUSED lapl_id, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE switch (args->op_type) { case H5VL_LINK_CREATE_HARD: { H5G_loc_t cur_loc; H5G_loc_t link_loc; void *cur_obj = args->args.hard.curr_obj; H5VL_loc_params_t *cur_params = &args->args.hard.curr_loc_params; if (NULL != cur_obj && H5G_loc_real(cur_obj, cur_params->obj_type, &cur_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); if (NULL != obj && H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); /* H5Lcreate_hard */ if (H5VL_OBJECT_BY_NAME == cur_params->type) { H5G_loc_t *cur_loc_p, *link_loc_p; /* Set up current & new location pointers */ cur_loc_p = &cur_loc; link_loc_p = &link_loc; if (NULL == cur_obj) cur_loc_p = link_loc_p; else if (NULL == obj) link_loc_p = cur_loc_p; else if (cur_loc_p->oloc->file != link_loc_p->oloc->file) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file."); /* Create the link */ if (H5L__create_hard(cur_loc_p, cur_params->loc_data.loc_by_name.name, link_loc_p, loc_params->loc_data.loc_by_name.name, lcpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link"); } /* end if */ else { /* H5Olink */ /* Link to the object */ if (H5L_link(&link_loc, loc_params->loc_data.loc_by_name.name, &cur_loc, lcpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link"); } /* end else */ break; } case H5VL_LINK_CREATE_SOFT: { H5G_loc_t link_loc; /* Group location for new link */ if (H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); if (H5L__create_soft(args->args.soft.target, &link_loc, loc_params->loc_data.loc_by_name.name, lcpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCREATE, FAIL, "unable to create link"); break; } case H5VL_LINK_CREATE_UD: { H5G_loc_t link_loc; /* Group location for new link */ if (H5G_loc_real(obj, loc_params->obj_type, &link_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); if (H5L__create_ud(&link_loc, loc_params->loc_data.loc_by_name.name, args->args.ud.buf, args->args.ud.buf_size, args->args.ud.type, lcpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link"); break; } default: HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "invalid link creation call"); } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_link_create() */ /*------------------------------------------------------------------------- * Function: H5VL__native_link_copy * * Purpose: Handles the link copy callback * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5VL__native_link_copy(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t H5_ATTR_UNUSED lapl_id, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { H5G_loc_t src_loc, *src_loc_p; H5G_loc_t dst_loc, *dst_loc_p; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE if (NULL != src_obj && H5G_loc_real(src_obj, loc_params1->obj_type, &src_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); if (NULL != dst_obj && H5G_loc_real(dst_obj, loc_params2->obj_type, &dst_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); /* Set up src & dst location pointers */ src_loc_p = &src_loc; dst_loc_p = &dst_loc; if (NULL == src_obj) src_loc_p = dst_loc_p; else if (NULL == dst_obj) dst_loc_p = src_loc_p; /* Copy the link */ if (H5L__move(src_loc_p, loc_params1->loc_data.loc_by_name.name, dst_loc_p, loc_params2->loc_data.loc_by_name.name, true, lcpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy link"); done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_link_copy() */ /*------------------------------------------------------------------------- * Function: H5VL__native_link_move * * Purpose: Handles the link move callback * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5VL__native_link_move(void *src_obj, const H5VL_loc_params_t *loc_params1, void *dst_obj, const H5VL_loc_params_t *loc_params2, hid_t lcpl_id, hid_t H5_ATTR_UNUSED lapl_id, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { H5G_loc_t src_loc, *src_loc_p; H5G_loc_t dst_loc, *dst_loc_p; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE if (NULL != src_obj && H5G_loc_real(src_obj, loc_params1->obj_type, &src_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); if (NULL != dst_obj && H5G_loc_real(dst_obj, loc_params2->obj_type, &dst_loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); /* Set up src & dst location pointers */ src_loc_p = &src_loc; dst_loc_p = &dst_loc; if (NULL == src_obj) src_loc_p = dst_loc_p; else if (NULL == dst_obj) dst_loc_p = src_loc_p; /* Move the link */ if (H5L__move(src_loc_p, loc_params1->loc_data.loc_by_name.name, dst_loc_p, loc_params2->loc_data.loc_by_name.name, false, lcpl_id) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link"); done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_link_move() */ /*------------------------------------------------------------------------- * Function: H5VL__native_link_get * * Purpose: Handles the link get callback * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5VL__native_link_get(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_get_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { H5G_loc_t loc; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); switch (args->op_type) { /* H5Lget_info/H5Lget_info_by_idx */ case H5VL_LINK_GET_INFO: { /* Get the link information */ if (loc_params->type == H5VL_OBJECT_BY_NAME) { if (H5L_get_info(&loc, loc_params->loc_data.loc_by_name.name, args->args.get_info.linfo) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info"); } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_IDX) { if (H5L__get_info_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, args->args.get_info.linfo) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info"); } /* end else-if */ else HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info"); break; } /* H5Lget_name_by_idx */ case H5VL_LINK_GET_NAME: { if (H5L__get_name_by_idx(&loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, args->args.get_name.name, args->args.get_name.name_size, args->args.get_name.name_len) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link info"); break; } /* H5Lget_val/H5Lget_val_by_idx */ case H5VL_LINK_GET_VAL: { /* Get the link information */ if (loc_params->type == H5VL_OBJECT_BY_NAME) { if (H5L__get_val(&loc, loc_params->loc_data.loc_by_name.name, args->args.get_val.buf, args->args.get_val.buf_size) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link value"); } else if (loc_params->type == H5VL_OBJECT_BY_IDX) { if (H5L__get_val_by_idx( &loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n, args->args.get_val.buf, args->args.get_val.buf_size) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link val"); } else HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to get link val"); break; } default: HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from link"); } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_link_get() */ /*------------------------------------------------------------------------- * Function: H5VL__native_link_specific * * Purpose: Handles the link specific callback * * Return: SUCCEED/FAIL * *------------------------------------------------------------------------- */ herr_t H5VL__native_link_specific(void *obj, const H5VL_loc_params_t *loc_params, H5VL_link_specific_args_t *args, hid_t H5_ATTR_UNUSED dxpl_id, void H5_ATTR_UNUSED **req) { herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_PACKAGE switch (args->op_type) { case H5VL_LINK_EXISTS: { H5G_loc_t loc; if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); if (H5L__exists(&loc, loc_params->loc_data.loc_by_name.name, args->args.exists.exists) < 0) HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "unable to specific link info"); break; } case H5VL_LINK_ITER: { H5VL_link_iterate_args_t *iter_args = &args->args.iterate; H5G_loc_t loc; /* Get the location */ if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); /* Visit or iterate over the links */ if (loc_params->type == H5VL_OBJECT_BY_SELF) { if (iter_args->recursive) { /* H5Lvisit */ if ((ret_value = H5G_visit(&loc, ".", iter_args->idx_type, iter_args->order, iter_args->op, iter_args->op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed"); } /* end if */ else { /* H5Literate */ if ((ret_value = H5L_iterate(&loc, ".", iter_args->idx_type, iter_args->order, iter_args->idx_p, iter_args->op, iter_args->op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "error iterating over links"); } /* end else */ } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_NAME) { if (iter_args->recursive) { /* H5Lvisit_by_name */ if ((ret_value = H5G_visit(&loc, loc_params->loc_data.loc_by_name.name, iter_args->idx_type, iter_args->order, iter_args->op, iter_args->op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "link visitation failed"); } /* end if */ else { /* H5Literate_by_name */ if ((ret_value = H5L_iterate(&loc, loc_params->loc_data.loc_by_name.name, iter_args->idx_type, iter_args->order, iter_args->idx_p, iter_args->op, iter_args->op_data)) < 0) HGOTO_ERROR(H5E_LINK, H5E_BADITER, FAIL, "error iterating over links"); } /* end else */ } /* end else-if */ else HGOTO_ERROR(H5E_LINK, H5E_UNSUPPORTED, FAIL, "unknown link iterate params"); break; } case H5VL_LINK_DELETE: { H5G_loc_t loc; if (H5G_loc_real(obj, loc_params->obj_type, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object"); /* Unlink */ if (loc_params->type == H5VL_OBJECT_BY_NAME) { /* H5Ldelete */ if (H5L__delete(&loc, loc_params->loc_data.loc_by_name.name) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link"); } /* end if */ else if (loc_params->type == H5VL_OBJECT_BY_IDX) { /* H5Ldelete_by_idx */ if (H5L__delete_by_idx( &loc, loc_params->loc_data.loc_by_idx.name, loc_params->loc_data.loc_by_idx.idx_type, loc_params->loc_data.loc_by_idx.order, loc_params->loc_data.loc_by_idx.n) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link"); } /* end else-if */ else HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link"); break; } default: HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "invalid specific operation"); } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5VL__native_link_specific() */