diff options
Diffstat (limited to 'src')
81 files changed, 17015 insertions, 5419 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f964992..3048484 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -162,6 +162,7 @@ IDE_GENERATED_PROPERTIES ("H5EA" "${H5EA_HDRS}" "${H5EA_SRCS}" ) SET (H5F_SRCS ${HDF5_SRC_DIR}/H5F.c + ${HDF5_SRC_DIR}/H5Fint.c ${HDF5_SRC_DIR}/H5Faccum.c ${HDF5_SRC_DIR}/H5Fcwfs.c ${HDF5_SRC_DIR}/H5Fdbg.c @@ -602,6 +603,17 @@ SET (H5V_HDRS ) IDE_GENERATED_PROPERTIES ("H5V" "${H5V_HDRS}" "${H5V_SRCS}" ) +SET (H5VL_SRCS + ${HDF5_SRC_DIR}/H5VL.c + ${HDF5_SRC_DIR}/H5VLint.c + ${HDF5_SRC_DIR}/H5VLnative.c +) +SET (H5VL_HDRS + ${HDF5_SRC_DIR}/H5VLpublic.h + ${HDF5_SRC_DIR}/H5VLpkg.h + ${HDF5_SRC_DIR}/H5VLnative.h +) +IDE_GENERATED_PROPERTIES ("H5VL" "${H5VL_HDRS}" "${H5VL_SRCS}" ) SET (H5WB_SRCS ${HDF5_SRC_DIR}/H5WB.c @@ -672,6 +684,7 @@ SET (common_SRCS ${H5T_SRCS} ${H5TS_SRCS} ${H5V_SRCS} + ${H5VL_SRCS} ${H5WB_SRCS} ${H5Z_SRCS} ) @@ -705,6 +718,7 @@ SET (H5_PUBLIC_HEADERS ${H5S_HDRS} ${H5SM_HDRS} ${H5T_HDRS} + ${H5VL_HDRS} ${H5Z_HDRS} ) @@ -749,6 +763,7 @@ SET (H5_PRIVATE_HEADERS ${HDF5_SRC_DIR}/H5Tprivate.h ${HDF5_SRC_DIR}/H5TSprivate.h ${HDF5_SRC_DIR}/H5Vprivate.h + ${HDF5_SRC_DIR}/H5VLprivate.h ${HDF5_SRC_DIR}/H5WBprivate.h ${HDF5_SRC_DIR}/H5Zprivate.h ${HDF5_SRC_DIR}/H5win32defs.h @@ -31,7 +31,7 @@ #include "H5Pprivate.h" /* Property lists */ #include "H5Tprivate.h" /* Datatypes */ #include "H5SLprivate.h" /* Skip lists */ - +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ /* Local Macros */ @@ -130,6 +130,7 @@ H5_init_library(void) H5_debug_g.pkg[H5_PKG_S].name = "s"; H5_debug_g.pkg[H5_PKG_T].name = "t"; H5_debug_g.pkg[H5_PKG_V].name = "v"; + H5_debug_g.pkg[H5_PKG_VL].name = "vl"; H5_debug_g.pkg[H5_PKG_Z].name = "z"; #ifdef H5_HAVE_MPE @@ -267,6 +268,7 @@ H5_term_library(void) * that depend on them. -QAK */ if(pending == 0) { + pending += DOWN(VL); pending += DOWN(AC); pending += DOWN(Z); pending += DOWN(FD); @@ -281,8 +283,9 @@ H5_term_library(void) if(pending == 0) pending += DOWN(SL); /* Don't shut down the free list code until _everything_ else is down */ - if(pending == 0) + if(pending == 0) { pending += DOWN(FL); + } } } while(pending && ntries++ < 100); @@ -36,6 +36,8 @@ #include "H5Opkg.h" /* Object headers */ #include "H5Sprivate.h" /* Dataspace functions */ #include "H5SMprivate.h" /* Shared Object Header Messages */ +#include "H5VLprivate.h" /* VOL plugins */ +#include "H5VLnative.h" /* VOL native plugin */ /****************/ /* Local Macros */ @@ -63,10 +65,6 @@ typedef struct H5A_iter_cb1 { /* Local Prototypes */ /********************/ -static herr_t H5A_open_common(const H5G_loc_t *loc, H5A_t *attr); -static herr_t H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id); -static herr_t H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id); - /*********************/ /* Package Variables */ @@ -97,7 +95,8 @@ static const H5I_class_t H5I_ATTR_CLS[1] = {{ 0, /* Class flags */ 64, /* Minimum hash size for class */ 0, /* # of reserved IDs for class */ - (H5I_free_t)H5A_close /* Callback routine for closing objects of this class */ + NULL, /* Callback routine for closing objects of this class */ + (H5I_free2_t)H5A_close_attr /* Callback routine for closing auxilary objects of this class */ }}; @@ -227,9 +226,11 @@ hid_t H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t UNUSED aapl_id) { - H5G_loc_t loc; /* Object location */ - H5T_t *type; /* Datatype to use for attribute */ - H5S_t *space; /* Dataspace to use for attribute */ + void *attr = NULL; /* attr token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5P_genplist_t *plist; /* Property list pointer */ + H5VL_loc_params_t loc_params; hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -238,22 +239,50 @@ H5Acreate2(hid_t loc_id, const char *attr_name, hid_t type_id, hid_t space_id, /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(0 == (H5F_INTENT(loc.oloc->file) & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_ARGS, H5E_WRITEERROR, FAIL, "no write intent on file") if(!attr_name || !*attr_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") - if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a type") - if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") - /* Go do the real work for attaching the attribute to the dataset */ - if((ret_value = H5A_create(&loc, attr_name, type, space, acpl_id, H5AC_dxpl_id)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create attribute") + /* Get correct property list */ + if(H5P_DEFAULT == acpl_id) + acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT; + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(acpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + //if((temp_id = H5T_get_named_id(type_id)) < 0) + //HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid type ID") + + /* set creation properties */ + if(H5P_set(plist, H5VL_ATTR_TYPE_ID, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5VL_ATTR_SPACE_ID, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") + //if(H5P_set(plist, H5VL_ATTR_LOC_PARAMS, &loc_params) < 0) + //HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for location") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the attribute through the VOL */ + if(NULL == (attr = H5VL_attr_create(obj, loc_params, vol_plugin, attr_name, acpl_id, aapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create attribute") + + /* Get an atom for the attribute */ + if((ret_value = H5I_register2(H5I_ATTR, attr, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: + if (ret_value < 0 && attr) + if(H5VL_attr_close (attr, vol_plugin, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* H5Acreate2() */ @@ -291,17 +320,15 @@ done: /* ARGSUSED */ hid_t H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, - hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t UNUSED aapl_id, + hid_t type_id, hid_t space_id, hid_t acpl_id, hid_t aapl_id, hid_t lapl_id) { - H5G_loc_t loc; /* Object location */ - H5G_loc_t obj_loc; /* Location used to open group */ - 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 'obj_name' found */ - H5T_t *type; /* Datatype to use for attribute */ - H5S_t *space; /* Dataspace to use for attribute */ - hid_t ret_value; /* Return value */ + void *attr = NULL; /* attr token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5P_genplist_t *plist; /* Property list pointer */ + H5VL_loc_params_t loc_params; + hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE8("i", "i*s*siiiii", loc_id, obj_name, attr_name, type_id, space_id, @@ -310,209 +337,52 @@ H5Acreate_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(0 == (H5F_INTENT(loc.oloc->file) & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_ARGS, H5E_WRITEERROR, FAIL, "no write intent on file") if(!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") if(!attr_name || !*attr_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") - if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a type") - if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") - /* Set up opened group location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); + /* Get correct property list */ + if(H5P_DEFAULT == acpl_id) + acpl_id = H5P_ATTRIBUTE_CREATE_DEFAULT; - /* Find the object's location */ - if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") - loc_found = TRUE; + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(acpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - /* Go do the real work for attaching the attribute to the dataset */ - if((ret_value = H5A_create(&obj_loc, attr_name, type, space, acpl_id, H5AC_dxpl_id)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create attribute") + /* set creation properties */ + if(H5P_set(plist, H5VL_ATTR_TYPE_ID, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5VL_ATTR_SPACE_ID, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") -done: - /* Release resources */ - if(loc_found && H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.obj_type = H5I_get_type(loc_id); + loc_params.loc_data.loc_by_name.name = obj_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; - FUNC_LEAVE_API(ret_value) -} /* H5Acreate_by_name() */ + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - -/*------------------------------------------------------------------------- - * Function: H5A_create - * - * Purpose: - * This is the guts of creating an attribute. - * Usage: - * hid_t H5A_create(ent, name, type, space) - * const H5G_entry_t *ent; IN: Pointer to symbol table entry for object to attribute - * const char *name; IN: Name of attribute - * H5T_t *type; IN: Datatype of attribute - * H5S_t *space; IN: Dataspace of attribute - * hid_t acpl_id IN: Attribute creation property list - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * April 2, 1998 - * - *------------------------------------------------------------------------- - */ -hid_t -H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, - const H5S_t *space, hid_t acpl_id, hid_t dxpl_id) -{ - H5A_t *attr = NULL; /* Attribute created */ - hssize_t snelmts; /* elements in attribute */ - size_t nelmts; /* elements in attribute */ - htri_t tri_ret; /* htri_t return value */ - hid_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT_TAG(dxpl_id, loc->oloc->addr, FAIL) - - /* check args */ - HDassert(loc); - HDassert(name); - HDassert(type); - HDassert(space); - - /* Check for existing attribute with same name */ - /* (technically, the "attribute create" operation will fail for a duplicated - * name, but it's going to be hard to unwind all the special cases on - * failure, so just check first, for now - QAK) - */ - if((tri_ret = H5O_attr_exists(loc->oloc, name, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "error checking attributes") - else if(tri_ret > 0) - HGOTO_ERROR(H5E_ATTR, H5E_ALREADYEXISTS, FAIL, "attribute already exists") - - /* Check if the dataspace has an extent set (or is NULL) */ - if(!(H5S_has_extent(space))) - HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "dataspace extent has not been set") - - /* Check if the datatype is "sensible" for use in a dataset */ - if(H5T_is_sensible(type) != TRUE) - HGOTO_ERROR(H5E_ATTR, H5E_BADTYPE, FAIL, "datatype is not sensible") - - /* Build the attribute information */ - if(NULL == (attr = H5FL_CALLOC(H5A_t))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed for attribute info") - - if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "can't allocate shared attr structure") - - /* If the creation property list is H5P_DEFAULT, use the default character encoding */ - if(acpl_id == H5P_DEFAULT) - attr->shared->encoding = H5F_DEFAULT_CSET; - else { - H5P_genplist_t *ac_plist; /* ACPL Property list */ - - /* Get a local copy of the attribute creation property list */ - if(NULL == (ac_plist = (H5P_genplist_t *)H5I_object(acpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - - if(H5P_get(ac_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get character encoding flag") - } /* end else */ - - /* Copy the attribute name */ - attr->shared->name = H5MM_xstrdup(name); - - /* Copy datatype */ - if(NULL == (attr->shared->dt = H5T_copy(type, H5T_COPY_ALL))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared datatype info") - - /* Mark datatype as being on disk now */ - if(H5T_set_loc(attr->shared->dt, loc->oloc->file, H5T_LOC_DISK) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") - - /* Set the latest format for datatype, if requested */ - if(H5F_USE_LATEST_FORMAT(loc->oloc->file)) - if(H5T_set_latest_version(attr->shared->dt) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of datatype") - - /* Copy the dataspace for the attribute */ - attr->shared->ds = H5S_copy(space, FALSE, TRUE); - - /* Set the latest format for dataspace, if requested */ - if(H5F_USE_LATEST_FORMAT(loc->oloc->file)) - if(H5S_set_latest_version(attr->shared->ds) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set latest version of dataspace") - - /* Copy the object header information */ - if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") - - /* Deep copy of the group hierarchy path */ - if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy path") - - /* Check if any of the pieces should be (or are already) shared in the - * SOHM table - */ - if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, 0, H5O_DTYPE_ID, attr->shared->dt, NULL) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share datatype failed") - if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, 0, H5O_SDSPACE_ID, attr->shared->ds, NULL) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share dataspace failed") - - /* Check whether datatype is committed & increment ref count - * (to maintain ref. count incr/decr similarity with "shared message" - * type of datatype sharing) - */ - if(H5T_committed(attr->shared->dt)) { - /* Increment the reference count on the shared datatype */ - if(H5T_link(attr->shared->dt, 1, dxpl_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count") - } /* end if */ - - /* Compute the size of pieces on disk. This is either the size of the - * datatype and dataspace messages themselves, or the size of the "shared" - * messages if either or both of them are shared. - */ - attr->shared->dt_size = H5O_msg_raw_size(attr->oloc.file, H5O_DTYPE_ID, FALSE, attr->shared->dt); - attr->shared->ds_size = H5O_msg_raw_size(attr->oloc.file, H5O_SDSPACE_ID, FALSE, attr->shared->ds); - - /* Get # of elements for attribute's dataspace */ - if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid") - H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t); - - HDassert(attr->shared->dt_size > 0); - HDassert(attr->shared->ds_size > 0); - attr->shared->data_size = nelmts * H5T_GET_SIZE(attr->shared->dt); + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Hold the symbol table entry (and file) open */ - if(H5O_open(&(attr->oloc)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open") - attr->obj_opened = TRUE; + /* Create the attribute through the VOL */ + if(NULL == (attr = H5VL_attr_create(obj, loc_params, vol_plugin, attr_name, acpl_id, aapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create attribute") - /* Set the version to encode the attribute with */ - if(H5A_set_version(attr->oloc.file, attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, FAIL, "unable to update attribute version") - - /* Insert the attribute into the object header */ - if(H5O_attr_create(&(attr->oloc), dxpl_id, attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create attribute in object header") - - /* Register the new attribute and get an ID for it */ - if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID") + /* Get an atom for the attribute */ + if((ret_value = H5I_register2(H5I_ATTR, attr, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: - /* Cleanup on failure */ - if(ret_value < 0 && attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") - - FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) -} /* H5A_create() */ + if (ret_value < 0 && attr) + if(H5VL_attr_close (attr, vol_plugin, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") + FUNC_LEAVE_API(ret_value) +} /* H5Acreate_by_name() */ /*-------------------------------------------------------------------------- @@ -535,10 +405,12 @@ done: H5Aclose or resource leaks will develop. --------------------------------------------------------------------------*/ hid_t -H5Aopen(hid_t loc_id, const char *attr_name, hid_t UNUSED aapl_id) +H5Aopen(hid_t loc_id, const char *attr_name, hid_t aapl_id) { - H5G_loc_t loc; /* Object location */ - H5A_t *attr = NULL; /* Attribute opened */ + void *attr = NULL; /* attr token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t ret_value; FUNC_ENTER_API(FAIL) @@ -547,29 +419,32 @@ H5Aopen(hid_t loc_id, const char *attr_name, hid_t UNUSED aapl_id) /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!attr_name || !*attr_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") - /* Read in attribute from object header */ - if(NULL == (attr = H5O_attr_open_by_name(loc.oloc, attr_name, H5AC_ind_dxpl_id))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to load attribute info from object header for attribute: '%s'", attr_name) + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); - /* Finish initializing attribute */ - if(H5A_open_common(&loc, attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to initialize attribute") + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* Register the attribute and get an ID for it */ - if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") -done: - /* Cleanup on failure */ - if(ret_value < 0) - if(attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") + /* Create the attribute through the VOL */ + if(NULL == (attr = H5VL_attr_open(obj, loc_params, vol_plugin, attr_name, aapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open attribute") + /* Get an atom for the attribute */ + if((ret_value = H5I_register2(H5I_ATTR, attr, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") + +done: + if (ret_value < 0 && attr) + if(H5VL_attr_close (attr, vol_plugin, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* H5Aopen() */ @@ -597,10 +472,12 @@ done: --------------------------------------------------------------------------*/ hid_t H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, - hid_t UNUSED aapl_id, hid_t lapl_id) + hid_t aapl_id, hid_t lapl_id) { - H5G_loc_t loc; /* Object location */ - H5A_t *attr = NULL; /* Attribute opened */ + void *attr = NULL; /* attr token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t ret_value; FUNC_ENTER_API(FAIL) @@ -609,8 +486,6 @@ H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") if(!attr_name || !*attr_name) @@ -621,20 +496,31 @@ H5Aopen_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Open the attribute on the object header */ - if(NULL == (attr = H5A_open_by_name(&loc, obj_name, attr_name, lapl_id, H5AC_ind_dxpl_id))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = obj_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); - /* Register the attribute and get an ID for it */ - if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID") + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") -done: - /* Cleanup on failure */ - if(ret_value < 0) - if(attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the attribute through the VOL */ + if(NULL == (attr = H5VL_attr_open(obj, loc_params, vol_plugin, attr_name, aapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open attribute") + /* Get an atom for the attribute */ + if((ret_value = H5I_register2(H5I_ATTR, attr, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") + +done: + if (ret_value < 0 && attr) + if(H5VL_attr_close (attr, vol_plugin, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* H5Aopen_by_name() */ @@ -665,10 +551,12 @@ done: --------------------------------------------------------------------------*/ hid_t H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, hid_t UNUSED aapl_id, hid_t lapl_id) + H5_iter_order_t order, hsize_t n, hid_t aapl_id, hid_t lapl_id) { - H5A_t *attr = NULL; /* Attribute opened */ - H5G_loc_t loc; /* Object location */ + void *attr = NULL; /* attr token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -678,8 +566,6 @@ H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) @@ -692,208 +578,36 @@ H5Aopen_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Open the attribute in the object header */ - if(NULL == (attr = H5A_open_by_idx(&loc, obj_name, idx_type, order, n, lapl_id, H5AC_ind_dxpl_id))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open attribute") - - /* Register the attribute and get an ID for it */ - if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID") - -done: - /* Cleanup on failure */ - if(ret_value < 0) - if(attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") - - FUNC_LEAVE_API(ret_value) -} /* H5Aopen_by_idx() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_open_common - * - * Purpose: - * Finishes initializing an attributes the open - * - * Usage: - * herr_t H5A_open_common(loc, name, dxpl_id) - * const H5G_loc_t *loc; IN: Pointer to group location for object - * H5A_t *attr; IN/OUT: Pointer to attribute to initialize - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * December 18, 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5A_open_common(const H5G_loc_t *loc, H5A_t *attr) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* check args */ - HDassert(loc); - HDassert(attr); - -#if defined(H5_USING_MEMCHECKER) || !defined(NDEBUG) - /* Clear object location */ - if(H5O_loc_reset(&(attr->oloc)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to reset location") -#endif /* H5_USING_MEMCHECKER */ - - /* Free any previous group hier. path */ - if(H5G_name_free(&(attr->path)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path") - - /* Deep copy of the symbol table entry */ - if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") - - /* Deep copy of the group hier. path */ - if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy entry") + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = obj_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); - /* Hold the symbol table entry (and file) open */ - if(H5O_open(&(attr->oloc)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open") - attr->obj_opened = TRUE; + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5A_open_common() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_open_by_idx - * - * Purpose: Open an attribute according to its index order - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * April 2, 1998 - * - *------------------------------------------------------------------------- - */ -H5A_t * -H5A_open_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, hsize_t n, hid_t lapl_id, hid_t dxpl_id) -{ - H5G_loc_t obj_loc; /* Location used to open group */ - 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 'obj_name' found */ - H5A_t *attr = NULL; /* Attribute from object header */ - H5A_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* check args */ - HDassert(loc); - HDassert(obj_name); + /* Create the attribute through the VOL */ + if(NULL == (attr = H5VL_attr_open(obj, loc_params, vol_plugin, NULL, aapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open attribute") - /* Set up opened group 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, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "object not found") - loc_found = TRUE; - - /* Read in attribute from object header */ - if(NULL == (attr = H5O_attr_open_by_idx(obj_loc.oloc, idx_type, order, n, dxpl_id))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to load attribute info from object header") - - /* Finish initializing attribute */ - if(H5A_open_common(&obj_loc, attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to initialize attribute") - - /* Set return value */ - ret_value = attr; + /* Get an atom for the attribute */ + if((ret_value = H5I_register2(H5I_ATTR, attr, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: - /* Release resources */ - if(loc_found && H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't free location") - - /* Cleanup on failure */ - if(ret_value == NULL) - if(attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5A_open_by_idx() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_open_by_name - * - * Purpose: Open an attribute in an object header, according to it's name - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * December 11, 2006 - * - *------------------------------------------------------------------------- - */ -H5A_t * -H5A_open_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name, - hid_t lapl_id, hid_t dxpl_id) -{ - H5G_loc_t obj_loc; /* Location used to open group */ - 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 'obj_name' found */ - H5A_t *attr = NULL; /* Attribute from object header */ - H5A_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) - - /* check args */ - HDassert(loc); - HDassert(obj_name); - HDassert(attr_name); - - /* Set up opened group 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, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "object not found") - loc_found = TRUE; - - /* Read in attribute from object header */ - if(NULL == (attr = H5O_attr_open_by_name(obj_loc.oloc, attr_name, dxpl_id))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to load attribute info from object header") - - /* Finish initializing attribute */ - if(H5A_open_common(loc, attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to initialize attribute") - - /* Set return value */ - ret_value = attr; - -done: - /* Release resources */ - if(loc_found && H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't free location") - - /* Cleanup on failure */ - if(ret_value == NULL) - if(attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5A_open_by_name() */ + if (ret_value < 0 && attr) + if(H5VL_attr_close (attr, vol_plugin, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") + FUNC_LEAVE_API(ret_value) +} /* H5Aopen_by_idx() */ /*-------------------------------------------------------------------------- @@ -915,24 +629,27 @@ done: herr_t H5Awrite(hid_t attr_id, hid_t dtype_id, const void *buf) { - H5A_t *attr; /* Attribute object for ID */ - H5T_t *mem_type; /* Memory datatype */ + H5VL_t *vol_plugin; + void *attr; herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ii*x", attr_id, dtype_id, buf); /* check arguments */ - if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") - if(NULL == (mem_type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(NULL == buf) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null attribute buffer") - /* Go write the actual data to the attribute */ - if((ret_value = H5A_write(attr, mem_type, buf, H5AC_dxpl_id)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (attr = (void *)H5I_object(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier") + + /* write the data through the VOL */ + if((ret_value = H5VL_attr_write(attr, vol_plugin, dtype_id, buf, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data") done: FUNC_LEAVE_API(ret_value) @@ -941,120 +658,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5A_write - PURPOSE - Actually write out data to an attribute - USAGE - herr_t H5A_write (attr, mem_type, buf) - H5A_t *attr; IN: Attribute to write - const H5T_t *mem_type; IN: Memory datatype of buffer - const void *buf; IN: Buffer of data to write - RETURNS - Non-negative on success/Negative on failure - - DESCRIPTION - This function writes a complete attribute to disk. ---------------------------------------------------------------------------*/ -static herr_t -H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id) -{ - uint8_t *tconv_buf = NULL; /* datatype conv buffer */ - hbool_t tconv_owned = FALSE; /* Whether the datatype conv buffer is owned by attribute */ - uint8_t *bkg_buf = NULL; /* temp conversion buffer */ - hssize_t snelmts; /* elements in attribute */ - size_t nelmts; /* elements in attribute */ - H5T_path_t *tpath = NULL; /* conversion information*/ - hid_t src_id = -1, dst_id = -1;/* temporary type atoms */ - size_t src_type_size; /* size of source type */ - size_t dst_type_size; /* size of destination type*/ - size_t buf_size; /* desired buffer size */ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT_TAG(dxpl_id, attr->oloc.addr, FAIL) - - HDassert(attr); - HDassert(mem_type); - HDassert(buf); - - /* Get # of elements for attribute's dataspace */ - if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid") - H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t); - - /* If there's actually data elements for the attribute, make a copy of the data passed in */ - if(nelmts > 0) { - /* Get the memory and file datatype sizes */ - src_type_size = H5T_GET_SIZE(mem_type); - dst_type_size = H5T_GET_SIZE(attr->shared->dt); - - /* Convert memory buffer into disk buffer */ - /* Set up type conversion function */ - if(NULL == (tpath = H5T_path_find(mem_type, attr->shared->dt, NULL, NULL, dxpl_id, FALSE))) - HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes") - - /* Check for type conversion required */ - if(!H5T_path_noop(tpath)) { - if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0 || - (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion") - - /* Get the maximum buffer size needed and allocate it */ - buf_size = nelmts * MAX(src_type_size, dst_type_size); - if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed") - if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed") - - /* Copy the user's data into the buffer for conversion */ - HDmemcpy(tconv_buf, buf, (src_type_size * nelmts)); - - /* Perform datatype conversion */ - if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed") - - /* Free the previous attribute data buffer, if there is one */ - if(attr->shared->data) - attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data); - - /* Set the pointer to the attribute data to the converted information */ - attr->shared->data = tconv_buf; - tconv_owned = TRUE; - } /* end if */ - /* No type conversion necessary */ - else { - HDassert(dst_type_size == src_type_size); - - /* Allocate the attribute buffer, if there isn't one */ - if(attr->shared->data == NULL) - if(NULL == (attr->shared->data = H5FL_BLK_MALLOC(attr_buf, dst_type_size * nelmts))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Copy the attribute data into the user's buffer */ - HDmemcpy(attr->shared->data, buf, (dst_type_size * nelmts)); - } /* end else */ - - /* Modify the attribute in the object header */ - if(H5O_attr_write(&(attr->oloc), dxpl_id, attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to modify attribute") - } /* end if */ - -done: - /* Release resources */ - if(src_id >= 0 && H5I_dec_ref(src_id) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") - if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") - if(tconv_buf && !tconv_owned) - tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf); - if(bkg_buf) - bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf); - - FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) -} /* H5A_write() */ - - -/*-------------------------------------------------------------------------- - NAME H5Aread PURPOSE Read in data from an attribute @@ -1072,24 +675,27 @@ done: herr_t H5Aread(hid_t attr_id, hid_t dtype_id, void *buf) { - H5A_t *attr; /* Attribute object for ID */ - H5T_t *mem_type; /* Memory datatype */ + H5VL_t *vol_plugin; + void *attr; herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ii*x", attr_id, dtype_id, buf); /* check arguments */ - if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") - if(NULL == (mem_type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(NULL == buf) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null attribute buffer") - /* Go write the actual data to the attribute */ - if((ret_value = H5A_read(attr, mem_type, buf, H5AC_dxpl_id)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (attr = (void *)H5I_object(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier") + + /* Read the data through the VOL */ + if((ret_value = H5VL_attr_read(attr, vol_plugin, dtype_id, buf, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data") done: FUNC_LEAVE_API(ret_value) @@ -1098,109 +704,6 @@ done: /*-------------------------------------------------------------------------- NAME - H5A_read - PURPOSE - Actually read in data from an attribute - USAGE - herr_t H5A_read (attr, mem_type, buf) - H5A_t *attr; IN: Attribute to read - const H5T_t *mem_type; IN: Memory datatype of buffer - void *buf; IN: Buffer for data to read - RETURNS - Non-negative on success/Negative on failure - - DESCRIPTION - This function reads a complete attribute from disk. ---------------------------------------------------------------------------*/ -static herr_t -H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id) -{ - uint8_t *tconv_buf = NULL; /* datatype conv buffer*/ - uint8_t *bkg_buf = NULL; /* background buffer */ - hssize_t snelmts; /* elements in attribute */ - size_t nelmts; /* elements in attribute*/ - H5T_path_t *tpath = NULL; /* type conversion info */ - hid_t src_id = -1, dst_id = -1;/* temporary type atoms*/ - size_t src_type_size; /* size of source type */ - size_t dst_type_size; /* size of destination type */ - size_t buf_size; /* desired buffer size */ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT - - HDassert(attr); - HDassert(mem_type); - HDassert(buf); - - /* Create buffer for data to store on disk */ - if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid") - H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t); - - if(nelmts > 0) { - /* Get the memory and file datatype sizes */ - src_type_size = H5T_GET_SIZE(attr->shared->dt); - dst_type_size = H5T_GET_SIZE(mem_type); - - /* Check if the attribute has any data yet, if not, fill with zeroes */ - if(attr->obj_opened && !attr->shared->data) - HDmemset(buf, 0, (dst_type_size * nelmts)); - else { /* Attribute exists and has a value */ - /* Convert memory buffer into disk buffer */ - /* Set up type conversion function */ - if(NULL == (tpath = H5T_path_find(attr->shared->dt, mem_type, NULL, NULL, dxpl_id, FALSE))) - HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes") - - /* Check for type conversion required */ - if(!H5T_path_noop(tpath)) { - if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0 || - (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion") - - /* Get the maximum buffer size needed and allocate it */ - buf_size = nelmts * MAX(src_type_size, dst_type_size); - if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size))) - HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed") - if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size))) - HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed") - - /* Copy the attribute data into the buffer for conversion */ - HDmemcpy(tconv_buf, attr->shared->data, (src_type_size * nelmts)); - - /* Perform datatype conversion. */ - if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed") - - /* Copy the converted data into the user's buffer */ - HDmemcpy(buf, tconv_buf, (dst_type_size * nelmts)); - } /* end if */ - /* No type conversion necessary */ - else { - HDassert(dst_type_size == src_type_size); - - /* Copy the attribute data into the user's buffer */ - HDmemcpy(buf, attr->shared->data, (dst_type_size * nelmts)); - } /* end else */ - } /* end else */ - } /* end if */ - -done: - /* Release resources */ - if(src_id >= 0 && H5I_dec_ref(src_id) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") - if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") - if(tconv_buf) - tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf); - if(bkg_buf) - bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf); - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5A_read() */ - - -/*-------------------------------------------------------------------------- - NAME H5Aget_space PURPOSE Gets a copy of the dataspace for an attribute @@ -1218,29 +721,25 @@ done: hid_t H5Aget_space(hid_t attr_id) { - H5A_t *attr; /* Attribute object for ID */ - H5S_t *ds = NULL; /* Copy of dataspace for attribute */ + H5VL_t *vol_plugin; + void *attr; hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", attr_id); - /* check arguments */ - if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") - - /* Copy the attribute's dataspace */ - if(NULL == (ds = H5S_copy(attr->shared->ds, FALSE, TRUE))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy dataspace") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (attr = (void *)H5I_object(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier") - /* Atomize */ - if((ret_value = H5I_register(H5I_DATASPACE, ds, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") + /* get the dataspace through the VOL */ + if(H5VL_attr_get(attr, vol_plugin, H5VL_ATTR_GET_SPACE, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get data space") done: - if(ret_value < 0 && ds) - (void)H5S_close(ds); - FUNC_LEAVE_API(ret_value) } /* H5Aget_space() */ @@ -1264,47 +763,25 @@ done: hid_t H5Aget_type(hid_t attr_id) { - H5A_t *attr; /* Attribute object for ID */ - H5T_t *dt = NULL; /* Copy of attribute's datatype */ + H5VL_t *vol_plugin; + void *attr; hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", attr_id); - /* check arguments */ - if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") - - /* Patch the datatype's "top level" file pointer */ - if(H5T_patch_file(attr->shared->dt, attr->oloc.file) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to patch datatype's file pointer") - - /* - * Copy the attribute's datatype. If the type is a named type then - * reopen the type before returning it to the user. Make the type - * read-only. - */ - if(NULL == (dt = H5T_copy(attr->shared->dt, H5T_COPY_REOPEN))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy datatype") - - /* Mark any datatypes as being in memory now */ - if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (attr = (void *)H5I_object(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier") - /* Lock copied type */ - if(H5T_lock(dt, FALSE) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype") - - /* Atomize */ - if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype ID") + /* get the datatype through the VOL */ + if(H5VL_attr_get(attr, vol_plugin, H5VL_ATTR_GET_TYPE, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get type") done: - if(ret_value < 0) { - if(dt && H5T_close(dt) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to release datatype") - } /* end if */ - FUNC_LEAVE_API(ret_value) } /* H5Aget_type() */ @@ -1331,34 +808,25 @@ done: hid_t H5Aget_create_plist(hid_t attr_id) { - H5A_t *attr; /* Attribute object for ID */ - H5P_genplist_t *plist; /* Default property list */ - hid_t new_plist_id; /* ID of ACPL to return */ - H5P_genplist_t *new_plist; /* ACPL to return */ - hid_t ret_value; + H5VL_t *vol_plugin; + void *attr; + hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", attr_id); HDassert(H5P_LST_ATTRIBUTE_CREATE_g != -1); - /* Get attribute and default attribute creation property list*/ - if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") - if(NULL == (plist = (H5P_genplist_t *)H5I_object(H5P_LST_ATTRIBUTE_CREATE_g))) - HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get default ACPL") - - /* Create the property list object to return */ - if((new_plist_id = H5P_copy_plist(plist, TRUE)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy attribute creation properties") - if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_plist_id))) - HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (attr = (void *)H5I_object(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier") - /* Set the character encoding on the new property list */ - if(H5P_set(new_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding") - - ret_value = new_plist_id; + /* get the acpl through the VOL */ + if(H5VL_attr_get(attr, vol_plugin, H5VL_ATTR_GET_ACPL, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get acpl") done: FUNC_LEAVE_API(ret_value) @@ -1389,72 +857,35 @@ done: ssize_t H5Aget_name(hid_t attr_id, size_t buf_size, char *buf) { - H5A_t *my_attr; /* Attribute object for ID */ - ssize_t ret_value; + H5VL_t *vol_plugin; + void *attr; + H5VL_loc_params_t loc_params; + ssize_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE3("Zs", "iz*s", attr_id, buf_size, buf); /* check arguments */ - if(NULL == (my_attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") if(!buf && buf_size) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer") - /* Call private function in turn */ - if(0 > (ret_value = H5A_get_name(my_attr, buf_size, buf))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get attribute name") - -done: - FUNC_LEAVE_API(ret_value) -} /* H5Aget_name() */ - - -/*-------------------------------------------------------------------------- - NAME - H5A_get_name - PURPOSE - Private function for H5Aget_name. Gets a copy of the name for an - attribute - RETURNS - This function returns the length of the attribute's name (which may be - longer than 'buf_size') on success or negative for failure. - DESCRIPTION - This function retrieves the name of an attribute for an attribute ID. - Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string - terminator. If the name of the attribute is longer than 'buf_size'-1, - the string terminator is stored in the last position of the buffer to - properly terminate the string. ---------------------------------------------------------------------------*/ -ssize_t -H5A_get_name(H5A_t *attr, size_t buf_size, char *buf) -{ - size_t copy_len, nbytes; - ssize_t ret_value; - - FUNC_ENTER_NOAPI(FAIL) - - /* get the real attribute length */ - nbytes = HDstrlen(attr->shared->name); - HDassert((ssize_t)nbytes >= 0); /*overflow, pretty unlikely --rpm*/ - - /* compute the string length which will fit into the user's buffer */ - copy_len = MIN(buf_size - 1, nbytes); - - /* Copy all/some of the name */ - if(buf && copy_len > 0) { - HDmemcpy(buf, attr->shared->name, copy_len); + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(attr_id); - /* Terminate the string */ - buf[copy_len]='\0'; - } /* end if */ + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (attr = (void *)H5I_object(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier") - /* Set return value */ - ret_value = (ssize_t)nbytes; + /* get the name through the VOL */ + if(H5VL_attr_get(attr, vol_plugin, H5VL_ATTR_GET_NAME, H5_REQUEST_NULL, loc_params, buf_size, buf, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get name") done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5A_get_name() */ + FUNC_LEAVE_API(ret_value) +} /* H5Aget_name() */ /*------------------------------------------------------------------------- @@ -1479,8 +910,9 @@ H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, char *name /*out*/, size_t size, hid_t lapl_id) { - H5G_loc_t loc; /* Object location */ - H5A_t *attr = NULL; /* Attribute object for name */ + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1490,8 +922,6 @@ H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, /* Check args */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) @@ -1504,25 +934,37 @@ H5Aget_name_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Open the attribute on the object header */ - if(NULL == (attr = H5A_open_by_idx(&loc, obj_name, idx_type, order, n, lapl_id, H5AC_ind_dxpl_id))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") - - /* Get the length of the name */ - ret_value = (ssize_t)HDstrlen(attr->shared->name); - - /* Copy the name into the user's buffer, if given */ - if(name) { - HDstrncpy(name, attr->shared->name, MIN((size_t)(ret_value + 1), size)); - if((size_t)ret_value >= size) - name[size - 1]='\0'; - } /* end if */ + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = obj_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the name through the VOL */ + if(H5VL_attr_get(obj, vol_plugin, H5VL_ATTR_GET_NAME, H5_REQUEST_NULL, + loc_params, size, name, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get name") + +#if 0 + if(H5VL_object_misc(loc_id, H5VL_ATTR_OPEN_BY_IDX, H5_REQUEST_NULL, &attr_id, + obj_name, idx_type, order, n, H5P_DEFAULT, lapl_id) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to open attribute") + + /* get the name through the VOL */ + if(H5VL_attr_get(attr_id, H5VL_ATTR_GET_NAME, H5_REQUEST_NULL, &ret_value, size, name) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get name") +#endif done: - /* Release resources */ - if(attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") - FUNC_LEAVE_API(ret_value) } /* end H5Aget_name_by_idx() */ @@ -1547,18 +989,23 @@ done: hsize_t H5Aget_storage_size(hid_t attr_id) { - H5A_t *attr; /* Attribute object for ID */ + H5VL_t *vol_plugin; + void *attr; hsize_t ret_value; /* Return value */ FUNC_ENTER_API(0) H5TRACE1("h", "i", attr_id); - /* Check args */ - if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not an attribute") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (attr = (void *)H5I_object(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid attribute identifier") - /* Set return value */ - ret_value = attr->shared->data_size; + /* get the storage size through the VOL */ + if(H5VL_attr_get(attr, vol_plugin, H5VL_ATTR_GET_STORAGE_SIZE, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, 0, "unable to get acpl") done: FUNC_LEAVE_API(ret_value) @@ -1581,19 +1028,27 @@ done: herr_t H5Aget_info(hid_t attr_id, H5A_info_t *ainfo) { - H5A_t *attr; /* Attribute object for name */ + H5VL_t *vol_plugin; + void *attr; + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*x", attr_id, ainfo); - /* Check args */ - if(NULL == (attr = (H5A_t *)H5I_object_verify(attr_id, H5I_ATTR))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (attr = (void *)H5I_object(attr_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier") - /* Get the attribute information */ - if(H5A_get_info(attr, ainfo) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(attr_id); + + /* get the attribute info through the VOL */ + if(H5VL_attr_get(attr, vol_plugin, H5VL_ATTR_GET_INFO, H5_REQUEST_NULL, loc_params, ainfo) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info") done: FUNC_LEAVE_API(ret_value) @@ -1617,8 +1072,9 @@ herr_t H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, H5A_info_t *ainfo, hid_t lapl_id) { - H5G_loc_t loc; /* Object location */ - H5A_t *attr = NULL; /* Attribute object for name */ + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1627,8 +1083,6 @@ H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, /* Check args */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") if(!attr_name || !*attr_name) @@ -1641,19 +1095,38 @@ H5Aget_info_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Open the attribute on the object header */ - if(NULL == (attr = H5A_open_by_name(&loc, obj_name, attr_name, lapl_id, H5AC_ind_dxpl_id))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = obj_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + /* get the attribute info through the VOL */ + if(H5VL_attr_get(obj, vol_plugin, H5VL_ATTR_GET_INFO, H5_REQUEST_NULL, loc_params, ainfo, attr_name) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info") + +#if 0 + /* Open the attribute through the VOL */ + if((attr_id = H5VL_attr_open(loc_id, loc_params, attr_name, H5P_DEFAULT, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to open attribute") + + /* get the attribute info through the VOL */ + if(H5VL_attr_get(attr_id, H5VL_ATTR_GET_INFO, H5_REQUEST_NULL, ainfo) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info") + + /* release resources */ + if(attr_id > 0 && H5VL_attr_close(attr_id, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") - /* Get the attribute information */ - if(H5A_get_info(attr, ainfo) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") +#endif done: - /* Cleanup on failure */ - if(attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") - FUNC_LEAVE_API(ret_value) } /* end H5Aget_info_by_name() */ @@ -1676,8 +1149,9 @@ herr_t H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5A_info_t *ainfo, hid_t lapl_id) { - H5G_loc_t loc; /* Object location */ - H5A_t *attr = NULL; /* Attribute object for name */ + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1687,8 +1161,6 @@ H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, /* Check args */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) @@ -1703,6 +1175,27 @@ H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = obj_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + /* get the attribute info through the VOL */ + if(H5VL_attr_get(obj, vol_plugin, H5VL_ATTR_GET_INFO, H5_REQUEST_NULL, + loc_params, ainfo) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info") + +#if 0 /* Open the attribute on the object header */ if(NULL == (attr = H5A_open_by_idx(&loc, obj_name, idx_type, order, n, lapl_id, H5AC_ind_dxpl_id))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") @@ -1711,57 +1204,26 @@ H5Aget_info_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, if(H5A_get_info(attr, ainfo) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") -done: + /* open the attribute through the VOL */ + if(H5VL_object_misc(loc_id, H5VL_ATTR_OPEN_BY_IDX, H5_REQUEST_NULL, &attr_id, + obj_name, idx_type, order, n, H5P_DEFAULT, lapl_id) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to open attribute") + + /* get the attribute info through the VOL */ + if(H5VL_attr_get(attr_id, H5VL_ATTR_GET_INFO, H5_REQUEST_NULL, ainfo) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info") + /* Release resources */ - if(attr && H5A_close(attr) < 0) + if(attr_id && H5VL_attr_close(attr_id, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") +#endif +done: FUNC_LEAVE_API(ret_value) } /* end H5Aget_info_by_idx() */ /*------------------------------------------------------------------------- - * Function: H5A_get_info - * - * Purpose: Retrieve information about an attribute. - * - * Return: Success: Non-negative - * Failure: Negative - * - * Programmer: Quincey Koziol - * February 6, 2007 - * - *------------------------------------------------------------------------- - */ -herr_t -H5A_get_info(const H5A_t *attr, H5A_info_t *ainfo) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Check args */ - HDassert(attr); - HDassert(ainfo); - - /* Set info for attribute */ - ainfo->cset = attr->shared->encoding; - ainfo->data_size = attr->shared->data_size; - if(attr->shared->crt_idx == H5O_MAX_CRT_ORDER_IDX) { - ainfo->corder_valid = FALSE; - ainfo->corder = 0; - } /* end if */ - else { - ainfo->corder_valid = TRUE; - ainfo->corder = attr->shared->crt_idx; - } /* end else */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_get_info() */ - - -/*------------------------------------------------------------------------- * Function: H5Arename * * Purpose: Rename an attribute @@ -1777,7 +1239,6 @@ done: herr_t H5Arename(hid_t loc_id, const char *old_name, const char *new_name) { - H5G_loc_t loc; /* Object location */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1788,15 +1249,28 @@ H5Arename(hid_t loc_id, const char *old_name, const char *new_name) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "name is nil") if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, & loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") /* Avoid thrashing things if the names are the same */ - if(HDstrcmp(old_name, new_name)) - /* Call attribute rename routine */ - if(H5O_attr_rename(loc.oloc, H5AC_dxpl_id, old_name, new_name) < 0) + if(HDstrcmp(old_name, new_name)) { + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* rename the attribute info through the VOL */ + if(H5VL_object_misc(obj, loc_params, vol_plugin, H5VL_ATTR_RENAME, H5_REQUEST_NULL, + old_name, new_name) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") - + } done: FUNC_LEAVE_API(ret_value) } /* H5Arename() */ @@ -1819,11 +1293,6 @@ herr_t H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name, const char *new_attr_name, hid_t lapl_id) { - H5G_loc_t loc; /* Object location */ - H5G_loc_t obj_loc; /* Location used to open group */ - 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 'obj_name' found */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1833,8 +1302,6 @@ H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name, /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") if(!old_attr_name || !*old_attr_name) @@ -1849,26 +1316,29 @@ H5Arename_by_name(hid_t loc_id, const char *obj_name, const char *old_attr_name, /* Avoid thrashing things if the names are the same */ if(HDstrcmp(old_attr_name, new_attr_name)) { - /* Set up opened group 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, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") - loc_found = TRUE; - - /* Call attribute rename routine */ - if(H5O_attr_rename(obj_loc.oloc, H5AC_dxpl_id, old_attr_name, new_attr_name) < 0) + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; + + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = obj_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* rename the attribute info through the VOL */ + if(H5VL_object_misc(obj, loc_params, vol_plugin, H5VL_ATTR_RENAME, H5_REQUEST_NULL, + old_attr_name, new_attr_name) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") } /* end if */ done: - /* Release resources */ - if(loc_found && H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") - FUNC_LEAVE_API(ret_value) } /* H5Arename_by_name() */ @@ -2046,6 +1516,19 @@ H5Aiterate_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, if((obj_loc_id = H5O_open_by_loc(&obj_loc, lapl_id, H5AC_ind_dxpl_id, TRUE)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open object") + /* get the native object from the ID created by the object header and create + a "VOL object" ID */ + { + void *temp_obj = NULL; + H5I_type_t obj_type; + obj_type = H5I_get_type(obj_loc_id); + if(NULL == (temp_obj = H5I_remove(obj_loc_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") + /* Get an atom for the datatype */ + if((obj_loc_id = H5VL_native_register(obj_type, temp_obj, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype") + } + /* Build attribute operator info */ attr_op.op_type = H5A_ATTR_OP_APP2; attr_op.u.app_op2 = op; @@ -2089,7 +1572,9 @@ done: herr_t H5Adelete(hid_t loc_id, const char *name) { - H5G_loc_t loc; /* Object location */ + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -2098,14 +1583,22 @@ H5Adelete(hid_t loc_id, const char *name) /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - 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") - /* Delete the attribute from the location */ - if(H5O_attr_remove(loc.oloc, name, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + /* Open the attribute through the VOL */ + if(H5VL_attr_remove(obj, loc_params, vol_plugin, name, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") done: FUNC_LEAVE_API(ret_value) @@ -2132,11 +1625,9 @@ herr_t H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id) { - H5G_loc_t loc; /* Object location */ - H5G_loc_t obj_loc; /* Location used to open group */ - 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 'obj_name' found */ + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -2145,8 +1636,6 @@ H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") if(!attr_name || !*attr_name) @@ -2157,25 +1646,23 @@ H5Adelete_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, 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 group location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = obj_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); - /* Find the object's location */ - if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") - loc_found = TRUE; + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - /* Delete the attribute from the location */ - if(H5O_attr_remove(obj_loc.oloc, attr_name, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + /* Open the attribute through the VOL */ + if(H5VL_attr_remove(obj, loc_params, vol_plugin, attr_name, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") done: - /* Release resources */ - if(loc_found && H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") - FUNC_LEAVE_API(ret_value) } /* H5Adelete_by_name() */ @@ -2208,11 +1695,9 @@ herr_t H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id) { - H5G_loc_t loc; /* Object location */ - H5G_loc_t obj_loc; /* Location used to open group */ - 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 'obj_name' found */ + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -2221,8 +1706,6 @@ H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N) @@ -2235,25 +1718,37 @@ H5Adelete_by_idx(hid_t loc_id, const char *obj_name, H5_index_t idx_type, 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 group 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, obj_name, &obj_loc/*out*/, lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") - loc_found = TRUE; - - /* Delete the attribute from the location */ - if(H5O_attr_remove_by_idx(obj_loc.oloc, idx_type, order, n, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = obj_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + /* Open the attribute through the VOL */ + if(H5VL_attr_remove(obj, loc_params, vol_plugin, NULL, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + +#if 0 + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = obj_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + + /* get the attribute info through the VOL */ + if(H5VL_object_misc(loc_id, H5VL_ATTR_DELETE_BY_IDX, H5_REQUEST_NULL, loc_params, + idx_type, order, n) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info") +#endif done: - /* Release resources */ - if(loc_found && H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") - FUNC_LEAVE_API(ret_value) } /* H5Adelete_by_idx() */ @@ -2295,271 +1790,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5A_copy - * - * Purpose: Copies attribute OLD_ATTR. - * - * Return: Success: Pointer to a new copy of the OLD_ATTR argument. - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Thursday, December 4, 1997 - * - * Modification:Raymond Lu - * 4 June 2008 - * Changed some attribute information to be shared. - * - *------------------------------------------------------------------------- - */ -H5A_t * -H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr) -{ - H5A_t *new_attr = NULL; - hbool_t allocated_attr = FALSE; /* Whether the attribute was allocated */ - H5A_t *ret_value = NULL; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) - - /* check args */ - HDassert(old_attr); - - /* Allocate attribute structure */ - if(_new_attr == NULL) { - if(NULL == (new_attr = H5FL_CALLOC(H5A_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - allocated_attr = TRUE; - } /* end if */ - else - new_attr = _new_attr; - - /* Copy the top level of the attribute */ - new_attr->sh_loc = old_attr->sh_loc; - - /* Deep copy of the group hierarchy path */ - if(H5G_name_copy(&(new_attr->path), &(old_attr->path), H5_COPY_DEEP) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy path") - - /* Share some attribute information */ - new_attr->shared = old_attr->shared; - - /* Increment reference count for shared object */ - new_attr->shared->nrefs++; - - /* Don't open the object header for a copy */ - new_attr->obj_opened = FALSE; - - /* Set the return value */ - ret_value = new_attr; - -done: - if(ret_value == NULL) - if(allocated_attr && new_attr && H5A_close(new_attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_copy() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_free - * - * Purpose: Frees all memory associated with an attribute, but does not - * free the H5A_t structure (which should be done in H5T_close). - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, November 15, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5A_free(H5A_t *attr) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - HDassert(attr); - - /* Free dynamicly allocated items */ - if(attr->shared->name) { - H5MM_xfree(attr->shared->name); - attr->shared->name = NULL; - } - if(attr->shared->dt) { - if(H5T_close(attr->shared->dt) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release datatype info") - attr->shared->dt = NULL; - } - if(attr->shared->ds) { - if(H5S_close(attr->shared->ds) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release dataspace info") - attr->shared->ds = NULL; - } - if(attr->shared->data) - attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_free() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_close - * - * Purpose: Frees an attribute and all associated memory. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, December 8, 1997 - * - * Modifications: - * Raymond Lu - * 4 June 2008 - * Changed some attribute object information to be shared. - *------------------------------------------------------------------------- - */ -herr_t -H5A_close(H5A_t *attr) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - HDassert(attr); - HDassert(attr->shared); - - /* Close the object's symbol-table entry */ - if(attr->obj_opened && (H5O_close(&(attr->oloc)) < 0)) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release object header info") - - /* Reference count can be 0. It only happens when H5A_create fails. */ - if(attr->shared->nrefs <= 1) { - /* Free dynamicly allocated items */ - if(H5A_free(attr) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info") - - /* Destroy shared attribute struct */ - attr->shared = H5FL_FREE(H5A_shared_t, attr->shared); - } /* end if */ - else { - /* There are other references to the shared part of the attribute. - * Only decrement the reference count. */ - --attr->shared->nrefs; - } /* end else */ - - /* Free group hierarchy path */ - if(H5G_name_free(&(attr->path)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path") - - attr->shared = NULL; - attr = H5FL_FREE(H5A_t, attr); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_close() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_oloc - * - * Purpose: Return the object location for an attribute. It's the - * object location for the object to which the attribute - * belongs, not the attribute itself. - * - * Return: Success: Ptr to entry - * Failure: NULL - * - * Programmer: Robb Matzke - * Thursday, August 6, 1998 - * - *------------------------------------------------------------------------- - */ -H5O_loc_t * -H5A_oloc(H5A_t *attr) -{ - H5O_loc_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) - - HDassert(attr); - - /* Set return value */ - ret_value = &(attr->oloc); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_oloc() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_nameof - * - * Purpose: Return the group hier. path for an attribute. It's the - * group hier. path for the object to which the attribute - * belongs, not the attribute itself. - * - * Return: Success: Ptr to entry - * Failure: NULL - * - * Programmer: Quincey Koziol - * Monday, September 12, 2005 - * - *------------------------------------------------------------------------- - */ -H5G_name_t * -H5A_nameof(H5A_t *attr) -{ - H5G_name_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) - - HDassert(attr); - - /* Set return value */ - ret_value=&(attr->path); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_nameof() */ - - -/*------------------------------------------------------------------------- - * Function: H5A_type - * - * Purpose: Return the datatype for an attribute. - * - * Return: Success: Ptr to entry - * Failure: NULL - * - * Programmer: Neil Fortner - * Friday, November 11, 2011 - * - *------------------------------------------------------------------------- - */ -H5T_t * -H5A_type(const H5A_t *attr) -{ - H5T_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(NULL) - - HDassert(attr); - - /* Set return value */ - ret_value = attr->shared->dt; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_type() */ - - -/*------------------------------------------------------------------------- * Function: H5Aexists * * Purpose: Checks if an attribute with a given name exists on an opened @@ -2576,7 +1806,9 @@ done: htri_t H5Aexists(hid_t obj_id, const char *attr_name) { - H5G_loc_t loc; /* Object location */ + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; htri_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -2585,14 +1817,22 @@ H5Aexists(hid_t obj_id, const char *attr_name) /* check arguments */ if(H5I_ATTR == H5I_get_type(obj_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(obj_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!attr_name || !*attr_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no attribute name") - /* Check if the attribute exists */ - if((ret_value = H5O_attr_exists(loc.oloc, attr_name, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (obj = (void *)H5VL_get_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(obj_id); + + /* get the attribute info through the VOL */ + if(H5VL_attr_get(obj, vol_plugin, H5VL_ATTR_EXISTS, H5_REQUEST_NULL, loc_params, attr_name, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info") done: FUNC_LEAVE_API(ret_value) @@ -2616,11 +1856,9 @@ htri_t H5Aexists_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, hid_t lapl_id) { - H5G_loc_t loc; /* Object location */ - H5G_loc_t obj_loc; /* Location used to open group */ - 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 'obj_name' found */ + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; htri_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -2629,8 +1867,6 @@ H5Aexists_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!obj_name || !*obj_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no object name") if(!attr_name || !*attr_name) @@ -2641,25 +1877,52 @@ H5Aexists_by_name(hid_t loc_id, const char *obj_name, const char *attr_name, 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 group location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") - /* Find the object's location */ - if(H5G_loc_find(&loc, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") - loc_found = TRUE; + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = obj_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); - /* Check if the attribute exists */ - if((ret_value = H5O_attr_exists(obj_loc.oloc, attr_name, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + /* get the attribute info through the VOL */ + if(H5VL_attr_get(obj, vol_plugin, H5VL_ATTR_EXISTS, H5_REQUEST_NULL, loc_params, attr_name, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get attribute info") done: - /* Release resources */ - if(loc_found && H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") - FUNC_LEAVE_API(ret_value) } /* H5Aexists_by_name() */ + +/*------------------------------------------------------------------------- + * Function: H5A_close_attr + * + * Purpose: Called when the ref count reaches zero on the attr_id + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * June 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5A_close_attr(void *attr, H5VL_t *vol_plugin) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Close the attr through the VOL*/ + if((ret_value = H5VL_attr_close(attr, vol_plugin, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "unable to close attribute") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_close_attr() */ diff --git a/src/H5Adeprec.c b/src/H5Adeprec.c index 7202edf..2cc3b80 100644 --- a/src/H5Adeprec.c +++ b/src/H5Adeprec.c @@ -47,6 +47,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Iprivate.h" /* IDs */ #include "H5Opkg.h" /* Object headers */ +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ @@ -138,9 +139,11 @@ hid_t H5Acreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t plist_id) { - H5G_loc_t loc; /* Object location */ - H5T_t *type; /* Datatype to use for attribute */ - H5S_t *space; /* Dataspace to use for attribute */ + void *attr = NULL; /* attr token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; + H5P_genplist_t *plist; /* Property list pointer */ hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -149,22 +152,46 @@ H5Acreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(0 == (H5F_INTENT(loc.oloc->file) & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_ARGS, H5E_WRITEERROR, FAIL, "no write intent on file") if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") - if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a type") - if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") - /* Go do the real work for attaching the attribute to the dataset */ - if((ret_value = H5A_create(&loc, name, type, space, plist_id, H5AC_dxpl_id)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create attribute") + /* Get correct property list */ + if(H5P_DEFAULT == plist_id) + plist_id = H5P_ATTRIBUTE_CREATE_DEFAULT; + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(plist_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* set creation properties */ + if(H5P_set(plist, H5VL_ATTR_TYPE_ID, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5VL_ATTR_SPACE_ID, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the attribute through the VOL */ + if(NULL == (attr = H5VL_attr_create(obj, loc_params, vol_plugin, name, plist_id, H5P_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create attribute") + + /* Get an atom for the attribute */ + if((ret_value = H5I_register2(H5I_ATTR, attr, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: + if (ret_value < 0 && attr) + if(H5VL_attr_close (attr, vol_plugin, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* H5Acreate1() */ @@ -194,8 +221,10 @@ done: hid_t H5Aopen_name(hid_t loc_id, const char *name) { - H5G_loc_t loc; /* Object location */ - H5A_t *attr = NULL; /* Attribute opened */ + void *attr = NULL; /* attr token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t ret_value; FUNC_ENTER_API(FAIL) @@ -204,25 +233,32 @@ H5Aopen_name(hid_t loc_id, const char *name) /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - 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") - /* Open the attribute on the object header */ - if(NULL == (attr = H5A_open_by_name(&loc, ".", name, H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute: '%s'", name) + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); - /* Register the attribute and get an ID for it */ - if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID") + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") -done: - /* Cleanup on failure */ - if(ret_value < 0) - if(attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the attribute through the VOL */ + if(NULL == (attr = H5VL_attr_open(obj, loc_params, vol_plugin, name, H5P_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open attribute") + /* Get an atom for the attribute */ + if((ret_value = H5I_register2(H5I_ATTR, attr, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") + +done: + if (ret_value < 0 && attr) + if(H5VL_attr_close (attr, vol_plugin, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* H5Aopen_name() */ @@ -252,8 +288,10 @@ done: hid_t H5Aopen_idx(hid_t loc_id, unsigned idx) { - H5G_loc_t loc; /* Object location */ - H5A_t *attr = NULL; /* Attribute opened */ + void *attr = NULL; /* attr token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t ret_value; FUNC_ENTER_API(FAIL) @@ -262,23 +300,34 @@ H5Aopen_idx(hid_t loc_id, unsigned idx) /* check arguments */ if(H5I_ATTR == H5I_get_type(loc_id)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - - /* Open the attribute in the object header */ - if(NULL == (attr = H5A_open_by_idx(&loc, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)idx, H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open attribute") - /* Register the attribute and get an ID for it */ - if((ret_value = H5I_register(H5I_ATTR, attr, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID") + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = "."; + loc_params.loc_data.loc_by_idx.idx_type = H5_INDEX_CRT_ORDER; + loc_params.loc_data.loc_by_idx.order = H5_ITER_INC; + loc_params.loc_data.loc_by_idx.n = (hsize_t)idx; + loc_params.loc_data.loc_by_idx.plist_id = H5P_LINK_ACCESS_DEFAULT; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the attribute through the VOL */ + if(NULL == (attr = H5VL_attr_open(obj, loc_params, vol_plugin, NULL, H5P_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open attribute") + + /* Get an atom for the attribute */ + if((ret_value = H5I_register2(H5I_ATTR, attr, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: - /* Cleanup on failure */ - if(ret_value < 0) - if(attr && H5A_close(attr) < 0) - HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") - + if (ret_value < 0 && attr) + if(H5VL_attr_close (attr, vol_plugin, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* H5Aopen_idx() */ @@ -304,56 +353,31 @@ done: int H5Aget_num_attrs(hid_t loc_id) { - H5O_loc_t *loc; /* Object location for attribute */ - void *obj; - int ret_value; + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; + H5O_info_t oinfo; + int ret_value; FUNC_ENTER_API(FAIL) H5TRACE1("Is", "i", loc_id); - /* check arguments */ - if(H5I_BADID == H5I_get_type(loc_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad location ID") - if(H5I_FILE == H5I_get_type(loc_id) || H5I_ATTR == H5I_get_type(loc_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute") - if(NULL == (obj = H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom") - switch(H5I_get_type (loc_id)) { - case H5I_DATASET: - if(NULL == (loc = H5D_oloc((H5D_t*)obj))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get location for object") - break; - - case H5I_DATATYPE: - if(NULL == (loc = H5T_oloc((H5T_t*)obj))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "target datatype is not committed") - break; - - case H5I_GROUP: - if(NULL == (loc = H5G_oloc((H5G_t*)obj))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get location for object") - break; - - case H5I_UNINIT: - case H5I_BADID: - case H5I_FILE: - case H5I_DATASPACE: - case H5I_ATTR: - case H5I_REFERENCE: - case H5I_VFL: - case H5I_GENPROP_CLS: - case H5I_GENPROP_LST: - case H5I_ERROR_CLASS: - case H5I_ERROR_MSG: - case H5I_ERROR_STACK: - case H5I_NTYPES: - default: - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "inappropriate attribute target") - } /*lint !e788 All appropriate cases are covered */ - - /* Look up the # of attributes for the object */ - if((ret_value = H5O_attr_count(loc, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "can't get attribute count for object") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Get the group info through the VOL using the location token */ + if(H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_GET_INFO, + H5_REQUEST_NULL, &oinfo) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") + + ret_value = oinfo.num_attrs; done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Aint.c b/src/H5Aint.c index ab9bece..ba900d9 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -43,7 +43,8 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ #include "H5SMprivate.h" /* Shared Object Header Messages */ - +#include "H5VLnative.h" /* Native Plugin */ +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ /* Local Macros */ @@ -119,6 +120,1169 @@ H5FL_SEQ_DEFINE(H5A_t_ptr); /*------------------------------------------------------------------------- + * Function: H5A_create + * + * Purpose: + * This is the guts of creating an attribute. + * Usage: + * hid_t H5A_create(ent, name, type, space) + * const H5G_entry_t *ent; IN: Pointer to symbol table entry for object to attribute + * const char *name; IN: Name of attribute + * H5T_t *type; IN: Datatype of attribute + * H5S_t *space; IN: Dataspace of attribute + * hid_t acpl_id IN: Attribute creation property list + * + * Return: attribute structure on success, NULL on Failuer + * + * Programmer: Quincey Koziol + * April 2, 1998 + * + * Modified: Mohamad Chaarawi + * June 2012 + * Retuen H5A_t* instead of hid_t + * + *------------------------------------------------------------------------- + */ +H5A_t * +H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, + const H5S_t *space, hid_t acpl_id, hid_t dxpl_id) +{ + hssize_t snelmts; /* elements in attribute */ + size_t nelmts; /* elements in attribute */ + htri_t tri_ret; /* htri_t return value */ + H5A_t *attr = NULL; + H5A_t *ret_value = NULL; /* Attribute created */ + + FUNC_ENTER_NOAPI_NOINIT_TAG(dxpl_id, loc->oloc->addr, NULL) + + /* check args */ + HDassert(loc); + HDassert(name); + HDassert(type); + HDassert(space); + + /* Check for existing attribute with same name */ + /* (technically, the "attribute create" operation will fail for a duplicated + * name, but it's going to be hard to unwind all the special cases on + * failure, so just check first, for now - QAK) + */ + if((tri_ret = H5O_attr_exists(loc->oloc, name, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "error checking attributes") + else if(tri_ret > 0) + HGOTO_ERROR(H5E_ATTR, H5E_ALREADYEXISTS, NULL, "attribute already exists") + + /* Check if the dataspace has an extent set (or is NULL) */ + if(!(H5S_has_extent(space))) + HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, NULL, "dataspace extent has not been set") + + /* Check if the datatype is "sensible" for use in a dataset */ + if(H5T_is_sensible(type) != TRUE) + HGOTO_ERROR(H5E_ATTR, H5E_BADTYPE, NULL, "datatype is not sensible") + + /* Build the attribute information */ + if(NULL == (attr = H5FL_CALLOC(H5A_t))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, NULL, "memory allocation failed for attribute info") + + if(NULL == (attr->shared = H5FL_CALLOC(H5A_shared_t))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, NULL, "can't allocate shared attr structure") + + /* If the creation property list is H5P_DEFAULT, use the default character encoding */ + if(acpl_id == H5P_DEFAULT) + attr->shared->encoding = H5F_DEFAULT_CSET; + else { + H5P_genplist_t *ac_plist; /* ACPL Property list */ + + /* Get a local copy of the attribute creation property list */ + if(NULL == (ac_plist = (H5P_genplist_t *)H5I_object(acpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list") + + if(H5P_get(ac_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get character encoding flag") + } /* end else */ + + /* Copy the attribute name */ + attr->shared->name = H5MM_xstrdup(name); + + /* Copy datatype */ + if(NULL == (attr->shared->dt = H5T_copy(type, H5T_COPY_ALL))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "can't get shared datatype info") + + /* Mark datatype as being on disk now */ + if(H5T_set_loc(attr->shared->dt, loc->oloc->file, H5T_LOC_DISK) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location") + + /* Set the latest format for datatype, if requested */ + if(H5F_USE_LATEST_FORMAT(loc->oloc->file)) + if(H5T_set_latest_version(attr->shared->dt) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of datatype") + + /* Copy the dataspace for the attribute */ + attr->shared->ds = H5S_copy(space, FALSE, TRUE); + + /* Set the latest format for dataspace, if requested */ + if(H5F_USE_LATEST_FORMAT(loc->oloc->file)) + if(H5S_set_latest_version(attr->shared->ds) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of dataspace") + + /* Copy the object header information */ + if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to copy entry") + + /* Deep copy of the group hierarchy path */ + if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy path") + + /* Check if any of the pieces should be (or are already) shared in the + * SOHM table + */ + if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, 0, H5O_DTYPE_ID, attr->shared->dt, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, NULL, "trying to share datatype failed") + if(H5SM_try_share(attr->oloc.file, dxpl_id, NULL, 0, H5O_SDSPACE_ID, attr->shared->ds, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, NULL, "trying to share dataspace failed") + + /* Check whether datatype is committed & increment ref count + * (to maintain ref. count incr/decr similarity with "shared message" + * type of datatype sharing) + */ + if(H5T_committed(attr->shared->dt)) { + /* Increment the reference count on the shared datatype */ + if(H5T_link(attr->shared->dt, 1, dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, NULL, "unable to adjust shared datatype link count") + } /* end if */ + + /* Compute the size of pieces on disk. This is either the size of the + * datatype and dataspace messages themselves, or the size of the "shared" + * messages if either or both of them are shared. + */ + attr->shared->dt_size = H5O_msg_raw_size(attr->oloc.file, H5O_DTYPE_ID, FALSE, attr->shared->dt); + attr->shared->ds_size = H5O_msg_raw_size(attr->oloc.file, H5O_SDSPACE_ID, FALSE, attr->shared->ds); + + /* Get # of elements for attribute's dataspace */ + if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, NULL, "dataspace is invalid") + H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t); + + HDassert(attr->shared->dt_size > 0); + HDassert(attr->shared->ds_size > 0); + attr->shared->data_size = nelmts * H5T_GET_SIZE(attr->shared->dt); + + /* Hold the symbol table entry (and file) open */ + if(H5O_open(&(attr->oloc)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to open") + attr->obj_opened = TRUE; + + /* Set the version to encode the attribute with */ + if(H5A_set_version(attr->oloc.file, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTSET, NULL, "unable to update attribute version") + + /* Insert the attribute into the object header */ + if(H5O_attr_create(&(attr->oloc), dxpl_id, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, NULL, "unable to create attribute in object header") + + ret_value = attr; +done: + if(NULL == ret_value && attr && H5A_close(attr)) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") + FUNC_LEAVE_NOAPI_TAG(ret_value, NULL) +} /* H5A_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_open_common + * + * Purpose: + * Finishes initializing an attributes the open + * + * Usage: + * herr_t H5A_open_common(loc, name, dxpl_id) + * const H5G_loc_t *loc; IN: Pointer to group location for object + * H5A_t *attr; IN/OUT: Pointer to attribute to initialize + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * December 18, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5A_open_common(const H5G_loc_t *loc, H5A_t *attr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* check args */ + HDassert(loc); + HDassert(attr); + +#if defined(H5_USING_MEMCHECKER) || !defined(NDEBUG) + /* Clear object location */ + if(H5O_loc_reset(&(attr->oloc)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to reset location") +#endif /* H5_USING_MEMCHECKER */ + + /* Free any previous group hier. path */ + if(H5G_name_free(&(attr->path)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path") + + /* Deep copy of the symbol table entry */ + if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry") + + /* Deep copy of the group hier. path */ + if(H5G_name_copy(&(attr->path), loc->path, H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, FAIL, "unable to copy entry") + + /* Hold the symbol table entry (and file) open */ + if(H5O_open(&(attr->oloc)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open") + attr->obj_opened = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_open_common() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_open_by_idx + * + * Purpose: Open an attribute according to its index order + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * April 2, 1998 + * + *------------------------------------------------------------------------- + */ +H5A_t * +H5A_open_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, hid_t lapl_id, hid_t dxpl_id) +{ + H5G_loc_t obj_loc; /* Location used to open group */ + 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 'obj_name' found */ + H5A_t *attr = NULL; /* Attribute from object header */ + H5A_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* check args */ + HDassert(loc); + HDassert(obj_name); + + /* Set up opened group 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, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "object not found") + loc_found = TRUE; + + /* Read in attribute from object header */ + if(NULL == (attr = H5O_attr_open_by_idx(obj_loc.oloc, idx_type, order, n, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to load attribute info from object header") + + /* Finish initializing attribute */ + if(H5A_open_common(&obj_loc, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to initialize attribute") + + /* Set return value */ + ret_value = attr; + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't free location") + + /* Cleanup on failure */ + if(ret_value == NULL) + if(attr && H5A_close(attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_open_by_idx() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_open_by_name + * + * Purpose: Open an attribute in an object header, according to it's name + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * December 11, 2006 + * + *------------------------------------------------------------------------- + */ +H5A_t * +H5A_open_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name, + hid_t lapl_id, hid_t dxpl_id) +{ + H5G_loc_t obj_loc; /* Location used to open group */ + 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 'obj_name' found */ + H5A_t *attr = NULL; /* Attribute from object header */ + H5A_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check args */ + HDassert(loc); + HDassert(obj_name); + HDassert(attr_name); + + /* Set up opened group 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, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "object not found") + loc_found = TRUE; + + /* Read in attribute from object header */ + if(NULL == (attr = H5O_attr_open_by_name(obj_loc.oloc, attr_name, dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to load attribute info from object header") + + /* Finish initializing attribute */ + if(H5A_open_common(loc, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to initialize attribute") + + /* Set return value */ + ret_value = attr; + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't free location") + + /* Cleanup on failure */ + if(ret_value == NULL) + if(attr && H5A_close(attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_open_by_name() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_write + PURPOSE + Actually write out data to an attribute + USAGE + herr_t H5A_write (attr, mem_type, buf) + H5A_t *attr; IN: Attribute to write + const H5T_t *mem_type; IN: Memory datatype of buffer + const void *buf; IN: Buffer of data to write + RETURNS + Non-negative on success/Negative on failure + + DESCRIPTION + This function writes a complete attribute to disk. +--------------------------------------------------------------------------*/ +herr_t +H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id) +{ + uint8_t *tconv_buf = NULL; /* datatype conv buffer */ + hbool_t tconv_owned = FALSE; /* Whether the datatype conv buffer is owned by attribute */ + uint8_t *bkg_buf = NULL; /* temp conversion buffer */ + hssize_t snelmts; /* elements in attribute */ + size_t nelmts; /* elements in attribute */ + H5T_path_t *tpath = NULL; /* conversion information*/ + hid_t src_id = -1, dst_id = -1;/* temporary type atoms */ + size_t src_type_size; /* size of source type */ + size_t dst_type_size; /* size of destination type*/ + size_t buf_size; /* desired buffer size */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT_TAG(dxpl_id, attr->oloc.addr, FAIL) + + HDassert(attr); + HDassert(mem_type); + HDassert(buf); + + /* Get # of elements for attribute's dataspace */ + if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid") + H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t); + + /* If there's actually data elements for the attribute, make a copy of the data passed in */ + if(nelmts > 0) { + /* Get the memory and file datatype sizes */ + src_type_size = H5T_GET_SIZE(mem_type); + dst_type_size = H5T_GET_SIZE(attr->shared->dt); + + /* Convert memory buffer into disk buffer */ + /* Set up type conversion function */ + if(NULL == (tpath = H5T_path_find(mem_type, attr->shared->dt, NULL, NULL, dxpl_id, FALSE))) + HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes") + + /* Check for type conversion required */ + if(!H5T_path_noop(tpath)) { + if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0 || + (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion") + + /* Get the maximum buffer size needed and allocate it */ + buf_size = nelmts * MAX(src_type_size, dst_type_size); + if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed") + if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTALLOC, FAIL, "memory allocation failed") + + /* Copy the user's data into the buffer for conversion */ + HDmemcpy(tconv_buf, buf, (src_type_size * nelmts)); + + /* Perform datatype conversion */ + if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed") + + /* Free the previous attribute data buffer, if there is one */ + if(attr->shared->data) + attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data); + + /* Set the pointer to the attribute data to the converted information */ + attr->shared->data = tconv_buf; + tconv_owned = TRUE; + } /* end if */ + /* No type conversion necessary */ + else { + HDassert(dst_type_size == src_type_size); + + /* Allocate the attribute buffer, if there isn't one */ + if(attr->shared->data == NULL) + if(NULL == (attr->shared->data = H5FL_BLK_MALLOC(attr_buf, dst_type_size * nelmts))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Copy the attribute data into the user's buffer */ + HDmemcpy(attr->shared->data, buf, (dst_type_size * nelmts)); + } /* end else */ + + /* Modify the attribute in the object header */ + if(H5O_attr_write(&(attr->oloc), dxpl_id, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to modify attribute") + } /* end if */ + +done: + /* Release resources */ + if(src_id >= 0 && H5I_dec_ref(src_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") + if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") + if(tconv_buf && !tconv_owned) + tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf); + if(bkg_buf) + bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf); + + FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL) +} /* H5A_write() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_read + PURPOSE + Actually read in data from an attribute + USAGE + herr_t H5A_read (attr, mem_type, buf) + H5A_t *attr; IN: Attribute to read + const H5T_t *mem_type; IN: Memory datatype of buffer + void *buf; IN: Buffer for data to read + RETURNS + Non-negative on success/Negative on failure + + DESCRIPTION + This function reads a complete attribute from disk. +--------------------------------------------------------------------------*/ +herr_t +H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id) +{ + uint8_t *tconv_buf = NULL; /* datatype conv buffer*/ + uint8_t *bkg_buf = NULL; /* background buffer */ + hssize_t snelmts; /* elements in attribute */ + size_t nelmts; /* elements in attribute*/ + H5T_path_t *tpath = NULL; /* type conversion info */ + hid_t src_id = -1, dst_id = -1;/* temporary type atoms*/ + size_t src_type_size; /* size of source type */ + size_t dst_type_size; /* size of destination type */ + size_t buf_size; /* desired buffer size */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(attr); + HDassert(mem_type); + HDassert(buf); + + /* Create buffer for data to store on disk */ + if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->shared->ds)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid") + H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t); + + if(nelmts > 0) { + /* Get the memory and file datatype sizes */ + src_type_size = H5T_GET_SIZE(attr->shared->dt); + dst_type_size = H5T_GET_SIZE(mem_type); + + /* Check if the attribute has any data yet, if not, fill with zeroes */ + if(attr->obj_opened && !attr->shared->data) + HDmemset(buf, 0, (dst_type_size * nelmts)); + else { /* Attribute exists and has a value */ + /* Convert memory buffer into disk buffer */ + /* Set up type conversion function */ + if(NULL == (tpath = H5T_path_find(attr->shared->dt, mem_type, NULL, NULL, dxpl_id, FALSE))) + HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes") + + /* Check for type conversion required */ + if(!H5T_path_noop(tpath)) { + if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->shared->dt, H5T_COPY_ALL), FALSE)) < 0 || + (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL), FALSE)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion") + + /* Get the maximum buffer size needed and allocate it */ + buf_size = nelmts * MAX(src_type_size, dst_type_size); + if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size))) + HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed") + if(NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size))) + HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Copy the attribute data into the buffer for conversion */ + HDmemcpy(tconv_buf, attr->shared->data, (src_type_size * nelmts)); + + /* Perform datatype conversion. */ + if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed") + + /* Copy the converted data into the user's buffer */ + HDmemcpy(buf, tconv_buf, (dst_type_size * nelmts)); + } /* end if */ + /* No type conversion necessary */ + else { + HDassert(dst_type_size == src_type_size); + + /* Copy the attribute data into the user's buffer */ + HDmemcpy(buf, attr->shared->data, (dst_type_size * nelmts)); + } /* end else */ + } /* end else */ + } /* end if */ + +done: + /* Release resources */ + if(src_id >= 0 && H5I_dec_ref(src_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") + if(dst_id >= 0 && H5I_dec_ref(dst_id) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to close temporary object") + if(tconv_buf) + tconv_buf = H5FL_BLK_FREE(attr_buf, tconv_buf); + if(bkg_buf) + bkg_buf = H5FL_BLK_FREE(attr_buf, bkg_buf); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_get_space + * + * Purpose: Returns and ID for the dataspace of the attribute. + * + * Return: Success: ID for dataspace + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5A_get_space(H5A_t *attr) +{ + H5S_t *ds = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Copy the attribute's dataspace */ + if(NULL == (ds = H5S_copy(attr->shared->ds, FALSE, TRUE))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy dataspace") + + /* Atomize */ + if((ret_value = H5I_register(H5I_DATASPACE, ds, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") + +done: + if(ret_value < 0 && ds) { + if(H5S_close(ds) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_get_space() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_get_type + * + * Purpose: Returns and ID for the datatype of the dataset. + * + * Return: Success: ID for datatype + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5A_get_type(H5A_t *attr) +{ + H5T_t *dt = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Patch the datatype's "top level" file pointer */ + if(H5T_patch_file(attr->shared->dt, attr->oloc.file) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to patch datatype's file pointer") + + /* + * Copy the attribute's datatype. If the type is a named type then + * reopen the type before returning it to the user. Make the type + * read-only. + */ + if(NULL == (dt = H5T_copy(attr->shared->dt, H5T_COPY_REOPEN))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy datatype") + + /* Mark any datatypes as being in memory now */ + if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") + + /* Lock copied type */ + if(H5T_lock(dt, FALSE) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype") + + /* Create an atom */ + if(H5T_committed(dt)) { + /* If this is a committed datatype, we need to recreate the + two level IDs, where the VOL object is a copy of the + returned datatype */ + if((ret_value = H5VL_native_register(H5I_DATATYPE, dt, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") + } + else { + if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype") + } + +done: + if(ret_value < 0) { + if(dt && H5T_close(dt) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_get_type() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_get_create_plist + PURPOSE + private version of H5Aget_create_plist + RETURNS + This function returns the ID of a copy of the attribute's creation + property list, or negative on failure. + + ERRORS + + DESCRIPTION + This function returns a copy of the creation property list for + an attribute. The resulting ID must be closed with H5Pclose() or + resource leaks will occur. +--------------------------------------------------------------------------*/ +hid_t +H5A_get_create_plist(H5A_t* attr) +{ + H5P_genplist_t *plist; /* Default property list */ + hid_t new_plist_id; /* ID of ACPL to return */ + H5P_genplist_t *new_plist; /* ACPL to return */ + hid_t ret_value; + FUNC_ENTER_NOAPI_NOINIT + + if(NULL == (plist = (H5P_genplist_t *)H5I_object(H5P_LST_ATTRIBUTE_CREATE_g))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get default ACPL") + + /* Create the property list object to return */ + if((new_plist_id = H5P_copy_plist(plist, TRUE)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy attribute creation properties") + if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_plist_id))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list") + + /* Set the character encoding on the new property list */ + if(H5P_set(new_plist, H5P_STRCRT_CHAR_ENCODING_NAME, &(attr->shared->encoding)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding") + + ret_value = new_plist_id; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5Aget_create_plist() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_get_name + PURPOSE + Private function for H5Aget_name. Gets a copy of the name for an + attribute + RETURNS + This function returns the length of the attribute's name (which may be + longer than 'buf_size') on success or negative for failure. + DESCRIPTION + This function retrieves the name of an attribute for an attribute ID. + Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string + terminator. If the name of the attribute is longer than 'buf_size'-1, + the string terminator is stored in the last position of the buffer to + properly terminate the string. +--------------------------------------------------------------------------*/ +ssize_t +H5A_get_name(H5A_t *attr, size_t buf_size, char *buf) +{ + size_t copy_len, nbytes; + ssize_t ret_value; + + FUNC_ENTER_NOAPI(FAIL) + + /* get the real attribute length */ + nbytes = HDstrlen(attr->shared->name); + HDassert((ssize_t)nbytes >= 0); /*overflow, pretty unlikely --rpm*/ + + /* compute the string length which will fit into the user's buffer */ + copy_len = MIN(buf_size - 1, nbytes); + + /* Copy all/some of the name */ + if(buf && copy_len > 0) { + HDmemcpy(buf, attr->shared->name, copy_len); + + /* Terminate the string */ + buf[copy_len]='\0'; + } /* end if */ + + /* Set return value */ + ret_value = (ssize_t)nbytes; + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_get_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_get_info + * + * Purpose: Retrieve information about an attribute. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * February 6, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5A_get_info(const H5A_t *attr, H5A_info_t *ainfo) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args */ + HDassert(attr); + HDassert(ainfo); + + /* Set info for attribute */ + ainfo->cset = attr->shared->encoding; + ainfo->data_size = attr->shared->data_size; + if(attr->shared->crt_idx == H5O_MAX_CRT_ORDER_IDX) { + ainfo->corder_valid = FALSE; + ainfo->corder = 0; + } /* end if */ + else { + ainfo->corder_valid = TRUE; + ainfo->corder = attr->shared->crt_idx; + } /* end else */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_get_info() */ + + +/*-------------------------------------------------------------------------- + NAME + H5A_delete_by_idx + PURPOSE + private version of H5Adelete_by_idx + RETURNS + Non-negative on success/Negative on failure +--------------------------------------------------------------------------*/ +herr_t +H5A_delete_by_idx(H5G_loc_t loc, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, hid_t lapl_id) +{ + H5G_loc_t obj_loc; /* Location used to open group */ + 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 'obj_name' found */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Set up opened group 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, obj_name, &obj_loc/*out*/, lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") + loc_found = TRUE; + + /* Delete the attribute from the location */ + if(H5O_attr_remove_by_idx(obj_loc.oloc, idx_type, order, n, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_delete_by_idx() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_copy + * + * Purpose: Copies attribute OLD_ATTR. + * + * Return: Success: Pointer to a new copy of the OLD_ATTR argument. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Thursday, December 4, 1997 + * + * Modification:Raymond Lu + * 4 June 2008 + * Changed some attribute information to be shared. + * + *------------------------------------------------------------------------- + */ +H5A_t * +H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr) +{ + H5A_t *new_attr = NULL; + hbool_t allocated_attr = FALSE; /* Whether the attribute was allocated */ + H5A_t *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check args */ + HDassert(old_attr); + + /* Allocate attribute structure */ + if(_new_attr == NULL) { + if(NULL == (new_attr = H5FL_CALLOC(H5A_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + allocated_attr = TRUE; + } /* end if */ + else + new_attr = _new_attr; + + /* Copy the top level of the attribute */ + new_attr->sh_loc = old_attr->sh_loc; + + /* Deep copy of the group hierarchy path */ + if(H5G_name_copy(&(new_attr->path), &(old_attr->path), H5_COPY_DEEP) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "unable to copy path") + + /* Share some attribute information */ + new_attr->shared = old_attr->shared; + + /* Increment reference count for shared object */ + new_attr->shared->nrefs++; + + /* Don't open the object header for a copy */ + new_attr->obj_opened = FALSE; + + /* Set the return value */ + ret_value = new_attr; + +done: + if(ret_value == NULL) + if(allocated_attr && new_attr && H5A_close(new_attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, NULL, "can't close attribute") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_free + * + * Purpose: Frees all memory associated with an attribute, but does not + * free the H5A_t structure (which should be done in H5T_close). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, November 15, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5A_free(H5A_t *attr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(attr); + + /* Free dynamicly allocated items */ + if(attr->shared->name) { + H5MM_xfree(attr->shared->name); + attr->shared->name = NULL; + } + if(attr->shared->dt) { + if(H5T_close(attr->shared->dt) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release datatype info") + attr->shared->dt = NULL; + } + if(attr->shared->ds) { + if(H5S_close(attr->shared->ds) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release dataspace info") + attr->shared->ds = NULL; + } + if(attr->shared->data) + attr->shared->data = H5FL_BLK_FREE(attr_buf, attr->shared->data); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_free() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_close + * + * Purpose: Frees an attribute and all associated memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, December 8, 1997 + * + * Modifications: + * Raymond Lu + * 4 June 2008 + * Changed some attribute object information to be shared. + *------------------------------------------------------------------------- + */ +herr_t +H5A_close(H5A_t *attr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + HDassert(attr); + HDassert(attr->shared); + + /* Close the object's symbol-table entry */ + if(attr->obj_opened && (H5O_close(&(attr->oloc)) < 0)) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release object header info") + + /* Reference count can be 0. It only happens when H5A_create fails. */ + if(attr->shared->nrefs <= 1) { + /* Free dynamicly allocated items */ + if(H5A_free(attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info") + + /* Destroy shared attribute struct */ + attr->shared = H5FL_FREE(H5A_shared_t, attr->shared); + } /* end if */ + else { + /* There are other references to the shared part of the attribute. + * Only decrement the reference count. */ + --attr->shared->nrefs; + } /* end else */ + + /* Free group hierarchy path */ + if(H5G_name_free(&(attr->path)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path") + + attr->shared = NULL; + attr = H5FL_FREE(H5A_t, attr); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_oloc + * + * Purpose: Return the object location for an attribute. It's the + * object location for the object to which the attribute + * belongs, not the attribute itself. + * + * Return: Success: Ptr to entry + * Failure: NULL + * + * Programmer: Robb Matzke + * Thursday, August 6, 1998 + * + *------------------------------------------------------------------------- + */ +H5O_loc_t * +H5A_oloc(H5A_t *attr) +{ + H5O_loc_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + HDassert(attr); + + /* Set return value */ + ret_value = &(attr->oloc); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_oloc() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_nameof + * + * Purpose: Return the group hier. path for an attribute. It's the + * group hier. path for the object to which the attribute + * belongs, not the attribute itself. + * + * Return: Success: Ptr to entry + * Failure: NULL + * + * Programmer: Quincey Koziol + * Monday, September 12, 2005 + * + *------------------------------------------------------------------------- + */ +H5G_name_t * +H5A_nameof(H5A_t *attr) +{ + H5G_name_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + HDassert(attr); + + /* Set return value */ + ret_value=&(attr->path); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_nameof() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_type + * + * Purpose: Return the datatype for an attribute. + * + * Return: Success: Ptr to entry + * Failure: NULL + * + * Programmer: Neil Fortner + * Friday, November 11, 2011 + * + *------------------------------------------------------------------------- + */ +H5T_t * +H5A_type(const H5A_t *attr) +{ + H5T_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + HDassert(attr); + + /* Set return value */ + ret_value = attr->shared->dt; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5A_type() */ + + +/*------------------------------------------------------------------------- + * Function: H5A_exists_by_name + * + * Purpose: Private version of H5Aexists_by_name + * + * Return: Success: TRUE/FALSE + * Failure: Negative + * + * Programmer: Quincey Koziol + * Thursday, November 1, 2007 + * + *------------------------------------------------------------------------- + */ +htri_t +H5A_exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name, + hid_t lapl_id) +{ + H5G_loc_t obj_loc; /* Location used to open group */ + 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 'obj_name' found */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Set up opened group 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, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") + loc_found = TRUE; + + /* Check if the attribute exists */ + if((ret_value = H5O_attr_exists(obj_loc.oloc, attr_name, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_exists_by_name() */ + + +/*------------------------------------------------------------------------- * Function: H5A__compact_build_table_cb * * Purpose: Object header iterator callback routine to copy attribute @@ -1259,3 +2423,53 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5A_dense_post_copy_file_all */ + +/*------------------------------------------------------------------------- + * Function: H5A_rename_by_name + * + * Purpose: Private version of H5Arename_by_name + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * February 20, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5A_rename_by_name(H5G_loc_t loc, const char *obj_name, const char *old_attr_name, + const char *new_attr_name, hid_t lapl_id) +{ + H5G_loc_t obj_loc; /* Location used to open group */ + 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 'obj_name' found */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Avoid thrashing things if the names are the same */ + if(HDstrcmp(old_attr_name, new_attr_name)) { + /* Set up opened group 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, obj_name, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") + loc_found = TRUE; + + /* Call attribute rename routine */ + if(H5O_attr_rename(obj_loc.oloc, H5AC_dxpl_id, old_attr_name, new_attr_name) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") + } /* end if */ + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5A_rename_by_name() */ diff --git a/src/H5Apkg.h b/src/H5Apkg.h index 26c8dff..c9411d5 100644 --- a/src/H5Apkg.h +++ b/src/H5Apkg.h @@ -185,19 +185,25 @@ H5_DLLVAR const H5B2_class_t H5A_BT2_CORDER[1]; /* Function prototypes for H5A package scope */ H5_DLL herr_t H5A_init(void); -H5_DLL hid_t H5A_create(const H5G_loc_t *loc, const char *name, +H5_DLL H5A_t *H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, const H5S_t *space, hid_t acpl_id, hid_t dxpl_id); -H5_DLL H5A_t * H5A_open_by_name(const H5G_loc_t *loc, const char *obj_name, +H5_DLL H5A_t *H5A_open_by_name(const H5G_loc_t *loc, const char *obj_name, const char *attr_name, hid_t lapl_id, hid_t dxpl_id); H5_DLL H5A_t *H5A_open_by_idx(const H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t lapl_id, hid_t dxpl_id); H5_DLL ssize_t H5A_get_name(H5A_t *attr, size_t buf_size, char *buf); H5_DLL H5A_t *H5A_copy(H5A_t *new_attr, const H5A_t *old_attr); H5_DLL herr_t H5A_get_info(const H5A_t *attr, H5A_info_t *ainfo); +H5_DLL hid_t H5A_get_type(H5A_t *attr); +H5_DLL hid_t H5A_get_space(H5A_t *attr); +H5_DLL hid_t H5A_get_create_plist(H5A_t* attr); H5_DLL herr_t H5A_free(H5A_t *attr); H5_DLL herr_t H5A_close(H5A_t *attr); H5_DLL htri_t H5A_get_ainfo(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_ainfo_t *ainfo); H5_DLL herr_t H5A_set_version(const H5F_t *f, H5A_t *attr); +H5_DLL herr_t H5A_open_common(const H5G_loc_t *loc, H5A_t *attr); +H5_DLL herr_t H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id); +H5_DLL herr_t H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id); /* Attribute "dense" storage routines */ H5_DLL herr_t H5A_dense_create(H5F_t *f, hid_t dxpl_id, H5O_ainfo_t *ainfo); diff --git a/src/H5Aprivate.h b/src/H5Aprivate.h index 6646fa2..fa774fa 100644 --- a/src/H5Aprivate.h +++ b/src/H5Aprivate.h @@ -32,7 +32,6 @@ /* Library Private Macros */ /**************************/ - /****************************/ /* Library Private Typedefs */ /****************************/ @@ -83,6 +82,11 @@ H5_DLL herr_t H5O_attr_iterate_real(hid_t loc_id, const H5O_loc_t *loc, H5_DLL herr_t H5O_attr_iterate(hid_t loc_id, hid_t dxpl_id, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_attr, const H5A_attr_iter_op_t *op, void *op_data); - +H5_DLL herr_t H5A_rename_by_name(H5G_loc_t loc, const char *obj_name, const char *old_attr_name, + const char *new_attr_name, hid_t lapl_id); +H5_DLL herr_t H5A_delete_by_idx(H5G_loc_t loc, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, hsize_t n, hid_t lapl_id); +H5_DLL htri_t H5A_exists_by_name(H5G_loc_t loc, const char *obj_name, const char *attr_name, + hid_t lapl_id); #endif /* _H5Aprivate_H */ @@ -31,7 +31,8 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free lists */ #include "H5Iprivate.h" /* IDs */ - +#include "H5MMprivate.h" /* Memory management */ +#include "H5VLprivate.h" /* VOL plugins */ /****************/ /* Local Macros */ @@ -63,10 +64,6 @@ H5FL_BLK_EXTERN(vlen_fl_buf); /* Library Private Variables */ /*****************************/ -/* Declare extern the free list to manage blocks of type conversion data */ -H5FL_BLK_EXTERN(type_conv); - - /*******************/ /* Local Variables */ /*******************/ @@ -91,6 +88,19 @@ H5D__init_pub_interface(void) FUNC_ENTER_STATIC_NOERR FUNC_LEAVE_NOAPI(H5D_init()) +#if 0 + herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_STATIC + + /* Initialize the atom group for the dataset IDs */ + if(H5I_register_type(H5I_DATASET, (size_t)H5I_DATASETID_HASHSIZE, H5D_RESERVED_ATOMS, + NULL, (H5I_free2_t)H5D_close_dataset)<H5I_FILE) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize interface") + + ret_value = H5D_init(); +done: + FUNC_LEAVE_NOAPI(ret_value) +#endif } /* H5D__init_pub_interface() */ @@ -127,22 +137,19 @@ hid_t H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id) { - H5G_loc_t loc; /* Object location to insert dataset into */ - H5D_t *dset = NULL; /* New dataset's info */ - const H5S_t *space; /* Dataspace for dataset */ - hid_t ret_value; /* Return value */ + void *dset = NULL; /* dset token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; + H5P_genplist_t *plist; /* Property list pointer */ + hid_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE7("i", "i*siiiii", loc_id, name, type_id, space_id, lcpl_id, dcpl_id, dapl_id); - /* Check arguments */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID") - if(H5I_DATATYPE != H5I_get_type(type_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype ID") - if(NULL == (space = (const H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace ID") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") /* Get correct property list */ if(H5P_DEFAULT == lcpl_id) @@ -165,17 +172,40 @@ H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list") - /* Create the new dataset & get its ID */ - if(NULL == (dset = H5D__create_named(&loc, name, type_id, space, lcpl_id, dcpl_id, dapl_id, H5AC_dxpl_id))) + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* set creation properties */ + if(H5P_set(plist, H5VL_DSET_TYPE_ID, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5VL_DSET_SPACE_ID, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") + if(H5P_set(plist, H5VL_DSET_LCPL_ID, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for lcpl id") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the dataset through the VOL */ + if(NULL == (dset = H5VL_dataset_create(obj, loc_params, vol_plugin, name, dcpl_id, dapl_id, H5_REQUEST_NULL))) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") - if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset") + + /* Get an atom for the dataset */ + if((ret_value = H5I_register2(H5I_DATASET, dset, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: - if(ret_value < 0) - if(dset && H5D_close(dset) < 0) + if (ret_value < 0 && dset) + if(H5VL_dataset_close (dset, vol_plugin, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") - FUNC_LEAVE_API(ret_value) } /* end H5Dcreate2() */ @@ -219,21 +249,17 @@ hid_t H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, hid_t dapl_id) { - H5G_loc_t loc; /* Object location to insert dataset into */ - H5D_t *dset = NULL; /* New dataset's info */ - const H5S_t *space; /* Dataspace for dataset */ + void *dset = NULL; /* dset token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; + H5P_genplist_t *plist; /* Property list pointer */ hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("i", "iiiii", loc_id, type_id, space_id, dcpl_id, dapl_id); /* Check arguments */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID") - if(H5I_DATATYPE != H5I_get_type(type_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype ID") - if(NULL == (space = (const H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace ID") if(H5P_DEFAULT == dcpl_id) dcpl_id = H5P_DATASET_CREATE_DEFAULT; else @@ -247,33 +273,39 @@ H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t dcpl_id, if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list") - /* build and open the new dataset */ - if(NULL == (dset = H5D__create(loc.oloc->file, type_id, space, dcpl_id, dapl_id, H5AC_dxpl_id))) + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* set creation properties */ + if(H5P_set(plist, H5VL_DSET_TYPE_ID, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5VL_DSET_SPACE_ID, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the dataset through the VOL */ + if(NULL == (dset = H5VL_dataset_create(obj, loc_params, vol_plugin, NULL, dcpl_id, dapl_id, H5_REQUEST_NULL))) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") - /* Register the new dataset to get an ID for it */ - if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset") + /* Get an atom for the dataset */ + if((ret_value = H5I_register2(H5I_DATASET, dset, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: - /* Release the dataset's object header, if it was created */ - if(dset) { - H5O_loc_t *oloc; /* Object location for dataset */ - - /* Get the new dataset's object location */ - if(NULL == (oloc = H5D_oloc(dset))) - HDONE_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get object location of dataset") - - /* Decrement refcount on dataset's object header in memory */ - if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object") - } /* end if */ - - /* Cleanup on failure */ - if(ret_value < 0) - if(dset && H5D_close(dset) < 0) + if (ret_value < 0 && dset) + if(H5VL_dataset_close (dset, vol_plugin, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") - FUNC_LEAVE_API(ret_value) } /* end H5Dcreate_anon() */ @@ -298,22 +330,16 @@ done: hid_t H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id) { - H5D_t *dset = NULL; - H5G_loc_t loc; /* Object location of group */ - H5G_loc_t dset_loc; /* Object location of dataset */ - H5G_name_t path; /* Dataset group hier. path */ - H5O_loc_t oloc; /* Dataset object location */ - H5O_type_t obj_type; /* Type of object at location */ - hbool_t loc_found = FALSE; /* Location at 'name' found */ - hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datset */ + void *dset = NULL; /* dset token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE3("i", "i*si", loc_id, name, dapl_id); /* Check args */ - 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") @@ -324,42 +350,29 @@ H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id) if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list") - /* Set up dataset location to fill in */ - dset_loc.oloc = &oloc; - dset_loc.path = &path; - H5G_loc_reset(&dset_loc); + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); - /* Find the dataset object */ - if(H5G_loc_find(&loc, name, &dset_loc, dapl_id, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found") - loc_found = TRUE; + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* Check that the object found is the correct type */ - if(H5O_obj_type(&oloc, &obj_type, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get object type") - if(obj_type != H5O_TYPE_DATASET) - HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Open the dataset */ - if(NULL == (dset = H5D_open(&dset_loc, dapl_id, dxpl_id))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset") + /* Create the dataset through the VOL */ + if(NULL == (dset = H5VL_dataset_open(obj, loc_params, vol_plugin, name, dapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") - /* Register an atom for the dataset */ - if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't register dataset atom") + /* Get an atom for the dataset */ + if((ret_value = H5I_register2(H5I_DATASET, dset, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: - if(ret_value < 0) { - if(dset) { - if(H5D_close(dset) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") - } /* end if */ - else { - if(loc_found && H5G_loc_free(&dset_loc) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't free location") - } /* end else */ - } /* end if */ - + if (ret_value < 0 && dset) + if(H5VL_dataset_close (dset, vol_plugin, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* end H5Dopen2() */ @@ -386,9 +399,9 @@ H5Dclose(hid_t dset_id) FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", dset_id); - /* Check args */ - if(NULL == H5I_object_verify(dset_id, H5I_DATASET)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + /* Check/fix arguments. */ + if(H5I_DATASET != H5I_get_type(dset_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset ID") /* * Decrement the counter on the dataset. It will be freed if the count @@ -401,6 +414,12 @@ H5Dclose(hid_t dset_id) if(H5I_dec_app_ref_always_close(dset_id) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID") +#if 0 + /* Close the dataset through the VOL */ + if((ret_value = H5VL_dataset_close(dset_id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to close dataset") +#endif + done: FUNC_LEAVE_API(ret_value) } /* end H5Dclose() */ @@ -425,33 +444,24 @@ done: hid_t H5Dget_space(hid_t dset_id) { - H5D_t *dset = NULL; - H5S_t *space = NULL; - hid_t ret_value; + H5VL_t *vol_plugin; + void *dset; + hid_t ret_value = FAIL; FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", dset_id); - /* Check args */ - if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") - - /* Read the data space message and return a data space object */ - if(NULL == (space = H5S_copy(dset->shared->space, FALSE, TRUE))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get data space") - - /* Create an atom */ - if((ret_value = H5I_register (H5I_DATASPACE, space, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (dset = (void *)H5I_object(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + /* get the dataspace through the VOL */ + if(H5VL_dataset_get(dset, vol_plugin, H5VL_DATASET_GET_SPACE, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get data space") done: - if(ret_value < 0) { - if(space!=NULL) { - if(H5S_close(space) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace") - } /* end if */ - } /* end if */ - FUNC_LEAVE_API(ret_value) } @@ -473,19 +483,23 @@ done: herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation) { - H5D_t *dset = NULL; + H5VL_t *vol_plugin; + void *dset; herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*Ds", dset_id, allocation); - /* Check arguments */ - if(NULL==(dset=(H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (dset = (void *)H5I_object(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") - /* Read data space address and return */ - if(H5D__get_space_status(dset, allocation, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get space status") + /* Read data space address through the VOL and return */ + if((ret_value=H5VL_dataset_get(dset, vol_plugin, H5VL_DATASET_GET_SPACE_STATUS, H5_REQUEST_NULL, allocation)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get space status") done: FUNC_LEAVE_API(ret_value) @@ -511,44 +525,25 @@ done: hid_t H5Dget_type(hid_t dset_id) { - - H5D_t *dset; /* Dataset */ - H5T_t *dt = NULL; /* Datatype to return */ - hid_t ret_value; /* Return value */ + H5VL_t *vol_plugin; + void *dset; + hid_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", dset_id); - /* Check args */ - if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") - - /* Patch the datatype's "top level" file pointer */ - if(H5T_patch_file(dset->shared->type, dset->oloc.file) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to patch datatype's file pointer") - - /* Copy the dataset's datatype */ - if(NULL == (dt = H5T_copy(dset->shared->type, H5T_COPY_REOPEN))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy datatype") - - /* Mark any datatypes as being in memory now */ - if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (dset = (void *)H5I_object(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") - /* Lock copied type */ - if(H5T_lock(dt, FALSE) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to lock transient datatype") - - /* Create an atom */ - if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype") + /* get the datatype through the VOL */ + if(H5VL_dataset_get(dset, vol_plugin, H5VL_DATASET_GET_TYPE, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get datatype") done: - if(ret_value < 0) { - if(dt && H5T_close(dt) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype") - } /* end if */ - FUNC_LEAVE_API(ret_value) } /* end H5Dget_type() */ @@ -572,104 +567,24 @@ done: hid_t H5Dget_create_plist(hid_t dset_id) { - H5D_t *dset; /* Dataset structure */ - H5P_genplist_t *dcpl_plist; /* Dataset's DCPL */ - H5P_genplist_t *new_plist; /* Copy of dataset's DCPL */ - H5O_fill_t copied_fill; /* Fill value to tweak */ - hid_t new_dcpl_id = FAIL; - hid_t ret_value; /* Return value */ + H5VL_t *vol_plugin; + void *dset; + hid_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", dset_id); - /* Check args */ - if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") - if(NULL == (dcpl_plist = (H5P_genplist_t *)H5I_object(dset->shared->dcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") - - /* Copy the creation property list */ - if((new_dcpl_id = H5P_copy_plist(dcpl_plist, TRUE)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to copy the creation property list") - if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_dcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") - - /* Retrieve any object creation properties */ - if(H5O_get_create_plist(&dset->oloc, H5AC_ind_dxpl_id, new_plist) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get object creation info") - - /* Get the fill value property */ - if(H5P_get(new_plist, H5D_CRT_FILL_VALUE_NAME, &copied_fill) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value") - - /* Check if there is a fill value, but no type yet */ - if(copied_fill.buf != NULL && copied_fill.type == NULL) { - H5T_path_t *tpath; /* Conversion information*/ - - /* Copy the dataset type into the fill value message */ - if(NULL == (copied_fill.type = H5T_copy(dset->shared->type, H5T_COPY_TRANSIENT))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy dataset datatype for fill value") - - /* Set up type conversion function */ - if(NULL == (tpath = H5T_path_find(dset->shared->type, copied_fill.type, NULL, NULL, H5AC_ind_dxpl_id, FALSE))) - HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types") - - /* Convert disk form of fill value into memory form */ - if(!H5T_path_noop(tpath)) { - hid_t dst_id, src_id; /* Source & destination datatypes for type conversion */ - uint8_t *bkg_buf = NULL; /* Background conversion buffer */ - size_t bkg_size; /* Size of background buffer */ - - /* Wrap copies of types to convert */ - dst_id = H5I_register(H5I_DATATYPE, H5T_copy(copied_fill.type, H5T_COPY_TRANSIENT), FALSE); - if(dst_id < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register datatype") - src_id = H5I_register(H5I_DATATYPE, H5T_copy(dset->shared->type, H5T_COPY_ALL), FALSE); - if(src_id < 0) { - H5I_dec_ref(dst_id); - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register datatype") - } /* end if */ - - /* Allocate a background buffer */ - bkg_size = MAX(H5T_GET_SIZE(copied_fill.type), H5T_GET_SIZE(dset->shared->type)); - if(H5T_path_bkg(tpath) && NULL == (bkg_buf = H5FL_BLK_CALLOC(type_conv, bkg_size))) { - H5I_dec_ref(src_id); - H5I_dec_ref(dst_id); - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - } /* end if */ - - /* Convert fill value */ - if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, copied_fill.buf, bkg_buf, H5AC_ind_dxpl_id) < 0) { - H5I_dec_ref(src_id); - H5I_dec_ref(dst_id); - if(bkg_buf) - bkg_buf = H5FL_BLK_FREE(type_conv, bkg_buf); - HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "datatype conversion failed") - } /* end if */ - - /* Release local resources */ - if(H5I_dec_ref(src_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to close temporary object") - if(H5I_dec_ref(dst_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to close temporary object") - if(bkg_buf) - bkg_buf = H5FL_BLK_FREE(type_conv, bkg_buf); - } /* end if */ - } /* end if */ - - /* Set back the fill value property to property list */ - if(H5P_set(new_plist, H5D_CRT_FILL_VALUE_NAME, &copied_fill) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set property list fill value") - - /* Set the return value */ - ret_value = new_dcpl_id; + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (dset = (void *)H5I_object(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") -done: - if(ret_value < 0) - if(new_dcpl_id > 0) - if(H5I_dec_app_ref(new_dcpl_id) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to close temporary object") + if(H5VL_dataset_get(dset, vol_plugin, H5VL_DATASET_GET_DCPL, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataset creation properties") +done: FUNC_LEAVE_API(ret_value) } /* end H5Dget_create_plist() */ @@ -710,45 +625,23 @@ done: hid_t H5Dget_access_plist(hid_t dset_id) { - H5D_t *dset; /* Dataset structure */ - H5P_genplist_t *old_plist; /* Default DAPL */ - H5P_genplist_t *new_plist; /* New DAPL */ - hid_t new_dapl_id = FAIL; - hid_t ret_value; /* Return value */ + H5VL_t *vol_plugin; + void *dset; + hid_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", dset_id); - /* Check args */ - if (NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") - - /* Make a copy of the default dataset access property list */ - if (NULL == (old_plist = (H5P_genplist_t *)H5I_object(H5P_LST_DATASET_ACCESS_g))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - if ((new_dapl_id = H5P_copy_plist(old_plist, TRUE)) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "can't copy dataset access property list") - if (NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_dapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - - /* If the dataset is chunked then copy the rdcc parameters */ - if (dset->shared->layout.type == H5D_CHUNKED) { - if (H5P_set(new_plist, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(dset->shared->cache.chunk.nslots)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache number of slots") - if (H5P_set(new_plist, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(dset->shared->cache.chunk.nbytes_max)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache byte size") - if (H5P_set(new_plist, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, &(dset->shared->cache.chunk.w0)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set preempt read chunks") - } /* end if */ - - /* Set the return value */ - ret_value = new_dapl_id; + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (dset = (void *)H5I_object(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + if(H5VL_dataset_get(dset, vol_plugin, H5VL_DATASET_GET_DAPL, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get dataset access properties") done: - if(ret_value < 0) - if(new_dapl_id >= 0) - if(H5I_dec_app_ref(new_dapl_id) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to close temporary object") FUNC_LEAVE_API(ret_value) } /* end H5Dget_access_plist() */ @@ -775,19 +668,23 @@ done: hsize_t H5Dget_storage_size(hid_t dset_id) { - H5D_t *dset; /* Dataset to query */ + H5VL_t *vol_plugin; + void *dset; hsize_t ret_value; /* Return value */ FUNC_ENTER_API(0) H5TRACE1("h", "i", dset_id); - /* Check args */ - if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a dataset") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (dset = (void *)H5I_object(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "invalid dataset identifier") - /* Set return value */ - if(H5D__get_storage_size(dset, H5AC_ind_dxpl_id, &ret_value) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, 0, "can't get size of dataset's storage") + /* get storage size through the VOL */ + if(H5VL_dataset_get(dset, vol_plugin, H5VL_DATASET_GET_STORAGE_SIZE, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, 0, "unable to get storage size") done: FUNC_LEAVE_API(ret_value) @@ -811,18 +708,23 @@ done: haddr_t H5Dget_offset(hid_t dset_id) { - H5D_t *dset; /* Dataset to query */ + H5VL_t *vol_plugin; + void *dset; haddr_t ret_value; /* Return value */ FUNC_ENTER_API(HADDR_UNDEF) H5TRACE1("a", "i", dset_id); - /* Check args */ - if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a dataset") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (dset = (void *)H5I_object(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "invalid dataset identifier") - /* Set return value */ - ret_value = H5D__get_offset(dset); + /* get offset through the VOL */ + if(H5VL_dataset_get(dset, vol_plugin, H5VL_DATASET_GET_OFFSET, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, HADDR_UNDEF, "unable to get offset") done: FUNC_LEAVE_API(ret_value) @@ -942,7 +844,8 @@ H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf) H5TRACE4("e", "iii*x", type_id, space_id, plist_id, buf); /* Check args */ - if(H5I_DATATYPE != H5I_get_type(type_id) || buf == NULL) + if((H5I_DATATYPE != H5I_get_type(type_id)) || + buf == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace") @@ -1004,7 +907,7 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, /* Check args */ if(H5I_DATASET != H5I_get_type(dataset_id) || - H5I_DATATYPE != H5I_get_type(type_id) || size == NULL) + (H5I_DATATYPE != H5I_get_type(type_id)) || size == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace") @@ -1014,9 +917,23 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, /* Save the dataset ID */ vlen_bufsize.dataset_id = dataset_id; - /* Get a copy of the dataspace ID */ if((vlen_bufsize.fspace_id = H5Dget_space(dataset_id)) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy dataspace") +#if 0 + { + H5VL_t *vol_plugin; + void *dset; + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dataset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (dset = (void *)H5I_object(dataset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + /* Get a copy of the dataspace ID */ + if(H5VL_dataset_get(dset, vol_plugin, H5VL_DATASET_GET_SPACE, H5_REQUEST_NULL, &(vlen_bufsize.fspace_id)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy dataspace") + } +#endif /* Create a scalar for the memory dataspace */ if((vlen_bufsize.mspace_id = H5Screate(H5S_SCALAR)) < 0) @@ -1086,23 +1003,57 @@ done: herr_t H5Dset_extent(hid_t dset_id, const hsize_t size[]) { - H5D_t *dset; /* Dataset for this operation */ + H5VL_t *vol_plugin; + void *dset; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*h", dset_id, size); - /* Check args */ - if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") if(!size) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no size specified") - /* Private function */ - if(H5D__set_extent(dset, size, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extend dataset") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (dset = (void *)H5I_object(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + + /* set the extent through the VOL */ + if((ret_value = H5VL_dataset_set_extent(dset, vol_plugin, size, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extent of dataset") done: FUNC_LEAVE_API(ret_value) } /* end H5Dset_extent() */ + +/*------------------------------------------------------------------------- + * Function: H5D_close_dataset + * + * Purpose: Called when the ref count reaches zero on the dataset_id + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * June 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_close_dataset(void *dset, H5VL_t *vol_plugin) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Close the dataset through the VOL*/ + if((ret_value = H5VL_dataset_close(dset, vol_plugin, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to close dataset") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_close_dataset() */ diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index 1999550..15dc409 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -44,7 +44,7 @@ #include "H5Dpkg.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Iprivate.h" /* IDs */ - +#include "H5VLprivate.h" /* VOL plugins */ /****************/ /* Local Macros */ @@ -141,42 +141,59 @@ hid_t H5Dcreate1(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t dcpl_id) { - H5G_loc_t loc; /* Object location to insert dataset into */ - H5D_t *dset = NULL; /* New dataset's info */ - const H5S_t *space; /* Dataspace for dataset */ + void *dset = NULL; /* dset token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; + H5P_genplist_t *plist; /* Property list pointer */ + hid_t lcpl_id = H5P_LINK_CREATE_DEFAULT; hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("i", "i*siii", loc_id, name, type_id, space_id, dcpl_id); - /* Check arguments */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID") - if(!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") - if(H5I_DATATYPE != H5I_get_type(type_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype ID") - if(NULL == (space = (const H5S_t *)H5I_object_verify(space_id,H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace ID") if(H5P_DEFAULT == dcpl_id) dcpl_id = H5P_DATASET_CREATE_DEFAULT; else if(TRUE != H5P_isa_class(dcpl_id, H5P_DATASET_CREATE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list ID") - /* Build and open the new dataset */ - if(NULL == (dset = H5D__create_named(&loc, name, type_id, space, H5P_LINK_CREATE_DEFAULT, dcpl_id, H5P_DATASET_ACCESS_DEFAULT, H5AC_dxpl_id))) + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* set creation properties */ + if(H5P_set(plist, H5VL_DSET_TYPE_ID, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for datatype id") + if(H5P_set(plist, H5VL_DSET_SPACE_ID, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for space id") + if(H5P_set(plist, H5VL_DSET_LCPL_ID, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for lcpl id") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the dataset through the VOL */ + if(NULL == (dset = H5VL_dataset_create(obj, loc_params, vol_plugin, name, dcpl_id, + H5P_DATASET_ACCESS_DEFAULT, H5_REQUEST_NULL))) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") - /* Register the new dataset to get an ID for it */ - if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset") + /* Get an atom for the dataset */ + if((ret_value = H5I_register2(H5I_DATASET, dset, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: - if(ret_value < 0) - if(dset && H5D_close(dset) < 0) + if (ret_value < 0 && dset) + if(H5VL_dataset_close (dset, vol_plugin, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") - FUNC_LEAVE_API(ret_value) } /* end H5Dcreate1() */ @@ -201,62 +218,43 @@ done: hid_t H5Dopen1(hid_t loc_id, const char *name) { - H5D_t *dset = NULL; - H5G_loc_t loc; /* Object location of group */ - H5G_loc_t dset_loc; /* Object location of dataset */ - H5G_name_t path; /* Dataset group hier. path */ - H5O_loc_t oloc; /* Dataset object location */ - H5O_type_t obj_type; /* Type of object at location */ - hbool_t loc_found = FALSE; /* Location at 'name' found */ + void *dset = NULL; /* dset token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t dapl_id = H5P_DATASET_ACCESS_DEFAULT; /* dapl to use to open dataset */ - hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datset */ hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE2("i", "i*s", loc_id, name); /* Check args */ - 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") - /* Set up dataset location to fill in */ - dset_loc.oloc = &oloc; - dset_loc.path = &path; - H5G_loc_reset(&dset_loc); + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); - /* Find the dataset object */ - if(H5G_loc_find(&loc, name, &dset_loc, H5P_DEFAULT, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found") - loc_found = TRUE; + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* Check that the object found is the correct type */ - if(H5O_obj_type(&oloc, &obj_type, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get object type") - if(obj_type != H5O_TYPE_DATASET) - HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Open the dataset */ - if(NULL == (dset = H5D_open(&dset_loc, dapl_id, dxpl_id))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset") + /* Create the dataset through the VOL */ + if(NULL == (dset = H5VL_dataset_open(obj, loc_params, vol_plugin, name, dapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") - /* Register an atom for the dataset */ - if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't register dataset atom") + /* Get an atom for the dataset */ + if((ret_value = H5I_register2(H5I_DATASET, dset, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: - if(ret_value < 0) { - if(dset != NULL) { - if(H5D_close(dset) < 0) - HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") - } /* end if */ - else { - if(loc_found && H5G_loc_free(&dset_loc) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") - } /* end else */ - } /* end if */ - + if (ret_value < 0 && dset) + if(H5VL_dataset_close (dset, vol_plugin, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* end H5Dopen1() */ diff --git a/src/H5Dint.c b/src/H5Dint.c index f313e52..402ff8d 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -34,7 +34,8 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ - +#include "H5VLnative.h" /* Native Plugin */ +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ /* Local Macros */ @@ -103,6 +104,9 @@ H5FL_BLK_EXTERN(sieve_buf); /* Declare the external free list to manage the H5D_chunk_info_t struct */ H5FL_EXTERN(H5D_chunk_info_t); +/* Declare extern the free list to manage blocks of type conversion data */ +H5FL_BLK_EXTERN(type_conv); + /* Define a static "default" dataset structure to use to initialize new datasets */ static H5D_shared_t H5D_def_dset; @@ -112,7 +116,8 @@ static const H5I_class_t H5I_DATASET_CLS[1] = {{ 0, /* Class flags */ 64, /* Minimum hash size for class */ 0, /* # of reserved IDs for class */ - (H5I_free_t)H5D_close /* Callback routine for closing objects of this class */ + NULL, /* Callback routine for closing objects of this class */ + (H5I_free2_t)H5D_close_dataset /* Callback routine for closing auxilary objects of this class */ }}; @@ -915,7 +920,7 @@ H5D_t * H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, hid_t dapl_id, hid_t dxpl_id) { - const H5T_t *type; /* Datatype for dataset */ + const H5T_t *type, *dt; /* Datatype for dataset */ H5D_t *new_dset = NULL; H5P_genplist_t *dc_plist = NULL; /* New Property list */ hbool_t has_vl_type = FALSE; /* Flag to indicate a VL-type for dataset */ @@ -933,9 +938,13 @@ H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, HDassert(H5I_GENPROP_LST == H5I_get_type(dxpl_id)); /* Get the dataset's datatype */ - if(NULL == (type = (const H5T_t *)H5I_object(type_id))) + if(NULL == (dt = (const H5T_t *)H5I_object(type_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a datatype") + /* Get the actual datatype object if this is a named datatype */ + if(NULL == (type = (const H5T_t *)H5T_get_named_type(dt))) + type = dt; + /* Check if the datatype is "sensible" for use in a dataset */ if(H5T_is_sensible(type) != TRUE) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "datatype is not sensible") @@ -2451,3 +2460,278 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_flush() */ + +/*------------------------------------------------------------------------- + * Function: H5D_get_create_plist + * + * Purpose: Returns a copy of the dataset creation property list. + * + * Return: Success: ID for a copy of the dataset creation + * property list. + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5D_get_create_plist(H5D_t *dset) +{ + H5P_genplist_t *dcpl_plist; /* Dataset's DCPL */ + H5P_genplist_t *new_plist; /* Copy of dataset's DCPL */ + H5O_fill_t copied_fill; /* Fill value to tweak */ + hid_t new_id = FAIL; + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Check args */ + if(NULL == (dcpl_plist = (H5P_genplist_t *)H5I_object(dset->shared->dcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") + + /* Copy the creation property list */ + if((new_id = H5P_copy_plist(dcpl_plist, TRUE)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to copy the creation property list") + if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") + + /* Retrieve any object creation properties */ + if(H5O_get_create_plist(&dset->oloc, H5AC_ind_dxpl_id, new_plist) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get object creation info") + + /* Get the fill value property */ + if(H5P_get(new_plist, H5D_CRT_FILL_VALUE_NAME, &copied_fill) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fill value") + + /* Check if there is a fill value, but no type yet */ + if(copied_fill.buf != NULL && copied_fill.type == NULL) { + H5T_path_t *tpath; /* Conversion information*/ + + /* Copy the dataset type into the fill value message */ + if(NULL == (copied_fill.type = H5T_copy(dset->shared->type, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy dataset datatype for fill value") + + /* Set up type conversion function */ + if(NULL == (tpath = H5T_path_find(dset->shared->type, copied_fill.type, NULL, NULL, H5AC_ind_dxpl_id, FALSE))) + HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types") + + /* Convert disk form of fill value into memory form */ + if(!H5T_path_noop(tpath)) { + hid_t dst_id, src_id; /* Source & destination datatypes for type conversion */ + uint8_t *bkg_buf = NULL; /* Background conversion buffer */ + size_t bkg_size; /* Size of background buffer */ + + /* Wrap copies of types to convert */ + dst_id = H5I_register(H5I_DATATYPE, H5T_copy(copied_fill.type, H5T_COPY_TRANSIENT), FALSE); + if(dst_id < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register datatype") + src_id = H5I_register(H5I_DATATYPE, H5T_copy(dset->shared->type, H5T_COPY_ALL), FALSE); + if(src_id < 0) { + H5I_dec_ref(dst_id); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy/register datatype") + } /* end if */ + + /* Allocate a background buffer */ + bkg_size = MAX(H5T_GET_SIZE(copied_fill.type), H5T_GET_SIZE(dset->shared->type)); + if(H5T_path_bkg(tpath) && NULL == (bkg_buf = H5FL_BLK_CALLOC(type_conv, bkg_size))) { + H5I_dec_ref(src_id); + H5I_dec_ref(dst_id); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + } /* end if */ + + /* Convert fill value */ + if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, copied_fill.buf, bkg_buf, H5AC_ind_dxpl_id) < 0) { + H5I_dec_ref(src_id); + H5I_dec_ref(dst_id); + if(bkg_buf) + bkg_buf = H5FL_BLK_FREE(type_conv, bkg_buf); + HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "datatype conversion failed") + } /* end if */ + + /* Release local resources */ + if(H5I_dec_ref(src_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to close temporary object") + if(H5I_dec_ref(dst_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to close temporary object") + if(bkg_buf) + bkg_buf = H5FL_BLK_FREE(type_conv, bkg_buf); + } /* end if */ + } /* end if */ + + /* Set back the fill value property to property list */ + if(H5P_set(new_plist, H5D_CRT_FILL_VALUE_NAME, &copied_fill) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set property list fill value") + + /* Set the return value */ + ret_value = new_id; + +done: + if(ret_value < 0) { + if(new_id > 0) + if(H5I_dec_app_ref(new_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't free") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_get_create_plist() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_get_access_plist + * + * Purpose: Returns a copy of the dataset access property list. + * + * Return: Success: ID for a copy of the dataset access + * property list. + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5D_get_access_plist(H5D_t *dset) +{ + H5P_genplist_t *old_plist; /* Default DAPL */ + H5P_genplist_t *new_plist; /* New DAPL */ + hid_t new_id = FAIL; + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Make a copy of the default dataset access property list */ + if (NULL == (old_plist = (H5P_genplist_t *)H5I_object(H5P_LST_DATASET_ACCESS_g))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + if ((new_id = H5P_copy_plist(old_plist, TRUE)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "can't copy dataset access property list") + if (NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + /* If the dataset is chunked then copy the rdcc parameters */ + if (dset->shared->layout.type == H5D_CHUNKED) { + if (H5P_set(new_plist, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(dset->shared->cache.chunk.nslots)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache number of slots") + if (H5P_set(new_plist, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(dset->shared->cache.chunk.nbytes_max)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache byte size") + if (H5P_set(new_plist, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, &(dset->shared->cache.chunk.w0)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set preempt read chunks") + } /* end if */ + + /* Set the return value */ + ret_value = new_id; + +done: + if(ret_value < 0) { + if(new_id > 0) + if(H5I_dec_app_ref(new_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't free") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_get_access_plist() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_get_space + * + * Purpose: Returns and ID for the dataspace of the dataset. + * + * Return: Success: ID for dataspace + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5D_get_space(H5D_t *dset) +{ + H5S_t *space = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Read the data space message and return a data space object */ + if(NULL == (space = H5S_copy(dset->shared->space, FALSE, TRUE))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get data space") + + /* Create an atom */ + if((ret_value = H5I_register (H5I_DATASPACE, space, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space") + +done: + if(ret_value < 0) { + if(space!=NULL) { + if(H5S_close(space) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace") + } /* end if */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_get_space() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_get_type + * + * Purpose: Returns and ID for the datatype of the dataset. + * + * Return: Success: ID for datatype + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5D_get_type(H5D_t *dset) +{ + H5T_t *dt = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Patch the datatype's "top level" file pointer */ + if(H5T_patch_file(dset->shared->type, dset->oloc.file) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to patch datatype's file pointer") + + /* Copy the dataset's datatype */ + if(NULL == (dt = H5T_copy(dset->shared->type, H5T_COPY_REOPEN))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy datatype") + + /* Mark any datatypes as being in memory now */ + if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location") + + /* Lock copied type */ + if(H5T_lock(dt, FALSE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to lock transient datatype") + + /* Create an atom */ + if(H5T_committed(dt)) { + /* If this is a committed datatype, we need to recreate the + two level IDs, where the VOL object is a copy of the + returned datatype */ + if((ret_value = H5VL_native_register(H5I_DATATYPE, dt, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype") + } + else { + if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype") + } +done: + if(ret_value < 0) { + if(dt && H5T_close(dt) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_get_type() */ diff --git a/src/H5Dio.c b/src/H5Dio.c index df1c4a3..e08e079 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -30,6 +30,7 @@ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Sprivate.h" /* Dataspace */ +#include "H5VLprivate.h" /* VOL plugins */ #ifdef H5_HAVE_PARALLEL /* Remove this if H5R_DATASET_REGION is no longer used in this file */ @@ -51,16 +52,6 @@ /* Local Prototypes */ /********************/ -/* Internal I/O routines */ -static herr_t H5D__read(H5D_t *dataset, hid_t mem_type_id, - const H5S_t *mem_space, const H5S_t *file_space, hid_t dset_xfer_plist, - void *buf/*out*/); -static herr_t H5D__write(H5D_t *dataset, hid_t mem_type_id, - const H5S_t *mem_space, const H5S_t *file_space, hid_t dset_xfer_plist, - const void *buf); -static herr_t H5D__pre_write(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, - hid_t file_space_id, hid_t dxpl_id, const void *buf); - /* Setup/teardown routines */ static herr_t H5D__ioinfo_init(H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id, const H5D_type_info_t *type_info, H5D_storage_t *store, @@ -125,62 +116,37 @@ herr_t H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, void *buf/*out*/) { - H5D_t *dset = NULL; - const H5S_t *mem_space = NULL; - const H5S_t *file_space = NULL; - char fake_char; - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_t *vol_plugin; + void *dset; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iiiiix", dset_id, mem_type_id, mem_space_id, file_space_id, plist_id, buf); - /* check arguments */ - if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") - if(NULL == dset->oloc.file) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") - if(mem_space_id < 0 || file_space_id < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") - if(H5S_ALL != mem_space_id) { - if(NULL == (mem_space = (const H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") - - /* Check for valid selection */ - if(H5S_SELECT_VALID(mem_space) != TRUE) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent") - } /* end if */ - if(H5S_ALL != file_space_id) { - if(NULL == (file_space = (const H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") - - /* Check for valid selection */ - if(H5S_SELECT_VALID(file_space) != TRUE) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent") - } /* end if */ - /* Get the default dataset transfer property list if the user didn't provide one */ if (H5P_DEFAULT == plist_id) plist_id= H5P_DATASET_XFER_DEFAULT; else if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_XFER)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") - if(!buf && (NULL == file_space || H5S_GET_SELECT_NPOINTS(file_space) != 0)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer") - /* If the buffer is nil, and 0 element is selected, make a fake buffer. - * This is for some MPI package like ChaMPIon on NCSA's tungsten which - * doesn't support this feature. - */ - if(!buf) - buf = &fake_char; + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (dset = (void *)H5I_object(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") - /* read raw data */ - if(H5D__read(dset, mem_type_id, mem_space, file_space, plist_id, buf/*out*/) < 0) + /* Read the data through the VOL */ + if((ret_value = H5VL_dataset_read(dset, vol_plugin, mem_type_id, mem_space_id, + file_space_id, plist_id, buf, H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") + done: FUNC_LEAVE_API(ret_value) } /* end H5Dread() */ @@ -221,17 +187,36 @@ herr_t H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t dxpl_id, const void *buf) { - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_t *vol_plugin; + void *dset; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "iiiii*x", dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf); + /* check arguments */ if(!dset_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") - if(H5D__pre_write(dset_id, mem_type_id, mem_space_id, file_space_id, dxpl_id, buf) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't prepare for writing data") + /* Get the default dataset transfer property list if the user didn't provide one */ + if(H5P_DEFAULT == dxpl_id) + dxpl_id= H5P_DATASET_XFER_DEFAULT; + else + if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms") + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (dset = (void *)H5I_object(dset_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") + + /* Write the data through the VOL */ + if((ret_value = H5VL_dataset_write(dset, vol_plugin, mem_type_id, mem_space_id, + file_space_id, dxpl_id, buf, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") done: FUNC_LEAVE_API(ret_value) @@ -250,22 +235,15 @@ done: * *------------------------------------------------------------------------- */ -static herr_t -H5D__pre_write(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, - hid_t file_space_id, hid_t dxpl_id, const void *buf) +herr_t +H5D__pre_write(H5D_t *dset, hid_t mem_type_id, const H5S_t *mem_space, + const H5S_t *file_space, hid_t dxpl_id, const void *buf) { - H5D_t *dset = NULL; H5P_genplist_t *plist; /* Property list pointer */ hbool_t direct_write = FALSE; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_STATIC - - /* check arguments */ - if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") - if(NULL == dset->oloc.file) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + FUNC_ENTER_PACKAGE /* Get the default dataset transfer property list if the user didn't provide one */ if(H5P_DEFAULT == dxpl_id) @@ -277,7 +255,6 @@ H5D__pre_write(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, /* Get the dataset transfer property list */ if(NULL == (plist = (H5P_genplist_t *)H5I_object(dxpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list") - if(H5P_get(plist, H5D_XFER_DIRECT_CHUNK_WRITE_FLAG_NAME, &direct_write) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "error getting flag for direct chunk write") @@ -327,40 +304,6 @@ H5D__pre_write(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id, if(H5D__chunk_direct_write(dset, dxpl_id, direct_filters, internal_offset, direct_datasize, buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write chunk directly") } else { /* Normal write */ - const H5S_t *mem_space = NULL; - const H5S_t *file_space = NULL; - char fake_char; - - if(mem_space_id < 0 || file_space_id < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") - - if(H5S_ALL != mem_space_id) { - if(NULL == (mem_space = (const H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") - - /* Check for valid selection */ - if(H5S_SELECT_VALID(mem_space) != TRUE) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "memory selection+offset not within extent") - } /* end if */ - if(H5S_ALL != file_space_id) { - if(NULL == (file_space = (const H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") - - /* Check for valid selection */ - if(H5S_SELECT_VALID(file_space) != TRUE) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "file selection+offset not within extent") - } /* end if */ - - if(!buf && (NULL == file_space || H5S_GET_SELECT_NPOINTS(file_space) != 0)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer") - - /* If the buffer is nil, and 0 element is selected, make a fake buffer. - * This is for some MPI package like ChaMPIon on NCSA's tungsten which - * doesn't support this feature. - */ - if(!buf) - buf = &fake_char; - /* write raw data */ if(H5D__write(dset, mem_type_id, mem_space, file_space, dxpl_id, buf) < 0) HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data") @@ -384,7 +327,7 @@ done: * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t *file_space, hid_t dxpl_id, void *buf/*out*/) { @@ -586,7 +529,7 @@ done: * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, const H5S_t *file_space, hid_t dxpl_id, const void *buf) { diff --git a/src/H5Doh.c b/src/H5Doh.c index abf76d0..2dab247 100644 --- a/src/H5Doh.c +++ b/src/H5Doh.c @@ -30,7 +30,8 @@ #include "H5FLprivate.h" /* Free lists */ #include "H5Iprivate.h" /* IDs */ #include "H5Opkg.h" /* Object headers */ - +#include "H5VLnative.h" /* Native Plugin */ +#include "H5VLprivate.h" /* VOL */ /****************/ /* Local Macros */ diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 1e2b91d..8baafe9 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -154,6 +154,15 @@ typedef struct H5D_copy_file_ud_t { /******************************/ /* Library Private Prototypes */ /******************************/ +/* Internal I/O routines */ +H5_DLL herr_t H5D__pre_write(H5D_t *dset, hid_t mem_type_id, const H5S_t *mem_space, + const H5S_t *file_space, hid_t dxpl_id, const void *buf); +H5_DLL herr_t H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, + const H5S_t *file_space, hid_t dset_xfer_plist, + void *buf/*out*/); +H5_DLL herr_t H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, + const H5S_t *file_space, hid_t dset_xfer_plist, + const void *buf); H5_DLL herr_t H5D_init(void); H5_DLL H5D_t *H5D_open(const H5G_loc_t *loc, hid_t dapl_id, hid_t dxpl_id); @@ -162,6 +171,10 @@ H5_DLL H5O_loc_t *H5D_oloc(H5D_t *dataset); H5_DLL H5G_name_t *H5D_nameof(H5D_t *dataset); H5_DLL H5T_t *H5D_typeof(const H5D_t *dset); H5_DLL herr_t H5D_flush(const H5F_t *f, hid_t dxpl_id); +H5_DLL hid_t H5D_get_access_plist(H5D_t *dset); +H5_DLL hid_t H5D_get_create_plist(H5D_t *dset); +H5_DLL hid_t H5D_get_space(H5D_t *dset); +H5_DLL hid_t H5D_get_type(H5D_t *dset); /* Functions that operate on vlen data */ H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id, @@ -125,7 +125,8 @@ static const H5I_class_t H5I_ERRCLS_CLS[1] = {{ 0, /* Class flags */ 64, /* Minimum hash size for class */ 0, /* # of reserved IDs for class */ - (H5I_free_t)H5E_unregister_class /* Callback routine for closing objects of this class */ + (H5I_free_t)H5E_unregister_class, /* Callback routine for closing objects of this class */ + NULL /* Callback routine for closing auxilary objects of this class */ }}; /* Error message ID class */ @@ -134,7 +135,8 @@ static const H5I_class_t H5I_ERRMSG_CLS[1] = {{ 0, /* Class flags */ 64, /* Minimum hash size for class */ 0, /* # of reserved IDs for class */ - (H5I_free_t)H5E_close_msg /* Callback routine for closing objects of this class */ + (H5I_free_t)H5E_close_msg, /* Callback routine for closing objects of this class */ + NULL /* Callback routine for closing auxilary objects of this class */ }}; /* Error stack ID class */ @@ -143,7 +145,8 @@ static const H5I_class_t H5I_ERRSTK_CLS[1] = {{ 0, /* Class flags */ 64, /* Minimum hash size for class */ 0, /* # of reserved IDs for class */ - (H5I_free_t)H5E_close_stack /* Callback routine for closing objects of this class */ + (H5I_free_t)H5E_close_stack,/* Callback routine for closing objects of this class */ + NULL /* Callback routine for closing auxilary objects of this class */ }}; diff --git a/src/H5Edefin.h b/src/H5Edefin.h index 2ae79e5..51a1f66 100644 --- a/src/H5Edefin.h +++ b/src/H5Edefin.h @@ -26,6 +26,7 @@ hid_t H5E_FILE_g = FAIL; /* File accessibilty */ hid_t H5E_SOHM_g = FAIL; /* Shared Object Header Messages */ hid_t H5E_SYM_g = FAIL; /* Symbol table */ hid_t H5E_VFL_g = FAIL; /* Virtual File Layer */ +hid_t H5E_VOL_g = FAIL; /* Virtual Object Layer */ hid_t H5E_INTERNAL_g = FAIL; /* Internal error (too specific to document in detail) */ hid_t H5E_BTREE_g = FAIL; /* B-Tree node */ hid_t H5E_REFERENCE_g = FAIL; /* References */ diff --git a/src/H5Einit.h b/src/H5Einit.h index a2eb02f..d62d6aa 100644 --- a/src/H5Einit.h +++ b/src/H5Einit.h @@ -49,6 +49,11 @@ if((msg = H5E_create_msg(cls, H5E_MAJOR, "Virtual File Layer"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_VFL_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_VOL_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Virtual Object Layer"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_VOL_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_INTERNAL_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Internal error (too specific to document in detail)"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h index ddfb1d3..eef9b2c 100644 --- a/src/H5Epubgen.h +++ b/src/H5Epubgen.h @@ -29,6 +29,7 @@ #define H5E_SOHM (H5OPEN H5E_SOHM_g) #define H5E_SYM (H5OPEN H5E_SYM_g) #define H5E_VFL (H5OPEN H5E_VFL_g) +#define H5E_VOL (H5OPEN H5E_VOL_g) #define H5E_INTERNAL (H5OPEN H5E_INTERNAL_g) #define H5E_BTREE (H5OPEN H5E_BTREE_g) #define H5E_REFERENCE (H5OPEN H5E_REFERENCE_g) @@ -61,6 +62,7 @@ H5_DLLVAR hid_t H5E_FILE_g; /* File accessibilty */ H5_DLLVAR hid_t H5E_SOHM_g; /* Shared Object Header Messages */ H5_DLLVAR hid_t H5E_SYM_g; /* Symbol table */ H5_DLLVAR hid_t H5E_VFL_g; /* Virtual File Layer */ +H5_DLLVAR hid_t H5E_VOL_g; /* Virtual Object Layer */ H5_DLLVAR hid_t H5E_INTERNAL_g; /* Internal error (too specific to document in detail) */ H5_DLLVAR hid_t H5E_BTREE_g; /* B-Tree node */ H5_DLLVAR hid_t H5E_REFERENCE_g; /* References */ diff --git a/src/H5Eterm.h b/src/H5Eterm.h index 6c621bc..ae1eb95 100644 --- a/src/H5Eterm.h +++ b/src/H5Eterm.h @@ -27,6 +27,7 @@ H5E_FILE_g= H5E_SOHM_g= H5E_SYM_g= H5E_VFL_g= +H5E_VOL_g= H5E_INTERNAL_g= H5E_BTREE_g= H5E_REFERENCE_g= @@ -20,27 +20,20 @@ #define H5F_PACKAGE /*suppress error about including H5Fpkg */ /* Interface initialization */ -#define H5_INTERFACE_INIT_FUNC H5F_init_interface +#define H5_INTERFACE_INIT_FUNC H5F__init_pub_interface /***********/ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5Aprivate.h" /* Attributes */ -#include "H5ACprivate.h" /* Metadata cache */ -#include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ -#include "H5FDprivate.h" /* File drivers */ -#include "H5Gprivate.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ -#include "H5MFprivate.h" /* File memory management */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ -#include "H5SMprivate.h" /* Shared Object Header Messages */ -#include "H5Tprivate.h" /* Datatypes */ - +#include "H5VLnative.h" /* Native Plugin */ +#include "H5VLprivate.h" /* VOL plugins */ /****************/ /* Local Macros */ @@ -50,70 +43,61 @@ /* Local Typedefs */ /******************/ -/* Struct only used by functions H5F_get_objects and H5F_get_objects_cb */ -typedef struct H5F_olist_t { - H5I_type_t obj_type; /* Type of object to look for */ - hid_t *obj_id_list; /* Pointer to the list of open IDs to return */ - size_t *obj_id_count; /* Number of open IDs */ - struct { - hbool_t local; /* Set flag for "local" file searches */ - union { - H5F_file_t *shared; /* Pointer to shared file to look inside */ - const H5F_t *file; /* Pointer to file to look inside */ - } ptr; - } file_info; - size_t list_index; /* Current index in open ID array */ - size_t max_index; /* Maximum # of IDs to put into array */ -} H5F_olist_t; - - -/********************/ -/* Package Typedefs */ -/********************/ - - /********************/ /* Local Prototypes */ /********************/ -static herr_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr); -static int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key); -static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, - H5FD_t *lf); -static herr_t H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, - const char *name, char ** /*out*/ actual_name); -static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush); -static herr_t H5F_close(H5F_t *f); - /*********************/ /* Package Variables */ /*********************/ - /*****************************/ /* Library Private Variables */ /*****************************/ - /*******************/ /* Local Variables */ /*******************/ -/* Declare a free list to manage the H5F_t struct */ -H5FL_DEFINE(H5F_t); - -/* Declare a free list to manage the H5F_file_t struct */ -H5FL_DEFINE(H5F_file_t); - /* File ID class */ static const H5I_class_t H5I_FILE_CLS[1] = {{ H5I_FILE, /* ID class value */ 0, /* Class flags */ 64, /* Minimum hash size for class */ 0, /* # of reserved IDs for class */ - (H5I_free_t)H5F_close /* Callback routine for closing objects of this class */ + NULL, /* Callback routine for closing objects of this class */ + (H5I_free2_t)H5F_close_file /* Callback routine for closing auxilary objects of this class */ }}; + +/*-------------------------------------------------------------------------- +NAME + H5F__init_pub_interface -- Initialize interface-specific information +USAGE + herr_t H5F__init_pub_interface() +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. (Just calls + H5F_init() currently). + +--------------------------------------------------------------------------*/ +static herr_t +H5F__init_pub_interface(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_STATIC + + /* + * Initialize the atom group for the file IDs. + */ + if(H5I_register_type(H5I_FILE_CLS) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to initialize interface") + + ret_value = H5F_init(); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F__init_pub_interface() */ /*------------------------------------------------------------------------- @@ -137,29 +121,7 @@ H5F_init(void) FUNC_ENTER_NOAPI(FAIL) /* FUNC_ENTER() does all the work */ -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_init() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_init_interface - * - * Purpose: Initialize interface-specific information. - * - * Return: Success: non-negative - * Failure: negative - * - * Programmer: Robb Matzke - * Friday, November 20, 1998 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_init_interface(void) -{ - herr_t ret_value = SUCCEED; /* Return value */ - +#if 0 FUNC_ENTER_NOAPI_NOINIT /* @@ -171,6 +133,11 @@ H5F_init_interface(void) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5F_init_interface() */ +#endif + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_init() */ /*------------------------------------------------------------------------- @@ -233,22 +200,22 @@ H5F_term_interface(void) hid_t H5Fget_create_plist(hid_t file_id) { - H5F_t *file; /* File info */ - H5P_genplist_t *plist; /* Property list */ - hid_t ret_value; /* Return value */ + H5VL_t *vol_plugin = NULL; + void *obj = NULL; + hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", file_id); - /* check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") - if(NULL == (plist = (H5P_genplist_t *)H5I_object(file->shared->fcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Create the property list object to return */ - if((ret_value = H5P_copy_plist(plist, TRUE)) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to copy file creation properties") + if(H5VL_file_get(obj, vol_plugin, H5VL_FILE_GET_FCPL, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file creation properties") done: FUNC_LEAVE_API(ret_value) @@ -279,19 +246,22 @@ done: hid_t H5Fget_access_plist(hid_t file_id) { - H5F_t *f; /* File info */ + H5VL_t *vol_plugin; + void *obj; hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", file_id); - /* Check args */ - if(NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Retrieve the file's access property list */ - if((ret_value = H5F_get_access_plist(f, TRUE)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file access property list") + if(H5VL_file_get(obj, vol_plugin, H5VL_FILE_GET_FAPL, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file creation properties") done: FUNC_LEAVE_API(ret_value) @@ -299,109 +269,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5F_get_access_plist - * - * Purpose: Returns a copy of the file access property list of the - * specified file. - * - * NOTE: Make sure that, if you are going to overwrite - * information in the copied property list that was - * previously opened and assigned to the property list, then - * you must close it before overwriting the values. - * - * Return: Success: Object ID for a copy of the file access - * property list. - * - * Failure: FAIL - * - * Programmer: Quincey Koziol - * Wednesday, May 25, 2005 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -hid_t -H5F_get_access_plist(H5F_t *f, hbool_t app_ref) -{ - H5P_genplist_t *new_plist; /* New property list */ - H5P_genplist_t *old_plist; /* Old property list */ - void *driver_info=NULL; - unsigned efc_size = 0; - hid_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(FAIL) - - /* Check args */ - HDassert(f); - - /* Make a copy of the default file access property list */ - if(NULL == (old_plist = (H5P_genplist_t *)H5I_object(H5P_LST_FILE_ACCESS_g))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - if((ret_value = H5P_copy_plist(old_plist, app_ref)) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "can't copy file access property list") - if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(ret_value))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - - /* Copy properties of the file access property list */ - if(H5P_set(new_plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial metadata cache resize config.") - if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache number of slots") - if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache byte size") - if(H5P_set(new_plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set preempt read chunks") - if(H5P_set(new_plist, H5F_ACS_ALIGN_THRHD_NAME, &(f->shared->threshold)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set alignment threshold") - if(H5P_set(new_plist, H5F_ACS_ALIGN_NAME, &(f->shared->alignment)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set alignment") - if(H5P_set(new_plist, H5F_ACS_GARBG_COLCT_REF_NAME, &(f->shared->gc_ref)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set garbage collect reference") - if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set metadata cache size") - if(H5P_set(new_plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't sieve buffer size") - if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'small data' cache size") - if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag") - if(f->shared->efc) - efc_size = H5F_efc_max_nfiles(f->shared->efc); - if(H5P_set(new_plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set elink file cache size") - - /* - * Since we're resetting the driver ID and info, close them if they - * exist in this new property list. - */ - if(H5P_facc_close(ret_value, NULL) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't free the old driver information") - - /* Increment the reference count on the driver ID and insert it into the property list */ - if(H5I_inc_ref(f->shared->lf->driver_id, FALSE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINC, FAIL, "unable to increment ref count on VFL driver") - if(H5P_set(new_plist, H5F_ACS_FILE_DRV_ID_NAME, &(f->shared->lf->driver_id)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file driver ID") - - /* Set the driver "info" in the property list */ - driver_info = H5FD_fapl_get(f->shared->lf); - if(driver_info != NULL && H5P_set(new_plist, H5F_ACS_FILE_DRV_INFO_NAME, &driver_info) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file driver info") - - /* Set the file close degree appropriately */ - if(f->shared->fc_degree == H5F_CLOSE_DEFAULT && H5P_set(new_plist, H5F_ACS_CLOSE_DEGREE_NAME, &(f->shared->lf->cls->fc_degree)) < 0) { - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree") - } else if(f->shared->fc_degree != H5F_CLOSE_DEFAULT && H5P_set(new_plist, H5F_ACS_CLOSE_DEGREE_NAME, &(f->shared->fc_degree)) < 0) { - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree") - } - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_access_plist() */ - - -/*------------------------------------------------------------------------- * Function: H5Fget_obj_count * * Purpose: Public function returning the number of opened object IDs @@ -417,61 +284,42 @@ done: ssize_t H5Fget_obj_count(hid_t file_id, unsigned types) { - H5F_t *f = NULL; /* File to query */ - size_t obj_count = 0; /* Number of opened objects */ - ssize_t ret_value; /* Return value */ + ssize_t ret_value = 0; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("Zs", "iIu", file_id, types); - /* Check arguments */ - if(file_id != (hid_t)H5F_OBJ_ALL && (NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id") if(0 == (types & H5F_OBJ_ALL)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type") - /* Perform the query */ - if(H5F_get_obj_count(f, types, TRUE, &obj_count) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_count failed") - - /* Set the return value */ - ret_value = (ssize_t)obj_count; - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Fget_obj_count() */ + if(file_id != (hid_t)H5F_OBJ_ALL) { + H5VL_t *vol_plugin; + void *obj; - -/*------------------------------------------------------------------------- - * Function: H5F_get_obj_count - * - * Purpose: Private function return the number of opened object IDs - * (files, datasets, groups, datatypes) in the same file. - * - * Return: SUCCEED on success, FAIL on failure. - * - * Programmer: Raymond Lu - * Wednesday, Dec 5, 2001 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref, size_t *obj_id_count_ptr) -{ - herr_t ret_value = SUCCEED; + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - FUNC_ENTER_NOAPI(FAIL) + if(H5VL_file_get(obj, vol_plugin, H5VL_FILE_GET_OBJ_COUNT, H5_REQUEST_NULL, types, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get object count in file(s)") + } + /* iterate over all open files and get the obj count for each */ + else { + H5F_trav_obj_cnt_t udata; - /* Sanity check */ - HDassert(obj_id_count_ptr); + udata.obj_count = &ret_value; + udata.types = types | H5F_OBJ_LOCAL; - /* Perform the query */ - if((ret_value = H5F_get_objects(f, types, 0, NULL, app_ref, obj_id_count_ptr)) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_objects failed") + if(H5I_iterate(H5I_FILE, H5F_get_obj_count_cb, &udata, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(1)") + } done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_obj_count() */ + FUNC_LEAVE_API(ret_value) +} /* end H5Fget_obj_count() */ /*------------------------------------------------------------------------- @@ -495,271 +343,46 @@ done: ssize_t H5Fget_obj_ids(hid_t file_id, unsigned types, size_t max_objs, hid_t *oid_list) { - H5F_t *f = NULL; /* File to query */ - size_t obj_id_count = 0; /* Number of open objects */ - ssize_t ret_value; /* Return value */ + ssize_t ret_value = 0; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("Zs", "iIuz*i", file_id, types, max_objs, oid_list); - /* Check arguments */ - if(file_id != (hid_t)H5F_OBJ_ALL && (NULL == (f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id") if(0 == (types & H5F_OBJ_ALL)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not an object type") HDassert(oid_list); - /* Perform the query */ - if(H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_id_count) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed") - - /* Set the return value */ - ret_value = (ssize_t)obj_id_count; - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Fget_obj_ids() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_obj_ids - * - * Purpose: Private function to return a list of opened object IDs. - * - * Return: Non-negative on success; can't fail. - * - * Programmer: Raymond Lu - * Wednesday, Dec 5, 2001 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref, size_t *obj_id_count_ptr) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity check */ - HDassert(obj_id_count_ptr); - - /* Perform the query */ - if((ret_value = H5F_get_objects(f, types, max_objs, oid_list, app_ref, obj_id_count_ptr)) < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_objects failed") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_obj_ids() */ - - -/*--------------------------------------------------------------------------- - * Function: H5F_get_objects - * - * Purpose: This function is called by H5F_get_obj_count or - * H5F_get_obj_ids to get number of object IDs and/or a - * list of opened object IDs (in return value). - * Return: Non-negative on success; Can't fail. - * - * Programmer: Raymond Lu - * Wednesday, Dec 5, 2001 - * - *--------------------------------------------------------------------------- - */ -static herr_t -H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr) -{ - size_t obj_id_count=0; /* Number of open IDs */ - H5F_olist_t olist; /* Structure to hold search results */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Sanity check */ - HDassert(obj_id_count_ptr); - - /* Set up search information */ - olist.obj_id_list = (max_index==0 ? NULL : obj_id_list); - olist.obj_id_count = &obj_id_count; - olist.list_index = 0; - olist.max_index = max_index; - - /* Determine if we are searching for local or global objects */ - if(types & H5F_OBJ_LOCAL) { - olist.file_info.local = TRUE; - olist.file_info.ptr.file = f; - } /* end if */ + /* Check arguments */ + if(file_id != (hid_t)H5F_OBJ_ALL) { + H5VL_t *vol_plugin; + void *obj; + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + if(H5VL_file_get(obj, vol_plugin, H5VL_FILE_GET_OBJ_IDS, H5_REQUEST_NULL, + types, max_objs, oid_list, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get object count in file(s)") + } + /* iterate over all open files and get the obj count for each */ else { - olist.file_info.local = FALSE; - olist.file_info.ptr.shared = f ? f->shared : NULL; - } /* end else */ - - /* Iterate through file IDs to count the number, and put their - * IDs on the object list. */ - if(types & H5F_OBJ_FILE) { - olist.obj_type = H5I_FILE; - if(H5I_iterate(H5I_FILE, H5F_get_objects_cb, &olist, app_ref) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(1)") - } /* end if */ + H5F_trav_obj_ids_t udata; - /* Search through dataset IDs to count number of datasets, and put their - * IDs on the object list */ - if(types & H5F_OBJ_DATASET) { - olist.obj_type = H5I_DATASET; - if(H5I_iterate(H5I_DATASET, H5F_get_objects_cb, &olist, app_ref) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(2)") - } /* end if */ - - /* Search through group IDs to count number of groups, and put their - * IDs on the object list */ - if(types & H5F_OBJ_GROUP) { - olist.obj_type = H5I_GROUP; - if(H5I_iterate(H5I_GROUP, H5F_get_objects_cb, &olist, app_ref) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(3)") - } /* end if */ - - /* Search through datatype IDs to count number of named datatypes, and put their - * IDs on the object list */ - if(types & H5F_OBJ_DATATYPE) { - olist.obj_type = H5I_DATATYPE; - if(H5I_iterate(H5I_DATATYPE, H5F_get_objects_cb, &olist, app_ref) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(4)") - } /* end if */ - - /* Search through attribute IDs to count number of attributes, and put their - * IDs on the object list */ - if(types & H5F_OBJ_ATTR) { - olist.obj_type = H5I_ATTR; - if(H5I_iterate(H5I_ATTR, H5F_get_objects_cb, &olist, app_ref) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(5)") - } /* end if */ - - /* Set the number of objects currently open */ - *obj_id_count_ptr = obj_id_count; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_objects() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_objects_cb - * - * Purpose: H5F_get_objects' callback function. It verifies if an - * object is in the file, and either count it or put its ID - * on the list. - * - * Return: TRUE if the array of object IDs is filled up. - * FALSE otherwise. - * - * Programmer: Raymond Lu - * Wednesday, Dec 5, 2001 - * - *------------------------------------------------------------------------- - */ -static int -H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) -{ - H5F_olist_t *olist = (H5F_olist_t *)key; /* Alias for search info */ - int ret_value = FALSE; /* Return value */ + udata.types = types | H5F_OBJ_LOCAL; + udata.max_objs = max_objs; + udata.oid_list = oid_list; + udata.obj_count = &ret_value; - FUNC_ENTER_NOAPI_NOINIT - - HDassert(obj_ptr); - HDassert(olist); - - /* Count file IDs */ - if(olist->obj_type == H5I_FILE) { - if((olist->file_info.local && - (!olist->file_info.ptr.file || (olist->file_info.ptr.file && (H5F_t*)obj_ptr == olist->file_info.ptr.file) )) - || (!olist->file_info.local && - ( !olist->file_info.ptr.shared || (olist->file_info.ptr.shared && ((H5F_t*)obj_ptr)->shared == olist->file_info.ptr.shared) ))) { - /* Add the object's ID to the ID list, if appropriate */ - if(olist->obj_id_list) { - olist->obj_id_list[olist->list_index] = obj_id; - olist->list_index++; - } - - /* Increment the number of open objects */ - if(olist->obj_id_count) - (*olist->obj_id_count)++; - - /* Check if we've filled up the array. Return TRUE only if - * we have filled up the array. Otherwise return FALSE(RET_VALUE is - * preset to FALSE) because H5I_iterate needs the return value of - * FALSE to continue the iteration. */ - if(olist->max_index>0 && olist->list_index>=olist->max_index) - HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */ - } - } /* end if */ - else { /* either count opened object IDs or put the IDs on the list */ - H5O_loc_t *oloc; /* Group entry info for object */ - - switch(olist->obj_type) { - case H5I_ATTR: - oloc = H5A_oloc((H5A_t *)obj_ptr); - break; - - case H5I_GROUP: - oloc = H5G_oloc((H5G_t *)obj_ptr); - break; - - case H5I_DATASET: - oloc = H5D_oloc((H5D_t *)obj_ptr); - break; - - case H5I_DATATYPE: - if(H5T_is_named((H5T_t*)obj_ptr)==TRUE) - oloc = H5T_oloc((H5T_t*)obj_ptr); - else - oloc = NULL; - break; - - case H5I_UNINIT: - case H5I_BADID: - case H5I_FILE: - case H5I_DATASPACE: - case H5I_REFERENCE: - case H5I_VFL: - case H5I_GENPROP_CLS: - case H5I_GENPROP_LST: - case H5I_ERROR_CLASS: - case H5I_ERROR_MSG: - case H5I_ERROR_STACK: - case H5I_NTYPES: - default: - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object") - } /* end switch */ - - if((olist->file_info.local && - ( (!olist->file_info.ptr.file && olist->obj_type == H5I_DATATYPE && H5T_is_immutable((H5T_t *)obj_ptr) == FALSE) - || (!olist->file_info.ptr.file && olist->obj_type != H5I_DATATYPE) - || (oloc && oloc->file == olist->file_info.ptr.file))) - || (!olist->file_info.local && - ((!olist->file_info.ptr.shared && olist->obj_type == H5I_DATATYPE && H5T_is_immutable((H5T_t *)obj_ptr) == FALSE) - || (!olist->file_info.ptr.shared && olist->obj_type != H5I_DATATYPE) - || (oloc && oloc->file && oloc->file->shared == olist->file_info.ptr.shared)))) { - /* Add the object's ID to the ID list, if appropriate */ - if(olist->obj_id_list) { - olist->obj_id_list[olist->list_index] = obj_id; - olist->list_index++; - } /* end if */ - - /* Increment the number of open objects */ - if(olist->obj_id_count) - (*olist->obj_id_count)++; - - /* Check if we've filled up the array. Return TRUE only if - * we have filled up the array. Otherwise return FALSE(RET_VALUE is - * preset to FALSE) because H5I_iterate needs the return value of - * FALSE to continue iterating. */ - if(olist->max_index>0 && olist->list_index>=olist->max_index) - HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */ - } /* end if */ - } /* end else */ + if(H5I_iterate(H5I_FILE, H5F_get_obj_ids_cb, &udata, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(1)") + } done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_objects_cb() */ + FUNC_LEAVE_API(ret_value) +} /* end H5Fget_obj_ids() */ /*------------------------------------------------------------------------- @@ -779,8 +402,9 @@ done: herr_t H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void **file_handle) { - H5F_t *file; /* File to query */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_t *vol_plugin; + void *obj; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "ii**x", file_id, fapl, file_handle); @@ -789,13 +413,17 @@ H5Fget_vfd_handle(hid_t file_id, hid_t fapl, void **file_handle) if(!file_handle) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file handle pointer") - /* Get the file */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file id") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* Retrieve the VFD handle for the file */ - if(H5F_get_vfd_handle(file, fapl, file_handle) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve VFD handle") + if((ret_value = H5VL_file_optional(obj, vol_plugin, H5VL_FILE_GET_VFD_HANDLE, + H5_REQUEST_NULL, file_handle, fapl)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file handle") done: FUNC_LEAVE_API(ret_value) @@ -803,625 +431,44 @@ done: /*------------------------------------------------------------------------- - * Function: H5Fis_hdf5 - * - * Purpose: Check the file signature to detect an HDF5 file. + * Function: H5Fis_accessible * - * Bugs: This function is not robust: it only uses the default file - * driver when attempting to open the file when in fact it - * should use all known file drivers. + * Purpose: Check if the file can be opened with the given fapl. * * Return: Success: TRUE/FALSE - * * Failure: Negative * - * Programmer: Unknown + * Programmer: Mohamad Chaarawi + * June 2012 * - * Modifications: - * Robb Matzke, 1999-08-02 - * Rewritten to use the virtual file layer. *------------------------------------------------------------------------- */ htri_t -H5Fis_hdf5(const char *name) +H5Fis_accessible(const char *name, hid_t fapl_id) { - H5FD_t *file = NULL; /* Low-level file struct */ - htri_t ret_value; /* Return value */ + htri_t ret_value = TRUE; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE1("t", "*s", name); + H5TRACE2("t", "*si", name, fapl_id); - /* Check args and all the boring stuff. */ + /* Check args */ if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no file name specified") - /* Open the file at the virtual file layer */ - if(NULL == (file = H5FD_open(name, H5F_ACC_RDONLY, H5P_FILE_ACCESS_DEFAULT, HADDR_UNDEF))) - HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to open file") - - /* The file is an hdf5 file if the hdf5 file signature can be found */ - ret_value = (HADDR_UNDEF != H5F_locate_signature(file, H5AC_ind_dxpl_id)); - -done: - /* Close the file */ - if(file) - if(H5FD_close(file) < 0 && ret_value >= 0) - HDONE_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file") - - FUNC_LEAVE_API(ret_value) -} /* end H5Fis_hdf5() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_new - * - * Purpose: Creates a new file object and initializes it. The - * H5Fopen and H5Fcreate functions then fill in various - * fields. If SHARED is a non-null pointer then the shared info - * to which it points has the reference count incremented. - * Otherwise a new, empty shared info struct is created and - * initialized with the specified file access property list. - * - * Errors: - * - * Return: Success: Ptr to a new file struct. - * - * Failure: NULL - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 18 1997 - * - *------------------------------------------------------------------------- - */ -static H5F_t * -H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) -{ - H5F_t *f = NULL, *ret_value; - - FUNC_ENTER_NOAPI_NOINIT - - if(NULL == (f = H5FL_CALLOC(H5F_t))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate top file structure") - f->file_id = -1; - - if(shared) { - HDassert(lf == NULL); - f->shared = shared; - } /* end if */ - else { - H5P_genplist_t *plist; /* Property list */ - unsigned efc_size; /* External file cache size */ - size_t u; /* Local index variable */ - - HDassert(lf != NULL); - if(NULL == (f->shared = H5FL_CALLOC(H5F_file_t))) - HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared file structure") - - f->shared->sohm_addr = HADDR_UNDEF; - f->shared->sohm_vers = HDF5_SHAREDHEADER_VERSION; - for(u = 0; u < NELMTS(f->shared->fs_addr); u++) - f->shared->fs_addr[u] = HADDR_UNDEF; - f->shared->accum.loc = HADDR_UNDEF; - f->shared->lf = lf; - - /* - * Copy the file creation and file access property lists into the - * new file handle. We do this early because some values might need - * to change as the file is being opened. - */ - if(NULL == (plist = (H5P_genplist_t *)H5I_object(fcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not property list") - f->shared->fcpl_id = H5P_copy_plist(plist, FALSE); - - /* Get the FCPL values to cache */ - if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &f->shared->sizeof_addr) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for address") - if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &f->shared->sizeof_size) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for object size") - if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &f->shared->sohm_nindexes) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get number of SOHM indexes") - HDassert(f->shared->sohm_nindexes < 255); - if(H5P_get(plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, &f->shared->fs_strategy) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file space strategy") - if(H5P_get(plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, &f->shared->fs_threshold) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get free-space section threshold") - - /* Get the FAPL values to cache */ - if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") - if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config") - if(H5P_get(plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache number of slots") - if(H5P_get(plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache byte size") - if(H5P_get(plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get preempt read chunk") - if(H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(f->shared->threshold)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold") - if(H5P_get(plist, H5F_ACS_ALIGN_NAME, &(f->shared->alignment)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment") - if(H5P_get(plist, H5F_ACS_GARBG_COLCT_REF_NAME,&(f->shared->gc_ref)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get garbage collect reference") - if(H5P_get(plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get sieve buffer size") - if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'latest format' flag") - if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get metadata cache size") - f->shared->meta_aggr.feature_flag = H5FD_FEAT_AGGREGATE_METADATA; - if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' cache size") - f->shared->sdata_aggr.feature_flag = H5FD_FEAT_AGGREGATE_SMALLDATA; - if(H5P_get(plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get elink file cache size") - if(efc_size > 0) - if(NULL == (f->shared->efc = H5F_efc_create(efc_size))) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't create external file cache") - - /* Get the VFD values to cache */ - f->shared->maxaddr = H5FD_get_maxaddr(lf); - if(!H5F_addr_defined(f->shared->maxaddr)) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad maximum address from VFD") - if(H5FD_get_feature_flags(lf, &f->shared->feature_flags) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get feature flags from VFD") - if(H5FD_get_fs_type_map(lf, f->shared->fs_type_map) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get free space type mapping from VFD") - if(H5MF_init_merge_flags(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "problem initializing free space merge flags") - f->shared->tmp_addr = f->shared->maxaddr; - /* Disable temp. space allocation for parallel I/O (for now) */ - /* (When we've arranged to have the relocated metadata addresses (and - * sizes) broadcast during the "end of epoch" metadata operations, - * this can be enabled - QAK) - */ - /* (This should be disabled when the metadata journaling branch is - * merged into the trunk and journaling is enabled, at least until - * we make it work. - QAK) - */ - f->shared->use_tmp_space = !H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI); - - /* - * Create a metadata cache with the specified number of elements. - * The cache might be created with a different number of elements and - * the access property list should be updated to reflect that. - */ - if(H5AC_create(f, &(f->shared->mdc_initCacheCfg)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create metadata cache") - - /* Create the file's "open object" information */ - if(H5FO_create(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object data structure") - - /* Add new "shared" struct to list of open files */ - if(H5F_sfile_add(f->shared) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to append to list of open files") - } /* end else */ - - f->shared->nrefs++; - - /* Create the file's "top open object" information */ - if(H5FO_top_create(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object data structure") - - /* Set return value */ - ret_value = f; - -done: - if(!ret_value && f) { - if(!shared) - f->shared = H5FL_FREE(H5F_file_t, f->shared); - f = H5FL_FREE(H5F_t, f); - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_new() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_dest - * - * Purpose: Destroys a file structure. This function flushes the cache - * but doesn't do any other cleanup other than freeing memory - * for the file struct. The shared info for the file is freed - * only when its reference count reaches zero. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 18 1997 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - - if(1 == f->shared->nrefs) { - /* Flush at this point since the file will be closed. - * Only try to flush the file if it was opened with write access, and if - * the caller requested a flush. - */ - if((H5F_ACC_RDWR & H5F_INTENT(f)) && flush) - if(H5F_flush(f, dxpl_id, TRUE) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") - - /* Release the external file cache */ - if(f->shared->efc) { - if(H5F_efc_destroy(f->shared->efc) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't destroy external file cache") - f->shared->efc = NULL; - } /* end if */ - - /* Release objects that depend on the superblock being initialized */ - if(f->shared->sblock) { - /* Shutdown file free space manager(s) */ - /* (We should release the free space information now (before truncating - * the file and before the metadata cache is shut down) since the - * free space manager is holding some data structures in memory - * and also because releasing free space can shrink the file's - * 'eoa' value) - */ - if(H5F_ACC_RDWR & H5F_INTENT(f)) { - if(H5MF_close(f, dxpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info") - - /* Flush the file again (if requested), as shutting down the - * free space manager may dirty some data structures again. - */ - if(flush) - if(H5F_flush(f, dxpl_id, TRUE) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") - } /* end if */ - - /* Unpin the superblock, since we're about to destroy the cache */ - if(H5AC_unpin_entry(f->shared->sblock) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock") - f->shared->sblock = NULL; - } /* end if */ - - /* Remove shared file struct from list of open files */ - if(H5F_sfile_remove(f->shared) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - - /* Shutdown the metadata cache */ - if(H5AC_dest(f, dxpl_id)) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - - /* - * Do not close the root group since we didn't count it, but free - * the memory associated with it. - */ - if(f->shared->root_grp) { - /* Free the root group */ - if(H5G_root_free(f->shared->root_grp) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - f->shared->root_grp = NULL; - } /* end if */ - - /* Destroy other components of the file */ - if(H5F_accum_reset(f, dxpl_id, TRUE) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - if(H5FO_dest(f) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - f->shared->cwfs = (struct H5HG_heap_t **)H5MM_xfree(f->shared->cwfs); - if(H5G_node_close(f) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") - - /* Destroy file creation properties */ - if(H5I_GENPROP_LST != H5I_get_type(f->shared->fcpl_id)) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a property list") - if(H5I_dec_ref(f->shared->fcpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close property list") - - /* Only truncate the file on an orderly close, with write-access */ - if(f->closing && (H5F_ACC_RDWR & H5F_INTENT(f))) { - /* Truncate the file to the current allocated size */ - if(H5FD_truncate(f->shared->lf, dxpl_id, (unsigned)TRUE) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "low level truncate failed") - } /* end if */ - - /* Close the file */ - if(H5FD_close(f->shared->lf) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") - - /* Free mount table */ - f->shared->mtab.child = (H5F_mount_t *)H5MM_xfree(f->shared->mtab.child); - f->shared->mtab.nalloc = 0; - - /* Destroy shared file struct */ - f->shared = (H5F_file_t *)H5FL_FREE(H5F_file_t, f->shared); - - } else if(f->shared->nrefs > 0) { - /* - * There are other references to the shared part of the file. - * Only decrement the reference count. - */ - --f->shared->nrefs; - } - - /* Free the non-shared part of the file */ - f->open_name = (char *)H5MM_xfree(f->open_name); - f->actual_name = (char *)H5MM_xfree(f->actual_name); - f->extpath = (char *)H5MM_xfree(f->extpath); - if(H5FO_top_dest(f) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file") - f->shared = NULL; - f = H5FL_FREE(H5F_t, f); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_dest() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_open - * - * Purpose: Opens (or creates) a file. This function understands the - * following flags which are similar in nature to the Posix - * open(2) flags. - * - * H5F_ACC_RDWR: Open with read/write access. If the file is - * currently open for read-only access then it - * will be reopened. Absence of this flag - * implies read-only access. - * - * H5F_ACC_CREAT: Create a new file if it doesn't exist yet. - * The permissions are 0666 bit-wise AND with - * the current umask. H5F_ACC_WRITE must also - * be specified. - * - * H5F_ACC_EXCL: This flag causes H5F_open() to fail if the - * file already exists. - * - * H5F_ACC_TRUNC: The file is truncated and a new HDF5 superblock - * is written. This operation will fail if the - * file is already open. - * - * Unlinking the file name from the group directed graph while - * the file is opened causes the file to continue to exist but - * one will not be able to upgrade the file from read-only - * access to read-write access by reopening it. Disk resources - * for the file are released when all handles to the file are - * closed. NOTE: This paragraph probably only applies to Unix; - * deleting the file name in other OS's has undefined results. - * - * The CREATE_PARMS argument is optional. A null pointer will - * cause the default file creation parameters to be used. - * - * The ACCESS_PARMS argument is optional. A null pointer will - * cause the default file access parameters to be used. - * - * Return: Success: A new file pointer. - * Failure: NULL - * - * Programmer: Robb Matzke - * Tuesday, September 23, 1997 - * - *------------------------------------------------------------------------- - */ -H5F_t * -H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, - hid_t dxpl_id) -{ - H5F_t *file = NULL; /*the success return value */ - H5F_file_t *shared = NULL; /*shared part of `file' */ - H5FD_t *lf = NULL; /*file driver part of `shared' */ - unsigned tent_flags; /*tentative flags */ - H5FD_class_t *drvr; /*file driver class info */ - H5P_genplist_t *a_plist; /*file access property list */ - H5F_close_degree_t fc_degree; /*file close degree */ - H5F_t *ret_value; /*actual return value */ - - FUNC_ENTER_NOAPI(NULL) - - /* - * If the driver has a `cmp' method then the driver is capable of - * determining when two file handles refer to the same file and the - * library can insure that when the application opens a file twice - * that the two handles coordinate their operations appropriately. - * Otherwise it is the application's responsibility to never open the - * same file more than once at a time. - */ - if(NULL == (drvr = H5FD_get_class(fapl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class") - - /* - * Opening a file is a two step process. First we try to open the - * file in a way which doesn't affect its state (like not truncating - * or creating it) so we can compare it with files that are already - * open. If that fails then we try again with the full set of flags - * (only if they're different than the original failed attempt). - * However, if the file driver can't distinquish between files then - * there's no reason to open the file tentatively because it's the - * application's responsibility to prevent this situation (there's no - * way for us to detect it here anyway). - */ - if(drvr->cmp) - tent_flags = flags & ~(H5F_ACC_CREAT|H5F_ACC_TRUNC|H5F_ACC_EXCL); + /* Check the file access property list */ + if(H5P_DEFAULT == fapl_id) + fapl_id = H5P_FILE_ACCESS_DEFAULT; else - tent_flags = flags; - - if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { - if(tent_flags == flags) { -#ifndef H5_USING_MEMCHECKER - time_t mytime = HDtime(NULL); - - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags) -#else /* H5_USING_MEMCHECKER */ - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags) -#endif /* H5_USING_MEMCHECKER */ - } /* end if */ - H5E_clear_stack(NULL); - tent_flags = flags; - if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { -#ifndef H5_USING_MEMCHECKER - time_t mytime = HDtime(NULL); - - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags) -#else /* H5_USING_MEMCHECKER */ - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags) -#endif /* H5_USING_MEMCHECKER */ - } /* end if */ - } /* end if */ - - /* Is the file already open? */ - if((shared = H5F_sfile_search(lf)) != NULL) { - /* - * The file is already open, so use that one instead of the one we - * just opened. We only one one H5FD_t* per file so one doesn't - * confuse the other. But fail if this request was to truncate the - * file (since we can't do that while the file is open), or if the - * request was to create a non-existent file (since the file already - * exists), or if the new request adds write access (since the - * readers don't expect the file to change under them). - */ - if(H5FD_close(lf) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") - if(flags & H5F_ACC_TRUNC) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to truncate a file which is already open") - if(flags & H5F_ACC_EXCL) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file exists") - if((flags & H5F_ACC_RDWR) && 0 == (shared->flags & H5F_ACC_RDWR)) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is already open for read-only") - - /* Allocate new "high-level" file struct */ - if((file = H5F_new(shared, fcpl_id, fapl_id, NULL)) == NULL) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") - } /* end if */ - else { - /* Check if tentative open was good enough */ - if(flags != tent_flags) { - /* - * This file is not yet open by the library and the flags we used to - * open it are different than the desired flags. Close the tentative - * file and open it for real. - */ - if(H5FD_close(lf) < 0) { - file = NULL; /*to prevent destruction of wrong file*/ - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") - } /* end if */ - if(NULL == (lf = H5FD_open(name, flags, fapl_id, HADDR_UNDEF))) { - file = NULL; /*to prevent destruction of wrong file*/ - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") - } /* end if */ - } /* end if */ - - if(NULL == (file = H5F_new(NULL, fcpl_id, fapl_id, lf))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") - file->shared->flags = flags; - } /* end else */ - - /* Short cuts */ - shared = file->shared; - lf = shared->lf; - - /* - * The intent at the top level file struct are not necessarily the same as - * the flags at the bottom. The top level describes how the file can be - * accessed through the HDF5 library. The bottom level describes how the - * file can be accessed through the C library. - */ - file->intent = flags; - file->open_name = H5MM_xstrdup(name); - - /* - * Read or write the file superblock, depending on whether the file is - * empty or not. - */ - if(0 == H5FD_get_eof(lf) && (flags & H5F_ACC_RDWR)) { - /* - * We've just opened a fresh new file (or truncated one). We need - * to create & write the superblock. - */ - - /* Initialize information about the superblock and allocate space for it */ - /* (Writes superblock extension messages, if there are any) */ - if(H5F_super_init(file, dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to allocate file superblock") - - /* Create and open the root group */ - /* (This must be after the space for the superblock is allocated in - * the file, since the superblock must be at offset 0) - */ - if(H5G_mkroot(file, dxpl_id, TRUE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group") - } else if (1 == shared->nrefs) { - /* Read the superblock if it hasn't been read before. */ - if(H5F_super_read(file, dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock") - - /* Open the root group */ - if(H5G_mkroot(file, dxpl_id, FALSE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group") - } /* end if */ - - /* Get the file access property list, for future queries */ - if(NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") - - /* - * Decide the file close degree. If it's the first time to open the - * file, set the degree to access property list value; if it's the - * second time or later, verify the access property list value matches - * the degree in shared file structure. - */ - if(H5P_get(a_plist, H5F_ACS_CLOSE_DEGREE_NAME, &fc_degree) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file close degree") - - if(shared->nrefs == 1) { - if(fc_degree == H5F_CLOSE_DEFAULT) - shared->fc_degree = lf->cls->fc_degree; - else - shared->fc_degree = fc_degree; - } else if(shared->nrefs > 1) { - if(fc_degree == H5F_CLOSE_DEFAULT && shared->fc_degree != lf->cls->fc_degree) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match") - if(fc_degree != H5F_CLOSE_DEFAULT && fc_degree != shared->fc_degree) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match") - } /* end if */ - - /* Formulate the absolute path for later search of target file for external links */ - if(H5_build_extpath(name, &file->extpath) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath") - - /* Formulate the actual file name, after following symlinks, etc. */ - if(H5F_build_actual_name(file, a_plist, name, &file->actual_name) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build actual name") + if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list") - /* Success */ - ret_value = file; + if(H5VL_file_misc(NULL, NULL, H5VL_FILE_IS_ACCESSIBLE, H5_REQUEST_NULL, + fapl_id, name, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file handle") done: - if(!ret_value && file) - if(H5F_dest(file, dxpl_id, FALSE) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_open() */ + FUNC_LEAVE_API(ret_value) +} /* end H5Fis_accessible() */ /*------------------------------------------------------------------------- @@ -1454,8 +501,9 @@ done: hid_t H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) { - H5F_t *new_file = NULL; /*file struct for new file */ - hid_t ret_value; /*return value */ + void *file = NULL; /*file token from VOL plugin */ + H5VL_t *vol_plugin; /* VOL plugin information */ + hid_t ret_value; /*return value */ FUNC_ENTER_API(FAIL) H5TRACE4("i", "*sIuii", filename, flags, fcpl_id, fapl_id); @@ -1486,33 +534,15 @@ H5Fcreate(const char *filename, unsigned flags, hid_t fcpl_id, hid_t fapl_id) if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list") - /* - * Adjust bit flags by turning on the creation bit and making sure that - * the EXCL or TRUNC bit is set. All newly-created files are opened for - * reading and writing. - */ - if (0==(flags & (H5F_ACC_EXCL|H5F_ACC_TRUNC))) - flags |= H5F_ACC_EXCL; /*default*/ - flags |= H5F_ACC_RDWR | H5F_ACC_CREAT; - - /* - * Create a new file or truncate an existing file. - */ - if(NULL == (new_file = H5F_open(filename, flags, fcpl_id, fapl_id, H5AC_dxpl_id))) + /* create a new file or truncate an existing file through the VOL */ + if(NULL == (file = H5VL_file_create(&vol_plugin, filename, flags, fcpl_id, fapl_id, H5_REQUEST_NULL))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file") - /* Get an atom for the file */ - if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file") - - /* Keep this ID in file object structure */ - new_file->file_id = ret_value; + /* Get an atom for the file with the VOL information as the auxilary struct*/ + if((ret_value = H5I_register2(H5I_FILE, file, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") done: - if(ret_value < 0 && new_file) - if(H5F_close(new_file) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") - FUNC_LEAVE_API(ret_value) } /* end H5Fcreate() */ @@ -1560,8 +590,9 @@ done: hid_t H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) { - H5F_t *new_file = NULL; /*file struct for new file */ - hid_t ret_value; /*return value */ + void *file = NULL; /*file token from VOL plugin */ + H5VL_t *vol_plugin; /* VOL plugin information */ + hid_t ret_value; /*return value */ FUNC_ENTER_API(FAIL) H5TRACE3("i", "*sIui", filename, flags, fapl_id); @@ -1579,21 +610,15 @@ H5Fopen(const char *filename, unsigned flags, hid_t fapl_id) if(TRUE != H5P_isa_class(fapl_id, H5P_FILE_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not file access property list") - /* Open the file */ - if(NULL == (new_file = H5F_open(filename, flags, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to open file") + /* Open the file through the VOL layer */ + if(NULL == (file = H5VL_file_open(&vol_plugin, filename, flags, fapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to create file") - /* Get an atom for the file */ - if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) + /* Get an atom for the file with the VOL information as the auxilary struct*/ + if((ret_value = H5I_register2(H5I_FILE, file, vol_plugin, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") - /* Keep this ID in file object structure */ - new_file->file_id = ret_value; - done: - if(ret_value < 0 && new_file && H5F_try_close(new_file) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") - FUNC_LEAVE_API(ret_value) } /* end H5Fopen() */ @@ -1615,392 +640,38 @@ done: herr_t H5Fflush(hid_t object_id, H5F_scope_t scope) { - H5F_t *f = NULL; /* File to flush */ - H5O_loc_t *oloc = NULL; /* Object location for ID */ + H5VL_t *vol_plugin; + void *obj; + H5I_type_t obj_type; + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "iFs", object_id, scope); - switch(H5I_get_type(object_id)) { - case H5I_FILE: - if(NULL == (f = (H5F_t *)H5I_object(object_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - break; - - case H5I_GROUP: - { - H5G_t *grp; - - if(NULL == (grp = (H5G_t *)H5I_object(object_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid group identifier") - oloc = H5G_oloc(grp); - } - break; - - case H5I_DATATYPE: - { - H5T_t *type; - - if(NULL == (type = (H5T_t *)H5I_object(object_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid type identifier") - oloc = H5T_oloc(type); - } - break; - - case H5I_DATASET: - { - H5D_t *dset; - - if(NULL == (dset = (H5D_t *)H5I_object(object_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier") - oloc = H5D_oloc(dset); - } - break; - - case H5I_ATTR: - { - H5A_t *attr; - - if(NULL == (attr = (H5A_t *)H5I_object(object_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier") - oloc = H5A_oloc(attr); - } - break; - - case H5I_UNINIT: - case H5I_BADID: - case H5I_DATASPACE: - case H5I_REFERENCE: - case H5I_VFL: - case H5I_GENPROP_CLS: - case H5I_GENPROP_LST: - case H5I_ERROR_CLASS: - case H5I_ERROR_MSG: - case H5I_ERROR_STACK: - case H5I_NTYPES: - default: - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") - } /* end switch */ - - if(!f) { - if(!oloc) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "object is not assocated with a file") - f = oloc->file; - } /* end if */ - if(!f) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "object is not associated with a file") - - /* Flush the file */ - /* - * Nothing to do if the file is read only. This determination is - * made at the shared open(2) flags level, implying that opening a - * file twice, once for read-only and once for read-write, and then - * calling H5Fflush() with the read-only handle, still causes data - * to be flushed. - */ - if(H5F_ACC_RDWR & H5F_INTENT(f)) { - /* Flush other files, depending on scope */ - if(H5F_SCOPE_GLOBAL == scope) { - /* Call the flush routine for mounted file hierarchies */ - if(H5F_flush_mounts(f, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush mounted file hierarchy") - } /* end if */ - else { - /* Call the flush routine, for this file */ - if(H5F_flush(f, H5AC_dxpl_id, FALSE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") - } /* end else */ - } /* end if */ - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Fflush() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_flush - * - * Purpose: Flushes cached data. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 29 1997 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_flush(H5F_t *f, hid_t dxpl_id, hbool_t closing) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - - /* Sanity check arguments */ - HDassert(f); - - /* Flush any cached dataset storage raw data */ - if(H5D_flush(f, dxpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache") - - /* Release any space allocated to space aggregators, so that the eoa value - * corresponds to the end of the space written to in the file. - */ - /* (needs to happen before cache flush, with superblock write, since the - * 'eoa' value is written in superblock -QAK) - */ - if(H5MF_free_aggrs(f, dxpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space") - - /* Flush the entire metadata cache */ - if(H5AC_flush(f, dxpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache") - - /* Flush out the metadata accumulator */ - if(H5F_accum_flush(f, dxpl_id) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush metadata accumulator") - - /* Flush file buffers to disk. */ - if(H5FD_flush(f->shared->lf, dxpl_id, closing) < 0) - /* Push error, but keep going*/ - HDONE_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_flush() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_close - * - * Purpose: Closes a file or causes the close operation to be pended. - * This function is called two ways: from the API it gets called - * by H5Fclose->H5I_dec_ref->H5F_close when H5I_dec_ref() - * decrements the file ID reference count to zero. The file ID - * is removed from the H5I_FILE group by H5I_dec_ref() just - * before H5F_close() is called. If there are open object - * headers then the close is pended by moving the file to the - * H5I_FILE_CLOSING ID group (the f->closing contains the ID - * assigned to file). - * - * This function is also called directly from H5O_close() when - * the last object header is closed for the file and the file - * has a pending close. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Tuesday, September 23, 1997 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_close(H5F_t *f) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Sanity check */ - HDassert(f); - HDassert(f->file_id > 0); /* This routine should only be called when a file ID's ref count drops to zero */ - - /* Perform checks for "semi" file close degree here, since closing the - * file is not allowed if there are objects still open */ - if(f->shared->fc_degree == H5F_CLOSE_SEMI) { - unsigned nopen_files = 0; /* Number of open files in file/mount hierarchy */ - unsigned nopen_objs = 0; /* Number of open objects in file/mount hierarchy */ - - /* Get the number of open objects and open files on this file/mount hierarchy */ - if(H5F_mount_count_ids(f, &nopen_files, &nopen_objs) < 0) - HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy") - - /* If there are no other file IDs open on this file/mount hier., but - * there are still open objects, issue an error and bail out now, - * without decrementing the file ID's reference count and triggering - * a "real" attempt at closing the file */ - if(nopen_files == 1 && nopen_objs > 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, there are objects still open") - } /* end if */ - - /* Reset the file ID for this file */ - f->file_id = -1; - - /* Attempt to close the file/mount hierarchy */ - if(H5F_try_close(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_close() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_try_close - * - * Purpose: Attempts to close a file due to one of several actions: - * - The reference count on the file ID dropped to zero - * - The last open object was closed in the file - * - The file was unmounted - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, July 19, 2005 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_try_close(H5F_t *f) -{ - unsigned nopen_files = 0; /* Number of open files in file/mount hierarchy */ - unsigned nopen_objs = 0; /* Number of open objects in file/mount hierarchy */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - - /* Check if this file is already in the process of closing */ - if(f->closing) - HGOTO_DONE(SUCCEED) - - /* Get the number of open objects and open files on this file/mount hierarchy */ - if(H5F_mount_count_ids(f, &nopen_files, &nopen_objs) < 0) - HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy") - - /* - * Close file according to close degree: - * - * H5F_CLOSE_WEAK: if there are still objects open, wait until - * they are all closed. - * H5F_CLOSE_SEMI: if there are still objects open, return fail; - * otherwise, close file. - * H5F_CLOSE_STRONG: if there are still objects open, close them - * first, then close file. - */ - switch(f->shared->fc_degree) { - case H5F_CLOSE_WEAK: - /* - * If file or object IDS are still open then delay deletion of - * resources until they have all been closed. Flush all - * caches and update the object header anyway so that failing to - * close all objects isn't a major problem. - */ - if((nopen_files + nopen_objs) > 0) - HGOTO_DONE(SUCCEED) - break; - - case H5F_CLOSE_SEMI: - /* Can leave safely if file IDs are still open on this file */ - if(nopen_files > 0) - HGOTO_DONE(SUCCEED) - - /* Sanity check: If close degree if "semi" and we have gotten this - * far and there are objects left open, bail out now */ - HDassert(nopen_files == 0 && nopen_objs == 0); - - /* If we've gotten this far (ie. there are no open objects in the file), fall through to flush & close */ - break; - - case H5F_CLOSE_STRONG: - /* If there are other open files in the hierarchy, we can leave now */ - if(nopen_files > 0) - HGOTO_DONE(SUCCEED) - - /* If we've gotten this far (ie. there are no open file IDs in the file/mount hierarchy), fall through to flush & close */ - break; - - case H5F_CLOSE_DEFAULT: - default: - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, unknown file close degree") - } /* end switch */ - - /* Mark this file as closing (prevents re-entering file shutdown code below) */ - f->closing = TRUE; - - /* If the file close degree is "strong", close all the open objects in this file */ - if(f->shared->fc_degree == H5F_CLOSE_STRONG) { - HDassert(nopen_files == 0); - - /* Forced close of all opened objects in this file */ - if(f->nopen_objs > 0) { - size_t obj_count; /* # of open objects */ - hid_t objs[128]; /* Array of objects to close */ - herr_t result; /* Local result from obj ID query */ - size_t u; /* Local index variable */ - - /* Get the list of IDs of open dataset, group, & attribute objects */ - while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_ATTR, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0 - && obj_count != 0 ) { - - /* Try to close all the open objects in this file */ - for(u = 0; u < obj_count; u++) - if(H5I_dec_ref(objs[u]) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object") - } /* end while */ - if(result < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(1)") - - /* Get the list of IDs of open named datatype objects */ - /* (Do this separately from the dataset & attribute IDs, because - * they could be using one of the named datatypes and then the - * open named datatype ID will get closed twice) - */ - while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATATYPE, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0 - && obj_count != 0) { - - /* Try to close all the open objects in this file */ - for(u = 0; u < obj_count; u++) - if(H5I_dec_ref(objs[u]) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object") - } /* end while */ - if(result < 0) - HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(2)") - } /* end if */ - } /* end if */ + obj_type = H5I_get_type(object_id); + if(H5I_FILE != obj_type && H5I_GROUP != obj_type && H5I_DATATYPE != obj_type && + H5I_DATASET != obj_type && H5I_ATTR != obj_type) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + } - /* Check if this is a child file in a mounting hierarchy & proceed up the - * hierarchy if so. - */ - if(f->parent) - if(H5F_try_close(f->parent) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close parent file") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(object_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Unmount and close each child before closing the current file. */ - if(H5F_close_mounts(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child files") + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(object_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* If there is more than one reference to the shared file struct and the - * file has an external file cache, we should see if it can be closed. This - * can happen if a cycle is formed with external file caches */ - if(f->shared->efc && (f->shared->nrefs > 1)) - if(H5F_efc_try_close(f) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't attempt to close EFC") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = obj_type; - /* Delay flush until the shared file struct is closed, in H5F_dest. If the - * application called H5Fclose, it would have been flushed in that function - * (unless it will have been flushed in H5F_dest anyways). */ - - /* - * Destroy the H5F_t struct and decrement the reference count for the - * shared H5F_file_t struct. If the reference count for the H5F_file_t - * struct reaches zero then destroy it also. - */ - if(H5F_dest(f, H5AC_dxpl_id, TRUE) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") + if((ret_value = H5VL_file_flush(obj, loc_params, vol_plugin, scope, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file") done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_try_close() */ + FUNC_LEAVE_API(ret_value) +} /* end H5Fflush() */ /*------------------------------------------------------------------------- @@ -2027,37 +698,36 @@ done: herr_t H5Fclose(hid_t file_id) { - H5F_t *f = NULL; - int nref; - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); /* Check/fix arguments. */ if(H5I_FILE != H5I_get_type(file_id)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file ID") - /* Flush file if this is the last reference to this id and we have write - * intent, unless it will be flushed by the "shared" file being closed. - * This is only necessary to replicate previous behaviour, and could be - * disabled by an option/property to improve performance. */ - if(NULL == (f = (H5F_t *)H5I_object(file_id))) + /* Decrement reference count on atom. When it reaches zero the file will be closed. */ + if(H5I_dec_app_ref(file_id) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") + +#if 0 + void *file; /*file token from VOL plugin */ + H5VL_t *vol_plugin; /* VOL plugin information */ + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the file object */ + if(NULL == (file = (void *)H5I_object(file_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - if((f->shared->nrefs > 1) && (H5F_INTENT(f) & H5F_ACC_RDWR)) { - if((nref = H5I_get_ref(file_id, FALSE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count") - if(nref == 1) - if(H5F_flush(f, H5AC_dxpl_id, FALSE) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") - } /* end if */ - /* - * Decrement reference count on atom. When it reaches zero the file will - * be closed. - */ - if(H5I_dec_app_ref(file_id) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTCLOSEFILE, FAIL, "decrementing file ID failed") + /* Close the file through the VOL*/ + if((ret_value = H5VL_file_close(file, vol_plugin, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") + + H5MM_free(vol_plugin); +#endif done: FUNC_LEAVE_API(ret_value) @@ -2065,6 +735,35 @@ done: /*------------------------------------------------------------------------- + * Function: H5F_close_file + * + * Purpose: Called when the ref count reaches zero on the file_id + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * June 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_close_file(void *file, H5VL_t *vol_plugin) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Close the file through the VOL*/ + if((ret_value = H5VL_file_close(file, vol_plugin, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_close_file() */ + + +/*------------------------------------------------------------------------- * Function: H5Freopen * * Purpose: Reopen a file. The new file handle which is returned points @@ -2089,39 +788,33 @@ done: hid_t H5Freopen(hid_t file_id) { - H5F_t *old_file = NULL; - H5F_t *new_file = NULL; + H5VL_t *vol_plugin; + void *obj; + void *file; /*file token from VOL plugin */ hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", file_id); - /* Check arguments */ - if(NULL == (old_file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Get a new "top level" file struct, sharing the same "low level" file struct */ - if(NULL == (new_file = H5F_new(old_file->shared, H5P_FILE_CREATE_DEFAULT, H5P_FILE_ACCESS_DEFAULT, NULL))) - HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* Keep old file's read/write intent in new file */ - new_file->intent = old_file->intent; + if(H5VL_file_optional(obj, vol_plugin, H5VL_FILE_REOPEN, H5_REQUEST_NULL, &file) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") - /* Duplicate old file's names */ - new_file->open_name = H5MM_xstrdup(old_file->open_name); - new_file->actual_name = H5MM_xstrdup(old_file->actual_name); + if (NULL == file) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") - if((ret_value = H5I_register(H5I_FILE, new_file, TRUE)) < 0) + /* Get an atom for the file with the VOL information as the auxilary struct*/ + if((ret_value = H5I_register2(H5I_FILE, file, vol_plugin, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") - /* Keep this ID in file object structure */ - new_file->file_id = ret_value; - done: - if(ret_value < 0 && new_file) - if(H5F_dest(new_file, H5AC_dxpl_id, FALSE) < 0) - HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file") - FUNC_LEAVE_API(ret_value) } /* end H5Freopen() */ @@ -2149,399 +842,24 @@ H5Fget_intent(hid_t file_id, unsigned *intent_flags) /* If no intent flags were passed in, exit quietly */ if(intent_flags) { - H5F_t * file; /* Pointer to file structure */ - - /* Get the internal file structure */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") - - /* HDF5 uses some flags internally that users don't know about. - * Simplify things for them so that they only get either H5F_ACC_RDWR - * or H5F_ACC_RDONLY. - */ - if(H5F_INTENT(file) & H5F_ACC_RDWR) - *intent_flags = H5F_ACC_RDWR; - else - *intent_flags = H5F_ACC_RDONLY; - } /* end if */ - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Fget_intent() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_get_id - * - * Purpose: Get the file ID, incrementing it, or "resurrecting" it as - * appropriate. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Raymond Lu - * Oct 29, 2003 - * - *------------------------------------------------------------------------- - */ -hid_t -H5F_get_id(H5F_t *file, hbool_t app_ref) -{ - hid_t ret_value; - - FUNC_ENTER_NOAPI_NOINIT - - HDassert(file); - - if(file->file_id == -1) { - /* Get an atom for the file */ - if((file->file_id = H5I_register(H5I_FILE, file, app_ref)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file") - } else { - /* Increment reference count on atom. */ - if(H5I_inc_ref(file->file_id, app_ref) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed") - } /* end else */ - - ret_value = file->file_id; + H5VL_t *vol_plugin; + void *obj; -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5F_get_id() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_incr_nopen_objs - * - * Purpose: Increment the number of open objects for a file. - * - * Return: Success: The number of open objects, after the increment - * - * Failure: (can't happen) - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Mar 6 2007 - * - *------------------------------------------------------------------------- - */ -unsigned -H5F_incr_nopen_objs(H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(f); - - FUNC_LEAVE_NOAPI(++f->nopen_objs) -} /* end H5F_incr_nopen_objs() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_decr_nopen_objs - * - * Purpose: Decrement the number of open objects for a file. - * - * Return: Success: The number of open objects, after the decrement - * - * Failure: (can't happen) - * - * Programmer: Quincey Koziol - * koziol@hdfgroup.org - * Mar 6 2007 - * - *------------------------------------------------------------------------- - */ -unsigned -H5F_decr_nopen_objs(H5F_t *f) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(f); - - FUNC_LEAVE_NOAPI(--f->nopen_objs) -} /* end H5F_decr_nopen_objs() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_build_actual_name - * - * Purpose: Retrieve the name of a file, after following symlinks, etc. - * - * Note: Currently only working for "POSIX I/O compatible" VFDs - * - * Return: Success: 0 - * Failure: -1 - * - * Programmer: Quincey Koziol - * November 25, 2009 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name, - char **actual_name/*out*/) -{ - hid_t new_fapl_id = -1; /* ID for duplicated FAPL */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Sanity check */ - HDassert(f); - HDassert(fapl); - HDassert(name); - HDassert(actual_name); + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* Clear actual name pointer to begin with */ - *actual_name = NULL; - -/* Assume that if the OS can't create symlinks, that we don't need to worry - * about resolving them either. -QAK - */ -#ifdef H5_HAVE_SYMLINK - /* Check for POSIX I/O compatible file handle */ - if(H5F_HAS_FEATURE(f, H5FD_FEAT_POSIX_COMPAT_HANDLE)) { - h5_stat_t lst; /* Stat info from lstat() call */ - - /* Call lstat() on the file's name */ - if(HDlstat(name, &lst) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stat info for file") - - /* Check for symbolic link */ - if(S_IFLNK == (lst.st_mode & S_IFMT)) { - H5P_genplist_t *new_fapl; /* Duplicated FAPL */ - int *fd; /* POSIX I/O file descriptor */ - h5_stat_t st; /* Stat info from stat() call */ - h5_stat_t fst; /* Stat info from fstat() call */ - char realname[PATH_MAX]; /* Fully resolved path name of file */ - hbool_t want_posix_fd; /* Flag for retrieving file descriptor from VFD */ - - /* Perform a sanity check that the file or link wasn't switched - * between when we opened it and when we called lstat(). This is - * according to the security best practices for lstat() documented - * here: https://www.securecoding.cert.org/confluence/display/seccode/POS35-C.+Avoid+race+conditions+while+checking+for+the+existence+of+a+symbolic+link - */ - - /* Copy the FAPL object to modify */ - if((new_fapl_id = H5P_copy_plist(fapl, FALSE)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy file access property list") - if(NULL == (new_fapl = (H5P_genplist_t *)H5I_object(new_fapl_id))) - HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "can't get property list") - - /* Set the character encoding on the new property list */ - want_posix_fd = TRUE; - if(H5P_set(new_fapl, H5F_ACS_WANT_POSIX_FD_NAME, &want_posix_fd) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding") - - /* Retrieve the file handle */ - if(H5F_get_vfd_handle(f, new_fapl_id, (void **)&fd) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve POSIX file descriptor") - - /* Stat the filename we're resolving */ - if(HDstat(name, &st) < 0) - HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to stat file") - - /* Stat the file we opened */ - if(HDfstat(*fd, &fst) < 0) - HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to fstat file") - - /* Verify that the files are really the same */ - if(st.st_mode != fst.st_mode || st.st_ino != fst.st_ino || st.st_dev != fst.st_dev) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "files' st_ino or st_dev fields changed!") - - /* Get the resolved path for the file name */ - if(NULL == HDrealpath(name, realname)) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve real path for file") - - /* Duplicate the resolved path for the file name */ - if(NULL == (*actual_name = (char *)H5MM_strdup(realname))) - HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate real path") - } /* end if */ - } /* end if */ -#endif /* H5_HAVE_SYMLINK */ - - /* Check if we've resolved the file's name */ - if(NULL == *actual_name) { - /* Just duplicate the name used to open the file */ - if(NULL == (*actual_name = (char *)H5MM_strdup(name))) - HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate open name") - } /* end else */ + if((ret_value = H5VL_file_get(obj, vol_plugin, H5VL_FILE_GET_INTENT, H5_REQUEST_NULL, intent_flags)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file intent") + } done: - if(new_fapl_id > 0 && H5Pclose(new_fapl_id) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close duplicated FAPL") - - FUNC_LEAVE_NOAPI(ret_value) -} /* H5F_build_actual_name() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_addr_encode_len - * - * Purpose: Encodes an address into the buffer pointed to by *PP and - * then increments the pointer to the first byte after the - * address. An undefined value is stored as all 1's. - * - * Return: void - * - * Programmer: Robb Matzke - * Friday, November 7, 1997 - * - *------------------------------------------------------------------------- - */ -void -H5F_addr_encode_len(size_t addr_len, uint8_t **pp/*in,out*/, haddr_t addr) -{ - unsigned u; /* Local index variable */ - - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(addr_len); - HDassert(pp && *pp); - - if(H5F_addr_defined(addr)) { - for(u = 0; u < addr_len; u++) { - *(*pp)++ = (uint8_t)(addr & 0xff); - addr >>= 8; - } /* end for */ - HDassert("overflow" && 0 == addr); - } /* end if */ - else { - for(u = 0; u < addr_len; u++) - *(*pp)++ = 0xff; - } /* end else */ - - FUNC_LEAVE_NOAPI_VOID -} /* end H5F_addr_encode_len() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_addr_encode - * - * Purpose: Encodes an address into the buffer pointed to by *PP and - * then increments the pointer to the first byte after the - * address. An undefined value is stored as all 1's. - * - * Return: void - * - * Programmer: Robb Matzke - * Friday, November 7, 1997 - * - *------------------------------------------------------------------------- - */ -void -H5F_addr_encode(const H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(f); - - H5F_addr_encode_len(H5F_SIZEOF_ADDR(f), pp, addr); - - FUNC_LEAVE_NOAPI_VOID -} /* end H5F_addr_encode() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_addr_decode_len - * - * Purpose: Decodes an address from the buffer pointed to by *PP and - * updates the pointer to point to the next byte after the - * address. - * - * If the value read is all 1's then the address is returned - * with an undefined value. - * - * Return: void - * - * Programmer: Robb Matzke - * Friday, November 7, 1997 - * - *------------------------------------------------------------------------- - */ -void -H5F_addr_decode_len(size_t addr_len, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) -{ - hbool_t all_zero = TRUE; /* True if address was all zeroes */ - unsigned u; /* Local index variable */ - - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(addr_len); - HDassert(pp && *pp); - HDassert(addr_p); - - /* Reset value in destination */ - *addr_p = 0; - - /* Decode bytes from address */ - for(u = 0; u < addr_len; u++) { - uint8_t c; /* Local decoded byte */ - - /* Get decoded byte (and advance pointer) */ - c = *(*pp)++; - - /* Check for non-undefined address byte value */ - if(c != 0xff) - all_zero = FALSE; - - if(u < sizeof(*addr_p)) { - haddr_t tmp = c; /* Local copy of address, for casting */ - - /* Shift decoded byte to correct position */ - tmp <<= (u * 8); /*use tmp to get casting right */ - - /* Merge into already decoded bytes */ - *addr_p |= tmp; - } /* end if */ - else - if(!all_zero) - HDassert(0 == **pp); /*overflow */ - } /* end for */ - - /* If 'all_zero' is still TRUE, the address was entirely composed of '0xff' - * bytes, which is the encoded form of 'HADDR_UNDEF', so set the destination - * to that value */ - if(all_zero) - *addr_p = HADDR_UNDEF; - - FUNC_LEAVE_NOAPI_VOID -} /* end H5F_addr_decode_len() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_addr_decode - * - * Purpose: Decodes an address from the buffer pointed to by *PP and - * updates the pointer to point to the next byte after the - * address. - * - * If the value read is all 1's then the address is returned - * with an undefined value. - * - * Return: void - * - * Programmer: Robb Matzke - * Friday, November 7, 1997 - * - *------------------------------------------------------------------------- - */ -void -H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(f); - - H5F_addr_decode_len(H5F_SIZEOF_ADDR(f), pp, addr_p); - - FUNC_LEAVE_NOAPI_VOID -} /* end H5F_addr_decode() */ + FUNC_LEAVE_API(ret_value) +} /* end H5Fget_intent() */ /*------------------------------------------------------------------------- @@ -2561,22 +879,23 @@ H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*o hssize_t H5Fget_freespace(hid_t file_id) { - H5F_t *file; /* File object for file ID */ - hsize_t tot_space; /* Amount of free space in the file */ + H5VL_t *vol_plugin; + void *obj; hssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("Hs", "i", file_id); - /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Go get the actual amount of free space in the file */ - if(H5MF_get_freespace(file, H5AC_ind_dxpl_id, &tot_space, NULL) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - ret_value = (hssize_t)tot_space; + if(H5VL_file_optional(obj, vol_plugin, H5VL_FILE_GET_FREE_SPACE, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file free space") done: FUNC_LEAVE_API(ret_value) @@ -2604,22 +923,23 @@ done: herr_t H5Fget_filesize(hid_t file_id, hsize_t *size) { - H5F_t *file; /* File object for file ID */ - haddr_t eof; /* End of file address */ + H5VL_t *vol_plugin; + void *obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*h", file_id, size); - /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Go get the actual file size */ - if(HADDR_UNDEF == (eof = H5FDget_eof(file->shared->lf))) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - *size = (hsize_t)eof; + if((ret_value = H5VL_file_optional(obj, vol_plugin, H5VL_FILE_GET_SIZE, H5_REQUEST_NULL, size)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file size") done: FUNC_LEAVE_API(ret_value) @@ -2670,90 +990,30 @@ done: ssize_t H5Fget_file_image(hid_t file_id, void *buf_ptr, size_t buf_len) { - H5F_t *file; /* File object for file ID */ - H5FD_t *fd_ptr; /* file driver */ - haddr_t eoa; /* End of file address */ + H5VL_t *vol_plugin; + void *obj; ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("Zs", "i*xz", file_id, buf_ptr, buf_len); - /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") - if(!file || !file->shared || !file->shared->lf) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file_id yields invalid file pointer") - fd_ptr = file->shared->lf; - if(!fd_ptr->cls) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "fd_ptr yields invalid class pointer") - - /* the address space used by the split and multi file drivers is not - * a good fit for this call. Since the plan is to depreciate these - * drivers anyway, don't bother to do a "force fit". - * - * The following clause tests for the multi file driver, and fails - * if the supplied file has the multi file driver as its top level - * file driver. However, this test will not work if there is some - * other file driver sitting on top of the multi file driver. - * - * I'm not sure if this is possible at present, but in all likelyhood, - * it will become possible in the future. On the other hand, we may - * remove the split/multi file drivers before then. - * - * I am leaving this solution in for now, but we should review it, - * and improve the solution if necessary. - * - * JRM -- 11/11/22 - */ - if(HDstrcmp(fd_ptr->cls->name, "multi") == 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Not supported for multi file driver.") - - /* While the family file driver is conceptually fully compatible - * with the get file image operation, it sets a file driver message - * in the super block that prevents the image being opened with any - * driver other than the family file driver. Needless to say, this - * rather defeats the purpose of the get file image operation. - * - * While this problem is quire solvable, the required time and - * resources are lacking at present. Hence, for now, we don't - * allow the get file image operation to be perfomed on files - * opened with the family file driver. - * - * Observe that the following test only looks at the top level - * driver, and fails if there is some other driver sitting on to - * of the family file driver. - * - * I don't think this can happen at present, but that may change - * in the future. - * JRM -- 12/21/11 - */ - if(HDstrcmp(fd_ptr->cls->name, "family") == 0) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "Not supported for family file driver.") - - - /* Go get the actual file size */ - if(HADDR_UNDEF == (eoa = H5FD_get_eoa(file->shared->lf, H5FD_MEM_DEFAULT))) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") - - /* set ret_value = to eoa -- will overwrite this if appropriate */ - ret_value = (ssize_t)eoa; + /* check id */ + if(H5I_FILE != H5I_get_type(file_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") - /* test to see if a buffer was provided -- if not, we are done */ - if(buf_ptr != NULL) { - size_t space_needed; /* size of file image */ + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Check for buffer too small */ - if((haddr_t)buf_len < eoa) - HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "supplied buffer too small") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - space_needed = (size_t)eoa; + /* get image through the VOL */ + if(H5VL_file_optional(obj, vol_plugin, H5VL_FILE_GET_FILE_IMAGE, H5_REQUEST_NULL, + buf_ptr, &ret_value, buf_len) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file image") - /* read in the file image */ - /* (Note compensation for base address addition in internal routine) */ - if(H5FD_read(fd_ptr, H5AC_ind_dxpl_id, H5FD_MEM_DEFAULT, 0, space_needed, buf_ptr) < 0) - HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "file image read request failed") - } /* end if */ - done: FUNC_LEAVE_API(ret_value) } /* H5Fget_file_image() */ @@ -2780,21 +1040,28 @@ done: herr_t H5Fget_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr) { - H5F_t *file; /* File object for file ID */ + H5VL_t *vol_plugin; + void *obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*x", file_id, config_ptr); - /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* check args */ if((NULL == config_ptr) || (config_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Bad config_ptr") - /* Go get the resize configuration */ - if(H5AC_get_cache_auto_resize_config(file->shared->cache, config_ptr) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_auto_resize_config() failed.") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + if((ret_value = H5VL_file_optional(obj, vol_plugin, H5VL_FILE_GET_MDC_CONF, H5_REQUEST_NULL, + config_ptr)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get mdc configuration") done: FUNC_LEAVE_API(ret_value) @@ -2819,19 +1086,22 @@ done: herr_t H5Fset_mdc_config(hid_t file_id, H5AC_cache_config_t *config_ptr) { - H5F_t *file; /* File object for file ID */ + H5VL_t *vol_plugin; + void *obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*x", file_id, config_ptr); - /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* set the resize configuration */ - if(H5AC_set_cache_auto_resize_config(file->shared->cache, config_ptr) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "H5AC_set_cache_auto_resize_config() failed.") + if(H5VL_file_optional(obj, vol_plugin, H5VL_FILE_SET_MDC_CONFIG, H5_REQUEST_NULL, config_ptr) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "uanvle to set MDC configuration") done: FUNC_LEAVE_API(ret_value) @@ -2857,22 +1127,27 @@ done: herr_t H5Fget_mdc_hit_rate(hid_t file_id, double *hit_rate_ptr) { - H5F_t *file; /* File object for file ID */ + H5VL_t *vol_plugin; + void *obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*d", file_id, hit_rate_ptr); - /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") - if(NULL == hit_rate_ptr) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL hit rate pointer") - /* Go get the current hit rate */ - if(H5AC_get_cache_hit_rate(file->shared->cache, hit_rate_ptr) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_hit_rate() failed.") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + if((ret_value = H5VL_file_optional(obj, vol_plugin, H5VL_FILE_GET_MDC_HR, H5_REQUEST_NULL, + hit_rate_ptr)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get MDC hit rate") done: FUNC_LEAVE_API(ret_value) @@ -2900,25 +1175,25 @@ herr_t H5Fget_mdc_size(hid_t file_id, size_t *max_size_ptr, size_t *min_clean_size_ptr, size_t *cur_size_ptr, int *cur_num_entries_ptr) { - H5F_t *file; /* File object for file ID */ - int32_t cur_num_entries; + H5VL_t *vol_plugin; + void *obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*z*z*z*Is", file_id, max_size_ptr, min_clean_size_ptr, cur_size_ptr, cur_num_entries_ptr); - /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Go get the size data */ - if(H5AC_get_cache_size(file->shared->cache, max_size_ptr, - min_clean_size_ptr, cur_size_ptr, &cur_num_entries) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_size() failed.") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - if(cur_num_entries_ptr != NULL) - *cur_num_entries_ptr = (int)cur_num_entries; + if((ret_value = H5VL_file_optional(obj, vol_plugin, H5VL_FILE_GET_MDC_SIZE, H5_REQUEST_NULL, max_size_ptr, + min_clean_size_ptr, cur_size_ptr, cur_num_entries_ptr)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get MDC size") done: FUNC_LEAVE_API(ret_value) @@ -2948,18 +1223,22 @@ done: herr_t H5Freset_mdc_hit_rate_stats(hid_t file_id) { - H5F_t *file; /* File object for file ID */ + H5VL_t *vol_plugin; + void *obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); - /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Reset the hit rate statistic */ - if(H5AC_reset_cache_hit_rate_stats(file->shared->cache) < 0) + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + if(H5VL_file_optional(obj, vol_plugin, H5VL_FILE_RESET_MDC_HIT_RATE, H5_REQUEST_NULL) < 0) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't reset cache hit rate") done: @@ -2992,40 +1271,31 @@ done: ssize_t H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size) { - H5F_t *f; /* Top file in mount hierarchy */ - size_t len; - ssize_t ret_value; + H5VL_t *vol_plugin = NULL; + void *obj = NULL; + ssize_t ret_value; + H5I_type_t type; FUNC_ENTER_API(FAIL) H5TRACE3("Zs", "ixz", obj_id, name, size); - /* For file IDs, get the file object directly */ - /* (This prevents the H5G_loc() call from returning the file pointer for - * the top file in a mount hierarchy) - */ - if(H5I_get_type(obj_id) == H5I_FILE ) { - if(NULL == (f = (H5F_t *)H5I_object(obj_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") - } /* end if */ - else { - H5G_loc_t loc; /* Object location */ - - /* Get symbol table entry */ - if(H5G_loc(obj_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object ID") - f = loc.oloc->file; - } /* end else */ + type = H5I_get_type(obj_id); + if(H5I_FILE != type && H5I_GROUP != type && H5I_DATATYPE != type && + H5I_DATASET != type && H5I_ATTR != type) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + } - len = HDstrlen(H5F_OPEN_NAME(f)); + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - if(name) { - HDstrncpy(name, H5F_OPEN_NAME(f), MIN(len + 1,size)); - if(len >= size) - name[size-1]='\0'; - } /* end if */ + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* Set return value */ - ret_value = (ssize_t)len; + if(H5VL_file_get(obj, vol_plugin, H5VL_FILE_GET_NAME, H5_REQUEST_NULL, + type, size, name, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file name") done: FUNC_LEAVE_API(ret_value) @@ -3052,8 +1322,10 @@ done: herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo) { - H5F_t *f; /* Top file in mount hierarchy */ - herr_t ret_value = SUCCEED; /* Return value */ + H5VL_t *vol_plugin; + void *obj; + H5I_type_t type; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*x", obj_id, finfo); @@ -3062,45 +1334,23 @@ H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo) if(!finfo) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct") - /* For file IDs, get the file object directly */ - /* (This prevents the H5G_loc() call from returning the file pointer for - * the top file in a mount hierarchy) - */ - if(H5I_get_type(obj_id) == H5I_FILE ) { - if(NULL == (f = (H5F_t *)H5I_object(obj_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") - } /* end if */ - else { - H5G_loc_t loc; /* Object location */ - - /* Get symbol table entry */ - if(H5G_loc(obj_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object ID") - f = loc.oloc->file; - } /* end else */ - HDassert(f->shared); - - /* Reset file info struct */ - HDmemset(finfo, 0, sizeof(*finfo)); - - /* Get the size of the superblock and any superblock extensions */ - if(H5F_super_size(f, H5AC_ind_dxpl_id, &finfo->super.super_size, &finfo->super.super_ext_size) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve superblock sizes") - - /* Get the size of any persistent free space */ - if(H5MF_get_freespace(f, H5AC_ind_dxpl_id, &finfo->free.tot_space, &finfo->free.meta_size) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve free space information") + type = H5I_get_type(obj_id); + if(H5I_FILE != type && H5I_GROUP != type && H5I_DATATYPE != type && + H5I_DATASET != type && H5I_ATTR != type) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + } - /* Check for SOHM info */ - if(H5F_addr_defined(f->shared->sohm_addr)) - if(H5SM_ih_size(f, H5AC_ind_dxpl_id, &finfo->sohm.hdr_size, &finfo->sohm.msgs_info) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve SOHM index & heap storage info") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Set version # fields */ - finfo->super.version = f->shared->sblock->super_vers; - finfo->sohm.version = f->shared->sohm_vers; - finfo->free.version = HDF5_FREESPACE_VERSION; + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + if((ret_value = H5VL_file_optional(obj, vol_plugin, H5VL_FILE_GET_INFO, H5_REQUEST_NULL, + type, finfo)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file info") done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_info2() */ @@ -3125,22 +1375,28 @@ ssize_t H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, H5F_sect_info_t *sect_info/*out*/) { - H5F_t *file; /* Top file in mount hierarchy */ - ssize_t ret_value; /* Return value */ + H5VL_t *vol_plugin; + void *obj; + ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("Zs", "iFmzx", file_id, type, nsects, sect_info); /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") if(sect_info && nsects == 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "nsects must be > 0") - /* Go get the free-space section information in the file */ - if((ret_value = H5MF_get_free_sections(file, H5AC_ind_dxpl_id, type, nsects, sect_info)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + if(H5VL_file_optional(obj, vol_plugin, H5VL_FILE_GET_FREE_SECTIONS, H5_REQUEST_NULL, sect_info, + &ret_value, type, nsects) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get file free sections") done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_free_sections() */ @@ -3163,168 +1419,24 @@ done: herr_t H5Fclear_elink_file_cache(hid_t file_id) { - H5F_t *file; /* File */ + H5VL_t *vol_plugin; + void *obj; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", file_id); - /* Check args */ - if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(file_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* Release the EFC */ - if(file->shared->efc) - if(H5F_efc_release(file->shared->efc) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") + if(H5VL_file_optional(obj, vol_plugin, H5VL_FILE_CLEAR_ELINK_CACHE, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") done: FUNC_LEAVE_API(ret_value) } /* end H5Fclear_elink_file_cache() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_set_grp_btree_shared - * - * Purpose: Set the grp_btree_shared field with a valid ref-count pointer. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * 7/19/11 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_set_grp_btree_shared(H5F_t *f, H5RC_t *rc) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - HDassert(rc); - - f->shared->grp_btree_shared = rc; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5F_set_grp_btree_shared() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_set_sohm_addr - * - * Purpose: Set the sohm_addr field with a new value. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * 7/20/11 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_set_sohm_addr(H5F_t *f, haddr_t addr) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - - f->shared->sohm_addr = addr; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5F_set_sohm_addr() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_set_sohm_vers - * - * Purpose: Set the sohm_vers field with a new value. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * 7/20/11 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_set_sohm_vers(H5F_t *f, unsigned vers) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - - f->shared->sohm_vers = vers; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5F_set_sohm_vers() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_set_sohm_nindexes - * - * Purpose: Set the sohm_nindexes field with a new value. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * 7/20/11 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_set_sohm_nindexes(H5F_t *f, unsigned nindexes) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - - f->shared->sohm_nindexes = nindexes; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5F_set_sohm_nindexes() */ - - -/*------------------------------------------------------------------------- - * Function: H5F_set_store_msg_crt_idx - * - * Purpose: Set the store_msg_crt_idx field with a new value. - * - * Return: Success: SUCCEED - * Failure: FAIL - * - * Programmer: Quincey Koziol - * 7/20/11 - * - *------------------------------------------------------------------------- - */ -herr_t -H5F_set_store_msg_crt_idx(H5F_t *f, hbool_t flag) -{ - /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOERR - - /* Sanity check */ - HDassert(f); - HDassert(f->shared); - - f->shared->store_msg_crt_idx = flag; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5F_set_store_msg_crt_idx() */ - @@ -108,7 +108,8 @@ static const H5I_class_t H5I_VFL_CLS[1] = {{ 0, /* Class flags */ 64, /* Minimum hash size for class */ 0, /* # of reserved IDs for class */ - (H5I_free_t)H5FD_free_cls /* Callback routine for closing objects of this class */ + (H5I_free_t)H5FD_free_cls, /* Callback routine for closing objects of this class */ + NULL /* Callback routine for closing auxilary objects of this class */ }}; diff --git a/src/H5Fdeprec.c b/src/H5Fdeprec.c index e3945ff..ef28e13 100644 --- a/src/H5Fdeprec.c +++ b/src/H5Fdeprec.c @@ -169,5 +169,46 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_info1() */ + +/*------------------------------------------------------------------------- + * Function: H5Fis_hdf5 + * + * Purpose: Check the file signature to detect an HDF5 file. + * + * Bugs: This function is not robust: it only uses the default file + * driver when attempting to open the file when in fact it + * should use all known file drivers. + * + * Return: Success: TRUE/FALSE + * + * Failure: Negative + * + * Programmer: Unknown + * + * Modifications: + * Robb Matzke, 1999-08-02 + * Rewritten to use the virtual file layer. + *------------------------------------------------------------------------- + */ +htri_t +H5Fis_hdf5(const char *name) +{ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("t", "*s", name); + + /* Check args and all the boring stuff. */ + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "no file name specified") + + /* Call private routine */ + if((ret_value = H5F_is_hdf5(name)) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to open file") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Fis_hdf5() */ + #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Fefc.c b/src/H5Fefc.c index 08d27a1..98f1d6b 100644 --- a/src/H5Fefc.c +++ b/src/H5Fefc.c @@ -35,7 +35,8 @@ #include "H5Fpkg.h" /* File access */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ - +#include "H5VLprivate.h" /* VOL */ +#include "H5Iprivate.h" /* IDs */ /* Special values for the "tag" field below */ #define H5F_EFC_TAG_DEFAULT -1 @@ -164,7 +165,7 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, * on the state of the efc. */ if(!efc) { if(NULL == (ret_value = H5F_open(name, flags, fcpl_id, fapl_id, - dxpl_id))) + dxpl_id))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open file") /* Increment the number of open objects to prevent the file from being @@ -237,7 +238,7 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, else { /* Cannot cache file, just open file and return */ if(NULL == (ret_value = H5F_open(name, flags, fcpl_id, fapl_id, - dxpl_id))) + dxpl_id))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open file") /* Increment the number of open objects to prevent the file from @@ -259,8 +260,9 @@ H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, /* Open the file */ if(NULL == (ent->file = H5F_open(name, flags, fcpl_id, fapl_id, - dxpl_id))) + dxpl_id))) HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open file") + open_file = TRUE; /* Increment the number of open objects to prevent the file from being @@ -348,7 +350,6 @@ H5F_efc_close(H5F_t *parent, H5F_t *file) /* Get external file cache */ efc = parent->shared->efc; - /* Check if the EFC exists. If it does not, just call H5F_try_close(). We * support this so clients do not have to make 2 different calls depending * on the state of the efc. */ diff --git a/src/H5Fint.c b/src/H5Fint.c new file mode 100644 index 0000000..bc196a9 --- /dev/null +++ b/src/H5Fint.c @@ -0,0 +1,2130 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5F_init_interface + + +/* Packages needed by this file... */ +#include "H5private.h" /* Generic Functions */ +#include "H5Aprivate.h" /* Attributes */ +#include "H5ACprivate.h" /* Metadata cache */ +#include "H5Dprivate.h" /* Datasets */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* File access */ +#include "H5FDprivate.h" /* File drivers */ +#include "H5Gprivate.h" /* Groups */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Pprivate.h" /* Property lists */ +#include "H5SMprivate.h" /* Shared Object Header Messages */ +#include "H5Tprivate.h" /* Datatypes */ +#include "H5VLnative.h" /* Native Plugin */ +#include "H5VLprivate.h" /* VOL plugins */ + +/* Struct only used by functions H5F_get_objects and H5F_get_objects_cb */ +typedef struct H5F_olist_t { + H5I_type_t obj_type; /* Type of object to look for */ + hid_t *obj_id_list; /* Pointer to the list of open IDs to return */ + size_t *obj_id_count; /* Number of open IDs */ + struct { + hbool_t local; /* Set flag for "local" file searches */ + union { + H5F_file_t *shared; /* Pointer to shared file to look inside */ + const H5F_t *file; /* Pointer to file to look inside */ + } ptr; + } file_info; + size_t list_index; /* Current index in open ID array */ + size_t max_index; /* Maximum # of IDs to put into array */ +} H5F_olist_t; + +/* private prototypes */ +static H5F_t *H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf); +static herr_t H5F_build_actual_name(const H5F_t *f, const struct H5P_genplist_t *fapl, + const char *name, char ** /*out*/ actual_name); +static herr_t H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush); + +/* Declare a free list to manage the H5F_t struct */ +H5FL_DEFINE(H5F_t); + +/* Declare a free list to manage the H5F_file_t struct */ +H5FL_DEFINE(H5F_file_t); + + +/*------------------------------------------------------------------------- + * Function: H5F_init_interface + * + * Purpose: Initialize interface-specific information. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Robb Matzke + * Friday, November 20, 1998 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_init_interface(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_init_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_access_plist + * + * Purpose: Returns a copy of the file access property list of the + * specified file. + * + * NOTE: Make sure that, if you are going to overwrite + * information in the copied property list that was + * previously opened and assigned to the property list, then + * you must close it before overwriting the values. + * + * Return: Success: Object ID for a copy of the file access + * property list. + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Wednesday, May 25, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5F_get_access_plist(H5F_t *f, hbool_t app_ref) +{ + H5P_genplist_t *new_plist; /* New property list */ + H5P_genplist_t *old_plist; /* Old property list */ + void *driver_info=NULL; + unsigned efc_size = 0; + hid_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args */ + HDassert(f); + + /* Make a copy of the default file access property list */ + if(NULL == (old_plist = (H5P_genplist_t *)H5I_object(H5P_LST_FILE_ACCESS_g))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + if((ret_value = H5P_copy_plist(old_plist, app_ref)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "can't copy file access property list") + if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(ret_value))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + /* Copy properties of the file access property list */ + if(H5P_set(new_plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial metadata cache resize config.") + if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache number of slots") + if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache byte size") + if(H5P_set(new_plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set preempt read chunks") + if(H5P_set(new_plist, H5F_ACS_ALIGN_THRHD_NAME, &(f->shared->threshold)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set alignment threshold") + if(H5P_set(new_plist, H5F_ACS_ALIGN_NAME, &(f->shared->alignment)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set alignment") + if(H5P_set(new_plist, H5F_ACS_GARBG_COLCT_REF_NAME, &(f->shared->gc_ref)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set garbage collect reference") + if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set metadata cache size") + if(H5P_set(new_plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't sieve buffer size") + if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'small data' cache size") + if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag") + if(f->shared->efc) + efc_size = H5F_efc_max_nfiles(f->shared->efc); + if(H5P_set(new_plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set elink file cache size") + + /* + * Since we're resetting the driver ID and info, close them if they + * exist in this new property list. + */ + if(H5P_facc_close(ret_value, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTFREE, FAIL, "can't free the old driver information") + + /* Increment the reference count on the driver ID and insert it into the property list */ + if(H5I_inc_ref(f->shared->lf->driver_id, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINC, FAIL, "unable to increment ref count on VFL driver") + if(H5P_set(new_plist, H5F_ACS_FILE_DRV_ID_NAME, &(f->shared->lf->driver_id)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file driver ID") + + /* Set the driver "info" in the property list */ + driver_info = H5FD_fapl_get(f->shared->lf); + if(driver_info != NULL && H5P_set(new_plist, H5F_ACS_FILE_DRV_INFO_NAME, &driver_info) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file driver info") + + /* Set the file close degree appropriately */ + if(f->shared->fc_degree == H5F_CLOSE_DEFAULT && H5P_set(new_plist, H5F_ACS_CLOSE_DEGREE_NAME, &(f->shared->lf->cls->fc_degree)) < 0) { + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree") + } else if(f->shared->fc_degree != H5F_CLOSE_DEFAULT && H5P_set(new_plist, H5F_ACS_CLOSE_DEGREE_NAME, &(f->shared->fc_degree)) < 0) { + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file close degree") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_access_plist() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_obj_count_cb + * + * Purpose: H5F_get_obj_count_cb callback function. It calls in the + * VOL and gets the object count for the file ID passed + * + * Return: TRUE if the value has been added. + * FALSE otherwise. + * + * Programmer: Mohamad Chaarawi + * May 2012 + * + *------------------------------------------------------------------------- + */ +int +H5F_get_obj_count_cb(void UNUSED *obj_ptr, hid_t obj_id, void *key) +{ + H5F_trav_obj_cnt_t *udata = (H5F_trav_obj_cnt_t *)key; + ssize_t obj_count = 0; + H5VL_t *vol_plugin; + void *obj; + int ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + if(H5VL_file_get(obj, vol_plugin, H5VL_FILE_GET_OBJ_COUNT, H5_REQUEST_NULL, + udata->types, &obj_count) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, H5_ITER_ERROR, "unable to get object count in file(s)") + + *(udata->obj_count) += obj_count; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_get_obj_count_cb */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_obj_count + * + * Purpose: Private function return the number of opened object IDs + * (files, datasets, groups, datatypes) in the same file. + * + * Return: SUCCEED on success, FAIL on failure. + * + * Programmer: Raymond Lu + * Wednesday, Dec 5, 2001 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_get_obj_count(const H5F_t *f, unsigned types, hbool_t app_ref, size_t *obj_id_count_ptr) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(obj_id_count_ptr); + + /* Perform the query */ + if((ret_value = H5F_get_objects(f, types, 0, NULL, app_ref, obj_id_count_ptr)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_objects failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_obj_count() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_obj_ids_cb + * + * Purpose: H5F_get_obj_ids_cb callback function. It calls in the + * VOL and gets the object ids for the file ID passed + * + * Return: TRUE if the value has been added. + * FALSE otherwise. + * + * Programmer: Mohamad Chaarawi + * May 2012 + * + *------------------------------------------------------------------------- + */ +int +H5F_get_obj_ids_cb(void UNUSED *obj_ptr, hid_t obj_id, void *key) +{ + H5F_trav_obj_ids_t *udata = (H5F_trav_obj_ids_t *)key; + H5VL_t *vol_plugin; + void *obj; + ssize_t obj_count = 0; + int ret_value = H5_ITER_CONT; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + if(H5VL_file_get(obj, vol_plugin, H5VL_FILE_GET_OBJ_IDS, H5_REQUEST_NULL, udata->types, + udata->max_objs, udata->oid_list, &obj_count) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, H5_ITER_ERROR, "unable to get object count in file(s)") + + *(udata->obj_count) += obj_count; + udata->max_objs -= obj_count; + udata->oid_list += obj_count; + + if(udata->max_objs <= 0) + ret_value = H5_ITER_STOP; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_get_obj_count_cb */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_obj_ids + * + * Purpose: Private function to return a list of opened object IDs. + * + * Return: Non-negative on success; can't fail. + * + * Programmer: Raymond Lu + * Wednesday, Dec 5, 2001 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_get_obj_ids(const H5F_t *f, unsigned types, size_t max_objs, hid_t *oid_list, hbool_t app_ref, size_t *obj_id_count_ptr) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(obj_id_count_ptr); + + /* Perform the query */ + if((ret_value = H5F_get_objects(f, types, max_objs, oid_list, app_ref, obj_id_count_ptr)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_objects failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_obj_ids() */ + + +/*--------------------------------------------------------------------------- + * Function: H5F_get_objects + * + * Purpose: This function is called by H5F_get_obj_count or + * H5F_get_obj_ids to get number of object IDs and/or a + * list of opened object IDs (in return value). + * Return: Non-negative on success; Can't fail. + * + * Programmer: Raymond Lu + * Wednesday, Dec 5, 2001 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr) +{ + size_t obj_id_count=0; /* Number of open IDs */ + H5F_olist_t olist; /* Structure to hold search results */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(obj_id_count_ptr); + + /* Set up search information */ + olist.obj_id_list = (max_index==0 ? NULL : obj_id_list); + olist.obj_id_count = &obj_id_count; + olist.list_index = 0; + olist.max_index = max_index; + + /* Determine if we are searching for local or global objects */ + if(types & H5F_OBJ_LOCAL) { + olist.file_info.local = TRUE; + olist.file_info.ptr.file = f; + } /* end if */ + else { + olist.file_info.local = FALSE; + olist.file_info.ptr.shared = f ? f->shared : NULL; + } /* end else */ + + /* Iterate through file IDs to count the number, and put their + * IDs on the object list. */ + if(types & H5F_OBJ_FILE) { + olist.obj_type = H5I_FILE; + if(H5I_iterate(H5I_FILE, H5F_get_objects_cb, &olist, app_ref) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(1)") + } /* end if */ + + /* Search through dataset IDs to count number of datasets, and put their + * IDs on the object list */ + if(types & H5F_OBJ_DATASET) { + olist.obj_type = H5I_DATASET; + if(H5I_iterate(H5I_DATASET, H5F_get_objects_cb, &olist, app_ref) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(2)") + } /* end if */ + + /* Search through group IDs to count number of groups, and put their + * IDs on the object list */ + if(types & H5F_OBJ_GROUP) { + olist.obj_type = H5I_GROUP; + if(H5I_iterate(H5I_GROUP, H5F_get_objects_cb, &olist, app_ref) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(3)") + } /* end if */ + + /* Search through datatype IDs to count number of named datatypes, and put their + * IDs on the object list */ + if(types & H5F_OBJ_DATATYPE) { + olist.obj_type = H5I_DATATYPE; + if(H5I_iterate(H5I_DATATYPE, H5F_get_objects_cb, &olist, app_ref) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(4)") + } /* end if */ + + /* Search through attribute IDs to count number of attributes, and put their + * IDs on the object list */ + if(types & H5F_OBJ_ATTR) { + olist.obj_type = H5I_ATTR; + if(H5I_iterate(H5I_ATTR, H5F_get_objects_cb, &olist, app_ref) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed(5)") + } /* end if */ + + /* Set the number of objects currently open */ + *obj_id_count_ptr = obj_id_count; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_objects() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_objects_cb + * + * Purpose: H5F_get_objects' callback function. It verifies if an + * object is in the file, and either count it or put its ID + * on the list. + * + * Return: TRUE if the array of object IDs is filled up. + * FALSE otherwise. + * + * Programmer: Raymond Lu + * Wednesday, Dec 5, 2001 + * + *------------------------------------------------------------------------- + */ +int +H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key) +{ + H5F_olist_t *olist = (H5F_olist_t *)key; /* Alias for search info */ + int ret_value = FALSE; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(obj_ptr); + HDassert(olist); + + /* Count file IDs */ + if(olist->obj_type == H5I_FILE) { + if((olist->file_info.local && + (!olist->file_info.ptr.file || (olist->file_info.ptr.file && (H5F_t*)obj_ptr == olist->file_info.ptr.file) )) + || (!olist->file_info.local && + ( !olist->file_info.ptr.shared || (olist->file_info.ptr.shared && ((H5F_t*)obj_ptr)->shared == olist->file_info.ptr.shared) ))) { + /* Add the object's ID to the ID list, if appropriate */ + if(olist->obj_id_list) { + olist->obj_id_list[olist->list_index] = obj_id; + olist->list_index++; + } + + /* Increment the number of open objects */ + if(olist->obj_id_count) + (*olist->obj_id_count)++; + + /* Check if we've filled up the array. Return TRUE only if + * we have filled up the array. Otherwise return FALSE(RET_VALUE is + * preset to FALSE) because H5I_iterate needs the return value of + * FALSE to continue the iteration. */ + if(olist->max_index>0 && olist->list_index>=olist->max_index) + HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */ + } + } /* end if */ + else { /* either count opened object IDs or put the IDs on the list */ + H5O_loc_t *oloc; /* Group entry info for object */ + + switch(olist->obj_type) { + case H5I_ATTR: + oloc = H5A_oloc((H5A_t *)obj_ptr); + break; + + case H5I_GROUP: + oloc = H5G_oloc((H5G_t *)obj_ptr); + break; + + case H5I_DATASET: + oloc = H5D_oloc((H5D_t *)obj_ptr); + break; + + case H5I_DATATYPE: + { + H5T_t *type; + /* Get the actual datatype object that should be the vol_obj */ + if(NULL == (type = (H5T_t *)H5T_get_named_type((H5T_t*)obj_ptr))) + oloc = NULL; + else + oloc = H5T_oloc(type); + break; + } + case H5I_UNINIT: + case H5I_BADID: + case H5I_FILE: + case H5I_DATASPACE: + case H5I_REFERENCE: + case H5I_VFL: + case H5I_VOL: + case H5I_GENPROP_CLS: + case H5I_GENPROP_LST: + case H5I_ERROR_CLASS: + case H5I_ERROR_MSG: + case H5I_ERROR_STACK: + case H5I_NTYPES: + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object") + } /* end switch */ + + if((olist->file_info.local && + ( (!olist->file_info.ptr.file && olist->obj_type == H5I_DATATYPE && H5T_is_immutable((H5T_t *)obj_ptr) == FALSE) + || (!olist->file_info.ptr.file && olist->obj_type != H5I_DATATYPE) + || (oloc && oloc->file == olist->file_info.ptr.file))) + || (!olist->file_info.local && + ((!olist->file_info.ptr.shared && olist->obj_type == H5I_DATATYPE && H5T_is_immutable((H5T_t *)obj_ptr) == FALSE) + || (!olist->file_info.ptr.shared && olist->obj_type != H5I_DATATYPE) + || (oloc && oloc->file && oloc->file->shared == olist->file_info.ptr.shared)))) { + /* Add the object's ID to the ID list, if appropriate */ + if(olist->obj_id_list) { + olist->obj_id_list[olist->list_index] = obj_id; + olist->list_index++; + } /* end if */ + + /* Increment the number of open objects */ + if(olist->obj_id_count) + (*olist->obj_id_count)++; + + /* Check if we've filled up the array. Return TRUE only if + * we have filled up the array. Otherwise return FALSE(RET_VALUE is + * preset to FALSE) because H5I_iterate needs the return value of + * FALSE to continue iterating. */ + if(olist->max_index>0 && olist->list_index>=olist->max_index) + HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */ + } /* end if */ + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_objects_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_is_hdf5 + * + * Purpose: Check the file signature to detect an HDF5 file. + * + * Bugs: This function is not robust: it only uses the default file + * driver when attempting to open the file when in fact it + * should use all known file drivers. + * + * Return: Success: TRUE/FALSE + * + * Failure: Negative + * + * Programmer: Unknown + * + * Modifications: + * Robb Matzke, 1999-08-02 + * Rewritten to use the virtual file layer. + *------------------------------------------------------------------------- + */ +htri_t +H5F_is_hdf5(const char *name) +{ + H5FD_t *file = NULL; /* Low-level file struct */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Open the file at the virtual file layer */ + if(NULL == (file = H5FD_open(name, H5F_ACC_RDONLY, H5P_FILE_ACCESS_DEFAULT, HADDR_UNDEF))) + HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to open file") + + /* The file is an hdf5 file if the hdf5 file signature can be found */ + ret_value = (HADDR_UNDEF != H5F_locate_signature(file, H5AC_ind_dxpl_id)); + +done: + /* Close the file */ + if(file) + if(H5FD_close(file) < 0 && ret_value >= 0) + HDONE_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_is_hdf5() */ + +/*------------------------------------------------------------------------- + * Function: H5F_new + * + * Purpose: Creates a new file object and initializes it. The + * H5Fopen and H5Fcreate functions then fill in various + * fields. If SHARED is a non-null pointer then the shared info + * to which it points has the reference count incremented. + * Otherwise a new, empty shared info struct is created and + * initialized with the specified file access property list. + * + * Errors: + * + * Return: Success: Ptr to a new file struct. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 18 1997 + * + *------------------------------------------------------------------------- + */ +static H5F_t * +H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) +{ + H5F_t *f = NULL, *ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + if(NULL == (f = H5FL_CALLOC(H5F_t))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate top file structure") + f->id_exists = FALSE; + + if(shared) { + HDassert(lf == NULL); + f->shared = shared; + } /* end if */ + else { + H5P_genplist_t *plist; /* Property list */ + unsigned efc_size; /* External file cache size */ + size_t u; /* Local index variable */ + + HDassert(lf != NULL); + if(NULL == (f->shared = H5FL_CALLOC(H5F_file_t))) + HGOTO_ERROR(H5E_FILE, H5E_NOSPACE, NULL, "can't allocate shared file structure") + + f->shared->sohm_addr = HADDR_UNDEF; + f->shared->sohm_vers = HDF5_SHAREDHEADER_VERSION; + for(u = 0; u < NELMTS(f->shared->fs_addr); u++) + f->shared->fs_addr[u] = HADDR_UNDEF; + f->shared->accum.loc = HADDR_UNDEF; + f->shared->lf = lf; + + /* + * Copy the file creation and file access property lists into the + * new file handle. We do this early because some values might need + * to change as the file is being opened. + */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not property list") + f->shared->fcpl_id = H5P_copy_plist(plist, FALSE); + + /* Get the FCPL values to cache */ + if(H5P_get(plist, H5F_CRT_ADDR_BYTE_NUM_NAME, &f->shared->sizeof_addr) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for address") + if(H5P_get(plist, H5F_CRT_OBJ_BYTE_NUM_NAME, &f->shared->sizeof_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for object size") + if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &f->shared->sohm_nindexes) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get number of SOHM indexes") + HDassert(f->shared->sohm_nindexes < 255); + if(H5P_get(plist, H5F_CRT_FILE_SPACE_STRATEGY_NAME, &f->shared->fs_strategy) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file space strategy") + if(H5P_get(plist, H5F_CRT_FREE_SPACE_THRESHOLD_NAME, &f->shared->fs_threshold) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get free-space section threshold") + + /* Get the FAPL values to cache */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") + if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config") + if(H5P_get(plist, H5F_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(f->shared->rdcc_nslots)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache number of slots") + if(H5P_get(plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache byte size") + if(H5P_get(plist, H5F_ACS_PREEMPT_READ_CHUNKS_NAME, &(f->shared->rdcc_w0)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get preempt read chunk") + if(H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(f->shared->threshold)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold") + if(H5P_get(plist, H5F_ACS_ALIGN_NAME, &(f->shared->alignment)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment") + if(H5P_get(plist, H5F_ACS_GARBG_COLCT_REF_NAME,&(f->shared->gc_ref)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get garbage collect reference") + if(H5P_get(plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get sieve buffer size") + if(H5P_get(plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'latest format' flag") + if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->meta_aggr.alloc_size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get metadata cache size") + f->shared->meta_aggr.feature_flag = H5FD_FEAT_AGGREGATE_METADATA; + if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' cache size") + f->shared->sdata_aggr.feature_flag = H5FD_FEAT_AGGREGATE_SMALLDATA; + if(H5P_get(plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get elink file cache size") + if(efc_size > 0) + if(NULL == (f->shared->efc = H5F_efc_create(efc_size))) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't create external file cache") + + /* Get the VFD values to cache */ + f->shared->maxaddr = H5FD_get_maxaddr(lf); + if(!H5F_addr_defined(f->shared->maxaddr)) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "bad maximum address from VFD") + if(H5FD_get_feature_flags(lf, &f->shared->feature_flags) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get feature flags from VFD") + if(H5FD_get_fs_type_map(lf, f->shared->fs_type_map) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get free space type mapping from VFD") + if(H5MF_init_merge_flags(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "problem initializing free space merge flags") + f->shared->tmp_addr = f->shared->maxaddr; + /* Disable temp. space allocation for parallel I/O (for now) */ + /* (When we've arranged to have the relocated metadata addresses (and + * sizes) broadcast during the "end of epoch" metadata operations, + * this can be enabled - QAK) + */ + /* (This should be disabled when the metadata journaling branch is + * merged into the trunk and journaling is enabled, at least until + * we make it work. - QAK) + */ + f->shared->use_tmp_space = !H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI); + + /* + * Create a metadata cache with the specified number of elements. + * The cache might be created with a different number of elements and + * the access property list should be updated to reflect that. + */ + if(H5AC_create(f, &(f->shared->mdc_initCacheCfg)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create metadata cache") + + /* Create the file's "open object" information */ + if(H5FO_create(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object data structure") + + /* Add new "shared" struct to list of open files */ + if(H5F_sfile_add(f->shared) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to append to list of open files") + } /* end else */ + + f->shared->nrefs++; + + /* Create the file's "top open object" information */ + if(H5FO_top_create(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object data structure") + + /* Set return value */ + ret_value = f; + +done: + if(!ret_value && f) { + if(!shared) + f->shared = H5FL_FREE(H5F_file_t, f->shared); + f = H5FL_FREE(H5F_t, f); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_new() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_dest + * + * Purpose: Destroys a file structure. This function flushes the cache + * but doesn't do any other cleanup other than freeing memory + * for the file struct. The shared info for the file is freed + * only when its reference count reaches zero. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 18 1997 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + + if(1 == f->shared->nrefs) { + /* Flush at this point since the file will be closed. + * Only try to flush the file if it was opened with write access, and if + * the caller requested a flush. + */ + if((H5F_ACC_RDWR & H5F_INTENT(f)) && flush) + if(H5F_flush(f, dxpl_id, TRUE) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + + /* Release the external file cache */ + if(f->shared->efc) { + if(H5F_efc_destroy(f->shared->efc) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't destroy external file cache") + f->shared->efc = NULL; + } /* end if */ + + /* Release objects that depend on the superblock being initialized */ + if(f->shared->sblock) { + /* Shutdown file free space manager(s) */ + /* (We should release the free space information now (before truncating + * the file and before the metadata cache is shut down) since the + * free space manager is holding some data structures in memory + * and also because releasing free space can shrink the file's + * 'eoa' value) + */ + if(H5F_ACC_RDWR & H5F_INTENT(f)) { + if(H5MF_close(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file free space info") + + /* Flush the file again (if requested), as shutting down the + * free space manager may dirty some data structures again. + */ + if(flush) + if(H5F_flush(f, dxpl_id, TRUE) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + } /* end if */ + + /* Unpin the superblock, since we're about to destroy the cache */ + if(H5AC_unpin_entry(f->shared->sblock) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin superblock") + f->shared->sblock = NULL; + } /* end if */ + + /* Remove shared file struct from list of open files */ + if(H5F_sfile_remove(f->shared) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + + /* Shutdown the metadata cache */ + if(H5AC_dest(f, dxpl_id)) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + + /* + * Do not close the root group since we didn't count it, but free + * the memory associated with it. + */ + if(f->shared->root_grp) { + /* Free the root group */ + if(H5G_root_free(f->shared->root_grp) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + f->shared->root_grp = NULL; + } /* end if */ + + /* Destroy other components of the file */ + if(H5F_accum_reset(f, dxpl_id, TRUE) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + if(H5FO_dest(f) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + f->shared->cwfs = (struct H5HG_heap_t **)H5MM_xfree(f->shared->cwfs); + if(H5G_node_close(f) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "problems closing file") + + /* Destroy file creation properties */ + if(H5I_GENPROP_LST != H5I_get_type(f->shared->fcpl_id)) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_BADTYPE, FAIL, "not a property list") + if(H5I_dec_ref(f->shared->fcpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close property list") + + /* Only truncate the file on an orderly close, with write-access */ + if(f->closing && (H5F_ACC_RDWR & H5F_INTENT(f))) { + /* Truncate the file to the current allocated size */ + if(H5FD_truncate(f->shared->lf, dxpl_id, (unsigned)TRUE) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_WRITEERROR, FAIL, "low level truncate failed") + } /* end if */ + + /* Close the file */ + if(H5FD_close(f->shared->lf) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close file") + + /* Free mount table */ + f->shared->mtab.child = (H5F_mount_t *)H5MM_xfree(f->shared->mtab.child); + f->shared->mtab.nalloc = 0; + + /* Destroy shared file struct */ + f->shared = (H5F_file_t *)H5FL_FREE(H5F_file_t, f->shared); + + } else if(f->shared->nrefs > 0) { + /* + * There are other references to the shared part of the file. + * Only decrement the reference count. + */ + --f->shared->nrefs; + } + + /* Free the non-shared part of the file */ + f->open_name = (char *)H5MM_xfree(f->open_name); + f->actual_name = (char *)H5MM_xfree(f->actual_name); + f->extpath = (char *)H5MM_xfree(f->extpath); + if(H5FO_top_dest(f) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "problems closing file") + f->shared = NULL; + f = H5FL_FREE(H5F_t, f); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_dest() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_open + * + * Purpose: Opens (or creates) a file. This function understands the + * following flags which are similar in nature to the Posix + * open(2) flags. + * + * H5F_ACC_RDWR: Open with read/write access. If the file is + * currently open for read-only access then it + * will be reopened. Absence of this flag + * implies read-only access. + * + * H5F_ACC_CREAT: Create a new file if it doesn't exist yet. + * The permissions are 0666 bit-wise AND with + * the current umask. H5F_ACC_WRITE must also + * be specified. + * + * H5F_ACC_EXCL: This flag causes H5F_open() to fail if the + * file already exists. + * + * H5F_ACC_TRUNC: The file is truncated and a new HDF5 superblock + * is written. This operation will fail if the + * file is already open. + * + * Unlinking the file name from the group directed graph while + * the file is opened causes the file to continue to exist but + * one will not be able to upgrade the file from read-only + * access to read-write access by reopening it. Disk resources + * for the file are released when all handles to the file are + * closed. NOTE: This paragraph probably only applies to Unix; + * deleting the file name in other OS's has undefined results. + * + * The CREATE_PARMS argument is optional. A null pointer will + * cause the default file creation parameters to be used. + * + * The ACCESS_PARMS argument is optional. A null pointer will + * cause the default file access parameters to be used. + * + * Return: Success: A new file pointer. + * Failure: NULL + * + * Programmer: Robb Matzke + * Tuesday, September 23, 1997 + * + *------------------------------------------------------------------------- + */ +H5F_t * +H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, + hid_t dxpl_id) +{ + H5F_t *file = NULL; /*the success return value */ + H5F_file_t *shared = NULL; /*shared part of `file' */ + H5FD_t *lf = NULL; /*file driver part of `shared' */ + unsigned tent_flags; /*tentative flags */ + H5FD_class_t *drvr; /*file driver class info */ + H5P_genplist_t *a_plist; /*file access property list */ + H5F_close_degree_t fc_degree; /*file close degree */ + H5F_t *ret_value; /*actual return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* + * If the driver has a `cmp' method then the driver is capable of + * determining when two file handles refer to the same file and the + * library can insure that when the application opens a file twice + * that the two handles coordinate their operations appropriately. + * Otherwise it is the application's responsibility to never open the + * same file more than once at a time. + */ + if(NULL == (drvr = H5FD_get_class(fapl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "unable to retrieve VFL class") + + /* + * Opening a file is a two step process. First we try to open the + * file in a way which doesn't affect its state (like not truncating + * or creating it) so we can compare it with files that are already + * open. If that fails then we try again with the full set of flags + * (only if they're different than the original failed attempt). + * However, if the file driver can't distinquish between files then + * there's no reason to open the file tentatively because it's the + * application's responsibility to prevent this situation (there's no + * way for us to detect it here anyway). + */ + if(drvr->cmp) + tent_flags = flags & ~(H5F_ACC_CREAT|H5F_ACC_TRUNC|H5F_ACC_EXCL); + else + tent_flags = flags; + + if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { + if(tent_flags == flags) { +#ifndef H5_USING_MEMCHECKER + time_t mytime = HDtime(NULL); + + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags) +#else /* H5_USING_MEMCHECKER */ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags) +#endif /* H5_USING_MEMCHECKER */ + } /* end if */ + H5E_clear_stack(NULL); + tent_flags = flags; + if(NULL == (lf = H5FD_open(name, tent_flags, fapl_id, HADDR_UNDEF))) { +#ifndef H5_USING_MEMCHECKER + time_t mytime = HDtime(NULL); + + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: time = %s, name = '%s', tent_flags = %x", HDctime(&mytime), name, tent_flags) +#else /* H5_USING_MEMCHECKER */ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', tent_flags = %x", name, tent_flags) +#endif /* H5_USING_MEMCHECKER */ + } /* end if */ + } /* end if */ + + /* Is the file already open? */ + if((shared = H5F_sfile_search(lf)) != NULL) { + /* + * The file is already open, so use that one instead of the one we + * just opened. We only one one H5FD_t* per file so one doesn't + * confuse the other. But fail if this request was to truncate the + * file (since we can't do that while the file is open), or if the + * request was to create a non-existent file (since the file already + * exists), or if the new request adds write access (since the + * readers don't expect the file to change under them). + */ + if(H5FD_close(lf) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") + if(flags & H5F_ACC_TRUNC) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to truncate a file which is already open") + if(flags & H5F_ACC_EXCL) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file exists") + if((flags & H5F_ACC_RDWR) && 0 == (shared->flags & H5F_ACC_RDWR)) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "file is already open for read-only") + + /* Allocate new "high-level" file struct */ + if((file = H5F_new(shared, fcpl_id, fapl_id, NULL)) == NULL) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") + } /* end if */ + else { + /* Check if tentative open was good enough */ + if(flags != tent_flags) { + /* + * This file is not yet open by the library and the flags we used to + * open it are different than the desired flags. Close the tentative + * file and open it for real. + */ + if(H5FD_close(lf) < 0) { + file = NULL; /*to prevent destruction of wrong file*/ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to close low-level file info") + } /* end if */ + if(NULL == (lf = H5FD_open(name, flags, fapl_id, HADDR_UNDEF))) { + file = NULL; /*to prevent destruction of wrong file*/ + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") + } /* end if */ + } /* end if */ + + if(NULL == (file = H5F_new(NULL, fcpl_id, fapl_id, lf))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create new file object") + file->shared->flags = flags; + } /* end else */ + + /* Short cuts */ + shared = file->shared; + lf = shared->lf; + + /* + * The intent at the top level file struct are not necessarily the same as + * the flags at the bottom. The top level describes how the file can be + * accessed through the HDF5 library. The bottom level describes how the + * file can be accessed through the C library. + */ + file->intent = flags; + file->open_name = H5MM_xstrdup(name); + + /* + * Read or write the file superblock, depending on whether the file is + * empty or not. + */ + if(0 == H5FD_get_eof(lf) && (flags & H5F_ACC_RDWR)) { + /* + * We've just opened a fresh new file (or truncated one). We need + * to create & write the superblock. + */ + + /* Initialize information about the superblock and allocate space for it */ + /* (Writes superblock extension messages, if there are any) */ + if(H5F_super_init(file, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to allocate file superblock") + + /* Create and open the root group */ + /* (This must be after the space for the superblock is allocated in + * the file, since the superblock must be at offset 0) + */ + if(H5G_mkroot(file, dxpl_id, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group") + } else if (1 == shared->nrefs) { + /* Read the superblock if it hasn't been read before. */ + if(H5F_super_read(file, dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock") + + /* Open the root group */ + if(H5G_mkroot(file, dxpl_id, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group") + } /* end if */ + + /* Get the file access property list, for future queries */ + if(NULL == (a_plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list") + + /* + * Decide the file close degree. If it's the first time to open the + * file, set the degree to access property list value; if it's the + * second time or later, verify the access property list value matches + * the degree in shared file structure. + */ + if(H5P_get(a_plist, H5F_ACS_CLOSE_DEGREE_NAME, &fc_degree) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get file close degree") + + if(shared->nrefs == 1) { + if(fc_degree == H5F_CLOSE_DEFAULT) + shared->fc_degree = lf->cls->fc_degree; + else + shared->fc_degree = fc_degree; + } else if(shared->nrefs > 1) { + if(fc_degree == H5F_CLOSE_DEFAULT && shared->fc_degree != lf->cls->fc_degree) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match") + if(fc_degree != H5F_CLOSE_DEFAULT && fc_degree != shared->fc_degree) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "file close degree doesn't match") + } /* end if */ + + /* Formulate the absolute path for later search of target file for external links */ + if(H5_build_extpath(name, &file->extpath) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build extpath") + + /* Formulate the actual file name, after following symlinks, etc. */ + if(H5F_build_actual_name(file, a_plist, name, &file->actual_name) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to build actual name") + + /* Success */ + ret_value = file; + +done: + if(!ret_value && file) + if(H5F_dest(file, dxpl_id, FALSE) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_flush + * + * Purpose: Flushes cached data. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 29 1997 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_flush(H5F_t *f, hid_t dxpl_id, hbool_t closing) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check arguments */ + HDassert(f); + + /* Flush any cached dataset storage raw data */ + if(H5D_flush(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache") + + /* Release any space allocated to space aggregators, so that the eoa value + * corresponds to the end of the space written to in the file. + */ + /* (needs to happen before cache flush, with superblock write, since the + * 'eoa' value is written in superblock -QAK) + */ + if(H5MF_free_aggrs(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release file space") + + /* Flush the entire metadata cache */ + if(H5AC_flush(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache") + + /* Flush out the metadata accumulator */ + if(H5F_accum_flush(f, dxpl_id) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_IO, H5E_CANTFLUSH, FAIL, "unable to flush metadata accumulator") + + /* Flush file buffers to disk. */ + if(H5FD_flush(f->shared->lf, dxpl_id, closing) < 0) + /* Push error, but keep going*/ + HDONE_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_flush() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_close + * + * Purpose: Closes a file or causes the close operation to be pended. + * This function is called two ways: from the API it gets called + * by H5Fclose->H5I_dec_ref->H5F_close when H5I_dec_ref() + * decrements the file ID reference count to zero. The file ID + * is removed from the H5I_FILE group by H5I_dec_ref() just + * before H5F_close() is called. If there are open object + * headers then the close is pended by moving the file to the + * H5I_FILE_CLOSING ID group (the f->closing contains the ID + * assigned to file). + * + * This function is also called directly from H5O_close() when + * the last object header is closed for the file and the file + * has a pending close. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Tuesday, September 23, 1997 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_close(H5F_t *f) +{ + herr_t ret_value = SUCCEED; /* Return value */ + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(f); + HDassert(f->id_exists); /* This routine should only be called when a file ID's ref count drops to zero */ + + /* Perform checks for "semi" file close degree here, since closing the + * file is not allowed if there are objects still open */ + if(f->shared->fc_degree == H5F_CLOSE_SEMI) { + unsigned nopen_files = 0; /* Number of open files in file/mount hierarchy */ + unsigned nopen_objs = 0; /* Number of open objects in file/mount hierarchy */ + + /* Get the number of open objects and open files on this file/mount hierarchy */ + if(H5F_mount_count_ids(f, &nopen_files, &nopen_objs) < 0) + HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy") + + /* If there are no other file IDs open on this file/mount hier., but + * there are still open objects, issue an error and bail out now, + * without decrementing the file ID's reference count and triggering + * a "real" attempt at closing the file */ + if(nopen_files == 1 && nopen_objs > 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, there are objects still open") + } /* end if */ + + /* Reset the file ID for this file */ + f->id_exists = FALSE; + + /* Attempt to close the file/mount hierarchy */ + if(H5F_try_close(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_try_close + * + * Purpose: Attempts to close a file due to one of several actions: + * - The reference count on the file ID dropped to zero + * - The last open object was closed in the file + * - The file was unmounted + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, July 19, 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_try_close(H5F_t *f) +{ + unsigned nopen_files = 0; /* Number of open files in file/mount hierarchy */ + unsigned nopen_objs = 0; /* Number of open objects in file/mount hierarchy */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + + /* Check if this file is already in the process of closing */ + if(f->closing) + HGOTO_DONE(SUCCEED) + + /* Get the number of open objects and open files on this file/mount hierarchy */ + if(H5F_mount_count_ids(f, &nopen_files, &nopen_objs) < 0) + HGOTO_ERROR(H5E_SYM, H5E_MOUNT, FAIL, "problem checking mount hierarchy") + + /* + * Close file according to close degree: + * + * H5F_CLOSE_WEAK: if there are still objects open, wait until + * they are all closed. + * H5F_CLOSE_SEMI: if there are still objects open, return fail; + * otherwise, close file. + * H5F_CLOSE_STRONG: if there are still objects open, close them + * first, then close file. + */ + switch(f->shared->fc_degree) { + case H5F_CLOSE_WEAK: + /* + * If file or object IDS are still open then delay deletion of + * resources until they have all been closed. Flush all + * caches and update the object header anyway so that failing to + * close all objects isn't a major problem. + */ + if((nopen_files + nopen_objs) > 0) + HGOTO_DONE(SUCCEED) + break; + + case H5F_CLOSE_SEMI: + /* Can leave safely if file IDs are still open on this file */ + if(nopen_files > 0) + HGOTO_DONE(SUCCEED) + + /* Sanity check: If close degree if "semi" and we have gotten this + * far and there are objects left open, bail out now */ + HDassert(nopen_files == 0 && nopen_objs == 0); + + /* If we've gotten this far (ie. there are no open objects in the file), fall through to flush & close */ + break; + + case H5F_CLOSE_STRONG: + /* If there are other open files in the hierarchy, we can leave now */ + if(nopen_files > 0) + HGOTO_DONE(SUCCEED) + + /* If we've gotten this far (ie. there are no open file IDs in the file/mount hierarchy), fall through to flush & close */ + break; + + case H5F_CLOSE_DEFAULT: + default: + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close file, unknown file close degree") + } /* end switch */ + + /* Mark this file as closing (prevents re-entering file shutdown code below) */ + f->closing = TRUE; + + /* If the file close degree is "strong", close all the open objects in this file */ + if(f->shared->fc_degree == H5F_CLOSE_STRONG) { + HDassert(nopen_files == 0); + + /* Forced close of all opened objects in this file */ + if(f->nopen_objs > 0) { + size_t obj_count; /* # of open objects */ + hid_t objs[128]; /* Array of objects to close */ + herr_t result; /* Local result from obj ID query */ + size_t u; /* Local index variable */ + + /* Get the list of IDs of open dataset, group, & attribute objects */ + while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATASET | H5F_OBJ_GROUP | H5F_OBJ_ATTR, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0 + && obj_count != 0 ) { + + /* Try to close all the open objects in this file */ + for(u = 0; u < obj_count; u++) + if(H5I_dec_ref(objs[u]) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object") + } /* end while */ + if(result < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(1)") + + /* Get the list of IDs of open named datatype objects */ + /* (Do this separately from the dataset & attribute IDs, because + * they could be using one of the named datatypes and then the + * open named datatype ID will get closed twice) + */ + while((result = H5F_get_obj_ids(f, H5F_OBJ_LOCAL | H5F_OBJ_DATATYPE, (int)(sizeof(objs) / sizeof(objs[0])), objs, FALSE, &obj_count)) <= 0 + && obj_count != 0) { + + /* Try to close all the open objects in this file */ + for(u = 0; u < obj_count; u++) + if(H5I_dec_ref(objs[u]) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CLOSEERROR, FAIL, "can't close object") + } /* end while */ + if(result < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed(2)") + } /* end if */ + } /* end if */ + + /* Check if this is a child file in a mounting hierarchy & proceed up the + * hierarchy if so. + */ + if(f->parent) { + if(H5F_try_close(f->parent) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close parent file") + } + /* Unmount and close each child before closing the current file. */ + if(H5F_close_mounts(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child files") + + /* If there is more than one reference to the shared file struct and the + * file has an external file cache, we should see if it can be closed. This + * can happen if a cycle is formed with external file caches */ + if(f->shared->efc && (f->shared->nrefs > 1)) + if(H5F_efc_try_close(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't attempt to close EFC") + + /* Delay flush until the shared file struct is closed, in H5F_dest. If the + * application called H5Fclose, it would have been flushed in that function + * (unless it will have been flushed in H5F_dest anyways). */ + + /* + * Destroy the H5F_t struct and decrement the reference count for the + * shared H5F_file_t struct. If the reference count for the H5F_file_t + * struct reaches zero then destroy it also. + */ + if(H5F_dest(f, H5AC_dxpl_id, TRUE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problems closing file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_try_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_reopen + * + * Purpose: Reopen a file. The new file handle which is returned points + * to the same file as the specified file handle. Both handles + * share caches and other information. The only difference + * between the handles is that the new handle is not mounted + * anywhere and no files are mounted on it. + * + * Return: Success: New file ID + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Friday, October 16, 1998 + * + * Modifications: + * Quincey Koziol, May 14, 2002 + * Keep old file's read/write intent in reopened file. + * + *------------------------------------------------------------------------- + */ +H5F_t * +H5F_reopen(H5F_t *f) +{ + H5F_t *ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Get a new "top level" file struct, sharing the same "low level" file struct */ + if(NULL == (ret_value = H5F_new(f->shared, H5P_FILE_CREATE_DEFAULT, + H5P_FILE_ACCESS_DEFAULT, NULL))) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to reopen file") + + /* Keep old file's read/write intent in new file */ + ret_value->intent = f->intent; + /* Duplicate old file's names */ + ret_value->open_name = H5MM_xstrdup(f->open_name); + ret_value->actual_name = H5MM_xstrdup(f->actual_name); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_reopen() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_incr_nopen_objs + * + * Purpose: Increment the number of open objects for a file. + * + * Return: Success: The number of open objects, after the increment + * + * Failure: (can't happen) + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 6 2007 + * + *------------------------------------------------------------------------- + */ +unsigned +H5F_incr_nopen_objs(H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + + FUNC_LEAVE_NOAPI(++f->nopen_objs) +} /* end H5F_incr_nopen_objs() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_decr_nopen_objs + * + * Purpose: Decrement the number of open objects for a file. + * + * Return: Success: The number of open objects, after the decrement + * + * Failure: (can't happen) + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Mar 6 2007 + * + *------------------------------------------------------------------------- + */ +unsigned +H5F_decr_nopen_objs(H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + + FUNC_LEAVE_NOAPI(--f->nopen_objs) +} /* end H5F_decr_nopen_objs() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_build_actual_name + * + * Purpose: Retrieve the name of a file, after following symlinks, etc. + * + * Note: Currently only working for "POSIX I/O compatible" VFDs + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Quincey Koziol + * November 25, 2009 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_build_actual_name(const H5F_t *f, const H5P_genplist_t *fapl, const char *name, + char **actual_name/*out*/) +{ + hid_t new_fapl_id = -1; /* ID for duplicated FAPL */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(f); + HDassert(fapl); + HDassert(name); + HDassert(actual_name); + + /* Clear actual name pointer to begin with */ + *actual_name = NULL; + +/* Assume that if the OS can't create symlinks, that we don't need to worry + * about resolving them either. -QAK + */ +#ifdef H5_HAVE_SYMLINK + /* Check for POSIX I/O compatible file handle */ + if(H5F_HAS_FEATURE(f, H5FD_FEAT_POSIX_COMPAT_HANDLE)) { + h5_stat_t lst; /* Stat info from lstat() call */ + + /* Call lstat() on the file's name */ + if(HDlstat(name, &lst) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve stat info for file") + + /* Check for symbolic link */ + if(S_IFLNK == (lst.st_mode & S_IFMT)) { + H5P_genplist_t *new_fapl; /* Duplicated FAPL */ + int *fd; /* POSIX I/O file descriptor */ + h5_stat_t st; /* Stat info from stat() call */ + h5_stat_t fst; /* Stat info from fstat() call */ + char realname[PATH_MAX]; /* Fully resolved path name of file */ + hbool_t want_posix_fd; /* Flag for retrieving file descriptor from VFD */ + + /* Perform a sanity check that the file or link wasn't switched + * between when we opened it and when we called lstat(). This is + * according to the security best practices for lstat() documented + * here: https://www.securecoding.cert.org/confluence/display/seccode/POS35-C.+Avoid+race+conditions+while+checking+for+the+existence+of+a+symbolic+link + */ + + /* Copy the FAPL object to modify */ + if((new_fapl_id = H5P_copy_plist(fapl, FALSE)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy file access property list") + if(NULL == (new_fapl = (H5P_genplist_t *)H5I_object(new_fapl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, FAIL, "can't get property list") + + /* Set the character encoding on the new property list */ + want_posix_fd = TRUE; + if(H5P_set(new_fapl, H5F_ACS_WANT_POSIX_FD_NAME, &want_posix_fd) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding") + + /* Retrieve the file handle */ + if(H5F_get_vfd_handle(f, new_fapl_id, (void **)&fd) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve POSIX file descriptor") + + /* Stat the filename we're resolving */ + if(HDstat(name, &st) < 0) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to stat file") + + /* Stat the file we opened */ + if(HDfstat(*fd, &fst) < 0) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, FAIL, "unable to fstat file") + + /* Verify that the files are really the same */ + if(st.st_mode != fst.st_mode || st.st_ino != fst.st_ino || st.st_dev != fst.st_dev) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "files' st_ino or st_dev fields changed!") + + /* Get the resolved path for the file name */ + if(NULL == HDrealpath(name, realname)) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve real path for file") + + /* Duplicate the resolved path for the file name */ + if(NULL == (*actual_name = (char *)H5MM_strdup(realname))) + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate real path") + } /* end if */ + } /* end if */ +#endif /* H5_HAVE_SYMLINK */ + + /* Check if we've resolved the file's name */ + if(NULL == *actual_name) { + /* Just duplicate the name used to open the file */ + if(NULL == (*actual_name = (char *)H5MM_strdup(name))) + HGOTO_ERROR(H5E_FILE, H5E_CANTALLOC, FAIL, "can't duplicate open name") + } /* end else */ + +done: + if(new_fapl_id > 0 && H5Pclose(new_fapl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close duplicated FAPL") + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_build_actual_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_addr_encode_len + * + * Purpose: Encodes an address into the buffer pointed to by *PP and + * then increments the pointer to the first byte after the + * address. An undefined value is stored as all 1's. + * + * Return: void + * + * Programmer: Robb Matzke + * Friday, November 7, 1997 + * + *------------------------------------------------------------------------- + */ +void +H5F_addr_encode_len(size_t addr_len, uint8_t **pp/*in,out*/, haddr_t addr) +{ + unsigned u; /* Local index variable */ + + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(addr_len); + HDassert(pp && *pp); + + if(H5F_addr_defined(addr)) { + for(u = 0; u < addr_len; u++) { + *(*pp)++ = (uint8_t)(addr & 0xff); + addr >>= 8; + } /* end for */ + HDassert("overflow" && 0 == addr); + } /* end if */ + else { + for(u = 0; u < addr_len; u++) + *(*pp)++ = 0xff; + } /* end else */ + + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_addr_encode_len() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_addr_encode + * + * Purpose: Encodes an address into the buffer pointed to by *PP and + * then increments the pointer to the first byte after the + * address. An undefined value is stored as all 1's. + * + * Return: void + * + * Programmer: Robb Matzke + * Friday, November 7, 1997 + * + *------------------------------------------------------------------------- + */ +void +H5F_addr_encode(const H5F_t *f, uint8_t **pp/*in,out*/, haddr_t addr) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + + H5F_addr_encode_len(H5F_SIZEOF_ADDR(f), pp, addr); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_addr_encode() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_addr_decode_len + * + * Purpose: Decodes an address from the buffer pointed to by *PP and + * updates the pointer to point to the next byte after the + * address. + * + * If the value read is all 1's then the address is returned + * with an undefined value. + * + * Return: void + * + * Programmer: Robb Matzke + * Friday, November 7, 1997 + * + *------------------------------------------------------------------------- + */ +void +H5F_addr_decode_len(size_t addr_len, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) +{ + hbool_t all_zero = TRUE; /* True if address was all zeroes */ + unsigned u; /* Local index variable */ + + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(addr_len); + HDassert(pp && *pp); + HDassert(addr_p); + + /* Reset value in destination */ + *addr_p = 0; + + /* Decode bytes from address */ + for(u = 0; u < addr_len; u++) { + uint8_t c; /* Local decoded byte */ + + /* Get decoded byte (and advance pointer) */ + c = *(*pp)++; + + /* Check for non-undefined address byte value */ + if(c != 0xff) + all_zero = FALSE; + + if(u < sizeof(*addr_p)) { + haddr_t tmp = c; /* Local copy of address, for casting */ + + /* Shift decoded byte to correct position */ + tmp <<= (u * 8); /*use tmp to get casting right */ + + /* Merge into already decoded bytes */ + *addr_p |= tmp; + } /* end if */ + else + if(!all_zero) + HDassert(0 == **pp); /*overflow */ + } /* end for */ + + /* If 'all_zero' is still TRUE, the address was entirely composed of '0xff' + * bytes, which is the encoded form of 'HADDR_UNDEF', so set the destination + * to that value */ + if(all_zero) + *addr_p = HADDR_UNDEF; + + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_addr_decode_len() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_addr_decode + * + * Purpose: Decodes an address from the buffer pointed to by *PP and + * updates the pointer to point to the next byte after the + * address. + * + * If the value read is all 1's then the address is returned + * with an undefined value. + * + * Return: void + * + * Programmer: Robb Matzke + * Friday, November 7, 1997 + * + *------------------------------------------------------------------------- + */ +void +H5F_addr_decode(const H5F_t *f, const uint8_t **pp/*in,out*/, haddr_t *addr_p/*out*/) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(f); + + H5F_addr_decode_len(H5F_SIZEOF_ADDR(f), pp, addr_p); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_addr_decode() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_file_image + * + * Purpose: Private version of H5Fget_file_image + * + * Return: Success: Bytes copied / number of bytes needed. + * Failure: negative value + * + * Programmer: John Mainzer + * 11/15/11 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5F_get_file_image(H5F_t *file, void *buf_ptr, size_t buf_len) +{ + H5FD_t *fd_ptr; /* file driver */ + haddr_t eoa; /* End of file address */ + ssize_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Check args */ + if(!file || !file->shared || !file->shared->lf) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "file_id yields invalid file pointer") + fd_ptr = file->shared->lf; + if(!fd_ptr->cls) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "fd_ptr yields invalid class pointer") + + /* the address space used by the split and multi file drivers is not + * a good fit for this call. Since the plan is to depreciate these + * drivers anyway, don't bother to do a "force fit". + * + * The following clause tests for the multi file driver, and fails + * if the supplied file has the multi file driver as its top level + * file driver. However, this test will not work if there is some + * other file driver sitting on top of the multi file driver. + * + * I'm not sure if this is possible at present, but in all likelyhood, + * it will become possible in the future. On the other hand, we may + * remove the split/multi file drivers before then. + * + * I am leaving this solution in for now, but we should review it, + * and improve the solution if necessary. + * + * JRM -- 11/11/22 + */ + if(HDstrcmp(fd_ptr->cls->name, "multi") == 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Not supported for multi file driver.") + + /* While the family file driver is conceptually fully compatible + * with the get file image operation, it sets a file driver message + * in the super block that prevents the image being opened with any + * driver other than the family file driver. Needless to say, this + * rather defeats the purpose of the get file image operation. + * + * While this problem is quire solvable, the required time and + * resources are lacking at present. Hence, for now, we don't + * allow the get file image operation to be perfomed on files + * opened with the family file driver. + * + * Observe that the following test only looks at the top level + * driver, and fails if there is some other driver sitting on to + * of the family file driver. + * + * I don't think this can happen at present, but that may change + * in the future. + * JRM -- 12/21/11 + */ + if(HDstrcmp(fd_ptr->cls->name, "family") == 0) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "Not supported for family file driver.") + + + /* Go get the actual file size */ + if(HADDR_UNDEF == (eoa = H5FD_get_eoa(file->shared->lf, H5FD_MEM_DEFAULT))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") + + /* set ret_value = to eoa -- will overwrite this if appropriate */ + ret_value = (ssize_t)eoa; + + /* test to see if a buffer was provided -- if not, we are done */ + if(buf_ptr != NULL) { + size_t space_needed; /* size of file image */ + + /* Check for buffer too small */ + if((haddr_t)buf_len < eoa) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "supplied buffer too small") + + space_needed = (size_t)eoa; + + /* read in the file image */ + /* (Note compensation for base address addition in internal routine) */ + if(H5FD_read(fd_ptr, H5AC_ind_dxpl_id, H5FD_MEM_DEFAULT, 0, space_needed, buf_ptr) < 0) + HGOTO_ERROR(H5E_FILE, H5E_READERROR, FAIL, "file image read request failed") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5F_get_file_image() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_set_grp_btree_shared + * + * Purpose: Set the grp_btree_shared field with a valid ref-count pointer. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * 7/19/11 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_set_grp_btree_shared(H5F_t *f, H5RC_t *rc) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + HDassert(rc); + + f->shared->grp_btree_shared = rc; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_set_grp_btree_shared() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_set_sohm_addr + * + * Purpose: Set the sohm_addr field with a new value. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * 7/20/11 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_set_sohm_addr(H5F_t *f, haddr_t addr) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + + f->shared->sohm_addr = addr; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_set_sohm_addr() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_set_sohm_vers + * + * Purpose: Set the sohm_vers field with a new value. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * 7/20/11 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_set_sohm_vers(H5F_t *f, unsigned vers) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + + f->shared->sohm_vers = vers; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_set_sohm_vers() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_set_sohm_nindexes + * + * Purpose: Set the sohm_nindexes field with a new value. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * 7/20/11 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_set_sohm_nindexes(H5F_t *f, unsigned nindexes) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + + f->shared->sohm_nindexes = nindexes; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_set_sohm_nindexes() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_set_store_msg_crt_idx + * + * Purpose: Set the store_msg_crt_idx field with a new value. + * + * Return: Success: SUCCEED + * Failure: FAIL + * + * Programmer: Quincey Koziol + * 7/20/11 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_set_store_msg_crt_idx(H5F_t *f, hbool_t flag) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + + f->shared->store_msg_crt_idx = flag; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5F_set_store_msg_crt_idx() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_get_id + * + * Purpose: Get the file ID, incrementing it, or "resurrecting" it as + * appropriate. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Raymond Lu + * Oct 29, 2003 + * + *------------------------------------------------------------------------- + */ +hid_t +H5F_get_id(H5F_t *file, hbool_t app_ref) +{ + hid_t ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(file); + + if (FAIL == (ret_value = H5I_get_id(file, H5I_FILE))) { + /* resurrect the ID - Register an ID with the native plugin */ + if((ret_value = H5VL_native_register(H5I_FILE, file, app_ref)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + file->id_exists = TRUE; + } + else { + /* Increment ref count on existing ID */ + if(H5I_inc_ref(ret_value, app_ref) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_get_id() */ diff --git a/src/H5Fmount.c b/src/H5Fmount.c index ee7af97..55f364c 100644 --- a/src/H5Fmount.c +++ b/src/H5Fmount.c @@ -28,11 +28,9 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Pprivate.h" /* Property lists */ #include "H5MMprivate.h" /* Memory management */ +#include "H5VLprivate.h" /* VOL plugins */ /* PRIVATE PROTOTYPES */ -static herr_t H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, - hid_t plist_id, hid_t dxpl_id); -static herr_t H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id); static void H5F_mount_count_ids_recurse(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs); @@ -126,7 +124,7 @@ done: * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, hid_t UNUSED plist_id, hid_t dxpl_id) { @@ -292,7 +290,7 @@ done: * *------------------------------------------------------------------------- */ -static herr_t +herr_t H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id) { H5G_t *child_group = NULL; /* Child's group in parent mtab */ @@ -470,28 +468,49 @@ H5F_is_mount(const H5F_t *file) herr_t H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id) { - H5G_loc_t loc; - H5F_t *child = NULL; - herr_t ret_value = SUCCEED; /* Return value */ + void *obj; + void *file; + H5VL_t *vol_plugin1; /* VOL structure attached to loc_id */ + H5VL_t *vol_plugin2; /* VOL structure attached to child_id */ + H5I_type_t type; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*sii", loc_id, name, child_id, plist_id); /* 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") - if(NULL == (child = (H5F_t *)H5I_object_verify(child_id, H5I_FILE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") if(H5P_DEFAULT == plist_id) plist_id = H5P_FILE_MOUNT_DEFAULT; else if(TRUE != H5P_isa_class(plist_id, H5P_FILE_MOUNT)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property list") - /* Do the mount */ - if(H5F_mount(&loc, name, child, plist_id, H5AC_dxpl_id) < 0) + type = H5I_get_type(loc_id); + if(H5I_FILE != type && H5I_GROUP != type) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or group object") + } + + /* get the plugin pointers */ + if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(child_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* check if both objects are associated with the same VOL plugin */ + if (vol_plugin1->cls != vol_plugin2->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Can't mount file onto object from different VOL plugin") + + /* get the group/file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the file object */ + if(NULL == (file = (void *)H5I_object(child_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + if((ret_value = H5VL_file_misc(obj, vol_plugin1, H5VL_FILE_MOUNT, H5_REQUEST_NULL, + type, name, file, plist_id)) < 0) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file") done: @@ -521,20 +540,32 @@ done: herr_t H5Funmount(hid_t loc_id, const char *name) { - H5G_loc_t loc; + void *obj; + H5VL_t *vol_plugin; /* VOL structure attached to loc_id */ + H5I_type_t type; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*s", loc_id, name); /* Check args */ - 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") - /* Unmount */ - if (H5F_unmount(&loc, name, H5AC_dxpl_id) < 0) + type = H5I_get_type(loc_id); + if(H5I_FILE != type && H5I_GROUP != type) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or group object") + } + + /* get the plugin pointers */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the group/file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + if((ret_value = H5VL_file_misc(obj, vol_plugin, H5VL_FILE_UNMOUNT, H5_REQUEST_NULL, type, name)) < 0) HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to unmount file") done: @@ -568,7 +599,7 @@ H5F_mount_count_ids_recurse(H5F_t *f, unsigned *nopen_files, unsigned *nopen_obj HDassert(nopen_objs); /* If this file is still open, increment number of file IDs open */ - if(f->file_id > 0) + if(f->id_exists) *nopen_files += 1; /* Increment number of open objects in file diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 334879c..98de62a 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -33,6 +33,7 @@ /* Other public headers needed by this file */ #include "H5Bpublic.h" /* B-tree header, for H5B_NUM_BTREE_ID */ +#include "H5VLpublic.h" /* Other private headers needed by this file */ #include "H5private.h" /* Generic Functions */ @@ -270,7 +271,7 @@ struct H5F_t { H5F_file_t *shared; /* The shared file info */ unsigned nopen_objs; /* Number of open object headers*/ H5FO_t *obj_count; /* # of time each object is opened through top file structure */ - hid_t file_id; /* ID of this file */ + hbool_t id_exists; /* Whether an ID for this struct exists */ hbool_t closing; /* File is in the process of being closed */ struct H5F_t *parent; /* Parent file that this file is mounted to */ unsigned nmounts; /* Number of children mounted to this file */ @@ -300,6 +301,8 @@ H5_DLL haddr_t H5F_locate_signature(H5FD_t *file, hid_t dxpl_id); H5_DLL herr_t H5F_flush(H5F_t *f, hid_t dxpl_id, hbool_t closing); /* File mount related routines */ +H5_DLL herr_t H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child, hid_t plist_id, hid_t dxpl_id); +H5_DLL herr_t H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id); H5_DLL herr_t H5F_close_mounts(H5F_t *f); H5_DLL int H5F_term_unmount_cb(void *obj_ptr, hid_t obj_id, void *key); H5_DLL herr_t H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs); diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index e1e1b05..a05d945 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -29,7 +29,6 @@ /* Private headers needed by this file */ #include "H5Vprivate.h" /* Vectors and arrays */ - /****************************/ /* Library Private Typedefs */ /****************************/ @@ -41,6 +40,19 @@ typedef struct H5F_file_t H5F_file_t; /* Block aggregation structure */ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; +/* User data for traversal routine to get ID counts */ +typedef struct { + ssize_t *obj_count; /* number of objects counted so far */ + unsigned types; /* types of objects to be counted */ +} H5F_trav_obj_cnt_t; + +/* User data for traversal routine to get ID lists */ +typedef struct { + size_t max_objs; + hid_t *oid_list; + ssize_t *obj_count; /* number of objects counted so far */ + unsigned types; /* types of objects to be counted */ +} H5F_trav_obj_ids_t; /* * Encode and decode macros for file meta-data. @@ -289,7 +301,7 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; #define H5F_NOPEN_OBJS(F) ((F)->nopen_objs) #define H5F_INCR_NOPEN_OBJS(F) ((F)->nopen_objs++) #define H5F_DECR_NOPEN_OBJS(F) ((F)->nopen_objs--) -#define H5F_FILE_ID(F) ((F)->file_id) +#define H5F_FILE_ID(F) ((F)->id_exists)//file_id) #define H5F_PARENT(F) ((F)->parent) #define H5F_NMOUNTS(F) ((F)->nmounts) #define H5F_DRIVER_ID(F) ((F)->shared->lf->driver_id) @@ -331,7 +343,7 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; #define H5F_NOPEN_OBJS(F) (H5F_get_nopen_objs(F)) #define H5F_INCR_NOPEN_OBJS(F) (H5F_incr_nopen_objs(F)) #define H5F_DECR_NOPEN_OBJS(F) (H5F_decr_nopen_objs(F)) -#define H5F_FILE_ID(F) (H5F_get_file_id(F)) +#define H5F_FILE_ID(F) (H5F_file_id_exists(F)) #define H5F_PARENT(F) (H5F_get_parent(F)) #define H5F_NMOUNTS(F) (H5F_get_nmounts(F)) #define H5F_DRIVER_ID(F) (H5F_get_driver_id(F)) @@ -453,6 +465,8 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; #define H5F_ACS_GARBG_COLCT_REF_NAME "gc_ref" /* Garbage-collect references */ #define H5F_ACS_FILE_DRV_ID_NAME "driver_id" /* File driver ID */ #define H5F_ACS_FILE_DRV_INFO_NAME "driver_info" /* File driver info */ +#define H5F_ACS_VOL_NAME "vol_cls" /* File VOL plugin */ +#define H5F_ACS_VOL_INFO_NAME "vol_info" /* FILE VOL info */ #define H5F_ACS_CLOSE_DEGREE_NAME "close_degree" /* File close degree */ #define H5F_ACS_FAMILY_OFFSET_NAME "family_offset" /* Offset position in file for family file driver */ #define H5F_ACS_FAMILY_NEWSIZE_NAME "family_newsize" /* New member size of family driver. (private property only used by h5repart) */ @@ -552,11 +566,19 @@ struct H5B_class_t; struct H5RC_t; struct H5O_loc_t; struct H5HG_heap_t; +struct H5VL_class_t; /* Private functions */ H5_DLL H5F_t *H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id); +H5_DLL herr_t H5F_close(H5F_t *f); H5_DLL herr_t H5F_try_close(H5F_t *f); +H5_DLL H5F_t *H5F_reopen(H5F_t *f); +H5_DLL htri_t H5F_is_hdf5(const char *name); +H5_DLL herr_t H5F_get_objects(const H5F_t *f, unsigned types, size_t max_index, hid_t *obj_id_list, hbool_t app_ref, size_t *obj_id_count_ptr); +H5_DLL int H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key); +H5_DLL int H5F_get_obj_count_cb(void *obj_ptr, hid_t obj_id, void *key); +H5_DLL int H5F_get_obj_ids_cb(void *obj_ptr, hid_t obj_id, void *key); /* Functions than retrieve values from the file struct */ H5_DLL unsigned H5F_get_intent(const H5F_t *f); @@ -568,7 +590,8 @@ H5_DLL hbool_t H5F_same_shared(const H5F_t *f1, const H5F_t *f2); H5_DLL unsigned H5F_get_nopen_objs(const H5F_t *f); H5_DLL unsigned H5F_incr_nopen_objs(H5F_t *f); H5_DLL unsigned H5F_decr_nopen_objs(H5F_t *f); -H5_DLL hid_t H5F_get_file_id(const H5F_t *f); +H5_DLL hbool_t H5F_file_id_exists(const H5F_t *f); +H5_DLL ssize_t H5F_get_file_image(H5F_t *f, void *buf_ptr, size_t buf_len); H5_DLL H5F_t *H5F_get_parent(const H5F_t *f); H5_DLL unsigned H5F_get_nmounts(const H5F_t *f); H5_DLL hid_t H5F_get_access_plist(H5F_t *f, hbool_t app_ref); diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index f32b3e0..6f7ae37 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -175,6 +175,7 @@ extern "C" { /* Functions in H5F.c */ H5_DLL htri_t H5Fis_hdf5(const char *filename); +H5_DLL htri_t H5Fis_accessible(const char *container_name, hid_t fapl_id); H5_DLL hid_t H5Fcreate(const char *filename, unsigned flags, hid_t create_plist, hid_t access_plist); H5_DLL hid_t H5Fopen(const char *filename, unsigned flags, diff --git a/src/H5Fquery.c b/src/H5Fquery.c index c04ba24..89d97f4 100644 --- a/src/H5Fquery.c +++ b/src/H5Fquery.c @@ -263,15 +263,15 @@ H5F_get_nopen_objs(const H5F_t *f) * *------------------------------------------------------------------------- */ -hid_t -H5F_get_file_id(const H5F_t *f) +hbool_t +H5F_file_id_exists(const H5F_t *f) { /* Use FUNC_ENTER_NOAPI_NOINIT_NOERR here to avoid performance issues */ FUNC_ENTER_NOAPI_NOINIT_NOERR HDassert(f); - FUNC_LEAVE_NOAPI(f->file_id) + FUNC_LEAVE_NOAPI(f->id_exists) } /* end H5F_get_file_id() */ @@ -1072,4 +1072,3 @@ H5F_use_tmp_space(const H5F_t *f) FUNC_LEAVE_NOAPI(f->shared->use_tmp_space) } /* end H5F_use_tmp_space() */ - diff --git a/src/H5Ftest.c b/src/H5Ftest.c index 73b00a6..0073db7 100644 --- a/src/H5Ftest.c +++ b/src/H5Ftest.c @@ -45,7 +45,7 @@ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ #include "H5SMpkg.h" /* Shared object header messages */ - +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ /* Local Macros */ @@ -93,8 +93,9 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ - +#include "H5VLprivate.h" /* VOL plugins */ /****************/ /* Local Macros */ @@ -136,7 +137,8 @@ static const H5I_class_t H5I_GROUP_CLS[1] = {{ 0, /* Class flags */ 64, /* Minimum hash size for class */ 0, /* # of reserved IDs for class */ - (H5I_free_t)H5G_close /* Callback routine for closing objects of this class */ + NULL, /* Callback routine for closing objects of this class */ + (H5I_free2_t)H5G_close_group /* Callback routine for closing auxilary objects of this class */ }}; @@ -268,19 +270,19 @@ H5G_term_interface(void) *------------------------------------------------------------------------- */ hid_t -H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, - hid_t gapl_id) +H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, hid_t gapl_id) { - H5G_loc_t loc; /* Location to create group */ - H5G_t *grp = NULL; /* New group created */ + void *grp = NULL; /* dset token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; + H5P_genplist_t *plist; /* Property list pointer */ hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("i", "i*siii", loc_id, name, lcpl_id, gcpl_id, gapl_id); /* 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") @@ -305,17 +307,35 @@ H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id, if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list") - /* Create the new group & get its ID */ - if(NULL == (grp = H5G__create_named(&loc, name, lcpl_id, gcpl_id, gapl_id, H5AC_dxpl_id))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") - if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(gcpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + if(H5P_set(plist, H5VL_GRP_LCPL_ID, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for lcpl id") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the group through the VOL */ + if(NULL == (grp = H5VL_group_create(obj, loc_params, vol_plugin, name, gcpl_id, gapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") + + /* Get an atom for the group */ + if((ret_value = H5I_register2(H5I_GROUP, grp, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: - if(ret_value < 0) - if(grp && H5G_close(grp) < 0) + if (ret_value < 0 && grp) + if(H5VL_group_close (grp, vol_plugin, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") - FUNC_LEAVE_API(ret_value) } /* end H5Gcreate2() */ @@ -358,18 +378,15 @@ done: hid_t H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id) { - H5G_loc_t loc; - H5G_t *grp = NULL; - H5G_obj_create_t gcrt_info; /* Information for group creation */ + void *grp = NULL; /* dset token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE3("i", "iii", loc_id, gcpl_id, gapl_id); - /* Check arguments */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - /* Check group creation property list */ if(H5P_DEFAULT == gcpl_id) gcpl_id = H5P_GROUP_CREATE_DEFAULT; @@ -384,36 +401,29 @@ H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id) if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list") - /* Set up group creation info */ - gcrt_info.gcpl_id = gcpl_id; - gcrt_info.cache_type = H5G_NOTHING_CACHED; - HDmemset(&gcrt_info.cache, 0, sizeof(gcrt_info.cache)); + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); - /* Create the new group & get its ID */ - if(NULL == (grp = H5G__create(loc.oloc->file, &gcrt_info, H5AC_dxpl_id))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") - if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") -done: - /* Release the group's object header, if it was created */ - if(grp) { - H5O_loc_t *oloc; /* Object location for group */ + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Get the new group's object location */ - if(NULL == (oloc = H5G_oloc(grp))) - HDONE_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object location of group") + /* Create the group through the VOL */ + if(NULL == (grp = H5VL_group_create(obj, loc_params, vol_plugin, NULL, gcpl_id, gapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") - /* Decrement refcount on group's object header in memory */ - if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object") - } /* end if */ + /* Get an atom for the group */ + if((ret_value = H5I_register2(H5I_GROUP, grp, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") - /* Cleanup on failure */ - if(ret_value < 0) - if(grp && H5G_close(grp) < 0) +done: + if (ret_value < 0 && grp) + if(H5VL_group_close (grp, vol_plugin, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") - FUNC_LEAVE_API(ret_value) } /* end H5Gcreate_anon() */ @@ -438,16 +448,16 @@ done: hid_t H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id) { - H5G_t *grp = NULL; /* Group opened */ - H5G_loc_t loc; /* Location of parent for group */ + void *grp = NULL; /* dset token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("i", "i*si", loc_id, name, gapl_id); /* Check args */ - 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") @@ -458,20 +468,29 @@ H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id) if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list") - /* Open the group */ - if((grp = H5G__open_name(&loc, name, gapl_id, H5AC_dxpl_id)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") - /* Register an ID for the group */ - if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the group through the VOL */ + if(NULL == (grp = H5VL_group_open(obj, loc_params, vol_plugin, name, gapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") + + /* Get an atom for the group */ + if((ret_value = H5I_register2(H5I_GROUP, grp, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: - if(ret_value < 0) { - if(grp && H5G_close(grp) < 0) + if (ret_value < 0 && grp) + if(H5VL_group_close (grp, vol_plugin, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") - } /* end if */ - FUNC_LEAVE_API(ret_value) } /* end H5Gopen2() */ @@ -493,86 +512,26 @@ done: *------------------------------------------------------------------------- */ hid_t -H5Gget_create_plist(hid_t group_id) +H5Gget_create_plist(hid_t grp_id) { - H5O_linfo_t linfo; /* Link info message */ - htri_t ginfo_exists; - htri_t linfo_exists; - htri_t pline_exists; - H5G_t *grp = NULL; - H5P_genplist_t *gcpl_plist; - H5P_genplist_t *new_plist; - hid_t new_gcpl_id = FAIL; - hid_t ret_value = FAIL; + H5VL_t *vol_plugin; + void *grp; + hid_t ret_value = FAIL; FUNC_ENTER_API(FAIL) - H5TRACE1("i", "i", group_id); - - /* Check args */ - if(NULL == (grp = (H5G_t *)H5I_object_verify(group_id, H5I_GROUP))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") - - /* Copy the default group creation property list */ - if(NULL == (gcpl_plist = (H5P_genplist_t *)H5I_object(H5P_LST_GROUP_CREATE_g))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get default group creation property list") - if((new_gcpl_id = H5P_copy_plist(gcpl_plist, TRUE)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to copy the creation property list") - if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_gcpl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") - - /* Retrieve any object creation properties */ - if(H5O_get_create_plist(&grp->oloc, H5AC_ind_dxpl_id, new_plist) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object creation info") - - /* Check for the group having a group info message */ - if((ginfo_exists = H5O_msg_exists(&(grp->oloc), H5O_GINFO_ID, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") - if(ginfo_exists) { - H5O_ginfo_t ginfo; /* Group info message */ - - /* Read the group info */ - if(NULL == H5O_msg_read(&(grp->oloc), H5O_GINFO_ID, &ginfo, H5AC_ind_dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info") - - /* Set the group info for the property list */ - if(H5P_set(new_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set group info") - } /* end if */ - - /* Check for the group having a link info message */ - if((linfo_exists = H5G__obj_get_linfo(&(grp->oloc), &linfo, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") - if(linfo_exists) { - /* Set the link info for the property list */ - if(H5P_set(new_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link info") - } /* end if */ - - /* Check for the group having a pipeline message */ - if((pline_exists = H5O_msg_exists(&(grp->oloc), H5O_PLINE_ID, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header") - if(pline_exists) { - H5O_pline_t pline; /* Pipeline message */ - - /* Read the pipeline */ - if(NULL == H5O_msg_read(&(grp->oloc), H5O_PLINE_ID, &pline, H5AC_ind_dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link pipeline") + H5TRACE1("i", "i", grp_id); - /* Set the pipeline for the property list */ - if(H5P_set(new_plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link pipeline") - } /* end if */ + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(grp_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (grp = (void *)H5I_object(grp_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid group identifier") - /* Set the return value */ - ret_value = new_gcpl_id; + if(H5VL_group_get(grp, vol_plugin, H5VL_GROUP_GET_GCPL, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group creation properties") done: - if(ret_value < 0) { - if(new_gcpl_id > 0) - if(H5I_dec_app_ref(new_gcpl_id) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't free") - } /* end if */ - FUNC_LEAVE_API(ret_value) } /* end H5Gget_create_plist() */ @@ -591,29 +550,38 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Gget_info(hid_t grp_id, H5G_info_t *grp_info) +H5Gget_info(hid_t loc_id, H5G_info_t *grp_info) { + H5VL_t *vol_plugin; + void *obj; H5I_type_t id_type; /* Type of ID */ - H5G_loc_t loc; /* Location of group */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*x", grp_id, grp_info); + H5TRACE2("e", "i*x", loc_id, grp_info); /* Check args */ - id_type = H5I_get_type(grp_id); + id_type = H5I_get_type(loc_id); if(!(H5I_GROUP == id_type || H5I_FILE == id_type)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") if(!grp_info) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct") - /* Get group location */ - if(H5G_loc(grp_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid group identifier") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = id_type; - /* Retrieve the group's information */ - if(H5G__obj_info(loc.oloc, grp_info/*out*/, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") + /* Get the group info through the VOL using the location token */ + if((ret_value = H5VL_group_get(obj, vol_plugin, H5VL_GROUP_GET_INFO, H5_REQUEST_NULL, + loc_params, grp_info)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: FUNC_LEAVE_API(ret_value) @@ -637,19 +605,15 @@ herr_t H5Gget_info_by_name(hid_t loc_id, const char *name, H5G_info_t *grp_info, hid_t lapl_id) { - H5G_loc_t loc; /* Location of group */ - H5G_loc_t grp_loc; /* Location used to open group */ - H5G_name_t grp_path; /* Opened object group hier. path */ - H5O_loc_t grp_oloc; /* Opened object object location */ - hbool_t loc_found = FALSE; /* Location at 'name' found */ + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*s*xi", loc_id, name, grp_info, lapl_id); /* Check args */ - 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(!grp_info) @@ -660,24 +624,24 @@ H5Gget_info_by_name(hid_t loc_id, const char *name, H5G_info_t *grp_info, 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 group location to fill in */ - grp_loc.oloc = &grp_oloc; - grp_loc.path = &grp_path; - H5G_loc_reset(&grp_loc); + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); - /* Find the group object */ - if(H5G_loc_find(&loc, name, &grp_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") - loc_found = TRUE; + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid group identifier") - /* Retrieve the group's information */ - if(H5G__obj_info(grp_loc.oloc, grp_info/*out*/, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") + /* Get the group info through the VOL using the location token */ + if((ret_value = H5VL_group_get(obj, vol_plugin, H5VL_GROUP_GET_INFO, H5_REQUEST_NULL, + loc_params, grp_info)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: - if(loc_found && H5G_loc_free(&grp_loc) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") - FUNC_LEAVE_API(ret_value) } /* end H5Gget_info_by_name() */ @@ -700,11 +664,9 @@ herr_t H5Gget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5G_info_t *grp_info, hid_t lapl_id) { - H5G_loc_t loc; /* Location of group */ - H5G_loc_t grp_loc; /* Location used to open group */ - H5G_name_t grp_path; /* Opened object group hier. path */ - H5O_loc_t grp_oloc; /* Opened object object location */ - hbool_t loc_found = FALSE; /* Entry at 'name' found */ + H5VL_t *vol_plugin; + void *obj; + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -712,8 +674,6 @@ H5Gget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, lapl_id); /* Check args */ - 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) @@ -728,25 +688,27 @@ H5Gget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, 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 group location to fill in */ - grp_loc.oloc = &grp_oloc; - grp_loc.path = &grp_path; - H5G_loc_reset(&grp_loc); - - /* Find the object's location, according to the order in the index */ - if(H5G_loc_find_by_idx(&loc, group_name, idx_type, order, n, &grp_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") - loc_found = TRUE; - - /* Retrieve the group's information */ - if(H5G__obj_info(grp_loc.oloc, grp_info/*out*/, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = group_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the dataset object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid group identifier") + + /* Get the group info through the VOL using the location token */ + if((ret_value = H5VL_group_get(obj, vol_plugin, H5VL_GROUP_GET_INFO, H5_REQUEST_NULL, + loc_params, grp_info)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: - /* Release the object location */ - if(loc_found && H5G_loc_free(&grp_loc) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") - FUNC_LEAVE_API(ret_value) } /* end H5Gget_info_by_idx() */ @@ -782,8 +744,42 @@ H5Gclose(hid_t group_id) */ if(H5I_dec_app_ref(group_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group") +#if 0 + /* Close the group through the VOL */ + if(H5VL_group_close(group_id, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group") +#endif done: FUNC_LEAVE_API(ret_value) } /* end H5Gclose() */ + +/*------------------------------------------------------------------------- + * Function: H5G_close_group + * + * Purpose: Called when the ref count reaches zero on the group_id + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * June 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_close_group(void *grp, H5VL_t *vol_plugin) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Close the group through the VOL*/ + if((ret_value = H5VL_group_close(grp, vol_plugin, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to close group") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_close_group() */ diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c index 9473011..5399219 100644 --- a/src/H5Gdeprec.c +++ b/src/H5Gdeprec.c @@ -47,7 +47,7 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ #include "H5Pprivate.h" /* Property lists */ - +#include "H5VLprivate.h" /* VOL plugins */ /****************/ /* Local Macros */ @@ -77,10 +77,6 @@ typedef struct { /* Local Prototypes */ /********************/ -static herr_t H5G_link_hard(hid_t cur_loc_id, const char *cur_name, - hid_t new_loc_id, const char *new_name); -static herr_t H5G_move(hid_t src_loc_id, const char *src_name, - hid_t dst_loc_id, const char *dst_name); 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*/); @@ -201,24 +197,26 @@ H5G_map_obj_type(H5O_type_t obj_type) hid_t H5Gcreate1(hid_t loc_id, const char *name, size_t size_hint) { - H5G_loc_t loc; /* Location to create group */ - H5G_t *grp = NULL; /* New group created */ + void *grp = NULL; /* dset token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t tmp_gcpl = (-1); /* Temporary group creation property list */ + hid_t lcpl_id = H5P_LINK_CREATE_DEFAULT; + H5P_genplist_t *plist; hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("i", "i*sz", loc_id, name, size_hint); /* 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 given") /* Check if we need to create a non-standard GCPL */ if(size_hint > 0) { - H5P_genplist_t *gc_plist; /* Property list created */ H5O_ginfo_t ginfo; /* Group info property */ + H5P_genplist_t *gc_plist; /* Property list created */ /* Get the default property list */ if(NULL == (gc_plist = (H5P_genplist_t *)H5I_object(H5P_GROUP_CREATE_DEFAULT))) @@ -244,20 +242,40 @@ H5Gcreate1(hid_t loc_id, const char *name, size_t size_hint) else tmp_gcpl = H5P_GROUP_CREATE_DEFAULT; - /* Create the new group & get its ID */ - if(NULL == (grp = H5G__create_named(&loc, name, H5P_LINK_CREATE_DEFAULT, - tmp_gcpl, H5P_GROUP_ACCESS_DEFAULT, H5AC_dxpl_id))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") - if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(tmp_gcpl))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* get creation properties */ + if(H5P_set(plist, H5VL_GRP_LCPL_ID, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for lcpl id") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the group through the VOL */ + if(NULL == (grp = H5VL_group_create(obj, loc_params, vol_plugin, name, tmp_gcpl, + H5P_GROUP_ACCESS_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") + + /* Get an atom for the group */ + if((ret_value = H5I_register2(H5I_GROUP, grp, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: if(tmp_gcpl > 0 && tmp_gcpl != H5P_GROUP_CREATE_DEFAULT) if(H5I_dec_ref(tmp_gcpl) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release property list") - - if(ret_value < 0) - if(grp && H5G_close(grp) < 0) + if (ret_value < 0 && grp) + if(H5VL_group_close (grp, vol_plugin, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") FUNC_LEAVE_API(ret_value) @@ -284,33 +302,42 @@ done: hid_t H5Gopen1(hid_t loc_id, const char *name) { - H5G_t *grp = NULL; /* Group opened */ - H5G_loc_t loc; /* Location of parent for group */ + void *grp = NULL; /* dset token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("i", "i*s", loc_id, name); /* Check args */ - 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") - /* Open the group */ - if((grp = H5G__open_name(&loc, name, H5P_DEFAULT, H5AC_dxpl_id)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); - /* Register an atom for the group */ - if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the group through the VOL */ + if(NULL == (grp = H5VL_group_open(obj, loc_params, vol_plugin, name, H5P_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") + + /* Get an atom for the group */ + if((ret_value = H5I_register2(H5I_GROUP, grp, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: - if(ret_value < 0) { - if(grp && H5G_close(grp) < 0) + if (ret_value < 0 && grp) + if(H5VL_group_close (grp, vol_plugin, H5_REQUEST_NULL) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group") - } /* end if */ - FUNC_LEAVE_API(ret_value) } /* end H5Gopen1() */ @@ -326,6 +353,8 @@ done: herr_t H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new_name) { + hid_t lcpl_id = H5P_LINK_CREATE_DEFAULT; + H5P_genplist_t *plist; /* Property list pointer */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -337,20 +366,68 @@ H5Glink(hid_t cur_loc_id, H5G_link_t type, const char *cur_name, const char *new if(!new_name || !*new_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified") + /* 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") + if(type == H5L_TYPE_HARD) { - if((ret_value = H5G_link_hard(cur_loc_id, cur_name, H5L_SAME_LOC, new_name)) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "couldn't create link") + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin = NULL; /* VOL plugin information */ + H5VL_loc_params_t loc_params1; + H5VL_loc_params_t loc_params2; + + loc_params1.type = H5VL_OBJECT_BY_NAME; + loc_params1.obj_type = H5I_get_type(cur_loc_id); + loc_params1.loc_data.loc_by_name.name = cur_name; + loc_params1.loc_data.loc_by_name.plist_id = H5P_DEFAULT; + + loc_params2.type = H5VL_OBJECT_BY_NAME; + loc_params2.loc_data.loc_by_name.name = new_name; + loc_params2.loc_data.loc_by_name.plist_id = H5P_DEFAULT; + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(cur_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(cur_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* set creation properties */ + if(H5P_set(plist, H5VL_LINK_TARGET, &obj) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target") + if(H5P_set(plist, H5VL_LINK_TARGET_LOC_PARAMS, &loc_params1) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target loc params") + + /* Create the link through the VOL */ + if((ret_value = H5VL_link_create(H5VL_LINK_CREATE_HARD, NULL, loc_params2, vol_plugin, + lcpl_id, H5P_DEFAULT, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end if */ else if(type == H5L_TYPE_SOFT) { - H5G_loc_t cur_loc; /* Group location for new link */ - - /* Finish checking arguments */ - if(H5G_loc(cur_loc_id, &cur_loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - - /* Create the link */ - if(H5L_create_soft(cur_name, &cur_loc, new_name, H5P_DEFAULT, H5P_DEFAULT, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin = NULL; /* VOL plugin information */ + H5VL_loc_params_t loc_params; + + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = new_name; + loc_params.loc_data.loc_by_name.plist_id = H5P_DEFAULT; + loc_params.obj_type = H5I_get_type(cur_loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(cur_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(cur_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* set creation properties */ + if(H5P_set(plist, H5VL_LINK_TARGET_NAME, &cur_name) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for target name") + + /* Create the link through the VOL */ + if((ret_value = H5VL_link_create(H5VL_LINK_CREATE_SOFT, obj, loc_params, vol_plugin, + lcpl_id, H5P_DEFAULT, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end else if */ else HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Not a valid link type") @@ -372,6 +449,8 @@ herr_t H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, hid_t new_loc_id, const char *new_name) { + hid_t lcpl_id = H5P_LINK_CREATE_DEFAULT; + H5P_genplist_t *plist; /* Property list pointer */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -383,25 +462,84 @@ H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, if(!new_name || !*new_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified") + /* 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") + if(type == H5L_TYPE_HARD) { - if((ret_value = H5G_link_hard(cur_loc_id, cur_name, new_loc_id, new_name)) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "couldn't create link") + void *obj1 = NULL; /* object token of loc_id */ + void *obj2 = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin1 = NULL; /* VOL plugin information */ + H5VL_t *vol_plugin2 = NULL; /* VOL plugin information */ + H5VL_loc_params_t loc_params1; + H5VL_loc_params_t loc_params2; + + loc_params1.type = H5VL_OBJECT_BY_NAME; + loc_params1.obj_type = H5I_get_type(cur_loc_id); + loc_params1.loc_data.loc_by_name.name = cur_name; + loc_params1.loc_data.loc_by_name.plist_id = H5P_DEFAULT; + + loc_params2.type = H5VL_OBJECT_BY_NAME; + loc_params2.obj_type = H5I_get_type(new_loc_id); + loc_params2.loc_data.loc_by_name.name = new_name; + loc_params2.loc_data.loc_by_name.plist_id = H5P_DEFAULT; + + /* get the file object */ + if(NULL == (obj1 = (void *)H5I_object(cur_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(cur_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the file object */ + if(NULL == (obj2 = (void *)H5I_object(new_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(new_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* set creation properties */ + if(H5P_set(plist, H5VL_LINK_TARGET, &obj1) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target id") + if(H5P_set(plist, H5VL_LINK_TARGET_LOC_PARAMS, &loc_params1) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target name") + + /* Create the link through the VOL */ + if((ret_value = H5VL_link_create(H5VL_LINK_CREATE_HARD, obj2, loc_params2, + (vol_plugin1!=NULL ? vol_plugin1 : vol_plugin2), + lcpl_id, H5P_DEFAULT, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end if */ else if(type == H5L_TYPE_SOFT) { - H5G_loc_t new_loc; /* Group location for new link */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; /* Soft links only need one location, the new_loc_id, but it's possible that * new_loc_id is H5L_SAME_LOC */ if(new_loc_id == H5L_SAME_LOC) new_loc_id = cur_loc_id; - /* Finish checking arguments */ - if(H5G_loc(new_loc_id, &new_loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - - /* Create the link */ - if(H5L_create_soft(cur_name, &new_loc, new_name, H5P_DEFAULT, H5P_DEFAULT, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = new_name; + loc_params.loc_data.loc_by_name.plist_id = H5P_DEFAULT; + loc_params.obj_type = H5I_get_type(new_loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(new_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(new_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* set creation properties */ + if(H5P_set(plist, H5VL_LINK_TARGET_NAME, &cur_name) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for target name") + + /* Create the link through the VOL */ + if((ret_value = H5VL_link_create(H5VL_LINK_CREATE_SOFT, obj, loc_params, vol_plugin, + lcpl_id, H5P_DEFAULT, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") } /* end else if */ else HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid link type") @@ -412,60 +550,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_link_hard - * - * Purpose: Creates a hard link from NEW_NAME to CUR_NAME. - * - * CUR_NAME must name an existing object. CUR_NAME and - * NEW_NAME are interpreted relative to CUR_LOC_ID and - * NEW_LOC_ID, which are either file IDs or group IDs. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, November 6, 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_link_hard(hid_t cur_loc_id, const char *cur_name, hid_t new_loc_id, - const char *new_name) -{ - H5G_loc_t cur_loc, *cur_loc_p; /* Information about current link's group */ - H5G_loc_t new_loc, *new_loc_p; /* Information about new link's group */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Finish checking arguments */ - 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") - - /* Set up current & new location pointers */ - 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.") - - /* Create the link */ - if(H5L_create_hard(cur_loc_p, cur_name, new_loc_p, new_name, - H5P_DEFAULT, H5P_DEFAULT, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_link_hard() */ - - -/*------------------------------------------------------------------------- * Function: H5Gmove * * Purpose: Moves and renames a link. The new API to do this is H5Lmove. @@ -475,14 +559,35 @@ done: herr_t H5Gmove(hid_t src_loc_id, const char *src_name, const char *dst_name) { + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin = NULL; /* VOL plugin information */ + H5VL_loc_params_t loc_params1; + H5VL_loc_params_t loc_params2; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "i*s*s", src_loc_id, src_name, dst_name); - /* Call common routine to move the link */ - if(H5G_move(src_loc_id, src_name, H5L_SAME_LOC, dst_name) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "couldn't move link") + loc_params1.type = H5VL_OBJECT_BY_NAME; + loc_params1.obj_type = H5I_get_type(src_loc_id); + loc_params1.loc_data.loc_by_name.name = src_name; + loc_params1.loc_data.loc_by_name.plist_id = H5P_DEFAULT; + + loc_params2.type = H5VL_OBJECT_BY_NAME; + loc_params2.loc_data.loc_by_name.name = dst_name; + loc_params2.loc_data.loc_by_name.plist_id = H5P_DEFAULT; + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(src_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(src_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the link through the VOL */ + if((ret_value = H5VL_link_move(obj, loc_params1, NULL, loc_params2, vol_plugin, + FALSE, H5P_DEFAULT, H5P_DEFAULT, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -500,14 +605,55 @@ herr_t H5Gmove2(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name) { + void *obj1 = NULL; /* object token of src_id */ + H5VL_t *vol_plugin1; /* VOL plugin information */ + H5VL_loc_params_t loc_params1; + void *obj2 = NULL; /* object token of dst_id */ + H5VL_t *vol_plugin2; /* VOL plugin information */ + H5VL_loc_params_t loc_params2; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*si*s", src_loc_id, src_name, dst_loc_id, dst_name); - /* Call common routine to move the link */ - if(H5G_move(src_loc_id, src_name, dst_loc_id, dst_name) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "couldn't move link") + /* set location paramter for source object */ + loc_params1.type = H5VL_OBJECT_BY_NAME; + loc_params1.loc_data.loc_by_name.name = src_name; + loc_params1.loc_data.loc_by_name.plist_id = H5P_DEFAULT; + loc_params1.obj_type = H5I_get_type(src_loc_id); + /* set location paramter for destination object */ + loc_params2.type = H5VL_OBJECT_BY_NAME; + loc_params2.loc_data.loc_by_name.name = dst_name; + loc_params2.loc_data.loc_by_name.plist_id = H5P_DEFAULT; + loc_params2.obj_type = H5I_get_type(dst_loc_id); + + if(H5L_SAME_LOC != src_loc_id) { + /* get the file object */ + if(NULL == (obj1 = (void *)H5I_object(src_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(src_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + } + if(H5L_SAME_LOC != dst_loc_id) { + /* get the file object */ + if(NULL == (obj2 = (void *)H5I_object(dst_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(dst_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + } + /* Make sure that the VOL plugins are the same */ + if(H5L_SAME_LOC != dst_loc_id && H5L_SAME_LOC != src_loc_id) { + if (vol_plugin1 != vol_plugin2) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL plugins and can't be linked") + } + + /* Move the link through the VOL */ + if((ret_value = H5VL_link_move(obj1, loc_params1, obj2, loc_params2, + (vol_plugin1!=NULL ? vol_plugin1 : vol_plugin2), + FALSE, H5P_DEFAULT, H5P_DEFAULT, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -515,63 +661,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_move - * - * Purpose: Renames an object within an HDF5 file and moves it to a new - * group. The original name SRC is unlinked from the group graph - * and then inserted with the new name DST (which can specify a - * new path for the object) as an atomic operation. The names - * are interpreted relative to SRC_LOC_ID and - * DST_LOC_ID, which are either file IDs or group ID. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, November 6, 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_move(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, - const char *dst_name) -{ - H5G_loc_t src_loc, *src_loc_p; /* Group info for source location */ - H5G_loc_t dst_loc, *dst_loc_p; /* Group info for destination location */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT - - /* Check arguments */ - 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") - - /* Set up src & dst location pointers */ - 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; - - /* Move the link */ - if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name, FALSE, H5P_DEFAULT, - H5P_DEFAULT, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_move() */ - - -/*------------------------------------------------------------------------- * Function: H5Gunlink * * Purpose: Removes a link. The new API is H5Ldelete/H5Ldelete_by_idx. @@ -581,21 +670,32 @@ done: herr_t H5Gunlink(hid_t loc_id, const char *name) { - H5G_loc_t loc; /* Group's location */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*s", loc_id, name); - /* 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") - /* Call H5L routine... */ - if(H5L_delete(&loc, name, H5P_DEFAULT, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "couldn't delete link") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.obj_type = H5I_get_type(loc_id); + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = H5P_LINK_ACCESS_DEFAULT; + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Delete the link through the VOL */ + if((ret_value = H5VL_link_remove(obj, loc_params, vol_plugin, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -613,21 +713,34 @@ done: herr_t H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/) { - H5G_loc_t loc; /* Group's location */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*szx", loc_id, name, size, buf); /* Check arguments */ - 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") - /* Call the new link routine which provides this capability */ - if(H5L_get_val(&loc, name, buf, size, H5P_DEFAULT, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "couldn't get link info") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.obj_type = H5I_get_type(loc_id); + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = H5P_LINK_ACCESS_DEFAULT; + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Get the link info through the VOL */ + if((ret_value = H5VL_link_get(obj, loc_params, vol_plugin, H5VL_LINK_GET_VAL, + H5_REQUEST_NULL, buf, size)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get link value") done: FUNC_LEAVE_API(ret_value) @@ -654,18 +767,31 @@ done: herr_t H5Gset_comment(hid_t loc_id, const char *name, const char *comment) { - H5G_loc_t loc; + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "i*s*s", loc_id, name, comment); - 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") - if(H5G_loc_set_comment(&loc, name, comment, H5P_DEFAULT, H5AC_dxpl_id) < 0) + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = H5P_LINK_ACCESS_DEFAULT; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* set comment on object through the VOL */ + if(H5VL_object_misc(obj, loc_params, vol_plugin, H5VL_OBJECT_SET_COMMENT, H5_REQUEST_NULL, comment) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to set comment value") done: @@ -699,21 +825,37 @@ done: int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf) { - H5G_loc_t loc; + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; + ssize_t size; int ret_value; FUNC_ENTER_API(FAIL) H5TRACE4("Is", "i*sz*s", loc_id, name, bufsize, buf); - 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") if(bufsize > 0 && !buf) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no buffer specified") - if((ret_value = (int)H5G_loc_get_comment(&loc, name, buf, bufsize, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to get comment value") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = H5P_LINK_ACCESS_DEFAULT; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + if(H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_GET_COMMENT, H5_REQUEST_NULL, + buf, bufsize, &size) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get object comment") + + ret_value = (int)size; done: FUNC_LEAVE_API(ret_value) @@ -751,6 +893,7 @@ herr_t H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, void *op_data) { + H5G_loc_t loc; /* Location of object */ H5G_link_iterate_t lnk_op; /* Link operator */ hsize_t last_obj; /* Index of last object looked at */ hsize_t idx; /* Internal location to hold index */ @@ -760,6 +903,8 @@ H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, H5TRACE5("e", "i*s*Isx*x", loc_id, name, idx_p, op, op_data); /* Check args */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID") if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") if(idx_p && *idx_p < 0) @@ -776,7 +921,7 @@ H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, lnk_op.op_func.op_old = op; /* Call private function. */ - if((ret_value = H5G_iterate(loc_id, name, H5_INDEX_NAME, H5_ITER_INC, idx, &last_obj, &lnk_op, op_data, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0) + if((ret_value = H5G_iterate(&loc, name, H5_INDEX_NAME, H5_ITER_INC, idx, &last_obj, &lnk_op, op_data, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group iteration failed") /* Set the index we stopped at */ diff --git a/src/H5Gint.c b/src/H5Gint.c index fe8b995..3eb374c 100644 --- a/src/H5Gint.c +++ b/src/H5Gint.c @@ -44,7 +44,9 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ - +#include "H5Pprivate.h" /* Property lists */ +#include "H5VLnative.h" /* Native Plugin */ +#include "H5VLprivate.h" /* VOL */ /****************/ /* Local Macros */ @@ -107,7 +109,6 @@ H5FL_DEFINE(H5G_shared_t); /* Declare the free list to manage H5_obj_t's */ H5FL_DEFINE(H5_obj_t); - /*****************************/ /* Library Private Variables */ /*****************************/ @@ -806,11 +807,10 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_iterate(hid_t loc_id, const char *group_name, +H5G_iterate(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, const H5G_link_iterate_t *lnk_op, void *op_data, hid_t lapl_id, hid_t dxpl_id) { - H5G_loc_t loc; /* Location of parent for group */ hid_t gid = -1; /* ID of group to iterate over */ H5G_t *grp = NULL; /* Pointer to group data structure to iterate over */ H5G_iter_appcall_ud_t udata; /* User data for callback */ @@ -827,11 +827,9 @@ H5G_iterate(hid_t loc_id, const char *group_name, * Open the group on which to operate. We also create a group ID which * we can pass to the application-defined operator. */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(NULL == (grp = H5G__open_name(&loc, group_name, lapl_id, dxpl_id))) + if(NULL == (grp = H5G__open_name(loc, group_name, lapl_id, dxpl_id))) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") - if((gid = H5I_register(H5I_GROUP, grp, TRUE)) < 0) + if((gid = H5VL_native_register(H5I_GROUP, grp, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") /* Set up user data for callback */ @@ -1072,7 +1070,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type, +H5G_visit(H5G_loc_t *loc, 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, hid_t dxpl_id) { @@ -1081,7 +1079,6 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type, htri_t linfo_exists; /* Whether the link info message exists */ hid_t gid = (-1); /* Group ID */ H5G_t *grp = NULL; /* Group opened */ - H5G_loc_t loc; /* Location of group passed in */ H5G_loc_t start_loc; /* Location of starting group */ unsigned rc; /* Reference count of object */ herr_t ret_value; /* Return value */ @@ -1091,16 +1088,12 @@ H5G_visit(hid_t loc_id, const char *group_name, H5_index_t idx_type, FUNC_ENTER_NOAPI(FAIL) - /* Check args */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - /* Open the group to begin visiting within */ - if((grp = H5G__open_name(&loc, group_name, lapl_id, dxpl_id)) == NULL) + if((grp = H5G__open_name(loc, group_name, lapl_id, dxpl_id)) == NULL) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") /* Register an ID for the starting group */ - if((gid = H5I_register(H5I_GROUP, grp, TRUE)) < 0) + if((gid = H5VL_native_register(H5I_GROUP, grp, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") /* Get the location of the starting group */ @@ -1191,3 +1184,96 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_visit() */ + +/*------------------------------------------------------------------------- + * Function: H5G_get_create_plist + * + * Purpose: Returns a copy of the group creation property list. + * + * Return: Success: ID for a copy of the group creation + * property list. + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5G_get_create_plist(H5G_t *grp) +{ + H5O_linfo_t linfo; /* Link info message */ + htri_t ginfo_exists; + htri_t linfo_exists; + htri_t pline_exists; + H5P_genplist_t *gcpl_plist; + H5P_genplist_t *new_plist; + hid_t new_id = FAIL; + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Copy the default group creation property list */ + if(NULL == (gcpl_plist = (H5P_genplist_t *)H5I_object(H5P_LST_GROUP_CREATE_g))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get default group creation property list") + if((new_id = H5P_copy_plist(gcpl_plist, TRUE)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to copy the creation property list") + if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") + + /* Retrieve any object creation properties */ + if(H5O_get_create_plist(&grp->oloc, H5AC_ind_dxpl_id, new_plist) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object creation info") + + /* Check for the group having a group info message */ + if((ginfo_exists = H5O_msg_exists(&(grp->oloc), H5O_GINFO_ID, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") + if(ginfo_exists) { + H5O_ginfo_t ginfo; /* Group info message */ + + /* Read the group info */ + if(NULL == H5O_msg_read(&(grp->oloc), H5O_GINFO_ID, &ginfo, H5AC_ind_dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info") + + /* Set the group info for the property list */ + if(H5P_set(new_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set group info") + } /* end if */ + + /* Check for the group having a link info message */ + if((linfo_exists = H5G__obj_get_linfo(&(grp->oloc), &linfo, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") + if(linfo_exists) { + /* Set the link info for the property list */ + if(H5P_set(new_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link info") + } /* end if */ + + /* Check for the group having a pipeline message */ + if((pline_exists = H5O_msg_exists(&(grp->oloc), H5O_PLINE_ID, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header") + if(pline_exists) { + H5O_pline_t pline; /* Pipeline message */ + + /* Read the pipeline */ + if(NULL == H5O_msg_read(&(grp->oloc), H5O_PLINE_ID, &pline, H5AC_ind_dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link pipeline") + + /* Set the pipeline for the property list */ + if(H5P_set(new_plist, H5O_CRT_PIPELINE_NAME, &pline) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link pipeline") + } /* end if */ + + /* Set the return value */ + ret_value = new_id; + +done: + if(ret_value < 0) { + if(new_id > 0) + if(H5I_dec_app_ref(new_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't free") + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_get_create_plist() */ diff --git a/src/H5Gloc.c b/src/H5Gloc.c index 9f0095a..2a83f15 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -41,7 +41,7 @@ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ - +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ /* Local Macros */ @@ -126,7 +126,6 @@ static herr_t H5G_loc_get_comment_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); - /*********************/ /* Package Variables */ /*********************/ @@ -143,6 +142,83 @@ static herr_t H5G_loc_get_comment_cb(H5G_loc_t *grp_loc, const char *name, +/*--------------------------------------------------------------------------- + * Function: H5G_loc_real + * + * Purpose: utility routine to get object location + * + * Returns: Non-negative on success or negative on failure + * + * Programmer: Mohamad Chaarawi + * June, 2012 + * + *--------------------------------------------------------------------------- + */ +herr_t +H5G_loc_real(void *obj, H5I_type_t type, H5G_loc_t *loc) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + switch(type) { + case H5I_FILE: + /* Construct a group location for root group of the file */ + if(H5G_root_loc((H5F_t *)obj, loc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unable to create location for file") + break; + case H5I_GROUP: + if(NULL == (loc->oloc = H5G_oloc((H5G_t *)obj))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of group") + if(NULL == (loc->path = H5G_nameof((H5G_t *)obj))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of group") + break; + case H5I_DATATYPE: + { + H5T_t *dt = NULL; + + /* Get the actual datatype object if the VOL object is set */ + if(NULL == (dt = (H5T_t *)H5T_get_named_type((const H5T_t *)obj))) + dt = (H5T_t *) obj; + + if(NULL == (loc->oloc = H5T_oloc(dt))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of datatype") + if(NULL == (loc->path = H5T_nameof(dt))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of datatype") + break; + } + case H5I_DATASET: + if(NULL == (loc->oloc = H5D_oloc((H5D_t *)obj))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of dataset") + if(NULL == (loc->path = H5D_nameof((H5D_t *)obj))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of dataset") + break; + case H5I_ATTR: + if(NULL == (loc->oloc = H5A_oloc((H5A_t *)obj))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of attribute") + if(NULL == (loc->path = H5A_nameof((H5A_t *)obj))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of attribute") + break; + case H5I_UNINIT: + case H5I_BADID: + case H5I_DATASPACE: + case H5I_REFERENCE: + case H5I_VFL: + case H5I_VOL: + case H5I_GENPROP_CLS: + case H5I_GENPROP_LST: + case H5I_ERROR_CLASS: + case H5I_ERROR_MSG: + case H5I_ERROR_STACK: + case H5I_NTYPES: + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + } /* end switch */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5G_loc_real */ + + /*------------------------------------------------------------------------- * Function: H5G_loc * @@ -163,6 +239,10 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc) FUNC_ENTER_NOAPI(FAIL) + if(H5G_loc_real(H5I_object(loc_id), H5I_get_type(loc_id), loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + +#if 0 switch(H5I_get_type(loc_id)) { case H5I_FILE: { @@ -248,11 +328,12 @@ H5G_loc(hid_t loc_id, H5G_loc_t *loc) case H5I_UNINIT: case H5I_BADID: case H5I_VFL: + case H5I_VOL: case H5I_NTYPES: default: HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object ID") } /* end switch */ - +#endif done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc() */ diff --git a/src/H5Gname.c b/src/H5Gname.c index 72da498..fd8bf92 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -824,12 +824,21 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key) break; case H5I_DATATYPE: - /* Avoid non-named datatypes */ - if(!H5T_is_named((H5T_t *)obj_ptr)) - HGOTO_DONE(SUCCEED) /* Do not exit search over IDs */ + { + H5T_t *type = NULL; - oloc = H5T_oloc((H5T_t *)obj_ptr); - obj_path = H5T_nameof((H5T_t *)obj_ptr); + /* Get the actual datatype object that should be the vol_obj */ + if(NULL == (type = (H5T_t *)H5T_get_named_type((H5T_t*)obj_ptr))) + HGOTO_DONE(SUCCEED) /* Do not exit search over IDs */ + + /* Avoid non-named datatypes */ + if(!H5T_is_named(type)) + HGOTO_DONE(SUCCEED) /* Do not exit search over IDs */ + + oloc = H5T_oloc(type); + obj_path = H5T_nameof(type); + break; + } break; case H5I_UNINIT: @@ -1317,7 +1326,7 @@ H5G_get_name_by_addr(hid_t file, hid_t lapl_id, hid_t dxpl_id, const H5O_loc_t * udata.path = NULL; /* Visit all the links in the file */ - if((status = H5G_visit(file, "/", H5_INDEX_NAME, H5_ITER_NATIVE, H5G_get_name_by_addr_cb, &udata, lapl_id, dxpl_id)) < 0) + if((status = H5G_visit(&root_loc, "/", H5_INDEX_NAME, H5_ITER_NATIVE, H5G_get_name_by_addr_cb, &udata, lapl_id, dxpl_id)) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group traversal failed while looking for object name") else if(status > 0) found_obj = TRUE; diff --git a/src/H5Goh.c b/src/H5Goh.c index c6115db..ebe30eb 100644 --- a/src/H5Goh.c +++ b/src/H5Goh.c @@ -29,7 +29,8 @@ #include "H5Gpkg.h" /* Groups */ #include "H5Iprivate.h" /* IDs */ #include "H5Opkg.h" /* Object headers */ - +#include "H5VLnative.h" /* Native Plugin */ +#include "H5VLprivate.h" /* VOL */ /****************/ /* Local Macros */ diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index f765b52..328ef93 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -202,6 +202,7 @@ H5_DLL herr_t H5G_get_shared_count(H5G_t *grp); H5_DLL herr_t H5G_mount(H5G_t *grp); H5_DLL hbool_t H5G_mounted(H5G_t *grp); H5_DLL herr_t H5G_unmount(H5G_t *grp); +H5_DLL hid_t H5G_get_create_plist(H5G_t *grp); #ifndef H5_NO_DEPRECATED_SYMBOLS H5_DLL H5G_obj_t H5G_map_obj_type(H5O_type_t obj_type); #endif /* H5_NO_DEPRECATED_SYMBOLS */ @@ -217,10 +218,10 @@ H5_DLL char *H5G_normalize(const char *name); H5_DLL herr_t H5G_traverse(const H5G_loc_t *loc, const char *name, unsigned target, H5G_traverse_t op, void *op_data, hid_t lapl_id, hid_t dxpl_id); -H5_DLL herr_t H5G_iterate(hid_t loc_id, const char *group_name, +H5_DLL herr_t H5G_iterate(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, const H5G_link_iterate_t *lnk_op, void *op_data, hid_t lapl_id, hid_t dxpl_id); -H5_DLL herr_t H5G_visit(hid_t loc_id, const char *group_name, +H5_DLL herr_t H5G_visit(H5G_loc_t *loc, 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, hid_t dxpl_id); @@ -276,6 +277,7 @@ H5_DLL H5RS_str_t *H5G_build_fullpath_refstr_str(H5RS_str_t *path_r, const char /* * These functions operate on group "locations" */ +H5_DLL herr_t H5G_loc_real(void *obj, H5I_type_t type, H5G_loc_t *loc); H5_DLL herr_t H5G_loc(hid_t loc_id, H5G_loc_t *loc); H5_DLL herr_t H5G_loc_find(const H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc/*out*/, hid_t lapl_id, hid_t dxpl_id); diff --git a/src/H5Gtest.c b/src/H5Gtest.c index 2b5d32a..4bd87f5 100644 --- a/src/H5Gtest.c +++ b/src/H5Gtest.c @@ -36,6 +36,7 @@ #include "H5Gpkg.h" /* Groups */ #include "H5HLprivate.h" /* Local Heaps */ #include "H5Iprivate.h" /* IDs */ +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ /* Local Macros */ @@ -537,12 +538,18 @@ H5G__user_path_test(hid_t obj_id, char *user_path, size_t *user_path_len, unsign break; case H5I_DATATYPE: - /* Avoid non-named datatypes */ - if(!H5T_is_named((H5T_t *)obj_ptr)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a named datatype") - - obj_path = H5T_nameof((H5T_t *)obj_ptr); - break; + { + H5T_t *type = NULL; + + /* Get the actual datatype object that should be the vol_obj */ + if(NULL == (type = (H5T_t *)H5T_get_named_type((H5T_t*)obj_ptr))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a named datatype") + /* Avoid non-named datatypes */ + if(!H5T_is_named(type)) + HGOTO_DONE(SUCCEED) /* Do not exit search over IDs */ + obj_path = H5T_nameof(type); + break; + } case H5I_UNINIT: case H5I_BADID: diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index 1efc521..abbe1d5 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -45,7 +45,8 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Ppublic.h" /* Property Lists */ #include "H5WBprivate.h" /* Wrapped Buffers */ - +#include "H5VLnative.h" /* Native Plugin */ +#include "H5VLprivate.h" /* VOL */ /****************/ /* Local Macros */ @@ -207,7 +208,7 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk, /* Create a group ID to pass to the user-defined callback */ if(NULL == (grp = H5G_open(&grp_loc_copy, dxpl_id))) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") - if((cur_grp = H5I_register(H5I_GROUP, grp, FALSE)) < 0) + if((cur_grp = H5VL_native_register(H5I_GROUP, grp, FALSE)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, FAIL, "unable to register group") /* Check for generic default property list and use link access default if so */ @@ -36,6 +36,7 @@ */ #define H5I_PACKAGE /*suppress error about including H5Ipkg */ +#define H5F_PACKAGE /* MSC - just a temp workaround */ /* Interface initialization */ #define H5_INTERFACE_INIT_FUNC H5I_init_interface @@ -48,6 +49,10 @@ #include "H5Ipkg.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Oprivate.h" /* Object headers */ +#include "H5Tprivate.h" /* Datatypes */ +#include "H5VLprivate.h" /* Virtual Object Layer */ + +#include "H5Fpkg.h" /* MSC- just a temp workaround FILES*/ /* Define this to compile in support for dumping ID information */ /* #define H5I_DEBUG_OUTPUT */ @@ -93,12 +98,13 @@ typedef struct H5I_id_info_t { unsigned count; /* ref. count for this atom */ unsigned app_count; /* ref. count of application visible atoms */ const void *obj_ptr; /* pointer associated with the atom */ + const void *aux_ptr; /* auxilary pointer associated with the atom */ struct H5I_id_info_t *next; /* link to next atom (in case of hash-clash)*/ } H5I_id_info_t; /* ID type structure used */ typedef struct { - const H5I_class_t *cls; /* Pointer to ID class */ + H5I_class_t *cls; /* Pointer to ID class */ unsigned count; /* # of times this type has been initialized*/ unsigned wrapped; /* Whether the id count has wrapped around */ unsigned ids; /* Current number of IDs held */ @@ -159,6 +165,7 @@ H5I_init_interface(void) { FUNC_ENTER_NOAPI_NOINIT_NOERR +done: FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5I_init_interface() */ @@ -282,6 +289,7 @@ H5Iregister_type(size_t hash_size, unsigned reserved, H5I_free_t free_func) cls->hash_size = hash_size; cls->reserved = reserved; cls->free_func = free_func; + cls->free_aux = NULL; /* Register the new ID class */ if(H5I_register_type(cls) < 0) @@ -590,6 +598,7 @@ H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref) for(cur = type_ptr->id_list[i]; cur; cur = next) { hbool_t delete_node; /* Flag to indicate node should be removed from linked list */ + herr_t result1 = SUCCEED, result2 = SUCCEED; /* * Do nothing to the object if the reference count is larger than @@ -602,7 +611,11 @@ H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref) /* Check for a 'free' function and call it, if it exists */ /* (Casting away const OK -QAK) */ - if(type_ptr->cls->free_func && (type_ptr->cls->free_func)((void *)cur->obj_ptr) < 0) { + if(cur->aux_ptr && type_ptr->cls->free_aux) + result1 = (type_ptr->cls->free_aux)((void *)cur->obj_ptr, (void *)cur->aux_ptr); + if(type_ptr->cls->free_func) + result2 = (type_ptr->cls->free_func)((void *)cur->obj_ptr); + if(result1 < 0 || result2 < 0) { if(force) { #ifdef H5I_DEBUG if(H5DEBUG(I)) { @@ -844,6 +857,7 @@ H5I_register(H5I_type_t type, const void *object, hbool_t app_ref) id_ptr->count = 1; /*initial reference count*/ id_ptr->app_count = !!app_ref; id_ptr->obj_ptr = object; + id_ptr->aux_ptr = NULL; id_ptr->next = NULL; /* hash bucket already full, prepend to front of chain */ @@ -913,6 +927,118 @@ done: /*------------------------------------------------------------------------- + * Function: H5I_register2 + * + * Purpose: This routine does the same as H5I_register, and additionally + * attaches an auxilary structure to the id + * + * Return: Success: New object id. + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * + * + *------------------------------------------------------------------------- + */ +hid_t +H5I_register2(H5I_type_t type, const void *object, const void *aux_object, hbool_t app_ref) +{ + H5I_id_type_t *type_ptr; /*ptr to the type */ + H5I_id_info_t *id_ptr; /*ptr to the new ID information */ + hid_t new_id = FAIL; /*new ID */ + unsigned hash_loc; /*new item's hash table location*/ + hid_t next_id; /*next ID to check */ + H5I_id_info_t *curr_id; /*ptr to the current atom */ + unsigned i; /*counter */ + hid_t ret_value = FAIL; /*return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check arguments */ + if(type <= H5I_BADID || type >= H5I_next_type) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") + type_ptr = H5I_id_type_list_g[type]; + if(NULL == type_ptr || type_ptr->count <= 0) + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type") + if(NULL == (id_ptr = H5FL_MALLOC(H5I_id_info_t))) + HGOTO_ERROR(H5E_ATOM, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Create the struct & it's ID */ + new_id = H5I_MAKE(type, type_ptr->nextid); + id_ptr->id = new_id; + id_ptr->count = 1; /*initial reference count*/ + id_ptr->app_count = !!app_ref; + id_ptr->obj_ptr = object; + id_ptr->aux_ptr = aux_object; + id_ptr->next = NULL; + + /* hash bucket already full, prepend to front of chain */ + hash_loc = type_ptr->nextid % (unsigned)type_ptr->cls->hash_size; + if(type_ptr->id_list[hash_loc] != NULL) + id_ptr->next = type_ptr->id_list[hash_loc]; + + /* Insert into the type */ + type_ptr->id_list[hash_loc] = id_ptr; + type_ptr->ids++; + type_ptr->nextid++; + + /* + * This next section of code checks for the 'nextid' getting too large and + * wrapping around, thus necessitating checking for duplicate IDs being + * handed out. + */ + if(type_ptr->nextid > (unsigned)ID_MASK) { + type_ptr->wrapped = 1; + type_ptr->nextid = type_ptr->cls->reserved; + } /* end if */ + + /* + * If we've wrapped around then we need to check for duplicate id's being + * handed out. + */ + if(type_ptr->wrapped) { + /* + * Make sure we check all available ID's. If we're about at the end + * of the range then wrap around and check the beginning values. If + * we check all possible values and didn't find any free ones *then* + * we can fail. + */ + for(i = type_ptr->cls->reserved; i < ID_MASK; i++) { + /* Handle end of range by wrapping to beginning */ + if(type_ptr->nextid > (unsigned)ID_MASK) + type_ptr->nextid = type_ptr->cls->reserved; + + /* new ID to check for */ + next_id = H5I_MAKE(type, type_ptr->nextid); + hash_loc = (unsigned)H5I_LOC(type_ptr->nextid, type_ptr->cls->hash_size); + curr_id = type_ptr->id_list[hash_loc]; + if(curr_id == NULL) + break; /* Ha! this is not likely... */ + + while(curr_id) { + if(curr_id->id == next_id) + break; + curr_id = curr_id->next; + } /* end while */ + if(!curr_id) + break; /* must not have found a match */ + type_ptr->nextid++; + } /* end for */ + + if(i >= (unsigned)ID_MASK) + /* All the IDs are gone! */ + HGOTO_ERROR(H5E_ATOM, H5E_NOIDS, FAIL, "no IDs available in type") + } /* end if */ + + /* Set return value */ + ret_value = new_id; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I_register2() */ + + +/*------------------------------------------------------------------------- * Function: H5I_subst * * Purpose: Substitute a new object pointer for the specified ID. @@ -977,7 +1103,6 @@ H5I_object(hid_t id) /* (Casting away const OK -QAK) */ ret_value = (void *)id_ptr->obj_ptr; } /* end if */ - done: FUNC_LEAVE_NOAPI(ret_value) } /* end if */ @@ -1359,7 +1484,9 @@ H5I_dec_ref(hid_t id) */ if(1 == id_ptr->count) { /* (Casting away const OK -QAK) */ - if(!type_ptr->cls->free_func || (type_ptr->cls->free_func)((void *)id_ptr->obj_ptr) >= 0) { + if((!type_ptr->cls->free_aux || !id_ptr->aux_ptr || + (type_ptr->cls->free_aux)((void *)id_ptr->obj_ptr, (void *)id_ptr->aux_ptr) >= 0) && + (!type_ptr->cls->free_func || (type_ptr->cls->free_func)((void *)id_ptr->obj_ptr) >= 0)) { H5I_remove(id); ret_value = 0; } /* end if */ @@ -1370,7 +1497,6 @@ H5I_dec_ref(hid_t id) --(id_ptr->count); ret_value = (int)id_ptr->count; } /* end else */ - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5I_dec_ref() */ @@ -2060,6 +2186,7 @@ H5I_iterate(H5I_type_t type, H5I_search_func_t func, void *udata, hbool_t app_re /* Check arguments */ if(type <= H5I_BADID || type >= H5I_next_type) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid type number") + type_ptr = H5I_id_type_list_g[type]; /* Only iterate through hash table if it is initialized and there are IDs in group */ @@ -2195,7 +2322,7 @@ H5Iget_name(hid_t id, char *name/*out*/, size_t size) /* Get object location */ if(H5G_loc(id, &loc) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object location") + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object location") /* Call internal group routine to retrieve object's name */ if((ret_value = H5G_get_name(&loc, name, size, NULL, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0) @@ -2209,8 +2336,10 @@ done: /*------------------------------------------------------------------------- * Function: H5Iget_file_id * - * Purpose: The public version of H5I_get_file_id(), obtains the file - * ID given an object ID. User has to close this ID. + * Purpose: Obtains the file ID given an object ID. User has to close + * this ID. This routine goes through the VOL to get the file + * struct and checks if an ID for that struct exists (increments + * ref count & returns this ID) or creates a new ID for it. * * Return: Success: file ID * @@ -2219,19 +2348,64 @@ done: * Programmer: Raymond Lu * Oct 27, 2003 * + * Modified: Mohamad Chaarawi + * September, 2012 + * Update for Virtual Object Layer *------------------------------------------------------------------------- */ hid_t H5Iget_file_id(hid_t obj_id) { - hid_t ret_value; /* Return value */ + H5VL_t *vol_plugin; + void *obj; + void *file = NULL; + H5I_type_t type; /* ID type */ + hid_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE1("i", "i", obj_id); - if((ret_value = H5I_get_file_id(obj_id, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve file ID") + /* Get object type */ + type = H5I_TYPE(obj_id); + if(H5I_FILE == type || H5I_DATATYPE == type || H5I_GROUP == type || + H5I_DATASET == type || H5I_ATTR == type) { + /* get the object pointer*/ + if(NULL == (obj = (void *)H5I_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* If this is a named datatype, get the vol_obj from the H5T_t struct*/ + if (H5I_DATATYPE == type) { + if (NULL == (obj = H5T_get_named_type((H5T_t *)obj))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a named datatype") + } + + /* Get the file through the VOL */ + if(H5VL_file_get(obj, vol_plugin, H5VL_OBJECT_GET_FILE, H5_REQUEST_NULL, type, &file) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to get file") + + if (NULL == file) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") + + /* Check if the ID already exists and procceed accordingly */ + if (FAIL == (ret_value = H5I_get_id(file, H5I_FILE))) { + /* resurrect the ID - Register an ID with the native plugin */ + if((ret_value = H5I_register2(H5I_FILE, file, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + } + else { + /* Increment ref count on existing ID */ + if(H5I_inc_ref(ret_value, TRUE) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed") + } + /* increment the ref count on the VOL plugin for the new ID */ + vol_plugin->nrefs ++; + } + else + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid object ID") done: FUNC_LEAVE_API(ret_value) } /* end H5Iget_file_id() */ @@ -2240,7 +2414,7 @@ done: /*------------------------------------------------------------------------- * Function: H5I_get_file_id * - * Purpose: The private version of H5Iget_file_id(), obtains the file + * Purpose: The native version of H5Iget_file_id(), obtains the file * ID given an object ID. * * Return: Success: file ID @@ -2249,32 +2423,51 @@ done: * Programmer: Raymond Lu * Oct 27, 2003 * + * Modified: Mohamad Chaarawi + * September, 2012 + * Update for Virtual Object Layer + * *------------------------------------------------------------------------- */ hid_t H5I_get_file_id(hid_t obj_id, hbool_t app_ref) { H5I_type_t type; /* ID type */ - hid_t ret_value; /* Return value */ + hid_t ret_value = FAIL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Get object type */ type = H5I_TYPE(obj_id); + + /* object is a file, just increment reference count on ID */ if(type == H5I_FILE) { - /* Increment reference count on file ID */ if(H5I_inc_ref(obj_id, app_ref) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed") - - /* Set return value */ ret_value = obj_id; } /* end if */ else if(type == H5I_DATATYPE || type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR) { H5G_loc_t loc; /* Location of object */ - /* Get the object location information */ - if(H5G_loc(obj_id, &loc) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get object location") + /* If object is a named datatype, we need to do extra processing to get the actual + datatype struct (the VOL struct) */ + if (H5I_DATATYPE == type) { + void *obj = NULL; + + /* get the dt object */ + if(NULL == (obj = (void *)H5I_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + if (NULL == (obj = H5T_get_named_type((H5T_t *)obj))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a named datatype") + /* Get the object location information */ + if(H5G_loc_real(obj, type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + } + else { + /* Get the object location information */ + if(H5G_loc(obj_id, &loc) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get object location") + } /* Get the file ID for the object */ if((ret_value = H5F_get_id(loc.oloc->file, app_ref)) < 0) @@ -2282,11 +2475,119 @@ H5I_get_file_id(hid_t obj_id, hbool_t app_ref) } /* end if */ else HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid object ID") - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5I_get_file_id() */ +/*------------------------------------------------------------------------- + * Function: H5I_register_aux + * + * Purpose: register an Auxilary object and a free func with an existing ID + * + * Return: Success: postive + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * May 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5I_register_aux(hid_t id, void *aux_ptr) +{ + H5I_id_info_t *id_ptr = NULL; /*ptr to the id*/ + herr_t ret_value = SUCCEED; /*return value*/ + + FUNC_ENTER_NOAPI_NOINIT + + if(NULL == (id_ptr = H5I_find_id(id))) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "Invalid ID") + + id_ptr->aux_ptr = aux_ptr; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I_register_aux() */ + + +/*------------------------------------------------------------------------- + * Function: H5I_get_aux + * + * Purpose: return the aux ptr + * + * Return: Success: Non-null auxilary pointer associated with the + * specified ID. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * May 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5I_get_aux(hid_t id) +{ + H5I_id_info_t *id_ptr = NULL; /*ptr to the new atom */ + void *ret_value = NULL; /*return value */ + + FUNC_ENTER_NOAPI(NULL) + + if(NULL != (id_ptr = H5I_find_id(id))) { + ret_value = (void *)id_ptr->aux_ptr; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I_get_aux() */ + + +/*------------------------------------------------------------------------- + * Function: H5I_get_id + * + * Purpose: return ID of vol object + * + * Return: Success: id of object + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * June 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5I_get_id(void *object, H5I_type_t type) +{ + hid_t ret_value = FAIL; /* Return value */ + H5I_id_type_t *type_ptr; /*ptr to the type */ + + FUNC_ENTER_NOAPI(FAIL) + + type_ptr = H5I_id_type_list_g[type]; + if(type_ptr == NULL || type_ptr->count <= 0) + HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type") + + /* Only iterate through hash table if there are IDs in group */ + if(type_ptr->ids > 0) { + H5I_id_info_t *id_ptr; /*ptr to the new ID */ + unsigned i; /*counter */ + + /* Start at the beginning of the array */ + for(i = 0; i < type_ptr->cls->hash_size; i++) { + id_ptr = type_ptr->id_list[i]; + while(id_ptr) { + if (id_ptr->obj_ptr == object) { + ret_value = id_ptr->id; + HGOTO_DONE(id_ptr->id); + } + id_ptr = id_ptr->next; + } /* end while */ + } /* end for */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5I_get_id() */ + /*------------------------------------------------------------------------- * Function: H5I_debug diff --git a/src/H5Iprivate.h b/src/H5Iprivate.h index ff1463d..fe07ced 100644 --- a/src/H5Iprivate.h +++ b/src/H5Iprivate.h @@ -24,9 +24,11 @@ /* Include package's public header */ #include "H5Ipublic.h" +#include "H5VLpublic.h" /* Private headers needed by this file */ #include "H5private.h" +#include "H5FLprivate.h" /* Free Lists */ /**************************/ /* Library Private Macros */ @@ -55,6 +57,7 @@ typedef struct H5I_class_t { * and are not allocated dynamically later.] */ H5I_free_t free_func; /* Free function for object's of this type */ + H5I_free2_t free_aux; /* Free function for auxilary objects of this type */ } H5I_class_t; @@ -71,6 +74,7 @@ H5_DLL int H5I_nmembers(H5I_type_t type); H5_DLL herr_t H5I_clear_type(H5I_type_t type, hbool_t force, hbool_t app_ref); H5_DLL int H5I_destroy_type(H5I_type_t type); H5_DLL hid_t H5I_register(H5I_type_t type, const void *object, hbool_t app_ref); +H5_DLL hid_t H5I_register2(H5I_type_t type, const void *object, const void* aux_object, hbool_t app_ref); H5_DLL void *H5I_subst(hid_t id, const void *new_object); H5_DLL void *H5I_object(hid_t id); H5_DLL void *H5I_object_verify(hid_t id, H5I_type_t id_type); @@ -87,6 +91,8 @@ H5_DLL int H5I_dec_app_ref_always_close(hid_t id); H5_DLL int H5I_inc_type_ref(H5I_type_t type); H5_DLL herr_t H5I_dec_type_ref(H5I_type_t type); H5_DLL int H5I_get_type_ref(H5I_type_t type); - +H5_DLL herr_t H5I_register_aux(hid_t id, void *aux_ptr); +H5_DLL void *H5I_get_aux(hid_t id); +H5_DLL hid_t H5I_get_id(void *object, H5I_type_t type); #endif /* _H5Iprivate_H */ diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h index d630556..13cd3bf 100644 --- a/src/H5Ipublic.h +++ b/src/H5Ipublic.h @@ -36,14 +36,15 @@ typedef enum H5I_type_t { H5I_UNINIT = (-2), /*uninitialized type */ H5I_BADID = (-1), /*invalid Type */ - H5I_FILE = 1, /*type ID for File objects */ - H5I_GROUP, /*type ID for Group objects */ + H5I_FILE = 1, /*type ID for File objects */ + H5I_GROUP, /*type ID for Group objects */ H5I_DATATYPE, /*type ID for Datatype objects */ H5I_DATASPACE, /*type ID for Dataspace objects */ H5I_DATASET, /*type ID for Dataset objects */ H5I_ATTR, /*type ID for Attribute objects */ H5I_REFERENCE, /*type ID for Reference objects */ H5I_VFL, /*type ID for virtual file layer */ + H5I_VOL, /*type ID for virtual object layer */ H5I_GENPROP_CLS, /*type ID for generic property list classes */ H5I_GENPROP_LST, /*type ID for generic property lists */ H5I_ERROR_CLASS, /*type ID for error classes */ @@ -67,6 +68,7 @@ typedef int hid_t; * (failure) then the object will remain in the ID type. */ typedef herr_t (*H5I_free_t)(void*); +typedef herr_t (*H5I_free2_t)(void*,void*); /* Type of the function to compare objects & keys */ typedef int (*H5I_search_func_t)(void *obj, hid_t id, void *key); @@ -36,6 +36,8 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Oprivate.h" /* File objects */ #include "H5Pprivate.h" /* Property lists */ +#include "H5VLnative.h" /* Native Plugin */ +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ /* Local Macros */ @@ -54,18 +56,6 @@ typedef struct { hid_t dxpl_id; /* DXPL to use in callback */ } H5L_trav_gi_t; -/* User data for path traversal routine for getting link info by index */ -typedef struct { - /* In */ - H5_index_t idx_type; /* Index to use */ - H5_iter_order_t order; /* Order to iterate in index */ - hsize_t n; /* Offset of link within index */ - hid_t dxpl_id; /* DXPL to use in callback */ - - /* Out */ - H5L_info_t *linfo; /* Buffer to return to user */ -} H5L_trav_gibi_t; - /* User data for path traversal callback to creating a link */ typedef struct { H5F_t *file; /* Pointer to the file */ @@ -101,47 +91,11 @@ typedef struct { void *buf; /* User buffer */ } H5L_trav_gv_t; -/* User data for path traversal routine for getting link value by index */ -typedef struct { - /* In */ - H5_index_t idx_type; /* Index to use */ - H5_iter_order_t order; /* Order to iterate in index */ - hsize_t n; /* Offset of link within index */ - hid_t dxpl_id; /* DXPL to use in callback */ - size_t size; /* Size of user buffer */ - - /* Out */ - void *buf; /* User buffer */ -} H5L_trav_gvbi_t; - /* User data for path traversal routine for removing link */ typedef struct { hid_t dxpl_id; /* DXPL to use in callback */ } H5L_trav_rm_t; -/* User data for path traversal routine for removing link by index */ -typedef struct { - /* In */ - H5_index_t idx_type; /* Index to use */ - H5_iter_order_t order; /* Order to iterate in index */ - hsize_t n; /* Offset of link within index */ - hid_t dxpl_id; /* DXPL to use in callback */ -} H5L_trav_rmbi_t; - -/* User data for path traversal routine for getting name by index */ -typedef struct { - /* In */ - H5_index_t idx_type; /* Index to use */ - H5_iter_order_t order; /* Order to iterate in index */ - hsize_t n; /* Offset of link within index */ - size_t size; /* Size of name buffer */ - hid_t dxpl_id; /* DXPL to use in callback */ - - /* Out */ - char *name; /* Buffer to return name to user */ - ssize_t name_len; /* Length of full name */ -} H5L_trav_gnbi_t; - /********************/ /* Local Prototypes */ /********************/ @@ -175,8 +129,6 @@ static herr_t H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, static herr_t H5L_exists_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 htri_t H5L_exists(const H5G_loc_t *loc, const char *name, hid_t lapl_id, - hid_t dxpl_id); static herr_t H5L_get_info_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*/); @@ -313,8 +265,12 @@ 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; + void *obj1 = NULL; /* object token of src_id */ + H5VL_t *vol_plugin1; /* VOL plugin information */ + H5VL_loc_params_t loc_params1; + void *obj2 = NULL; /* object token of dst_id */ + H5VL_t *vol_plugin2; /* VOL plugin information */ + H5VL_loc_params_t loc_params2; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -324,10 +280,6 @@ H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, /* Check arguments */ 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) @@ -335,18 +287,51 @@ H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, 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") - /* Set up src & dst location pointers */ - 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; + /* Check the link create property list */ + if(H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_DEFAULT; + /* Check the link access property list */ + if(H5P_DEFAULT == lapl_id) + lapl_id = H5P_LINK_ACCESS_DEFAULT; - /* Move the link */ - if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name, FALSE, lcpl_id, - lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link") + /* set location paramter for source object */ + loc_params1.type = H5VL_OBJECT_BY_NAME; + loc_params1.loc_data.loc_by_name.name = src_name; + loc_params1.loc_data.loc_by_name.plist_id = lapl_id; + loc_params1.obj_type = H5I_get_type(src_loc_id); + /* set location paramter for destination object */ + loc_params2.type = H5VL_OBJECT_BY_NAME; + loc_params2.loc_data.loc_by_name.name = dst_name; + loc_params2.loc_data.loc_by_name.plist_id = lapl_id; + loc_params2.obj_type = H5I_get_type(dst_loc_id); + + if(H5L_SAME_LOC != src_loc_id) { + /* get the file object */ + if(NULL == (obj1 = (void *)H5I_object(src_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(src_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + } + if(H5L_SAME_LOC != dst_loc_id) { + /* get the file object */ + if(NULL == (obj2 = (void *)H5I_object(dst_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(dst_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + } + /* Make sure that the VOL plugins are the same */ + if(H5L_SAME_LOC != dst_loc_id && H5L_SAME_LOC != src_loc_id) { + if (vol_plugin1->cls != vol_plugin2->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL plugins and can't be linked") + } + + /* Move the link through the VOL */ + if((ret_value = H5VL_link_move(obj1, loc_params1, obj2, loc_params2, + (vol_plugin1!=NULL ? vol_plugin1 : vol_plugin2), + FALSE, lcpl_id, lapl_id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -371,8 +356,12 @@ 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; + void *obj1 = NULL; /* object token of src_id */ + H5VL_t *vol_plugin1; /* VOL plugin information */ + H5VL_loc_params_t loc_params1; + void *obj2 = NULL; /* object token of dst_id */ + H5VL_t *vol_plugin2; /* VOL plugin information */ + H5VL_loc_params_t loc_params2; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -382,10 +371,6 @@ H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, /* Check arguments */ 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) @@ -393,19 +378,51 @@ H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, 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") - /* Set up src & dst location pointers */ - 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; - - /* Copy the link */ - if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name, TRUE, lcpl_id, - lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTMOVE, FAIL, "unable to move link") + /* Check the link create property list */ + if(H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_DEFAULT; + /* Check the link access property list */ + if(H5P_DEFAULT == lapl_id) + lapl_id = H5P_LINK_ACCESS_DEFAULT; + /* set location paramter for source object */ + loc_params1.type = H5VL_OBJECT_BY_NAME; + loc_params1.loc_data.loc_by_name.name = src_name; + loc_params1.loc_data.loc_by_name.plist_id = lapl_id; + loc_params1.obj_type = H5I_get_type(src_loc_id); + /* set location paramter for destination object */ + loc_params2.type = H5VL_OBJECT_BY_NAME; + loc_params2.loc_data.loc_by_name.name = dst_name; + loc_params2.loc_data.loc_by_name.plist_id = lapl_id; + loc_params2.obj_type = H5I_get_type(dst_loc_id); + + if(H5L_SAME_LOC != src_loc_id) { + /* get the file object */ + if(NULL == (obj1 = (void *)H5I_object(src_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(src_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + } + if(H5L_SAME_LOC != dst_loc_id) { + /* get the file object */ + if(NULL == (obj2 = (void *)H5I_object(dst_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(dst_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + } + /* Make sure that the VOL plugins are the same */ + if(H5L_SAME_LOC != dst_loc_id && H5L_SAME_LOC != src_loc_id) { + if (vol_plugin1->cls != vol_plugin2->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL plugins and can't be linked") + } + + /* Move the link through the VOL */ + if((ret_value = H5VL_link_move(obj1, loc_params1, obj2, loc_params2, + (vol_plugin1!=NULL ? vol_plugin1 : vol_plugin2), + TRUE, lcpl_id, lapl_id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) } /* end H5Lcopy() */ @@ -433,15 +450,18 @@ 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; /* Group location for new link */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; + H5P_genplist_t *plist; /* Property list pointer */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "*si*sii", link_target, link_loc_id, link_name, lcpl_id, lapl_id); /* Check arguments */ - if(H5G_loc(link_loc_id, &link_loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(link_loc_id == H5L_SAME_LOC) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "link location id should not be H5L_SAME_LOC") if(!link_target || !*link_target) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no target specified") if(!link_name || !*link_name) @@ -449,9 +469,37 @@ H5Lcreate_soft(const char *link_target, 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") - /* Create the link */ - if(H5L_create_soft(link_target, &link_loc, link_name, lcpl_id, lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + /* Check the group access property list */ + if(H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_DEFAULT; + /* Check the link access property list */ + if(H5P_DEFAULT == lapl_id) + lapl_id = H5P_LINK_ACCESS_DEFAULT; + + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = link_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(link_loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(link_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(link_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* 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_LINK_TARGET_NAME, &link_target) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for target name") + + /* Create the link through the VOL */ + if((ret_value = H5VL_link_create(H5VL_LINK_CREATE_SOFT, obj, loc_params, vol_plugin, + lcpl_id, lapl_id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -478,9 +526,14 @@ 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; /* Return value */ + void *obj1 = NULL; /* object token of loc_id */ + void *obj2 = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin1 = NULL; /* VOL plugin information */ + H5VL_t *vol_plugin2 = NULL; /* VOL plugin information */ + H5VL_loc_params_t loc_params1; + H5VL_loc_params_t loc_params2; + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "i*si*sii", cur_loc_id, cur_name, new_loc_id, new_name, lcpl_id, @@ -489,10 +542,6 @@ H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name, /* Check arguments */ 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 || !*cur_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified") if(!new_name || !*new_name) @@ -500,20 +549,60 @@ H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name, 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") - /* Set up current & new location pointers */ - 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.") + /* Check the link create property list */ + if(H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_DEFAULT; + /* Check the link access property list */ + if(H5P_DEFAULT == lapl_id) + lapl_id = H5P_LINK_ACCESS_DEFAULT; - /* Create the link */ - if(H5L_create_hard(cur_loc_p, cur_name, new_loc_p, new_name, - lcpl_id, lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + loc_params1.type = H5VL_OBJECT_BY_NAME; + loc_params1.obj_type = H5I_get_type(cur_loc_id); + loc_params1.loc_data.loc_by_name.name = cur_name; + loc_params1.loc_data.loc_by_name.plist_id = lapl_id; + + loc_params2.type = H5VL_OBJECT_BY_NAME; + loc_params2.obj_type = H5I_get_type(new_loc_id); + loc_params2.loc_data.loc_by_name.name = new_name; + loc_params2.loc_data.loc_by_name.plist_id = lapl_id; + + if(H5L_SAME_LOC != cur_loc_id) { + /* get the file object */ + if(NULL == (obj1 = (void *)H5I_object(cur_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(cur_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + } + if(H5L_SAME_LOC != new_loc_id) { + /* get the file object */ + if(NULL == (obj2 = (void *)H5I_object(new_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(new_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + } + /* Make sure that the VOL plugins are the same */ + if(H5L_SAME_LOC != new_loc_id && H5L_SAME_LOC != cur_loc_id) { + if (vol_plugin1->cls != vol_plugin2->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL plugins and can't be linked") + } + + /* 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_LINK_TARGET, &obj1) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target id") + if(H5P_set(plist, H5VL_LINK_TARGET_LOC_PARAMS, &loc_params1) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target name") + + /* Create the link through the VOL */ + if((ret_value = H5VL_link_create(H5VL_LINK_CREATE_HARD, obj2, loc_params2, + (vol_plugin1!=NULL ? vol_plugin1 : vol_plugin2), + lcpl_id, lapl_id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -548,7 +637,10 @@ 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; + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; + H5P_genplist_t *plist; /* Property list pointer */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -556,16 +648,46 @@ H5Lcreate_ud(hid_t link_loc_id, const char *link_name, H5L_type_t link_type, udata_size, lcpl_id, lapl_id); /* Check arguments */ - 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") - /* Create external link */ - if(H5L_create_ud(&link_loc, link_name, udata, udata_size, link_type, lcpl_id, lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + /* Check the group access property list */ + if(H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_DEFAULT; + /* Check the link access property list */ + if(H5P_DEFAULT == lapl_id) + lapl_id = H5P_LINK_ACCESS_DEFAULT; + + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = link_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(link_loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(link_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(link_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* 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_LINK_TYPE, &link_type) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value from plist") + if(H5P_set(plist, H5VL_LINK_UDATA, &udata) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value from plist") + if(H5P_set(plist, H5VL_LINK_UDATA_SIZE, &udata_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value from plist") + + /* Create the link through the VOL */ + if((ret_value = H5VL_link_create(H5VL_LINK_CREATE_UD, obj, loc_params, vol_plugin, + lcpl_id, lapl_id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -592,21 +714,33 @@ done: herr_t H5Ldelete(hid_t loc_id, const char *name, hid_t lapl_id) { - H5G_loc_t loc; /* Group's location */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "i*si", loc_id, name, lapl_id); /* 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") - /* Unlink */ - if(H5L_delete(&loc, name, lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.obj_type = H5I_get_type(loc_id); + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Delete the link through the VOL */ + if((ret_value = H5VL_link_remove(obj, loc_params, vol_plugin, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -636,16 +770,15 @@ 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; /* Group's location */ - H5L_trav_rmbi_t udata; /* User data for callback */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "i*sIiIohi", loc_id, group_name, idx_type, order, n, lapl_id); /* Check arguments */ - 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) @@ -658,15 +791,24 @@ H5Ldelete_by_idx(hid_t loc_id, const char *group_name, 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 user data for unlink operation */ - udata.idx_type = idx_type; - udata.order = order; - udata.n = n; - udata.dxpl_id = H5AC_dxpl_id; - - /* Traverse the group hierarchy to remove the link */ - if(H5G_traverse(&loc, group_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK|H5G_TARGET_MOUNT, H5L_delete_by_idx_cb, &udata, lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = group_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Delete the link through the VOL */ + if((ret_value = H5VL_link_remove(obj, loc_params, vol_plugin, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -696,15 +838,15 @@ herr_t H5Lget_val(hid_t loc_id, const char *name, void *buf/*out*/, size_t size, hid_t lapl_id) { - H5G_loc_t loc; /* Group location for location to query */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "i*sxzi", loc_id, name, buf, size, lapl_id); /* Check arguments */ - 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(H5P_DEFAULT == lapl_id) @@ -713,9 +855,22 @@ H5Lget_val(hid_t loc_id, const char *name, void *buf/*out*/, size_t size, if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Get the link value */ - if(H5L_get_val(&loc, name, buf, size, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value for '%s'", name) + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.obj_type = H5I_get_type(loc_id); + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Get the link info through the VOL */ + if((ret_value = H5VL_link_get(obj, loc_params, vol_plugin, H5VL_LINK_GET_VAL, + H5_REQUEST_NULL, buf, size)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get link value") done: FUNC_LEAVE_API(ret_value) @@ -745,8 +900,9 @@ 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/*out*/, size_t size, hid_t lapl_id) { - H5G_loc_t loc; /* Group location for location to query */ - H5L_trav_gvbi_t udata; /* User data for callback */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -754,8 +910,6 @@ H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, lapl_id); /* Check arguments */ - 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) @@ -768,18 +922,25 @@ H5Lget_val_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, 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 user data for retrieving information */ - udata.idx_type = idx_type; - udata.order = order; - udata.n = n; - udata.dxpl_id = H5AC_ind_dxpl_id; - udata.buf = buf; - udata.size = size; - - /* Traverse the group hierarchy to locate the object to get info about */ - if(H5G_traverse(&loc, group_name, H5G_TARGET_SLINK | H5G_TARGET_UDLINK, H5L_get_val_by_idx_cb, &udata, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") - + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = group_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Get the link info through the VOL */ + if((ret_value = H5VL_link_get(obj, loc_params, vol_plugin, H5VL_LINK_GET_VAL, + H5_REQUEST_NULL, buf, size)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get link value") done: FUNC_LEAVE_API(ret_value) @@ -802,15 +963,15 @@ done: htri_t H5Lexists(hid_t loc_id, const char *name, hid_t lapl_id) { - H5G_loc_t loc; + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; htri_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE3("t", "i*si", loc_id, name, lapl_id); /* Check arguments */ - 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(H5P_DEFAULT == lapl_id) @@ -819,9 +980,21 @@ H5Lexists(hid_t loc_id, const char *name, 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") - /* Check for the existence of the link */ - if((ret_value = H5L_exists(&loc, name, lapl_id, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.obj_type = H5I_get_type(loc_id); + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* check link existence through the VOL */ + if(H5VL_link_get(obj, loc_params, vol_plugin, H5VL_LINK_EXISTS, H5_REQUEST_NULL, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get link info") done: FUNC_LEAVE_API(ret_value) @@ -846,15 +1019,14 @@ herr_t H5Lget_info(hid_t loc_id, const char *name, H5L_info_t *linfo /*out*/, hid_t lapl_id) { - H5G_loc_t loc; + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*sxi", loc_id, name, linfo, lapl_id); - /* Check arguments */ - 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(H5P_DEFAULT == lapl_id) @@ -863,9 +1035,22 @@ H5Lget_info(hid_t loc_id, const char *name, H5L_info_t *linfo /*out*/, if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Get the link information */ - if(H5L_get_info(&loc, name, linfo, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.obj_type = H5I_get_type(loc_id); + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Get the link info through the VOL */ + if((ret_value = H5VL_link_get(obj, loc_params, vol_plugin, H5VL_LINK_GET_INFO, + H5_REQUEST_NULL, linfo)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: FUNC_LEAVE_API(ret_value) @@ -891,8 +1076,9 @@ 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 /*out*/, hid_t lapl_id) { - H5G_loc_t loc; /* Group location for group to query */ - H5L_trav_gibi_t udata; /* User data for callback */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -900,8 +1086,6 @@ H5Lget_info_by_idx(hid_t loc_id, const char *group_name, lapl_id); /* Check arguments */ - 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) @@ -914,17 +1098,25 @@ H5Lget_info_by_idx(hid_t loc_id, const char *group_name, 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 user data for callback */ - udata.idx_type = idx_type; - udata.order = order; - udata.n = n; - udata.dxpl_id = H5AC_ind_dxpl_id; - udata.linfo = linfo; - - /* Traverse the group hierarchy to locate the object to get info about */ - if(H5G_traverse(&loc, group_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_get_info_by_idx_cb, &udata, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") - + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = group_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Get the link info through the VOL */ + if((ret_value = H5VL_link_get(obj, loc_params, vol_plugin, H5VL_LINK_GET_INFO, H5_REQUEST_NULL, + linfo)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: FUNC_LEAVE_API(ret_value) @@ -1080,8 +1272,9 @@ 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 /*out*/, size_t size, hid_t lapl_id) { - H5G_loc_t loc; /* Location of group */ - H5L_trav_gnbi_t udata; /* User data for callback */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1089,8 +1282,6 @@ H5Lget_name_by_idx(hid_t loc_id, const char *group_name, lapl_id); /* Check arguments */ - 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) @@ -1103,21 +1294,25 @@ H5Lget_name_by_idx(hid_t loc_id, const char *group_name, 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 user data for callback */ - udata.idx_type = idx_type; - udata.order = order; - udata.n = n; - udata.dxpl_id = H5AC_ind_dxpl_id; - udata.name = name; - udata.size = size; - udata.name_len = -1; - - /* Traverse the group hierarchy to locate the link to get name of */ - if(H5G_traverse(&loc, group_name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_get_name_by_idx_cb, &udata, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") - - /* Set the return value */ - ret_value = udata.name_len; + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = group_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Get the link info through the VOL */ + if((H5VL_link_get(obj, loc_params, vol_plugin, H5VL_LINK_GET_NAME, H5_REQUEST_NULL, + name, size, &ret_value)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get link name") done: FUNC_LEAVE_API(ret_value) @@ -1147,20 +1342,20 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Literate(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, +H5Literate(hid_t id, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, H5L_iterate_t op, void *op_data) { + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; H5I_type_t id_type; /* Type of ID */ - H5G_link_iterate_t lnk_op; /* Link operator */ - hsize_t last_lnk; /* Index of last object looked at */ - hsize_t idx; /* Internal location to hold index */ herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE6("e", "iIiIo*hx*x", grp_id, idx_type, order, idx_p, op, op_data); + H5TRACE6("e", "iIiIo*hx*x", id, idx_type, order, idx_p, op, op_data); /* Check arguments */ - id_type = H5I_get_type(grp_id); + id_type = H5I_get_type(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) @@ -1170,22 +1365,21 @@ H5Literate(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, if(!op) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified") - /* Set up iteration beginning/end info */ - idx = (idx_p == NULL ? 0 : *idx_p); - last_lnk = 0; + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(id); - /* Build link operator info */ - lnk_op.op_type = H5G_LINK_OP_NEW; - lnk_op.op_func.op_new = op; + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Iterate over the links */ - if((ret_value = H5G_iterate(grp_id, ".", idx_type, order, idx, &last_lnk, &lnk_op, op_data, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0) + /* iterate over the links through the VOL */ + if((ret_value = H5VL_link_iterate(obj, loc_params, vol_plugin, FALSE, idx_type, order, idx_p, + op, op_data, H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link iteration failed") - /* Set the index we stopped at */ - if(idx_p) - *idx_p = last_lnk; - done: FUNC_LEAVE_API(ret_value) } /* end H5Literate() */ @@ -1218,9 +1412,9 @@ 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) { - H5G_link_iterate_t lnk_op; /* Link operator */ - hsize_t last_lnk; /* Index of last object looked at */ - hsize_t idx; /* Internal location to hold index */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1242,22 +1436,23 @@ H5Literate_by_name(hid_t loc_id, const char *group_name, 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 iteration beginning/end info */ - idx = (idx_p == NULL ? 0 : *idx_p); - last_lnk = 0; - - /* Build link operator info */ - lnk_op.op_type = H5G_LINK_OP_NEW; - lnk_op.op_func.op_new = op; - - /* Iterate over the links */ - if((ret_value = H5G_iterate(loc_id, group_name, idx_type, order, idx, &last_lnk, &lnk_op, op_data, lapl_id, H5AC_ind_dxpl_id)) < 0) + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.obj_type = H5I_get_type(loc_id); + loc_params.loc_data.loc_by_name.name = group_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* iterate over the links through the VOL */ + if((ret_value = H5VL_link_iterate(obj, loc_params, vol_plugin, FALSE, idx_type, order, idx_p, + op, op_data, H5_REQUEST_NULL)) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link iteration failed") - /* Set the index we stopped at */ - if(idx_p) - *idx_p = last_lnk; - done: FUNC_LEAVE_API(ret_value) } /* end H5Literate_by_name() */ @@ -1295,14 +1490,18 @@ herr_t H5Lvisit(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, H5L_iterate_t op, void *op_data) { + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; H5I_type_t id_type; /* Type of ID */ herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "iIiIox*x", grp_id, idx_type, order, op, op_data); - /* Check args */ id_type = H5I_get_type(grp_id); + + /* Check args */ 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) @@ -1312,9 +1511,20 @@ H5Lvisit(hid_t grp_id, H5_index_t idx_type, H5_iter_order_t order, if(!op) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified") - /* Call internal group visitation routine */ - if((ret_value = H5G_visit(grp_id, ".", idx_type, order, op, op_data, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link visitation failed") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(grp_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(grp_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(grp_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* iterate over the links through the VOL */ + if((ret_value = H5VL_link_iterate(obj, loc_params, vol_plugin, TRUE, idx_type, order, NULL, + op, op_data, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link iteration failed") done: FUNC_LEAVE_API(ret_value) @@ -1353,6 +1563,9 @@ 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) { + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1374,9 +1587,22 @@ H5Lvisit_by_name(hid_t loc_id, const char *group_name, H5_index_t idx_type, if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Call internal group visitation routine */ - if((ret_value = H5G_visit(loc_id, group_name, idx_type, order, op, op_data, lapl_id, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link visitation failed") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.obj_type = H5I_get_type(loc_id); + loc_params.loc_data.loc_by_name.name = group_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* visit the links through the VOL */ + if((ret_value = H5VL_link_iterate(obj, loc_params, vol_plugin, TRUE, idx_type, order, NULL, + op, op_data, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link iteration failed") done: FUNC_LEAVE_API(ret_value) @@ -1755,7 +1981,7 @@ H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED /* Set up location for user-defined callback */ if((grp = H5G_open(&temp_loc, udata->dxpl_id)) == NULL) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") - if((grp_id = H5I_register(H5I_GROUP, grp, TRUE)) < 0) + if((grp_id = H5VL_native_register(H5I_GROUP, grp, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register ID for group") /* Make callback */ @@ -2263,6 +2489,35 @@ done: /*------------------------------------------------------------------------- + * Function: H5L_get_val_by_idx + * + * Purpose: Get Value of a link + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5L_get_val_by_idx(H5G_loc_t *loc, const char *name, void *udata, hid_t lapl_id, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Traverse the group hierarchy to locate the object to get val about */ + if(H5G_traverse(loc, name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_get_val_by_idx_cb, + (H5L_trav_gvbi_t *)udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link val") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_get_val_by_idx() */ + + +/*------------------------------------------------------------------------- * Function: H5L_delete_cb * * Purpose: Callback for deleting a link. This routine @@ -2393,6 +2648,39 @@ done: /*------------------------------------------------------------------------- + * Function: H5L_delete_by_idx + * + * Purpose: Delete a link from a group. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5L_delete_by_idx(H5G_loc_t *loc, const char *name, void *udata, hid_t lapl_id, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(loc); + HDassert(name && *name); + + /* Traverse the group hierarchy to remove the link */ + if(H5G_traverse(loc, name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK|H5G_TARGET_MOUNT, + H5L_delete_by_idx_cb, (H5L_trav_rmbi_t *)udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_delete_by_idx() */ + + +/*------------------------------------------------------------------------- * Function: H5L_move_dest_cb * * Purpose: Second callback for moving and renaming an object. This routine @@ -2467,7 +2755,7 @@ H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, /* Set up location for user-defined callback */ if((grp = H5G_open(&temp_loc, udata->dxpl_id)) == NULL) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") - if((grp_id = H5I_register(H5I_GROUP, grp, TRUE)) < 0) + if((grp_id = H5VL_native_register(H5I_GROUP, grp, TRUE)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group ID") if(udata->copy) { @@ -2752,7 +3040,7 @@ H5L_exists_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, * *------------------------------------------------------------------------- */ -static htri_t +htri_t H5L_exists(const H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id) { hbool_t exists = FALSE; /* Whether the link exists in the group */ @@ -2897,6 +3185,35 @@ done: /*------------------------------------------------------------------------- + * Function: H5L_get_info_by_idx + * + * Purpose: Get_Info a link from a group. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5L_get_info_by_idx(H5G_loc_t *loc, const char *name, void *udata, hid_t lapl_id, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Traverse the group hierarchy to locate the object to get info about */ + if(H5G_traverse(loc, name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_get_info_by_idx_cb, + (H5L_trav_gibi_t *)udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_get_info_by_idx() */ + + +/*------------------------------------------------------------------------- * Function: H5L_get_default_lcpl * * Purpose: Accessor for the default Link Creation Property List @@ -2966,6 +3283,35 @@ done: /*------------------------------------------------------------------------- + * Function: H5L_get_name_by_idx + * + * Purpose: Get name of a link from a group. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5L_get_name_by_idx(H5G_loc_t *loc, const char *name, void *udata, hid_t lapl_id, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Traverse the group hierarchy to locate the object to get name about */ + if(H5G_traverse(loc, name, H5G_TARGET_SLINK|H5G_TARGET_UDLINK, H5L_get_name_by_idx_cb, + (H5L_trav_gnbi_t *)udata, lapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link name") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_get_name_by_idx() */ + + +/*------------------------------------------------------------------------- * Function: H5L_link_copy_file * * Purpose: Copy a link and the object it points to from one file to diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index a1245ba..0739daf 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -28,6 +28,8 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Opublic.h" /* File objects */ #include "H5Pprivate.h" /* Property lists */ +#include "H5VLnative.h" /* Native Plugin */ +#include "H5VLprivate.h" /* Virtual Object Layer */ static hid_t H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, const void *udata, size_t UNUSED udata_size, hid_t lapl_id); @@ -443,6 +445,19 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, if((ext_obj = H5O_open_name(&root_loc, obj_name, lapl_id, FALSE)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") + /* get the native object from the ID created by the object header and create + a "VOL object" ID */ + { + void *temp_obj = NULL; + H5I_type_t obj_type; + obj_type = H5I_get_type(ext_obj); + if(NULL == (temp_obj = H5I_remove(ext_obj))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") + /* Get an atom for the datatype */ + if((ext_obj = H5VL_native_register(obj_type, temp_obj, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype") + } + /* Set return value */ ret_value = ext_obj; @@ -542,13 +557,17 @@ 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 */ 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 */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; + 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) @@ -560,11 +579,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_SYM, H5E_BADVALUE, FAIL, "can't normalize object name") @@ -583,9 +604,34 @@ H5Lcreate_external(const char *file_name, const char *obj_name, p += file_name_len; HDstrncpy((char *)p, norm_obj_name, norm_obj_name_len); /* External link's object */ - /* Create an external link */ - if(H5L_create_ud(&link_loc, link_name, ext_link_buf, buf_size, H5L_TYPE_EXTERNAL, lcpl_id, lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = link_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(link_loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(link_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(link_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* 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_LINK_TYPE, &link_type) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value from plist") + if(H5P_set(plist, H5VL_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_LINK_UDATA_SIZE, &buf_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value from plist") + + /* Create the link through the VOL */ + if((ret_value = H5VL_link_create(H5VL_LINK_CREATE_UD, obj, loc_params, vol_plugin, + lcpl_id, lapl_id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: H5MM_xfree(ext_link_buf); diff --git a/src/H5Lprivate.h b/src/H5Lprivate.h index f3079bc..e4cb328 100644 --- a/src/H5Lprivate.h +++ b/src/H5Lprivate.h @@ -49,6 +49,53 @@ /****************************/ /* Library Private Typedefs */ /****************************/ +/* User data for path traversal routine for getting link value by index */ +typedef struct { + /* In */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ + hid_t dxpl_id; /* DXPL to use in callback */ + size_t size; /* Size of user buffer */ + + /* Out */ + void *buf; /* User buffer */ +} H5L_trav_gvbi_t; + +/* User data for path traversal routine for getting link info by index */ +typedef struct { + /* In */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ + hid_t dxpl_id; /* DXPL to use in callback */ + + /* Out */ + H5L_info_t *linfo; /* Buffer to return to user */ +} H5L_trav_gibi_t; + +/* User data for path traversal routine for getting name by index */ +typedef struct { + /* In */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ + size_t size; /* Size of name buffer */ + hid_t dxpl_id; /* DXPL to use in callback */ + + /* Out */ + char *name; /* Buffer to return name to user */ + ssize_t name_len; /* Length of full name */ +} H5L_trav_gnbi_t; + +/* User data for path traversal routine for removing link by index */ +typedef struct { + /* In */ + H5_index_t idx_type; /* Index to use */ + H5_iter_order_t order; /* Order to iterate in index */ + hsize_t n; /* Offset of link within index */ + hid_t dxpl_id; /* DXPL to use in callback */ +} H5L_trav_rmbi_t; /* Structure for external link traversal callback property */ typedef struct H5L_elink_cb_t { @@ -85,8 +132,17 @@ H5_DLL herr_t H5L_get_info(const H5G_loc_t *loc, const char *name, H5L_info_t *linkbuf/*out*/, hid_t lapl_id, hid_t dxpl_id); H5_DLL herr_t H5L_delete(H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id); +H5_DLL herr_t H5L_delete_by_idx(H5G_loc_t *loc, const char *name, + void *udata, hid_t lapl_id, hid_t dxpl_id); +H5_DLL htri_t H5L_exists(const H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id); +H5_DLL herr_t H5L_get_info_by_idx(H5G_loc_t *loc, const char *name, void *udata, + hid_t lapl_id, hid_t dxpl_id); +H5_DLL herr_t H5L_get_name_by_idx(H5G_loc_t *loc, const char *name, void *udata, + hid_t lapl_id, hid_t dxpl_id); H5_DLL herr_t H5L_get_val(H5G_loc_t *loc, const char *name, void *buf/*out*/, size_t size, hid_t lapl_id, hid_t dxpl_id); +H5_DLL herr_t H5L_get_val_by_idx(H5G_loc_t *loc, const char *name, void *udata, + hid_t lapl_id, hid_t dxpl_id); H5_DLL herr_t H5L_register_external(void); /* User-defined link functions */ @@ -46,7 +46,8 @@ #include "H5MFprivate.h" /* File memory management */ #include "H5Opkg.h" /* Object headers */ #include "H5SMprivate.h" /* Shared object header messages */ - +#include "H5VLnative.h" /* Native Plugin */ +#include "H5VLprivate.h" /* Virtual Object Layer */ /****************/ /* Local Macros */ @@ -80,9 +81,6 @@ typedef struct { static herr_t H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh); static herr_t H5O_obj_type_real(H5O_t *oh, H5O_type_t *obj_type); -static herr_t H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type, - H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id, - hid_t dxpl_id); static herr_t H5O_get_hdr_info_real(const H5O_t *oh, H5O_hdr_info_t *hdr); static const H5O_obj_class_t *H5O_obj_class_real(H5O_t *oh); @@ -230,21 +228,38 @@ H5O_init_interface(void) hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id) { - H5G_loc_t loc; + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5I_type_t opened_type; + void *opened_obj = NULL; + H5VL_loc_params_t loc_params; hid_t ret_value = FAIL; FUNC_ENTER_API(FAIL) H5TRACE3("i", "i*si", loc_id, name, lapl_id); - /* Check args */ - 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") - /* Open the object */ - if((ret_value = H5O_open_name(&loc, name, lapl_id, TRUE)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Open the object through the VOL */ + if(NULL == (opened_obj = H5VL_object_open(obj, loc_params, vol_plugin, &opened_type, + H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") + + if ((ret_value = H5VL_object_register(opened_obj, opened_type, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: FUNC_LEAVE_API(ret_value) @@ -278,19 +293,17 @@ hid_t H5Oopen_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; - H5G_loc_t obj_loc; /* Location used to open group */ - 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 */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5I_type_t opened_type; + void *opened_obj = NULL; + H5VL_loc_params_t loc_params; hid_t ret_value = FAIL; FUNC_ENTER_API(FAIL) H5TRACE6("i", "i*sIiIohi", loc_id, group_name, idx_type, order, n, lapl_id); /* Check args */ - 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) @@ -303,26 +316,29 @@ H5Oopen_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, 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 group location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = group_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); - /* Find the object's location, according to the order in the index */ - if(H5G_loc_find_by_idx(&loc, group_name, idx_type, order, n, &obj_loc/*out*/, lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") - loc_found = TRUE; + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Open the object */ - if((ret_value = H5O_open_by_loc(&obj_loc, lapl_id, H5AC_dxpl_id, TRUE)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") + /* Open the object through the VOL */ + if(NULL == (opened_obj = H5VL_object_open(obj, loc_params, vol_plugin, &opened_type, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") -done: - /* Release the object location if we failed after copying it */ - if(ret_value < 0 && loc_found) - if(H5G_loc_free(&obj_loc) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + if ((ret_value = H5VL_object_register(opened_obj, opened_type, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") +done: FUNC_LEAVE_API(ret_value) } /* end H5Oopen_by_idx() */ @@ -365,36 +381,35 @@ done: hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr) { - H5G_loc_t loc; - H5G_loc_t obj_loc; /* Location used to open group */ - H5G_name_t obj_path; /* Opened object group hier. path */ - H5O_loc_t obj_oloc; /* Opened object object location */ - hid_t lapl_id = H5P_LINK_ACCESS_DEFAULT; /* lapl to use to open this object */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5I_type_t opened_type; + void *opened_obj = NULL; + H5VL_loc_params_t loc_params; hid_t ret_value = FAIL; FUNC_ENTER_API(FAIL) H5TRACE2("i", "ia", loc_id, addr); - /* Check args */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(!H5F_addr_defined(addr)) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no address supplied") + loc_params.type = H5VL_OBJECT_BY_ADDR; + loc_params.loc_data.loc_by_addr.addr = addr; + loc_params.obj_type = H5I_get_type(loc_id); - /* Set up opened group location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); - obj_loc.oloc->addr = addr; - obj_loc.oloc->file = loc.oloc->file; - H5G_name_reset(obj_loc.path); /* objects opened through this routine don't have a path name */ + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Open the object */ - if((ret_value = H5O_open_by_loc(&obj_loc, lapl_id, H5AC_dxpl_id, TRUE)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") + /* Open the object through the VOL */ + if(NULL == (opened_obj = H5VL_object_open(obj, loc_params, vol_plugin, &opened_type, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") -done: + if ((ret_value = H5VL_object_register(opened_obj, opened_type, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") +done: FUNC_LEAVE_API(ret_value) } /* end H5Oopen_by_addr() */ @@ -424,20 +439,21 @@ herr_t H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, hid_t lapl_id) { - H5G_loc_t new_loc; - H5G_loc_t obj_loc; - herr_t ret_value = SUCCEED; /* Return value */ + void *obj1 = NULL; /* object token of loc_id */ + void *obj2 = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin1 = NULL; /* VOL plugin information */ + H5VL_t *vol_plugin2 = NULL; /* VOL plugin information */ + H5VL_loc_params_t loc_params1; + H5VL_loc_params_t loc_params2; + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("e", "ii*sii", obj_id, new_loc_id, new_name, lcpl_id, lapl_id); /* Check arguments */ - if(H5G_loc(obj_id, &obj_loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(new_loc_id == H5L_SAME_LOC) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "cannot use H5L_SAME_LOC when only one location is specified") - if(H5G_loc(new_loc_id, &new_loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!new_name || !*new_name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") /* Avoid compiler warning on 32-bit machines */ @@ -448,9 +464,55 @@ H5Olink(hid_t obj_id, hid_t new_loc_id, const char *new_name, hid_t lcpl_id, 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") - /* Link to the object */ - if(H5L_link(&new_loc, new_name, &obj_loc, lcpl_id, lapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + /* Check the group access property list */ + if(H5P_DEFAULT == lcpl_id) + lcpl_id = H5P_LINK_CREATE_DEFAULT; + + loc_params1.type = H5VL_OBJECT_BY_SELF; + loc_params1.obj_type = H5I_get_type(obj_id); + + loc_params2.type = H5VL_OBJECT_BY_NAME; + loc_params2.obj_type = H5I_get_type(new_loc_id); + loc_params2.loc_data.loc_by_name.name = new_name; + loc_params2.loc_data.loc_by_name.plist_id = lapl_id; + + if(H5L_SAME_LOC != obj_id) { + /* get the file object */ + if(NULL == (obj1 = (void *)H5VL_get_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + } + if(H5L_SAME_LOC != new_loc_id) { + /* get the file object */ + if(NULL == (obj2 = (void *)H5VL_get_object(new_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(new_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + } + /* Make sure that the VOL plugins are the same */ + if(H5L_SAME_LOC != new_loc_id && H5L_SAME_LOC != obj_id) { + if (vol_plugin1->cls != vol_plugin2->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL plugins and can't be linked") + } + + /* 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_LINK_TARGET, &obj1) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target id") + if(H5P_set(plist, H5VL_LINK_TARGET_LOC_PARAMS, &loc_params1) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set property value for target id") + + /* Create the link through the VOL */ + if((ret_value = H5VL_link_create(H5VL_LINK_CREATE_HARD, obj2, loc_params2, + (vol_plugin1!=NULL ? vol_plugin1 : vol_plugin2), + lcpl_id, lapl_id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create link") done: FUNC_LEAVE_API(ret_value) @@ -480,17 +542,27 @@ done: herr_t H5Oincr_refcount(hid_t object_id) { - H5O_loc_t *oloc; + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", object_id); - /* Get the object's oloc so we can adjust its link count */ - if((oloc = H5O_get_loc(object_id)) == NULL) - HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(object_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(object_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(object_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - if(H5O_link(oloc, 1, H5AC_dxpl_id) < 0) + /* change the ref count through the VOL */ + if(H5VL_object_misc(obj, loc_params, vol_plugin, H5VL_OBJECT_CHANGE_REF_COUNT, + H5_REQUEST_NULL, 1) < 0) HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "modifying object link count failed") done: @@ -521,17 +593,26 @@ done: herr_t H5Odecr_refcount(hid_t object_id) { - H5O_loc_t *oloc; + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; FUNC_ENTER_API(FAIL) H5TRACE1("e", "i", object_id); - /* Get the object's oloc so we can adjust its link count */ - if((oloc = H5O_get_loc(object_id)) == NULL) - HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(object_id); - if(H5O_link(oloc, -1, H5AC_dxpl_id) < 0) + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(object_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(object_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* change the ref count through the VOL */ + if(H5VL_object_misc(obj, loc_params, vol_plugin, H5VL_OBJECT_CHANGE_REF_COUNT, H5_REQUEST_NULL, -1) < 0) HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "modifying object link count failed") done: @@ -555,15 +636,15 @@ done: htri_t H5Oexists_by_name(hid_t loc_id, const char *name, hid_t lapl_id) { - H5G_loc_t loc; /* Location info */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("t", "i*si", loc_id, name, lapl_id); /* Check args */ - 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(H5P_DEFAULT == lapl_id) @@ -572,8 +653,20 @@ H5Oexists_by_name(hid_t loc_id, const char *name, 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") - /* Check if the object exists */ - if((ret_value = H5G_loc_exists(&loc, name, lapl_id, H5AC_dxpl_id)) < 0) + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* change the ref count through the VOL */ + if(H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_EXISTS, H5_REQUEST_NULL, &ret_value) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine if '%s' exists", name) done: @@ -597,21 +690,32 @@ done: herr_t H5Oget_info(hid_t loc_id, H5O_info_t *oinfo) { - H5G_loc_t loc; /* Location of group */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*x", loc_id, oinfo); /* Check args */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!oinfo) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct") - /* Retrieve the object's information */ - if(H5G_loc_info(&loc, ".", TRUE, oinfo/*out*/, H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Get the group info through the VOL using the location token */ + if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_GET_INFO, + H5_REQUEST_NULL, oinfo)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: FUNC_LEAVE_API(ret_value) @@ -634,15 +738,15 @@ done: herr_t H5Oget_info_by_name(hid_t loc_id, const char *name, H5O_info_t *oinfo, hid_t lapl_id) { - H5G_loc_t loc; /* Location of group */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*s*xi", loc_id, name, oinfo, lapl_id); /* Check args */ - 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(!oinfo) @@ -653,9 +757,23 @@ H5Oget_info_by_name(hid_t loc_id, const char *name, H5O_info_t *oinfo, hid_t lap if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Retrieve the object's information */ - if(H5G_loc_info(&loc, name, TRUE, oinfo/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Get the group info through the VOL using the location token */ + if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_GET_INFO, + H5_REQUEST_NULL, oinfo)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: FUNC_LEAVE_API(ret_value) @@ -680,11 +798,9 @@ herr_t H5Oget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, H5O_info_t *oinfo, hid_t lapl_id) { - H5G_loc_t loc; /* Location of group */ - H5G_loc_t obj_loc; /* Location used to open group */ - 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 */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) @@ -692,8 +808,6 @@ H5Oget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, lapl_id); /* Check args */ - 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) @@ -708,25 +822,27 @@ H5Oget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type, 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 group location to fill in */ - obj_loc.oloc = &obj_oloc; - obj_loc.path = &obj_path; - H5G_loc_reset(&obj_loc); - - /* Find the object's location, according to the order in the index */ - if(H5G_loc_find_by_idx(&loc, group_name, idx_type, order, n, &obj_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") - loc_found = TRUE; - - /* Retrieve the object's information */ - if(H5O_get_info(obj_loc.oloc, H5AC_ind_dxpl_id, TRUE, oinfo) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve object info") + loc_params.type = H5VL_OBJECT_BY_IDX; + loc_params.loc_data.loc_by_idx.name = group_name; + loc_params.loc_data.loc_by_idx.idx_type = idx_type; + loc_params.loc_data.loc_by_idx.order = order; + loc_params.loc_data.loc_by_idx.n = n; + loc_params.loc_data.loc_by_idx.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Get the group info through the VOL using the location token */ + if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_GET_INFO, + H5_REQUEST_NULL, oinfo)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: - /* Release the object location */ - if(loc_found && 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_by_idx() */ @@ -751,19 +867,27 @@ done: herr_t H5Oset_comment(hid_t obj_id, const char *comment) { - H5G_loc_t loc; /* Location of group */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE2("e", "i*s", obj_id, comment); - /* Check args */ - if(H5G_loc(obj_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(obj_id); - /* (Re)set the object's comment */ - if(H5G_loc_set_comment(&loc, ".", comment, H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* set comment on object through the VOL */ + if(H5VL_object_misc(obj, loc_params, vol_plugin, H5VL_OBJECT_SET_COMMENT, H5_REQUEST_NULL, comment) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to set comment value") done: FUNC_LEAVE_API(ret_value) @@ -791,15 +915,15 @@ herr_t H5Oset_comment_by_name(hid_t loc_id, const char *name, const char *comment, hid_t lapl_id) { - H5G_loc_t loc; /* Location of group */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "i*s*si", loc_id, name, comment, lapl_id); /* Check args */ - 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(H5P_DEFAULT == lapl_id) @@ -808,9 +932,21 @@ H5Oset_comment_by_name(hid_t loc_id, const char *name, const char *comment, if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* (Re)set the object's comment */ - if(H5G_loc_set_comment(&loc, name, comment, lapl_id, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* set comment on object through the VOL */ + if(H5VL_object_misc(obj, loc_params, vol_plugin, H5VL_OBJECT_SET_COMMENT, H5_REQUEST_NULL, comment) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to set comment value") done: FUNC_LEAVE_API(ret_value) @@ -834,21 +970,29 @@ done: *------------------------------------------------------------------------- */ ssize_t -H5Oget_comment(hid_t obj_id, char *comment, size_t bufsize) +H5Oget_comment(hid_t loc_id, char *comment, size_t bufsize) { - H5G_loc_t loc; /* Location of group */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE3("Zs", "i*sz", obj_id, comment, bufsize); + H5TRACE3("Zs", "i*sz", loc_id, comment, bufsize); - /* Check args */ - if(H5G_loc(obj_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); - /* Retrieve the object's comment */ - if((ret_value = H5G_loc_get_comment(&loc, ".", comment/*out*/, bufsize, H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + if(H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_GET_COMMENT, H5_REQUEST_NULL, + comment, bufsize, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get object comment") done: FUNC_LEAVE_API(ret_value) @@ -875,15 +1019,15 @@ ssize_t H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comment, size_t bufsize, hid_t lapl_id) { - H5G_loc_t loc; /* Location of group */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("Zs", "i*s*szi", loc_id, name, comment, bufsize, lapl_id); /* Check args */ - 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(H5P_DEFAULT == lapl_id) @@ -892,9 +1036,21 @@ H5Oget_comment_by_name(hid_t loc_id, const char *name, char *comment, size_t buf if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Retrieve the object's comment */ - if((ret_value = H5G_loc_get_comment(&loc, name, comment/*out*/, bufsize, lapl_id, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + if(H5VL_object_get(obj, loc_params, vol_plugin, H5VL_OBJECT_GET_COMMENT, H5_REQUEST_NULL, + comment, bufsize, &ret_value) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get object info") done: FUNC_LEAVE_API(ret_value) @@ -937,6 +1093,9 @@ herr_t H5Ovisit(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op, void *op_data) { + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -950,9 +1109,20 @@ H5Ovisit(hid_t obj_id, H5_index_t idx_type, H5_iter_order_t order, if(!op) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no callback operator specified") - /* Call internal object visitation routine */ - if((ret_value = H5O_visit(obj_id, ".", idx_type, order, op, op_data, H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "object visitation failed") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(obj_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* iterate over the objects through the VOL */ + if((ret_value = H5VL_object_visit(obj, loc_params, vol_plugin, idx_type, order, op, op_data, + H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link iteration failed") done: FUNC_LEAVE_API(ret_value) @@ -995,6 +1165,9 @@ herr_t H5Ovisit_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id) { + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -1016,9 +1189,22 @@ H5Ovisit_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID") - /* Call internal object visitation routine */ - if((ret_value = H5O_visit(loc_id, obj_name, idx_type, order, op, op_data, lapl_id, H5AC_ind_dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "object visitation failed") + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = obj_name; + loc_params.loc_data.loc_by_name.plist_id = lapl_id; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5VL_get_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* iterate over the objects through the VOL */ + if((ret_value = H5VL_object_visit(obj, loc_params, vol_plugin, idx_type, order, op, + op_data, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link iteration failed") done: FUNC_LEAVE_API(ret_value) @@ -1080,6 +1266,12 @@ H5Oclose(hid_t object_id) break; } /* end switch */ +#if 0 + /* Close the object through the VOL */ + if(H5VL_object_close(object_id, H5_REQUEST_NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close object") +#endif + done: FUNC_LEAVE_API(ret_value) } /* end H5Oclose() */ @@ -1443,7 +1635,7 @@ H5O_close(H5O_loc_t *loc) #ifdef H5O_DEBUG if(H5DEBUG(O)) { - if(H5F_FILE_ID(loc->file)< 0 && 1 == H5F_NREFS(loc->file)) + if(H5F_FILE_ID(loc->file) && 1 == H5F_NREFS(loc->file)) HDfprintf(H5DEBUG(O), "< %a auto %lu remaining\n", loc->addr, (unsigned long)H5F_NOPEN_OBJS(loc->file)); @@ -1456,10 +1648,11 @@ H5O_close(H5O_loc_t *loc) * If the file open object count has reached the number of open mount points * (each of which has a group open in the file) attempt to close the file. */ - if(H5F_NOPEN_OBJS(loc->file) == H5F_NMOUNTS(loc->file)) + if(H5F_NOPEN_OBJS(loc->file) == H5F_NMOUNTS(loc->file)) { /* Attempt to close down the file hierarchy */ if(H5F_try_close(loc->file) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close") + } /* Release location information */ if(H5O_loc_free(loc) < 0) @@ -2474,6 +2667,7 @@ H5O_get_loc(hid_t object_id) case H5I_ATTR: case H5I_REFERENCE: case H5I_VFL: + case H5I_VOL: case H5I_GENPROP_CLS: case H5I_GENPROP_LST: case H5I_ERROR_CLASS: @@ -3254,13 +3448,12 @@ done: * *------------------------------------------------------------------------- */ -static herr_t -H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type, +herr_t +H5O_visit(H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id, hid_t dxpl_id) { H5O_iter_visit_ud_t udata; /* User data for callback */ - H5G_loc_t loc; /* Location of reference object */ 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 */ @@ -3274,17 +3467,13 @@ H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type, /* Portably initialize user data struct to zeros */ HDmemset(&udata, 0, sizeof(udata)); - /* Check args */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - /* Set up opened group 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, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0) + if(H5G_loc_find(loc, obj_name, &obj_loc/*out*/, lapl_id, dxpl_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "object not found") loc_found = TRUE; @@ -3297,6 +3486,40 @@ H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type, if((obj_id = H5O_open_by_loc(&obj_loc, lapl_id, dxpl_id, TRUE)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object") + /* get the native object from the ID created by the object header and create + a "VOL object" ID */ + { + void *temp_obj = NULL; + H5I_type_t obj_type; + obj_type = H5I_get_type(obj_id); + if(NULL == (temp_obj = H5I_remove(obj_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") + /* Get an atom for the datatype */ + if((obj_id = H5VL_native_register(obj_type, temp_obj, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype") + } +#if 0 + /* if this is a named datatype, we need to create the two-fold datatype + to be comaptible with the VOL */ + if(H5I_DATATYPE == H5I_get_type(obj_id)) { + H5T_t *type = NULL; + void *temp_obj = NULL; + + if(NULL == (temp_obj = H5I_remove(obj_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") + + /* Copy the dataset's datatype */ + if(NULL == (type = H5T_copy((H5T_t *)temp_obj, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy datatype") + + H5T_set_vol_object(type, temp_obj); + + /* Get an atom for the datatype */ + if((obj_id = H5VL_native_register(H5I_DATATYPE, type, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype") + } +#endif + /* Make callback for starting object */ if((ret_value = op(obj_id, ".", &oinfo, op_data)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "can't visit objects") @@ -3308,6 +3531,7 @@ H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type, /* Check for object being a group */ if(oinfo.type == H5O_TYPE_GROUP) { H5G_loc_t start_loc; /* Location of starting group */ + H5G_loc_t vis_loc; /* Location of visited group */ /* Get the location of the starting group */ if(H5G_loc(obj_id, &start_loc) < 0) @@ -3343,8 +3567,12 @@ H5O_visit(hid_t loc_id, const char *obj_name, H5_index_t idx_type, HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object node into visited list") } /* end if */ + /* Get the location of the visited group */ + if(H5G_loc(obj_id, &vis_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") /* Call internal group visitation routine */ - if((ret_value = H5G_visit(obj_id, ".", idx_type, order, H5O_visit_cb, &udata, lapl_id, dxpl_id)) < 0) + if((ret_value = H5G_visit(&vis_loc, ".", idx_type, order, H5O_visit_cb, &udata, + lapl_id, dxpl_id)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") } /* end if */ diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index dc79e47..597c7e1 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -45,7 +45,7 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ #include "H5Pprivate.h" /* Property lists */ - +#include "H5VLprivate.h" /* VOL */ /****************/ /* Local Macros */ @@ -205,10 +205,78 @@ herr_t H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id) { - H5G_loc_t loc; /* Source group group location */ - H5G_loc_t src_loc; /* Source object group location */ - H5G_loc_t dst_loc; /* Destination group location */ + void *obj1 = NULL; /* object token of src_id */ + H5VL_t *vol_plugin1; /* VOL plugin information */ + H5VL_loc_params_t loc_params1; + void *obj2 = NULL; /* object token of dst_id */ + H5VL_t *vol_plugin2; /* VOL plugin information */ + H5VL_loc_params_t loc_params2; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE6("e", "i*si*sii", src_loc_id, src_name, dst_loc_id, dst_name, + ocpypl_id, lcpl_id); + + /* Get correct property lists */ + if(H5P_DEFAULT == lcpl_id) { + if((lcpl_id = H5L_get_default_lcpl()) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to get default lcpl") + } /* end if */ + else + if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list") + /* Get object copy property list */ + if(H5P_DEFAULT == ocpypl_id) + ocpypl_id = H5P_OBJECT_COPY_DEFAULT; + else + if(TRUE != H5P_isa_class(ocpypl_id, H5P_OBJECT_COPY)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not object copy property list") + + /* get the object */ + if(NULL == (obj1 = (void *)H5I_object(src_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin1 = (H5VL_t *)H5I_get_aux(src_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "src ID does not contain VOL information") + loc_params1.type = H5VL_OBJECT_BY_SELF; + loc_params1.obj_type = H5I_get_type(src_loc_id); + + /* get the object */ + if(NULL == (obj2 = (void *)H5I_object(dst_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin2 = (H5VL_t *)H5I_get_aux(dst_loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dst ID does not contain VOL information") + loc_params2.type = H5VL_OBJECT_BY_SELF; + loc_params2.obj_type = H5I_get_type(dst_loc_id); + + /* Open the object through the VOL */ + if((ret_value = H5VL_object_copy(obj1, loc_params1, vol_plugin1, src_name, + obj2, loc_params2, vol_plugin2, dst_name, + ocpypl_id, lcpl_id, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Ocopy() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_copy + * + * Purpose: private version of H5Ocopy + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t H5O_copy(H5G_loc_t *loc, const char *src_name, H5G_loc_t *dst_loc, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id) +{ + H5G_loc_t src_loc; /* Source object group location */ /* for opening the destination object */ H5G_name_t src_path; /* Opened source object hier. path */ H5O_loc_t src_oloc; /* Opened source object object location */ @@ -217,19 +285,7 @@ H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(FAIL) - H5TRACE6("e", "i*si*sii", src_loc_id, src_name, dst_loc_id, dst_name, - ocpypl_id, lcpl_id); - - /* Check arguments */ - if(H5G_loc(src_loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(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 source name specified") - if(!dst_name || !*dst_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified") + FUNC_ENTER_NOAPI_NOINIT /* check if destination name already exists */ { @@ -243,7 +299,7 @@ H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, H5G_loc_reset(&tmp_loc); /* Check if object already exists in destination */ - if(H5G_loc_find(&dst_loc, dst_name, &tmp_loc, H5P_DEFAULT, H5AC_dxpl_id) >= 0) { + if(H5G_loc_find(dst_loc, dst_name, &tmp_loc, H5P_DEFAULT, H5AC_dxpl_id) >= 0) { H5G_name_free(&tmp_path); HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "destination object already exists") } /* end if */ @@ -255,7 +311,7 @@ H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, H5G_loc_reset(&src_loc); /* Find the source object to copy */ - if(H5G_loc_find(&loc, src_name, &src_loc/*out*/, H5P_DEFAULT, H5AC_dxpl_id) < 0) + if(H5G_loc_find(loc, src_name, &src_loc/*out*/, H5P_DEFAULT, H5AC_dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found") loc_found = TRUE; @@ -264,24 +320,8 @@ H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object") obj_open = TRUE; - /* Get correct property lists */ - if(H5P_DEFAULT == lcpl_id) { - if((lcpl_id = H5L_get_default_lcpl()) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to get default lcpl") - } /* end if */ - else - if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list") - - /* Get object copy property list */ - if(H5P_DEFAULT == ocpypl_id) - ocpypl_id = H5P_OBJECT_COPY_DEFAULT; - else - if(TRUE != H5P_isa_class(ocpypl_id, H5P_OBJECT_COPY)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not object copy property list") - /* Do the actual copying of the object */ - if(H5O_copy_obj(&src_loc, &dst_loc, dst_name, ocpypl_id, lcpl_id) < 0) + if(H5O_copy_obj(&src_loc, dst_loc, dst_name, ocpypl_id, lcpl_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") done: @@ -290,8 +330,8 @@ done: if(obj_open) H5O_close(&src_oloc); - FUNC_LEAVE_API(ret_value) -} /* end H5Ocopy() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_copy() */ /*------------------------------------------------------------------------- @@ -1769,7 +1809,7 @@ H5O_copy_search_comm_dt(H5F_t *file_src, H5O_t *oh_src, HDassert(oh_src); HDassert(oloc_dst); HDassert(oloc_dst->file); - HDassert(H5F_FILE_ID(oloc_dst->file) >= 0); + HDassert(H5F_FILE_ID(oloc_dst->file)); HDassert(cpy_info); /* Allocate key */ @@ -1881,7 +1921,7 @@ H5O_copy_search_comm_dt(H5F_t *file_src, H5O_t *oh_src, /* Traverse the destination file, adding committed datatypes to the skip * list */ - if(H5G_visit(H5F_FILE_ID(oloc_dst->file), "/", H5_INDEX_NAME, H5_ITER_NATIVE, H5O_copy_search_comm_dt_cb, &udata, H5P_LINK_ACCESS_DEFAULT, dxpl_id) < 0) + if(H5G_visit(&dst_root_loc, "/", H5_INDEX_NAME, H5_ITER_NATIVE, H5O_copy_search_comm_dt_cb, &udata, H5P_LINK_ACCESS_DEFAULT, dxpl_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "object visitation failed") cpy_info->dst_dt_list_complete = TRUE; } /* end if */ diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 1f8a1cd..9319a28 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -533,6 +533,9 @@ H5_DLL int H5O_link_oh(H5F_t *f, int adjust, hid_t dxpl_id, H5O_t *oh, hbool_t * H5_DLL herr_t H5O_inc_rc(H5O_t *oh); H5_DLL herr_t H5O_dec_rc(H5O_t *oh); H5_DLL herr_t H5O_free(H5O_t *oh); +H5_DLL herr_t H5O_visit(H5G_loc_t *loc, const char *obj_name, H5_index_t idx_type, + H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id, + hid_t dxpl_id); /* Object header message routines */ H5_DLL herr_t H5O_msg_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh, diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 8e2dfa4..0acffae 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -738,6 +738,9 @@ H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst H5_DLL herr_t H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id, H5F_t *file_dst, void *_dst_ref, size_t ref_count, H5R_type_t ref_type, H5O_copy_t *cpy_info); +H5_DLL herr_t H5O_copy(H5G_loc_t *src_loc, const char *src_name, + H5G_loc_t *dst_loc, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id); /* Debugging routines */ H5_DLL herr_t H5O_debug_id(unsigned type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth); diff --git a/src/H5Pacpl.c b/src/H5Pacpl.c index b30bf1e..df972b2 100644 --- a/src/H5Pacpl.c +++ b/src/H5Pacpl.c @@ -33,7 +33,9 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ +#include "H5Aprivate.h" /* Attributes */ #include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ #include "H5Ppkg.h" /* Property lists */ @@ -41,6 +43,9 @@ /* Local Macros */ /****************/ +/* Definitions for locations parameters */ +#define H5A_CRT_LOCATION_SIZE sizeof(H5VL_loc_params_t) +#define H5A_CRT_LOCATION_DEF {H5I_BADID} /******************/ /* Local Typedefs */ @@ -55,7 +60,8 @@ /********************/ /* Local Prototypes */ /********************/ - +/* Property class callbacks */ +static herr_t H5P_acrt_reg_prop(H5P_genclass_t *pclass); /*********************/ /* Package Variables */ @@ -68,7 +74,7 @@ const H5P_libclass_t H5P_CLS_ACRT[1] = {{ &H5P_CLS_STRING_CREATE_g, /* Parent class ID */ &H5P_CLS_ATTRIBUTE_CREATE_g, /* Pointer to class ID */ &H5P_LST_ATTRIBUTE_CREATE_g, /* Pointer to default property list ID */ - NULL, /* Default property registration routine */ + H5P_acrt_reg_prop, /* Default property registration routine */ NULL, /* Class creation callback */ NULL, /* Class creation callback info */ NULL, /* Class copy callback */ @@ -83,3 +89,43 @@ const H5P_libclass_t H5P_CLS_ACRT[1] = {{ /*****************************/ + +/*------------------------------------------------------------------------- + * Function: H5P_acrt_reg_prop + * + * Purpose: Register the attribute creation property list class's properties + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April 5, 2012 + *------------------------------------------------------------------------- + */ +static herr_t +H5P_acrt_reg_prop(H5P_genclass_t *pclass) +{ + hid_t type_id = FAIL; + hid_t space_id = FAIL; + H5VL_loc_params_t loc_params = H5A_CRT_LOCATION_DEF; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Register the type ID property*/ + if(H5P_register_real(pclass, H5VL_ATTR_TYPE_ID, sizeof(hid_t), &type_id, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register the space ID property */ + if(H5P_register_real(pclass, H5VL_ATTR_SPACE_ID, sizeof(hid_t), &space_id, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register the lcpl ID property */ + if(H5P_register_real(pclass, H5VL_ATTR_LOC_PARAMS, H5A_CRT_LOCATION_SIZE, &loc_params, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_acrt_reg_prop() */ diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index b3090ab..6117ff5 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -203,6 +203,9 @@ static hbool_t H5P_dcrt_def_layout_init_g = FALSE; static herr_t H5P__dcrt_reg_prop(H5P_genclass_t *pclass) { + hid_t type_id = FAIL; + hid_t space_id = FAIL; + hid_t lcpl_id = H5P_LINK_CREATE_DEFAULT; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -231,6 +234,21 @@ H5P__dcrt_reg_prop(H5P_genclass_t *pclass) NULL, NULL, H5D_CRT_EXT_FILE_LIST_CMP, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the type ID property*/ + if(H5P_register_real(pclass, H5VL_DSET_TYPE_ID, sizeof(hid_t), &type_id, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register the space ID property */ + if(H5P_register_real(pclass, H5VL_DSET_SPACE_ID, sizeof(hid_t), &space_id, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register the lcpl ID property */ + if(H5P_register_real(pclass, H5VL_DSET_LCPL_ID, sizeof(hid_t), &lcpl_id, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P__dcrt_reg_prop() */ diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 4faed4f..0636095 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -29,7 +29,6 @@ /****************/ #define H5P_PACKAGE /*suppress error about including H5Ppkg */ - /***********/ /* Headers */ /***********/ @@ -39,6 +38,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5Fprivate.h" /* Files */ #include "H5FDprivate.h" /* File drivers */ +#include "H5VLprivate.h" /* VOL plugins */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory Management */ #include "H5Ppkg.h" /* Property lists */ @@ -46,11 +46,14 @@ /* Includes needed to set as default file driver */ #include "H5FDsec2.h" /* Posix unbuffered I/O file driver */ #include "H5FDstdio.h" /* Standard C buffered I/O */ + +/* Includes needed to set as default VOL driver */ +#include "H5VLnative.h" /* Native H5 VOL plugin */ + #ifdef H5_HAVE_WINDOWS #include "H5FDwindows.h" /* Windows buffered I/O */ #endif - /****************/ /* Local Macros */ /****************/ @@ -154,6 +157,14 @@ #define H5F_ACS_EFC_SIZE_DEF 0 #define H5F_ACS_EFC_SIZE_ENC H5P__encode_unsigned #define H5F_ACS_EFC_SIZE_DEC H5P__decode_unsigned + +/* Definition for VOL plugin */ +#define H5F_ACS_VOL_SIZE sizeof(void *) +#define H5F_ACS_VOL_DEF H5VL_NATIVE +/* Definition for vol info */ +#define H5F_ACS_VOL_INFO_SIZE sizeof(void*) +#define H5F_ACS_VOL_INFO_DEF NULL + /* Definition of pointer to initial file image info */ #define H5F_ACS_FILE_IMAGE_INFO_SIZE sizeof(H5FD_file_image_info_t) #define H5F_ACS_FILE_IMAGE_INFO_DEF H5FD_DEFAULT_FILE_IMAGE_INFO @@ -161,7 +172,6 @@ #define H5F_ACS_FILE_IMAGE_INFO_COPY H5P_file_image_info_copy #define H5F_ACS_FILE_IMAGE_INFO_CLOSE H5P_file_image_info_close - /******************/ /* Local Typedefs */ /******************/ @@ -264,6 +274,8 @@ static const H5FD_file_image_info_t H5F_def_file_image_info_g = H5F_ACS_FILE_IMA static herr_t H5P_facc_reg_prop(H5P_genclass_t *pclass) { + H5VL_class_t *vol_cls = H5F_ACS_VOL_DEF; /* Default VOL plugin */ + void *vol_info = H5F_ACS_VOL_INFO_DEF; /* Default VOL plugin information*/ const hid_t def_driver_id = H5F_ACS_FILE_DRV_ID_DEF; /* Default VFL driver ID (initialized from a variable) */ herr_t ret_value = SUCCEED; /* Return value */ @@ -390,6 +402,16 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass) NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the file VOL ID */ + if(H5P_register_real(pclass, H5F_ACS_VOL_NAME, H5F_ACS_VOL_SIZE, &vol_cls, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + /* Register the file VOL INFO */ + if(H5P_register_real(pclass, H5F_ACS_VOL_INFO_NAME, H5F_ACS_VOL_INFO_SIZE, &vol_info, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the initial file image info */ /* (Note: this property should not have an encode/decode callback -QAK) */ if(H5P_register_real(pclass, H5F_ACS_FILE_IMAGE_INFO_NAME, H5F_ACS_FILE_IMAGE_INFO_SIZE, &H5F_def_file_image_info_g, @@ -423,6 +445,7 @@ static herr_t H5P_facc_create(hid_t fapl_id, void UNUSED *copy_data) { hid_t driver_id; + H5VL_class_t *vol_cls; H5P_genplist_t *plist; /* Property list */ herr_t ret_value = SUCCEED; @@ -432,6 +455,21 @@ H5P_facc_create(hid_t fapl_id, void UNUSED *copy_data) if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + /* Retrieve VOL plugin property */ + if(H5P_get(plist, H5F_ACS_VOL_NAME, &vol_cls) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol plugin") + + if(NULL != vol_cls) { + void *vol_info; + + /* Retrieve VOL plugin info property */ + if(H5P_get(plist, H5F_ACS_VOL_INFO_NAME, &vol_info) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol info") + /* Set the vol for the property list */ + if(H5VL_fapl_open(plist, vol_cls, vol_info) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set vol") + } + /* Retrieve driver ID property */ if(H5P_get(plist, H5F_ACS_FILE_DRV_ID_NAME, &driver_id) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID") @@ -473,28 +511,44 @@ static herr_t H5P_facc_copy(hid_t dst_fapl_id, hid_t src_fapl_id, void UNUSED *copy_data) { hid_t driver_id; + H5VL_class_t *vol_cls; H5P_genplist_t *src_plist; /* Source property list */ + H5P_genplist_t *dst_plist; /* Destination property list */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT - /* Get driver ID from source property list */ + if(NULL == (src_plist = (H5P_genplist_t *)H5I_object(src_fapl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") + if(NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") + + /* get VOL plugin from source property list */ + if(H5P_get(src_plist, H5F_ACS_VOL_NAME, &vol_cls) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol ID") + if(NULL != vol_cls) { + void *vol_info; + + /* Retrieve VOL plugin property */ + if(H5P_get(dst_plist, H5F_ACS_VOL_INFO_NAME, &vol_info) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol info") + + /* Set the vp; for the destination property list */ + if(H5VL_fapl_open(dst_plist, vol_cls, vol_info) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set vol") + } /* end if */ + + /* Get driver ID from source property list */ if(H5P_get(src_plist, H5F_ACS_FILE_DRV_ID_NAME, &driver_id) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver ID") - if(driver_id > 0) { - H5P_genplist_t *dst_plist; /* Destination property list */ void *driver_info; /* Get driver info from source property list */ if(H5P_get(src_plist, H5F_ACS_FILE_DRV_INFO_NAME, &driver_info) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get driver info") - /* Set the driver for the destination property list */ - if(NULL == (dst_plist = (H5P_genplist_t *)H5I_object(dst_fapl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") if(H5FD_fapl_open(dst_plist, driver_id, driver_info) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set driver") } /* end if */ @@ -523,9 +577,10 @@ done: herr_t H5P_facc_close(hid_t fapl_id, void UNUSED *close_data) { - hid_t driver_id; + hid_t driver_id; + H5VL_class_t *vol_cls; H5P_genplist_t *plist; /* Property list */ - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(FAIL) @@ -533,6 +588,19 @@ H5P_facc_close(hid_t fapl_id, void UNUSED *close_data) if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + /* Get vol plugin */ + if(H5P_get(plist, H5F_ACS_VOL_NAME, &vol_cls) < 0) + HGOTO_DONE(FAIL) /* Can't return errors when library is shutting down */ + if(NULL != vol_cls) { + void *vol_info; + /* Retrieve VOL plugin info property */ + if(H5P_get(plist, H5F_ACS_VOL_INFO_NAME, &vol_info) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol info") + /* Close the driver for the property list */ + if(H5VL_fapl_close(vol_cls, vol_info) < 0) + HGOTO_DONE(FAIL) /* Can't return errors when library is shutting down */ + } /* end if */ + /* Get driver ID property */ if(H5P_get(plist, H5F_ACS_FILE_DRV_ID_NAME, &driver_id) < 0) HGOTO_DONE(FAIL) /* Can't return errors when library is shutting down */ @@ -1950,6 +2018,171 @@ done: /*------------------------------------------------------------------------- + * Function: H5P_set_vol + * + * Purpose: Set the vol plugin for a file access property list + * (PLIST_ID). The vol properties will + * be copied into the property list and the reference count on + * the vol will be incremented. + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5P_set_vol(H5P_genplist_t *plist, H5VL_class_t *vol_cls, const void *vol_info) +{ + H5VL_class_t *old_vol_cls; + void *old_vol_info; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + if(TRUE == H5P_isa_class(plist->plist_id, H5P_FILE_ACCESS)) { + /* Get the current vol information */ + if(H5P_get(plist, H5F_ACS_VOL_NAME, &old_vol_cls) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol class") + if(H5P_get(plist, H5F_ACS_VOL_INFO_NAME, &old_vol_info) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol info") + + /* Close the vol for the property list */ + if(H5VL_fapl_close(old_vol_cls, old_vol_info)<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't reset vol") + + /* Set the vol for the property list */ + if(H5VL_fapl_open(plist, vol_cls, vol_info)<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set vol") + } + else + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_set_vol() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_vol + * + * Purpose: Set the file vol plugin (VOL_ID) for a file access + * property list (PLIST_ID) + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_vol(hid_t plist_id, hid_t new_vol_id, const void *new_vol_info) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5VL_class_t *vol_cls; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "ii", plist_id, new_vol_id); + + /* Check arguments */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + if(NULL == (vol_cls = (H5VL_class_t *)H5I_object_verify(new_vol_id, H5I_VOL))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file vol ID") + + /* Set the vol */ + if(H5P_set_vol(plist, vol_cls, new_vol_info) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set vol") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_vol() */ + + +/*------------------------------------------------------------------------- + * Function: H5P_get_vol_info + * + * Purpose: Returns a pointer directly to the file vol-specific + * information of a file access property list. + * + * Return: Success: Ptr to *uncopied* vol specific data + * structure if any. + * + * Failure: NULL. Null is also returned if the vol has + * not registered any vol-specific properties + * although no error is pushed on the stack in + * this case. + * + * Programmer: Mohamad Chaarawi + * July, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5P_get_vol_info(H5P_genplist_t *plist) +{ + void *ret_value=NULL; + + FUNC_ENTER_NOAPI(NULL) + + /* Get the current vol info */ + if( TRUE == H5P_isa_class(plist->plist_id, H5P_FILE_ACCESS) ) { + if(H5P_get(plist, H5F_ACS_VOL_INFO_NAME, &ret_value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,NULL,"can't get vol info"); + } else { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list"); + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5P_get_vol_info() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_vol_info + * + * Purpose: Returns a pointer directly to the file vol-specific + * information of a file access property list. + * + * Return: Success: Ptr to *uncopied* vol specific data + * structure if any. + * + * Failure: NULL. Null is also returned if the vol has + * not registered any vol-specific properties + * although no error is pushed on the stack in + * this case. + * + * Programmer: Mohamad Chaarawi + * July 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5Pget_vol_info(hid_t plist_id) +{ + H5P_genplist_t *plist; /* Property list pointer */ + void *ret_value; /* Return value */ + + FUNC_ENTER_API(NULL) + + if(NULL == (plist = (H5P_genplist_t *)H5I_object_verify(plist_id, H5I_GENPROP_LST))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list") + + if(NULL == (ret_value = H5P_get_vol_info(plist))) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol info") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_vol_info() */ + + +/*------------------------------------------------------------------------- * Function: H5Pset_file_image * * Purpose: Sets the initial file image. Some file drivers can initialize @@ -2979,4 +3212,3 @@ H5P__facc_multi_type_dec(const void **_pp, void *_value) FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5P__facc_multi_type_dec() */ - diff --git a/src/H5Pgcpl.c b/src/H5Pgcpl.c index 0210700..1d7d184 100644 --- a/src/H5Pgcpl.c +++ b/src/H5Pgcpl.c @@ -123,6 +123,7 @@ static const H5O_linfo_t H5G_def_linfo_g = H5G_CRT_LINK_INFO_DEF; /* Defaul static herr_t H5P__gcrt_reg_prop(H5P_genclass_t *pclass) { + hid_t lcpl_id = H5P_LINK_CREATE_DEFAULT; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -139,6 +140,11 @@ H5P__gcrt_reg_prop(H5P_genclass_t *pclass) NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the lcpl ID property */ + if(H5P_register_real(pclass, H5VL_GRP_LCPL_ID, sizeof(hid_t), &lcpl_id, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P__gcrt_reg_prop() */ diff --git a/src/H5Pint.c b/src/H5Pint.c index 88c3247..52db9d5 100644 --- a/src/H5Pint.c +++ b/src/H5Pint.c @@ -271,7 +271,8 @@ static const H5I_class_t H5I_GENPROPCLS_CLS[1] = {{ 0, /* Class flags */ 64, /* Minimum hash size for class */ 0, /* # of reserved IDs for class */ - (H5I_free_t)H5P_close_class /* Callback routine for closing objects of this class */ + (H5I_free_t)H5P_close_class,/* Callback routine for closing objects of this class */ + NULL /* Callback routine for closing auxilary objects of this class */ }}; /* Generic Property List ID class */ @@ -280,7 +281,8 @@ static const H5I_class_t H5I_GENPROPLST_CLS[1] = {{ 0, /* Class flags */ 128, /* Minimum hash size for class */ 0, /* # of reserved IDs for class */ - (H5I_free_t)H5P_close /* Callback routine for closing objects of this class */ + (H5I_free_t)H5P_close, /* Callback routine for closing objects of this class */ + NULL /* Callback routine for closing auxilary objects of this class */ }}; @@ -407,6 +409,7 @@ H5P_init_interface(void) */ if(H5I_register_type(H5I_GENPROPCLS_CLS) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group") + if(H5I_register_type(H5I_GENPROPLST_CLS) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize ID group") diff --git a/src/H5Plcpl.c b/src/H5Plcpl.c index d81d55c..a16a005 100644 --- a/src/H5Plcpl.c +++ b/src/H5Plcpl.c @@ -51,6 +51,31 @@ #define H5L_CRT_INTERMEDIATE_GROUP_ENC H5P__encode_unsigned #define H5L_CRT_INTERMEDIATE_GROUP_DEC H5P__decode_unsigned +/* ======== VOL specific properties ========= */ +/* Definitions for target object ID */ +#define H5L_CRT_TARGET_SIZE sizeof(void *) +#define H5L_CRT_TARGET_DEF NULL + +/* Definitions for Location params */ +#define H5L_CRT_LOCATION_SIZE sizeof(H5VL_loc_params_t) +#define H5L_CRT_LOCATION_DEF {H5I_BADID, H5VL_OBJECT_BY_SELF} + +/* Definitions for target object NAME */ +#define H5L_CRT_TARGET_NAME_SIZE sizeof(char *) +#define H5L_CRT_TARGET_NAME_DEF NULL + +/* Definitions for link type */ +#define H5L_CRT_LINK_TYPE_SIZE sizeof(link_type) +#define H5L_CRT_LINK_TYPE_DEF H5L_TYPE_ERROR + +/* Definitions for UDATA */ +#define H5L_CRT_UDATA_SIZE sizeof(void *) +#define H5L_CRT_UDATA_DEF NULL + +/* Definitions for UDATA_SIZE */ +#define H5L_CRT_UDATA_SIZE_SIZE sizeof(size_t) +#define H5L_CRT_UDATA_SIZE_DEF 0 + /******************/ /* Local Typedefs */ /******************/ @@ -118,6 +143,12 @@ static const unsigned H5L_def_intmd_group_g = H5L_CRT_INTERMEDIATE_GROUP_DEF; herr_t H5P_lcrt_reg_prop(H5P_genclass_t *pclass) { + void* target = H5L_CRT_TARGET_DEF; + H5VL_loc_params_t loc_params = H5L_CRT_LOCATION_DEF; + char *target_name = H5L_CRT_TARGET_NAME_DEF; + H5L_type_t link_type = H5L_CRT_LINK_TYPE_DEF; + void *udata = H5L_CRT_UDATA_DEF; + size_t udata_size = H5L_CRT_UDATA_SIZE_DEF; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -128,6 +159,30 @@ H5P_lcrt_reg_prop(H5P_genclass_t *pclass) NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + if(H5P_register_real(pclass, H5VL_LINK_TARGET, H5L_CRT_TARGET_SIZE, &target, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + if(H5P_register_real(pclass, H5VL_LINK_TARGET_LOC_PARAMS, H5L_CRT_LOCATION_SIZE, &loc_params, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + if(H5P_register_real(pclass, H5VL_LINK_TARGET_NAME, H5L_CRT_TARGET_NAME_SIZE, &target_name, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + if(H5P_register_real(pclass, H5VL_LINK_TYPE, H5L_CRT_LINK_TYPE_SIZE, &link_type, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + if(H5P_register_real(pclass, H5VL_LINK_UDATA, H5L_CRT_UDATA_SIZE, &udata, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + + if(H5P_register_real(pclass, H5VL_LINK_UDATA_SIZE, H5L_CRT_UDATA_SIZE_SIZE, &udata_size, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P_lcrt_reg_prop() */ diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 6560064..3835a16 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -22,6 +22,8 @@ /* Include package's public header */ #include "H5Ppublic.h" +#include "H5VLpublic.h" + /* Private headers needed by this file */ #include "H5private.h" /* Generic Functions */ #include "H5Oprivate.h" /* Object headers */ @@ -96,6 +98,8 @@ H5_DLL hid_t H5P_get_driver(H5P_genplist_t *plist); H5_DLL void * H5P_get_driver_info(H5P_genplist_t *plist); H5_DLL herr_t H5P_set_driver(H5P_genplist_t *plist, hid_t new_driver_id, const void *new_driver_info); +H5_DLL herr_t H5P_set_vol(H5P_genplist_t *plist, H5VL_class_t *vol_cls, const void *vol_info); +H5_DLL void * H5P_get_vol_info(H5P_genplist_t *plist); H5_DLL herr_t H5P_set_vlen_mem_manager(H5P_genplist_t *plist, H5MM_allocate_t alloc_func, void *alloc_info, H5MM_free_t free_func, void *free_info); diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 6b17e0b..882b195 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -307,6 +307,14 @@ H5_DLL herr_t H5Pset_driver(hid_t plist_id, hid_t driver_id, const void *driver_info); H5_DLL hid_t H5Pget_driver(hid_t plist_id); H5_DLL void *H5Pget_driver_info(hid_t plist_id); +H5_DLL herr_t H5Pset_vol(hid_t plist_id, hid_t new_vol_id, const void *new_vol_info); +H5_DLL void *H5Pget_vol_info(hid_t plist_id); + +/* +H5_DLL herr_t H5Pset_vol(hid_t plist_id, hid_t vol_id, const void *vol_info); +H5_DLL hid_t H5Pget_vol(hid_t plist_id); +H5_DLL void *H5Pget_vol_info(hid_t plist_id); +*/ H5_DLL herr_t H5Pset_family_offset(hid_t fapl_id, hsize_t offset); H5_DLL herr_t H5Pget_family_offset(hid_t fapl_id, hsize_t *offset); H5_DLL herr_t H5Pset_multi_type(hid_t fapl_id, H5FD_mem_t type); @@ -36,6 +36,7 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Rpkg.h" /* References */ #include "H5Sprivate.h" /* Dataspaces */ +#include "H5VLprivate.h" /* VOL plugins */ /****************/ @@ -52,12 +53,6 @@ /* Local Prototypes */ /********************/ -static herr_t H5R_create(void *ref, H5G_loc_t *loc, const char *name, - H5R_type_t ref_type, H5S_t *space, hid_t dxpl_id); -static H5S_t * H5R_get_region(H5F_t *file, hid_t dxpl_id, const void *_ref); -static ssize_t H5R_get_name(H5F_t *file, hid_t lapl_id, hid_t dxpl_id, hid_t id, - H5R_type_t ref_type, const void *_ref, char *name, size_t size); - /*********************/ /* Package Variables */ @@ -79,7 +74,8 @@ static const H5I_class_t H5I_REFERENCE_CLS[1] = {{ 0, /* Class flags */ 64, /* Minimum hash size for class */ 0, /* # of reserved IDs for class */ - NULL /* Callback routine for closing objects of this class */ + NULL, /* Callback routine for closing objects of this class */ + NULL /* Callback routine for closing auxilary objects of this class */ }}; @@ -203,7 +199,7 @@ H5R_term_interface(void) EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static herr_t +herr_t H5R_create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space, hid_t dxpl_id) { H5G_loc_t obj_loc; /* Group hier. location of object */ @@ -347,8 +343,9 @@ done: herr_t H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id) { - H5G_loc_t loc; /* File location */ - H5S_t *space = NULL; /* Pointer to dataspace containing region */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) @@ -357,8 +354,6 @@ H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t /* Check args */ if(ref == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") - 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 given") if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) @@ -367,12 +362,21 @@ H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "reference type not supported") if(space_id == (-1) && ref_type == H5R_DATASET_REGION) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "reference region dataspace id must be valid") - if(space_id != (-1) && (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - /* Create reference */ - if((ret_value = H5R_create(ref, &loc, name, ref_type, space, H5AC_dxpl_id)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to create reference") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* create the ref through the VOL */ + if(ret_value = H5VL_object_misc(obj, loc_params, vol_plugin, H5VL_REF_CREATE, H5_REQUEST_NULL, + ref, name, ref_type, space_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "modifying object link count failed") done: FUNC_LEAVE_API(ret_value) @@ -566,29 +570,44 @@ done: hid_t H5Rdereference2(hid_t obj_id, hid_t oapl_id, H5R_type_t ref_type, const void *_ref) { - H5G_loc_t loc; /* Group location */ - H5F_t *file = NULL; /* File object */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5I_type_t opened_type; + void *opened_obj = NULL; + H5VL_loc_params_t loc_params; hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE4("i", "iiRt*x", obj_id, oapl_id, ref_type, _ref); /* Check args */ - if(H5G_loc(obj_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(oapl_id < 0) + if(oapl_id < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") if(_ref == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") - /* Get the file pointer from the entry */ - file = loc.oloc->file; + /* get the vol object */ + if(NULL == (obj = (void *)H5VL_get_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + loc_params.type = H5VL_OBJECT_BY_REF; + loc_params.loc_data.loc_by_ref.ref_type = ref_type; + loc_params.loc_data.loc_by_ref._ref = _ref; + loc_params.loc_data.loc_by_ref.plist_id = oapl_id; + loc_params.obj_type = H5I_get_type(obj_id); - /* Create reference */ - if((ret_value = H5R_dereference(file, oapl_id, H5AC_dxpl_id, ref_type, _ref, TRUE)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to dereference object") + /* Open the object through the VOL */ + if(NULL == (opened_obj = H5VL_object_open(obj, loc_params, vol_plugin, &opened_type, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") + + /* Get an atom for the object */ + if ((ret_value = H5VL_object_register(opened_obj, opened_type, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: FUNC_LEAVE_API(ret_value) @@ -616,7 +635,7 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static H5S_t * +H5S_t * H5R_get_region(H5F_t *file, hid_t dxpl_id, const void *_ref) { H5O_loc_t oloc; /* Object location */ @@ -690,28 +709,34 @@ done: hid_t H5Rget_region(hid_t id, H5R_type_t ref_type, const void *ref) { - H5G_loc_t loc; /* Object's group location */ - H5S_t *space = NULL; /* Dataspace object */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE3("i", "iRt*x", id, ref_type, ref); /* Check args */ - if(H5G_loc(id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(ref_type != H5R_DATASET_REGION) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") if(ref == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") - /* Get the dataspace with the correct region selected */ - if((space = H5R_get_region(loc.oloc->file, H5AC_ind_dxpl_id, ref)) == NULL) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create dataspace") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Atomize */ - if((ret_value = H5I_register (H5I_DATASPACE, space, TRUE)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") + /* Get the space id through the VOL */ + if(H5VL_object_get(obj, loc_params, vol_plugin, H5VL_REF_GET_REGION, H5_REQUEST_NULL, + &ret_value, ref_type, ref) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: FUNC_LEAVE_API(ret_value) @@ -831,23 +856,34 @@ herr_t H5Rget_obj_type2(hid_t id, H5R_type_t ref_type, const void *ref, H5O_type_t *obj_type) { - H5G_loc_t loc; /* Object location */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "iRt*x*Ot", id, ref_type, ref, obj_type); /* Check args */ - if(H5G_loc(id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") if(ref == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") - /* Get the object information */ - if(H5R_get_obj_type(loc.oloc->file, H5AC_ind_dxpl_id, ref_type, ref, obj_type) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to determine object type") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(id); + + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the object type through the VOL */ + if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, H5VL_REF_GET_TYPE, + H5_REQUEST_NULL, obj_type, ref_type, ref)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: FUNC_LEAVE_API(ret_value) @@ -882,10 +918,11 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -static ssize_t -H5R_get_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t id, H5R_type_t ref_type, +ssize_t +H5R_get_name(H5G_loc_t *loc, hid_t lapl_id, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref, char *name, size_t size) { + H5F_t *f; hid_t file_id = (-1); /* ID for file that the reference is in */ H5O_loc_t oloc; /* Object location describing object for reference */ ssize_t ret_value; /* Return value */ @@ -893,10 +930,13 @@ H5R_get_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t id, H5R_type_t ref_ty FUNC_ENTER_NOAPI_NOINIT /* Check args */ - HDassert(f); HDassert(_ref); HDassert(name); + /* Get the file pointer from the entry */ + f = loc->oloc->file; + HDassert(f); + /* Initialize the object location */ H5O_loc_reset(&oloc); oloc.file = f; @@ -939,8 +979,8 @@ H5R_get_name(H5F_t *f, hid_t lapl_id, hid_t dxpl_id, hid_t id, H5R_type_t ref_ty } /* end switch */ /* Retrieve file ID for name search */ - if((file_id = H5I_get_file_id(id, FALSE)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTGET, FAIL, "can't retrieve file ID") + if((file_id = H5F_get_id(f, FALSE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get file ID") /* Get name, length, etc. */ if((ret_value = H5G_get_name_by_addr(file_id, lapl_id, dxpl_id, &oloc, name, size)) < 0) @@ -984,28 +1024,34 @@ ssize_t H5Rget_name(hid_t id, H5R_type_t ref_type, const void *_ref, char *name, size_t size) { - H5G_loc_t loc; /* Group location */ - H5F_t *file; /* File object */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; ssize_t ret_value; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE5("Zs", "iRt*x*sz", id, ref_type, _ref, name, size); /* Check args */ - if(H5G_loc(id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") if(_ref == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") - /* Get the file pointer from the entry */ - file = loc.oloc->file; + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(id); - /* Get name */ - if((ret_value = H5R_get_name(file, H5P_DEFAULT, H5AC_dxpl_id, id, ref_type, _ref, name, size)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to determine object path") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + /* get the object type through the VOL */ + if(H5VL_object_get(obj, loc_params, vol_plugin, H5VL_REF_GET_NAME, H5_REQUEST_NULL, + &ret_value, name, size, ref_type, _ref) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") done: FUNC_LEAVE_API(ret_value) } /* end H5Rget_name() */ diff --git a/src/H5Rdeprec.c b/src/H5Rdeprec.c index d0c79a8..8933ed5 100644 --- a/src/H5Rdeprec.c +++ b/src/H5Rdeprec.c @@ -44,9 +44,11 @@ #include "H5ACprivate.h" /* Metadata cache */ #include "H5Eprivate.h" /* Error handling */ #include "H5Gprivate.h" /* Groups */ +#include "H5Iprivate.h" /* IDs */ #include "H5Oprivate.h" /* Object headers */ #include "H5Rpkg.h" /* References */ #include "H5Ppublic.h" /* for using H5P_DATASET_ACCESS_DEFAULT */ +#include "H5VLprivate.h" /* VOL plugins */ #ifndef H5_NO_DEPRECATED_SYMBOLS /****************/ @@ -132,7 +134,9 @@ H5R_init_deprec_interface(void) H5G_obj_t H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref) { - H5G_loc_t loc; /* Object location */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; H5O_type_t obj_type; /* Object type */ H5G_obj_t ret_value; /* Return value */ @@ -140,16 +144,25 @@ H5Rget_obj_type1(hid_t id, H5R_type_t ref_type, const void *ref) H5TRACE3("Go", "iRt*x", id, ref_type, ref); /* Check args */ - if(H5G_loc(id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a location") if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference type") if(ref == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference pointer") - /* Get the object information */ - if(H5R_get_obj_type(loc.oloc->file, H5AC_ind_dxpl_id, ref_type, ref, &obj_type) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(id); + + /* get the vol object */ + if(NULL == (obj = (void *)H5VL_get_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* get the object type through the VOL */ + if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, H5VL_REF_GET_TYPE, + H5_REQUEST_NULL, &obj_type, ref_type, ref)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTGET, FAIL, "unable to get group info") /* Set return value */ ret_value = H5G_map_obj_type(obj_type); @@ -184,27 +197,42 @@ done: hid_t H5Rdereference1(hid_t obj_id, H5R_type_t ref_type, const void *_ref) { - H5G_loc_t loc; /* Group location */ - H5F_t *file = NULL; /* File object */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5I_type_t opened_type; + void *opened_obj = NULL; + H5VL_loc_params_t loc_params; hid_t ret_value; FUNC_ENTER_API(FAIL) H5TRACE3("i", "iRt*x", obj_id, ref_type, _ref); /* Check args */ - if(H5G_loc(obj_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") if(_ref == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer") - /* Get the file pointer from the entry */ - file = loc.oloc->file; - - /* Create reference */ - if((ret_value = H5R_dereference(file, H5P_DATASET_ACCESS_DEFAULT, H5AC_dxpl_id, ref_type, _ref, TRUE)) < 0) - HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable dereference object") + /* get the vol object */ + if(NULL == (obj = (void *)H5VL_get_object(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(obj_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + loc_params.type = H5VL_OBJECT_BY_REF; + loc_params.loc_data.loc_by_ref.ref_type = ref_type; + loc_params.loc_data.loc_by_ref._ref = _ref; + loc_params.loc_data.loc_by_ref.plist_id = H5P_DATASET_ACCESS_DEFAULT; + loc_params.obj_type = H5I_get_type(obj_id); + + /* Open the object through the VOL */ + if(NULL == (opened_obj = H5VL_object_open(obj, loc_params, vol_plugin, &opened_type, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open object") + + /* Get an atom for the object */ + if ((ret_value = H5VL_object_register(opened_obj, opened_type, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Rpkg.h b/src/H5Rpkg.h index 8c66a90..26a2d02 100644 --- a/src/H5Rpkg.h +++ b/src/H5Rpkg.h @@ -33,6 +33,7 @@ /* Other private headers needed by this file */ #include "H5Fprivate.h" /* File access */ +#include "H5Sprivate.h" /* Dataspaces */ /**************************/ /* Package Private Macros */ @@ -59,7 +60,13 @@ H5_DLL herr_t H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref, H5O_type_t *obj_type); H5_DLL hid_t H5R_dereference(H5F_t *file, hid_t dapl_id, hid_t dxpl_id, H5R_type_t ref_type, const void *_ref, hbool_t app_ref); - +H5_DLL herr_t H5R_create(void *ref, H5G_loc_t *loc, const char *name, + H5R_type_t ref_type, H5S_t *space, hid_t dxpl_id); +H5_DLL H5S_t * H5R_get_region(H5F_t *file, hid_t dxpl_id, const void *_ref); +H5_DLL ssize_t H5R_get_name(H5G_loc_t *loc, hid_t lapl_id, hid_t dxpl_id, H5R_type_t ref_type, + const void *_ref, char *name, size_t size); +//H5_DLL ssize_t H5R_get_name(H5F_t *file, hid_t lapl_id, hid_t dxpl_id, hid_t id, +// H5R_type_t ref_type, const void *_ref, char *name, size_t size); #endif /* _H5Rpkg_H */ @@ -92,7 +92,8 @@ static const H5I_class_t H5I_DATASPACE_CLS[1] = {{ 0, /* Class flags */ 64, /* Minimum hash size for class */ 2, /* # of reserved IDs for class */ - (H5I_free_t)H5S_close /* Callback routine for closing objects of this class */ + (H5I_free_t)H5S_close, /* Callback routine for closing objects of this class */ + NULL /* Callback routine for closing auxilary objects of this class */ }}; @@ -45,6 +45,7 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ #include "H5Tpkg.h" /* Datatypes */ +#include "H5VLprivate.h" /* Virtual Object Layer */ /* Check for header needed for SGI floating-point code */ #ifdef H5_HAVE_SYS_FPU_H @@ -530,7 +531,8 @@ static const H5I_class_t H5I_DATATYPE_CLS[1] = {{ 0, /* Class flags */ 64, /* Minimum hash size for class */ 8, /* # of reserved IDs for class */ - (H5I_free_t)H5T_close /* Callback routine for closing objects of this class */ + (H5I_free_t)H5T_close, /* Callback routine for closing objects of this class */ + (H5I_free2_t)H5T_close_datatype /* Callback routine for closing auxilary objects of this class */ }}; @@ -1756,13 +1758,13 @@ H5Tclose(hid_t type_id) /* Check args */ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(H5T_STATE_IMMUTABLE == dt->shared->state) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "immutable datatype") + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "immutable datatype") /* When the reference count reaches zero the resources are freed */ if(H5I_dec_app_ref(type_id) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id") + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "problem freeing id") done: FUNC_LEAVE_API(ret_value) @@ -2982,6 +2984,7 @@ H5T_decode(const unsigned char *buf) if(H5T_set_loc(ret_value, NULL, H5T_LOC_MEMORY) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location") + ret_value->vol_obj = NULL; done: /* Release fake file structure */ if(f && H5F_fake_free(f) < 0) @@ -3103,6 +3106,7 @@ H5T__create(H5T_class_t type, size_t size) if(H5T_STRING != type || H5T_VARIABLE != size) dt->shared->size = size; + dt->vol_obj = NULL; /* Set return value */ ret_value = dt; @@ -3176,7 +3180,7 @@ H5T_copy(H5T_t *old_dt, H5T_copy_t method) /* Copy shared information (entry information is copied last) */ *(new_dt->shared) = *(old_dt->shared); - + new_dt->vol_obj = NULL; /* Check what sort of copy we are making */ switch (method) { case H5T_COPY_TRANSIENT: @@ -3487,6 +3491,7 @@ H5T__alloc(void) if(NULL == (dt->shared = H5FL_CALLOC(H5T_shared_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") dt->shared->version = H5O_DTYPE_VERSION_1; + dt->vol_obj = NULL; /* Assign return value */ ret_value = dt; diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index bfae624..9d02c72 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -37,9 +37,10 @@ #include "H5FOprivate.h" /* File objects */ #include "H5Iprivate.h" /* IDs */ #include "H5Lprivate.h" /* Links */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ #include "H5Tpkg.h" /* Datatypes */ - +#include "H5VLprivate.h" /* VOL plugins */ /****************/ /* Local Macros */ @@ -120,22 +121,23 @@ H5T_init_commit_interface(void) */ herr_t H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, - hid_t tcpl_id, hid_t tapl_id) + hid_t tcpl_id, hid_t tapl_id) { - H5G_loc_t loc; /* Location to create datatype */ - H5T_t *type; /* Datatype for ID */ + void *dt = NULL; + H5T_t *type = NULL; + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE6("e", "i*siiii", loc_id, name, type_id, lcpl_id, tcpl_id, tapl_id); /* Check arguments */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if (H5Tcommitted(type_id)) + HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is already committed") if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") - if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* Get correct property list */ if(H5P_DEFAULT == lcpl_id) @@ -158,9 +160,32 @@ H5Tcommit2(hid_t loc_id, const char *name, hid_t type_id, hid_t lcpl_id, if(TRUE != H5P_isa_class(tapl_id, H5P_DATATYPE_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype access property list") - /* Commit the type */ - if(H5T__commit_named(&loc, name, type, lcpl_id, tcpl_id, tapl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype") + if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the object from the loc_id */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* commit the datatype through the VOL */ + if (NULL == (dt = H5VL_datatype_commit(obj, loc_params, vol_plugin, name, type_id, lcpl_id, + tcpl_id, tapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to commit datatype") + + /* attach the vol object created using the commit call to the + library datatype structure */ + /* set the committed type object to the VOL pluging pointer in the H5T_t struct */ + type->vol_obj = dt; + + /* attach VOL information to the ID */ + if (H5I_register_aux(type_id, vol_plugin) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't attach vol info to ID") done: FUNC_LEAVE_API(ret_value) @@ -271,18 +296,19 @@ done: herr_t H5Tcommit_anon(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id) { - H5G_loc_t loc; /* Group location for location */ - H5T_t *type = NULL; /* Datatype created */ + void *dt = NULL; + H5T_t *type = NULL; + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE4("e", "iiii", loc_id, type_id, tcpl_id, tapl_id); - /* Check arguments */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + /* check args */ + if (H5Tcommitted(type_id)) + HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is already committed") /* Get correct property list */ if(H5P_DEFAULT == tcpl_id) @@ -298,22 +324,32 @@ H5Tcommit_anon(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id) if(TRUE != H5P_isa_class(tapl_id, H5P_DATATYPE_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype access property list") - /* Commit the type */ - if(H5T__commit(loc.oloc->file, type, tcpl_id, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); - /* Release the datatype's object header */ - { - H5O_loc_t *oloc; /* Object location for datatype */ + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Get the new committed datatype's object location */ - if(NULL == (oloc = H5T_oloc(type))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to get object location of committed datatype") + /* commite the datatype through the VOL */ + if (NULL == (dt = H5VL_datatype_commit(obj, loc_params, vol_plugin, NULL, type_id, H5P_DEFAULT, + tcpl_id, tapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to commit datatype") - /* Decrement refcount on committed datatype's object header in memory */ - if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object") - } /* end if */ + /* attach the vol object created using the commit call to the + library datatype structure */ + if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + + /* set the committed type object to the VOL pluging pointer in the H5T_t struct */ + type->vol_obj = dt; + + /* attach VOL information to the ID */ + if (H5I_register_aux(type_id, vol_plugin) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't attach vol info to ID") done: FUNC_LEAVE_API(ret_value) @@ -492,12 +528,18 @@ done: htri_t H5T_committed(const H5T_t *type) { - /* Use no-init for efficiency */ + const H5T_t *dt; + FUNC_ENTER_NOAPI_NOINIT_NOERR HDassert(type); - FUNC_LEAVE_NOAPI(H5T_STATE_OPEN == type->shared->state || H5T_STATE_NAMED == type->shared->state) + if (NULL == type->vol_obj) + dt = type; + else + dt = (const H5T_t *)type->vol_obj; + + FUNC_LEAVE_NOAPI(H5T_STATE_OPEN == dt->shared->state || H5T_STATE_NAMED == dt->shared->state) } /* end H5T_committed() */ @@ -551,23 +593,17 @@ done: hid_t H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id) { - H5T_t *type = NULL; /* Datatype opened in file */ - H5G_loc_t loc; /* Group location of object to open */ - H5G_name_t path; /* Datatype group hier. path */ - H5O_loc_t oloc; /* Datatype object location */ - H5O_type_t obj_type; /* Type of object at location */ - H5G_loc_t type_loc; /* Group object for datatype */ - hbool_t obj_found = FALSE; /* Object at 'name' found */ - hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datatype */ - hid_t ret_value = FAIL; /* Return value */ + void *dt = NULL; /* datatype token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; + hid_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("i", "i*si", loc_id, name, tapl_id); /* Check args */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(!name || !*name) + if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") /* Get correct property list */ @@ -577,43 +613,28 @@ H5Topen2(hid_t loc_id, const char *name, hid_t tapl_id) if(TRUE != H5P_isa_class(tapl_id, H5P_DATATYPE_ACCESS)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not datatype access property list") - /* Set up datatype location to fill in */ - type_loc.oloc = &oloc; - type_loc.path = &path; - H5G_loc_reset(&type_loc); - - /* - * Find the named datatype object header and read the datatype message - * from it. - */ - if(H5G_loc_find(&loc, name, &type_loc/*out*/, tapl_id, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found") - obj_found = TRUE; + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); - /* Check that the object found is the correct type */ - if(H5O_obj_type(&oloc, &obj_type, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get object type") - if(obj_type != H5O_TYPE_NAMED_DATATYPE) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a named datatype") + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") - /* Open it */ - if(NULL == (type = H5T_open(&type_loc, dxpl_id))) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open named datatype") + /* Create the datatype through the VOL */ + if(NULL == (dt = H5VL_datatype_open(obj, loc_params, vol_plugin, name, tapl_id, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open datatype") - /* Register the type and return the ID */ - if((ret_value = H5I_register(H5I_DATATYPE, type, TRUE)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register named datatype") + /* Get an atom for the datatype */ + if ((ret_value = H5VL_create_datatype(dt, vol_plugin, TRUE, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize datatype handle") done: - if(ret_value < 0) { - if(type != NULL) - H5T_close(type); - else { - if(obj_found && H5F_addr_defined(type_loc.oloc->addr)) - H5G_loc_free(&type_loc); - } /* end else */ - } /* end if */ - + if (ret_value < 0 && dt) + if(H5VL_datatype_close (dt, vol_plugin, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* end H5Topen2() */ @@ -657,13 +678,17 @@ H5Tget_create_plist(hid_t dtype_id) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to copy the creation property list") /* Check if the datatype is committed */ - if((status = H5T_committed(type)) < 0) + if((status = H5Tcommitted(dtype_id)) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't check whether datatype is committed") /* Retrieve further information, if the datatype is committed */ if(status > 0) { H5P_genplist_t *new_plist; /* New datatype creation property list */ + /* get the named datatype object */ + if(NULL == (type = (H5T_t *)H5VL_get_object(dtype_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* Get property list object for new TCPL */ if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_tcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") @@ -886,3 +911,138 @@ H5T_update_shared(H5T_t *dt) FUNC_LEAVE_NOAPI(SUCCEED) } /* H5T_update_shared() */ + +/*------------------------------------------------------------------------- + * Function: H5T_get_named_type + * + * Purpose: returns the VOL object or the named datatype structure + * if it exists + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * June 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5T_get_named_type(const H5T_t *dt) +{ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + if(NULL != dt->vol_obj) + ret_value = dt->vol_obj; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_get_named_type() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_create_datatype + * + * Purpose: Create a Library datatype with a plugin specific datatype object + * + * Return: Success: A datatype identifier + * + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * June, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_create_datatype(void *dt_obj, H5VL_t *vol_plugin, hbool_t app_ref, hid_t req) +{ + ssize_t nalloc; + unsigned char *buf = NULL; + H5T_t *dt = NULL; /* datatype token from VOL plugin */ + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI(FAIL) + + /* get required buf size for encoding the datatype */ + if((nalloc = H5VL_datatype_get_binary(dt_obj, vol_plugin, NULL, 0, req)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to get datatype size") + + /* allocate buffer to store binary description of the datatype */ + if (NULL == (buf = (unsigned char *) H5MM_malloc ((size_t)nalloc))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate space for datatype") + + /* get binary description of the datatype */ + if((nalloc = H5VL_datatype_get_binary(dt_obj, vol_plugin, buf, (size_t) nalloc, req)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to get datatype size") + + if(NULL == (dt = H5T_decode(buf))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't decode datatype") + dt->vol_obj = dt_obj; + + H5MM_free(buf); + + /* Get an atom for the datatype with the VOL information as the auxilary struct*/ + if((ret_value = H5I_register2(H5I_DATATYPE, dt, vol_plugin, app_ref)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_create_datatype() */ + + +/*------------------------------------------------------------------------- + * Function: H5T_close_datatype + * + * Purpose: Called when the ref count reaches zero on the datatype_id + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * June 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_close_datatype(void *type, H5VL_t *vol_plugin) +{ + H5T_t *dt = (H5T_t *)type; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Close the datatype through the VOL*/ + if (NULL != dt->vol_obj) + if((ret_value = H5VL_datatype_close(dt->vol_obj, vol_plugin, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to close datatype") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5T_close_datatype() */ + + +/*------------------------------------------------------------------------- + * Function: H5T_set_vol_object + * + * Purpose: Set the vol_object in the H5T_t struct. + * Called from outside the H5T package + * + * Return: Succeed + * + * Programmer: Mohamad Chaarawi + * June 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_set_vol_object(H5T_t *type, void *vol_obj) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + type->vol_obj = vol_obj; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5T_set_vol_object() */ diff --git a/src/H5Tconv.c b/src/H5Tconv.c index b732817..4e5d1f0 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -629,7 +629,7 @@ case H5T_CONV_INIT: \ /* Sanity check and initialize statistics */ \ cdata->need_bkg = H5T_BKG_NO; \ - if (NULL==(st=(H5T_t*)H5I_object(src_id)) || NULL==(dt=(H5T_t*)H5I_object(dst_id))) \ + if (NULL==(st=(H5T_t*)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL==(dt=(H5T_t*)H5I_object_verify(dst_id, H5I_DATATYPE))) \ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \ "unable to dereference datatype object ID") \ if (st->shared->size!=sizeof(ST) || dt->shared->size!=sizeof(DT)) \ @@ -676,7 +676,7 @@ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") \ \ /* Get source and destination datatypes */ \ - if(NULL == (st = (H5T_t *)H5I_object(src_id)) || NULL == (dt = (H5T_t *)H5I_object(dst_id))) \ + if (NULL==(st=(H5T_t*)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL==(dt=(H5T_t*)H5I_object_verify(dst_id, H5I_DATATYPE))) \ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to dereference datatype object ID") \ \ /* Get source & destination precisions into a variable */ \ @@ -1050,7 +1050,7 @@ H5T__conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, switch(cdata->command) { case H5T_CONV_INIT: /* Capability query */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset || @@ -1093,7 +1093,7 @@ H5T__conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, case H5T_CONV_CONV: /* The conversion */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* Check for "no op" reference conversion */ @@ -1458,8 +1458,8 @@ H5T__conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, switch(cdata->command) { case H5T_CONV_INIT: /* Capability query */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || + NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset || @@ -1495,7 +1495,7 @@ H5T__conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* The conversion */ - if(NULL == (src = (H5T_t *)H5I_object(src_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") buf_stride = buf_stride ? buf_stride : src->shared->size; @@ -1563,8 +1563,8 @@ H5T__conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, switch(cdata->command) { case H5T_CONV_INIT: /* Capability query */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || + NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(H5T_ORDER_LE != src->shared->u.atomic.order && H5T_ORDER_BE != src->shared->u.atomic.order) @@ -1580,7 +1580,7 @@ H5T__conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* @@ -2108,7 +2108,7 @@ H5T__conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * otherwise initialize the `priv' field of `cdata' with information * that remains (almost) constant for this conversion path. */ - if (NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if (NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") if(H5T_COMPOUND != src->shared->type) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype") @@ -2130,7 +2130,7 @@ H5T__conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* * Conversion. */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") HDassert(priv); HDassert(bkg && cdata->need_bkg); @@ -2358,7 +2358,7 @@ H5T__conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, * otherwise initialize the `priv' field of `cdata' with information * that remains (almost) constant for this conversion path. */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(H5T_COMPOUND != src->shared->type) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype") @@ -2417,7 +2417,7 @@ H5T__conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, /* * Conversion. */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* Update cached data if necessary */ @@ -2739,7 +2739,7 @@ H5T__conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * the `priv' field of `cdata' with information about the underlying * integer conversion. */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") if(H5T_ENUM != src->shared->type) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype") @@ -2766,7 +2766,7 @@ H5T__conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; case H5T_CONV_CONV: - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(H5T_ENUM != src->shared->type) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype") @@ -3050,7 +3050,7 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * information that remains (almost) constant for this * conversion path. */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") if(H5T_VLEN != src->shared->type) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype") @@ -3075,7 +3075,7 @@ H5T__conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* * Conversion. */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* Initialize source & destination strides */ @@ -3361,7 +3361,7 @@ H5T__conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * information that remains (almost) constant for this * conversion path. */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") HDassert(H5T_ARRAY==src->shared->type); HDassert(H5T_ARRAY==dst->shared->type); @@ -3386,7 +3386,7 @@ H5T__conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* * Conversion. */ - if (NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if (NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* @@ -3519,7 +3519,8 @@ H5T__conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, switch(cdata->command) { case H5T_CONV_INIT: - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || + NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(H5T_ORDER_LE != src->shared->u.atomic.order && H5T_ORDER_BE != src->shared->u.atomic.order) HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") @@ -3535,7 +3536,8 @@ H5T__conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || + NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* @@ -3941,7 +3943,8 @@ H5T__conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, switch(cdata->command) { case H5T_CONV_INIT: - if(NULL == (src_p = (H5T_t *)H5I_object(src_id)) || NULL == (dst_p = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src_p = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || + NULL == (dst_p = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; @@ -3961,7 +3964,8 @@ H5T__conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if(NULL == (src_p = (H5T_t *)H5I_object(src_id)) || NULL == (dst_p = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src_p = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || + NULL == (dst_p = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; @@ -4486,7 +4490,7 @@ H5T__conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, switch(cdata->command) { case H5T_CONV_INIT: - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(8 * src->shared->size != src->shared->u.atomic.prec || 8 * dst->shared->size != dst->shared->u.atomic.prec) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad precision") @@ -4510,7 +4514,7 @@ H5T__conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || NULL == (dst = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* @@ -8780,7 +8784,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, switch(cdata->command) { case H5T_CONV_INIT: - if(NULL == (src_p = (H5T_t*)H5I_object(src_id)) || NULL == (dst_p = (H5T_t*)H5I_object(dst_id))) + if(NULL == (src_p = (H5T_t*)H5I_object_verify(src_id, H5I_DATATYPE)) || + NULL == (dst_p = (H5T_t*)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; @@ -8798,7 +8803,8 @@ H5T__conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if(NULL == (src_p = (H5T_t*)H5I_object(src_id)) || NULL == (dst_p = (H5T_t*)H5I_object(dst_id))) + if(NULL == (src_p = (H5T_t*)H5I_object_verify(src_id, H5I_DATATYPE)) || + NULL == (dst_p = (H5T_t*)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; @@ -9369,7 +9375,8 @@ H5T__conv_i_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, switch(cdata->command) { case H5T_CONV_INIT: - if(NULL == (src_p = (H5T_t *)H5I_object(src_id)) || NULL == (dst_p = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src_p = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || + NULL == (dst_p = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; @@ -9387,7 +9394,8 @@ H5T__conv_i_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if(NULL == (src_p = (H5T_t *)H5I_object(src_id)) || NULL == (dst_p = (H5T_t *)H5I_object(dst_id))) + if(NULL == (src_p = (H5T_t *)H5I_object_verify(src_id, H5I_DATATYPE)) || + NULL == (dst_p = (H5T_t *)H5I_object_verify(dst_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; diff --git a/src/H5Tdeprec.c b/src/H5Tdeprec.c index 32080fe..b59591a 100644 --- a/src/H5Tdeprec.c +++ b/src/H5Tdeprec.c @@ -47,7 +47,7 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Ppublic.h" /* Property Lists */ #include "H5Tpkg.h" /* Datatypes */ - +#include "H5VLprivate.h" /* VOL plugins */ #ifndef H5_NO_DEPRECATED_SYMBOLS /****************/ @@ -125,25 +125,48 @@ H5T_init_deprec_interface(void) herr_t H5Tcommit1(hid_t loc_id, const char *name, hid_t type_id) { - H5G_loc_t loc; /* Location to create datatype */ - H5T_t *type; /* Datatype for ID */ + void *dt = NULL; + H5T_t *type = NULL; + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(FAIL) H5TRACE3("e", "i*si", loc_id, name, type_id); /* Check arguments */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if (H5Tcommitted(type_id)) + HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is already committed") if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") - /* Commit the datatype to the file, using default property list values */ - if(H5T__commit_named(&loc, name, type, H5P_LINK_CREATE_DEFAULT, - H5P_DATATYPE_CREATE_DEFAULT, H5P_DATATYPE_ACCESS_DEFAULT, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); + + /* get the object from the loc_id */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid object identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* commit the datatype through the VOL */ + if (NULL == (dt = H5VL_datatype_commit(obj, loc_params, vol_plugin, name, type_id, + H5P_LINK_CREATE_DEFAULT, H5P_DATATYPE_CREATE_DEFAULT, + H5P_DATATYPE_ACCESS_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to commit datatype") + + /* attach the vol object created using the commit call to the + library datatype structure */ + /* set the committed type object to the VOL pluging pointer in the H5T_t struct */ + type->vol_obj = dt; + + /* attach VOL information to the ID */ + if (H5I_register_aux(type_id, vol_plugin) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't attach vol info to ID") done: FUNC_LEAVE_API(ret_value) @@ -169,62 +192,42 @@ done: hid_t H5Topen1(hid_t loc_id, const char *name) { - H5T_t *type = NULL; - H5G_loc_t loc; - H5G_name_t path; /* Datatype group hier. path */ - H5O_loc_t oloc; /* Datatype object location */ - H5O_type_t obj_type; /* Type of object at location */ - H5G_loc_t type_loc; /* Group object for datatype */ - hbool_t obj_found = FALSE; /* Object at 'name' found */ - hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datatype */ - hid_t ret_value = FAIL; + void *dt = NULL; /* datatype token from VOL plugin */ + void *obj = NULL; /* object token of loc_id */ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5VL_loc_params_t loc_params; + hid_t ret_value = FAIL; /* Return value */ FUNC_ENTER_API(FAIL) - H5TRACE2("i", "i*s", loc_id, name); + H5TRACE2("i", "i*si", loc_id, name); /* Check args */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(!name || !*name) + if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") - /* Set up datatype location to fill in */ - type_loc.oloc = &oloc; - type_loc.path = &path; - H5G_loc_reset(&type_loc); - - /* - * Find the named datatype object header and read the datatype message - * from it. - */ - if(H5G_loc_find(&loc, name, &type_loc/*out*/, H5P_DEFAULT, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found") - obj_found = TRUE; - - /* Check that the object found is the correct type */ - if(H5O_obj_type(&oloc, &obj_type, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "can't get object type") - if(obj_type != H5O_TYPE_NAMED_DATATYPE) - HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a named datatype") - - /* Open it */ - if((type = H5T_open(&type_loc, dxpl_id)) == NULL) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open named datatype") - - /* Register the type and return the ID */ - if((ret_value = H5I_register(H5I_DATATYPE, type, TRUE)) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register named datatype") + loc_params.type = H5VL_OBJECT_BY_SELF; + loc_params.obj_type = H5I_get_type(loc_id); -done: - if(ret_value < 0) { - if(type != NULL) - H5T_close(type); - else { - if(obj_found && H5F_addr_defined(type_loc.oloc->addr)) - H5G_loc_free(&type_loc); - } /* end else */ - } /* end if */ + /* get the file object */ + if(NULL == (obj = (void *)H5I_object(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier") + /* get the plugin pointer */ + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux(loc_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + /* Create the datatype through the VOL */ + if(NULL == (dt = H5VL_datatype_open(obj, loc_params, vol_plugin, name, + H5P_DATATYPE_ACCESS_DEFAULT, H5_REQUEST_NULL))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to open datatype") + /* Get an atom for the datatype */ + if ((ret_value = H5VL_create_datatype(dt, vol_plugin, TRUE, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize datatype handle") + +done: + if (ret_value < 0 && dt) + if(H5VL_datatype_close (dt, vol_plugin, H5_REQUEST_NULL) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release dataset") FUNC_LEAVE_API(ret_value) } /* end H5Topen1() */ #endif /* H5_NO_DEPRECATED_SYMBOLS */ diff --git a/src/H5Toh.c b/src/H5Toh.c index 7961706..99cb396 100644 --- a/src/H5Toh.c +++ b/src/H5Toh.c @@ -29,7 +29,8 @@ #include "H5Iprivate.h" /* IDs */ #include "H5Opkg.h" /* Object headers */ #include "H5Tpkg.h" /* Datatypes */ - +#include "H5VLnative.h" /* Native Plugin */ +#include "H5VLprivate.h" /* VOL */ /****************/ /* Local Macros */ @@ -132,26 +133,26 @@ done: static hid_t H5O_dtype_open(const H5G_loc_t *obj_loc, hid_t UNUSED lapl_id, hid_t dxpl_id, hbool_t app_ref) { - H5T_t *type = NULL; /* Datatype opened */ - hid_t ret_value; /* Return value */ + H5T_t *dt = NULL; /* Datatype opened */ + hid_t ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT HDassert(obj_loc); /* Open the datatype */ - if(NULL == (type = H5T_open(obj_loc, dxpl_id))) + if(NULL == (dt = H5T_open(obj_loc, dxpl_id))) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open datatype") /* Register an ID for the datatype */ - if((ret_value = H5I_register(H5I_DATATYPE, type, app_ref)) < 0) + if((ret_value = H5I_register(H5I_DATATYPE, dt, app_ref)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype") done: - if(ret_value < 0) - if(type && H5T_close(type) < 0) - HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to release datatype") - + if(ret_value < 0) { + if(dt && H5T_close(dt) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype") + } FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_dtype_open() */ @@ -216,15 +217,18 @@ done: static H5O_loc_t * H5O_dtype_get_oloc(hid_t obj_id) { - H5T_t *type; /* Datatype opened */ + H5T_t *type=NULL, *dt=NULL; /* Datatype opened */ H5O_loc_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT /* Get the datatype */ - if(NULL == (type = (H5T_t *)H5I_object(obj_id))) + if(NULL == (dt = (H5T_t *)H5I_object(obj_id))) HGOTO_ERROR(H5E_OHDR, H5E_BADATOM, NULL, "couldn't get object from ID") + if(NULL == (type = (H5T_t *)H5T_get_named_type(dt))) + type = dt; + /* Get the datatype's object header location */ if(NULL == (ret_value = H5T_oloc(type))) HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to get object location from object") diff --git a/src/H5Torder.c b/src/H5Torder.c index 35be454..b807464 100644 --- a/src/H5Torder.c +++ b/src/H5Torder.c @@ -236,6 +236,8 @@ H5Tset_order(hid_t type_id, H5T_order_t order) HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") if(order < H5T_ORDER_LE || order > H5T_ORDER_NONE || order == H5T_ORDER_MIXED) HGOTO_ERROR(H5E_DATATYPE, H5E_BADVALUE, FAIL, "illegal byte order") + if (NULL != dt->vol_obj) + HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is already committed") if(H5T_STATE_TRANSIENT != dt->shared->state) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype is read-only") diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index 8323e15..0553d19 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -393,6 +393,7 @@ struct H5T_t { H5T_shared_t *shared; /* all other information */ H5O_loc_t oloc; /* Object location, if the type is a named type */ H5G_name_t path; /* group hier. path if the type is a named type */ + void *vol_obj; }; /* The master list of soft conversion functions */ diff --git a/src/H5Tprecis.c b/src/H5Tprecis.c index c5ac186..671ae2e 100644 --- a/src/H5Tprecis.c +++ b/src/H5Tprecis.c @@ -174,12 +174,14 @@ H5Tset_precision(hid_t type_id, size_t prec) FUNC_ENTER_API(FAIL) H5TRACE2("e", "iz", type_id, prec); - + /* Check args */ if (NULL == (dt = H5I_object_verify(type_id,H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if (H5T_STATE_TRANSIENT!=dt->shared->state) - HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is read-only") + HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is read-only") + if (NULL != dt->vol_obj) + HGOTO_ERROR(H5E_ARGS, H5E_CANTSET, FAIL, "datatype is committed") if (prec == 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "precision must be positive") if (H5T_ENUM==dt->shared->type && dt->shared->u.enumer.nmembs>0) diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 558afaf..7a48bd5 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -24,6 +24,7 @@ /* Other public headers needed by this file */ #include "H5MMpublic.h" /* Memory management */ +#include "H5VLpublic.h" /* VOL */ /* Private headers needed by this file */ #include "H5private.h" /* Generic Functions */ @@ -139,6 +140,9 @@ H5_DLL uint32_t H5T_hash(H5F_t * file, const H5T_t *dt); H5_DLL herr_t H5T_set_latest_version(H5T_t *dt); H5_DLL herr_t H5T_patch_file(H5T_t *dt, H5F_t *f); H5_DLL htri_t H5T_is_variable_str(const H5T_t *dt); +H5_DLL void * H5T_get_named_type(const H5T_t *dt); +H5_DLL hid_t H5VL_create_datatype(void *dt_obj, H5VL_t *vol_plugin, hbool_t app_ref, hid_t req); +H5_DLL herr_t H5T_set_vol_object(H5T_t *type, void *vol_obj); /* Reference specific functions */ H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt); diff --git a/src/H5VL.c b/src/H5VL.c new file mode 100644 index 0000000..9c42f99 --- /dev/null +++ b/src/H5VL.c @@ -0,0 +1,2207 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov> + * January, 2012 + * + * Purpose: The Virtual Object Layer as described in documentation. + * The pupose is to provide an abstraction on how to access the + * underlying HDF5 container, whether in a local file with + * a specific file format, or remotely on other machines, etc... + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5VL_PACKAGE /*suppress error about including H5VLpkg */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5VL_init_interface + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Aprivate.h" /* Attributes */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5VLpkg.h" /* VOL package header */ +#include "H5VLprivate.h" /* VOL */ + +/********************/ +/* Local Prototypes */ +/********************/ +static herr_t H5VL_free_cls(H5VL_class_t *cls); + +/*******************/ +/* Local Variables */ +/*******************/ + +/* VOL ID class */ +static const H5I_class_t H5I_VOL_CLS[1] = {{ + H5I_VOL, /* ID class value */ + 0, /* Class flags */ + 64, /* Minimum hash size for class */ + 0, /* # of reserved IDs for class */ + (H5I_free_t)H5VL_free_cls, /* Callback routine for closing objects of this class */ + NULL, /* Callback routine for closing auxilary objects of this class */ +}}; + + +/*------------------------------------------------------------------------- + * Function: H5VL_init + * + * Purpose: Initialize the interface from some other package. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_init(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + /* FUNC_ENTER() does all the work */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_init() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_init_interface + * + * Purpose: Initialize the virtual object layer. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_init_interface(void) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* register VOL ID type */ + if(H5I_register_type(H5I_VOL_CLS) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to initialize interface") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_init_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_term_interface + * + * Purpose: Terminate this interface: free all memory and reset global + * variables to their initial values. Release all ID groups + * associated with this interface. + * + * Return: Success: Positive if anything was done that might + * have affected other interfaces; zero + * otherwise. + * + * Failure: Never fails. + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5VL_term_interface(void) +{ + int n = 0, n1 = 0; + hbool_t term = TRUE; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + if(H5_interface_initialize_g) { + if((n1=H5I_nmembers(H5I_VOL))!=0) { + H5I_clear_type(H5I_VOL, FALSE, FALSE); + term = FALSE; + } else { + H5I_dec_type_ref(H5I_VOL); + } + + if (term) { + H5_interface_initialize_g = 0; + n = 1; + } + else { + n = n1; + } + } + + FUNC_LEAVE_NOAPI(n) +} + + +/*------------------------------------------------------------------------- + * Function: H5VL_free_cls + * + * Purpose: Frees a file vol class struct and returns an indication of + * success. This function is used as the free callback for the + * virtual object layer object identifiers (cf H5VL_init_interface). + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_free_cls(H5VL_class_t *cls) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + /* Sanity check */ + HDassert(cls); + + if(cls->terminate && cls->terminate() < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEOBJ, FAIL, "vol plugin '%s' did not terminate cleanly", cls->name) + + H5MM_free(cls); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_free_cls() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLregister + * + * Purpose: Registers a new vol plugin as a member of the virtual object + * layer class. + * + * Return: Success: A vol plugin ID which is good until the + * library is closed or the plugin is + * unregistered. + * + * Failure: A negative value. + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VLregister(const H5VL_class_t *cls) +{ + hid_t ret_value; + + FUNC_ENTER_API(FAIL) + H5TRACE1("i", "*x", cls); + + /* Check arguments */ + if(!cls) + HGOTO_ERROR(H5E_ARGS, H5E_UNINITIALIZED, FAIL, "null class pointer is disallowed") + /* MSC - check if required callback are defined */ + + /* Create the new class ID */ + if((ret_value=H5VL_register(cls, sizeof(H5VL_class_t), TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register vol plugin ID") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLregister() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLunregister + * + * Purpose: Removes a vol plugin ID from the library. This in no way affects + * file access property lists which have been defined to use + * this vol plugin or files which are already opened under with + * this plugin. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLunregister(hid_t vol_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", vol_id); + + /* Check arguments */ + if(NULL == H5I_object_verify(vol_id, H5I_VOL)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a vol plugin") + + /* The H5VL_class_t struct will be freed by this function */ + if(H5I_dec_app_ref(vol_id) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDEC, FAIL, "unable to unregister vol plugin") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLunregister() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLis_registered + * + * Purpose: Tests whether a VOL class has been registered or not + * + * Return: Positive if the VOL class has been registered + * Zero if it is unregistered + * Negative on error (if the class is not a valid class ID) + * + * Programmer: Mohamad Chaarawi + * June 2012 + * + *------------------------------------------------------------------------- + */ +htri_t +H5VLis_registered(hid_t id) +{ + htri_t ret_value = FALSE; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("t", "Ll", id); + + /* Check arguments */ + if(NULL != H5I_object_verify(id, H5I_VOL)) + ret_value = TRUE; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLis_registered() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLget_plugin_name + * + * Purpose: Returns the plugin name for the VOL associated with the + * object or file ID + * + * Return: Success: The length of the plugin name + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * June, 2012 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5VLget_plugin_name(hid_t id, char *name/*out*/, size_t size) +{ + ssize_t ret_value; + + FUNC_ENTER_API(FAIL) + H5TRACE3("i", "*x", id, name, size); + + if((ret_value = H5VL_get_plugin_name(id, name, size)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "Can't get plugin name") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLget_plugin_name() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VLregister_object + * + * Purpose: utility routine to register the native VOL plugin to an ID + * + * Returns: Non-negative on success or negative on failure + * + * Programmer: Mohamad Chaarawi + * June, 2012 + * + *--------------------------------------------------------------------------- + */ +hid_t +H5VLobject_register(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls) +{ + H5VL_t *vol_plugin; /* VOL plugin information */ + hid_t ret_value = FAIL; + + FUNC_ENTER_API(FAIL) + + /* Build the vol plugin struct */ + if(NULL == (vol_plugin = (H5VL_t *)H5MM_calloc(sizeof(H5VL_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + vol_plugin->cls = cls; + vol_plugin->nrefs = 1; + + if ((ret_value = H5VL_object_register(obj, obj_type, vol_plugin, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5VLregister_object */ + + +/*------------------------------------------------------------------------- + * Function: H5VLattr_create + * + * Purpose: Creates an attribute through the VOL + * + * Return: Success: pointer to the new attr. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VLattr_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t acpl_id, hid_t aapl_id, hid_t req) +{ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_API(NULL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object/VOL class pointer") + if(NULL == (ret_value = H5VL_attr_create(obj, loc_params, vol_plugin, name, acpl_id, aapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "unable to create attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLattr_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLattr_open + * + * Purpose: Opens an attribute through the VOL + * + * Return: Success: pointer to the new attr. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VLattr_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t aapl_id, hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_API(NULL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object/VOL class pointer") + if(NULL == (ret_value = H5VL_attr_open(obj, loc_params, vol_plugin, name, aapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "unable to open attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLattr_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLattr_read + * + * Purpose: Reads data from attr through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t H5VLattr_read(void *attr, H5VL_t *vol_plugin, hid_t mem_type_id, void *buf, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if (NULL == attr || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_attr_read(attr, vol_plugin, mem_type_id, buf, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to read attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLattr_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLattr_write + * + * Purpose: Writes data to attr through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t H5VLattr_write(void *attr, H5VL_t *vol_plugin, hid_t mem_type_id, const void *buf, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if (NULL == attr || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_attr_write(attr, vol_plugin, mem_type_id, buf, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to write attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLattr_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLattr_get + * + * Purpose: Get specific information about the attribute through the VOL + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLattr_get(void *obj, H5VL_t *vol_plugin, H5VL_attr_get_t get_type, hid_t req, va_list arguments) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + + switch (get_type) { + /* H5Aexists/exists_by_name */ + case H5VL_ATTR_EXISTS: + { + H5VL_loc_params_t loc_params = va_arg (arguments, H5VL_loc_params_t); + char *attr_name = va_arg (arguments, char *); + htri_t *ret = va_arg (arguments, htri_t *); + + if((ret_value = H5VL_attr_get(obj, vol_plugin, get_type, req, + loc_params, attr_name, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get attribute information") + break; + } + /* H5Aget_space */ + case H5VL_ATTR_GET_SPACE: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + + if((ret_value = H5VL_attr_get(obj, vol_plugin, get_type, req, ret_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get attribute information") + break; + } + /* H5Aget_type */ + case H5VL_ATTR_GET_TYPE: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + + if((ret_value = H5VL_attr_get(obj, vol_plugin, get_type, req, ret_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get attribute information") + break; + } + /* H5Aget_create_plist */ + case H5VL_ATTR_GET_ACPL: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + + if((ret_value = H5VL_attr_get(obj, vol_plugin, get_type, req, ret_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get attribute information") + break; + } + /* H5Aget_name */ + case H5VL_ATTR_GET_NAME: + { + H5VL_loc_params_t loc_params = va_arg (arguments, H5VL_loc_params_t); + size_t buf_size = va_arg (arguments, size_t); + char *buf = va_arg (arguments, char *); + ssize_t *ret_val = va_arg (arguments, ssize_t *); + + if((ret_value = H5VL_attr_get(obj, vol_plugin, get_type, req, + loc_params, buf_size, buf, ret_val)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get attribute information") + break; + } + /* H5Aget_info */ + case H5VL_ATTR_GET_INFO: + { + H5VL_loc_params_t loc_params = va_arg (arguments, H5VL_loc_params_t); + H5A_info_t *ainfo = va_arg (arguments, H5A_info_t *); + + if(H5VL_OBJECT_BY_SELF == loc_params.type) { + if((ret_value = H5VL_attr_get(obj, vol_plugin, get_type, req, loc_params, ainfo)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get attribute information") + } + else if(H5VL_OBJECT_BY_NAME == loc_params.type) { + char *attr_name = va_arg (arguments, char *); + + if((ret_value = H5VL_attr_get(obj, vol_plugin, get_type, req, loc_params, ainfo, attr_name)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get attribute information") + } + else if(H5VL_OBJECT_BY_IDX == loc_params.type) { + if((ret_value = H5VL_attr_get(obj, vol_plugin, get_type, req, loc_params, ainfo)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get attribute information") + } + else + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get name of attr") + + break; + } + case H5VL_ATTR_GET_STORAGE_SIZE: + { + hsize_t *ret = va_arg (arguments, hsize_t *); + if((ret_value = H5VL_attr_get(obj, vol_plugin, get_type, req, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get attribute information") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from attr") + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLattr_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLattr_remove + * + * Purpose: Removes an attribute through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLattr_remove(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, + const char *attr_name, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_attr_remove(obj, loc_params, vol_plugin, attr_name, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to remove attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLattr_remove() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLattr_close + * + * Purpose: Closes an attribute through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLattr_close(void *attr, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if (NULL == attr || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_attr_close(attr, vol_plugin, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to close attribute") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLattr_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLdatatype_commit + * + * Purpose: Commits a datatype to the file through the VOL + * + * Return: Success: Positive + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VLdatatype_commit(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t req) +{ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_API(NULL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object/VOL class pointer") + if(NULL == (ret_value = H5VL_datatype_commit(obj, loc_params, vol_plugin, name, type_id, + lcpl_id, tcpl_id, tapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "unable to commit datatype") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdatatype_commit() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLdatatype_open + * + * Purpose: Opens a named datatype through the VOL + * + * Return: Success: User ID of the datatype. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VLdatatype_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t tapl_id, hid_t req) +{ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_API(NULL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object/VOL class pointer") + if(NULL == (ret_value = H5VL_datatype_open(obj, loc_params, vol_plugin, name, tapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "unable to open datatype") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdatatype_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLdatatype_get_binary + * + * Purpose: gets required size to serialize datatype description + * + * Return: Success: size needed + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5VLdatatype_get_binary(void *obj, H5VL_t *vol_plugin, unsigned char *buf, size_t size, hid_t req) +{ + ssize_t ret_value = FAIL; + + FUNC_ENTER_API(FAIL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_datatype_get_binary(obj, vol_plugin, buf, size, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to encode datatype") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdatatype_get_binary() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLdatatype_close + * + * Purpose: Closes a datatype through the VOL + * + * Return: Success: Positive + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * May, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLdatatype_close(void *dt, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + if (NULL == dt || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_datatype_close(dt, vol_plugin, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to close datatype") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdatatype_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLdataset_create + * + * Purpose: Creates a dataset through the VOL + * + * Return: Success: pointer to dataset + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VLdataset_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t dcpl_id, hid_t dapl_id, hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_API(NULL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object/VOL class pointer") + if(NULL == (ret_value = H5VL_dataset_create(obj, loc_params, vol_plugin, name, + dcpl_id, dapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "unable to create dataset") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdataset_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLdataset_open + * + * Purpose: Opens a dataset through the VOL + * + * Return: Success: pointer to dataset + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VLdataset_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t dapl_id, hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_API(NULL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object/VOL class pointer") + if(NULL == (ret_value = H5VL_dataset_open(obj, loc_params, vol_plugin, name, dapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "unable to open dataset") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdataset_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLdataset_read + * + * Purpose: Reads data from dataset through the VOL +* + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLdataset_read(void *dset, H5VL_t *vol_plugin, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t plist_id, void *buf, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if (NULL == dset || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_dataset_read(dset, vol_plugin, mem_type_id, mem_space_id, file_space_id, + plist_id, buf, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to read dataset") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdataset_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLdataset_write + * + * Purpose: Writes data from dataset through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLdataset_write(void *dset, H5VL_t *vol_plugin, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t plist_id, const void *buf, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if (NULL == dset || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_dataset_write(dset, vol_plugin, mem_type_id, mem_space_id, file_space_id, + plist_id, buf, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to write dataset") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdataset_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLdataset_set_extent + * + * Purpose: Modifies the dimensions of a dataset + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLdataset_set_extent(void *dset, H5VL_t *vol_plugin, const hsize_t size[], hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if (NULL == dset || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_dataset_set_extent(dset, vol_plugin, size, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to set extent of dataset") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdataset_set_extent() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLdataset_get + * + * Purpose: Get specific information about the dataset through the VOL + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLdataset_get(void *dset, H5VL_t *vol_plugin, H5VL_dataset_get_t get_type, hid_t req, va_list arguments) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if (NULL == dset || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + + switch (get_type) { + /* H5Dget_space */ + case H5VL_DATASET_GET_SPACE: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + + if((ret_value = H5VL_dataset_get(dset, vol_plugin, get_type, req, ret_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get dataset information") + break; + } + /* H5Dget_space_statuc */ + case H5VL_DATASET_GET_SPACE_STATUS: + { + H5D_space_status_t *allocation = va_arg (arguments, H5D_space_status_t *); + + if((ret_value = H5VL_dataset_get(dset, vol_plugin, get_type, req, allocation)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get dataset information") + break; + } + /* H5Dget_type */ + case H5VL_DATASET_GET_TYPE: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + + if((ret_value = H5VL_dataset_get(dset, vol_plugin, get_type, req, ret_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get dataset information") + break; + } + /* H5Dget_create_plist */ + case H5VL_DATASET_GET_DCPL: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + + if((ret_value = H5VL_dataset_get(dset, vol_plugin, get_type, req, ret_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get dataset information") + break; + } + /* H5Dget_access_plist */ + case H5VL_DATASET_GET_DAPL: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + + if((ret_value = H5VL_dataset_get(dset, vol_plugin, get_type, req, ret_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get dataset information") + break; + } + /* H5Dget_storage_size */ + case H5VL_DATASET_GET_STORAGE_SIZE: + { + hsize_t *ret = va_arg (arguments, hsize_t *); + + if((ret_value = H5VL_dataset_get(dset, vol_plugin, get_type, req, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get dataset information") + break; + } + /* H5Dget_offset */ + case H5VL_DATASET_GET_OFFSET: + { + haddr_t *ret = va_arg (arguments, haddr_t *); + + if((ret_value = H5VL_dataset_get(dset, vol_plugin, get_type, req, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get dataset information") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from dataset") + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdataset_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLdataset_close + * + * Purpose: Closes a dataset through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLdataset_close(void *dset, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if (NULL == dset || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_dataset_close(dset, vol_plugin, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to close dataset") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLdataset_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLfile_create + * + * Purpose: Creates a file through the VOL + * + * Return: Success: pointer to file. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VLfile_create(H5VL_t **vol_plugin, const char *name, unsigned flags, hid_t fcpl_id, + hid_t fapl_id, hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_API(NULL) + + if(NULL == (ret_value = H5VL_file_create(vol_plugin, name, flags, fcpl_id, fapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "unable to create file") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLfile_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLfile_open + * + * Purpose: Opens a file through the VOL. + * + * Return: Success: pointer to file. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VLfile_open(H5VL_t **vol_plugin, const char *name, unsigned flags, hid_t fapl_id, hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_API(NULL) + + if(NULL == (ret_value = H5VL_file_open(vol_plugin, name, flags, fapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "unable to create file") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLfile_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLfile_flush + * + * Purpose: Flushes a file through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLfile_flush(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, + H5F_scope_t scope, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_file_flush(obj, loc_params, vol_plugin, scope, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to flush file") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLfile_flush() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLfile_get + * + * Purpose: Get specific information about the file through the VOL + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLfile_get(void *file, H5VL_t *vol_plugin, H5VL_file_get_t get_type, hid_t req, va_list arguments) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == file || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + + switch (get_type) { + /* H5Fget_access_plist */ + case H5VL_FILE_GET_FAPL: + { + hid_t *plist_id = va_arg (arguments, hid_t *); + + if((ret_value = H5VL_file_get(file, vol_plugin, get_type, req, plist_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get file information") + break; + } + /* H5Fget_create_plist */ + case H5VL_FILE_GET_FCPL: + { + hid_t *plist_id = va_arg (arguments, hid_t *); + + if((ret_value = H5VL_file_get(file, vol_plugin, get_type, req, plist_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get file information") + break; + } + /* H5Fget_obj_count */ + case H5VL_FILE_GET_OBJ_COUNT: + { + unsigned types = va_arg (arguments, unsigned); + ssize_t *ret = va_arg (arguments, ssize_t *); + + if((ret_value = H5VL_file_get(file, vol_plugin, get_type, req, types, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get file information") + break; + } + /* H5Fget_obj_ids */ + case H5VL_FILE_GET_OBJ_IDS: + { + unsigned types = va_arg (arguments, unsigned); + size_t max_objs = va_arg (arguments, size_t); + hid_t *oid_list = va_arg (arguments, hid_t *); + ssize_t *ret = va_arg (arguments, ssize_t *); + + if((ret_value = H5VL_file_get(file, vol_plugin, get_type, req, types, max_objs, + oid_list, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get file information") + break; + } + /* H5Fget_intent */ + case H5VL_FILE_GET_INTENT: + { + unsigned *ret = va_arg (arguments, unsigned *); + + if((ret_value = H5VL_file_get(file, vol_plugin, get_type, req, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get file information") + break; + } + /* H5Fget_name */ + case H5VL_FILE_GET_NAME: + { + H5I_type_t type = va_arg (arguments, H5I_type_t); + size_t size = va_arg (arguments, size_t); + char *name = va_arg (arguments, char *); + ssize_t *ret = va_arg (arguments, ssize_t *); + + if((ret_value = H5VL_file_get(file, vol_plugin, get_type, req, type, size, + name, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get file information") + break; + } + /* H5I_get_file_id */ + case H5VL_OBJECT_GET_FILE: + { + H5I_type_t type = va_arg (arguments, H5I_type_t); + void **ret = va_arg (arguments, void **); + + if((ret_value = H5VL_file_get(file, vol_plugin, get_type, req, type, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get file information") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information") + } /* end switch */ + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLfile_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLfile_misc + * + * Purpose: perform a specified operation through the VOL + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLfile_misc(void *file, H5VL_t *vol_plugin, H5VL_file_misc_t misc_type, hid_t req, va_list arguments) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == file || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + + switch (misc_type) { + /* H5Fmount */ + case H5VL_FILE_MOUNT: + { + H5I_type_t type = va_arg (arguments, H5I_type_t); + const char *name = va_arg (arguments, const char *); + H5F_t *child = va_arg (arguments, H5F_t *); + hid_t plist_id = va_arg (arguments, hid_t); + + if((ret_value = H5VL_file_misc(file, vol_plugin, misc_type, req, + type, name, child, plist_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + + break; + } + /* H5Fmount */ + case H5VL_FILE_UNMOUNT: + { + H5I_type_t type = va_arg (arguments, H5I_type_t); + const char *name = va_arg (arguments, const char *); + + if((ret_value = H5VL_file_misc(file, vol_plugin, misc_type, req, type, name)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + /* H5Fis_accessible */ + case H5VL_FILE_IS_ACCESSIBLE: + { + hid_t fapl_id = va_arg (arguments, hid_t); + const char *name = va_arg (arguments, const char *); + htri_t *ret = va_arg (arguments, htri_t *); + + if((ret_value = H5VL_file_misc(file, vol_plugin, misc_type, req, fapl_id, name, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't recognize this operation type") + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLfile_misc() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLfile_optional + * + * Purpose: perform a plugin specific operation + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLfile_optional(void *file, H5VL_t *vol_plugin, H5VL_file_optional_t optional_type, hid_t req, va_list arguments) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == file || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + + switch (optional_type) { + /* H5Fget_filesize */ + case H5VL_FILE_GET_SIZE: + { + hsize_t *ret = va_arg (arguments, hsize_t *); + + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + /* H5Fget_file_image */ + case H5VL_FILE_GET_FILE_IMAGE: + { + void *buf_ptr = va_arg (arguments, void *); + ssize_t *ret = va_arg (arguments, ssize_t *); + size_t buf_len = va_arg (arguments, size_t ); + + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req, + buf_ptr, ret, buf_len)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + /* H5Fget_freespace */ + case H5VL_FILE_GET_FREE_SPACE: + { + hssize_t *ret = va_arg (arguments, hssize_t *); + + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + case H5VL_FILE_GET_FREE_SECTIONS: + { + H5F_sect_info_t *sect_info = va_arg (arguments, H5F_sect_info_t *); + ssize_t *ret = va_arg (arguments, ssize_t *); + H5F_mem_t type = va_arg (arguments, H5F_mem_t); + size_t nsects = va_arg (arguments, size_t); + + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req, + sect_info, ret, type, nsects)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + /* H5Fget_info2 */ + case H5VL_FILE_GET_INFO: + { + H5I_type_t type = va_arg (arguments, H5I_type_t); + H5F_info2_t *finfo = va_arg (arguments, H5F_info2_t *); + + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req, type, finfo)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + /* H5Fget_mdc_config */ + case H5VL_FILE_GET_MDC_CONF: + { + H5AC_cache_config_t *config_ptr = va_arg (arguments, H5AC_cache_config_t *); + + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req, config_ptr)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + /* H5Fget_mdc_hit_rate */ + case H5VL_FILE_GET_MDC_HR: + { + double *hit_rate_ptr = va_arg (arguments, double *); + + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req, hit_rate_ptr)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + /* H5Fget_mdc_size */ + case H5VL_FILE_GET_MDC_SIZE: + { + size_t *max_size_ptr = va_arg (arguments, size_t *); + size_t *min_clean_size_ptr = va_arg (arguments, size_t *); + size_t *cur_size_ptr = va_arg (arguments, size_t *); + int *cur_num_entries_ptr = va_arg (arguments, int *); + + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req, max_size_ptr, + min_clean_size_ptr, cur_size_ptr, cur_num_entries_ptr)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + /* H5Fget_vfd_handle */ + case H5VL_FILE_GET_VFD_HANDLE: + { + void **file_handle = va_arg (arguments, void **); + hid_t fapl = va_arg (arguments, hid_t); + + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req, file_handle, fapl)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + /* H5Fclear_elink_file_cache */ + case H5VL_FILE_CLEAR_ELINK_CACHE: + { + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + /* H5Freopen */ + case H5VL_FILE_REOPEN: + { + void **ret = va_arg (arguments, void **); + + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + /* H5Freset_mdc_hit_rate_stats */ + case H5VL_FILE_RESET_MDC_HIT_RATE: + { + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + case H5VL_FILE_SET_MDC_CONFIG: + { + H5AC_cache_config_t *config_ptr = va_arg (arguments, H5AC_cache_config_t *); + + if((ret_value = H5VL_file_optional(file, vol_plugin, optional_type, req, config_ptr)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to operate on the file") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't recognize this operation type") + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLfile_optional() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLfile_close + * + * Purpose: Closes a file through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLfile_close(void *file, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == file || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_file_close(file, vol_plugin, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to close file") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLfile_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLgroup_create + * + * Purpose: Creates a group through the VOL + * + * Return: Success: pointer to new group. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VLgroup_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t gcpl_id, hid_t gapl_id, hid_t req) +{ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_API(NULL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object/VOL class pointer") + if(NULL == (ret_value = H5VL_group_create(obj, loc_params, vol_plugin, name, + gcpl_id, gapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "unable to create group") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLgroup_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLgroup_open + * + * Purpose: Opens a group through the VOL + * + * Return: Success: pointer to new group. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VLgroup_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t gapl_id, hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_API(NULL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object/VOL class pointer") + if(NULL == (ret_value = H5VL_group_open(obj, loc_params, vol_plugin, name, + gapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "unable to open group") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLgroup_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLgroup_get + * + * Purpose: Get specific information about the group through the VOL + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLgroup_get(void *obj, H5VL_t *vol_plugin, H5VL_group_get_t get_type, hid_t req, va_list arguments) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + + switch (get_type) { + /* H5Gget_create_plist */ + case H5VL_GROUP_GET_GCPL: + { + hid_t *new_gcpl_id = va_arg (arguments, hid_t *); + + if((ret_value = H5VL_group_get(obj, vol_plugin, get_type, req, new_gcpl_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get group information") + break; + } + /* H5Gget_info */ + case H5VL_GROUP_GET_INFO: + { + H5VL_loc_params_t loc_params = va_arg (arguments, H5VL_loc_params_t); + H5G_info_t *grp_info = va_arg (arguments, H5G_info_t *); + + if((ret_value = H5VL_group_get(obj, vol_plugin, get_type, req, loc_params, grp_info)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get group information") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from group") + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLgroup_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLgroup_close + * + * Purpose: Closes a group through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLgroup_close(void *grp, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == grp || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_group_close(grp, vol_plugin, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to close group") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLgroup_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLlink_create + * + * Purpose: Creates a hard link through the VOL + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLlink_create(H5VL_link_create_type_t create_type, void *obj, H5VL_loc_params_t loc_params, + H5VL_t *vol_plugin, hid_t lcpl_id, hid_t lapl_id, hid_t req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + if(NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_link_create(create_type, obj, loc_params, vol_plugin, lcpl_id, lapl_id, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to create link") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLlink_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLlink_move + * + * Purpose: Copy or move a link from src to dst. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +H5_DLL herr_t H5VLlink_move(void *src_obj, H5VL_loc_params_t loc_params1, void *dst_obj, + H5VL_loc_params_t loc_params2, H5VL_t *vol_plugin, + hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id, hid_t req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + if(NULL == src_obj || NULL == dst_obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_link_move(src_obj, loc_params1, dst_obj, loc_params2, vol_plugin, + copy_flag, lcpl_id, lapl_id, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to move object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLlink_move() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLlink_iterate + * + * Purpose: Iterate over links in a group + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * May, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t H5VLlink_iterate(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, + hbool_t recursive, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, + H5L_iterate_t op, void *op_data, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_link_iterate(obj, loc_params, vol_plugin, recursive, idx_type, order, idx, + op, op_data, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "Link iteration failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLlink_iterate() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLlink_get + * + * Purpose: Get specific information about the link through the VOL + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLlink_get(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_link_get_t get_type, + hid_t req, va_list arguments) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + + switch (get_type) { + /* H5Lexists */ + case H5VL_LINK_EXISTS: + { + htri_t *ret = va_arg (arguments, htri_t *); + + if((ret_value = H5VL_link_get(obj, loc_params, vol_plugin, get_type, req, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get link information") + break; + } + /* H5Lget_info/H5Lget_info_by_idx */ + case H5VL_LINK_GET_INFO: + { + H5L_info_t *linfo = va_arg (arguments, H5L_info_t *); + + if((ret_value = H5VL_link_get(obj, loc_params, vol_plugin, get_type, req, linfo)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get link information") + break; + } + /* H5Lget_name_by_idx */ + case H5VL_LINK_GET_NAME: + { + char *name = va_arg (arguments, char *); + size_t size = va_arg (arguments, size_t); + ssize_t *ret = va_arg (arguments, ssize_t *); + + if((ret_value = H5VL_link_get(obj, loc_params, vol_plugin, get_type, req, + name, size, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get link information") + break; + } + /* H5Lget_val/H5Lget_val_by_idx */ + case H5VL_LINK_GET_VAL: + { + void *buf = va_arg (arguments, void *); + size_t size = va_arg (arguments, size_t); + + if((ret_value = H5VL_link_get(obj, loc_params, vol_plugin, get_type, req, buf, size)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to get link information") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from link") + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLlink_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLlink_remove + * + * Purpose: Removes a link through the VOL. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +H5_DLL herr_t H5VLlink_remove(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + + if(NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_link_remove(obj, loc_params, vol_plugin, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to remove link") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLlink_remove() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLobject_open + * + * Purpose: Opens a object through the VOL + * + * Return: Success: User ID of the new object. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VLobject_open(void *obj, H5VL_loc_params_t params, H5VL_t *vol_plugin, H5I_type_t *opened_type, + hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_API(NULL) + + if (NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object/VOL class pointer") + if(NULL == (ret_value = H5VL_object_open(obj, params, vol_plugin, opened_type, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "unable to create group") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLobject_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLobject_copy + * + * Purpose: Copies an object to another destination through the VOL + * + * Return: Success: Non Negative + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLobject_copy(void *src_obj, H5VL_loc_params_t loc_params1, H5VL_t *vol_plugin1, const char *src_name, + void *dst_obj, H5VL_loc_params_t loc_params2, H5VL_t *vol_plugin2, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == src_obj || NULL == dst_obj || NULL == vol_plugin1 || + NULL == vol_plugin2 || NULL == vol_plugin1->cls || NULL == vol_plugin2->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_object_copy(src_obj, loc_params1, vol_plugin1, src_name, + dst_obj, loc_params2, vol_plugin2, dst_name, + ocpypl_id, lcpl_id, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "unable to move object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLobject_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLobject_visit + * + * Purpose: Iterate over links in a group + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * May, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t H5VLobject_visit(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5_index_t idx_type, + H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_object_visit(obj, loc_params, vol_plugin, idx_type, order, + op, op_data, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "Object Visit Failed") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLobject_visit() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLobject_get + * + * Purpose: Get specific information about the object through the VOL + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLobject_get(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_object_get_t get_type, + hid_t req, va_list arguments) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + + switch (get_type) { + /* H5Oexists_by_name */ + case H5VL_OBJECT_EXISTS: + { + htri_t *ret = va_arg (arguments, htri_t *); + + if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, get_type, req, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "Object Visit Failed") + break; + } + /* H5Oget_info / H5Oget_info_by_name / H5Oget_info_by_idx */ + case H5VL_OBJECT_GET_INFO: + { + H5O_info_t *obj_info = va_arg (arguments, H5O_info_t *); + + if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, get_type, req, obj_info)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "Object Visit Failed") + break; + } + /* H5Oget_comment / H5Oget_comment_by_name */ + case H5VL_OBJECT_GET_COMMENT: + { + char *comment = va_arg (arguments, char *); + size_t bufsize = va_arg (arguments, size_t); + ssize_t *ret = va_arg (arguments, ssize_t *); + + if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, get_type, req, + comment, bufsize, ret)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "Object Visit Failed") + break; + } + /* H5Rget_region */ + case H5VL_REF_GET_REGION: + { + hid_t *ret = va_arg (arguments, hid_t *); + H5R_type_t ref_type = va_arg (arguments, H5R_type_t); + void *ref = va_arg (arguments, void *); + + if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, get_type, req, + ret, ref_type, ref)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "Object Visit Failed") + break; + } + /* H5Rget_obj_type2 */ + case H5VL_REF_GET_TYPE: + { + H5O_type_t *obj_type = va_arg (arguments, H5O_type_t *); + H5R_type_t ref_type = va_arg (arguments, H5R_type_t); + void *ref = va_arg (arguments, void *); + + if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, get_type, req, + obj_type, ref_type, ref)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "Object Visit Failed") + break; + } + /* H5Rget_name */ + case H5VL_REF_GET_NAME: + { + ssize_t *ret = va_arg (arguments, ssize_t *); + char *name = va_arg (arguments, char *); + size_t size = va_arg (arguments, size_t); + H5R_type_t ref_type = va_arg (arguments, H5R_type_t); + void *ref = va_arg (arguments, void *); + + if((ret_value = H5VL_object_get(obj, loc_params, vol_plugin, get_type, req, + ret, name, size, ref_type, ref)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "Object Visit Failed") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from object") + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLobject_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLobject_misc + * + * Purpose: perform a plugin specific operation + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLobject_misc(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_object_misc_t misc_type, + hid_t req, va_list arguments) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + + switch (misc_type) { + /* H5Arename/rename_by_name */ + case H5VL_ATTR_RENAME: + { + const char *old_name = va_arg (arguments, const char *); + const char *new_name = va_arg (arguments, const char *); + + if((ret_value = H5VL_object_misc(obj, loc_params, vol_plugin, misc_type, req, + old_name, new_name)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "Object Visit Failed") + break; + } + /* H5Oincr_refcount / H5Odecr_refcount */ + case H5VL_OBJECT_CHANGE_REF_COUNT: + { + int update_ref = va_arg (arguments, int); + + if((ret_value = H5VL_object_misc(obj, loc_params, vol_plugin, misc_type, req, update_ref)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "Object Visit Failed") + break; + } + /* H5Oset_comment */ + case H5VL_OBJECT_SET_COMMENT: + { + const char *comment = va_arg (arguments, char *); + + if((ret_value = H5VL_object_misc(obj, loc_params, vol_plugin, misc_type, req, comment)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "Object Visit Failed") + break; + } + case H5VL_REF_CREATE: + { + void *ref = va_arg (arguments, void *); + const char *name = va_arg (arguments, char *); + H5R_type_t ref_type = va_arg (arguments, H5R_type_t); + hid_t space_id = va_arg (arguments, hid_t); + + if((ret_value = H5VL_object_misc(obj, loc_params, vol_plugin, misc_type, req, + ref, name, ref_type, space_id)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "Object Visit Failed") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't recognize this operation type") + } + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLobject_misc() */ + + +/*------------------------------------------------------------------------- + * Function: H5VLobject_close + * + * Purpose: Closes a object through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VLobject_close(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + + if(NULL == obj || NULL == vol_plugin || NULL == vol_plugin->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object/VOL class pointer") + if((ret_value = H5VL_object_close(obj, loc_params, vol_plugin, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "unable to close object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5VLobject_close() */ diff --git a/src/H5VLint.c b/src/H5VLint.c new file mode 100644 index 0000000..25b6fd2 --- /dev/null +++ b/src/H5VLint.c @@ -0,0 +1,2043 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov> + * January, 2012 + * + * Purpose: The Virtual Object Layer as described in documentation. + * The pupose is to provide an abstraction on how to access the + * underlying HDF5 container, whether in a local file with + * a specific file format, or remotely on other machines, etc... + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5VL_PACKAGE /*suppress error about including H5VLpkg */ +#define H5I_PACKAGE /*suppress error about including H5Ipkg */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5VL_int_init_interface + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Dprivate.h" /* Datasets */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Ipkg.h" /* IDs Package header */ +#include "H5Lprivate.h" /* Links */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Pprivate.h" /* Property lists */ +#include "H5Oprivate.h" /* Object headers */ +#include "H5VLpkg.h" /* VOL package header */ +#include "H5VLprivate.h" /* VOL */ + + +/*-------------------------------------------------------------------------- +NAME + H5VL_int_init_interface -- Initialize interface-specific information +USAGE + herr_t H5VL_int_init_interface() + +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. (Just calls + H5VL_init_iterface currently). + +--------------------------------------------------------------------------*/ +static herr_t +H5VL_int_init_interface(void) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + FUNC_LEAVE_NOAPI(H5VL_init()) +} /* H5VL_int_init_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_register + * + * Purpose: Registers a new vol plugin as a member of the virtual object + * layer class. + * + * Return: Success: A vol plugin ID which is good until the + * library is closed or the driver is + * unregistered. + * + * Failure: A negative value. + * + * Programmer: Mohamad Chaarawi + * January, 2012 + *------------------------------------------------------------------------- + */ +hid_t +H5VL_register(const void *_cls, size_t size, hbool_t app_ref) +{ + const H5VL_class_t *cls = (const H5VL_class_t *)_cls; + H5VL_class_t *saved = NULL; + hid_t ret_value; + + FUNC_ENTER_NOAPI(FAIL) + + /* Check arguments */ + HDassert(cls); + + /* Copy the class structure so the caller can reuse or free it */ + if(NULL == (saved = (H5VL_class_t *)H5MM_malloc(size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for vol plugin class struct") + HDmemcpy(saved, cls, size); + + /* Create the new class ID */ + if((ret_value = H5I_register(H5I_VOL, saved, app_ref)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register vol plugin ID") + +done: + if(ret_value < 0) + if(saved) + H5MM_xfree(saved); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_register() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_get_class + * + * Purpose: Obtains a pointer to the vol plugin struct containing all the + * callback pointers, etc. The PLIST_ID argument can be a file + * access property list or a vol plugin identifier. + * + * Return: Success: Ptr to the vol plugin information. The pointer is + * only valid as long as the vol plugin remains + * registered or some file or property list + * exists which references the vol plugin. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +H5VL_class_t * +H5VL_get_class(hid_t id) +{ + H5VL_class_t *ret_value = NULL; + + FUNC_ENTER_NOAPI(NULL) + + if(H5I_VOL == H5I_get_type(id)) + ret_value = (H5VL_class_t *)H5I_object(id); + else { + H5P_genplist_t *plist; /* Property list pointer */ + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID") + + if(TRUE == H5P_isa_class(id, H5P_FILE_ACCESS)) { + if(H5P_get(plist, H5F_ACS_VOL_NAME, &ret_value) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin") + } else { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a vol plugin id, file access property list") + } + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_get_class() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_fapl_open + * + * Purpose: Mark a vol as used by a file access property list + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_fapl_open(H5P_genplist_t *plist, H5VL_class_t *vol_cls, const void *vol_info) +{ + void *copied_vol_info = NULL; /* Temporary VOL driver info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if(H5VL_fapl_copy(vol_cls, vol_info, &copied_vol_info) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "can't copy VFL driver info") + + /* Set the vol properties for the list */ + if(H5P_set(plist, H5F_ACS_VOL_NAME, &vol_cls) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set vol ID") + if(H5P_set(plist, H5F_ACS_VOL_INFO_NAME, &copied_vol_info) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "can't set vol info") + copied_vol_info = NULL; + +done: + if(ret_value < 0) + if(copied_vol_info && H5VL_fapl_close(vol_cls, copied_vol_info) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close copy of driver info") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_fapl_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_fapl_copy + * + * Purpose: copies plugin specific info to the fapl + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * July, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_fapl_copy(H5VL_class_t *vol_cls, const void *vol_info, void **copied_info) +{ + void *new_info = NULL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Copy old pl, if one exists */ + if(vol_info) { + /* Allow the driver to copy or do it ourselves */ + if(vol_cls->fapl_copy) { + new_info = (vol_cls->fapl_copy)(vol_info); + if(NULL == new_info) + HGOTO_ERROR(H5E_VOL, H5E_NOSPACE, FAIL, "property list copy failed") + } + else if(vol_cls->fapl_size > 0) { + if(NULL == (new_info = H5MM_malloc(vol_cls->fapl_size))) + HGOTO_ERROR(H5E_VOL, H5E_NOSPACE, FAIL, "property list allocation failed") + HDmemcpy(new_info, vol_info, vol_cls->fapl_size); + } else + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "no way to copy plugin property list") + } /* end if */ + + /* Set copied value */ + *copied_info = new_info; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_fapl_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_fapl_close + * + * Purpose: Closes a vol for a property list + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_fapl_close(H5VL_class_t *vol_cls, void *vol_info) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL != vol_cls) { + /* Allow driver to free or do it ourselves */ + if(vol_info && vol_cls->fapl_free) { + if((vol_cls->fapl_free)(vol_info) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "plugin free request failed") + } /* end if */ + else + H5MM_xfree(vol_info); + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_fapl_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_close + * + * Purpose: decrements the ref count on the number of references + * outstanding for a VOL plugin + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * May, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_close(H5VL_class_t UNUSED *vol_plugin) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_get_plugin_name + * + * Purpose: Private version of H5VLget_plugin_name + * + * Return: Success: The length of the plugin name + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * June, 2012 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5VL_get_plugin_name(hid_t id, char *name/*out*/, size_t size) +{ + H5VL_t *vol_plugin; /* VOL structure attached to id */ + size_t len; + ssize_t ret_value; + + FUNC_ENTER_NOAPI(FAIL) + + if (NULL == (vol_plugin = (H5VL_t *)H5I_get_aux (id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Object/File does not contain VOL information") + + len = HDstrlen(vol_plugin->cls->name); + + if(name) { + HDstrncpy(name, vol_plugin->cls->name, MIN(len + 1,size)); + if(len >= size) + name[size-1]='\0'; + } /* end if */ + + /* Set the return value for the API call */ + ret_value = (ssize_t)len; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_get_plugin_name() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_object_register + * + * Purpose: utility function to create a user id for an object created + * or opened through the VOL + * + * Return: Success: registered ID + * Failure: FAIL + * + * Programmer: Mohamad Chaarawi + * June, 2012 + * + *------------------------------------------------------------------------- + */ +hid_t +H5VL_object_register(void *obj, H5I_type_t obj_type, H5VL_t *vol_plugin, hbool_t app_ref) +{ + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI(FAIL) + + /* Get an atom for the object and attach VOL information and free function to the ID */ + switch(obj_type) { + case H5I_GROUP: + if((ret_value = H5I_register2(obj_type, obj, vol_plugin, app_ref)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") + break; + + case H5I_DATASET: + if((ret_value = H5I_register2(obj_type, obj, vol_plugin, app_ref)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize dataset handle") + break; + + case H5I_DATATYPE: + if ((ret_value = H5VL_create_datatype(obj, vol_plugin, app_ref, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize datatype handle") + break; + + case H5I_UNINIT: + case H5I_BADID: + case H5I_FILE: + case H5I_DATASPACE: + case H5I_ATTR: + case H5I_REFERENCE: + case H5I_VFL: + case H5I_VOL: + case H5I_GENPROP_CLS: + case H5I_GENPROP_LST: + case H5I_ERROR_CLASS: + case H5I_ERROR_MSG: + case H5I_ERROR_STACK: + case H5I_NTYPES: + default: + HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, FAIL, "invalid object type") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_object_register() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_get_object + * + * Purpose: utility function to return the object pointer associated with + * an hid_t. This routine is the same as H5I_object for all types + * except for named datatypes, where the vol_obj is returned that + * is attached to the H5T_t struct. + * + * Return: Success: object pointer + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * June, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VL_get_object(hid_t id) +{ + void *ret_value = NULL; + + FUNC_ENTER_NOAPI(NULL) + + /* get the object */ + if(NULL == (ret_value = (void *)H5I_object(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "invalid identifier") + + /* if this is a datatype, get the VOL object attached to the H5T_t struct */ + if (H5I_DATATYPE == H5I_get_type(id)) { + if (NULL == (ret_value = H5T_get_named_type((H5T_t *)ret_value))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a named datatype") + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_get_object() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_attr_create + * + * Purpose: Creates an attribute through the VOL + * + * Return: Success: pointer to the new attr. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VL_attr_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t acpl_id, hid_t aapl_id, hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check if the corresponding VOL create callback exists */ + if(NULL == vol_plugin->cls->attr_cls.create) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `attr create' method") + /* call the corresponding VOL create callback */ + if(NULL == (ret_value = (vol_plugin->cls->attr_cls.create) (obj, loc_params, name, acpl_id, aapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "create failed") + + vol_plugin->nrefs ++; +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_attr_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_attr_open + * + * Purpose: Opens an attribute through the VOL + * + * Return: Success: pointer to the new attr. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VL_attr_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t aapl_id, hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check if the type specific corresponding VOL open callback exists */ + if(NULL == vol_plugin->cls->attr_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `attr open' method") + /* call the corresponding VOL open callback */ + if(NULL == (ret_value = (vol_plugin->cls->attr_cls.open) (obj, loc_params, name, aapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "attribute open failed") + + vol_plugin->nrefs ++; +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_attr_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_attr_read + * + * Purpose: Reads data from attr through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t H5VL_attr_read(void *attr, H5VL_t *vol_plugin, hid_t mem_type_id, void *buf, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->attr_cls.read) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr read' method") + if((ret_value = (vol_plugin->cls->attr_cls.read)(attr, mem_type_id, buf, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "read failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_attr_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_attr_write + * + * Purpose: Writes data to attr through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t H5VL_attr_write(void *attr, H5VL_t *vol_plugin, hid_t mem_type_id, const void *buf, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->attr_cls.write) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr write' method") + if((ret_value = (vol_plugin->cls->attr_cls.write)(attr, mem_type_id, buf, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "write failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_attr_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_attr_get + * + * Purpose: Get specific information about the attribute through the VOL + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_attr_get(void *obj, H5VL_t *vol_plugin, H5VL_attr_get_t get_type, hid_t req, ...) +{ + va_list arguments; /* argument list passed from the API call */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->attr_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr get' method") + va_start (arguments, req); + if((ret_value = (vol_plugin->cls->attr_cls.get)(obj, get_type, req, arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed") + va_end (arguments); +#if 0 + /* if the get_type is a named datatype, attach the vol info to it */ + if(H5VL_ATTR_GET_TYPE == get_type) { + hid_t *ret_id; + + va_start (arguments, req); + ret_id = va_arg (arguments, hid_t *); + + if(H5Tcommitted(*ret_id)) { + /* attach VOL information to the ID */ + if (H5I_register_aux(*ret_id, vol_plugin, (H5I_free_t)H5VL_close) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't attach vol info to ID") + } + va_end (arguments); + } +#endif +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_attr_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_attr_remove + * + * Purpose: Removes an attribute through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_attr_remove(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, + const char *attr_name, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->attr_cls.remove) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr remove' method") + if((ret_value = (vol_plugin->cls->attr_cls.remove)(obj, loc_params, attr_name, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTDELETE, FAIL, "remove failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_attr_remove() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_attr_close + * + * Purpose: Closes an attribute through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_attr_close(void *attr, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* if the VOL class does not implement a specific attr close + callback, try the object close */ + if(NULL == vol_plugin->cls->attr_cls.close){ + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `attr close' method") + /* + if(H5VL_object_close(id, req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close object") + */ + } + else if((ret_value = (vol_plugin->cls->attr_cls.close)(attr, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed") + + vol_plugin->nrefs --; + if (0 == vol_plugin->nrefs) { + if (NULL != vol_plugin->container_name) + H5MM_xfree(vol_plugin->container_name); + if (NULL != vol_plugin) + H5MM_free(vol_plugin); + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_attr_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_datatype_commit + * + * Purpose: Commits a datatype to the file through the VOL + * + * Return: Success: Positive + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VL_datatype_commit(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t req) +{ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check if the corresponding VOL commit callback exists */ + if(NULL == vol_plugin->cls->datatype_cls.commit) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `datatype commit' method") + + /* call the corresponding VOL commit callback */ + if(NULL == (ret_value = (vol_plugin->cls->datatype_cls.commit) + (obj, loc_params, name, type_id, lcpl_id, tcpl_id, tapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "commit failed") + vol_plugin->nrefs ++; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_datatype_commit() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_datatype_open + * + * Purpose: Opens a named datatype through the VOL + * + * Return: Success: User ID of the datatype. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VL_datatype_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t tapl_id, hid_t req) +{ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check if the type specific corresponding VOL open callback exists */ + if(NULL == vol_plugin->cls->datatype_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "no datatype open callback"); +#if 0 + H5VL_loc_params_t loc_params; + + loc_params.type = H5VL_OBJECT_BY_NAME; + loc_params.loc_data.loc_by_name.name = name; + loc_params.loc_data.loc_by_name.plist_id = tapl_id; + + /* Open the object class */ + if((ret_value = H5VL_object_open(id, loc_params, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to open object") +#endif + /* call the corresponding VOL open callback */ + if(NULL == (ret_value = (vol_plugin->cls->datatype_cls.open)(obj, loc_params, name, tapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed") + vol_plugin->nrefs ++; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_datatype_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_datatype_get_binary + * + * Purpose: gets required size to serialize datatype description + * + * Return: Success: size needed + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +ssize_t +H5VL_datatype_get_binary(void *obj, H5VL_t *vol_plugin, unsigned char *buf, size_t size, hid_t req) +{ + ssize_t ret_value = FAIL; + + FUNC_ENTER_NOAPI(FAIL) + + /* check if the type specific corresponding VOL open callback exists */ + if(NULL == vol_plugin->cls->datatype_cls.get_binary) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "no datatype get_binary callback"); + /* call the corresponding VOL open callback */ + if((ret_value = (vol_plugin->cls->datatype_cls.get_binary)(obj, buf, size, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "get binary failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_datatype_get_binary() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_datatype_close + * + * Purpose: Closes a datatype through the VOL + * + * Return: Success: Positive + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * May, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_datatype_close(void *dt, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* check if the corresponding VOL close callback exists */ + if(NULL == vol_plugin->cls->datatype_cls.close) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `datatype close' method") + + /* call the corresponding VOL close callback */ + if((ret_value = (vol_plugin->cls->datatype_cls.close)(dt, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed") + + vol_plugin->nrefs --; + if (0 == vol_plugin->nrefs) { + if (NULL != vol_plugin->container_name) + H5MM_xfree(vol_plugin->container_name); + if (NULL != vol_plugin) + H5MM_free(vol_plugin); + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_datatype_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dataset_create + * + * Purpose: Creates a dataset through the VOL + * + * Return: Success: pointer to dataset + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VL_dataset_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t dcpl_id, hid_t dapl_id, hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check if the corresponding VOL create callback exists */ + if(NULL == vol_plugin->cls->dataset_cls.create) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `dataset create' method") + /* call the corresponding VOL create callback */ + if(NULL == (ret_value = (vol_plugin->cls->dataset_cls.create)(obj, loc_params, name, dcpl_id, dapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "create failed") + vol_plugin->nrefs ++; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dataset_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dataset_open + * + * Purpose: Opens a dataset through the VOL + * + * Return: Success: pointer to dataset + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VL_dataset_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t dapl_id, hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check if the type specific corresponding VOL open callback exists */ + if(NULL == vol_plugin->cls->dataset_cls.open) { + ; +#if 0 + /* Open the object class */ + if((ret_value = H5VL_object_open(id, loc_params, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to open object") +#endif + } + else { + /* call the corresponding VOL open callback */ + if(NULL == (ret_value = (vol_plugin->cls->dataset_cls.open)(obj, loc_params, name, dapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed") + vol_plugin->nrefs ++; + + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dataset_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dataset_read + * + * Purpose: Reads data from dataset through the VOL +* + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_dataset_read(void *dset, H5VL_t *vol_plugin, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t plist_id, void *buf, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->dataset_cls.read) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset read' method") + if((ret_value = (vol_plugin->cls->dataset_cls.read) + (dset, mem_type_id, mem_space_id, file_space_id, plist_id, buf, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_READERROR, FAIL, "read failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dataset_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dataset_write + * + * Purpose: Writes data from dataset through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_dataset_write(void *dset, H5VL_t *vol_plugin, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t plist_id, const void *buf, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->dataset_cls.write) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset write' method") + if((ret_value = (vol_plugin->cls->dataset_cls.write) + (dset, mem_type_id, mem_space_id, file_space_id, plist_id, buf, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_WRITEERROR, FAIL, "write failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dataset_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dataset_set_extent + * + * Purpose: Modifies the dimensions of a dataset + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_dataset_set_extent(void *dset, H5VL_t *vol_plugin, const hsize_t size[], hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->dataset_cls.set_extent) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset set_extent' method") + if((ret_value = (vol_plugin->cls->dataset_cls.set_extent)(dset, size, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "set_extent failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dataset_set_extent() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dataset_get + * + * Purpose: Get specific information about the dataset through the VOL + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_dataset_get(void *dset, H5VL_t *vol_plugin, H5VL_dataset_get_t get_type, hid_t req, ...) +{ + va_list arguments; /* argument list passed from the API call */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->dataset_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `dataset get' method") + + va_start (arguments, req); + if((ret_value = (vol_plugin->cls->dataset_cls.get)(dset, get_type, req, arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed") + va_end (arguments); + +#if 0 + /* if the get_type is a named datatype, create a wrapper for it */ + if(H5VL_DATASET_GET_TYPE == get_type) { + hid_t *ret_id; + + va_start (arguments, req); + ret_id = va_arg (arguments, hid_t *); + + if(H5Tcommitted(*ret_id)) { + /* attach VOL information to the ID */ + if (H5I_register_aux(*ret_id, vol_plugin, (H5I_free_t)H5VL_close) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "can't attach vol info to ID") + } + va_end (arguments); + } +#endif + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dataset_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_dataset_close + * + * Purpose: Closes a dataset through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_dataset_close(void *dset, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* if the VOL class does not implement a specific dataset close + callback, try the object close */ + if(NULL == vol_plugin->cls->dataset_cls.close){ + ; +#if 0 + if(H5VL_object_close(id, req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close object") +#endif + } + else { + if((ret_value = (vol_plugin->cls->dataset_cls.close)(dset, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed") + } + + vol_plugin->nrefs --; + if (0 == vol_plugin->nrefs) { + if (NULL != vol_plugin->container_name) + H5MM_xfree(vol_plugin->container_name); + if (NULL != vol_plugin) + H5MM_free(vol_plugin); + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_dataset_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_file_create + * + * Purpose: Creates a file through the VOL + * + * Return: Success: pointer to file. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VL_file_create(H5VL_t **plugin, const char *name, unsigned flags, hid_t fcpl_id, + hid_t fapl_id, hid_t req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5VL_class_t *vol_cls; /* VOL class attached to fapl_id */ + H5VL_t *vol_plugin = NULL; /* the public VOL struct */ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* get the VOL info from the fapl */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") + if(H5P_get(plist, H5F_ACS_VOL_NAME, &vol_cls) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin ID") + + /* check if the corresponding VOL create callback exists */ + if(NULL == vol_cls->file_cls.create) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file create' method") + /* call the corresponding VOL create callback */ + if(NULL == (ret_value = (vol_cls->file_cls.create)(name, flags, fcpl_id, fapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "create failed") + + /* Build the vol plugin struct */ + if(NULL == (*plugin = (H5VL_t *)H5MM_calloc(sizeof(H5VL_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + vol_plugin = *plugin; + vol_plugin->cls = vol_cls; + vol_plugin->nrefs = 1; + if((vol_plugin->container_name = H5MM_xstrdup(name)) == NULL) + HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,NULL,"memory allocation failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_file_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_file_open + * + * Purpose: Opens a file through the VOL. + * + * Return: Success: pointer to file. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VL_file_open(H5VL_t **plugin, const char *name, unsigned flags, hid_t fapl_id, hid_t req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5VL_class_t *vol_cls; /* VOL class attached to fapl_id */ + H5VL_t *vol_plugin = NULL; /* the public VOL struct */ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* get the VOL info from the fapl */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") + if(H5P_get(plist, H5F_ACS_VOL_NAME, &vol_cls) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get vol plugin ID") + + /* check if the corresponding VOL create callback exists */ + if(NULL == vol_cls->file_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `file open' method") + /* call the corresponding VOL create callback */ + if(NULL == (ret_value = (vol_cls->file_cls.open)(name, flags, fapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed") + + /* Build the vol plugin struct */ + if(NULL == (*plugin = (H5VL_t *)H5MM_calloc(sizeof(H5VL_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + vol_plugin = *plugin; + vol_plugin->cls = vol_cls; + vol_plugin->nrefs = 1; + if((vol_plugin->container_name = H5MM_xstrdup(name)) == NULL) + HGOTO_ERROR(H5E_RESOURCE,H5E_NOSPACE,NULL,"memory allocation failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_file_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_file_flush + * + * Purpose: Flushes a file through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_file_flush(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5F_scope_t scope, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->file_cls.flush) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file flush' method") + if((ret_value = (vol_plugin->cls->file_cls.flush)(obj, loc_params, scope, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTFLUSH, FAIL, "flush failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_file_flush() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_file_get + * + * Purpose: Get specific information about the file through the VOL + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_file_get(void *file, H5VL_t *vol_plugin, H5VL_file_get_t get_type, hid_t req, ...) +{ + va_list arguments; /* argument list passed from the API call */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->file_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file get' method") + + va_start(arguments, req); + if((ret_value = (vol_plugin->cls->file_cls.get)(file, get_type, req, arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed") + va_end(arguments); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_file_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_file_misc + * + * Purpose: perform a specified operation through the VOL + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_file_misc(void *file, H5VL_t *vol_plugin, H5VL_file_misc_t misc_type, hid_t req, ...) +{ + va_list arguments; /* argument list passed from the API call */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if (misc_type == H5VL_FILE_IS_ACCESSIBLE) { + H5P_genplist_t *plist; /* Property list pointer */ + H5VL_class_t *vol_cls; /* VOL class attached to fapl_id */ + va_list tmp_args; /* argument list passed from the API call */ + hid_t fapl_id; + + va_start (tmp_args, req); + fapl_id = va_arg (tmp_args, hid_t); + va_end (tmp_args); + + /* get the VOL info from the fapl */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(fapl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + if(H5P_get(plist, H5F_ACS_VOL_NAME, &vol_cls) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get vol plugin") + + va_start (arguments, req); + if((ret_value = (vol_cls->file_cls.misc)(file, misc_type, req, arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "misc failed") + va_end (arguments); + } + else { + if(NULL == vol_plugin->cls->file_cls.misc) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file misc' method") + + va_start (arguments, req); + if((ret_value = (vol_plugin->cls->file_cls.misc)(file, misc_type, req, arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "misc failed") + va_end (arguments); + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_file_misc() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_file_optional + * + * Purpose: perform a plugin specific operation + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_file_optional(void *file, H5VL_t *vol_plugin, H5VL_file_optional_t optional_type, hid_t req, ...) +{ + va_list arguments; /* argument list passed from the API call */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->file_cls.optional) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file optional' method") + + va_start (arguments, req); + if((ret_value = (vol_plugin->cls->file_cls.optional)(file, optional_type, req, arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "optional failed") + va_end (arguments); + + /* if the get_type is a named datatype, attach the vol info to it */ + if(H5VL_FILE_REOPEN == optional_type) { + vol_plugin->nrefs ++; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_file_optional() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_file_close + * + * Purpose: Closes a file through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_file_close(void *file, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->file_cls.close) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `file close' method") + if((ret_value = (vol_plugin->cls->file_cls.close)(file, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTCLOSEFILE, FAIL, "close failed") + + vol_plugin->nrefs --; + if (0 == vol_plugin->nrefs) { + if (NULL != vol_plugin->container_name) + H5MM_xfree(vol_plugin->container_name); + if (NULL != vol_plugin) + H5MM_free(vol_plugin); + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_file_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_group_create + * + * Purpose: Creates a group through the VOL + * + * Return: Success: pointer to new group. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VL_group_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t gcpl_id, hid_t gapl_id, hid_t req) +{ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check if the corresponding VOL create callback exists */ + if(NULL == vol_plugin->cls->group_cls.create) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `group create' method") + /* call the corresponding VOL create callback */ + if(NULL == (ret_value = (vol_plugin->cls->group_cls.create)(obj, loc_params, name, gcpl_id, gapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "create failed") + vol_plugin->nrefs ++; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_group_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_group_open + * + * Purpose: Opens a group through the VOL + * + * Return: Success: pointer to new group. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VL_group_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, + hid_t gapl_id, hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check if the type specific corresponding VOL open callback exists */ + if(NULL == vol_plugin->cls->group_cls.open) { + ; +#if 0 + /* Open the object class */ + if((ret_value = H5VL_object_open(id, loc_params, H5_REQUEST_NULL)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to open object") +#endif + } + else { + /* call the corresponding VOL open callback */ + if(NULL == (ret_value = (vol_plugin->cls->group_cls.open)(obj, loc_params, name, gapl_id, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed") + vol_plugin->nrefs ++; + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_group_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_group_get + * + * Purpose: Get specific information about the group through the VOL + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_group_get(void *obj, H5VL_t *vol_plugin, H5VL_group_get_t get_type, hid_t req, ...) +{ + va_list arguments; /* argument list passed from the API call */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->group_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `group get' method") + va_start (arguments, req); + if((ret_value = (vol_plugin->cls->group_cls.get)(obj, get_type, req, arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed") + va_end (arguments); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_group_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_group_close + * + * Purpose: Closes a group through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_group_close(void *grp, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* if the VOL class does not implement a specific group close + callback, try the object close */ + if(NULL == vol_plugin->cls->group_cls.close) { + ; +#if 0 + if(H5VL_object_close(id, req) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close object") +#endif + } + else { + if((ret_value = (vol_plugin->cls->group_cls.close)(grp, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed") + } + + vol_plugin->nrefs --; + if (0 == vol_plugin->nrefs) { + if (NULL != vol_plugin->container_name) + H5MM_xfree(vol_plugin->container_name); + if (NULL != vol_plugin) + H5MM_free(vol_plugin); + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_group_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_link_create + * + * Purpose: Creates a hard link through the VOL + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_link_create(H5VL_link_create_type_t create_type, void *obj, H5VL_loc_params_t loc_params, + H5VL_t *vol_plugin, hid_t lcpl_id, hid_t lapl_id, hid_t req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* check if the corresponding VOL create callback exists */ + if(NULL == vol_plugin->cls->link_cls.create) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `link create' method") + /* call the corresponding VOL create callback */ + if((ret_value = (vol_plugin->cls->link_cls.create) + (create_type, obj, loc_params, lcpl_id, lapl_id, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "link create failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_link_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_link_move + * + * Purpose: Copy or move a link from src to dst. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +H5_DLL herr_t H5VL_link_move(void *src_obj, H5VL_loc_params_t loc_params1, void *dst_obj, + H5VL_loc_params_t loc_params2, H5VL_t *vol_plugin, + hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id, hid_t req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* check if the corresponding VOL move callback exists */ + if(NULL == vol_plugin->cls->link_cls.move) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `link move' method") + /* call the corresponding VOL move callback */ + if((ret_value = (vol_plugin->cls->link_cls.move) + (src_obj, loc_params1, dst_obj, loc_params2, copy_flag, lcpl_id, lapl_id, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "link move failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_link_move() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_link_iterate + * + * Purpose: Iterate over links in a group + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * May, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t H5VL_link_iterate(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, + hbool_t recursive, H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, + H5L_iterate_t op, void *op_data, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->link_cls.iterate) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `link iterate' method") + if((ret_value = (vol_plugin->cls->link_cls.iterate)(obj, loc_params, recursive, idx_type, + order, idx, op, op_data, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_BADITER, FAIL, "iteration failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_link_iterate() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_link_get + * + * Purpose: Get specific information about the link through the VOL + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_link_get(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_link_get_t get_type, + hid_t req, ...) +{ + va_list arguments; /* argument list passed from the API call */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->link_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `link get' method") + va_start (arguments, req); + if((ret_value = (vol_plugin->cls->link_cls.get)(obj, loc_params, get_type, req, arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed") + va_end (arguments); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_link_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_link_remove + * + * Purpose: Removes a link through the VOL. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +H5_DLL herr_t H5VL_link_remove(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* check if the corresponding VOL remove callback exists */ + if(NULL == vol_plugin->cls->link_cls.remove) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `link remove' method") + /* call the corresponding VOL remove callback */ + if((ret_value = (vol_plugin->cls->link_cls.remove)(obj, loc_params, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, FAIL, "link remove failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_link_remove() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_object_open + * + * Purpose: Opens a object through the VOL + * + * Return: Success: User ID of the new object. + * + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +void * +H5VL_object_open(void *obj, H5VL_loc_params_t params, H5VL_t *vol_plugin, H5I_type_t *opened_type, + hid_t req) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(NULL) + + /* check if the corresponding VOL open callback exists */ + if(NULL == vol_plugin->cls->object_cls.open) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "vol plugin has no `object open' method") + /* call the corresponding VOL open callback */ + if(NULL == (ret_value = (vol_plugin->cls->object_cls.open)(obj, params, opened_type, req))) + HGOTO_ERROR(H5E_VOL, H5E_CANTINIT, NULL, "open failed") + vol_plugin->nrefs++; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_object_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_object_copy + * + * Purpose: Copies an object to another destination through the VOL + * + * Return: Success: Non Negative + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_object_copy(void *src_obj, H5VL_loc_params_t loc_params1, H5VL_t *vol_plugin1, const char *src_name, + void *dst_obj, H5VL_loc_params_t loc_params2, H5VL_t *vol_plugin2, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + /* check if both objects are associated with the same VOL plugin */ + if(vol_plugin1->cls != vol_plugin2->cls) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "Objects are accessed through different VOL plugins and can't be copied") + + if(NULL == vol_plugin1->cls->object_cls.copy) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object copy' method") + if((ret_value = (vol_plugin1->cls->object_cls.copy) + (src_obj, loc_params1, src_name, dst_obj, loc_params2, dst_name, ocpypl_id, lcpl_id, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "copy failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_object_copy() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_object_visit + * + * Purpose: Iterate over links in a group + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * May, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t H5VL_object_visit(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5_index_t idx_type, + H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->object_cls.visit) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object visit' method") + + if((ret_value = (vol_plugin->cls->object_cls.visit)(obj, loc_params, idx_type, order, op, + op_data, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_BADITER, FAIL, "object visitation failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_object_visit() */ + +#if 0 + +/*------------------------------------------------------------------------- + * Function: H5VL_object_lookup + * + * Purpose: Lookup the object location in the file + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_object_lookup(hid_t id, H5VL_loc_type_t lookup_type, void **location, hid_t req, ...) +{ + va_list arguments; /* argument list passed from the API call */ + H5VL_class_t *vol_plugin; /* VOL structure attached to id */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if (NULL == (vol_plugin = (H5VL_class_t *)H5I_get_aux(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + if(NULL == vol_plugin->object_cls.lookup) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object lookup' method") + + va_start (arguments, req); + if((ret_value = (vol_plugin->object_cls.lookup)(id, lookup_type, location, req, arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "lookup of object location failed") + va_end (arguments); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_object_lookup() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_object_free_loc + * + * Purpose: Free the location token + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * May, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_object_free_loc(hid_t id, void *location, hid_t req) +{ + H5VL_class_t *vol_plugin; /* VOL structure attached to id */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if (NULL == (vol_plugin = (H5VL_class_t *)H5I_get_aux(id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "ID does not contain VOL information") + + if(NULL == vol_plugin->object_cls.free_loc) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object free_loc' method") + + if((ret_value = (vol_plugin->object_cls.free_loc)(location, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "freeing location token of object location failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_object_free_loc() */ +#endif + + +/*------------------------------------------------------------------------- + * Function: H5VL_object_get + * + * Purpose: Get specific information about the object through the VOL + * + * Return: Success: non negative + * + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_object_get(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_object_get_t get_type, hid_t req, ...) +{ + va_list arguments; /* argument list passed from the API call */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->object_cls.get) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object get' method") + + va_start (arguments, req); + if((ret_value = (vol_plugin->cls->object_cls.get)(obj, loc_params, get_type, req, arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "get failed") + va_end (arguments); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_object_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_object_misc + * + * Purpose: perform a plugin specific operation + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_object_misc(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_object_misc_t misc_type, hid_t req, ...) +{ + va_list arguments; /* argument list passed from the API call */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->object_cls.misc) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object misc' method") + + va_start (arguments, req); + if((ret_value = (vol_plugin->cls->object_cls.misc)(obj, loc_params, misc_type, req, arguments)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "misc failed") + va_end (arguments); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_object_misc() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_object_close + * + * Purpose: Closes a object through the VOL + * + * Return: Success: Non Negative + * + * Failure: Negative + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5VL_object_close(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, hid_t req) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(FAIL) + + if(NULL == vol_plugin->cls->object_cls.close) + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "vol plugin has no `object close' method") + if((ret_value = (vol_plugin->cls->object_cls.close)(obj, loc_params, req)) < 0) + HGOTO_ERROR(H5E_VOL, H5E_CANTRELEASE, FAIL, "close failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_object_close() */ diff --git a/src/H5VLnative.c b/src/H5VLnative.c new file mode 100644 index 0000000..5900068 --- /dev/null +++ b/src/H5VLnative.c @@ -0,0 +1,3641 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov> + * January, 2012 + * + * Purpose: The native VOL plugin where access is to a single HDF5 file + * using HDF5 VFDs. + */ + +#define H5A_PACKAGE /*suppress error about including H5Apkg */ +#define H5D_PACKAGE /*suppress error about including H5Dpkg */ +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ +#define H5G_PACKAGE /*suppress error about including H5Gpkg */ +#define H5L_PACKAGE /*suppress error about including H5Lpkg */ +#define H5O_PACKAGE /*suppress error about including H5Opkg */ +#define H5R_PACKAGE /*suppress error about including H5Rpkg */ +#define H5T_PACKAGE /*suppress error about including H5Tpkg */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5VL_native_init_interface + + +#include "H5private.h" /* Generic Functions */ +#include "H5Apkg.h" /* Attribute pkg */ +#include "H5Aprivate.h" /* Attributes */ +#include "H5Dpkg.h" /* Dataset pkg */ +#include "H5Dprivate.h" /* Datasets */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fprivate.h" /* File access */ +#include "H5Fpkg.h" /* File pkg */ +#include "H5Gpkg.h" /* Groups */ +#include "H5HGprivate.h" /* Global Heaps */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* links */ +#include "H5Lpkg.h" /* links headers */ +#include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Opkg.h" /* Object headers */ +#include "H5Pprivate.h" /* Property lists */ +#include "H5Rpkg.h" /* References */ +#include "H5SMprivate.h" /* Shared Object Header Messages */ +#include "H5Tpkg.h" /* Datatypes */ +#include "H5Tprivate.h" /* Datatypes */ +#include "H5VLprivate.h" /* VOL plugins */ +#include "H5VLnative.h" /* Native VOL plugin */ + +/* Prototypes */ +static H5F_t *H5VL_native_get_file(void *obj, H5I_type_t type); + +/* Atrribute callbacks */ +static void *H5VL_native_attr_create(void *obj, H5VL_loc_params_t loc_params, const char *attr_name, hid_t acpl_id, hid_t aapl_id, hid_t req); +static void *H5VL_native_attr_open(void *obj, H5VL_loc_params_t loc_params, const char *attr_name, hid_t aapl_id, hid_t req); +static herr_t H5VL_native_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t req); +static herr_t H5VL_native_attr_write(void *attr, hid_t dtype_id, const void *buf, hid_t req); +static herr_t H5VL_native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t req, va_list arguments); +static herr_t H5VL_native_attr_remove(void *obj, H5VL_loc_params_t loc_params, const char *attr_name, hid_t req); +static herr_t H5VL_native_attr_close(void *attr, hid_t req); + +/* Datatype callbacks */ +static void *H5VL_native_datatype_commit(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t req); +static void *H5VL_native_datatype_open(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t tapl_id, hid_t req); +static ssize_t H5VL_native_datatype_get_binary(void *obj, unsigned char *buf, size_t size, hid_t req); +static herr_t H5VL_native_datatype_close(void *dt, hid_t req); + +/* Dataset callbacks */ +static void *H5VL_native_dataset_create(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t dcpl_id, hid_t dapl_id, hid_t req); +static void *H5VL_native_dataset_open(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t dapl_id, hid_t req); +static herr_t H5VL_native_dataset_read(void *dset, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t plist_id, void *buf, hid_t req); +static herr_t H5VL_native_dataset_write(void *dset, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t plist_id, const void *buf, hid_t req); +static herr_t H5VL_native_dataset_set_extent(void *dset, const hsize_t size[], hid_t req); +static herr_t H5VL_native_dataset_get(void *dset, H5VL_dataset_get_t get_type, hid_t req, va_list arguments); +static herr_t H5VL_native_dataset_close(void *dset, hid_t req); + +/* File callbacks */ +static void *H5VL_native_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t req); +static void *H5VL_native_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t req); +static herr_t H5VL_native_file_flush(void *obj, H5VL_loc_params_t loc_params, H5F_scope_t scope, hid_t req); +static herr_t H5VL_native_file_get(void *file, H5VL_file_get_t get_type, hid_t req, va_list arguments); +static herr_t H5VL_native_file_misc(void *file, H5VL_file_misc_t misc_type, hid_t req, va_list arguments); +static herr_t H5VL_native_file_optional(void *file, H5VL_file_optional_t optional_type, hid_t req, va_list arguments); +static herr_t H5VL_native_file_close(void *file, hid_t req); + +/* Group callbacks */ +static void *H5VL_native_group_create(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t gcpl_id, hid_t gapl_id, hid_t req); +static void *H5VL_native_group_open(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t gapl_id, hid_t req); +static herr_t H5VL_native_group_get(void *obj, H5VL_group_get_t get_type, hid_t req, va_list arguments); +static herr_t H5VL_native_group_close(void *grp, hid_t req); + +/* Link callbacks */ +static herr_t H5VL_native_link_create(H5VL_link_create_type_t create_type, void *obj, + H5VL_loc_params_t loc_params, hid_t lcpl_id, hid_t lapl_id, hid_t req); +static herr_t H5VL_native_link_move(void *src_obj, H5VL_loc_params_t loc_params1, + void *dst_obj, H5VL_loc_params_t loc_params2, + hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id, hid_t req); +static herr_t H5VL_native_link_iterate(void *obj, H5VL_loc_params_t loc_params, hbool_t recursive, + H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, + H5L_iterate_t op, void *op_data, hid_t req); +static herr_t H5VL_native_link_get(void *obj, H5VL_loc_params_t loc_params, H5VL_link_get_t get_type, hid_t req, va_list arguments); +static herr_t H5VL_native_link_remove(void *obj, H5VL_loc_params_t loc_params, hid_t req); + +/* Object callbacks */ +static void *H5VL_native_object_open(void *obj, H5VL_loc_params_t loc_params, H5I_type_t *opened_type, hid_t req); +static herr_t H5VL_native_object_copy(void *src_obj, H5VL_loc_params_t loc_params1, const char *src_name, + void *dst_obj, H5VL_loc_params_t loc_params2, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id, hid_t req); +static herr_t H5VL_native_object_visit(void *obj, H5VL_loc_params_t loc_params, H5_index_t idx_type, + H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t req); +//static herr_t H5VL_native_object_lookup(hid_t loc_id, H5VL_loc_type_t lookup_type, void **location, hid_t req, va_list arguments); +//static herr_t H5VL_native_object_free_loc(void *location, hid_t req); +static herr_t H5VL_native_object_get(void *obj, H5VL_loc_params_t loc_params, H5VL_object_get_t get_type, hid_t req, va_list arguments); +static herr_t H5VL_native_object_misc(void *obj, H5VL_loc_params_t loc_params, H5VL_object_misc_t misc_type, hid_t req, va_list arguments); +static herr_t H5VL_native_object_optional(void *obj, H5VL_loc_params_t loc_params, H5VL_object_optional_t optional_type, hid_t req, va_list arguments); +static herr_t H5VL_native_object_close(void *obj, H5VL_loc_params_t loc_params, hid_t req); + +static H5VL_class_t H5VL_native_g = { + NATIVE, + "native", /* name */ + NULL, /* initialize */ + NULL, /* terminate */ + 0, /* fapl_size */ + NULL, /* fapl_copy */ + NULL, /* fapl_free */ + { /* attribute_cls */ + H5VL_native_attr_create, /* create */ + H5VL_native_attr_open, /* open */ + H5VL_native_attr_read, /* read */ + H5VL_native_attr_write, /* write */ + H5VL_native_attr_get, /* get */ + H5VL_native_attr_remove, /* remove */ + H5VL_native_attr_close /* close */ + }, + { /* datatype_cls */ + H5VL_native_datatype_commit, /* commit */ + H5VL_native_datatype_open, /* open */ + H5VL_native_datatype_get_binary, /* get_size */ + H5VL_native_datatype_close /* close */ + }, + { /* dataset_cls */ + H5VL_native_dataset_create, /* create */ + H5VL_native_dataset_open, /* open */ + H5VL_native_dataset_read, /* read */ + H5VL_native_dataset_write, /* write */ + H5VL_native_dataset_set_extent, /* set extent */ + H5VL_native_dataset_get, /* get */ + H5VL_native_dataset_close /* close */ + }, + { /* file_cls */ + H5VL_native_file_create, /* create */ + H5VL_native_file_open, /* open */ + H5VL_native_file_flush, /* flush */ + H5VL_native_file_get, /* get */ + H5VL_native_file_misc, /* misc */ + H5VL_native_file_optional, /* optional */ + H5VL_native_file_close /* close */ + }, + { /* group_cls */ + H5VL_native_group_create, /* create */ + H5VL_native_group_open, /* open */ + H5VL_native_group_get, /* get */ + H5VL_native_group_close /* close */ + }, + { /* link_cls */ + H5VL_native_link_create, /* create */ + H5VL_native_link_move, /* move */ + H5VL_native_link_iterate, /* iterate */ + H5VL_native_link_get, /* get */ + H5VL_native_link_remove /* remove */ + }, + { /* object_cls */ + H5VL_native_object_open, /* open */ + H5VL_native_object_copy, /* copy */ + H5VL_native_object_visit, /* visit */ + H5VL_native_object_get, /* get */ + H5VL_native_object_misc, /* misc */ + H5VL_native_object_optional, /* optional */ + H5VL_native_object_close /* close */ + } +}; + + +/*-------------------------------------------------------------------------- +NAME + H5VL_native_init_interface -- Initialize interface-specific information +USAGE + herr_t H5VL_native_init_interface() + +RETURNS + Non-negative on success/Negative on failure +DESCRIPTION + Initializes any interface-specific data or routines. (Just calls + H5VL_native_init currently). + +--------------------------------------------------------------------------*/ +static herr_t +H5VL_native_init_interface(void) +{ + FUNC_ENTER_NOAPI_NOINIT_NOERR + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5VL_native_init_interface() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_init + * + * Purpose: Initialize this vol plugin by registering the driver with the + * library. + * + * Return: Success: The ID for the native plugin. + * Failure: Negative. + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +H5VL_class_t * +H5VL_native_init(void) +{ + H5VL_class_t *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + /* Set return value */ + ret_value = &H5VL_native_g; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_init() */ + + +/*--------------------------------------------------------------------------- + * Function: H5VL_native_get_file + * + * Purpose: utility routine to get file object + * + * Returns: Non-negative on success or negative on failure + * + * Programmer: Mohamad Chaarawi + * June, 2012 + * + *--------------------------------------------------------------------------- + */ +static H5F_t * +H5VL_native_get_file(void *obj, H5I_type_t type) +{ + H5F_t *ret_value = NULL; /* File to flush */ + H5O_loc_t *oloc = NULL; /* Object location for ID */ + + FUNC_ENTER_NOAPI_NOINIT + + switch(type) { + case H5I_FILE: + ret_value = (H5F_t *) obj; + break; + case H5I_GROUP: + { + H5G_t *grp; + grp = (H5G_t *)obj; + oloc = H5G_oloc(grp); + break; + } + case H5I_DATATYPE: + { + H5T_t *dt; + dt = (H5T_t *)obj; + oloc = H5T_oloc(dt); + break; + } + case H5I_DATASET: + { + H5D_t *dset; + dset = (H5D_t *)obj; + oloc = H5D_oloc(dset); + break; + } + + case H5I_ATTR: + { + H5A_t *attr; + attr = (H5A_t *)obj; + oloc = H5A_oloc(attr); + break; + } + case H5I_UNINIT: + case H5I_BADID: + case H5I_DATASPACE: + case H5I_REFERENCE: + case H5I_VFL: + case H5I_VOL: + case H5I_GENPROP_CLS: + case H5I_GENPROP_LST: + case H5I_ERROR_CLASS: + case H5I_ERROR_MSG: + case H5I_ERROR_STACK: + case H5I_NTYPES: + default: + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + } /* end switch */ + + if(!ret_value) { + if(!oloc) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "object is not assocated with a file") + ret_value = oloc->file; + } /* end if */ + if(!ret_value) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "object is not associated with a file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +}/* H5VL_native_get_file */ + + +/*--------------------------------------------------------------------------- + * Function: H5VL_native_register + * + * Purpose: utility routine to register and ID with the native VOL plugin + * as an auxilary object + * + * Returns: Non-negative on success or negative on failure + * + * Programmer: Mohamad Chaarawi + * June, 2012 + * + *--------------------------------------------------------------------------- + */ +hid_t +H5VL_native_register(H5I_type_t type, void *obj, hbool_t app_ref) +{ + H5VL_t *vol_plugin; /* VOL plugin information */ + H5T_t *dt = NULL; + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(obj); + + /* Build the vol plugin struct */ + if(NULL == (vol_plugin = (H5VL_t *)H5MM_calloc(sizeof(H5VL_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + vol_plugin->cls = &H5VL_native_g; + vol_plugin->nrefs = 1; + + /* if this is a named datatype, we need to create the two-fold datatype + to be comaptible with the VOL */ + if(H5I_DATATYPE == type) { + /* Copy the dataset's datatype */ + if(NULL == (dt = H5T_copy((H5T_t *)obj, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy datatype") + + H5T_set_vol_object(dt, obj); + obj = (void *) dt; + } + + /* Get an atom for the object with the VOL information as the auxilary struct*/ + if((ret_value = H5I_register2(type, obj, (void *)vol_plugin, app_ref)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file handle") + +done: + if(ret_value < 0 && dt && H5T_close(dt) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype") + FUNC_LEAVE_NOAPI(ret_value) +} /* H5VL_native_register */ + + +/*------------------------------------------------------------------------- + * Function: H5Pset_fapl_native + * + * Purpose: Modify the file access property list to use the H5VL_NATIVE + * plugin defined in this source file. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fapl_native(hid_t fapl_id) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value; + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", fapl_id); + + if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") + + ret_value = H5P_set_vol(plist, &H5VL_native_g, NULL); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_fapl_native() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_attr_create + * + * Purpose: Creates an attribute on an object. + * + * Return: Success: attr id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_native_attr_create(void *obj, H5VL_loc_params_t loc_params, const char *attr_name, hid_t acpl_id, + hid_t UNUSED aapl_id, hid_t UNUSED req) +{ + H5G_loc_t loc; /* Object location */ + H5G_loc_t obj_loc; /* Location used to open group */ + hbool_t loc_found = FALSE; + H5P_genplist_t *plist; /* Property list pointer */ + hid_t type_id, space_id; + H5T_t *type, *dt; /* Datatype to use for attribute */ + H5S_t *space; /* Dataspace to use for attribute */ + H5A_t *attr = NULL; + void *ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(acpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID") + + /* get creation properties */ + if(H5P_get(plist, H5VL_ATTR_TYPE_ID, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for datatype id") + if(H5P_get(plist, H5VL_ATTR_SPACE_ID, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for space id") + + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + if(0 == (H5F_INTENT(loc.oloc->file) & H5F_ACC_RDWR)) + HGOTO_ERROR(H5E_ARGS, H5E_WRITEERROR, NULL, "no write intent on file") + + if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a type") + /* Get the actual datatype object if this is a named datatype */ + if(NULL == (type = (H5T_t *)H5T_get_named_type(dt))) + type = dt; + + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data space") + + if(loc_params.type == H5VL_OBJECT_BY_SELF) { /* H5Acreate */ + /* Go do the real work for attaching the attribute to the dataset */ + if(NULL == (attr = H5A_create(&loc, attr_name, type, space, acpl_id, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to create attribute") + } + else if(loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Acreate_by_name */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5O_loc_t obj_oloc; /* Opened object object location */ + + /* Set up opened group 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, loc_params.loc_data.loc_by_name.name, &obj_loc/*out*/, + loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "object not found") + loc_found = TRUE; + + /* Go do the real work for attaching the attribute to the dataset */ + if(NULL == (attr = H5A_create(&obj_loc, attr_name, type, space, acpl_id, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to create attribute") + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "unknown attribute create parameters") + } + ret_value = (void *)attr; + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, NULL, "can't free location") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_attr_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_attr_open + * + * Purpose: Opens a attr inside a native h5 file. + * + * Return: Success: attr id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_native_attr_open(void *obj, H5VL_loc_params_t loc_params, const char *attr_name, + hid_t UNUSED aapl_id, hid_t UNUSED req) +{ + H5G_loc_t loc; /* Object location */ + H5A_t *attr = NULL; /* Attribute opened */ + void *ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + /* check arguments */ + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + if(loc_params.type == H5VL_OBJECT_BY_SELF) { /* H5Aopen */ + /* Read in attribute from object header */ + if(NULL == (attr = H5O_attr_open_by_name(loc.oloc, attr_name, H5AC_ind_dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to load attribute info from object header for attribute: '%s'", attr_name) + /* Finish initializing attribute */ + if(H5A_open_common(&loc, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "unable to initialize attribute") + } + else if(loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Aopen_by_name */ + /* Open the attribute on the object header */ + if(NULL == (attr = H5A_open_by_name(&loc, loc_params.loc_data.loc_by_name.name, attr_name, + loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "can't open attribute") + } + else if(loc_params.type == H5VL_OBJECT_BY_IDX) { /* H5Aopen_by_idx */ + /* Open the attribute in the object header */ + if(NULL == (attr = H5A_open_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, + loc_params.loc_data.loc_by_idx.plist_id, H5AC_ind_dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to open attribute") + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "unknown attribute open parameters") + } + + ret_value = (void *)attr; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_attr_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_attr_read + * + * Purpose: Reads in data from attribute. + * + * Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_attr_read(void *attr, hid_t dtype_id, void *buf, hid_t UNUSED req) +{ + H5T_t *mem_type; /* Memory datatype */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if(NULL == (mem_type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + /* Go write the actual data to the attribute */ + if((ret_value = H5A_read((H5A_t*)attr, mem_type, buf, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_attr_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_attr_write + * + * Purpose: Writes out data to attribute. + * + * Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_attr_write(void *attr, hid_t dtype_id, const void *buf, hid_t UNUSED req) +{ + H5T_t *mem_type; /* Memory datatype */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if(NULL == (mem_type = (H5T_t *)H5I_object_verify(dtype_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + /* Go write the actual data to the attribute */ + if((ret_value = H5A_write((H5A_t*)attr, mem_type, buf, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_attr_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_attr_get + * + * Purpose: Gets certain information about an attribute + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_attr_get(void *obj, H5VL_attr_get_t get_type, hid_t UNUSED req, va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + switch (get_type) { + /* H5Aexists/exists_by_name */ + case H5VL_ATTR_EXISTS: + { + H5VL_loc_params_t loc_params = va_arg (arguments, H5VL_loc_params_t); + char *attr_name = va_arg (arguments, char *); + htri_t *ret = va_arg (arguments, htri_t *); + H5G_loc_t loc; + + /* check arguments */ + 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(loc_params.type == H5VL_OBJECT_BY_SELF) { /* H5Aexists */ + /* Check if the attribute exists */ + if((*ret = H5O_attr_exists(loc.oloc, attr_name, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + } + else if(loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Aopen_by_name */ + /* Check if the attribute exists */ + if((*ret = H5A_exists_by_name(loc, loc_params.loc_data.loc_by_name.name, + attr_name, + loc_params.loc_data.loc_by_name.plist_id)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to determine if attribute exists") + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown parameters") + } + break; + } + /* H5Aget_space */ + case H5VL_ATTR_GET_SPACE: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + H5A_t *attr = (H5A_t *)obj; + + if((*ret_id = H5A_get_space(attr)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get space ID of attribute") + break; + } + /* H5Aget_type */ + case H5VL_ATTR_GET_TYPE: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + H5A_t *attr = (H5A_t *)obj; + + if((*ret_id = H5A_get_type(attr)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of attribute") + break; + } + /* H5Aget_create_plist */ + case H5VL_ATTR_GET_ACPL: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + H5A_t *attr = (H5A_t *)obj; + + if((*ret_id = H5A_get_create_plist(attr)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for attr") + + break; + } + /* H5Aget_name */ + case H5VL_ATTR_GET_NAME: + { + H5VL_loc_params_t loc_params = va_arg (arguments, H5VL_loc_params_t); + size_t buf_size = va_arg (arguments, size_t); + char *buf = va_arg (arguments, char *); + ssize_t *ret_val = va_arg (arguments, ssize_t *); + H5A_t *attr = NULL; + + if(H5VL_OBJECT_BY_SELF == loc_params.type) { + attr = (H5A_t *)obj; + /* Call private function in turn */ + if(0 > (*ret_val = H5A_get_name(attr, buf_size, buf))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get attribute name") + } + else if(H5VL_OBJECT_BY_IDX == loc_params.type) { + H5G_loc_t loc; + + /* check arguments */ + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Open the attribute on the object header */ + if(NULL == (attr = H5A_open_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, + loc_params.loc_data.loc_by_idx.plist_id, + H5AC_ind_dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") + + /* Get the length of the name */ + *ret_val = (ssize_t)HDstrlen(attr->shared->name); + + /* Copy the name into the user's buffer, if given */ + if(buf) { + HDstrncpy(buf, attr->shared->name, MIN((size_t)(*ret_val + 1), buf_size)); + if((size_t)(*ret_val) >= buf_size) + buf[buf_size - 1]='\0'; + } /* end if */ + + /* Release resources */ + if(attr && H5A_close(attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") + } + else + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get name of attr") + + break; + } + /* H5Aget_info */ + case H5VL_ATTR_GET_INFO: + { + H5VL_loc_params_t loc_params = va_arg (arguments, H5VL_loc_params_t); + H5A_info_t *ainfo = va_arg (arguments, H5A_info_t *); + H5A_t *attr = NULL; + + if(H5VL_OBJECT_BY_SELF == loc_params.type) { + attr = (H5A_t *)obj; + if(H5A_get_info(attr, ainfo) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get attribute info") + } + else if(H5VL_OBJECT_BY_NAME == loc_params.type) { + char *attr_name = va_arg (arguments, char *); + H5G_loc_t loc; + + /* check arguments */ + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Open the attribute on the object header */ + if(NULL == (attr = H5A_open_by_name(&loc, loc_params.loc_data.loc_by_name.name, + attr_name, + loc_params.loc_data.loc_by_name.plist_id, + H5AC_ind_dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") + + /* Get the attribute information */ + if(H5A_get_info(attr, ainfo) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") + + /* Release resources */ + if(attr && H5A_close(attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") + } + else if(H5VL_OBJECT_BY_IDX == loc_params.type) { + H5G_loc_t loc; + + /* check arguments */ + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Open the attribute on the object header */ + if(NULL == (attr = H5A_open_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, + loc_params.loc_data.loc_by_idx.plist_id, + H5AC_ind_dxpl_id))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "can't open attribute") + + /* Get the attribute information */ + if(H5A_get_info(attr, ainfo) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "unable to get attribute info") + + /* Release resources */ + if(attr && H5A_close(attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't close attribute") + } + else + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get name of attr") + + break; + } + case H5VL_ATTR_GET_STORAGE_SIZE: + { + hsize_t *ret = va_arg (arguments, hsize_t *); + H5A_t *attr = (H5A_t *)obj; + + /* Set return value */ + *ret = attr->shared->data_size; + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from attr") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_attr_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_attr_remove + * + * Purpose: Deletes an attribute from a location + * + * Return: Success: 0 + * Failure: -1, attr not deleted. + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_attr_remove(void *obj, H5VL_loc_params_t loc_params, const char *attr_name, + hid_t UNUSED req) +{ + H5G_loc_t loc; /* Object location */ + H5G_loc_t obj_loc; /* Location used to open group */ + 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 'obj_name' found */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* check arguments */ + 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(H5VL_OBJECT_BY_SELF == loc_params.type) { /* H5Adelete */ + /* Delete the attribute from the location */ + if(H5O_attr_remove(loc.oloc, attr_name, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + } + else if(H5VL_OBJECT_BY_NAME == loc_params.type) { /* H5Adelete_by_name */ + /* Set up opened group 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, loc_params.loc_data.loc_by_name.name, &obj_loc/*out*/, + loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") + loc_found = TRUE; + + /* Delete the attribute from the location */ + if(H5O_attr_remove(obj_loc.oloc, attr_name, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + } + else if(H5VL_OBJECT_BY_IDX == loc_params.type) { /* H5Adelete_by_idx */ + /* Set up opened group 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, loc_params.loc_data.loc_by_idx.name, &obj_loc/*out*/, + loc_params.loc_data.loc_by_idx.plist_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "object not found") + loc_found = TRUE; + + /* Delete the attribute from the location */ + if(H5O_attr_remove_by_idx(obj_loc.oloc, 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, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown attribute remove parameters") + } + +done: + /* Release resources */ + if(loc_found && H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't free location") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_attr_remove() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_attr_close + * + * Purpose: Closes an attribute. + * + * Return: Success: 0 + * Failure: -1, attr not closed. + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_attr_close(void *attr, hid_t UNUSED req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if(H5A_close((H5A_t*)attr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't close attribute") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_attr_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_datatype_commit + * + * Purpose: Commits a datatype inside a native h5 file. + * + * Return: Success: datatype id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_native_datatype_commit(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t type_id, + hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t UNUSED req) +{ + H5G_loc_t loc; /* Location to commit datatype */ + H5T_t *dt; /* Datatype for ID */ + H5T_t *type; /* copy of the original type which will be committed */ + void *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* check arguments */ + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a datatype") + + /* + * Check arguments. We cannot commit an immutable type because H5Tclose() + * normally fails on such types (try H5Tclose(H5T_NATIVE_INT)) but closing + * a named type should always succeed. + */ + if(H5T_STATE_NAMED == dt->shared->state || H5T_STATE_OPEN == dt->shared->state) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "datatype is already committed") + if(H5T_STATE_IMMUTABLE == dt->shared->state) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "datatype is immutable") + + /* Check for a "sensible" datatype to store on disk */ + if(H5T_is_sensible(dt) <= 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "datatype is not sensible") + + /* Copy the datatype - the copied one will be the type that is + committed, and attached to original datatype above the VOL + layer*/ + if(NULL == (type = H5T_copy(dt, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to copy"); + + if(NULL != name) { /* H5Tcommit */ + /* Commit the type */ + if(H5T__commit_named(&loc, name, type, lcpl_id, tcpl_id, tapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to commit datatype") + } + else { /* H5Tcommit_anon */ + /* Commit the type */ + if(H5T__commit(loc.oloc->file, type, tcpl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to commit datatype") + + /* Release the datatype's object header */ + { + H5O_loc_t *oloc; /* Object location for datatype */ + + /* Get the new committed datatype's object location */ + if(NULL == (oloc = H5T_oloc(type))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, NULL, "unable to get object location of committed datatype") + + /* Decrement refcount on committed datatype's object header in memory */ + if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDEC, NULL, "unable to decrement refcount on newly created object") + } /* end if */ + } + ret_value = (void *)type; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_datatype_commit() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_datatype_open + * + * Purpose: Opens a named datatype inside a native h5 file. + * + * Return: Success: datatype id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_native_datatype_open(void *obj, H5VL_loc_params_t loc_params, const char *name, + hid_t tapl_id, hid_t UNUSED req) +{ + H5T_t *type = NULL; /* Datatype opened in file */ + H5G_loc_t loc; /* Group location of object to open */ + H5G_name_t path; /* Datatype group hier. path */ + H5O_loc_t oloc; /* Datatype object location */ + H5O_type_t obj_type; /* Type of object at location */ + H5G_loc_t type_loc; /* Group object for datatype */ + hbool_t obj_found = FALSE; /* Object at 'name' found */ + hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datatype */ + void *ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + /* Set up datatype location to fill in */ + type_loc.oloc = &oloc; + type_loc.path = &path; + H5G_loc_reset(&type_loc); + + /* + * Find the named datatype object header and read the datatype message + * from it. + */ + if(H5G_loc_find(&loc, name, &type_loc/*out*/, tapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL, "not found") + obj_found = TRUE; + + /* Check that the object found is the correct type */ + if(H5O_obj_type(&oloc, &obj_type, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, NULL, "can't get object type") + if(obj_type != H5O_TYPE_NAMED_DATATYPE) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, NULL, "not a named datatype") + + /* Open it */ + if(NULL == (type = H5T_open(&type_loc, dxpl_id))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open named datatype") + + ret_value = (void *)type; +done: + if(NULL == type) + if(obj_found && H5F_addr_defined(type_loc.oloc->addr)) + H5G_loc_free(&type_loc); + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_datatype_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_datatype_get_binary + * + * Purpose: gets size required to encode the datatype + * + * Return: Success: datatype id. + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static ssize_t +H5VL_native_datatype_get_binary(void *obj, unsigned char *buf, size_t size, hid_t UNUSED req) +{ + H5T_t *type = (H5T_t *)obj; + size_t nalloc = size; + ssize_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + if(H5T_encode(type, buf, &nalloc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't determine serialized length of datatype") + + ret_value = (ssize_t) nalloc; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_datatype_get_binary() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_datatype_close + * + * Purpose: Closes an datatype. + * + * Return: Success: 0 + * Failure: -1, datatype not closed. + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_datatype_close(void *dt, hid_t UNUSED req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if(H5T_close((H5T_t*)dt) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't close datatype") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_datatype_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_dataset_create + * + * Purpose: Creates a dataset inside a native h5 file. + * + * Return: Success: dataset id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_native_dataset_create(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t dcpl_id, + hid_t dapl_id, hid_t UNUSED req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5G_loc_t loc; /* Object location to insert dataset into */ + hid_t type_id, space_id, lcpl_id; + H5D_t *dset = NULL; /* New dataset's info */ + const H5S_t *space; /* Dataspace for dataset */ + void *ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID") + + /* get creation properties */ + if(H5P_get(plist, H5VL_DSET_TYPE_ID, &type_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for datatype id") + if(H5P_get(plist, H5VL_DSET_SPACE_ID, &space_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for space id") + if(H5P_get(plist, H5VL_DSET_LCPL_ID, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for lcpl id") + + /* Check arguments */ + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + if(H5I_DATATYPE != H5I_get_type(type_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a datatype ID") + if(NULL == (space = (const H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a dataspace ID") + + /* H5Dcreate_anon */ + if(NULL == name) { + /* build and open the new dataset */ + if(NULL == (dset = H5D__create(loc.oloc->file, type_id, space, dcpl_id, dapl_id, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to create dataset") + } + /* H5Dcreate2 */ + else { + /* Create the new dataset & get its ID */ + if(NULL == (dset = H5D__create_named(&loc, name, type_id, space, lcpl_id, + dcpl_id, dapl_id, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to create dataset") + } + ret_value = (void *)dset; + +done: + if(NULL == name) { + /* Release the dataset's object header, if it was created */ + if(dset) { + H5O_loc_t *oloc; /* Object location for dataset */ + + /* Get the new dataset's object location */ + if(NULL == (oloc = H5D_oloc(dset))) + HDONE_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "unable to get object location of dataset") + + /* Decrement refcount on dataset's object header in memory */ + if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, NULL, "unable to decrement refcount on newly created object") + } /* end if */ + } + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_dataset_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_dataset_open + * + * Purpose: Opens a dataset inside a native h5 file. + * + * Return: Success: dataset id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_native_dataset_open(void *obj, H5VL_loc_params_t loc_params, const char *name, + hid_t dapl_id, hid_t UNUSED req) +{ + H5D_t *dset = NULL; + H5G_loc_t loc; /* Object location of group */ + H5G_loc_t dset_loc; /* Object location of dataset */ + H5G_name_t path; /* Dataset group hier. path */ + H5O_loc_t oloc; /* Dataset object location */ + H5O_type_t obj_type; /* Type of object at location */ + hbool_t loc_found = FALSE; /* Location at 'name' found */ + hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datset */ + void *ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + /* Set up dataset location to fill in */ + dset_loc.oloc = &oloc; + dset_loc.path = &path; + H5G_loc_reset(&dset_loc); + + /* Find the dataset object */ + if(H5G_loc_find(&loc, name, &dset_loc, dapl_id, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, NULL, "not found") + loc_found = TRUE; + + /* Check that the object found is the correct type */ + if(H5O_obj_type(&oloc, &obj_type, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't get object type") + if(obj_type != H5O_TYPE_DATASET) + HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, NULL, "not a dataset") + + /* Open the dataset */ + if(NULL == (dset = H5D_open(&dset_loc, dapl_id, dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't open dataset") + + ret_value = (void *)dset; + +done: + if(NULL == dset && loc_found && H5G_loc_free(&dset_loc) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, NULL, "can't free location") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_dataset_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_dataset_read + * + * Purpose: Reads raw data from a dataset into a buffer. + * + * Return: Success: 0 + * Failure: -1, dataset not readd. + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_dataset_read(void *obj, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t plist_id, void *buf, hid_t UNUSED req) +{ + H5D_t *dset = (H5D_t *)obj; + const H5S_t *mem_space = NULL; + const H5S_t *file_space = NULL; + char fake_char; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* check arguments */ + if(NULL == dset->oloc.file) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + + if(H5S_ALL != mem_space_id) { + if(NULL == (mem_space = (const H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") + + /* Check for valid selection */ + if(H5S_SELECT_VALID(mem_space) != TRUE) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent") + } /* end if */ + if(H5S_ALL != file_space_id) { + if(NULL == (file_space = (const H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") + + /* Check for valid selection */ + if(H5S_SELECT_VALID(file_space) != TRUE) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent") + } /* end if */ + + if(!buf && (NULL == file_space || H5S_GET_SELECT_NPOINTS(file_space) != 0)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer") + + /* If the buffer is nil, and 0 element is selected, make a fake buffer. + * This is for some MPI package like ChaMPIon on NCSA's tungsten which + * doesn't support this feature. + */ + if(!buf) + buf = &fake_char; + + /* read raw data */ + if(H5D__read(dset, mem_type_id, mem_space, file_space, plist_id, buf/*out*/) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_dataset_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_dataset_write + * + * Purpose: Writes raw data from a buffer into a dataset. + * + * Return: Success: 0 + * Failure: -1, dataset not writed. + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_dataset_write(void *obj, hid_t mem_type_id, hid_t mem_space_id, + hid_t file_space_id, hid_t dxpl_id, const void *buf, hid_t UNUSED req) +{ + H5D_t *dset = (H5D_t *)obj; + const H5S_t *mem_space = NULL; + const H5S_t *file_space = NULL; + char fake_char; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* check arguments */ + if(NULL == dset->oloc.file) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset") + + if(H5S_ALL != mem_space_id) { + if(NULL == (mem_space = (const H5S_t *)H5I_object_verify(mem_space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") + + /* Check for valid selection */ + if(H5S_SELECT_VALID(mem_space) != TRUE) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent") + } /* end if */ + if(H5S_ALL != file_space_id) { + if(NULL == (file_space = (const H5S_t *)H5I_object_verify(file_space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space") + + /* Check for valid selection */ + if(H5S_SELECT_VALID(file_space) != TRUE) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent") + } /* end if */ + + if(!buf && (NULL == file_space || H5S_GET_SELECT_NPOINTS(file_space) != 0)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer") + + /* If the buffer is nil, and 0 element is selected, make a fake buffer. + * This is for some MPI package like ChaMPIon on NCSA's tungsten which + * doesn't support this feature. + */ + if(!buf) + buf = &fake_char; + + if(H5D__pre_write(dset, mem_type_id, mem_space, file_space, dxpl_id, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't prepare for writing data") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_dataset_write() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_dataset_set_extent + * + * Purpose: Set Extent of dataset + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_dataset_set_extent(void *obj, const hsize_t size[], hid_t UNUSED req) +{ + H5D_t *dset = (H5D_t *)obj; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Private function */ + if(H5D__set_extent(dset, size, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extend dataset") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_dataset_set_extent() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_dataset_get + * + * Purpose: Gets certain information about a dataset + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_dataset_get(void *obj, H5VL_dataset_get_t get_type, hid_t UNUSED req, va_list arguments) +{ + H5D_t *dset = (H5D_t *)obj; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + switch (get_type) { + /* H5Dget_space */ + case H5VL_DATASET_GET_SPACE: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + + if((*ret_id = H5D_get_space(dset)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get space ID of dataset") + + break; + } + /* H5Dget_space_statuc */ + case H5VL_DATASET_GET_SPACE_STATUS: + { + H5D_space_status_t *allocation = va_arg (arguments, H5D_space_status_t *); + + /* Read data space address and return */ + if(H5D__get_space_status(dset, allocation, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get space status") + + break; + } + /* H5Dget_type */ + case H5VL_DATASET_GET_TYPE: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + + if((*ret_id = H5D_get_type(dset)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of dataset") + + break; + } + /* H5Dget_create_plist */ + case H5VL_DATASET_GET_DCPL: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + + if((*ret_id = H5D_get_create_plist(dset)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for dataset") + + break; + } + /* H5Dget_access_plist */ + case H5VL_DATASET_GET_DAPL: + { + hid_t *ret_id = va_arg (arguments, hid_t *); + + if((*ret_id = H5D_get_access_plist(dset)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get access property list for dataset") + + break; + } + /* H5Dget_storage_size */ + case H5VL_DATASET_GET_STORAGE_SIZE: + { + hsize_t *ret = va_arg (arguments, hsize_t *); + + /* Set return value */ + if(H5D__get_storage_size(dset, H5AC_ind_dxpl_id, ret) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, 0, "can't get size of dataset's storage") + break; + } + /* H5Dget_offset */ + case H5VL_DATASET_GET_OFFSET: + { + haddr_t *ret = va_arg (arguments, haddr_t *); + + /* Set return value */ + *ret = H5D__get_offset(dset); + if(!H5F_addr_defined(*ret)) + *ret = HADDR_UNDEF; + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from dataset") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_dataset_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_dataset_close + * + * Purpose: Closes a dataset. + * + * Return: Success: 0 + * Failure: -1, dataset not closed. + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_dataset_close(void *dset, hid_t UNUSED req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if(H5D_close((H5D_t*)dset) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't close dataset") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_dataset_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_file_create + * + * Purpose: Creates a file as a native HDF5 file. + * + * Return: Success: the file id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_native_file_create(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, + hid_t UNUSED req) +{ + H5F_t *new_file = NULL; + void *ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + /* + * Adjust bit flags by turning on the creation bit and making sure that + * the EXCL or TRUNC bit is set. All newly-created files are opened for + * reading and writing. + */ + if(0==(flags & (H5F_ACC_EXCL|H5F_ACC_TRUNC))) + flags |= H5F_ACC_EXCL; /*default*/ + flags |= H5F_ACC_RDWR | H5F_ACC_CREAT; + + /* Create the file */ + if(NULL == (new_file = H5F_open(name, flags, fcpl_id, fapl_id, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create file") + + new_file->id_exists = TRUE; + ret_value = (void *)new_file; + +done: + if(NULL == ret_value && new_file) + if(H5F_close(new_file) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_file_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_file_open + * + * Purpose: Opens a file as a native HDF5 file. + * + * Return: Success: file id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_native_file_open(const char *name, unsigned flags, hid_t fapl_id, hid_t UNUSED req) +{ + H5F_t *new_file = NULL; + void *ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + /* Open the file */ + if(NULL == (new_file = H5F_open(name, flags, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") + + new_file->id_exists = TRUE; + ret_value = (void *)new_file; + +done: + if(NULL == ret_value && new_file && H5F_try_close(new_file) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "problems closing file") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_file_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_file_flush + * + * Purpose: Flushs a native HDF5 file. + * + * Return: Success: 0 + * Failure: -1, file not flushed. + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_file_flush(void *obj, H5VL_loc_params_t loc_params, H5F_scope_t scope, hid_t UNUSED req) +{ + H5F_t *f = NULL; /* File to flush */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if(NULL == (f = H5VL_native_get_file(obj, loc_params.obj_type))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + } + + /* Flush the file */ + /* + * Nothing to do if the file is read only. This determination is + * made at the shared open(2) flags level, implying that opening a + * file twice, once for read-only and once for read-write, and then + * calling H5Fflush() with the read-only handle, still causes data + * to be flushed. + */ + if(H5F_ACC_RDWR & H5F_INTENT(f)) { + /* Flush other files, depending on scope */ + if(H5F_SCOPE_GLOBAL == scope) { + /* Call the flush routine for mounted file hierarchies */ + if(H5F_flush_mounts(f, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush mounted file hierarchy") + } /* end if */ + else { + /* Call the flush routine, for this file */ + if(H5F_flush(f, H5AC_dxpl_id, FALSE) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file's cached information") + } /* end else */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_file_flush() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_file_get + * + * Purpose: Gets certain data about a file + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_file_get(void *obj, H5VL_file_get_t get_type, hid_t UNUSED req, va_list arguments) +{ + H5F_t *f = NULL; /* File struct */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + switch (get_type) { + /* H5Fget_access_plist */ + case H5VL_FILE_GET_FAPL: + { + H5P_genplist_t *new_plist; /* New property list */ + hid_t *plist_id = va_arg (arguments, hid_t *); + + f = (H5F_t *)obj; + /* Retrieve the file's access property list */ + if((*plist_id = H5F_get_access_plist(f, TRUE)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get file access property list") + + if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(*plist_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + /* Set the VOL class in the property list - we don't + have a VOL info for the native plugin */ + if(H5P_set(new_plist, H5F_ACS_VOL_NAME, &H5VL_native_g) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set file VOL plugin") + break; + } + /* H5Fget_create_plist */ + case H5VL_FILE_GET_FCPL: + { + H5P_genplist_t *plist; /* Property list */ + hid_t *plist_id = va_arg (arguments, hid_t *); + + f = (H5F_t *)obj; + if(NULL == (plist = (H5P_genplist_t *)H5I_object(f->shared->fcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + /* Create the property list object to return */ + if((*plist_id = H5P_copy_plist(plist, TRUE)) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to copy file creation properties") + + break; + } + /* H5Fget_obj_count */ + case H5VL_FILE_GET_OBJ_COUNT: + { + unsigned types = va_arg (arguments, unsigned); + ssize_t *ret = va_arg (arguments, ssize_t *); + size_t obj_count = 0; /* Number of opened objects */ + + f = (H5F_t *)obj; + /* Perform the query */ + if(H5F_get_obj_count(f, types, TRUE, &obj_count) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_count failed") + + /* Set the return value */ + *ret = (ssize_t)obj_count; + break; + } + /* H5Fget_obj_ids */ + case H5VL_FILE_GET_OBJ_IDS: + { + unsigned types = va_arg (arguments, unsigned); + size_t max_objs = va_arg (arguments, size_t); + hid_t *oid_list = va_arg (arguments, hid_t *); + ssize_t *ret = va_arg (arguments, ssize_t *); + size_t obj_count = 0; /* Number of opened objects */ + + f = (H5F_t *)obj; + /* Perform the query */ + if(H5F_get_obj_ids(f, types, max_objs, oid_list, TRUE, &obj_count) < 0) + HGOTO_ERROR(H5E_INTERNAL, H5E_BADITER, FAIL, "H5F_get_obj_ids failed") + + /* Set the return value */ + *ret = (ssize_t)obj_count; + break; + } + /* H5Fget_intent */ + case H5VL_FILE_GET_INTENT: + { + unsigned *ret = va_arg (arguments, unsigned *); + + f = (H5F_t *)obj; + /* HDF5 uses some flags internally that users don't know about. + * Simplify things for them so that they only get either H5F_ACC_RDWR + * or H5F_ACC_RDONLY. + */ + if(H5F_INTENT(f) & H5F_ACC_RDWR) + *ret = H5F_ACC_RDWR; + else + *ret = H5F_ACC_RDONLY; + break; + } + /* H5Fget_name */ + case H5VL_FILE_GET_NAME: + { + H5I_type_t type = va_arg (arguments, H5I_type_t); + size_t size = va_arg (arguments, size_t); + char *name = va_arg (arguments, char *); + ssize_t *ret = va_arg (arguments, ssize_t *); + size_t len; + + if(NULL == (f = H5VL_native_get_file(obj, type))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + } + + len = HDstrlen(H5F_OPEN_NAME(f)); + + if(name) { + HDstrncpy(name, H5F_OPEN_NAME(f), MIN(len + 1,size)); + if(len >= size) + name[size-1]='\0'; + } /* end if */ + + /* Set the return value for the API call */ + *ret = (ssize_t)len; + break; + } + /* H5I_get_file_id */ + case H5VL_OBJECT_GET_FILE: + { + H5I_type_t type = va_arg (arguments, H5I_type_t); + void **ret = va_arg (arguments, void **); + + if(NULL == (f = H5VL_native_get_file(obj, type))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + } + f->id_exists = TRUE; + *ret = (void*)f; + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information") + } /* end switch */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_file_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_file_misc + * + * Purpose: Perform an operation + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_file_misc(void *obj, H5VL_file_misc_t misc_type, hid_t UNUSED req, va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + switch (misc_type) { + /* H5Fmount */ + case H5VL_FILE_MOUNT: + { + H5I_type_t type = va_arg (arguments, H5I_type_t); + const char *name = va_arg (arguments, const char *); + H5F_t *child = va_arg (arguments, H5F_t *); + hid_t plist_id = va_arg (arguments, hid_t); + H5G_loc_t loc; + + if(H5G_loc_real(obj, type, &loc) < 0) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + } + /* Do the mount */ + if(H5F_mount(&loc, name, child, plist_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file") + + break; + } + /* H5Fmount */ + case H5VL_FILE_UNMOUNT: + { + H5I_type_t type = va_arg (arguments, H5I_type_t); + const char *name = va_arg (arguments, const char *); + H5G_loc_t loc; + + if(H5G_loc_real(obj, type, &loc) < 0) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + } + /* Unmount */ + if(H5F_unmount(&loc, name, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to unmount file") + + break; + } + /* H5Fis_accessible */ + case H5VL_FILE_IS_ACCESSIBLE: + { + hid_t UNUSED fapl_id = va_arg (arguments, hid_t); + const char *name = va_arg (arguments, const char *); + htri_t *ret = va_arg (arguments, htri_t *); + + /* Call private routine */ + if((*ret = H5F_is_hdf5(name)) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to open file") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't recognize this operation type") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_file_misc() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_file_optional + * + * Purpose: Perform a plugin specific operation on a native file + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * May, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_file_optional(void *obj, H5VL_file_optional_t optional_type, hid_t UNUSED req, va_list arguments) +{ + H5F_t *f = NULL; /* File */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + switch (optional_type) { + /* H5Fget_filesize */ + case H5VL_FILE_GET_SIZE: + { + haddr_t eof; /* End of file address */ + hsize_t *ret = va_arg (arguments, hsize_t *); + + f = (H5F_t *)obj; + /* Go get the actual file size */ + if(HADDR_UNDEF == (eof = H5FDget_eof(f->shared->lf))) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to get file size") + *ret = (hsize_t)eof; + break; + } + /* H5Fget_file_image */ + case H5VL_FILE_GET_FILE_IMAGE: + { + void *buf_ptr = va_arg (arguments, void *); + ssize_t *ret = va_arg (arguments, ssize_t *); + size_t buf_len = va_arg (arguments, size_t ); + + f = (H5F_t *)obj; + /* Do the actual work */ + if((*ret = H5F_get_file_image(f, buf_ptr, buf_len)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "get file image failed") + break; + } + /* H5Fget_freespace */ + case H5VL_FILE_GET_FREE_SPACE: + { + hsize_t tot_space; /* Amount of free space in the file */ + hssize_t *ret = va_arg (arguments, hssize_t *); + + f = (H5F_t *)obj; + /* Go get the actual amount of free space in the file */ + if(H5MF_get_freespace(f, H5AC_ind_dxpl_id, &tot_space, NULL) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") + *ret = (hssize_t)tot_space; + break; + } + case H5VL_FILE_GET_FREE_SECTIONS: + { + H5F_sect_info_t *sect_info = va_arg (arguments, H5F_sect_info_t *); + ssize_t *ret = va_arg (arguments, ssize_t *); + H5F_mem_t type = va_arg (arguments, H5F_mem_t); + size_t nsects = va_arg (arguments, size_t); + + f = (H5F_t *)obj; + /* Go get the free-space section information in the file */ + if((*ret = H5MF_get_free_sections(f, H5AC_ind_dxpl_id, + type, nsects, sect_info)) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "unable to check free space for file") + break; + } + /* H5Fget_info2 */ + case H5VL_FILE_GET_INFO: + { + H5I_type_t type = va_arg (arguments, H5I_type_t); + H5F_info2_t *finfo = va_arg (arguments, H5F_info2_t *); + + if(NULL == (f = H5VL_native_get_file(obj, type))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + } + + /* For file IDs, get the file object directly */ + /* (This prevents the H5G_loc() call from returning the file pointer for + * the top file in a mount hierarchy) + */ + HDassert(f->shared); + + /* Reset file info struct */ + HDmemset(finfo, 0, sizeof(*finfo)); + + /* Get the size of the superblock and any superblock extensions */ + if(H5F_super_size(f, H5AC_ind_dxpl_id, &finfo->super.super_size, + &finfo->super.super_ext_size) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve superblock sizes") + + /* Get the size of any persistent free space */ + if(H5MF_get_freespace(f, H5AC_ind_dxpl_id, &finfo->free.tot_space, + &finfo->free.meta_size) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve free space information") + + /* Check for SOHM info */ + if(H5F_addr_defined(f->shared->sohm_addr)) + if(H5SM_ih_size(f, H5AC_ind_dxpl_id, &finfo->sohm.hdr_size, &finfo->sohm.msgs_info) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "Unable to retrieve SOHM index & heap storage info") + + /* Set version # fields */ + finfo->super.version = f->shared->sblock->super_vers; + finfo->sohm.version = f->shared->sohm_vers; + finfo->free.version = HDF5_FREESPACE_VERSION; + break; + } + /* H5Fget_mdc_config */ + case H5VL_FILE_GET_MDC_CONF: + { + H5AC_cache_config_t *config_ptr = va_arg (arguments, H5AC_cache_config_t *); + + f = (H5F_t *)obj; + /* Go get the resize configuration */ + if(H5AC_get_cache_auto_resize_config(f->shared->cache, config_ptr) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_auto_resize_config() failed.") + break; + } + /* H5Fget_mdc_hit_rate */ + case H5VL_FILE_GET_MDC_HR: + { + double *hit_rate_ptr = va_arg (arguments, double *); + + f = (H5F_t *)obj; + /* Go get the current hit rate */ + if(H5AC_get_cache_hit_rate(f->shared->cache, hit_rate_ptr) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_hit_rate() failed.") + break; + } + /* H5Fget_mdc_size */ + case H5VL_FILE_GET_MDC_SIZE: + { + size_t *max_size_ptr = va_arg (arguments, size_t *); + size_t *min_clean_size_ptr = va_arg (arguments, size_t *); + size_t *cur_size_ptr = va_arg (arguments, size_t *); + int *cur_num_entries_ptr = va_arg (arguments, int *); + int32_t cur_num_entries; + + f = (H5F_t *)obj; + /* Go get the size data */ + if(H5AC_get_cache_size(f->shared->cache, max_size_ptr, min_clean_size_ptr, + cur_size_ptr, &cur_num_entries) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5AC_get_cache_size() failed.") + + if(cur_num_entries_ptr != NULL) + *cur_num_entries_ptr = (int)cur_num_entries; + break; + } + /* H5Fget_vfd_handle */ + case H5VL_FILE_GET_VFD_HANDLE: + { + void **file_handle = va_arg (arguments, void **); + hid_t fapl = va_arg (arguments, hid_t); + + f = (H5F_t *)obj; + /* Retrieve the VFD handle for the file */ + if(H5F_get_vfd_handle(f, fapl, file_handle) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't retrieve VFD handle") + break; + } + /* H5Fclear_elink_file_cache */ + case H5VL_FILE_CLEAR_ELINK_CACHE: + { + f = (H5F_t *)obj; + /* Release the EFC */ + if(f->shared->efc) + if(H5F_efc_release(f->shared->efc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") + break; + } + /* H5Freopen */ + case H5VL_FILE_REOPEN: + { + void **ret = va_arg (arguments, void **); + H5F_t *new_file = NULL; + + f = (H5F_t *)obj; + if(NULL == (new_file = H5F_reopen(f))) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to reopen file") + new_file->id_exists = TRUE; + + *ret = (void *)new_file; + break; + } + /* H5Freset_mdc_hit_rate_stats */ + case H5VL_FILE_RESET_MDC_HIT_RATE: + { + f = (H5F_t *)obj; + /* Reset the hit rate statistic */ + if(H5AC_reset_cache_hit_rate_stats(f->shared->cache) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't reset cache hit rate") + break; + } + case H5VL_FILE_SET_MDC_CONFIG: + { + H5AC_cache_config_t *config_ptr = va_arg (arguments, H5AC_cache_config_t *); + + f = (H5F_t *)obj; + /* set the resize configuration */ + if(H5AC_set_cache_auto_resize_config(f->shared->cache, config_ptr) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "H5AC_set_cache_auto_resize_config() failed.") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't recognize this operation type") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_file_optional() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_file_close + * + * Purpose: Closes a file. + * + * Return: Success: 0 + * Failure: -1, file not closed. + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_file_close(void *file, hid_t UNUSED req) +{ + int nref; + H5F_t *f = (H5F_t *)file; + hid_t file_id = FAIL; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Flush file if this is the last reference to this id and we have write + * intent, unless it will be flushed by the "shared" file being closed. + * This is only necessary to replicate previous behaviour, and could be + * disabled by an option/property to improve performance. */ + if((f->shared->nrefs > 1) && (H5F_INTENT(f) & H5F_ACC_RDWR)) { + /* get the file ID corresponding to the H5F_t struct */ + if((file_id = H5I_get_id(f, H5I_FILE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "invalid atom") + /* get the number of references outstanding for this file ID */ + if((nref = H5I_get_ref(file_id, FALSE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get ID ref count") + if(nref == 1) + if(H5F_flush(f, H5AC_dxpl_id, FALSE) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + } /* end if */ + /* close the file */ + if(H5F_close(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "can't close file") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_file_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_group_create + * + * Purpose: Creates a group inside a native h5 file. + * + * Return: Success: group id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_native_group_create(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t gcpl_id, + hid_t gapl_id, hid_t UNUSED req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + H5G_loc_t loc; /* Location to create group */ + H5G_t *grp = NULL; /* New group created */ + hid_t lcpl_id; + void *ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + /* Get the plist structure */ + if(NULL == (plist = (H5P_genplist_t *)H5I_object(gcpl_id))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "can't find object for ID") + + /* get creation properties */ + if(H5P_get(plist, H5VL_GRP_LCPL_ID, &lcpl_id) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get property value for lcpl id") + + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + /* if name is NULL then this is from H5Gcreate_anon */ + if(name == NULL) { + H5G_obj_create_t gcrt_info; /* Information for group creation */ + /* Set up group creation info */ + gcrt_info.gcpl_id = gcpl_id; + gcrt_info.cache_type = H5G_NOTHING_CACHED; + HDmemset(&gcrt_info.cache, 0, sizeof(gcrt_info.cache)); + + /* Create the new group & get its ID */ + if(NULL == (grp = H5G__create(loc.oloc->file, &gcrt_info, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group") + } + /* otherwise it's from H5Gcreate */ + else { + /* Create the new group & get its ID */ + if(NULL == (grp = H5G__create_named(&loc, name, lcpl_id, gcpl_id, gapl_id, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group") + } + ret_value = (void *)grp; + +done: + if(name == NULL) { + /* Release the group's object header, if it was created */ + if(grp) { + H5O_loc_t *oloc; /* Object location for group */ + + /* Get the new group's object location */ + if(NULL == (oloc = H5G_oloc(grp))) + HDONE_ERROR(H5E_SYM, H5E_CANTGET, NULL, "unable to get object location of group") + + /* Decrement refcount on group's object header in memory */ + if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDEC, NULL, "unable to decrement refcount on newly created object") + } /* end if */ + } + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_group_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_group_open + * + * Purpose: Opens a group inside a native h5 file. + * + * Return: Success: group id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * January, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_native_group_open(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t gapl_id, hid_t UNUSED req) +{ + H5G_loc_t loc; /* Location to open group */ + H5G_t *grp = NULL; /* New group opend */ + void *ret_value; + + FUNC_ENTER_NOAPI_NOINIT + + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + /* Open the group */ + if((grp = H5G__open_name(&loc, name, gapl_id, H5AC_dxpl_id)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open group") + + ret_value = (void *)grp; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_group_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_group_get + * + * Purpose: Gets certain data about a group + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * February, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_group_get(void *obj, H5VL_group_get_t get_type, hid_t UNUSED req, va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + switch (get_type) { + /* H5Gget_create_plist */ + case H5VL_GROUP_GET_GCPL: + { + hid_t *new_gcpl_id = va_arg (arguments, hid_t *); + H5G_t *grp = (H5G_t *)obj; + + if((*new_gcpl_id = H5G_get_create_plist(grp)) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get creation property list for group") + break; + } + /* H5Gget_info */ + case H5VL_GROUP_GET_INFO: + { + H5VL_loc_params_t loc_params = va_arg (arguments, H5VL_loc_params_t); + H5G_info_t *grp_info = va_arg (arguments, H5G_info_t *); + 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(loc_params.type == H5VL_OBJECT_BY_SELF) { /* H5Gget_info */ + /* Retrieve the group's information */ + if(H5G__obj_info(loc.oloc, grp_info, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") + } + else if(loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Gget_info_by_name */ + H5G_loc_t grp_loc; /* Location used to open group */ + H5G_name_t grp_path; /* Opened object group hier. path */ + H5O_loc_t grp_oloc; /* Opened object object location */ + + /* Set up opened group location to fill in */ + grp_loc.oloc = &grp_oloc; + grp_loc.path = &grp_path; + H5G_loc_reset(&grp_loc); + + /* Find the group object */ + if(H5G_loc_find(&loc, loc_params.loc_data.loc_by_name.name, &grp_loc/*out*/, + loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") + + /* Retrieve the group's information */ + if(H5G__obj_info(grp_loc.oloc, grp_info/*out*/, H5AC_ind_dxpl_id) < 0) { + H5G_loc_free(&grp_loc); + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") + } + + /* Release the object location */ + if(H5G_loc_free(&grp_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + } + else if(loc_params.type == H5VL_OBJECT_BY_IDX) { /* H5Gget_info_by_idx */ + H5G_loc_t grp_loc; /* Location used to open group */ + H5G_name_t grp_path; /* Opened object group hier. path */ + H5O_loc_t grp_oloc; /* Opened object object location */ + + /* Set up opened group location to fill in */ + grp_loc.oloc = &grp_oloc; + grp_loc.path = &grp_path; + H5G_loc_reset(&grp_loc); + + /* Find the object's location, according to the order in the index */ + if(H5G_loc_find_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, &grp_loc/*out*/, + loc_params.loc_data.loc_by_idx.plist_id, + H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") + + /* Retrieve the group's information */ + if(H5G__obj_info(grp_loc.oloc, grp_info/*out*/, H5AC_ind_dxpl_id) < 0) { + H5G_loc_free(&grp_loc); + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info") + } + + /* Release the object location */ + if(H5G_loc_free(&grp_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get info parameters") + } + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from group") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_group_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_group_close + * + * Purpose: Closes a group. + * + * Return: Success: 0 + * Failure: -1, group not closed. + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_group_close(void *grp, hid_t UNUSED req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if(H5G_close((H5G_t *)grp) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close group") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_group_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_link_create + * + * Purpose: Creates an hard/soft/UD/external links. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_link_create(H5VL_link_create_type_t create_type, void *obj, H5VL_loc_params_t loc_params, + hid_t lcpl_id, hid_t lapl_id, hid_t UNUSED req) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* 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"); + + switch (create_type) { + case H5VL_LINK_CREATE_HARD: + { + H5G_loc_t cur_loc; + H5G_loc_t link_loc; + void *cur_obj; + H5VL_loc_params_t cur_params; + + if(H5P_get(plist, H5VL_LINK_TARGET, &cur_obj) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for current location id") + if(H5P_get(plist, H5VL_LINK_TARGET_LOC_PARAMS, &cur_params) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for current name") + + 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((ret_value = 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, lapl_id, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + } + else { /* H5Olink */ + /* Link to the object */ + if(H5L_link(&link_loc, loc_params.loc_data.loc_by_name.name, &cur_loc, lcpl_id, + lapl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + } + break; + } + case H5VL_LINK_CREATE_SOFT: + { + char *target_name; + 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(H5P_get(plist, H5VL_LINK_TARGET_NAME, &target_name) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for targe name") + + /* Create the link */ + if((ret_value = H5L_create_soft(target_name, &link_loc, loc_params.loc_data.loc_by_name.name, + lcpl_id, lapl_id, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "unable to create link") + break; + } + case H5VL_LINK_CREATE_UD: + { + H5G_loc_t link_loc; /* Group location for new link */ + H5L_type_t link_type; + void *udata; + size_t udata_size; + + 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(H5P_get(plist, H5VL_LINK_TYPE, &link_type) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for link type") + if(H5P_get(plist, H5VL_LINK_UDATA, &udata) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for udata") + if(H5P_get(plist, H5VL_LINK_UDATA_SIZE, &udata_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for udata size") + + /* Create link */ + if(H5L_create_ud(&link_loc, loc_params.loc_data.loc_by_name.name, udata, udata_size, + link_type, lcpl_id, lapl_id, H5AC_dxpl_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") + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_link_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_link_move + * + * Purpose: Renames an object within an HDF5 file and moves it to a new + * group. The original name SRC is unlinked from the group graph + * and then inserted with the new name DST (which can specify a + * new path for the object) as an atomic operation. The names + * are interpreted relative to SRC_LOC_ID and + * DST_LOC_ID, which are either file IDs or group ID. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_link_move(void *src_obj, H5VL_loc_params_t loc_params1, + void *dst_obj, H5VL_loc_params_t loc_params2, + hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id, hid_t 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_NOAPI_NOINIT + + 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/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, + copy_flag, lcpl_id, lapl_id, H5AC_dxpl_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_iterate + * + * Purpose: Iterates through links in a group + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * May, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t H5VL_native_link_iterate(void *obj, H5VL_loc_params_t loc_params, hbool_t recursive, + H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx_p, + H5L_iterate_t op, void *op_data, hid_t UNUSED req) +{ + H5G_loc_t loc; + herr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + 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(!recursive) { + H5G_link_iterate_t lnk_op; /* Link operator */ + hsize_t last_lnk; /* Index of last object looked at */ + hsize_t idx; /* Internal location to hold index */ + + /* Set up iteration beginning/end info */ + idx = (idx_p == NULL ? 0 : *idx_p); + last_lnk = 0; + + /* Build link operator info */ + lnk_op.op_type = H5G_LINK_OP_NEW; + lnk_op.op_func.op_new = op; + + /* Iterate over the links */ + if(loc_params.type == H5VL_OBJECT_BY_SELF) { + if((ret_value = H5G_iterate(&loc, ".", idx_type, order, idx, &last_lnk, &lnk_op, op_data, + H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link iteration failed") + } + else if(loc_params.type == H5VL_OBJECT_BY_NAME) { + if((ret_value = H5G_iterate(&loc, loc_params.loc_data.loc_by_name.name, + idx_type, order, idx, &last_lnk, &lnk_op, op_data, + loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link iteration failed") + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown link iterate params") + } + + /* Set the index we stopped at */ + if(idx_p) + *idx_p = last_lnk; + } + else { + /* Call internal group visitation routine */ + if(loc_params.type == H5VL_OBJECT_BY_SELF) { + if((ret_value = H5G_visit(&loc, ".", idx_type, order, op, op_data, + H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link visitation failed") + } + else if(loc_params.type == H5VL_OBJECT_BY_NAME) { + if((ret_value = H5G_visit(&loc, loc_params.loc_data.loc_by_name.name, + idx_type, order, op, op_data, + loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "link visitation failed") + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown link visit params") + } + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_link_iterate() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_link_get + * + * Purpose: Gets certain data about a link + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_link_get(void *obj, H5VL_loc_params_t loc_params, H5VL_link_get_t get_type, + hid_t UNUSED req, va_list arguments) +{ + H5G_loc_t loc; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + 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 (get_type) { + /* H5Lexists */ + case H5VL_LINK_EXISTS: + { + htri_t *ret = va_arg (arguments, htri_t *); + + /* Check for the existence of the link */ + if((*ret = H5L_exists(&loc, loc_params.loc_data.loc_by_name.name, + loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") + break; + } + /* H5Lget_info/H5Lget_info_by_idx */ + case H5VL_LINK_GET_INFO: + { + H5L_info_t *linfo = va_arg (arguments, H5L_info_t *); + + /* Get the link information */ + if(loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Lget_info */ + if(H5L_get_info(&loc, loc_params.loc_data.loc_by_name.name, linfo, + loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") + } + else if(loc_params.type == H5VL_OBJECT_BY_IDX) { /* H5Lget_info_by_idx */ + H5L_trav_gibi_t udata; /* User data for callback */ + + /* Set up user data for retrieving information */ + udata.idx_type = loc_params.loc_data.loc_by_idx.idx_type; + udata.order = loc_params.loc_data.loc_by_idx.order; + udata.n = loc_params.loc_data.loc_by_idx.n; + udata.dxpl_id = H5AC_ind_dxpl_id; + udata.linfo = linfo; + if(H5L_get_info_by_idx(&loc, loc_params.loc_data.loc_by_idx.name, &udata, + loc_params.loc_data.loc_by_idx.plist_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") + } + else + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") + break; + } + /* H5Lget_name_by_idx */ + case H5VL_LINK_GET_NAME: + { + char *name = va_arg (arguments, char *); + size_t size = va_arg (arguments, size_t); + ssize_t *ret = va_arg (arguments, ssize_t *); + H5L_trav_gnbi_t udata; /* User data for callback */ + + /* Set up user data for callback */ + udata.idx_type = loc_params.loc_data.loc_by_idx.idx_type; + udata.order = loc_params.loc_data.loc_by_idx.order; + udata.n = loc_params.loc_data.loc_by_idx.n; + udata.dxpl_id = H5AC_ind_dxpl_id; + udata.name = name; + udata.size = size; + udata.name_len = -1; + + /* Get the link name */ + if(H5L_get_name_by_idx(&loc, loc_params.loc_data.loc_by_idx.name, &udata, + loc_params.loc_data.loc_by_idx.plist_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") + + *ret = udata.name_len; + break; + } + /* H5Lget_val/H5Lget_val_by_idx */ + case H5VL_LINK_GET_VAL: + { + void *buf = va_arg (arguments, void *); + size_t size = va_arg (arguments, size_t); + + /* Get the link information */ + if(loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Lget_val */ + if(H5L_get_val(&loc, loc_params.loc_data.loc_by_name.name, buf, size, + loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value") + } + else if(loc_params.type == H5VL_OBJECT_BY_IDX) { /* H5Lget_val_by_idx */ + H5L_trav_gvbi_t udata; /* User data for callback */ + + /* Set up user data for retrieving information */ + udata.idx_type = loc_params.loc_data.loc_by_idx.idx_type; + udata.order = loc_params.loc_data.loc_by_idx.order; + udata.n = loc_params.loc_data.loc_by_idx.n; + udata.dxpl_id = H5AC_ind_dxpl_id; + udata.buf = buf; + udata.size = size; + + if(H5L_get_val_by_idx(&loc, loc_params.loc_data.loc_by_idx.name, &udata, + loc_params.loc_data.loc_by_idx.plist_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link val") + } + else + HGOTO_ERROR(H5E_SYM, 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") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_link_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_link_remove + * + * Purpose: Removes the specified NAME from the group graph and + * decrements the link count for the object to which NAME + * points. If the link count reaches zero then all file-space + * associated with the object will be reclaimed (but if the + * object is open, then the reclamation of the file space is + * delayed until all handles to the object are closed). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_link_remove(void *obj, H5VL_loc_params_t loc_params, hid_t UNUSED req) +{ + H5G_loc_t loc; /* Object location */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + 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, + loc_params.loc_data.loc_by_name.plist_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") + } + else if(loc_params.type == H5VL_OBJECT_BY_IDX) { /* H5Ldelete_by_idx */ + H5L_trav_rmbi_t udata; /* User data for callback */ + + /* Set up user data for unlink operation */ + udata.idx_type = loc_params.loc_data.loc_by_idx.idx_type; + udata.order = loc_params.loc_data.loc_by_idx.order; + udata.n = loc_params.loc_data.loc_by_idx.n; + udata.dxpl_id = H5AC_dxpl_id; + + if(H5L_delete_by_idx(&loc, loc_params.loc_data.loc_by_idx.name, &udata, + loc_params.loc_data.loc_by_idx.plist_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") + } + else + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "unable to delete link") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_link_remove() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_object_open + * + * Purpose: Opens a object inside a native h5 file. + * + * Return: Success: object id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static void * +H5VL_native_object_open(void *obj, H5VL_loc_params_t loc_params, H5I_type_t *opened_type, + hid_t UNUSED req) +{ + H5G_loc_t loc; + H5G_loc_t obj_loc; /* Location used to open group */ + 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 */ + hid_t temp_id = FAIL; + void *ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file or file object") + + switch (loc_params.type) { + case H5VL_OBJECT_BY_NAME: + { + /* Open the object */ + if((temp_id = H5O_open_name(&loc, loc_params.loc_data.loc_by_name.name, + loc_params.loc_data.loc_by_name.plist_id, TRUE)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open object") + break; + } + case H5VL_OBJECT_BY_IDX: + { + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object's location, according to the order in the index */ + if(H5G_loc_find_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, + &obj_loc/*out*/, loc_params.loc_data.loc_by_idx.plist_id, + H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "group not found") + loc_found = TRUE; + + /* Open the object */ + if((temp_id = H5O_open_by_loc(&obj_loc, loc_params.loc_data.loc_by_name.plist_id, + H5AC_dxpl_id, TRUE)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open object") + break; + } + case H5VL_OBJECT_BY_ADDR: + { + if(!H5F_addr_defined(loc_params.loc_data.loc_by_addr.addr)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "no address supplied") + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + obj_loc.oloc->addr = loc_params.loc_data.loc_by_addr.addr; + obj_loc.oloc->file = loc.oloc->file; + H5G_name_reset(obj_loc.path); /* objects opened through this routine don't have a path name */ + + /* Open the object */ + if((temp_id = H5O_open_by_loc(&obj_loc, H5P_LINK_ACCESS_DEFAULT, + H5AC_dxpl_id, TRUE)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open object") + break; + } + case H5VL_OBJECT_BY_REF: + { + H5F_t *file = NULL; + + /* Get the file pointer from the entry */ + file = loc.oloc->file; + + /* Create reference */ + if((temp_id = H5R_dereference(file, loc_params.loc_data.loc_by_ref.plist_id, + H5AC_dxpl_id, + loc_params.loc_data.loc_by_ref.ref_type, + loc_params.loc_data.loc_by_ref._ref, + TRUE)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, NULL, "unable to dereference object") + break; + } + case H5VL_OBJECT_BY_SELF: + default: + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, NULL, "unknown open parameters") + } + + *opened_type = H5I_get_type (temp_id); + if(NULL == (ret_value = H5I_remove(temp_id))) + HDONE_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open object") + +done: + /* Release the object location if we failed after copying it */ + if(temp_id < 0 && loc_found) + if(H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, NULL, "can't free location") + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_object_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_object_copy + * + * Purpose: Copys a object inside a native h5 file. + * + * Return: Success: object id. + * Failure: NULL + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_object_copy(void *src_obj, H5VL_loc_params_t loc_params1, const char *src_name, + void *dst_obj, H5VL_loc_params_t loc_params2, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id, hid_t UNUSED req) +{ + H5G_loc_t src_loc; /* Source object group location */ + H5G_loc_t dst_loc; /* Destination group location */ + hid_t ret_value = FAIL; + + FUNC_ENTER_NOAPI_NOINIT + + /* get location for objects */ + if(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(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") + + /* Open the object */ + if((ret_value = H5O_copy(&src_loc, src_name, &dst_loc, dst_name, ocpypl_id, lcpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "unable to copy object") +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_object_copy() */ + + + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_object_visit + * + * Purpose: Iterates through all objects linked to an object + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * May, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t H5VL_native_object_visit(void *obj, H5VL_loc_params_t loc_params, H5_index_t idx_type, + H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t UNUSED req) +{ + H5G_loc_t loc; + herr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if(H5G_loc_real(obj, loc_params.obj_type, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object") + + /* Call internal object visitation routine */ + if(loc_params.type == H5VL_OBJECT_BY_SELF) { /* H5Ovisit */ + if((ret_value = H5O_visit(&loc, ".", idx_type, order, op, op_data, + H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "object visitation failed") + } + else if(loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Ovisit_by_name */ + if((ret_value = H5O_visit(&loc, loc_params.loc_data.loc_by_name.name, idx_type, order, + op, op_data, loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "object visitation failed") + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown object visit params") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_object_visit() */ + +#if 0 + +/*------------------------------------------------------------------------- + * Function: H5VL_native_object_lookup + * + * Purpose: Lookup the object location in the file + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_object_lookup(hid_t loc_id, H5VL_loc_type_t lookup_type, void **loc_token, + hid_t UNUSED req, va_list arguments) +{ + H5G_loc_t loc; + H5G_loc_t *obj_loc; + H5G_loc_t **location = (H5G_loc_t **)loc_token; + haddr_t obj_addr; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + *location = (H5G_loc_t *) H5MM_malloc (sizeof (H5G_loc_t)); + + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + + obj_loc = *location; + obj_loc->oloc = (H5O_loc_t *) H5MM_malloc (sizeof (H5O_loc_t)); + obj_loc->path = (H5G_name_t *) H5MM_malloc (sizeof (H5G_name_t)); + H5G_loc_reset(obj_loc); + + switch (lookup_type) { + case H5VL_OBJECT_BY_SELF: + obj_loc->oloc->addr = loc.oloc->addr; + obj_loc->oloc->file = loc.oloc->file; + obj_loc->oloc->holding_file = loc.oloc->holding_file; + obj_loc->path = loc.path; + break; + case H5VL_OBJECT_BY_NAME: + { + char *name = va_arg (arguments, char *); + hid_t lapl_id = va_arg (arguments, hid_t); + + HDassert(name && *name); + + /* Find the object's location */ + if((ret_value = H5G_loc_find(&loc, name, obj_loc, lapl_id, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + break; + } + case H5VL_OBJECT_BY_IDX: + { + char *group_name = va_arg (arguments, char *); + H5_index_t idx_type = va_arg (arguments, H5_index_t); + H5_iter_order_t order = va_arg (arguments, H5_iter_order_t); + hsize_t n = va_arg (arguments, hsize_t); + hid_t lapl_id = va_arg (arguments, hid_t); + + /* Find the object's location, according to the order in the index */ + if((ret_value = H5G_loc_find_by_idx(&loc, group_name, idx_type, order, n, + obj_loc/*out*/, lapl_id, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") + break; + } + case H5VL_OBJECT_BY_ADDR: + { + obj_addr = va_arg (arguments, haddr_t); + obj_loc->oloc->addr = obj_addr; + obj_loc->oloc->file = loc.oloc->file; + obj_loc->oloc->holding_file = loc.oloc->holding_file; + break; + } + case H5VL_OBJECT_BY_REF: + { + H5R_type_t ref_type = va_arg (arguments, H5R_type_t); + void *_ref = va_arg (arguments, void *); + H5F_t *file = NULL; /* File object */ + + /* Get the file pointer from the entry */ + file = loc.oloc->file; + + HDassert(_ref); + HDassert(ref_type > H5R_BADTYPE || ref_type < H5R_MAXTYPE); + HDassert(file); + + switch(ref_type) { + case H5R_OBJECT: + obj_loc->oloc->addr = *(const hobj_ref_t *)_ref; /* Only object references currently supported */ + obj_loc->oloc->file = loc.oloc->file; + obj_loc->oloc->holding_file = loc.oloc->holding_file; + break; + + case H5R_DATASET_REGION: + { + H5HG_t hobjid; /* Heap object ID */ + uint8_t *buf; /* Buffer to store serialized selection in */ + const uint8_t *p; /* Pointer to OID to store */ + + /* Get the heap ID for the dataset region */ + p = (const uint8_t *)_ref; + H5F_addr_decode(file, &p, &(hobjid.addr)); + INT32DECODE(p, hobjid.idx); + + /* Get the dataset region from the heap (allocate inside routine) */ + if(NULL == (buf = (uint8_t *)H5HG_read(file, H5AC_dxpl_id, + &hobjid, NULL, NULL))) + HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") + + /* Get the object oid for the dataset */ + p = buf; + //H5F_addr_decode(file, &p, &(obj_addr)); + H5F_addr_decode(file, &p, &(obj_loc->oloc->addr)); + obj_loc->oloc->file = file; + /* Free the buffer allocated in H5HG_read() */ + H5MM_xfree(buf); + } /* end case */ + break; + + case H5R_BADTYPE: + case H5R_MAXTYPE: + default: + HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)") + } /* end switch */ + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't lookup this object") + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_object_lookup() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_object_free_loc + * + * Purpose: Free the location token + * + * Return: Success: non negative + * Failure: negative + * + * Programmer: Mohamad Chaarawi + * May, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_object_free_loc(void *location, hid_t UNUSED req) +{ + H5G_loc_t *obj_loc = (H5G_loc_t *)location; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + if(H5G_loc_free(obj_loc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + + if(NULL != obj_loc->oloc) { + H5MM_free(obj_loc->oloc); + } + if(NULL != obj_loc->path) { + H5MM_free(obj_loc->path); + } + if(NULL != obj_loc) { + H5MM_free(obj_loc); + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_object_free_loc() */ +#endif + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_object_misc + * + * Purpose: Perform a plugin specific operation for an objectibute + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_object_misc(void *obj, H5VL_loc_params_t loc_params, H5VL_object_misc_t misc_type, + hid_t UNUSED req, va_list arguments) +{ + H5G_loc_t loc; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + 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 (misc_type) { + /* H5Arename/rename_by_name */ + case H5VL_ATTR_RENAME: + { + const char *old_name = va_arg (arguments, const char *); + const char *new_name = va_arg (arguments, const char *); + + if(loc_params.type == H5VL_OBJECT_BY_SELF) { /* H5Arename */ + /* Call attribute rename routine */ + if(H5O_attr_rename(loc.oloc, H5AC_dxpl_id, old_name, new_name) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") + } + else if(loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Arename_by_name */ + /* Call attribute rename routine */ + if(H5A_rename_by_name(loc, loc_params.loc_data.loc_by_name.name, old_name, + new_name, loc_params.loc_data.loc_by_name.plist_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown attribute rename parameters") + } + break; + } + /* H5Oincr_refcount / H5Odecr_refcount */ + case H5VL_OBJECT_CHANGE_REF_COUNT: + { + int update_ref = va_arg (arguments, int); + H5O_loc_t *oloc = loc.oloc; + + /* Get the object's oloc so we can adjust its link count + if((oloc = H5O_get_loc(loc_id)) == NULL) + HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID") + */ + + if(H5O_link(oloc, update_ref, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "modifying object link count failed") + + break; + } + /* H5Oset_comment */ + case H5VL_OBJECT_SET_COMMENT: + { + const char *comment = va_arg (arguments, char *); + + if(loc_params.type == H5VL_OBJECT_BY_SELF) { /* H5Oset_comment */ + /* (Re)set the object's comment */ + if(H5G_loc_set_comment(&loc, ".", comment, H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + } + else if(loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Oset_comment_by_name */ + /* (Re)set the object's comment */ + if(H5G_loc_set_comment(&loc, loc_params.loc_data.loc_by_name.name, comment, + loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown set_coment parameters") + } + break; + } + case H5VL_REF_CREATE: + { + void *ref = va_arg (arguments, void *); + const char *name = va_arg (arguments, char *); + H5R_type_t ref_type = va_arg (arguments, H5R_type_t); + hid_t space_id = va_arg (arguments, hid_t); + H5S_t *space = NULL; /* Pointer to dataspace containing region */ + + if(space_id != (-1) && (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") + + /* Create reference */ + if((ret_value = H5R_create(ref, &loc, name, ref_type, space, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to create reference") + + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't recognize this operation type") + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_object_misc() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_object_optional + * + * Purpose: Perform a plugin specific operation for an objectibute + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * April, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_object_optional(void UNUSED *obj, H5VL_loc_params_t UNUSED loc_params, + H5VL_object_optional_t optional_type, hid_t UNUSED req, va_list UNUSED arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + switch (optional_type) { + case H5VL_OPTIONAL: + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't perform this operation on object"); + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_object_optional() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_object_get + * + * Purpose: Gets certain data about a file + * + * Return: Success: 0 + * Failure: -1 + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_object_get(void *obj, H5VL_loc_params_t loc_params, H5VL_object_get_t get_type, + hid_t UNUSED req, va_list arguments) +{ + herr_t ret_value = SUCCEED; /* Return value */ + H5G_loc_t loc; /* Location of group */ + + FUNC_ENTER_NOAPI_NOINIT + + 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 (get_type) { + /* H5Oexists_by_name */ + case H5VL_OBJECT_EXISTS: + { + htri_t *ret = va_arg (arguments, htri_t *); + + if(loc_params.type == H5VL_OBJECT_BY_NAME) { + /* Check if the object exists */ + if((*ret = H5G_loc_exists(&loc, loc_params.loc_data.loc_by_name.name, + loc_params.loc_data.loc_by_name.plist_id, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine if '%s' exists", + loc_params.loc_data.loc_by_name.name) + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown object exists parameters") + } + break; + } + /* H5Oget_info / H5Oget_info_by_name / H5Oget_info_by_idx */ + case H5VL_OBJECT_GET_INFO: + { + H5O_info_t *obj_info = va_arg (arguments, H5O_info_t *); + + if(loc_params.type == H5VL_OBJECT_BY_SELF) { /* H5Oget_info */ + /* Retrieve the object's information */ + if(H5G_loc_info(&loc, ".", TRUE, obj_info, H5P_LINK_ACCESS_DEFAULT, + H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + } + else if(loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Oget_info_by_name */ + /* Retrieve the object's information */ + if(H5G_loc_info(&loc, loc_params.loc_data.loc_by_name.name, TRUE, obj_info, + loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + } + else if(loc_params.type == H5VL_OBJECT_BY_IDX) { /* H5Oget_info_by_idx */ + H5G_loc_t obj_loc; /* Location used to open group */ + H5G_name_t obj_path; /* Opened object group hier. path */ + H5O_loc_t obj_oloc; /* Opened object object location */ + + /* Set up opened group location to fill in */ + obj_loc.oloc = &obj_oloc; + obj_loc.path = &obj_path; + H5G_loc_reset(&obj_loc); + + /* Find the object's location, according to the order in the index */ + if(H5G_loc_find_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, &obj_loc/*out*/, + loc_params.loc_data.loc_by_idx.plist_id, + H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") + + /* Retrieve the object's information */ + if(H5O_get_info(obj_loc.oloc, H5AC_ind_dxpl_id, TRUE, obj_info) < 0) { + H5G_loc_free(&obj_loc); + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve object info") + } + + /* Release the object location */ + if(H5G_loc_free(&obj_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown get info parameters") + } + break; + } + /* H5Oget_comment / H5Oget_comment_by_name */ + case H5VL_OBJECT_GET_COMMENT: + { + char *comment = va_arg (arguments, char *); + size_t bufsize = va_arg (arguments, size_t); + ssize_t *ret = va_arg (arguments, ssize_t *); + + /* Retrieve the object's comment */ + if(loc_params.type == H5VL_OBJECT_BY_SELF) { /* H5Oget_comment */ + if((*ret = H5G_loc_get_comment(&loc, ".", comment/*out*/, bufsize, + H5P_LINK_ACCESS_DEFAULT, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + } + else if(loc_params.type == H5VL_OBJECT_BY_NAME) { /* H5Oget_comment_by_name */ + if((*ret = H5G_loc_get_comment(&loc, loc_params.loc_data.loc_by_name.name, comment/*out*/, bufsize, + loc_params.loc_data.loc_by_name.plist_id, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + } + else { + HGOTO_ERROR(H5E_VOL, H5E_UNSUPPORTED, FAIL, "unknown set_coment parameters") + } + break; + } + /* H5Rget_region */ + case H5VL_REF_GET_REGION: + { + hid_t *ret = va_arg (arguments, hid_t *); + H5R_type_t UNUSED ref_type = va_arg (arguments, H5R_type_t); + void *ref = va_arg (arguments, void *); + H5S_t *space = NULL; /* Dataspace object */ + + /* Get the dataspace with the correct region selected */ + if((space = H5R_get_region(loc.oloc->file, H5AC_ind_dxpl_id, ref)) == NULL) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create dataspace") + + /* Atomize */ + if((*ret = H5I_register (H5I_DATASPACE, space, TRUE)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom") + + break; + } + /* H5Rget_obj_type2 */ + case H5VL_REF_GET_TYPE: + { + H5O_type_t *obj_type = va_arg (arguments, H5O_type_t *); + H5R_type_t ref_type = va_arg (arguments, H5R_type_t); + void *ref = va_arg (arguments, void *); + + /* Get the object information */ + if(H5R_get_obj_type(loc.oloc->file, H5AC_ind_dxpl_id, ref_type, ref, obj_type) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to determine object type") + break; + } + /* H5Rget_name */ + case H5VL_REF_GET_NAME: + { + ssize_t *ret = va_arg (arguments, ssize_t *); + char *name = va_arg (arguments, char *); + size_t size = va_arg (arguments, size_t); + H5R_type_t ref_type = va_arg (arguments, H5R_type_t); + void *ref = va_arg (arguments, void *); + + /* Get name */ + if((*ret = H5R_get_name(&loc, H5P_DEFAULT, H5AC_dxpl_id, ref_type, ref, name, size)) < 0) + HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to determine object path") + break; + } + default: + HGOTO_ERROR(H5E_VOL, H5E_CANTGET, FAIL, "can't get this type of information from object") + } +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_object_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5VL_native_object_close + * + * Purpose: Closes a object. + * + * Return: Success: 0 + * Failure: -1, object not closed. + * + * Programmer: Mohamad Chaarawi + * March, 2012 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5VL_native_object_close(void UNUSED *obj, H5VL_loc_params_t loc_params, hid_t UNUSED req) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Get the type of the object and close it in the correct way */ + switch(loc_params.obj_type) { + case H5I_GROUP: + case H5I_DATATYPE: + case H5I_DATASET: + break; + case H5I_UNINIT: + case H5I_BADID: + case H5I_FILE: + case H5I_DATASPACE: + case H5I_ATTR: + case H5I_REFERENCE: + case H5I_VFL: + case H5I_VOL: + case H5I_GENPROP_CLS: + case H5I_GENPROP_LST: + case H5I_ERROR_CLASS: + case H5I_ERROR_MSG: + case H5I_ERROR_STACK: + case H5I_NTYPES: + default: + HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FAIL, "not a valid file object ID (dataset, group, or datatype)") + break; + } /* end switch */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5VL_native_object_close() */ diff --git a/src/H5VLnative.h b/src/H5VLnative.h new file mode 100644 index 0000000..37eb93b --- /dev/null +++ b/src/H5VLnative.h @@ -0,0 +1,39 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov> + * January, 2012 + * + * Purpose: The public header file for the Native VOL plugin. + */ +#ifndef H5VLnative_H +#define H5VLnative_H + +#define H5VL_NATIVE (H5VL_native_init()) + +#ifdef __cplusplus +extern "C" { +#endif + +H5_DLL H5VL_class_t *H5VL_native_init(void); +H5_DLL herr_t H5Pset_fapl_native(hid_t fapl_id); + //H5_DLL herr_t H5VL_native_register_aux(hid_t obj_id); +H5_DLL hid_t H5VL_native_register(H5I_type_t type, void *obj, hbool_t app_ref); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/H5VLpkg.h b/src/H5VLpkg.h new file mode 100644 index 0000000..3739689 --- /dev/null +++ b/src/H5VLpkg.h @@ -0,0 +1,65 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.org> + * January, 2012 + * + * Purpose: This file contains declarations which are visible only within + * the H5VL package. Source files outside the H5VL package should + * include H5VLprivate.h instead. + */ +#ifndef H5VL_PACKAGE +#error "Do not include this file outside the H5VL package!" +#endif + +#ifndef _H5VLpkg_H +#define _H5VLpkg_H + +/* Get package's private header */ +#include "H5VLprivate.h" /* File drivers */ + +/* Other private headers needed by this file */ +#include "H5FLprivate.h" /* Free lists */ + +/**************************/ +/* Package Private Macros */ +/**************************/ + + +/****************************/ +/* Package Private Typedefs */ +/****************************/ + + +/*****************************/ +/* Package Private Variables */ +/*****************************/ + + +/******************************/ +/* Package Private Prototypes */ +/******************************/ +H5_DLL herr_t H5VL_init(void); + +/* +H5_DLL haddr_t H5VL_alloc_real(H5VL_t *file, hid_t dxpl_id, H5VL_mem_t type, + hsize_t size, haddr_t *align_addr, hsize_t *align_size); +H5_DLL herr_t H5VL_free_real(H5VL_t *file, hid_t dxpl_id, H5VL_mem_t type, + haddr_t addr, hsize_t size); +*/ + +#endif /* _H5VLpkg_H */ + diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h new file mode 100644 index 0000000..ed3719f --- /dev/null +++ b/src/H5VLprivate.h @@ -0,0 +1,120 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.gov> + * January, 2011 + */ +#ifndef _H5VLprivate_H +#define _H5VLprivate_H + +#include "H5VLpublic.h" + +/**************************/ +/* Library Private Macros */ +/**************************/ + +/****************************/ +/* Library Private Typedefs */ +/****************************/ +#define H5_REQUEST_NULL -1 + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/******************************/ +/* Library Private Prototypes */ +/******************************/ + +/* Forward declarations for prototype arguments */ +struct H5P_genplist_t; +struct H5F_t; + +H5_DLL int H5VL_term_interface(void); +H5_DLL H5VL_class_t *H5VL_get_class(hid_t id); +H5_DLL hid_t H5VL_register(const void *cls, size_t size, hbool_t app_ref); +H5_DLL hid_t H5VL_object_register(void *obj, H5I_type_t obj_type, H5VL_t *vol_plugin, hbool_t app_ref); +H5_DLL ssize_t H5VL_get_plugin_name(hid_t id, char *name/*out*/, size_t size); +H5_DLL void *H5VL_get_object(hid_t id); +H5_DLL herr_t H5VL_close(H5VL_class_t *vol_plugin); + +H5_DLL void *H5VL_attr_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *attr_name, hid_t acpl_id, hid_t aapl_id, hid_t req); +H5_DLL void *H5VL_attr_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t aapl_id, hid_t req); +H5_DLL herr_t H5VL_attr_read(void *attr, H5VL_t *vol_plugin, hid_t dtype_id, void *buf, hid_t req); +H5_DLL herr_t H5VL_attr_write(void *attr, H5VL_t *vol_plugin, hid_t dtype_id, const void *buf, hid_t req); +H5_DLL herr_t H5VL_attr_get(void *attr, H5VL_t *vol_plugin, H5VL_attr_get_t get_type, hid_t req, ...); +H5_DLL herr_t H5VL_attr_remove(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *attr_name, hid_t req); +H5_DLL herr_t H5VL_attr_close(void *attr, H5VL_t *vol_plugin, hid_t req); + +H5_DLL void *H5VL_dataset_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t dcpl_id, hid_t dapl_id, hid_t req); +H5_DLL void *H5VL_dataset_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t dapl_id, hid_t req); +H5_DLL herr_t H5VL_dataset_read(void *dset, H5VL_t *vol_plugin, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, void *buf, hid_t req); +H5_DLL herr_t H5VL_dataset_write(void *dset, H5VL_t *vol_plugin, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf, hid_t req); +H5_DLL herr_t H5VL_dataset_set_extent(void *dset, H5VL_t *vol_plugin, const hsize_t size[], hid_t req); +H5_DLL herr_t H5VL_dataset_get(void *dset, H5VL_t *vol_plugin, H5VL_dataset_get_t get_type, hid_t req, ...); +H5_DLL herr_t H5VL_dataset_close(void *dset, H5VL_t *vol_plugin, hid_t req); + +H5_DLL void *H5VL_datatype_commit(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t req); +H5_DLL void *H5VL_datatype_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t tapl_id, hid_t req); +H5_DLL ssize_t H5VL_datatype_get_binary(void *obj, H5VL_t *vol_plugin, unsigned char *buf, size_t size, hid_t req); +H5_DLL herr_t H5VL_datatype_close(void *dt, H5VL_t *vol_plugin, hid_t req); + +H5_DLL void *H5VL_file_create(H5VL_t **vol_plugin, const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t req); +H5_DLL void *H5VL_file_open(H5VL_t **vol_plugin, const char *name, unsigned flags, hid_t fapl_id, hid_t req); +H5_DLL herr_t H5VL_file_flush(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5F_scope_t scope, hid_t req); +H5_DLL herr_t H5VL_file_misc(void *file, H5VL_t *vol_plugin, H5VL_file_misc_t misc_type, hid_t req, ...); +H5_DLL herr_t H5VL_file_optional(void *file, H5VL_t *vol_plugin, H5VL_file_optional_t optional_type, hid_t req, ...); +H5_DLL herr_t H5VL_file_get(void *file, H5VL_t *vol_plugin, H5VL_file_get_t get_type, hid_t req, ...); +H5_DLL herr_t H5VL_file_close(void *file, H5VL_t *vol_plugin, hid_t req); + +H5_DLL void *H5VL_group_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t gcpl_id, hid_t gapl_id, hid_t req); +H5_DLL void *H5VL_group_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t gapl_id, hid_t req); +H5_DLL herr_t H5VL_group_close(void *grp, H5VL_t *vol_plugin, hid_t req); +H5_DLL herr_t H5VL_group_get(void *obj, H5VL_t *vol_plugin, H5VL_group_get_t get_type, hid_t req, ...); + +H5_DLL herr_t H5VL_link_create(H5VL_link_create_type_t create_type, void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, hid_t lcpl_id, hid_t lapl_id, hid_t req); +H5_DLL herr_t H5VL_link_move(void *src_obj, H5VL_loc_params_t loc_params1, + void *dst_obj, H5VL_loc_params_t loc_params2, H5VL_t *vol_plugin, + hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id, hid_t req); +H5_DLL herr_t H5VL_link_iterate(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, + hbool_t recursive, H5_index_t idx_type, H5_iter_order_t order, + hsize_t *idx, H5L_iterate_t op, void *op_data, hid_t req); +H5_DLL herr_t H5VL_link_get(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_link_get_t get_type, hid_t req, ...); +H5_DLL herr_t H5VL_link_remove(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, hid_t req); + +H5_DLL void *H5VL_object_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5I_type_t *opened_type, hid_t req); +H5_DLL herr_t H5VL_object_copy(void *src_obj, H5VL_loc_params_t loc_params1, H5VL_t *vol_plugin1, const char *src_name, + void *dst_obj, H5VL_loc_params_t loc_params2, H5VL_t *vol_plugin2, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id, hid_t req); +H5_DLL herr_t H5VL_object_visit(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t req); +H5_DLL herr_t H5VL_object_get(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_object_get_t get_type, hid_t req, ...); +H5_DLL herr_t H5VL_object_misc(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_object_misc_t misc_type, hid_t req, ...); +H5_DLL herr_t H5VL_object_optional(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_object_misc_t optional_type, hid_t req, ...); +//H5_DLL herr_t H5VL_object_lookup(hid_t uid, H5VL_loc_type_t lookup_type, void **location, hid_t req, ...); +//H5_DLL herr_t H5VL_object_free_loc(hid_t loc_id, void *location, hid_t req); +H5_DLL herr_t H5VL_object_close(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, hid_t req); + +H5_DLL herr_t H5VL_fapl_open(struct H5P_genplist_t *plist, H5VL_class_t *vol_cls, const void *vol_info); +H5_DLL herr_t H5VL_fapl_copy(H5VL_class_t *vol_cls, const void *vol_info, void **copied_info); +H5_DLL herr_t H5VL_fapl_close(H5VL_class_t *vol_cls, void *vol_info); + +H5_DLL herr_t H5F_close_file(void *file, H5VL_t *vol_plugin); +H5_DLL herr_t H5A_close_attr(void *attr, H5VL_t *vol_plugin); +H5_DLL herr_t H5D_close_dataset(void *dset, H5VL_t *vol_plugin); +H5_DLL herr_t H5G_close_group(void *grp, H5VL_t *vol_plugin); +H5_DLL herr_t H5T_close_datatype(void *dt, H5VL_t *vol_plugin); + +#endif /* _H5VLprivate_H */ diff --git a/src/H5VLpublic.h b/src/H5VLpublic.h new file mode 100644 index 0000000..670a5b7 --- /dev/null +++ b/src/H5VLpublic.h @@ -0,0 +1,398 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * 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 files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: Mohamad Chaarawi <chaarawi@hdfgroup.org> + * January 23, 2012 + */ +#ifndef _H5VLpublic_H +#define _H5VLpublic_H + +#include "stdarg.h" + +#include "H5public.h" +#include "H5Fpublic.h" +#include "H5Lpublic.h" +#include "H5Opublic.h" +#include "H5Rpublic.h" + +/* Dataset creation property names */ +#define H5VL_DSET_TYPE_ID "dataset_type_id" +#define H5VL_DSET_SPACE_ID "dataset_space_id" +#define H5VL_DSET_LCPL_ID "dataset_lcpl_id" + +/* Attribute creation property names */ +#define H5VL_ATTR_TYPE_ID "attr_type_id" +#define H5VL_ATTR_SPACE_ID "attr_space_id" +#define H5VL_ATTR_LOC_PARAMS "attr_location" + +/* Link creation property names */ +#define H5VL_LINK_TARGET "target_location_object" +#define H5VL_LINK_TARGET_LOC_PARAMS "target_params" +#define H5VL_LINK_TARGET_NAME "target_name" +#define H5VL_LINK_TYPE "link type" +#define H5VL_LINK_UDATA "udata" +#define H5VL_LINK_UDATA_SIZE "udata size" + +/* Group creation property names */ +#define H5VL_GRP_LCPL_ID "group_lcpl_id" + +/* types for all attr get API routines */ +typedef enum H5VL_attr_get_t { + H5VL_ATTR_EXISTS = 0, /* H5Aexists */ + H5VL_ATTR_GET_SPACE = 1, /* dataspace */ + H5VL_ATTR_GET_TYPE = 2, /* datatype */ + H5VL_ATTR_GET_ACPL = 3, /* creation property list */ + H5VL_ATTR_GET_NAME = 4, /* access property list */ + H5VL_ATTR_GET_STORAGE_SIZE = 5, /* storage size */ + H5VL_ATTR_GET_INFO = 6 /* offset */ +} H5VL_attr_get_t; + +/* types for all dataset get API routines */ +typedef enum H5VL_dataset_get_t { + H5VL_DATASET_GET_SPACE = 0, /* dataspace */ + H5VL_DATASET_GET_SPACE_STATUS = 1, /* space status */ + H5VL_DATASET_GET_TYPE = 2, /* datatype */ + H5VL_DATASET_GET_DCPL = 3, /* creation property list */ + H5VL_DATASET_GET_DAPL = 4, /* access property list */ + H5VL_DATASET_GET_STORAGE_SIZE = 5, /* storage size */ + H5VL_DATASET_GET_OFFSET = 6 /* offset */ +} H5VL_dataset_get_t; + +/* types for all file get API routines */ +typedef enum H5VL_file_get_t { + H5VL_FILE_GET_FAPL = 0, /*file access property list */ + H5VL_FILE_GET_FCPL = 1, /*file creation property list */ + H5VL_FILE_GET_INTENT = 2, /*file intent */ + H5VL_FILE_GET_NAME = 3, /*file name */ + H5VL_FILE_GET_OBJ_COUNT = 4, /*object count in file */ + H5VL_FILE_GET_OBJ_IDS = 5, /*object ids in file */ + H5VL_OBJECT_GET_FILE = 6 +} H5VL_file_get_t; + +/* types for all file misc operations */ +typedef enum H5VL_file_misc_t { + H5VL_FILE_MOUNT = 0, + H5VL_FILE_UNMOUNT = 1, + H5VL_FILE_IS_ACCESSIBLE = 2 +} H5VL_file_misc_t; + +/* types for all file optional operations */ +typedef enum H5VL_file_optional_t { + H5VL_FILE_CLEAR_ELINK_CACHE = 0, + H5VL_FILE_GET_FILE_IMAGE = 1, /*file image */ + H5VL_FILE_GET_FREE_SECTIONS = 2, /*file free selections */ + H5VL_FILE_GET_FREE_SPACE = 3, /*file freespace */ + H5VL_FILE_GET_INFO = 4, /*file info */ + H5VL_FILE_GET_MDC_CONF = 5, /*file metadata cache configuration */ + H5VL_FILE_GET_MDC_HR = 6, /*file metadata cache hit rate */ + H5VL_FILE_GET_MDC_SIZE = 7, /*file metadata cache size */ + H5VL_FILE_GET_SIZE = 8, /*file size */ + H5VL_FILE_GET_VFD_HANDLE = 9, /*file VFD handle */ + H5VL_FILE_REOPEN = 10, + H5VL_FILE_RESET_MDC_HIT_RATE = 11, + H5VL_FILE_SET_MDC_CONFIG = 12 +} H5VL_file_optional_t; + +/* types for all group get API routines */ +typedef enum H5VL_group_get_t { + H5VL_GROUP_GET_GCPL = 0, /*group creation property list */ + H5VL_GROUP_GET_INFO = 1 /*group info */ +} H5VL_group_get_t; + +/* link create types for VOL */ +typedef enum H5VL_link_create_type_t { + H5VL_LINK_CREATE_HARD = 0, + H5VL_LINK_CREATE_SOFT = 1, + H5VL_LINK_CREATE_UD = 2 +} H5VL_link_create_type_t; + +/* types for all link get API routines */ +typedef enum H5VL_link_get_t { + H5VL_LINK_EXISTS = 0, /*link existence */ + H5VL_LINK_GET_INFO = 1, /*link info */ + H5VL_LINK_GET_NAME = 2, /*link name */ + H5VL_LINK_GET_VAL = 3 /*link value */ +} H5VL_link_get_t; + +/* types for all object general operations */ +typedef enum H5VL_object_misc_t { + H5VL_ATTR_RENAME = 0, /* H5Arename */ + H5VL_OBJECT_CHANGE_REF_COUNT = 1, /* H5Oincr/decr_refcount */ + H5VL_OBJECT_SET_COMMENT = 2, /* H5Oset_comment(_by_name) */ + H5VL_REF_CREATE = 3 /* H5Rcreate */ +} H5VL_object_misc_t; + +/* types for all object general operations */ +typedef enum H5VL_object_optional_t { + H5VL_OPTIONAL = 0 +} H5VL_object_optional_t; + +/* types for all object get API routines */ +typedef enum H5VL_object_get_t { + H5VL_OBJECT_EXISTS = 0, /* H5Oexists_by_name) */ + H5VL_OBJECT_GET_INFO = 1, /*object info */ + H5VL_OBJECT_GET_COMMENT = 2, /*object comment */ + H5VL_REF_GET_REGION = 3, /*dataspace of region */ + H5VL_REF_GET_TYPE = 4, /*type of object */ + H5VL_REF_GET_NAME = 5 /*object name */ +} H5VL_object_get_t; + +/* types for different ways that objects are located in an HDF5 container */ +typedef enum H5VL_loc_type_t { + H5VL_OBJECT_BY_SELF = 0, + H5VL_OBJECT_BY_NAME = 1, + H5VL_OBJECT_BY_IDX = 2, + H5VL_OBJECT_BY_ADDR = 3, + H5VL_OBJECT_BY_REF = 4 +} H5VL_loc_type_t; + +struct H5VL_loc_by_name { + const char *name; + hid_t plist_id; +}; + +struct H5VL_loc_by_idx { + const char *name; + H5_index_t idx_type; + H5_iter_order_t order; + hsize_t n; + hid_t plist_id; +}; + +struct H5VL_loc_by_addr { + haddr_t addr; +}; + +struct H5VL_loc_by_ref { + H5R_type_t ref_type; + const void *_ref; + hid_t plist_id; +}; + +/* Structure to hold parameters for object locations. + either: BY_ID, BY_NAME, BY_IDX, BY_ADDR, BY_REF */ +typedef struct H5VL_loc_params_t { + H5I_type_t obj_type; + H5VL_loc_type_t type; + union{ + struct H5VL_loc_by_name loc_by_name; + struct H5VL_loc_by_idx loc_by_idx; + struct H5VL_loc_by_addr loc_by_addr; + struct H5VL_loc_by_ref loc_by_ref; + }loc_data; +} H5VL_loc_params_t; + +#define H5VL_VOL_DEFAULT 0 /* Default VOL plugin value */ + +/* Forward declaration */ +typedef struct H5VL_t H5VL_t; + +/* H5A routines */ +typedef struct H5VL_attr_class_t { + void *(*create)(void *obj, H5VL_loc_params_t loc_params, const char *attr_name, hid_t acpl_id, hid_t aapl_id, hid_t req); + void *(*open) (void *obj, H5VL_loc_params_t loc_params, const char *attr_name, hid_t aapl_id, hid_t req); + herr_t (*read) (void *attr, hid_t mem_type_id, void *buf, hid_t req); + herr_t (*write) (void *attr, hid_t mem_type_id, const void *buf, hid_t req); + herr_t (*get) (void *attr, H5VL_attr_get_t get_type, hid_t req, va_list arguments); + herr_t (*remove)(void *obj, H5VL_loc_params_t loc_params, const char *attr_name, hid_t req); + herr_t (*close) (void *attr, hid_t req); +} H5VL_attr_class_t; + +/* H5T routines*/ +typedef struct H5VL_datatype_class_t { + void *(*commit)(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t type_id, + hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t req); + void *(*open) (void *obj, H5VL_loc_params_t loc_params, const char * name, hid_t tapl_id, hid_t req); + ssize_t (*get_binary) (void *obj, unsigned char *buf, size_t size, hid_t req); + herr_t (*close) (void *dt, hid_t req); +} H5VL_datatype_class_t; + +/* H5D routines */ +typedef struct H5VL_dataset_class_t { + void *(*create)(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t dcpl_id, hid_t dapl_id, hid_t req); + void *(*open) (void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t dapl_id, hid_t req); + herr_t (*read) (void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, + hid_t xfer_plist_id, void * buf, hid_t req); + herr_t (*write) (void *dset, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, + hid_t xfer_plist_id, const void * buf, hid_t req); + herr_t (*set_extent) (void *dset, const hsize_t size[], hid_t req); + herr_t (*get) (void *dset, H5VL_dataset_get_t get_type, hid_t req, va_list arguments); + herr_t (*close) (void *dset, hid_t req); +} H5VL_dataset_class_t; + +/* H5F routines */ +typedef struct H5VL_file_class_t { + void *(*create)(const char *name, unsigned flags, hid_t fcpl_id, + hid_t fapl_id, hid_t req); + void *(*open) (const char *name, unsigned flags, hid_t fapl_id, hid_t req); + herr_t (*flush) (void *obj, H5VL_loc_params_t loc_params, H5F_scope_t scope, hid_t req); + herr_t (*get) (void *file, H5VL_file_get_t get_type, hid_t req, va_list arguments); + herr_t (*misc) (void *file, H5VL_file_misc_t misc_type, hid_t req, va_list arguments); + herr_t (*optional)(void *file, H5VL_file_optional_t op_type, hid_t req, va_list arguments); + herr_t (*close) (void *file, hid_t req); +} H5VL_file_class_t; + +/* H5G routines */ +typedef struct H5VL_group_class_t { + void *(*create)(void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t gcpl_id, hid_t gapl_id, hid_t req); + void *(*open) (void *obj, H5VL_loc_params_t loc_params, const char *name, hid_t gapl_id, hid_t req); + herr_t (*get) (void *obj, H5VL_group_get_t get_type, hid_t req, va_list arguments); + herr_t (*close) (void *grp, hid_t req); +} H5VL_group_class_t; + +/* H5L routines */ +typedef struct H5VL_link_class_t { + herr_t (*create)(H5VL_link_create_type_t create_type, void *obj, H5VL_loc_params_t loc_params, + hid_t lcpl_id, hid_t lapl_id, hid_t req); + herr_t (*move) (void *src_obj, H5VL_loc_params_t loc_params1, + void *dst_obj, H5VL_loc_params_t loc_params2, + hbool_t copy_flag, hid_t lcpl, hid_t lapl, hid_t req); + herr_t (*iterate) (void *obj, H5VL_loc_params_t loc_params, hbool_t recursive, + H5_index_t idx_type, H5_iter_order_t order, hsize_t *idx, + H5L_iterate_t op, void *op_data, hid_t req); + herr_t (*get) (void *obj, H5VL_loc_params_t loc_params, H5VL_link_get_t get_type, hid_t req, va_list arguments); + herr_t (*remove)(void *obj, H5VL_loc_params_t loc_params, hid_t req); +} H5VL_link_class_t; + +/* H5O routines */ +typedef struct H5VL_object_class_t { + void *(*open) (void *obj, H5VL_loc_params_t loc_params, H5I_type_t *opened_type, hid_t req); + herr_t (*copy) (void *src_obj, H5VL_loc_params_t loc_params1, const char *src_name, + void *dst_obj, H5VL_loc_params_t loc_params2, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id, hid_t req); + herr_t (*visit) (void *obj, H5VL_loc_params_t loc_params, H5_index_t idx_type, + H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t req); + //herr_t (*lookup)(hid_t loc_id, H5VL_loc_type_t lookup_type, void **location, hid_t req, va_list arguments); + //herr_t (*free_loc)(void *location, hid_t req); + herr_t (*get) (void *obj, H5VL_loc_params_t loc_params, H5VL_object_get_t get_type, hid_t req, va_list arguments); + herr_t (*misc) (void *obj, H5VL_loc_params_t loc_params, H5VL_object_misc_t misc_type, hid_t req, va_list arguments); + herr_t (*optional)(void *obj, H5VL_loc_params_t loc_params, H5VL_object_optional_t op_type, hid_t req, va_list arguments); + herr_t (*close) (void *obj, H5VL_loc_params_t loc_params, hid_t req); +} H5VL_object_class_t; + +/* enum value to identify the class of a VOL plugin (mostly for comparison purposes */ +typedef enum H5VL_class_value_t { + NATIVE = 0, + DUMMY = 1 +} H5VL_class_value_t; + +/* Class information for each VOL driver */ +typedef struct H5VL_class_t { + H5VL_class_value_t value; + const char *name; + herr_t (*initialize)(void); + herr_t (*terminate)(void); + size_t fapl_size; + void * (*fapl_copy)(const void *info); + herr_t (*fapl_free)(void *info); + H5VL_attr_class_t attr_cls; + H5VL_datatype_class_t datatype_cls; + H5VL_dataset_class_t dataset_cls; + H5VL_file_class_t file_cls; + H5VL_group_class_t group_cls; + H5VL_link_class_t link_cls; + H5VL_object_class_t object_cls; +} H5VL_class_t; + +/* + * The main datatype for each plugin. Public fields common to all + * plugins are declared here and the plugin appends private fields in + * memory. + */ +struct H5VL_t { + const H5VL_class_t *cls; /*constant class info */ + const char *container_name; /* name of the underlying storage container */ + unsigned long feature_flags; /* VOL Driver feature Flags */ + int nrefs; /* number of references by objects using this struct */ +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* ATTRIBUTE OBJECT ROUTINES */ +H5_DLL void *H5VLattr_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *attr_name, hid_t acpl_id, hid_t aapl_id, hid_t req); +H5_DLL void *H5VLattr_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t aapl_id, hid_t req); +H5_DLL herr_t H5VLattr_read(void *attr, H5VL_t *vol_plugin, hid_t dtype_id, void *buf, hid_t req); +H5_DLL herr_t H5VLattr_write(void *attr, H5VL_t *vol_plugin, hid_t dtype_id, const void *buf, hid_t req); +H5_DLL herr_t H5VLattr_get(void *attr, H5VL_t *vol_plugin, H5VL_attr_get_t get_type, hid_t req, va_list arguments); +H5_DLL herr_t H5VLattr_remove(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *attr_name, hid_t req); +H5_DLL herr_t H5VLattr_close(void *attr, H5VL_t *vol_plugin, hid_t req); + +/* DATASE OBJECT ROUTINES */ +H5_DLL void *H5VLdataset_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t dcpl_id, hid_t dapl_id, hid_t req); +H5_DLL void *H5VLdataset_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t dapl_id, hid_t req); +H5_DLL herr_t H5VLdataset_read(void *dset, H5VL_t *vol_plugin, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, void *buf, hid_t req); +H5_DLL herr_t H5VLdataset_write(void *dset, H5VL_t *vol_plugin, hid_t mem_type_id, hid_t mem_space_id, hid_t file_space_id, hid_t plist_id, const void *buf, hid_t req); +H5_DLL herr_t H5VLdataset_set_extent(void *dset, H5VL_t *vol_plugin, const hsize_t size[], hid_t req); +H5_DLL herr_t H5VLdataset_get(void *dset, H5VL_t *vol_plugin, H5VL_dataset_get_t get_type, hid_t req, va_list arguments); +H5_DLL herr_t H5VLdataset_close(void *dset, H5VL_t *vol_plugin, hid_t req); + +/* DATATYPE OBJECT ROUTINES */ +H5_DLL void *H5VLdatatype_commit(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t type_id, hid_t lcpl_id, hid_t tcpl_id, hid_t tapl_id, hid_t req); +H5_DLL void *H5VLdatatype_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t tapl_id, hid_t req); +H5_DLL ssize_t H5VLdatatype_get_binary(void *obj, H5VL_t *vol_plugin, unsigned char *buf, size_t size, hid_t req); +H5_DLL herr_t H5VLdatatype_close(void *dt, H5VL_t *vol_plugin, hid_t req); + +/* FILE OBJECT ROUTINES */ +H5_DLL void *H5VLfile_create(H5VL_t **vol_plugin, const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t req); +H5_DLL void *H5VLfile_open(H5VL_t **vol_plugin, const char *name, unsigned flags, hid_t fapl_id, hid_t req); +H5_DLL herr_t H5VLfile_flush(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5F_scope_t scope, hid_t req); +H5_DLL herr_t H5VLfile_misc(void *file, H5VL_t *vol_plugin, H5VL_file_misc_t misc_type, hid_t req, va_list arguments); +H5_DLL herr_t H5VLfile_optional(void *file, H5VL_t *vol_plugin, H5VL_file_optional_t optional_type, hid_t req, va_list arguments); +H5_DLL herr_t H5VLfile_get(void *file, H5VL_t *vol_plugin, H5VL_file_get_t get_type, hid_t req, va_list arguments); +H5_DLL herr_t H5VLfile_close(void *file, H5VL_t *vol_plugin, hid_t req); + +/* GROUP OBJECT ROUTINES */ +H5_DLL void *H5VLgroup_create(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t gcpl_id, hid_t gapl_id, hid_t req); +H5_DLL void *H5VLgroup_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, const char *name, hid_t gapl_id, hid_t req); +H5_DLL herr_t H5VLgroup_close(void *grp, H5VL_t *vol_plugin, hid_t req); +H5_DLL herr_t H5VLgroup_get(void *obj, H5VL_t *vol_plugin, H5VL_group_get_t get_type, hid_t req, va_list arguments); + +/* LINK OBJECT ROUTINES */ +H5_DLL herr_t H5VLlink_create(H5VL_link_create_type_t create_type, void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, hid_t lcpl_id, hid_t lapl_id, hid_t req); +H5_DLL herr_t H5VLlink_move(void *src_obj, H5VL_loc_params_t loc_params1, + void *dst_obj, H5VL_loc_params_t loc_params2, H5VL_t *vol_plugin, + hbool_t copy_flag, hid_t lcpl_id, hid_t lapl_id, hid_t req); +H5_DLL herr_t H5VLlink_iterate(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, + hbool_t recursive, H5_index_t idx_type, H5_iter_order_t order, + hsize_t *idx, H5L_iterate_t op, void *op_data, hid_t req); +H5_DLL herr_t H5VLlink_get(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_link_get_t get_type, hid_t req, va_list arguments); +H5_DLL herr_t H5VLlink_remove(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, hid_t req); + +/* OBJECT ROUTINES */ +H5_DLL void *H5VLobject_open(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5I_type_t *opened_type, hid_t req); +H5_DLL herr_t H5VLobject_copy(void *src_obj, H5VL_loc_params_t loc_params1, H5VL_t *vol_plugin1, const char *src_name, + void *dst_obj, H5VL_loc_params_t loc_params2, H5VL_t *vol_plugin2, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id, hid_t req); +H5_DLL herr_t H5VLobject_visit(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t req); +H5_DLL herr_t H5VLobject_get(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_object_get_t get_type, hid_t req, va_list arguments); +H5_DLL herr_t H5VLobject_misc(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_object_misc_t misc_type, hid_t req, va_list arguments); +H5_DLL herr_t H5VLobject_optional(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, H5VL_object_misc_t optional_type, hid_t req, va_list arguments); +H5_DLL herr_t H5VLobject_close(void *obj, H5VL_loc_params_t loc_params, H5VL_t *vol_plugin, hid_t req); + +/* Function prototypes */ +H5_DLL hid_t H5VLregister(const H5VL_class_t *cls); +H5_DLL herr_t H5VLunregister(hid_t plugin_id); +H5_DLL htri_t H5VLis_registered(hid_t id); +H5_DLL ssize_t H5VLget_plugin_name(hid_t id, char *name/*out*/, size_t size); +H5_DLL hid_t H5VLobject_register(void *obj, H5I_type_t obj_type, const H5VL_class_t *cls); + +#ifdef __cplusplus +} +#endif + +#endif /* _H5VLpublic_H */ diff --git a/src/H5config.h.in b/src/H5config.h.in index 0308b38..d9016dc 100644 --- a/src/H5config.h.in +++ b/src/H5config.h.in @@ -20,6 +20,9 @@ /* Define the default virtual file driver to compile */ #undef DEFAULT_VFD +/* Define the default vol plugin to compile */ +#undef DEFAULT_VOL + /* Define if `dev_t' is a scalar */ #undef DEV_T_IS_SCALAR diff --git a/src/H5private.h b/src/H5private.h index 44dd01b..46c02e7 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -1556,6 +1556,7 @@ typedef enum { H5_PKG_S, /*Data spaces */ H5_PKG_T, /*Data types */ H5_PKG_V, /*Vector functions */ + H5_PKG_VL, /*VOL functions */ H5_PKG_Z, /*Raw data filters */ H5_NPKGS /*Must be last */ } H5_pkg_t; diff --git a/src/Makefile.am b/src/Makefile.am index 2669bdd..47bdb61 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -53,12 +53,13 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ - H5F.c H5Faccum.c H5Fcwfs.c \ + H5F.c H5Fint.c H5Faccum.c H5Fcwfs.c \ H5Fdbg.c H5Fdeprec.c H5Fefc.c H5Ffake.c H5Fio.c \ H5Fmount.c H5Fmpi.c H5Fquery.c \ H5Fsfile.c H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \ H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \ H5FAstat.c H5FAtest.c \ + H5VL.c H5VLint.c H5VLnative.c \ H5FD.c H5FDcore.c \ H5FDdirect.c H5FDfamily.c H5FDint.c H5FDlog.c H5FDmpi.c H5FDmpio.c \ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c \ @@ -116,6 +117,7 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers H5Epubgen.h H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDcore.h H5FDdirect.h \ H5FDfamily.h H5FDlog.h H5FDmpi.h H5FDmpio.h H5FDmpiposix.h \ H5FDmulti.h H5FDsec2.h H5FDstdio.h \ + H5VLpublic.h H5VLnative.h \ H5Gpublic.h H5Ipublic.h H5Lpublic.h \ H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h H5Spublic.h \ H5Tpublic.h H5Zpublic.h diff --git a/src/Makefile.in b/src/Makefile.in index febb111..d04c4e1 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1,8 +1,9 @@ -# Makefile.in generated by automake 1.12.3 from Makefile.am. +# Makefile.in generated by automake 1.12 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2012 Free Software Foundation, Inc. - +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -130,53 +131,52 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5Dtest.lo H5E.lo H5Edeprec.lo H5Eint.lo H5EA.lo H5EAcache.lo \ H5EAdbg.lo H5EAdblkpage.lo H5EAdblock.lo H5EAhdr.lo \ H5EAiblock.lo H5EAint.lo H5EAsblock.lo H5EAstat.lo H5EAtest.lo \ - H5F.lo H5Faccum.lo H5Fcwfs.lo H5Fdbg.lo H5Fdeprec.lo H5Fefc.lo \ - H5Ffake.lo H5Fio.lo H5Fmount.lo H5Fmpi.lo H5Fquery.lo \ - H5Fsfile.lo H5Fsuper.lo H5Fsuper_cache.lo H5Ftest.lo H5FA.lo \ - H5FAcache.lo H5FAdbg.lo H5FAdblock.lo H5FAdblkpage.lo \ - H5FAhdr.lo H5FAstat.lo H5FAtest.lo H5FD.lo H5FDcore.lo \ - H5FDdirect.lo H5FDfamily.lo H5FDint.lo H5FDlog.lo H5FDmpi.lo \ - H5FDmpio.lo H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo \ - H5FDspace.lo H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo \ - H5FSdbg.lo H5FSsection.lo H5FSstat.lo H5FStest.lo H5G.lo \ - H5Gbtree2.lo H5Gcache.lo H5Gcompact.lo H5Gdense.lo \ - H5Gdeprec.lo H5Gent.lo H5Gint.lo H5Glink.lo H5Gloc.lo \ - H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Groot.lo H5Gstab.lo \ - H5Gtest.lo H5Gtraverse.lo H5HF.lo H5HFbtree2.lo H5HFcache.lo \ - H5HFdbg.lo H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo \ - H5HFiblock.lo H5HFiter.lo H5HFman.lo H5HFsection.lo \ - H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HFtiny.lo H5HG.lo \ - H5HGcache.lo H5HGdbg.lo H5HGquery.lo H5HL.lo H5HLcache.lo \ - H5HLdbg.lo H5HLint.lo H5HP.lo H5I.lo H5Itest.lo H5L.lo \ - H5Lexternal.lo H5lib_settings.lo H5MF.lo H5MFaggr.lo \ - H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo H5MPtest.lo H5O.lo \ - H5Oainfo.lo H5Oalloc.lo H5Oattr.lo H5Oattribute.lo H5Obogus.lo \ - H5Obtreek.lo H5Ocache.lo H5Ochunk.lo H5Ocont.lo H5Ocopy.lo \ - H5Odbg.lo H5Odrvinfo.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo \ - H5Ofsinfo.lo H5Oginfo.lo H5Olayout.lo H5Olinfo.lo H5Olink.lo \ - H5Omessage.lo H5Omtime.lo H5Oname.lo H5Onull.lo H5Opline.lo \ - H5Orefcount.lo H5Osdspace.lo H5Oshared.lo H5Ostab.lo \ - H5Oshmesg.lo H5Otest.lo H5Ounknown.lo H5P.lo H5Pacpl.lo \ - H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo H5Pdxpl.lo H5Pencdec.lo \ - H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo H5Pgcpl.lo H5Pint.lo \ - H5Plapl.lo H5Plcpl.lo H5Pocpl.lo H5Pocpypl.lo H5Pstrcpl.lo \ - H5Ptest.lo H5R.lo H5Rdeprec.lo H5RC.lo H5RS.lo H5S.lo \ - H5Sall.lo H5Sdbg.lo H5Shyper.lo H5Smpio.lo H5Snone.lo \ - H5Spoint.lo H5Sselect.lo H5Stest.lo H5SL.lo H5SM.lo \ - H5SMbtree2.lo H5SMcache.lo H5SMmessage.lo H5SMtest.lo H5ST.lo \ - H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo H5Tcompound.lo \ - H5Tconv.lo H5Tcset.lo H5Tdbg.lo H5Tdeprec.lo H5Tenum.lo \ - H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo H5Tnative.lo \ - H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo H5Tpad.lo \ - H5Tprecis.lo H5Tstrpad.lo H5Tvisit.lo H5Tvlen.lo H5TS.lo \ - H5V.lo H5WB.lo H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo \ + H5F.lo H5Fint.lo H5Faccum.lo H5Fcwfs.lo H5Fdbg.lo H5Fdeprec.lo \ + H5Fefc.lo H5Ffake.lo H5Fio.lo H5Fmount.lo H5Fmpi.lo \ + H5Fquery.lo H5Fsfile.lo H5Fsuper.lo H5Fsuper_cache.lo \ + H5Ftest.lo H5FA.lo H5FAcache.lo H5FAdbg.lo H5FAdblock.lo \ + H5FAdblkpage.lo H5FAhdr.lo H5FAstat.lo H5FAtest.lo H5VL.lo \ + H5VLint.lo H5VLnative.lo H5FD.lo H5FDcore.lo H5FDdirect.lo \ + H5FDfamily.lo H5FDint.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo \ + H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDspace.lo \ + H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \ + H5FSsection.lo H5FSstat.lo H5FStest.lo H5G.lo H5Gbtree2.lo \ + H5Gcache.lo H5Gcompact.lo H5Gdense.lo H5Gdeprec.lo H5Gent.lo \ + H5Gint.lo H5Glink.lo H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo \ + H5Goh.lo H5Groot.lo H5Gstab.lo H5Gtest.lo H5Gtraverse.lo \ + H5HF.lo H5HFbtree2.lo H5HFcache.lo H5HFdbg.lo H5HFdblock.lo \ + H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo H5HFiblock.lo H5HFiter.lo \ + H5HFman.lo H5HFsection.lo H5HFspace.lo H5HFstat.lo H5HFtest.lo \ + H5HFtiny.lo H5HG.lo H5HGcache.lo H5HGdbg.lo H5HGquery.lo \ + H5HL.lo H5HLcache.lo H5HLdbg.lo H5HLint.lo H5HP.lo H5I.lo \ + H5Itest.lo H5L.lo H5Lexternal.lo H5lib_settings.lo H5MF.lo \ + H5MFaggr.lo H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo \ + H5MPtest.lo H5O.lo H5Oainfo.lo H5Oalloc.lo H5Oattr.lo \ + H5Oattribute.lo H5Obogus.lo H5Obtreek.lo H5Ocache.lo \ + H5Ochunk.lo H5Ocont.lo H5Ocopy.lo H5Odbg.lo H5Odrvinfo.lo \ + H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Ofsinfo.lo H5Oginfo.lo \ + H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omessage.lo H5Omtime.lo \ + H5Oname.lo H5Onull.lo H5Opline.lo H5Orefcount.lo H5Osdspace.lo \ + H5Oshared.lo H5Ostab.lo H5Oshmesg.lo H5Otest.lo H5Ounknown.lo \ + H5P.lo H5Pacpl.lo H5Pdapl.lo H5Pdcpl.lo H5Pdeprec.lo \ + H5Pdxpl.lo H5Pencdec.lo H5Pfapl.lo H5Pfcpl.lo H5Pfmpl.lo \ + H5Pgcpl.lo H5Pint.lo H5Plapl.lo H5Plcpl.lo H5Pocpl.lo \ + H5Pocpypl.lo H5Pstrcpl.lo H5Ptest.lo H5R.lo H5Rdeprec.lo \ + H5RC.lo H5RS.lo H5S.lo H5Sall.lo H5Sdbg.lo H5Shyper.lo \ + H5Smpio.lo H5Snone.lo H5Spoint.lo H5Sselect.lo H5Stest.lo \ + H5SL.lo H5SM.lo H5SMbtree2.lo H5SMcache.lo H5SMmessage.lo \ + H5SMtest.lo H5ST.lo H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo \ + H5Tcompound.lo H5Tconv.lo H5Tcset.lo H5Tdbg.lo H5Tdeprec.lo \ + H5Tenum.lo H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo \ + H5Tnative.lo H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo \ + H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo H5Tvisit.lo H5Tvlen.lo \ + H5TS.lo H5V.lo H5WB.lo H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo \ H5Znbit.lo H5Zshuffle.lo H5Zszip.lo H5Zscaleoffset.lo \ H5Ztrans.lo libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent -am__v_lt_1 = libhdf5_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libhdf5_la_LDFLAGS) $(LDFLAGS) -o $@ @@ -190,18 +190,6 @@ H5detect_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ H5make_libsettings_SOURCES = H5make_libsettings.c H5make_libsettings_OBJECTS = H5make_libsettings.$(OBJEXT) H5make_libsettings_LDADD = $(LDADD) -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/bin/depcomp am__depfiles_maybe = depfiles @@ -215,7 +203,9 @@ LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -223,7 +213,9 @@ LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; SOURCES = $(libhdf5_la_SOURCES) H5detect.c H5make_libsettings.c DIST_SOURCES = $(libhdf5_la_SOURCES) H5detect.c H5make_libsettings.c am__can_run_installinfo = \ @@ -550,12 +542,13 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ - H5F.c H5Faccum.c H5Fcwfs.c \ + H5F.c H5Fint.c H5Faccum.c H5Fcwfs.c \ H5Fdbg.c H5Fdeprec.c H5Fefc.c H5Ffake.c H5Fio.c \ H5Fmount.c H5Fmpi.c H5Fquery.c \ H5Fsfile.c H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \ H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \ H5FAstat.c H5FAtest.c \ + H5VL.c H5VLint.c H5VLnative.c \ H5FD.c H5FDcore.c \ H5FDdirect.c H5FDfamily.c H5FDint.c H5FDlog.c H5FDmpi.c H5FDmpio.c \ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c \ @@ -613,6 +606,7 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers H5Epubgen.h H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDcore.h H5FDdirect.h \ H5FDfamily.h H5FDlog.h H5FDmpi.h H5FDmpio.h H5FDmpiposix.h \ H5FDmulti.h H5FDsec2.h H5FDstdio.h \ + H5VLpublic.h H5VLnative.h \ H5Gpublic.h H5Ipublic.h H5Lpublic.h \ H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h H5Spublic.h \ H5Tpublic.h H5Zpublic.h @@ -839,6 +833,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdeprec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fefc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ffake.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fint.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fmount.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fmpi.Plo@am__quote@ @@ -998,6 +993,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tvisit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tvlen.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5V.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VL.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5VLnative.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5WB.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Z.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Zdeflate.Plo@am__quote@ @@ -38,6 +38,10 @@ #include "H5Spublic.h" /* Dataspaces */ #include "H5Tpublic.h" /* Datatypes */ #include "H5Zpublic.h" /* Data filters */ +#include "H5VLpublic.h" /* VOL plugins */ + +/* Predefined VOL plugins */ +#include "H5VLnative.h" /* Native HDF5 plugin */ /* Predefined file drivers */ #include "H5FDcore.h" /* Files stored entirely in memory */ |