diff options
Diffstat (limited to 'src/H5Lexternal.c')
-rw-r--r-- | src/H5Lexternal.c | 110 |
1 files changed, 72 insertions, 38 deletions
diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index 7c32309..0f3296f 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -33,6 +33,7 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Opublic.h" /* File objects */ #include "H5Pprivate.h" /* Property lists */ +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ @@ -102,7 +103,7 @@ static const H5L_class_t H5L_EXTERN_LINK_CLASS[1] = {{ * link access property list, appends that prefix to the * filename being opened. * - * Return: ID of the opened object on success/Negative on failure + * Return: ID of the opened object on success/H5I_INVALID_HID on failure * * Programmer: James Laird * Monday, July 10, 2006 @@ -125,12 +126,14 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group, unsigned intent; /* File access permissions */ H5L_elink_cb_t cb_info; /* Callback info struct */ hid_t fapl_id = -1; /* File access property list for external link's file */ - hid_t ext_obj = -1; /* ID for external link's object */ + void *ext_obj = NULL; /* External link's object */ + hid_t ext_obj_id = H5I_INVALID_HID; /* ID for external link's object */ + H5I_type_t opened_type; /* ID type of external link's object */ char *parent_group_name = NULL;/* Temporary pointer to group name */ char local_group_name[H5L_EXT_TRAVERSE_BUF_SIZE]; /* Local buffer to hold group name */ H5P_genplist_t *fa_plist; /* File access property list pointer */ - H5F_close_degree_t fc_degree = H5F_CLOSE_WEAK; /* File close degree for target file */ - char *elink_prefix; /* Pointer to elink prefix */ + H5F_close_degree_t fc_degree = H5F_CLOSE_WEAK; /* File close degree for target file */ + char *elink_prefix = NULL; /* Pointer to elink prefix */ hid_t ret_value = H5I_INVALID_HID; /* Return value */ FUNC_ENTER_STATIC @@ -140,9 +143,9 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group, /* Check external link version & flags */ if(((*p >> 4) & 0x0F) > H5L_EXT_VERSION) - HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, FAIL, "bad version number for external link") + HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, H5I_INVALID_HID, "bad version number for external link") if((*p & 0x0F) & ~H5L_EXT_FLAGS_ALL) - HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, FAIL, "bad flags for external link") + HGOTO_ERROR(H5E_LINK, H5E_CANTDECODE, H5I_INVALID_HID, "bad flags for external link") p++; /* Gather some information from the external link's user data */ @@ -152,19 +155,19 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group, /* Get the plist structure */ if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5I_INVALID_HID, "can't find object for ID") /* Get the fapl_id set for lapl_id if any */ if(H5P_get(plist, H5L_ACS_ELINK_FAPL_NAME, &fapl_id) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fapl for links") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't get fapl for links") /* Get the location for the group holding the external link */ if(H5G_loc(cur_group, &loc) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get object location") + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, H5I_INVALID_HID, "can't get object location") /* get the access flags set for lapl_id if any */ if(H5P_get(plist, H5L_ACS_ELINK_FLAGS_NAME, &intent) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get elink file access flags") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't get elink file access flags") /* get the file access mode flags for the parent file, if they were not set * on lapl_id */ @@ -172,15 +175,15 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group, intent = H5F_INTENT(loc.oloc->file); if((fapl_id == H5P_DEFAULT) && ((fapl_id = H5F_get_access_plist(loc.oloc->file, FALSE)) < 0)) - HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't get parent's file access property list") + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, H5I_INVALID_HID, "can't get parent's file access property list") /* Get callback_info */ if(H5P_get(plist, H5L_ACS_ELINK_CB_NAME, &cb_info) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get elink callback info") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't get elink callback info") /* Get file access property list */ if(NULL == (fa_plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5I_INVALID_HID, "can't find object for ID") /* Make callback if it exists */ if(cb_info.func) { @@ -192,7 +195,7 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group, /* Query length of parent group name */ if((group_name_len = H5G_get_name(&loc, NULL, (size_t) 0, NULL)) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve length of group name") + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, H5I_INVALID_HID, "unable to retrieve length of group name") /* Account for null terminator */ group_name_len++; @@ -200,59 +203,64 @@ H5L__extern_traverse(const char H5_ATTR_UNUSED *link_name, hid_t cur_group, /* Check if we need to allocate larger buffer */ if((size_t)group_name_len > sizeof(local_group_name)) { if(NULL == (parent_group_name = (char *)H5MM_malloc((size_t)group_name_len))) - HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, FAIL, "can't allocate buffer to hold group name, group_name_len = %zd", group_name_len) + HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, H5I_INVALID_HID, "can't allocate buffer to hold group name, group_name_len = %zd", group_name_len) } /* end if */ else parent_group_name = local_group_name; /* Get parent group name */ if(H5G_get_name(&loc, parent_group_name, (size_t) group_name_len, NULL) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve group name") + HGOTO_ERROR(H5E_LINK, H5E_CANTGET, H5I_INVALID_HID, "unable to retrieve group name") /* Make callback */ if((cb_info.func)(parent_file_name, parent_group_name, file_name, obj_name, &intent, fapl_id, cb_info.user_data) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "traversal operator failed") + HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, H5I_INVALID_HID, "traversal operator failed") /* Check access flags */ if((intent & H5F_ACC_TRUNC) || (intent & H5F_ACC_EXCL)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid file open flags") } /* end if */ /* Set file close degree for new file to "weak" */ if(H5P_set(fa_plist, H5F_ACS_CLOSE_DEGREE_NAME, &fc_degree) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree") + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, H5I_INVALID_HID, "can't set file close degree") /* Get the current elink prefix */ if(H5P_peek(plist, H5L_ACS_ELINK_PREFIX_NAME, &elink_prefix) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external link prefix") + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, H5I_INVALID_HID, "can't get external link prefix") /* Search for the target file */ if(NULL == (ext_file = H5F_prefix_open_file(loc.oloc->file, H5F_PREFIX_ELINK, elink_prefix, file_name, intent, fapl_id))) - HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, FAIL, "unable to open external file, external link file name = '%s'", file_name) + HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, H5I_INVALID_HID, "unable to open external file, external link file name = '%s'", file_name) /* Retrieve the "group location" for the file's root group */ if(H5G_root_loc(ext_file, &root_loc) < 0) - HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "unable to create location for file") + HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, H5I_INVALID_HID, "unable to create location for file") /* Open the object referenced in the external file */ - if((ext_obj = H5O_open_name(&root_loc, obj_name, FALSE)) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTOPENOBJ, FAIL, "unable to open object") + if(NULL == (ext_obj = H5O_open_name(&root_loc, obj_name, &opened_type))) + HGOTO_ERROR(H5E_LINK, H5E_CANTOPENOBJ, H5I_INVALID_HID, "unable to open object") + + /* Get an ID for the external link's object */ + if((ext_obj_id = H5VL_wrap_register(opened_type, ext_obj, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register external link object") /* Set return value */ - ret_value = ext_obj; + ret_value = ext_obj_id; done: +/* XXX (VOL MERGE): Probably also want to consider closing ext_obj here on failures */ /* Release resources */ if(fapl_id > 0 && H5I_dec_ref(fapl_id) < 0) - HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list") + HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, H5I_INVALID_HID, "unable to close atom for file access property list") if(ext_file && H5F_efc_close(loc.oloc->file, ext_file) < 0) - HDONE_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, FAIL, "problem closing external file") + HDONE_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, H5I_INVALID_HID, "problem closing external file") if(parent_group_name && parent_group_name != local_group_name) parent_group_name = (char *)H5MM_xfree(parent_group_name); if(ret_value < 0) { /* Close object if it's open and something failed */ - if(ext_obj >= 0 && H5I_dec_ref(ext_obj) < 0) - HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for external object") + if(ext_obj_id >= 0 && H5I_dec_ref(ext_obj_id) < 0) + HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, H5I_INVALID_HID, "unable to close atom for external object") } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -312,7 +320,7 @@ done: /*------------------------------------------------------------------------- * Function: H5Lcreate_external * - * Purpose: Creates an external link from LINK_NAME to OBJ_NAME. + * Purpose: Creates an external link from LINK_NAME to OBJ_NAME. * * External links are links to objects in other HDF5 files. They * are allowed to "dangle" like soft links internal to a file. @@ -322,9 +330,9 @@ done: * LINK_NAME is interpreted relative to LINK_LOC_ID, which is * either a file ID or a group ID. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Quincey Koziol + * Programmer: Quincey Koziol * Wednesday, May 18, 2005 * *------------------------------------------------------------------------- @@ -333,13 +341,16 @@ herr_t H5Lcreate_external(const char *file_name, const char *obj_name, hid_t link_loc_id, const char *link_name, hid_t lcpl_id, hid_t lapl_id) { - H5G_loc_t link_loc; /* Group location to create link */ - char *norm_obj_name = NULL; /* Pointer to normalized current name */ + H5VL_object_t *vol_obj = NULL; /* Object token of loc_id */ + H5VL_loc_params_t loc_params; + char *norm_obj_name = NULL; /* Pointer to normalized current name */ void *ext_link_buf = NULL; /* Buffer to contain external link */ size_t buf_size; /* Size of buffer to hold external link */ size_t file_name_len; /* Length of file name string */ size_t norm_obj_name_len; /* Length of normalized object name string */ uint8_t *p; /* Pointer into external link buffer */ + H5P_genplist_t *plist; /* Property list pointer */ + H5L_type_t link_type = H5L_TYPE_EXTERNAL; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -351,11 +362,13 @@ H5Lcreate_external(const char *file_name, const char *obj_name, HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no file name specified") if(!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name specified") - 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") + /* Check the group access property list */ + if(H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_DEFAULT; + /* Get normalized copy of the link target */ if(NULL == (norm_obj_name = H5G_normalize(obj_name))) HGOTO_ERROR(H5E_LINK, H5E_BADVALUE, FAIL, "can't normalize object name") @@ -378,9 +391,30 @@ H5Lcreate_external(const char *file_name, const char *obj_name, 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") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = link_name; + loc_params.loc_data.loc_by_name.lapl_id = lapl_id; + loc_params.obj_type = H5I_get_type(link_loc_id); + + /* get the location object */ + if(NULL == (vol_obj = (H5VL_object_t *)H5I_object(link_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(lcpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set creation properties */ + if(H5P_set(plist, H5VL_PROP_LINK_TYPE, &link_type) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value from plist") + if(H5P_set(plist, H5VL_PROP_LINK_UDATA, &ext_link_buf) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value from plist") + if(H5P_set(plist, H5VL_PROP_LINK_UDATA_SIZE, &buf_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value from plist") + /* Create an external link */ - if(H5L__create_ud(&link_loc, link_name, ext_link_buf, buf_size, H5L_TYPE_EXTERNAL, lcpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + if(H5VL_link_create(H5VL_LINK_CREATE_UD, vol_obj, &loc_params, lcpl_id, lapl_id, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create external link") done: H5MM_xfree(ext_link_buf); |